use interscript_rs::Runtime;
use std::path::PathBuf;
fn corpus_dir() -> Vec<PathBuf> {
let dir = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("tests/corpus");
vec![dir.clone()]
}
fn rt() -> Runtime {
Runtime::new(corpus_dir())
}
#[test]
fn vendored_corpus_embedded_tests_pass() {
let dir = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("tests/corpus");
let mut maps: Vec<PathBuf> = std::fs::read_dir(&dir)
.expect("tests/corpus exists")
.flatten()
.map(|e| e.path())
.filter(|p| p.extension().and_then(|e| e.to_str()) == Some("isc"))
.collect();
maps.sort();
assert!(maps.len() >= 9, "expected the vendored corpus, found {}", maps.len());
let runtime = rt();
let mut total_pass = 0usize;
let mut total_fail = 0usize;
for map in &maps {
let id = map.file_stem().unwrap().to_string_lossy().to_string();
let (passed, failed, failures) = runtime.run_tests(&id).unwrap_or_else(|e| {
panic!("map {id} failed to load: {e}");
});
total_pass += passed;
total_fail += failed;
assert_eq!(failed, 0, "map {id} failures: {failures:?}");
}
assert!(total_pass >= 10, "expected real test data, got {total_pass}");
}
#[test]
fn boundary_before_and_after_semantics() {
let runtime = rt();
assert_eq!(
runtime.transliterate("rs-boundary", "у k").unwrap(),
"ŭ q"
);
assert_eq!(runtime.transliterate("rs-boundary", "kу").unwrap(), "qŭ");
assert_eq!(runtime.transliterate("rs-boundary", "kku").unwrap(), "qku");
}
#[test]
fn empty_constraint_semantics() {
let runtime = rt();
assert_eq!(
runtime.transliterate("rs-empty-constraints", "aa").unwrap(),
"XX"
);
}
#[test]
fn any_and_negation_semantics() {
let runtime = rt();
assert_eq!(
runtime.transliterate("rs-any", "kakibldcx").unwrap(),
"KmKm*L**m"
);
}
#[test]
fn capture_ref_semantics() {
let runtime = rt();
assert_eq!(runtime.transliterate("rs-capture", "ckzk").unwrap(), "cqsk");
}
#[test]
fn parallel_longest_match_and_constraints() {
let runtime = rt();
assert_eq!(
runtime.transliterate("rs-parallel", "abcd d").unwrap(),
"2d D"
);
}
#[test]
fn parallel_tree_duplicate_keys_last_win() {
let runtime = rt();
assert_eq!(
runtime.transliterate("rs-parallel-tree", "i ab i").unwrap(),
"b AB b"
);
}
#[test]
fn funcall_chain_semantics() {
let runtime = rt();
assert_eq!(
runtime.transliterate("rs-funcalls", "§heating").unwrap(),
" h e a t i n g"
);
}
#[test]
fn library_import_dependency() {
let runtime = rt();
assert_eq!(runtime.transliterate("rs-libdep", "aA 7").unwrap(), "aU #");
}
#[test]
fn aliased_dependency_stage_run() {
let runtime = rt();
assert_eq!(
runtime.transliterate("rs-stage-run", "xaya").unwrap(),
"Xbyb"
);
assert_eq!(
runtime.transliterate("rs-stage-run-dep", "y").unwrap(),
"Y"
);
}
#[test]
fn nested_any_composition() {
let runtime = rt();
assert_eq!(
runtime.transliterate("rs-nested-any", "가ᄀᆨ").unwrap(),
"HJJ"
);
}
#[test]
fn word_boundary_is_unicode_aware() {
let runtime = rt();
assert_eq!(
runtime.transliterate("rs-boundary", "καλ у").unwrap(),
"καλ ŭ"
);
}
#[test]
fn truncated_map_is_parse_error() {
let runtime = rt();
let err = runtime
.transliterate("rs-nonexistent", "x")
.err()
.expect("missing map errors");
assert!(matches!(err, interscript_rs::Error::MapNotFound(_)));
}
#[test]
fn dependency_cycle_detected() {
let dir = std::env::temp_dir().join(format!("iscrs-cycle-{}", std::process::id()));
std::fs::create_dir_all(&dir).unwrap();
std::fs::write(dir.join("a.isc"), "system \"a\" { dependency \"b\" as b\n stage main { run map.b.stage.main } }\n").unwrap();
std::fs::write(dir.join("b.isc"), "system \"b\" { dependency \"a\" as a\n stage main { run map.a.stage.main } }\n").unwrap();
let runtime = Runtime::new(vec![dir.clone()]);
let err = runtime.transliterate("a", "x").err().expect("cycle errors");
assert!(
matches!(err, interscript_rs::Error::DependencyCycle(_)),
"got {err:?}"
);
std::fs::remove_dir_all(&dir).ok();
}