diff --git a/crates/plotnik-compiler/src/compile/compile_tests.rs b/crates/plotnik-compiler/src/compile/compile_tests.rs index 622f9b7..5618ce9 100644 --- a/crates/plotnik-compiler/src/compile/compile_tests.rs +++ b/crates/plotnik-compiler/src/compile/compile_tests.rs @@ -1,117 +1,55 @@ //! Integration tests for the compilation pipeline. -use std::cell::RefCell; - -use super::*; -use crate::{emit::StringTableBuilder, query::QueryBuilder}; - -/// Helper to compile a query with default context. -fn compile_query(query: &crate::query::QueryAnalyzed) -> CompileResult { - let strings = RefCell::new(StringTableBuilder::new()); - let ctx = CompileCtx { - interner: query.interner(), - type_ctx: query.type_context(), - symbol_table: &query.symbol_table, - strings: &strings, - node_types: None, - node_fields: None, - }; - Compiler::compile(&ctx).unwrap() -} +use crate::shot_bytecode; #[test] fn compile_simple_named_node() { - let query = QueryBuilder::one_liner("Test = (identifier)") - .parse() - .unwrap() - .analyze(); - - let result = compile_query(&query); - - // Should have at least one instruction - assert!(!result.instructions.is_empty()); - // Should have one entrypoint - assert_eq!(result.def_entries.len(), 1); + shot_bytecode!("Test = (identifier)"); } #[test] fn compile_alternation() { - let query = QueryBuilder::one_liner("Test = [(identifier) (number)]") - .parse() - .unwrap() - .analyze(); - - let result = compile_query(&query); - - assert!(!result.instructions.is_empty()); + shot_bytecode!("Test = [(identifier) (number)]"); } #[test] fn compile_sequence() { - let query = QueryBuilder::one_liner("Test = {(comment) (function)}") - .parse() - .unwrap() - .analyze(); - - let result = compile_query(&query); - - assert!(!result.instructions.is_empty()); + shot_bytecode!("Test = {(comment) (identifier)}"); } #[test] fn compile_quantified() { - let query = QueryBuilder::one_liner("Test = (identifier)*") - .parse() - .unwrap() - .analyze(); - - let result = compile_query(&query); - - assert!(!result.instructions.is_empty()); + shot_bytecode!("Test = (identifier)*"); } #[test] fn compile_capture() { - let query = QueryBuilder::one_liner("Test = (identifier) @id") - .parse() - .unwrap() - .analyze(); - - let result = compile_query(&query); - - assert!(!result.instructions.is_empty()); + shot_bytecode!("Test = (identifier) @id"); } #[test] fn compile_nested() { - let query = QueryBuilder::one_liner("Test = (call_expression function: (identifier) @fn)") - .parse() - .unwrap() - .analyze(); - - let result = compile_query(&query); - - assert!(!result.instructions.is_empty()); + shot_bytecode!("Test = (call_expression function: (identifier) @fn)"); } #[test] fn compile_large_tagged_alternation() { // Regression test: alternations with 30+ branches should compile // by splitting epsilon transitions into a cascade. - let branches: String = (0..30) - .map(|i| format!("A{i}: (identifier) @x{i}")) - .collect::>() - .join(" "); - let query_str = format!("Q = [{branches}]"); - - let query = QueryBuilder::one_liner(&query_str) - .parse() - .unwrap() - .analyze(); - - let result = compile_query(&query); - - assert!(!result.instructions.is_empty()); + shot_bytecode!(r#" + Q = [ + A0: (identifier) @x0 A1: (identifier) @x1 A2: (identifier) @x2 + A3: (identifier) @x3 A4: (identifier) @x4 A5: (identifier) @x5 + A6: (identifier) @x6 A7: (identifier) @x7 A8: (identifier) @x8 + A9: (identifier) @x9 A10: (identifier) @x10 A11: (identifier) @x11 + A12: (identifier) @x12 A13: (identifier) @x13 A14: (identifier) @x14 + A15: (identifier) @x15 A16: (identifier) @x16 A17: (identifier) @x17 + A18: (identifier) @x18 A19: (identifier) @x19 A20: (identifier) @x20 + A21: (identifier) @x21 A22: (identifier) @x22 A23: (identifier) @x23 + A24: (identifier) @x24 A25: (identifier) @x25 A26: (identifier) @x26 + A27: (identifier) @x27 A28: (identifier) @x28 A29: (identifier) @x29 + ] + "#); } #[test] @@ -119,44 +57,17 @@ fn compile_unlabeled_alternation_5_branches_with_captures() { // Regression test: unlabeled alternation with 5+ branches where each has // a unique capture requires 8+ pre-effects (4 nulls + 4 sets per branch). // This exceeds the 3-bit limit (max 7) and must cascade via epsilon chain. - let query = QueryBuilder::one_liner( - "Q = [(identifier) @a (number) @b (string) @c (binary_expression) @d (call_expression) @e]", - ) - .parse() - .unwrap() - .analyze(); - - let result = compile_query(&query); - - assert!(!result.instructions.is_empty()); - - // Verify that effects cascade created extra epsilon instructions. - // With 5 branches, each branch needs 8 pre-effects (4 missing captures × 2 effects). - // This requires at least one cascade step per branch. - let epsilon_count = result - .instructions - .iter() - .filter(|i| matches!(i, crate::bytecode::InstructionIR::Match(m) if m.is_epsilon())) - .count(); - - // Should have more epsilon transitions than without cascade - // (5 branches + cascade steps for overflow effects) - assert!(epsilon_count >= 5, "expected cascade epsilon steps"); + shot_bytecode!( + "Q = [(identifier) @a (number) @b (string) @c (binary_expression) @d (call_expression) @e]" + ); } #[test] fn compile_unlabeled_alternation_8_branches_with_captures() { // Even more extreme: 8 branches means 14 pre-effects per branch (7 nulls + 7 sets). // This requires 2 cascade steps per branch. - let query = QueryBuilder::one_liner( - "Q = [(identifier) @a (number) @b (string) @c (binary_expression) @d \ - (call_expression) @e (member_expression) @f (array) @g (object) @h]", - ) - .parse() - .unwrap() - .analyze(); - - let result = compile_query(&query); - - assert!(!result.instructions.is_empty()); + shot_bytecode!(r#" + Q = [(identifier) @a (number) @b (string) @c (binary_expression) @d + (call_expression) @e (member_expression) @f (array) @g (object) @h] + "#); } diff --git a/crates/plotnik-compiler/src/compile/snapshots/plotnik_compiler__compile__compile_tests__compile_alternation.snap b/crates/plotnik-compiler/src/compile/snapshots/plotnik_compiler__compile__compile_tests__compile_alternation.snap new file mode 100644 index 0000000..d22b2c0 --- /dev/null +++ b/crates/plotnik-compiler/src/compile/snapshots/plotnik_compiler__compile__compile_tests__compile_alternation.snap @@ -0,0 +1,34 @@ +--- +source: crates/plotnik-compiler/src/compile/compile_tests.rs +--- +Test = [(identifier) (number)] +--- +[strings] +S0 "Beauty will save the world" +S1 "Test" +S2 "identifier" +S3 "number" + +[type_defs] +T0 = + +[type_members] + +[type_names] +N0: S1 → T0 ; Test + +[entrypoints] +Test = 06 :: T0 + +[transitions] +_ObjWrap: + 00 ε [Obj] 02 + 02 Trampoline 03 + 03 ε [EndObj] 05 + 05 ▶ + +Test: + 06 ε 09, 10 + 08 ▶ + 09 ! (identifier) 08 + 10 ! (number) 08 diff --git a/crates/plotnik-compiler/src/compile/snapshots/plotnik_compiler__compile__compile_tests__compile_capture.snap b/crates/plotnik-compiler/src/compile/snapshots/plotnik_compiler__compile__compile_tests__compile_capture.snap new file mode 100644 index 0000000..e8242a3 --- /dev/null +++ b/crates/plotnik-compiler/src/compile/snapshots/plotnik_compiler__compile__compile_tests__compile_capture.snap @@ -0,0 +1,34 @@ +--- +source: crates/plotnik-compiler/src/compile/compile_tests.rs +--- +Test = (identifier) @id +--- +[strings] +S0 "Beauty will save the world" +S1 "id" +S2 "Test" +S3 "identifier" + +[type_defs] +T0 = +T1 = Struct M0:1 ; { id } + +[type_members] +M0: S1 → T0 ; id: + +[type_names] +N0: S2 → T1 ; Test + +[entrypoints] +Test = 6 :: T1 + +[transitions] +_ObjWrap: + 0 ε [Obj] 2 + 2 Trampoline 3 + 3 ε [EndObj] 5 + 5 ▶ + +Test: + 6 ! (identifier) [Node Set(M0)] 8 + 8 ▶ diff --git a/crates/plotnik-compiler/src/compile/snapshots/plotnik_compiler__compile__compile_tests__compile_large_tagged_alternation.snap b/crates/plotnik-compiler/src/compile/snapshots/plotnik_compiler__compile__compile_tests__compile_large_tagged_alternation.snap new file mode 100644 index 0000000..18b9750 --- /dev/null +++ b/crates/plotnik-compiler/src/compile/snapshots/plotnik_compiler__compile__compile_tests__compile_large_tagged_alternation.snap @@ -0,0 +1,255 @@ +--- +source: crates/plotnik-compiler/src/compile/compile_tests.rs +--- +Q = [ + A0: (identifier) @x0 A1: (identifier) @x1 A2: (identifier) @x2 + A3: (identifier) @x3 A4: (identifier) @x4 A5: (identifier) @x5 + A6: (identifier) @x6 A7: (identifier) @x7 A8: (identifier) @x8 + A9: (identifier) @x9 A10: (identifier) @x10 A11: (identifier) @x11 + A12: (identifier) @x12 A13: (identifier) @x13 A14: (identifier) @x14 + A15: (identifier) @x15 A16: (identifier) @x16 A17: (identifier) @x17 + A18: (identifier) @x18 A19: (identifier) @x19 A20: (identifier) @x20 + A21: (identifier) @x21 A22: (identifier) @x22 A23: (identifier) @x23 + A24: (identifier) @x24 A25: (identifier) @x25 A26: (identifier) @x26 + A27: (identifier) @x27 A28: (identifier) @x28 A29: (identifier) @x29 +] +--- +[strings] +S00 "Beauty will save the world" +S01 "x0" +S02 "x1" +S03 "x2" +S04 "x3" +S05 "x4" +S06 "x5" +S07 "x6" +S08 "x7" +S09 "x8" +S10 "x9" +S11 "x10" +S12 "x11" +S13 "x12" +S14 "x13" +S15 "x14" +S16 "x15" +S17 "x16" +S18 "x17" +S19 "x18" +S20 "x19" +S21 "x20" +S22 "x21" +S23 "x22" +S24 "x23" +S25 "x24" +S26 "x25" +S27 "x26" +S28 "x27" +S29 "x28" +S30 "x29" +S31 "A0" +S32 "A1" +S33 "A2" +S34 "A3" +S35 "A4" +S36 "A5" +S37 "A6" +S38 "A7" +S39 "A8" +S40 "A9" +S41 "A10" +S42 "A11" +S43 "A12" +S44 "A13" +S45 "A14" +S46 "A15" +S47 "A16" +S48 "A17" +S49 "A18" +S50 "A19" +S51 "A20" +S52 "A21" +S53 "A22" +S54 "A23" +S55 "A24" +S56 "A25" +S57 "A26" +S58 "A27" +S59 "A28" +S60 "A29" +S61 "Q" +S62 "identifier" + +[type_defs] +T00 = +T01 = Struct M00:1 ; { x0 } +T02 = Struct M01:1 ; { x1 } +T03 = Struct M02:1 ; { x2 } +T04 = Struct M03:1 ; { x3 } +T05 = Struct M04:1 ; { x4 } +T06 = Struct M05:1 ; { x5 } +T07 = Struct M06:1 ; { x6 } +T08 = Struct M07:1 ; { x7 } +T09 = Struct M08:1 ; { x8 } +T10 = Struct M09:1 ; { x9 } +T11 = Struct M10:1 ; { x10 } +T12 = Struct M11:1 ; { x11 } +T13 = Struct M12:1 ; { x12 } +T14 = Struct M13:1 ; { x13 } +T15 = Struct M14:1 ; { x14 } +T16 = Struct M15:1 ; { x15 } +T17 = Struct M16:1 ; { x16 } +T18 = Struct M17:1 ; { x17 } +T19 = Struct M18:1 ; { x18 } +T20 = Struct M19:1 ; { x19 } +T21 = Struct M20:1 ; { x20 } +T22 = Struct M21:1 ; { x21 } +T23 = Struct M22:1 ; { x22 } +T24 = Struct M23:1 ; { x23 } +T25 = Struct M24:1 ; { x24 } +T26 = Struct M25:1 ; { x25 } +T27 = Struct M26:1 ; { x26 } +T28 = Struct M27:1 ; { x27 } +T29 = Struct M28:1 ; { x28 } +T30 = Struct M29:1 ; { x29 } +T31 = Enum M30:30 ; A0 | A1 | A2 | A3 | A4 | A5 | A6 | A7 | A8 | A9 | A10 | A11 | A12 | A13 | A14 | A15 | A16 | A17 | A18 | A19 | A20 | A21 | A22 | A23 | A24 | A25 | A26 | A27 | A28 | A29 + +[type_members] +M00: S01 → T00 ; x0: +M01: S02 → T00 ; x1: +M02: S03 → T00 ; x2: +M03: S04 → T00 ; x3: +M04: S05 → T00 ; x4: +M05: S06 → T00 ; x5: +M06: S07 → T00 ; x6: +M07: S08 → T00 ; x7: +M08: S09 → T00 ; x8: +M09: S10 → T00 ; x9: +M10: S11 → T00 ; x10: +M11: S12 → T00 ; x11: +M12: S13 → T00 ; x12: +M13: S14 → T00 ; x13: +M14: S15 → T00 ; x14: +M15: S16 → T00 ; x15: +M16: S17 → T00 ; x16: +M17: S18 → T00 ; x17: +M18: S19 → T00 ; x18: +M19: S20 → T00 ; x19: +M20: S21 → T00 ; x20: +M21: S22 → T00 ; x21: +M22: S23 → T00 ; x22: +M23: S24 → T00 ; x23: +M24: S25 → T00 ; x24: +M25: S26 → T00 ; x25: +M26: S27 → T00 ; x26: +M27: S28 → T00 ; x27: +M28: S29 → T00 ; x28: +M29: S30 → T00 ; x29: +M30: S31 → T01 ; A0: T01 +M31: S32 → T02 ; A1: T02 +M32: S33 → T03 ; A2: T03 +M33: S34 → T04 ; A3: T04 +M34: S35 → T05 ; A4: T05 +M35: S36 → T06 ; A5: T06 +M36: S37 → T07 ; A6: T07 +M37: S38 → T08 ; A7: T08 +M38: S39 → T09 ; A8: T09 +M39: S40 → T10 ; A9: T10 +M40: S41 → T11 ; A10: T11 +M41: S42 → T12 ; A11: T12 +M42: S43 → T13 ; A12: T13 +M43: S44 → T14 ; A13: T14 +M44: S45 → T15 ; A14: T15 +M45: S46 → T16 ; A15: T16 +M46: S47 → T17 ; A16: T17 +M47: S48 → T18 ; A17: T18 +M48: S49 → T19 ; A18: T19 +M49: S50 → T20 ; A19: T20 +M50: S51 → T21 ; A20: T21 +M51: S52 → T22 ; A21: T22 +M52: S53 → T23 ; A22: T23 +M53: S54 → T24 ; A23: T24 +M54: S55 → T25 ; A24: T25 +M55: S56 → T26 ; A25: T26 +M56: S57 → T27 ; A26: T27 +M57: S58 → T28 ; A27: T28 +M58: S59 → T29 ; A28: T29 +M59: S60 → T30 ; A29: T30 + +[type_names] +N0: S61 → T31 ; Q + +[entrypoints] +Q = 006 :: T31 + +[transitions] +_ObjWrap: + 000 ε [Obj] 002 + 002 Trampoline 003 + 003 ε [EndObj] 005 + 005 ▶ + +Q: + 006 ε 008 + 007 ... + 008 ε 120, 123, 128 + 010 ▶ + 011 ! [Enum(M30)] (identifier) [Node Set(M0) EndEnum] 010 + 014 ... + 015 ... + 016 ! [Enum(M31)] (identifier) [Node Set(M1) EndEnum] 010 + 019 ! [Enum(M32)] (identifier) [Node Set(M2) EndEnum] 010 + 022 ... + 023 ... + 024 ! [Enum(M33)] (identifier) [Node Set(M3) EndEnum] 010 + 027 ! [Enum(M34)] (identifier) [Node Set(M4) EndEnum] 010 + 030 ... + 031 ... + 032 ! [Enum(M35)] (identifier) [Node Set(M5) EndEnum] 010 + 035 ! [Enum(M36)] (identifier) [Node Set(M6) EndEnum] 010 + 038 ... + 039 ... + 040 ! [Enum(M37)] (identifier) [Node Set(M7) EndEnum] 010 + 043 ! [Enum(M38)] (identifier) [Node Set(M8) EndEnum] 010 + 046 ... + 047 ... + 048 ! [Enum(M39)] (identifier) [Node Set(M9) EndEnum] 010 + 051 ! [Enum(M40)] (identifier) [Node Set(M10) EndEnum] 010 + 054 ... + 055 ... + 056 ! [Enum(M41)] (identifier) [Node Set(M11) EndEnum] 010 + 059 ! [Enum(M42)] (identifier) [Node Set(M12) EndEnum] 010 + 062 ... + 063 ... + 064 ! [Enum(M43)] (identifier) [Node Set(M13) EndEnum] 010 + 067 ! [Enum(M44)] (identifier) [Node Set(M14) EndEnum] 010 + 070 ... + 071 ... + 072 ! [Enum(M45)] (identifier) [Node Set(M15) EndEnum] 010 + 075 ! [Enum(M46)] (identifier) [Node Set(M16) EndEnum] 010 + 078 ... + 079 ... + 080 ! [Enum(M47)] (identifier) [Node Set(M17) EndEnum] 010 + 083 ! [Enum(M48)] (identifier) [Node Set(M18) EndEnum] 010 + 086 ... + 087 ... + 088 ! [Enum(M49)] (identifier) [Node Set(M19) EndEnum] 010 + 091 ! [Enum(M50)] (identifier) [Node Set(M20) EndEnum] 010 + 094 ... + 095 ... + 096 ! [Enum(M51)] (identifier) [Node Set(M21) EndEnum] 010 + 099 ! [Enum(M52)] (identifier) [Node Set(M22) EndEnum] 010 + 102 ... + 103 ... + 104 ! [Enum(M53)] (identifier) [Node Set(M23) EndEnum] 010 + 107 ! [Enum(M54)] (identifier) [Node Set(M24) EndEnum] 010 + 110 ... + 111 ... + 112 ! [Enum(M55)] (identifier) [Node Set(M25) EndEnum] 010 + 115 ! [Enum(M56)] (identifier) [Node Set(M26) EndEnum] 010 + 118 ... + 119 ... + 120 ! [Enum(M57)] (identifier) [Node Set(M27) EndEnum] 010 + 123 ! [Enum(M58)] (identifier) [Node Set(M28) EndEnum] 010 + 126 ... + 127 ... + 128 ! [Enum(M59)] (identifier) [Node Set(M29) EndEnum] 010 diff --git a/crates/plotnik-compiler/src/compile/snapshots/plotnik_compiler__compile__compile_tests__compile_nested.snap b/crates/plotnik-compiler/src/compile/snapshots/plotnik_compiler__compile__compile_tests__compile_nested.snap new file mode 100644 index 0000000..640b9c4 --- /dev/null +++ b/crates/plotnik-compiler/src/compile/snapshots/plotnik_compiler__compile__compile_tests__compile_nested.snap @@ -0,0 +1,39 @@ +--- +source: crates/plotnik-compiler/src/compile/compile_tests.rs +--- +Test = (call_expression function: (identifier) @fn) +--- +[strings] +S0 "Beauty will save the world" +S1 "fn" +S2 "Test" +S3 "call_expression" +S4 "identifier" +S5 "function" + +[type_defs] +T0 = +T1 = Struct M0:1 ; { fn } + +[type_members] +M0: S1 → T0 ; fn: + +[type_names] +N0: S2 → T1 ; Test + +[entrypoints] +Test = 06 :: T1 + +[transitions] +_ObjWrap: + 00 ε [Obj] 02 + 02 Trampoline 03 + 03 ε [EndObj] 05 + 05 ▶ + +Test: + 06 ! (call_expression) 08 + 07 ... + 08 ▽ function: (identifier) [Node Set(M0)] 10 + 10 △ _ 11 + 11 ▶ diff --git a/crates/plotnik-compiler/src/compile/snapshots/plotnik_compiler__compile__compile_tests__compile_quantified.snap b/crates/plotnik-compiler/src/compile/snapshots/plotnik_compiler__compile__compile_tests__compile_quantified.snap new file mode 100644 index 0000000..2b6377b --- /dev/null +++ b/crates/plotnik-compiler/src/compile/snapshots/plotnik_compiler__compile__compile_tests__compile_quantified.snap @@ -0,0 +1,38 @@ +--- +source: crates/plotnik-compiler/src/compile/compile_tests.rs +--- +Test = (identifier)* +--- +[strings] +S0 "Beauty will save the world" +S1 "Test" +S2 "identifier" + +[type_defs] +T0 = +T1 = ArrayStar(T0) ; * + +[type_members] + +[type_names] +N0: S1 → T1 ; Test + +[entrypoints] +Test = 06 :: T1 + +[transitions] +_ObjWrap: + 00 ε [Obj] 02 + 02 Trampoline 03 + 03 ε [EndObj] 05 + 05 ▶ + +Test: + 06 ε 13, 08 + 08 ▶ + 09 ! (identifier) 18, 08 + 11 ▷ _ 09, 11, 08 + 13 ! _ 09, 11, 08 + 15 ... + 16 ▷ _ 09, 16, 08 + 18 ▷ _ 09, 16, 08 diff --git a/crates/plotnik-compiler/src/compile/snapshots/plotnik_compiler__compile__compile_tests__compile_sequence.snap b/crates/plotnik-compiler/src/compile/snapshots/plotnik_compiler__compile__compile_tests__compile_sequence.snap new file mode 100644 index 0000000..abbb219 --- /dev/null +++ b/crates/plotnik-compiler/src/compile/snapshots/plotnik_compiler__compile__compile_tests__compile_sequence.snap @@ -0,0 +1,33 @@ +--- +source: crates/plotnik-compiler/src/compile/compile_tests.rs +--- +Test = {(comment) (identifier)} +--- +[strings] +S0 "Beauty will save the world" +S1 "Test" +S2 "comment" +S3 "identifier" + +[type_defs] +T0 = + +[type_members] + +[type_names] +N0: S1 → T0 ; Test + +[entrypoints] +Test = 6 :: T0 + +[transitions] +_ObjWrap: + 0 ε [Obj] 2 + 2 Trampoline 3 + 3 ε [EndObj] 5 + 5 ▶ + +Test: + 6 ! (comment) 7 + 7 ▷ (identifier) 8 + 8 ▶ diff --git a/crates/plotnik-compiler/src/compile/snapshots/plotnik_compiler__compile__compile_tests__compile_simple_named_node.snap b/crates/plotnik-compiler/src/compile/snapshots/plotnik_compiler__compile__compile_tests__compile_simple_named_node.snap new file mode 100644 index 0000000..27384b0 --- /dev/null +++ b/crates/plotnik-compiler/src/compile/snapshots/plotnik_compiler__compile__compile_tests__compile_simple_named_node.snap @@ -0,0 +1,31 @@ +--- +source: crates/plotnik-compiler/src/compile/compile_tests.rs +--- +Test = (identifier) +--- +[strings] +S0 "Beauty will save the world" +S1 "Test" +S2 "identifier" + +[type_defs] +T0 = + +[type_members] + +[type_names] +N0: S1 → T0 ; Test + +[entrypoints] +Test = 6 :: T0 + +[transitions] +_ObjWrap: + 0 ε [Obj] 2 + 2 Trampoline 3 + 3 ε [EndObj] 5 + 5 ▶ + +Test: + 6 ! (identifier) 7 + 7 ▶ diff --git a/crates/plotnik-compiler/src/compile/snapshots/plotnik_compiler__compile__compile_tests__compile_unlabeled_alternation_5_branches_with_captures.snap b/crates/plotnik-compiler/src/compile/snapshots/plotnik_compiler__compile__compile_tests__compile_unlabeled_alternation_5_branches_with_captures.snap new file mode 100644 index 0000000..03b5474 --- /dev/null +++ b/crates/plotnik-compiler/src/compile/snapshots/plotnik_compiler__compile__compile_tests__compile_unlabeled_alternation_5_branches_with_captures.snap @@ -0,0 +1,89 @@ +--- +source: crates/plotnik-compiler/src/compile/compile_tests.rs +--- +Q = [(identifier) @a (number) @b (string) @c (binary_expression) @d (call_expression) @e] +--- +[strings] +S00 "Beauty will save the world" +S01 "a" +S02 "b" +S03 "c" +S04 "d" +S05 "e" +S06 "Q" +S07 "identifier" +S08 "number" +S09 "string" +S10 "binary_expression" +S11 "call_expression" + +[type_defs] +T00 = +T01 = Struct M00:5 ; { a, b, c, d, e } +T02 = Struct M05:1 ; { a } +T03 = Struct M06:1 ; { b } +T04 = Struct M07:1 ; { c } +T05 = Struct M08:1 ; { d } +T06 = Struct M09:1 ; { e } +T07 = Struct M10:2 ; { a, b } +T08 = Struct M12:3 ; { a, b, c } +T09 = Struct M15:4 ; { a, b, c, d } +T10 = Optional(T00) ; ? + +[type_members] +M00: S01 → T10 ; a: T10 +M01: S02 → T10 ; b: T10 +M02: S03 → T10 ; c: T10 +M03: S04 → T10 ; d: T10 +M04: S05 → T10 ; e: T10 +M05: S01 → T00 ; a: +M06: S02 → T00 ; b: +M07: S03 → T00 ; c: +M08: S04 → T00 ; d: +M09: S05 → T00 ; e: +M10: S01 → T10 ; a: T10 +M11: S02 → T10 ; b: T10 +M12: S01 → T10 ; a: T10 +M13: S02 → T10 ; b: T10 +M14: S03 → T10 ; c: T10 +M15: S01 → T10 ; a: T10 +M16: S02 → T10 ; b: T10 +M17: S03 → T10 ; c: T10 +M18: S04 → T10 ; d: T10 + +[type_names] +N0: S06 → T01 ; Q + +[entrypoints] +Q = 08 :: T01 + +[transitions] +_ObjWrap: + 00 ε [Obj] 02 + 02 Trampoline 03 + 03 ε [EndObj] 05 + 05 ▶ + 06 ▶ + 07 ... + +Q: + 08 ε 11, 18, 26, 34, 42 + 11 ε [Null Set(M1) Null Set(M2) Null Set(M3) Null] 14 + 14 ε [Set(M4)] 16 + 16 ! (identifier) [Node Set(M0)] 06 + 18 ε [Null Set(M0) Null Set(M2) Null Set(M3) Null] 21 + 21 ε [Set(M4)] 24 + 23 ... + 24 ! (number) [Node Set(M1)] 06 + 26 ε [Null Set(M0) Null Set(M1) Null Set(M3) Null] 29 + 29 ε [Set(M4)] 32 + 31 ... + 32 ! (string) [Node Set(M2)] 06 + 34 ε [Null Set(M0) Null Set(M1) Null Set(M2) Null] 37 + 37 ε [Set(M4)] 40 + 39 ... + 40 ! (binary_expression) [Node Set(M3)] 06 + 42 ε [Null Set(M0) Null Set(M1) Null Set(M2) Null] 45 + 45 ε [Set(M3)] 48 + 47 ... + 48 ! (call_expression) [Node Set(M4)] 06 diff --git a/crates/plotnik-compiler/src/compile/snapshots/plotnik_compiler__compile__compile_tests__compile_unlabeled_alternation_8_branches_with_captures.snap b/crates/plotnik-compiler/src/compile/snapshots/plotnik_compiler__compile__compile_tests__compile_unlabeled_alternation_8_branches_with_captures.snap new file mode 100644 index 0000000..8096647 --- /dev/null +++ b/crates/plotnik-compiler/src/compile/snapshots/plotnik_compiler__compile__compile_tests__compile_unlabeled_alternation_8_branches_with_captures.snap @@ -0,0 +1,133 @@ +--- +source: crates/plotnik-compiler/src/compile/compile_tests.rs +--- +Q = [(identifier) @a (number) @b (string) @c (binary_expression) @d + (call_expression) @e (member_expression) @f (array) @g (object) @h] +--- +[strings] +S00 "Beauty will save the world" +S01 "a" +S02 "b" +S03 "c" +S04 "d" +S05 "e" +S06 "f" +S07 "g" +S08 "h" +S09 "Q" +S10 "identifier" +S11 "number" +S12 "string" +S13 "binary_expression" +S14 "call_expression" +S15 "member_expression" +S16 "array" +S17 "object" + +[type_defs] +T00 = +T01 = Struct M00:8 ; { a, b, c, d, e, f, g, h } +T02 = Struct M08:1 ; { a } +T03 = Struct M09:1 ; { b } +T04 = Struct M10:1 ; { c } +T05 = Struct M11:1 ; { d } +T06 = Struct M12:1 ; { e } +T07 = Struct M13:1 ; { f } +T08 = Struct M14:1 ; { g } +T09 = Struct M15:1 ; { h } +T10 = Struct M16:2 ; { a, b } +T11 = Struct M18:3 ; { a, b, c } +T12 = Struct M21:4 ; { a, b, c, d } +T13 = Struct M25:5 ; { a, b, c, d, e } +T14 = Struct M30:6 ; { a, b, c, d, e, f } +T15 = Struct M36:7 ; { a, b, c, d, e, f, g } +T16 = Optional(T00) ; ? + +[type_members] +M00: S01 → T16 ; a: T16 +M01: S02 → T16 ; b: T16 +M02: S03 → T16 ; c: T16 +M03: S04 → T16 ; d: T16 +M04: S05 → T16 ; e: T16 +M05: S06 → T16 ; f: T16 +M06: S07 → T16 ; g: T16 +M07: S08 → T16 ; h: T16 +M08: S01 → T00 ; a: +M09: S02 → T00 ; b: +M10: S03 → T00 ; c: +M11: S04 → T00 ; d: +M12: S05 → T00 ; e: +M13: S06 → T00 ; f: +M14: S07 → T00 ; g: +M15: S08 → T00 ; h: +M16: S01 → T16 ; a: T16 +M17: S02 → T16 ; b: T16 +M18: S01 → T16 ; a: T16 +M19: S02 → T16 ; b: T16 +M20: S03 → T16 ; c: T16 +M21: S01 → T16 ; a: T16 +M22: S02 → T16 ; b: T16 +M23: S03 → T16 ; c: T16 +M24: S04 → T16 ; d: T16 +M25: S01 → T16 ; a: T16 +M26: S02 → T16 ; b: T16 +M27: S03 → T16 ; c: T16 +M28: S04 → T16 ; d: T16 +M29: S05 → T16 ; e: T16 +M30: S01 → T16 ; a: T16 +M31: S02 → T16 ; b: T16 +M32: S03 → T16 ; c: T16 +M33: S04 → T16 ; d: T16 +M34: S05 → T16 ; e: T16 +M35: S06 → T16 ; f: T16 +M36: S01 → T16 ; a: T16 +M37: S02 → T16 ; b: T16 +M38: S03 → T16 ; c: T16 +M39: S04 → T16 ; d: T16 +M40: S05 → T16 ; e: T16 +M41: S06 → T16 ; f: T16 +M42: S07 → T16 ; g: T16 + +[type_names] +N0: S09 → T01 ; Q + +[entrypoints] +Q = 08 :: T01 + +[transitions] +_ObjWrap: + 00 ε [Obj] 02 + 02 Trampoline 03 + 03 ε [EndObj] 05 + 05 ▶ + 06 ▶ + 07 ... + +Q: + 08 ε 11, 21, 29, 37, 45, 53, 61, 69 + 11 ε [Null Set(M1) Null Set(M2) Null Set(M3) Null] 16 + 14 ... + 15 ... + 16 ε [Set(M4) Null Set(M5) Null Set(M6) Null Set(M7)] 19 + 19 ! (identifier) [Node Set(M0)] 06 + 21 ε [Null Set(M0) Null Set(M2) Null Set(M3) Null] 24 + 24 ε [Set(M4) Null Set(M5) Null Set(M6) Null Set(M7)] 27 + 27 ! (number) [Node Set(M1)] 06 + 29 ε [Null Set(M0) Null Set(M1) Null Set(M3) Null] 32 + 32 ε [Set(M4) Null Set(M5) Null Set(M6) Null Set(M7)] 35 + 35 ! (string) [Node Set(M2)] 06 + 37 ε [Null Set(M0) Null Set(M1) Null Set(M2) Null] 40 + 40 ε [Set(M4) Null Set(M5) Null Set(M6) Null Set(M7)] 43 + 43 ! (binary_expression) [Node Set(M3)] 06 + 45 ε [Null Set(M0) Null Set(M1) Null Set(M2) Null] 48 + 48 ε [Set(M3) Null Set(M5) Null Set(M6) Null Set(M7)] 51 + 51 ! (call_expression) [Node Set(M4)] 06 + 53 ε [Null Set(M0) Null Set(M1) Null Set(M2) Null] 56 + 56 ε [Set(M3) Null Set(M4) Null Set(M6) Null Set(M7)] 59 + 59 ! (member_expression) [Node Set(M5)] 06 + 61 ε [Null Set(M0) Null Set(M1) Null Set(M2) Null] 64 + 64 ε [Set(M3) Null Set(M4) Null Set(M5) Null Set(M7)] 67 + 67 ! (array) [Node Set(M6)] 06 + 69 ε [Null Set(M0) Null Set(M1) Null Set(M2) Null] 72 + 72 ε [Set(M3) Null Set(M4) Null Set(M5) Null Set(M6)] 75 + 75 ! (object) [Node Set(M7)] 06 diff --git a/crates/plotnik-compiler/src/emit/emit_tests.rs b/crates/plotnik-compiler/src/emit/emit_tests.rs index 1c33a46..1cd95c5 100644 --- a/crates/plotnik-compiler/src/emit/emit_tests.rs +++ b/crates/plotnik-compiler/src/emit/emit_tests.rs @@ -3,487 +3,460 @@ //! Tests are organized by language feature and use file-based snapshots. //! Each test verifies the bytecode output for a specific language construct. -use crate::Query; -use indoc::indoc; - -macro_rules! snap { - ($query:expr) => {{ - let query = $query.trim(); - let bytecode = Query::expect_valid_bytecode(query); - insta::with_settings!({ - omit_expression => true - }, { - insta::assert_snapshot!(format!("{query}\n---\n{bytecode}")); - }); - }}; -} +use crate::shot_bytecode; // Nodes #[test] fn nodes_named() { - snap!(indoc! {r#" + shot_bytecode!(r#" Test = (identifier) @id - "#}); + "#); } #[test] fn nodes_anonymous() { - snap!(indoc! {r#" + shot_bytecode!(r#" Test = (binary_expression "+" @op) - "#}); + "#); } #[test] fn nodes_wildcard_any() { - snap!(indoc! {r#" + shot_bytecode!(r#" Test = (pair key: _ @key) - "#}); + "#); } #[test] fn nodes_wildcard_named() { - snap!(indoc! {r#" + shot_bytecode!(r#" Test = (pair key: (_) @key) - "#}); + "#); } #[test] fn nodes_error() { - snap!(indoc! {r#" + shot_bytecode!(r#" Test = (ERROR) @err - "#}); + "#); } #[test] fn nodes_missing() { - snap!(indoc! {r#" + shot_bytecode!(r#" Test = (MISSING) @m - "#}); + "#); } // Captures #[test] fn captures_basic() { - snap!(indoc! {r#" + shot_bytecode!(r#" Test = (identifier) @name - "#}); + "#); } #[test] fn captures_multiple() { - snap!(indoc! {r#" + shot_bytecode!(r#" Test = (binary_expression (identifier) @a (number) @b) - "#}); + "#); } #[test] fn captures_nested_flat() { - snap!(indoc! {r#" + shot_bytecode!(r#" Test = (array (array (identifier) @c) @b) @a - "#}); + "#); } #[test] fn captures_deeply_nested() { - snap!(indoc! {r#" + shot_bytecode!(r#" Test = (array (array (array (identifier) @d) @c) @b) @a - "#}); + "#); } #[test] fn captures_with_type_string() { - snap!(indoc! {r#" + shot_bytecode!(r#" Test = (identifier) @name :: string - "#}); + "#); } #[test] fn captures_with_type_custom() { - snap!(indoc! {r#" + shot_bytecode!(r#" Test = (identifier) @name :: Identifier - "#}); + "#); } #[test] fn captures_struct_scope() { - snap!(indoc! {r#" + shot_bytecode!(r#" Test = {(identifier) @a (number) @b} @item - "#}); + "#); } #[test] fn captures_wrapper_struct() { - snap!(indoc! {r#" + shot_bytecode!(r#" Test = {{(identifier) @id (number) @num} @row}* @rows - "#}); + "#); } #[test] fn captures_optional_wrapper_struct() { - snap!(indoc! {r#" + shot_bytecode!(r#" Test = {{(identifier) @id} @inner}? @outer - "#}); + "#); } #[test] fn captures_struct_with_type_annotation() { - // Type annotation on struct capture should name the struct, not create an alias - snap!(indoc! {r#" + shot_bytecode!(r#" Test = {(identifier) @fn} @outer :: FunctionInfo - "#}); + "#); } #[test] fn captures_enum_with_type_annotation() { - // Type annotation on tagged alternation should name the enum - snap!(indoc! {r#" + shot_bytecode!(r#" Test = [A: (identifier) @id B: (number) @num] @expr :: Expression - "#}); + "#); } // Fields #[test] fn fields_single() { - snap!(indoc! {r#" + shot_bytecode!(r#" Test = (function_declaration name: (identifier) @name) - "#}); + "#); } #[test] fn fields_multiple() { - snap!(indoc! {r#" + shot_bytecode!(r#" Test = (binary_expression left: (_) @left right: (_) @right) - "#}); + "#); } #[test] fn fields_negated() { - snap!(indoc! {r#" + shot_bytecode!(r#" Test = (pair key: (property_identifier) @key -value) - "#}); + "#); } #[test] fn fields_alternation() { - // Regression test: alternation in field position must have navigation on - // the field-checking wrapper, not on the alternation branches. - // See: wrapper navigates Down + checks field, branches use Stay. - snap!(indoc! {r#" + shot_bytecode!(r#" Test = (call_expression function: [(identifier) @fn (number) @num]) - "#}); + "#); } // Quantifiers #[test] fn quantifiers_optional() { - snap!(indoc! {r#" + shot_bytecode!(r#" Test = (function_declaration (decorator)? @dec) - "#}); + "#); } #[test] fn quantifiers_star() { - snap!(indoc! {r#" + shot_bytecode!(r#" Test = (identifier)* @items - "#}); + "#); } #[test] fn quantifiers_plus() { - snap!(indoc! {r#" + shot_bytecode!(r#" Test = (identifier)+ @items - "#}); + "#); } #[test] fn quantifiers_optional_nongreedy() { - snap!(indoc! {r#" + shot_bytecode!(r#" Test = (function_declaration (decorator)?? @dec) - "#}); + "#); } #[test] fn quantifiers_star_nongreedy() { - snap!(indoc! {r#" + shot_bytecode!(r#" Test = (identifier)*? @items - "#}); + "#); } #[test] fn quantifiers_plus_nongreedy() { - snap!(indoc! {r#" + shot_bytecode!(r#" Test = (identifier)+? @items - "#}); + "#); } #[test] fn quantifiers_struct_array() { - snap!(indoc! {r#" + shot_bytecode!(r#" Test = (array {(identifier) @a (number) @b}* @items) - "#}); + "#); } #[test] fn quantifiers_first_child_array() { - snap!(indoc! {r#" + shot_bytecode!(r#" Test = (array (identifier)* @ids (number) @n) - "#}); + "#); } #[test] fn quantifiers_repeat_navigation() { - snap!(indoc! {r#" + shot_bytecode!(r#" Test = (function_declaration (decorator)* @decs) - "#}); + "#); } -/// Regression test: sequence quantifiers in called definitions need sibling navigation. -/// Previously, `{...}*` compiled without navigation, causing infinite loops. #[test] fn quantifiers_sequence_in_called_def() { - snap!(indoc! {r#" + shot_bytecode!(r#" Item = (identifier) @name Collect = {(Item) @item}* @items Test = (array (Collect)) - "#}); + "#); } // Sequences #[test] fn sequences_basic() { - snap!(indoc! {r#" + shot_bytecode!(r#" Test = (array {(identifier) (number)}) - "#}); + "#); } #[test] fn sequences_with_captures() { - snap!(indoc! {r#" + shot_bytecode!(r#" Test = (array {(identifier) @a (number) @b}) - "#}); + "#); } #[test] fn sequences_nested() { - snap!(indoc! {r#" + shot_bytecode!(r#" Test = (array {(identifier) {(number) (string)} (null)}) - "#}); + "#); } #[test] fn sequences_in_quantifier() { - // Sequence with internal captures - valid for struct array - snap!(indoc! {r#" + shot_bytecode!(r#" Test = (array {(identifier) @id (number) @num}* @items) - "#}); + "#); } // Alternations #[test] fn alternations_unlabeled() { - snap!(indoc! {r#" + shot_bytecode!(r#" Test = [(identifier) @id (string) @str] - "#}); + "#); } #[test] fn alternations_labeled() { - snap!(indoc! {r#" + shot_bytecode!(r#" Test = [ A: (identifier) @a B: (number) @b ] - "#}); + "#); } #[test] fn alternations_null_injection() { - snap!(indoc! {r#" + shot_bytecode!(r#" Test = [(identifier) @x (number) @y] - "#}); + "#); } #[test] fn alternations_captured() { - snap!(indoc! {r#" + shot_bytecode!(r#" Test = [(identifier) (number)] @value - "#}); + "#); } #[test] fn alternations_captured_tagged() { - snap!(indoc! {r#" + shot_bytecode!(r#" Test = [A: (identifier) @a B: (number) @b] @item - "#}); + "#); } #[test] fn alternations_tagged_with_definition_ref() { - snap!(indoc! {r#" + shot_bytecode!(r#" Inner = (identifier) @name Test = [A: (Inner) B: (number) @b] @item - "#}); + "#); } #[test] fn alternations_in_quantifier() { - snap!(indoc! {r#" + shot_bytecode!(r#" Test = (object { [A: (pair) @a B: (shorthand_property_identifier) @b] @item }* @items) - "#}); + "#); } #[test] fn alternations_no_internal_captures() { - snap!(indoc! {r#" + shot_bytecode!(r#" Test = (program [(identifier) (number)] @x) - "#}); + "#); } #[test] fn alternations_tagged_in_field_constraint() { - // Regression test: captured tagged alternation as field value should not emit Node effect. - // The capture `@kind` applies to the field expression, but the value determines - // whether it's a structured scope (enum in this case). - snap!(indoc! {r#" + shot_bytecode!(r#" Test = (pair key: [A: (identifier) @a B: (number)] @kind) - "#}); + "#); } // Anchors #[test] fn anchors_between_siblings() { - snap!(indoc! {r#" + shot_bytecode!(r#" Test = (array (identifier) . (number)) - "#}); + "#); } #[test] fn anchors_first_child() { - snap!(indoc! {r#" + shot_bytecode!(r#" Test = (array . (identifier)) - "#}); + "#); } #[test] fn anchors_last_child() { - snap!(indoc! {r#" + shot_bytecode!(r#" Test = (array (identifier) .) - "#}); + "#); } #[test] fn anchors_with_anonymous() { - snap!(indoc! {r#" + shot_bytecode!(r#" Test = (binary_expression "+" . (identifier)) - "#}); + "#); } #[test] fn anchors_no_anchor() { - snap!(indoc! {r#" + shot_bytecode!(r#" Test = (array (identifier) (number)) - "#}); + "#); } // Named expressions #[test] fn definitions_single() { - snap!(indoc! {r#" + shot_bytecode!(r#" Foo = (identifier) @id - "#}); + "#); } #[test] fn definitions_multiple() { - snap!(indoc! {r#" + shot_bytecode!(r#" Foo = (identifier) @id Bar = (string) @str - "#}); + "#); } #[test] fn definitions_reference() { - snap!(indoc! {r#" + shot_bytecode!(r#" Expression = [(identifier) @name (number) @value] Root = (function_declaration name: (identifier) @name) - "#}); + "#); } #[test] fn definitions_nested_capture() { - snap!(indoc! {r#" + shot_bytecode!(r#" Inner = (call_expression (identifier) @name) Outer = (array {(Inner) @item}* @items) - "#}); + "#); } // Recursion #[test] fn recursion_simple() { - snap!(indoc! {r#" + shot_bytecode!(r#" Expr = [ Lit: (number) @value :: string Rec: (call_expression function: (identifier) @fn arguments: (Expr) @inner) ] - "#}); + "#); } #[test] fn recursion_with_structured_result() { - snap!(indoc! {r#" + shot_bytecode!(r#" Expr = [ Lit: (number) @value :: string Nested: (call_expression function: (identifier) @fn arguments: (Expr) @inner) ] Test = (program (Expr) @expr) - "#}); + "#); } // Optionals #[test] fn optional_first_child() { - snap!(indoc! {r#" + shot_bytecode!(r#" Test = (program (identifier)? @id (number) @n) - "#}); + "#); } #[test] fn optional_null_injection() { - snap!(indoc! {r#" + shot_bytecode!(r#" Test = (function_declaration (decorator)? @dec) - "#}); + "#); } // Optimization: prefix collapse #[test] fn opt_prefix_collapse() { - // Alternation branches with shared prefix: [(object ...) (object ...)] - // Without optimization: two separate (object) instructions - // With optimization: one (object) with merged successors - snap!(indoc! {r#" + shot_bytecode!(r#" Test = [(object (pair)) (object (string))] - "#}); + "#); } // Comprehensive #[test] fn comprehensive_multi_definition() { - snap!(indoc! {r#" + shot_bytecode!(r#" Ident = (identifier) @name :: string Expression = [ Literal: (number) @value @@ -492,5 +465,5 @@ fn comprehensive_multi_definition() { Assignment = (assignment_expression left: (identifier) @target right: (Expression) @value) - "#}); + "#); } diff --git a/crates/plotnik-compiler/src/emit/layout_tests.rs b/crates/plotnik-compiler/src/emit/layout_tests.rs index d8ca17e..0c0a68a 100644 --- a/crates/plotnik-compiler/src/emit/layout_tests.rs +++ b/crates/plotnik-compiler/src/emit/layout_tests.rs @@ -2,54 +2,40 @@ //! //! Tests verify cache-line aligned layout and gap-filling optimization. -use crate::Query; -use indoc::indoc; - -macro_rules! snap { - ($query:expr) => {{ - let query = $query.trim(); - let bytecode = Query::expect_valid_bytecode(query); - insta::with_settings!({ - omit_expression => true - }, { - insta::assert_snapshot!(format!("{query}\n---\n{bytecode}")); - }); - }}; -} +use crate::shot_bytecode; #[test] fn single_instruction() { - snap!(indoc! {r#" + shot_bytecode!(r#" Test = (identifier) @id - "#}); + "#); } #[test] fn linear_chain() { - snap!(indoc! {r#" + shot_bytecode!(r#" Test = (array (identifier) @a (number) @b) - "#}); + "#); } #[test] fn branch() { - snap!(indoc! {r#" + shot_bytecode!(r#" Test = [(identifier) @id (number) @num] - "#}); + "#); } #[test] fn call_return() { - snap!(indoc! {r#" + shot_bytecode!(r#" Inner = (identifier) @name Test = (array (Inner) @item) - "#}); + "#); } #[test] fn cache_line_boundary() { - // Many small instructions followed by larger one - snap!(indoc! {r#" + shot_bytecode!(r#" Test = (array (identifier) @a (identifier) @b @@ -58,15 +44,14 @@ fn cache_line_boundary() { (identifier) @e [(number) @x (string) @y] ) - "#}); + "#); } #[test] fn large_instruction() { - // Instruction with many effects/successors - snap!(indoc! {r#" + shot_bytecode!(r#" Test = (object {(pair) @a (pair) @b (pair) @c (pair) @d}* @items ) - "#}); + "#); } diff --git a/crates/plotnik-compiler/src/lib.rs b/crates/plotnik-compiler/src/lib.rs index d592020..b590b36 100644 --- a/crates/plotnik-compiler/src/lib.rs +++ b/crates/plotnik-compiler/src/lib.rs @@ -20,6 +20,9 @@ pub mod parser; pub mod query; pub mod typegen; +#[cfg(test)] +pub mod test_utils; + /// Result type for analysis passes that produce both output and diagnostics. /// /// Each pass returns its typed output alongside any diagnostics it collected. diff --git a/crates/plotnik-compiler/src/parser/tests/grammar/alternations_tests.rs b/crates/plotnik-compiler/src/parser/tests/grammar/alternations_tests.rs index 8f1c68e..f3b36e1 100644 --- a/crates/plotnik-compiler/src/parser/tests/grammar/alternations_tests.rs +++ b/crates/plotnik-compiler/src/parser/tests/grammar/alternations_tests.rs @@ -1,716 +1,162 @@ -use crate::Query; -use indoc::indoc; +//! Alternation parsing tests. + +use crate::shot_cst; #[test] fn alternation() { - let input = indoc! {r#" - Q = [(identifier) (string)] - "#}; - - let res = Query::expect_valid_cst(input); - - insta::assert_snapshot!(res, @r#" - Root - Def - Id "Q" - Equals "=" - Alt - BracketOpen "[" - Branch - Tree - ParenOpen "(" - Id "identifier" - ParenClose ")" - Branch - Tree - ParenOpen "(" - Id "string" - ParenClose ")" - BracketClose "]" + shot_cst!(r#" + Q = [(identifier) (string)] "#); } #[test] fn alternation_with_anonymous() { - let input = indoc! {r#" - Q = ["true" "false"] - "#}; - - let res = Query::expect_valid_cst(input); - - insta::assert_snapshot!(res, @r#" - Root - Def - Id "Q" - Equals "=" - Alt - BracketOpen "[" - Branch - Str - DoubleQuote "\"" - StrVal "true" - DoubleQuote "\"" - Branch - Str - DoubleQuote "\"" - StrVal "false" - DoubleQuote "\"" - BracketClose "]" + shot_cst!(r#" + Q = ["true" "false"] "#); } #[test] fn alternation_with_capture() { - let input = indoc! {r#" - Q = [(identifier) (string)] @value - "#}; - - let res = Query::expect_valid_cst(input); - - insta::assert_snapshot!(res, @r#" - Root - Def - Id "Q" - Equals "=" - Capture - Alt - BracketOpen "[" - Branch - Tree - ParenOpen "(" - Id "identifier" - ParenClose ")" - Branch - Tree - ParenOpen "(" - Id "string" - ParenClose ")" - BracketClose "]" - CaptureToken "@value" + shot_cst!(r#" + Q = [(identifier) (string)] @value "#); } #[test] fn alternation_with_quantifier() { - let input = indoc! {r#" - Q = [ - (identifier) - (string)* @strings - ] - "#}; - - let res = Query::expect_valid_cst(input); - - insta::assert_snapshot!(res, @r#" - Root - Def - Id "Q" - Equals "=" - Alt - BracketOpen "[" - Branch - Tree - ParenOpen "(" - Id "identifier" - ParenClose ")" - Branch - Capture - Quantifier - Tree - ParenOpen "(" - Id "string" - ParenClose ")" - Star "*" - CaptureToken "@strings" - BracketClose "]" + shot_cst!(r#" + Q = [ + (identifier) + (string)* @strings + ] "#); } #[test] fn alternation_nested() { - let input = indoc! {r#" - Q = (expr - [(binary) (unary)] - ) - "#}; - - let res = Query::expect_valid_cst(input); - - insta::assert_snapshot!(res, @r#" - Root - Def - Id "Q" - Equals "=" - Tree - ParenOpen "(" - Id "expr" - Alt - BracketOpen "[" - Branch - Tree - ParenOpen "(" - Id "binary" - ParenClose ")" - Branch - Tree - ParenOpen "(" - Id "unary" - ParenClose ")" - BracketClose "]" - ParenClose ")" + shot_cst!(r#" + Q = (expr + [(binary) (unary)] + ) "#); } #[test] fn alternation_in_field() { - let input = indoc! {r#" - Q = (call - arguments: [(string) (number)] - ) - "#}; - - let res = Query::expect_valid_cst(input); - - insta::assert_snapshot!(res, @r#" - Root - Def - Id "Q" - Equals "=" - Tree - ParenOpen "(" - Id "call" - Field - Id "arguments" - Colon ":" - Alt - BracketOpen "[" - Branch - Tree - ParenOpen "(" - Id "string" - ParenClose ")" - Branch - Tree - ParenOpen "(" - Id "number" - ParenClose ")" - BracketClose "]" - ParenClose ")" + shot_cst!(r#" + Q = (call + arguments: [(string) (number)] + ) "#); } #[test] fn unlabeled_alternation_three_items() { - let input = indoc! {r#" - Q = [(identifier) (number) (string)] - "#}; - - let res = Query::expect_valid_cst(input); - - insta::assert_snapshot!(res, @r#" - Root - Def - Id "Q" - Equals "=" - Alt - BracketOpen "[" - Branch - Tree - ParenOpen "(" - Id "identifier" - ParenClose ")" - Branch - Tree - ParenOpen "(" - Id "number" - ParenClose ")" - Branch - Tree - ParenOpen "(" - Id "string" - ParenClose ")" - BracketClose "]" + shot_cst!(r#" + Q = [(identifier) (number) (string)] "#); } #[test] fn tagged_alternation_simple() { - let input = indoc! {r#" - Q = [ - Ident: (identifier) - Num: (number) - ] - "#}; - - let res = Query::expect_valid_cst(input); - - insta::assert_snapshot!(res, @r#" - Root - Def - Id "Q" - Equals "=" - Alt - BracketOpen "[" - Branch - Id "Ident" - Colon ":" - Tree - ParenOpen "(" - Id "identifier" - ParenClose ")" - Branch - Id "Num" - Colon ":" - Tree - ParenOpen "(" - Id "number" - ParenClose ")" - BracketClose "]" + shot_cst!(r#" + Q = [ + Ident: (identifier) + Num: (number) + ] "#); } #[test] fn tagged_alternation_single_line() { - let input = indoc! {r#" - Q = [A: (a) B: (b) C: (c)] - "#}; - - let res = Query::expect_valid_cst(input); - - insta::assert_snapshot!(res, @r#" - Root - Def - Id "Q" - Equals "=" - Alt - BracketOpen "[" - Branch - Id "A" - Colon ":" - Tree - ParenOpen "(" - Id "a" - ParenClose ")" - Branch - Id "B" - Colon ":" - Tree - ParenOpen "(" - Id "b" - ParenClose ")" - Branch - Id "C" - Colon ":" - Tree - ParenOpen "(" - Id "c" - ParenClose ")" - BracketClose "]" + shot_cst!(r#" + Q = [A: (a) B: (b) C: (c)] "#); } #[test] fn tagged_alternation_with_captures() { - let input = indoc! {r#" - Q = [ - Assign: (assignment_expression left: (identifier) @left) - Call: (call_expression function: (identifier) @func) - ] @stmt - "#}; - - let res = Query::expect_valid_cst(input); - - insta::assert_snapshot!(res, @r#" - Root - Def - Id "Q" - Equals "=" - Capture - Alt - BracketOpen "[" - Branch - Id "Assign" - Colon ":" - Tree - ParenOpen "(" - Id "assignment_expression" - Capture - Field - Id "left" - Colon ":" - Tree - ParenOpen "(" - Id "identifier" - ParenClose ")" - CaptureToken "@left" - ParenClose ")" - Branch - Id "Call" - Colon ":" - Tree - ParenOpen "(" - Id "call_expression" - Capture - Field - Id "function" - Colon ":" - Tree - ParenOpen "(" - Id "identifier" - ParenClose ")" - CaptureToken "@func" - ParenClose ")" - BracketClose "]" - CaptureToken "@stmt" + shot_cst!(r#" + Q = [ + Assign: (assignment_expression left: (identifier) @left) + Call: (call_expression function: (identifier) @func) + ] @stmt "#); } #[test] fn tagged_alternation_with_type_annotation() { - let input = indoc! {r#" - Q = [ - Base: (identifier) @name - Access: (member_expression object: (_) @obj) - ] @chain :: MemberChain - "#}; - - let res = Query::expect_valid_cst(input); - - insta::assert_snapshot!(res, @r#" - Root - Def - Id "Q" - Equals "=" - Capture - Alt - BracketOpen "[" - Branch - Id "Base" - Colon ":" - Capture - Tree - ParenOpen "(" - Id "identifier" - ParenClose ")" - CaptureToken "@name" - Branch - Id "Access" - Colon ":" - Tree - ParenOpen "(" - Id "member_expression" - Capture - Field - Id "object" - Colon ":" - Tree - ParenOpen "(" - Underscore "_" - ParenClose ")" - CaptureToken "@obj" - ParenClose ")" - BracketClose "]" - CaptureToken "@chain" - Type - DoubleColon "::" - Id "MemberChain" + shot_cst!(r#" + Q = [ + Base: (identifier) @name + Access: (member_expression object: (_) @obj) + ] @chain :: MemberChain "#); } #[test] fn tagged_alternation_nested() { - let input = indoc! {r#" - Q = (expr - [ - Binary: (binary_expression) - Unary: (unary_expression) - ]) - "#}; - - let res = Query::expect_valid_cst(input); - - insta::assert_snapshot!(res, @r#" - Root - Def - Id "Q" - Equals "=" - Tree - ParenOpen "(" - Id "expr" - Alt - BracketOpen "[" - Branch - Id "Binary" - Colon ":" - Tree - ParenOpen "(" - Id "binary_expression" - ParenClose ")" - Branch - Id "Unary" - Colon ":" - Tree - ParenOpen "(" - Id "unary_expression" - ParenClose ")" - BracketClose "]" - ParenClose ")" + shot_cst!(r#" + Q = (expr + [ + Binary: (binary_expression) + Unary: (unary_expression) + ]) "#); } #[test] fn tagged_alternation_in_named_def() { - let input = indoc! {r#" - Statement = [ - Assign: (assignment_expression) - Call: (call_expression) - Return: (return_statement) - ] - "#}; - - let res = Query::expect_valid_cst(input); - - insta::assert_snapshot!(res, @r#" - Root - Def - Id "Statement" - Equals "=" - Alt - BracketOpen "[" - Branch - Id "Assign" - Colon ":" - Tree - ParenOpen "(" - Id "assignment_expression" - ParenClose ")" - Branch - Id "Call" - Colon ":" - Tree - ParenOpen "(" - Id "call_expression" - ParenClose ")" - Branch - Id "Return" - Colon ":" - Tree - ParenOpen "(" - Id "return_statement" - ParenClose ")" - BracketClose "]" + shot_cst!(r#" + Statement = [ + Assign: (assignment_expression) + Call: (call_expression) + Return: (return_statement) + ] "#); } #[test] fn tagged_alternation_with_quantifier() { - let input = indoc! {r#" - Q = [ - Single: (statement) - Multiple: (statement)+ - ] - "#}; - - let res = Query::expect_valid_cst(input); - - insta::assert_snapshot!(res, @r#" - Root - Def - Id "Q" - Equals "=" - Alt - BracketOpen "[" - Branch - Id "Single" - Colon ":" - Tree - ParenOpen "(" - Id "statement" - ParenClose ")" - Branch - Id "Multiple" - Colon ":" - Quantifier - Tree - ParenOpen "(" - Id "statement" - ParenClose ")" - Plus "+" - BracketClose "]" + shot_cst!(r#" + Q = [ + Single: (statement) + Multiple: (statement)+ + ] "#); } #[test] fn tagged_alternation_with_sequence() { - let input = indoc! {r#" - Q = [ - Pair: {(key) (value)} - Single: (value) - ] - "#}; - - let res = Query::expect_valid_cst(input); - - insta::assert_snapshot!(res, @r#" - Root - Def - Id "Q" - Equals "=" - Alt - BracketOpen "[" - Branch - Id "Pair" - Colon ":" - Seq - BraceOpen "{" - Tree - ParenOpen "(" - Id "key" - ParenClose ")" - Tree - ParenOpen "(" - Id "value" - ParenClose ")" - BraceClose "}" - Branch - Id "Single" - Colon ":" - Tree - ParenOpen "(" - Id "value" - ParenClose ")" - BracketClose "]" + shot_cst!(r#" + Q = [ + Pair: {(key) (value)} + Single: (value) + ] "#); } #[test] fn tagged_alternation_with_nested_alternation() { - let input = indoc! {r#" - Q = [ - Literal: [(number) (string)] - Ident: (identifier) - ] - "#}; - - let res = Query::expect_valid_cst(input); - - insta::assert_snapshot!(res, @r#" - Root - Def - Id "Q" - Equals "=" - Alt - BracketOpen "[" - Branch - Id "Literal" - Colon ":" - Alt - BracketOpen "[" - Branch - Tree - ParenOpen "(" - Id "number" - ParenClose ")" - Branch - Tree - ParenOpen "(" - Id "string" - ParenClose ")" - BracketClose "]" - Branch - Id "Ident" - Colon ":" - Tree - ParenOpen "(" - Id "identifier" - ParenClose ")" - BracketClose "]" + shot_cst!(r#" + Q = [ + Literal: [(number) (string)] + Ident: (identifier) + ] "#); } #[test] fn tagged_alternation_full_example() { - let input = indoc! {r#" - Expression = [ - Ident: (identifier) @name :: string - Num: (number) @value :: string - Str: (string) @value :: string - Binary: (binary_expression - left: (Expression) @left - right: (Expression) @right) - ] - "#}; - - let res = Query::expect_valid_cst(input); - - insta::assert_snapshot!(res, @r#" - Root - Def - Id "Expression" - Equals "=" - Alt - BracketOpen "[" - Branch - Id "Ident" - Colon ":" - Capture - Tree - ParenOpen "(" - Id "identifier" - ParenClose ")" - CaptureToken "@name" - Type - DoubleColon "::" - Id "string" - Branch - Id "Num" - Colon ":" - Capture - Tree - ParenOpen "(" - Id "number" - ParenClose ")" - CaptureToken "@value" - Type - DoubleColon "::" - Id "string" - Branch - Id "Str" - Colon ":" - Capture - Tree - ParenOpen "(" - Id "string" - ParenClose ")" - CaptureToken "@value" - Type - DoubleColon "::" - Id "string" - Branch - Id "Binary" - Colon ":" - Tree - ParenOpen "(" - Id "binary_expression" - Capture - Field - Id "left" - Colon ":" - Ref - ParenOpen "(" - Id "Expression" - ParenClose ")" - CaptureToken "@left" - Capture - Field - Id "right" - Colon ":" - Ref - ParenOpen "(" - Id "Expression" - ParenClose ")" - CaptureToken "@right" - ParenClose ")" - BracketClose "]" + shot_cst!(r#" + Expression = [ + Ident: (identifier) @name :: string + Num: (number) @value :: string + Str: (string) @value :: string + Binary: (binary_expression + left: (Expression) @left + right: (Expression) @right) + ] "#); } diff --git a/crates/plotnik-compiler/src/parser/tests/grammar/anchors_tests.rs b/crates/plotnik-compiler/src/parser/tests/grammar/anchors_tests.rs index d5875a8..a24bdff 100644 --- a/crates/plotnik-compiler/src/parser/tests/grammar/anchors_tests.rs +++ b/crates/plotnik-compiler/src/parser/tests/grammar/anchors_tests.rs @@ -1,192 +1,45 @@ -use crate::Query; -use indoc::indoc; +//! Anchor parsing tests. + +use crate::shot_cst; #[test] fn anchor_first_child() { - let input = indoc! {r#" - Q = (block . (first_statement)) - "#}; - - let res = Query::expect_valid_cst(input); - - insta::assert_snapshot!(res, @r#" - Root - Def - Id "Q" - Equals "=" - Tree - ParenOpen "(" - Id "block" - Anchor - Dot "." - Tree - ParenOpen "(" - Id "first_statement" - ParenClose ")" - ParenClose ")" + shot_cst!(r#" + Q = (block . (first_statement)) "#); } #[test] fn anchor_last_child() { - let input = indoc! {r#" - Q = (block (last_statement) .) - "#}; - - let res = Query::expect_valid_cst(input); - - insta::assert_snapshot!(res, @r#" - Root - Def - Id "Q" - Equals "=" - Tree - ParenOpen "(" - Id "block" - Tree - ParenOpen "(" - Id "last_statement" - ParenClose ")" - Anchor - Dot "." - ParenClose ")" + shot_cst!(r#" + Q = (block (last_statement) .) "#); } #[test] fn anchor_adjacency() { - let input = indoc! {r#" - Q = (dotted_name (identifier) @a . (identifier) @b) - "#}; - - let res = Query::expect_valid_cst(input); - - insta::assert_snapshot!(res, @r#" - Root - Def - Id "Q" - Equals "=" - Tree - ParenOpen "(" - Id "dotted_name" - Capture - Tree - ParenOpen "(" - Id "identifier" - ParenClose ")" - CaptureToken "@a" - Anchor - Dot "." - Capture - Tree - ParenOpen "(" - Id "identifier" - ParenClose ")" - CaptureToken "@b" - ParenClose ")" + shot_cst!(r#" + Q = (dotted_name (identifier) @a . (identifier) @b) "#); } #[test] fn anchor_both_ends() { - let input = indoc! {r#" - Q = (array . (element) .) - "#}; - - let res = Query::expect_valid_cst(input); - - insta::assert_snapshot!(res, @r#" - Root - Def - Id "Q" - Equals "=" - Tree - ParenOpen "(" - Id "array" - Anchor - Dot "." - Tree - ParenOpen "(" - Id "element" - ParenClose ")" - Anchor - Dot "." - ParenClose ")" + shot_cst!(r#" + Q = (array . (element) .) "#); } #[test] fn anchor_multiple_adjacent() { - let input = indoc! {r#" - Q = (tuple . (a) . (b) . (c) .) - "#}; - - let res = Query::expect_valid_cst(input); - - insta::assert_snapshot!(res, @r#" - Root - Def - Id "Q" - Equals "=" - Tree - ParenOpen "(" - Id "tuple" - Anchor - Dot "." - Tree - ParenOpen "(" - Id "a" - ParenClose ")" - Anchor - Dot "." - Tree - ParenOpen "(" - Id "b" - ParenClose ")" - Anchor - Dot "." - Tree - ParenOpen "(" - Id "c" - ParenClose ")" - Anchor - Dot "." - ParenClose ")" + shot_cst!(r#" + Q = (tuple . (a) . (b) . (c) .) "#); } #[test] fn anchor_in_sequence() { - // Boundary anchors in sequences require parent node context - let input = indoc! {r#" - Q = (parent {. (first) (second) .}) - "#}; - - let res = Query::expect_valid_cst(input); - - insta::assert_snapshot!(res, @r#" - Root - Def - Id "Q" - Equals "=" - Tree - ParenOpen "(" - Id "parent" - Seq - BraceOpen "{" - Anchor - Dot "." - Tree - ParenOpen "(" - Id "first" - ParenClose ")" - Tree - ParenOpen "(" - Id "second" - ParenClose ")" - Anchor - Dot "." - BraceClose "}" - ParenClose ")" + shot_cst!(r#" + Q = (parent {. (first) (second) .}) "#); } diff --git a/crates/plotnik-compiler/src/parser/tests/grammar/captures_tests.rs b/crates/plotnik-compiler/src/parser/tests/grammar/captures_tests.rs index 3c67de4..af9c088 100644 --- a/crates/plotnik-compiler/src/parser/tests/grammar/captures_tests.rs +++ b/crates/plotnik-compiler/src/parser/tests/grammar/captures_tests.rs @@ -1,491 +1,122 @@ -use crate::Query; -use indoc::indoc; +//! Capture parsing tests. + +use crate::shot_cst; #[test] fn capture() { - let input = indoc! {r#" - Q = (identifier) @name - "#}; - - let res = Query::expect_valid_cst(input); - - insta::assert_snapshot!(res, @r#" - Root - Def - Id "Q" - Equals "=" - Capture - Tree - ParenOpen "(" - Id "identifier" - ParenClose ")" - CaptureToken "@name" + shot_cst!(r#" + Q = (identifier) @name "#); } #[test] fn capture_nested() { - let input = indoc! {r#" - Q = (call function: (identifier) @func) - "#}; - - let res = Query::expect_valid_cst(input); - - insta::assert_snapshot!(res, @r#" - Root - Def - Id "Q" - Equals "=" - Tree - ParenOpen "(" - Id "call" - Capture - Field - Id "function" - Colon ":" - Tree - ParenOpen "(" - Id "identifier" - ParenClose ")" - CaptureToken "@func" - ParenClose ")" + shot_cst!(r#" + Q = (call function: (identifier) @func) "#); } #[test] fn multiple_captures() { - let input = indoc! {r#" - Q = (binary - left: (_) @left - right: (_) @right) @expr - "#}; - - let res = Query::expect_valid_cst(input); - - insta::assert_snapshot!(res, @r#" - Root - Def - Id "Q" - Equals "=" - Capture - Tree - ParenOpen "(" - Id "binary" - Capture - Field - Id "left" - Colon ":" - Tree - ParenOpen "(" - Underscore "_" - ParenClose ")" - CaptureToken "@left" - Capture - Field - Id "right" - Colon ":" - Tree - ParenOpen "(" - Underscore "_" - ParenClose ")" - CaptureToken "@right" - ParenClose ")" - CaptureToken "@expr" + shot_cst!(r#" + Q = (binary + left: (_) @left + right: (_) @right) @expr "#); } #[test] fn capture_with_type_annotation() { - let input = indoc! {r#" - Q = (identifier) @name :: string - "#}; - - let res = Query::expect_valid_cst(input); - - insta::assert_snapshot!(res, @r#" - Root - Def - Id "Q" - Equals "=" - Capture - Tree - ParenOpen "(" - Id "identifier" - ParenClose ")" - CaptureToken "@name" - Type - DoubleColon "::" - Id "string" + shot_cst!(r#" + Q = (identifier) @name :: string "#); } #[test] fn capture_with_custom_type() { - let input = indoc! {r#" - Q = (function_declaration) @fn :: FunctionDecl - "#}; - - let res = Query::expect_valid_cst(input); - - insta::assert_snapshot!(res, @r#" - Root - Def - Id "Q" - Equals "=" - Capture - Tree - ParenOpen "(" - Id "function_declaration" - ParenClose ")" - CaptureToken "@fn" - Type - DoubleColon "::" - Id "FunctionDecl" + shot_cst!(r#" + Q = (function_declaration) @fn :: FunctionDecl "#); } #[test] fn capture_without_type_annotation() { - let input = indoc! {r#" - Q = (identifier) @name - "#}; - - let res = Query::expect_valid_cst(input); - - insta::assert_snapshot!(res, @r#" - Root - Def - Id "Q" - Equals "=" - Capture - Tree - ParenOpen "(" - Id "identifier" - ParenClose ")" - CaptureToken "@name" + shot_cst!(r#" + Q = (identifier) @name "#); } #[test] fn multiple_captures_with_types() { - let input = indoc! {r#" - Q = (binary - left: (_) @left :: Node - right: (_) @right :: string) @expr :: BinaryExpr - "#}; - - let res = Query::expect_valid_cst(input); - - insta::assert_snapshot!(res, @r#" - Root - Def - Id "Q" - Equals "=" - Capture - Tree - ParenOpen "(" - Id "binary" - Capture - Field - Id "left" - Colon ":" - Tree - ParenOpen "(" - Underscore "_" - ParenClose ")" - CaptureToken "@left" - Type - DoubleColon "::" - Id "Node" - Capture - Field - Id "right" - Colon ":" - Tree - ParenOpen "(" - Underscore "_" - ParenClose ")" - CaptureToken "@right" - Type - DoubleColon "::" - Id "string" - ParenClose ")" - CaptureToken "@expr" - Type - DoubleColon "::" - Id "BinaryExpr" + shot_cst!(r#" + Q = (binary + left: (_) @left :: Node + right: (_) @right :: string) @expr :: BinaryExpr "#); } #[test] fn sequence_capture_with_type() { - let input = indoc! {r#" - Q = {(a) (b)} @seq :: MySequence - "#}; - - let res = Query::expect_valid_cst(input); - - insta::assert_snapshot!(res, @r#" - Root - Def - Id "Q" - Equals "=" - Capture - Seq - BraceOpen "{" - Tree - ParenOpen "(" - Id "a" - ParenClose ")" - Tree - ParenOpen "(" - Id "b" - ParenClose ")" - BraceClose "}" - CaptureToken "@seq" - Type - DoubleColon "::" - Id "MySequence" + shot_cst!(r#" + Q = {(a) (b)} @seq :: MySequence "#); } #[test] fn alternation_capture_with_type() { - let input = indoc! {r#" - Q = [(identifier) (number)] @value :: Value - "#}; - - let res = Query::expect_valid_cst(input); - - insta::assert_snapshot!(res, @r#" - Root - Def - Id "Q" - Equals "=" - Capture - Alt - BracketOpen "[" - Branch - Tree - ParenOpen "(" - Id "identifier" - ParenClose ")" - Branch - Tree - ParenOpen "(" - Id "number" - ParenClose ")" - BracketClose "]" - CaptureToken "@value" - Type - DoubleColon "::" - Id "Value" + shot_cst!(r#" + Q = [(identifier) (number)] @value :: Value "#); } #[test] fn quantified_capture_with_type() { - let input = indoc! {r#" - Q = (statement)+ @stmts :: Statement - "#}; - - let res = Query::expect_valid_cst(input); - - insta::assert_snapshot!(res, @r#" - Root - Def - Id "Q" - Equals "=" - Capture - Quantifier - Tree - ParenOpen "(" - Id "statement" - ParenClose ")" - Plus "+" - CaptureToken "@stmts" - Type - DoubleColon "::" - Id "Statement" + shot_cst!(r#" + Q = (statement)+ @stmts :: Statement "#); } #[test] fn nested_captures_with_types() { - let input = indoc! {r#" - Q = (function - name: (identifier) @name :: string - body: (block - (statement)* @body_stmts :: Statement)) @func :: Function - "#}; - - let res = Query::expect_valid_cst(input); - - insta::assert_snapshot!(res, @r#" - Root - Def - Id "Q" - Equals "=" - Capture - Tree - ParenOpen "(" - Id "function" - Capture - Field - Id "name" - Colon ":" - Tree - ParenOpen "(" - Id "identifier" - ParenClose ")" - CaptureToken "@name" - Type - DoubleColon "::" - Id "string" - Field - Id "body" - Colon ":" - Tree - ParenOpen "(" - Id "block" - Capture - Quantifier - Tree - ParenOpen "(" - Id "statement" - ParenClose ")" - Star "*" - CaptureToken "@body_stmts" - Type - DoubleColon "::" - Id "Statement" - ParenClose ")" - ParenClose ")" - CaptureToken "@func" - Type - DoubleColon "::" - Id "Function" + shot_cst!(r#" + Q = (function + name: (identifier) @name :: string + body: (block + (statement)* @body_stmts :: Statement)) @func :: Function "#); } #[test] fn capture_with_type_no_spaces() { - let input = indoc! {r#" - Q = (identifier) @name::string - "#}; - - let res = Query::expect_valid_cst(input); - - insta::assert_snapshot!(res, @r#" - Root - Def - Id "Q" - Equals "=" - Capture - Tree - ParenOpen "(" - Id "identifier" - ParenClose ")" - CaptureToken "@name" - Type - DoubleColon "::" - Id "string" + shot_cst!(r#" + Q = (identifier) @name::string "#); } #[test] fn capture_literal() { - let input = indoc! {r#" - Q = "foo" @keyword - "#}; - - let res = Query::expect_valid_cst(input); - - insta::assert_snapshot!(res, @r#" - Root - Def - Id "Q" - Equals "=" - Capture - Str - DoubleQuote "\"" - StrVal "foo" - DoubleQuote "\"" - CaptureToken "@keyword" + shot_cst!(r#" + Q = "foo" @keyword "#); } #[test] fn capture_literal_with_type() { - let input = indoc! {r#" - Q = "return" @kw :: string - "#}; - - let res = Query::expect_valid_cst(input); - - insta::assert_snapshot!(res, @r#" - Root - Def - Id "Q" - Equals "=" - Capture - Str - DoubleQuote "\"" - StrVal "return" - DoubleQuote "\"" - CaptureToken "@kw" - Type - DoubleColon "::" - Id "string" + shot_cst!(r#" + Q = "return" @kw :: string "#); } #[test] fn capture_literal_in_tree() { - let input = indoc! {r#" - Q = (binary_expression "+" @op) - "#}; - - let res = Query::expect_valid_cst(input); - - insta::assert_snapshot!(res, @r#" - Root - Def - Id "Q" - Equals "=" - Tree - ParenOpen "(" - Id "binary_expression" - Capture - Str - DoubleQuote "\"" - StrVal "+" - DoubleQuote "\"" - CaptureToken "@op" - ParenClose ")" + shot_cst!(r#" + Q = (binary_expression "+" @op) "#); } #[test] fn capture_literal_with_quantifier() { - let input = indoc! {r#" - Q = ","* @commas - "#}; - - let res = Query::expect_valid_cst(input); - - insta::assert_snapshot!(res, @r#" - Root - Def - Id "Q" - Equals "=" - Capture - Quantifier - Str - DoubleQuote "\"" - StrVal "," - DoubleQuote "\"" - Star "*" - CaptureToken "@commas" + shot_cst!(r#" + Q = ","* @commas "#); } diff --git a/crates/plotnik-compiler/src/parser/tests/grammar/definitions_tests.rs b/crates/plotnik-compiler/src/parser/tests/grammar/definitions_tests.rs index f10b8bf..949ff1c 100644 --- a/crates/plotnik-compiler/src/parser/tests/grammar/definitions_tests.rs +++ b/crates/plotnik-compiler/src/parser/tests/grammar/definitions_tests.rs @@ -1,372 +1,91 @@ -use crate::Query; -use indoc::indoc; +//! Definition parsing tests. + +use crate::{shot_cst, shot_error}; #[test] fn simple_named_def() { - let input = indoc! {r#" - Expr = (identifier) - "#}; - - let res = Query::expect_valid_cst(input); - - insta::assert_snapshot!(res, @r#" - Root - Def - Id "Expr" - Equals "=" - Tree - ParenOpen "(" - Id "identifier" - ParenClose ")" + shot_cst!(r#" + Expr = (identifier) "#); } #[test] fn named_def_with_alternation() { - let input = indoc! {r#" - Value = [(identifier) (number) (string)] - "#}; - - let res = Query::expect_valid_cst(input); - - insta::assert_snapshot!(res, @r#" - Root - Def - Id "Value" - Equals "=" - Alt - BracketOpen "[" - Branch - Tree - ParenOpen "(" - Id "identifier" - ParenClose ")" - Branch - Tree - ParenOpen "(" - Id "number" - ParenClose ")" - Branch - Tree - ParenOpen "(" - Id "string" - ParenClose ")" - BracketClose "]" + shot_cst!(r#" + Value = [(identifier) (number) (string)] "#); } #[test] fn named_def_with_sequence() { - let input = indoc! {r#" - Pair = {(identifier) (expression)} - "#}; - - let res = Query::expect_valid_cst(input); - - insta::assert_snapshot!(res, @r#" - Root - Def - Id "Pair" - Equals "=" - Seq - BraceOpen "{" - Tree - ParenOpen "(" - Id "identifier" - ParenClose ")" - Tree - ParenOpen "(" - Id "expression" - ParenClose ")" - BraceClose "}" + shot_cst!(r#" + Pair = {(identifier) (expression)} "#); } #[test] fn named_def_with_captures() { - let input = indoc! {r#" - BinaryOp = (binary_expression - left: (_) @left - operator: _ @op - right: (_) @right) - "#}; - - let res = Query::expect_valid_cst(input); - - insta::assert_snapshot!(res, @r#" - Root - Def - Id "BinaryOp" - Equals "=" - Tree - ParenOpen "(" - Id "binary_expression" - Capture - Field - Id "left" - Colon ":" - Tree - ParenOpen "(" - Underscore "_" - ParenClose ")" - CaptureToken "@left" - Capture - Field - Id "operator" - Colon ":" - Wildcard - Underscore "_" - CaptureToken "@op" - Capture - Field - Id "right" - Colon ":" - Tree - ParenOpen "(" - Underscore "_" - ParenClose ")" - CaptureToken "@right" - ParenClose ")" + shot_cst!(r#" + BinaryOp = (binary_expression + left: (_) @left + operator: _ @op + right: (_) @right) "#); } #[test] fn multiple_named_defs() { - let input = indoc! {r#" - Expr = (expression) - Stmt = (statement) - "#}; - - let res = Query::expect_valid_cst(input); - - insta::assert_snapshot!(res, @r#" - Root - Def - Id "Expr" - Equals "=" - Tree - ParenOpen "(" - Id "expression" - ParenClose ")" - Def - Id "Stmt" - Equals "=" - Tree - ParenOpen "(" - Id "statement" - ParenClose ")" + shot_cst!(r#" + Expr = (expression) + Stmt = (statement) "#); } #[test] fn named_def_then_expression() { - let input = indoc! {r#" - Expr = [(identifier) (number)] - (program (Expr) @value) - "#}; - - let res = Query::expect_invalid(input); - - insta::assert_snapshot!(res, @r" - error: definition must be named - | - 2 | (program (Expr) @value) - | ^^^^^^^^^^^^^^^^^^^^^^^ - | - help: give it a name like `Name = (program (Expr) @value)` - "); + shot_error!(r#" + Expr = [(identifier) (number)] + (program (Expr) @value) + "#); } #[test] fn named_def_referencing_another() { - let input = indoc! {r#" - Literal = [(number) (string)] - Expr = [(identifier) (Literal)] - "#}; - - let res = Query::expect_valid_cst(input); - - insta::assert_snapshot!(res, @r#" - Root - Def - Id "Literal" - Equals "=" - Alt - BracketOpen "[" - Branch - Tree - ParenOpen "(" - Id "number" - ParenClose ")" - Branch - Tree - ParenOpen "(" - Id "string" - ParenClose ")" - BracketClose "]" - Def - Id "Expr" - Equals "=" - Alt - BracketOpen "[" - Branch - Tree - ParenOpen "(" - Id "identifier" - ParenClose ")" - Branch - Ref - ParenOpen "(" - Id "Literal" - ParenClose ")" - BracketClose "]" + shot_cst!(r#" + Literal = [(number) (string)] + Expr = [(identifier) (Literal)] "#); } #[test] fn named_def_with_quantifier() { - let input = indoc! {r#" - Statements = (statement)+ - "#}; - - let res = Query::expect_valid_cst(input); - - insta::assert_snapshot!(res, @r#" - Root - Def - Id "Statements" - Equals "=" - Quantifier - Tree - ParenOpen "(" - Id "statement" - ParenClose ")" - Plus "+" + shot_cst!(r#" + Statements = (statement)+ "#); } #[test] fn named_def_complex_recursive() { - let input = indoc! {r#" - NestedCall = (call_expression - function: [(identifier) @name (NestedCall) @inner] - arguments: (arguments)) - "#}; - - let res = Query::expect_valid_cst(input); - - insta::assert_snapshot!(res, @r#" - Root - Def - Id "NestedCall" - Equals "=" - Tree - ParenOpen "(" - Id "call_expression" - Field - Id "function" - Colon ":" - Alt - BracketOpen "[" - Branch - Capture - Tree - ParenOpen "(" - Id "identifier" - ParenClose ")" - CaptureToken "@name" - Branch - Capture - Ref - ParenOpen "(" - Id "NestedCall" - ParenClose ")" - CaptureToken "@inner" - BracketClose "]" - Field - Id "arguments" - Colon ":" - Tree - ParenOpen "(" - Id "arguments" - ParenClose ")" - ParenClose ")" + shot_cst!(r#" + NestedCall = (call_expression + function: [(identifier) @name (NestedCall) @inner] + arguments: (arguments)) "#); } #[test] fn named_def_with_type_annotation() { - let input = indoc! {r#" - Func = (function_declaration - name: (identifier) @name :: string - body: (_) @body) - "#}; - - let res = Query::expect_valid_cst(input); - - insta::assert_snapshot!(res, @r#" - Root - Def - Id "Func" - Equals "=" - Tree - ParenOpen "(" - Id "function_declaration" - Capture - Field - Id "name" - Colon ":" - Tree - ParenOpen "(" - Id "identifier" - ParenClose ")" - CaptureToken "@name" - Type - DoubleColon "::" - Id "string" - Capture - Field - Id "body" - Colon ":" - Tree - ParenOpen "(" - Underscore "_" - ParenClose ")" - CaptureToken "@body" - ParenClose ")" + shot_cst!(r#" + Func = (function_declaration + name: (identifier) @name :: string + body: (_) @body) "#); } #[test] fn unnamed_def_allowed_as_last() { - let input = indoc! {r#" - Expr = (identifier) - Q = (program (Expr) @value) - "#}; - - let res = Query::expect_valid_cst(input); - - insta::assert_snapshot!(res, @r#" - Root - Def - Id "Expr" - Equals "=" - Tree - ParenOpen "(" - Id "identifier" - ParenClose ")" - Def - Id "Q" - Equals "=" - Tree - ParenOpen "(" - Id "program" - Capture - Ref - ParenOpen "(" - Id "Expr" - ParenClose ")" - CaptureToken "@value" - ParenClose ")" + shot_cst!(r#" + Expr = (identifier) + Q = (program (Expr) @value) "#); } diff --git a/crates/plotnik-compiler/src/parser/tests/grammar/fields_tests.rs b/crates/plotnik-compiler/src/parser/tests/grammar/fields_tests.rs index 93f43b9..abb4161 100644 --- a/crates/plotnik-compiler/src/parser/tests/grammar/fields_tests.rs +++ b/crates/plotnik-compiler/src/parser/tests/grammar/fields_tests.rs @@ -1,272 +1,65 @@ -use crate::Query; -use indoc::indoc; +//! Field parsing tests. + +use crate::shot_cst; #[test] fn field_expression() { - let input = indoc! {r#" - Q = (call function: (identifier)) - "#}; - - let res = Query::expect_valid_cst(input); - - insta::assert_snapshot!(res, @r#" - Root - Def - Id "Q" - Equals "=" - Tree - ParenOpen "(" - Id "call" - Field - Id "function" - Colon ":" - Tree - ParenOpen "(" - Id "identifier" - ParenClose ")" - ParenClose ")" + shot_cst!(r#" + Q = (call function: (identifier)) "#); } #[test] fn multiple_fields() { - let input = indoc! {r#" - Q = (assignment - left: (identifier) - right: (expression)) - "#}; - - let res = Query::expect_valid_cst(input); - - insta::assert_snapshot!(res, @r#" - Root - Def - Id "Q" - Equals "=" - Tree - ParenOpen "(" - Id "assignment" - Field - Id "left" - Colon ":" - Tree - ParenOpen "(" - Id "identifier" - ParenClose ")" - Field - Id "right" - Colon ":" - Tree - ParenOpen "(" - Id "expression" - ParenClose ")" - ParenClose ")" + shot_cst!(r#" + Q = (assignment + left: (identifier) + right: (expression)) "#); } #[test] fn negated_field() { - let input = indoc! {r#" - Q = (function -async) - "#}; - - let res = Query::expect_valid_cst(input); - - insta::assert_snapshot!(res, @r#" - Root - Def - Id "Q" - Equals "=" - Tree - ParenOpen "(" - Id "function" - NegatedField - Minus "-" - Id "async" - ParenClose ")" + shot_cst!(r#" + Q = (function -async) "#); } #[test] fn negated_and_regular_fields() { - let input = indoc! {r#" - Q = (function - -async - name: (identifier)) - "#}; - - let res = Query::expect_valid_cst(input); - - insta::assert_snapshot!(res, @r#" - Root - Def - Id "Q" - Equals "=" - Tree - ParenOpen "(" - Id "function" - NegatedField - Minus "-" - Id "async" - Field - Id "name" - Colon ":" - Tree - ParenOpen "(" - Id "identifier" - ParenClose ")" - ParenClose ")" + shot_cst!(r#" + Q = (function + -async + name: (identifier)) "#); } #[test] fn mixed_children_and_fields() { - let input = indoc! {r#" - Q = (if - condition: (expr) - (then_block) - else: (else_block)) - "#}; - - let res = Query::expect_valid_cst(input); - - insta::assert_snapshot!(res, @r#" - Root - Def - Id "Q" - Equals "=" - Tree - ParenOpen "(" - Id "if" - Field - Id "condition" - Colon ":" - Tree - ParenOpen "(" - Id "expr" - ParenClose ")" - Tree - ParenOpen "(" - Id "then_block" - ParenClose ")" - Field - Id "else" - Colon ":" - Tree - ParenOpen "(" - Id "else_block" - ParenClose ")" - ParenClose ")" + shot_cst!(r#" + Q = (if + condition: (expr) + (then_block) + else: (else_block)) "#); } #[test] fn fields_and_quantifiers() { - let input = indoc! {r#" - Q = (node - foo: (foo)? - foo: (foo)?? - bar: (bar)* - bar: (bar)*? - baz: (baz)+? - baz: (baz)+?) - "#}; - - let res = Query::expect_valid_cst(input); - - insta::assert_snapshot!(res, @r#" - Root - Def - Id "Q" - Equals "=" - Tree - ParenOpen "(" - Id "node" - Quantifier - Field - Id "foo" - Colon ":" - Tree - ParenOpen "(" - Id "foo" - ParenClose ")" - Question "?" - Quantifier - Field - Id "foo" - Colon ":" - Tree - ParenOpen "(" - Id "foo" - ParenClose ")" - QuestionQuestion "??" - Quantifier - Field - Id "bar" - Colon ":" - Tree - ParenOpen "(" - Id "bar" - ParenClose ")" - Star "*" - Quantifier - Field - Id "bar" - Colon ":" - Tree - ParenOpen "(" - Id "bar" - ParenClose ")" - StarQuestion "*?" - Quantifier - Field - Id "baz" - Colon ":" - Tree - ParenOpen "(" - Id "baz" - ParenClose ")" - PlusQuestion "+?" - Quantifier - Field - Id "baz" - Colon ":" - Tree - ParenOpen "(" - Id "baz" - ParenClose ")" - PlusQuestion "+?" - ParenClose ")" + shot_cst!(r#" + Q = (node + foo: (foo)? + foo: (foo)?? + bar: (bar)* + bar: (bar)*? + baz: (baz)+? + baz: (baz)+?) "#); } #[test] fn fields_with_quantifiers_and_captures() { - let input = indoc! {r#" - Q = (node foo: (bar)* @baz) - "#}; - - let res = Query::expect_valid_cst(input); - - insta::assert_snapshot!(res, @r#" - Root - Def - Id "Q" - Equals "=" - Tree - ParenOpen "(" - Id "node" - Capture - Quantifier - Field - Id "foo" - Colon ":" - Tree - ParenOpen "(" - Id "bar" - ParenClose ")" - Star "*" - CaptureToken "@baz" - ParenClose ")" + shot_cst!(r#" + Q = (node foo: (bar)* @baz) "#); } diff --git a/crates/plotnik-compiler/src/parser/tests/grammar/nodes_tests.rs b/crates/plotnik-compiler/src/parser/tests/grammar/nodes_tests.rs index 16a0501..a3036c1 100644 --- a/crates/plotnik-compiler/src/parser/tests/grammar/nodes_tests.rs +++ b/crates/plotnik-compiler/src/parser/tests/grammar/nodes_tests.rs @@ -1,378 +1,115 @@ -use crate::Query; -use indoc::indoc; +//! Node parsing tests. + +use crate::shot_cst; #[test] fn empty_input() { - insta::assert_snapshot!(Query::expect_valid_cst(""), @"Root"); + shot_cst!(""); } #[test] fn simple_named_node() { - let input = indoc! {r#" - Q = (identifier) - "#}; - - let res = Query::expect_valid_cst(input); - - insta::assert_snapshot!(res, @r#" - Root - Def - Id "Q" - Equals "=" - Tree - ParenOpen "(" - Id "identifier" - ParenClose ")" + shot_cst!(r#" + Q = (identifier) "#); } #[test] fn nested_node() { - let input = indoc! {r#" - Q = (function_definition name: (identifier)) - "#}; - - let res = Query::expect_valid_cst(input); - - insta::assert_snapshot!(res, @r#" - Root - Def - Id "Q" - Equals "=" - Tree - ParenOpen "(" - Id "function_definition" - Field - Id "name" - Colon ":" - Tree - ParenOpen "(" - Id "identifier" - ParenClose ")" - ParenClose ")" + shot_cst!(r#" + Q = (function_definition name: (identifier)) "#); } #[test] fn deeply_nested() { - let input = indoc! {r#" - Q = (a - (b - (c - (d)))) - "#}; - - let res = Query::expect_valid_cst(input); - - insta::assert_snapshot!(res, @r#" - Root - Def - Id "Q" - Equals "=" - Tree - ParenOpen "(" - Id "a" - Tree - ParenOpen "(" - Id "b" - Tree - ParenOpen "(" - Id "c" - Tree - ParenOpen "(" - Id "d" - ParenClose ")" - ParenClose ")" - ParenClose ")" - ParenClose ")" + shot_cst!(r#" + Q = (a + (b + (c + (d)))) "#); } #[test] fn sibling_children() { - let input = indoc! {r#" - Q = (block - (statement) - (statement) - (statement)) - "#}; - - let res = Query::expect_valid_cst(input); - - insta::assert_snapshot!(res, @r#" - Root - Def - Id "Q" - Equals "=" - Tree - ParenOpen "(" - Id "block" - Tree - ParenOpen "(" - Id "statement" - ParenClose ")" - Tree - ParenOpen "(" - Id "statement" - ParenClose ")" - Tree - ParenOpen "(" - Id "statement" - ParenClose ")" - ParenClose ")" + shot_cst!(r#" + Q = (block + (statement) + (statement) + (statement)) "#); } #[test] fn wildcard() { - let input = indoc! {r#" - Q = (_) - "#}; - - let res = Query::expect_valid_cst(input); - - insta::assert_snapshot!(res, @r#" - Root - Def - Id "Q" - Equals "=" - Tree - ParenOpen "(" - Underscore "_" - ParenClose ")" + shot_cst!(r#" + Q = (_) "#); } #[test] fn anonymous_node() { - let input = indoc! {r#" - Q = "if" - "#}; - - let res = Query::expect_valid_cst(input); - - insta::assert_snapshot!(res, @r#" - Root - Def - Id "Q" - Equals "=" - Str - DoubleQuote "\"" - StrVal "if" - DoubleQuote "\"" + shot_cst!(r#" + Q = "if" "#); } #[test] fn anonymous_node_operator() { - let input = indoc! {r#" - Q = "+=" - "#}; - - let res = Query::expect_valid_cst(input); - - insta::assert_snapshot!(res, @r#" - Root - Def - Id "Q" - Equals "=" - Str - DoubleQuote "\"" - StrVal "+=" - DoubleQuote "\"" + shot_cst!(r#" + Q = "+=" "#); } #[test] fn supertype_basic() { - let input = indoc! {r#" - Q = (expression/binary_expression) - "#}; - - let res = Query::expect_valid_cst(input); - - insta::assert_snapshot!(res, @r#" - Root - Def - Id "Q" - Equals "=" - Tree - ParenOpen "(" - Id "expression" - Slash "/" - Id "binary_expression" - ParenClose ")" + shot_cst!(r#" + Q = (expression/binary_expression) "#); } #[test] fn supertype_with_string_subtype() { - let input = indoc! {r#" - Q = (expression/"()") - "#}; - - let res = Query::expect_valid_cst(input); - - insta::assert_snapshot!(res, @r#" - Root - Def - Id "Q" - Equals "=" - Tree - ParenOpen "(" - Id "expression" - Slash "/" - DoubleQuote "\"" - StrVal "()" - DoubleQuote "\"" - ParenClose ")" + shot_cst!(r#" + Q = (expression/"()") "#); } #[test] fn supertype_with_capture() { - let input = indoc! {r#" - Q = (expression/binary_expression) @expr - "#}; - - let res = Query::expect_valid_cst(input); - - insta::assert_snapshot!(res, @r#" - Root - Def - Id "Q" - Equals "=" - Capture - Tree - ParenOpen "(" - Id "expression" - Slash "/" - Id "binary_expression" - ParenClose ")" - CaptureToken "@expr" + shot_cst!(r#" + Q = (expression/binary_expression) @expr "#); } #[test] fn supertype_with_children() { - let input = indoc! {r#" - Q = (expression/binary_expression - left: (_) @left - right: (_) @right) - "#}; - - let res = Query::expect_valid_cst(input); - - insta::assert_snapshot!(res, @r#" - Root - Def - Id "Q" - Equals "=" - Tree - ParenOpen "(" - Id "expression" - Slash "/" - Id "binary_expression" - Capture - Field - Id "left" - Colon ":" - Tree - ParenOpen "(" - Underscore "_" - ParenClose ")" - CaptureToken "@left" - Capture - Field - Id "right" - Colon ":" - Tree - ParenOpen "(" - Underscore "_" - ParenClose ")" - CaptureToken "@right" - ParenClose ")" + shot_cst!(r#" + Q = (expression/binary_expression + left: (_) @left + right: (_) @right) "#); } #[test] fn supertype_nested() { - let input = indoc! {r#" - Q = (statement/expression_statement - (expression/call_expression)) - "#}; - - let res = Query::expect_valid_cst(input); - - insta::assert_snapshot!(res, @r#" - Root - Def - Id "Q" - Equals "=" - Tree - ParenOpen "(" - Id "statement" - Slash "/" - Id "expression_statement" - Tree - ParenOpen "(" - Id "expression" - Slash "/" - Id "call_expression" - ParenClose ")" - ParenClose ")" + shot_cst!(r#" + Q = (statement/expression_statement + (expression/call_expression)) "#); } #[test] fn supertype_in_alternation() { - let input = indoc! {r#" - Q = [(expression/identifier) (expression/number)] - "#}; - - let res = Query::expect_valid_cst(input); - - insta::assert_snapshot!(res, @r#" - Root - Def - Id "Q" - Equals "=" - Alt - BracketOpen "[" - Branch - Tree - ParenOpen "(" - Id "expression" - Slash "/" - Id "identifier" - ParenClose ")" - Branch - Tree - ParenOpen "(" - Id "expression" - Slash "/" - Id "number" - ParenClose ")" - BracketClose "]" + shot_cst!(r#" + Q = [(expression/identifier) (expression/number)] "#); } #[test] fn no_supertype_plain_node() { - let input = indoc! {r#" - Q = (identifier) - "#}; - - let res = Query::expect_valid_cst(input); - - insta::assert_snapshot!(res, @r#" - Root - Def - Id "Q" - Equals "=" - Tree - ParenOpen "(" - Id "identifier" - ParenClose ")" + shot_cst!(r#" + Q = (identifier) "#); } diff --git a/crates/plotnik-compiler/src/parser/tests/grammar/quantifiers_tests.rs b/crates/plotnik-compiler/src/parser/tests/grammar/quantifiers_tests.rs index 3a197d8..cff2b48 100644 --- a/crates/plotnik-compiler/src/parser/tests/grammar/quantifiers_tests.rs +++ b/crates/plotnik-compiler/src/parser/tests/grammar/quantifiers_tests.rs @@ -1,119 +1,39 @@ -use crate::Query; -use indoc::indoc; +//! Quantifier parsing tests. + +use crate::shot_cst; #[test] fn quantifier_star() { - let input = indoc! {r#" - Q = (statement)* - "#}; - - let res = Query::expect_valid_cst(input); - - insta::assert_snapshot!(res, @r#" - Root - Def - Id "Q" - Equals "=" - Quantifier - Tree - ParenOpen "(" - Id "statement" - ParenClose ")" - Star "*" + shot_cst!(r#" + Q = (statement)* "#); } #[test] fn quantifier_plus() { - let input = indoc! {r#" - Q = (statement)+ - "#}; - - let res = Query::expect_valid_cst(input); - - insta::assert_snapshot!(res, @r#" - Root - Def - Id "Q" - Equals "=" - Quantifier - Tree - ParenOpen "(" - Id "statement" - ParenClose ")" - Plus "+" + shot_cst!(r#" + Q = (statement)+ "#); } #[test] fn quantifier_optional() { - let input = indoc! {r#" - Q = (statement)? - "#}; - - let res = Query::expect_valid_cst(input); - - insta::assert_snapshot!(res, @r#" - Root - Def - Id "Q" - Equals "=" - Quantifier - Tree - ParenOpen "(" - Id "statement" - ParenClose ")" - Question "?" + shot_cst!(r#" + Q = (statement)? "#); } #[test] fn quantifier_with_capture() { - let input = indoc! {r#" - Q = (statement)* @statements - "#}; - - let res = Query::expect_valid_cst(input); - - insta::assert_snapshot!(res, @r#" - Root - Def - Id "Q" - Equals "=" - Capture - Quantifier - Tree - ParenOpen "(" - Id "statement" - ParenClose ")" - Star "*" - CaptureToken "@statements" + shot_cst!(r#" + Q = (statement)* @statements "#); } #[test] fn quantifier_inside_node() { - let input = indoc! {r#" - Q = (block - (statement)*) - "#}; - - let res = Query::expect_valid_cst(input); - - insta::assert_snapshot!(res, @r#" - Root - Def - Id "Q" - Equals "=" - Tree - ParenOpen "(" - Id "block" - Quantifier - Tree - ParenOpen "(" - Id "statement" - ParenClose ")" - Star "*" - ParenClose ")" + shot_cst!(r#" + Q = (block + (statement)*) "#); } diff --git a/crates/plotnik-compiler/src/parser/tests/grammar/sequences_tests.rs b/crates/plotnik-compiler/src/parser/tests/grammar/sequences_tests.rs index 4ee3572..2b8b36d 100644 --- a/crates/plotnik-compiler/src/parser/tests/grammar/sequences_tests.rs +++ b/crates/plotnik-compiler/src/parser/tests/grammar/sequences_tests.rs @@ -1,15 +1,11 @@ -use crate::Query; -use indoc::indoc; +//! Sequence parsing tests. -// Tree-sitter compatibility: ((a) (b)) parses as Seq, not as wildcard Tree with children +use crate::{shot_cst, shot_error, Query}; #[test] fn treesitter_sequence_parses_as_seq() { - // Tree-sitter style ((a) (b)) should produce Seq, same structure as {(a) (b)} let input = "Q = ((a) (b))"; - let res = Query::expect_cst_with_warnings(input); - insta::assert_snapshot!(res, @r#" Root Def @@ -31,11 +27,8 @@ fn treesitter_sequence_parses_as_seq() { #[test] fn treesitter_single_item_sequence_parses_as_seq() { - // Regression test: ((x)) should be Seq containing x, not wildcard Tree with child x let input = "Q = ((expression_statement))"; - let res = Query::expect_cst_with_warnings(input); - insta::assert_snapshot!(res, @r#" Root Def @@ -53,139 +46,43 @@ fn treesitter_single_item_sequence_parses_as_seq() { #[test] fn named_node_with_child_remains_tree() { - // (foo (bar)) is a named node with child, NOT a sequence - let input = "Q = (foo (bar))"; - - let res = Query::expect_valid_cst(input); - - insta::assert_snapshot!(res, @r#" - Root - Def - Id "Q" - Equals "=" - Tree - ParenOpen "(" - Id "foo" - Tree - ParenOpen "(" - Id "bar" - ParenClose ")" - ParenClose ")" + shot_cst!(r#" + Q = (foo (bar)) "#); } #[test] fn simple_sequence() { - let input = indoc! {r#" - Q = {(a) (b)} - "#}; - - let res = Query::expect_valid_cst(input); - - insta::assert_snapshot!(res, @r#" - Root - Def - Id "Q" - Equals "=" - Seq - BraceOpen "{" - Tree - ParenOpen "(" - Id "a" - ParenClose ")" - Tree - ParenOpen "(" - Id "b" - ParenClose ")" - BraceClose "}" + shot_cst!(r#" + Q = {(a) (b)} "#); } #[test] fn empty_sequence() { - let input = indoc! {r#" - Q = {} - "#}; - - let res = Query::expect_invalid(input); - - insta::assert_snapshot!(res, @r" - error: empty `{}` is not allowed - | - 1 | Q = {} - | ^^ - | - help: sequences must contain at least one expression - "); + shot_error!(r#" + Q = {} + "#); } #[test] fn sequence_single_element() { - let input = indoc! {r#" - Q = {(identifier)} - "#}; - - let res = Query::expect_valid_cst(input); - - insta::assert_snapshot!(res, @r#" - Root - Def - Id "Q" - Equals "=" - Seq - BraceOpen "{" - Tree - ParenOpen "(" - Id "identifier" - ParenClose ")" - BraceClose "}" + shot_cst!(r#" + Q = {(identifier)} "#); } #[test] fn sequence_with_captures() { - let input = indoc! {r#" - Q = {(comment)* @comments (function) @fn} - "#}; - - let res = Query::expect_valid_cst(input); - - insta::assert_snapshot!(res, @r#" - Root - Def - Id "Q" - Equals "=" - Seq - BraceOpen "{" - Capture - Quantifier - Tree - ParenOpen "(" - Id "comment" - ParenClose ")" - Star "*" - CaptureToken "@comments" - Capture - Tree - ParenOpen "(" - Id "function" - ParenClose ")" - CaptureToken "@fn" - BraceClose "}" + shot_cst!(r#" + Q = {(comment)* @comments (function) @fn} "#); } #[test] fn sequence_with_quantifier() { - // Note: This tests parser behavior only. The pattern `{(a) (b)}+` is - // semantically invalid (multi-element sequence without captures), but - // we're only testing that the parser produces the correct CST. - let input = indoc! {r#" - Q = {(a) (b)}+ - "#}; - + let input = "Q = {(a) (b)}+"; let res = Query::parse_cst(input); - insta::assert_snapshot!(res, @r#" Root Def @@ -209,115 +106,29 @@ fn sequence_with_quantifier() { #[test] fn nested_sequences() { - let input = indoc! {r#" - Q = {{(a)} {(b)}} - "#}; - - let res = Query::expect_valid_cst(input); - - insta::assert_snapshot!(res, @r#" - Root - Def - Id "Q" - Equals "=" - Seq - BraceOpen "{" - Seq - BraceOpen "{" - Tree - ParenOpen "(" - Id "a" - ParenClose ")" - BraceClose "}" - Seq - BraceOpen "{" - Tree - ParenOpen "(" - Id "b" - ParenClose ")" - BraceClose "}" - BraceClose "}" + shot_cst!(r#" + Q = {{(a)} {(b)}} "#); } #[test] fn sequence_in_named_node() { - let input = indoc! {r#" - Q = (block {(statement) (statement)}) - "#}; - - let res = Query::expect_valid_cst(input); - - insta::assert_snapshot!(res, @r#" - Root - Def - Id "Q" - Equals "=" - Tree - ParenOpen "(" - Id "block" - Seq - BraceOpen "{" - Tree - ParenOpen "(" - Id "statement" - ParenClose ")" - Tree - ParenOpen "(" - Id "statement" - ParenClose ")" - BraceClose "}" - ParenClose ")" + shot_cst!(r#" + Q = (block {(statement) (statement)}) "#); } #[test] fn sequence_with_alternation() { - let input = indoc! {r#" - Q = {[(a) (b)] (c)} - "#}; - - let res = Query::expect_valid_cst(input); - - insta::assert_snapshot!(res, @r#" - Root - Def - Id "Q" - Equals "=" - Seq - BraceOpen "{" - Alt - BracketOpen "[" - Branch - Tree - ParenOpen "(" - Id "a" - ParenClose ")" - Branch - Tree - ParenOpen "(" - Id "b" - ParenClose ")" - BracketClose "]" - Tree - ParenOpen "(" - Id "c" - ParenClose ")" - BraceClose "}" + shot_cst!(r#" + Q = {[(a) (b)] (c)} "#); } #[test] fn sequence_comma_separated_expression() { - // Note: This tests parser behavior only. The inner pattern `{"," (number)}*` - // is semantically invalid (multi-element sequence without captures), but - // we're only testing that the parser produces the correct CST. - let input = indoc! {r#" - Q = {(number) {"," (number)}*} - "#}; - + let input = r#"Q = {(number) {"," (number)}*}"#; let res = Query::parse_cst(input); - insta::assert_snapshot!(res, @r#" Root Def @@ -348,36 +159,7 @@ fn sequence_comma_separated_expression() { #[test] fn sequence_with_anchor() { - // Boundary anchors require parent node context - let input = indoc! {r#" - Q = (parent {. (first) (second) .}) - "#}; - - let res = Query::expect_valid_cst(input); - - insta::assert_snapshot!(res, @r#" - Root - Def - Id "Q" - Equals "=" - Tree - ParenOpen "(" - Id "parent" - Seq - BraceOpen "{" - Anchor - Dot "." - Tree - ParenOpen "(" - Id "first" - ParenClose ")" - Tree - ParenOpen "(" - Id "second" - ParenClose ")" - Anchor - Dot "." - BraceClose "}" - ParenClose ")" + shot_cst!(r#" + Q = (parent {. (first) (second) .}) "#); } diff --git a/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__alternations_tests__alternation.snap b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__alternations_tests__alternation.snap new file mode 100644 index 0000000..1ad03aa --- /dev/null +++ b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__alternations_tests__alternation.snap @@ -0,0 +1,22 @@ +--- +source: crates/plotnik-compiler/src/parser/tests/grammar/alternations_tests.rs +--- +Q = [(identifier) (string)] +--- +Root + Def + Id "Q" + Equals "=" + Alt + BracketOpen "[" + Branch + Tree + ParenOpen "(" + Id "identifier" + ParenClose ")" + Branch + Tree + ParenOpen "(" + Id "string" + ParenClose ")" + BracketClose "]" diff --git a/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__alternations_tests__alternation_in_field.snap b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__alternations_tests__alternation_in_field.snap new file mode 100644 index 0000000..303fdd4 --- /dev/null +++ b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__alternations_tests__alternation_in_field.snap @@ -0,0 +1,31 @@ +--- +source: crates/plotnik-compiler/src/parser/tests/grammar/alternations_tests.rs +--- +Q = (call + arguments: [(string) (number)] +) +--- +Root + Def + Id "Q" + Equals "=" + Tree + ParenOpen "(" + Id "call" + Field + Id "arguments" + Colon ":" + Alt + BracketOpen "[" + Branch + Tree + ParenOpen "(" + Id "string" + ParenClose ")" + Branch + Tree + ParenOpen "(" + Id "number" + ParenClose ")" + BracketClose "]" + ParenClose ")" diff --git a/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__alternations_tests__alternation_nested.snap b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__alternations_tests__alternation_nested.snap new file mode 100644 index 0000000..6866911 --- /dev/null +++ b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__alternations_tests__alternation_nested.snap @@ -0,0 +1,28 @@ +--- +source: crates/plotnik-compiler/src/parser/tests/grammar/alternations_tests.rs +--- +Q = (expr + [(binary) (unary)] +) +--- +Root + Def + Id "Q" + Equals "=" + Tree + ParenOpen "(" + Id "expr" + Alt + BracketOpen "[" + Branch + Tree + ParenOpen "(" + Id "binary" + ParenClose ")" + Branch + Tree + ParenOpen "(" + Id "unary" + ParenClose ")" + BracketClose "]" + ParenClose ")" diff --git a/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__alternations_tests__alternation_with_anonymous.snap b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__alternations_tests__alternation_with_anonymous.snap new file mode 100644 index 0000000..a0dfe08 --- /dev/null +++ b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__alternations_tests__alternation_with_anonymous.snap @@ -0,0 +1,22 @@ +--- +source: crates/plotnik-compiler/src/parser/tests/grammar/alternations_tests.rs +--- +Q = ["true" "false"] +--- +Root + Def + Id "Q" + Equals "=" + Alt + BracketOpen "[" + Branch + Str + DoubleQuote "\"" + StrVal "true" + DoubleQuote "\"" + Branch + Str + DoubleQuote "\"" + StrVal "false" + DoubleQuote "\"" + BracketClose "]" diff --git a/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__alternations_tests__alternation_with_capture.snap b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__alternations_tests__alternation_with_capture.snap new file mode 100644 index 0000000..85c3a86 --- /dev/null +++ b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__alternations_tests__alternation_with_capture.snap @@ -0,0 +1,24 @@ +--- +source: crates/plotnik-compiler/src/parser/tests/grammar/alternations_tests.rs +--- +Q = [(identifier) (string)] @value +--- +Root + Def + Id "Q" + Equals "=" + Capture + Alt + BracketOpen "[" + Branch + Tree + ParenOpen "(" + Id "identifier" + ParenClose ")" + Branch + Tree + ParenOpen "(" + Id "string" + ParenClose ")" + BracketClose "]" + CaptureToken "@value" diff --git a/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__alternations_tests__alternation_with_quantifier.snap b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__alternations_tests__alternation_with_quantifier.snap new file mode 100644 index 0000000..918a4ab --- /dev/null +++ b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__alternations_tests__alternation_with_quantifier.snap @@ -0,0 +1,29 @@ +--- +source: crates/plotnik-compiler/src/parser/tests/grammar/alternations_tests.rs +--- +Q = [ + (identifier) + (string)* @strings +] +--- +Root + Def + Id "Q" + Equals "=" + Alt + BracketOpen "[" + Branch + Tree + ParenOpen "(" + Id "identifier" + ParenClose ")" + Branch + Capture + Quantifier + Tree + ParenOpen "(" + Id "string" + ParenClose ")" + Star "*" + CaptureToken "@strings" + BracketClose "]" diff --git a/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__alternations_tests__tagged_alternation_full_example.snap b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__alternations_tests__tagged_alternation_full_example.snap new file mode 100644 index 0000000..db973ff --- /dev/null +++ b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__alternations_tests__tagged_alternation_full_example.snap @@ -0,0 +1,80 @@ +--- +source: crates/plotnik-compiler/src/parser/tests/grammar/alternations_tests.rs +--- +Expression = [ + Ident: (identifier) @name :: string + Num: (number) @value :: string + Str: (string) @value :: string + Binary: (binary_expression + left: (Expression) @left + right: (Expression) @right) +] +--- +Root + Def + Id "Expression" + Equals "=" + Alt + BracketOpen "[" + Branch + Id "Ident" + Colon ":" + Capture + Tree + ParenOpen "(" + Id "identifier" + ParenClose ")" + CaptureToken "@name" + Type + DoubleColon "::" + Id "string" + Branch + Id "Num" + Colon ":" + Capture + Tree + ParenOpen "(" + Id "number" + ParenClose ")" + CaptureToken "@value" + Type + DoubleColon "::" + Id "string" + Branch + Id "Str" + Colon ":" + Capture + Tree + ParenOpen "(" + Id "string" + ParenClose ")" + CaptureToken "@value" + Type + DoubleColon "::" + Id "string" + Branch + Id "Binary" + Colon ":" + Tree + ParenOpen "(" + Id "binary_expression" + Capture + Field + Id "left" + Colon ":" + Ref + ParenOpen "(" + Id "Expression" + ParenClose ")" + CaptureToken "@left" + Capture + Field + Id "right" + Colon ":" + Ref + ParenOpen "(" + Id "Expression" + ParenClose ")" + CaptureToken "@right" + ParenClose ")" + BracketClose "]" diff --git a/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__alternations_tests__tagged_alternation_in_named_def.snap b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__alternations_tests__tagged_alternation_in_named_def.snap new file mode 100644 index 0000000..4077aab --- /dev/null +++ b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__alternations_tests__tagged_alternation_in_named_def.snap @@ -0,0 +1,37 @@ +--- +source: crates/plotnik-compiler/src/parser/tests/grammar/alternations_tests.rs +--- +Statement = [ + Assign: (assignment_expression) + Call: (call_expression) + Return: (return_statement) +] +--- +Root + Def + Id "Statement" + Equals "=" + Alt + BracketOpen "[" + Branch + Id "Assign" + Colon ":" + Tree + ParenOpen "(" + Id "assignment_expression" + ParenClose ")" + Branch + Id "Call" + Colon ":" + Tree + ParenOpen "(" + Id "call_expression" + ParenClose ")" + Branch + Id "Return" + Colon ":" + Tree + ParenOpen "(" + Id "return_statement" + ParenClose ")" + BracketClose "]" diff --git a/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__alternations_tests__tagged_alternation_nested.snap b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__alternations_tests__tagged_alternation_nested.snap new file mode 100644 index 0000000..ca64b9b --- /dev/null +++ b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__alternations_tests__tagged_alternation_nested.snap @@ -0,0 +1,34 @@ +--- +source: crates/plotnik-compiler/src/parser/tests/grammar/alternations_tests.rs +--- +Q = (expr + [ + Binary: (binary_expression) + Unary: (unary_expression) + ]) +--- +Root + Def + Id "Q" + Equals "=" + Tree + ParenOpen "(" + Id "expr" + Alt + BracketOpen "[" + Branch + Id "Binary" + Colon ":" + Tree + ParenOpen "(" + Id "binary_expression" + ParenClose ")" + Branch + Id "Unary" + Colon ":" + Tree + ParenOpen "(" + Id "unary_expression" + ParenClose ")" + BracketClose "]" + ParenClose ")" diff --git a/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__alternations_tests__tagged_alternation_simple.snap b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__alternations_tests__tagged_alternation_simple.snap new file mode 100644 index 0000000..cc6c5f5 --- /dev/null +++ b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__alternations_tests__tagged_alternation_simple.snap @@ -0,0 +1,29 @@ +--- +source: crates/plotnik-compiler/src/parser/tests/grammar/alternations_tests.rs +--- +Q = [ + Ident: (identifier) + Num: (number) +] +--- +Root + Def + Id "Q" + Equals "=" + Alt + BracketOpen "[" + Branch + Id "Ident" + Colon ":" + Tree + ParenOpen "(" + Id "identifier" + ParenClose ")" + Branch + Id "Num" + Colon ":" + Tree + ParenOpen "(" + Id "number" + ParenClose ")" + BracketClose "]" diff --git a/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__alternations_tests__tagged_alternation_single_line.snap b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__alternations_tests__tagged_alternation_single_line.snap new file mode 100644 index 0000000..2070059 --- /dev/null +++ b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__alternations_tests__tagged_alternation_single_line.snap @@ -0,0 +1,33 @@ +--- +source: crates/plotnik-compiler/src/parser/tests/grammar/alternations_tests.rs +--- +Q = [A: (a) B: (b) C: (c)] +--- +Root + Def + Id "Q" + Equals "=" + Alt + BracketOpen "[" + Branch + Id "A" + Colon ":" + Tree + ParenOpen "(" + Id "a" + ParenClose ")" + Branch + Id "B" + Colon ":" + Tree + ParenOpen "(" + Id "b" + ParenClose ")" + Branch + Id "C" + Colon ":" + Tree + ParenOpen "(" + Id "c" + ParenClose ")" + BracketClose "]" diff --git a/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__alternations_tests__tagged_alternation_with_captures.snap b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__alternations_tests__tagged_alternation_with_captures.snap new file mode 100644 index 0000000..ffeb1f8 --- /dev/null +++ b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__alternations_tests__tagged_alternation_with_captures.snap @@ -0,0 +1,49 @@ +--- +source: crates/plotnik-compiler/src/parser/tests/grammar/alternations_tests.rs +--- +Q = [ + Assign: (assignment_expression left: (identifier) @left) + Call: (call_expression function: (identifier) @func) +] @stmt +--- +Root + Def + Id "Q" + Equals "=" + Capture + Alt + BracketOpen "[" + Branch + Id "Assign" + Colon ":" + Tree + ParenOpen "(" + Id "assignment_expression" + Capture + Field + Id "left" + Colon ":" + Tree + ParenOpen "(" + Id "identifier" + ParenClose ")" + CaptureToken "@left" + ParenClose ")" + Branch + Id "Call" + Colon ":" + Tree + ParenOpen "(" + Id "call_expression" + Capture + Field + Id "function" + Colon ":" + Tree + ParenOpen "(" + Id "identifier" + ParenClose ")" + CaptureToken "@func" + ParenClose ")" + BracketClose "]" + CaptureToken "@stmt" diff --git a/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__alternations_tests__tagged_alternation_with_nested_alternation.snap b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__alternations_tests__tagged_alternation_with_nested_alternation.snap new file mode 100644 index 0000000..e0e2e47 --- /dev/null +++ b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__alternations_tests__tagged_alternation_with_nested_alternation.snap @@ -0,0 +1,38 @@ +--- +source: crates/plotnik-compiler/src/parser/tests/grammar/alternations_tests.rs +--- +Q = [ + Literal: [(number) (string)] + Ident: (identifier) +] +--- +Root + Def + Id "Q" + Equals "=" + Alt + BracketOpen "[" + Branch + Id "Literal" + Colon ":" + Alt + BracketOpen "[" + Branch + Tree + ParenOpen "(" + Id "number" + ParenClose ")" + Branch + Tree + ParenOpen "(" + Id "string" + ParenClose ")" + BracketClose "]" + Branch + Id "Ident" + Colon ":" + Tree + ParenOpen "(" + Id "identifier" + ParenClose ")" + BracketClose "]" diff --git a/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__alternations_tests__tagged_alternation_with_quantifier.snap b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__alternations_tests__tagged_alternation_with_quantifier.snap new file mode 100644 index 0000000..d6ab82e --- /dev/null +++ b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__alternations_tests__tagged_alternation_with_quantifier.snap @@ -0,0 +1,31 @@ +--- +source: crates/plotnik-compiler/src/parser/tests/grammar/alternations_tests.rs +--- +Q = [ + Single: (statement) + Multiple: (statement)+ +] +--- +Root + Def + Id "Q" + Equals "=" + Alt + BracketOpen "[" + Branch + Id "Single" + Colon ":" + Tree + ParenOpen "(" + Id "statement" + ParenClose ")" + Branch + Id "Multiple" + Colon ":" + Quantifier + Tree + ParenOpen "(" + Id "statement" + ParenClose ")" + Plus "+" + BracketClose "]" diff --git a/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__alternations_tests__tagged_alternation_with_sequence.snap b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__alternations_tests__tagged_alternation_with_sequence.snap new file mode 100644 index 0000000..cb234ae --- /dev/null +++ b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__alternations_tests__tagged_alternation_with_sequence.snap @@ -0,0 +1,36 @@ +--- +source: crates/plotnik-compiler/src/parser/tests/grammar/alternations_tests.rs +--- +Q = [ + Pair: {(key) (value)} + Single: (value) +] +--- +Root + Def + Id "Q" + Equals "=" + Alt + BracketOpen "[" + Branch + Id "Pair" + Colon ":" + Seq + BraceOpen "{" + Tree + ParenOpen "(" + Id "key" + ParenClose ")" + Tree + ParenOpen "(" + Id "value" + ParenClose ")" + BraceClose "}" + Branch + Id "Single" + Colon ":" + Tree + ParenOpen "(" + Id "value" + ParenClose ")" + BracketClose "]" diff --git a/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__alternations_tests__tagged_alternation_with_type_annotation.snap b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__alternations_tests__tagged_alternation_with_type_annotation.snap new file mode 100644 index 0000000..082d72e --- /dev/null +++ b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__alternations_tests__tagged_alternation_with_type_annotation.snap @@ -0,0 +1,45 @@ +--- +source: crates/plotnik-compiler/src/parser/tests/grammar/alternations_tests.rs +--- +Q = [ + Base: (identifier) @name + Access: (member_expression object: (_) @obj) +] @chain :: MemberChain +--- +Root + Def + Id "Q" + Equals "=" + Capture + Alt + BracketOpen "[" + Branch + Id "Base" + Colon ":" + Capture + Tree + ParenOpen "(" + Id "identifier" + ParenClose ")" + CaptureToken "@name" + Branch + Id "Access" + Colon ":" + Tree + ParenOpen "(" + Id "member_expression" + Capture + Field + Id "object" + Colon ":" + Tree + ParenOpen "(" + Underscore "_" + ParenClose ")" + CaptureToken "@obj" + ParenClose ")" + BracketClose "]" + CaptureToken "@chain" + Type + DoubleColon "::" + Id "MemberChain" diff --git a/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__alternations_tests__unlabeled_alternation_three_items.snap b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__alternations_tests__unlabeled_alternation_three_items.snap new file mode 100644 index 0000000..78ab13a --- /dev/null +++ b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__alternations_tests__unlabeled_alternation_three_items.snap @@ -0,0 +1,27 @@ +--- +source: crates/plotnik-compiler/src/parser/tests/grammar/alternations_tests.rs +--- +Q = [(identifier) (number) (string)] +--- +Root + Def + Id "Q" + Equals "=" + Alt + BracketOpen "[" + Branch + Tree + ParenOpen "(" + Id "identifier" + ParenClose ")" + Branch + Tree + ParenOpen "(" + Id "number" + ParenClose ")" + Branch + Tree + ParenOpen "(" + Id "string" + ParenClose ")" + BracketClose "]" diff --git a/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__anchors_tests__anchor_adjacency.snap b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__anchors_tests__anchor_adjacency.snap new file mode 100644 index 0000000..a5342e5 --- /dev/null +++ b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__anchors_tests__anchor_adjacency.snap @@ -0,0 +1,27 @@ +--- +source: crates/plotnik-compiler/src/parser/tests/grammar/anchors_tests.rs +--- +Q = (dotted_name (identifier) @a . (identifier) @b) +--- +Root + Def + Id "Q" + Equals "=" + Tree + ParenOpen "(" + Id "dotted_name" + Capture + Tree + ParenOpen "(" + Id "identifier" + ParenClose ")" + CaptureToken "@a" + Anchor + Dot "." + Capture + Tree + ParenOpen "(" + Id "identifier" + ParenClose ")" + CaptureToken "@b" + ParenClose ")" diff --git a/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__anchors_tests__anchor_both_ends.snap b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__anchors_tests__anchor_both_ends.snap new file mode 100644 index 0000000..e783e56 --- /dev/null +++ b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__anchors_tests__anchor_both_ends.snap @@ -0,0 +1,21 @@ +--- +source: crates/plotnik-compiler/src/parser/tests/grammar/anchors_tests.rs +--- +Q = (array . (element) .) +--- +Root + Def + Id "Q" + Equals "=" + Tree + ParenOpen "(" + Id "array" + Anchor + Dot "." + Tree + ParenOpen "(" + Id "element" + ParenClose ")" + Anchor + Dot "." + ParenClose ")" diff --git a/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__anchors_tests__anchor_first_child.snap b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__anchors_tests__anchor_first_child.snap new file mode 100644 index 0000000..92c77b9 --- /dev/null +++ b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__anchors_tests__anchor_first_child.snap @@ -0,0 +1,19 @@ +--- +source: crates/plotnik-compiler/src/parser/tests/grammar/anchors_tests.rs +--- +Q = (block . (first_statement)) +--- +Root + Def + Id "Q" + Equals "=" + Tree + ParenOpen "(" + Id "block" + Anchor + Dot "." + Tree + ParenOpen "(" + Id "first_statement" + ParenClose ")" + ParenClose ")" diff --git a/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__anchors_tests__anchor_in_sequence.snap b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__anchors_tests__anchor_in_sequence.snap new file mode 100644 index 0000000..9f1b497 --- /dev/null +++ b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__anchors_tests__anchor_in_sequence.snap @@ -0,0 +1,28 @@ +--- +source: crates/plotnik-compiler/src/parser/tests/grammar/anchors_tests.rs +--- +Q = (parent {. (first) (second) .}) +--- +Root + Def + Id "Q" + Equals "=" + Tree + ParenOpen "(" + Id "parent" + Seq + BraceOpen "{" + Anchor + Dot "." + Tree + ParenOpen "(" + Id "first" + ParenClose ")" + Tree + ParenOpen "(" + Id "second" + ParenClose ")" + Anchor + Dot "." + BraceClose "}" + ParenClose ")" diff --git a/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__anchors_tests__anchor_last_child.snap b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__anchors_tests__anchor_last_child.snap new file mode 100644 index 0000000..103d983 --- /dev/null +++ b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__anchors_tests__anchor_last_child.snap @@ -0,0 +1,19 @@ +--- +source: crates/plotnik-compiler/src/parser/tests/grammar/anchors_tests.rs +--- +Q = (block (last_statement) .) +--- +Root + Def + Id "Q" + Equals "=" + Tree + ParenOpen "(" + Id "block" + Tree + ParenOpen "(" + Id "last_statement" + ParenClose ")" + Anchor + Dot "." + ParenClose ")" diff --git a/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__anchors_tests__anchor_multiple_adjacent.snap b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__anchors_tests__anchor_multiple_adjacent.snap new file mode 100644 index 0000000..2a119ca --- /dev/null +++ b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__anchors_tests__anchor_multiple_adjacent.snap @@ -0,0 +1,33 @@ +--- +source: crates/plotnik-compiler/src/parser/tests/grammar/anchors_tests.rs +--- +Q = (tuple . (a) . (b) . (c) .) +--- +Root + Def + Id "Q" + Equals "=" + Tree + ParenOpen "(" + Id "tuple" + Anchor + Dot "." + Tree + ParenOpen "(" + Id "a" + ParenClose ")" + Anchor + Dot "." + Tree + ParenOpen "(" + Id "b" + ParenClose ")" + Anchor + Dot "." + Tree + ParenOpen "(" + Id "c" + ParenClose ")" + Anchor + Dot "." + ParenClose ")" diff --git a/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__captures_tests__alternation_capture_with_type.snap b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__captures_tests__alternation_capture_with_type.snap new file mode 100644 index 0000000..db37eba --- /dev/null +++ b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__captures_tests__alternation_capture_with_type.snap @@ -0,0 +1,27 @@ +--- +source: crates/plotnik-compiler/src/parser/tests/grammar/captures_tests.rs +--- +Q = [(identifier) (number)] @value :: Value +--- +Root + Def + Id "Q" + Equals "=" + Capture + Alt + BracketOpen "[" + Branch + Tree + ParenOpen "(" + Id "identifier" + ParenClose ")" + Branch + Tree + ParenOpen "(" + Id "number" + ParenClose ")" + BracketClose "]" + CaptureToken "@value" + Type + DoubleColon "::" + Id "Value" diff --git a/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__captures_tests__capture.snap b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__captures_tests__capture.snap new file mode 100644 index 0000000..bcf2321 --- /dev/null +++ b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__captures_tests__capture.snap @@ -0,0 +1,15 @@ +--- +source: crates/plotnik-compiler/src/parser/tests/grammar/captures_tests.rs +--- +Q = (identifier) @name +--- +Root + Def + Id "Q" + Equals "=" + Capture + Tree + ParenOpen "(" + Id "identifier" + ParenClose ")" + CaptureToken "@name" diff --git a/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__captures_tests__capture_literal.snap b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__captures_tests__capture_literal.snap new file mode 100644 index 0000000..c5c689f --- /dev/null +++ b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__captures_tests__capture_literal.snap @@ -0,0 +1,15 @@ +--- +source: crates/plotnik-compiler/src/parser/tests/grammar/captures_tests.rs +--- +Q = "foo" @keyword +--- +Root + Def + Id "Q" + Equals "=" + Capture + Str + DoubleQuote "\"" + StrVal "foo" + DoubleQuote "\"" + CaptureToken "@keyword" diff --git a/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__captures_tests__capture_literal_in_tree.snap b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__captures_tests__capture_literal_in_tree.snap new file mode 100644 index 0000000..de2da6b --- /dev/null +++ b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__captures_tests__capture_literal_in_tree.snap @@ -0,0 +1,19 @@ +--- +source: crates/plotnik-compiler/src/parser/tests/grammar/captures_tests.rs +--- +Q = (binary_expression "+" @op) +--- +Root + Def + Id "Q" + Equals "=" + Tree + ParenOpen "(" + Id "binary_expression" + Capture + Str + DoubleQuote "\"" + StrVal "+" + DoubleQuote "\"" + CaptureToken "@op" + ParenClose ")" diff --git a/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__captures_tests__capture_literal_with_quantifier.snap b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__captures_tests__capture_literal_with_quantifier.snap new file mode 100644 index 0000000..ef7abc9 --- /dev/null +++ b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__captures_tests__capture_literal_with_quantifier.snap @@ -0,0 +1,17 @@ +--- +source: crates/plotnik-compiler/src/parser/tests/grammar/captures_tests.rs +--- +Q = ","* @commas +--- +Root + Def + Id "Q" + Equals "=" + Capture + Quantifier + Str + DoubleQuote "\"" + StrVal "," + DoubleQuote "\"" + Star "*" + CaptureToken "@commas" diff --git a/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__captures_tests__capture_literal_with_type.snap b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__captures_tests__capture_literal_with_type.snap new file mode 100644 index 0000000..98fa0af --- /dev/null +++ b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__captures_tests__capture_literal_with_type.snap @@ -0,0 +1,18 @@ +--- +source: crates/plotnik-compiler/src/parser/tests/grammar/captures_tests.rs +--- +Q = "return" @kw :: string +--- +Root + Def + Id "Q" + Equals "=" + Capture + Str + DoubleQuote "\"" + StrVal "return" + DoubleQuote "\"" + CaptureToken "@kw" + Type + DoubleColon "::" + Id "string" diff --git a/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__captures_tests__capture_nested.snap b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__captures_tests__capture_nested.snap new file mode 100644 index 0000000..766a61d --- /dev/null +++ b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__captures_tests__capture_nested.snap @@ -0,0 +1,22 @@ +--- +source: crates/plotnik-compiler/src/parser/tests/grammar/captures_tests.rs +--- +Q = (call function: (identifier) @func) +--- +Root + Def + Id "Q" + Equals "=" + Tree + ParenOpen "(" + Id "call" + Capture + Field + Id "function" + Colon ":" + Tree + ParenOpen "(" + Id "identifier" + ParenClose ")" + CaptureToken "@func" + ParenClose ")" diff --git a/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__captures_tests__capture_with_custom_type.snap b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__captures_tests__capture_with_custom_type.snap new file mode 100644 index 0000000..e294e3e --- /dev/null +++ b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__captures_tests__capture_with_custom_type.snap @@ -0,0 +1,18 @@ +--- +source: crates/plotnik-compiler/src/parser/tests/grammar/captures_tests.rs +--- +Q = (function_declaration) @fn :: FunctionDecl +--- +Root + Def + Id "Q" + Equals "=" + Capture + Tree + ParenOpen "(" + Id "function_declaration" + ParenClose ")" + CaptureToken "@fn" + Type + DoubleColon "::" + Id "FunctionDecl" diff --git a/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__captures_tests__capture_with_type_annotation.snap b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__captures_tests__capture_with_type_annotation.snap new file mode 100644 index 0000000..4c6110b --- /dev/null +++ b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__captures_tests__capture_with_type_annotation.snap @@ -0,0 +1,18 @@ +--- +source: crates/plotnik-compiler/src/parser/tests/grammar/captures_tests.rs +--- +Q = (identifier) @name :: string +--- +Root + Def + Id "Q" + Equals "=" + Capture + Tree + ParenOpen "(" + Id "identifier" + ParenClose ")" + CaptureToken "@name" + Type + DoubleColon "::" + Id "string" diff --git a/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__captures_tests__capture_with_type_no_spaces.snap b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__captures_tests__capture_with_type_no_spaces.snap new file mode 100644 index 0000000..0c3f811 --- /dev/null +++ b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__captures_tests__capture_with_type_no_spaces.snap @@ -0,0 +1,18 @@ +--- +source: crates/plotnik-compiler/src/parser/tests/grammar/captures_tests.rs +--- +Q = (identifier) @name::string +--- +Root + Def + Id "Q" + Equals "=" + Capture + Tree + ParenOpen "(" + Id "identifier" + ParenClose ")" + CaptureToken "@name" + Type + DoubleColon "::" + Id "string" diff --git a/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__captures_tests__capture_without_type_annotation.snap b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__captures_tests__capture_without_type_annotation.snap new file mode 100644 index 0000000..bcf2321 --- /dev/null +++ b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__captures_tests__capture_without_type_annotation.snap @@ -0,0 +1,15 @@ +--- +source: crates/plotnik-compiler/src/parser/tests/grammar/captures_tests.rs +--- +Q = (identifier) @name +--- +Root + Def + Id "Q" + Equals "=" + Capture + Tree + ParenOpen "(" + Id "identifier" + ParenClose ")" + CaptureToken "@name" diff --git a/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__captures_tests__multiple_captures.snap b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__captures_tests__multiple_captures.snap new file mode 100644 index 0000000..c0b233c --- /dev/null +++ b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__captures_tests__multiple_captures.snap @@ -0,0 +1,35 @@ +--- +source: crates/plotnik-compiler/src/parser/tests/grammar/captures_tests.rs +--- +Q = (binary + left: (_) @left + right: (_) @right) @expr +--- +Root + Def + Id "Q" + Equals "=" + Capture + Tree + ParenOpen "(" + Id "binary" + Capture + Field + Id "left" + Colon ":" + Tree + ParenOpen "(" + Underscore "_" + ParenClose ")" + CaptureToken "@left" + Capture + Field + Id "right" + Colon ":" + Tree + ParenOpen "(" + Underscore "_" + ParenClose ")" + CaptureToken "@right" + ParenClose ")" + CaptureToken "@expr" diff --git a/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__captures_tests__multiple_captures_with_types.snap b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__captures_tests__multiple_captures_with_types.snap new file mode 100644 index 0000000..3e806cd --- /dev/null +++ b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__captures_tests__multiple_captures_with_types.snap @@ -0,0 +1,44 @@ +--- +source: crates/plotnik-compiler/src/parser/tests/grammar/captures_tests.rs +--- +Q = (binary + left: (_) @left :: Node + right: (_) @right :: string) @expr :: BinaryExpr +--- +Root + Def + Id "Q" + Equals "=" + Capture + Tree + ParenOpen "(" + Id "binary" + Capture + Field + Id "left" + Colon ":" + Tree + ParenOpen "(" + Underscore "_" + ParenClose ")" + CaptureToken "@left" + Type + DoubleColon "::" + Id "Node" + Capture + Field + Id "right" + Colon ":" + Tree + ParenOpen "(" + Underscore "_" + ParenClose ")" + CaptureToken "@right" + Type + DoubleColon "::" + Id "string" + ParenClose ")" + CaptureToken "@expr" + Type + DoubleColon "::" + Id "BinaryExpr" diff --git a/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__captures_tests__nested_captures_with_types.snap b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__captures_tests__nested_captures_with_types.snap new file mode 100644 index 0000000..5961a03 --- /dev/null +++ b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__captures_tests__nested_captures_with_types.snap @@ -0,0 +1,51 @@ +--- +source: crates/plotnik-compiler/src/parser/tests/grammar/captures_tests.rs +--- +Q = (function + name: (identifier) @name :: string + body: (block + (statement)* @body_stmts :: Statement)) @func :: Function +--- +Root + Def + Id "Q" + Equals "=" + Capture + Tree + ParenOpen "(" + Id "function" + Capture + Field + Id "name" + Colon ":" + Tree + ParenOpen "(" + Id "identifier" + ParenClose ")" + CaptureToken "@name" + Type + DoubleColon "::" + Id "string" + Field + Id "body" + Colon ":" + Tree + ParenOpen "(" + Id "block" + Capture + Quantifier + Tree + ParenOpen "(" + Id "statement" + ParenClose ")" + Star "*" + CaptureToken "@body_stmts" + Type + DoubleColon "::" + Id "Statement" + ParenClose ")" + ParenClose ")" + CaptureToken "@func" + Type + DoubleColon "::" + Id "Function" diff --git a/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__captures_tests__quantified_capture_with_type.snap b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__captures_tests__quantified_capture_with_type.snap new file mode 100644 index 0000000..fed137d --- /dev/null +++ b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__captures_tests__quantified_capture_with_type.snap @@ -0,0 +1,20 @@ +--- +source: crates/plotnik-compiler/src/parser/tests/grammar/captures_tests.rs +--- +Q = (statement)+ @stmts :: Statement +--- +Root + Def + Id "Q" + Equals "=" + Capture + Quantifier + Tree + ParenOpen "(" + Id "statement" + ParenClose ")" + Plus "+" + CaptureToken "@stmts" + Type + DoubleColon "::" + Id "Statement" diff --git a/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__captures_tests__sequence_capture_with_type.snap b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__captures_tests__sequence_capture_with_type.snap new file mode 100644 index 0000000..42d804c --- /dev/null +++ b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__captures_tests__sequence_capture_with_type.snap @@ -0,0 +1,25 @@ +--- +source: crates/plotnik-compiler/src/parser/tests/grammar/captures_tests.rs +--- +Q = {(a) (b)} @seq :: MySequence +--- +Root + Def + Id "Q" + Equals "=" + Capture + Seq + BraceOpen "{" + Tree + ParenOpen "(" + Id "a" + ParenClose ")" + Tree + ParenOpen "(" + Id "b" + ParenClose ")" + BraceClose "}" + CaptureToken "@seq" + Type + DoubleColon "::" + Id "MySequence" diff --git a/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__definitions_tests__multiple_named_defs.snap b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__definitions_tests__multiple_named_defs.snap new file mode 100644 index 0000000..c08d63c --- /dev/null +++ b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__definitions_tests__multiple_named_defs.snap @@ -0,0 +1,21 @@ +--- +source: crates/plotnik-compiler/src/parser/tests/grammar/definitions_tests.rs +--- +Expr = (expression) +Stmt = (statement) +--- +Root + Def + Id "Expr" + Equals "=" + Tree + ParenOpen "(" + Id "expression" + ParenClose ")" + Def + Id "Stmt" + Equals "=" + Tree + ParenOpen "(" + Id "statement" + ParenClose ")" diff --git a/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__definitions_tests__named_def_complex_recursive.snap b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__definitions_tests__named_def_complex_recursive.snap new file mode 100644 index 0000000..40f5c94 --- /dev/null +++ b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__definitions_tests__named_def_complex_recursive.snap @@ -0,0 +1,42 @@ +--- +source: crates/plotnik-compiler/src/parser/tests/grammar/definitions_tests.rs +--- +NestedCall = (call_expression + function: [(identifier) @name (NestedCall) @inner] + arguments: (arguments)) +--- +Root + Def + Id "NestedCall" + Equals "=" + Tree + ParenOpen "(" + Id "call_expression" + Field + Id "function" + Colon ":" + Alt + BracketOpen "[" + Branch + Capture + Tree + ParenOpen "(" + Id "identifier" + ParenClose ")" + CaptureToken "@name" + Branch + Capture + Ref + ParenOpen "(" + Id "NestedCall" + ParenClose ")" + CaptureToken "@inner" + BracketClose "]" + Field + Id "arguments" + Colon ":" + Tree + ParenOpen "(" + Id "arguments" + ParenClose ")" + ParenClose ")" diff --git a/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__definitions_tests__named_def_referencing_another.snap b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__definitions_tests__named_def_referencing_another.snap new file mode 100644 index 0000000..d71b859 --- /dev/null +++ b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__definitions_tests__named_def_referencing_another.snap @@ -0,0 +1,39 @@ +--- +source: crates/plotnik-compiler/src/parser/tests/grammar/definitions_tests.rs +--- +Literal = [(number) (string)] +Expr = [(identifier) (Literal)] +--- +Root + Def + Id "Literal" + Equals "=" + Alt + BracketOpen "[" + Branch + Tree + ParenOpen "(" + Id "number" + ParenClose ")" + Branch + Tree + ParenOpen "(" + Id "string" + ParenClose ")" + BracketClose "]" + Def + Id "Expr" + Equals "=" + Alt + BracketOpen "[" + Branch + Tree + ParenOpen "(" + Id "identifier" + ParenClose ")" + Branch + Ref + ParenOpen "(" + Id "Literal" + ParenClose ")" + BracketClose "]" diff --git a/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__definitions_tests__named_def_then_expression.snap b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__definitions_tests__named_def_then_expression.snap new file mode 100644 index 0000000..87c80f6 --- /dev/null +++ b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__definitions_tests__named_def_then_expression.snap @@ -0,0 +1,12 @@ +--- +source: crates/plotnik-compiler/src/parser/tests/grammar/definitions_tests.rs +--- +Expr = [(identifier) (number)] +(program (Expr) @value) +--- +error: definition must be named + | +2 | (program (Expr) @value) + | ^^^^^^^^^^^^^^^^^^^^^^^ + | +help: give it a name like `Name = (program (Expr) @value)` diff --git a/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__definitions_tests__named_def_with_alternation.snap b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__definitions_tests__named_def_with_alternation.snap new file mode 100644 index 0000000..2e82883 --- /dev/null +++ b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__definitions_tests__named_def_with_alternation.snap @@ -0,0 +1,27 @@ +--- +source: crates/plotnik-compiler/src/parser/tests/grammar/definitions_tests.rs +--- +Value = [(identifier) (number) (string)] +--- +Root + Def + Id "Value" + Equals "=" + Alt + BracketOpen "[" + Branch + Tree + ParenOpen "(" + Id "identifier" + ParenClose ")" + Branch + Tree + ParenOpen "(" + Id "number" + ParenClose ")" + Branch + Tree + ParenOpen "(" + Id "string" + ParenClose ")" + BracketClose "]" diff --git a/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__definitions_tests__named_def_with_captures.snap b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__definitions_tests__named_def_with_captures.snap new file mode 100644 index 0000000..1f79d84 --- /dev/null +++ b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__definitions_tests__named_def_with_captures.snap @@ -0,0 +1,41 @@ +--- +source: crates/plotnik-compiler/src/parser/tests/grammar/definitions_tests.rs +--- +BinaryOp = (binary_expression + left: (_) @left + operator: _ @op + right: (_) @right) +--- +Root + Def + Id "BinaryOp" + Equals "=" + Tree + ParenOpen "(" + Id "binary_expression" + Capture + Field + Id "left" + Colon ":" + Tree + ParenOpen "(" + Underscore "_" + ParenClose ")" + CaptureToken "@left" + Capture + Field + Id "operator" + Colon ":" + Wildcard + Underscore "_" + CaptureToken "@op" + Capture + Field + Id "right" + Colon ":" + Tree + ParenOpen "(" + Underscore "_" + ParenClose ")" + CaptureToken "@right" + ParenClose ")" diff --git a/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__definitions_tests__named_def_with_quantifier.snap b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__definitions_tests__named_def_with_quantifier.snap new file mode 100644 index 0000000..0cdc13b --- /dev/null +++ b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__definitions_tests__named_def_with_quantifier.snap @@ -0,0 +1,15 @@ +--- +source: crates/plotnik-compiler/src/parser/tests/grammar/definitions_tests.rs +--- +Statements = (statement)+ +--- +Root + Def + Id "Statements" + Equals "=" + Quantifier + Tree + ParenOpen "(" + Id "statement" + ParenClose ")" + Plus "+" diff --git a/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__definitions_tests__named_def_with_sequence.snap b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__definitions_tests__named_def_with_sequence.snap new file mode 100644 index 0000000..73b8971 --- /dev/null +++ b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__definitions_tests__named_def_with_sequence.snap @@ -0,0 +1,20 @@ +--- +source: crates/plotnik-compiler/src/parser/tests/grammar/definitions_tests.rs +--- +Pair = {(identifier) (expression)} +--- +Root + Def + Id "Pair" + Equals "=" + Seq + BraceOpen "{" + Tree + ParenOpen "(" + Id "identifier" + ParenClose ")" + Tree + ParenOpen "(" + Id "expression" + ParenClose ")" + BraceClose "}" diff --git a/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__definitions_tests__named_def_with_type_annotation.snap b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__definitions_tests__named_def_with_type_annotation.snap new file mode 100644 index 0000000..d4857ba --- /dev/null +++ b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__definitions_tests__named_def_with_type_annotation.snap @@ -0,0 +1,36 @@ +--- +source: crates/plotnik-compiler/src/parser/tests/grammar/definitions_tests.rs +--- +Func = (function_declaration + name: (identifier) @name :: string + body: (_) @body) +--- +Root + Def + Id "Func" + Equals "=" + Tree + ParenOpen "(" + Id "function_declaration" + Capture + Field + Id "name" + Colon ":" + Tree + ParenOpen "(" + Id "identifier" + ParenClose ")" + CaptureToken "@name" + Type + DoubleColon "::" + Id "string" + Capture + Field + Id "body" + Colon ":" + Tree + ParenOpen "(" + Underscore "_" + ParenClose ")" + CaptureToken "@body" + ParenClose ")" diff --git a/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__definitions_tests__simple_named_def.snap b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__definitions_tests__simple_named_def.snap new file mode 100644 index 0000000..9d1229d --- /dev/null +++ b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__definitions_tests__simple_named_def.snap @@ -0,0 +1,13 @@ +--- +source: crates/plotnik-compiler/src/parser/tests/grammar/definitions_tests.rs +--- +Expr = (identifier) +--- +Root + Def + Id "Expr" + Equals "=" + Tree + ParenOpen "(" + Id "identifier" + ParenClose ")" diff --git a/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__definitions_tests__unnamed_def_allowed_as_last.snap b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__definitions_tests__unnamed_def_allowed_as_last.snap new file mode 100644 index 0000000..8345197 --- /dev/null +++ b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__definitions_tests__unnamed_def_allowed_as_last.snap @@ -0,0 +1,27 @@ +--- +source: crates/plotnik-compiler/src/parser/tests/grammar/definitions_tests.rs +--- +Expr = (identifier) +Q = (program (Expr) @value) +--- +Root + Def + Id "Expr" + Equals "=" + Tree + ParenOpen "(" + Id "identifier" + ParenClose ")" + Def + Id "Q" + Equals "=" + Tree + ParenOpen "(" + Id "program" + Capture + Ref + ParenOpen "(" + Id "Expr" + ParenClose ")" + CaptureToken "@value" + ParenClose ")" diff --git a/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__fields_tests__field_expression.snap b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__fields_tests__field_expression.snap new file mode 100644 index 0000000..5c781a9 --- /dev/null +++ b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__fields_tests__field_expression.snap @@ -0,0 +1,20 @@ +--- +source: crates/plotnik-compiler/src/parser/tests/grammar/fields_tests.rs +--- +Q = (call function: (identifier)) +--- +Root + Def + Id "Q" + Equals "=" + Tree + ParenOpen "(" + Id "call" + Field + Id "function" + Colon ":" + Tree + ParenOpen "(" + Id "identifier" + ParenClose ")" + ParenClose ")" diff --git a/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__fields_tests__fields_and_quantifiers.snap b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__fields_tests__fields_and_quantifiers.snap new file mode 100644 index 0000000..dd6d2c5 --- /dev/null +++ b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__fields_tests__fields_and_quantifiers.snap @@ -0,0 +1,73 @@ +--- +source: crates/plotnik-compiler/src/parser/tests/grammar/fields_tests.rs +--- +Q = (node + foo: (foo)? + foo: (foo)?? + bar: (bar)* + bar: (bar)*? + baz: (baz)+? + baz: (baz)+?) +--- +Root + Def + Id "Q" + Equals "=" + Tree + ParenOpen "(" + Id "node" + Quantifier + Field + Id "foo" + Colon ":" + Tree + ParenOpen "(" + Id "foo" + ParenClose ")" + Question "?" + Quantifier + Field + Id "foo" + Colon ":" + Tree + ParenOpen "(" + Id "foo" + ParenClose ")" + QuestionQuestion "??" + Quantifier + Field + Id "bar" + Colon ":" + Tree + ParenOpen "(" + Id "bar" + ParenClose ")" + Star "*" + Quantifier + Field + Id "bar" + Colon ":" + Tree + ParenOpen "(" + Id "bar" + ParenClose ")" + StarQuestion "*?" + Quantifier + Field + Id "baz" + Colon ":" + Tree + ParenOpen "(" + Id "baz" + ParenClose ")" + PlusQuestion "+?" + Quantifier + Field + Id "baz" + Colon ":" + Tree + ParenOpen "(" + Id "baz" + ParenClose ")" + PlusQuestion "+?" + ParenClose ")" diff --git a/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__fields_tests__fields_with_quantifiers_and_captures.snap b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__fields_tests__fields_with_quantifiers_and_captures.snap new file mode 100644 index 0000000..e19b014 --- /dev/null +++ b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__fields_tests__fields_with_quantifiers_and_captures.snap @@ -0,0 +1,24 @@ +--- +source: crates/plotnik-compiler/src/parser/tests/grammar/fields_tests.rs +--- +Q = (node foo: (bar)* @baz) +--- +Root + Def + Id "Q" + Equals "=" + Tree + ParenOpen "(" + Id "node" + Capture + Quantifier + Field + Id "foo" + Colon ":" + Tree + ParenOpen "(" + Id "bar" + ParenClose ")" + Star "*" + CaptureToken "@baz" + ParenClose ")" diff --git a/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__fields_tests__mixed_children_and_fields.snap b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__fields_tests__mixed_children_and_fields.snap new file mode 100644 index 0000000..1bccf77 --- /dev/null +++ b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__fields_tests__mixed_children_and_fields.snap @@ -0,0 +1,34 @@ +--- +source: crates/plotnik-compiler/src/parser/tests/grammar/fields_tests.rs +--- +Q = (if + condition: (expr) + (then_block) + else: (else_block)) +--- +Root + Def + Id "Q" + Equals "=" + Tree + ParenOpen "(" + Id "if" + Field + Id "condition" + Colon ":" + Tree + ParenOpen "(" + Id "expr" + ParenClose ")" + Tree + ParenOpen "(" + Id "then_block" + ParenClose ")" + Field + Id "else" + Colon ":" + Tree + ParenOpen "(" + Id "else_block" + ParenClose ")" + ParenClose ")" diff --git a/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__fields_tests__multiple_fields.snap b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__fields_tests__multiple_fields.snap new file mode 100644 index 0000000..bbd2f4e --- /dev/null +++ b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__fields_tests__multiple_fields.snap @@ -0,0 +1,29 @@ +--- +source: crates/plotnik-compiler/src/parser/tests/grammar/fields_tests.rs +--- +Q = (assignment + left: (identifier) + right: (expression)) +--- +Root + Def + Id "Q" + Equals "=" + Tree + ParenOpen "(" + Id "assignment" + Field + Id "left" + Colon ":" + Tree + ParenOpen "(" + Id "identifier" + ParenClose ")" + Field + Id "right" + Colon ":" + Tree + ParenOpen "(" + Id "expression" + ParenClose ")" + ParenClose ")" diff --git a/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__fields_tests__negated_and_regular_fields.snap b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__fields_tests__negated_and_regular_fields.snap new file mode 100644 index 0000000..f07d2a3 --- /dev/null +++ b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__fields_tests__negated_and_regular_fields.snap @@ -0,0 +1,25 @@ +--- +source: crates/plotnik-compiler/src/parser/tests/grammar/fields_tests.rs +--- +Q = (function + -async + name: (identifier)) +--- +Root + Def + Id "Q" + Equals "=" + Tree + ParenOpen "(" + Id "function" + NegatedField + Minus "-" + Id "async" + Field + Id "name" + Colon ":" + Tree + ParenOpen "(" + Id "identifier" + ParenClose ")" + ParenClose ")" diff --git a/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__fields_tests__negated_field.snap b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__fields_tests__negated_field.snap new file mode 100644 index 0000000..c7458ba --- /dev/null +++ b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__fields_tests__negated_field.snap @@ -0,0 +1,16 @@ +--- +source: crates/plotnik-compiler/src/parser/tests/grammar/fields_tests.rs +--- +Q = (function -async) +--- +Root + Def + Id "Q" + Equals "=" + Tree + ParenOpen "(" + Id "function" + NegatedField + Minus "-" + Id "async" + ParenClose ")" diff --git a/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__nodes_tests__anonymous_node.snap b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__nodes_tests__anonymous_node.snap new file mode 100644 index 0000000..44c7f61 --- /dev/null +++ b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__nodes_tests__anonymous_node.snap @@ -0,0 +1,13 @@ +--- +source: crates/plotnik-compiler/src/parser/tests/grammar/nodes_tests.rs +--- +Q = "if" +--- +Root + Def + Id "Q" + Equals "=" + Str + DoubleQuote "\"" + StrVal "if" + DoubleQuote "\"" diff --git a/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__nodes_tests__anonymous_node_operator.snap b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__nodes_tests__anonymous_node_operator.snap new file mode 100644 index 0000000..7446ce1 --- /dev/null +++ b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__nodes_tests__anonymous_node_operator.snap @@ -0,0 +1,13 @@ +--- +source: crates/plotnik-compiler/src/parser/tests/grammar/nodes_tests.rs +--- +Q = "+=" +--- +Root + Def + Id "Q" + Equals "=" + Str + DoubleQuote "\"" + StrVal "+=" + DoubleQuote "\"" diff --git a/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__nodes_tests__deeply_nested.snap b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__nodes_tests__deeply_nested.snap new file mode 100644 index 0000000..14851b2 --- /dev/null +++ b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__nodes_tests__deeply_nested.snap @@ -0,0 +1,28 @@ +--- +source: crates/plotnik-compiler/src/parser/tests/grammar/nodes_tests.rs +--- +Q = (a + (b + (c + (d)))) +--- +Root + Def + Id "Q" + Equals "=" + Tree + ParenOpen "(" + Id "a" + Tree + ParenOpen "(" + Id "b" + Tree + ParenOpen "(" + Id "c" + Tree + ParenOpen "(" + Id "d" + ParenClose ")" + ParenClose ")" + ParenClose ")" + ParenClose ")" diff --git a/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__nodes_tests__empty_input.snap b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__nodes_tests__empty_input.snap new file mode 100644 index 0000000..f6e5fa4 --- /dev/null +++ b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__nodes_tests__empty_input.snap @@ -0,0 +1,6 @@ +--- +source: crates/plotnik-compiler/src/parser/tests/grammar/nodes_tests.rs +--- + +--- +Root diff --git a/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__nodes_tests__nested_node.snap b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__nodes_tests__nested_node.snap new file mode 100644 index 0000000..1e9d8b6 --- /dev/null +++ b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__nodes_tests__nested_node.snap @@ -0,0 +1,20 @@ +--- +source: crates/plotnik-compiler/src/parser/tests/grammar/nodes_tests.rs +--- +Q = (function_definition name: (identifier)) +--- +Root + Def + Id "Q" + Equals "=" + Tree + ParenOpen "(" + Id "function_definition" + Field + Id "name" + Colon ":" + Tree + ParenOpen "(" + Id "identifier" + ParenClose ")" + ParenClose ")" diff --git a/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__nodes_tests__no_supertype_plain_node.snap b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__nodes_tests__no_supertype_plain_node.snap new file mode 100644 index 0000000..a1514f0 --- /dev/null +++ b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__nodes_tests__no_supertype_plain_node.snap @@ -0,0 +1,13 @@ +--- +source: crates/plotnik-compiler/src/parser/tests/grammar/nodes_tests.rs +--- +Q = (identifier) +--- +Root + Def + Id "Q" + Equals "=" + Tree + ParenOpen "(" + Id "identifier" + ParenClose ")" diff --git a/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__nodes_tests__sibling_children.snap b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__nodes_tests__sibling_children.snap new file mode 100644 index 0000000..0c6282f --- /dev/null +++ b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__nodes_tests__sibling_children.snap @@ -0,0 +1,28 @@ +--- +source: crates/plotnik-compiler/src/parser/tests/grammar/nodes_tests.rs +--- +Q = (block + (statement) + (statement) + (statement)) +--- +Root + Def + Id "Q" + Equals "=" + Tree + ParenOpen "(" + Id "block" + Tree + ParenOpen "(" + Id "statement" + ParenClose ")" + Tree + ParenOpen "(" + Id "statement" + ParenClose ")" + Tree + ParenOpen "(" + Id "statement" + ParenClose ")" + ParenClose ")" diff --git a/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__nodes_tests__simple_named_node.snap b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__nodes_tests__simple_named_node.snap new file mode 100644 index 0000000..a1514f0 --- /dev/null +++ b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__nodes_tests__simple_named_node.snap @@ -0,0 +1,13 @@ +--- +source: crates/plotnik-compiler/src/parser/tests/grammar/nodes_tests.rs +--- +Q = (identifier) +--- +Root + Def + Id "Q" + Equals "=" + Tree + ParenOpen "(" + Id "identifier" + ParenClose ")" diff --git a/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__nodes_tests__supertype_basic.snap b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__nodes_tests__supertype_basic.snap new file mode 100644 index 0000000..9df8244 --- /dev/null +++ b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__nodes_tests__supertype_basic.snap @@ -0,0 +1,15 @@ +--- +source: crates/plotnik-compiler/src/parser/tests/grammar/nodes_tests.rs +--- +Q = (expression/binary_expression) +--- +Root + Def + Id "Q" + Equals "=" + Tree + ParenOpen "(" + Id "expression" + Slash "/" + Id "binary_expression" + ParenClose ")" diff --git a/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__nodes_tests__supertype_in_alternation.snap b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__nodes_tests__supertype_in_alternation.snap new file mode 100644 index 0000000..fc363bf --- /dev/null +++ b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__nodes_tests__supertype_in_alternation.snap @@ -0,0 +1,26 @@ +--- +source: crates/plotnik-compiler/src/parser/tests/grammar/nodes_tests.rs +--- +Q = [(expression/identifier) (expression/number)] +--- +Root + Def + Id "Q" + Equals "=" + Alt + BracketOpen "[" + Branch + Tree + ParenOpen "(" + Id "expression" + Slash "/" + Id "identifier" + ParenClose ")" + Branch + Tree + ParenOpen "(" + Id "expression" + Slash "/" + Id "number" + ParenClose ")" + BracketClose "]" diff --git a/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__nodes_tests__supertype_nested.snap b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__nodes_tests__supertype_nested.snap new file mode 100644 index 0000000..a2b0c7c --- /dev/null +++ b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__nodes_tests__supertype_nested.snap @@ -0,0 +1,22 @@ +--- +source: crates/plotnik-compiler/src/parser/tests/grammar/nodes_tests.rs +--- +Q = (statement/expression_statement + (expression/call_expression)) +--- +Root + Def + Id "Q" + Equals "=" + Tree + ParenOpen "(" + Id "statement" + Slash "/" + Id "expression_statement" + Tree + ParenOpen "(" + Id "expression" + Slash "/" + Id "call_expression" + ParenClose ")" + ParenClose ")" diff --git a/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__nodes_tests__supertype_with_capture.snap b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__nodes_tests__supertype_with_capture.snap new file mode 100644 index 0000000..6f07ce4 --- /dev/null +++ b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__nodes_tests__supertype_with_capture.snap @@ -0,0 +1,17 @@ +--- +source: crates/plotnik-compiler/src/parser/tests/grammar/nodes_tests.rs +--- +Q = (expression/binary_expression) @expr +--- +Root + Def + Id "Q" + Equals "=" + Capture + Tree + ParenOpen "(" + Id "expression" + Slash "/" + Id "binary_expression" + ParenClose ")" + CaptureToken "@expr" diff --git a/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__nodes_tests__supertype_with_children.snap b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__nodes_tests__supertype_with_children.snap new file mode 100644 index 0000000..c1758cf --- /dev/null +++ b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__nodes_tests__supertype_with_children.snap @@ -0,0 +1,35 @@ +--- +source: crates/plotnik-compiler/src/parser/tests/grammar/nodes_tests.rs +--- +Q = (expression/binary_expression + left: (_) @left + right: (_) @right) +--- +Root + Def + Id "Q" + Equals "=" + Tree + ParenOpen "(" + Id "expression" + Slash "/" + Id "binary_expression" + Capture + Field + Id "left" + Colon ":" + Tree + ParenOpen "(" + Underscore "_" + ParenClose ")" + CaptureToken "@left" + Capture + Field + Id "right" + Colon ":" + Tree + ParenOpen "(" + Underscore "_" + ParenClose ")" + CaptureToken "@right" + ParenClose ")" diff --git a/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__nodes_tests__supertype_with_string_subtype.snap b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__nodes_tests__supertype_with_string_subtype.snap new file mode 100644 index 0000000..9f9ea30 --- /dev/null +++ b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__nodes_tests__supertype_with_string_subtype.snap @@ -0,0 +1,17 @@ +--- +source: crates/plotnik-compiler/src/parser/tests/grammar/nodes_tests.rs +--- +Q = (expression/"()") +--- +Root + Def + Id "Q" + Equals "=" + Tree + ParenOpen "(" + Id "expression" + Slash "/" + DoubleQuote "\"" + StrVal "()" + DoubleQuote "\"" + ParenClose ")" diff --git a/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__nodes_tests__wildcard.snap b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__nodes_tests__wildcard.snap new file mode 100644 index 0000000..4596879 --- /dev/null +++ b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__nodes_tests__wildcard.snap @@ -0,0 +1,13 @@ +--- +source: crates/plotnik-compiler/src/parser/tests/grammar/nodes_tests.rs +--- +Q = (_) +--- +Root + Def + Id "Q" + Equals "=" + Tree + ParenOpen "(" + Underscore "_" + ParenClose ")" diff --git a/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__quantifiers_tests__quantifier_inside_node.snap b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__quantifiers_tests__quantifier_inside_node.snap new file mode 100644 index 0000000..47408e5 --- /dev/null +++ b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__quantifiers_tests__quantifier_inside_node.snap @@ -0,0 +1,20 @@ +--- +source: crates/plotnik-compiler/src/parser/tests/grammar/quantifiers_tests.rs +--- +Q = (block + (statement)*) +--- +Root + Def + Id "Q" + Equals "=" + Tree + ParenOpen "(" + Id "block" + Quantifier + Tree + ParenOpen "(" + Id "statement" + ParenClose ")" + Star "*" + ParenClose ")" diff --git a/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__quantifiers_tests__quantifier_optional.snap b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__quantifiers_tests__quantifier_optional.snap new file mode 100644 index 0000000..6c7dcef --- /dev/null +++ b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__quantifiers_tests__quantifier_optional.snap @@ -0,0 +1,15 @@ +--- +source: crates/plotnik-compiler/src/parser/tests/grammar/quantifiers_tests.rs +--- +Q = (statement)? +--- +Root + Def + Id "Q" + Equals "=" + Quantifier + Tree + ParenOpen "(" + Id "statement" + ParenClose ")" + Question "?" diff --git a/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__quantifiers_tests__quantifier_plus.snap b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__quantifiers_tests__quantifier_plus.snap new file mode 100644 index 0000000..d5f4761 --- /dev/null +++ b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__quantifiers_tests__quantifier_plus.snap @@ -0,0 +1,15 @@ +--- +source: crates/plotnik-compiler/src/parser/tests/grammar/quantifiers_tests.rs +--- +Q = (statement)+ +--- +Root + Def + Id "Q" + Equals "=" + Quantifier + Tree + ParenOpen "(" + Id "statement" + ParenClose ")" + Plus "+" diff --git a/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__quantifiers_tests__quantifier_star.snap b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__quantifiers_tests__quantifier_star.snap new file mode 100644 index 0000000..88c3d12 --- /dev/null +++ b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__quantifiers_tests__quantifier_star.snap @@ -0,0 +1,15 @@ +--- +source: crates/plotnik-compiler/src/parser/tests/grammar/quantifiers_tests.rs +--- +Q = (statement)* +--- +Root + Def + Id "Q" + Equals "=" + Quantifier + Tree + ParenOpen "(" + Id "statement" + ParenClose ")" + Star "*" diff --git a/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__quantifiers_tests__quantifier_with_capture.snap b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__quantifiers_tests__quantifier_with_capture.snap new file mode 100644 index 0000000..a56f4e9 --- /dev/null +++ b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__quantifiers_tests__quantifier_with_capture.snap @@ -0,0 +1,17 @@ +--- +source: crates/plotnik-compiler/src/parser/tests/grammar/quantifiers_tests.rs +--- +Q = (statement)* @statements +--- +Root + Def + Id "Q" + Equals "=" + Capture + Quantifier + Tree + ParenOpen "(" + Id "statement" + ParenClose ")" + Star "*" + CaptureToken "@statements" diff --git a/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__sequences_tests__empty_sequence.snap b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__sequences_tests__empty_sequence.snap new file mode 100644 index 0000000..e7d66f1 --- /dev/null +++ b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__sequences_tests__empty_sequence.snap @@ -0,0 +1,11 @@ +--- +source: crates/plotnik-compiler/src/parser/tests/grammar/sequences_tests.rs +--- +Q = {} +--- +error: empty `{}` is not allowed + | +1 | Q = {} + | ^^ + | +help: sequences must contain at least one expression diff --git a/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__sequences_tests__named_node_with_child_remains_tree.snap b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__sequences_tests__named_node_with_child_remains_tree.snap new file mode 100644 index 0000000..d2c8511 --- /dev/null +++ b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__sequences_tests__named_node_with_child_remains_tree.snap @@ -0,0 +1,17 @@ +--- +source: crates/plotnik-compiler/src/parser/tests/grammar/sequences_tests.rs +--- +Q = (foo (bar)) +--- +Root + Def + Id "Q" + Equals "=" + Tree + ParenOpen "(" + Id "foo" + Tree + ParenOpen "(" + Id "bar" + ParenClose ")" + ParenClose ")" diff --git a/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__sequences_tests__nested_sequences.snap b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__sequences_tests__nested_sequences.snap new file mode 100644 index 0000000..d4a3275 --- /dev/null +++ b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__sequences_tests__nested_sequences.snap @@ -0,0 +1,26 @@ +--- +source: crates/plotnik-compiler/src/parser/tests/grammar/sequences_tests.rs +--- +Q = {{(a)} {(b)}} +--- +Root + Def + Id "Q" + Equals "=" + Seq + BraceOpen "{" + Seq + BraceOpen "{" + Tree + ParenOpen "(" + Id "a" + ParenClose ")" + BraceClose "}" + Seq + BraceOpen "{" + Tree + ParenOpen "(" + Id "b" + ParenClose ")" + BraceClose "}" + BraceClose "}" diff --git a/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__sequences_tests__sequence_in_named_node.snap b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__sequences_tests__sequence_in_named_node.snap new file mode 100644 index 0000000..0e6297a --- /dev/null +++ b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__sequences_tests__sequence_in_named_node.snap @@ -0,0 +1,24 @@ +--- +source: crates/plotnik-compiler/src/parser/tests/grammar/sequences_tests.rs +--- +Q = (block {(statement) (statement)}) +--- +Root + Def + Id "Q" + Equals "=" + Tree + ParenOpen "(" + Id "block" + Seq + BraceOpen "{" + Tree + ParenOpen "(" + Id "statement" + ParenClose ")" + Tree + ParenOpen "(" + Id "statement" + ParenClose ")" + BraceClose "}" + ParenClose ")" diff --git a/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__sequences_tests__sequence_single_element.snap b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__sequences_tests__sequence_single_element.snap new file mode 100644 index 0000000..2f25873 --- /dev/null +++ b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__sequences_tests__sequence_single_element.snap @@ -0,0 +1,16 @@ +--- +source: crates/plotnik-compiler/src/parser/tests/grammar/sequences_tests.rs +--- +Q = {(identifier)} +--- +Root + Def + Id "Q" + Equals "=" + Seq + BraceOpen "{" + Tree + ParenOpen "(" + Id "identifier" + ParenClose ")" + BraceClose "}" diff --git a/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__sequences_tests__sequence_with_alternation.snap b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__sequences_tests__sequence_with_alternation.snap new file mode 100644 index 0000000..d610cdc --- /dev/null +++ b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__sequences_tests__sequence_with_alternation.snap @@ -0,0 +1,29 @@ +--- +source: crates/plotnik-compiler/src/parser/tests/grammar/sequences_tests.rs +--- +Q = {[(a) (b)] (c)} +--- +Root + Def + Id "Q" + Equals "=" + Seq + BraceOpen "{" + Alt + BracketOpen "[" + Branch + Tree + ParenOpen "(" + Id "a" + ParenClose ")" + Branch + Tree + ParenOpen "(" + Id "b" + ParenClose ")" + BracketClose "]" + Tree + ParenOpen "(" + Id "c" + ParenClose ")" + BraceClose "}" diff --git a/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__sequences_tests__sequence_with_anchor.snap b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__sequences_tests__sequence_with_anchor.snap new file mode 100644 index 0000000..852b875 --- /dev/null +++ b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__sequences_tests__sequence_with_anchor.snap @@ -0,0 +1,28 @@ +--- +source: crates/plotnik-compiler/src/parser/tests/grammar/sequences_tests.rs +--- +Q = (parent {. (first) (second) .}) +--- +Root + Def + Id "Q" + Equals "=" + Tree + ParenOpen "(" + Id "parent" + Seq + BraceOpen "{" + Anchor + Dot "." + Tree + ParenOpen "(" + Id "first" + ParenClose ")" + Tree + ParenOpen "(" + Id "second" + ParenClose ")" + Anchor + Dot "." + BraceClose "}" + ParenClose ")" diff --git a/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__sequences_tests__sequence_with_captures.snap b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__sequences_tests__sequence_with_captures.snap new file mode 100644 index 0000000..fb76d13 --- /dev/null +++ b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__sequences_tests__sequence_with_captures.snap @@ -0,0 +1,26 @@ +--- +source: crates/plotnik-compiler/src/parser/tests/grammar/sequences_tests.rs +--- +Q = {(comment)* @comments (function) @fn} +--- +Root + Def + Id "Q" + Equals "=" + Seq + BraceOpen "{" + Capture + Quantifier + Tree + ParenOpen "(" + Id "comment" + ParenClose ")" + Star "*" + CaptureToken "@comments" + Capture + Tree + ParenOpen "(" + Id "function" + ParenClose ")" + CaptureToken "@fn" + BraceClose "}" diff --git a/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__sequences_tests__simple_sequence.snap b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__sequences_tests__simple_sequence.snap new file mode 100644 index 0000000..669843a --- /dev/null +++ b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__sequences_tests__simple_sequence.snap @@ -0,0 +1,20 @@ +--- +source: crates/plotnik-compiler/src/parser/tests/grammar/sequences_tests.rs +--- +Q = {(a) (b)} +--- +Root + Def + Id "Q" + Equals "=" + Seq + BraceOpen "{" + Tree + ParenOpen "(" + Id "a" + ParenClose ")" + Tree + ParenOpen "(" + Id "b" + ParenClose ")" + BraceClose "}" diff --git a/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__special_tests__error_in_alternation.snap b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__special_tests__error_in_alternation.snap new file mode 100644 index 0000000..3c7455b --- /dev/null +++ b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__special_tests__error_in_alternation.snap @@ -0,0 +1,22 @@ +--- +source: crates/plotnik-compiler/src/parser/tests/grammar/special_tests.rs +--- +Q = [(ERROR) (identifier)] +--- +Root + Def + Id "Q" + Equals "=" + Alt + BracketOpen "[" + Branch + Tree + ParenOpen "(" + KwError "ERROR" + ParenClose ")" + Branch + Tree + ParenOpen "(" + Id "identifier" + ParenClose ")" + BracketClose "]" diff --git a/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__special_tests__error_node.snap b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__special_tests__error_node.snap new file mode 100644 index 0000000..b54e314 --- /dev/null +++ b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__special_tests__error_node.snap @@ -0,0 +1,13 @@ +--- +source: crates/plotnik-compiler/src/parser/tests/grammar/special_tests.rs +--- +Q = (ERROR) +--- +Root + Def + Id "Q" + Equals "=" + Tree + ParenOpen "(" + KwError "ERROR" + ParenClose ")" diff --git a/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__special_tests__error_node_with_capture.snap b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__special_tests__error_node_with_capture.snap new file mode 100644 index 0000000..d43eaa1 --- /dev/null +++ b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__special_tests__error_node_with_capture.snap @@ -0,0 +1,15 @@ +--- +source: crates/plotnik-compiler/src/parser/tests/grammar/special_tests.rs +--- +Q = (ERROR) @err +--- +Root + Def + Id "Q" + Equals "=" + Capture + Tree + ParenOpen "(" + KwError "ERROR" + ParenClose ")" + CaptureToken "@err" diff --git a/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__special_tests__error_with_quantifier.snap b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__special_tests__error_with_quantifier.snap new file mode 100644 index 0000000..3f22358 --- /dev/null +++ b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__special_tests__error_with_quantifier.snap @@ -0,0 +1,15 @@ +--- +source: crates/plotnik-compiler/src/parser/tests/grammar/special_tests.rs +--- +Q = (ERROR)* +--- +Root + Def + Id "Q" + Equals "=" + Quantifier + Tree + ParenOpen "(" + KwError "ERROR" + ParenClose ")" + Star "*" diff --git a/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__special_tests__missing_in_sequence.snap b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__special_tests__missing_in_sequence.snap new file mode 100644 index 0000000..7278bbc --- /dev/null +++ b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__special_tests__missing_in_sequence.snap @@ -0,0 +1,23 @@ +--- +source: crates/plotnik-compiler/src/parser/tests/grammar/special_tests.rs +--- +Q = {(MISSING ";") (identifier)} +--- +Root + Def + Id "Q" + Equals "=" + Seq + BraceOpen "{" + Tree + ParenOpen "(" + KwMissing "MISSING" + DoubleQuote "\"" + StrVal ";" + DoubleQuote "\"" + ParenClose ")" + Tree + ParenOpen "(" + Id "identifier" + ParenClose ")" + BraceClose "}" diff --git a/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__special_tests__missing_node_bare.snap b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__special_tests__missing_node_bare.snap new file mode 100644 index 0000000..c7074a4 --- /dev/null +++ b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__special_tests__missing_node_bare.snap @@ -0,0 +1,13 @@ +--- +source: crates/plotnik-compiler/src/parser/tests/grammar/special_tests.rs +--- +Q = (MISSING) +--- +Root + Def + Id "Q" + Equals "=" + Tree + ParenOpen "(" + KwMissing "MISSING" + ParenClose ")" diff --git a/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__special_tests__missing_node_with_capture.snap b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__special_tests__missing_node_with_capture.snap new file mode 100644 index 0000000..c647c2c --- /dev/null +++ b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__special_tests__missing_node_with_capture.snap @@ -0,0 +1,18 @@ +--- +source: crates/plotnik-compiler/src/parser/tests/grammar/special_tests.rs +--- +Q = (MISSING ";") @missing_semi +--- +Root + Def + Id "Q" + Equals "=" + Capture + Tree + ParenOpen "(" + KwMissing "MISSING" + DoubleQuote "\"" + StrVal ";" + DoubleQuote "\"" + ParenClose ")" + CaptureToken "@missing_semi" diff --git a/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__special_tests__missing_node_with_string.snap b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__special_tests__missing_node_with_string.snap new file mode 100644 index 0000000..574985c --- /dev/null +++ b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__special_tests__missing_node_with_string.snap @@ -0,0 +1,16 @@ +--- +source: crates/plotnik-compiler/src/parser/tests/grammar/special_tests.rs +--- +Q = (MISSING ";") +--- +Root + Def + Id "Q" + Equals "=" + Tree + ParenOpen "(" + KwMissing "MISSING" + DoubleQuote "\"" + StrVal ";" + DoubleQuote "\"" + ParenClose ")" diff --git a/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__special_tests__missing_node_with_type.snap b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__special_tests__missing_node_with_type.snap new file mode 100644 index 0000000..dd8ca66 --- /dev/null +++ b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__special_tests__missing_node_with_type.snap @@ -0,0 +1,14 @@ +--- +source: crates/plotnik-compiler/src/parser/tests/grammar/special_tests.rs +--- +Q = (MISSING identifier) +--- +Root + Def + Id "Q" + Equals "=" + Tree + ParenOpen "(" + KwMissing "MISSING" + Id "identifier" + ParenClose ")" diff --git a/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__special_tests__missing_with_quantifier.snap b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__special_tests__missing_with_quantifier.snap new file mode 100644 index 0000000..9871f7f --- /dev/null +++ b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__special_tests__missing_with_quantifier.snap @@ -0,0 +1,16 @@ +--- +source: crates/plotnik-compiler/src/parser/tests/grammar/special_tests.rs +--- +Q = (MISSING identifier)? +--- +Root + Def + Id "Q" + Equals "=" + Quantifier + Tree + ParenOpen "(" + KwMissing "MISSING" + Id "identifier" + ParenClose ")" + Question "?" diff --git a/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__special_tests__special_node_nested.snap b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__special_tests__special_node_nested.snap new file mode 100644 index 0000000..a8e7ca3 --- /dev/null +++ b/crates/plotnik-compiler/src/parser/tests/grammar/snapshots/plotnik_compiler__parser__tests__grammar__special_tests__special_node_nested.snap @@ -0,0 +1,25 @@ +--- +source: crates/plotnik-compiler/src/parser/tests/grammar/special_tests.rs +--- +Q = (function_definition + body: (block (ERROR))) +--- +Root + Def + Id "Q" + Equals "=" + Tree + ParenOpen "(" + Id "function_definition" + Field + Id "body" + Colon ":" + Tree + ParenOpen "(" + Id "block" + Tree + ParenOpen "(" + KwError "ERROR" + ParenClose ")" + ParenClose ")" + ParenClose ")" diff --git a/crates/plotnik-compiler/src/parser/tests/grammar/special_tests.rs b/crates/plotnik-compiler/src/parser/tests/grammar/special_tests.rs index 0fb1039..b44dced 100644 --- a/crates/plotnik-compiler/src/parser/tests/grammar/special_tests.rs +++ b/crates/plotnik-compiler/src/parser/tests/grammar/special_tests.rs @@ -1,269 +1,81 @@ -use crate::Query; -use indoc::indoc; +//! Special node (ERROR, MISSING) parsing tests. + +use crate::shot_cst; #[test] fn error_node() { - let input = indoc! {r#" - Q = (ERROR) - "#}; - - let res = Query::expect_valid_cst(input); - - insta::assert_snapshot!(res, @r#" - Root - Def - Id "Q" - Equals "=" - Tree - ParenOpen "(" - KwError "ERROR" - ParenClose ")" + shot_cst!(r#" + Q = (ERROR) "#); } #[test] fn error_node_with_capture() { - let input = indoc! {r#" - Q = (ERROR) @err - "#}; - - let res = Query::expect_valid_cst(input); - - insta::assert_snapshot!(res, @r#" - Root - Def - Id "Q" - Equals "=" - Capture - Tree - ParenOpen "(" - KwError "ERROR" - ParenClose ")" - CaptureToken "@err" + shot_cst!(r#" + Q = (ERROR) @err "#); } #[test] fn missing_node_bare() { - let input = indoc! {r#" - Q = (MISSING) - "#}; - - let res = Query::expect_valid_cst(input); - - insta::assert_snapshot!(res, @r#" - Root - Def - Id "Q" - Equals "=" - Tree - ParenOpen "(" - KwMissing "MISSING" - ParenClose ")" + shot_cst!(r#" + Q = (MISSING) "#); } #[test] fn missing_node_with_type() { - let input = indoc! {r#" - Q = (MISSING identifier) - "#}; - - let res = Query::expect_valid_cst(input); - - insta::assert_snapshot!(res, @r#" - Root - Def - Id "Q" - Equals "=" - Tree - ParenOpen "(" - KwMissing "MISSING" - Id "identifier" - ParenClose ")" + shot_cst!(r#" + Q = (MISSING identifier) "#); } #[test] fn missing_node_with_string() { - let input = indoc! {r#" - Q = (MISSING ";") - "#}; - - let res = Query::expect_valid_cst(input); - - insta::assert_snapshot!(res, @r#" - Root - Def - Id "Q" - Equals "=" - Tree - ParenOpen "(" - KwMissing "MISSING" - DoubleQuote "\"" - StrVal ";" - DoubleQuote "\"" - ParenClose ")" + shot_cst!(r#" + Q = (MISSING ";") "#); } #[test] fn missing_node_with_capture() { - let input = indoc! {r#" - Q = (MISSING ";") @missing_semi - "#}; - - let res = Query::expect_valid_cst(input); - - insta::assert_snapshot!(res, @r#" - Root - Def - Id "Q" - Equals "=" - Capture - Tree - ParenOpen "(" - KwMissing "MISSING" - DoubleQuote "\"" - StrVal ";" - DoubleQuote "\"" - ParenClose ")" - CaptureToken "@missing_semi" + shot_cst!(r#" + Q = (MISSING ";") @missing_semi "#); } #[test] fn error_in_alternation() { - let input = indoc! {r#" - Q = [(ERROR) (identifier)] - "#}; - - let res = Query::expect_valid_cst(input); - - insta::assert_snapshot!(res, @r#" - Root - Def - Id "Q" - Equals "=" - Alt - BracketOpen "[" - Branch - Tree - ParenOpen "(" - KwError "ERROR" - ParenClose ")" - Branch - Tree - ParenOpen "(" - Id "identifier" - ParenClose ")" - BracketClose "]" + shot_cst!(r#" + Q = [(ERROR) (identifier)] "#); } #[test] fn missing_in_sequence() { - let input = indoc! {r#" - Q = {(MISSING ";") (identifier)} - "#}; - - let res = Query::expect_valid_cst(input); - - insta::assert_snapshot!(res, @r#" - Root - Def - Id "Q" - Equals "=" - Seq - BraceOpen "{" - Tree - ParenOpen "(" - KwMissing "MISSING" - DoubleQuote "\"" - StrVal ";" - DoubleQuote "\"" - ParenClose ")" - Tree - ParenOpen "(" - Id "identifier" - ParenClose ")" - BraceClose "}" + shot_cst!(r#" + Q = {(MISSING ";") (identifier)} "#); } #[test] fn special_node_nested() { - let input = indoc! {r#" - Q = (function_definition - body: (block (ERROR))) - "#}; - - let res = Query::expect_valid_cst(input); - - insta::assert_snapshot!(res, @r#" - Root - Def - Id "Q" - Equals "=" - Tree - ParenOpen "(" - Id "function_definition" - Field - Id "body" - Colon ":" - Tree - ParenOpen "(" - Id "block" - Tree - ParenOpen "(" - KwError "ERROR" - ParenClose ")" - ParenClose ")" - ParenClose ")" + shot_cst!(r#" + Q = (function_definition + body: (block (ERROR))) "#); } #[test] fn error_with_quantifier() { - let input = indoc! {r#" - Q = (ERROR)* - "#}; - - let res = Query::expect_valid_cst(input); - - insta::assert_snapshot!(res, @r#" - Root - Def - Id "Q" - Equals "=" - Quantifier - Tree - ParenOpen "(" - KwError "ERROR" - ParenClose ")" - Star "*" + shot_cst!(r#" + Q = (ERROR)* "#); } #[test] fn missing_with_quantifier() { - let input = indoc! {r#" - Q = (MISSING identifier)? - "#}; - - let res = Query::expect_valid_cst(input); - - insta::assert_snapshot!(res, @r#" - Root - Def - Id "Q" - Equals "=" - Quantifier - Tree - ParenOpen "(" - KwMissing "MISSING" - Id "identifier" - ParenClose ")" - Question "?" + shot_cst!(r#" + Q = (MISSING identifier)? "#); } diff --git a/crates/plotnik-compiler/src/parser/tests/grammar/trivia_tests.rs b/crates/plotnik-compiler/src/parser/tests/grammar/trivia_tests.rs index 381508d..5533f72 100644 --- a/crates/plotnik-compiler/src/parser/tests/grammar/trivia_tests.rs +++ b/crates/plotnik-compiler/src/parser/tests/grammar/trivia_tests.rs @@ -1,3 +1,7 @@ +//! Trivia (whitespace, comments) preservation tests. +//! +//! These tests use expect_valid_cst_full to verify trivia nodes are captured. + use crate::Query; use indoc::indoc; diff --git a/crates/plotnik-compiler/src/test_utils.rs b/crates/plotnik-compiler/src/test_utils.rs new file mode 100644 index 0000000..0719965 --- /dev/null +++ b/crates/plotnik-compiler/src/test_utils.rs @@ -0,0 +1,61 @@ +//! Test utilities and snapshot macros. + +/// Snapshot test for bytecode output. +#[macro_export] +macro_rules! shot_bytecode { + ($query:literal) => {{ + let query = indoc::indoc!($query).trim(); + let output = $crate::Query::expect_valid_bytecode(query); + insta::with_settings!({ omit_expression => true }, { + insta::assert_snapshot!(format!("{query}\n---\n{output}")); + }); + }}; +} + +/// Snapshot test for CST output. +#[macro_export] +macro_rules! shot_cst { + ($query:literal) => {{ + let query = indoc::indoc!($query).trim(); + let output = $crate::Query::expect_valid_cst(query); + insta::with_settings!({ omit_expression => true }, { + insta::assert_snapshot!(format!("{query}\n---\n{output}")); + }); + }}; +} + +/// Snapshot test for AST output. +#[macro_export] +macro_rules! shot_ast { + ($query:literal) => {{ + let query = indoc::indoc!($query).trim(); + let output = $crate::Query::expect_valid_ast(query); + insta::with_settings!({ omit_expression => true }, { + insta::assert_snapshot!(format!("{query}\n---\n{output}")); + }); + }}; +} + +/// Snapshot test for TypeScript type output. +#[macro_export] +macro_rules! shot_types { + ($query:literal) => {{ + let query = indoc::indoc!($query).trim(); + let output = $crate::Query::expect_valid_types(query); + insta::with_settings!({ omit_expression => true }, { + insta::assert_snapshot!(format!("{query}\n---\n{output}")); + }); + }}; +} + +/// Snapshot test for error diagnostics. +#[macro_export] +macro_rules! shot_error { + ($query:literal) => {{ + let query = indoc::indoc!($query).trim(); + let output = $crate::Query::expect_invalid(query); + insta::with_settings!({ omit_expression => true }, { + insta::assert_snapshot!(format!("{query}\n---\n{output}")); + }); + }}; +}