Merge branch 'main' into pierremtb/issue5301-Expose-the-sectional-argument-in-the-Sweep-command-flow

This commit is contained in:
Pierre Jacquier
2025-03-17 16:58:35 -04:00
committed by GitHub
20 changed files with 2028 additions and 1111 deletions

View File

@ -220,8 +220,12 @@ jobs:
- name: Run ubuntu/chrome snapshots
if: needs.conditions.outputs.should-run == 'true'
run: |
yarn test:snapshots
uses: nick-fields/retry@v3.0.2
with:
shell: bash
command: yarn test:snapshots
timeout_minutes: 30
max_attempts: 3
env:
CI: true
NODE_ENV: development
@ -289,8 +293,8 @@ jobs:
matrix:
# TODO: enable self-hosted-windows-8-cores once available
os: [namespace-profile-ubuntu-8-cores, namespace-profile-macos-8-cores, windows-16-cores]
shardIndex: [1, 2, 3, 4]
shardTotal: [4]
shardIndex: [1, 2, 3, 4, 5, 6, 7, 8]
shardTotal: [8]
# TODO: add ref here for main and latest release tag
runs-on: ${{ matrix.os }}
steps:
@ -358,7 +362,7 @@ jobs:
shell: bash
command: .github/ci-cd-scripts/playwright-electron.sh ${{matrix.shardIndex}} ${{matrix.shardTotal}} ${{matrix.os}}
timeout_minutes: 30
max_attempts: 25
max_attempts: 15
env:
CI: true
FAIL_ON_CONSOLE_ERRORS: true

Binary file not shown.

Before

Width:  |  Height:  |  Size: 72 KiB

After

Width:  |  Height:  |  Size: 72 KiB

View File

