use interscript_rs::interpreter::{execute_stage_pub, Runtime};
use std::path::PathBuf;
fn reverse_maps() -> Vec<PathBuf> {
vec![PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("tests/reverse_maps")]
}
fn reverse_run(map_id: &str, input: &str) -> String {
let rt = Runtime::new(reverse_maps());
let doc = rt.load(map_id).expect("map loads");
let reversed = interscript_rs::reverse::reverse_document(&doc).expect("reverse");
execute_stage_pub(&reversed, "main", input).expect("reverse stage executes")
}
#[test]
fn reverse_name_swaps_source_and_target() {
use interscript_rs::reverse::reverse_name;
assert_eq!(reverse_name("alalc-bul-Cyrl-Latn-1997"), "alalc-bul-Latn-Cyrl-1997");
assert_eq!(reverse_name("alalc-bul-Latn-Cyrl-1997"), "alalc-bul-Cyrl-Latn-1997");
assert_eq!(reverse_name("some-map-reverse"), "some-map");
assert_eq!(reverse_name("short-x"), "short-x-reverse");
assert_eq!(reverse_name("a-b-c"), "a-b-c-reverse");
}
#[test]
fn parallel_rules_swap_and_reverse_order() {
assert_eq!(reverse_run("rev-parallel", "phth"), "phthh");
assert_eq!(reverse_run("rev-parallel", "x"), "x");
assert_eq!(reverse_run("rev-parallel", "fats"), "phaths");
}
#[test]
fn sequential_children_reverse_order() {
assert_eq!(reverse_run("rev-sequence", "Q"), "ab");
assert_eq!(reverse_run("rev-sequence", "X"), "ab");
assert_eq!(reverse_run("rev-sequence", "ab"), "ab");
assert_eq!(reverse_run("rev-sequence", "abq"), "abq");
}
#[test]
fn case_swap_downcases_the_from_tree() {
assert_eq!(reverse_run("rev-case", "abc"), "Abc");
assert_eq!(reverse_run("rev-case", "abc ABC"), "Abc ABC");
}
#[test]
fn boundary_constraints_pass_through_unchanged() {
assert_eq!(reverse_run("rev-boundary", "r y"), "r x");
assert_eq!(reverse_run("rev-boundary", "yq"), "yq");
assert_eq!(reverse_run("rev-boundary", "qr"), "qr");
}
#[test]
fn capture_and_ref_exchange_sides() {
assert_eq!(reverse_run("rev-capture", "Xbc"), "abcd");
assert_eq!(reverse_run("rev-capture", "Xd"), "Xd");
assert_eq!(reverse_run("rev-capture", "abcd"), "abcd");
}
#[test]
fn funcalls_invert_through_the_reverse_function_map() {
assert_eq!(reverse_run("rev-funcall", "a-b-c"), "abc");
assert_eq!(reverse_run("rev-funcall", "abc"), "abc");
}
#[test]
fn dependency_documents_reverse_with_the_parent() {
assert_eq!(reverse_run("rev-dep", "men"), "mem");
assert_eq!(reverse_run("rev-dep", "pem"), "mem");
}
#[test]
fn real_corpus_map_reverses_like_ruby() {
assert_eq!(reverse_run("alalc-bul-Cyrl-Latn-1997", "Kirillicata"), "Кириллиcата");
assert_eq!(reverse_run("alalc-bul-Cyrl-Latn-1997", "zapad"), "запад");
assert_eq!(reverse_run("alalc-bul-Cyrl-Latn-1997", "Sofiya"), "Софиyа");
}
#[test]
fn empty_reversed_from_disables_the_rule() {
assert_eq!(reverse_run("rev-delete", "hh"), "hh");
assert_eq!(reverse_run("rev-delete", "hi"), "hi");
}
#[test]
fn upcase_funcall_reverse_is_unsupported_like_ruby() {
let rt = Runtime::new(reverse_maps());
let doc = rt.load("rev-upcase-funcall").expect("map loads");
let err = match interscript_rs::reverse::reverse_document(&doc) {
Err(e) => e,
Ok(_) => panic!("upcase funcall reverse must be rejected"),
};
assert!(err.to_string().contains("upcase"), "{err}");
}