diff --git a/Cargo.lock b/Cargo.lock index af6e9537..c24ac9c9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -184,6 +184,7 @@ dependencies = [ name = "air-testing-framework" version = "0.1.0" dependencies = [ + "air-parser", "air-test-utils", "itertools", "maplit", diff --git a/crates/testing-framework/Cargo.toml b/crates/testing-framework/Cargo.toml index 506a32ae..698cef87 100644 --- a/crates/testing-framework/Cargo.toml +++ b/crates/testing-framework/Cargo.toml @@ -15,6 +15,7 @@ path = "src/lib.rs" [dependencies] air-test-utils = { path = "../air-lib/test-utils" } +air-parser = { path = "../air-lib/air-parser" } itertools = "0.10.4" strum = { version="0.24.1", features=["derive"] } diff --git a/crates/testing-framework/src/execution/mod.rs b/crates/testing-framework/src/execution/mod.rs index 4fd9b5a7..00516bac 100644 --- a/crates/testing-framework/src/execution/mod.rs +++ b/crates/testing-framework/src/execution/mod.rs @@ -42,6 +42,9 @@ impl TestExecutor { extra_peers: impl IntoIterator, annotated_air_script: &str, ) -> Result { + // validate the AIR script with the standard parser first + air_parser::parse(annotated_air_script)?; + let mut sexp = Sexp::from_str(annotated_air_script)?; let mut walker = Transformer::new(); walker.transform(&mut sexp); @@ -504,4 +507,26 @@ mod tests { ExecutionTrace::from(vec![scalar_number(1), request_sent_by("peer1"),]), ) } + + #[test] + fn test_invalid_air() { + let res = TestExecutor::new( + TestRunParameters::from_init_peer_id("init_peer_id"), + vec![], + std::iter::empty(), + r#"(seq +(call "peer1" ("service" "func") [1 22] arg) ; behaviour=echo +) +"#, + ); + + assert!(res.is_err()); + // TestExecutor doesn't implement Debug, so we have to unpack the error this way: + if let Err(err) = res { + assert_eq!( + err, + "error: \n ┌─ script.air:3:1\n │\n3 │ )\n │ ^ expected \"(\"\n\n" + ); + } + } }