Compare commits

...

92 Commits

Author SHA1 Message Date
2204575466 Fix to not blow away files with comments 2025-03-21 16:54:19 -04:00
65f9bcc4ea Fix so that only comments doesn't format to empty 2025-03-21 16:54:19 -04:00
ced2072768 A snapshot a day keeps the bugs away! 📷🐛 2025-03-21 20:40:04 +00:00
5e1fbccaec A snapshot a day keeps the bugs away! 📷🐛 2025-03-21 20:25:24 +00:00
658700b533 A snapshot a day keeps the bugs away! 📷🐛 2025-03-21 20:01:12 +00:00
670d95e692 Merge branch 'main' into jtran/units-indicator 2025-03-21 15:46:42 -04:00
5654e9daaa Add more tests for sweep sectional (#5930)
* Add more tests for sweep sectional

* A snapshot a day keeps the bugs away! 📷🐛

* Add rust doc test for sectional

* A snapshot a day keeps the bugs away! 📷🐛

* Ran redo-kcl-stdlib-docs

* A snapshot a day keeps the bugs away! 📷🐛

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-03-21 14:52:04 -04:00
d443576c7c Strip ANSI control sequences to clean up Axiom dashboard (#5934) 2025-03-21 17:54:56 +00:00
e00317f316 Sync the all-e2e branch with main (#5927) 2025-03-21 17:43:23 +00:00
744bb254e9 Fix yarn lint 2025-03-21 12:59:13 -04:00
b9a61c83d6 Possibly the last test that needs updated with an inline unit annotation 2025-03-21 12:41:11 -04:00
b5c25fe9e7 More test updates to use inline in setting 2025-03-21 12:32:45 -04:00
a3b6da03d3 Undo kclSamplesInputPath approach.
Instead, just add a second reliable executor input file to use.
2025-03-21 12:13:19 -04:00
e6c060c410 A snapshot a day keeps the bugs away! 📷🐛 2025-03-21 16:00:35 +00:00
09dabd8fc2 I'm pretty sure our lighting is very affected by scale 2025-03-21 11:46:26 -04:00
dfac82d2aa Merge branch 'main' into jtran/units-indicator 2025-03-21 11:42:58 -04:00
cb32881cf2 Fix up more tests with setting annotations 2025-03-21 11:42:42 -04:00
a01498bf33 A snapshot a day keeps the bugs away! 📷🐛 2025-03-21 15:15:40 +00:00
c2f1ff67f2 Make ML branding more inline & more prominent (#5815)
* Make changes to ML button

* A snapshot a day keeps the bugs away! 📷🐛

* A snapshot a day keeps the bugs away! 📷🐛

* A snapshot a day keeps the bugs away! 📷🐛

---------

Co-authored-by: Zookeeper Lee <lee@zoo.dev>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Pierre Jacquier <pierre@zoo.dev>
2025-03-21 15:07:23 +00:00
d1d3caad5c A snapshot a day keeps the bugs away! 📷🐛 2025-03-21 15:02:02 +00:00
c62e0bfd64 Fix up point-and-click tests with unit setting lines 2025-03-21 10:48:01 -04:00
256b6b33f3 A snapshot a day keeps the bugs away! 📷🐛 2025-03-21 14:37:22 +00:00
35c80a78bb Merge branch 'main' into jtran/units-indicator 2025-03-21 10:23:42 -04:00
869126e436 #5783 Only show axis planes when there are no errors (#5799)
* Only show axis planes when there are no errors

* run prettier

* A snapshot a day keeps the bugs away! 📷🐛

* KclSingleton hasErrors refactor

* A snapshot a day keeps the bugs away! 📷🐛

* A snapshot a day keeps the bugs away! 📷🐛

* A snapshot a day keeps the bugs away! 📷🐛

* A snapshot a day keeps the bugs away! 📷🐛

* A snapshot a day keeps the bugs away! 📷🐛

* A snapshot a day keeps the bugs away! 📷🐛

* A snapshot a day keeps the bugs away! 📷🐛

* A snapshot a day keeps the bugs away! 📷🐛

* A snapshot a day keeps the bugs away! 📷🐛

* A snapshot a day keeps the bugs away! 📷🐛

* A snapshot a day keeps the bugs away! 📷🐛

* A snapshot a day keeps the bugs away! 📷🐛

* A snapshot a day keeps the bugs away! 📷🐛

* A snapshot a day keeps the bugs away! 📷🐛

* A snapshot a day keeps the bugs away! 📷🐛

* A snapshot a day keeps the bugs away! 📷🐛

* A snapshot a day keeps the bugs away! 📷🐛

* A snapshot a day keeps the bugs away! 📷🐛

* A snapshot a day keeps the bugs away! 📷🐛

* A snapshot a day keeps the bugs away! 📷🐛

* A snapshot a day keeps the bugs away! 📷🐛

* A snapshot a day keeps the bugs away! 📷🐛

* A snapshot a day keeps the bugs away! 📷🐛

* A snapshot a day keeps the bugs away! 📷🐛

* A snapshot a day keeps the bugs away! 📷🐛

* A snapshot a day keeps the bugs away! 📷🐛

* A snapshot a day keeps the bugs away! 📷🐛

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-03-21 06:44:44 -04:00
e8feb0309b Automatic fixing of deprecations and use non-quoted default planes by default (#5902)
* Automatic fixing of deprecations and use non-quoted default planes by default

Signed-off-by: Nick Cameron <nrc@ncameron.org>

* A snapshot a day keeps the bugs away! 📷🐛

* A snapshot a day keeps the bugs away! 📷🐛

* A snapshot a day keeps the bugs away! 📷🐛

* A snapshot a day keeps the bugs away! 📷🐛

* A snapshot a day keeps the bugs away! 📷🐛

---------

Signed-off-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-03-21 09:39:12 +00:00
06b35b76ff Refactor logic to skip unreliable tests (#5919) 2025-03-21 03:52:30 +00:00
89d1f7f3d3 fix resize (#5921)
* fix resize

* assert stream dimensions
2025-03-21 02:13:26 +00:00
66b9b501ac test: Fix snapshot test to use mask (#5914)
* Fix snapshot test to use mask

* A snapshot a day keeps the bugs away! 📷🐛

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-03-21 01:20:47 +00:00
9248b2e42d #5905 Cleanup console warnings (#5908)
* Fix ToolBar WebkitAppRegion warning

* make intersectionPlane non-nullable, avoid trying to create it multiple times to get rid of warning

* remove derived scene from sceneEntities

* intersectionPlane is now always non-null, make it readonly too

* sceneInfra small cleanups

* A snapshot a day keeps the bugs away! 📷🐛

* A snapshot a day keeps the bugs away! 📷🐛

* Clean up snapshots

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Pierre Jacquier <pierre@zoo.dev>
2025-03-21 00:55:20 +00:00
054bb5b500 Add sectional argument and edit flow for point-and-click Sweep (#5480)
* WIP: Expose the sectional argument in the Sweep command flow
Fixes #5301

* A snapshot a day keeps the bugs away! 📷🐛 (OS: namespace-profile-ubuntu-8-cores)

* A snapshot a day keeps the bugs away! 📷🐛 (OS: namespace-profile-ubuntu-8-cores)

* A snapshot a day keeps the bugs away! 📷🐛 (OS: namespace-profile-ubuntu-8-cores)

* Working edit flow

* Lint

* Allow in place editing, more consistent code

* A snapshot a day keeps the bugs away! 📷🐛 (OS: namespace-profile-ubuntu-8-cores)

* A snapshot a day keeps the bugs away! 📷🐛 (OS: namespace-profile-ubuntu-8-cores)

* Remove validation on non-selection arg

* A snapshot a day keeps the bugs away! 📷🐛 (OS: namespace-profile-ubuntu-8-cores)

* Comment out bad test

* Clean up for review

* Hack sectional

* Made selection args hidden

* Fix edit issue in e2e

* Clean up

* Add face filtering filter for opposite and next adjacent faces

* Lint

* Fixme back

* A snapshot a day keeps the bugs away! 📷🐛

* A snapshot a day keeps the bugs away! 📷🐛

* A snapshot a day keeps the bugs away! 📷🐛

* Use updateModelingState in codemod

* A snapshot a day keeps the bugs away! 📷🐛

* A snapshot a day keeps the bugs away! 📷🐛

* A snapshot a day keeps the bugs away! 📷🐛

* A snapshot a day keeps the bugs away! 📷🐛

* A snapshot a day keeps the bugs away! 📷🐛

* A snapshot a day keeps the bugs away! 📷🐛

* A snapshot a day keeps the bugs away! 📷🐛

* A snapshot a day keeps the bugs away! 📷🐛

* A snapshot a day keeps the bugs away! 📷🐛

* A snapshot a day keeps the bugs away! 📷🐛

* A snapshot a day keeps the bugs away! 📷🐛

* A snapshot a day keeps the bugs away! 📷🐛

* A snapshot a day keeps the bugs away! 📷🐛

* A snapshot a day keeps the bugs away! 📷🐛

* A snapshot a day keeps the bugs away! 📷🐛

* Improve filtering readibility

* Fix base test

* I liked return but clippy didn't

* Working tests, isolating the change to sectional sweep, don't like the api change

* A snapshot a day keeps the bugs away! 📷🐛

* A snapshot a day keeps the bugs away! 📷🐛

* A snapshot a day keeps the bugs away! 📷🐛

* A snapshot a day keeps the bugs away! 📷🐛

* Clean up snapshots

* A snapshot a day keeps the bugs away! 📷🐛

* A snapshot a day keeps the bugs away! 📷🐛

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-03-20 20:42:41 -04:00
a5e682f9b0 Fix to reset to the default units when clearing the scene 2025-03-20 19:16:15 -04:00
c1319ca980 Add cache test 2025-03-20 19:16:15 -04:00
6e8fcdc088 A snapshot a day keeps the bugs away! 📷🐛 2025-03-20 22:52:01 +00:00
12b546ea24 Bump the patch group across 1 directory with 7 updates (#5888)
* Bump the patch group across 1 directory with 7 updates

Bumps the patch group with 6 updates in the /rust directory:

| Package | From | To |
| --- | --- | --- |
| [async-trait](https://github.com/dtolnay/async-trait) | `0.1.87` | `0.1.88` |
| [kittycad-modeling-cmds](https://github.com/KittyCAD/modeling-api) | `0.2.105` | `0.2.107` |
| [zip](https://github.com/zip-rs/zip2) | `2.4.1` | `2.4.2` |
| [time](https://github.com/time-rs/time) | `0.3.39` | `0.3.40` |
| [reqwest](https://github.com/seanmonstar/reqwest) | `0.12.14` | `0.12.15` |
| [handlebars](https://github.com/sunng87/handlebars-rust) | `6.3.1` | `6.3.2` |



Updates `async-trait` from 0.1.87 to 0.1.88
- [Release notes](https://github.com/dtolnay/async-trait/releases)
- [Commits](https://github.com/dtolnay/async-trait/compare/0.1.87...0.1.88)

Updates `kittycad-modeling-cmds` from 0.2.105 to 0.2.107
- [Commits](https://github.com/KittyCAD/modeling-api/compare/kittycad-modeling-cmds-0.2.105...kittycad-modeling-cmds-0.2.107)

Updates `uuid` from 1.15.1 to 1.16.0
- [Release notes](https://github.com/uuid-rs/uuid/releases)
- [Commits](https://github.com/uuid-rs/uuid/compare/v1.15.1...v1.16.0)

Updates `zip` from 2.4.1 to 2.4.2
- [Release notes](https://github.com/zip-rs/zip2/releases)
- [Changelog](https://github.com/zip-rs/zip2/blob/master/CHANGELOG.md)
- [Commits](https://github.com/zip-rs/zip2/compare/v2.4.1...v2.4.2)

Updates `time` from 0.3.39 to 0.3.40
- [Release notes](https://github.com/time-rs/time/releases)
- [Changelog](https://github.com/time-rs/time/blob/main/CHANGELOG.md)
- [Commits](https://github.com/time-rs/time/compare/v0.3.39...v0.3.40)

Updates `reqwest` from 0.12.14 to 0.12.15
- [Release notes](https://github.com/seanmonstar/reqwest/releases)
- [Changelog](https://github.com/seanmonstar/reqwest/blob/master/CHANGELOG.md)
- [Commits](https://github.com/seanmonstar/reqwest/compare/v0.12.14...v0.12.15)

Updates `handlebars` from 6.3.1 to 6.3.2
- [Release notes](https://github.com/sunng87/handlebars-rust/releases)
- [Changelog](https://github.com/sunng87/handlebars-rust/blob/master/CHANGELOG.md)
- [Commits](https://github.com/sunng87/handlebars-rust/compare/v6.3.1...v6.3.2)

---
updated-dependencies:
- dependency-name: async-trait
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: patch
- dependency-name: kittycad-modeling-cmds
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: patch
- dependency-name: uuid
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: patch
- dependency-name: zip
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: patch
- dependency-name: time
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: patch
- dependency-name: reqwest
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: patch
- dependency-name: handlebars
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: patch
...

Signed-off-by: dependabot[bot] <support@github.com>

* A snapshot a day keeps the bugs away! 📷🐛

* A snapshot a day keeps the bugs away! 📷🐛

* A snapshot a day keeps the bugs away! 📷🐛

* A snapshot a day keeps the bugs away! 📷🐛

* A snapshot a day keeps the bugs away! 📷🐛

* A snapshot a day keeps the bugs away! 📷🐛

* A snapshot a day keeps the bugs away! 📷🐛

* A snapshot a day keeps the bugs away! 📷🐛

* A snapshot a day keeps the bugs away! 📷🐛

* A snapshot a day keeps the bugs away! 📷🐛

* A snapshot a day keeps the bugs away! 📷🐛

* A snapshot a day keeps the bugs away! 📷🐛

* A snapshot a day keeps the bugs away! 📷🐛

* A snapshot a day keeps the bugs away! 📷🐛

* A snapshot a day keeps the bugs away! 📷🐛

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-03-20 22:50:43 +00:00
273b3b59e2 Merge branch 'main' into jtran/units-indicator 2025-03-20 18:38:37 -04:00
bc6c40c1e8 Remove unused xstate typegen (#5917) 2025-03-20 22:14:39 +00:00
bac7ae4ff1 A snapshot a day keeps the bugs away! 📷🐛 2025-03-20 22:03:24 +00:00
1d550da40b More types stuff (#5901)
* parse union and fancy array types

Signed-off-by: Nick Cameron <nrc@ncameron.org>

* type aliases

Signed-off-by: Nick Cameron <nrc@ncameron.org>

* Treat Helix and Face as primitive types

Signed-off-by: Nick Cameron <nrc@ncameron.org>

* code motion: factor our execution::types module

Signed-off-by: Nick Cameron <nrc@ncameron.org>

* Tests for type coercion and subtyping

Signed-off-by: Nick Cameron <nrc@ncameron.org>

* Add Point2D/3D to std

Signed-off-by: Nick Cameron <nrc@ncameron.org>

* Rebasing and fixes

Signed-off-by: Nick Cameron <nrc@ncameron.org>

---------

Signed-off-by: Nick Cameron <nrc@ncameron.org>
2025-03-21 10:56:55 +13:00
9f5c2512a7 A snapshot a day keeps the bugs away! 📷🐛 2025-03-20 21:48:58 +00:00
485c5ab455 Fix chamfer e2e tests 2025-03-20 17:34:30 -04:00
d0cba2f080 Update output after new keyboard sample 2025-03-20 17:34:30 -04:00
7f1ed3b7cc A snapshot a day keeps the bugs away! 📷🐛 2025-03-20 17:34:30 -04:00
9e73987796 A snapshot a day keeps the bugs away! 📷🐛 2025-03-20 17:34:30 -04:00
01e1589cd6 A snapshot a day keeps the bugs away! 📷🐛 2025-03-20 17:34:30 -04:00
4b1901db7e A snapshot a day keeps the bugs away! 📷🐛 2025-03-20 17:34:30 -04:00
a892699b65 A snapshot a day keeps the bugs away! 📷🐛 2025-03-20 17:34:30 -04:00
76dbb4a5d3 A snapshot a day keeps the bugs away! 📷🐛 2025-03-20 17:34:30 -04:00
d6cb471791 A snapshot a day keeps the bugs away! 📷🐛 2025-03-20 17:34:29 -04:00
ac4d68a812 Fix snapshot test to use mask 2025-03-20 17:34:12 -04:00
423ab5169f Add new assertion when creating project 2025-03-20 17:34:12 -04:00
6f013ec5fe Revert "Add arrow down to try to fix tests"
This reverts commit cde90b0e058e9fd4d4b68087c971195d3843d104.
2025-03-20 17:34:12 -04:00
8c3fc51d28 Change signature to reduce wasm round-trips 2025-03-20 17:34:12 -04:00
cffb777a7b Fix lint 2025-03-20 17:34:12 -04:00
0409b3159c Fix to consider only @settings to not be worth preserving 2025-03-20 17:34:12 -04:00
27c2c50508 Fix more tests 2025-03-20 17:34:12 -04:00
8f5eb9266b Fix formatting 2025-03-20 17:34:12 -04:00
041000fbb6 Trying to fix test assertions 2025-03-20 17:34:12 -04:00
15c3f21acc Add arrow down to try to fix tests 2025-03-20 17:34:12 -04:00
626dbf46f8 Fix tests 2025-03-20 17:34:12 -04:00
dc3a17149d Regenerate derive-docs 2025-03-20 17:34:11 -04:00
98238d040b Update output after setting units differently 2025-03-20 17:34:11 -04:00
3dff5b1c30 Remove units from settings struct 2025-03-20 17:34:11 -04:00
2f362e1774 Change tolerance to use the module units 2025-03-20 17:34:11 -04:00
fd45574652 Fix loading samples 2025-03-20 17:34:11 -04:00
1e23f37287 Change so that the new file in new projects get the units 2025-03-20 17:34:11 -04:00
8936a885c3 Move definition so that all units stuff is together and no cyclic imports 2025-03-20 17:34:09 -04:00
e94bdeb2ce Change so that new KCL files respect the length unit setting 2025-03-20 17:33:37 -04:00
494d8bdf4c Change lower-right controls units menu to be tied to only the per-file units 2025-03-20 17:33:36 -04:00
9da8574103 Add edit flow for named constants / parameters (#5911)
* Add support for forcing kcl input create variable

* Command palette padding tweak

* Make traverse function work for ExpressionStatements

* Add utilities for getting earliest safe index in AST

* Fix the insertIndex logic to not be based on the selection anymore

* Add workflow to create a named constant

* Fix bug with nameEndInDigits matcher

* Tweak command config

* Add a three-dot menu to feature tree pane to create parameters

* Add E2E test for create parameter flow

* Remove edit flow oops

* Fix tsc error

* Fix E2E test

* Update named constant position in edit flow test

* Add tags into consideration for safe insert index

Per @Irev-dev's helpful feedback, with unit tests!

* Fix tsc by removing a generic type

* Remove unused imports

* Fix lints

* A snapshot a day keeps the bugs away! 📷🐛

* Add utilities for working with variable declarations

* Add "edit parameter" user flow

* Add edit flow config

* WIP working on de-bloating useCalculateKclExpreesion

* Add the ability to specify a `displayName` for an arg

* Add utility to type check on SourceRanges

* Review step design tweak fixes

* Refactor useCalculateKclExpression to take a sourceRange

* Make option arg validation work for objects and arrays

Using an admittedly dumb stringification approach

* Make edit flow never move the constant to be edited

* Add E2E test section

* Fix lints

* Remove lying comment, tiny CSS tweak

* A snapshot a day keeps the bugs away! 📷🐛

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-03-20 16:41:09 -04:00
2c6404f671 Continue running broken tests for Axiom metrics (#5883)
* Install Vector on Ubuntu to log failed test to Axiom

* Allow flaky tests to run on main for Axiom metrics

* Enable problematic tests on a dedicated branch
2025-03-20 16:28:08 -04:00
09c6f51141 Bump the patch group in /packages/codemirror-lsp-client with 2 updates (#5825) 2025-03-20 20:10:15 +00:00
755c7df59c Expand Makefile to run web and desktop apps (#5916) 2025-03-20 16:08:35 -04:00
73b38cd9e2 Bump the patch group with 2 updates (#5826)
Bumps the patch group with 2 updates: [taiki-e/install-action](https://github.com/taiki-e/install-action) and [google-github-actions/setup-gcloud](https://github.com/google-github-actions/setup-gcloud).


Updates `taiki-e/install-action` from 2.49.15 to 2.49.27
- [Release notes](https://github.com/taiki-e/install-action/releases)
- [Commits](https://github.com/taiki-e/install-action/compare/v2.49.15...v2.49.27)

Updates `google-github-actions/setup-gcloud` from 2.1.2 to 2.1.4
- [Release notes](https://github.com/google-github-actions/setup-gcloud/releases)
- [Changelog](https://github.com/google-github-actions/setup-gcloud/blob/main/CHANGELOG.md)
- [Commits](https://github.com/google-github-actions/setup-gcloud/compare/v2.1.2...v2.1.4)

---
updated-dependencies:
- dependency-name: taiki-e/install-action
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: patch
- dependency-name: google-github-actions/setup-gcloud
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-03-20 13:02:39 -07:00
227cb70d72 Bump the patch group in /rust/kcl-language-server with 2 updates (#5834)
* Bump the patch group in /rust/kcl-language-server with 2 updates

Bumps the patch group in /rust/kcl-language-server with 2 updates: [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) and [esbuild](https://github.com/evanw/esbuild).


Updates `@types/node` from 22.13.9 to 22.13.10
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

Updates `esbuild` from 0.25.0 to 0.25.1
- [Release notes](https://github.com/evanw/esbuild/releases)
- [Changelog](https://github.com/evanw/esbuild/blob/main/CHANGELOG.md)
- [Commits](https://github.com/evanw/esbuild/compare/v0.25.0...v0.25.1)

---
updated-dependencies:
- dependency-name: "@types/node"
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: patch
- dependency-name: esbuild
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: patch
...

Signed-off-by: dependabot[bot] <support@github.com>

* A snapshot a day keeps the bugs away! 📷🐛

* A snapshot a day keeps the bugs away! 📷🐛

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-03-20 12:12:59 -07:00
b36e416ab2 Only show "Edit sketch" button when code pane is focused with sketch selected (#5691)
* Only show "Edit sketch" button when code pane is focused with sketch selected

Closes #4273. WIP until tests are updated, since this will impact many
that look for the "Edit sketch" button.

* Start removing "edit sketch" point-and-click from E2E

* Update more E2E tests

* Update more tests that assumed Edit Sketch button

* A snapshot a day keeps the bugs away! 📷🐛

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-03-20 17:10:28 +00:00
612d03bf73 Bump the major group in /.github/actions/github-release with 2 updates (#5829)
Bumps the major group in /.github/actions/github-release with 2 updates: [@actions/github](https://github.com/actions/toolkit/tree/HEAD/packages/github) and [glob](https://github.com/isaacs/node-glob).


Updates `@actions/github` from 5.1.1 to 6.0.0
- [Changelog](https://github.com/actions/toolkit/blob/main/packages/github/RELEASES.md)
- [Commits](https://github.com/actions/toolkit/commits/HEAD/packages/github)

Updates `glob` from 7.2.3 to 11.0.1
- [Changelog](https://github.com/isaacs/node-glob/blob/main/changelog.md)
- [Commits](https://github.com/isaacs/node-glob/compare/v7.2.3...v11.0.1)

---
updated-dependencies:
- dependency-name: "@actions/github"
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: major
- dependency-name: glob
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-03-20 09:27:44 -07:00
c8ec35cd4a Clean KCL Samples and Update Walkie Talkie (#5904)
* Clean KCL Samples and Update Walkie Talkie

* revolve keyword args

* Update kcl-samples simulation test output

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-03-20 09:22:17 -07:00
83ca08b26c Update dependabot config (#5907) 2025-03-20 09:10:50 -04:00
ce98218bf0 Create main.kcl (#5898)
* Create main.kcl

* Update kcl-samples simulation test output

* Update kcl-samples simulation test output

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Josh Gomez <114548659+jgomez720@users.noreply.github.com>
2025-03-19 23:28:07 -07:00
2d43399703 Update pipe flange assembly (#5893)
* update pipe flange assy and small change to walkie talkie

* update header in globals.kcl

* Update kcl-samples simulation test output

* Update kcl-samples simulation test output

* Update output after merge

---------

Co-authored-by: jgomez720 <114548659+jgomez720@users.noreply.github.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-03-20 03:49:06 +00:00
461a2c3ab2 Support comments on attributes (#5850)
Signed-off-by: Nick Cameron <nrc@ncameron.org>
2025-03-20 16:23:20 +13:00
79be72c5f0 Fix a couple of panics (#5900)
* Ensure batches in the engine are cleared between scenes

Signed-off-by: Nick Cameron <nrc@ncameron.org>

* Avoid panicking reading arguments out of bounds

Signed-off-by: Nick Cameron <nrc@ncameron.org>

---------

Signed-off-by: Nick Cameron <nrc@ncameron.org>
2025-03-20 02:59:16 +00:00
9ddb4e629f Stub csg functions for front end (#5899)
* initial placeholder csg functions

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

* updates

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

* generate docs

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

* generate docs

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

---------

Signed-off-by: Jess Frazelle <github@jessfraz.com>
2025-03-20 02:26:57 +00:00
25e8e7081b Fix workflow to commit all generated kcl-samples files (#5896) 2025-03-20 01:10:54 +00:00
c5164cbee3 Fix electron renderer topLevelAwait in electron-forge (#5895)
* Fix electron renderer topLevelAwait

* Actually we need both for both cases, adding back plus comments
2025-03-19 20:54:35 -04:00
809b333248 bump kcl and friends before tomorrow release (#5897)
Signed-off-by: Jess Frazelle <github@jessfraz.com>
2025-03-19 17:12:02 -07:00
a933646667 Fix e2e workflow when only kcl-samples changes (#5894) 2025-03-19 19:46:44 -04:00
98a68f5cd9 Step file unfuck ci (#5891)
* remove the files

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

* remove step shit from kcl-samples

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>

* updates

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

* A snapshot a day keeps the bugs away! 📷🐛

* A snapshot a day keeps the bugs away! 📷🐛

---------

Signed-off-by: Jess Frazelle <github@jessfraz.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-03-19 16:43:10 -07:00
33dc254e43 Fix yarn build:wasm to format generated files (#5889) 2025-03-19 23:29:27 +00:00
b54295f2f7 get common edge (#5869)
* get common edge

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

* fmt

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

* updates

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

* add get common edge

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

* docs

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

---------

Signed-off-by: Jess Frazelle <github@jessfraz.com>
2025-03-20 09:12:27 +11:00
a7e09a89ef Improve snapshot testing (#5856)
* Improve snapshot testing

Signed-off-by: Nick Cameron <nrc@ncameron.org>

* A snapshot a day keeps the bugs away! 📷🐛

* A snapshot a day keeps the bugs away! 📷🐛

---------

Signed-off-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-03-19 15:06:27 -07:00
4b6166dc4f fix no profile errors (#5877)
* fix no profile errors

* add test and tweak a couple things

* quick fix

* fix animation

* add another test

* Use actor.getSnapshot in the debug function

So we don't have to rebuild that listener every time that the state
changes.

* try fix tests

---------

Co-authored-by: Frank Noirot <frankjohnson1993@gmail.com>
2025-03-20 08:30:11 +11:00
1157 changed files with 251220 additions and 758547 deletions

View File

@ -4,7 +4,7 @@
"main": "main.js",
"dependencies": {
"@actions/core": "^1.6",
"@actions/github": "^5.0",
"glob": "^7.1.5"
"@actions/github": "^6.0",
"glob": "^11.0.1"
}
}

View File

@ -4,27 +4,27 @@
set -euo pipefail
if [[ ! -f "test-results/.last-run.json" ]]; then
# if no last run artifact, than run plawright normally
# If no last run artifact, than run Playwright normally
echo "run playwright normally"
if [[ "$3" == *ubuntu* ]]; then
xvfb-run --auto-servernum --server-args="-screen 0 1280x960x24" -- yarn test:playwright:electron:ubuntu -- --shard=$1/$2 || true
elif [[ "$3" == *windows* ]]; then
yarn test:playwright:electron:windows -- --shard=$1/$2 || true
elif [[ "$3" == *macos* ]]; then
yarn test:playwright:electron:macos -- --shard=$1/$2 || true
else
echo "Do not run playwright. Unable to detect os runtime."
exit 1
fi
# # send to axiom
node playwrightProcess.mjs | tee /tmp/github-actions.log > /dev/null 2>&1
if [[ "$3" == *ubuntu* ]]; then
xvfb-run --auto-servernum --server-args="-screen 0 1280x960x24" -- yarn test:playwright:electron:ubuntu -- --shard=$1/$2 || true
elif [[ "$3" == *windows* ]]; then
yarn test:playwright:electron:windows -- --shard=$1/$2 || true
elif [[ "$3" == *macos* ]]; then
yarn test:playwright:electron:macos -- --shard=$1/$2 || true
else
echo "Do not run Playwright. Unable to detect os runtime."
exit 1
fi
# Log failures for Axiom to pick up
node playwrightProcess.mjs > /tmp/github-actions.log
fi
retry=1
max_retrys=1
max_retries=1
# retry failed tests, doing our own retries because using inbuilt playwright retries causes connection issues
while [[ $retry -le $max_retrys ]]; do
# Retry failed tests, doing our own retries because using inbuilt Playwright retries causes connection issues
while [[ $retry -le $max_retries ]]; do
if [[ -f "test-results/.last-run.json" ]]; then
failed_tests=$(jq '.failedTests | length' test-results/.last-run.json)
if [[ $failed_tests -gt 0 ]]; then
@ -40,8 +40,8 @@ while [[ $retry -le $max_retrys ]]; do
echo "Do not run playwright. Unable to detect os runtime."
exit 1
fi
# send to axiom
node playwrightProcess.mjs | tee /tmp/github-actions.log > /dev/null 2>&1
# Log failures for Axiom to pick up
node playwrightProcess.mjs > /tmp/github-actions.log
retry=$((retry + 1))
else
echo "retried=false" >>$GITHUB_OUTPUT
@ -58,7 +58,7 @@ echo "retried=false" >>$GITHUB_OUTPUT
if [[ -f "test-results/.last-run.json" ]]; then
failed_tests=$(jq '.failedTests | length' test-results/.last-run.json)
if [[ $failed_tests -gt 0 ]]; then
# if it still fails after 3 retrys, then fail the job
# If it still fails after 3 retries, then fail the job
exit 1
fi
fi

View File

@ -230,39 +230,6 @@ updates:
update-types:
- minor
- patch
- package-ecosystem: pip
directory: /public/kcl-samples
schedule:
interval: weekly
day: monday
time: '03:00'
timezone: America/Los_Angeles
open-pull-requests-limit: 5
reviewers:
- adamchalmers
- franknoirot
- irev-dev
- jessfraz
groups:
security:
applies-to: security-updates
update-types:
- major
- minor
- patch
patch:
applies-to: version-updates
update-types:
- patch
major:
applies-to: version-updates
update-types:
- major
minor:
applies-to: version-updates
update-types:
- minor
- patch
- package-ecosystem: pip
directory: /rust/kcl-python-bindings
schedule:

View File

@ -24,7 +24,7 @@ jobs:
uses: actions-rust-lang/setup-rust-toolchain@v1
with:
cache: false # Configured below.
- uses: taiki-e/install-action@955a6ff1416eae278c9f833008a9beb4b7f9afe3
- uses: taiki-e/install-action@37bdc826eaedac215f638a96472df572feab0f9b
with:
tool: wasm-pack
- name: Rust Cache

View File

@ -77,7 +77,7 @@ jobs:
with:
cache: false # Configured below.
- uses: taiki-e/install-action@955a6ff1416eae278c9f833008a9beb4b7f9afe3
- uses: taiki-e/install-action@37bdc826eaedac215f638a96472df572feab0f9b
if: ${{ steps.wasm.outputs.should-build-wasm == 'true' }}
with:
tool: wasm-pack

View File

@ -100,9 +100,14 @@ jobs:
shell: bash
run: |
set -euo pipefail
cd rust
pushd rust
just overwrite-sim-test kcl_samples
git add kcl-lib/tests
popd
git add \
rust/kcl-lib/tests \
public/kcl-samples/manifest.json \
public/kcl-samples/README.md \
public/kcl-samples/screenshots
git config --local user.email "github-actions[bot]@users.noreply.github.com"
git config --local user.name "github-actions[bot]"
git remote set-url origin https://${{ github.actor }}:${{ secrets.GITHUB_TOKEN }}@github.com/${{ github.repository }}.git

View File

@ -137,7 +137,7 @@ jobs:
with:
cache: false # Configured below.
- uses: taiki-e/install-action@955a6ff1416eae278c9f833008a9beb4b7f9afe3
- uses: taiki-e/install-action@37bdc826eaedac215f638a96472df572feab0f9b
if: ${{ needs.conditions.outputs.should-run == 'true' && steps.wasm.outputs.should-build-wasm == 'true' }}
with:
tool: wasm-pack
@ -325,6 +325,7 @@ jobs:
run: yarn
- name: Cache Playwright Browsers
if: needs.conditions.outputs.should-run == 'true'
uses: actions/cache@v4
with:
path: |
@ -332,20 +333,29 @@ jobs:
key: ${{ runner.os }}-playwright-${{ hashFiles('yarn.lock') }}
- name: Install Playwright Browsers
if: needs.conditions.outputs.should-run == 'true'
run: yarn playwright install --with-deps
- name: Build web
if: needs.conditions.outputs.should-run == 'true'
run: yarn tronb:vite:dev
- name: Install good sed
if: startsWith(matrix.os, 'macos')
- name: Install vector
if: contains(matrix.os, 'ubuntu')
shell: bash
run: |
brew install gnu-sed
echo "/opt/homebrew/opt/gnu-sed/libexec/gnubin" >> $GITHUB_PATH
# TODO: Add back axiom logs
curl --proto '=https' --tlsv1.2 -sSfL https://sh.vector.dev > /tmp/vector.sh
chmod +x /tmp/vector.sh
/tmp/vector.sh -y -no-modify-path
mkdir -p /tmp/vector
cp .github/workflows/vector.toml /tmp/vector.toml
sed -i "s#GITHUB_WORKFLOW#${GITHUB_WORKFLOW}#g" /tmp/vector.toml
sed -i "s#GITHUB_REPOSITORY#${GITHUB_REPOSITORY}#g" /tmp/vector.toml
sed -i "s#GITHUB_SHA#${GITHUB_SHA}#g" /tmp/vector.toml
sed -i "s#GITHUB_REF_NAME#${GITHUB_REF_NAME}#g" /tmp/vector.toml
sed -i "s#GH_ACTIONS_AXIOM_TOKEN#${{secrets.GH_ACTIONS_AXIOM_TOKEN}}#g" /tmp/vector.toml
cat /tmp/vector.toml
${HOME}/.vector/bin/vector --config /tmp/vector.toml &
- uses: actions/download-artifact@v4
if: ${{ needs.conditions.outputs.should-run == 'true' && !cancelled() && (success() || failure()) }}

View File

@ -376,7 +376,7 @@ jobs:
with:
credentials_json: "${{ secrets.GOOGLE_CLOUD_DL_SA }}"
- name: Set up Cloud SDK
uses: google-github-actions/setup-gcloud@v2.1.2
uses: google-github-actions/setup-gcloud@v2.1.4
with:
project_id: kittycadapi
- name: "upload files to gcp"

View File

@ -37,7 +37,7 @@ jobs:
node-version-file: '.nvmrc'
cache: 'yarn'
- run: yarn install
- uses: taiki-e/install-action@955a6ff1416eae278c9f833008a9beb4b7f9afe3
- uses: taiki-e/install-action@37bdc826eaedac215f638a96472df572feab0f9b
with:
tool: wasm-pack
- run: yarn build:wasm
@ -57,7 +57,7 @@ jobs:
with:
workspaces: './rust'
- uses: taiki-e/install-action@955a6ff1416eae278c9f833008a9beb4b7f9afe3
- uses: taiki-e/install-action@37bdc826eaedac215f638a96472df572feab0f9b
with:
tool: wasm-pack
- run: yarn build:wasm
@ -100,7 +100,7 @@ jobs:
cache: 'yarn'
- run: yarn install
- uses: taiki-e/install-action@955a6ff1416eae278c9f833008a9beb4b7f9afe3
- uses: taiki-e/install-action@37bdc826eaedac215f638a96472df572feab0f9b
with:
tool: wasm-pack
- run: yarn build:wasm
@ -129,7 +129,7 @@ jobs:
cache: 'yarn'
- run: yarn install
- uses: taiki-e/install-action@955a6ff1416eae278c9f833008a9beb4b7f9afe3
- uses: taiki-e/install-action@37bdc826eaedac215f638a96472df572feab0f9b
with:
tool: wasm-pack
- run: yarn build:wasm

View File

@ -1,5 +1,8 @@
name: update-dev-branch
# This is used to sync the `dev` branch with the `main` branch to continuously
# deploy a second instance of the app to Vercel: https://app.dev.zoo.dev
on:
push:
branches:
@ -26,4 +29,4 @@ jobs:
# reset to main
git reset --hard origin/main
# force push it
git push -f origin dev
git push --force origin dev

29
.github/workflows/update-e2e-branch.yml vendored Normal file
View File

@ -0,0 +1,29 @@
name: update-e2e-branch
# This is used to sync the `all-e2e` branch with the `main` branch for the
# logic in the test utility `orRunWhenFullSuiteEnabled()` that allows all e2e
# tests to run on a particular branch to analyze failures metrics in Axiom.
on:
schedule:
- cron: '0 * * * *' # runs every hour
permissions:
contents: write
jobs:
update-branch:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- shell: bash
run: |
# checkout our branch
git checkout all-e2e || git checkout -b all-e2e
# fetch origin
git fetch origin
# reset to main
git reset --hard origin/main
# force push it
git push --force origin all-e2e

1
.gitignore vendored
View File

@ -50,6 +50,7 @@ e2e/playwright/**/*.png
e2e/playwright/export-snapshots/*
!e2e/playwright/export-snapshots/*.png
!e2e/playwright/snapshot-tests.spec.ts-snapshots/*.png
trace.zip
/public/kcl-samples.zip
/public/kcl-samples/.github

118
Makefile
View File

@ -1,12 +1,111 @@
.PHONY: dev
.PHONY: all
all: install build check
KCL_WASM_LIB_FILES := $(wildcard rust/**/*.rs)
TS_SRC := $(wildcard src/**/*.tsx) $(wildcard src/**/*.ts)
XSTATE_TYPEGENS := $(wildcard src/machines/*.typegen.ts)
###############################################################################
# INSTALL
dev: node_modules public/kcl_wasm_lib_bg.wasm $(XSTATE_TYPEGENS)
WASM_PACK ?= ~/.cargo/bin/wasm-pack
.PHONY: install
install: node_modules/.yarn-integrity $(WASM_PACK) ## Install dependencies
node_modules/.yarn-integrity: package.json yarn.lock
yarn install
@ touch $@
$(WASM_PACK):
yarn install:rust
yarn install:wasm-pack:sh
###############################################################################
# BUILD
RUST_SOURCES := $(wildcard rust/*) $(wildcard rust/**/*)
TYPESCRIPT_SOURCES := $(wildcard src/**/*.tsx) $(wildcard src/**/*.ts)
.PHONY: build
build: build-web build-desktop
.PHONY: build-web
build-web: public/kcl_wasm_lib_bg.wasm build/index.html
.PHONY: build-desktop
build-desktop: public/kcl_wasm_lib_bg.wasm .vite/build/main.js
public/kcl_wasm_lib_bg.wasm: $(RUST_SOURCES)
yarn build:wasm
build/index.html: $(TYPESCRIPT_SOURCES)
yarn build:local
.vite/build/main.js: $(TYPESCRIPT_SOURCES)
yarn tronb:vite:dev
###############################################################################
# CHECK
.PHONY: check
check: format lint
.PHONY: format
format: install ## Format the code
yarn fmt
.PHONY: lint
lint: install ## Lint the code
yarn tsc
yarn lint
###############################################################################
# RUN
.PHONY: run
run: run-web
.PHONY: run-web
run-web: install build-web ## Start the web app
yarn start
.PHONY: run-desktop
run-desktop: install build-desktop ## Start the desktop app
yarn tron:start
###############################################################################
# TEST
GREP ?= ""
.PHONY: test
test: test-unit test-e2e
.PHONY: test-unit
test-unit: install ## Run the unit tests
@ nc -z localhost 3000 || ( echo "Error: localhost:3000 not available, 'make run-web' first" && exit 1 )
yarn test:unit
.PHONY: test-e2e
test-e2e: install build-desktop ## Run the e2e tests
yarn test:playwright:electron --workers=1 --grep=$(GREP)
###############################################################################
# CLEAN
.PHONY: clean
clean: ## Delete all artifacts
rm -rf .vite/ build/
rm -rf trace.zip playwright-report/ test-results/
rm -rf public/kcl_wasm_lib_bg.wasm
rm -rf rust/*/bindings/ rust/*/pkg/ rust/target/
rm -rf node_modules/ rust/*/node_modules/
.PHONY: help
help: install
@ grep -E '^[^[:space:]]+:.*## .*$$' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}'
.DEFAULT_GOAL := help
###############################################################################
# I'm sorry this is so specific to my setup you may as well ignore this.
# This is so you don't have to deal with electron windows popping up constantly.
# It should work for you other Linux users.
@ -14,12 +113,3 @@ lee-electron-test:
Xephyr -br -ac -noreset -screen 1200x500 :2 &
DISPLAY=:2 NODE_ENV=development PW_TEST_CONNECT_WS_ENDPOINT=ws://127.0.0.1:4444/ yarn tron:test -g "when using the file tree"
killall Xephyr
$(XSTATE_TYPEGENS): $(TS_SRC)
yarn xstate typegen 'src/**/*.ts?(x)'
public/kcl_wasm_lib_bg.wasm: $(KCL_WASM_LIB_FILES)
yarn build:wasm
node_modules: package.json yarn.lock
yarn install

View File

@ -33,7 +33,7 @@ abs(num: number): number
```js
myAngle = -120
sketch001 = startSketchOn('XZ')
sketch001 = startSketchOn(XZ)
|> startProfileAt([0, 0], %)
|> line(end = [8, 0])
|> angledLine({ angle = abs(myAngle), length = 5 }, %)

View File

@ -31,7 +31,7 @@ acos(num: number): number
### Examples
```js
sketch001 = startSketchOn('XZ')
sketch001 = startSketchOn(XZ)
|> startProfileAt([0, 0], %)
|> angledLine({
angle = toDegrees(acos(0.5)),

View File

@ -33,7 +33,7 @@ angleToMatchLengthX(
### Examples
```js
sketch001 = startSketchOn('XZ')
sketch001 = startSketchOn(XZ)
|> startProfileAt([0, 0], %)
|> line(end = [2, 5], tag = $seg01)
|> angledLineToX([-angleToMatchLengthX(seg01, 7, %), 10], %)

View File

@ -33,7 +33,7 @@ angleToMatchLengthY(
### Examples
```js
sketch001 = startSketchOn('XZ')
sketch001 = startSketchOn(XZ)
|> startProfileAt([0, 0], %)
|> line(end = [1, 2], tag = $seg01)
|> angledLine({

View File

@ -36,7 +36,7 @@ appearance(
```js
// Add color to an extruded solid.
exampleSketch = startSketchOn("XZ")
exampleSketch = startSketchOn(XZ)
|> startProfileAt([0, 0], %)
|> line(endAbsolute = [10, 0])
|> line(endAbsolute = [0, 10])
@ -52,7 +52,7 @@ example = extrude(exampleSketch, length = 5)
```js
// Add color to a revolved solid.
sketch001 = startSketchOn('XY')
sketch001 = startSketchOn(XY)
|> circle(center = [15, 0], radius = 5)
|> revolve(angle = 360, axis = 'y')
|> appearance(color = '#ff0000', metalness = 90, roughness = 90)
@ -63,7 +63,7 @@ sketch001 = startSketchOn('XY')
```js
// Add color to different solids.
fn cube(center) {
return startSketchOn('XY')
return startSketchOn(XY)
|> startProfileAt([center[0] - 10, center[1] - 10], %)
|> line(endAbsolute = [center[0] + 10, center[1] - 10])
|> line(endAbsolute = [center[0] + 10, center[1] + 10])
@ -95,7 +95,7 @@ appearance(
```js
// You can set the appearance before or after you shell it will yield the same result.
// This example shows setting the appearance _after_ the shell.
firstSketch = startSketchOn('XY')
firstSketch = startSketchOn(XY)
|> startProfileAt([-12, 12], %)
|> line(end = [24, 0])
|> line(end = [0, -24])
@ -112,7 +112,7 @@ shell(firstSketch, faces = ['end'], thickness = 0.25)
```js
// You can set the appearance before or after you shell it will yield the same result.
// This example shows setting the appearance _before_ the shell.
firstSketch = startSketchOn('XY')
firstSketch = startSketchOn(XY)
|> startProfileAt([-12, 12], %)
|> line(end = [24, 0])
|> line(end = [0, -24])
@ -129,7 +129,7 @@ shell(firstSketch, faces = ['end'], thickness = 0.25)
```js
// Setting the appearance of a 3D pattern can be done _before_ or _after_ the pattern.
// This example shows _before_ the pattern.
exampleSketch = startSketchOn('XZ')
exampleSketch = startSketchOn(XZ)
|> startProfileAt([0, 0], %)
|> line(end = [0, 2])
|> line(end = [3, 1])
@ -146,7 +146,7 @@ example = extrude(exampleSketch, length = 1)
```js
// Setting the appearance of a 3D pattern can be done _before_ or _after_ the pattern.
// This example shows _after_ the pattern.
exampleSketch = startSketchOn('XZ')
exampleSketch = startSketchOn(XZ)
|> startProfileAt([0, 0], %)
|> line(end = [0, 2])
|> line(end = [3, 1])
@ -162,7 +162,7 @@ example = extrude(exampleSketch, length = 1)
```js
// Color the result of a 2D pattern that was extruded.
exampleSketch = startSketchOn('XZ')
exampleSketch = startSketchOn(XZ)
|> startProfileAt([.5, 25], %)
|> line(end = [0, 5])
|> line(end = [-1, 0])
@ -184,9 +184,8 @@ example = extrude(exampleSketch, length = 1)
```js
// Color the result of a sweep.
// Create a path for the sweep.
sweepPath = startSketchOn('XZ')
sweepPath = startSketchOn(XZ)
|> startProfileAt([0.05, 0.05], %)
|> line(end = [0, 7])
|> tangentialArc({ offset = 90, radius = 5 }, %)
@ -194,10 +193,10 @@ sweepPath = startSketchOn('XZ')
|> tangentialArc({ offset = -90, radius = 5 }, %)
|> line(end = [0, 7])
pipeHole = startSketchOn('XY')
pipeHole = startSketchOn(XY)
|> circle(center = [0, 0], radius = 1.5)
sweepSketch = startSketchOn('XY')
sweepSketch = startSketchOn(XY)
|> circle(center = [0, 0], radius = 2)
|> hole(pipeHole, %)
|> sweep(path = sweepPath)

View File

@ -31,7 +31,7 @@ asin(num: number): number
### Examples
```js
sketch001 = startSketchOn('XZ')
sketch001 = startSketchOn(XZ)
|> startProfileAt([0, 0], %)
|> angledLine({
angle = toDegrees(asin(0.5)),

View File

@ -31,7 +31,7 @@ atan(num: number): number
### Examples
```js
sketch001 = startSketchOn('XZ')
sketch001 = startSketchOn(XZ)
|> startProfileAt([0, 0], %)
|> angledLine({
angle = toDegrees(atan(1.25)),

View File

@ -35,7 +35,7 @@ atan2(
### Examples
```js
sketch001 = startSketchOn('XZ')
sketch001 = startSketchOn(XZ)
|> startProfileAt([0, 0], %)
|> angledLine({
angle = toDegrees(atan2(1.25, 2)),

View File

@ -31,7 +31,7 @@ ceil(num: number): number
### Examples
```js
sketch001 = startSketchOn('XZ')
sketch001 = startSketchOn(XZ)
|> startProfileAt([0, 0], %)
|> line(endAbsolute = [12, 10])
|> line(end = [ceil(7.02986), 0])

View File

@ -41,7 +41,7 @@ length = 10
thickness = 1
chamferLength = 2
mountingPlateSketch = startSketchOn("XY")
mountingPlateSketch = startSketchOn(XY)
|> startProfileAt([-width / 2, -length / 2], %)
|> line(endAbsolute = [width / 2, -length / 2], tag = $edge1)
|> line(endAbsolute = [width / 2, length / 2], tag = $edge2)
@ -65,7 +65,7 @@ mountingPlate = extrude(mountingPlateSketch, length = thickness)
```js
// Sketch on the face of a chamfer.
fn cube(pos, scale) {
sg = startSketchOn('XY')
sg = startSketchOn(XY)
|> startProfileAt(pos, %)
|> line(end = [0, scale])
|> line(end = [scale, 0])

File diff suppressed because one or more lines are too long

View File

@ -37,7 +37,7 @@ circleThreePoint(
### Examples
```js
exampleSketch = startSketchOn("XY")
exampleSketch = startSketchOn(XY)
|> circleThreePoint(p1 = [10, 10], p2 = [20, 8], p3 = [15, 5])
|> extrude(length = 5)
```

View File

@ -28,7 +28,7 @@ e(): number
### Examples
```js
exampleSketch = startSketchOn("XZ")
exampleSketch = startSketchOn(XZ)
|> startProfileAt([0, 0], %)
|> angledLine({ angle = 30, length = 2 * e() ^ 2 }, %)
|> yLine(endAbsolute = 0)

File diff suppressed because one or more lines are too long

View File

@ -42,7 +42,7 @@ length = 10
thickness = 1
filletRadius = 2
mountingPlateSketch = startSketchOn("XY")
mountingPlateSketch = startSketchOn(XY)
|> startProfileAt([-width / 2, -length / 2], %)
|> line(endAbsolute = [width / 2, -length / 2], tag = $edge1)
|> line(endAbsolute = [width / 2, length / 2], tag = $edge2)
@ -69,7 +69,7 @@ length = 10
thickness = 1
filletRadius = 1
mountingPlateSketch = startSketchOn("XY")
mountingPlateSketch = startSketchOn(XY)
|> startProfileAt([-width / 2, -length / 2], %)
|> line(endAbsolute = [width / 2, -length / 2], tag = $edge1)
|> line(endAbsolute = [width / 2, length / 2], tag = $edge2)

View File

@ -31,7 +31,7 @@ floor(num: number): number
### Examples
```js
sketch001 = startSketchOn('XZ')
sketch001 = startSketchOn(XZ)
|> startProfileAt([0, 0], %)
|> line(endAbsolute = [12, 10])
|> line(end = [floor(7.02986), 0])

54
docs/kcl/getCommonEdge.md Normal file

File diff suppressed because one or more lines are too long

View File

@ -27,7 +27,7 @@ getNextAdjacentEdge(tag: TagIdentifier): Uuid
### Examples
```js
exampleSketch = startSketchOn('XZ')
exampleSketch = startSketchOn(XZ)
|> startProfileAt([0, 0], %)
|> line(end = [10, 0])
|> angledLine({ angle = 60, length = 10 }, %)

View File

@ -27,7 +27,7 @@ getOppositeEdge(tag: TagIdentifier): Uuid
### Examples
```js
exampleSketch = startSketchOn('XZ')
exampleSketch = startSketchOn(XZ)
|> startProfileAt([0, 0], %)
|> line(end = [10, 0])
|> angledLine({ angle = 60, length = 10 }, %)

View File

@ -27,7 +27,7 @@ getPreviousAdjacentEdge(tag: TagIdentifier): Uuid
### Examples
```js
exampleSketch = startSketchOn('XZ')
exampleSketch = startSketchOn(XZ)
|> startProfileAt([0, 0], %)
|> line(end = [10, 0])
|> angledLine({ angle = 60, length = 10 }, %)

View File

@ -50,7 +50,7 @@ helixPath = helix(
)
// Create a spring by sweeping around the helix path.
springSketch = startSketchOn('YZ')
springSketch = startSketchOn(YZ)
|> circle(center = [0, 0], radius = 0.5)
|> sweep(path = helixPath)
```
@ -59,7 +59,7 @@ springSketch = startSketchOn('YZ')
```js
// Create a helix around an edge.
helper001 = startSketchOn('XZ')
helper001 = startSketchOn(XZ)
|> startProfileAt([0, 0], %)
|> line(end = [0, 10], tag = $edge001)
@ -73,7 +73,7 @@ helixPath = helix(
)
// Create a spring by sweeping around the helix path.
springSketch = startSketchOn('XY')
springSketch = startSketchOn(XY)
|> circle(center = [0, 0], radius = 0.5)
|> sweep(path = helixPath)
```
@ -97,7 +97,7 @@ helixPath = helix(
)
// Create a spring by sweeping around the helix path.
springSketch = startSketchOn('XY')
springSketch = startSketchOn(XY)
|> circle(center = [0, 0], radius = 1)
|> sweep(path = helixPath)
```

View File

@ -31,7 +31,7 @@ helixRevolutions(
### Examples
```js
part001 = startSketchOn('XY')
part001 = startSketchOn(XY)
|> circle(center = [5, 5], radius = 10)
|> extrude(length = 10)
|> helixRevolutions({

View File

@ -32,7 +32,7 @@ hollow(
```js
// Hollow a basic sketch.
firstSketch = startSketchOn('XY')
firstSketch = startSketchOn(XY)
|> startProfileAt([-12, 12], %)
|> line(end = [24, 0])
|> line(end = [0, -24])
@ -46,7 +46,7 @@ firstSketch = startSketchOn('XY')
```js
// Hollow a basic sketch.
firstSketch = startSketchOn('-XZ')
firstSketch = startSketchOn(-XZ)
|> startProfileAt([-12, 12], %)
|> line(end = [24, 0])
|> line(end = [0, -24])
@ -61,7 +61,7 @@ firstSketch = startSketchOn('-XZ')
```js
// Hollow a sketch on face object.
size = 100
case = startSketchOn('-XZ')
case = startSketchOn(-XZ)
|> startProfileAt([-size, -size], %)
|> line(end = [2 * size, 0])
|> line(end = [0, 2 * size])

View File

@ -69,7 +69,7 @@ model = import("tests/inputs/cube.step")
```js
import height, buildSketch from "common.kcl"
plane = 'XZ'
plane = XZ
margin = 2
s1 = buildSketch(plane, [0, 0])
s2 = buildSketch(plane, [0, height() + margin])

View File

@ -22,8 +22,12 @@ layout: manual
* [`string`](kcl/types/string)
* [`tag`](kcl/types/tag)
* **std**
* [`Face`](kcl/types/Face)
* [`HALF_TURN`](kcl/consts/std-HALF_TURN)
* [`Helix`](kcl/types/Helix)
* [`Plane`](kcl/types/Plane)
* [`Point2d`](kcl/types/Point2d)
* [`Point3d`](kcl/types/Point3d)
* [`QUARTER_TURN`](kcl/consts/std-QUARTER_TURN)
* [`Sketch`](kcl/types/Sketch)
* [`Solid`](kcl/types/Solid)
@ -65,6 +69,7 @@ layout: manual
* [`fillet`](kcl/fillet)
* [`floor`](kcl/floor)
* [`ft`](kcl/ft)
* [`getCommonEdge`](kcl/getCommonEdge)
* [`getNextAdjacentEdge`](kcl/getNextAdjacentEdge)
* [`getOppositeEdge`](kcl/getOppositeEdge)
* [`getPreviousAdjacentEdge`](kcl/getPreviousAdjacentEdge)

View File

@ -36,7 +36,7 @@ int(num: number): number
n = int(ceil(5 / 2))
assertEqual(n, 3, 0.0001, "5/2 = 2.5, rounded up makes 3")
// Draw n cylinders.
startSketchOn('XZ')
startSketchOn(XZ)
|> circle(center = [0, 0], radius = 2)
|> extrude(length = 5)
|> patternTransform(

50
docs/kcl/intersect.md Normal file

File diff suppressed because one or more lines are too long

View File

@ -27,7 +27,7 @@ lastSegX(sketch: Sketch): number
### Examples
```js
exampleSketch = startSketchOn("XZ")
exampleSketch = startSketchOn(XZ)
|> startProfileAt([0, 0], %)
|> line(end = [5, 0])
|> line(end = [20, 5])

View File

@ -27,7 +27,7 @@ lastSegY(sketch: Sketch): number
### Examples
```js
exampleSketch = startSketchOn("XZ")
exampleSketch = startSketchOn(XZ)
|> startProfileAt([0, 0], %)
|> line(end = [5, 0])
|> line(end = [20, 5])

View File

@ -31,7 +31,7 @@ ln(num: number): number
### Examples
```js
exampleSketch = startSketchOn("XZ")
exampleSketch = startSketchOn(XZ)
|> startProfileAt([0, 0], %)
|> line(end = [ln(100), 15])
|> line(end = [5, -6])

View File

@ -42,7 +42,7 @@ loft(
```js
// Loft a square and a triangle.
squareSketch = startSketchOn('XY')
squareSketch = startSketchOn(XY)
|> startProfileAt([-100, 200], %)
|> line(end = [200, 0])
|> line(end = [0, -200])
@ -50,7 +50,7 @@ squareSketch = startSketchOn('XY')
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|> close()
triangleSketch = startSketchOn(offsetPlane('XY', offset = 75))
triangleSketch = startSketchOn(offsetPlane(XY, offset = 75))
|> startProfileAt([0, 125], %)
|> line(end = [-15, -30])
|> line(end = [30, 0])
@ -64,7 +64,7 @@ loft([squareSketch, triangleSketch])
```js
// Loft a square, a circle, and another circle.
squareSketch = startSketchOn('XY')
squareSketch = startSketchOn(XY)
|> startProfileAt([-100, 200], %)
|> line(end = [200, 0])
|> line(end = [0, -200])
@ -72,10 +72,10 @@ squareSketch = startSketchOn('XY')
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|> close()
circleSketch0 = startSketchOn(offsetPlane('XY', offset = 75))
circleSketch0 = startSketchOn(offsetPlane(XY, offset = 75))
|> circle(center = [0, 100], radius = 50)
circleSketch1 = startSketchOn(offsetPlane('XY', offset = 150))
circleSketch1 = startSketchOn(offsetPlane(XY, offset = 150))
|> circle(center = [0, 100], radius = 20)
loft([
@ -89,7 +89,7 @@ loft([
```js
// Loft a square, a circle, and another circle with options.
squareSketch = startSketchOn('XY')
squareSketch = startSketchOn(XY)
|> startProfileAt([-100, 200], %)
|> line(end = [200, 0])
|> line(end = [0, -200])
@ -97,10 +97,10 @@ squareSketch = startSketchOn('XY')
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|> close()
circleSketch0 = startSketchOn(offsetPlane('XY', offset = 75))
circleSketch0 = startSketchOn(offsetPlane(XY, offset = 75))
|> circle(center = [0, 100], radius = 50)
circleSketch1 = startSketchOn(offsetPlane('XY', offset = 150))
circleSketch1 = startSketchOn(offsetPlane(XY, offset = 150))
|> circle(center = [0, 100], radius = 20)
loft(

View File

@ -35,7 +35,7 @@ log(
### Examples
```js
exampleSketch = startSketchOn("XZ")
exampleSketch = startSketchOn(XZ)
|> startProfileAt([0, 0], %)
|> line(end = [log(100, 5), 0])
|> line(end = [5, 8])

View File

@ -31,7 +31,7 @@ log10(num: number): number
### Examples
```js
exampleSketch = startSketchOn("XZ")
exampleSketch = startSketchOn(XZ)
|> startProfileAt([0, 0], %)
|> line(end = [log10(100), 0])
|> line(end = [5, 8])

View File

@ -31,7 +31,7 @@ log2(num: number): number
### Examples
```js
exampleSketch = startSketchOn("XZ")
exampleSketch = startSketchOn(XZ)
|> startProfileAt([0, 0], %)
|> line(end = [log2(100), 0])
|> line(end = [5, 8])

View File

@ -33,7 +33,7 @@ map(
```js
r = 10 // radius
fn drawCircle(id) {
return startSketchOn("XY")
return startSketchOn(XY)
|> circle(center = [id * 2 * r, 0], radius = r)
}
@ -49,7 +49,7 @@ circles = map([1..3], drawCircle)
r = 10 // radius
// Call `map`, using an anonymous function instead of a named one.
circles = map([1..3], fn(id) {
return startSketchOn("XY")
return startSketchOn(XY)
|> circle(center = [id * 2 * r, 0], radius = r)
})
```

View File

@ -31,7 +31,7 @@ max(args: [number]): number
### Examples
```js
exampleSketch = startSketchOn("XZ")
exampleSketch = startSketchOn(XZ)
|> startProfileAt([0, 0], %)
|> angledLine({
angle = 70,

View File

@ -31,7 +31,7 @@ min(args: [number]): number
### Examples
```js
exampleSketch = startSketchOn("XZ")
exampleSketch = startSketchOn(XZ)
|> startProfileAt([0, 0], %)
|> angledLine({
angle = 70,

View File

@ -34,7 +34,7 @@ mirror2d(
```js
// Mirror an un-closed sketch across the Y axis.
sketch001 = startSketchOn('XZ')
sketch001 = startSketchOn(XZ)
|> startProfileAt([0, 10], %)
|> line(end = [15, 0])
|> line(end = [-7, -3])
@ -53,7 +53,7 @@ example = extrude(sketch001, length = 10)
```js
// Mirror a un-closed sketch across the Y axis.
sketch001 = startSketchOn('XZ')
sketch001 = startSketchOn(XZ)
|> startProfileAt([0, 8.5], %)
|> line(end = [20, -8.5])
|> line(end = [-20, -8.5])
@ -66,11 +66,11 @@ example = extrude(sketch001, length = 10)
```js
// Mirror a un-closed sketch across an edge.
helper001 = startSketchOn('XZ')
helper001 = startSketchOn(XZ)
|> startProfileAt([0, 0], %)
|> line(end = [0, 10], tag = $edge001)
sketch001 = startSketchOn('XZ')
sketch001 = startSketchOn(XZ)
|> startProfileAt([0, 8.5], %)
|> line(end = [20, -8.5])
|> line(end = [-20, -8.5])
@ -83,7 +83,7 @@ sketch001 = startSketchOn('XZ')
```js
// Mirror an un-closed sketch across a custom axis.
sketch001 = startSketchOn('XZ')
sketch001 = startSketchOn(XZ)
|> startProfileAt([0, 8.5], %)
|> line(end = [20, -8.5])
|> line(end = [-20, -8.5])

View File

@ -32,7 +32,7 @@ offsetPlane(
```js
// Loft a square and a circle on the `XY` plane using offset.
squareSketch = startSketchOn('XY')
squareSketch = startSketchOn(XY)
|> startProfileAt([-100, 200], %)
|> line(end = [200, 0])
|> line(end = [0, -200])
@ -40,7 +40,7 @@ squareSketch = startSketchOn('XY')
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|> close()
circleSketch = startSketchOn(offsetPlane('XY', offset = 150))
circleSketch = startSketchOn(offsetPlane(XY, offset = 150))
|> circle(center = [0, 100], radius = 50)
loft([squareSketch, circleSketch])
@ -50,7 +50,7 @@ loft([squareSketch, circleSketch])
```js
// Loft a square and a circle on the `XZ` plane using offset.
squareSketch = startSketchOn('XZ')
squareSketch = startSketchOn(XZ)
|> startProfileAt([-100, 200], %)
|> line(end = [200, 0])
|> line(end = [0, -200])
@ -58,7 +58,7 @@ squareSketch = startSketchOn('XZ')
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|> close()
circleSketch = startSketchOn(offsetPlane('XZ', offset = 150))
circleSketch = startSketchOn(offsetPlane(XZ, offset = 150))
|> circle(center = [0, 100], radius = 50)
loft([squareSketch, circleSketch])
@ -68,7 +68,7 @@ loft([squareSketch, circleSketch])
```js
// Loft a square and a circle on the `YZ` plane using offset.
squareSketch = startSketchOn('YZ')
squareSketch = startSketchOn(YZ)
|> startProfileAt([-100, 200], %)
|> line(end = [200, 0])
|> line(end = [0, -200])
@ -76,7 +76,7 @@ squareSketch = startSketchOn('YZ')
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|> close()
circleSketch = startSketchOn(offsetPlane('YZ', offset = 150))
circleSketch = startSketchOn(offsetPlane(YZ, offset = 150))
|> circle(center = [0, 100], radius = 50)
loft([squareSketch, circleSketch])
@ -86,7 +86,7 @@ loft([squareSketch, circleSketch])
```js
// Loft a square and a circle on the `-XZ` plane using offset.
squareSketch = startSketchOn('-XZ')
squareSketch = startSketchOn(-XZ)
|> startProfileAt([-100, 200], %)
|> line(end = [200, 0])
|> line(end = [0, -200])
@ -94,7 +94,7 @@ squareSketch = startSketchOn('-XZ')
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|> close()
circleSketch = startSketchOn(offsetPlane('-XZ', offset = -150))
circleSketch = startSketchOn(offsetPlane(-XZ, offset = -150))
|> circle(center = [0, 100], radius = 50)
loft([squareSketch, circleSketch])
@ -104,12 +104,12 @@ loft([squareSketch, circleSketch])
```js
// A circle on the XY plane
startSketchOn("XY")
startSketchOn(XY)
|> startProfileAt([0, 0], %)
|> circle(radius = 10, center = [0, 0])
// Triangle on the plane 4 units above
startSketchOn(offsetPlane("XY", offset = 4))
startSketchOn(offsetPlane(XY, offset = 4))
|> startProfileAt([0, 0], %)
|> line(end = [10, 0])
|> line(end = [0, 10])

View File

@ -39,7 +39,7 @@ patternCircular2d(
### Examples
```js
exampleSketch = startSketchOn('XZ')
exampleSketch = startSketchOn(XZ)
|> startProfileAt([.5, 25], %)
|> line(end = [0, 5])
|> line(end = [-1, 0])

View File

@ -41,7 +41,7 @@ patternCircular3d(
### Examples
```js
exampleSketch = startSketchOn('XZ')
exampleSketch = startSketchOn(XZ)
|> circle(center = [0, 0], radius = 1)
example = extrude(exampleSketch, length = -5)

View File

@ -37,7 +37,7 @@ patternLinear2d(
### Examples
```js
exampleSketch = startSketchOn('XZ')
exampleSketch = startSketchOn(XZ)
|> circle(center = [0, 0], radius = 1)
|> patternLinear2d(axis = [1, 0], instances = 7, distance = 4)

View File

@ -37,7 +37,7 @@ patternLinear3d(
### Examples
```js
exampleSketch = startSketchOn('XZ')
exampleSketch = startSketchOn(XZ)
|> startProfileAt([0, 0], %)
|> line(end = [0, 2])
|> line(end = [3, 1])
@ -53,7 +53,7 @@ example = extrude(exampleSketch, length = 1)
```js
// Pattern a whole sketch on face.
size = 100
case = startSketchOn('XY')
case = startSketchOn(XY)
|> startProfileAt([-size, -size], %)
|> line(end = [2 * size, 0])
|> line(end = [0, 2 * size])
@ -84,7 +84,7 @@ patternLinear3d(
```js
// Pattern an object on a face.
size = 100
case = startSketchOn('XY')
case = startSketchOn(XY)
|> startProfileAt([-size, -size], %)
|> line(end = [2 * size, 0])
|> line(end = [0, 2 * size])

View File

@ -67,7 +67,7 @@ fn transform(id) {
}
// Sketch 4 cylinders.
sketch001 = startSketchOn('XZ')
sketch001 = startSketchOn(XZ)
|> circle(center = [0, 0], radius = 2)
|> extrude(length = 5)
|> patternTransform(instances = 4, transform = transform)
@ -83,7 +83,7 @@ fn transform(id) {
return { translate = [4 * (1 + id), 0, 0] }
}
sketch001 = startSketchOn('XZ')
sketch001 = startSketchOn(XZ)
|> circle(center = [0, 0], radius = 2)
|> extrude(length = 5)
|> patternTransform(instances = 4, transform = transform)
@ -101,7 +101,7 @@ fn cube(length, center) {
p2 = [l + x, l + y]
p3 = [l + x, -l + y]
return startSketchOn('XY')
return startSketchOn(XY)
|> startProfileAt(p0, %)
|> line(endAbsolute = p1)
|> line(endAbsolute = p2)
@ -139,7 +139,7 @@ fn cube(length, center) {
p2 = [l + x, l + y]
p3 = [l + x, -l + y]
return startSketchOn('XY')
return startSketchOn(XY)
|> startProfileAt(p0, %)
|> line(endAbsolute = p1)
|> line(endAbsolute = p2)
@ -182,7 +182,7 @@ fn transform(replicaId) {
}
// Each layer is just a pretty thin cylinder.
fn layer() {
return startSketchOn("XY")
return startSketchOn(XY)
// or some other plane idk
|> circle(center = [0, 0], radius = 1, tag = $tag1)
|> extrude(length = h)
@ -203,7 +203,7 @@ fn transform(i) {
{ rotation = { angle = 45 * i } }
]
}
startSketchOn('XY')
startSketchOn(XY)
|> startProfileAt([0, 0], %)
|> polygon({
radius = 10,

View File

@ -41,7 +41,7 @@ fn transform(id) {
}
// Sketch 4 circles.
sketch001 = startSketchOn('XZ')
sketch001 = startSketchOn(XZ)
|> circle(center = [0, 0], radius = 2)
|> patternTransform2d(instances = 4, transform = transform)
```

View File

@ -30,7 +30,7 @@ pi(): number
```js
circumference = 70
exampleSketch = startSketchOn("XZ")
exampleSketch = startSketchOn(XZ)
|> circle(center = [0, 0], radius = circumference / (2 * pi()))
example = extrude(exampleSketch, length = 5)

View File

@ -27,7 +27,7 @@ polar(data: PolarCoordsData): [number]
### Examples
```js
exampleSketch = startSketchOn('XZ')
exampleSketch = startSketchOn(XZ)
|> startProfileAt([0, 0], %)
|> line(end = polar({ angle = 30, length = 5 }), tag = $thing)
|> line(end = [0, 5])

View File

@ -34,7 +34,7 @@ polygon(
```js
// Create a regular hexagon inscribed in a circle of radius 10
hex = startSketchOn('XY')
hex = startSketchOn(XY)
|> polygon({
radius = 10,
numSides = 6,
@ -49,7 +49,7 @@ example = extrude(hex, length = 5)
```js
// Create a square circumscribed around a circle of radius 5
square = startSketchOn('XY')
square = startSketchOn(XY)
|> polygon({
radius = 5.0,
numSides = 4,

View File

@ -35,7 +35,7 @@ pow(
### Examples
```js
exampleSketch = startSketchOn("XZ")
exampleSketch = startSketchOn(XZ)
|> startProfileAt([0, 0], %)
|> angledLine({ angle = 50, length = pow(5, 2) }, %)
|> yLine(endAbsolute = 0)

View File

@ -52,7 +52,6 @@ fn sum(arr):
sumSoFar = add(sumSoFar, i)
return sumSoFar */
// We use `assertEqual` to check that our `sum` function gives the
// expected result. It's good to check your work!
assertEqual(sum([1, 2, 3]), 6, 0.00001, "1 + 2 + 3 summed is 6")
@ -83,7 +82,7 @@ fn decagon(radius) {
stepAngle = 1 / 10 * TAU
// Start the decagon sketch at this point.
startOfDecagonSketch = startSketchOn('XY')
startOfDecagonSketch = startSketchOn(XY)
|> startProfileAt([cos(0) * radius, sin(0) * radius], %)
// Use a `reduce` to draw the remaining decagon sides.
@ -114,7 +113,6 @@ fn decagon(radius):
fullDecagon = partialDecagon // it's now full
return fullDecagon */
// Use the `decagon` function declared above, to sketch a decagon with radius 5.
decagon(5.0)
|> close()

File diff suppressed because one or more lines are too long

View File

@ -57,9 +57,8 @@ rotate(
```js
// Rotate a pipe with roll, pitch, and yaw.
// Create a path for the sweep.
sweepPath = startSketchOn('XZ')
sweepPath = startSketchOn(XZ)
|> startProfileAt([0.05, 0.05], %)
|> line(end = [0, 7])
|> tangentialArc({ offset = 90, radius = 5 }, %)
@ -68,10 +67,10 @@ sweepPath = startSketchOn('XZ')
|> line(end = [0, 7])
// Create a hole for the pipe.
pipeHole = startSketchOn('XY')
pipeHole = startSketchOn(XY)
|> circle(center = [0, 0], radius = 1.5)
sweepSketch = startSketchOn('XY')
sweepSketch = startSketchOn(XY)
|> circle(center = [0, 0], radius = 2)
|> hole(pipeHole, %)
|> sweep(path = sweepPath)
@ -83,9 +82,8 @@ sweepSketch = startSketchOn('XY')
```js
// Rotate a pipe about an axis with an angle.
// Create a path for the sweep.
sweepPath = startSketchOn('XZ')
sweepPath = startSketchOn(XZ)
|> startProfileAt([0.05, 0.05], %)
|> line(end = [0, 7])
|> tangentialArc({ offset = 90, radius = 5 }, %)
@ -94,10 +92,10 @@ sweepPath = startSketchOn('XZ')
|> line(end = [0, 7])
// Create a hole for the pipe.
pipeHole = startSketchOn('XY')
pipeHole = startSketchOn(XY)
|> circle(center = [0, 0], radius = 1.5)
sweepSketch = startSketchOn('XY')
sweepSketch = startSketchOn(XY)
|> circle(center = [0, 0], radius = 2)
|> hole(pipeHole, %)
|> sweep(path = sweepPath)
@ -122,7 +120,7 @@ cube
// Sweep two sketches along the same path.
sketch001 = startSketchOn('XY')
sketch001 = startSketchOn(XY)
rectangleSketch = startProfileAt([-200, 23.86], sketch001)
|> angledLine([0, 73.47], %, $rectangleSegmentA001)
|> angledLine([
@ -138,7 +136,7 @@ rectangleSketch = startProfileAt([-200, 23.86], sketch001)
circleSketch = circle(sketch001, center = [200, -30.29], radius = 32.63)
sketch002 = startSketchOn('YZ')
sketch002 = startSketchOn(YZ)
sweepPath = startProfileAt([0, 0], sketch002)
|> yLine(length = 231.81)
|> tangentialArc({ radius = 80, offset = -90 }, %)
@ -154,7 +152,7 @@ rotate(parts, axis = [0, 0, 1.0], angle = 90)
```js
// Translate and rotate a sketch to create a loft.
sketch001 = startSketchOn('XY')
sketch001 = startSketchOn(XY)
fn square() {
return startProfileAt([-10, 10], sketch001)

View File

@ -31,7 +31,7 @@ round(num: number): number
### Examples
```js
sketch001 = startSketchOn('XZ')
sketch001 = startSketchOn(XZ)
|> startProfileAt([0, 0], %)
|> line(endAbsolute = [12, 10])
|> line(end = [round(7.02986), 0])

View File

@ -37,9 +37,8 @@ scale(
```js
// Scale a pipe.
// Create a path for the sweep.
sweepPath = startSketchOn('XZ')
sweepPath = startSketchOn(XZ)
|> startProfileAt([0.05, 0.05], %)
|> line(end = [0, 7])
|> tangentialArc({ offset = 90, radius = 5 }, %)
@ -48,10 +47,10 @@ sweepPath = startSketchOn('XZ')
|> line(end = [0, 7])
// Create a hole for the pipe.
pipeHole = startSketchOn('XY')
pipeHole = startSketchOn(XY)
|> circle(center = [0, 0], radius = 1.5)
sweepSketch = startSketchOn('XY')
sweepSketch = startSketchOn(XY)
|> circle(center = [0, 0], radius = 2)
|> hole(pipeHole, %)
|> sweep(path = sweepPath)
@ -76,7 +75,7 @@ cube
// Sweep two sketches along the same path.
sketch001 = startSketchOn('XY')
sketch001 = startSketchOn(XY)
rectangleSketch = startProfileAt([-200, 23.86], sketch001)
|> angledLine([0, 73.47], %, $rectangleSegmentA001)
|> angledLine([
@ -92,7 +91,7 @@ rectangleSketch = startProfileAt([-200, 23.86], sketch001)
circleSketch = circle(sketch001, center = [200, -30.29], radius = 32.63)
sketch002 = startSketchOn('YZ')
sketch002 = startSketchOn(YZ)
sweepPath = startProfileAt([0, 0], sketch002)
|> yLine(length = 231.81)
|> tangentialArc({ radius = 80, offset = -90 }, %)

View File

@ -27,7 +27,7 @@ segAng(tag: TagIdentifier): number
### Examples
```js
exampleSketch = startSketchOn('XZ')
exampleSketch = startSketchOn(XZ)
|> startProfileAt([0, 0], %)
|> line(end = [10, 0])
|> line(end = [5, 10], tag = $seg01)

View File

@ -28,7 +28,7 @@ segEnd(tag: TagIdentifier): [number]
```js
w = 15
cube = startSketchOn('XY')
cube = startSketchOn(XY)
|> startProfileAt([0, 0], %)
|> line(end = [w, 0], tag = $line1)
|> line(end = [0, w], tag = $line2)
@ -38,7 +38,7 @@ cube = startSketchOn('XY')
|> extrude(length = 5)
fn cylinder(radius, tag) {
return startSketchOn('XY')
return startSketchOn(XY)
|> startProfileAt([0, 0], %)
|> circle(radius = radius, center = segEnd(tag))
|> extrude(length = radius)

View File

@ -27,7 +27,7 @@ segEndX(tag: TagIdentifier): number
### Examples
```js
exampleSketch = startSketchOn('XZ')
exampleSketch = startSketchOn(XZ)
|> startProfileAt([0, 0], %)
|> line(end = [20, 0], tag = $thing)
|> line(end = [0, 5])

View File

@ -27,7 +27,7 @@ segEndY(tag: TagIdentifier): number
### Examples
```js
exampleSketch = startSketchOn('XZ')
exampleSketch = startSketchOn(XZ)
|> startProfileAt([0, 0], %)
|> line(end = [20, 0])
|> line(end = [0, 3], tag = $thing)

View File

@ -27,7 +27,7 @@ segLen(tag: TagIdentifier): number
### Examples
```js
exampleSketch = startSketchOn("XZ")
exampleSketch = startSketchOn(XZ)
|> startProfileAt([0, 0], %)
|> angledLine({ angle = 60, length = 10 }, %, $thing)
|> tangentialArc({ offset = -120, radius = 5 }, %)

View File

@ -28,7 +28,7 @@ segStart(tag: TagIdentifier): [number]
```js
w = 15
cube = startSketchOn('XY')
cube = startSketchOn(XY)
|> startProfileAt([0, 0], %)
|> line(end = [w, 0], tag = $line1)
|> line(end = [0, w], tag = $line2)
@ -38,7 +38,7 @@ cube = startSketchOn('XY')
|> extrude(length = 5)
fn cylinder(radius, tag) {
return startSketchOn('XY')
return startSketchOn(XY)
|> startProfileAt([0, 0], %)
|> circle(radius = radius, center = segStart(tag))
|> extrude(length = radius)

View File

@ -27,7 +27,7 @@ segStartX(tag: TagIdentifier): number
### Examples
```js
exampleSketch = startSketchOn('XZ')
exampleSketch = startSketchOn(XZ)
|> startProfileAt([0, 0], %)
|> line(end = [20, 0], tag = $thing)
|> line(end = [0, 5])

View File

@ -27,7 +27,7 @@ segStartY(tag: TagIdentifier): number
### Examples
```js
exampleSketch = startSketchOn('XZ')
exampleSketch = startSketchOn(XZ)
|> startProfileAt([0, 0], %)
|> line(end = [20, 0])
|> line(end = [0, 3], tag = $thing)

View File

@ -34,7 +34,7 @@ shell(
```js
// Remove the end face for the extrusion.
firstSketch = startSketchOn('XY')
firstSketch = startSketchOn(XY)
|> startProfileAt([-12, 12], %)
|> line(end = [24, 0])
|> line(end = [0, -24])
@ -50,7 +50,7 @@ shell(firstSketch, faces = ['end'], thickness = 0.25)
```js
// Remove the start face for the extrusion.
firstSketch = startSketchOn('-XZ')
firstSketch = startSketchOn(-XZ)
|> startProfileAt([-12, 12], %)
|> line(end = [24, 0])
|> line(end = [0, -24])
@ -66,7 +66,7 @@ shell(firstSketch, faces = ['start'], thickness = 0.25)
```js
// Remove a tagged face and the end face for the extrusion.
firstSketch = startSketchOn('XY')
firstSketch = startSketchOn(XY)
|> startProfileAt([-12, 12], %)
|> line(end = [24, 0])
|> line(end = [0, -24])
@ -82,7 +82,7 @@ shell(firstSketch, faces = [myTag], thickness = 0.25)
```js
// Remove multiple faces at once.
firstSketch = startSketchOn('XY')
firstSketch = startSketchOn(XY)
|> startProfileAt([-12, 12], %)
|> line(end = [24, 0])
|> line(end = [0, -24])
@ -99,7 +99,7 @@ shell(firstSketch, faces = [myTag, 'end'], thickness = 0.25)
```js
// Shell a sketch on face.
size = 100
case = startSketchOn('-XZ')
case = startSketchOn(-XZ)
|> startProfileAt([-size, -size], %)
|> line(end = [2 * size, 0])
|> line(end = [0, 2 * size])
@ -124,7 +124,7 @@ shell(case, faces = ['start'], thickness = 5)
```js
// Shell a sketch on face object on the end face.
size = 100
case = startSketchOn('XY')
case = startSketchOn(XY)
|> startProfileAt([-size, -size], %)
|> line(end = [2 * size, 0])
|> line(end = [0, 2 * size])
@ -152,7 +152,7 @@ shell(thing1, faces = ['end'], thickness = 5)
size = 100
case = startSketchOn('XY')
case = startSketchOn(XY)
|> startProfileAt([-size, -size], %)
|> line(end = [2 * size, 0])
|> line(end = [0, 2 * size])

View File

@ -31,7 +31,7 @@ sqrt(num: number): number
### Examples
```js
exampleSketch = startSketchOn("XZ")
exampleSketch = startSketchOn(XZ)
|> startProfileAt([0, 0], %)
|> angledLine({ angle = 50, length = sqrt(2500) }, %)
|> yLine(endAbsolute = 0)

File diff suppressed because it is too large Load Diff

56
docs/kcl/subtract.md Normal file

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

@ -28,7 +28,7 @@ tau(): number
### Examples
```js
exampleSketch = startSketchOn("XZ")
exampleSketch = startSketchOn(XZ)
|> startProfileAt([0, 0], %)
|> angledLine({ angle = 50, length = 10 * tau() }, %)
|> yLine(endAbsolute = 0)

View File

@ -31,7 +31,7 @@ toDegrees(num: number): number
### Examples
```js
exampleSketch = startSketchOn("XZ")
exampleSketch = startSketchOn(XZ)
|> startProfileAt([0, 0], %)
|> angledLine({
angle = 50,

View File

@ -31,7 +31,7 @@ toRadians(num: number): number
### Examples
```js
exampleSketch = startSketchOn("XZ")
exampleSketch = startSketchOn(XZ)
|> startProfileAt([0, 0], %)
|> angledLine({
angle = 50,

View File

@ -35,9 +35,8 @@ translate(
```js
// Move a pipe.
// Create a path for the sweep.
sweepPath = startSketchOn('XZ')
sweepPath = startSketchOn(XZ)
|> startProfileAt([0.05, 0.05], %)
|> line(end = [0, 7])
|> tangentialArc({ offset = 90, radius = 5 }, %)
@ -46,10 +45,10 @@ sweepPath = startSketchOn('XZ')
|> line(end = [0, 7])
// Create a hole for the pipe.
pipeHole = startSketchOn('XY')
pipeHole = startSketchOn(XY)
|> circle(center = [0, 0], radius = 1.5)
sweepSketch = startSketchOn('XY')
sweepSketch = startSketchOn(XY)
|> circle(center = [0, 0], radius = 2)
|> hole(pipeHole, %)
|> sweep(path = sweepPath)
@ -74,7 +73,7 @@ cube
// Sweep two sketches along the same path.
sketch001 = startSketchOn('XY')
sketch001 = startSketchOn(XY)
rectangleSketch = startProfileAt([-200, 23.86], sketch001)
|> angledLine([0, 73.47], %, $rectangleSegmentA001)
|> angledLine([
@ -90,7 +89,7 @@ rectangleSketch = startProfileAt([-200, 23.86], sketch001)
circleSketch = circle(sketch001, center = [200, -30.29], radius = 32.63)
sketch002 = startSketchOn('YZ')
sketch002 = startSketchOn(YZ)
sweepPath = startProfileAt([0, 0], sketch002)
|> yLine(length = 231.81)
|> tangentialArc({ radius = 80, offset = -90 }, %)
@ -132,7 +131,7 @@ square(10)
```js
// Translate and rotate a sketch to create a loft.
sketch001 = startSketchOn('XY')
sketch001 = startSketchOn(XY)
fn square() {
return startProfileAt([-10, 10], sketch001)

View File

@ -1,28 +1,12 @@
---
title: "Face"
title: "std::Face"
excerpt: "A face."
layout: manual
---
A face.
**Type:** `object`
## Properties
| Property | Type | Description | Required |
|----------|------|-------------|----------|
| `id` |[`string`](/docs/kcl/types/string)| The id of the face. | No |
| `artifactId` |[`ArtifactId`](/docs/kcl/types/ArtifactId)| The artifact ID. | No |
| `value` |[`string`](/docs/kcl/types/string)| The tag of the face. | No |
| `xAxis` |[`Point3d`](/docs/kcl/types/Point3d)| What should the face's X axis be? | No |
| `yAxis` |[`Point3d`](/docs/kcl/types/Point3d)| What should the face's Y axis be? | No |
| `zAxis` |[`Point3d`](/docs/kcl/types/Point3d)| The z-axis (normal). | No |
| `solid` |[`Solid`](/docs/kcl/types/Solid)| The solid the face is on. | No |
| `units` |[`UnitLen`](/docs/kcl/types/UnitLen)| A unit of length. | No |

View File

@ -1,26 +1,12 @@
---
title: "Helix"
title: "std::Helix"
excerpt: "A helix."
layout: manual
---
A helix.
**Type:** `object`
## Properties
| Property | Type | Description | Required |
|----------|------|-------------|----------|
| `value` |[`string`](/docs/kcl/types/string)| The id of the helix. | No |
| `artifactId` |[`ArtifactId`](/docs/kcl/types/ArtifactId)| The artifact ID. | No |
| `revolutions` |[`number`](/docs/kcl/types/number)| Number of revolutions. | No |
| `angleStart` |[`number`](/docs/kcl/types/number)| Start angle (in degrees). | No |
| `ccw` |`boolean`| Is the helix rotation counter clockwise? | No |
| `units` |[`UnitLen`](/docs/kcl/types/UnitLen)| A unit of length. | No |

View File

@ -188,7 +188,7 @@ Any KCL value.
| Property | Type | Description | Required |
|----------|------|-------------|----------|
| `type` |enum: [`Face`](/docs/kcl/types/Face)| | No |
| `value` |[`Face`](/docs/kcl/types/Face)| A face. | No |
| `value` |[`Face`](/docs/kcl/types/Face)| | No |
----
@ -236,7 +236,7 @@ Any KCL value.
| Property | Type | Description | Required |
|----------|------|-------------|----------|
| `type` |enum: [`Helix`](/docs/kcl/types/Helix)| | No |
| `value` |[`Helix`](/docs/kcl/types/Helix)| A helix. | No |
| `value` |[`Helix`](/docs/kcl/types/Helix)| | No |
----

17
docs/kcl/types/Point2d.md Normal file
View File

@ -0,0 +1,17 @@
---
title: "std::Point2d"
excerpt: "A point in two dimensional space."
layout: manual
---
A point in two dimensional space.
```kcl
type Point2d = [number; 2]
```
`Point2d` is an alias for a two-element array of [number](/docs/kcl/types/number)s. To write a value
with type `Point2d`, use an array, e.g., `[0, 0]` or `[5.0, 3.14]`.

View File

@ -1,22 +1,17 @@
---
title: "Point3d"
excerpt: ""
title: "std::Point3d"
excerpt: "A point in three dimensional space."
layout: manual
---
A point in three dimensional space.
**Type:** `object`
```kcl
type Point3d = [number; 3]
```
`Point3d` is an alias for a three-element array of [number](/docs/kcl/types/number)s. To write a value
with type `Point3d`, use an array, e.g., `[0, 0, 0]` or `[5.0, 3.14, 6.8]`.
## Properties
| Property | Type | Description | Required |
|----------|------|-------------|----------|
| `x` |[`number`](/docs/kcl/types/number)| | No |
| `y` |[`number`](/docs/kcl/types/number)| | No |
| `z` |[`number`](/docs/kcl/types/number)| | No |

View File

@ -22,7 +22,6 @@ A path to sweep along.
----
A helix.
[`Helix`](/docs/kcl/types/Helix)

50
docs/kcl/union.md Normal file

File diff suppressed because one or more lines are too long

View File

@ -5,6 +5,7 @@ import {
TEST_COLORS,
commonPoints,
PERSIST_MODELING_CONTEXT,
orRunWhenFullSuiteEnabled,
} from './test-utils'
import { HomePageFixture } from './fixtures/homePageFixture'
@ -46,7 +47,7 @@ async function doBasicSketch(
await page.mouse.click(700, 200)
if (openPanes.includes('code')) {
await expect(u.codeLocator).toHaveText(`sketch001 = startSketchOn('XZ')`)
await expect(u.codeLocator).toHaveText(`sketch001 = startSketchOn(XZ)`)
}
await u.closeDebugPanel()
@ -56,7 +57,7 @@ async function doBasicSketch(
await page.mouse.click(startXPx + PUR * 10, 500 - PUR * 10)
if (openPanes.includes('code')) {
await expect(u.codeLocator).toContainText(
`sketch001 = startSketchOn('XZ')profile001 = startProfileAt(${commonPoints.startAt}, sketch001)`
`sketch001 = startSketchOn(XZ)profile001 = startProfileAt(${commonPoints.startAt}, sketch001)`
)
}
await page.waitForTimeout(500)
@ -65,14 +66,14 @@ async function doBasicSketch(
if (openPanes.includes('code')) {
await expect(u.codeLocator)
.toHaveText(`sketch001 = startSketchOn('XZ')profile001 = startProfileAt(${commonPoints.startAt}, sketch001)
.toHaveText(`sketch001 = startSketchOn(XZ)profile001 = startProfileAt(${commonPoints.startAt}, sketch001)
|> xLine(length = ${commonPoints.num1})`)
}
await page.waitForTimeout(500)
await page.mouse.click(startXPx + PUR * 20, 500 - PUR * 20)
if (openPanes.includes('code')) {
await expect(u.codeLocator)
.toHaveText(`sketch001 = startSketchOn('XZ')profile001 = startProfileAt(${
.toHaveText(`sketch001 = startSketchOn(XZ)profile001 = startProfileAt(${
commonPoints.startAt
}, sketch001)
|> xLine(length = ${commonPoints.num1})
@ -84,7 +85,7 @@ async function doBasicSketch(
await page.mouse.click(startXPx, 500 - PUR * 20)
if (openPanes.includes('code')) {
await expect(u.codeLocator)
.toHaveText(`sketch001 = startSketchOn('XZ')profile001 = startProfileAt(${
.toHaveText(`@settings(defaultLengthUnit = in)sketch001 = startSketchOn('XZ')profile001 = startProfileAt(${
commonPoints.startAt
}, sketch001)
|> xLine(length = ${commonPoints.num1})
@ -144,7 +145,7 @@ async function doBasicSketch(
// Open the code pane.
await u.openKclCodePanel()
await expect(u.codeLocator)
.toHaveText(`sketch001 = startSketchOn('XZ')profile001 = startProfileAt(${
.toHaveText(`@settings(defaultLengthUnit = in)sketch001 = startSketchOn('XZ')profile001 = startProfileAt(${
commonPoints.startAt
}, sketch001)
|> xLine(length = ${commonPoints.num1}, tag = $seg01)
@ -153,7 +154,8 @@ async function doBasicSketch(
}
test.describe('Basic sketch', { tag: ['@skipWin'] }, () => {
test.fixme('code pane open at start', async ({ page, homePage }) => {
test('code pane open at start', async ({ page, homePage }) => {
test.fixme(orRunWhenFullSuiteEnabled())
await doBasicSketch(page, homePage, ['code'])
})

View File

@ -46,7 +46,7 @@ test.describe(
},
}
const code = `sketch001 = startSketchOn('${plane}')profile001 = startProfileAt([0.91, -1.22], sketch001)`
const code = `@settings(defaultLengthUnit = in)sketch001 = startSketchOn('${plane}')profile001 = startProfileAt([0.91, -1.22], sketch001)`
await u.openDebugPanel()

View File

@ -1,6 +1,9 @@
import { test, expect } from './zoo-test'
import { getUtils, executorInputPath } from './test-utils'
import {
orRunWhenFullSuiteEnabled,
getUtils,
executorInputPath,
} from './test-utils'
import { join } from 'path'
import { bracket } from 'lib/exampleKcl'
import { TEST_CODE_LONG_WITH_ERROR_OUT_OF_VIEW } from './storageStates'
@ -19,7 +22,7 @@ test.describe('Code pane and errors', { tag: ['@skipWin'] }, () => {
localStorage.setItem(
'persistCode',
`// Extruded Triangle
sketch001 = startSketchOn('XZ')
sketch001 = startSketchOn(XZ)
|> startProfileAt([0, 0], %)
|> line(end = [10, 0])
|> line(end = [-5, 10])
@ -46,11 +49,12 @@ test.describe('Code pane and errors', { tag: ['@skipWin'] }, () => {
await expect(codePaneButtonHolder).toContainText('notification')
})
test.skip('Opening and closing the code pane will consistently show error diagnostics', async ({
test('Opening and closing the code pane will consistently show error diagnostics', async ({
page,
homePage,
editor,
}) => {
test.fixme(orRunWhenFullSuiteEnabled())
const u = await getUtils(page)
// Load the app with the working starter code
@ -119,45 +123,47 @@ test.describe('Code pane and errors', { tag: ['@skipWin'] }, () => {
await expect(page.locator('.cm-tooltip').first()).toBeVisible()
})
test.fixme(
'When error is not in view you can click the badge to scroll to it',
async ({ page, homePage, context }) => {
// Load the app with the working starter code
await context.addInitScript((code) => {
localStorage.setItem('persistCode', code)
}, TEST_CODE_LONG_WITH_ERROR_OUT_OF_VIEW)
test('When error is not in view you can click the badge to scroll to it', async ({
page,
homePage,
context,
}) => {
test.fixme(orRunWhenFullSuiteEnabled())
// Load the app with the working starter code
await context.addInitScript((code) => {
localStorage.setItem('persistCode', code)
}, TEST_CODE_LONG_WITH_ERROR_OUT_OF_VIEW)
await page.setBodyDimensions({ width: 1200, height: 500 })
await homePage.goToModelingScene()
await page.setBodyDimensions({ width: 1200, height: 500 })
await homePage.goToModelingScene()
await page.waitForTimeout(1000)
await page.waitForTimeout(1000)
// Ensure badge is present
const codePaneButtonHolder = page.locator('#code-button-holder')
await expect(codePaneButtonHolder).toContainText('notification')
// Ensure badge is present
const codePaneButtonHolder = page.locator('#code-button-holder')
await expect(codePaneButtonHolder).toContainText('notification')
// Ensure we have no errors in the gutter, since error out of view.
await expect(page.locator('.cm-lint-marker-error')).not.toBeVisible()
// Ensure we have no errors in the gutter, since error out of view.
await expect(page.locator('.cm-lint-marker-error')).not.toBeVisible()
// Click the badge.
const badge = page.locator('#code-badge')
await expect(badge).toBeVisible()
await badge.click()
// Click the badge.
const badge = page.locator('#code-badge')
await expect(badge).toBeVisible()
await badge.click()
// Ensure we have an error diagnostic.
await expect(page.locator('.cm-lint-marker-error').first()).toBeVisible()
// Ensure we have an error diagnostic.
await expect(page.locator('.cm-lint-marker-error').first()).toBeVisible()
// Hover over the error to see the error message
await page.hover('.cm-lint-marker-error')
await expect(
page
.getByText(
'Modeling command failed: [ApiError { error_code: InternalEngine, message: "Solid3D revolve failed: sketch profile must lie entirely on one side of the revolution axis" }]'
)
.first()
).toBeVisible()
}
)
// Hover over the error to see the error message
await page.hover('.cm-lint-marker-error')
await expect(
page
.getByText(
'Modeling command failed: [ApiError { error_code: InternalEngine, message: "Solid3D revolve failed: sketch profile must lie entirely on one side of the revolution axis" }]'
)
.first()
).toBeVisible()
})
test('When error is not in view WITH LINTS you can click the badge to scroll to it', async ({
context,
@ -244,11 +250,11 @@ test(
])
await Promise.all([
fsp.copyFile(
executorInputPath('router-template-slate.kcl'),
executorInputPath('cylinder-inches.kcl'),
join(routerTemplateDir, 'main.kcl')
),
fsp.copyFile(
executorInputPath('focusrite_scarlett_mounting_braket.kcl'),
executorInputPath('e2e-can-sketch-on-chamfer.kcl'),
join(bracketDir, 'main.kcl')
),
])

View File

@ -1,6 +1,10 @@
import { test, expect } from './zoo-test'
import * as fsp from 'fs/promises'
import { executorInputPath, getUtils } from './test-utils'
import {
executorInputPath,
getUtils,
orRunWhenFullSuiteEnabled,
} from './test-utils'
import { KCL_DEFAULT_LENGTH } from 'lib/constants'
import path, { join } from 'path'
@ -12,7 +16,7 @@ test.describe('Command bar tests', { tag: ['@skipWin'] }, () => {
await page.addInitScript(async () => {
localStorage.setItem(
'persistCode',
`sketch001 = startSketchOn('XY')
`sketch001 = startSketchOn(XY)
|> startProfileAt([-10, -10], %)
|> line(end = [20, 0])
|> line(end = [0, 20])
@ -47,11 +51,12 @@ test.describe('Command bar tests', { tag: ['@skipWin'] }, () => {
})
// TODO: fix this test after the electron migration
test.fixme('Fillet from command bar', async ({ page, homePage }) => {
test('Fillet from command bar', async ({ page, homePage }) => {
test.fixme(orRunWhenFullSuiteEnabled())
await page.addInitScript(async () => {
localStorage.setItem(
'persistCode',
`sketch001 = startSketchOn('XY')
`sketch001 = startSketchOn(XY)
|> startProfileAt([-5, -5], %)
|> line(end = [0, 10])
|> line(end = [10, 0])
@ -234,7 +239,7 @@ test.describe('Command bar tests', { tag: ['@skipWin'] }, () => {
localStorage.setItem(
'persistCode',
`distance = sqrt(20)
sketch001 = startSketchOn('XZ')
sketch001 = startSketchOn(XZ)
|> startProfileAt([-6.95, 10.98], %)
|> line(end = [25.1, 0.41])
|> line(end = [0.73, -20.93])
@ -488,7 +493,7 @@ test.describe('Command bar tests', { tag: ['@skipWin'] }, () => {
})
})
test(`Can add a named parameter or constant`, async ({
test(`Can add and edit a named parameter or constant`, async ({
page,
homePage,
context,
@ -510,7 +515,7 @@ c = 3 + a`
// but you do because all modeling commands have that requirement
await scene.settled(cmdBar)
await test.step(`Go through the command palette flow`, async () => {
await test.step(`Create a parameter via command bar`, async () => {
await cmdBar.cmdBarOpenBtn.click()
await cmdBar.chooseCommand('create parameter')
await cmdBar.expectState({
@ -535,5 +540,57 @@ c = 3 + a`
await editor.expectEditor.toContain(
`a = 5b = a * amyParameter001 = b - 5c = 3 + a`
)
const newValue = `2 * b + a`
await test.step(`Edit the parameter via command bar`, async () => {
await cmdBar.cmdBarOpenBtn.click()
await cmdBar.chooseCommand('edit parameter')
await cmdBar.expectState({
stage: 'arguments',
commandName: 'Edit parameter',
currentArgKey: 'Name',
currentArgValue: '',
headerArguments: {
Name: '',
Value: '',
},
highlightedHeaderArg: 'Name',
})
await cmdBar
.selectOption({
name: 'myParameter001',
})
.click()
await cmdBar.expectState({
stage: 'arguments',
commandName: 'Edit parameter',
currentArgKey: 'value',
currentArgValue: 'b - 5',
headerArguments: {
Name: 'myParameter001',
Value: '',
},
highlightedHeaderArg: 'value',
})
await cmdBar.argumentInput.locator('[contenteditable]').fill(newValue)
await cmdBar.progressCmdBar()
await cmdBar.expectState({
stage: 'review',
commandName: 'Edit parameter',
headerArguments: {
Name: 'myParameter001',
// KCL inputs show the *computed* value, not the input value, in the command palette header
Value: '55',
},
})
await cmdBar.progressCmdBar()
await cmdBar.expectState({
stage: 'commandBarClosed',
})
})
await editor.expectEditor.toContain(
`a = 5b = a * amyParameter001 = ${newValue}c = 3 + a`
)
})
})

View File

@ -20,7 +20,7 @@ test.describe('Copilot ghost text', () => {
await page.keyboard.press('Enter')
await expect(page.locator('.cm-ghostText').first()).toBeVisible()
await expect(page.locator('.cm-content')).toHaveText(
`fn cube = (pos, scale) => { sg = startSketchOn('XY') |> startProfileAt(pos, %) |> line(end = [0, scale], %) |> line(end = [scale, 0]) |> line(end = [0, -scale]) return sg}part001 = cube([0,0], 20) |> close() |> extrude(length = 20)`
`fn cube = (pos, scale) => { sg = startSketchOn(XY) |> startProfileAt(pos, %) |> line(end = [0, scale], %) |> line(end = [scale, 0]) |> line(end = [0, -scale]) return sg}part001 = cube([0,0], 20) |> close() |> extrude(length = 20)`
)
await expect(page.locator('.cm-ghostText').first()).toHaveText(
`fn cube = (pos, scale) => {`
@ -29,7 +29,7 @@ test.describe('Copilot ghost text', () => {
// We should be able to hit Tab to accept the completion.
await page.keyboard.press('Tab')
await expect(page.locator('.cm-content')).toHaveText(
`fn cube = (pos, scale) => { sg = startSketchOn('XY') |> startProfileAt(pos, %) |> line(end = [0, scale], %) |> line(end = [scale, 0]) |> line(end = [0, -scale]) return sg}part001 = cube([0,0], 20) |> close() |> extrude(length = 20)`
`fn cube = (pos, scale) => { sg = startSketchOn(XY) |> startProfileAt(pos, %) |> line(end = [0, scale], %) |> line(end = [scale, 0]) |> line(end = [0, -scale]) return sg}part001 = cube([0,0], 20) |> close() |> extrude(length = 20)`
)
// Hit enter a few times.
@ -37,7 +37,7 @@ test.describe('Copilot ghost text', () => {
await page.keyboard.press('Enter')
await expect(page.locator('.cm-content')).toHaveText(
`fn cube = (pos, scale) => { sg = startSketchOn('XY') |> startProfileAt(pos, %) |> line(end = [0, scale], %) |> line(end = [scale, 0]) |> line(end = [0, -scale]) return sg}part001 = cube([0,0], 20) |> close() |> extrude(length = 20) `
`fn cube = (pos, scale) => { sg = startSketchOn(XY) |> startProfileAt(pos, %) |> line(end = [0, scale], %) |> line(end = [scale, 0]) |> line(end = [0, -scale]) return sg}part001 = cube([0,0], 20) |> close() |> extrude(length = 20) `
)
await expect(page.locator('.cm-ghostText')).not.toBeVisible()
@ -80,7 +80,7 @@ test.describe('Copilot ghost text', () => {
await page.keyboard.press('Enter')
await expect(page.locator('.cm-content')).toHaveText(
`fn cube = (pos, scale) => { sg = startSketchOn('XY') |> startProfileAt(pos, %) |> line(end = [0, scale], %) |> line(end = [scale, 0]) |> line(end = [0, -scale]) return sg}part001 = cube([0,0], 20) |> close() |> extrude(length = 20)`
`fn cube = (pos, scale) => { sg = startSketchOn(XY) |> startProfileAt(pos, %) |> line(end = [0, scale], %) |> line(end = [scale, 0]) |> line(end = [0, -scale]) return sg}part001 = cube([0,0], 20) |> close() |> extrude(length = 20)`
)
await expect(page.locator('.cm-ghostText').first()).toHaveText(
`fn cube = (pos, scale) => {`
@ -89,7 +89,7 @@ test.describe('Copilot ghost text', () => {
// We should be able to hit Tab to accept the completion.
await page.keyboard.press('Tab')
await expect(page.locator('.cm-content')).toContainText(
`fn cube = (pos, scale) => { sg = startSketchOn('XY') |> startProfileAt(pos, %) |> line(end = [0, scale], %) |> line(end = [scale, 0]) |> line(end = [0, -scale]) return sg}part001 = cube([0,0], 20) |> close() |> extrude(length = 20)`
`fn cube = (pos, scale) => { sg = startSketchOn(XY) |> startProfileAt(pos, %) |> line(end = [0, scale], %) |> line(end = [scale, 0]) |> line(end = [0, -scale]) return sg}part001 = cube([0,0], 20) |> close() |> extrude(length = 20)`
)
})
@ -123,7 +123,7 @@ test.describe('Copilot ghost text', () => {
await page.waitForTimeout(500)
await expect(page.locator('.cm-ghostText').first()).not.toBeVisible()
await expect(page.locator('.cm-content')).toHaveText(
`sketch001 = startSketchOn('XZ')`
`sketch001 = startSketchOn(XZ)`
)
// Escape to exit the tool.
@ -139,7 +139,7 @@ test.describe('Copilot ghost text', () => {
await page.waitForTimeout(500)
await expect(page.locator('.cm-ghostText').first()).not.toBeVisible()
await expect(page.locator('.cm-content')).toHaveText(
`sketch001 = startSketchOn('XZ')`
`sketch001 = startSketchOn(XZ)`
)
// Escape again to exit sketch mode.
@ -156,7 +156,7 @@ test.describe('Copilot ghost text', () => {
await page.keyboard.press('Enter')
await expect(page.locator('.cm-content')).toHaveText(
`sketch001 = startSketchOn('XZ')fn cube = (pos, scale) => { sg = startSketchOn('XY') |> startProfileAt(pos, %) |> line(end = [0, scale], %) |> line(end = [scale, 0]) |> line(end = [0, -scale]) return sg}part001 = cube([0,0], 20) |> close() |> extrude(length = 20)`
`sketch001 = startSketchOn(XZ)fn cube = (pos, scale) => { sg = startSketchOn(XY) |> startProfileAt(pos, %) |> line(end = [0, scale], %) |> line(end = [scale, 0]) |> line(end = [0, -scale]) return sg}part001 = cube([0,0], 20) |> close() |> extrude(length = 20)`
)
await expect(page.locator('.cm-ghostText').first()).toHaveText(
`fn cube = (pos, scale) => {`
@ -165,7 +165,7 @@ test.describe('Copilot ghost text', () => {
// We should be able to hit Tab to accept the completion.
await page.keyboard.press('Tab')
await expect(page.locator('.cm-content')).toHaveText(
`sketch001 = startSketchOn('XZ')fn cube = (pos, scale) => { sg = startSketchOn('XY') |> startProfileAt(pos, %) |> line(end = [0, scale], %) |> line(end = [scale, 0]) |> line(end = [0, -scale]) return sg}part001 = cube([0,0], 20) |> close() |> extrude(length = 20)`
`sketch001 = startSketchOn(XZ)fn cube = (pos, scale) => { sg = startSketchOn(XY) |> startProfileAt(pos, %) |> line(end = [0, scale], %) |> line(end = [scale, 0]) |> line(end = [0, -scale]) return sg}part001 = cube([0,0], 20) |> close() |> extrude(length = 20)`
)
// Hit enter a few times.
@ -173,7 +173,7 @@ test.describe('Copilot ghost text', () => {
await page.keyboard.press('Enter')
await expect(page.locator('.cm-content')).toHaveText(
`sketch001 = startSketchOn('XZ')fn cube = (pos, scale) => { sg = startSketchOn('XY') |> startProfileAt(pos, %) |> line(end = [0, scale], %) |> line(end = [scale, 0]) |> line(end = [0, -scale]) return sg}part001 = cube([0,0], 20) |> close() |> extrude(length = 20) `
`sketch001 = startSketchOn(XZ)fn cube = (pos, scale) => { sg = startSketchOn(XY) |> startProfileAt(pos, %) |> line(end = [0, scale], %) |> line(end = [scale, 0]) |> line(end = [0, -scale]) return sg}part001 = cube([0,0], 20) |> close() |> extrude(length = 20) `
)
await expect(page.locator('.cm-ghostText')).not.toBeVisible()
@ -194,7 +194,7 @@ test.describe('Copilot ghost text', () => {
await page.keyboard.press('Enter')
await expect(page.locator('.cm-ghostText').first()).toBeVisible()
await expect(page.locator('.cm-content')).toHaveText(
`fn cube = (pos, scale) => { sg = startSketchOn('XY') |> startProfileAt(pos, %) |> line(end = [0, scale], %) |> line(end = [scale, 0]) |> line(end = [0, -scale]) return sg}part001 = cube([0,0], 20) |> close() |> extrude(length = 20)`
`fn cube = (pos, scale) => { sg = startSketchOn(XY) |> startProfileAt(pos, %) |> line(end = [0, scale], %) |> line(end = [scale, 0]) |> line(end = [0, -scale]) return sg}part001 = cube([0,0], 20) |> close() |> extrude(length = 20)`
)
await expect(page.locator('.cm-ghostText').first()).toHaveText(
`fn cube = (pos, scale) => {`
@ -225,7 +225,7 @@ test.describe('Copilot ghost text', () => {
await page.keyboard.press('Enter')
await expect(page.locator('.cm-ghostText').first()).toBeVisible()
await expect(page.locator('.cm-content')).toHaveText(
`fn cube = (pos, scale) => { sg = startSketchOn('XY') |> startProfileAt(pos, %) |> line(end = [0, scale], %) |> line(end = [scale, 0]) |> line(end = [0, -scale]) return sg}part001 = cube([0,0], 20) |> close() |> extrude(length = 20)`
`fn cube = (pos, scale) => { sg = startSketchOn(XY) |> startProfileAt(pos, %) |> line(end = [0, scale], %) |> line(end = [scale, 0]) |> line(end = [0, -scale]) return sg}part001 = cube([0,0], 20) |> close() |> extrude(length = 20)`
)
await expect(page.locator('.cm-ghostText').first()).toHaveText(
`fn cube = (pos, scale) => {`
@ -256,7 +256,7 @@ test.describe('Copilot ghost text', () => {
await page.keyboard.press('Enter')
await expect(page.locator('.cm-ghostText').first()).toBeVisible()
await expect(page.locator('.cm-content')).toHaveText(
`fn cube = (pos, scale) => { sg = startSketchOn('XY') |> startProfileAt(pos, %) |> line(end = [0, scale], %) |> line(end = [scale, 0]) |> line(end = [0, -scale]) return sg}part001 = cube([0,0], 20) |> close() |> extrude(length = 20)`
`fn cube = (pos, scale) => { sg = startSketchOn(XY) |> startProfileAt(pos, %) |> line(end = [0, scale], %) |> line(end = [scale, 0]) |> line(end = [0, -scale]) return sg}part001 = cube([0,0], 20) |> close() |> extrude(length = 20)`
)
await expect(page.locator('.cm-ghostText').first()).toHaveText(
`fn cube = (pos, scale) => {`
@ -287,7 +287,7 @@ test.describe('Copilot ghost text', () => {
await page.keyboard.press('Enter')
await expect(page.locator('.cm-ghostText').first()).toBeVisible()
await expect(page.locator('.cm-content')).toHaveText(
`fn cube = (pos, scale) => { sg = startSketchOn('XY') |> startProfileAt(pos, %) |> line(end = [0, scale], %) |> line(end = [scale, 0]) |> line(end = [0, -scale]) return sg}part001 = cube([0,0], 20) |> close() |> extrude(length = 20)`
`fn cube = (pos, scale) => { sg = startSketchOn(XY) |> startProfileAt(pos, %) |> line(end = [0, scale], %) |> line(end = [scale, 0]) |> line(end = [0, -scale]) return sg}part001 = cube([0,0], 20) |> close() |> extrude(length = 20)`
)
await expect(page.locator('.cm-ghostText').first()).toHaveText(
`fn cube = (pos, scale) => {`
@ -315,7 +315,7 @@ test.describe('Copilot ghost text', () => {
await page.keyboard.press('Enter')
await expect(page.locator('.cm-ghostText').first()).toBeVisible()
await expect(page.locator('.cm-content')).toHaveText(
`fn cube = (pos, scale) => { sg = startSketchOn('XY') |> startProfileAt(pos, %) |> line(end = [0, scale], %) |> line(end = [scale, 0]) |> line(end = [0, -scale]) return sg}part001 = cube([0,0], 20) |> close() |> extrude(length = 20)`
`fn cube = (pos, scale) => { sg = startSketchOn(XY) |> startProfileAt(pos, %) |> line(end = [0, scale], %) |> line(end = [scale, 0]) |> line(end = [0, -scale]) return sg}part001 = cube([0,0], 20) |> close() |> extrude(length = 20)`
)
await expect(page.locator('.cm-ghostText').first()).toHaveText(
`fn cube = (pos, scale) => {`
@ -326,7 +326,7 @@ test.describe('Copilot ghost text', () => {
await expect(page.locator('.cm-ghostText').first()).toBeVisible()
await expect(page.locator('.cm-content')).toHaveText(
`fn cube = (pos, scale) => { sg = startSketchOn('XY') |> startProfileAt(pos, %) |> line(end = [0, scale], %) |> line(end = [scale, 0]) |> line(end = [0, -scale]) return sg}part001 = cube([0,0], 20) |> close() |> extrude(length = 20)`
`fn cube = (pos, scale) => { sg = startSketchOn(XY) |> startProfileAt(pos, %) |> line(end = [0, scale], %) |> line(end = [scale, 0]) |> line(end = [0, -scale]) return sg}part001 = cube([0,0], 20) |> close() |> extrude(length = 20)`
)
})
@ -348,7 +348,7 @@ test.describe('Copilot ghost text', () => {
await page.keyboard.press('Enter')
await expect(page.locator('.cm-ghostText').first()).toBeVisible()
await expect(page.locator('.cm-content')).toHaveText(
`fn cube = (pos, scale) => { sg = startSketchOn('XY') |> startProfileAt(pos, %) |> line(end = [0, scale], %) |> line(end = [scale, 0]) |> line(end = [0, -scale]) return sg}part001 = cube([0,0], 20) |> close() |> extrude(length = 20)`
`fn cube = (pos, scale) => { sg = startSketchOn(XY) |> startProfileAt(pos, %) |> line(end = [0, scale], %) |> line(end = [scale, 0]) |> line(end = [0, -scale]) return sg}part001 = cube([0,0], 20) |> close() |> extrude(length = 20)`
)
await expect(page.locator('.cm-ghostText').first()).toHaveText(
`fn cube = (pos, scale) => {`
@ -409,7 +409,7 @@ test.describe('Copilot ghost text', () => {
await page.keyboard.press('Enter')
await expect(page.locator('.cm-ghostText').first()).toBeVisible()
await expect(page.locator('.cm-content')).toHaveText(
`{thing: "blah"}fn cube = (pos, scale) => { sg = startSketchOn('XY') |> startProfileAt(pos, %) |> line(end = [0, scale], %) |> line(end = [scale, 0]) |> line(end = [0, -scale]) return sg}part001 = cube([0,0], 20) |> close() |> extrude(length = 20)`
`{thing: "blah"}fn cube = (pos, scale) => { sg = startSketchOn(XY) |> startProfileAt(pos, %) |> line(end = [0, scale], %) |> line(end = [scale, 0]) |> line(end = [0, -scale]) return sg}part001 = cube([0,0], 20) |> close() |> extrude(length = 20)`
)
await expect(page.locator('.cm-ghostText').first()).toHaveText(
`fn cube = (pos, scale) => {`
@ -450,7 +450,7 @@ test.describe('Copilot ghost text', () => {
await page.keyboard.press('Enter')
await expect(page.locator('.cm-ghostText').first()).toBeVisible()
await expect(page.locator('.cm-content')).toHaveText(
`fn cube = (pos, scale) => { sg = startSketchOn('XY') |> startProfileAt(pos, %) |> line(end = [0, scale], %) |> line(end = [scale, 0]) |> line(end = [0, -scale]) return sg}part001 = cube([0,0], 20) |> close() |> extrude(length = 20)`
`fn cube = (pos, scale) => { sg = startSketchOn(XY) |> startProfileAt(pos, %) |> line(end = [0, scale], %) |> line(end = [scale, 0]) |> line(end = [0, -scale]) return sg}part001 = cube([0,0], 20) |> close() |> extrude(length = 20)`
)
await expect(page.locator('.cm-ghostText').first()).toHaveText(
`fn cube = (pos, scale) => {`
@ -483,7 +483,7 @@ test.describe('Copilot ghost text', () => {
await page.keyboard.press('Enter')
await expect(page.locator('.cm-ghostText').first()).toBeVisible()
await expect(page.locator('.cm-content')).toHaveText(
`fn cube = (pos, scale) => { sg = startSketchOn('XY') |> startProfileAt(pos, %) |> line(end = [0, scale], %) |> line(end = [scale, 0]) |> line(end = [0, -scale]) return sg}part001 = cube([0,0], 20) |> close() |> extrude(length = 20)`
`fn cube = (pos, scale) => { sg = startSketchOn(XY) |> startProfileAt(pos, %) |> line(end = [0, scale], %) |> line(end = [scale, 0]) |> line(end = [0, -scale]) return sg}part001 = cube([0,0], 20) |> close() |> extrude(length = 20)`
)
await expect(page.locator('.cm-ghostText').first()).toHaveText(
`fn cube = (pos, scale) => {`
@ -514,7 +514,7 @@ test.describe('Copilot ghost text', () => {
await page.keyboard.press('Enter')
await expect(page.locator('.cm-ghostText').first()).toBeVisible()
await expect(page.locator('.cm-content')).toHaveText(
`fn cube = (pos, scale) => { sg = startSketchOn('XY') |> startProfileAt(pos, %) |> line(end = [0, scale], %) |> line(end = [scale, 0]) |> line(end = [0, -scale]) return sg}part001 = cube([0,0], 20) |> close() |> extrude(length = 20)`
`fn cube = (pos, scale) => { sg = startSketchOn(XY) |> startProfileAt(pos, %) |> line(end = [0, scale], %) |> line(end = [scale, 0]) |> line(end = [0, -scale]) return sg}part001 = cube([0,0], 20) |> close() |> extrude(length = 20)`
)
await expect(page.locator('.cm-ghostText').first()).toHaveText(
`fn cube = (pos, scale) => {`

View File

@ -18,7 +18,7 @@ test.describe('Debug pane', () => {
context,
homePage,
}) => {
const code = `sketch001 = startSketchOn('XZ')
const code = `sketch001 = startSketchOn(XZ)
|> startProfileAt([0, 0], %)
|> line(end = [1, 1])
`

View File

@ -20,11 +20,11 @@ test(
await Promise.all([fsp.mkdir(bracketDir, { recursive: true })])
await Promise.all([
fsp.copyFile(
executorInputPath('router-template-slate.kcl'),
executorInputPath('cylinder-inches.kcl'),
path.join(bracketDir, 'other.kcl')
),
fsp.copyFile(
executorInputPath('focusrite_scarlett_mounting_braket.kcl'),
executorInputPath('e2e-can-sketch-on-chamfer.kcl'),
path.join(bracketDir, 'main.kcl')
),
])
@ -107,7 +107,7 @@ test(
},
{ timeout: 15_000 }
)
.toBeGreaterThan(300_000)
.toBeGreaterThan(30_000)
})
})
@ -187,7 +187,7 @@ test(
},
{ timeout: 15_000 }
)
.toBeGreaterThan(70_000)
.toBeGreaterThan(50_000)
})
})
}

View File

@ -2,10 +2,10 @@ import { test, expect } from './zoo-test'
import fsp from 'fs/promises'
import { uuidv4 } from 'lib/utils'
import {
darkModeBgColor,
darkModePlaneColorXZ,
executorInputPath,
getUtils,
orRunWhenFullSuiteEnabled,
TEST_COLORS,
} from './test-utils'
import { join } from 'path'
@ -21,7 +21,7 @@ test.describe('Editor tests', { tag: ['@skipWin'] }, () => {
await expect(page.locator('.cm-lint-marker-error')).not.toBeVisible()
await u.codeLocator.click()
await page.keyboard.type(`sketch001 = startSketchOn('XY')
await page.keyboard.type(`sketch001 = startSketchOn(XY)
|> startProfileAt([-10, -10], %)
|> line(end = [20, 0])
|> line(end = [0, 20])
@ -32,26 +32,30 @@ test.describe('Editor tests', { tag: ['@skipWin'] }, () => {
await page.keyboard.press('/')
await page.keyboard.up('ControlOrMeta')
await expect(page.locator('.cm-content'))
.toHaveText(`sketch001 = startSketchOn('XY')
await expect(page.locator('.cm-content')).toHaveText(
`@settings(defaultLengthUnit = in)
sketch001 = startSketchOn('XY')
|> startProfileAt([-10, -10], %)
|> line(end = [20, 0])
|> line(end = [0, 20])
|> line(end = [-20, 0])
// |> close()`)
// |> close()`.replaceAll('\n', '')
)
// uncomment the code
await page.keyboard.down('ControlOrMeta')
await page.keyboard.press('/')
await page.keyboard.up('ControlOrMeta')
await expect(page.locator('.cm-content'))
.toHaveText(`sketch001 = startSketchOn('XY')
await expect(page.locator('.cm-content')).toHaveText(
`@settings(defaultLengthUnit = in)
sketch001 = startSketchOn('XY')
|> startProfileAt([-10, -10], %)
|> line(end = [20, 0])
|> line(end = [0, 20])
|> line(end = [-20, 0])
|> close()`)
|> close()`.replaceAll('\n', '')
)
})
test('ensure we use the cache, and do not re-execute', async ({
@ -65,7 +69,7 @@ test.describe('Editor tests', { tag: ['@skipWin'] }, () => {
await u.waitForPageLoad()
await u.codeLocator.click()
await page.keyboard.type(`sketch001 = startSketchOn('XY')
await page.keyboard.type(`sketch001 = startSketchOn(XY)
|> startProfileAt([-10, -10], %)
|> line(end = [20, 0])
|> line(end = [0, 20])
@ -114,7 +118,7 @@ test.describe('Editor tests', { tag: ['@skipWin'] }, () => {
await u.waitForPageLoad()
await u.codeLocator.click()
await page.keyboard.type(`sketch001 = startSketchOn('XY')
await page.keyboard.type(`sketch001 = startSketchOn(XY)
|> startProfileAt([-10, -10], %)
|> line(end = [20, 0])
|> line(end = [0, 20])
@ -169,7 +173,7 @@ test.describe('Editor tests', { tag: ['@skipWin'] }, () => {
await expect(page.locator('.cm-lint-marker-error')).not.toBeVisible()
await u.codeLocator.click()
await page.keyboard.type(`sketch001 = startSketchOn('XY')
await page.keyboard.type(`sketch001 = startSketchOn(XY)
|> startProfileAt([-10, -10], %)
|> line(end = [20, 0])
|> line(end = [0, 20])
@ -178,13 +182,15 @@ test.describe('Editor tests', { tag: ['@skipWin'] }, () => {
await page.locator('#code-pane button:first-child').click()
await page.locator('button:has-text("Format code")').click()
await expect(page.locator('.cm-content'))
.toHaveText(`sketch001 = startSketchOn('XY')
await expect(page.locator('.cm-content')).toHaveText(
`@settings(defaultLengthUnit = in)
sketch001 = startSketchOn('XY')
|> startProfileAt([-10, -10], %)
|> line(end = [20, 0])
|> line(end = [0, 20])
|> line(end = [-20, 0])
|> close()`)
|> close()`.replaceAll('\n', '')
)
})
test('if you click the format button it formats your code and executes so lints are still there', async ({
@ -200,7 +206,7 @@ test.describe('Editor tests', { tag: ['@skipWin'] }, () => {
await expect(page.locator('.cm-lint-marker-error')).not.toBeVisible()
await u.codeLocator.click()
await page.keyboard.type(`sketch_001 = startSketchOn('XY')
await page.keyboard.type(`sketch_001 = startSketchOn(XY)
|> startProfileAt([-10, -10], %)
|> line(end = [20, 0])
|> line(end = [0, 20])
@ -227,13 +233,15 @@ test.describe('Editor tests', { tag: ['@skipWin'] }, () => {
await u.expectCmdLog('[data-message-type="execution-done"]')
await u.closeDebugPanel()
await expect(page.locator('.cm-content'))
.toHaveText(`sketch_001 = startSketchOn('XY')
await expect(page.locator('.cm-content')).toHaveText(
`@settings(defaultLengthUnit = in)
sketch_001 = startSketchOn('XY')
|> startProfileAt([-10, -10], %)
|> line(end = [20, 0])
|> line(end = [0, 20])
|> line(end = [-20, 0])
|> close()`)
|> close()`.replaceAll('\n', '')
)
// error in guter
await expect(page.locator('.cm-lint-marker-info').first()).toBeVisible()
@ -246,7 +254,7 @@ test.describe('Editor tests', { tag: ['@skipWin'] }, () => {
})
test('fold gutters work', async ({ page, homePage }) => {
const fullCode = `sketch001 = startSketchOn('XY')
const fullCode = `sketch001 = startSketchOn(XY)
|> startProfileAt([-10, -10], %)
|> line(end = [20, 0])
|> line(end = [0, 20])
@ -255,7 +263,7 @@ test.describe('Editor tests', { tag: ['@skipWin'] }, () => {
await page.addInitScript(async () => {
localStorage.setItem(
'persistCode',
`sketch001 = startSketchOn('XY')
`sketch001 = startSketchOn(XY)
|> startProfileAt([-10, -10], %)
|> line(end = [20, 0])
|> line(end = [0, 20])
@ -293,7 +301,7 @@ test.describe('Editor tests', { tag: ['@skipWin'] }, () => {
await foldGutterFoldLine.click()
await expect(page.locator('.cm-content')).toHaveText(
`sketch001 = startSketchOn('XY')… `
`sketch001 = startSketchOn(XY)… `
)
await expect(page.locator('.cm-content')).not.toHaveText(fullCode)
await expect(foldGutterFoldLine).not.toBeVisible()
@ -324,7 +332,7 @@ test.describe('Editor tests', { tag: ['@skipWin'] }, () => {
await page.addInitScript(async () => {
localStorage.setItem(
'persistCode',
`sketch001 = startSketchOn('XY')
`sketch001 = startSketchOn(XY)
|> startProfileAt([-10, -10], %)
|> line(end = [20, 0])
|> line(end = [0, 20])
@ -371,7 +379,7 @@ test.describe('Editor tests', { tag: ['@skipWin'] }, () => {
await page.addInitScript(async () => {
localStorage.setItem(
'persistCode',
`sketch001 = startSketchOn('XY')
`sketch001 = startSketchOn(XY)
|> startProfileAt([-10, -10], %)
|> line(end = [20, 0])
|> line(end = [0, 20])
@ -398,7 +406,7 @@ test.describe('Editor tests', { tag: ['@skipWin'] }, () => {
await page.keyboard.press('Alt+Shift+KeyF')
await expect(page.locator('.cm-content'))
.toHaveText(`sketch001 = startSketchOn('XY')
.toHaveText(`sketch001 = startSketchOn(XY)
|> startProfileAt([-10, -10], %)
|> line(end = [20, 0])
|> line(end = [0, 20])
@ -414,7 +422,7 @@ test.describe('Editor tests', { tag: ['@skipWin'] }, () => {
await page.addInitScript(async () => {
localStorage.setItem(
'persistCode',
`sketch_001 = startSketchOn('XY')
`sketch_001 = startSketchOn(XY)
|> startProfileAt([-10, -10], %)
|> line(end = [20, 0])
|> line(end = [0, 20])
@ -451,7 +459,7 @@ test.describe('Editor tests', { tag: ['@skipWin'] }, () => {
await u.closeDebugPanel()
await expect(page.locator('.cm-content'))
.toHaveText(`sketch_001 = startSketchOn('XY')
.toHaveText(`sketch_001 = startSketchOn(XY)
|> startProfileAt([-10, -10], %)
|> line(end = [20, 0])
|> line(end = [0, 20])
@ -524,7 +532,7 @@ test.describe('Editor tests', { tag: ['@skipWin'] }, () => {
await page.addInitScript(async () => {
localStorage.setItem(
'persistCode',
`sketch001 = startSketchOn('XZ')
`sketch001 = startSketchOn(XZ)
|> startProfileAt([3.29, 7.86], %)
|> line(end = [2.48, 2.44])
|> line(end = [2.66, 1.17])
@ -635,20 +643,22 @@ test.describe('Editor tests', { tag: ['@skipWin'] }, () => {
await expect(page.locator('.cm-lint-marker-error')).not.toBeVisible()
})
test.fixme(
'error with 2 source ranges gets 2 diagnostics',
async ({ page, homePage }) => {
const u = await getUtils(page)
await page.addInitScript(async () => {
localStorage.setItem(
'persistCode',
`length = .750
test('error with 2 source ranges gets 2 diagnostics', async ({
page,
homePage,
}) => {
test.fixme(orRunWhenFullSuiteEnabled())
const u = await getUtils(page)
await page.addInitScript(async () => {
localStorage.setItem(
'persistCode',
`length = .750
width = 0.500
height = 0.500
dia = 4
fn squareHole = (l, w) => {
squareHoleSketch = startSketchOn('XY')
squareHoleSketch = startSketchOn(XY)
|> startProfileAt([-width / 2, -length / 2], %)
|> line(endAbsolute = [width / 2, -length / 2])
|> line(endAbsolute = [width / 2, length / 2])
@ -657,53 +667,52 @@ test.describe('Editor tests', { tag: ['@skipWin'] }, () => {
return squareHoleSketch
}
`
)
})
await page.setBodyDimensions({ width: 1000, height: 500 })
)
})
await page.setBodyDimensions({ width: 1000, height: 500 })
await homePage.goToModelingScene()
await u.waitForPageLoad()
await page.waitForTimeout(1000)
await homePage.goToModelingScene()
await u.waitForPageLoad()
await page.waitForTimeout(1000)
await u.openDebugPanel()
await u.expectCmdLog('[data-message-type="execution-done"]')
await u.closeDebugPanel()
await u.openDebugPanel()
await u.expectCmdLog('[data-message-type="execution-done"]')
await u.closeDebugPanel()
// check no error to begin with
await expect(page.locator('.cm-lint-marker-error')).not.toBeVisible()
// check no error to begin with
await expect(page.locator('.cm-lint-marker-error')).not.toBeVisible()
// Click on the bottom of the code editor to add a new line
await u.codeLocator.click()
await page.keyboard.press('ArrowDown')
await page.keyboard.press('ArrowDown')
await page.keyboard.press('ArrowDown')
await page.keyboard.press('ArrowDown')
await page.keyboard.press('ArrowDown')
await page.keyboard.press('ArrowDown')
await page.keyboard.press('ArrowDown')
await page.keyboard.press('ArrowDown')
await page.keyboard.press('ArrowDown')
await page.keyboard.press('ArrowDown')
await page.keyboard.press('ArrowDown')
await page.keyboard.press('ArrowDown')
await page.keyboard.press('ArrowDown')
await page.keyboard.press('Enter')
await page.keyboard.type(`extrusion = startSketchOn('XY')
// Click on the bottom of the code editor to add a new line
await u.codeLocator.click()
await page.keyboard.press('ArrowDown')
await page.keyboard.press('ArrowDown')
await page.keyboard.press('ArrowDown')
await page.keyboard.press('ArrowDown')
await page.keyboard.press('ArrowDown')
await page.keyboard.press('ArrowDown')
await page.keyboard.press('ArrowDown')
await page.keyboard.press('ArrowDown')
await page.keyboard.press('ArrowDown')
await page.keyboard.press('ArrowDown')
await page.keyboard.press('ArrowDown')
await page.keyboard.press('ArrowDown')
await page.keyboard.press('ArrowDown')
await page.keyboard.press('Enter')
await page.keyboard.type(`extrusion = startSketchOn(XY)
|> circle(center: [0, 0], radius: dia/2)
|> hole(squareHole(length, width, height), %)
|> extrude(length = height)`)
// error in gutter
await expect(page.locator('.cm-lint-marker-error').first()).toBeVisible()
await page.hover('.cm-lint-marker-error:first-child')
await expect(
page.getByText('Expected 2 arguments, got 3').first()
).toBeVisible()
// error in gutter
await expect(page.locator('.cm-lint-marker-error').first()).toBeVisible()
await page.hover('.cm-lint-marker-error:first-child')
await expect(
page.getByText('Expected 2 arguments, got 3').first()
).toBeVisible()
// Make sure there are two diagnostics
await expect(page.locator('.cm-lint-marker-error')).toHaveCount(2)
}
)
// Make sure there are two diagnostics
await expect(page.locator('.cm-lint-marker-error')).toHaveCount(2)
})
test('if your kcl gets an error from the engine it is inlined', async ({
context,
page,
@ -712,7 +721,7 @@ test.describe('Editor tests', { tag: ['@skipWin'] }, () => {
await context.addInitScript(async () => {
localStorage.setItem(
'persistCode',
`box = startSketchOn('XY')
`box = startSketchOn(XY)
|> startProfileAt([0, 0], %)
|> line(end = [0, 10])
|> line(end = [10, 0])
@ -771,7 +780,7 @@ test.describe('Editor tests', { tag: ['@skipWin'] }, () => {
}).toPass()
// this makes sure we can accept a completion with click
await page.getByText('startSketchOn').click()
await page.keyboard.type("'XZ'")
await page.keyboard.type('XZ')
await page.keyboard.press('Tab')
await page.keyboard.press('Enter')
await page.keyboard.type(' |> startProfi')
@ -814,10 +823,12 @@ test.describe('Editor tests', { tag: ['@skipWin'] }, () => {
// there shouldn't be any auto complete options for 'lin' in the comment
await expect(page.locator('.cm-completionLabel')).not.toBeVisible()
await expect(page.locator('.cm-content'))
.toHaveText(`sketch001 = startSketchOn('XZ')
await expect(page.locator('.cm-content')).toHaveText(
`@settings(defaultLengthUnit = in)
sketch001 = startSketchOn('XZ')
|> startProfileAt([3.14, 12], %)
|> xLine(%, length = 5) // lin`)
|> xLine(%, length = 5) // lin`.replaceAll('\n', '')
)
// expect there to be no KCL errors
await expect(page.locator('.cm-lint-marker-error')).toHaveCount(0)
@ -845,7 +856,7 @@ test.describe('Editor tests', { tag: ['@skipWin'] }, () => {
await page.keyboard.press('ArrowDown')
await page.keyboard.press('Tab')
await page.waitForTimeout(500)
await page.keyboard.type("'XZ'")
await page.keyboard.type('XZ')
await page.keyboard.press('Tab')
await page.keyboard.press('Enter')
await page.keyboard.type(' |> startProfi')
@ -887,10 +898,12 @@ test.describe('Editor tests', { tag: ['@skipWin'] }, () => {
// there shouldn't be any auto complete options for 'lin' in the comment
await expect(page.locator('.cm-completionLabel')).not.toBeVisible()
await expect(page.locator('.cm-content'))
.toHaveText(`sketch001 = startSketchOn('XZ')
await expect(page.locator('.cm-content')).toHaveText(
`@settings(defaultLengthUnit = in)
sketch001 = startSketchOn('XZ')
|> startProfileAt([3.14, 12], %)
|> xLine(%, length = 5) // lin`)
|> xLine(%, length = 5) // lin`.replaceAll('\n', '')
)
})
})
test('Can undo a click and point extrude with ctrl+z', async ({
@ -902,7 +915,7 @@ test.describe('Editor tests', { tag: ['@skipWin'] }, () => {
await context.addInitScript(async () => {
localStorage.setItem(
'persistCode',
`sketch001 = startSketchOn('XZ')
`sketch001 = startSketchOn(XZ)
|> startProfileAt([4.61, -14.01], %)
|> line(end = [12.73, -0.09])
|> tangentialArcTo([24.95, -5.38], %)
@ -954,7 +967,7 @@ test.describe('Editor tests', { tag: ['@skipWin'] }, () => {
// expect the code to have changed
await expect(page.locator('.cm-content')).toHaveText(
`sketch001 = startSketchOn('XZ') |> startProfileAt([4.61, -14.01], %) |> line(end = [12.73, -0.09]) |> tangentialArcTo([24.95, -5.38], %) |> close()extrude001 = extrude(sketch001, length = 5)`
`sketch001 = startSketchOn(XZ) |> startProfileAt([4.61, -14.01], %) |> line(end = [12.73, -0.09]) |> tangentialArcTo([24.95, -5.38], %) |> close()extrude001 = extrude(sketch001, length = 5)`
)
// Now hit undo
@ -964,7 +977,7 @@ test.describe('Editor tests', { tag: ['@skipWin'] }, () => {
await page.waitForTimeout(100)
await expect(page.locator('.cm-content'))
.toHaveText(`sketch001 = startSketchOn('XZ')
.toHaveText(`sketch001 = startSketchOn(XZ)
|> startProfileAt([4.61, -14.01], %)
|> line(end = [12.73, -0.09])
|> tangentialArcTo([24.95, -5.38], %)
@ -979,7 +992,7 @@ test.describe('Editor tests', { tag: ['@skipWin'] }, () => {
await page.addInitScript(async () => {
localStorage.setItem(
'persistCode',
`sketch001 = startSketchOn('XZ')
`sketch001 = startSketchOn(XZ)
|> startProfileAt([4.61, -10.01], %)
|> line(end = [12.73, -0.09])
|> tangentialArcTo([24.95, -0.38], %)
@ -1070,7 +1083,7 @@ test.describe('Editor tests', { tag: ['@skipWin'] }, () => {
// expect the code to have changed
await expect(page.locator('.cm-content'))
.toHaveText(`sketch001 = startSketchOn('XZ')
.toHaveText(`sketch001 = startSketchOn(XZ)
|> startProfileAt([2.71, -2.71], %)
|> line(end = [15.4, -2.78])
|> tangentialArcTo([27.6, -3.05], %)
@ -1084,7 +1097,7 @@ test.describe('Editor tests', { tag: ['@skipWin'] }, () => {
await page.keyboard.up('Control')
await expect(page.locator('.cm-content'))
.toHaveText(`sketch001 = startSketchOn('XZ')
.toHaveText(`sketch001 = startSketchOn(XZ)
|> startProfileAt([2.71, -2.71], %)
|> line(end = [15.4, -2.78])
|> tangentialArcTo([24.95, -0.38], %)
@ -1097,7 +1110,7 @@ test.describe('Editor tests', { tag: ['@skipWin'] }, () => {
await page.keyboard.up('Control')
await expect(page.locator('.cm-content'))
.toHaveText(`sketch001 = startSketchOn('XZ')
.toHaveText(`sketch001 = startSketchOn(XZ)
|> startProfileAt([2.71, -2.71], %)
|> line(end = [12.73, -0.09])
|> tangentialArcTo([24.95, -0.38], %)
@ -1112,7 +1125,7 @@ test.describe('Editor tests', { tag: ['@skipWin'] }, () => {
await page.waitForTimeout(100)
await expect(page.locator('.cm-content'))
.toHaveText(`sketch001 = startSketchOn('XZ')
.toHaveText(`sketch001 = startSketchOn(XZ)
|> startProfileAt([4.61, -10.01], %)
|> line(end = [12.73, -0.09])
|> tangentialArcTo([24.95, -0.38], %)
@ -1121,10 +1134,11 @@ test.describe('Editor tests', { tag: ['@skipWin'] }, () => {
}
)
test.fixme(
test(
`Can use the import stdlib function on a local OBJ file`,
{ tag: '@electron' },
async ({ page, context }, testInfo) => {
test.fixme(orRunWhenFullSuiteEnabled())
await context.folderSetupFn(async (dir) => {
const bracketDir = join(dir, 'cube')
await fsp.mkdir(bracketDir, { recursive: true })
@ -1161,7 +1175,8 @@ test.describe('Editor tests', { tag: ['@skipWin'] }, () => {
await u.waitForPageLoad()
await expect
.poll(
async () => locationToHavColor(notTheOrigin, darkModePlaneColorXZ),
async () =>
locationToHavColor(notTheOrigin, TEST_COLORS.DARK_MODE_PLANE_XZ),
{
timeout: 5000,
message: 'XZ plane color is visible',
@ -1182,16 +1197,23 @@ test.describe('Editor tests', { tag: ['@skipWin'] }, () => {
await test.step(`Verify that we see the imported geometry and no errors`, async () => {
await expect(errorIndicators).toHaveCount(0)
await expect
.poll(async () => locationToHavColor(origin, darkModePlaneColorXZ), {
timeout: 3000,
message: 'Plane color should not be visible',
})
.poll(
async () =>
locationToHavColor(origin, TEST_COLORS.DARK_MODE_PLANE_XZ),
{
timeout: 3000,
message: 'Plane color should not be visible',
}
)
.toBeGreaterThan(15)
await expect
.poll(async () => locationToHavColor(origin, darkModeBgColor), {
timeout: 3000,
message: 'Background color should not be visible',
})
.poll(
async () => locationToHavColor(origin, TEST_COLORS.DARK_MODE_BKGD),
{
timeout: 3000,
message: 'Background color should not be visible',
}
)
.toBeGreaterThan(15)
})
}

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