KCL: New simulation test pipeline (#4351)
The idea behind this is to test all the various stages of executing KCL separately, i.e. - Start with a program - Tokenize it - Parse those tokens into an AST - Recast the AST - Execute the AST, outputting - a PNG of the rendered model - serialized program memory Each of these steps reads some input and writes some output to disk. The output of one step becomes the input to the next step. These intermediate artifacts are also snapshotted (like expectorate or 2020) to ensure we're aware of any changes to how KCL works. A change could be a bug, or it could be harmless, or deliberate, but keeping it checked into the repo means we can easily track changes. Note: UUIDs sent back by the engine are currently nondeterministic, so they would break all the snapshot tests. So, the snapshots use a regex filter and replace anything that looks like a uuid with [uuid] when writing program memory to a snapshot. In the future I hope our UUIDs will be seedable and easy to make deterministic. At that point, we can stop filtering the UUIDs. We run this pipeline on many different KCL programs. Each keeps its inputs (KCL programs), outputs (PNG, program memory snapshot) and intermediate artifacts (AST, token lists, etc) in that directory. I also added a new `just` command to easily generate these tests. You can run `just new-sim-test gear $(cat gear.kcl)` to set up a new gear test directory and generate all the intermediate artifacts for the first time. This doesn't need any macros, it just appends some new lines of normal Rust source code to `tests.rs`, so it's easy to see exactly what the code is doing. This uses `cargo insta` for convenient snapshot testing of artifacts as JSON, and `twenty-twenty` for snapshotting PNGs. This was heavily inspired by Predrag Gruevski's talk at EuroRust 2024 about deterministic simulation testing, and how it can both reduce bugs and also reduce testing/CI time. Very grateful to him for chatting with me about this over the last couple of weeks.
This commit is contained in:
2
src/wasm-lib/.config/insta.yaml
Normal file
2
src/wasm-lib/.config/insta.yaml
Normal file
@ -0,0 +1,2 @@
|
||||
test:
|
||||
runner: nextest
|
||||
5
src/wasm-lib/Cargo.lock
generated
5
src/wasm-lib/Cargo.lock
generated
@ -1453,13 +1453,14 @@ checksum = "a257582fdcde896fd96463bf2d40eefea0580021c0712a0e2b028b60b47a837a"
|
||||
|
||||
[[package]]
|
||||
name = "insta"
|
||||
version = "1.40.0"
|
||||
version = "1.41.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6593a41c7a73841868772495db7dc1e8ecab43bb5c0b6da2059246c4b506ab60"
|
||||
checksum = "a1f72d3e19488cf7d8ea52d2fc0f8754fc933398b337cd3cbdb28aaeb35159ef"
|
||||
dependencies = [
|
||||
"console",
|
||||
"lazy_static",
|
||||
"linked-hash-map",
|
||||
"regex",
|
||||
"serde",
|
||||
"similar",
|
||||
]
|
||||
|
||||
@ -57,6 +57,10 @@ debug = true
|
||||
[profile.dev]
|
||||
debug = 0
|
||||
|
||||
[profile.dev.package]
|
||||
insta.opt-level = 3
|
||||
similar.opt-level = 3
|
||||
|
||||
[profile.test]
|
||||
debug = "line-tables-only"
|
||||
|
||||
|
||||
@ -1,10 +1,29 @@
|
||||
cnr := "cargo nextest run"
|
||||
cita := "cargo insta test --accept"
|
||||
|
||||
# Create a new KCL snapshot test from `tests/inputs/my-test.kcl`.
|
||||
new-test name:
|
||||
echo "kcl_test!(\"{{name}}\", {{name}});" >> tests/executor/visuals.rs
|
||||
TWENTY_TWENTY=overwrite cargo nextest run --test executor -E 'test(=visuals::{{name}})'
|
||||
TWENTY_TWENTY=overwrite {{cnr}} --test executor -E 'test(=visuals::{{name}})'
|
||||
|
||||
lint:
|
||||
cargo clippy --workspace --all-targets -- -D warnings
|
||||
|
||||
redo-kcl-stdlib-docs:
|
||||
EXPECTORATE=overwrite cargo nextest run -p kcl-lib docs::gen_std_tests::test_generate_stdlib
|
||||
EXPECTORATE=overwrite {{cnr}} -p kcl-lib docs::gen_std_tests::test_generate_stdlib
|
||||
|
||||
# Create a new KCL deterministic simulation test case.
|
||||
new-sim-test test_name kcl_program:
|
||||
# Each test file gets its own directory. This will contain the KCL program, and its
|
||||
# snapshotted artifacts (e.g. serialized tokens, serialized ASTs, program memory,
|
||||
# PNG snapshots, etc).
|
||||
mkdir kcl/tests/{{test_name}}
|
||||
echo "{{kcl_program}}" > kcl/tests/{{test_name}}/input.kcl
|
||||
# Add the various tests for this new test case.
|
||||
cat kcl/tests/simtest.tmpl | sed "s/TEST_NAME_HERE/{{test_name}}/" >> kcl/src/tests.rs
|
||||
# Run all the tests for the first time, in the right order.
|
||||
{{cita}} -p kcl-lib -- tests::{{test_name}}::tokenize
|
||||
{{cita}} -p kcl-lib -- tests::{{test_name}}::parse
|
||||
{{cita}} -p kcl-lib -- tests::{{test_name}}::unparse
|
||||
TWENTY_TWENTY=overwrite {{cita}} -p kcl-lib -- tests::{{test_name}}::kcl_test_execute
|
||||
|
||||
|
||||
@ -77,16 +77,8 @@ engine = []
|
||||
pyo3 = ["dep:pyo3"]
|
||||
# Helper functions also used in benchmarks.
|
||||
lsp-test-util = []
|
||||
|
||||
tabled = ["dep:tabled"]
|
||||
|
||||
[profile.release]
|
||||
panic = "abort"
|
||||
debug = true
|
||||
|
||||
[profile.bench]
|
||||
debug = true # Flamegraphs of benchmarks require accurate debug symbols
|
||||
|
||||
[dev-dependencies]
|
||||
base64 = "0.22.1"
|
||||
criterion = { version = "0.5.1", features = ["async_tokio"] }
|
||||
@ -94,7 +86,7 @@ expectorate = "1.1.0"
|
||||
handlebars = "6.2.0"
|
||||
iai = "0.1"
|
||||
image = { version = "0.25.3", default-features = false, features = ["png"] }
|
||||
insta = { version = "1.40.0", features = ["json"] }
|
||||
insta = { version = "1.41.0", features = ["json", "filters"] }
|
||||
itertools = "0.13.0"
|
||||
pretty_assertions = "1.4.1"
|
||||
tokio = { version = "1.40.0", features = ["rt-multi-thread", "macros", "time"] }
|
||||
|
||||
@ -2454,7 +2454,19 @@ impl ExecutorContext {
|
||||
id_generator: IdGenerator,
|
||||
project_directory: Option<String>,
|
||||
) -> Result<TakeSnapshot> {
|
||||
let _ = self.run(program, None, id_generator, project_directory).await?;
|
||||
self.execute_and_prepare(program, id_generator, project_directory)
|
||||
.await
|
||||
.map(|(_state, snap)| snap)
|
||||
}
|
||||
|
||||
/// Execute the program, return the interpreter and outputs.
|
||||
pub async fn execute_and_prepare(
|
||||
&self,
|
||||
program: &Program,
|
||||
id_generator: IdGenerator,
|
||||
project_directory: Option<String>,
|
||||
) -> Result<(ExecState, TakeSnapshot)> {
|
||||
let state = self.run(program, None, id_generator, project_directory).await?;
|
||||
|
||||
// Zoom to fit.
|
||||
self.engine
|
||||
@ -2487,7 +2499,7 @@ impl ExecutorContext {
|
||||
else {
|
||||
anyhow::bail!("Unexpected response from engine: {:?}", resp);
|
||||
};
|
||||
Ok(contents)
|
||||
Ok((state, contents))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -25,6 +25,8 @@ pub mod lint;
|
||||
pub mod lsp;
|
||||
pub mod parser;
|
||||
pub mod settings;
|
||||
#[cfg(test)]
|
||||
mod simulation_tests;
|
||||
pub mod std;
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
pub mod test_server;
|
||||
|
||||
@ -3043,7 +3043,6 @@ e
|
||||
let parser = crate::parser::Parser::new(tokens);
|
||||
let result = parser.ast();
|
||||
assert!(result.is_err());
|
||||
dbg!(&result);
|
||||
assert!(result
|
||||
.err()
|
||||
.unwrap()
|
||||
|
||||
130
src/wasm-lib/kcl/src/simulation_tests.rs
Normal file
130
src/wasm-lib/kcl/src/simulation_tests.rs
Normal file
@ -0,0 +1,130 @@
|
||||
use crate::{ast::types::Program, errors::KclError, parser::Parser, token::Token};
|
||||
|
||||
/// Deserialize the data from a snapshot.
|
||||
fn get<T: serde::de::DeserializeOwned>(snapshot: &str) -> T {
|
||||
let mut parts = snapshot.split("---");
|
||||
let _empty = parts.next().unwrap();
|
||||
let _header = parts.next().unwrap();
|
||||
let snapshot_data = parts.next().unwrap();
|
||||
serde_json::from_str(snapshot_data)
|
||||
.and_then(serde_json::from_value)
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
fn assert_snapshot<F, R>(test_name: &str, operation: &str, f: F)
|
||||
where
|
||||
F: FnOnce() -> R,
|
||||
{
|
||||
let mut settings = insta::Settings::clone_current();
|
||||
// These make the snapshots more readable and match our dir structure.
|
||||
settings.set_omit_expression(true);
|
||||
settings.set_snapshot_path(format!("../tests/{test_name}"));
|
||||
settings.set_prepend_module_to_snapshot(false);
|
||||
settings.set_description(format!("{operation} {test_name}.kcl"));
|
||||
// Sorting maps makes them easier to diff.
|
||||
settings.set_sort_maps(true);
|
||||
// Replace UUIDs with the string "[uuid]", because otherwise the tests would constantly
|
||||
// be changing the UUID. This is a stopgap measure until we make the engine more deterministic.
|
||||
settings.add_filter(
|
||||
r"\b[[:xdigit:]]{8}-[[:xdigit:]]{4}-[[:xdigit:]]{4}-[[:xdigit:]]{4}-[[:xdigit:]]{12}\b",
|
||||
"[uuid]",
|
||||
);
|
||||
// Run `f` (the closure that was passed in) with these settings.
|
||||
settings.bind(f);
|
||||
}
|
||||
|
||||
fn read(filename: &'static str, test_name: &str) -> String {
|
||||
std::fs::read_to_string(format!("tests/{test_name}/{filename}")).unwrap()
|
||||
}
|
||||
|
||||
fn tokenize(test_name: &str) {
|
||||
let input = read("input.kcl", test_name);
|
||||
let token_res = crate::token::lexer(&input);
|
||||
|
||||
assert_snapshot(test_name, "Result of tokenizing", || {
|
||||
insta::assert_json_snapshot!("tokens", token_res);
|
||||
});
|
||||
}
|
||||
|
||||
fn parse(test_name: &str) {
|
||||
let input = read("tokens.snap", test_name);
|
||||
let tokens: Result<Vec<Token>, KclError> = get(&input);
|
||||
let Ok(tokens) = tokens else {
|
||||
return;
|
||||
};
|
||||
|
||||
// Parse the tokens into an AST.
|
||||
let parse_res = Parser::new(tokens).ast();
|
||||
assert_snapshot(test_name, "Result of parsing", || {
|
||||
insta::assert_json_snapshot!("ast", parse_res);
|
||||
});
|
||||
}
|
||||
|
||||
fn unparse(test_name: &str) {
|
||||
let input = read("ast.snap", test_name);
|
||||
let ast_res: Result<Program, KclError> = get(&input);
|
||||
let Ok(ast) = ast_res else {
|
||||
return;
|
||||
};
|
||||
// Check recasting the AST produces the original string.
|
||||
let actual = ast.recast(&Default::default(), 0);
|
||||
let expected = read("input.kcl", test_name);
|
||||
pretty_assertions::assert_eq!(
|
||||
actual,
|
||||
expected,
|
||||
"Parse then unparse didn't recreate the original KCL file"
|
||||
);
|
||||
}
|
||||
|
||||
async fn execute(test_name: &str) {
|
||||
// Read the AST from disk.
|
||||
let input = read("ast.snap", test_name);
|
||||
let ast_res: Result<Program, KclError> = get(&input);
|
||||
let Ok(ast) = ast_res else {
|
||||
return;
|
||||
};
|
||||
|
||||
// Run the program.
|
||||
let exec_res = crate::test_server::execute_and_snapshot_ast(ast, crate::settings::types::UnitLength::Mm).await;
|
||||
match exec_res {
|
||||
Ok((program_memory, png)) => {
|
||||
twenty_twenty::assert_image(format!("tests/{test_name}/rendered_model.png"), &png, 0.99);
|
||||
assert_snapshot(test_name, "Program memory after executing", || {
|
||||
insta::assert_json_snapshot!("program_memory", program_memory);
|
||||
});
|
||||
}
|
||||
Err(e) => {
|
||||
assert_snapshot(test_name, "Error from executing", || {
|
||||
insta::assert_snapshot!("execution_error", e);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mod cube {
|
||||
const TEST_NAME: &str = "cube";
|
||||
|
||||
/// Test tokenizing KCL.
|
||||
#[test]
|
||||
fn tokenize() {
|
||||
super::tokenize(TEST_NAME)
|
||||
}
|
||||
|
||||
/// Test parsing KCL.
|
||||
#[test]
|
||||
fn parse() {
|
||||
super::parse(TEST_NAME)
|
||||
}
|
||||
|
||||
/// Test that parsing and unparsing KCL produces the original KCL input.
|
||||
#[test]
|
||||
fn unparse() {
|
||||
super::unparse(TEST_NAME)
|
||||
}
|
||||
|
||||
/// Test that KCL is executed correctly.
|
||||
#[tokio::test(flavor = "multi_thread")]
|
||||
async fn kcl_test_execute() {
|
||||
super::execute(TEST_NAME).await
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,969 @@
|
||||
---
|
||||
source: kcl/src/tests.rs
|
||||
expression: tokens
|
||||
---
|
||||
Ok:
|
||||
- type: keyword
|
||||
start: 0
|
||||
end: 2
|
||||
value: fn
|
||||
- type: whitespace
|
||||
start: 2
|
||||
end: 3
|
||||
value: " "
|
||||
- type: word
|
||||
start: 3
|
||||
end: 9
|
||||
value: square
|
||||
- type: whitespace
|
||||
start: 9
|
||||
end: 10
|
||||
value: " "
|
||||
- type: operator
|
||||
start: 10
|
||||
end: 11
|
||||
value: "="
|
||||
- type: whitespace
|
||||
start: 11
|
||||
end: 12
|
||||
value: " "
|
||||
- type: brace
|
||||
start: 12
|
||||
end: 13
|
||||
value: (
|
||||
- type: word
|
||||
start: 13
|
||||
end: 19
|
||||
value: length
|
||||
- type: comma
|
||||
start: 19
|
||||
end: 20
|
||||
value: ","
|
||||
- type: whitespace
|
||||
start: 20
|
||||
end: 21
|
||||
value: " "
|
||||
- type: word
|
||||
start: 21
|
||||
end: 27
|
||||
value: center
|
||||
- type: brace
|
||||
start: 27
|
||||
end: 28
|
||||
value: )
|
||||
- type: whitespace
|
||||
start: 28
|
||||
end: 29
|
||||
value: " "
|
||||
- type: operator
|
||||
start: 29
|
||||
end: 31
|
||||
value: "=>"
|
||||
- type: whitespace
|
||||
start: 31
|
||||
end: 32
|
||||
value: " "
|
||||
- type: brace
|
||||
start: 32
|
||||
end: 33
|
||||
value: "{"
|
||||
- type: whitespace
|
||||
start: 33
|
||||
end: 36
|
||||
value: "\n "
|
||||
- type: word
|
||||
start: 36
|
||||
end: 37
|
||||
value: l
|
||||
- type: whitespace
|
||||
start: 37
|
||||
end: 38
|
||||
value: " "
|
||||
- type: operator
|
||||
start: 38
|
||||
end: 39
|
||||
value: "="
|
||||
- type: whitespace
|
||||
start: 39
|
||||
end: 40
|
||||
value: " "
|
||||
- type: word
|
||||
start: 40
|
||||
end: 46
|
||||
value: length
|
||||
- type: whitespace
|
||||
start: 46
|
||||
end: 47
|
||||
value: " "
|
||||
- type: operator
|
||||
start: 47
|
||||
end: 48
|
||||
value: /
|
||||
- type: whitespace
|
||||
start: 48
|
||||
end: 49
|
||||
value: " "
|
||||
- type: number
|
||||
start: 49
|
||||
end: 50
|
||||
value: "2"
|
||||
- type: whitespace
|
||||
start: 50
|
||||
end: 53
|
||||
value: "\n "
|
||||
- type: word
|
||||
start: 53
|
||||
end: 54
|
||||
value: x
|
||||
- type: whitespace
|
||||
start: 54
|
||||
end: 55
|
||||
value: " "
|
||||
- type: operator
|
||||
start: 55
|
||||
end: 56
|
||||
value: "="
|
||||
- type: whitespace
|
||||
start: 56
|
||||
end: 57
|
||||
value: " "
|
||||
- type: word
|
||||
start: 57
|
||||
end: 63
|
||||
value: center
|
||||
- type: brace
|
||||
start: 63
|
||||
end: 64
|
||||
value: "["
|
||||
- type: number
|
||||
start: 64
|
||||
end: 65
|
||||
value: "0"
|
||||
- type: brace
|
||||
start: 65
|
||||
end: 66
|
||||
value: "]"
|
||||
- type: whitespace
|
||||
start: 66
|
||||
end: 69
|
||||
value: "\n "
|
||||
- type: word
|
||||
start: 69
|
||||
end: 70
|
||||
value: y
|
||||
- type: whitespace
|
||||
start: 70
|
||||
end: 71
|
||||
value: " "
|
||||
- type: operator
|
||||
start: 71
|
||||
end: 72
|
||||
value: "="
|
||||
- type: whitespace
|
||||
start: 72
|
||||
end: 73
|
||||
value: " "
|
||||
- type: word
|
||||
start: 73
|
||||
end: 79
|
||||
value: center
|
||||
- type: brace
|
||||
start: 79
|
||||
end: 80
|
||||
value: "["
|
||||
- type: number
|
||||
start: 80
|
||||
end: 81
|
||||
value: "1"
|
||||
- type: brace
|
||||
start: 81
|
||||
end: 82
|
||||
value: "]"
|
||||
- type: whitespace
|
||||
start: 82
|
||||
end: 85
|
||||
value: "\n "
|
||||
- type: word
|
||||
start: 85
|
||||
end: 87
|
||||
value: p0
|
||||
- type: whitespace
|
||||
start: 87
|
||||
end: 88
|
||||
value: " "
|
||||
- type: operator
|
||||
start: 88
|
||||
end: 89
|
||||
value: "="
|
||||
- type: whitespace
|
||||
start: 89
|
||||
end: 90
|
||||
value: " "
|
||||
- type: brace
|
||||
start: 90
|
||||
end: 91
|
||||
value: "["
|
||||
- type: operator
|
||||
start: 91
|
||||
end: 92
|
||||
value: "-"
|
||||
- type: word
|
||||
start: 92
|
||||
end: 93
|
||||
value: l
|
||||
- type: whitespace
|
||||
start: 93
|
||||
end: 94
|
||||
value: " "
|
||||
- type: operator
|
||||
start: 94
|
||||
end: 95
|
||||
value: +
|
||||
- type: whitespace
|
||||
start: 95
|
||||
end: 96
|
||||
value: " "
|
||||
- type: word
|
||||
start: 96
|
||||
end: 97
|
||||
value: x
|
||||
- type: comma
|
||||
start: 97
|
||||
end: 98
|
||||
value: ","
|
||||
- type: whitespace
|
||||
start: 98
|
||||
end: 99
|
||||
value: " "
|
||||
- type: operator
|
||||
start: 99
|
||||
end: 100
|
||||
value: "-"
|
||||
- type: word
|
||||
start: 100
|
||||
end: 101
|
||||
value: l
|
||||
- type: whitespace
|
||||
start: 101
|
||||
end: 102
|
||||
value: " "
|
||||
- type: operator
|
||||
start: 102
|
||||
end: 103
|
||||
value: +
|
||||
- type: whitespace
|
||||
start: 103
|
||||
end: 104
|
||||
value: " "
|
||||
- type: word
|
||||
start: 104
|
||||
end: 105
|
||||
value: y
|
||||
- type: brace
|
||||
start: 105
|
||||
end: 106
|
||||
value: "]"
|
||||
- type: whitespace
|
||||
start: 106
|
||||
end: 109
|
||||
value: "\n "
|
||||
- type: word
|
||||
start: 109
|
||||
end: 111
|
||||
value: p1
|
||||
- type: whitespace
|
||||
start: 111
|
||||
end: 112
|
||||
value: " "
|
||||
- type: operator
|
||||
start: 112
|
||||
end: 113
|
||||
value: "="
|
||||
- type: whitespace
|
||||
start: 113
|
||||
end: 114
|
||||
value: " "
|
||||
- type: brace
|
||||
start: 114
|
||||
end: 115
|
||||
value: "["
|
||||
- type: operator
|
||||
start: 115
|
||||
end: 116
|
||||
value: "-"
|
||||
- type: word
|
||||
start: 116
|
||||
end: 117
|
||||
value: l
|
||||
- type: whitespace
|
||||
start: 117
|
||||
end: 118
|
||||
value: " "
|
||||
- type: operator
|
||||
start: 118
|
||||
end: 119
|
||||
value: +
|
||||
- type: whitespace
|
||||
start: 119
|
||||
end: 120
|
||||
value: " "
|
||||
- type: word
|
||||
start: 120
|
||||
end: 121
|
||||
value: x
|
||||
- type: comma
|
||||
start: 121
|
||||
end: 122
|
||||
value: ","
|
||||
- type: whitespace
|
||||
start: 122
|
||||
end: 124
|
||||
value: " "
|
||||
- type: word
|
||||
start: 124
|
||||
end: 125
|
||||
value: l
|
||||
- type: whitespace
|
||||
start: 125
|
||||
end: 126
|
||||
value: " "
|
||||
- type: operator
|
||||
start: 126
|
||||
end: 127
|
||||
value: +
|
||||
- type: whitespace
|
||||
start: 127
|
||||
end: 128
|
||||
value: " "
|
||||
- type: word
|
||||
start: 128
|
||||
end: 129
|
||||
value: y
|
||||
- type: brace
|
||||
start: 129
|
||||
end: 130
|
||||
value: "]"
|
||||
- type: whitespace
|
||||
start: 130
|
||||
end: 133
|
||||
value: "\n "
|
||||
- type: word
|
||||
start: 133
|
||||
end: 135
|
||||
value: p2
|
||||
- type: whitespace
|
||||
start: 135
|
||||
end: 136
|
||||
value: " "
|
||||
- type: operator
|
||||
start: 136
|
||||
end: 137
|
||||
value: "="
|
||||
- type: whitespace
|
||||
start: 137
|
||||
end: 138
|
||||
value: " "
|
||||
- type: brace
|
||||
start: 138
|
||||
end: 139
|
||||
value: "["
|
||||
- type: whitespace
|
||||
start: 139
|
||||
end: 140
|
||||
value: " "
|
||||
- type: word
|
||||
start: 140
|
||||
end: 141
|
||||
value: l
|
||||
- type: whitespace
|
||||
start: 141
|
||||
end: 142
|
||||
value: " "
|
||||
- type: operator
|
||||
start: 142
|
||||
end: 143
|
||||
value: +
|
||||
- type: whitespace
|
||||
start: 143
|
||||
end: 144
|
||||
value: " "
|
||||
- type: word
|
||||
start: 144
|
||||
end: 145
|
||||
value: x
|
||||
- type: comma
|
||||
start: 145
|
||||
end: 146
|
||||
value: ","
|
||||
- type: whitespace
|
||||
start: 146
|
||||
end: 148
|
||||
value: " "
|
||||
- type: word
|
||||
start: 148
|
||||
end: 149
|
||||
value: l
|
||||
- type: whitespace
|
||||
start: 149
|
||||
end: 150
|
||||
value: " "
|
||||
- type: operator
|
||||
start: 150
|
||||
end: 151
|
||||
value: +
|
||||
- type: whitespace
|
||||
start: 151
|
||||
end: 152
|
||||
value: " "
|
||||
- type: word
|
||||
start: 152
|
||||
end: 153
|
||||
value: y
|
||||
- type: brace
|
||||
start: 153
|
||||
end: 154
|
||||
value: "]"
|
||||
- type: whitespace
|
||||
start: 154
|
||||
end: 157
|
||||
value: "\n "
|
||||
- type: word
|
||||
start: 157
|
||||
end: 159
|
||||
value: p3
|
||||
- type: whitespace
|
||||
start: 159
|
||||
end: 160
|
||||
value: " "
|
||||
- type: operator
|
||||
start: 160
|
||||
end: 161
|
||||
value: "="
|
||||
- type: whitespace
|
||||
start: 161
|
||||
end: 162
|
||||
value: " "
|
||||
- type: brace
|
||||
start: 162
|
||||
end: 163
|
||||
value: "["
|
||||
- type: whitespace
|
||||
start: 163
|
||||
end: 164
|
||||
value: " "
|
||||
- type: word
|
||||
start: 164
|
||||
end: 165
|
||||
value: l
|
||||
- type: whitespace
|
||||
start: 165
|
||||
end: 166
|
||||
value: " "
|
||||
- type: operator
|
||||
start: 166
|
||||
end: 167
|
||||
value: +
|
||||
- type: whitespace
|
||||
start: 167
|
||||
end: 168
|
||||
value: " "
|
||||
- type: word
|
||||
start: 168
|
||||
end: 169
|
||||
value: x
|
||||
- type: comma
|
||||
start: 169
|
||||
end: 170
|
||||
value: ","
|
||||
- type: whitespace
|
||||
start: 170
|
||||
end: 171
|
||||
value: " "
|
||||
- type: operator
|
||||
start: 171
|
||||
end: 172
|
||||
value: "-"
|
||||
- type: word
|
||||
start: 172
|
||||
end: 173
|
||||
value: l
|
||||
- type: whitespace
|
||||
start: 173
|
||||
end: 174
|
||||
value: " "
|
||||
- type: operator
|
||||
start: 174
|
||||
end: 175
|
||||
value: +
|
||||
- type: whitespace
|
||||
start: 175
|
||||
end: 176
|
||||
value: " "
|
||||
- type: word
|
||||
start: 176
|
||||
end: 177
|
||||
value: y
|
||||
- type: brace
|
||||
start: 177
|
||||
end: 178
|
||||
value: "]"
|
||||
- type: whitespace
|
||||
start: 178
|
||||
end: 181
|
||||
value: "\n "
|
||||
- type: keyword
|
||||
start: 181
|
||||
end: 187
|
||||
value: return
|
||||
- type: whitespace
|
||||
start: 187
|
||||
end: 188
|
||||
value: " "
|
||||
- type: word
|
||||
start: 188
|
||||
end: 201
|
||||
value: startSketchAt
|
||||
- type: brace
|
||||
start: 201
|
||||
end: 202
|
||||
value: (
|
||||
- type: word
|
||||
start: 202
|
||||
end: 204
|
||||
value: p0
|
||||
- type: brace
|
||||
start: 204
|
||||
end: 205
|
||||
value: )
|
||||
- type: whitespace
|
||||
start: 205
|
||||
end: 210
|
||||
value: "\n "
|
||||
- type: operator
|
||||
start: 210
|
||||
end: 212
|
||||
value: "|>"
|
||||
- type: whitespace
|
||||
start: 212
|
||||
end: 213
|
||||
value: " "
|
||||
- type: word
|
||||
start: 213
|
||||
end: 219
|
||||
value: lineTo
|
||||
- type: brace
|
||||
start: 219
|
||||
end: 220
|
||||
value: (
|
||||
- type: word
|
||||
start: 220
|
||||
end: 222
|
||||
value: p1
|
||||
- type: comma
|
||||
start: 222
|
||||
end: 223
|
||||
value: ","
|
||||
- type: whitespace
|
||||
start: 223
|
||||
end: 224
|
||||
value: " "
|
||||
- type: operator
|
||||
start: 224
|
||||
end: 225
|
||||
value: "%"
|
||||
- type: brace
|
||||
start: 225
|
||||
end: 226
|
||||
value: )
|
||||
- type: whitespace
|
||||
start: 226
|
||||
end: 231
|
||||
value: "\n "
|
||||
- type: operator
|
||||
start: 231
|
||||
end: 233
|
||||
value: "|>"
|
||||
- type: whitespace
|
||||
start: 233
|
||||
end: 234
|
||||
value: " "
|
||||
- type: word
|
||||
start: 234
|
||||
end: 240
|
||||
value: lineTo
|
||||
- type: brace
|
||||
start: 240
|
||||
end: 241
|
||||
value: (
|
||||
- type: word
|
||||
start: 241
|
||||
end: 243
|
||||
value: p2
|
||||
- type: comma
|
||||
start: 243
|
||||
end: 244
|
||||
value: ","
|
||||
- type: whitespace
|
||||
start: 244
|
||||
end: 245
|
||||
value: " "
|
||||
- type: operator
|
||||
start: 245
|
||||
end: 246
|
||||
value: "%"
|
||||
- type: brace
|
||||
start: 246
|
||||
end: 247
|
||||
value: )
|
||||
- type: whitespace
|
||||
start: 247
|
||||
end: 252
|
||||
value: "\n "
|
||||
- type: operator
|
||||
start: 252
|
||||
end: 254
|
||||
value: "|>"
|
||||
- type: whitespace
|
||||
start: 254
|
||||
end: 255
|
||||
value: " "
|
||||
- type: word
|
||||
start: 255
|
||||
end: 261
|
||||
value: lineTo
|
||||
- type: brace
|
||||
start: 261
|
||||
end: 262
|
||||
value: (
|
||||
- type: word
|
||||
start: 262
|
||||
end: 264
|
||||
value: p3
|
||||
- type: comma
|
||||
start: 264
|
||||
end: 265
|
||||
value: ","
|
||||
- type: whitespace
|
||||
start: 265
|
||||
end: 266
|
||||
value: " "
|
||||
- type: operator
|
||||
start: 266
|
||||
end: 267
|
||||
value: "%"
|
||||
- type: brace
|
||||
start: 267
|
||||
end: 268
|
||||
value: )
|
||||
- type: whitespace
|
||||
start: 268
|
||||
end: 273
|
||||
value: "\n "
|
||||
- type: operator
|
||||
start: 273
|
||||
end: 275
|
||||
value: "|>"
|
||||
- type: whitespace
|
||||
start: 275
|
||||
end: 276
|
||||
value: " "
|
||||
- type: word
|
||||
start: 276
|
||||
end: 282
|
||||
value: lineTo
|
||||
- type: brace
|
||||
start: 282
|
||||
end: 283
|
||||
value: (
|
||||
- type: word
|
||||
start: 283
|
||||
end: 285
|
||||
value: p0
|
||||
- type: comma
|
||||
start: 285
|
||||
end: 286
|
||||
value: ","
|
||||
- type: whitespace
|
||||
start: 286
|
||||
end: 287
|
||||
value: " "
|
||||
- type: operator
|
||||
start: 287
|
||||
end: 288
|
||||
value: "%"
|
||||
- type: brace
|
||||
start: 288
|
||||
end: 289
|
||||
value: )
|
||||
- type: whitespace
|
||||
start: 289
|
||||
end: 294
|
||||
value: "\n "
|
||||
- type: operator
|
||||
start: 294
|
||||
end: 296
|
||||
value: "|>"
|
||||
- type: whitespace
|
||||
start: 296
|
||||
end: 297
|
||||
value: " "
|
||||
- type: word
|
||||
start: 297
|
||||
end: 302
|
||||
value: close
|
||||
- type: brace
|
||||
start: 302
|
||||
end: 303
|
||||
value: (
|
||||
- type: operator
|
||||
start: 303
|
||||
end: 304
|
||||
value: "%"
|
||||
- type: brace
|
||||
start: 304
|
||||
end: 305
|
||||
value: )
|
||||
- type: whitespace
|
||||
start: 305
|
||||
end: 306
|
||||
value: "\n"
|
||||
- type: brace
|
||||
start: 306
|
||||
end: 307
|
||||
value: "}"
|
||||
- type: whitespace
|
||||
start: 307
|
||||
end: 309
|
||||
value: "\n\n"
|
||||
- type: keyword
|
||||
start: 309
|
||||
end: 311
|
||||
value: fn
|
||||
- type: whitespace
|
||||
start: 311
|
||||
end: 312
|
||||
value: " "
|
||||
- type: word
|
||||
start: 312
|
||||
end: 316
|
||||
value: cube
|
||||
- type: whitespace
|
||||
start: 316
|
||||
end: 317
|
||||
value: " "
|
||||
- type: operator
|
||||
start: 317
|
||||
end: 318
|
||||
value: "="
|
||||
- type: whitespace
|
||||
start: 318
|
||||
end: 319
|
||||
value: " "
|
||||
- type: brace
|
||||
start: 319
|
||||
end: 320
|
||||
value: (
|
||||
- type: word
|
||||
start: 320
|
||||
end: 326
|
||||
value: length
|
||||
- type: comma
|
||||
start: 326
|
||||
end: 327
|
||||
value: ","
|
||||
- type: whitespace
|
||||
start: 327
|
||||
end: 328
|
||||
value: " "
|
||||
- type: word
|
||||
start: 328
|
||||
end: 334
|
||||
value: center
|
||||
- type: brace
|
||||
start: 334
|
||||
end: 335
|
||||
value: )
|
||||
- type: whitespace
|
||||
start: 335
|
||||
end: 336
|
||||
value: " "
|
||||
- type: operator
|
||||
start: 336
|
||||
end: 338
|
||||
value: "=>"
|
||||
- type: whitespace
|
||||
start: 338
|
||||
end: 339
|
||||
value: " "
|
||||
- type: brace
|
||||
start: 339
|
||||
end: 340
|
||||
value: "{"
|
||||
- type: whitespace
|
||||
start: 340
|
||||
end: 343
|
||||
value: "\n "
|
||||
- type: keyword
|
||||
start: 343
|
||||
end: 349
|
||||
value: return
|
||||
- type: whitespace
|
||||
start: 349
|
||||
end: 350
|
||||
value: " "
|
||||
- type: word
|
||||
start: 350
|
||||
end: 356
|
||||
value: square
|
||||
- type: brace
|
||||
start: 356
|
||||
end: 357
|
||||
value: (
|
||||
- type: word
|
||||
start: 357
|
||||
end: 363
|
||||
value: length
|
||||
- type: comma
|
||||
start: 363
|
||||
end: 364
|
||||
value: ","
|
||||
- type: whitespace
|
||||
start: 364
|
||||
end: 365
|
||||
value: " "
|
||||
- type: word
|
||||
start: 365
|
||||
end: 371
|
||||
value: center
|
||||
- type: brace
|
||||
start: 371
|
||||
end: 372
|
||||
value: )
|
||||
- type: whitespace
|
||||
start: 372
|
||||
end: 377
|
||||
value: "\n "
|
||||
- type: operator
|
||||
start: 377
|
||||
end: 379
|
||||
value: "|>"
|
||||
- type: whitespace
|
||||
start: 379
|
||||
end: 380
|
||||
value: " "
|
||||
- type: word
|
||||
start: 380
|
||||
end: 387
|
||||
value: extrude
|
||||
- type: brace
|
||||
start: 387
|
||||
end: 388
|
||||
value: (
|
||||
- type: word
|
||||
start: 388
|
||||
end: 394
|
||||
value: length
|
||||
- type: comma
|
||||
start: 394
|
||||
end: 395
|
||||
value: ","
|
||||
- type: whitespace
|
||||
start: 395
|
||||
end: 396
|
||||
value: " "
|
||||
- type: operator
|
||||
start: 396
|
||||
end: 397
|
||||
value: "%"
|
||||
- type: brace
|
||||
start: 397
|
||||
end: 398
|
||||
value: )
|
||||
- type: whitespace
|
||||
start: 398
|
||||
end: 399
|
||||
value: "\n"
|
||||
- type: brace
|
||||
start: 399
|
||||
end: 400
|
||||
value: "}"
|
||||
- type: whitespace
|
||||
start: 400
|
||||
end: 402
|
||||
value: "\n\n"
|
||||
- type: word
|
||||
start: 402
|
||||
end: 407
|
||||
value: width
|
||||
- type: whitespace
|
||||
start: 407
|
||||
end: 408
|
||||
value: " "
|
||||
- type: operator
|
||||
start: 408
|
||||
end: 409
|
||||
value: "="
|
||||
- type: whitespace
|
||||
start: 409
|
||||
end: 410
|
||||
value: " "
|
||||
- type: number
|
||||
start: 410
|
||||
end: 412
|
||||
value: "20"
|
||||
- type: whitespace
|
||||
start: 412
|
||||
end: 413
|
||||
value: "\n"
|
||||
- type: word
|
||||
start: 413
|
||||
end: 417
|
||||
value: cube
|
||||
- type: brace
|
||||
start: 417
|
||||
end: 418
|
||||
value: (
|
||||
- type: word
|
||||
start: 418
|
||||
end: 423
|
||||
value: width
|
||||
- type: comma
|
||||
start: 423
|
||||
end: 424
|
||||
value: ","
|
||||
- type: whitespace
|
||||
start: 424
|
||||
end: 425
|
||||
value: " "
|
||||
- type: brace
|
||||
start: 425
|
||||
end: 426
|
||||
value: "["
|
||||
- type: number
|
||||
start: 426
|
||||
end: 428
|
||||
value: "20"
|
||||
- type: comma
|
||||
start: 428
|
||||
end: 429
|
||||
value: ","
|
||||
- type: whitespace
|
||||
start: 429
|
||||
end: 430
|
||||
value: " "
|
||||
- type: number
|
||||
start: 430
|
||||
end: 431
|
||||
value: "0"
|
||||
- type: brace
|
||||
start: 431
|
||||
end: 432
|
||||
value: "]"
|
||||
- type: brace
|
||||
start: 432
|
||||
end: 433
|
||||
value: )
|
||||
- type: whitespace
|
||||
start: 433
|
||||
end: 434
|
||||
value: "\n"
|
||||
@ -1,7 +1,8 @@
|
||||
//! Types used to send data to the test server.
|
||||
|
||||
use crate::{
|
||||
executor::{new_zoo_client, ExecutorContext, ExecutorSettings, IdGenerator},
|
||||
ast::types::Program,
|
||||
executor::{new_zoo_client, ExecutorContext, ExecutorSettings, IdGenerator, ProgramMemory},
|
||||
settings::types::UnitLength,
|
||||
};
|
||||
|
||||
@ -16,22 +17,37 @@ pub struct RequestBody {
|
||||
/// This returns the bytes of the snapshot.
|
||||
pub async fn execute_and_snapshot(code: &str, units: UnitLength) -> anyhow::Result<image::DynamicImage> {
|
||||
let ctx = new_context(units, true).await?;
|
||||
do_execute_and_snapshot(&ctx, code).await
|
||||
let tokens = crate::token::lexer(code)?;
|
||||
let parser = crate::parser::Parser::new(tokens);
|
||||
let program = parser.ast()?;
|
||||
do_execute_and_snapshot(&ctx, program).await.map(|(_state, snap)| snap)
|
||||
}
|
||||
|
||||
/// Executes a kcl program and takes a snapshot of the result.
|
||||
/// This returns the bytes of the snapshot.
|
||||
pub async fn execute_and_snapshot_ast(
|
||||
ast: Program,
|
||||
units: UnitLength,
|
||||
) -> anyhow::Result<(ProgramMemory, image::DynamicImage)> {
|
||||
let ctx = new_context(units, true).await?;
|
||||
do_execute_and_snapshot(&ctx, ast)
|
||||
.await
|
||||
.map(|(state, snap)| (state.memory, snap))
|
||||
}
|
||||
|
||||
pub async fn execute_and_snapshot_no_auth(code: &str, units: UnitLength) -> anyhow::Result<image::DynamicImage> {
|
||||
let ctx = new_context(units, false).await?;
|
||||
do_execute_and_snapshot(&ctx, code).await
|
||||
}
|
||||
|
||||
async fn do_execute_and_snapshot(ctx: &ExecutorContext, code: &str) -> anyhow::Result<image::DynamicImage> {
|
||||
let tokens = crate::token::lexer(code)?;
|
||||
let parser = crate::parser::Parser::new(tokens);
|
||||
let program = parser.ast()?;
|
||||
do_execute_and_snapshot(&ctx, program).await.map(|(_state, snap)| snap)
|
||||
}
|
||||
|
||||
let snapshot = ctx
|
||||
.execute_and_prepare_snapshot(&program, IdGenerator::default(), None)
|
||||
.await?;
|
||||
async fn do_execute_and_snapshot(
|
||||
ctx: &ExecutorContext,
|
||||
program: Program,
|
||||
) -> anyhow::Result<(crate::executor::ExecState, image::DynamicImage)> {
|
||||
let (exec_state, snapshot) = ctx.execute_and_prepare(&program, IdGenerator::default(), None).await?;
|
||||
|
||||
// Create a temporary file to write the output to.
|
||||
let output_file = std::env::temp_dir().join(format!("kcl_output_{}.png", uuid::Uuid::new_v4()));
|
||||
@ -39,7 +55,7 @@ async fn do_execute_and_snapshot(ctx: &ExecutorContext, code: &str) -> anyhow::R
|
||||
std::fs::write(&output_file, snapshot.contents.0)?;
|
||||
// Decode the snapshot, return it.
|
||||
let img = image::ImageReader::open(output_file).unwrap().decode()?;
|
||||
Ok(img)
|
||||
Ok((exec_state, img))
|
||||
}
|
||||
|
||||
async fn new_context(units: UnitLength, with_auth: bool) -> anyhow::Result<ExecutorContext> {
|
||||
|
||||
795
src/wasm-lib/kcl/tests/cube/ast.snap
Normal file
795
src/wasm-lib/kcl/tests/cube/ast.snap
Normal file
@ -0,0 +1,795 @@
|
||||
---
|
||||
source: kcl/src/tests.rs
|
||||
description: Result of parsing cube.kcl
|
||||
snapshot_kind: text
|
||||
---
|
||||
{
|
||||
"Ok": {
|
||||
"start": 0,
|
||||
"end": 344,
|
||||
"body": [
|
||||
{
|
||||
"type": "VariableDeclaration",
|
||||
"type": "VariableDeclaration",
|
||||
"start": 0,
|
||||
"end": 316,
|
||||
"declarations": [
|
||||
{
|
||||
"type": "VariableDeclarator",
|
||||
"start": 3,
|
||||
"end": 316,
|
||||
"id": {
|
||||
"type": "Identifier",
|
||||
"start": 3,
|
||||
"end": 7,
|
||||
"name": "cube"
|
||||
},
|
||||
"init": {
|
||||
"type": "FunctionExpression",
|
||||
"type": "FunctionExpression",
|
||||
"start": 10,
|
||||
"end": 316,
|
||||
"params": [
|
||||
{
|
||||
"type": "Parameter",
|
||||
"identifier": {
|
||||
"type": "Identifier",
|
||||
"start": 11,
|
||||
"end": 17,
|
||||
"name": "length"
|
||||
},
|
||||
"optional": false
|
||||
},
|
||||
{
|
||||
"type": "Parameter",
|
||||
"identifier": {
|
||||
"type": "Identifier",
|
||||
"start": 19,
|
||||
"end": 25,
|
||||
"name": "center"
|
||||
},
|
||||
"optional": false
|
||||
}
|
||||
],
|
||||
"body": {
|
||||
"start": 30,
|
||||
"end": 316,
|
||||
"body": [
|
||||
{
|
||||
"type": "VariableDeclaration",
|
||||
"type": "VariableDeclaration",
|
||||
"start": 34,
|
||||
"end": 48,
|
||||
"declarations": [
|
||||
{
|
||||
"type": "VariableDeclarator",
|
||||
"start": 34,
|
||||
"end": 48,
|
||||
"id": {
|
||||
"type": "Identifier",
|
||||
"start": 34,
|
||||
"end": 35,
|
||||
"name": "l"
|
||||
},
|
||||
"init": {
|
||||
"type": "BinaryExpression",
|
||||
"type": "BinaryExpression",
|
||||
"start": 38,
|
||||
"end": 48,
|
||||
"operator": "/",
|
||||
"left": {
|
||||
"type": "Identifier",
|
||||
"type": "Identifier",
|
||||
"start": 38,
|
||||
"end": 44,
|
||||
"name": "length"
|
||||
},
|
||||
"right": {
|
||||
"type": "Literal",
|
||||
"type": "Literal",
|
||||
"start": 47,
|
||||
"end": 48,
|
||||
"value": 2,
|
||||
"raw": "2"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"kind": "const"
|
||||
},
|
||||
{
|
||||
"type": "VariableDeclaration",
|
||||
"type": "VariableDeclaration",
|
||||
"start": 51,
|
||||
"end": 64,
|
||||
"declarations": [
|
||||
{
|
||||
"type": "VariableDeclarator",
|
||||
"start": 51,
|
||||
"end": 64,
|
||||
"id": {
|
||||
"type": "Identifier",
|
||||
"start": 51,
|
||||
"end": 52,
|
||||
"name": "x"
|
||||
},
|
||||
"init": {
|
||||
"type": "MemberExpression",
|
||||
"type": "MemberExpression",
|
||||
"start": 55,
|
||||
"end": 64,
|
||||
"object": {
|
||||
"type": "Identifier",
|
||||
"type": "Identifier",
|
||||
"start": 55,
|
||||
"end": 61,
|
||||
"name": "center"
|
||||
},
|
||||
"property": {
|
||||
"type": "Literal",
|
||||
"type": "Literal",
|
||||
"start": 62,
|
||||
"end": 63,
|
||||
"value": 0,
|
||||
"raw": "0"
|
||||
},
|
||||
"computed": false
|
||||
}
|
||||
}
|
||||
],
|
||||
"kind": "const"
|
||||
},
|
||||
{
|
||||
"type": "VariableDeclaration",
|
||||
"type": "VariableDeclaration",
|
||||
"start": 67,
|
||||
"end": 80,
|
||||
"declarations": [
|
||||
{
|
||||
"type": "VariableDeclarator",
|
||||
"start": 67,
|
||||
"end": 80,
|
||||
"id": {
|
||||
"type": "Identifier",
|
||||
"start": 67,
|
||||
"end": 68,
|
||||
"name": "y"
|
||||
},
|
||||
"init": {
|
||||
"type": "MemberExpression",
|
||||
"type": "MemberExpression",
|
||||
"start": 71,
|
||||
"end": 80,
|
||||
"object": {
|
||||
"type": "Identifier",
|
||||
"type": "Identifier",
|
||||
"start": 71,
|
||||
"end": 77,
|
||||
"name": "center"
|
||||
},
|
||||
"property": {
|
||||
"type": "Literal",
|
||||
"type": "Literal",
|
||||
"start": 78,
|
||||
"end": 79,
|
||||
"value": 1,
|
||||
"raw": "1"
|
||||
},
|
||||
"computed": false
|
||||
}
|
||||
}
|
||||
],
|
||||
"kind": "const"
|
||||
},
|
||||
{
|
||||
"type": "VariableDeclaration",
|
||||
"type": "VariableDeclaration",
|
||||
"start": 83,
|
||||
"end": 104,
|
||||
"declarations": [
|
||||
{
|
||||
"type": "VariableDeclarator",
|
||||
"start": 83,
|
||||
"end": 104,
|
||||
"id": {
|
||||
"type": "Identifier",
|
||||
"start": 83,
|
||||
"end": 85,
|
||||
"name": "p0"
|
||||
},
|
||||
"init": {
|
||||
"type": "ArrayExpression",
|
||||
"type": "ArrayExpression",
|
||||
"start": 88,
|
||||
"end": 104,
|
||||
"elements": [
|
||||
{
|
||||
"type": "BinaryExpression",
|
||||
"type": "BinaryExpression",
|
||||
"start": 89,
|
||||
"end": 95,
|
||||
"operator": "+",
|
||||
"left": {
|
||||
"type": "UnaryExpression",
|
||||
"type": "UnaryExpression",
|
||||
"start": 89,
|
||||
"end": 91,
|
||||
"operator": "-",
|
||||
"argument": {
|
||||
"type": "Identifier",
|
||||
"type": "Identifier",
|
||||
"start": 90,
|
||||
"end": 91,
|
||||
"name": "l"
|
||||
}
|
||||
},
|
||||
"right": {
|
||||
"type": "Identifier",
|
||||
"type": "Identifier",
|
||||
"start": 94,
|
||||
"end": 95,
|
||||
"name": "x"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "BinaryExpression",
|
||||
"type": "BinaryExpression",
|
||||
"start": 97,
|
||||
"end": 103,
|
||||
"operator": "+",
|
||||
"left": {
|
||||
"type": "UnaryExpression",
|
||||
"type": "UnaryExpression",
|
||||
"start": 97,
|
||||
"end": 99,
|
||||
"operator": "-",
|
||||
"argument": {
|
||||
"type": "Identifier",
|
||||
"type": "Identifier",
|
||||
"start": 98,
|
||||
"end": 99,
|
||||
"name": "l"
|
||||
}
|
||||
},
|
||||
"right": {
|
||||
"type": "Identifier",
|
||||
"type": "Identifier",
|
||||
"start": 102,
|
||||
"end": 103,
|
||||
"name": "y"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
"kind": "const"
|
||||
},
|
||||
{
|
||||
"type": "VariableDeclaration",
|
||||
"type": "VariableDeclaration",
|
||||
"start": 107,
|
||||
"end": 127,
|
||||
"declarations": [
|
||||
{
|
||||
"type": "VariableDeclarator",
|
||||
"start": 107,
|
||||
"end": 127,
|
||||
"id": {
|
||||
"type": "Identifier",
|
||||
"start": 107,
|
||||
"end": 109,
|
||||
"name": "p1"
|
||||
},
|
||||
"init": {
|
||||
"type": "ArrayExpression",
|
||||
"type": "ArrayExpression",
|
||||
"start": 112,
|
||||
"end": 127,
|
||||
"elements": [
|
||||
{
|
||||
"type": "BinaryExpression",
|
||||
"type": "BinaryExpression",
|
||||
"start": 113,
|
||||
"end": 119,
|
||||
"operator": "+",
|
||||
"left": {
|
||||
"type": "UnaryExpression",
|
||||
"type": "UnaryExpression",
|
||||
"start": 113,
|
||||
"end": 115,
|
||||
"operator": "-",
|
||||
"argument": {
|
||||
"type": "Identifier",
|
||||
"type": "Identifier",
|
||||
"start": 114,
|
||||
"end": 115,
|
||||
"name": "l"
|
||||
}
|
||||
},
|
||||
"right": {
|
||||
"type": "Identifier",
|
||||
"type": "Identifier",
|
||||
"start": 118,
|
||||
"end": 119,
|
||||
"name": "x"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "BinaryExpression",
|
||||
"type": "BinaryExpression",
|
||||
"start": 121,
|
||||
"end": 126,
|
||||
"operator": "+",
|
||||
"left": {
|
||||
"type": "Identifier",
|
||||
"type": "Identifier",
|
||||
"start": 121,
|
||||
"end": 122,
|
||||
"name": "l"
|
||||
},
|
||||
"right": {
|
||||
"type": "Identifier",
|
||||
"type": "Identifier",
|
||||
"start": 125,
|
||||
"end": 126,
|
||||
"name": "y"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
"kind": "const"
|
||||
},
|
||||
{
|
||||
"type": "VariableDeclaration",
|
||||
"type": "VariableDeclaration",
|
||||
"start": 130,
|
||||
"end": 149,
|
||||
"declarations": [
|
||||
{
|
||||
"type": "VariableDeclarator",
|
||||
"start": 130,
|
||||
"end": 149,
|
||||
"id": {
|
||||
"type": "Identifier",
|
||||
"start": 130,
|
||||
"end": 132,
|
||||
"name": "p2"
|
||||
},
|
||||
"init": {
|
||||
"type": "ArrayExpression",
|
||||
"type": "ArrayExpression",
|
||||
"start": 135,
|
||||
"end": 149,
|
||||
"elements": [
|
||||
{
|
||||
"type": "BinaryExpression",
|
||||
"type": "BinaryExpression",
|
||||
"start": 136,
|
||||
"end": 141,
|
||||
"operator": "+",
|
||||
"left": {
|
||||
"type": "Identifier",
|
||||
"type": "Identifier",
|
||||
"start": 136,
|
||||
"end": 137,
|
||||
"name": "l"
|
||||
},
|
||||
"right": {
|
||||
"type": "Identifier",
|
||||
"type": "Identifier",
|
||||
"start": 140,
|
||||
"end": 141,
|
||||
"name": "x"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "BinaryExpression",
|
||||
"type": "BinaryExpression",
|
||||
"start": 143,
|
||||
"end": 148,
|
||||
"operator": "+",
|
||||
"left": {
|
||||
"type": "Identifier",
|
||||
"type": "Identifier",
|
||||
"start": 143,
|
||||
"end": 144,
|
||||
"name": "l"
|
||||
},
|
||||
"right": {
|
||||
"type": "Identifier",
|
||||
"type": "Identifier",
|
||||
"start": 147,
|
||||
"end": 148,
|
||||
"name": "y"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
"kind": "const"
|
||||
},
|
||||
{
|
||||
"type": "VariableDeclaration",
|
||||
"type": "VariableDeclaration",
|
||||
"start": 152,
|
||||
"end": 172,
|
||||
"declarations": [
|
||||
{
|
||||
"type": "VariableDeclarator",
|
||||
"start": 152,
|
||||
"end": 172,
|
||||
"id": {
|
||||
"type": "Identifier",
|
||||
"start": 152,
|
||||
"end": 154,
|
||||
"name": "p3"
|
||||
},
|
||||
"init": {
|
||||
"type": "ArrayExpression",
|
||||
"type": "ArrayExpression",
|
||||
"start": 157,
|
||||
"end": 172,
|
||||
"elements": [
|
||||
{
|
||||
"type": "BinaryExpression",
|
||||
"type": "BinaryExpression",
|
||||
"start": 158,
|
||||
"end": 163,
|
||||
"operator": "+",
|
||||
"left": {
|
||||
"type": "Identifier",
|
||||
"type": "Identifier",
|
||||
"start": 158,
|
||||
"end": 159,
|
||||
"name": "l"
|
||||
},
|
||||
"right": {
|
||||
"type": "Identifier",
|
||||
"type": "Identifier",
|
||||
"start": 162,
|
||||
"end": 163,
|
||||
"name": "x"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "BinaryExpression",
|
||||
"type": "BinaryExpression",
|
||||
"start": 165,
|
||||
"end": 171,
|
||||
"operator": "+",
|
||||
"left": {
|
||||
"type": "UnaryExpression",
|
||||
"type": "UnaryExpression",
|
||||
"start": 165,
|
||||
"end": 167,
|
||||
"operator": "-",
|
||||
"argument": {
|
||||
"type": "Identifier",
|
||||
"type": "Identifier",
|
||||
"start": 166,
|
||||
"end": 167,
|
||||
"name": "l"
|
||||
}
|
||||
},
|
||||
"right": {
|
||||
"type": "Identifier",
|
||||
"type": "Identifier",
|
||||
"start": 170,
|
||||
"end": 171,
|
||||
"name": "y"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
"kind": "const"
|
||||
},
|
||||
{
|
||||
"type": "ReturnStatement",
|
||||
"type": "ReturnStatement",
|
||||
"start": 176,
|
||||
"end": 314,
|
||||
"argument": {
|
||||
"type": "PipeExpression",
|
||||
"type": "PipeExpression",
|
||||
"start": 183,
|
||||
"end": 314,
|
||||
"body": [
|
||||
{
|
||||
"type": "CallExpression",
|
||||
"type": "CallExpression",
|
||||
"start": 183,
|
||||
"end": 200,
|
||||
"callee": {
|
||||
"type": "Identifier",
|
||||
"start": 183,
|
||||
"end": 196,
|
||||
"name": "startSketchAt"
|
||||
},
|
||||
"arguments": [
|
||||
{
|
||||
"type": "Identifier",
|
||||
"type": "Identifier",
|
||||
"start": 197,
|
||||
"end": 199,
|
||||
"name": "p0"
|
||||
}
|
||||
],
|
||||
"optional": false
|
||||
},
|
||||
{
|
||||
"type": "CallExpression",
|
||||
"type": "CallExpression",
|
||||
"start": 206,
|
||||
"end": 219,
|
||||
"callee": {
|
||||
"type": "Identifier",
|
||||
"start": 206,
|
||||
"end": 212,
|
||||
"name": "lineTo"
|
||||
},
|
||||
"arguments": [
|
||||
{
|
||||
"type": "Identifier",
|
||||
"type": "Identifier",
|
||||
"start": 213,
|
||||
"end": 215,
|
||||
"name": "p1"
|
||||
},
|
||||
{
|
||||
"type": "PipeSubstitution",
|
||||
"type": "PipeSubstitution",
|
||||
"start": 217,
|
||||
"end": 218
|
||||
}
|
||||
],
|
||||
"optional": false
|
||||
},
|
||||
{
|
||||
"type": "CallExpression",
|
||||
"type": "CallExpression",
|
||||
"start": 225,
|
||||
"end": 238,
|
||||
"callee": {
|
||||
"type": "Identifier",
|
||||
"start": 225,
|
||||
"end": 231,
|
||||
"name": "lineTo"
|
||||
},
|
||||
"arguments": [
|
||||
{
|
||||
"type": "Identifier",
|
||||
"type": "Identifier",
|
||||
"start": 232,
|
||||
"end": 234,
|
||||
"name": "p2"
|
||||
},
|
||||
{
|
||||
"type": "PipeSubstitution",
|
||||
"type": "PipeSubstitution",
|
||||
"start": 236,
|
||||
"end": 237
|
||||
}
|
||||
],
|
||||
"optional": false
|
||||
},
|
||||
{
|
||||
"type": "CallExpression",
|
||||
"type": "CallExpression",
|
||||
"start": 244,
|
||||
"end": 257,
|
||||
"callee": {
|
||||
"type": "Identifier",
|
||||
"start": 244,
|
||||
"end": 250,
|
||||
"name": "lineTo"
|
||||
},
|
||||
"arguments": [
|
||||
{
|
||||
"type": "Identifier",
|
||||
"type": "Identifier",
|
||||
"start": 251,
|
||||
"end": 253,
|
||||
"name": "p3"
|
||||
},
|
||||
{
|
||||
"type": "PipeSubstitution",
|
||||
"type": "PipeSubstitution",
|
||||
"start": 255,
|
||||
"end": 256
|
||||
}
|
||||
],
|
||||
"optional": false
|
||||
},
|
||||
{
|
||||
"type": "CallExpression",
|
||||
"type": "CallExpression",
|
||||
"start": 263,
|
||||
"end": 276,
|
||||
"callee": {
|
||||
"type": "Identifier",
|
||||
"start": 263,
|
||||
"end": 269,
|
||||
"name": "lineTo"
|
||||
},
|
||||
"arguments": [
|
||||
{
|
||||
"type": "Identifier",
|
||||
"type": "Identifier",
|
||||
"start": 270,
|
||||
"end": 272,
|
||||
"name": "p0"
|
||||
},
|
||||
{
|
||||
"type": "PipeSubstitution",
|
||||
"type": "PipeSubstitution",
|
||||
"start": 274,
|
||||
"end": 275
|
||||
}
|
||||
],
|
||||
"optional": false
|
||||
},
|
||||
{
|
||||
"type": "CallExpression",
|
||||
"type": "CallExpression",
|
||||
"start": 282,
|
||||
"end": 290,
|
||||
"callee": {
|
||||
"type": "Identifier",
|
||||
"start": 282,
|
||||
"end": 287,
|
||||
"name": "close"
|
||||
},
|
||||
"arguments": [
|
||||
{
|
||||
"type": "PipeSubstitution",
|
||||
"type": "PipeSubstitution",
|
||||
"start": 288,
|
||||
"end": 289
|
||||
}
|
||||
],
|
||||
"optional": false
|
||||
},
|
||||
{
|
||||
"type": "CallExpression",
|
||||
"type": "CallExpression",
|
||||
"start": 296,
|
||||
"end": 314,
|
||||
"callee": {
|
||||
"type": "Identifier",
|
||||
"start": 296,
|
||||
"end": 303,
|
||||
"name": "extrude"
|
||||
},
|
||||
"arguments": [
|
||||
{
|
||||
"type": "Identifier",
|
||||
"type": "Identifier",
|
||||
"start": 304,
|
||||
"end": 310,
|
||||
"name": "length"
|
||||
},
|
||||
{
|
||||
"type": "PipeSubstitution",
|
||||
"type": "PipeSubstitution",
|
||||
"start": 312,
|
||||
"end": 313
|
||||
}
|
||||
],
|
||||
"optional": false
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
"nonCodeMeta": {
|
||||
"nonCodeNodes": {
|
||||
"6": [
|
||||
{
|
||||
"type": "NonCodeNode",
|
||||
"start": 172,
|
||||
"end": 176,
|
||||
"value": {
|
||||
"type": "newLine"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"start": []
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"kind": "fn"
|
||||
},
|
||||
{
|
||||
"type": "VariableDeclaration",
|
||||
"type": "VariableDeclaration",
|
||||
"start": 318,
|
||||
"end": 343,
|
||||
"declarations": [
|
||||
{
|
||||
"type": "VariableDeclarator",
|
||||
"start": 318,
|
||||
"end": 343,
|
||||
"id": {
|
||||
"type": "Identifier",
|
||||
"start": 318,
|
||||
"end": 324,
|
||||
"name": "myCube"
|
||||
},
|
||||
"init": {
|
||||
"type": "CallExpression",
|
||||
"type": "CallExpression",
|
||||
"start": 327,
|
||||
"end": 343,
|
||||
"callee": {
|
||||
"type": "Identifier",
|
||||
"start": 327,
|
||||
"end": 331,
|
||||
"name": "cube"
|
||||
},
|
||||
"arguments": [
|
||||
{
|
||||
"type": "Literal",
|
||||
"type": "Literal",
|
||||
"start": 332,
|
||||
"end": 334,
|
||||
"value": 40,
|
||||
"raw": "40"
|
||||
},
|
||||
{
|
||||
"type": "ArrayExpression",
|
||||
"type": "ArrayExpression",
|
||||
"start": 336,
|
||||
"end": 342,
|
||||
"elements": [
|
||||
{
|
||||
"type": "Literal",
|
||||
"type": "Literal",
|
||||
"start": 337,
|
||||
"end": 338,
|
||||
"value": 0,
|
||||
"raw": "0"
|
||||
},
|
||||
{
|
||||
"type": "Literal",
|
||||
"type": "Literal",
|
||||
"start": 340,
|
||||
"end": 341,
|
||||
"value": 0,
|
||||
"raw": "0"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"optional": false
|
||||
}
|
||||
}
|
||||
],
|
||||
"kind": "const"
|
||||
}
|
||||
],
|
||||
"nonCodeMeta": {
|
||||
"nonCodeNodes": {
|
||||
"0": [
|
||||
{
|
||||
"type": "NonCodeNode",
|
||||
"start": 316,
|
||||
"end": 318,
|
||||
"value": {
|
||||
"type": "newLine"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"start": []
|
||||
}
|
||||
}
|
||||
}
|
||||
7
src/wasm-lib/kcl/tests/cube/execution_error.snap.new
Normal file
7
src/wasm-lib/kcl/tests/cube/execution_error.snap.new
Normal file
@ -0,0 +1,7 @@
|
||||
---
|
||||
source: kcl/src/simulation_tests.rs
|
||||
assertion_line: 98
|
||||
description: Error from executing cube.kcl
|
||||
snapshot_kind: text
|
||||
---
|
||||
No API token found in environment variables. Use KITTYCAD_API_TOKEN or ZOO_API_TOKEN
|
||||
19
src/wasm-lib/kcl/tests/cube/input.kcl
Normal file
19
src/wasm-lib/kcl/tests/cube/input.kcl
Normal file
@ -0,0 +1,19 @@
|
||||
fn cube = (length, center) => {
|
||||
l = length / 2
|
||||
x = center[0]
|
||||
y = center[1]
|
||||
p0 = [-l + x, -l + y]
|
||||
p1 = [-l + x, l + y]
|
||||
p2 = [l + x, l + y]
|
||||
p3 = [l + x, -l + y]
|
||||
|
||||
return startSketchAt(p0)
|
||||
|> lineTo(p1, %)
|
||||
|> lineTo(p2, %)
|
||||
|> lineTo(p3, %)
|
||||
|> lineTo(p0, %)
|
||||
|> close(%)
|
||||
|> extrude(length, %)
|
||||
}
|
||||
|
||||
myCube = cube(40, [0, 0])
|
||||
976
src/wasm-lib/kcl/tests/cube/program_memory.snap
Normal file
976
src/wasm-lib/kcl/tests/cube/program_memory.snap
Normal file
@ -0,0 +1,976 @@
|
||||
---
|
||||
source: kcl/src/tests.rs
|
||||
description: Program memory after executing cube.kcl
|
||||
snapshot_kind: text
|
||||
---
|
||||
{
|
||||
"environments": [
|
||||
{
|
||||
"bindings": {
|
||||
"HALF_TURN": {
|
||||
"type": "UserVal",
|
||||
"type": "UserVal",
|
||||
"value": 180,
|
||||
"__meta": []
|
||||
},
|
||||
"QUARTER_TURN": {
|
||||
"type": "UserVal",
|
||||
"type": "UserVal",
|
||||
"value": 90,
|
||||
"__meta": []
|
||||
},
|
||||
"THREE_QUARTER_TURN": {
|
||||
"type": "UserVal",
|
||||
"type": "UserVal",
|
||||
"value": 270,
|
||||
"__meta": []
|
||||
},
|
||||
"ZERO": {
|
||||
"type": "UserVal",
|
||||
"type": "UserVal",
|
||||
"value": 0,
|
||||
"__meta": []
|
||||
},
|
||||
"cube": {
|
||||
"type": "Function",
|
||||
"expression": {
|
||||
"type": "FunctionExpression",
|
||||
"start": 10,
|
||||
"end": 316,
|
||||
"params": [
|
||||
{
|
||||
"type": "Parameter",
|
||||
"identifier": {
|
||||
"type": "Identifier",
|
||||
"start": 11,
|
||||
"end": 17,
|
||||
"name": "length"
|
||||
},
|
||||
"optional": false
|
||||
},
|
||||
{
|
||||
"type": "Parameter",
|
||||
"identifier": {
|
||||
"type": "Identifier",
|
||||
"start": 19,
|
||||
"end": 25,
|
||||
"name": "center"
|
||||
},
|
||||
"optional": false
|
||||
}
|
||||
],
|
||||
"body": {
|
||||
"start": 30,
|
||||
"end": 316,
|
||||
"body": [
|
||||
{
|
||||
"type": "VariableDeclaration",
|
||||
"type": "VariableDeclaration",
|
||||
"start": 34,
|
||||
"end": 48,
|
||||
"declarations": [
|
||||
{
|
||||
"type": "VariableDeclarator",
|
||||
"start": 34,
|
||||
"end": 48,
|
||||
"id": {
|
||||
"type": "Identifier",
|
||||
"start": 34,
|
||||
"end": 35,
|
||||
"name": "l"
|
||||
},
|
||||
"init": {
|
||||
"type": "BinaryExpression",
|
||||
"type": "BinaryExpression",
|
||||
"start": 38,
|
||||
"end": 48,
|
||||
"operator": "/",
|
||||
"left": {
|
||||
"type": "Identifier",
|
||||
"type": "Identifier",
|
||||
"start": 38,
|
||||
"end": 44,
|
||||
"name": "length"
|
||||
},
|
||||
"right": {
|
||||
"type": "Literal",
|
||||
"type": "Literal",
|
||||
"start": 47,
|
||||
"end": 48,
|
||||
"value": 2,
|
||||
"raw": "2"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"kind": "const"
|
||||
},
|
||||
{
|
||||
"type": "VariableDeclaration",
|
||||
"type": "VariableDeclaration",
|
||||
"start": 51,
|
||||
"end": 64,
|
||||
"declarations": [
|
||||
{
|
||||
"type": "VariableDeclarator",
|
||||
"start": 51,
|
||||
"end": 64,
|
||||
"id": {
|
||||
"type": "Identifier",
|
||||
"start": 51,
|
||||
"end": 52,
|
||||
"name": "x"
|
||||
},
|
||||
"init": {
|
||||
"type": "MemberExpression",
|
||||
"type": "MemberExpression",
|
||||
"start": 55,
|
||||
"end": 64,
|
||||
"object": {
|
||||
"type": "Identifier",
|
||||
"type": "Identifier",
|
||||
"start": 55,
|
||||
"end": 61,
|
||||
"name": "center"
|
||||
},
|
||||
"property": {
|
||||
"type": "Literal",
|
||||
"type": "Literal",
|
||||
"start": 62,
|
||||
"end": 63,
|
||||
"value": 0,
|
||||
"raw": "0"
|
||||
},
|
||||
"computed": false
|
||||
}
|
||||
}
|
||||
],
|
||||
"kind": "const"
|
||||
},
|
||||
{
|
||||
"type": "VariableDeclaration",
|
||||
"type": "VariableDeclaration",
|
||||
"start": 67,
|
||||
"end": 80,
|
||||
"declarations": [
|
||||
{
|
||||
"type": "VariableDeclarator",
|
||||
"start": 67,
|
||||
"end": 80,
|
||||
"id": {
|
||||
"type": "Identifier",
|
||||
"start": 67,
|
||||
"end": 68,
|
||||
"name": "y"
|
||||
},
|
||||
"init": {
|
||||
"type": "MemberExpression",
|
||||
"type": "MemberExpression",
|
||||
"start": 71,
|
||||
"end": 80,
|
||||
"object": {
|
||||
"type": "Identifier",
|
||||
"type": "Identifier",
|
||||
"start": 71,
|
||||
"end": 77,
|
||||
"name": "center"
|
||||
},
|
||||
"property": {
|
||||
"type": "Literal",
|
||||
"type": "Literal",
|
||||
"start": 78,
|
||||
"end": 79,
|
||||
"value": 1,
|
||||
"raw": "1"
|
||||
},
|
||||
"computed": false
|
||||
}
|
||||
}
|
||||
],
|
||||
"kind": "const"
|
||||
},
|
||||
{
|
||||
"type": "VariableDeclaration",
|
||||
"type": "VariableDeclaration",
|
||||
"start": 83,
|
||||
"end": 104,
|
||||
"declarations": [
|
||||
{
|
||||
"type": "VariableDeclarator",
|
||||
"start": 83,
|
||||
"end": 104,
|
||||
"id": {
|
||||
"type": "Identifier",
|
||||
"start": 83,
|
||||
"end": 85,
|
||||
"name": "p0"
|
||||
},
|
||||
"init": {
|
||||
"type": "ArrayExpression",
|
||||
"type": "ArrayExpression",
|
||||
"start": 88,
|
||||
"end": 104,
|
||||
"elements": [
|
||||
{
|
||||
"type": "BinaryExpression",
|
||||
"type": "BinaryExpression",
|
||||
"start": 89,
|
||||
"end": 95,
|
||||
"operator": "+",
|
||||
"left": {
|
||||
"type": "UnaryExpression",
|
||||
"type": "UnaryExpression",
|
||||
"start": 89,
|
||||
"end": 91,
|
||||
"operator": "-",
|
||||
"argument": {
|
||||
"type": "Identifier",
|
||||
"type": "Identifier",
|
||||
"start": 90,
|
||||
"end": 91,
|
||||
"name": "l"
|
||||
}
|
||||
},
|
||||
"right": {
|
||||
"type": "Identifier",
|
||||
"type": "Identifier",
|
||||
"start": 94,
|
||||
"end": 95,
|
||||
"name": "x"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "BinaryExpression",
|
||||
"type": "BinaryExpression",
|
||||
"start": 97,
|
||||
"end": 103,
|
||||
"operator": "+",
|
||||
"left": {
|
||||
"type": "UnaryExpression",
|
||||
"type": "UnaryExpression",
|
||||
"start": 97,
|
||||
"end": 99,
|
||||
"operator": "-",
|
||||
"argument": {
|
||||
"type": "Identifier",
|
||||
"type": "Identifier",
|
||||
"start": 98,
|
||||
"end": 99,
|
||||
"name": "l"
|
||||
}
|
||||
},
|
||||
"right": {
|
||||
"type": "Identifier",
|
||||
"type": "Identifier",
|
||||
"start": 102,
|
||||
"end": 103,
|
||||
"name": "y"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
"kind": "const"
|
||||
},
|
||||
{
|
||||
"type": "VariableDeclaration",
|
||||
"type": "VariableDeclaration",
|
||||
"start": 107,
|
||||
"end": 127,
|
||||
"declarations": [
|
||||
{
|
||||
"type": "VariableDeclarator",
|
||||
"start": 107,
|
||||
"end": 127,
|
||||
"id": {
|
||||
"type": "Identifier",
|
||||
"start": 107,
|
||||
"end": 109,
|
||||
"name": "p1"
|
||||
},
|
||||
"init": {
|
||||
"type": "ArrayExpression",
|
||||
"type": "ArrayExpression",
|
||||
"start": 112,
|
||||
"end": 127,
|
||||
"elements": [
|
||||
{
|
||||
"type": "BinaryExpression",
|
||||
"type": "BinaryExpression",
|
||||
"start": 113,
|
||||
"end": 119,
|
||||
"operator": "+",
|
||||
"left": {
|
||||
"type": "UnaryExpression",
|
||||
"type": "UnaryExpression",
|
||||
"start": 113,
|
||||
"end": 115,
|
||||
"operator": "-",
|
||||
"argument": {
|
||||
"type": "Identifier",
|
||||
"type": "Identifier",
|
||||
"start": 114,
|
||||
"end": 115,
|
||||
"name": "l"
|
||||
}
|
||||
},
|
||||
"right": {
|
||||
"type": "Identifier",
|
||||
"type": "Identifier",
|
||||
"start": 118,
|
||||
"end": 119,
|
||||
"name": "x"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "BinaryExpression",
|
||||
"type": "BinaryExpression",
|
||||
"start": 121,
|
||||
"end": 126,
|
||||
"operator": "+",
|
||||
"left": {
|
||||
"type": "Identifier",
|
||||
"type": "Identifier",
|
||||
"start": 121,
|
||||
"end": 122,
|
||||
"name": "l"
|
||||
},
|
||||
"right": {
|
||||
"type": "Identifier",
|
||||
"type": "Identifier",
|
||||
"start": 125,
|
||||
"end": 126,
|
||||
"name": "y"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
"kind": "const"
|
||||
},
|
||||
{
|
||||
"type": "VariableDeclaration",
|
||||
"type": "VariableDeclaration",
|
||||
"start": 130,
|
||||
"end": 149,
|
||||
"declarations": [
|
||||
{
|
||||
"type": "VariableDeclarator",
|
||||
"start": 130,
|
||||
"end": 149,
|
||||
"id": {
|
||||
"type": "Identifier",
|
||||
"start": 130,
|
||||
"end": 132,
|
||||
"name": "p2"
|
||||
},
|
||||
"init": {
|
||||
"type": "ArrayExpression",
|
||||
"type": "ArrayExpression",
|
||||
"start": 135,
|
||||
"end": 149,
|
||||
"elements": [
|
||||
{
|
||||
"type": "BinaryExpression",
|
||||
"type": "BinaryExpression",
|
||||
"start": 136,
|
||||
"end": 141,
|
||||
"operator": "+",
|
||||
"left": {
|
||||
"type": "Identifier",
|
||||
"type": "Identifier",
|
||||
"start": 136,
|
||||
"end": 137,
|
||||
"name": "l"
|
||||
},
|
||||
"right": {
|
||||
"type": "Identifier",
|
||||
"type": "Identifier",
|
||||
"start": 140,
|
||||
"end": 141,
|
||||
"name": "x"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "BinaryExpression",
|
||||
"type": "BinaryExpression",
|
||||
"start": 143,
|
||||
"end": 148,
|
||||
"operator": "+",
|
||||
"left": {
|
||||
"type": "Identifier",
|
||||
"type": "Identifier",
|
||||
"start": 143,
|
||||
"end": 144,
|
||||
"name": "l"
|
||||
},
|
||||
"right": {
|
||||
"type": "Identifier",
|
||||
"type": "Identifier",
|
||||
"start": 147,
|
||||
"end": 148,
|
||||
"name": "y"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
"kind": "const"
|
||||
},
|
||||
{
|
||||
"type": "VariableDeclaration",
|
||||
"type": "VariableDeclaration",
|
||||
"start": 152,
|
||||
"end": 172,
|
||||
"declarations": [
|
||||
{
|
||||
"type": "VariableDeclarator",
|
||||
"start": 152,
|
||||
"end": 172,
|
||||
"id": {
|
||||
"type": "Identifier",
|
||||
"start": 152,
|
||||
"end": 154,
|
||||
"name": "p3"
|
||||
},
|
||||
"init": {
|
||||
"type": "ArrayExpression",
|
||||
"type": "ArrayExpression",
|
||||
"start": 157,
|
||||
"end": 172,
|
||||
"elements": [
|
||||
{
|
||||
"type": "BinaryExpression",
|
||||
"type": "BinaryExpression",
|
||||
"start": 158,
|
||||
"end": 163,
|
||||
"operator": "+",
|
||||
"left": {
|
||||
"type": "Identifier",
|
||||
"type": "Identifier",
|
||||
"start": 158,
|
||||
"end": 159,
|
||||
"name": "l"
|
||||
},
|
||||
"right": {
|
||||
"type": "Identifier",
|
||||
"type": "Identifier",
|
||||
"start": 162,
|
||||
"end": 163,
|
||||
"name": "x"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "BinaryExpression",
|
||||
"type": "BinaryExpression",
|
||||
"start": 165,
|
||||
"end": 171,
|
||||
"operator": "+",
|
||||
"left": {
|
||||
"type": "UnaryExpression",
|
||||
"type": "UnaryExpression",
|
||||
"start": 165,
|
||||
"end": 167,
|
||||
"operator": "-",
|
||||
"argument": {
|
||||
"type": "Identifier",
|
||||
"type": "Identifier",
|
||||
"start": 166,
|
||||
"end": 167,
|
||||
"name": "l"
|
||||
}
|
||||
},
|
||||
"right": {
|
||||
"type": "Identifier",
|
||||
"type": "Identifier",
|
||||
"start": 170,
|
||||
"end": 171,
|
||||
"name": "y"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
"kind": "const"
|
||||
},
|
||||
{
|
||||
"type": "ReturnStatement",
|
||||
"type": "ReturnStatement",
|
||||
"start": 176,
|
||||
"end": 314,
|
||||
"argument": {
|
||||
"type": "PipeExpression",
|
||||
"type": "PipeExpression",
|
||||
"start": 183,
|
||||
"end": 314,
|
||||
"body": [
|
||||
{
|
||||
"type": "CallExpression",
|
||||
"type": "CallExpression",
|
||||
"start": 183,
|
||||
"end": 200,
|
||||
"callee": {
|
||||
"type": "Identifier",
|
||||
"start": 183,
|
||||
"end": 196,
|
||||
"name": "startSketchAt"
|
||||
},
|
||||
"arguments": [
|
||||
{
|
||||
"type": "Identifier",
|
||||
"type": "Identifier",
|
||||
"start": 197,
|
||||
"end": 199,
|
||||
"name": "p0"
|
||||
}
|
||||
],
|
||||
"optional": false
|
||||
},
|
||||
{
|
||||
"type": "CallExpression",
|
||||
"type": "CallExpression",
|
||||
"start": 206,
|
||||
"end": 219,
|
||||
"callee": {
|
||||
"type": "Identifier",
|
||||
"start": 206,
|
||||
"end": 212,
|
||||
"name": "lineTo"
|
||||
},
|
||||
"arguments": [
|
||||
{
|
||||
"type": "Identifier",
|
||||
"type": "Identifier",
|
||||
"start": 213,
|
||||
"end": 215,
|
||||
"name": "p1"
|
||||
},
|
||||
{
|
||||
"type": "PipeSubstitution",
|
||||
"type": "PipeSubstitution",
|
||||
"start": 217,
|
||||
"end": 218
|
||||
}
|
||||
],
|
||||
"optional": false
|
||||
},
|
||||
{
|
||||
"type": "CallExpression",
|
||||
"type": "CallExpression",
|
||||
"start": 225,
|
||||
"end": 238,
|
||||
"callee": {
|
||||
"type": "Identifier",
|
||||
"start": 225,
|
||||
"end": 231,
|
||||
"name": "lineTo"
|
||||
},
|
||||
"arguments": [
|
||||
{
|
||||
"type": "Identifier",
|
||||
"type": "Identifier",
|
||||
"start": 232,
|
||||
"end": 234,
|
||||
"name": "p2"
|
||||
},
|
||||
{
|
||||
"type": "PipeSubstitution",
|
||||
"type": "PipeSubstitution",
|
||||
"start": 236,
|
||||
"end": 237
|
||||
}
|
||||
],
|
||||
"optional": false
|
||||
},
|
||||
{
|
||||
"type": "CallExpression",
|
||||
"type": "CallExpression",
|
||||
"start": 244,
|
||||
"end": 257,
|
||||
"callee": {
|
||||
"type": "Identifier",
|
||||
"start": 244,
|
||||
"end": 250,
|
||||
"name": "lineTo"
|
||||
},
|
||||
"arguments": [
|
||||
{
|
||||
"type": "Identifier",
|
||||
"type": "Identifier",
|
||||
"start": 251,
|
||||
"end": 253,
|
||||
"name": "p3"
|
||||
},
|
||||
{
|
||||
"type": "PipeSubstitution",
|
||||
"type": "PipeSubstitution",
|
||||
"start": 255,
|
||||
"end": 256
|
||||
}
|
||||
],
|
||||
"optional": false
|
||||
},
|
||||
{
|
||||
"type": "CallExpression",
|
||||
"type": "CallExpression",
|
||||
"start": 263,
|
||||
"end": 276,
|
||||
"callee": {
|
||||
"type": "Identifier",
|
||||
"start": 263,
|
||||
"end": 269,
|
||||
"name": "lineTo"
|
||||
},
|
||||
"arguments": [
|
||||
{
|
||||
"type": "Identifier",
|
||||
"type": "Identifier",
|
||||
"start": 270,
|
||||
"end": 272,
|
||||
"name": "p0"
|
||||
},
|
||||
{
|
||||
"type": "PipeSubstitution",
|
||||
"type": "PipeSubstitution",
|
||||
"start": 274,
|
||||
"end": 275
|
||||
}
|
||||
],
|
||||
"optional": false
|
||||
},
|
||||
{
|
||||
"type": "CallExpression",
|
||||
"type": "CallExpression",
|
||||
"start": 282,
|
||||
"end": 290,
|
||||
"callee": {
|
||||
"type": "Identifier",
|
||||
"start": 282,
|
||||
"end": 287,
|
||||
"name": "close"
|
||||
},
|
||||
"arguments": [
|
||||
{
|
||||
"type": "PipeSubstitution",
|
||||
"type": "PipeSubstitution",
|
||||
"start": 288,
|
||||
"end": 289
|
||||
}
|
||||
],
|
||||
"optional": false
|
||||
},
|
||||
{
|
||||
"type": "CallExpression",
|
||||
"type": "CallExpression",
|
||||
"start": 296,
|
||||
"end": 314,
|
||||
"callee": {
|
||||
"type": "Identifier",
|
||||
"start": 296,
|
||||
"end": 303,
|
||||
"name": "extrude"
|
||||
},
|
||||
"arguments": [
|
||||
{
|
||||
"type": "Identifier",
|
||||
"type": "Identifier",
|
||||
"start": 304,
|
||||
"end": 310,
|
||||
"name": "length"
|
||||
},
|
||||
{
|
||||
"type": "PipeSubstitution",
|
||||
"type": "PipeSubstitution",
|
||||
"start": 312,
|
||||
"end": 313
|
||||
}
|
||||
],
|
||||
"optional": false
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
"nonCodeMeta": {
|
||||
"nonCodeNodes": {
|
||||
"6": [
|
||||
{
|
||||
"type": "NonCodeNode",
|
||||
"start": 172,
|
||||
"end": 176,
|
||||
"value": {
|
||||
"type": "newLine"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"start": []
|
||||
}
|
||||
}
|
||||
},
|
||||
"memory": {
|
||||
"environments": [
|
||||
{
|
||||
"bindings": {
|
||||
"HALF_TURN": {
|
||||
"type": "UserVal",
|
||||
"type": "UserVal",
|
||||
"value": 180,
|
||||
"__meta": []
|
||||
},
|
||||
"QUARTER_TURN": {
|
||||
"type": "UserVal",
|
||||
"type": "UserVal",
|
||||
"value": 90,
|
||||
"__meta": []
|
||||
},
|
||||
"THREE_QUARTER_TURN": {
|
||||
"type": "UserVal",
|
||||
"type": "UserVal",
|
||||
"value": 270,
|
||||
"__meta": []
|
||||
},
|
||||
"ZERO": {
|
||||
"type": "UserVal",
|
||||
"type": "UserVal",
|
||||
"value": 0,
|
||||
"__meta": []
|
||||
}
|
||||
},
|
||||
"parent": null
|
||||
}
|
||||
],
|
||||
"currentEnv": 0,
|
||||
"return": null
|
||||
},
|
||||
"__meta": [
|
||||
{
|
||||
"sourceRange": [
|
||||
10,
|
||||
316
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"myCube": {
|
||||
"type": "Solid",
|
||||
"type": "Solid",
|
||||
"id": "[uuid]",
|
||||
"value": [
|
||||
{
|
||||
"faceId": "[uuid]",
|
||||
"id": "[uuid]",
|
||||
"sourceRange": [
|
||||
206,
|
||||
219
|
||||
],
|
||||
"tag": null,
|
||||
"type": "extrudePlane"
|
||||
},
|
||||
{
|
||||
"faceId": "[uuid]",
|
||||
"id": "[uuid]",
|
||||
"sourceRange": [
|
||||
225,
|
||||
238
|
||||
],
|
||||
"tag": null,
|
||||
"type": "extrudePlane"
|
||||
},
|
||||
{
|
||||
"faceId": "[uuid]",
|
||||
"id": "[uuid]",
|
||||
"sourceRange": [
|
||||
244,
|
||||
257
|
||||
],
|
||||
"tag": null,
|
||||
"type": "extrudePlane"
|
||||
},
|
||||
{
|
||||
"faceId": "[uuid]",
|
||||
"id": "[uuid]",
|
||||
"sourceRange": [
|
||||
263,
|
||||
276
|
||||
],
|
||||
"tag": null,
|
||||
"type": "extrudePlane"
|
||||
}
|
||||
],
|
||||
"sketch": {
|
||||
"type": "Sketch",
|
||||
"id": "[uuid]",
|
||||
"paths": [
|
||||
{
|
||||
"__geoMeta": {
|
||||
"id": "[uuid]",
|
||||
"sourceRange": [
|
||||
206,
|
||||
219
|
||||
]
|
||||
},
|
||||
"from": [
|
||||
-20.0,
|
||||
-20.0
|
||||
],
|
||||
"tag": null,
|
||||
"to": [
|
||||
-20.0,
|
||||
20.0
|
||||
],
|
||||
"type": "ToPoint"
|
||||
},
|
||||
{
|
||||
"__geoMeta": {
|
||||
"id": "[uuid]",
|
||||
"sourceRange": [
|
||||
225,
|
||||
238
|
||||
]
|
||||
},
|
||||
"from": [
|
||||
-20.0,
|
||||
20.0
|
||||
],
|
||||
"tag": null,
|
||||
"to": [
|
||||
20.0,
|
||||
20.0
|
||||
],
|
||||
"type": "ToPoint"
|
||||
},
|
||||
{
|
||||
"__geoMeta": {
|
||||
"id": "[uuid]",
|
||||
"sourceRange": [
|
||||
244,
|
||||
257
|
||||
]
|
||||
},
|
||||
"from": [
|
||||
20.0,
|
||||
20.0
|
||||
],
|
||||
"tag": null,
|
||||
"to": [
|
||||
20.0,
|
||||
-20.0
|
||||
],
|
||||
"type": "ToPoint"
|
||||
},
|
||||
{
|
||||
"__geoMeta": {
|
||||
"id": "[uuid]",
|
||||
"sourceRange": [
|
||||
263,
|
||||
276
|
||||
]
|
||||
},
|
||||
"from": [
|
||||
20.0,
|
||||
-20.0
|
||||
],
|
||||
"tag": null,
|
||||
"to": [
|
||||
-20.0,
|
||||
-20.0
|
||||
],
|
||||
"type": "ToPoint"
|
||||
},
|
||||
{
|
||||
"__geoMeta": {
|
||||
"id": "[uuid]",
|
||||
"sourceRange": [
|
||||
282,
|
||||
290
|
||||
]
|
||||
},
|
||||
"from": [
|
||||
-20.0,
|
||||
-20.0
|
||||
],
|
||||
"tag": null,
|
||||
"to": [
|
||||
-20.0,
|
||||
-20.0
|
||||
],
|
||||
"type": "ToPoint"
|
||||
}
|
||||
],
|
||||
"on": {
|
||||
"type": "plane",
|
||||
"id": "[uuid]",
|
||||
"value": "XY",
|
||||
"origin": {
|
||||
"x": 0.0,
|
||||
"y": 0.0,
|
||||
"z": 0.0
|
||||
},
|
||||
"xAxis": {
|
||||
"x": 1.0,
|
||||
"y": 0.0,
|
||||
"z": 0.0
|
||||
},
|
||||
"yAxis": {
|
||||
"x": 0.0,
|
||||
"y": 1.0,
|
||||
"z": 0.0
|
||||
},
|
||||
"zAxis": {
|
||||
"x": 0.0,
|
||||
"y": 0.0,
|
||||
"z": 1.0
|
||||
},
|
||||
"__meta": []
|
||||
},
|
||||
"start": {
|
||||
"from": [
|
||||
-20.0,
|
||||
-20.0
|
||||
],
|
||||
"to": [
|
||||
-20.0,
|
||||
-20.0
|
||||
],
|
||||
"tag": null,
|
||||
"__geoMeta": {
|
||||
"id": "[uuid]",
|
||||
"sourceRange": [
|
||||
183,
|
||||
200
|
||||
]
|
||||
}
|
||||
},
|
||||
"__meta": [
|
||||
{
|
||||
"sourceRange": [
|
||||
183,
|
||||
200
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"height": 40.0,
|
||||
"startCapId": "[uuid]",
|
||||
"endCapId": "[uuid]",
|
||||
"__meta": [
|
||||
{
|
||||
"sourceRange": [
|
||||
183,
|
||||
200
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"parent": null
|
||||
}
|
||||
],
|
||||
"currentEnv": 0,
|
||||
"return": null
|
||||
}
|
||||
BIN
src/wasm-lib/kcl/tests/cube/rendered_model.png
Normal file
BIN
src/wasm-lib/kcl/tests/cube/rendered_model.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 91 KiB |
1257
src/wasm-lib/kcl/tests/cube/tokens.snap
Normal file
1257
src/wasm-lib/kcl/tests/cube/tokens.snap
Normal file
File diff suppressed because it is too large
Load Diff
27
src/wasm-lib/kcl/tests/simtest.tmpl
Normal file
27
src/wasm-lib/kcl/tests/simtest.tmpl
Normal file
@ -0,0 +1,27 @@
|
||||
mod TEST_NAME_HERE {
|
||||
const TEST_NAME: &str = "TEST_NAME_HERE";
|
||||
|
||||
/// Test tokenizing KCL.
|
||||
#[test]
|
||||
fn tokenize() {
|
||||
super::tokenize(TEST_NAME)
|
||||
}
|
||||
|
||||
/// Test parsing KCL.
|
||||
#[test]
|
||||
fn parse() {
|
||||
super::parse(TEST_NAME)
|
||||
}
|
||||
|
||||
/// Test that parsing and unparsing KCL produces the original KCL input.
|
||||
#[test]
|
||||
fn unparse() {
|
||||
super::unparse(TEST_NAME)
|
||||
}
|
||||
|
||||
/// Test that KCL is executed correctly.
|
||||
#[tokio::test(flavor = "multi_thread")]
|
||||
async fn kcl_test_execute() {
|
||||
super::execute(TEST_NAME).await
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user