Setup a testing bench
Signed-off-by: Marcel Müller <neikos@neikos.email>
This commit is contained in:
parent
4470af3926
commit
d3e6410ec0
16 changed files with 336 additions and 4 deletions
81
Cargo.lock
generated
81
Cargo.lock
generated
|
|
@ -2,6 +2,15 @@
|
|||
# It is not intended for manual editing.
|
||||
version = 4
|
||||
|
||||
[[package]]
|
||||
name = "aho-corasick"
|
||||
version = "1.1.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "annotate-snippets"
|
||||
version = "0.12.13"
|
||||
|
|
@ -31,6 +40,16 @@ version = "2.11.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "843867be96c8daad0d758b57df9392b6d8d271134fce549de6ce169ff98a92af"
|
||||
|
||||
[[package]]
|
||||
name = "bstr"
|
||||
version = "1.12.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "63044e1ae8e69f3b5a92c736ca6269b8d12fa7efe39bf34ddb06d102cf0e2cab"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.4"
|
||||
|
|
@ -107,6 +126,19 @@ dependencies = [
|
|||
"wasip3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "globset"
|
||||
version = "0.4.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "52dfc19153a48bde0cbd630453615c8151bce3a5adfac7a0aebfbf0a1e1f57e3"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"bstr",
|
||||
"log",
|
||||
"regex-automata",
|
||||
"regex-syntax",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.15.5"
|
||||
|
|
@ -153,9 +185,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "e82db8c87c7f1ccecb34ce0c24399b8a73081427f3c7c50a5d597925356115e4"
|
||||
dependencies = [
|
||||
"console",
|
||||
"globset",
|
||||
"once_cell",
|
||||
"similar",
|
||||
"tempfile",
|
||||
"walkdir",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -234,6 +268,23 @@ version = "6.0.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf"
|
||||
|
||||
[[package]]
|
||||
name = "regex-automata"
|
||||
version = "0.4.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6e1dd4122fc1595e8162618945476892eefca7b88c52820e74af6262213cae8f"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
"regex-syntax",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex-syntax"
|
||||
version = "0.8.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dc897dd8d9e8bd1ed8cdad82b5966c3e0ecae09fb1907d58efaa013543185d0a"
|
||||
|
||||
[[package]]
|
||||
name = "rustix"
|
||||
version = "1.1.4"
|
||||
|
|
@ -247,6 +298,15 @@ dependencies = [
|
|||
"windows-sys 0.61.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "same-file"
|
||||
version = "1.0.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502"
|
||||
dependencies = [
|
||||
"winapi-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "semver"
|
||||
version = "1.0.27"
|
||||
|
|
@ -260,6 +320,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e"
|
||||
dependencies = [
|
||||
"serde_core",
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -334,6 +395,7 @@ dependencies = [
|
|||
"insta",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"temple",
|
||||
"thiserror",
|
||||
"winnow",
|
||||
]
|
||||
|
|
@ -376,6 +438,16 @@ version = "0.2.6"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853"
|
||||
|
||||
[[package]]
|
||||
name = "walkdir"
|
||||
version = "2.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b"
|
||||
dependencies = [
|
||||
"same-file",
|
||||
"winapi-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasip2"
|
||||
version = "1.0.2+wasi-0.2.9"
|
||||
|
|
@ -428,6 +500,15 @@ dependencies = [
|
|||
"semver",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi-util"
|
||||
version = "0.1.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22"
|
||||
dependencies = [
|
||||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-link"
|
||||
version = "0.2.1"
|
||||
|
|
|
|||
12
Cargo.toml
12
Cargo.toml
|
|
@ -6,11 +6,19 @@ edition = "2024"
|
|||
[dependencies]
|
||||
annotate-snippets = "0.12.13"
|
||||
displaydoc = "0.2.5"
|
||||
serde = "1.0.228"
|
||||
serde = { version = "1.0.228", features = ["derive"] }
|
||||
serde_json = "1.0.149"
|
||||
thiserror = "2.0.18"
|
||||
winnow = { version = "0.7.14", features = ["unstable-recover"] }
|
||||
|
||||
[dev-dependencies]
|
||||
annotate-snippets = { version = "0.12.13", features = ["testing-colors"] }
|
||||
insta = "1.46.3"
|
||||
insta = { version = "1.46.3", features = ["glob"] }
|
||||
temple = { path = ".", features = ["serialize"] }
|
||||
|
||||
[profile.dev.package]
|
||||
insta.opt-level = 3
|
||||
similar.opt-level = 3
|
||||
|
||||
[features]
|
||||
serialize = []
|
||||
|
|
|
|||
|
|
@ -15,7 +15,10 @@ pub enum EvaluationError {
|
|||
ExplicitAbort,
|
||||
}
|
||||
|
||||
pub fn execute(instructions: &[Instruction], global_context: &Context) -> Result<String, EvaluationError> {
|
||||
pub fn execute(
|
||||
instructions: &[Instruction],
|
||||
global_context: &Context,
|
||||
) -> Result<String, EvaluationError> {
|
||||
let mut output = String::new();
|
||||
|
||||
let mut scopes: HashMap<crate::emit::VariableSlot, serde_json::Value> = HashMap::new();
|
||||
|
|
|
|||
19
src/input.rs
19
src/input.rs
|
|
@ -14,12 +14,31 @@ pub struct TempleInput {
|
|||
range: Range<usize>,
|
||||
}
|
||||
|
||||
impl TempleInput {
|
||||
pub fn from_parts(backing: Arc<str>, range: Range<usize>) -> TempleInput {
|
||||
TempleInput { backing, range }
|
||||
}
|
||||
|
||||
pub fn into_parts(self) -> (Arc<str>, Range<usize>) {
|
||||
(self.backing, self.range)
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Debug for TempleInput {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "\"{}\"", self.as_str())
|
||||
}
|
||||
}
|
||||
|
||||
impl From<String> for TempleInput {
|
||||
fn from(value: String) -> Self {
|
||||
let range = 0..value.len();
|
||||
let backing = Arc::from(value);
|
||||
|
||||
TempleInput { backing, range }
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&str> for TempleInput {
|
||||
fn from(value: &str) -> Self {
|
||||
let backing = Arc::from(value.to_string());
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ use crate::input::TempleInput;
|
|||
pub mod ast;
|
||||
pub mod emit;
|
||||
pub mod eval;
|
||||
mod input;
|
||||
pub mod input;
|
||||
pub mod parser;
|
||||
|
||||
#[derive(Debug, Error, Display)]
|
||||
|
|
|
|||
42
tests/cases/ast@interpolation.snap
Normal file
42
tests/cases/ast@interpolation.snap
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
---
|
||||
source: tests/file_tests.rs
|
||||
expression: ast
|
||||
input_file: tests/cases/interpolation.temple
|
||||
---
|
||||
TemplateAst {
|
||||
root: [
|
||||
StaticContent(
|
||||
TemplateToken {
|
||||
kind: Content,
|
||||
source: "Hello! I'm",
|
||||
},
|
||||
),
|
||||
Interpolation {
|
||||
prev_whitespace: Some(
|
||||
TemplateToken {
|
||||
kind: Whitespace,
|
||||
source: " ",
|
||||
},
|
||||
),
|
||||
wants_output: Some(
|
||||
TemplateToken {
|
||||
kind: WantsOutput,
|
||||
source: "=",
|
||||
},
|
||||
),
|
||||
expression: VariableAccess(
|
||||
TemplateToken {
|
||||
kind: Ident,
|
||||
source: "name",
|
||||
},
|
||||
),
|
||||
post_whitespace: Some(
|
||||
TemplateToken {
|
||||
kind: Whitespace,
|
||||
source: "
|
||||
",
|
||||
},
|
||||
),
|
||||
},
|
||||
],
|
||||
}
|
||||
16
tests/cases/ast@simple.snap
Normal file
16
tests/cases/ast@simple.snap
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
---
|
||||
source: tests/file_tests.rs
|
||||
expression: ast
|
||||
input_file: tests/cases/simple.temple
|
||||
---
|
||||
TemplateAst {
|
||||
root: [
|
||||
StaticContent(
|
||||
TemplateToken {
|
||||
kind: Content,
|
||||
source: "Hello World!
|
||||
",
|
||||
},
|
||||
),
|
||||
],
|
||||
}
|
||||
28
tests/cases/instructions@interpolation.snap
Normal file
28
tests/cases/instructions@interpolation.snap
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
---
|
||||
source: tests/file_tests.rs
|
||||
expression: emit
|
||||
input_file: tests/cases/interpolation.temple
|
||||
---
|
||||
[
|
||||
AppendContent {
|
||||
content: "Hello! I'm",
|
||||
},
|
||||
AppendContent {
|
||||
content: " ",
|
||||
},
|
||||
LoadFromContextToSlot {
|
||||
name: "name",
|
||||
slot: VariableSlot {
|
||||
index: 0,
|
||||
},
|
||||
},
|
||||
EmitFromSlot {
|
||||
slot: VariableSlot {
|
||||
index: 0,
|
||||
},
|
||||
},
|
||||
AppendContent {
|
||||
content: "
|
||||
",
|
||||
},
|
||||
]
|
||||
11
tests/cases/instructions@simple.snap
Normal file
11
tests/cases/instructions@simple.snap
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
---
|
||||
source: tests/file_tests.rs
|
||||
expression: emit
|
||||
input_file: tests/cases/simple.temple
|
||||
---
|
||||
[
|
||||
AppendContent {
|
||||
content: "Hello World!
|
||||
",
|
||||
},
|
||||
]
|
||||
5
tests/cases/interpolation.temple
Normal file
5
tests/cases/interpolation.temple
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"name": "Hemera"
|
||||
}
|
||||
---
|
||||
Hello! I'm {{= name }}
|
||||
6
tests/cases/output@interpolation.snap
Normal file
6
tests/cases/output@interpolation.snap
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
---
|
||||
source: tests/file_tests.rs
|
||||
expression: output
|
||||
input_file: tests/cases/interpolation.temple
|
||||
---
|
||||
"Hello! I'm Hemera\n"
|
||||
6
tests/cases/output@simple.snap
Normal file
6
tests/cases/output@simple.snap
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
---
|
||||
source: tests/file_tests.rs
|
||||
expression: output
|
||||
input_file: tests/cases/simple.temple
|
||||
---
|
||||
"Hello World!\n"
|
||||
46
tests/cases/parsed@interpolation.snap
Normal file
46
tests/cases/parsed@interpolation.snap
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
---
|
||||
source: tests/file_tests.rs
|
||||
expression: parsed
|
||||
input_file: tests/cases/interpolation.temple
|
||||
---
|
||||
ParsedTemplate {
|
||||
tokens: [
|
||||
TemplateToken {
|
||||
kind: Content,
|
||||
source: "Hello! I'm",
|
||||
},
|
||||
TemplateToken {
|
||||
kind: Whitespace,
|
||||
source: " ",
|
||||
},
|
||||
TemplateToken {
|
||||
kind: LeftDelim,
|
||||
source: "{{",
|
||||
},
|
||||
TemplateToken {
|
||||
kind: WantsOutput,
|
||||
source: "=",
|
||||
},
|
||||
TemplateToken {
|
||||
kind: Whitespace,
|
||||
source: " ",
|
||||
},
|
||||
TemplateToken {
|
||||
kind: Ident,
|
||||
source: "name",
|
||||
},
|
||||
TemplateToken {
|
||||
kind: Whitespace,
|
||||
source: " ",
|
||||
},
|
||||
TemplateToken {
|
||||
kind: RightDelim,
|
||||
source: "}}",
|
||||
},
|
||||
TemplateToken {
|
||||
kind: Whitespace,
|
||||
source: "
|
||||
",
|
||||
},
|
||||
],
|
||||
}
|
||||
14
tests/cases/parsed@simple.snap
Normal file
14
tests/cases/parsed@simple.snap
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
---
|
||||
source: tests/file_tests.rs
|
||||
expression: parsed
|
||||
input_file: tests/cases/simple.temple
|
||||
---
|
||||
ParsedTemplate {
|
||||
tokens: [
|
||||
TemplateToken {
|
||||
kind: Content,
|
||||
source: "Hello World!
|
||||
",
|
||||
},
|
||||
],
|
||||
}
|
||||
1
tests/cases/simple.temple
Normal file
1
tests/cases/simple.temple
Normal file
|
|
@ -0,0 +1 @@
|
|||
Hello World!
|
||||
46
tests/file_tests.rs
Normal file
46
tests/file_tests.rs
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
use std::collections::HashMap;
|
||||
|
||||
use temple::Context;
|
||||
|
||||
#[test]
|
||||
fn check_cases() {
|
||||
insta::glob!("cases/*.temple", |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);
|
||||
let _guard = settings.bind_to_scope();
|
||||
|
||||
let input = std::fs::read_to_string(path).unwrap();
|
||||
|
||||
let (context, input) = input.split_once("\n---\n").unwrap_or_else(|| ("", &input));
|
||||
|
||||
let map = if !context.is_empty() {
|
||||
serde_json::from_str::<HashMap<String, serde_json::Value>>(context).unwrap()
|
||||
} else {
|
||||
HashMap::new()
|
||||
};
|
||||
|
||||
let mut context = Context::new();
|
||||
|
||||
for (k, v) in map {
|
||||
context.insert(k, v);
|
||||
}
|
||||
|
||||
let parsed = temple::parser::parse(input.into()).unwrap();
|
||||
|
||||
insta::assert_debug_snapshot!("parsed", parsed);
|
||||
|
||||
let ast = temple::ast::parse(parsed.tokens()).unwrap();
|
||||
|
||||
insta::assert_debug_snapshot!("ast", ast);
|
||||
|
||||
let emit = temple::emit::emit_machine(ast);
|
||||
|
||||
insta::assert_debug_snapshot!("instructions", emit);
|
||||
|
||||
let output = temple::eval::execute(&emit, &context).unwrap();
|
||||
|
||||
insta::assert_debug_snapshot!("output", output);
|
||||
});
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue