use std::path::{Path, PathBuf};
pub(crate) fn rust_source_files(dir: &Path) -> Vec<PathBuf> {
let mut files = Vec::new();
for entry in std::fs::read_dir(dir).expect("read a source directory") {
let path = entry.expect("read a directory entry").path();
if path.is_dir() {
files.extend(rust_source_files(&path));
} else if path.extension().is_some_and(|extension| extension == "rs") {
files.push(path);
}
}
files
}
pub(crate) fn production_rust_source_files(dir: &Path) -> Vec<PathBuf> {
let root = ["main.rs", "lib.rs"]
.iter()
.map(|name| dir.join(name))
.find(|path| path.is_file())
.unwrap_or_else(|| panic!("{} holds neither a main.rs nor a lib.rs", dir.display()));
let source = std::fs::read_to_string(&root).expect("read a crate root");
let lines: Vec<&str> = source.lines().collect();
let mut test_only: Vec<PathBuf> = Vec::new();
for (index, line) in lines.iter().enumerate() {
if line.trim() != "#[cfg(test)]" {
continue;
}
let Some(declaration) = lines.get(index + 1).map(|next| next.trim()) else {
continue;
};
let Some(name) = declaration
.strip_prefix("mod ")
.and_then(|rest| rest.strip_suffix(';'))
else {
continue; };
test_only.push(dir.join(format!("{name}.rs")));
test_only.push(dir.join(name));
}
rust_source_files(dir)
.into_iter()
.filter(|path| !test_only.iter().any(|excluded| path.starts_with(excluded)))
.collect()
}
pub(crate) fn normalised_production(source: &str) -> String {
let mut normalised = String::new();
for line in code_only(source).lines() {
let trimmed = line.trim();
if trimmed.is_empty() {
continue;
}
if !normalised.is_empty() {
normalised.push(' ');
}
normalised.push_str(&trimmed.split_whitespace().collect::<Vec<_>>().join(" "));
}
normalised
}
pub(crate) fn code_only(source: &str) -> String {
let chars: Vec<char> = source.chars().collect();
let mut code = String::new();
let mut index = 0;
while index < chars.len() {
let character = chars[index];
if character == '/' && chars.get(index + 1) == Some(&'/') {
while index < chars.len() && chars[index] != '\n' {
index += 1;
}
continue;
}
if character == '/' && chars.get(index + 1) == Some(&'*') {
index = block_comment_end(&chars, index);
code.push(' ');
continue;
}
if let Some(end) = raw_string_end(&chars, index) {
code.push_str("\"\"");
index = end;
continue;
}
if character == '"' {
index = string_end(&chars, index);
code.push_str("\"\"");
continue;
}
if let Some(end) = char_literal_end(&chars, index) {
code.push_str("''");
index = end;
continue;
}
code.push(character);
index += 1;
}
code
}
fn block_comment_end(chars: &[char], start: usize) -> usize {
let mut depth = 1usize;
let mut index = start + 2;
while index < chars.len() && depth > 0 {
if chars[index] == '/' && chars.get(index + 1) == Some(&'*') {
depth += 1;
index += 2;
} else if chars[index] == '*' && chars.get(index + 1) == Some(&'/') {
depth -= 1;
index += 2;
} else {
index += 1;
}
}
index
}
fn string_end(chars: &[char], start: usize) -> usize {
let mut index = start + 1;
while index < chars.len() {
match chars[index] {
'\\' => index += 2,
'"' => return index + 1,
_ => index += 1,
}
}
chars.len()
}
fn raw_string_end(chars: &[char], start: usize) -> Option<usize> {
let previous = start.checked_sub(1).and_then(|before| chars.get(before));
if previous.is_some_and(|character| character.is_alphanumeric() || *character == '_') {
return None;
}
let mut index = start;
if chars.get(index) == Some(&'b') {
index += 1;
}
if chars.get(index) != Some(&'r') {
return None;
}
index += 1;
let first_hash = index;
while chars.get(index) == Some(&'#') {
index += 1;
}
let hashes = index - first_hash;
if chars.get(index) != Some(&'"') {
return None;
}
index += 1;
while index < chars.len() {
if chars[index] == '"' && (1..=hashes).all(|offset| chars.get(index + offset) == Some(&'#'))
{
return Some(index + 1 + hashes);
}
index += 1;
}
Some(chars.len())
}
fn char_literal_end(chars: &[char], start: usize) -> Option<usize> {
if chars.get(start) != Some(&'\'') {
return None;
}
if chars.get(start + 1) == Some(&'\\') {
let mut index = start + 2;
while index < chars.len() {
if chars[index] == '\'' {
return Some(index + 1);
}
index += 1;
}
return None;
}
if chars.get(start + 2) == Some(&'\'') {
return Some(start + 3);
}
None
}
pub(crate) fn block_at(source: &str, start: usize) -> Option<String> {
let lines: Vec<&str> = source.lines().collect();
let opener = lines.get(start)?;
let indent = &opener[..opener.len() - opener.trim_start().len()];
let closer = format!("{indent}}}");
let end = lines
.iter()
.enumerate()
.skip(start + 1)
.find(|(_, line)| **line == closer)
.map(|(index, _)| index)?;
Some(lines[start..=end].join("\n"))
}
pub(crate) fn blocks_opened_by(source: &str, needle: &str) -> Vec<String> {
let mut blocks = Vec::new();
for (index, line) in source.lines().enumerate() {
if line.trim_start().starts_with("//") || !line.contains(needle) {
continue;
}
if !line.trim_end().ends_with('{') {
blocks.push(line.to_string());
continue;
}
blocks.push(
block_at(source, index).unwrap_or_else(|| panic!("an unclosed block at: {line}")),
);
}
blocks
}
pub(crate) fn match_blocks_over(source: &str, needle: &str) -> Vec<String> {
blocks_opened_by(source, needle)
.into_iter()
.filter(|block| {
block
.lines()
.next()
.is_some_and(|line| line.trim_start().starts_with("match "))
})
.collect()
}
pub(crate) fn production_source(source: &str) -> String {
let lines: Vec<&str> = source.lines().collect();
let tests_module = lines.iter().enumerate().rposition(|(index, line)| {
line.trim() == "#[cfg(test)]"
&& lines
.get(index + 1)
.is_some_and(|next| next.trim_start().starts_with("mod tests"))
});
let mut production = String::new();
for (index, line) in lines.iter().enumerate() {
if Some(index) == tests_module {
break;
}
production.push_str(line);
production.push('\n');
}
production
}
pub(crate) fn production_source_at(path: &Path) -> String {
production_source(&std::fs::read_to_string(path).expect("read a crate source file"))
}
pub(crate) fn source_region(source: &str, name: &str) -> Option<String> {
let begin = format!("// scan: {name} begin");
let end = format!("// scan: {name} end");
let after_begin = source.find(&begin)? + begin.len();
let end_offset = source[after_begin..].find(&end)?;
Some(source[after_begin..after_begin + end_offset].to_string())
}
pub(crate) fn workspace_crate_src_dirs() -> Vec<PathBuf> {
let manifest_dir = Path::new(env!("CARGO_MANIFEST_DIR"));
vec![
manifest_dir.join("src"),
manifest_dir.join("../repon-core/src"),
]
}
pub(crate) fn workspace_rust_source_dirs() -> Vec<PathBuf> {
let manifest_dir = Path::new(env!("CARGO_MANIFEST_DIR"));
vec![
manifest_dir.join("src"),
manifest_dir.join("tests"),
manifest_dir.join("../repon-core/src"),
manifest_dir.join("../repon-core/tests"),
]
}
pub(crate) struct SourceLine {
pub(crate) path: PathBuf,
pub(crate) number: usize,
pub(crate) text: String,
}
pub(crate) fn all_lines_where(dirs: &[PathBuf], matches: impl Fn(&str) -> bool) -> Vec<SourceLine> {
let mut found = Vec::new();
for dir in dirs {
for path in rust_source_files(dir) {
let source = std::fs::read_to_string(&path).expect("read a workspace source file");
for (index, line) in source.lines().enumerate() {
if line.trim_start().starts_with("//") {
continue;
}
if matches(line) {
found.push(SourceLine {
path: path.clone(),
number: index + 1,
text: line.trim().to_string(),
});
}
}
}
}
found
}
pub(crate) fn production_lines_containing(needle: &str) -> Vec<String> {
production_lines_under_containing(&workspace_crate_src_dirs(), needle)
}
pub(crate) fn production_lines_under_containing(dirs: &[PathBuf], needle: &str) -> Vec<String> {
let mut offending = Vec::new();
for dir in dirs {
for path in rust_source_files(dir) {
let production = production_source_at(&path);
for (number, line) in production.lines().enumerate() {
if line.trim_start().starts_with("//") {
continue;
}
if line.contains(needle) {
offending.push(format!("{}:{}", path.display(), number + 1));
}
}
}
}
offending
}
pub(crate) fn incomplete_settled_known_destructures(source: &str) -> (usize, Vec<usize>) {
const NEEDLE: &str = "Settled::Known";
let bytes = source.as_bytes();
let mut total = 0;
let mut incomplete = Vec::new();
for (found, _) in source.match_indices(NEEDLE) {
let line_start = source[..found]
.rfind('\n')
.map_or(0, |position| position + 1);
let line_end = source[found..]
.find('\n')
.map_or(source.len(), |position| found + position);
if source[line_start..line_end].trim_start().starts_with("//") {
continue;
}
let after = &source[found + NEEDLE.len()..];
let Some(brace_offset) = after.find(|character: char| !character.is_whitespace()) else {
continue;
};
if after.as_bytes()[brace_offset] != b'{' {
continue; }
total += 1;
let mut brace_depth = 1i32;
let mut paren_depth = 0i32;
let mut position = found + NEEDLE.len() + brace_offset + 1;
let mut bare_rest_at = None;
while position < bytes.len() && brace_depth > 0 {
match bytes[position] {
b'{' => brace_depth += 1,
b'}' => {
brace_depth -= 1;
if brace_depth == 0 {
break;
}
}
b'(' => paren_depth += 1,
b')' => paren_depth -= 1,
b'.' if brace_depth == 1
&& paren_depth == 0
&& bytes.get(position + 1) == Some(&b'.') =>
{
bare_rest_at = Some(position);
}
_ => {}
}
position += 1;
}
if let Some(rest_position) = bare_rest_at {
incomplete.push(source[..rest_position].matches('\n').count() + 1);
}
}
(total, incomplete)
}
fn assert_top_border_drawn_with(
buf: &ratatui::buffer::Buffer,
area: ratatui::layout::Rect,
border: crate::glyphs::Border,
title: &str,
surface: &str,
) {
let crate::glyphs::Border {
top_left,
top_right,
horizontal,
..
} = border;
let row: String = (area.x..area.right())
.map(|x| buf[(x, area.y)].symbol())
.collect();
let run = usize::from(area.width) - 2;
let title_width = title.chars().count();
assert!(
title_width <= run,
"{surface}: the title {title:?} does not fit between the corners of {area:?}, so this \
helper cannot say which cells of the top run it covers"
);
let expected = format!(
"{top_left}{title}{}{top_right}",
horizontal.to_string().repeat(run - title_width)
);
assert_eq!(
row, expected,
"{surface}: the whole top border, corners and horizontal run alike, must come from the \
glyph table"
);
}
fn assert_side_borders_drawn_with(
buf: &ratatui::buffer::Buffer,
area: ratatui::layout::Rect,
border: crate::glyphs::Border,
surface: &str,
) {
let sides = (area.y + 1)..(area.bottom() - 1);
assert!(
!sides.is_empty(),
"{surface}: {area:?} has no row between its top and bottom borders, so the two vertical \
runs would go unchecked"
);
for y in sides {
assert_eq!(
buf[(area.x, y)].symbol(),
border.vertical.to_string(),
"{surface}: row {y} of the left border must come from the glyph table"
);
assert_eq!(
buf[(area.right() - 1, y)].symbol(),
border.vertical.to_string(),
"{surface}: row {y} of the right border must come from the glyph table"
);
}
}
pub(crate) fn assert_frame_drawn_with(
buf: &ratatui::buffer::Buffer,
area: ratatui::layout::Rect,
border: crate::glyphs::Border,
title: &str,
surface: &str,
) {
assert!(
area.width >= 2 && area.height >= 2,
"{surface}: a frame needs at least 2x2 to have a border at all, got {area:?}"
);
assert_top_border_drawn_with(buf, area, border, title, surface);
let crate::glyphs::Border {
bottom_left,
bottom_right,
horizontal,
..
} = border;
let run = usize::from(area.width) - 2;
let expected_bottom = format!(
"{bottom_left}{}{bottom_right}",
horizontal.to_string().repeat(run)
);
let bottom_row: String = (area.x..area.right())
.map(|x| buf[(x, area.bottom() - 1)].symbol())
.collect();
assert_eq!(
bottom_row, expected_bottom,
"{surface}: the whole bottom border, corners and horizontal run alike, must come from \
the glyph table"
);
assert_side_borders_drawn_with(buf, area, border, surface);
}
pub(crate) fn assert_bordered_frame_and_top_title_drawn_with(
buf: &ratatui::buffer::Buffer,
area: ratatui::layout::Rect,
border: crate::glyphs::Border,
title: &str,
surface: &str,
) {
assert!(
area.width >= 2 && area.height >= 2,
"{surface}: a frame needs at least 2x2 to have a border at all, got {area:?}"
);
assert_top_border_drawn_with(buf, area, border, title, surface);
assert_side_borders_drawn_with(buf, area, border, surface);
let bottom_y = area.bottom() - 1;
assert_eq!(
buf[(area.x, bottom_y)].symbol(),
border.bottom_left.to_string(),
"{surface}: the bottom-left corner must come from the glyph table"
);
assert_eq!(
buf[(area.right() - 1, bottom_y)].symbol(),
border.bottom_right.to_string(),
"{surface}: the bottom-right corner must come from the glyph table"
);
}
pub(crate) fn capture_tracing(f: impl FnOnce()) -> String {
#[derive(Clone, Default)]
struct Captured(std::sync::Arc<std::sync::Mutex<Vec<u8>>>);
impl std::io::Write for Captured {
fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
self.0
.lock()
.expect("captured-log mutex")
.extend_from_slice(buf);
Ok(buf.len())
}
fn flush(&mut self) -> std::io::Result<()> {
Ok(())
}
}
impl<'a> tracing_subscriber::fmt::MakeWriter<'a> for Captured {
type Writer = Self;
fn make_writer(&'a self) -> Self::Writer {
self.clone()
}
}
let captured = Captured::default();
let subscriber = tracing_subscriber::fmt()
.with_writer(captured.clone())
.with_ansi(false)
.finish();
tracing::subscriber::with_default(subscriber, f);
let bytes = captured.0.lock().expect("captured-log mutex").clone();
String::from_utf8_lossy(&bytes).into_owned()
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn a_panic_message_naming_an_action_does_not_satisfy_a_scan_for_that_arm() {
let source = "match dispatch(key) {\n Some(other) => unreachable!(\n \
\"only the input vocabulary, including Action::AcceptCompletion, got \
{other:?}\"\n ),\n}\n";
let normalised = normalised_production(source);
assert!(
!normalised.contains("Action::AcceptCompletion"),
"the panic message's prose still reads as code: {normalised}"
);
assert!(
normalised.contains("unreachable!"),
"the call around the message must survive: {normalised}"
);
}
#[test]
fn a_quote_in_a_character_literal_does_not_swallow_the_code_after_it() {
let source = "fn parse<'a>(text: &'a str) -> Option<&'a str> {\n \
text.strip_prefix('\"')?.split_once('\"').map(Action::Named)\n}\n";
let normalised = normalised_production(source);
assert!(
normalised.contains("split_once") && normalised.contains("Action::Named"),
"code after a quote-bearing character literal went missing: {normalised}"
);
}
#[test]
fn production_source_reads_past_a_test_only_item_to_the_tests_module() {
let source = "#[cfg(test)]\nfn only_built_for_tests() {}\n\nfn real_production() {}\n\n\
#[cfg(test)]\nmod tests {\n fn in_the_module() {}\n}\n";
let production = production_source(source);
assert!(production.contains("fn real_production"));
assert!(!production.contains("fn in_the_module"));
}
#[test]
fn production_source_scans_a_file_with_no_tests_module_whole() {
let source = "fn only_production() {}\n";
assert!(production_source(source).contains("fn only_production"));
}
#[test]
fn source_region_extracts_only_the_lines_between_its_named_markers() {
let source = "fn before() {}\n\
// scan: example begin\n\
fn inside() {}\n\
// scan: example end\n\
fn after() {}\n";
let region = source_region(source, "example").expect("the marker pair is present");
assert!(region.contains("fn inside"));
assert!(!region.contains("fn before"));
assert!(!region.contains("fn after"));
}
#[test]
fn source_region_is_none_when_either_marker_is_missing() {
let only_begin = "// scan: example begin\nfn inside() {}\n";
let neither = "fn inside() {}\n";
assert!(source_region(only_begin, "example").is_none());
assert!(source_region(neither, "example").is_none());
}
#[test]
fn production_source_cuts_at_the_trailing_tests_module_when_a_file_has_two() {
let source = "#[cfg(test)]\nmod tests {\n fn first_module() {}\n}\n\n\
fn real_production() {}\n\n\
#[cfg(test)]\nmod tests {\n fn second_module() {}\n}\n";
let production = production_source(source);
assert!(
production.contains("fn first_module") && production.contains("fn real_production"),
"everything up to the real, trailing tests module counts as production"
);
assert!(!production.contains("fn second_module"));
}
#[test]
fn a_doc_comment_naming_the_test_attribute_does_not_truncate_the_scan() {
let manifest_dir = Path::new(env!("CARGO_MANIFEST_DIR"));
let theme = manifest_dir.join("src").join("theme.rs");
let whole = std::fs::read_to_string(&theme).expect("read theme.rs");
let cfg_test_attribute = format!("{}{}{}", "#[cfg(", "test", ")]");
let naive = whole.split(&cfg_test_attribute).next().unwrap_or(&whole);
let production = production_source_at(&theme);
assert!(
whole.contains("#[cfg(test)]") && naive.lines().count() < 20,
"this test is only meaningful while theme.rs still names the attribute in prose \
ahead of its tests module; if that changed, pin it to another file that does"
);
assert!(
production.lines().count() > naive.lines().count() * 10,
"the scan must read past a doc comment that names the attribute, got {} lines \
against the naive cut's {}",
production.lines().count(),
naive.lines().count()
);
}
fn naive_cfg_test_cut_needle() -> String {
format!("{}{}{}", "split(\"#[cfg(", "test", ")]\")")
}
fn lines_containing_the_naive_cfg_test_cut(source: &str) -> Vec<usize> {
let needle = naive_cfg_test_cut_needle();
source
.lines()
.enumerate()
.filter(|(_, line)| !line.trim_start().starts_with("//") && line.contains(&needle))
.map(|(index, _)| index + 1)
.collect()
}
#[test]
fn the_scan_would_catch_a_reintroduction_of_the_naive_cut() {
let comment = format!(
"// a comment naming {} is not a match",
"split(\"#[cfg(test)]\")"
);
let offender = format!(
"let production = source.{}.next().unwrap_or(&source);",
"split(\"#[cfg(test)]\")"
);
let source = format!("fn f() {{\n {comment}\n {offender}\n}}\n");
assert_eq!(lines_containing_the_naive_cfg_test_cut(&source), vec![3]);
}
#[test]
fn the_naive_cfg_test_cut_never_reappears_in_this_crates_source() {
let manifest_dir = Path::new(env!("CARGO_MANIFEST_DIR"));
let mut offending_locations = Vec::new();
for path in rust_source_files(&manifest_dir.join("src")) {
let whole = std::fs::read_to_string(&path).expect("read a crate source file");
for line_number in lines_containing_the_naive_cfg_test_cut(&whole) {
offending_locations.push(format!("{}:{}", path.display(), line_number));
}
}
assert!(
offending_locations.is_empty(),
"found the naive `#[cfg(test)]` split this ticket replaced with \
`production_source_at`, at: {offending_locations:?}"
);
}
fn tests_module_cut_comparison_needle() -> String {
format!("{}() == \"{}{}{}\"", "trim", "#[cfg(", "test", ")]")
}
fn lines_shaped_like_the_tests_module_cut(source: &str) -> Vec<usize> {
let needle = tests_module_cut_comparison_needle();
source
.lines()
.enumerate()
.filter(|(_, line)| !line.trim_start().starts_with("//") && line.contains(&needle))
.map(|(index, _)| index + 1)
.collect()
}
#[test]
fn the_scan_would_catch_a_reintroduction_of_the_tests_module_cut_under_a_new_name() {
let offender = format!(
"fn a_totally_new_name_for_the_same_cut(line: &str) -> bool {{\n line.{}\n}}\n",
tests_module_cut_comparison_needle()
);
assert_eq!(lines_shaped_like_the_tests_module_cut(&offender), vec![2]);
}
#[test]
fn no_second_definition_of_the_tests_module_cut_exists_anywhere_in_this_crates_source() {
let manifest_dir = Path::new(env!("CARGO_MANIFEST_DIR"));
let mut offending_locations = Vec::new();
for path in rust_source_files(&manifest_dir.join("src")) {
if path
.file_name()
.is_some_and(|name| name == "test_support.rs")
{
continue;
}
let whole = std::fs::read_to_string(&path).expect("read a crate source file");
for line_number in lines_shaped_like_the_tests_module_cut(&whole) {
offending_locations.push(format!("{}:{}", path.display(), line_number));
}
}
assert!(
offending_locations.is_empty(),
"found a second definition of the tests-module cut, by shape rather than by one \
of the three names this ticket retired, at: {offending_locations:?}"
);
}
#[test]
fn rust_source_files_and_production_source_at_together_read_the_full_crate_source() {
let manifest_dir = Path::new(env!("CARGO_MANIFEST_DIR"));
let files = rust_source_files(&manifest_dir.join("src"));
let total_production_lines: usize = files
.iter()
.map(|path| production_source_at(path).lines().count())
.sum();
assert!(
files.len() >= 20,
"expected at least the 21 files measured when this ticket started, found {}",
files.len()
);
assert!(
total_production_lines >= 4_800,
"expected at least (a lower bound under) the 5,050 production lines measured \
when this ticket started, found {total_production_lines}; a lower count means a \
scan's input shrank"
);
}
#[test]
fn an_action_steps_child_never_uses_the_process_group_call_setsid_is_exclusive_with() {
let needle = format!("process_group{}", "(");
let offending = production_lines_containing(&needle);
assert!(
offending.is_empty(),
"found `{needle}`, which fails with EPERM alongside `setsid` and must never be \
used for an Action step's child (docs/spec/actions.md's \"The child\"), at: \
{offending:?}"
);
}
#[test]
fn no_environment_variable_forces_or_strips_colour_for_an_action_step() {
let needles = [
format!("{}{}", "FORCE_COL", "OR"),
format!("{}{}", "CLICOLOR_F", "ORCE"),
format!("{}{}", "NO_COL", "OR"),
];
for needle in needles {
let offending = production_lines_containing(&needle);
assert!(
offending.is_empty(),
"found `{needle}`; neither CLICOLOR_FORCE=1 nor FORCE_COLOR=1 recovers colour \
from a pipe and a PTY needs no help doing it, so none of the three belong in \
an Action step's environment (docs/spec/actions.md's \"The PTY\"), at: \
{offending:?}"
);
}
}
fn production_lines_containing_including_comments(needle: &str) -> Vec<String> {
let mut offending = Vec::new();
for dir in workspace_crate_src_dirs() {
for path in rust_source_files(&dir) {
let production = production_source_at(&path);
for (number, line) in production.lines().enumerate() {
if line.contains(needle) {
offending.push(format!("{}:{}", path.display(), number + 1));
}
}
}
}
offending
}
#[test]
fn the_removed_no_upstream_and_no_remote_unknown_reasons_exist_nowhere_in_the_code() {
for needle in [
format!("Unknown::{}", "NoUpstream"),
format!("Unknown::{}", "NoRemote"),
] {
let offending = production_lines_containing(&needle);
assert!(
offending.is_empty(),
"found `{needle}`; ADR 0019 removed both reasons from the closed `Unknown` \
set, at: {offending:?}"
);
}
}
#[test]
fn the_stale_no_upstream_gloss_appears_nowhere_in_the_code_or_comments() {
let needle = format!("you could {} and have not", "push");
let offending = production_lines_containing_including_comments(&needle);
assert!(
offending.is_empty(),
"found the stale gloss `{needle}`, corrected by ADR 0019 (false for a detached \
HEAD and for every Submodule row already carrying `-`), at: {offending:?}"
);
}
#[test]
fn no_reflog_based_branch_recovery_exists_anywhere_in_the_workspace() {
let dirs = workspace_crate_src_dirs();
let files_scanned: usize = dirs.iter().map(|dir| rust_source_files(dir).len()).sum();
assert!(
files_scanned > 0,
"scanned zero source files; workspace_crate_src_dirs points somewhere that no \
longer exists, and this scan would otherwise pass on having inspected nothing"
);
let needle = format!("log_{}(", "iter");
let offending = production_lines_containing(&needle);
assert!(
offending.is_empty(),
"found a call to gix's own reflog reader (`Reference::log_iter`); ADR 0019 \
measured and rejected reflog-based recovery of a detached HEAD's original \
branch name, at: {offending:?}"
);
}
#[test]
fn no_remote_head_is_ever_written_back_to_a_reference() {
let dirs = workspace_crate_src_dirs();
let files_scanned: usize = dirs.iter().map(|dir| rust_source_files(dir).len()).sum();
assert!(
files_scanned > 0,
"scanned zero source files; workspace_crate_src_dirs points somewhere that no \
longer exists, and this scan would otherwise pass on having inspected nothing"
);
let needle = format!("Target::{}(", "Symbolic");
let offending = production_lines_containing(&needle);
assert!(
offending.is_empty(),
"found a hand-built symbolic ref target (`gix::refs::Target::Symbolic`), the only \
way to write `refs/remotes/<remote>/HEAD`; ADR 0012 keeps the network's advertised \
default branch in memory only and never writes it back, at: {offending:?}"
);
}
#[test]
fn no_per_step_timeout_wraps_waiting_for_an_action_steps_child() {
let needle = format!("wait_{}", "timeout(");
let offending = production_lines_containing(&needle);
assert!(
offending.is_empty(),
"found `{needle}`; a legitimate step can take minutes, so there is no per-step \
timeout, configurable or fixed, only per-step elapsed time \
(docs/spec/actions.md's \"Cancellation and quit\"), at: {offending:?}"
);
}
#[test]
fn an_actions_completion_never_synchronously_reprobes_each_affected_entity_the_way_a_launcher_return_does()
{
let core_source = std::fs::read_to_string(
Path::new(env!("CARGO_MANIFEST_DIR")).join("../repon-core/src/core.rs"),
)
.expect("read repon-core's core.rs");
let completion_path = source_region(&core_source, "action-completion-path")
.expect("core.rs carries the action-completion-path scan markers");
let needle = format!(".{}(", "probe_now");
let offending: Vec<&str> = completion_path
.lines()
.filter(|line| !line.trim_start().starts_with("//") && line.contains(&needle))
.collect();
assert!(
offending.is_empty(),
"found a call to `probe_now` inside run_action's own completion path; \
docs/spec/actions.md's \"Refreshing around a run\" explicitly rejects \
synchronously re-probing each affected entity when an Action finishes \
(measured: about 3.6s for forty entities under the fan-out's own contention, a \
frozen TUI), at: {offending:?}"
);
}
#[test]
fn the_boolean_dirtiness_check_is_never_called_as_a_substitute_for_typed_counts() {
let needle = format!("is_{}(", "dirty");
let offending = production_lines_containing(&needle);
assert!(
offending.is_empty(),
"found `{needle}`; refresh.md measured the boolean check and rejected it as a \
phase C substitute, at: {offending:?}"
);
}
#[test]
fn dirty_counts_passes_its_own_cancel_flag_to_should_interrupt_owned() {
let core_source = std::fs::read_to_string(
Path::new(env!("CARGO_MANIFEST_DIR")).join("../repon-core/src/git.rs"),
)
.expect("read repon-core's git.rs");
let region = source_region(&core_source, "dirty-counts-cancel")
.expect("git.rs carries the dirty-counts-cancel scan markers");
let normalised = normalised_production(®ion);
assert!(
normalised.contains("should_interrupt_owned(cancel)"),
"expected dirty_counts's marked region to pass its own `cancel` parameter to \
`should_interrupt_owned`, found: {normalised:?}"
);
assert!(
normalised.contains("thread_limit = Some(1)"),
"expected dirty_counts's marked region to set gix's per-repository thread limit \
to 1, found: {normalised:?}"
);
}
#[test]
fn probe_fan_out_still_uses_rayons_global_pool_rather_than_a_dedicated_one() {
let core_source = std::fs::read_to_string(
Path::new(env!("CARGO_MANIFEST_DIR")).join("../repon-core/src/core.rs"),
)
.expect("read repon-core's core.rs");
let region = source_region(&core_source, "probe-fanout-pool")
.expect("core.rs carries the probe-fanout-pool scan markers");
let normalised = normalised_production(®ion);
assert!(
normalised.contains("rayon::spawn("),
"expected the probe fan-out's marked region to still dispatch each entity with \
rayon::spawn onto the global pool, found: {normalised:?}"
);
assert!(
!normalised.contains("ThreadPoolBuilder"),
"found a ThreadPoolBuilder inside the probe fan-out's marked region: the fan-out \
now builds a dedicated pool, a real decision docs/adr/0013's own sweep did not \
make; update the ADR (and this test) if that is a deliberate change"
);
}
fn settled_known_needle() -> String {
format!("{}::{}", "Settled", "Known")
}
#[test]
fn incomplete_settled_known_destructures_flags_a_bare_rest_pattern() {
let source = format!(
"match x {{\n {} {{ value, .. }} => value,\n}}\n",
settled_known_needle()
);
let (total, incomplete) = incomplete_settled_known_destructures(&source);
assert_eq!(total, 1);
assert_eq!(incomplete, vec![2]);
}
#[test]
fn incomplete_settled_known_destructures_accepts_every_field_named() {
let source = format!(
"match x {{\n {} {{ value, at, stale }} => value,\n}}\n",
settled_known_needle()
);
let (total, incomplete) = incomplete_settled_known_destructures(&source);
assert_eq!(total, 1);
assert!(incomplete.is_empty());
}
#[test]
fn incomplete_settled_known_destructures_ignores_a_nested_types_own_rest_pattern() {
let source = format!(
"match x {{\n {} {{ value: Head::Branch {{ name, .. }}, at, stale }} => value,\n}}\n",
settled_known_needle()
);
let (total, incomplete) = incomplete_settled_known_destructures(&source);
assert_eq!(total, 1);
assert!(
incomplete.is_empty(),
"the nested Head::Branch rest pattern is not Settled::Known's own"
);
}
#[test]
fn incomplete_settled_known_destructures_skips_a_comment_naming_the_shape_in_prose() {
let source = format!(
"// {} {{ value, .. }} is the shape this test bans\nfn f() {{}}\n",
settled_known_needle()
);
let (total, incomplete) = incomplete_settled_known_destructures(&source);
assert_eq!(total, 0);
assert!(incomplete.is_empty());
}
#[test]
fn every_settled_known_destructure_names_every_field_it_does_not_use() {
let mut files_scanned = 0;
let mut total_sites = 0;
let mut offending = Vec::new();
for dir in workspace_crate_src_dirs() {
for path in rust_source_files(&dir) {
files_scanned += 1;
let source = std::fs::read_to_string(&path).expect("read a crate source file");
let (sites, incomplete_lines) = incomplete_settled_known_destructures(&source);
total_sites += sites;
for line in incomplete_lines {
offending.push(format!("{}:{}", path.display(), line));
}
}
}
assert!(
files_scanned > 0,
"scanned zero source files; workspace_crate_src_dirs points somewhere that no \
longer exists, and this scan would otherwise pass on having inspected nothing"
);
assert!(
total_sites > 0,
"found zero `Settled::Known {{ }}` sites across either crate; this scan's own \
matcher broke rather than the type disappearing, and would otherwise pass \
vacuously"
);
assert!(
offending.is_empty(),
"found a `Settled::Known` destructure hiding a field behind a bare `..`, which \
lets a fourth field reach this site unnoticed; name every field it does not \
use instead (`at: _, stale: _`, say), at: {offending:?}"
);
}
#[test]
fn exactly_eight_production_call_sites_start_a_generation_from_the_repon_crate() {
let files: usize = workspace_crate_src_dirs()
.iter()
.map(|dir| rust_source_files(dir).len())
.sum();
assert!(
files > 0,
"scanned zero source files; workspace_crate_src_dirs points somewhere that no \
longer exists, and this scan would otherwise pass on having inspected nothing"
);
let ordered = production_lines_containing(&format!(".{}(", "refresh"));
let over_everything = production_lines_containing(&format!(".{}(", "refresh_all"));
let at_launch = production_lines_containing(&format!("Core::{}(", "start"));
assert!(
!ordered.is_empty() && !over_everything.is_empty() && !at_launch.is_empty(),
"found zero calls to one of `Core::refresh`, `Core::refresh_all` and \
`Core::start`; this scan's own needles broke rather than every trigger \
disappearing, and it would otherwise pass vacuously"
);
assert_eq!(
ordered.len(),
4,
"expected exactly four production call sites into `Core::refresh` (returning \
from suspension, RefreshAll, terminal focus gained and RefreshSelection); a \
count that moved means a trigger was added, removed, or a call site \
duplicated, at: {ordered:?}"
);
assert_eq!(
over_everything.len(),
1,
"expected exactly one production call site into `Core::refresh_all` (a Set \
switch); a count that moved means a trigger was added, removed, or a call \
site duplicated, at: {over_everything:?}"
);
assert_eq!(
at_launch.len(),
3,
"expected exactly three production call sites into `Core::start` (startup, a \
Set switch's rebuild and `repon status`'s own one-shot dispatch), each of \
which starts that `Core`'s Generation 1 with its own first walk; a count that \
moved means a trigger was added, removed, or a call site duplicated, at: \
{at_launch:?}"
);
}
#[test]
fn exactly_five_production_call_sites_mint_a_new_generation_in_repon_core() {
let core_src = vec![workspace_crate_src_dirs()[1].clone()];
assert!(
!rust_source_files(&core_src[0]).is_empty(),
"scanned zero files under repon-core/src; the relative path above no longer \
resolves, and this scan would otherwise pass on having inspected nothing"
);
let ordered = production_lines_under_containing(&core_src, &format!(".{}(", "dispatch"));
let over_everything = production_lines_under_containing(
&core_src,
&format!(".{}(", "dispatch_over_everything"),
);
let reserved =
production_lines_under_containing(&core_src, &format!(".{}(", "reserve_generation"));
assert!(
!ordered.is_empty() && !over_everything.is_empty() && !reserved.is_empty(),
"found zero calls to one of `RefreshHandles::dispatch`, \
`RefreshHandles::dispatch_over_everything` and \
`RefreshHandles::reserve_generation`; this scan's own needles broke rather \
than every Generation-minting call site disappearing, and it would otherwise \
pass vacuously"
);
assert_eq!(
ordered.len(),
3,
"expected exactly three production call sites into `RefreshHandles::dispatch` \
(`Core::refresh`'s own body, an Action's completion inside `Core::run_action`, and \
a finished periodic fetch's completion inside `run_fetch_cycle`); a count that \
moved means a new place starts one, at: {ordered:?}"
);
assert_eq!(
over_everything.len(),
1,
"expected exactly one production call site into \
`RefreshHandles::dispatch_over_everything` (`Core::refresh_all`'s own body); a \
count that moved means a new place starts one, at: {over_everything:?}"
);
assert_eq!(
reserved.len(),
3,
"expected exactly three production call sites into \
`RefreshHandles::reserve_generation` (`dispatch`, `dispatch_over_everything` \
and `start_internal`'s own first Generation); a count that moved means a new \
place mints one, at: {reserved:?}"
);
}
#[test]
fn no_push_commit_merge_rebase_or_reset_operation_exists_in_production_code() {
let dirs = workspace_crate_src_dirs();
let files_scanned: usize = dirs.iter().map(|dir| rust_source_files(dir).len()).sum();
assert!(
files_scanned > 0,
"scanned zero source files; workspace_crate_src_dirs points somewhere that no \
longer exists, and this scan would otherwise pass on having inspected nothing"
);
let needles: [(&str, &str); 5] = [
(
"a push-direction remote operation (gix's own `Direction::Push`)",
"Direction::Push",
),
(
"a commit created via gix's own commit machinery",
".commit(",
),
("a merge via gix's own merge machinery", ".merge("),
("a rebase via gix's own machinery", ".rebase("),
("a reset via gix's own machinery", ".reset("),
];
for (description, needle) in needles {
let offending = production_lines_containing(needle);
assert!(
offending.is_empty(),
"found {description} (needle `{needle}`) in production code, which this \
ticket's narrowest-safe-operation rule forbids outright: {offending:?}"
);
}
}
#[test]
fn the_fast_forward_only_auto_update_actually_exists() {
let offending = production_lines_containing("fn fast_forward(");
assert!(
!offending.is_empty(),
"found no `fn fast_forward(` in repon-core; the mutating-operations scan above \
is only the whole claim while this mechanism actually exists"
);
}
#[test]
fn exactly_three_production_call_sites_cancel_a_generation_in_repon_core() {
let core_src = vec![workspace_crate_src_dirs()[1].clone()];
assert!(
!rust_source_files(&core_src[0]).is_empty(),
"scanned zero files under repon-core/src; the relative path above no longer \
resolves, and this scan would otherwise pass on having inspected nothing"
);
let offending =
production_lines_under_containing(&core_src, &format!("{}(", "cancel_in_flight"));
assert!(
!offending.is_empty(),
"found zero mentions of `cancel_in_flight`; this scan's own needle broke rather \
than every cancellation call site disappearing, and would otherwise pass vacuously"
);
assert_eq!(
offending.len(),
4,
"expected exactly three production call sites that cancel a Generation (an \
Action starting, the Suspension pause and a `Core` being dropped), plus the \
function's own declaration; a count that moved means a new place cancels one, \
at: {offending:?}"
);
}
}