@ -12,17 +12,17 @@
"main": ".vite/build/main.js",
"license": "MIT",
"dependencies": {
"@codemirror/autocomplete": "^6.17.0",
"@codemirror/autocomplete": "^6.18.6",
"@codemirror/commands": "^6.8.0",
"@codemirror/language": "^6.10.8",
"@codemirror/language": "^6.11.0",
"@codemirror/lint": "^6.8.4",
"@codemirror/search": "^6.5.10",
"@codemirror/state": "^6.4.1",
"@codemirror/theme-one-dark": "^6.1.2",
"@csstools/postcss-oklab-function": "^4.0.7",
"@fortawesome/fontawesome-svg-core": "^6.5.2",
"@fortawesome/free-brands-svg-icons": "^6.5.2",
"@fortawesome/free-solid-svg-icons": "^6.4.2",
"@fortawesome/fontawesome-svg-core": "^6.7.2",
"@fortawesome/free-brands-svg-icons": "^6.7.2",
"@fortawesome/free-solid-svg-icons": "^6.7.2",
"@fortawesome/react-fontawesome": "^0.2.0",
"@headlessui/react": "^1.7.19",
"@headlessui/tailwindcss": "^0.2.0",
@ -35,35 +35,35 @@
"@tweenjs/tween.js": "^23.1.1",
"@xstate/inspect": "^0.8.0",
"@xstate/react": "^4.1.1",
"bonjour-service": "^1.2.1",
"bonjour-service": "^1.3.0",
"chokidar": "^4.0.1",
"codemirror": "^6.0.1",
"decamelize": "^6.0.0",
"diff": "^7.0.0",
"electron-updater": "^6.6.0",
"fuse.js": "^7.0.0",
"fuse.js": "^7.1.0",
"html2canvas-pro": "^1.5.8",
"isomorphic-fetch": "^3.0.0",
"json-rpc-2.0": "^1.6.0",
"jszip": "^3.10.1",
"minimist": "^1.2.8",
"openid-client": "^5.6.5",
"re-resizable": "^6.9.11",
"re-resizable": "^6.11.2",
"react": "^18.3.1",
"react-dom": "^18.2.0",
"react-hot-toast": "^2.4.1",
"react-hot-toast": "^2.5.2",
"react-hotkeys-hook": "^4.6.1",
"react-json-view": "^1.21.3",
"react-modal": "^3.16.3",
"react-modal-promise": "^1.0.2",
"react-router-dom": "^6.28.0",
"sketch-helpers": "^0.0.4",
"three": "^0.172.0",
"three": "^0.174.0",
"ua-parser-js": "^1.0.37",
"uuid": "^11.0.2",
"uuid": "^11.1.0",
"vscode-jsonrpc": "^8.2.1",
"vscode-languageserver-protocol": "^3.17.5",
"vscode-uri": "^3.0.8",
"vscode-uri": "^3.1.0",
"web-vitals": "^3.5.2",
"xstate": "^5.19.2",
"yargs": "^17.7.2"
@ -151,16 +151,16 @@
},
"devDependencies": {
"@babel/plugin-proposal-private-property-in-object": "^7.21.11",
"@babel/preset-env": "^7.25.4",
"@electron-forge/cli": "^7.6.1",
"@electron-forge/plugin-fuses": "^7.6.1",
"@electron-forge/plugin-vite": "^7.6.1",
"@babel/preset-env": "^7.26.9",
"@electron-forge/cli": "^7.7.0",
"@electron-forge/plugin-fuses": "^7.7.0",
"@electron-forge/plugin-vite": "^7.7.0",
"@electron/fuses": "^1.8.0",
"@electron/notarize": "^2.5.0",
"@iarna/toml": "^2.2.5",
"@lezer/generator": "^1.7.2",
"@nabla/vite-plugin-eslint": "^2.0.5",
"@playwright/test": "^1.49.0",
"@playwright/test": "^1.51.0",
"@testing-library/jest-dom": "^5.14.1",
"@testing-library/react": "^15.0.2",
"@types/diff": "^7.0.1",
@ -174,7 +174,7 @@
"@types/react": "^18.3.4",
"@types/react-dom": "^18.3.1",
"@types/react-modal": "^3.16.3",
"@types/three": "^0.172.0",
"@types/three": "^0.174.0",
"@types/ua-parser-js": "^0.7.39",
"@types/uuid": "^9.0.8",
"@types/wicg-file-system-access": "^2023.10.5",
@ -187,11 +187,11 @@
"electron-builder": "^26.0.6",
"eslint": "^8.0.1",
"eslint-plugin-css-modules": "^2.12.0",
"eslint-plugin-import": "^2.30.0",
"eslint-plugin-jest": "^28.10.0",
"eslint-plugin-import": "^2.31.0",
"eslint-plugin-jest": "^28.11.0",
"eslint-plugin-jsx-a11y": "^6.10.2",
"eslint-plugin-react": "^7.37.4",
"eslint-plugin-react-hooks": "^5.1.0",
"eslint-plugin-react-hooks": "^5.2.0",
"eslint-plugin-react-perf": "^3.3.3",
"eslint-plugin-suggest-no-throw": "^1.0.0",
"eslint-plugin-testing-library": "^7.1.1",
@ -208,8 +208,8 @@
"setimmediate": "^1.0.5",
"tailwindcss": "^3.4.17",
"ts-node": "^10.0.0",
"typescript": "^5.7.3",
"typescript-eslint": "^8.23.0",
"typescript": "^5.8.2",
"typescript-eslint": "^8.26.1",
"vite": "^5.4.12",
"vite-plugin-package-version": "^1.1.0",
"vite-tsconfig-paths": "^4.3.2",

View File

@ -19,14 +19,14 @@
"private": false,
"dependencies": {
"@codemirror/autocomplete": "6.18.6",
"@codemirror/language": "^6.10.2",
"@codemirror/state": "^6.4.1",
"@codemirror/language": "^6.11.0",
"@codemirror/state": "^6.5.2",
"@lezer/highlight": "^1.2.0",
"@ts-stack/markdown": "^1.5.0",
"json-rpc-2.0": "^1.7.0",
"typescript": "^5.7.2",
"typescript": "^5.8.2",
"vscode-languageserver-protocol": "^3.17.5",
"vscode-uri": "^3.0.8"
"vscode-uri": "^3.1.0"
},
"devDependencies": {
"@types/node": "^22.13.9",

View File

@ -12,10 +12,10 @@
"@codemirror/view" "^6.17.0"
"@lezer/common" "^1.0.0"
"@codemirror/language@^6.0.0", "@codemirror/language@^6.10.2":
version "6.10.2"
resolved "https://registry.yarnpkg.com/@codemirror/language/-/language-6.10.2.tgz#4056dc219619627ffe995832eeb09cea6060be61"
integrity sha512-kgbTYTo0Au6dCSc/TFy7fK3fpJmgHDv1sG1KNQKJXVi+xBTEeBPY/M30YXiU6mMXeH+YIDLsbrT4ZwNRdtF+SA==
"@codemirror/language@^6.0.0", "@codemirror/language@^6.11.0":
version "6.11.0"
resolved "https://registry.yarnpkg.com/@codemirror/language/-/language-6.11.0.tgz#5ae90972601497f4575f30811519d720bf7232c9"
integrity sha512-A7+f++LodNNc1wGgoRDTt78cOwWm9KVezApgjOMp1W4hM0898nsqBXwF+sbePE7ZRcjN7Sa1Z5m2oN27XkmEjQ==
dependencies:
"@codemirror/state" "^6.0.0"
"@codemirror/view" "^6.23.0"
@ -24,10 +24,12 @@
"@lezer/lr" "^1.0.0"
style-mod "^4.0.0"
"@codemirror/state@^6.0.0", "@codemirror/state@^6.4.0", "@codemirror/state@^6.4.1":
version "6.4.1"
resolved "https://registry.yarnpkg.com/@codemirror/state/-/state-6.4.1.tgz#da57143695c056d9a3c38705ed34136e2b68171b"
integrity sha512-QkEyUiLhsJoZkbumGZlswmAhA7CBU02Wrz7zvH4SrcifbsqwlXShVXg65f3v/ts57W3dqyamEriMhij1Z3Zz4A==
"@codemirror/state@^6.0.0", "@codemirror/state@^6.4.0", "@codemirror/state@^6.5.2":
version "6.5.2"
resolved "https://registry.yarnpkg.com/@codemirror/state/-/state-6.5.2.tgz#8eca3a64212a83367dc85475b7d78d5c9b7076c6"
integrity sha512-FVqsPqtPWKVVL3dPSxy8wEF/ymIEuVzF1PK3VbUgrxXpJUSHQWWZz4JMToquRxnkw+36LTamCZG2iua2Ptq0fA==
dependencies:
"@marijn/find-cluster-break" "^1.0.0"
"@codemirror/view@^6.17.0", "@codemirror/view@^6.23.0":
version "6.28.2"
@ -82,6 +84,11 @@
dependencies:
"@lezer/common" "^1.0.0"
"@marijn/find-cluster-break@^1.0.0":
version "1.0.2"
resolved "https://registry.yarnpkg.com/@marijn/find-cluster-break/-/find-cluster-break-1.0.2.tgz#775374306116d51c0c500b8c4face0f9a04752d8"
integrity sha512-l0h88YhZFyKdXIFNfSWpyjStDjGHwZ/U7iobcK1cQQD8sejsONdQtTVU+1wVN1PBw40PiiHB1vA5S7VTfQiP9g==
"@ts-stack/markdown@^1.5.0":
version "1.5.0"
resolved "https://registry.yarnpkg.com/@ts-stack/markdown/-/markdown-1.5.0.tgz#5dc298a20dc3dc040143c5a5948201eb6bf5419d"
@ -182,10 +189,10 @@ tslib@^2.3.0:
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.3.tgz#0438f810ad7a9edcde7a241c3d80db693c8cbfe0"
integrity sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==
typescript@^5.7.2:
version "5.7.2"
resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.7.2.tgz#3169cf8c4c8a828cde53ba9ecb3d2b1d5dd67be6"
integrity sha512-i5t66RHxDvVN40HfDd1PsEThGNnlMCMT3jMUuoh9/0TaqWevNontacunWyN02LA9/fIbEWlcHZcgTKb9QoaLfg==
typescript@^5.8.2:
version "5.8.2"
resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.8.2.tgz#8170b3702f74b79db2e5a96207c15e65807999e4"
integrity sha512-aJn6wq13/afZp/jT9QZmwEjDqqvSGp1VT5GVg+f/t6/oVyrgXM6BY1h9BRh/O5p3PlUPAe+WuiEZOmb/49RqoQ==
undici-types@~6.20.0:
version "6.20.0"
@ -215,10 +222,10 @@ vscode-languageserver-types@3.17.5:
resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.17.5.tgz#3273676f0cf2eab40b3f44d085acbb7f08a39d8a"
integrity sha512-Ld1VelNuX9pdF39h2Hgaeb5hEZM2Z3jUrrMgWQAu82jMtZp7p3vJT3BzToKtZI7NgQssZje5o0zryOrhQvzQAg==
vscode-uri@^3.0.8:
version "3.0.8"
resolved "https://registry.yarnpkg.com/vscode-uri/-/vscode-uri-3.0.8.tgz#1770938d3e72588659a172d0fd4642780083ff9f"
integrity sha512-AyFQ0EVmsOZOlAnxoFOGOq1SQDWAB7C6aqMGS23svWAllfOaxbuFvcT8D1i8z3Gyn8fraVeZNNmN6e9bxxXkKw==
vscode-uri@^3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/vscode-uri/-/vscode-uri-3.1.0.tgz#dd09ec5a66a38b5c3fffc774015713496d14e09c"
integrity sha512-/BpdSx+yCQGnCvecbyXdxHDkuk55/G3xwnC0GqY4gmQ3j+A+g8kzzgB4Nk/SINjqn6+waqw3EgbVF2QKExkRxQ==
w3c-keyname@^2.2.4:
version "2.2.8"

View File

@ -13,7 +13,7 @@ export default defineConfig({
/* Do not retry */
retries: 0,
/* Different amount of parallelism on CI and local. */
workers: 8,
workers: 1,
/* Reporter to use. See https://playwright.dev/docs/test-reporters */
reporter: [
['dot'],

View File

@ -2245,3 +2245,24 @@ mod assembly_mixed_units_cubes {
super::execute(TEST_NAME, true).await
}
}
mod bad_units_in_annotation {
const TEST_NAME: &str = "bad_units_in_annotation";
/// 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, true).await
}
}

View File

@ -0,0 +1,56 @@
---
source: kcl-lib/src/simulation_tests.rs
description: Artifact commands bad_units_in_annotation.kcl
---
[
{
"cmdId": "[uuid]",
"range": [
0,
0,
0
],
"command": {
"type": "edge_lines_visible",
"hidden": false
}
},
{
"cmdId": "[uuid]",
"range": [
0,
0,
0
],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{
"cmdId": "[uuid]",
"range": [
0,
0,
0
],
"command": {
"type": "object_visible",
"object_id": "[uuid]",
"hidden": true
}
},
{
"cmdId": "[uuid]",
"range": [
0,
0,
0
],
"command": {
"type": "object_visible",
"object_id": "[uuid]",
"hidden": true
}
}
]

View File

@ -0,0 +1,6 @@
---
source: kcl-lib/src/simulation_tests.rs
description: Artifact graph flowchart bad_units_in_annotation.kcl
extension: md
snapshot_kind: binary
---

View File

@ -0,0 +1,3 @@
```mermaid
flowchart LR
```

View File

@ -0,0 +1,847 @@
---
source: kcl-lib/src/simulation_tests.rs
description: Result of parsing bad_units_in_annotation.kcl
---
{
"Ok": {
"body": [
{
"declaration": {
"end": 143,
"id": {
"end": 135,
"name": "oxygenRadius",
"start": 123,
"type": "Identifier"
},
"init": {
"end": 143,
"raw": "0.066",
"start": 138,
"type": "Literal",
"type": "Literal",
"value": {
"value": 0.066,
"suffix": "None"
}
},
"start": 123,
"type": "VariableDeclarator"
},
"end": 143,
"kind": "const",
"start": 123,
"type": "VariableDeclaration",
"type": "VariableDeclaration"
},
{
"declaration": {
"end": 206,
"id": {
"end": 198,
"name": "hydrogenRadius",
"start": 184,
"type": "Identifier"
},
"init": {
"end": 206,
"raw": "0.053",
"start": 201,
"type": "Literal",
"type": "Literal",
"value": {
"value": 0.053,
"suffix": "None"
}
},
"start": 184,
"type": "VariableDeclarator"
},
"end": 206,
"kind": "const",
"start": 184,
"type": "VariableDeclaration",
"type": "VariableDeclaration"
},
{
"declaration": {
"end": 278,
"id": {
"end": 270,
"name": "oxygenHydrogenDistance",
"start": 248,
"type": "Identifier"
},
"init": {
"end": 278,
"raw": "0.096",
"start": 273,
"type": "Literal",
"type": "Literal",
"value": {
"value": 0.096,
"suffix": "None"
}
},
"start": 248,
"type": "VariableDeclarator"
},
"end": 278,
"kind": "const",
"start": 248,
"type": "VariableDeclaration",
"type": "VariableDeclaration"
},
{
"declaration": {
"end": 354,
"id": {
"end": 346,
"name": "bondAngle",
"start": 337,
"type": "Identifier"
},
"init": {
"end": 354,
"raw": "104.5",
"start": 349,
"type": "Literal",
"type": "Literal",
"value": {
"value": 104.5,
"suffix": "None"
}
},
"start": 337,
"type": "VariableDeclarator"
},
"end": 354,
"kind": "const",
"start": 337,
"type": "VariableDeclaration",
"type": "VariableDeclaration"
},
{
"declaration": {
"end": 580,
"id": {
"end": 447,
"name": "createAtom",
"start": 437,
"type": "Identifier"
},
"init": {
"body": {
"body": [
{
"argument": {
"body": [
{
"arguments": [
{
"end": 493,
"raw": "'XY'",
"start": 489,
"type": "Literal",
"type": "Literal",
"value": "XY"
}
],
"callee": {
"end": 488,
"name": "startSketchOn",
"start": 475,
"type": "Identifier"
},
"end": 494,
"start": 475,
"type": "CallExpression",
"type": "CallExpression"
},
{
"arguments": [
{
"type": "LabeledArg",
"label": {
"end": 515,
"name": "center",
"start": 509,
"type": "Identifier"
},
"arg": {
"end": 524,
"name": "center",
"start": 518,
"type": "Identifier",
"type": "Identifier"
}
},
{
"type": "LabeledArg",
"label": {
"end": 532,
"name": "radius",
"start": 526,
"type": "Identifier"
},
"arg": {
"end": 541,
"name": "radius",
"start": 535,
"type": "Identifier",
"type": "Identifier"
}
}
],
"callee": {
"end": 508,
"name": "circle",
"start": 502,
"type": "Identifier"
},
"end": 542,
"start": 502,
"type": "CallExpressionKw",
"type": "CallExpressionKw",
"unlabeled": null
},
{
"arguments": [
{
"type": "LabeledArg",
"label": {
"end": 564,
"name": "length",
"start": 558,
"type": "Identifier"
},
"arg": {
"end": 577,
"left": {
"end": 573,
"name": "radius",
"start": 567,
"type": "Identifier",
"type": "Identifier"
},
"operator": "*",
"right": {
"end": 577,
"raw": "2",
"start": 576,
"type": "Literal",
"type": "Literal",
"value": {
"value": 2.0,
"suffix": "None"
}
},
"start": 567,
"type": "BinaryExpression",
"type": "BinaryExpression"
}
}
],
"callee": {
"end": 557,
"name": "extrude",
"start": 550,
"type": "Identifier"
},
"end": 578,
"start": 550,
"type": "CallExpressionKw",
"type": "CallExpressionKw",
"unlabeled": null
}
],
"end": 578,
"start": 475,
"type": "PipeExpression",
"type": "PipeExpression"
},
"end": 578,
"start": 468,
"type": "ReturnStatement",
"type": "ReturnStatement"
}
],
"end": 580,
"start": 464
},
"end": 580,
"params": [
{
"type": "Parameter",
"identifier": {
"end": 454,
"name": "center",
"start": 448,
"type": "Identifier"
}
},
{
"type": "Parameter",
"identifier": {
"end": 462,
"name": "radius",
"start": 456,
"type": "Identifier"
}
}
],
"start": 447,
"type": "FunctionExpression",
"type": "FunctionExpression"
},
"start": 437,
"type": "VariableDeclarator"
},
"end": 580,
"kind": "fn",
"start": 434,
"type": "VariableDeclaration",
"type": "VariableDeclaration"
},
{
"declaration": {
"end": 667,
"id": {
"end": 632,
"name": "oxygenAtom",
"start": 622,
"type": "Identifier"
},
"init": {
"arguments": [
{
"elements": [
{
"end": 648,
"raw": "0",
"start": 647,
"type": "Literal",
"type": "Literal",
"value": {
"value": 0.0,
"suffix": "None"
}
},
{
"end": 651,
"raw": "0",
"start": 650,
"type": "Literal",
"type": "Literal",
"value": {
"value": 0.0,
"suffix": "None"
}
}
],
"end": 652,
"start": 646,
"type": "ArrayExpression",
"type": "ArrayExpression"
},
{
"end": 666,
"name": "oxygenRadius",
"start": 654,
"type": "Identifier",
"type": "Identifier"
}
],
"callee": {
"end": 645,
"name": "createAtom",
"start": 635,
"type": "Identifier"
},
"end": 667,
"start": 635,
"type": "CallExpression",
"type": "CallExpression"
},
"start": 622,
"type": "VariableDeclarator"
},
"end": 667,
"kind": "const",
"start": 622,
"type": "VariableDeclaration",
"type": "VariableDeclaration"
},
{
"declaration": {
"end": 790,
"id": {
"end": 733,
"name": "hydrogenOffsetX",
"start": 718,
"type": "Identifier"
},
"init": {
"end": 790,
"left": {
"end": 758,
"name": "oxygenHydrogenDistance",
"start": 736,
"type": "Identifier",
"type": "Identifier"
},
"operator": "*",
"right": {
"arguments": [
{
"arguments": [
{
"end": 788,
"left": {
"end": 784,
"name": "bondAngle",
"start": 775,
"type": "Identifier",
"type": "Identifier"
},
"operator": "/",
"right": {
"end": 788,
"raw": "2",
"start": 787,
"type": "Literal",
"type": "Literal",
"value": {
"value": 2.0,
"suffix": "None"
}
},
"start": 775,
"type": "BinaryExpression",
"type": "BinaryExpression"
}
],
"callee": {
"end": 774,
"name": "toRadians",
"start": 765,
"type": "Identifier"
},
"end": 789,
"start": 765,
"type": "CallExpression",
"type": "CallExpression"
}
],
"callee": {
"end": 764,
"name": "cos",
"start": 761,
"type": "Identifier"
},
"end": 790,
"start": 761,
"type": "CallExpression",
"type": "CallExpression"
},
"start": 736,
"type": "BinaryExpression",
"type": "BinaryExpression"
},
"start": 718,
"type": "VariableDeclarator"
},
"end": 790,
"kind": "const",
"start": 718,
"type": "VariableDeclaration",
"type": "VariableDeclaration"
},
{
"declaration": {
"end": 863,
"id": {
"end": 806,
"name": "hydrogenOffsetY",
"start": 791,
"type": "Identifier"
},
"init": {
"end": 863,
"left": {
"end": 831,
"name": "oxygenHydrogenDistance",
"start": 809,
"type": "Identifier",
"type": "Identifier"
},
"operator": "*",
"right": {
"arguments": [
{
"arguments": [
{
"end": 861,
"left": {
"end": 857,
"name": "bondAngle",
"start": 848,
"type": "Identifier",
"type": "Identifier"
},
"operator": "/",
"right": {
"end": 861,
"raw": "2",
"start": 860,
"type": "Literal",
"type": "Literal",
"value": {
"value": 2.0,
"suffix": "None"
}
},
"start": 848,
"type": "BinaryExpression",
"type": "BinaryExpression"
}
],
"callee": {
"end": 847,
"name": "toRadians",
"start": 838,
"type": "Identifier"
},
"end": 862,
"start": 838,
"type": "CallExpression",
"type": "CallExpression"
}
],
"callee": {
"end": 837,
"name": "sin",
"start": 834,
"type": "Identifier"
},
"end": 863,
"start": 834,
"type": "CallExpression",
"type": "CallExpression"
},
"start": 809,
"type": "BinaryExpression",
"type": "BinaryExpression"
},
"start": 791,
"type": "VariableDeclarator"
},
"end": 863,
"kind": "const",
"start": 791,
"type": "VariableDeclaration",
"type": "VariableDeclaration"
},
{
"declaration": {
"end": 972,
"id": {
"end": 907,
"name": "hydrogenAtom1",
"start": 894,
"type": "Identifier"
},
"init": {
"arguments": [
{
"elements": [
{
"end": 937,
"name": "hydrogenOffsetX",
"start": 922,
"type": "Identifier",
"type": "Identifier"
},
{
"end": 954,
"name": "hydrogenOffsetY",
"start": 939,
"type": "Identifier",
"type": "Identifier"
}
],
"end": 955,
"start": 921,
"type": "ArrayExpression",
"type": "ArrayExpression"
},
{
"end": 971,
"name": "hydrogenRadius",
"start": 957,
"type": "Identifier",
"type": "Identifier"
}
],
"callee": {
"end": 920,
"name": "createAtom",
"start": 910,
"type": "Identifier"
},
"end": 972,
"start": 910,
"type": "CallExpression",
"type": "CallExpression"
},
"start": 894,
"type": "VariableDeclarator"
},
"end": 972,
"kind": "const",
"start": 894,
"type": "VariableDeclaration",
"type": "VariableDeclaration"
},
{
"declaration": {
"end": 1052,
"id": {
"end": 986,
"name": "hydrogenAtom2",
"start": 973,
"type": "Identifier"
},
"init": {
"arguments": [
{
"elements": [
{
"argument": {
"end": 1017,
"name": "hydrogenOffsetX",
"start": 1002,
"type": "Identifier",
"type": "Identifier"
},
"end": 1017,
"operator": "-",
"start": 1001,
"type": "UnaryExpression",
"type": "UnaryExpression"
},
{
"end": 1034,
"name": "hydrogenOffsetY",
"start": 1019,
"type": "Identifier",
"type": "Identifier"
}
],
"end": 1035,
"start": 1000,
"type": "ArrayExpression",
"type": "ArrayExpression"
},
{
"end": 1051,
"name": "hydrogenRadius",
"start": 1037,
"type": "Identifier",
"type": "Identifier"
}
],
"callee": {
"end": 999,
"name": "createAtom",
"start": 989,
"type": "Identifier"
},
"end": 1052,
"start": 989,
"type": "CallExpression",
"type": "CallExpression"
},
"start": 973,
"type": "VariableDeclarator"
},
"end": 1052,
"kind": "const",
"start": 973,
"type": "VariableDeclaration",
"type": "VariableDeclaration"
}
],
"end": 1053,
"innerAttrs": [
{
"end": 33,
"name": {
"end": 9,
"name": "settings",
"start": 1,
"type": "Identifier"
},
"properties": [
{
"end": 32,
"key": {
"end": 27,
"name": "defaultLengthUnit",
"start": 10,
"type": "Identifier"
},
"start": 10,
"type": "ObjectProperty",
"value": {
"end": 32,
"name": "nm",
"start": 30,
"type": "Identifier",
"type": "Identifier"
}
}
],
"start": 0,
"type": "Annotation"
}
],
"nonCodeMeta": {
"nonCodeNodes": {
"0": [
{
"end": 183,
"start": 143,
"type": "NonCodeNode",
"value": {
"type": "inlineComment",
"value": "Approximate radius of an oxygen atom",
"style": "line"
}
}
],
"1": [
{
"end": 247,
"start": 206,
"type": "NonCodeNode",
"value": {
"type": "inlineComment",
"value": "Approximate radius of a hydrogen atom",
"style": "line"
}
}
],
"2": [
{
"end": 336,
"start": 278,
"type": "NonCodeNode",
"value": {
"type": "inlineComment",
"value": "Approximate distance between oxygen and hydrogen atoms",
"style": "line"
}
}
],
"3": [
{
"end": 379,
"start": 354,
"type": "NonCodeNode",
"value": {
"type": "inlineComment",
"value": "Bond angle in degrees",
"style": "line"
}
},
{
"end": 382,
"start": 379,
"type": "NonCodeNode",
"value": {
"type": "newLine"
}
},
{
"end": 433,
"start": 382,
"type": "NonCodeNode",
"value": {
"type": "blockComment",
"value": "Function to create a sphere representing an atom",
"style": "line"
}
}
],
"4": [
{
"end": 621,
"start": 580,
"type": "NonCodeNode",
"value": {
"type": "newLineBlockComment",
"value": "Create the oxygen atom at the origin",
"style": "line"
}
}
],
"5": [
{
"end": 717,
"start": 667,
"type": "NonCodeNode",
"value": {
"type": "newLineBlockComment",
"value": "Calculate the positions of the hydrogen atoms",
"style": "line"
}
}
],
"7": [
{
"end": 893,
"start": 863,
"type": "NonCodeNode",
"value": {
"type": "newLineBlockComment",
"value": "Create the hydrogen atoms",
"style": "line"
}
}
]
},
"startNodes": [
{
"end": 84,
"start": 34,
"type": "NonCodeNode",
"value": {
"type": "blockComment",
"value": "Generated by Text-to-CAD: draw a water molecule",
"style": "line"
}
},
{
"end": 87,
"start": 84,
"type": "NonCodeNode",
"value": {
"type": "newLine"
}
},
{
"end": 122,
"start": 87,
"type": "NonCodeNode",
"value": {
"type": "blockComment",
"value": "Constants for the water molecule",
"style": "line"
}
}
]
},
"start": 0
}
}

View File

@ -0,0 +1,14 @@
---
source: kcl-lib/src/simulation_tests.rs
description: Error from executing bad_units_in_annotation.kcl
---
KCL Semantic error
× semantic: Unexpected value for length units: `nm`; expected one of `mm`,
│ `cm`, `m`, `in`, `ft`, `yd`
╭─[1:1]
1 │ @settings(defaultLengthUnit = nm)
· ────────────────┬────────────────
· ╰── tests/bad_units_in_annotation/input.kcl
2 │ // Generated by Text-to-CAD: draw a water molecule
╰────

View File

@ -0,0 +1,28 @@
@settings(defaultLengthUnit = nm)
// Generated by Text-to-CAD: draw a water molecule
// Constants for the water molecule
oxygenRadius = 0.066 // Approximate radius of an oxygen atom
hydrogenRadius = 0.053 // Approximate radius of a hydrogen atom
oxygenHydrogenDistance = 0.096 // Approximate distance between oxygen and hydrogen atoms
bondAngle = 104.5 // Bond angle in degrees
// Function to create a sphere representing an atom
fn createAtom(center, radius) {
return startSketchOn('XY')
|> circle(center = center, radius = radius)
|> extrude(length = radius * 2)
}
// Create the oxygen atom at the origin
oxygenAtom = createAtom([0, 0], oxygenRadius)
// Calculate the positions of the hydrogen atoms
hydrogenOffsetX = oxygenHydrogenDistance * cos(toRadians(bondAngle / 2))
hydrogenOffsetY = oxygenHydrogenDistance * sin(toRadians(bondAngle / 2))
// Create the hydrogen atoms
hydrogenAtom1 = createAtom([hydrogenOffsetX, hydrogenOffsetY], hydrogenRadius)
hydrogenAtom2 = createAtom([-hydrogenOffsetX, hydrogenOffsetY], hydrogenRadius)

View File

@ -0,0 +1,5 @@
---
source: kcl-lib/src/simulation_tests.rs
description: Operations executed bad_units_in_annotation.kcl
---
[]

View File

@ -401,10 +401,8 @@ async fn execute_and_export(path: String, export_format: FileExportFormat) -> Py
.map_err(|err| pyo3::exceptions::PyException::new_err(err.to_string()))?;
let program = kcl_lib::Program::parse_no_errs(&code)
.map_err(|err| into_miette_for_parse(&path.display().to_string(), &code, err))?;
let settings = program.meta_settings()?.unwrap_or_default();
let units: UnitLength = settings.default_length_units.into();
let (ctx, mut state) = new_context_state(Some(path))
let (ctx, mut state) = new_context_state(Some(path.clone()))
.await
.map_err(|err| pyo3::exceptions::PyException::new_err(err.to_string()))?;
// Execute the program.
@ -412,6 +410,12 @@ async fn execute_and_export(path: String, export_format: FileExportFormat) -> Py
.await
.map_err(|err| into_miette(err, &code))?;
let settings = program
.meta_settings()
.map_err(|err| into_miette_for_parse(&path.display().to_string(), &code, err))?
.unwrap_or_default();
let units: UnitLength = settings.default_length_units.into();
// This will not return until there are files.
let resp = ctx
.engine
@ -445,8 +449,6 @@ async fn execute_code_and_export(code: String, export_format: FileExportFormat)
.spawn(async move {
let program =
kcl_lib::Program::parse_no_errs(&code).map_err(|err| into_miette_for_parse("", &code, err))?;
let settings = program.meta_settings()?.unwrap_or_default();
let units: UnitLength = settings.default_length_units.into();
let (ctx, mut state) = new_context_state(None)
.await
@ -456,6 +458,12 @@ async fn execute_code_and_export(code: String, export_format: FileExportFormat)
.await
.map_err(|err| into_miette(err, &code))?;
let settings = program
.meta_settings()
.map_err(|err| into_miette_for_parse("", &code, err))?
.unwrap_or_default();
let units: UnitLength = settings.default_length_units.into();
// This will not return until there are files.
let resp = ctx
.engine

View File

@ -9,6 +9,7 @@ files_dir = os.path.join(os.path.dirname(os.path.realpath(__file__)), "..", "fil
kcl_dir = os.path.join(
os.path.dirname(os.path.realpath(__file__)), "..", "..", "kcl-lib"
)
tests_dir = os.path.join(kcl_dir, "tests")
lego_file = os.path.join(kcl_dir, "e2e", "executor", "inputs", "lego.kcl")
walkie_talkie_dir = os.path.join(
os.path.dirname(os.path.realpath(__file__)),
@ -146,3 +147,20 @@ def test_kcl_lint():
finding_title = finding.title
assert finding_title is not None
assert len(finding_title) > 0
@pytest.mark.asyncio
async def test_kcl_execute_code_and_export_with_bad_units():
bad_units_file = os.path.join(tests_dir, "bad_units_in_annotation", "input.kcl")
# Read from a file.
with open(bad_units_file, "r") as f:
code = str(f.read())
assert code is not None
assert len(code) > 0
try:
await kcl.execute_code_and_export(code, kcl.FileExportFormat.Step)
except Exception as e:
assert e is not None
assert len(str(e)) > 0
print(e)
assert "[1:1]" in str(e)

View File

@ -34,6 +34,7 @@ import { settingsActor, useSettings } from 'machines/appMachine'
import { createRouteCommands } from 'lib/commandBarConfigs/routeCommandConfig'
import { useToken } from 'machines/appMachine'
import { createNamedViewsCommand } from 'lib/commandBarConfigs/namedViewsConfig'
import { reportRejection } from 'lib/trap'
type MachineContext<T extends AnyStateMachine> = {
state: StateFrom<T>
@ -60,6 +61,20 @@ export const FileMachineProvider = ({
[]
)
// Write code mirror content to disk when the page is trying to reroute
// Our logic for codeManager.writeToFile has an artificial 1000ms timeout which
// won't run quickly enough so users can make an edit, exit the page and lose their
// progress within that 1000ms window.
useEffect(() => {
const preventUnload = (event: BeforeUnloadEvent) => {
codeManager.writeToFileNoTimeout().catch(reportRejection)
}
window.addEventListener('beforeunload', preventUnload)
return () => {
window.removeEventListener('beforeunload', preventUnload)
}
}, [])
useEffect(() => {
// TODO: Engine feature is not deployed
if (DEV) {

View File

@ -164,6 +164,32 @@ export default class CodeManager {
}
}
// When we unload the page via changing routes we want to instantly write to disk to save their progress
// There is a race condition in the system. writeToFile takes 1000ms to run, if they make an edit and leave within the 1000ms
// window they won't get their content saved. Use this to always save their file before rerouting
async writeToFileNoTimeout() {
if (isDesktop()) {
return new Promise((resolve, reject) => {
if (!this._currentFilePath)
return reject(new Error('currentFilePath not set'))
// Wait one event loop to give a chance for params to be set
// Save the file to disk
window.electron
.writeFile(this._currentFilePath, this.code ?? '')
.then(resolve)
.catch((err: Error) => {
// TODO: add tracing per GH issue #254 (https://github.com/KittyCAD/modeling-app/issues/254)
console.error('error saving file', err)
toast.error('Error saving file, please check file permissions')
reject(err)
})
})
} else {
safeLSSetItem(PERSIST_CODE_KEY, this.code)
}
}
async updateEditorWithAstAndWriteToFile(ast: Program) {
// We clear the AST when there it cannot be parsed, so if we are trying to write an empty AST, its
// probably because of an earlier error. That's a bad state to be in and it's not going to be

View File

@ -862,6 +862,8 @@ export const modelingMachine = setup({
}
sceneInfra.setCallbacks({
onClick: (args) => {
if (!args) return
if (args.mouseEvent.which !== 1) return
const twoD = args.intersectionPoint?.twoD
if (twoD) {
sceneInfra.modelingSend({
@ -893,6 +895,8 @@ export const modelingMachine = setup({
}
sceneInfra.setCallbacks({
onClick: (args) => {
if (!args) return
if (args.mouseEvent.which !== 1) return
const twoD = args.intersectionPoint?.twoD
if (twoD) {
sceneInfra.modelingSend({

1969
yarn.lock

File diff suppressed because it is too large Load Diff