mirror of
https://github.com/penpot/penpot.git
synced 2026-05-23 08:53:39 +00:00
Add focused common JavaScript test execution with log-level control and a quiet test wrapper matching the frontend workflow. Update developer docs and testing memories to reflect the common/frontend test split, and document why runner helper extraction is deferred. Signed-off-by: Codex <codex@openai.com>
320 lines
11 KiB
Clojure
320 lines
11 KiB
Clojure
;; This Source Code Form is subject to the terms of the Mozilla Public
|
|
;; 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 INC
|
|
|
|
(ns common-tests.runner
|
|
(:require
|
|
#?(:clj [common-tests.fressian-test])
|
|
#?(:cljs [app.common.logging :as l])
|
|
#?(:cljs [clojure.string :as str])
|
|
#?(:cljs [clojure.tools.cli :refer [parse-opts]])
|
|
#?(:cljs [goog.object :as gobj])
|
|
[clojure.test :as t]
|
|
[common-tests.attrs-test]
|
|
[common-tests.buffer-test]
|
|
[common-tests.colors-test]
|
|
[common-tests.data-test]
|
|
[common-tests.files-builder-test]
|
|
[common-tests.files-changes-test]
|
|
[common-tests.files-migrations-test]
|
|
[common-tests.files.shapes-builder-test]
|
|
[common-tests.geom-align-test]
|
|
[common-tests.geom-bounds-map-test]
|
|
[common-tests.geom-flex-layout-test]
|
|
[common-tests.geom-grid-layout-test]
|
|
[common-tests.geom-grid-test]
|
|
[common-tests.geom-line-test]
|
|
[common-tests.geom-modif-tree-test]
|
|
[common-tests.geom-modifiers-test]
|
|
[common-tests.geom-point-test]
|
|
[common-tests.geom-proportions-test]
|
|
[common-tests.geom-rect-test]
|
|
[common-tests.geom-shapes-common-test]
|
|
[common-tests.geom-shapes-constraints-test]
|
|
[common-tests.geom-shapes-corners-test]
|
|
[common-tests.geom-shapes-effects-test]
|
|
[common-tests.geom-shapes-intersect-test]
|
|
[common-tests.geom-shapes-strokes-test]
|
|
[common-tests.geom-shapes-test]
|
|
[common-tests.geom-shapes-text-test]
|
|
[common-tests.geom-shapes-tree-seq-test]
|
|
[common-tests.geom-snap-test]
|
|
[common-tests.geom-test]
|
|
[common-tests.logic.chained-propagation-test]
|
|
[common-tests.logic.comp-creation-test]
|
|
[common-tests.logic.comp-detach-with-nested-test]
|
|
[common-tests.logic.comp-remove-swap-slots-test]
|
|
[common-tests.logic.comp-reset-test]
|
|
[common-tests.logic.comp-sync-test]
|
|
[common-tests.logic.comp-touched-test]
|
|
[common-tests.logic.copying-and-duplicating-test]
|
|
[common-tests.logic.duplicated-pages-test]
|
|
[common-tests.logic.move-shapes-test]
|
|
[common-tests.logic.multiple-nesting-levels-test]
|
|
[common-tests.logic.swap-and-reset-test]
|
|
[common-tests.logic.swap-as-override-test]
|
|
[common-tests.logic.token-test]
|
|
[common-tests.media-test]
|
|
[common-tests.path-names-test]
|
|
[common-tests.record-test]
|
|
[common-tests.schema-test]
|
|
[common-tests.spec-test]
|
|
[common-tests.svg-path-test]
|
|
[common-tests.svg-test]
|
|
[common-tests.text-test]
|
|
[common-tests.time-test]
|
|
[common-tests.types.absorb-assets-test]
|
|
[common-tests.types.color-test]
|
|
[common-tests.types.components-test]
|
|
[common-tests.types.container-test]
|
|
[common-tests.types.fill-test]
|
|
[common-tests.types.modifiers-test]
|
|
[common-tests.types.nitrate-permissions-test]
|
|
[common-tests.types.objects-map-test]
|
|
[common-tests.types.path-data-test]
|
|
[common-tests.types.shape-decode-encode-test]
|
|
[common-tests.types.shape-interactions-test]
|
|
[common-tests.types.shape-layout-test]
|
|
[common-tests.types.token-test]
|
|
[common-tests.types.tokens-lib-test]
|
|
[common-tests.undo-stack-test]
|
|
[common-tests.uuid-test]))
|
|
|
|
(def test-namespaces
|
|
[#?(:clj 'common-tests.fressian-test)
|
|
'common-tests.attrs-test
|
|
'common-tests.buffer-test
|
|
'common-tests.colors-test
|
|
'common-tests.data-test
|
|
'common-tests.files-changes-test
|
|
'common-tests.files-builder-test
|
|
'common-tests.files-migrations-test
|
|
'common-tests.geom-align-test
|
|
'common-tests.geom-bounds-map-test
|
|
'common-tests.geom-flex-layout-test
|
|
'common-tests.geom-grid-layout-test
|
|
'common-tests.geom-grid-test
|
|
'common-tests.geom-line-test
|
|
'common-tests.geom-modif-tree-test
|
|
'common-tests.geom-modifiers-test
|
|
'common-tests.geom-point-test
|
|
'common-tests.geom-proportions-test
|
|
'common-tests.geom-rect-test
|
|
'common-tests.geom-shapes-common-test
|
|
'common-tests.geom-shapes-constraints-test
|
|
'common-tests.geom-shapes-corners-test
|
|
'common-tests.geom-shapes-effects-test
|
|
'common-tests.geom-shapes-intersect-test
|
|
'common-tests.geom-shapes-strokes-test
|
|
'common-tests.geom-shapes-test
|
|
'common-tests.geom-shapes-text-test
|
|
'common-tests.geom-shapes-tree-seq-test
|
|
'common-tests.geom-snap-test
|
|
'common-tests.geom-test
|
|
'common-tests.logic.chained-propagation-test
|
|
'common-tests.logic.comp-creation-test
|
|
'common-tests.logic.comp-detach-with-nested-test
|
|
'common-tests.logic.comp-remove-swap-slots-test
|
|
'common-tests.logic.comp-reset-test
|
|
'common-tests.logic.comp-sync-test
|
|
'common-tests.logic.comp-touched-test
|
|
'common-tests.logic.copying-and-duplicating-test
|
|
'common-tests.logic.duplicated-pages-test
|
|
'common-tests.logic.move-shapes-test
|
|
'common-tests.logic.multiple-nesting-levels-test
|
|
'common-tests.logic.swap-and-reset-test
|
|
'common-tests.logic.swap-as-override-test
|
|
'common-tests.logic.token-test
|
|
'common-tests.media-test
|
|
'common-tests.path-names-test
|
|
'common-tests.record-test
|
|
'common-tests.schema-test
|
|
'common-tests.spec-test
|
|
'common-tests.svg-path-test
|
|
'common-tests.svg-test
|
|
'common-tests.text-test
|
|
'common-tests.time-test
|
|
'common-tests.types.absorb-assets-test
|
|
'common-tests.types.color-test
|
|
'common-tests.types.components-test
|
|
'common-tests.types.container-test
|
|
'common-tests.types.fill-test
|
|
'common-tests.types.modifiers-test
|
|
'common-tests.types.nitrate-permissions-test
|
|
'common-tests.types.objects-map-test
|
|
'common-tests.types.path-data-test
|
|
'common-tests.types.shape-decode-encode-test
|
|
'common-tests.types.shape-interactions-test
|
|
'common-tests.types.shape-layout-test
|
|
'common-tests.types.token-test
|
|
'common-tests.types.tokens-lib-test
|
|
'common-tests.undo-stack-test
|
|
'common-tests.uuid-test])
|
|
|
|
#?(:cljs
|
|
(assert (every? find-ns-obj test-namespaces)
|
|
"test-namespaces contains a namespace that isn't required in runner.cljc"))
|
|
|
|
#?(:cljs (enable-console-print!))
|
|
|
|
#?(:cljs
|
|
(defmethod cljs.test/report [:cljs.test/default :end-run-tests] [m]
|
|
(if (cljs.test/successful? m)
|
|
(.exit js/process 0)
|
|
(.exit js/process 1))))
|
|
|
|
#?(:cljs
|
|
(do
|
|
;; This runner intentionally mirrors frontend-tests.runner. Both runners need
|
|
;; forwarded CLI args, focused namespace/var execution, fixture preservation,
|
|
;; and app log-level setup. A shared helper could own those mechanics, but we
|
|
;; keep the logic local while there are only two test targets because sharing
|
|
;; it would add cross-module 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. common-tests.logic.comp-sync-test/test-sync-when-changing-attribute"]
|
|
["-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))]
|
|
(cond-> args
|
|
(= "--" (first args)) rest)))
|
|
|
|
(defn- usage
|
|
[summary]
|
|
(str "Usage: pnpm run test:js -- [options]\n\n"
|
|
"Options:\n"
|
|
summary "\n\n"
|
|
"Focus examples:\n"
|
|
" pnpm run test:js -- --focus common-tests.logic.comp-sync-test\n"
|
|
" pnpm run test:js -- --focus common-tests.logic.comp-sync-test/test-sync-when-changing-attribute\n\n"
|
|
"Log level example (quiets app logging during the run):\n"
|
|
" pnpm run test:js -- --focus common-tests.logic.comp-sync-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/run-block
|
|
(concat [(fn [] (t/set-env! env))]
|
|
(t/test-vars-block vars)
|
|
[(fn []
|
|
(vswap! summary
|
|
(partial merge-with +)
|
|
(:report-counters (t/get-and-clear-env!))))
|
|
(fn []
|
|
(t/set-env! env)
|
|
(t/do-report @summary)
|
|
(t/report (assoc @summary :type :end-run-tests))
|
|
(t/clear-env!))]))))
|
|
|
|
(defn- run-focused-test!
|
|
[focus]
|
|
(run-test-vars! [(selected-tests (parse-focus focus))]))
|
|
|
|
(defn- run-all-tests!
|
|
[]
|
|
(run-test-vars! (map #(selected-tests {:ns %}) test-namespaces)))))
|
|
|
|
(defn -main
|
|
[& _args]
|
|
#?(:cljs
|
|
(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
|
|
(when-let [level (:log-level options)]
|
|
(l/setup! {:app level}))
|
|
(if (:focus options)
|
|
(run-focused-test! (:focus options))
|
|
(run-all-tests!)))))
|
|
:clj
|
|
(apply t/run-tests test-namespaces)))
|