use drawlang_syntax::fmt::format;
use drawlang_syntax::parse_source;
fn example(name: &str) -> String {
let path = format!("{}/../../examples/{name}", env!("CARGO_MANIFEST_DIR"));
std::fs::read_to_string(&path).unwrap_or_else(|e| panic!("read {path}: {e}"))
}
fn fmt(src: &str) -> String {
let parsed = parse_source(src);
assert!(!parsed.has_errors(), "{:?}", parsed.diagnostics);
format(&parsed.file, src)
}
#[test]
fn idempotent_on_examples() {
for name in ["hello.drawl", "gpu-topology.drawl", "cpu-arch.drawl"] {
let src = example(name);
let once = fmt(&src);
let twice = fmt(&once);
assert_eq!(once, twice, "{name}: fmt must be idempotent");
}
}
#[test]
fn formatted_output_still_parses_clean() {
for name in ["hello.drawl", "gpu-topology.drawl", "cpu-arch.drawl"] {
let formatted = fmt(&example(name));
let reparsed = parse_source(&formatted);
assert!(
reparsed.diagnostics.is_empty(),
"{name}: formatted output must parse clean:\n{formatted}"
);
}
}
#[test]
fn comments_round_trip() {
let src = "drawl 0.1\n\n// leading comment\nn { label: \"x\" } // trailing\n";
let out = fmt(src);
assert!(out.contains("// leading comment"), "{out}");
assert!(out.contains("// trailing"), "{out}");
}
#[test]
fn strings_and_interpolation_round_trip() {
let src = "drawl 0.1\nfor i in 0..2 { n { label: \"GPU {i + 1} \\\"x\\\"\" } }\n";
let out = fmt(src);
assert!(out.contains(r#""GPU {i + 1} \"x\"""#), "{out}");
let reparsed = parse_source(&out);
assert!(
reparsed.diagnostics.is_empty(),
"{:?}",
reparsed.diagnostics
);
}
#[test]
fn normalizes_messy_spacing() {
let messy = "drawl 0.1\na{label:\"A\"}\nb { label : \"B\" }\na->b:\"edge\"\n";
let out = fmt(messy);
assert!(out.contains("a { label: \"A\" }"), "{out}");
assert!(out.contains("a -> b : \"edge\""), "{out}");
}