From 98393a13c4841a19adc2877b8d2cb435bcd9611f Mon Sep 17 00:00:00 2001 From: Miguel de Benito Delgado Date: Tue, 6 Oct 2026 12:32:05 +0200 Subject: [PATCH] :construction: WIP 24 Relocate all code, delete old benchmarks --- .clj-kondo/config.edn | 2 +- frontend/deps.edn | 8 +- frontend/package.json | 10 +- .../benches/render_wasm/browser/bridge.cljs | 0 .../benches/render_wasm/browser/pilot.html | 0 .../benches/render_wasm/builder.clj | 0 .../benches/render_wasm/builder.cljs | 0 .../benches/render_wasm/cases.cljs | 0 .../benches/render_wasm/codec.cljs | 0 .../benches/render_wasm/declarations.clj | 0 .../benches/render_wasm/declarations.cljs | 0 .../benches/render_wasm/failures.cljs | 0 .../benches/render_wasm/fingerprint.cljs | 0 .../benches/render_wasm/measurement.cljs | 0 .../benches/render_wasm/node/pilot.cljs | 10 +- .../benches/render_wasm/node/runner.cljs | 8 +- .../benches/render_wasm/random.cljs | 0 .../benches/render_wasm/report/analysis.cljs | 0 .../benches/render_wasm/report/compare.cljs | 0 .../benches/render_wasm/report/format.cljs | 0 .../benches/render_wasm/report/summarize.cljs | 0 .../benches/render_wasm/result.cljs | 0 .../benches/render_wasm/runtime/camera.cljs | 0 .../benches/render_wasm/runtime/protocol.cljs | 0 .../benches/render_wasm/scenes/masks.cljs | 0 .../benches/render_wasm/scenes/paths.cljs | 0 .../benches/render_wasm/scenes/plus.cljs | 0 .../benches/render_wasm/scenes/rects.cljs | 0 .../benches/render_wasm/snapshot.cljs | 0 frontend/shadow-cljs.edn | 27 ++- .../render_wasm}/boolean_test.cljs | 4 +- .../render_wasm}/builder_test.cljs | 4 +- .../render_wasm}/containers_test.cljs | 4 +- .../render_wasm}/contracts_test.cljs | 4 +- .../render_wasm}/fingerprint_test.cljs | 2 +- .../render_wasm}/geometry_scenes_test.cljs | 4 +- .../render_wasm}/lifecycle_test.cljs | 22 +- .../render_wasm}/protocol_test.cljs | 2 +- .../render_wasm}/report_test.cljs | 2 +- .../performance_tests/render_wasm/runner.cljs | 195 ++++++++++++++++++ .../render_wasm}/scene_snapshot_test.cljs | 2 +- .../render_wasm}/test_helpers.cljs | 2 +- 42 files changed, 266 insertions(+), 46 deletions(-) rename frontend/{test => performance}/benches/render_wasm/browser/bridge.cljs (100%) rename frontend/{test => performance}/benches/render_wasm/browser/pilot.html (100%) rename frontend/{test => performance}/benches/render_wasm/builder.clj (100%) rename frontend/{test => performance}/benches/render_wasm/builder.cljs (100%) rename frontend/{test => performance}/benches/render_wasm/cases.cljs (100%) rename frontend/{test => performance}/benches/render_wasm/codec.cljs (100%) rename frontend/{test => performance}/benches/render_wasm/declarations.clj (100%) rename frontend/{test => performance}/benches/render_wasm/declarations.cljs (100%) rename frontend/{test => performance}/benches/render_wasm/failures.cljs (100%) rename frontend/{test => performance}/benches/render_wasm/fingerprint.cljs (100%) rename frontend/{test => performance}/benches/render_wasm/measurement.cljs (100%) rename frontend/{test => performance}/benches/render_wasm/node/pilot.cljs (97%) rename frontend/{test => performance}/benches/render_wasm/node/runner.cljs (84%) rename frontend/{test => performance}/benches/render_wasm/random.cljs (100%) rename frontend/{test => performance}/benches/render_wasm/report/analysis.cljs (100%) rename frontend/{test => performance}/benches/render_wasm/report/compare.cljs (100%) rename frontend/{test => performance}/benches/render_wasm/report/format.cljs (100%) rename frontend/{test => performance}/benches/render_wasm/report/summarize.cljs (100%) rename frontend/{test => performance}/benches/render_wasm/result.cljs (100%) rename frontend/{test => performance}/benches/render_wasm/runtime/camera.cljs (100%) rename frontend/{test => performance}/benches/render_wasm/runtime/protocol.cljs (100%) rename frontend/{test => performance}/benches/render_wasm/scenes/masks.cljs (100%) rename frontend/{test => performance}/benches/render_wasm/scenes/paths.cljs (100%) rename frontend/{test => performance}/benches/render_wasm/scenes/plus.cljs (100%) rename frontend/{test => performance}/benches/render_wasm/scenes/rects.cljs (100%) rename frontend/{test => performance}/benches/render_wasm/snapshot.cljs (100%) rename frontend/test/{frontend_tests/benches => performance_tests/render_wasm}/boolean_test.cljs (99%) rename frontend/test/{frontend_tests/benches => performance_tests/render_wasm}/builder_test.cljs (99%) rename frontend/test/{frontend_tests/benches => performance_tests/render_wasm}/containers_test.cljs (99%) rename frontend/test/{frontend_tests/benches => performance_tests/render_wasm}/contracts_test.cljs (99%) rename frontend/test/{frontend_tests/benches => performance_tests/render_wasm}/fingerprint_test.cljs (99%) rename frontend/test/{frontend_tests/benches => performance_tests/render_wasm}/geometry_scenes_test.cljs (97%) rename frontend/test/{frontend_tests/benches => performance_tests/render_wasm}/lifecycle_test.cljs (97%) rename frontend/test/{frontend_tests/benches => performance_tests/render_wasm}/protocol_test.cljs (99%) rename frontend/test/{frontend_tests/benches => performance_tests/render_wasm}/report_test.cljs (99%) create mode 100644 frontend/test/performance_tests/render_wasm/runner.cljs rename frontend/test/{frontend_tests/benches => performance_tests/render_wasm}/scene_snapshot_test.cljs (99%) rename frontend/test/{frontend_tests/benches => performance_tests/render_wasm}/test_helpers.cljs (96%) diff --git a/.clj-kondo/config.edn b/.clj-kondo/config.edn index e1883ae4d4..67ea6d4994 100644 --- a/.clj-kondo/config.edn +++ b/.clj-kondo/config.edn @@ -39,7 +39,7 @@ "^(?:backend|frontend|exporter|common)/deps.edn" "^(?:backend|frontend|exporter|common)/scripts/" "^(?:backend|frontend|exporter|common)/dev/" - "^(?:backend|frontend|exporter|common)/test/(?!benches/|frontend_tests/benches/)"] + "^(?:backend|frontend|exporter|common)/test/(?!performance_tests/)"] :linter-name true} diff --git a/frontend/deps.edn b/frontend/deps.edn index 1aaab63117..299e74018d 100644 --- a/frontend/deps.edn +++ b/frontend/deps.edn @@ -1,4 +1,4 @@ -{:paths ["src" "vendor" "resources" "test"] +{:paths ["src" "vendor" "resources" "test" "performance"] :deps {;; Carries `app.common.render-wasm.*`, shared with the headless exporter. penpot/common @@ -37,8 +37,7 @@ instaparse/instaparse {:mvn/version "1.5.0"} garden/garden {:git/url "https://github.com/noprompt/garden" - :git/sha "05590ecb5f6fa670856f3d1ab400aa4961047480"} - } + :git/sha "05590ecb5f6fa670856f3d1ab400aa4961047480"}} :aliases {:outdated @@ -70,5 +69,4 @@ :renderer-bench {:main-opts ["-m" "shadow.cljs.devtools.cli"] - :jvm-opts ["-Dpenpot.wasm.profile-marks=false"]} - }} + :jvm-opts ["-Dpenpot.wasm.profile-marks=false"]}}} diff --git a/frontend/package.json b/frontend/package.json index ddde7fb84f..e116e34a20 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -26,19 +26,21 @@ "build:app:main": "clojure -M:dev:shadow-cljs release main worker", "build:app:worker": "clojure -M:dev:shadow-cljs release worker", "build:app": "pnpm run clear:shadow-cache && pnpm run build:app:main && pnpm run build:app:libs", - "check-fmt:clj": "cljfmt check --parallel=true src/ test/", + "check-fmt:clj": "cljfmt check --parallel=true src/ performance/ test/", "check-fmt:js": "prettier -c src/**/*.stories.jsx -c playwright/**/*.js -c scripts/**/*.js -c text-editor/**/*.js", "check-fmt:scss": "prettier -c resources/styles -c src/**/*.scss", - "fmt:clj": "cljfmt fix --parallel=true src/ test/", + "fmt:clj": "cljfmt fix --parallel=true src/ performance/ test/", "fmt:js": "prettier -c src/**/*.stories.jsx -c playwright/**/*.js -c scripts/**/*.js -c text-editor/**/*.js -w", "fmt:scss": "prettier -c resources/styles -c src/**/*.scss -w", - "lint:clj": "clj-kondo --fail-level error --config-dir ../.clj-kondo --lint ../common/src src/ test/benches/ test/frontend_tests/benches/", + "lint:clj": "clj-kondo --fail-level error --config-dir ../.clj-kondo --lint ../common/src src/ performance/ test/performance_tests/render_wasm/", "lint:js": "exit 0", - "lint:renderer-benchmarks": "clj-kondo --config-dir ../.clj-kondo --lint test/benches/ test/frontend_tests/benches/", + "lint:performance": "clj-kondo --config-dir ../.clj-kondo --lint performance/ test/performance_tests/render_wasm/", "lint:scss": "pnpm exec stylelint '{src,resources}/**/*.scss'", "build:test": "pnpm run build:wasm && clojure -M:dev:shadow-cljs compile test", + "build:performance-tests": "clojure -M:dev:shadow-cljs compile performance-tests", "test": "pnpm run build:test && node target/tests/test.js", "test:quiet": "node ./scripts/test-quiet.js", + "test:performance-tests": "pnpm run build:performance-tests && node target/performance-tests/test.js", "test:storybook": "vitest run --project=storybook", "watch:test": "mkdir -p target/tests && concurrently \"clojure -M:dev:shadow-cljs watch test\" \"nodemon -C -d 2 -w target/tests --exec 'node target/tests/test.js'\"", "test:e2e": "playwright test --project default", diff --git a/frontend/test/benches/render_wasm/browser/bridge.cljs b/frontend/performance/benches/render_wasm/browser/bridge.cljs similarity index 100% rename from frontend/test/benches/render_wasm/browser/bridge.cljs rename to frontend/performance/benches/render_wasm/browser/bridge.cljs diff --git a/frontend/test/benches/render_wasm/browser/pilot.html b/frontend/performance/benches/render_wasm/browser/pilot.html similarity index 100% rename from frontend/test/benches/render_wasm/browser/pilot.html rename to frontend/performance/benches/render_wasm/browser/pilot.html diff --git a/frontend/test/benches/render_wasm/builder.clj b/frontend/performance/benches/render_wasm/builder.clj similarity index 100% rename from frontend/test/benches/render_wasm/builder.clj rename to frontend/performance/benches/render_wasm/builder.clj diff --git a/frontend/test/benches/render_wasm/builder.cljs b/frontend/performance/benches/render_wasm/builder.cljs similarity index 100% rename from frontend/test/benches/render_wasm/builder.cljs rename to frontend/performance/benches/render_wasm/builder.cljs diff --git a/frontend/test/benches/render_wasm/cases.cljs b/frontend/performance/benches/render_wasm/cases.cljs similarity index 100% rename from frontend/test/benches/render_wasm/cases.cljs rename to frontend/performance/benches/render_wasm/cases.cljs diff --git a/frontend/test/benches/render_wasm/codec.cljs b/frontend/performance/benches/render_wasm/codec.cljs similarity index 100% rename from frontend/test/benches/render_wasm/codec.cljs rename to frontend/performance/benches/render_wasm/codec.cljs diff --git a/frontend/test/benches/render_wasm/declarations.clj b/frontend/performance/benches/render_wasm/declarations.clj similarity index 100% rename from frontend/test/benches/render_wasm/declarations.clj rename to frontend/performance/benches/render_wasm/declarations.clj diff --git a/frontend/test/benches/render_wasm/declarations.cljs b/frontend/performance/benches/render_wasm/declarations.cljs similarity index 100% rename from frontend/test/benches/render_wasm/declarations.cljs rename to frontend/performance/benches/render_wasm/declarations.cljs diff --git a/frontend/test/benches/render_wasm/failures.cljs b/frontend/performance/benches/render_wasm/failures.cljs similarity index 100% rename from frontend/test/benches/render_wasm/failures.cljs rename to frontend/performance/benches/render_wasm/failures.cljs diff --git a/frontend/test/benches/render_wasm/fingerprint.cljs b/frontend/performance/benches/render_wasm/fingerprint.cljs similarity index 100% rename from frontend/test/benches/render_wasm/fingerprint.cljs rename to frontend/performance/benches/render_wasm/fingerprint.cljs diff --git a/frontend/test/benches/render_wasm/measurement.cljs b/frontend/performance/benches/render_wasm/measurement.cljs similarity index 100% rename from frontend/test/benches/render_wasm/measurement.cljs rename to frontend/performance/benches/render_wasm/measurement.cljs diff --git a/frontend/test/benches/render_wasm/node/pilot.cljs b/frontend/performance/benches/render_wasm/node/pilot.cljs similarity index 97% rename from frontend/test/benches/render_wasm/node/pilot.cljs rename to frontend/performance/benches/render_wasm/node/pilot.cljs index 476af4a6cf..d882a26851 100644 --- a/frontend/test/benches/render_wasm/node/pilot.cljs +++ b/frontend/performance/benches/render_wasm/node/pilot.cljs @@ -32,7 +32,7 @@ Follow README.md's prepared renderer release commands first. clojure -M:dev:renderer-bench release bench-render-wasm-browser pnpm run build:renderer-benchmarks:pilot - node target/renderer-benchmarks/pilot.cjs --seed 42 --screenshot /tmp/pilot-rects.png + node target/performance/render-wasm/pilot.cjs --seed 42 --screenshot /tmp/pilot-rects.png The pilot serves the release browser bundle, so compile `bench-render-wasm-browser` first (after the prepared renderer build @@ -62,10 +62,10 @@ (defn- frontend-root "Resolves the frontend checkout root from the compiled pilot location - (`target/renderer-benchmarks/pilot.cjs`, next to `runner.cjs`). Ticket 10 + (`target/performance/render-wasm/pilot.cjs`, next to `runner.cjs`). Ticket 10 owns command cwd resolution; the pilot pins its own roots instead." [] - (path/resolve js/__dirname ".." "..")) + (path/resolve js/__dirname ".." ".." "..")) (def ^:private mime {".html" "text/html" @@ -209,9 +209,9 @@ (trace "pilot: parsing args") (let [opts (parse-args (or argv [])) root (frontend-root) - bundle (path/join root "target" "renderer-benchmarks" "browser") + bundle (path/join root "target" "performance" "render-wasm" "browser") js-dir (path/join root "resources" "public" "js") - html (path/join root "test" "benches" "render_wasm" "browser" "pilot.html") + html (path/join root "performance" "bench" "render_wasm" "browser" "pilot.html") seed (:seed opts) selected (some #(when (= (:id %) (:case-id opts)) %) (cases/collect-cases {:master-seed seed})) diff --git a/frontend/test/benches/render_wasm/node/runner.cljs b/frontend/performance/benches/render_wasm/node/runner.cljs similarity index 84% rename from frontend/test/benches/render_wasm/node/runner.cljs rename to frontend/performance/benches/render_wasm/node/runner.cljs index 0721154a33..3ab15e716a 100644 --- a/frontend/test/benches/render_wasm/node/runner.cljs +++ b/frontend/performance/benches/render_wasm/node/runner.cljs @@ -30,7 +30,7 @@ (defn- usage [summary] - (str "Usage: node target/renderer-benchmarks/runner.cjs [options]\n\n" + (str "Usage: node target/performance/render-wasm/runner.cjs [options]\n\n" "Options:\n" summary "\n\n" "No command is implemented yet. Upcoming tickets add:\n" @@ -57,9 +57,9 @@ (seq errors) (fail! (str/join "\n" errors)) - ;; TODO(mem:render-wasm/performance/cljs-rewrite/10-process-build-and-server, - ;; mem:render-wasm/performance/cljs-rewrite/11-runner-and-failure-accounting, - ;; mem:render-wasm/performance/cljs-rewrite/14-custom-measured-operations): + ;; TODO(mem:render-wasm/performance_tests/cljs-rewrite/10-process-build-and-server, + ;; mem:render-wasm/performance_tests/cljs-rewrite/11-runner-and-failure-accounting, + ;; mem:render-wasm/performance_tests/cljs-rewrite/14-custom-measured-operations): ;; dispatch `run`, `ab` and `compare` instead of failing. (seq arguments) (fail! (str "Unknown command: " (str/join " " arguments) "\nTry --help")) diff --git a/frontend/test/benches/render_wasm/random.cljs b/frontend/performance/benches/render_wasm/random.cljs similarity index 100% rename from frontend/test/benches/render_wasm/random.cljs rename to frontend/performance/benches/render_wasm/random.cljs diff --git a/frontend/test/benches/render_wasm/report/analysis.cljs b/frontend/performance/benches/render_wasm/report/analysis.cljs similarity index 100% rename from frontend/test/benches/render_wasm/report/analysis.cljs rename to frontend/performance/benches/render_wasm/report/analysis.cljs diff --git a/frontend/test/benches/render_wasm/report/compare.cljs b/frontend/performance/benches/render_wasm/report/compare.cljs similarity index 100% rename from frontend/test/benches/render_wasm/report/compare.cljs rename to frontend/performance/benches/render_wasm/report/compare.cljs diff --git a/frontend/test/benches/render_wasm/report/format.cljs b/frontend/performance/benches/render_wasm/report/format.cljs similarity index 100% rename from frontend/test/benches/render_wasm/report/format.cljs rename to frontend/performance/benches/render_wasm/report/format.cljs diff --git a/frontend/test/benches/render_wasm/report/summarize.cljs b/frontend/performance/benches/render_wasm/report/summarize.cljs similarity index 100% rename from frontend/test/benches/render_wasm/report/summarize.cljs rename to frontend/performance/benches/render_wasm/report/summarize.cljs diff --git a/frontend/test/benches/render_wasm/result.cljs b/frontend/performance/benches/render_wasm/result.cljs similarity index 100% rename from frontend/test/benches/render_wasm/result.cljs rename to frontend/performance/benches/render_wasm/result.cljs diff --git a/frontend/test/benches/render_wasm/runtime/camera.cljs b/frontend/performance/benches/render_wasm/runtime/camera.cljs similarity index 100% rename from frontend/test/benches/render_wasm/runtime/camera.cljs rename to frontend/performance/benches/render_wasm/runtime/camera.cljs diff --git a/frontend/test/benches/render_wasm/runtime/protocol.cljs b/frontend/performance/benches/render_wasm/runtime/protocol.cljs similarity index 100% rename from frontend/test/benches/render_wasm/runtime/protocol.cljs rename to frontend/performance/benches/render_wasm/runtime/protocol.cljs diff --git a/frontend/test/benches/render_wasm/scenes/masks.cljs b/frontend/performance/benches/render_wasm/scenes/masks.cljs similarity index 100% rename from frontend/test/benches/render_wasm/scenes/masks.cljs rename to frontend/performance/benches/render_wasm/scenes/masks.cljs diff --git a/frontend/test/benches/render_wasm/scenes/paths.cljs b/frontend/performance/benches/render_wasm/scenes/paths.cljs similarity index 100% rename from frontend/test/benches/render_wasm/scenes/paths.cljs rename to frontend/performance/benches/render_wasm/scenes/paths.cljs diff --git a/frontend/test/benches/render_wasm/scenes/plus.cljs b/frontend/performance/benches/render_wasm/scenes/plus.cljs similarity index 100% rename from frontend/test/benches/render_wasm/scenes/plus.cljs rename to frontend/performance/benches/render_wasm/scenes/plus.cljs diff --git a/frontend/test/benches/render_wasm/scenes/rects.cljs b/frontend/performance/benches/render_wasm/scenes/rects.cljs similarity index 100% rename from frontend/test/benches/render_wasm/scenes/rects.cljs rename to frontend/performance/benches/render_wasm/scenes/rects.cljs diff --git a/frontend/test/benches/render_wasm/snapshot.cljs b/frontend/performance/benches/render_wasm/snapshot.cljs similarity index 100% rename from frontend/test/benches/render_wasm/snapshot.cljs rename to frontend/performance/benches/render_wasm/snapshot.cljs diff --git a/frontend/shadow-cljs.edn b/frontend/shadow-cljs.edn index 7d6b84b46e..306ec6fe72 100644 --- a/frontend/shadow-cljs.edn +++ b/frontend/shadow-cljs.edn @@ -177,10 +177,27 @@ :elide-asserts true :anon-fn-naming-policy :off}}} + :performance-tests + {:target :esm + :output-dir "target/performance-tests" + :runtime :custom + :js-options {:js-provider :import} + + + :modules + {:test {:init-fn performance-tests.render-wasm.runner/init + :prepend-js ";if (typeof globalThis.navigator?.userAgent === 'undefined') { globalThis.navigator = {userAgent: ''}; };"}} + + :release + {:compiler-options + {:fn-invoke-direct true + :elide-asserts true + :anon-fn-naming-policy :off}}} + :bench-render-wasm-runner {:target :node-script - :output-to "target/renderer-benchmarks/runner.cjs" - :output-dir "target/renderer-benchmarks/runner/" + :output-to "target/performance/render-wasm/runner.cjs" + :output-dir "target/performance/render-wasm/runner/" :main benches.render-wasm.node.runner/-main :devtools {:autoload false} @@ -197,8 +214,8 @@ :bench-render-wasm-pilot {:target :node-script - :output-to "target/renderer-benchmarks/pilot.cjs" - :output-dir "target/renderer-benchmarks/pilot/" + :output-to "target/performance/render-wasm/pilot.cjs" + :output-dir "target/performance/render-wasm/pilot/" :main benches.render-wasm.node.pilot/-main :devtools {:autoload false} @@ -215,7 +232,7 @@ :bench-render-wasm-browser {:target :esm - :output-dir "target/renderer-benchmarks/browser/" + :output-dir "target/performance/render-wasm/browser/" ;; Bundle npm deps (date-fns via app.common): the pilot serves plain ;; static files with no import-map resolver. TODO(10): revisit when ;; ticket 10 owns staging; artifacts must stay self-contained. diff --git a/frontend/test/frontend_tests/benches/boolean_test.cljs b/frontend/test/performance_tests/render_wasm/boolean_test.cljs similarity index 99% rename from frontend/test/frontend_tests/benches/boolean_test.cljs rename to frontend/test/performance_tests/render_wasm/boolean_test.cljs index 1679663a4a..87a3889f2e 100644 --- a/frontend/test/frontend_tests/benches/boolean_test.cljs +++ b/frontend/test/performance_tests/render_wasm/boolean_test.cljs @@ -4,7 +4,7 @@ ;; ;; Copyright (c) KALEIDOS SUBSIDIARY SL -(ns frontend-tests.benches.boolean-test +(ns performance-tests.render-wasm.boolean-test (:require [app.common.geom.point :as gpt] [app.common.geom.shapes.intersect :as gint] @@ -14,7 +14,7 @@ [benches.render-wasm.builder :as b :include-macros true] [benches.render-wasm.snapshot :as snapshot] [cljs.test :as t :include-macros true] - [frontend-tests.benches.test-helpers :as helpers])) + [performance-tests.render-wasm.test-helpers :as helpers])) (t/deftest difference-of-overlapping-rects-keeps-hierarchy-and-bounds (let [red {:fill-color "#ff0000" :fill-opacity 1} diff --git a/frontend/test/frontend_tests/benches/builder_test.cljs b/frontend/test/performance_tests/render_wasm/builder_test.cljs similarity index 99% rename from frontend/test/frontend_tests/benches/builder_test.cljs rename to frontend/test/performance_tests/render_wasm/builder_test.cljs index 828801e0fe..dbb8e49cac 100644 --- a/frontend/test/frontend_tests/benches/builder_test.cljs +++ b/frontend/test/performance_tests/render_wasm/builder_test.cljs @@ -4,7 +4,7 @@ ;; ;; Copyright (c) KALEIDOS SUBSIDIARY SL -(ns frontend-tests.benches.builder-test +(ns performance-tests.render-wasm.builder-test "Tests canonical scene construction and the shared seeded number generator. Fixed random sequences preserve scene draws during generator extraction." (:require @@ -15,7 +15,7 @@ [benches.render-wasm.scenes.rects] [benches.render-wasm.snapshot :as snapshot] [cljs.test :as t :include-macros true] - [frontend-tests.benches.test-helpers :as helpers])) + [performance-tests.render-wasm.test-helpers :as helpers])) (defn- build ([] (build {})) diff --git a/frontend/test/frontend_tests/benches/containers_test.cljs b/frontend/test/performance_tests/render_wasm/containers_test.cljs similarity index 99% rename from frontend/test/frontend_tests/benches/containers_test.cljs rename to frontend/test/performance_tests/render_wasm/containers_test.cljs index 3d9f842f33..cf495409d3 100644 --- a/frontend/test/frontend_tests/benches/containers_test.cljs +++ b/frontend/test/performance_tests/render_wasm/containers_test.cljs @@ -4,12 +4,12 @@ ;; ;; Copyright (c) KALEIDOS SUBSIDIARY SL -(ns frontend-tests.benches.containers-test +(ns performance-tests.render-wasm.containers-test (:require [app.common.uuid :as uuid] [benches.render-wasm.builder :as builder :include-macros true] [cljs.test :as t :include-macros true] - [frontend-tests.benches.test-helpers :as helpers])) + [performance-tests.render-wasm.test-helpers :as helpers])) (t/deftest frame-attaches-children-in-order (let [instance (builder/scene {:seed 1} diff --git a/frontend/test/frontend_tests/benches/contracts_test.cljs b/frontend/test/performance_tests/render_wasm/contracts_test.cljs similarity index 99% rename from frontend/test/frontend_tests/benches/contracts_test.cljs rename to frontend/test/performance_tests/render_wasm/contracts_test.cljs index 80dc366be7..f2fea4ed07 100644 --- a/frontend/test/frontend_tests/benches/contracts_test.cljs +++ b/frontend/test/performance_tests/render_wasm/contracts_test.cljs @@ -4,7 +4,7 @@ ;; ;; Copyright (c) KALEIDOS SUBSIDIARY SL -(ns frontend-tests.benches.contracts-test +(ns performance-tests.render-wasm.contracts-test (:require [app.common.schema :as sm] [app.common.transit :as transit] @@ -425,7 +425,7 @@ (t/is (decl/transit-round-trips? (first collected)))) (t/is (empty? @body-calls)) (let [entry (decl/registered-case :contracts-scene/case)] - (t/is (= "frontend-tests.benches.contracts-test" (:ns entry))) + (t/is (= "performance-tests.render-wasm.contracts-test" (:ns entry))) (t/is (fn? (:run! entry))) (t/is (= :runtime ((:run! entry) :runtime))) (t/is (= [:touched] @body-calls)))) diff --git a/frontend/test/frontend_tests/benches/fingerprint_test.cljs b/frontend/test/performance_tests/render_wasm/fingerprint_test.cljs similarity index 99% rename from frontend/test/frontend_tests/benches/fingerprint_test.cljs rename to frontend/test/performance_tests/render_wasm/fingerprint_test.cljs index daeaff24b9..151063bf12 100644 --- a/frontend/test/frontend_tests/benches/fingerprint_test.cljs +++ b/frontend/test/performance_tests/render_wasm/fingerprint_test.cljs @@ -4,7 +4,7 @@ ;; ;; Copyright (c) KALEIDOS SUBSIDIARY SL -(ns frontend-tests.benches.fingerprint-test +(ns performance-tests.render-wasm.fingerprint-test "Tests content identity with production records, paths and collection types. Validated scene snapshots retain child order even when maps reorder." (:require diff --git a/frontend/test/frontend_tests/benches/geometry_scenes_test.cljs b/frontend/test/performance_tests/render_wasm/geometry_scenes_test.cljs similarity index 97% rename from frontend/test/frontend_tests/benches/geometry_scenes_test.cljs rename to frontend/test/performance_tests/render_wasm/geometry_scenes_test.cljs index a47697fe9d..0457391dfd 100644 --- a/frontend/test/frontend_tests/benches/geometry_scenes_test.cljs +++ b/frontend/test/performance_tests/render_wasm/geometry_scenes_test.cljs @@ -4,7 +4,7 @@ ;; ;; Copyright (c) KALEIDOS SUBSIDIARY SL -(ns frontend-tests.benches.geometry-scenes-test +(ns performance-tests.render-wasm.geometry-scenes-test (:require [app.common.types.path :as path] [app.common.uuid :as uuid] @@ -16,7 +16,7 @@ [benches.render-wasm.scenes.plus] [benches.render-wasm.snapshot :as snapshot] [cljs.test :as t :include-macros true] - [frontend-tests.benches.test-helpers :as helpers])) + [performance-tests.render-wasm.test-helpers :as helpers])) (t/deftest curved-paths-use-canonical-content-and-stable-order (let [params {:count 12 :width 1920 :height 1080 :seed 42} diff --git a/frontend/test/frontend_tests/benches/lifecycle_test.cljs b/frontend/test/performance_tests/render_wasm/lifecycle_test.cljs similarity index 97% rename from frontend/test/frontend_tests/benches/lifecycle_test.cljs rename to frontend/test/performance_tests/render_wasm/lifecycle_test.cljs index 80fb45a28b..d2afaf37db 100644 --- a/frontend/test/frontend_tests/benches/lifecycle_test.cljs +++ b/frontend/test/performance_tests/render_wasm/lifecycle_test.cljs @@ -4,7 +4,7 @@ ;; ;; Copyright (c) KALEIDOS SUBSIDIARY SL -(ns frontend-tests.benches.lifecycle-test +(ns performance-tests.render-wasm.lifecycle-test "Tests the browser bridge with fake DOM and renderer boundaries. It covers bridge input, ownership, disposal and `load-scene` with fake @@ -253,6 +253,8 @@ prev-window (unchecked-get js/globalThis "window") prev-import (unchecked-get js/globalThis "dynamicImport") prev-performance (unchecked-get js/globalThis "performance") + prev-now-fn (unchecked-get prev-performance "now") + prev-now-desc (js/Object.getOwnPropertyDescriptor prev-performance "now") prev-now (unchecked-get js/globalThis "__benchNow") prev-script (unchecked-get js/globalThis "__benchRenderScript") prev-calls (unchecked-get js/globalThis "__benchCalls") @@ -283,19 +285,25 @@ (cb timestamp)) (cb 0))) nil)} - performance #js {:now (fn [] - (if-some [clock (unchecked-get js/globalThis "__benchNow")] - clock - (.now prev-performance)))} + fake-now (fn [] + (if-some [clock (unchecked-get js/globalThis "__benchNow")] + clock + (.call prev-now-fn prev-performance))) dynamic-import (fn [url] (js/eval (str "import(" (pr-str url) ")")))] (unchecked-set js/globalThis "document" document) (unchecked-set js/globalThis "window" window) - (unchecked-set js/globalThis "performance" performance) + ;; Patch `now` on the real object: shadow hangs the compiled + ;; `performance.*` namespaces off the global `performance` object, so + ;; replacing that global hides every `benches.render-wasm.*` var. + (js/Object.defineProperty prev-performance "now" + #js {:value fake-now :configurable true :writable true}) (unchecked-set js/globalThis "dynamicImport" dynamic-import) (fn restore! [] (unchecked-set js/globalThis "document" prev-document) (unchecked-set js/globalThis "window" prev-window) - (unchecked-set js/globalThis "performance" prev-performance) + (if (undefined? prev-now-desc) + (js-delete prev-performance "now") + (js/Object.defineProperty prev-performance "now" prev-now-desc)) (unchecked-set js/globalThis "__benchNow" prev-now) (unchecked-set js/globalThis "__benchRenderScript" prev-script) (unchecked-set js/globalThis "__benchCalls" prev-calls) diff --git a/frontend/test/frontend_tests/benches/protocol_test.cljs b/frontend/test/performance_tests/render_wasm/protocol_test.cljs similarity index 99% rename from frontend/test/frontend_tests/benches/protocol_test.cljs rename to frontend/test/performance_tests/render_wasm/protocol_test.cljs index 670d91a71a..9e3ba8d0f1 100644 --- a/frontend/test/frontend_tests/benches/protocol_test.cljs +++ b/frontend/test/performance_tests/render_wasm/protocol_test.cljs @@ -4,7 +4,7 @@ ;; ;; Copyright (c) KALEIDOS SUBSIDIARY SL -(ns frontend-tests.benches.protocol-test +(ns performance-tests.render-wasm.protocol-test "Tests drain, restore and interact with an injected clock and renderer. Browser entry tests cover load and warm pan with a fake module." (:require diff --git a/frontend/test/frontend_tests/benches/report_test.cljs b/frontend/test/performance_tests/render_wasm/report_test.cljs similarity index 99% rename from frontend/test/frontend_tests/benches/report_test.cljs rename to frontend/test/performance_tests/render_wasm/report_test.cljs index 89530ade26..d2254c8c40 100644 --- a/frontend/test/frontend_tests/benches/report_test.cljs +++ b/frontend/test/performance_tests/render_wasm/report_test.cljs @@ -4,7 +4,7 @@ ;; ;; Copyright (c) KALEIDOS SUBSIDIARY SL -(ns frontend-tests.benches.report-test +(ns performance-tests.render-wasm.report-test "Pure tests for raw records, exploratory statistics and saved-run comparisons. Fixtures use saved case definitions without importing a registry or renderer." (:require diff --git a/frontend/test/performance_tests/render_wasm/runner.cljs b/frontend/test/performance_tests/render_wasm/runner.cljs new file mode 100644 index 0000000000..0f1968202a --- /dev/null +++ b/frontend/test/performance_tests/render_wasm/runner.cljs @@ -0,0 +1,195 @@ +;; License, v. 2.0. If a copy of the MPL was not distributed with this +;; file, You can obtain one at http://mozilla.org/MPL/2.0/. +;; +;; Copyright (c) KALEIDOS SUBSIDIARY SL + +(ns performance-tests.render-wasm.runner + (:require + [app.common.logging :as l] + [cljs.test :as t] + [clojure.string :as str] + [clojure.tools.cli :refer [parse-opts]] + [goog.object :as gobj] + [performance-tests.render-wasm.boolean-test] + [performance-tests.render-wasm.builder-test] + [performance-tests.render-wasm.containers-test] + [performance-tests.render-wasm.contracts-test] + [performance-tests.render-wasm.fingerprint-test] + [performance-tests.render-wasm.geometry-scenes-test] + [performance-tests.render-wasm.lifecycle-test] + [performance-tests.render-wasm.protocol-test] + [performance-tests.render-wasm.report-test] + [performance-tests.render-wasm.scene-snapshot-test])) + +(enable-console-print!) + +(defmethod t/report [:cljs.test/default :begin-test-var] [m] + (let [v (:var m)] + (println (str " ▸ " (:ns (meta v)) "/" (:name (meta v)))))) + +(defmethod t/report [:cljs.test/default :end-run-tests] [m] + (if (cljs.test/successful? m) + (.exit js/process 0) + (.exit js/process 1))) + +(def test-namespaces + ['performance-tests.render-wasm.boolean-test + 'performance-tests.render-wasm.builder-test + 'performance-tests.render-wasm.containers-test + 'performance-tests.render-wasm.contracts-test + 'performance-tests.render-wasm.fingerprint-test + 'performance-tests.render-wasm.geometry-scenes-test + 'performance-tests.render-wasm.lifecycle-test + 'performance-tests.render-wasm.protocol-test + 'performance-tests.render-wasm.report-test + 'performance-tests.render-wasm.scene-snapshot-test]) + +(assert (every? find-ns-obj test-namespaces) + "test-namespaces contains a namespace that isn't required in runner.cljs") + +;; This runner mirrors frontend-tests.runner for the bench-only +;; :performance-tests target. Both runners need forwarded CLI args, focused +;; namespace/var execution, fixture preservation, and app log-level +;; setup. The logic stays local to avoid cross-target test classpath +;; coupling. +(def ^:private log-levels + #{:trace :debug :info :warn :error}) + +(def cli-options + [["-f" "--focus FOCUS" "Run one test namespace or one test var, e.g. performance-tests.render-wasm.contracts-test"] + ["-l" "--log-level LEVEL" "Set app logger level: trace|debug|info|warn|error" + :parse-fn keyword + :validate [log-levels "must be one of trace, debug, info, warn, error"]] + ["-h" "--help"]]) + +(defn- argv + [] + (let [args (->> (.-argv js/process) + (array-seq) + (drop 2))] + ;; `pnpm run test:performance-tests -- --focus ...` forwards the separator to + ;; the node process, so drop one leading `--` before handing args to + ;; tools.cli. + (cond-> args + (= "--" (first args)) rest))) + +(defn- usage + [summary] + (str "Usage: pnpm run test:performance-tests -- [options]\n\n" + "Options:\n" + summary "\n\n" + "Focus examples:\n" + " pnpm run test:performance-tests -- --focus performance-tests.render-wasm.contracts-test\n" + " pnpm run test:performance-tests -- --focus performance-tests.render-wasm.contracts-test/some-test-var\n\n" + "Log level example (quiets app logging during the run):\n" + " pnpm run test:performance-tests -- --focus performance-tests.render-wasm.contracts-test --log-level warn")) + +(defn- fail! + [message] + (js/console.error message) + (.exit js/process 1)) + +(defn- parse-focus + [focus] + (let [[ns-name test-name & extra] (str/split focus #"/")] + (cond + (or (str/blank? ns-name) (seq extra)) + (fail! (str "Invalid --focus value: " focus)) + + (some? test-name) + {:ns (symbol ns-name) :test test-name} + + :else + {:ns (symbol ns-name)}))) + +(defn- fixture-value + [ns-obj fixture-name] + (let [value (gobj/get ns-obj (munge fixture-name))] + (when-not (undefined? value) + value))) + +(defn- ns-test-vars + [ns-sym] + (when-let [ns-obj (find-ns-obj ns-sym)] + (->> (js-keys ns-obj) + (keep (fn [key] + (some-> (gobj/get ns-obj key) + (.-cljs$lang$var)))) + (filter (comp :test meta)) + (sort-by (comp :line meta))))) + +(defn- ns-fixtures + [ns-sym vars] + (when-let [ns-obj (find-ns-obj ns-sym)] + (let [ns-key (or (some-> vars first meta :ns) ns-sym) + once-fixtures (fixture-value ns-obj "cljs-test-once-fixtures") + each-fixtures (fixture-value ns-obj "cljs-test-each-fixtures")] + {:once (when once-fixtures {ns-key once-fixtures}) + :each (when each-fixtures {ns-key each-fixtures})}))) + +(defn- selected-tests + [{:keys [ns test]}] + (when-not (some #{ns} test-namespaces) + (fail! (str "Unknown test namespace: " ns))) + (let [vars (vec (ns-test-vars ns))] + (when (empty? vars) + (fail! (str "No tests found in namespace: " ns))) + (if test + (let [test-sym (symbol test) + test-var (some #(when (= test-sym (:name (meta %))) %) vars)] + (if test-var + {:vars [test-var] + :fixtures (ns-fixtures ns [test-var])} + (fail! (str "Unknown test var: " ns "/" test)))) + {:vars vars + :fixtures (ns-fixtures ns vars)}))) + +(defn- merge-fixtures + [fixtures] + {:once (apply merge (keep :once fixtures)) + :each (apply merge (keep :each fixtures))}) + +(defn- run-test-vars! + [tests] + (let [vars (vec (mapcat :vars tests)) + fixtures (merge-fixtures (map :fixtures tests)) + env (assoc (t/empty-env) + :once-fixtures (:once fixtures) + :each-fixtures (:each fixtures)) + summary (volatile! {:test 0 :pass 0 :fail 0 :error 0 :type :summary})] + + (t/set-env! env) + + (t/run-block + (concat (t/test-vars-block vars) + [(fn [] + (vswap! summary + (partial merge-with +) + (:report-counters (t/get-current-env)))) + (fn [] + (t/report @summary) + (t/report (assoc @summary :type :end-run-tests)))])))) + +(defn- run-focused-test! + [focus] + (run-test-vars! [(selected-tests (parse-focus focus))])) + +(defn init + [] + (let [{:keys [options errors summary]} (parse-opts (argv) cli-options)] + (cond + (seq errors) + (fail! (str/join "\n" errors)) + + (:help options) + (do + (println (usage summary)) + (.exit js/process 0)) + + :else + (do + (l/setup! {:app (or (:log-level options) :warn)}) + + (if (:focus options) + (run-focused-test! (:focus options)) + (run-test-vars! (map #(selected-tests {:ns %}) test-namespaces))))))) diff --git a/frontend/test/frontend_tests/benches/scene_snapshot_test.cljs b/frontend/test/performance_tests/render_wasm/scene_snapshot_test.cljs similarity index 99% rename from frontend/test/frontend_tests/benches/scene_snapshot_test.cljs rename to frontend/test/performance_tests/render_wasm/scene_snapshot_test.cljs index 06b7d05175..08f6070de3 100644 --- a/frontend/test/frontend_tests/benches/scene_snapshot_test.cljs +++ b/frontend/test/performance_tests/render_wasm/scene_snapshot_test.cljs @@ -4,7 +4,7 @@ ;; ;; Copyright (c) KALEIDOS SUBSIDIARY SL -(ns frontend-tests.benches.scene-snapshot-test +(ns performance-tests.render-wasm.scene-snapshot-test (:require [app.common.schema :as sm] [app.common.types.shape :as cts] diff --git a/frontend/test/frontend_tests/benches/test_helpers.cljs b/frontend/test/performance_tests/render_wasm/test_helpers.cljs similarity index 96% rename from frontend/test/frontend_tests/benches/test_helpers.cljs rename to frontend/test/performance_tests/render_wasm/test_helpers.cljs index 5eec3e4bb9..4609e8f079 100644 --- a/frontend/test/frontend_tests/benches/test_helpers.cljs +++ b/frontend/test/performance_tests/render_wasm/test_helpers.cljs @@ -1,4 +1,4 @@ -(ns frontend-tests.benches.test-helpers +(ns performance-tests.render-wasm.test-helpers "Shared helpers for renderer benchmark scene tests. These helpers assert nothing about shapes or the renderer. They only