Andrey Antukh 779983d38e 📎 Standardize test scripts and add execution discipline docs
- Remove conditional build from test scripts (frontend, common)
- Remove test:jvm from common package.json (JVM tests via clojure directly)
- Remove test from backend package.json (JVM tests via clojure directly)
- Unify common/scripts/test-quiet.js with frontend's BUILD_STEPS pattern
- Add execution discipline section to mem:testing (no piping, tee to file)
- Add READ mem:testing FIRST directives to module testing docs

AI-assisted-by: deepseek-v4-flash
2026-07-16 14:57:05 +00:00

3.2 KiB

Common Testing and Verification

common/ is CLJC shared code. Tests should cover the relevant runtime(s): JVM for backend/common logic and JS for frontend/exporter behavior. For geometry, component, and file-model changes, JVM tests are common and fast, but JS/browser behavior can differ when WASM modifier math or CLJS-specific state is involved.

Unit tests

READ mem:testing FIRST — it defines the execution discipline (no piping, tee to file, preferred commands) that applies to all CLJS/JS and JVM test runs.

Common tests live under common/test/common_tests/ and use clojure.test. They are CLJC and run on both JVM and JS.

From common/:

  • Full JVM test run: clojure -M:dev:test
  • Full JS test run (always builds, suppressed output): pnpm run test:quiet
  • Full JS test run (always builds, build output visible): pnpm run test
  • Focus a JVM test namespace: clojure -M:dev:test --focus common-tests.logic.variants-switch-test
  • Focus a JVM test var: clojure -M:dev:test --focus common-tests.logic.variants-switch-test/test-basic-switch
  • Focus a JS test namespace: pnpm run test:quiet -- --focus common-tests.logic.comp-sync-test
  • Focus a JS test var: pnpm run test:quiet -- --focus common-tests.logic.comp-sync-test/test-sync-when-changing-attribute
  • Quiet logging during a JS run: append --log-level warn (or trace|debug|info|warn|error)
  • Build JS test target only (no run): pnpm run build:test
  • After build:test has been run, run the compiled runner directly: node target/tests/test.js [--focus ...] [--log-level ...].

New common JS test namespaces must be required/listed in common_tests/runner.cljc; new vars in existing namespaces need no runner change. Multiple JVM --focus flags compose as a union.

Test helpers

Helpers live under common/src/app/common/test_helpers/ and are usually aliased with short th* prefixes. Test namespaces using label->uuid helpers should start with (t/use-fixtures :each thi/test-fixture) so labels reset between tests.

Useful builders:

  • thf/sample-file creates a base file.
  • tho/add-simple-component creates a simple component.
  • thc/instantiate-component instantiates a component copy.
  • thv/add-variant-with-child creates a variant container with two child variants.
  • thv/add-variant-with-copy creates variants whose children are component instances.

add-variant-with-copy does not accept position params for children; use gsh/absolute-move after creation if positions matter.

Driving production paths

For shape mutations, prefer production-path helpers such as cls/generate-update-shapes plus thf/apply-changes. For component swaps with keep-touched behavior, use tho/swap-component-in-shape with {:keep-touched? true}.

thf/apply-changes validates by default and usually gives the most useful invariant failure. Pass :validate? false only for intentionally malformed intermediate state.

Geometry setup caution

For geometry-sensitive tests, read mem:common/geometry-invariants before positioning shapes. Use geometry-preserving helpers or production change helpers rather than direct single-field edits.

Debugging

Use mem:common/component-debugging-recipes for shape-tree dumps, undo/change inspection, and temporary live instrumentation recipes.