Generate images for examples in derive docs (#1916)

* start

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* update derive docs

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* add new docs

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* u[dates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

---------

Signed-off-by: Jess Frazelle <github@jessfraz.com>
This commit is contained in:
Jess Frazelle
2024-03-26 21:28:50 -07:00
committed by GitHub
parent 86de039dc4
commit 1dac62067a
162 changed files with 1411 additions and 54 deletions

View File

@ -1,3 +1,3 @@
[codespell] [codespell]
ignore-words-list: crate,everytime,inout,co-ordinate,ot,nwo,absolutey ignore-words-list: crate,everytime,inout,co-ordinate,ot,nwo,absolutey
skip: **/target,node_modules,build,**/Cargo.lock skip: **/target,node_modules,build,**/Cargo.lock,./docs/kcl/*.md

View File

@ -12,6 +12,10 @@ Computes the absolute value of a number.
abs(num: number) -> number abs(num: number) -> number
``` ```
### Tags
* `math`
### Examples ### Examples
```js ```js

View File

@ -12,6 +12,10 @@ Computes the arccosine of a number (in radians).
acos(num: number) -> number acos(num: number) -> number
``` ```
### Tags
* `math`
### Examples ### Examples
```js ```js

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -12,6 +12,10 @@ Computes the arcsine of a number (in radians).
asin(num: number) -> number asin(num: number) -> number
``` ```
### Tags
* `math`
### Examples ### Examples
```js ```js

View File

@ -12,6 +12,10 @@ Computes the arctangent of a number (in radians).
atan(num: number) -> number atan(num: number) -> number
``` ```
### Tags
* `math`
### Examples ### Examples
```js ```js

File diff suppressed because one or more lines are too long

View File

@ -12,6 +12,10 @@ Computes the smallest integer greater than or equal to a number.
ceil(num: number) -> number ceil(num: number) -> number
``` ```
### Tags
* `math`
### Examples ### Examples
```js ```js

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -12,6 +12,10 @@ Computes the sine of a number (in radians).
cos(num: number) -> number cos(num: number) -> number
``` ```
### Tags
* `math`
### Examples ### Examples
```js ```js

View File

@ -12,6 +12,10 @@ Return the value of Eulers number `e`.
e() -> number e() -> number
``` ```
### Tags
* `math`
### Examples ### Examples
```js ```js

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -12,6 +12,10 @@ Computes the largest integer less than or equal to a number.
floor(num: number) -> number floor(num: number) -> number
``` ```
### Tags
* `math`
### Examples ### Examples
```js ```js

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -12,6 +12,10 @@ Returns the angle of the given leg for x.
legAngX(hypotenuse: number, leg: number) -> number legAngX(hypotenuse: number, leg: number) -> number
``` ```
### Tags
* `utilities`
### Examples ### Examples
```js ```js

View File

@ -12,6 +12,10 @@ Returns the angle of the given leg for y.
legAngY(hypotenuse: number, leg: number) -> number legAngY(hypotenuse: number, leg: number) -> number
``` ```
### Tags
* `utilities`
### Examples ### Examples
```js ```js

View File

@ -12,6 +12,10 @@ Returns the length of the given leg.
legLen(hypotenuse: number, leg: number) -> number legLen(hypotenuse: number, leg: number) -> number
``` ```
### Tags
* `utilities`
### Examples ### Examples
```js ```js

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -12,6 +12,10 @@ Computes the natural logarithm of the number.
ln(num: number) -> number ln(num: number) -> number
``` ```
### Tags
* `math`
### Examples ### Examples
```js ```js

View File

@ -12,6 +12,10 @@ The result might not be correctly rounded owing to implementation details; `log2
log(num: number, base: number) -> number log(num: number, base: number) -> number
``` ```
### Tags
* `math`
### Examples ### Examples
```js ```js

View File

@ -12,6 +12,10 @@ Computes the base 10 logarithm of the number.
log10(num: number) -> number log10(num: number) -> number
``` ```
### Tags
* `math`
### Examples ### Examples
```js ```js

View File

@ -12,6 +12,10 @@ Computes the base 2 logarithm of the number.
log2(num: number) -> number log2(num: number) -> number
``` ```
### Tags
* `math`
### Examples ### Examples
```js ```js

View File

@ -12,6 +12,10 @@ Computes the maximum of the given arguments.
max(args: [number]) -> number max(args: [number]) -> number
``` ```
### Tags
* `math`
### Examples ### Examples
```js ```js

View File

@ -12,6 +12,10 @@ Computes the minimum of the given arguments.
min(args: [number]) -> number min(args: [number]) -> number
``` ```
### Tags
* `math`
### Examples ### Examples
```js ```js

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -12,6 +12,10 @@ Return the value of `pi`. Archimedes constant (π).
pi() -> number pi() -> number
``` ```
### Tags
* `math`
### Examples ### Examples
```js ```js

View File

@ -12,6 +12,10 @@ Computes the number to a power.
pow(num: number, pow: number) -> number pow(num: number, pow: number) -> number
``` ```
### Tags
* `math`
### Examples ### Examples
```js ```js

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -12,6 +12,10 @@ Computes the sine of a number (in radians).
sin(num: number) -> number sin(num: number) -> number
``` ```
### Tags
* `math`
### Examples ### Examples
```js ```js

View File

@ -12,6 +12,10 @@ Computes the square root of a number.
sqrt(num: number) -> number sqrt(num: number) -> number
``` ```
### Tags
* `math`
### Examples ### Examples
```js ```js

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -3,7 +3,9 @@
"name": "abs", "name": "abs",
"summary": "Computes the absolute value of a number.", "summary": "Computes the absolute value of a number.",
"description": "", "description": "",
"tags": [], "tags": [
"math"
],
"args": [ "args": [
{ {
"name": "num", "name": "num",
@ -34,7 +36,9 @@
"name": "acos", "name": "acos",
"summary": "Computes the arccosine of a number (in radians).", "summary": "Computes the arccosine of a number (in radians).",
"description": "", "description": "",
"tags": [], "tags": [
"math"
],
"args": [ "args": [
{ {
"name": "num", "name": "num",
@ -16041,7 +16045,9 @@
"name": "asin", "name": "asin",
"summary": "Computes the arcsine of a number (in radians).", "summary": "Computes the arcsine of a number (in radians).",
"description": "", "description": "",
"tags": [], "tags": [
"math"
],
"args": [ "args": [
{ {
"name": "num", "name": "num",
@ -16072,7 +16078,9 @@
"name": "atan", "name": "atan",
"summary": "Computes the arctangent of a number (in radians).", "summary": "Computes the arctangent of a number (in radians).",
"description": "", "description": "",
"tags": [], "tags": [
"math"
],
"args": [ "args": [
{ {
"name": "num", "name": "num",
@ -18105,7 +18113,9 @@
"name": "ceil", "name": "ceil",
"summary": "Computes the smallest integer greater than or equal to a number.", "summary": "Computes the smallest integer greater than or equal to a number.",
"description": "", "description": "",
"tags": [], "tags": [
"math"
],
"args": [ "args": [
{ {
"name": "num", "name": "num",
@ -22378,7 +22388,9 @@
"name": "cos", "name": "cos",
"summary": "Computes the sine of a number (in radians).", "summary": "Computes the sine of a number (in radians).",
"description": "", "description": "",
"tags": [], "tags": [
"math"
],
"args": [ "args": [
{ {
"name": "num", "name": "num",
@ -22409,7 +22421,9 @@
"name": "e", "name": "e",
"summary": "Return the value of Eulers number `e`.", "summary": "Return the value of Eulers number `e`.",
"description": "", "description": "",
"tags": [], "tags": [
"math"
],
"args": [], "args": [],
"returnValue": { "returnValue": {
"name": "", "name": "",
@ -25738,7 +25752,9 @@
"name": "floor", "name": "floor",
"summary": "Computes the largest integer less than or equal to a number.", "summary": "Computes the largest integer less than or equal to a number.",
"description": "", "description": "",
"tags": [], "tags": [
"math"
],
"args": [ "args": [
{ {
"name": "num", "name": "num",
@ -35212,7 +35228,9 @@
"name": "import", "name": "import",
"summary": "Import a CAD file.", "summary": "Import a CAD file.",
"description": "For formats lacking unit data (STL, OBJ, PLY), the default import unit is millimeters. Otherwise you can specify the unit by passing in the options parameter. If you import a gltf file, we will try to find the bin file and import it as well.\nImport paths are relative to the current project directory. This only works in the desktop app not in browser.", "description": "For formats lacking unit data (STL, OBJ, PLY), the default import unit is millimeters. Otherwise you can specify the unit by passing in the options parameter. If you import a gltf file, we will try to find the bin file and import it as well.\nImport paths are relative to the current project directory. This only works in the desktop app not in browser.",
"tags": [], "tags": [
"norun"
],
"args": [ "args": [
{ {
"name": "file_path", "name": "file_path",
@ -37847,7 +37865,9 @@
"name": "legAngX", "name": "legAngX",
"summary": "Returns the angle of the given leg for x.", "summary": "Returns the angle of the given leg for x.",
"description": "", "description": "",
"tags": [], "tags": [
"utilities"
],
"args": [ "args": [
{ {
"name": "hypotenuse", "name": "hypotenuse",
@ -37887,7 +37907,9 @@
"name": "legAngY", "name": "legAngY",
"summary": "Returns the angle of the given leg for y.", "summary": "Returns the angle of the given leg for y.",
"description": "", "description": "",
"tags": [], "tags": [
"utilities"
],
"args": [ "args": [
{ {
"name": "hypotenuse", "name": "hypotenuse",
@ -37927,7 +37949,9 @@
"name": "legLen", "name": "legLen",
"summary": "Returns the length of the given leg.", "summary": "Returns the length of the given leg.",
"description": "", "description": "",
"tags": [], "tags": [
"utilities"
],
"args": [ "args": [
{ {
"name": "hypotenuse", "name": "hypotenuse",
@ -41907,7 +41931,9 @@
"name": "ln", "name": "ln",
"summary": "Computes the natural logarithm of the number.", "summary": "Computes the natural logarithm of the number.",
"description": "", "description": "",
"tags": [], "tags": [
"math"
],
"args": [ "args": [
{ {
"name": "num", "name": "num",
@ -41938,7 +41964,9 @@
"name": "log", "name": "log",
"summary": "Computes the logarithm of the number with respect to an arbitrary base.", "summary": "Computes the logarithm of the number with respect to an arbitrary base.",
"description": "The result might not be correctly rounded owing to implementation details; `log2()` can produce more accurate results for base 2, and `log10()` can produce more accurate results for base 10.", "description": "The result might not be correctly rounded owing to implementation details; `log2()` can produce more accurate results for base 2, and `log10()` can produce more accurate results for base 10.",
"tags": [], "tags": [
"math"
],
"args": [ "args": [
{ {
"name": "num", "name": "num",
@ -41978,7 +42006,9 @@
"name": "log10", "name": "log10",
"summary": "Computes the base 10 logarithm of the number.", "summary": "Computes the base 10 logarithm of the number.",
"description": "", "description": "",
"tags": [], "tags": [
"math"
],
"args": [ "args": [
{ {
"name": "num", "name": "num",
@ -42009,7 +42039,9 @@
"name": "log2", "name": "log2",
"summary": "Computes the base 2 logarithm of the number.", "summary": "Computes the base 2 logarithm of the number.",
"description": "", "description": "",
"tags": [], "tags": [
"math"
],
"args": [ "args": [
{ {
"name": "num", "name": "num",
@ -42040,7 +42072,9 @@
"name": "max", "name": "max",
"summary": "Computes the maximum of the given arguments.", "summary": "Computes the maximum of the given arguments.",
"description": "", "description": "",
"tags": [], "tags": [
"math"
],
"args": [ "args": [
{ {
"name": "args", "name": "args",
@ -42074,7 +42108,9 @@
"name": "min", "name": "min",
"summary": "Computes the minimum of the given arguments.", "summary": "Computes the minimum of the given arguments.",
"description": "", "description": "",
"tags": [], "tags": [
"math"
],
"args": [ "args": [
{ {
"name": "args", "name": "args",
@ -49233,7 +49269,9 @@
"name": "pi", "name": "pi",
"summary": "Return the value of `pi`. Archimedes constant (π).", "summary": "Return the value of `pi`. Archimedes constant (π).",
"description": "", "description": "",
"tags": [], "tags": [
"math"
],
"args": [], "args": [],
"returnValue": { "returnValue": {
"name": "", "name": "",
@ -49254,7 +49292,9 @@
"name": "pow", "name": "pow",
"summary": "Computes the number to a power.", "summary": "Computes the number to a power.",
"description": "", "description": "",
"tags": [], "tags": [
"math"
],
"args": [ "args": [
{ {
"name": "num", "name": "num",
@ -55146,7 +55186,9 @@
"name": "sin", "name": "sin",
"summary": "Computes the sine of a number (in radians).", "summary": "Computes the sine of a number (in radians).",
"description": "", "description": "",
"tags": [], "tags": [
"math"
],
"args": [ "args": [
{ {
"name": "num", "name": "num",
@ -55177,7 +55219,9 @@
"name": "sqrt", "name": "sqrt",
"summary": "Computes the square root of a number.", "summary": "Computes the square root of a number.",
"description": "", "description": "",
"tags": [], "tags": [
"math"
],
"args": [ "args": [
{ {
"name": "num", "name": "num",
@ -58785,7 +58829,9 @@
"name": "tan", "name": "tan",
"summary": "Computes the tangent of a number (in radians).", "summary": "Computes the tangent of a number (in radians).",
"description": "", "description": "",
"tags": [], "tags": [
"math"
],
"args": [ "args": [
{ {
"name": "num", "name": "num",
@ -62781,7 +62827,9 @@
"name": "tau", "name": "tau",
"summary": "Return the value of `tau`. The full circle constant (τ). Equal to 2π.", "summary": "Return the value of `tau`. The full circle constant (τ). Equal to 2π.",
"description": "", "description": "",
"tags": [], "tags": [
"math"
],
"args": [], "args": [],
"returnValue": { "returnValue": {
"name": "", "name": "",
@ -62802,7 +62850,9 @@
"name": "toDegrees", "name": "toDegrees",
"summary": "Converts a number from radians to degrees.", "summary": "Converts a number from radians to degrees.",
"description": "", "description": "",
"tags": [], "tags": [
"math"
],
"args": [ "args": [
{ {
"name": "num", "name": "num",
@ -62833,7 +62883,9 @@
"name": "toRadians", "name": "toRadians",
"summary": "Converts a number from degrees to radians.", "summary": "Converts a number from degrees to radians.",
"description": "", "description": "",
"tags": [], "tags": [
"math"
],
"args": [ "args": [
{ {
"name": "num", "name": "num",

View File

@ -12,6 +12,10 @@ Computes the tangent of a number (in radians).
tan(num: number) -> number tan(num: number) -> number
``` ```
### Tags
* `math`
### Examples ### Examples
```js ```js

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -12,6 +12,10 @@ Return the value of `tau`. The full circle constant (τ). Equal to 2π.
tau() -> number tau() -> number
``` ```
### Tags
* `math`
### Examples ### Examples
```js ```js

View File

@ -12,6 +12,10 @@ Converts a number from radians to degrees.
toDegrees(num: number) -> number toDegrees(num: number) -> number
``` ```
### Tags
* `math`
### Examples ### Examples
```js ```js

View File

@ -12,6 +12,10 @@ Converts a number from degrees to radians.
toRadians(num: number) -> number toRadians(num: number) -> number
``` ```
### Tags
* `math`
### Examples ### Examples
```js ```js

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -322,6 +322,12 @@ version = "0.21.7"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567"
[[package]]
name = "base64"
version = "0.22.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9475866fec1451be56a3c2400fd081ff546538961565ccb5b7142cbd22bc7a51"
[[package]] [[package]]
name = "base64ct" name = "base64ct"
version = "1.6.0" version = "1.6.0"
@ -1843,9 +1849,11 @@ dependencies = [
"approx 0.5.1", "approx 0.5.1",
"async-recursion", "async-recursion",
"async-trait", "async-trait",
"base64 0.22.0",
"bson", "bson",
"chrono", "chrono",
"clap", "clap",
"convert_case",
"criterion", "criterion",
"dashmap", "dashmap",
"databake", "databake",
@ -1853,6 +1861,7 @@ dependencies = [
"expectorate", "expectorate",
"futures", "futures",
"gltf-json", "gltf-json",
"image",
"insta", "insta",
"itertools 0.12.1", "itertools 0.12.1",
"js-sys", "js-sys",
@ -1874,6 +1883,7 @@ dependencies = [
"tokio-tungstenite", "tokio-tungstenite",
"tower-lsp", "tower-lsp",
"ts-rs", "ts-rs",
"twenty-twenty",
"uuid", "uuid",
"wasm-bindgen", "wasm-bindgen",
"wasm-bindgen-futures", "wasm-bindgen-futures",

View File

@ -201,7 +201,7 @@ fn do_stdlib_inner(
.code_blocks .code_blocks
.iter() .iter()
.enumerate() .enumerate()
.map(|(index, code_block)| generate_code_block_test(&fn_name_str, code_block, index)) .map(|(index, code_block)| generate_code_block_test(&fn_name_str, code_block, index, &metadata.tags))
.collect::<Vec<_>>(); .collect::<Vec<_>>();
let tags = metadata let tags = metadata
@ -731,12 +731,18 @@ fn parse_array_type(type_name: &str) -> Option<(&str, usize)> {
// For each kcl code block, we want to generate a test that checks that the // For each kcl code block, we want to generate a test that checks that the
// code block is valid kcl code and compiles and executes. // code block is valid kcl code and compiles and executes.
fn generate_code_block_test(fn_name: &str, code_block: &str, index: usize) -> proc_macro2::TokenStream { fn generate_code_block_test(
fn_name: &str,
code_block: &str,
index: usize,
tags: &[String],
) -> proc_macro2::TokenStream {
let test_name = format_ident!("serial_test_example_{}{}", fn_name, index); let test_name = format_ident!("serial_test_example_{}{}", fn_name, index);
let test_name_str = format!("serial_test_example_{}{}", fn_name, index);
// TODO: We ignore import for now, because the files don't exist and we just want // TODO: We ignore import for now, because the files don't exist and we just want
// to show easy imports. // to show easy imports.
let ignored = if fn_name == "import" { let ignored = if tags.contains(&"norun".to_string()) {
quote! { #[ignore] } quote! { #[ignore] }
} else { } else {
quote! {} quote! {}
@ -778,9 +784,58 @@ fn generate_code_block_test(fn_name: &str, code_block: &str, index: usize) -> pr
let parser = crate::parser::Parser::new(tokens); let parser = crate::parser::Parser::new(tokens);
let program = parser.ast().unwrap(); let program = parser.ast().unwrap();
let mut mem: crate::executor::ProgramMemory = Default::default(); let mut mem: crate::executor::ProgramMemory = Default::default();
let ctx = crate::executor::ExecutorContext::new(ws,kittycad::types::UnitLength::Mm).await.unwrap(); let units = kittycad::types::UnitLength::Mm;
let ctx = crate::executor::ExecutorContext::new(ws, units.clone()).await.unwrap();
crate::executor::execute(program, &mut mem, crate::executor::BodyType::Root, &ctx).await.unwrap(); crate::executor::execute(program, &mut mem, crate::executor::BodyType::Root, &ctx).await.unwrap();
let (x, y) = crate::std::utils::get_camera_zoom_magnitude_per_unit_length(units);
ctx.engine
.send_modeling_cmd(
false,
uuid::Uuid::new_v4(),
crate::executor::SourceRange::default(),
kittycad::types::ModelingCmd::DefaultCameraLookAt {
center: kittycad::types::Point3D { x: 0.0, y: 0.0, z: 0.0 },
up: kittycad::types::Point3D { x: 0.0, y: 0.0, z: 1.0 },
vantage: kittycad::types::Point3D { x: 0.0, y: -x, z: y },
sequence: None,
},
)
.await.unwrap();
// Send a snapshot request to the engine.
let resp = ctx
.engine
.send_modeling_cmd(
false,
uuid::Uuid::new_v4(),
crate::executor::SourceRange::default(),
kittycad::types::ModelingCmd::TakeSnapshot {
format: kittycad::types::ImageFormat::Png,
},
)
.await.unwrap();
// 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()));
if let kittycad::types::OkWebSocketResponseData::Modeling {
modeling_response: kittycad::types::OkModelingCmdResponse::TakeSnapshot { data },
} = &resp
{
// Save the snapshot locally.
std::fs::write(&output_file, &data.contents.0).unwrap();
} else {
panic!("Unexpected response from engine: {:?}", resp);
}
// Read the output file.
let actual = image::io::Reader::open(output_file).unwrap().decode().unwrap();
twenty_twenty::assert_image(&format!("tests/outputs/{}.png", #test_name_str), &actual, 1.0);
} }
} }
} }

View File

@ -345,6 +345,7 @@ fn test_stdlib_doc_comment_with_code_on_ignored_function() {
let (item, errors) = do_stdlib( let (item, errors) = do_stdlib(
quote! { quote! {
name = "import", name = "import",
tags = ["norun"]
}, },
quote! { quote! {
/// This is some function. /// This is some function.

View File

@ -29,12 +29,72 @@ mod test_examples_show {
let parser = crate::parser::Parser::new(tokens); let parser = crate::parser::Parser::new(tokens);
let program = parser.ast().unwrap(); let program = parser.ast().unwrap();
let mut mem: crate::executor::ProgramMemory = Default::default(); let mut mem: crate::executor::ProgramMemory = Default::default();
let ctx = crate::executor::ExecutorContext::new(ws, kittycad::types::UnitLength::Mm) let units = kittycad::types::UnitLength::Mm;
let ctx = crate::executor::ExecutorContext::new(ws, units.clone())
.await .await
.unwrap(); .unwrap();
crate::executor::execute(program, &mut mem, crate::executor::BodyType::Root, &ctx) crate::executor::execute(program, &mut mem, crate::executor::BodyType::Root, &ctx)
.await .await
.unwrap(); .unwrap();
let (x, y) = crate::std::utils::get_camera_zoom_magnitude_per_unit_length(units);
ctx.engine
.send_modeling_cmd(
false,
uuid::Uuid::new_v4(),
crate::executor::SourceRange::default(),
kittycad::types::ModelingCmd::DefaultCameraLookAt {
center: kittycad::types::Point3D {
x: 0.0,
y: 0.0,
z: 0.0,
},
up: kittycad::types::Point3D {
x: 0.0,
y: 0.0,
z: 1.0,
},
vantage: kittycad::types::Point3D {
x: 0.0,
y: -x,
z: y,
},
sequence: None,
},
)
.await
.unwrap();
let resp = ctx
.engine
.send_modeling_cmd(
false,
uuid::Uuid::new_v4(),
crate::executor::SourceRange::default(),
kittycad::types::ModelingCmd::TakeSnapshot {
format: kittycad::types::ImageFormat::Png,
},
)
.await
.unwrap();
let output_file =
std::env::temp_dir().join(format!("kcl_output_{}.png", uuid::Uuid::new_v4()));
if let kittycad::types::OkWebSocketResponseData::Modeling {
modeling_response: kittycad::types::OkModelingCmdResponse::TakeSnapshot { data },
} = &resp
{
std::fs::write(&output_file, &data.contents.0).unwrap();
} else {
panic!("Unexpected response from engine: {:?}", resp);
}
let actual = image::io::Reader::open(output_file)
.unwrap()
.decode()
.unwrap();
twenty_twenty::assert_image(
&format!("tests/outputs/{}.png", "serial_test_example_show0"),
&actual,
1.0,
);
} }
#[tokio::test(flavor = "multi_thread", worker_threads = 5)] #[tokio::test(flavor = "multi_thread", worker_threads = 5)]
@ -66,12 +126,72 @@ mod test_examples_show {
let parser = crate::parser::Parser::new(tokens); let parser = crate::parser::Parser::new(tokens);
let program = parser.ast().unwrap(); let program = parser.ast().unwrap();
let mut mem: crate::executor::ProgramMemory = Default::default(); let mut mem: crate::executor::ProgramMemory = Default::default();
let ctx = crate::executor::ExecutorContext::new(ws, kittycad::types::UnitLength::Mm) let units = kittycad::types::UnitLength::Mm;
let ctx = crate::executor::ExecutorContext::new(ws, units.clone())
.await .await
.unwrap(); .unwrap();
crate::executor::execute(program, &mut mem, crate::executor::BodyType::Root, &ctx) crate::executor::execute(program, &mut mem, crate::executor::BodyType::Root, &ctx)
.await .await
.unwrap(); .unwrap();
let (x, y) = crate::std::utils::get_camera_zoom_magnitude_per_unit_length(units);
ctx.engine
.send_modeling_cmd(
false,
uuid::Uuid::new_v4(),
crate::executor::SourceRange::default(),
kittycad::types::ModelingCmd::DefaultCameraLookAt {
center: kittycad::types::Point3D {
x: 0.0,
y: 0.0,
z: 0.0,
},
up: kittycad::types::Point3D {
x: 0.0,
y: 0.0,
z: 1.0,
},
vantage: kittycad::types::Point3D {
x: 0.0,
y: -x,
z: y,
},
sequence: None,
},
)
.await
.unwrap();
let resp = ctx
.engine
.send_modeling_cmd(
false,
uuid::Uuid::new_v4(),
crate::executor::SourceRange::default(),
kittycad::types::ModelingCmd::TakeSnapshot {
format: kittycad::types::ImageFormat::Png,
},
)
.await
.unwrap();
let output_file =
std::env::temp_dir().join(format!("kcl_output_{}.png", uuid::Uuid::new_v4()));
if let kittycad::types::OkWebSocketResponseData::Modeling {
modeling_response: kittycad::types::OkModelingCmdResponse::TakeSnapshot { data },
} = &resp
{
std::fs::write(&output_file, &data.contents.0).unwrap();
} else {
panic!("Unexpected response from engine: {:?}", resp);
}
let actual = image::io::Reader::open(output_file)
.unwrap()
.decode()
.unwrap();
twenty_twenty::assert_image(
&format!("tests/outputs/{}.png", "serial_test_example_show1"),
&actual,
1.0,
);
} }
} }

View File

@ -29,12 +29,72 @@ mod test_examples_show {
let parser = crate::parser::Parser::new(tokens); let parser = crate::parser::Parser::new(tokens);
let program = parser.ast().unwrap(); let program = parser.ast().unwrap();
let mut mem: crate::executor::ProgramMemory = Default::default(); let mut mem: crate::executor::ProgramMemory = Default::default();
let ctx = crate::executor::ExecutorContext::new(ws, kittycad::types::UnitLength::Mm) let units = kittycad::types::UnitLength::Mm;
let ctx = crate::executor::ExecutorContext::new(ws, units.clone())
.await .await
.unwrap(); .unwrap();
crate::executor::execute(program, &mut mem, crate::executor::BodyType::Root, &ctx) crate::executor::execute(program, &mut mem, crate::executor::BodyType::Root, &ctx)
.await .await
.unwrap(); .unwrap();
let (x, y) = crate::std::utils::get_camera_zoom_magnitude_per_unit_length(units);
ctx.engine
.send_modeling_cmd(
false,
uuid::Uuid::new_v4(),
crate::executor::SourceRange::default(),
kittycad::types::ModelingCmd::DefaultCameraLookAt {
center: kittycad::types::Point3D {
x: 0.0,
y: 0.0,
z: 0.0,
},
up: kittycad::types::Point3D {
x: 0.0,
y: 0.0,
z: 1.0,
},
vantage: kittycad::types::Point3D {
x: 0.0,
y: -x,
z: y,
},
sequence: None,
},
)
.await
.unwrap();
let resp = ctx
.engine
.send_modeling_cmd(
false,
uuid::Uuid::new_v4(),
crate::executor::SourceRange::default(),
kittycad::types::ModelingCmd::TakeSnapshot {
format: kittycad::types::ImageFormat::Png,
},
)
.await
.unwrap();
let output_file =
std::env::temp_dir().join(format!("kcl_output_{}.png", uuid::Uuid::new_v4()));
if let kittycad::types::OkWebSocketResponseData::Modeling {
modeling_response: kittycad::types::OkModelingCmdResponse::TakeSnapshot { data },
} = &resp
{
std::fs::write(&output_file, &data.contents.0).unwrap();
} else {
panic!("Unexpected response from engine: {:?}", resp);
}
let actual = image::io::Reader::open(output_file)
.unwrap()
.decode()
.unwrap();
twenty_twenty::assert_image(
&format!("tests/outputs/{}.png", "serial_test_example_show0"),
&actual,
1.0,
);
} }
} }

View File

@ -29,12 +29,72 @@ mod test_examples_my_func {
let parser = crate::parser::Parser::new(tokens); let parser = crate::parser::Parser::new(tokens);
let program = parser.ast().unwrap(); let program = parser.ast().unwrap();
let mut mem: crate::executor::ProgramMemory = Default::default(); let mut mem: crate::executor::ProgramMemory = Default::default();
let ctx = crate::executor::ExecutorContext::new(ws, kittycad::types::UnitLength::Mm) let units = kittycad::types::UnitLength::Mm;
let ctx = crate::executor::ExecutorContext::new(ws, units.clone())
.await .await
.unwrap(); .unwrap();
crate::executor::execute(program, &mut mem, crate::executor::BodyType::Root, &ctx) crate::executor::execute(program, &mut mem, crate::executor::BodyType::Root, &ctx)
.await .await
.unwrap(); .unwrap();
let (x, y) = crate::std::utils::get_camera_zoom_magnitude_per_unit_length(units);
ctx.engine
.send_modeling_cmd(
false,
uuid::Uuid::new_v4(),
crate::executor::SourceRange::default(),
kittycad::types::ModelingCmd::DefaultCameraLookAt {
center: kittycad::types::Point3D {
x: 0.0,
y: 0.0,
z: 0.0,
},
up: kittycad::types::Point3D {
x: 0.0,
y: 0.0,
z: 1.0,
},
vantage: kittycad::types::Point3D {
x: 0.0,
y: -x,
z: y,
},
sequence: None,
},
)
.await
.unwrap();
let resp = ctx
.engine
.send_modeling_cmd(
false,
uuid::Uuid::new_v4(),
crate::executor::SourceRange::default(),
kittycad::types::ModelingCmd::TakeSnapshot {
format: kittycad::types::ImageFormat::Png,
},
)
.await
.unwrap();
let output_file =
std::env::temp_dir().join(format!("kcl_output_{}.png", uuid::Uuid::new_v4()));
if let kittycad::types::OkWebSocketResponseData::Modeling {
modeling_response: kittycad::types::OkModelingCmdResponse::TakeSnapshot { data },
} = &resp
{
std::fs::write(&output_file, &data.contents.0).unwrap();
} else {
panic!("Unexpected response from engine: {:?}", resp);
}
let actual = image::io::Reader::open(output_file)
.unwrap()
.decode()
.unwrap();
twenty_twenty::assert_image(
&format!("tests/outputs/{}.png", "serial_test_example_my_func0"),
&actual,
1.0,
);
} }
#[tokio::test(flavor = "multi_thread", worker_threads = 5)] #[tokio::test(flavor = "multi_thread", worker_threads = 5)]
@ -66,12 +126,72 @@ mod test_examples_my_func {
let parser = crate::parser::Parser::new(tokens); let parser = crate::parser::Parser::new(tokens);
let program = parser.ast().unwrap(); let program = parser.ast().unwrap();
let mut mem: crate::executor::ProgramMemory = Default::default(); let mut mem: crate::executor::ProgramMemory = Default::default();
let ctx = crate::executor::ExecutorContext::new(ws, kittycad::types::UnitLength::Mm) let units = kittycad::types::UnitLength::Mm;
let ctx = crate::executor::ExecutorContext::new(ws, units.clone())
.await .await
.unwrap(); .unwrap();
crate::executor::execute(program, &mut mem, crate::executor::BodyType::Root, &ctx) crate::executor::execute(program, &mut mem, crate::executor::BodyType::Root, &ctx)
.await .await
.unwrap(); .unwrap();
let (x, y) = crate::std::utils::get_camera_zoom_magnitude_per_unit_length(units);
ctx.engine
.send_modeling_cmd(
false,
uuid::Uuid::new_v4(),
crate::executor::SourceRange::default(),
kittycad::types::ModelingCmd::DefaultCameraLookAt {
center: kittycad::types::Point3D {
x: 0.0,
y: 0.0,
z: 0.0,
},
up: kittycad::types::Point3D {
x: 0.0,
y: 0.0,
z: 1.0,
},
vantage: kittycad::types::Point3D {
x: 0.0,
y: -x,
z: y,
},
sequence: None,
},
)
.await
.unwrap();
let resp = ctx
.engine
.send_modeling_cmd(
false,
uuid::Uuid::new_v4(),
crate::executor::SourceRange::default(),
kittycad::types::ModelingCmd::TakeSnapshot {
format: kittycad::types::ImageFormat::Png,
},
)
.await
.unwrap();
let output_file =
std::env::temp_dir().join(format!("kcl_output_{}.png", uuid::Uuid::new_v4()));
if let kittycad::types::OkWebSocketResponseData::Modeling {
modeling_response: kittycad::types::OkModelingCmdResponse::TakeSnapshot { data },
} = &resp
{
std::fs::write(&output_file, &data.contents.0).unwrap();
} else {
panic!("Unexpected response from engine: {:?}", resp);
}
let actual = image::io::Reader::open(output_file)
.unwrap()
.decode()
.unwrap();
twenty_twenty::assert_image(
&format!("tests/outputs/{}.png", "serial_test_example_my_func1"),
&actual,
1.0,
);
} }
} }

View File

@ -30,12 +30,72 @@ mod test_examples_import {
let parser = crate::parser::Parser::new(tokens); let parser = crate::parser::Parser::new(tokens);
let program = parser.ast().unwrap(); let program = parser.ast().unwrap();
let mut mem: crate::executor::ProgramMemory = Default::default(); let mut mem: crate::executor::ProgramMemory = Default::default();
let ctx = crate::executor::ExecutorContext::new(ws, kittycad::types::UnitLength::Mm) let units = kittycad::types::UnitLength::Mm;
let ctx = crate::executor::ExecutorContext::new(ws, units.clone())
.await .await
.unwrap(); .unwrap();
crate::executor::execute(program, &mut mem, crate::executor::BodyType::Root, &ctx) crate::executor::execute(program, &mut mem, crate::executor::BodyType::Root, &ctx)
.await .await
.unwrap(); .unwrap();
let (x, y) = crate::std::utils::get_camera_zoom_magnitude_per_unit_length(units);
ctx.engine
.send_modeling_cmd(
false,
uuid::Uuid::new_v4(),
crate::executor::SourceRange::default(),
kittycad::types::ModelingCmd::DefaultCameraLookAt {
center: kittycad::types::Point3D {
x: 0.0,
y: 0.0,
z: 0.0,
},
up: kittycad::types::Point3D {
x: 0.0,
y: 0.0,
z: 1.0,
},
vantage: kittycad::types::Point3D {
x: 0.0,
y: -x,
z: y,
},
sequence: None,
},
)
.await
.unwrap();
let resp = ctx
.engine
.send_modeling_cmd(
false,
uuid::Uuid::new_v4(),
crate::executor::SourceRange::default(),
kittycad::types::ModelingCmd::TakeSnapshot {
format: kittycad::types::ImageFormat::Png,
},
)
.await
.unwrap();
let output_file =
std::env::temp_dir().join(format!("kcl_output_{}.png", uuid::Uuid::new_v4()));
if let kittycad::types::OkWebSocketResponseData::Modeling {
modeling_response: kittycad::types::OkModelingCmdResponse::TakeSnapshot { data },
} = &resp
{
std::fs::write(&output_file, &data.contents.0).unwrap();
} else {
panic!("Unexpected response from engine: {:?}", resp);
}
let actual = image::io::Reader::open(output_file)
.unwrap()
.decode()
.unwrap();
twenty_twenty::assert_image(
&format!("tests/outputs/{}.png", "serial_test_example_import0"),
&actual,
1.0,
);
} }
#[tokio::test(flavor = "multi_thread", worker_threads = 5)] #[tokio::test(flavor = "multi_thread", worker_threads = 5)]
@ -68,12 +128,72 @@ mod test_examples_import {
let parser = crate::parser::Parser::new(tokens); let parser = crate::parser::Parser::new(tokens);
let program = parser.ast().unwrap(); let program = parser.ast().unwrap();
let mut mem: crate::executor::ProgramMemory = Default::default(); let mut mem: crate::executor::ProgramMemory = Default::default();
let ctx = crate::executor::ExecutorContext::new(ws, kittycad::types::UnitLength::Mm) let units = kittycad::types::UnitLength::Mm;
let ctx = crate::executor::ExecutorContext::new(ws, units.clone())
.await .await
.unwrap(); .unwrap();
crate::executor::execute(program, &mut mem, crate::executor::BodyType::Root, &ctx) crate::executor::execute(program, &mut mem, crate::executor::BodyType::Root, &ctx)
.await .await
.unwrap(); .unwrap();
let (x, y) = crate::std::utils::get_camera_zoom_magnitude_per_unit_length(units);
ctx.engine
.send_modeling_cmd(
false,
uuid::Uuid::new_v4(),
crate::executor::SourceRange::default(),
kittycad::types::ModelingCmd::DefaultCameraLookAt {
center: kittycad::types::Point3D {
x: 0.0,
y: 0.0,
z: 0.0,
},
up: kittycad::types::Point3D {
x: 0.0,
y: 0.0,
z: 1.0,
},
vantage: kittycad::types::Point3D {
x: 0.0,
y: -x,
z: y,
},
sequence: None,
},
)
.await
.unwrap();
let resp = ctx
.engine
.send_modeling_cmd(
false,
uuid::Uuid::new_v4(),
crate::executor::SourceRange::default(),
kittycad::types::ModelingCmd::TakeSnapshot {
format: kittycad::types::ImageFormat::Png,
},
)
.await
.unwrap();
let output_file =
std::env::temp_dir().join(format!("kcl_output_{}.png", uuid::Uuid::new_v4()));
if let kittycad::types::OkWebSocketResponseData::Modeling {
modeling_response: kittycad::types::OkModelingCmdResponse::TakeSnapshot { data },
} = &resp
{
std::fs::write(&output_file, &data.contents.0).unwrap();
} else {
panic!("Unexpected response from engine: {:?}", resp);
}
let actual = image::io::Reader::open(output_file)
.unwrap()
.decode()
.unwrap();
twenty_twenty::assert_image(
&format!("tests/outputs/{}.png", "serial_test_example_import1"),
&actual,
1.0,
);
} }
} }
@ -112,7 +232,7 @@ impl crate::docs::StdLibFn for Import {
} }
fn tags(&self) -> Vec<String> { fn tags(&self) -> Vec<String> {
vec![] vec!["norun".to_string()]
} }
fn args(&self) -> Vec<crate::docs::StdLibFnArg> { fn args(&self) -> Vec<crate::docs::StdLibFnArg> {

View File

@ -29,12 +29,72 @@ mod test_examples_line_to {
let parser = crate::parser::Parser::new(tokens); let parser = crate::parser::Parser::new(tokens);
let program = parser.ast().unwrap(); let program = parser.ast().unwrap();
let mut mem: crate::executor::ProgramMemory = Default::default(); let mut mem: crate::executor::ProgramMemory = Default::default();
let ctx = crate::executor::ExecutorContext::new(ws, kittycad::types::UnitLength::Mm) let units = kittycad::types::UnitLength::Mm;
let ctx = crate::executor::ExecutorContext::new(ws, units.clone())
.await .await
.unwrap(); .unwrap();
crate::executor::execute(program, &mut mem, crate::executor::BodyType::Root, &ctx) crate::executor::execute(program, &mut mem, crate::executor::BodyType::Root, &ctx)
.await .await
.unwrap(); .unwrap();
let (x, y) = crate::std::utils::get_camera_zoom_magnitude_per_unit_length(units);
ctx.engine
.send_modeling_cmd(
false,
uuid::Uuid::new_v4(),
crate::executor::SourceRange::default(),
kittycad::types::ModelingCmd::DefaultCameraLookAt {
center: kittycad::types::Point3D {
x: 0.0,
y: 0.0,
z: 0.0,
},
up: kittycad::types::Point3D {
x: 0.0,
y: 0.0,
z: 1.0,
},
vantage: kittycad::types::Point3D {
x: 0.0,
y: -x,
z: y,
},
sequence: None,
},
)
.await
.unwrap();
let resp = ctx
.engine
.send_modeling_cmd(
false,
uuid::Uuid::new_v4(),
crate::executor::SourceRange::default(),
kittycad::types::ModelingCmd::TakeSnapshot {
format: kittycad::types::ImageFormat::Png,
},
)
.await
.unwrap();
let output_file =
std::env::temp_dir().join(format!("kcl_output_{}.png", uuid::Uuid::new_v4()));
if let kittycad::types::OkWebSocketResponseData::Modeling {
modeling_response: kittycad::types::OkModelingCmdResponse::TakeSnapshot { data },
} = &resp
{
std::fs::write(&output_file, &data.contents.0).unwrap();
} else {
panic!("Unexpected response from engine: {:?}", resp);
}
let actual = image::io::Reader::open(output_file)
.unwrap()
.decode()
.unwrap();
twenty_twenty::assert_image(
&format!("tests/outputs/{}.png", "serial_test_example_line_to0"),
&actual,
1.0,
);
} }
#[tokio::test(flavor = "multi_thread", worker_threads = 5)] #[tokio::test(flavor = "multi_thread", worker_threads = 5)]
@ -66,12 +126,72 @@ mod test_examples_line_to {
let parser = crate::parser::Parser::new(tokens); let parser = crate::parser::Parser::new(tokens);
let program = parser.ast().unwrap(); let program = parser.ast().unwrap();
let mut mem: crate::executor::ProgramMemory = Default::default(); let mut mem: crate::executor::ProgramMemory = Default::default();
let ctx = crate::executor::ExecutorContext::new(ws, kittycad::types::UnitLength::Mm) let units = kittycad::types::UnitLength::Mm;
let ctx = crate::executor::ExecutorContext::new(ws, units.clone())
.await .await
.unwrap(); .unwrap();
crate::executor::execute(program, &mut mem, crate::executor::BodyType::Root, &ctx) crate::executor::execute(program, &mut mem, crate::executor::BodyType::Root, &ctx)
.await .await
.unwrap(); .unwrap();
let (x, y) = crate::std::utils::get_camera_zoom_magnitude_per_unit_length(units);
ctx.engine
.send_modeling_cmd(
false,
uuid::Uuid::new_v4(),
crate::executor::SourceRange::default(),
kittycad::types::ModelingCmd::DefaultCameraLookAt {
center: kittycad::types::Point3D {
x: 0.0,
y: 0.0,
z: 0.0,
},
up: kittycad::types::Point3D {
x: 0.0,
y: 0.0,
z: 1.0,
},
vantage: kittycad::types::Point3D {
x: 0.0,
y: -x,
z: y,
},
sequence: None,
},
)
.await
.unwrap();
let resp = ctx
.engine
.send_modeling_cmd(
false,
uuid::Uuid::new_v4(),
crate::executor::SourceRange::default(),
kittycad::types::ModelingCmd::TakeSnapshot {
format: kittycad::types::ImageFormat::Png,
},
)
.await
.unwrap();
let output_file =
std::env::temp_dir().join(format!("kcl_output_{}.png", uuid::Uuid::new_v4()));
if let kittycad::types::OkWebSocketResponseData::Modeling {
modeling_response: kittycad::types::OkModelingCmdResponse::TakeSnapshot { data },
} = &resp
{
std::fs::write(&output_file, &data.contents.0).unwrap();
} else {
panic!("Unexpected response from engine: {:?}", resp);
}
let actual = image::io::Reader::open(output_file)
.unwrap()
.decode()
.unwrap();
twenty_twenty::assert_image(
&format!("tests/outputs/{}.png", "serial_test_example_line_to1"),
&actual,
1.0,
);
} }
} }

View File

@ -29,12 +29,72 @@ mod test_examples_min {
let parser = crate::parser::Parser::new(tokens); let parser = crate::parser::Parser::new(tokens);
let program = parser.ast().unwrap(); let program = parser.ast().unwrap();
let mut mem: crate::executor::ProgramMemory = Default::default(); let mut mem: crate::executor::ProgramMemory = Default::default();
let ctx = crate::executor::ExecutorContext::new(ws, kittycad::types::UnitLength::Mm) let units = kittycad::types::UnitLength::Mm;
let ctx = crate::executor::ExecutorContext::new(ws, units.clone())
.await .await
.unwrap(); .unwrap();
crate::executor::execute(program, &mut mem, crate::executor::BodyType::Root, &ctx) crate::executor::execute(program, &mut mem, crate::executor::BodyType::Root, &ctx)
.await .await
.unwrap(); .unwrap();
let (x, y) = crate::std::utils::get_camera_zoom_magnitude_per_unit_length(units);
ctx.engine
.send_modeling_cmd(
false,
uuid::Uuid::new_v4(),
crate::executor::SourceRange::default(),
kittycad::types::ModelingCmd::DefaultCameraLookAt {
center: kittycad::types::Point3D {
x: 0.0,
y: 0.0,
z: 0.0,
},
up: kittycad::types::Point3D {
x: 0.0,
y: 0.0,
z: 1.0,
},
vantage: kittycad::types::Point3D {
x: 0.0,
y: -x,
z: y,
},
sequence: None,
},
)
.await
.unwrap();
let resp = ctx
.engine
.send_modeling_cmd(
false,
uuid::Uuid::new_v4(),
crate::executor::SourceRange::default(),
kittycad::types::ModelingCmd::TakeSnapshot {
format: kittycad::types::ImageFormat::Png,
},
)
.await
.unwrap();
let output_file =
std::env::temp_dir().join(format!("kcl_output_{}.png", uuid::Uuid::new_v4()));
if let kittycad::types::OkWebSocketResponseData::Modeling {
modeling_response: kittycad::types::OkModelingCmdResponse::TakeSnapshot { data },
} = &resp
{
std::fs::write(&output_file, &data.contents.0).unwrap();
} else {
panic!("Unexpected response from engine: {:?}", resp);
}
let actual = image::io::Reader::open(output_file)
.unwrap()
.decode()
.unwrap();
twenty_twenty::assert_image(
&format!("tests/outputs/{}.png", "serial_test_example_min0"),
&actual,
1.0,
);
} }
#[tokio::test(flavor = "multi_thread", worker_threads = 5)] #[tokio::test(flavor = "multi_thread", worker_threads = 5)]
@ -66,12 +126,72 @@ mod test_examples_min {
let parser = crate::parser::Parser::new(tokens); let parser = crate::parser::Parser::new(tokens);
let program = parser.ast().unwrap(); let program = parser.ast().unwrap();
let mut mem: crate::executor::ProgramMemory = Default::default(); let mut mem: crate::executor::ProgramMemory = Default::default();
let ctx = crate::executor::ExecutorContext::new(ws, kittycad::types::UnitLength::Mm) let units = kittycad::types::UnitLength::Mm;
let ctx = crate::executor::ExecutorContext::new(ws, units.clone())
.await .await
.unwrap(); .unwrap();
crate::executor::execute(program, &mut mem, crate::executor::BodyType::Root, &ctx) crate::executor::execute(program, &mut mem, crate::executor::BodyType::Root, &ctx)
.await .await
.unwrap(); .unwrap();
let (x, y) = crate::std::utils::get_camera_zoom_magnitude_per_unit_length(units);
ctx.engine
.send_modeling_cmd(
false,
uuid::Uuid::new_v4(),
crate::executor::SourceRange::default(),
kittycad::types::ModelingCmd::DefaultCameraLookAt {
center: kittycad::types::Point3D {
x: 0.0,
y: 0.0,
z: 0.0,
},
up: kittycad::types::Point3D {
x: 0.0,
y: 0.0,
z: 1.0,
},
vantage: kittycad::types::Point3D {
x: 0.0,
y: -x,
z: y,
},
sequence: None,
},
)
.await
.unwrap();
let resp = ctx
.engine
.send_modeling_cmd(
false,
uuid::Uuid::new_v4(),
crate::executor::SourceRange::default(),
kittycad::types::ModelingCmd::TakeSnapshot {
format: kittycad::types::ImageFormat::Png,
},
)
.await
.unwrap();
let output_file =
std::env::temp_dir().join(format!("kcl_output_{}.png", uuid::Uuid::new_v4()));
if let kittycad::types::OkWebSocketResponseData::Modeling {
modeling_response: kittycad::types::OkModelingCmdResponse::TakeSnapshot { data },
} = &resp
{
std::fs::write(&output_file, &data.contents.0).unwrap();
} else {
panic!("Unexpected response from engine: {:?}", resp);
}
let actual = image::io::Reader::open(output_file)
.unwrap()
.decode()
.unwrap();
twenty_twenty::assert_image(
&format!("tests/outputs/{}.png", "serial_test_example_min1"),
&actual,
1.0,
);
} }
} }

View File

@ -29,12 +29,72 @@ mod test_examples_show {
let parser = crate::parser::Parser::new(tokens); let parser = crate::parser::Parser::new(tokens);
let program = parser.ast().unwrap(); let program = parser.ast().unwrap();
let mut mem: crate::executor::ProgramMemory = Default::default(); let mut mem: crate::executor::ProgramMemory = Default::default();
let ctx = crate::executor::ExecutorContext::new(ws, kittycad::types::UnitLength::Mm) let units = kittycad::types::UnitLength::Mm;
let ctx = crate::executor::ExecutorContext::new(ws, units.clone())
.await .await
.unwrap(); .unwrap();
crate::executor::execute(program, &mut mem, crate::executor::BodyType::Root, &ctx) crate::executor::execute(program, &mut mem, crate::executor::BodyType::Root, &ctx)
.await .await
.unwrap(); .unwrap();
let (x, y) = crate::std::utils::get_camera_zoom_magnitude_per_unit_length(units);
ctx.engine
.send_modeling_cmd(
false,
uuid::Uuid::new_v4(),
crate::executor::SourceRange::default(),
kittycad::types::ModelingCmd::DefaultCameraLookAt {
center: kittycad::types::Point3D {
x: 0.0,
y: 0.0,
z: 0.0,
},
up: kittycad::types::Point3D {
x: 0.0,
y: 0.0,
z: 1.0,
},
vantage: kittycad::types::Point3D {
x: 0.0,
y: -x,
z: y,
},
sequence: None,
},
)
.await
.unwrap();
let resp = ctx
.engine
.send_modeling_cmd(
false,
uuid::Uuid::new_v4(),
crate::executor::SourceRange::default(),
kittycad::types::ModelingCmd::TakeSnapshot {
format: kittycad::types::ImageFormat::Png,
},
)
.await
.unwrap();
let output_file =
std::env::temp_dir().join(format!("kcl_output_{}.png", uuid::Uuid::new_v4()));
if let kittycad::types::OkWebSocketResponseData::Modeling {
modeling_response: kittycad::types::OkModelingCmdResponse::TakeSnapshot { data },
} = &resp
{
std::fs::write(&output_file, &data.contents.0).unwrap();
} else {
panic!("Unexpected response from engine: {:?}", resp);
}
let actual = image::io::Reader::open(output_file)
.unwrap()
.decode()
.unwrap();
twenty_twenty::assert_image(
&format!("tests/outputs/{}.png", "serial_test_example_show0"),
&actual,
1.0,
);
} }
} }

View File

@ -1,7 +1,6 @@
#[cfg(test)] #[cfg(test)]
mod test_examples_import { mod test_examples_import {
#[tokio::test(flavor = "multi_thread", worker_threads = 5)] #[tokio::test(flavor = "multi_thread", worker_threads = 5)]
#[ignore]
async fn serial_test_example_import0() { async fn serial_test_example_import0() {
let user_agent = concat!(env!("CARGO_PKG_NAME"), ".rs/", env!("CARGO_PKG_VERSION"),); let user_agent = concat!(env!("CARGO_PKG_NAME"), ".rs/", env!("CARGO_PKG_VERSION"),);
let http_client = reqwest::Client::builder() let http_client = reqwest::Client::builder()
@ -30,12 +29,72 @@ mod test_examples_import {
let parser = crate::parser::Parser::new(tokens); let parser = crate::parser::Parser::new(tokens);
let program = parser.ast().unwrap(); let program = parser.ast().unwrap();
let mut mem: crate::executor::ProgramMemory = Default::default(); let mut mem: crate::executor::ProgramMemory = Default::default();
let ctx = crate::executor::ExecutorContext::new(ws, kittycad::types::UnitLength::Mm) let units = kittycad::types::UnitLength::Mm;
let ctx = crate::executor::ExecutorContext::new(ws, units.clone())
.await .await
.unwrap(); .unwrap();
crate::executor::execute(program, &mut mem, crate::executor::BodyType::Root, &ctx) crate::executor::execute(program, &mut mem, crate::executor::BodyType::Root, &ctx)
.await .await
.unwrap(); .unwrap();
let (x, y) = crate::std::utils::get_camera_zoom_magnitude_per_unit_length(units);
ctx.engine
.send_modeling_cmd(
false,
uuid::Uuid::new_v4(),
crate::executor::SourceRange::default(),
kittycad::types::ModelingCmd::DefaultCameraLookAt {
center: kittycad::types::Point3D {
x: 0.0,
y: 0.0,
z: 0.0,
},
up: kittycad::types::Point3D {
x: 0.0,
y: 0.0,
z: 1.0,
},
vantage: kittycad::types::Point3D {
x: 0.0,
y: -x,
z: y,
},
sequence: None,
},
)
.await
.unwrap();
let resp = ctx
.engine
.send_modeling_cmd(
false,
uuid::Uuid::new_v4(),
crate::executor::SourceRange::default(),
kittycad::types::ModelingCmd::TakeSnapshot {
format: kittycad::types::ImageFormat::Png,
},
)
.await
.unwrap();
let output_file =
std::env::temp_dir().join(format!("kcl_output_{}.png", uuid::Uuid::new_v4()));
if let kittycad::types::OkWebSocketResponseData::Modeling {
modeling_response: kittycad::types::OkModelingCmdResponse::TakeSnapshot { data },
} = &resp
{
std::fs::write(&output_file, &data.contents.0).unwrap();
} else {
panic!("Unexpected response from engine: {:?}", resp);
}
let actual = image::io::Reader::open(output_file)
.unwrap()
.decode()
.unwrap();
twenty_twenty::assert_image(
&format!("tests/outputs/{}.png", "serial_test_example_import0"),
&actual,
1.0,
);
} }
} }

View File

@ -1,7 +1,6 @@
#[cfg(test)] #[cfg(test)]
mod test_examples_import { mod test_examples_import {
#[tokio::test(flavor = "multi_thread", worker_threads = 5)] #[tokio::test(flavor = "multi_thread", worker_threads = 5)]
#[ignore]
async fn serial_test_example_import0() { async fn serial_test_example_import0() {
let user_agent = concat!(env!("CARGO_PKG_NAME"), ".rs/", env!("CARGO_PKG_VERSION"),); let user_agent = concat!(env!("CARGO_PKG_NAME"), ".rs/", env!("CARGO_PKG_VERSION"),);
let http_client = reqwest::Client::builder() let http_client = reqwest::Client::builder()
@ -30,12 +29,72 @@ mod test_examples_import {
let parser = crate::parser::Parser::new(tokens); let parser = crate::parser::Parser::new(tokens);
let program = parser.ast().unwrap(); let program = parser.ast().unwrap();
let mut mem: crate::executor::ProgramMemory = Default::default(); let mut mem: crate::executor::ProgramMemory = Default::default();
let ctx = crate::executor::ExecutorContext::new(ws, kittycad::types::UnitLength::Mm) let units = kittycad::types::UnitLength::Mm;
let ctx = crate::executor::ExecutorContext::new(ws, units.clone())
.await .await
.unwrap(); .unwrap();
crate::executor::execute(program, &mut mem, crate::executor::BodyType::Root, &ctx) crate::executor::execute(program, &mut mem, crate::executor::BodyType::Root, &ctx)
.await .await
.unwrap(); .unwrap();
let (x, y) = crate::std::utils::get_camera_zoom_magnitude_per_unit_length(units);
ctx.engine
.send_modeling_cmd(
false,
uuid::Uuid::new_v4(),
crate::executor::SourceRange::default(),
kittycad::types::ModelingCmd::DefaultCameraLookAt {
center: kittycad::types::Point3D {
x: 0.0,
y: 0.0,
z: 0.0,
},
up: kittycad::types::Point3D {
x: 0.0,
y: 0.0,
z: 1.0,
},
vantage: kittycad::types::Point3D {
x: 0.0,
y: -x,
z: y,
},
sequence: None,
},
)
.await
.unwrap();
let resp = ctx
.engine
.send_modeling_cmd(
false,
uuid::Uuid::new_v4(),
crate::executor::SourceRange::default(),
kittycad::types::ModelingCmd::TakeSnapshot {
format: kittycad::types::ImageFormat::Png,
},
)
.await
.unwrap();
let output_file =
std::env::temp_dir().join(format!("kcl_output_{}.png", uuid::Uuid::new_v4()));
if let kittycad::types::OkWebSocketResponseData::Modeling {
modeling_response: kittycad::types::OkModelingCmdResponse::TakeSnapshot { data },
} = &resp
{
std::fs::write(&output_file, &data.contents.0).unwrap();
} else {
panic!("Unexpected response from engine: {:?}", resp);
}
let actual = image::io::Reader::open(output_file)
.unwrap()
.decode()
.unwrap();
twenty_twenty::assert_image(
&format!("tests/outputs/{}.png", "serial_test_example_import0"),
&actual,
1.0,
);
} }
} }

View File

@ -1,7 +1,6 @@
#[cfg(test)] #[cfg(test)]
mod test_examples_import { mod test_examples_import {
#[tokio::test(flavor = "multi_thread", worker_threads = 5)] #[tokio::test(flavor = "multi_thread", worker_threads = 5)]
#[ignore]
async fn serial_test_example_import0() { async fn serial_test_example_import0() {
let user_agent = concat!(env!("CARGO_PKG_NAME"), ".rs/", env!("CARGO_PKG_VERSION"),); let user_agent = concat!(env!("CARGO_PKG_NAME"), ".rs/", env!("CARGO_PKG_VERSION"),);
let http_client = reqwest::Client::builder() let http_client = reqwest::Client::builder()
@ -30,12 +29,72 @@ mod test_examples_import {
let parser = crate::parser::Parser::new(tokens); let parser = crate::parser::Parser::new(tokens);
let program = parser.ast().unwrap(); let program = parser.ast().unwrap();
let mut mem: crate::executor::ProgramMemory = Default::default(); let mut mem: crate::executor::ProgramMemory = Default::default();
let ctx = crate::executor::ExecutorContext::new(ws, kittycad::types::UnitLength::Mm) let units = kittycad::types::UnitLength::Mm;
let ctx = crate::executor::ExecutorContext::new(ws, units.clone())
.await .await
.unwrap(); .unwrap();
crate::executor::execute(program, &mut mem, crate::executor::BodyType::Root, &ctx) crate::executor::execute(program, &mut mem, crate::executor::BodyType::Root, &ctx)
.await .await
.unwrap(); .unwrap();
let (x, y) = crate::std::utils::get_camera_zoom_magnitude_per_unit_length(units);
ctx.engine
.send_modeling_cmd(
false,
uuid::Uuid::new_v4(),
crate::executor::SourceRange::default(),
kittycad::types::ModelingCmd::DefaultCameraLookAt {
center: kittycad::types::Point3D {
x: 0.0,
y: 0.0,
z: 0.0,
},
up: kittycad::types::Point3D {
x: 0.0,
y: 0.0,
z: 1.0,
},
vantage: kittycad::types::Point3D {
x: 0.0,
y: -x,
z: y,
},
sequence: None,
},
)
.await
.unwrap();
let resp = ctx
.engine
.send_modeling_cmd(
false,
uuid::Uuid::new_v4(),
crate::executor::SourceRange::default(),
kittycad::types::ModelingCmd::TakeSnapshot {
format: kittycad::types::ImageFormat::Png,
},
)
.await
.unwrap();
let output_file =
std::env::temp_dir().join(format!("kcl_output_{}.png", uuid::Uuid::new_v4()));
if let kittycad::types::OkWebSocketResponseData::Modeling {
modeling_response: kittycad::types::OkModelingCmdResponse::TakeSnapshot { data },
} = &resp
{
std::fs::write(&output_file, &data.contents.0).unwrap();
} else {
panic!("Unexpected response from engine: {:?}", resp);
}
let actual = image::io::Reader::open(output_file)
.unwrap()
.decode()
.unwrap();
twenty_twenty::assert_image(
&format!("tests/outputs/{}.png", "serial_test_example_import0"),
&actual,
1.0,
);
} }
} }

View File

@ -29,12 +29,72 @@ mod test_examples_show {
let parser = crate::parser::Parser::new(tokens); let parser = crate::parser::Parser::new(tokens);
let program = parser.ast().unwrap(); let program = parser.ast().unwrap();
let mut mem: crate::executor::ProgramMemory = Default::default(); let mut mem: crate::executor::ProgramMemory = Default::default();
let ctx = crate::executor::ExecutorContext::new(ws, kittycad::types::UnitLength::Mm) let units = kittycad::types::UnitLength::Mm;
let ctx = crate::executor::ExecutorContext::new(ws, units.clone())
.await .await
.unwrap(); .unwrap();
crate::executor::execute(program, &mut mem, crate::executor::BodyType::Root, &ctx) crate::executor::execute(program, &mut mem, crate::executor::BodyType::Root, &ctx)
.await .await
.unwrap(); .unwrap();
let (x, y) = crate::std::utils::get_camera_zoom_magnitude_per_unit_length(units);
ctx.engine
.send_modeling_cmd(
false,
uuid::Uuid::new_v4(),
crate::executor::SourceRange::default(),
kittycad::types::ModelingCmd::DefaultCameraLookAt {
center: kittycad::types::Point3D {
x: 0.0,
y: 0.0,
z: 0.0,
},
up: kittycad::types::Point3D {
x: 0.0,
y: 0.0,
z: 1.0,
},
vantage: kittycad::types::Point3D {
x: 0.0,
y: -x,
z: y,
},
sequence: None,
},
)
.await
.unwrap();
let resp = ctx
.engine
.send_modeling_cmd(
false,
uuid::Uuid::new_v4(),
crate::executor::SourceRange::default(),
kittycad::types::ModelingCmd::TakeSnapshot {
format: kittycad::types::ImageFormat::Png,
},
)
.await
.unwrap();
let output_file =
std::env::temp_dir().join(format!("kcl_output_{}.png", uuid::Uuid::new_v4()));
if let kittycad::types::OkWebSocketResponseData::Modeling {
modeling_response: kittycad::types::OkModelingCmdResponse::TakeSnapshot { data },
} = &resp
{
std::fs::write(&output_file, &data.contents.0).unwrap();
} else {
panic!("Unexpected response from engine: {:?}", resp);
}
let actual = image::io::Reader::open(output_file)
.unwrap()
.decode()
.unwrap();
twenty_twenty::assert_image(
&format!("tests/outputs/{}.png", "serial_test_example_show0"),
&actual,
1.0,
);
} }
} }

View File

@ -67,12 +67,16 @@ debug = true
debug = true # Flamegraphs of benchmarks require accurate debug symbols debug = true # Flamegraphs of benchmarks require accurate debug symbols
[dev-dependencies] [dev-dependencies]
base64 = "0.22.0"
convert_case = "0.6.0"
criterion = "0.5.1" criterion = "0.5.1"
expectorate = "1.1.0" expectorate = "1.1.0"
image = "0.24.9"
insta = { version = "1.36.1", features = ["json"] } insta = { version = "1.36.1", features = ["json"] }
itertools = "0.12.1" itertools = "0.12.1"
pretty_assertions = "1.4.0" pretty_assertions = "1.4.0"
tokio = { version = "1.36.0", features = ["rt-multi-thread", "macros", "time"] } tokio = { version = "1.36.0", features = ["rt-multi-thread", "macros", "time"] }
twenty-twenty = "0.7.0"
[[bench]] [[bench]]
name = "compiler_benchmark" name = "compiler_benchmark"

View File

@ -149,6 +149,7 @@ pub async fn import(args: Args) -> Result<MemoryItem, KclError> {
/// ``` /// ```
#[stdlib { #[stdlib {
name = "import", name = "import",
tags = ["norun"],
}] }]
async fn inner_import( async fn inner_import(
file_path: String, file_path: String,

View File

@ -25,6 +25,7 @@ pub async fn cos(args: Args) -> Result<MemoryItem, KclError> {
/// ``` /// ```
#[stdlib { #[stdlib {
name = "cos", name = "cos",
tags = ["math"],
}] }]
fn inner_cos(num: f64) -> Result<f64, KclError> { fn inner_cos(num: f64) -> Result<f64, KclError> {
Ok(num.cos()) Ok(num.cos())
@ -45,6 +46,7 @@ pub async fn sin(args: Args) -> Result<MemoryItem, KclError> {
/// ``` /// ```
#[stdlib { #[stdlib {
name = "sin", name = "sin",
tags = ["math"],
}] }]
fn inner_sin(num: f64) -> Result<f64, KclError> { fn inner_sin(num: f64) -> Result<f64, KclError> {
Ok(num.sin()) Ok(num.sin())
@ -65,6 +67,7 @@ pub async fn tan(args: Args) -> Result<MemoryItem, KclError> {
/// ``` /// ```
#[stdlib { #[stdlib {
name = "tan", name = "tan",
tags = ["math"],
}] }]
fn inner_tan(num: f64) -> Result<f64, KclError> { fn inner_tan(num: f64) -> Result<f64, KclError> {
Ok(num.tan()) Ok(num.tan())
@ -84,6 +87,7 @@ pub async fn pi(args: Args) -> Result<MemoryItem, KclError> {
/// ``` /// ```
#[stdlib { #[stdlib {
name = "pi", name = "pi",
tags = ["math"],
}] }]
fn inner_pi() -> Result<f64, KclError> { fn inner_pi() -> Result<f64, KclError> {
Ok(std::f64::consts::PI) Ok(std::f64::consts::PI)
@ -104,6 +108,7 @@ pub async fn sqrt(args: Args) -> Result<MemoryItem, KclError> {
/// ``` /// ```
#[stdlib { #[stdlib {
name = "sqrt", name = "sqrt",
tags = ["math"],
}] }]
fn inner_sqrt(num: f64) -> Result<f64, KclError> { fn inner_sqrt(num: f64) -> Result<f64, KclError> {
Ok(num.sqrt()) Ok(num.sqrt())
@ -124,6 +129,7 @@ pub async fn abs(args: Args) -> Result<MemoryItem, KclError> {
/// ``` /// ```
#[stdlib { #[stdlib {
name = "abs", name = "abs",
tags = ["math"],
}] }]
fn inner_abs(num: f64) -> Result<f64, KclError> { fn inner_abs(num: f64) -> Result<f64, KclError> {
Ok(num.abs()) Ok(num.abs())
@ -144,6 +150,7 @@ pub async fn floor(args: Args) -> Result<MemoryItem, KclError> {
/// ``` /// ```
#[stdlib { #[stdlib {
name = "floor", name = "floor",
tags = ["math"],
}] }]
fn inner_floor(num: f64) -> Result<f64, KclError> { fn inner_floor(num: f64) -> Result<f64, KclError> {
Ok(num.floor()) Ok(num.floor())
@ -164,6 +171,7 @@ pub async fn ceil(args: Args) -> Result<MemoryItem, KclError> {
/// ``` /// ```
#[stdlib { #[stdlib {
name = "ceil", name = "ceil",
tags = ["math"],
}] }]
fn inner_ceil(num: f64) -> Result<f64, KclError> { fn inner_ceil(num: f64) -> Result<f64, KclError> {
Ok(num.ceil()) Ok(num.ceil())
@ -184,6 +192,7 @@ pub async fn min(args: Args) -> Result<MemoryItem, KclError> {
/// ``` /// ```
#[stdlib { #[stdlib {
name = "min", name = "min",
tags = ["math"],
}] }]
fn inner_min(args: Vec<f64>) -> f64 { fn inner_min(args: Vec<f64>) -> f64 {
let mut min = std::f64::MAX; let mut min = std::f64::MAX;
@ -211,6 +220,7 @@ pub async fn max(args: Args) -> Result<MemoryItem, KclError> {
/// ``` /// ```
#[stdlib { #[stdlib {
name = "max", name = "max",
tags = ["math"],
}] }]
fn inner_max(args: Vec<f64>) -> f64 { fn inner_max(args: Vec<f64>) -> f64 {
let mut max = std::f64::MAX; let mut max = std::f64::MAX;
@ -252,6 +262,7 @@ pub async fn pow(args: Args) -> Result<MemoryItem, KclError> {
/// ``` /// ```
#[stdlib { #[stdlib {
name = "pow", name = "pow",
tags = ["math"],
}] }]
fn inner_pow(num: f64, pow: f64) -> Result<f64, KclError> { fn inner_pow(num: f64, pow: f64) -> Result<f64, KclError> {
Ok(num.powf(pow)) Ok(num.powf(pow))
@ -272,6 +283,7 @@ pub async fn acos(args: Args) -> Result<MemoryItem, KclError> {
/// ``` /// ```
#[stdlib { #[stdlib {
name = "acos", name = "acos",
tags = ["math"],
}] }]
fn inner_acos(num: f64) -> Result<f64, KclError> { fn inner_acos(num: f64) -> Result<f64, KclError> {
Ok(num.acos()) Ok(num.acos())
@ -292,6 +304,7 @@ pub async fn asin(args: Args) -> Result<MemoryItem, KclError> {
/// ``` /// ```
#[stdlib { #[stdlib {
name = "asin", name = "asin",
tags = ["math"],
}] }]
fn inner_asin(num: f64) -> Result<f64, KclError> { fn inner_asin(num: f64) -> Result<f64, KclError> {
Ok(num.asin()) Ok(num.asin())
@ -312,6 +325,7 @@ pub async fn atan(args: Args) -> Result<MemoryItem, KclError> {
/// ``` /// ```
#[stdlib { #[stdlib {
name = "atan", name = "atan",
tags = ["math"],
}] }]
fn inner_atan(num: f64) -> Result<f64, KclError> { fn inner_atan(num: f64) -> Result<f64, KclError> {
Ok(num.atan()) Ok(num.atan())
@ -353,6 +367,7 @@ pub async fn log(args: Args) -> Result<MemoryItem, KclError> {
/// ``` /// ```
#[stdlib { #[stdlib {
name = "log", name = "log",
tags = ["math"],
}] }]
fn inner_log(num: f64, base: f64) -> Result<f64, KclError> { fn inner_log(num: f64, base: f64) -> Result<f64, KclError> {
Ok(num.log(base)) Ok(num.log(base))
@ -373,6 +388,7 @@ pub async fn log2(args: Args) -> Result<MemoryItem, KclError> {
/// ``` /// ```
#[stdlib { #[stdlib {
name = "log2", name = "log2",
tags = ["math"],
}] }]
fn inner_log2(num: f64) -> Result<f64, KclError> { fn inner_log2(num: f64) -> Result<f64, KclError> {
Ok(num.log2()) Ok(num.log2())
@ -393,6 +409,7 @@ pub async fn log10(args: Args) -> Result<MemoryItem, KclError> {
/// ``` /// ```
#[stdlib { #[stdlib {
name = "log10", name = "log10",
tags = ["math"],
}] }]
fn inner_log10(num: f64) -> Result<f64, KclError> { fn inner_log10(num: f64) -> Result<f64, KclError> {
Ok(num.log10()) Ok(num.log10())
@ -413,6 +430,7 @@ pub async fn ln(args: Args) -> Result<MemoryItem, KclError> {
/// ``` /// ```
#[stdlib { #[stdlib {
name = "ln", name = "ln",
tags = ["math"],
}] }]
fn inner_ln(num: f64) -> Result<f64, KclError> { fn inner_ln(num: f64) -> Result<f64, KclError> {
Ok(num.ln()) Ok(num.ln())
@ -432,6 +450,7 @@ pub async fn e(args: Args) -> Result<MemoryItem, KclError> {
/// ``` /// ```
#[stdlib { #[stdlib {
name = "e", name = "e",
tags = ["math"],
}] }]
fn inner_e() -> Result<f64, KclError> { fn inner_e() -> Result<f64, KclError> {
Ok(std::f64::consts::E) Ok(std::f64::consts::E)
@ -451,6 +470,7 @@ pub async fn tau(args: Args) -> Result<MemoryItem, KclError> {
/// ``` /// ```
#[stdlib { #[stdlib {
name = "tau", name = "tau",
tags = ["math"],
}] }]
fn inner_tau() -> Result<f64, KclError> { fn inner_tau() -> Result<f64, KclError> {
Ok(std::f64::consts::TAU) Ok(std::f64::consts::TAU)
@ -471,6 +491,7 @@ pub async fn to_radians(args: Args) -> Result<MemoryItem, KclError> {
/// ``` /// ```
#[stdlib { #[stdlib {
name = "toRadians", name = "toRadians",
tags = ["math"],
}] }]
fn inner_to_radians(num: f64) -> Result<f64, KclError> { fn inner_to_radians(num: f64) -> Result<f64, KclError> {
Ok(num.to_radians()) Ok(num.to_radians())
@ -491,6 +512,7 @@ pub async fn to_degrees(args: Args) -> Result<MemoryItem, KclError> {
/// ``` /// ```
#[stdlib { #[stdlib {
name = "toDegrees", name = "toDegrees",
tags = ["math"],
}] }]
fn inner_to_degrees(num: f64) -> Result<f64, KclError> { fn inner_to_degrees(num: f64) -> Result<f64, KclError> {
Ok(num.to_degrees()) Ok(num.to_degrees())

View File

@ -923,6 +923,7 @@ pub async fn leg_length(args: Args) -> Result<MemoryItem, KclError> {
/// ``` /// ```
#[stdlib { #[stdlib {
name = "legLen", name = "legLen",
tags = ["utilities"],
}] }]
fn inner_leg_length(hypotenuse: f64, leg: f64) -> f64 { fn inner_leg_length(hypotenuse: f64, leg: f64) -> f64 {
(hypotenuse.powi(2) - f64::min(hypotenuse.abs(), leg.abs()).powi(2)).sqrt() (hypotenuse.powi(2) - f64::min(hypotenuse.abs(), leg.abs()).powi(2)).sqrt()
@ -942,6 +943,7 @@ pub async fn leg_angle_x(args: Args) -> Result<MemoryItem, KclError> {
/// ``` /// ```
#[stdlib { #[stdlib {
name = "legAngX", name = "legAngX",
tags = ["utilities"],
}] }]
fn inner_leg_angle_x(hypotenuse: f64, leg: f64) -> f64 { fn inner_leg_angle_x(hypotenuse: f64, leg: f64) -> f64 {
(leg.min(hypotenuse) / hypotenuse).acos().to_degrees() (leg.min(hypotenuse) / hypotenuse).acos().to_degrees()
@ -961,6 +963,7 @@ pub async fn leg_angle_y(args: Args) -> Result<MemoryItem, KclError> {
/// ``` /// ```
#[stdlib { #[stdlib {
name = "legAngY", name = "legAngY",
tags = ["utilities"],
}] }]
fn inner_leg_angle_y(hypotenuse: f64, leg: f64) -> f64 { fn inner_leg_angle_y(hypotenuse: f64, leg: f64) -> f64 {
(leg.min(hypotenuse) / hypotenuse).asin().to_degrees() (leg.min(hypotenuse) / hypotenuse).asin().to_degrees()
@ -983,6 +986,8 @@ pub enum Primitive {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use base64::Engine;
use convert_case::Casing;
use itertools::Itertools; use itertools::Itertools;
use crate::std::StdLib; use crate::std::StdLib;
@ -1054,13 +1059,68 @@ layout: manual
fn_docs.push_str(&signature); fn_docs.push_str(&signature);
fn_docs.push_str("\n```\n\n"); fn_docs.push_str("\n```\n\n");
// If the function has tags, we should add them to the docs.
let mut tags = internal_fn.tags().clone();
// Remove norun tag from the list of tags.
tags.retain(|tag| tag != "norun");
if !tags.is_empty() {
fn_docs.push_str("### Tags\n\n");
for tag in tags {
fn_docs.push_str(&format!("* `{}`\n", tag));
}
fn_docs.push('\n');
}
if !internal_fn.examples().is_empty() { if !internal_fn.examples().is_empty() {
fn_docs.push_str("### Examples\n\n"); fn_docs.push_str("### Examples\n\n");
for example in internal_fn.examples() { for (index, example) in internal_fn.examples().iter().enumerate() {
fn_docs.push_str("```js\n"); fn_docs.push_str("```js\n");
fn_docs.push_str(&example); fn_docs.push_str(example);
fn_docs.push_str("\n```\n\n"); fn_docs.push_str("\n```\n\n");
// If this is not a "math" or "utilities" function,
// we should add the image to the docs.
if !internal_fn.tags().contains(&"math".to_string())
&& !internal_fn.tags().contains(&"utilities".to_string())
&& !internal_fn.tags().contains(&"norun".to_string())
{
// Get the path to this specific rust file.
let dir = env!("CARGO_MANIFEST_DIR");
// Convert from camel case to snake case.
let mut fn_name = internal_fn.name().to_case(convert_case::Case::Snake);
// Clean the fn name.
if fn_name.starts_with("last_seg_") {
fn_name = fn_name.replace("last_seg_", "last_segment_");
} else if fn_name.contains("_2_d") {
fn_name = fn_name.replace("_2_d", "_2d");
} else if fn_name.contains("_3_d") {
fn_name = fn_name.replace("_3_d", "_3d");
} else if fn_name == "seg_ang" {
fn_name = "segment_angle".to_string();
} else if fn_name == "seg_len" {
fn_name = "segment_length".to_string();
} else if fn_name.starts_with("seg_") {
fn_name = fn_name.replace("seg_", "segment_");
}
// Read the image file and encode as base64.
let image_path = format!("{}/tests/outputs/serial_test_example_{}{}.png", dir, fn_name, index);
let image_data = std::fs::read(&image_path)
.unwrap_or_else(|_| panic!("Failed to read image file: {}", image_path));
let encoded = base64::engine::general_purpose::STANDARD.encode(&image_data);
fn_docs.push_str(&format!(
r#"![Rendered example of {} {}](data:image/png;base64,{})
"#,
internal_fn.name(),
index,
encoded,
));
}
} }
} }

View File

@ -168,7 +168,6 @@ pub async fn revolve(args: Args) -> Result<MemoryItem, KclError> {
/// angle: 90, /// angle: 90,
/// axis: getOppositeEdge('revolveAxis', box) /// axis: getOppositeEdge('revolveAxis', box)
/// }, %) /// }, %)
///
/// ``` /// ```
#[stdlib { #[stdlib {
name = "revolve", name = "revolve",

Binary file not shown.

After

Width:  |  Height:  |  Size: 92 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 92 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 93 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 93 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 102 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 104 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 95 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 96 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 102 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 102 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 101 KiB

Some files were not shown because too many files have changed in this diff Show More