use std::{ fs, path::{Path, PathBuf}, process::{Command, Output}, sync::atomic::{AtomicUsize, Ordering}, }; static NEXT_FIXTURE_ID: AtomicUsize = AtomicUsize::new(0); #[test] fn add_fixture_prints_expected_parse_tree() { let compiler = env!("CARGO_BIN_EXE_glagol"); let fixture = Path::new("../examples/add.slo"); let expected = fs::read_to_string("../tests/add.sexpr").expect("read add.sexpr"); let output = run_tree_printer(compiler, fixture); assert!( output.status.success(), "tree printer failed\nstdout:\n{}\nstderr:\n{}", String::from_utf8_lossy(&output.stdout), String::from_utf8_lossy(&output.stderr), ); let actual = String::from_utf8(output.stdout).expect("tree printer output is UTF-8"); assert_eq!(actual, expected); assert!( output.stderr.is_empty(), "tree printer wrote stderr:\n{}", String::from_utf8_lossy(&output.stderr), ); } #[test] fn parser_atoms_print_stably() { let compiler = env!("CARGO_BIN_EXE_glagol"); let fixture = write_fixture( "parser-atoms", r#" (module syntax) (sample () 3.5 "line\nquote\"slash\\" ->) "#, ); let expected = fs::read_to_string("../tests/parser-atoms.sexpr").expect("read parser-atoms.sexpr"); let output = run_tree_printer(compiler, &fixture); assert!( output.status.success(), "tree printer failed\nstdout:\n{}\nstderr:\n{}", String::from_utf8_lossy(&output.stdout), String::from_utf8_lossy(&output.stderr), ); let actual = String::from_utf8(output.stdout).expect("tree printer output is UTF-8"); assert_eq!(actual, expected); assert!( output.stderr.is_empty(), "tree printer wrote stderr:\n{}", String::from_utf8_lossy(&output.stderr), ); } #[test] fn top_level_test_prints_expected_parse_tree() { let compiler = env!("CARGO_BIN_EXE_glagol"); let fixture = Path::new("../tests/top-level-test.slo"); let expected = fs::read_to_string("../tests/top-level-test.sexpr").expect("read top-level-test.sexpr"); let output = run_tree_printer(compiler, fixture); assert!( output.status.success(), "tree printer failed\nstdout:\n{}\nstderr:\n{}", String::from_utf8_lossy(&output.stdout), String::from_utf8_lossy(&output.stderr), ); let actual = String::from_utf8(output.stdout).expect("tree printer output is UTF-8"); assert_eq!(actual, expected); assert!( output.stderr.is_empty(), "tree printer wrote stderr:\n{}", String::from_utf8_lossy(&output.stderr), ); } fn run_tree_printer(compiler: &str, fixture: &Path) -> Output { Command::new(compiler) .arg("--print-tree") .arg(fixture) .output() .unwrap_or_else(|err| { panic!( "run glagol --print-tree on `{}`: {}", fixture.display(), err ) }) } fn write_fixture(name: &str, source: &str) -> PathBuf { let mut path = std::env::temp_dir(); let id = NEXT_FIXTURE_ID.fetch_add(1, Ordering::Relaxed); path.push(format!( "glagol-tree-printer-{}-{}-{}.slo", std::process::id(), id, name )); fs::write(&path, source).unwrap_or_else(|err| panic!("write `{}`: {}", path.display(), err)); path }