slovo/compiler/tests/lowering_inspector.rs

400 lines
15 KiB
Rust

use std::{fs, path::Path, process::Command};
const LOWERING_FIXTURES: &[LoweringFixture] = &[
LoweringFixture {
name: "add",
source: "../examples/add.slo",
surface_snapshot: "../tests/add.surface.lower",
checked_snapshot: "../tests/add.checked.lower",
},
LoweringFixture {
name: "top-level-test",
source: "../tests/top-level-test.slo",
surface_snapshot: "../tests/top-level-test.surface.lower",
checked_snapshot: "../tests/top-level-test.checked.lower",
},
LoweringFixture {
name: "type-aliases",
source: "../tests/type-aliases.slo",
surface_snapshot: "../tests/type-aliases.surface.lower",
checked_snapshot: "../tests/type-aliases.checked.lower",
},
LoweringFixture {
name: "comments",
source: "../tests/comments.slo",
surface_snapshot: "../tests/comments.surface.lower",
checked_snapshot: "../tests/comments.checked.lower",
},
LoweringFixture {
name: "formatter-stability-v1",
source: "../tests/formatter-stability-v1.fmt",
surface_snapshot: "../tests/formatter-stability-v1.surface.lower",
checked_snapshot: "../tests/formatter-stability-v1.checked.lower",
},
LoweringFixture {
name: "unsafe",
source: "../tests/unsafe.slo",
surface_snapshot: "../tests/unsafe.surface.lower",
checked_snapshot: "../tests/unsafe.checked.lower",
},
LoweringFixture {
name: "local-variables",
source: "../examples/local-variables.slo",
surface_snapshot: "../tests/local-variables.surface.lower",
checked_snapshot: "../tests/local-variables.checked.lower",
},
LoweringFixture {
name: "composite-locals",
source: "../examples/composite-locals.slo",
surface_snapshot: "../tests/composite-locals.surface.lower",
checked_snapshot: "../tests/composite-locals.checked.lower",
},
LoweringFixture {
name: "composite-struct-fields",
source: "../examples/composite-struct-fields.slo",
surface_snapshot: "../tests/composite-struct-fields.surface.lower",
checked_snapshot: "../tests/composite-struct-fields.checked.lower",
},
LoweringFixture {
name: "array-struct-fields",
source: "../examples/array-struct-fields.slo",
surface_snapshot: "../tests/array-struct-fields.surface.lower",
checked_snapshot: "../tests/array-struct-fields.checked.lower",
},
LoweringFixture {
name: "array-struct-elements",
source: "../examples/array-struct-elements.slo",
surface_snapshot: "../tests/array-struct-elements.surface.lower",
checked_snapshot: "../tests/array-struct-elements.checked.lower",
},
LoweringFixture {
name: "if",
source: "../examples/if.slo",
surface_snapshot: "../tests/if.surface.lower",
checked_snapshot: "../tests/if.checked.lower",
},
LoweringFixture {
name: "while",
source: "../examples/while.slo",
surface_snapshot: "../tests/while.surface.lower",
checked_snapshot: "../tests/while.checked.lower",
},
LoweringFixture {
name: "struct",
source: "../examples/struct.slo",
surface_snapshot: "../tests/struct.surface.lower",
checked_snapshot: "../tests/struct.checked.lower",
},
LoweringFixture {
name: "struct-value-flow",
source: "../examples/struct-value-flow.slo",
surface_snapshot: "../tests/struct-value-flow.surface.lower",
checked_snapshot: "../tests/struct-value-flow.checked.lower",
},
LoweringFixture {
name: "enum-struct-fields",
source: "../examples/enum-struct-fields.slo",
surface_snapshot: "../tests/enum-struct-fields.surface.lower",
checked_snapshot: "../tests/enum-struct-fields.checked.lower",
},
LoweringFixture {
name: "enum-payload-direct-scalars",
source: "../examples/enum-payload-direct-scalars.slo",
surface_snapshot: "../tests/enum-payload-direct-scalars.surface.lower",
checked_snapshot: "../tests/enum-payload-direct-scalars.checked.lower",
},
LoweringFixture {
name: "enum-payload-structs",
source: "../examples/enum-payload-structs.slo",
surface_snapshot: "../tests/enum-payload-structs.surface.lower",
checked_snapshot: "../tests/enum-payload-structs.checked.lower",
},
LoweringFixture {
name: "primitive-struct-fields",
source: "../examples/primitive-struct-fields.slo",
surface_snapshot: "../tests/primitive-struct-fields.surface.lower",
checked_snapshot: "../tests/primitive-struct-fields.checked.lower",
},
LoweringFixture {
name: "numeric-struct-fields",
source: "../examples/numeric-struct-fields.slo",
surface_snapshot: "../tests/numeric-struct-fields.surface.lower",
checked_snapshot: "../tests/numeric-struct-fields.checked.lower",
},
LoweringFixture {
name: "array",
source: "../examples/array.slo",
surface_snapshot: "../tests/array.surface.lower",
checked_snapshot: "../tests/array.checked.lower",
},
LoweringFixture {
name: "array-direct-scalars",
source: "../examples/array-direct-scalars.slo",
surface_snapshot: "../tests/array-direct-scalars.surface.lower",
checked_snapshot: "../tests/array-direct-scalars.checked.lower",
},
LoweringFixture {
name: "array-direct-scalars-value-flow",
source: "../examples/array-direct-scalars-value-flow.slo",
surface_snapshot: "../tests/array-direct-scalars-value-flow.surface.lower",
checked_snapshot: "../tests/array-direct-scalars-value-flow.checked.lower",
},
LoweringFixture {
name: "array-enum",
source: "../examples/array-enum.slo",
surface_snapshot: "../tests/array-enum.surface.lower",
checked_snapshot: "../tests/array-enum.checked.lower",
},
LoweringFixture {
name: "array-string",
source: "../examples/array-string.slo",
surface_snapshot: "../tests/array-string.surface.lower",
checked_snapshot: "../tests/array-string.checked.lower",
},
LoweringFixture {
name: "array-string-value-flow",
source: "../examples/array-string-value-flow.slo",
surface_snapshot: "../tests/array-string-value-flow.surface.lower",
checked_snapshot: "../tests/array-string-value-flow.checked.lower",
},
LoweringFixture {
name: "array-value-flow",
source: "../examples/array-value-flow.slo",
surface_snapshot: "../tests/array-value-flow.surface.lower",
checked_snapshot: "../tests/array-value-flow.checked.lower",
},
LoweringFixture {
name: "option-result",
source: "../examples/option-result.slo",
surface_snapshot: "../tests/option-result.surface.lower",
checked_snapshot: "../tests/option-result.checked.lower",
},
LoweringFixture {
name: "option-result-flow",
source: "../examples/option-result-flow.slo",
surface_snapshot: "../tests/option-result-flow.surface.lower",
checked_snapshot: "../tests/option-result-flow.checked.lower",
},
LoweringFixture {
name: "option-result-payload",
source: "../examples/option-result-payload.slo",
surface_snapshot: "../tests/option-result-payload.surface.lower",
checked_snapshot: "../tests/option-result-payload.checked.lower",
},
LoweringFixture {
name: "option-result-match",
source: "../examples/option-result-match.slo",
surface_snapshot: "../tests/option-result-match.surface.lower",
checked_snapshot: "../tests/option-result-match.checked.lower",
},
LoweringFixture {
name: "string-print",
source: "../examples/string-print.slo",
surface_snapshot: "../tests/string-print.surface.lower",
checked_snapshot: "../tests/string-print.checked.lower",
},
LoweringFixture {
name: "string-value-flow",
source: "../examples/string-value-flow.slo",
surface_snapshot: "../tests/string-value-flow.surface.lower",
checked_snapshot: "../tests/string-value-flow.checked.lower",
},
LoweringFixture {
name: "print-bool",
source: "../examples/print-bool.slo",
surface_snapshot: "../tests/print-bool.surface.lower",
checked_snapshot: "../tests/print-bool.checked.lower",
},
LoweringFixture {
name: "random",
source: "../examples/random.slo",
surface_snapshot: "../tests/random.surface.lower",
checked_snapshot: "../tests/random.checked.lower",
},
LoweringFixture {
name: "stdin-result",
source: "../examples/stdin-result.slo",
surface_snapshot: "../tests/stdin-result.surface.lower",
checked_snapshot: "../tests/stdin-result.checked.lower",
},
LoweringFixture {
name: "string-parse-i32-result",
source: "../examples/string-parse-i32-result.slo",
surface_snapshot: "../tests/string-parse-i32-result.surface.lower",
checked_snapshot: "../tests/string-parse-i32-result.checked.lower",
},
LoweringFixture {
name: "string-parse-i64-result",
source: "../examples/string-parse-i64-result.slo",
surface_snapshot: "../tests/string-parse-i64-result.surface.lower",
checked_snapshot: "../tests/string-parse-i64-result.checked.lower",
},
LoweringFixture {
name: "string-parse-f64-result",
source: "../examples/string-parse-f64-result.slo",
surface_snapshot: "../tests/string-parse-f64-result.surface.lower",
checked_snapshot: "../tests/string-parse-f64-result.checked.lower",
},
LoweringFixture {
name: "string-parse-bool-result",
source: "../examples/string-parse-bool-result.slo",
surface_snapshot: "../tests/string-parse-bool-result.surface.lower",
checked_snapshot: "../tests/string-parse-bool-result.checked.lower",
},
LoweringFixture {
name: "result-helpers",
source: "../examples/result-helpers.slo",
surface_snapshot: "../tests/result-helpers.surface.lower",
checked_snapshot: "../tests/result-helpers.checked.lower",
},
LoweringFixture {
name: "standard-runtime",
source: "../examples/standard-runtime.slo",
surface_snapshot: "../tests/standard-runtime.surface.lower",
checked_snapshot: "../tests/standard-runtime.checked.lower",
},
LoweringFixture {
name: "owned-string-concat",
source: "../examples/owned-string-concat.slo",
surface_snapshot: "../tests/owned-string-concat.surface.lower",
checked_snapshot: "../tests/owned-string-concat.checked.lower",
},
LoweringFixture {
name: "standard-io-host-env",
source: "../tests/standard-io-host-env.slo",
surface_snapshot: "../tests/standard-io-host-env.surface.lower",
checked_snapshot: "../tests/standard-io-host-env.checked.lower",
},
LoweringFixture {
name: "host-io-result",
source: "../tests/host-io-result.slo",
surface_snapshot: "../tests/host-io-result.surface.lower",
checked_snapshot: "../tests/host-io-result.checked.lower",
},
LoweringFixture {
name: "integer-to-string",
source: "../examples/integer-to-string.slo",
surface_snapshot: "../tests/integer-to-string.surface.lower",
checked_snapshot: "../tests/integer-to-string.checked.lower",
},
LoweringFixture {
name: "f64-to-string",
source: "../examples/f64-to-string.slo",
surface_snapshot: "../tests/f64-to-string.surface.lower",
checked_snapshot: "../tests/f64-to-string.checked.lower",
},
LoweringFixture {
name: "f64-to-i32-result",
source: "../examples/f64-to-i32-result.slo",
surface_snapshot: "../tests/f64-to-i32-result.surface.lower",
checked_snapshot: "../tests/f64-to-i32-result.checked.lower",
},
LoweringFixture {
name: "f64-to-i64-result",
source: "../examples/f64-to-i64-result.slo",
surface_snapshot: "../tests/f64-to-i64-result.surface.lower",
checked_snapshot: "../tests/f64-to-i64-result.checked.lower",
},
LoweringFixture {
name: "checked-i64-to-i32-conversion",
source: "../examples/checked-i64-to-i32-conversion.slo",
surface_snapshot: "../tests/checked-i64-to-i32-conversion.surface.lower",
checked_snapshot: "../tests/checked-i64-to-i32-conversion.checked.lower",
},
LoweringFixture {
name: "vec-i32",
source: "../examples/vec-i32.slo",
surface_snapshot: "../tests/vec-i32.surface.lower",
checked_snapshot: "../tests/vec-i32.checked.lower",
},
];
#[test]
fn promoted_fixtures_print_expected_surface_ast() {
for fixture in LOWERING_FIXTURES {
assert_lowering_fixture(fixture, LoweringMode::Surface);
}
}
#[test]
fn promoted_fixtures_print_expected_checked_ast() {
for fixture in LOWERING_FIXTURES {
assert_lowering_fixture(fixture, LoweringMode::Checked);
}
}
struct LoweringFixture {
name: &'static str,
source: &'static str,
surface_snapshot: &'static str,
checked_snapshot: &'static str,
}
#[derive(Clone, Copy)]
enum LoweringMode {
Surface,
Checked,
}
impl LoweringMode {
fn flag(self) -> &'static str {
match self {
LoweringMode::Surface => "--inspect-lowering=surface",
LoweringMode::Checked => "--inspect-lowering=checked",
}
}
fn snapshot(self, fixture: &LoweringFixture) -> &'static str {
match self {
LoweringMode::Surface => fixture.surface_snapshot,
LoweringMode::Checked => fixture.checked_snapshot,
}
}
}
fn assert_lowering_fixture(fixture: &LoweringFixture, mode: LoweringMode) {
let expected =
fs::read_to_string(Path::new(env!("CARGO_MANIFEST_DIR")).join(mode.snapshot(fixture)))
.expect("read lowering inspector fixture");
let output = run_lowering_inspector(mode.flag(), fixture.source);
assert_success_output(output, expected, fixture.name, mode.flag());
}
fn run_lowering_inspector(mode: &str, fixture: &str) -> std::process::Output {
let compiler = env!("CARGO_BIN_EXE_glagol");
let fixture = Path::new(fixture);
Command::new(compiler)
.arg(mode)
.arg(fixture)
.current_dir(Path::new(env!("CARGO_MANIFEST_DIR")))
.output()
.unwrap_or_else(|err| panic!("run glagol {} on fixture: {}", mode, err))
}
fn assert_success_output(output: std::process::Output, expected: String, name: &str, mode: &str) {
assert!(
output.status.success(),
"lowering inspector failed for `{}` `{}`\nstdout:\n{}\nstderr:\n{}",
name,
mode,
String::from_utf8_lossy(&output.stdout),
String::from_utf8_lossy(&output.stderr),
);
let actual = String::from_utf8(output.stdout).expect("lowering inspector output is UTF-8");
assert_eq!(
actual, expected,
"lowering inspector fixture drifted for `{}` `{}`",
name, mode
);
assert!(
output.stderr.is_empty(),
"lowering inspector wrote stderr for `{}` `{}`:\n{}",
name,
mode,
String::from_utf8_lossy(&output.stderr),
);
}