use std::path::Path;
use crate::files::{is_markdown, is_scan_target};
const REGISTERED_EXTENSIONS: &[&str] = &[
".py",
".js",
".jsx",
".mjs",
".cjs",
".ts",
".tsx",
".mts",
".cts",
".go",
".rs",
".java",
".kt",
".kts",
".scala",
".sc",
".groovy",
".gradle",
".sh",
".bash",
".swift",
".c",
".h",
".cpp",
".hpp",
".cc",
".hh",
".cxx",
".hxx",
".cs",
".rb",
".rake",
".gemspec",
".php",
".vue",
".svelte",
".tf",
".tfvars",
".ex",
".exs",
".sql",
".dockerfile",
];
#[test]
fn every_registered_extension_is_a_scan_target() {
for ext in REGISTERED_EXTENSIONS {
let path_string = format!("foo{ext}");
let path = Path::new(&path_string);
assert!(
is_scan_target(path),
"expected `{ext}` to be a scan target, but is_scan_target returned false"
);
}
}
#[test]
fn the_hand_written_list_matches_the_language_registry() {
let mut registered: Vec<String> = crate::languages::source_extensions()
.iter()
.map(|e| e.to_string())
.collect();
registered.sort();
let mut ours: Vec<String> = REGISTERED_EXTENSIONS
.iter()
.map(|e| e.to_string())
.collect();
ours.sort();
assert_eq!(ours, registered);
}
#[test]
fn every_registered_filename_and_stem_variant_is_a_scan_target() {
for lang in crate::languages::all_languages() {
for name in lang.filenames {
let path = Path::new(name);
assert!(
is_scan_target(path),
"registered filename `{name}` ({}) is not a scan target",
lang.name
);
assert!(
!is_markdown(path),
"registered filename `{name}` must not be markdown"
);
}
for stem in lang.filename_prefixes {
let variant = format!("{stem}.variant");
assert!(
is_scan_target(Path::new(&variant)),
"stem variant `{variant}` ({}) is not a scan target",
lang.name
);
}
}
}
#[test]
fn the_two_file_classes_are_disjoint() {
for ext in REGISTERED_EXTENSIONS {
let name = format!("foo{ext}");
assert!(!is_markdown(Path::new(&name)), "{ext}");
}
assert!(!is_scan_target(Path::new("README.md")));
assert!(!is_scan_target(Path::new("README.MD")));
assert!(is_markdown(Path::new("README.md")));
}
#[test]
fn extensions_not_owned_by_any_language_or_the_documentation_analyzer_are_not_targets() {
let path_txt = Path::new("notes.txt");
let path_lock = Path::new("Cargo.lock");
let path_png = Path::new("logo.png");
let path_makefile = Path::new("Makefile");
assert!(!is_scan_target(path_txt), ".txt is not a scan target");
assert!(!is_scan_target(path_lock), ".lock is not a scan target");
assert!(!is_scan_target(path_png), ".png is not a scan target");
assert!(
!is_scan_target(path_makefile),
"an extensionless name is not a scan target"
);
}
#[test]
fn scan_target_match_is_case_insensitive() {
assert!(is_scan_target(Path::new("FOO.PY")));
assert!(is_scan_target(Path::new("Main.Go")));
assert!(is_markdown(Path::new("README.MD")));
}
#[test]
fn a_dotfile_with_no_extension_is_not_a_target_and_does_not_panic() {
assert!(!is_scan_target(Path::new(".gitignore")));
assert!(!is_scan_target(Path::new("..")));
}
#[test]
fn is_markdown_is_markdown_only() {
assert!(is_markdown(Path::new("README.md")));
assert!(is_markdown(Path::new("README.MD")));
assert!(!is_markdown(Path::new("foo.py")));
assert!(!is_markdown(Path::new("notes.txt")));
}