From 06816567ff589c1dd87a0a0ed1927e4a40cfa02c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcel=20M=C3=BCller?= Date: Thu, 12 Mar 2026 18:15:20 +0100 Subject: [PATCH 1/3] Use macro per-test-file MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Marcel Müller --- Cargo.lock | 13 ++ Cargo.toml | 1 + ...o__ast__tests__check_nested_simple_if.snap | 152 ------------------ tests/cases/4-output@condition.snap | 6 - tests/cases/4-output@identifiers.snap | 6 - tests/cases/4-output@if_else_if.snap | 6 - tests/cases/4-output@multiple.snap | 6 - tests/cases/4-output@trim_whitespace.snap | 6 - ...condition.snap => condition.1-parsed.snap} | 6 +- ...st@condition.snap => condition.2-ast.snap} | 6 +- ...ion.snap => condition.3-instructions.snap} | 6 +- tests/cases/condition.4-output.snap | 10 ++ ...tifiers.snap => identifiers.1-parsed.snap} | 5 +- ...dentifiers.snap => identifiers.2-ast.snap} | 5 +- ...s.snap => identifiers.3-instructions.snap} | 5 +- tests/cases/identifiers.4-output.snap | 14 ++ ..._else_if.snap => if_else_if.1-parsed.snap} | 7 +- ...@if_else_if.snap => if_else_if.2-ast.snap} | 7 +- ...if.snap => if_else_if.3-instructions.snap} | 7 +- tests/cases/if_else_if.4-output.snap | 11 ++ ...ation.snap => interpolation.1-parsed.snap} | 5 +- ...polation.snap => interpolation.2-ast.snap} | 5 +- ...snap => interpolation.3-instructions.snap} | 5 +- ...ation.snap => interpolation.4-output.snap} | 5 +- ...d@literals.snap => literals.1-parsed.snap} | 1 - ...-ast@literals.snap => literals.2-ast.snap} | 1 - ...rals.snap => literals.3-instructions.snap} | 1 - ...t@literals.snap => literals.4-output.snap} | 1 - ...-parsed@maths.snap => maths.1-parsed.snap} | 1 - .../{2-ast@maths.snap => maths.2-ast.snap} | 1 - ...s@maths.snap => maths.3-instructions.snap} | 1 - ...-output@maths.snap => maths.4-output.snap} | 1 - ...d@multiple.snap => multiple.1-parsed.snap} | 6 +- ...-ast@multiple.snap => multiple.2-ast.snap} | 6 +- ...iple.snap => multiple.3-instructions.snap} | 6 +- tests/cases/multiple.4-output.snap | 10 ++ ...arsed@simple.snap => simple.1-parsed.snap} | 4 +- .../{2-ast@simple.snap => simple.2-ast.snap} | 4 +- ...simple.snap => simple.3-instructions.snap} | 4 +- ...utput@simple.snap => simple.4-output.snap} | 4 +- ...mple_for.snap => simple_for.1-parsed.snap} | 1 - ...@simple_for.snap => simple_for.2-ast.snap} | 1 - ...or.snap => simple_for.3-instructions.snap} | 1 - ...mple_for.snap => simple_for.4-output.snap} | 1 - ...ace.snap => trim_whitespace.1-parsed.snap} | 6 +- ...espace.snap => trim_whitespace.2-ast.snap} | 6 +- ...ap => trim_whitespace.3-instructions.snap} | 6 +- tests/cases/trim_whitespace.4-output.snap | 10 ++ tests/file_tests.rs | 95 ++++++----- 49 files changed, 213 insertions(+), 271 deletions(-) delete mode 100644 src/ast/snapshots/nomo__ast__tests__check_nested_simple_if.snap delete mode 100644 tests/cases/4-output@condition.snap delete mode 100644 tests/cases/4-output@identifiers.snap delete mode 100644 tests/cases/4-output@if_else_if.snap delete mode 100644 tests/cases/4-output@multiple.snap delete mode 100644 tests/cases/4-output@trim_whitespace.snap rename tests/cases/{1-parsed@condition.snap => condition.1-parsed.snap} (87%) rename tests/cases/{2-ast@condition.snap => condition.2-ast.snap} (92%) rename tests/cases/{3-instructions@condition.snap => condition.3-instructions.snap} (91%) create mode 100644 tests/cases/condition.4-output.snap rename tests/cases/{1-parsed@identifiers.snap => identifiers.1-parsed.snap} (97%) rename tests/cases/{2-ast@identifiers.snap => identifiers.2-ast.snap} (97%) rename tests/cases/{3-instructions@identifiers.snap => identifiers.3-instructions.snap} (98%) create mode 100644 tests/cases/identifiers.4-output.snap rename tests/cases/{1-parsed@if_else_if.snap => if_else_if.1-parsed.snap} (85%) rename tests/cases/{2-ast@if_else_if.snap => if_else_if.2-ast.snap} (91%) rename tests/cases/{3-instructions@if_else_if.snap => if_else_if.3-instructions.snap} (90%) create mode 100644 tests/cases/if_else_if.4-output.snap rename tests/cases/{1-parsed@interpolation.snap => interpolation.1-parsed.snap} (84%) rename tests/cases/{2-ast@interpolation.snap => interpolation.2-ast.snap} (86%) rename tests/cases/{3-instructions@interpolation.snap => interpolation.3-instructions.snap} (88%) rename tests/cases/{4-output@interpolation.snap => interpolation.4-output.snap} (52%) rename tests/cases/{1-parsed@literals.snap => literals.1-parsed.snap} (94%) rename tests/cases/{2-ast@literals.snap => literals.2-ast.snap} (97%) rename tests/cases/{3-instructions@literals.snap => literals.3-instructions.snap} (96%) rename tests/cases/{4-output@literals.snap => literals.4-output.snap} (80%) rename tests/cases/{1-parsed@maths.snap => maths.1-parsed.snap} (98%) rename tests/cases/{2-ast@maths.snap => maths.2-ast.snap} (98%) rename tests/cases/{3-instructions@maths.snap => maths.3-instructions.snap} (99%) rename tests/cases/{4-output@maths.snap => maths.4-output.snap} (81%) rename tests/cases/{1-parsed@multiple.snap => multiple.1-parsed.snap} (84%) rename tests/cases/{2-ast@multiple.snap => multiple.2-ast.snap} (86%) rename tests/cases/{3-instructions@multiple.snap => multiple.3-instructions.snap} (88%) create mode 100644 tests/cases/multiple.4-output.snap rename tests/cases/{1-parsed@simple.snap => simple.1-parsed.snap} (76%) rename tests/cases/{2-ast@simple.snap => simple.2-ast.snap} (79%) rename tests/cases/{3-instructions@simple.snap => simple.3-instructions.snap} (82%) rename tests/cases/{4-output@simple.snap => simple.4-output.snap} (62%) rename tests/cases/{1-parsed@simple_for.snap => simple_for.1-parsed.snap} (98%) rename tests/cases/{2-ast@simple_for.snap => simple_for.2-ast.snap} (98%) rename tests/cases/{3-instructions@simple_for.snap => simple_for.3-instructions.snap} (98%) rename tests/cases/{4-output@simple_for.snap => simple_for.4-output.snap} (88%) rename tests/cases/{1-parsed@trim_whitespace.snap => trim_whitespace.1-parsed.snap} (89%) rename tests/cases/{2-ast@trim_whitespace.snap => trim_whitespace.2-ast.snap} (92%) rename tests/cases/{3-instructions@trim_whitespace.snap => trim_whitespace.3-instructions.snap} (90%) create mode 100644 tests/cases/trim_whitespace.4-output.snap diff --git a/Cargo.lock b/Cargo.lock index 729eb06..6a3e2bc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -442,6 +442,7 @@ dependencies = [ "insta", "serde", "serde_json", + "test_each_file", "thiserror", "winnow", ] @@ -701,6 +702,18 @@ dependencies = [ "windows-sys 0.61.2", ] +[[package]] +name = "test_each_file" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44619e49a1f62888c271dc50533f036363a7936f99c7cb467ca9d45224cf83b3" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "unicode-ident", +] + [[package]] name = "thiserror" version = "2.0.18" diff --git a/Cargo.toml b/Cargo.toml index 8e383d2..f93866f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,6 +23,7 @@ criterion = "0.8.2" insta = { version = "1.46.3", features = ["glob", "serde"] } serde = { version = "1.0.228", features = ["derive"] } serde_json = "1.0.149" +test_each_file = "0.3.7" [profile.dev.package] insta.opt-level = 3 diff --git a/src/ast/snapshots/nomo__ast__tests__check_nested_simple_if.snap b/src/ast/snapshots/nomo__ast__tests__check_nested_simple_if.snap deleted file mode 100644 index 27bbdad..0000000 --- a/src/ast/snapshots/nomo__ast__tests__check_nested_simple_if.snap +++ /dev/null @@ -1,152 +0,0 @@ ---- -source: src/ast/mod.rs -expression: parsed ---- -ParsedTemplate { - tokens: [ - TemplateToken { - kind: LeftDelim, - source: "{{" (0..2), - }, - TemplateToken { - kind: Whitespace, - source: " " (2..3), - }, - TemplateToken { - kind: ConditionalIf, - source: "if" (3..5), - }, - TemplateToken { - kind: Whitespace, - source: " " (5..6), - }, - TemplateToken { - kind: Ident, - source: "foo" (6..9), - }, - TemplateToken { - kind: Whitespace, - source: " " (9..10), - }, - TemplateToken { - kind: RightDelim, - source: "}}" (10..12), - }, - TemplateToken { - kind: Whitespace, - source: "\n " (12..25), - }, - TemplateToken { - kind: LeftDelim, - source: "{{" (25..27), - }, - TemplateToken { - kind: Whitespace, - source: " " (27..28), - }, - TemplateToken { - kind: ConditionalIf, - source: "if" (28..30), - }, - TemplateToken { - kind: Whitespace, - source: " " (30..31), - }, - TemplateToken { - kind: Ident, - source: "bar" (31..34), - }, - TemplateToken { - kind: Whitespace, - source: " " (34..35), - }, - TemplateToken { - kind: RightDelim, - source: "}}" (35..37), - }, - TemplateToken { - kind: Whitespace, - source: "\n " (37..54), - }, - TemplateToken { - kind: Content, - source: "Hiii" (54..58), - }, - TemplateToken { - kind: Whitespace, - source: "\n " (58..71), - }, - TemplateToken { - kind: LeftDelim, - source: "{{" (71..73), - }, - TemplateToken { - kind: Whitespace, - source: " " (73..74), - }, - TemplateToken { - kind: End, - source: "end" (74..77), - }, - TemplateToken { - kind: Whitespace, - source: " " (77..78), - }, - TemplateToken { - kind: RightDelim, - source: "}}" (78..80), - }, - TemplateToken { - kind: Whitespace, - source: "\n " (80..89), - }, - TemplateToken { - kind: LeftDelim, - source: "{{" (89..91), - }, - TemplateToken { - kind: Whitespace, - source: " " (91..92), - }, - TemplateToken { - kind: End, - source: "end" (92..95), - }, - TemplateToken { - kind: Whitespace, - source: " " (95..96), - }, - TemplateToken { - kind: RightDelim, - source: "}}" (96..98), - }, - TemplateToken { - kind: Whitespace, - source: "\n\n " (98..108), - }, - TemplateToken { - kind: LeftDelim, - source: "{{" (108..110), - }, - TemplateToken { - kind: Whitespace, - source: " " (110..111), - }, - TemplateToken { - kind: Ident, - source: "value" (111..116), - }, - TemplateToken { - kind: Whitespace, - source: " " (116..117), - }, - TemplateToken { - kind: RightDelim, - source: "}}" (117..119), - }, - TemplateToken { - kind: Whitespace, - source: "\n " (119..128), - }, - ], -} diff --git a/tests/cases/4-output@condition.snap b/tests/cases/4-output@condition.snap deleted file mode 100644 index 1d5af6f..0000000 --- a/tests/cases/4-output@condition.snap +++ /dev/null @@ -1,6 +0,0 @@ ---- -source: tests/file_tests.rs -expression: output -input_file: tests/cases/condition.nomo ---- -"\n Hello World!\n\n\nmore" diff --git a/tests/cases/4-output@identifiers.snap b/tests/cases/4-output@identifiers.snap deleted file mode 100644 index 33a3457..0000000 --- a/tests/cases/4-output@identifiers.snap +++ /dev/null @@ -1,6 +0,0 @@ ---- -source: tests/file_tests.rs -expression: output -input_file: tests/cases/identifiers.nomo ---- -"Foo\nFoo\nFoo\nFoo\nFoo\nFoo" diff --git a/tests/cases/4-output@if_else_if.snap b/tests/cases/4-output@if_else_if.snap deleted file mode 100644 index c815937..0000000 --- a/tests/cases/4-output@if_else_if.snap +++ /dev/null @@ -1,6 +0,0 @@ ---- -source: tests/file_tests.rs -expression: output -input_file: tests/cases/if_else_if.nomo ---- -"\n Hello World!\n" diff --git a/tests/cases/4-output@multiple.snap b/tests/cases/4-output@multiple.snap deleted file mode 100644 index b6a763a..0000000 --- a/tests/cases/4-output@multiple.snap +++ /dev/null @@ -1,6 +0,0 @@ ---- -source: tests/file_tests.rs -expression: output -input_file: tests/cases/multiple.nomo ---- -"Hi there! My name is Hemera Green" diff --git a/tests/cases/4-output@trim_whitespace.snap b/tests/cases/4-output@trim_whitespace.snap deleted file mode 100644 index 03e2039..0000000 --- a/tests/cases/4-output@trim_whitespace.snap +++ /dev/null @@ -1,6 +0,0 @@ ---- -source: tests/file_tests.rs -expression: output -input_file: tests/cases/trim_whitespace.nomo ---- -"Hello Hemera" diff --git a/tests/cases/1-parsed@condition.snap b/tests/cases/condition.1-parsed.snap similarity index 87% rename from tests/cases/1-parsed@condition.snap rename to tests/cases/condition.1-parsed.snap index 9a4d638..e2ec981 100644 --- a/tests/cases/1-parsed@condition.snap +++ b/tests/cases/condition.1-parsed.snap @@ -1,7 +1,11 @@ --- source: tests/file_tests.rs expression: parsed -input_file: tests/cases/condition.nomo +info: + input: "{{ if test }}\n Hello World!\n{{ end }}\n\n{{= stuff }}" + context: + stuff: more + test: true --- ParsedTemplate { tokens: [ diff --git a/tests/cases/2-ast@condition.snap b/tests/cases/condition.2-ast.snap similarity index 92% rename from tests/cases/2-ast@condition.snap rename to tests/cases/condition.2-ast.snap index ae3a62e..40e042f 100644 --- a/tests/cases/2-ast@condition.snap +++ b/tests/cases/condition.2-ast.snap @@ -1,7 +1,11 @@ --- source: tests/file_tests.rs expression: ast -input_file: tests/cases/condition.nomo +info: + input: "{{ if test }}\n Hello World!\n{{ end }}\n\n{{= stuff }}" + context: + stuff: more + test: true --- TemplateAst { root: [ diff --git a/tests/cases/3-instructions@condition.snap b/tests/cases/condition.3-instructions.snap similarity index 91% rename from tests/cases/3-instructions@condition.snap rename to tests/cases/condition.3-instructions.snap index 5f79488..a317547 100644 --- a/tests/cases/3-instructions@condition.snap +++ b/tests/cases/condition.3-instructions.snap @@ -1,7 +1,11 @@ --- source: tests/file_tests.rs expression: emit -input_file: tests/cases/condition.nomo +info: + input: "{{ if test }}\n Hello World!\n{{ end }}\n\n{{= stuff }}" + context: + stuff: more + test: true --- VMInstructions { labels: { diff --git a/tests/cases/condition.4-output.snap b/tests/cases/condition.4-output.snap new file mode 100644 index 0000000..bfdf149 --- /dev/null +++ b/tests/cases/condition.4-output.snap @@ -0,0 +1,10 @@ +--- +source: tests/file_tests.rs +expression: output +info: + input: "{{ if test }}\n Hello World!\n{{ end }}\n\n{{= stuff }}" + context: + stuff: more + test: true +--- +"\n Hello World!\n\n\nmore" diff --git a/tests/cases/1-parsed@identifiers.snap b/tests/cases/identifiers.1-parsed.snap similarity index 97% rename from tests/cases/1-parsed@identifiers.snap rename to tests/cases/identifiers.1-parsed.snap index 31760f1..acc7ff8 100644 --- a/tests/cases/1-parsed@identifiers.snap +++ b/tests/cases/identifiers.1-parsed.snap @@ -4,13 +4,12 @@ expression: parsed info: input: "{{= _name }}\n{{= a_name }}\n{{= name }}\n{{= _name1 }}\n{{= _namE }}\n{{= name1 }}" context: - _namE: Foo name1: Foo - name: Foo _name: Foo + _namE: Foo a_name: Foo + name: Foo _name1: Foo -input_file: tests/cases/identifiers.nomo --- ParsedTemplate { tokens: [ diff --git a/tests/cases/2-ast@identifiers.snap b/tests/cases/identifiers.2-ast.snap similarity index 97% rename from tests/cases/2-ast@identifiers.snap rename to tests/cases/identifiers.2-ast.snap index 4333d9d..932b2f6 100644 --- a/tests/cases/2-ast@identifiers.snap +++ b/tests/cases/identifiers.2-ast.snap @@ -4,13 +4,12 @@ expression: ast info: input: "{{= _name }}\n{{= a_name }}\n{{= name }}\n{{= _name1 }}\n{{= _namE }}\n{{= name1 }}" context: - _namE: Foo name1: Foo - name: Foo _name: Foo + _namE: Foo a_name: Foo + name: Foo _name1: Foo -input_file: tests/cases/identifiers.nomo --- TemplateAst { root: [ diff --git a/tests/cases/3-instructions@identifiers.snap b/tests/cases/identifiers.3-instructions.snap similarity index 98% rename from tests/cases/3-instructions@identifiers.snap rename to tests/cases/identifiers.3-instructions.snap index 9556d23..f3d8ddc 100644 --- a/tests/cases/3-instructions@identifiers.snap +++ b/tests/cases/identifiers.3-instructions.snap @@ -4,13 +4,12 @@ expression: emit info: input: "{{= _name }}\n{{= a_name }}\n{{= name }}\n{{= _name1 }}\n{{= _namE }}\n{{= name1 }}" context: - _namE: Foo name1: Foo - name: Foo _name: Foo + _namE: Foo a_name: Foo + name: Foo _name1: Foo -input_file: tests/cases/identifiers.nomo --- VMInstructions { labels: {}, diff --git a/tests/cases/identifiers.4-output.snap b/tests/cases/identifiers.4-output.snap new file mode 100644 index 0000000..5834f52 --- /dev/null +++ b/tests/cases/identifiers.4-output.snap @@ -0,0 +1,14 @@ +--- +source: tests/file_tests.rs +expression: output +info: + input: "{{= _name }}\n{{= a_name }}\n{{= name }}\n{{= _name1 }}\n{{= _namE }}\n{{= name1 }}" + context: + name1: Foo + _name: Foo + _namE: Foo + a_name: Foo + name: Foo + _name1: Foo +--- +"Foo\nFoo\nFoo\nFoo\nFoo\nFoo" diff --git a/tests/cases/1-parsed@if_else_if.snap b/tests/cases/if_else_if.1-parsed.snap similarity index 85% rename from tests/cases/1-parsed@if_else_if.snap rename to tests/cases/if_else_if.1-parsed.snap index 287fce6..06161fa 100644 --- a/tests/cases/1-parsed@if_else_if.snap +++ b/tests/cases/if_else_if.1-parsed.snap @@ -1,7 +1,12 @@ --- source: tests/file_tests.rs expression: parsed -input_file: tests/cases/if_else_if.nomo +info: + input: "{{ if test }}\n Not Hello World! :C\n{{ else if another_test }}\n Hello World!\n{{ end }}" + context: + test: false + stuff: more + another_test: true --- ParsedTemplate { tokens: [ diff --git a/tests/cases/2-ast@if_else_if.snap b/tests/cases/if_else_if.2-ast.snap similarity index 91% rename from tests/cases/2-ast@if_else_if.snap rename to tests/cases/if_else_if.2-ast.snap index 3bc850b..eba26c3 100644 --- a/tests/cases/2-ast@if_else_if.snap +++ b/tests/cases/if_else_if.2-ast.snap @@ -1,7 +1,12 @@ --- source: tests/file_tests.rs expression: ast -input_file: tests/cases/if_else_if.nomo +info: + input: "{{ if test }}\n Not Hello World! :C\n{{ else if another_test }}\n Hello World!\n{{ end }}" + context: + test: false + stuff: more + another_test: true --- TemplateAst { root: [ diff --git a/tests/cases/3-instructions@if_else_if.snap b/tests/cases/if_else_if.3-instructions.snap similarity index 90% rename from tests/cases/3-instructions@if_else_if.snap rename to tests/cases/if_else_if.3-instructions.snap index 124556e..5504ab9 100644 --- a/tests/cases/3-instructions@if_else_if.snap +++ b/tests/cases/if_else_if.3-instructions.snap @@ -1,7 +1,12 @@ --- source: tests/file_tests.rs expression: emit -input_file: tests/cases/if_else_if.nomo +info: + input: "{{ if test }}\n Not Hello World! :C\n{{ else if another_test }}\n Hello World!\n{{ end }}" + context: + test: false + stuff: more + another_test: true --- VMInstructions { labels: { diff --git a/tests/cases/if_else_if.4-output.snap b/tests/cases/if_else_if.4-output.snap new file mode 100644 index 0000000..1cc7406 --- /dev/null +++ b/tests/cases/if_else_if.4-output.snap @@ -0,0 +1,11 @@ +--- +source: tests/file_tests.rs +expression: output +info: + input: "{{ if test }}\n Not Hello World! :C\n{{ else if another_test }}\n Hello World!\n{{ end }}" + context: + test: false + stuff: more + another_test: true +--- +"\n Hello World!\n" diff --git a/tests/cases/1-parsed@interpolation.snap b/tests/cases/interpolation.1-parsed.snap similarity index 84% rename from tests/cases/1-parsed@interpolation.snap rename to tests/cases/interpolation.1-parsed.snap index 662117b..44d635a 100644 --- a/tests/cases/1-parsed@interpolation.snap +++ b/tests/cases/interpolation.1-parsed.snap @@ -1,7 +1,10 @@ --- source: tests/file_tests.rs expression: parsed -input_file: tests/cases/interpolation.nomo +info: + input: "Hello! I'm {{= name }}" + context: + name: Hemera --- ParsedTemplate { tokens: [ diff --git a/tests/cases/2-ast@interpolation.snap b/tests/cases/interpolation.2-ast.snap similarity index 86% rename from tests/cases/2-ast@interpolation.snap rename to tests/cases/interpolation.2-ast.snap index 272123a..377f6f3 100644 --- a/tests/cases/2-ast@interpolation.snap +++ b/tests/cases/interpolation.2-ast.snap @@ -1,7 +1,10 @@ --- source: tests/file_tests.rs expression: ast -input_file: tests/cases/interpolation.nomo +info: + input: "Hello! I'm {{= name }}" + context: + name: Hemera --- TemplateAst { root: [ diff --git a/tests/cases/3-instructions@interpolation.snap b/tests/cases/interpolation.3-instructions.snap similarity index 88% rename from tests/cases/3-instructions@interpolation.snap rename to tests/cases/interpolation.3-instructions.snap index 82dc16b..c47d18a 100644 --- a/tests/cases/3-instructions@interpolation.snap +++ b/tests/cases/interpolation.3-instructions.snap @@ -1,7 +1,10 @@ --- source: tests/file_tests.rs expression: emit -input_file: tests/cases/interpolation.nomo +info: + input: "Hello! I'm {{= name }}" + context: + name: Hemera --- VMInstructions { labels: {}, diff --git a/tests/cases/4-output@interpolation.snap b/tests/cases/interpolation.4-output.snap similarity index 52% rename from tests/cases/4-output@interpolation.snap rename to tests/cases/interpolation.4-output.snap index f27078d..b7e4214 100644 --- a/tests/cases/4-output@interpolation.snap +++ b/tests/cases/interpolation.4-output.snap @@ -1,6 +1,9 @@ --- source: tests/file_tests.rs expression: output -input_file: tests/cases/interpolation.nomo +info: + input: "Hello! I'm {{= name }}" + context: + name: Hemera --- "Hello! I'm Hemera" diff --git a/tests/cases/1-parsed@literals.snap b/tests/cases/literals.1-parsed.snap similarity index 94% rename from tests/cases/1-parsed@literals.snap rename to tests/cases/literals.1-parsed.snap index bc0d851..0a528a6 100644 --- a/tests/cases/1-parsed@literals.snap +++ b/tests/cases/literals.1-parsed.snap @@ -4,7 +4,6 @@ expression: parsed info: input: "{{ if true }}\n Hello World!\n{{ end }}" context: {} -input_file: tests/cases/literals.nomo --- ParsedTemplate { tokens: [ diff --git a/tests/cases/2-ast@literals.snap b/tests/cases/literals.2-ast.snap similarity index 97% rename from tests/cases/2-ast@literals.snap rename to tests/cases/literals.2-ast.snap index 85453dc..74b53ba 100644 --- a/tests/cases/2-ast@literals.snap +++ b/tests/cases/literals.2-ast.snap @@ -4,7 +4,6 @@ expression: ast info: input: "{{ if true }}\n Hello World!\n{{ end }}" context: {} -input_file: tests/cases/literals.nomo --- TemplateAst { root: [ diff --git a/tests/cases/3-instructions@literals.snap b/tests/cases/literals.3-instructions.snap similarity index 96% rename from tests/cases/3-instructions@literals.snap rename to tests/cases/literals.3-instructions.snap index 7f68e85..3955988 100644 --- a/tests/cases/3-instructions@literals.snap +++ b/tests/cases/literals.3-instructions.snap @@ -4,7 +4,6 @@ expression: emit info: input: "{{ if true }}\n Hello World!\n{{ end }}" context: {} -input_file: tests/cases/literals.nomo --- VMInstructions { labels: { diff --git a/tests/cases/4-output@literals.snap b/tests/cases/literals.4-output.snap similarity index 80% rename from tests/cases/4-output@literals.snap rename to tests/cases/literals.4-output.snap index 3a38d32..60c99e3 100644 --- a/tests/cases/4-output@literals.snap +++ b/tests/cases/literals.4-output.snap @@ -4,6 +4,5 @@ expression: output info: input: "{{ if true }}\n Hello World!\n{{ end }}" context: {} -input_file: tests/cases/literals.nomo --- "\n Hello World!\n" diff --git a/tests/cases/1-parsed@maths.snap b/tests/cases/maths.1-parsed.snap similarity index 98% rename from tests/cases/1-parsed@maths.snap rename to tests/cases/maths.1-parsed.snap index 837a801..d779936 100644 --- a/tests/cases/1-parsed@maths.snap +++ b/tests/cases/maths.1-parsed.snap @@ -4,7 +4,6 @@ expression: parsed info: input: "{{= 5 * 3 }}\n{{= 2 * 3 + 4 * 3 }}\n{{= 3 / 3 + 3 }}" context: {} -input_file: tests/cases/maths.nomo --- ParsedTemplate { tokens: [ diff --git a/tests/cases/2-ast@maths.snap b/tests/cases/maths.2-ast.snap similarity index 98% rename from tests/cases/2-ast@maths.snap rename to tests/cases/maths.2-ast.snap index 6aa9130..45be132 100644 --- a/tests/cases/2-ast@maths.snap +++ b/tests/cases/maths.2-ast.snap @@ -4,7 +4,6 @@ expression: ast info: input: "{{= 5 * 3 }}\n{{= 2 * 3 + 4 * 3 }}\n{{= 3 / 3 + 3 }}" context: {} -input_file: tests/cases/maths.nomo --- TemplateAst { root: [ diff --git a/tests/cases/3-instructions@maths.snap b/tests/cases/maths.3-instructions.snap similarity index 99% rename from tests/cases/3-instructions@maths.snap rename to tests/cases/maths.3-instructions.snap index d6a4920..7722f26 100644 --- a/tests/cases/3-instructions@maths.snap +++ b/tests/cases/maths.3-instructions.snap @@ -4,7 +4,6 @@ expression: emit info: input: "{{= 5 * 3 }}\n{{= 2 * 3 + 4 * 3 }}\n{{= 3 / 3 + 3 }}" context: {} -input_file: tests/cases/maths.nomo --- VMInstructions { labels: {}, diff --git a/tests/cases/4-output@maths.snap b/tests/cases/maths.4-output.snap similarity index 81% rename from tests/cases/4-output@maths.snap rename to tests/cases/maths.4-output.snap index ab89da7..b694479 100644 --- a/tests/cases/4-output@maths.snap +++ b/tests/cases/maths.4-output.snap @@ -4,6 +4,5 @@ expression: output info: input: "{{= 5 * 3 }}\n{{= 2 * 3 + 4 * 3 }}\n{{= 3 / 3 + 3 }}" context: {} -input_file: tests/cases/maths.nomo --- "15\n18\n4" diff --git a/tests/cases/1-parsed@multiple.snap b/tests/cases/multiple.1-parsed.snap similarity index 84% rename from tests/cases/1-parsed@multiple.snap rename to tests/cases/multiple.1-parsed.snap index 89c0a2a..d04d1a3 100644 --- a/tests/cases/1-parsed@multiple.snap +++ b/tests/cases/multiple.1-parsed.snap @@ -1,7 +1,11 @@ --- source: tests/file_tests.rs expression: parsed -input_file: tests/cases/multiple.nomo +info: + input: "Hi there! My name is {{= name }} {{= lastname }}" + context: + name: Hemera + lastname: Green --- ParsedTemplate { tokens: [ diff --git a/tests/cases/2-ast@multiple.snap b/tests/cases/multiple.2-ast.snap similarity index 86% rename from tests/cases/2-ast@multiple.snap rename to tests/cases/multiple.2-ast.snap index 3f8b6ea..9adbc67 100644 --- a/tests/cases/2-ast@multiple.snap +++ b/tests/cases/multiple.2-ast.snap @@ -1,7 +1,11 @@ --- source: tests/file_tests.rs expression: ast -input_file: tests/cases/multiple.nomo +info: + input: "Hi there! My name is {{= name }} {{= lastname }}" + context: + name: Hemera + lastname: Green --- TemplateAst { root: [ diff --git a/tests/cases/3-instructions@multiple.snap b/tests/cases/multiple.3-instructions.snap similarity index 88% rename from tests/cases/3-instructions@multiple.snap rename to tests/cases/multiple.3-instructions.snap index b6f13eb..ef538c1 100644 --- a/tests/cases/3-instructions@multiple.snap +++ b/tests/cases/multiple.3-instructions.snap @@ -1,7 +1,11 @@ --- source: tests/file_tests.rs expression: emit -input_file: tests/cases/multiple.nomo +info: + input: "Hi there! My name is {{= name }} {{= lastname }}" + context: + name: Hemera + lastname: Green --- VMInstructions { labels: {}, diff --git a/tests/cases/multiple.4-output.snap b/tests/cases/multiple.4-output.snap new file mode 100644 index 0000000..d1047d4 --- /dev/null +++ b/tests/cases/multiple.4-output.snap @@ -0,0 +1,10 @@ +--- +source: tests/file_tests.rs +expression: output +info: + input: "Hi there! My name is {{= name }} {{= lastname }}" + context: + name: Hemera + lastname: Green +--- +"Hi there! My name is Hemera Green" diff --git a/tests/cases/1-parsed@simple.snap b/tests/cases/simple.1-parsed.snap similarity index 76% rename from tests/cases/1-parsed@simple.snap rename to tests/cases/simple.1-parsed.snap index 1bb543e..6a95bef 100644 --- a/tests/cases/1-parsed@simple.snap +++ b/tests/cases/simple.1-parsed.snap @@ -1,7 +1,9 @@ --- source: tests/file_tests.rs expression: parsed -input_file: tests/cases/simple.nomo +info: + input: Hello World! + context: {} --- ParsedTemplate { tokens: [ diff --git a/tests/cases/2-ast@simple.snap b/tests/cases/simple.2-ast.snap similarity index 79% rename from tests/cases/2-ast@simple.snap rename to tests/cases/simple.2-ast.snap index 48a5a9c..edc75fe 100644 --- a/tests/cases/2-ast@simple.snap +++ b/tests/cases/simple.2-ast.snap @@ -1,7 +1,9 @@ --- source: tests/file_tests.rs expression: ast -input_file: tests/cases/simple.nomo +info: + input: Hello World! + context: {} --- TemplateAst { root: [ diff --git a/tests/cases/3-instructions@simple.snap b/tests/cases/simple.3-instructions.snap similarity index 82% rename from tests/cases/3-instructions@simple.snap rename to tests/cases/simple.3-instructions.snap index 752a53b..ce35108 100644 --- a/tests/cases/3-instructions@simple.snap +++ b/tests/cases/simple.3-instructions.snap @@ -1,7 +1,9 @@ --- source: tests/file_tests.rs expression: emit -input_file: tests/cases/simple.nomo +info: + input: Hello World! + context: {} --- VMInstructions { labels: {}, diff --git a/tests/cases/4-output@simple.snap b/tests/cases/simple.4-output.snap similarity index 62% rename from tests/cases/4-output@simple.snap rename to tests/cases/simple.4-output.snap index 35ba658..9dd7070 100644 --- a/tests/cases/4-output@simple.snap +++ b/tests/cases/simple.4-output.snap @@ -1,6 +1,8 @@ --- source: tests/file_tests.rs expression: output -input_file: tests/cases/simple.nomo +info: + input: Hello World! + context: {} --- "Hello World!" diff --git a/tests/cases/1-parsed@simple_for.snap b/tests/cases/simple_for.1-parsed.snap similarity index 98% rename from tests/cases/1-parsed@simple_for.snap rename to tests/cases/simple_for.1-parsed.snap index 4e391b7..a4b269f 100644 --- a/tests/cases/1-parsed@simple_for.snap +++ b/tests/cases/simple_for.1-parsed.snap @@ -8,7 +8,6 @@ info: values: - one - two -input_file: tests/cases/simple_for.nomo --- ParsedTemplate { tokens: [ diff --git a/tests/cases/2-ast@simple_for.snap b/tests/cases/simple_for.2-ast.snap similarity index 98% rename from tests/cases/2-ast@simple_for.snap rename to tests/cases/simple_for.2-ast.snap index 5071ece..3a9c2d8 100644 --- a/tests/cases/2-ast@simple_for.snap +++ b/tests/cases/simple_for.2-ast.snap @@ -8,7 +8,6 @@ info: values: - one - two -input_file: tests/cases/simple_for.nomo --- TemplateAst { root: [ diff --git a/tests/cases/3-instructions@simple_for.snap b/tests/cases/simple_for.3-instructions.snap similarity index 98% rename from tests/cases/3-instructions@simple_for.snap rename to tests/cases/simple_for.3-instructions.snap index 0cac073..f082c47 100644 --- a/tests/cases/3-instructions@simple_for.snap +++ b/tests/cases/simple_for.3-instructions.snap @@ -8,7 +8,6 @@ info: values: - one - two -input_file: tests/cases/simple_for.nomo --- VMInstructions { labels: { diff --git a/tests/cases/4-output@simple_for.snap b/tests/cases/simple_for.4-output.snap similarity index 88% rename from tests/cases/4-output@simple_for.snap rename to tests/cases/simple_for.4-output.snap index 0c2ca8d..ac83af5 100644 --- a/tests/cases/4-output@simple_for.snap +++ b/tests/cases/simple_for.4-output.snap @@ -8,6 +8,5 @@ info: values: - one - two -input_file: tests/cases/simple_for.nomo --- "one\ntwo\n\nNo Values >:C" diff --git a/tests/cases/1-parsed@trim_whitespace.snap b/tests/cases/trim_whitespace.1-parsed.snap similarity index 89% rename from tests/cases/1-parsed@trim_whitespace.snap rename to tests/cases/trim_whitespace.1-parsed.snap index b95d570..f8f1912 100644 --- a/tests/cases/1-parsed@trim_whitespace.snap +++ b/tests/cases/trim_whitespace.1-parsed.snap @@ -1,7 +1,11 @@ --- source: tests/file_tests.rs expression: parsed -input_file: tests/cases/trim_whitespace.nomo +info: + input: "{{ if test -}}\n Hello {{= stuff -}}\n{{- end }}" + context: + stuff: Hemera + test: true --- ParsedTemplate { tokens: [ diff --git a/tests/cases/2-ast@trim_whitespace.snap b/tests/cases/trim_whitespace.2-ast.snap similarity index 92% rename from tests/cases/2-ast@trim_whitespace.snap rename to tests/cases/trim_whitespace.2-ast.snap index 0e20a97..bcd0a35 100644 --- a/tests/cases/2-ast@trim_whitespace.snap +++ b/tests/cases/trim_whitespace.2-ast.snap @@ -1,7 +1,11 @@ --- source: tests/file_tests.rs expression: ast -input_file: tests/cases/trim_whitespace.nomo +info: + input: "{{ if test -}}\n Hello {{= stuff -}}\n{{- end }}" + context: + stuff: Hemera + test: true --- TemplateAst { root: [ diff --git a/tests/cases/3-instructions@trim_whitespace.snap b/tests/cases/trim_whitespace.3-instructions.snap similarity index 90% rename from tests/cases/3-instructions@trim_whitespace.snap rename to tests/cases/trim_whitespace.3-instructions.snap index 5c1ad06..31112d0 100644 --- a/tests/cases/3-instructions@trim_whitespace.snap +++ b/tests/cases/trim_whitespace.3-instructions.snap @@ -1,7 +1,11 @@ --- source: tests/file_tests.rs expression: emit -input_file: tests/cases/trim_whitespace.nomo +info: + input: "{{ if test -}}\n Hello {{= stuff -}}\n{{- end }}" + context: + stuff: Hemera + test: true --- VMInstructions { labels: { diff --git a/tests/cases/trim_whitespace.4-output.snap b/tests/cases/trim_whitespace.4-output.snap new file mode 100644 index 0000000..cde8c8b --- /dev/null +++ b/tests/cases/trim_whitespace.4-output.snap @@ -0,0 +1,10 @@ +--- +source: tests/file_tests.rs +expression: output +info: + input: "{{ if test -}}\n Hello {{= stuff -}}\n{{- end }}" + context: + stuff: Hemera + test: true +--- +"Hello Hemera" diff --git a/tests/file_tests.rs b/tests/file_tests.rs index 523758d..8e01a7d 100644 --- a/tests/file_tests.rs +++ b/tests/file_tests.rs @@ -1,4 +1,5 @@ use std::collections::HashMap; +use std::path::Path; use nomo::Context; @@ -8,57 +9,55 @@ struct Info { context: HashMap, } -#[test] -fn check_cases() { - insta::glob!("cases/*.nomo", |path| { - let mut settings = insta::Settings::clone_current(); - settings.set_snapshot_path("cases"); - settings.set_snapshot_suffix(path.file_stem().unwrap().display().to_string()); - settings.set_prepend_module_to_snapshot(false); +test_each_file::test_each_path! { for ["nomo"] in "./tests/cases/" => check_for_input } +fn check_for_input([path]: [&Path; 1]) { + let mut settings = insta::Settings::clone_current(); + settings.set_snapshot_path("cases"); + settings.set_prepend_module_to_snapshot(false); - let input = std::fs::read_to_string(path).unwrap(); + let basename = path.file_stem().unwrap().to_string_lossy(); + let input = std::fs::read_to_string(path).unwrap(); - let (context, input) = input.split_once("\n---\n").unwrap_or_else(|| ("", &input)); + let (context, input) = input.split_once("\n---\n").unwrap_or_else(|| ("", &input)); - let map = if !context.is_empty() { - serde_json::from_str::>(context).unwrap() - } else { - HashMap::new() - }; + let map = if !context.is_empty() { + serde_json::from_str::>(context).unwrap() + } else { + HashMap::new() + }; - settings.set_info(&Info { - input: input.to_string(), - context: map.clone(), - }); - - let mut context = Context::new(); - - for (k, v) in map { - context.try_insert(k, v).unwrap(); - } - - let parsed = nomo::parser::parse(input.into()).unwrap(); - - let _guard = settings.bind_to_scope(); - - insta::assert_debug_snapshot!("1-parsed", parsed); - - let ast = match nomo::ast::parse(parsed.tokens()) { - Ok(ast) => ast, - Err(err) => { - eprintln!("{}", err.to_report(input)); - panic!("Could not evaluate ast"); - } - }; - - insta::assert_debug_snapshot!("2-ast", ast); - - let emit = nomo::emit::emit_machine(ast); - - insta::assert_debug_snapshot!("3-instructions", emit); - - let output = nomo::eval::execute(&emit, &context).unwrap(); - - insta::assert_debug_snapshot!("4-output", output); + settings.set_info(&Info { + input: input.to_string(), + context: map.clone(), }); + + let mut context = Context::new(); + + for (k, v) in map { + context.try_insert(k, v).unwrap(); + } + + let parsed = nomo::parser::parse(input.into()).unwrap(); + + let _guard = settings.bind_to_scope(); + + insta::assert_debug_snapshot!(format!("{basename}.1-parsed"), parsed); + + let ast = match nomo::ast::parse(parsed.tokens()) { + Ok(ast) => ast, + Err(err) => { + eprintln!("{}", err.to_report(input)); + panic!("Could not evaluate ast"); + } + }; + + insta::assert_debug_snapshot!(format!("{basename}.2-ast"), ast); + + let emit = nomo::emit::emit_machine(ast); + + insta::assert_debug_snapshot!(format!("{basename}.3-instructions"), emit); + + let output = nomo::eval::execute(&emit, &context).unwrap(); + + insta::assert_debug_snapshot!(format!("{basename}.4-output"), output); } From 9aeeb4eb5b198671ff77b10cd5b9828104000cff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcel=20M=C3=BCller?= Date: Thu, 12 Mar 2026 18:17:22 +0100 Subject: [PATCH 2/3] Scope tests in cases MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Marcel Müller --- tests/file_tests.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/file_tests.rs b/tests/file_tests.rs index 8e01a7d..db3c666 100644 --- a/tests/file_tests.rs +++ b/tests/file_tests.rs @@ -3,13 +3,14 @@ use std::path::Path; use nomo::Context; +test_each_file::test_each_path! { for ["nomo"] in "./tests/cases/" as cases => check_for_input } + #[derive(serde::Serialize)] struct Info { input: String, context: HashMap, } -test_each_file::test_each_path! { for ["nomo"] in "./tests/cases/" => check_for_input } fn check_for_input([path]: [&Path; 1]) { let mut settings = insta::Settings::clone_current(); settings.set_snapshot_path("cases"); From d41cd5784705453cba820ac0875f6704b16d956d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcel=20M=C3=BCller?= Date: Fri, 13 Mar 2026 07:40:21 +0100 Subject: [PATCH 3/3] Add asting benchmark MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Marcel Müller --- Cargo.toml | 4 ++++ benches/asting.rs | 54 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+) create mode 100644 benches/asting.rs diff --git a/Cargo.toml b/Cargo.toml index f93866f..fe1e716 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,6 +7,10 @@ edition = "2024" name = "parsing" harness = false +[[bench]] +name = "asting" +harness = false + [profile.bench] debug = true diff --git a/benches/asting.rs b/benches/asting.rs new file mode 100644 index 0000000..1528069 --- /dev/null +++ b/benches/asting.rs @@ -0,0 +1,54 @@ +use criterion::BenchmarkId; +use criterion::Criterion; +use criterion::criterion_group; +use criterion::criterion_main; +use nomo::input::NomoInput; + +fn asting_benchmark(c: &mut Criterion) { + let mut parsing = c.benchmark_group("Asting"); + + for size in [1, 10, 200, 1000] { + let mut input = String::new(); + + for _ in 0..size { + input.push_str("{{ if foo }}{{= variable }}{{ end }}"); + } + + let input = NomoInput::from(input); + + parsing.throughput(criterion::Throughput::Bytes(input.len() as u64)); + parsing.bench_with_input(BenchmarkId::from_parameter(size), &input, |b, input| { + b.iter(|| { + let tokens = nomo::parser::parse(input.clone()).unwrap(); + let _ast = nomo::ast::parse(tokens.tokens()).unwrap(); + }); + }); + } +} + +fn asting_nested(c: &mut Criterion) { + let mut parsing = c.benchmark_group("Asting"); + + for size in [1, 2, 8, 12] { + let mut input = String::new(); + + for _ in 0..size { + input = format!( + "{{{{ for foo in bar }}}} {input} {{{{ if foo }}}} Hi! {input} {{{{ end }}}} Yooo {{{{ end }}}}" + ); + } + + let input = NomoInput::from(input); + + parsing.throughput(criterion::Throughput::Bytes(input.len() as u64)); + parsing.bench_with_input(BenchmarkId::from_parameter(size), &input, |b, input| { + b.iter(|| { + let tokens = nomo::parser::parse(input.clone()).unwrap(); + let _ast = nomo::ast::parse(tokens.tokens()).unwrap(); + }); + }); + } +} + +criterion_group!(benches, asting_benchmark, asting_nested); +criterion_main!(benches);