From 5be103156570df6880d942e1b39e700be5199ec3 Mon Sep 17 00:00:00 2001 From: Brandon Correa <50252804+brandoncorrea@users.noreply.github.com> Date: Sat, 25 May 2024 13:02:58 -0500 Subject: [PATCH 01/16] Refactoring: require :as instead of :refer, reduce tags instead of loop, shared load-reporter function between clj/s --- spec/speclj/config_spec.cljc | 6 +- spec/speclj/core_spec.cljc | 8 +-- spec/speclj/platform_spec.cljc | 10 ++- spec/speclj/report/documentation_spec.cljc | 11 ++- spec/speclj/report/progress_spec.cljc | 17 +++-- spec/speclj/reporting_spec.cljc | 51 +++++++------- spec/speclj/run/standard_spec.clj | 4 +- spec/speclj/should_spec.cljc | 70 +++++++++---------- spec/speclj/stub_spec.cljc | 35 +++++----- spec/speclj/tags_spec.cljc | 81 +++++++++++----------- src/speclj/config.cljc | 53 +++++++------- src/speclj/run/standard.cljs | 53 +++++++------- 12 files changed, 193 insertions(+), 206 deletions(-) diff --git a/spec/speclj/config_spec.cljc b/spec/speclj/config_spec.cljc index 3cd86b4..934c6c5 100644 --- a/spec/speclj/config_spec.cljc +++ b/spec/speclj/config_spec.cljc @@ -6,7 +6,7 @@ [speclj.platform :as platform] [speclj.report.progress] [speclj.report.silent] - [speclj.run.standard :refer [run-specs]])) + [speclj.run.standard :as standard])) (describe "Config" @@ -65,6 +65,4 @@ ) -(run-specs) - - +(standard/run-specs) diff --git a/spec/speclj/core_spec.cljc b/spec/speclj/core_spec.cljc index bc15c3e..453ce8a 100644 --- a/spec/speclj/core_spec.cljc +++ b/spec/speclj/core_spec.cljc @@ -5,8 +5,7 @@ before after before-all after-all with with! with-all with-all! around around-all redefs-around]]) (:require [speclj.platform] - [speclj.components] - [speclj.run.standard :refer [run-specs]])) + [speclj.components])) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; FOCUS SPECS (remain commented except when 'fiddling') ;; @@ -322,7 +321,7 @@ (describe "with" (def lazy-calls (atom 0)) (with with-example - (swap! lazy-calls inc)) + (swap! lazy-calls inc)) (it "never deref'ed with-example" (should= 0 @lazy-calls)) @@ -369,6 +368,3 @@ (it "has not been reset and deref'ed" (should= 1 @non-lazy-with-all-calls))) - -;(run-specs :tags ["two"]) -;(run-specs) diff --git a/spec/speclj/platform_spec.cljc b/spec/speclj/platform_spec.cljc index 15e2f67..78a1073 100644 --- a/spec/speclj/platform_spec.cljc +++ b/spec/speclj/platform_spec.cljc @@ -1,9 +1,7 @@ (ns speclj.platform-spec - (#?(:clj :require :cljs :require-macros) - [speclj.core :refer [describe it should= should-throw]] - [speclj.platform :refer [if-cljs try-catch-anything]]) - (:require - [speclj.run.standard :refer [run-specs]])) + (:require [speclj.core #?(:clj :refer :cljs :refer-macros) [describe it should= should-throw]] + [speclj.platform #?(:clj :refer :cljs :refer-macros) [if-cljs try-catch-anything]] + [speclj.run.standard :as standard])) (defmacro which-env [] (if-cljs :cljs :clj)) @@ -37,4 +35,4 @@ :yep (catch :nope 'whatever))))))) -(run-specs) +(standard/run-specs) diff --git a/spec/speclj/report/documentation_spec.cljc b/spec/speclj/report/documentation_spec.cljc index 24a16c3..aa23264 100644 --- a/spec/speclj/report/documentation_spec.cljc +++ b/spec/speclj/report/documentation_spec.cljc @@ -1,15 +1,13 @@ (ns speclj.report.documentation-spec - (#?(:clj :require :cljs :require-macros) - [speclj.core :refer [before context describe it should= with -new-exception -new-failure -new-pending]]) - (:require #?(:cljs [goog.string]) ;cljs bug? + (:require #?(:cljs [goog.string]) ;cljs bug? + [speclj.core #?(:clj :refer :cljs :refer-macros) [before context describe it should= with -new-exception -new-failure -new-pending]] [speclj.components :refer [new-description new-characteristic install]] [speclj.platform :refer [endl]] [speclj.report.documentation :refer [new-documentation-reporter]] [speclj.reporting :refer [report-description report-pass report-pending report-fail report-error red green yellow]] [speclj.results :refer [pass-result fail-result pending-result error-result]] - [speclj.run.standard :refer [run-specs]]) - ) + [speclj.run.standard :as standard])) (describe "Speccdoc Reporter" (with reporter (new-documentation-reporter)) @@ -80,5 +78,4 @@ ) ) - -(run-specs) +(standard/run-specs) diff --git a/spec/speclj/report/progress_spec.cljc b/spec/speclj/report/progress_spec.cljc index 570356e..a7f54b5 100644 --- a/spec/speclj/report/progress_spec.cljc +++ b/spec/speclj/report/progress_spec.cljc @@ -1,16 +1,15 @@ (ns speclj.report.progress-spec - (#?(:clj :require :cljs :require-macros) - [speclj.core :refer [around describe it should should= with -new-exception -new-failure -new-pending]]) - (:require [clojure.string :as str] - #?(:cljs [goog.string]) ;cljs bug? + (:require [speclj.core #?(:clj :refer :cljs :refer-macros) [around describe it should should= with -new-exception -new-failure -new-pending]] + [clojure.string :as str] + #?(:cljs [goog.string]) ;cljs bug? [speclj.components :refer [new-description new-characteristic install]] [speclj.config :refer [*color?* *full-stack-trace?* *omit-pending?*]] - [speclj.platform :refer [format-seconds]] + [speclj.platform :as platform] [speclj.report.progress :refer [new-progress-reporter full-name print-summary print-pendings print-errors]] [speclj.reporting :refer [report-description report-pass report-pending report-fail report-error red green yellow grey report-runs]] [speclj.results :refer [pass-result fail-result pending-result error-result]] - [speclj.run.standard :refer [run-specs]])) + [speclj.run.standard :as standard])) (describe "Progress Reporter" (with reporter (new-progress-reporter)) @@ -64,7 +63,7 @@ (should= 4 (count lines)) (should= "" (nth lines 0)) (should= "" (nth lines 1)) - (should= (str "Finished in " (format-seconds 0.123) " seconds") (nth lines 2)) + (should= (str "Finished in " (platform/format-seconds 0.123) " seconds") (nth lines 2)) (should= (green "3 examples, 0 failures") (nth lines 3))))) (it "reports failing run results" @@ -94,7 +93,7 @@ (should= (red " Expected dives") (nth lines 13)) ; (should= "/Users/micahmartin/Projects/clojure/speclj/spec/speclj/report/progress_spec.clj:56" (nth lines 14)) (should= "" (nth lines 15)) - (should= (str "Finished in " (format-seconds 0.321) " seconds") (nth lines 16)) + (should= (str "Finished in " (platform/format-seconds 0.321) " seconds") (nth lines 16)) (should= (red "3 examples, 3 failures") (nth lines 17))))) (it "reports pending run results" @@ -161,4 +160,4 @@ (should= "Outer Inner char" (full-name char)))) ) -(run-specs :stacktrace true) +(standard/run-specs :stacktrace true) diff --git a/spec/speclj/reporting_spec.cljc b/spec/speclj/reporting_spec.cljc index 9a7bfec..d24b3ed 100644 --- a/spec/speclj/reporting_spec.cljc +++ b/spec/speclj/reporting_spec.cljc @@ -1,38 +1,37 @@ (ns speclj.reporting-spec - (#?(:clj :require :cljs :require-macros) - [speclj.core :refer [describe context around it should=]]) - (:require [speclj.config :refer [*color?* *full-stack-trace?*]] - [speclj.run.standard :refer [run-specs]] - [speclj.reporting :refer [green grey indent red prefix stack-trace-str yellow]])) + (:require [speclj.core #?(:clj :refer :cljs :refer-macros) [describe context around it should=]] + [speclj.config :as config] + [speclj.run.standard :as standard] + [speclj.reporting :as sut])) (describe "Reporting" (context "without color" - (around [it] (binding [*color?* false] (it))) + (around [it] (binding [config/*color?* false] (it))) (it "prints all colors as plain text" - (should= "text" (red "text")) - (should= "text" (green "text")) - (should= "text" (grey "text"))) + (should= "text" (sut/red "text")) + (should= "text" (sut/green "text")) + (should= "text" (sut/grey "text"))) ) (context "with color" - (around [it] (binding [*color?* true] (it))) + (around [it] (binding [config/*color?* true] (it))) (it "prints in red" - (should= "\u001b[31mtext\u001b[0m" (red "text"))) + (should= "\u001b[31mtext\u001b[0m" (sut/red "text"))) (it "prints in green" - (should= "\u001b[32mtext\u001b[0m" (green "text"))) + (should= "\u001b[32mtext\u001b[0m" (sut/green "text"))) (it "prints in yellow" - (should= "\u001b[33mtext\u001b[0m" (yellow "text"))) + (should= "\u001b[33mtext\u001b[0m" (sut/yellow "text"))) (it "prints in grey" - (should= "\u001b[90mtext\u001b[0m" (grey "text"))) + (should= "\u001b[90mtext\u001b[0m" (sut/grey "text"))) ) (context "with elided stacktrace" - (around [it] (binding [*full-stack-trace?* false] (it))) + (around [it] (binding [config/*full-stack-trace?* false] (it))) #?(:clj (it "prints elided stack traces" @@ -57,7 +56,7 @@ (StackTraceElement. "clojure.core$load" "doInvoke" "core.clj" 4904) (StackTraceElement. "my_code$end" "invoke" "my_file.clj" 124) ])) - (should= expected (stack-trace-str exception))))) + (should= expected (sut/stack-trace-str exception))))) #?(:clj (it "prints elided stack traces of caused exceptions" @@ -82,20 +81,20 @@ Caused by: java.lang.Exception: Cause (StackTraceElement. "clojure.core$load" "doInvoke" "core.clj" 4904) (StackTraceElement. "my_code$end" "invoke" "my_file.clj" 124) ])) - (should= expected (stack-trace-str exception))))) + (should= expected (sut/stack-trace-str exception))))) (it "prefixes lines of text" - (should= "--foo" (prefix "--" "foo")) - (should= "++bar" (prefix "++" "bar")) - (should= "=foobar" (prefix "=" "foo" "bar")) - (should= "--foo\n--bar" (prefix "--" "foo\nbar"))) + (should= "--foo" (sut/prefix "--" "foo")) + (should= "++bar" (sut/prefix "++" "bar")) + (should= "=foobar" (sut/prefix "=" "foo" "bar")) + (should= "--foo\n--bar" (sut/prefix "--" "foo\nbar"))) (it "can indent" - (should= " foo" (indent 1 "foo")) - (should= " bar" (indent 1.5 "bar")) - (should= " foo\n bar" (indent 1 "foo\nbar")) - (should= " foo\n bar" (indent 2 "foo\nbar"))) + (should= " foo" (sut/indent 1 "foo")) + (should= " bar" (sut/indent 1.5 "bar")) + (should= " foo\n bar" (sut/indent 1 "foo\nbar")) + (should= " foo\n bar" (sut/indent 2 "foo\nbar"))) ) ) -(run-specs) +(standard/run-specs) diff --git a/spec/speclj/run/standard_spec.clj b/spec/speclj/run/standard_spec.clj index e356b43..4730998 100644 --- a/spec/speclj/run/standard_spec.clj +++ b/spec/speclj/run/standard_spec.clj @@ -1,5 +1,5 @@ (ns speclj.run.standard-spec - (:require [speclj.core :refer [describe focus-it it should= with]] + (:require [speclj.core :refer [describe it should= with]] [speclj.report.silent :refer [new-silent-reporter]] [speclj.run.standard :refer :all] [speclj.running :refer [run-directories]]) @@ -37,4 +37,4 @@ ) -(run-specs) \ No newline at end of file +(run-specs) diff --git a/spec/speclj/should_spec.cljc b/spec/speclj/should_spec.cljc index c5d7908..06e7636 100644 --- a/spec/speclj/should_spec.cljc +++ b/spec/speclj/should_spec.cljc @@ -1,8 +1,8 @@ (ns speclj.should-spec (#?(:clj :require :cljs :require-macros) - [speclj.core :refer [it xit focus-it - context focus-context - describe focus-describe + [speclj.core :refer [it + context + describe should should-not should= should-not= should== should-not== @@ -21,7 +21,7 @@ -to-s -new-throwable -new-exception]] [speclj.spec-helper :refer [should-fail! should-pass! failure-message]]) (:require [speclj.platform :refer [endl exception type-name throwable]] - [speclj.run.standard :refer [run-specs]])) + [speclj.run.standard :as standard])) (describe "Should Assertions: " (context "should" @@ -305,7 +305,7 @@ (it "errors on unhandled types" (should-throw exception (str "should-contain doesn't know how to handle these types: [" (type-name (type 1)) " " (type-name (type 1)) "]") - (should-contain 1 2))) + (should-contain 1 2))) (it "handles nil containers gracefully" (should-fail! (should-contain "foo" nil)) @@ -340,7 +340,7 @@ (it "errors on unhandled types" (should-throw exception (str "should-not-contain doesn't know how to handle these types: [" (type-name (type 1)) " " (type-name (type 1)) "]") - (should-not-contain 1 2))) + (should-not-contain 1 2))) (it "handles nil containers gracefully" (should-pass! (should-not-contain "foo" nil)) @@ -368,9 +368,9 @@ (it "errors on unhandled types" (should-throw exception (str "should-have-count doesn't know how to handle these types: [" (type-name (type 1)) " " (type-name (type :not-countable)) "]") - (should-have-count 1 :not-countable)) + (should-have-count 1 :not-countable)) (should-throw exception (str "should-have-count doesn't know how to handle these types: [" (type-name (type :nan)) " " (type-name (type [])) "]") - (should-have-count :nan [])))) + (should-have-count :nan [])))) (context "should-not-have-count" (it "checks for anything but an exact count" @@ -392,9 +392,9 @@ (it "errors on unhandled types" (should-throw exception (str "should-not-have-count doesn't know how to handle these types: [" (type-name (type 1)) " " (type-name (type :not-countable)) "]") - (should-not-have-count 1 :not-countable)) + (should-not-have-count 1 :not-countable)) (should-throw exception (str "should-not-have-count doesn't know how to handle these types: [" (type-name (type :nan)) " " (type-name (type [])) "]") - (should-not-have-count :nan [])))) + (should-not-have-count :nan [])))) (context "should-not-be-nil" (it "checks for inequality with nil" @@ -429,7 +429,7 @@ (it "errors on unexpected types" (should-throw exception (str "should-start-with doesn't know how to handle these types: [" (type-name (type 1)) " " (type-name (type 1)) "]") - (should-start-with 1 2)))) + (should-start-with 1 2)))) (context "should-not-start-with" (it "checks for prefix in strings" @@ -448,7 +448,7 @@ (it "errors on unexpected types" (should-throw exception (str "should-not-start-with doesn't know how to handle these types: [" (type-name (type 1)) " " (type-name (type 1)) "]") - (should-not-start-with 1 2)))) + (should-not-start-with 1 2)))) (context "should-end-with" (it "checks for prefix in strings" @@ -468,7 +468,7 @@ (it "errors on unexpected types" (should-throw exception (str "should-end-with doesn't know how to handle these types: [" (type-name (type 1)) " " (type-name (type 1)) "]") - (should-end-with 1 2)))) + (should-end-with 1 2)))) (context "should-not-end-with" (it "checks for prefix in strings" @@ -487,7 +487,7 @@ (it "errors on unexpected types" (should-throw exception (str "should-not-end-with doesn't know how to handle these types: [" (type-name (type 1)) " " (type-name (type 1)) "]") - (should-not-end-with 1 2)))) + (should-not-end-with 1 2)))) (context "should-throw" #?(:clj @@ -540,18 +540,18 @@ (failure-message (should-throw exception #(speclj.platform/error-message %) (throw (-new-exception "Not my message"))))))) (context "should-not-throw" - (it "tests that nothing was thrown" - (should-pass! (should-not-throw (+ 1 1))) - (should-fail! (should-not-throw (throw (-new-throwable "error")))) - #?(:cljs - (should= - (str "Expected nothing thrown from: " (pr-str '(throw (-new-throwable "error"))) endl " but got: #object[String error]") - (failure-message (should-not-throw (throw (-new-throwable "error"))))) - :clj - (should-contain - (str "Expected nothing thrown from: " (pr-str '(throw (-new-throwable "error"))) endl - " but got: #error {\n :cause \"error\"\n :via\n [{:type java.lang.Throwable\n :message \"error\"\n") - (failure-message (should-not-throw (throw (-new-throwable "error")))))))) + (it "tests that nothing was thrown" + (should-pass! (should-not-throw (+ 1 1))) + (should-fail! (should-not-throw (throw (-new-throwable "error")))) + #?(:cljs + (should= + (str "Expected nothing thrown from: " (pr-str '(throw (-new-throwable "error"))) endl " but got: #object[String error]") + (failure-message (should-not-throw (throw (-new-throwable "error"))))) + :clj + (should-contain + (str "Expected nothing thrown from: " (pr-str '(throw (-new-throwable "error"))) endl + " but got: #error {\n :cause \"error\"\n :via\n [{:type java.lang.Throwable\n :message \"error\"\n") + (failure-message (should-not-throw (throw (-new-throwable "error")))))))) (context "should-be-a" @@ -590,9 +590,9 @@ (context "should<" (it "degenerate cases" (should-throw exception (str "should< doesn't know how to handle these types: [nil nil]") - (should< nil nil)) + (should< nil nil)) (should-throw exception (str "should< doesn't know how to handle these types: [" (type-name (type "a")) " " (type-name (type \a)) "]") - (should< "a" \a))) + (should< "a" \a))) (it "failure cases" (should-fail! (should< 1 0)) @@ -606,9 +606,9 @@ (context "should>" (it "degenerate cases" (should-throw exception (str "should> doesn't know how to handle these types: [nil nil]") - (should> nil nil)) + (should> nil nil)) (should-throw exception (str "should> doesn't know how to handle these types: [" (type-name (type "a")) " " (type-name (type \a)) "]") - (should> "a" \a))) + (should> "a" \a))) (it "failure cases" (should-fail! (should> 0 1)) @@ -622,9 +622,9 @@ (context "should<=" (it "degenerate cases" (should-throw exception (str "should<= doesn't know how to handle these types: [nil nil]") - (should<= nil nil)) + (should<= nil nil)) (should-throw exception (str "should<= doesn't know how to handle these types: [" (type-name (type "a")) " " (type-name (type \a)) "]") - (should<= "a" \a))) + (should<= "a" \a))) (it "failure cases" (should-fail! (should<= 1 0)) @@ -639,9 +639,9 @@ (context "should>=" (it "degenerate cases" (should-throw exception (str "should>= doesn't know how to handle these types: [nil nil]") - (should>= nil nil)) + (should>= nil nil)) (should-throw exception (str "should>= doesn't know how to handle these types: [" (type-name (type "a")) " " (type-name (type \a)) "]") - (should>= "a" \a))) + (should>= "a" \a))) (it "failure cases" (should-fail! (should>= 0 1)) @@ -655,4 +655,4 @@ ) -(run-specs :stacktrace true) +(standard/run-specs :stacktrace true) diff --git a/spec/speclj/stub_spec.cljc b/spec/speclj/stub_spec.cljc index 43587cf..9e36f69 100644 --- a/spec/speclj/stub_spec.cljc +++ b/spec/speclj/stub_spec.cljc @@ -1,10 +1,9 @@ (ns speclj.stub-spec - (#?(:clj :require :cljs :require-macros) - [speclj.core :refer [around before context describe it should= should-throw should-invoke should-have-invoked should-not-invoke should-not-have-invoked with with-stubs stub -new-exception]] - [speclj.spec-helper :refer [should-fail! should-pass! failure-message]]) - (:require [speclj.stub :as stub :refer [*stubbed-invocations* invocations-of first-invocation-of last-invocation-of]] + (:require [speclj.spec-helper #?(:clj :refer :cljs :refer-macros) [should-fail! should-pass! failure-message]] + [speclj.core #?(:clj :refer :cljs :refer-macros) [around before context describe it should= should-throw should-invoke should-have-invoked should-not-invoke should-not-have-invoked with with-stubs stub -new-exception]] + [speclj.stub :as stub] [speclj.platform :refer [endl exception]] - [speclj.run.standard :refer [run-specs]] + [speclj.run.standard :as standard] #?(:cljs [clojure.data]))) (defn foo-bar-fn [] nil) @@ -20,11 +19,11 @@ (it "invocations are recorded" (let [stub-fn (stub "fizz")] (stub-fn) - (should= [["fizz" []]] @*stubbed-invocations*) + (should= [["fizz" []]] @stub/*stubbed-invocations*) (stub-fn :bang) - (should= [["fizz" []] ["fizz" [:bang]]] @*stubbed-invocations*) + (should= [["fizz" []] ["fizz" [:bang]]] @stub/*stubbed-invocations*) (stub-fn :foo :bar) - (should= [["fizz" []] ["fizz" [:bang]] ["fizz" [:foo :bar]]] @*stubbed-invocations*))) + (should= [["fizz" []] ["fizz" [:bang]] ["fizz" [:foo :bar]]] @stub/*stubbed-invocations*))) (it "return values" (should= nil ((stub :foo))) @@ -52,7 +51,7 @@ #?(:clj (it "invoke with wrong number of params" (should-throw exception "Stub :foo was invoked with 0 arguments, but the :invoke fn has a different arity" - ((stub :foo {:invoke (fn [a] a)}))))) + ((stub :foo {:invoke (fn [a] a)}))))) (it "throw error when :invoke argument is not a fn" (should-throw exception "stub's :invoke argument must be an ifn" ((stub :foo {:invoke 42})))) @@ -86,16 +85,16 @@ (@bar 4)) (it "all" - (should= [[1] [2]] (invocations-of :foo)) - (should= [[3] [4]] (invocations-of :bar))) + (should= [[1] [2]] (stub/invocations-of :foo)) + (should= [[3] [4]] (stub/invocations-of :bar))) (it "first" - (should= [1] (first-invocation-of :foo)) - (should= [3] (first-invocation-of :bar))) + (should= [1] (stub/first-invocation-of :foo)) + (should= [3] (stub/first-invocation-of :bar))) (it "last" - (should= [2] (last-invocation-of :foo)) - (should= [4] (last-invocation-of :bar))) + (should= [2] (stub/last-invocation-of :foo)) + (should= [4] (stub/last-invocation-of :bar))) ) (context "clearing" @@ -105,8 +104,8 @@ (stub/clear!)) (it "removes all invocations" - (should= [] (invocations-of :foo)) - (should= [] (invocations-of :bar))) + (should= [] (stub/invocations-of :foo)) + (should= [] (stub/invocations-of :bar))) ) @@ -327,4 +326,4 @@ ) ) -(run-specs) +(standard/run-specs) diff --git a/spec/speclj/tags_spec.cljc b/spec/speclj/tags_spec.cljc index a2ffa64..a3c6226 100644 --- a/spec/speclj/tags_spec.cljc +++ b/spec/speclj/tags_spec.cljc @@ -1,69 +1,68 @@ (ns speclj.tags-spec - (#?(:clj :require :cljs :require-macros) - [speclj.core :refer [around context describe it should= tags]]) - (:require [clojure.string :as str] - [speclj.config :refer [*runner* *reporters*]] - [speclj.report.silent :refer [new-silent-reporter]] - [speclj.run.standard :refer [new-standard-runner run-specs]] - [speclj.tags :refer [tag-sets-for pass-includes? pass-excludes? pass-tag-filter? describe-filter]])) + (:require [speclj.core #?(:clj :refer :cljs :refer-macros) [around context describe it should= tags]] + [clojure.string :as str] + [speclj.config :as config] + [speclj.report.silent :as silent] + [speclj.run.standard :as standard] + [speclj.tags :as sut])) (describe "Tags" (it "filters included tags" - (should= true (pass-includes? #{} [:one])) - (should= true (pass-includes? #{} [:two])) - (should= true (pass-includes? #{:one} [:one])) - (should= false (pass-includes? #{:one} [:two])) - (should= true (pass-includes? #{:one :two} [:one :two])) - (should= false (pass-includes? #{:one :two} [:one])) - (should= true (pass-includes? #{:one :two} [:one :two :three])) - (should= true (pass-includes? #{} [:one :two :three]))) + (should= true (sut/pass-includes? #{} [:one])) + (should= true (sut/pass-includes? #{} [:two])) + (should= true (sut/pass-includes? #{:one} [:one])) + (should= false (sut/pass-includes? #{:one} [:two])) + (should= true (sut/pass-includes? #{:one :two} [:one :two])) + (should= false (sut/pass-includes? #{:one :two} [:one])) + (should= true (sut/pass-includes? #{:one :two} [:one :two :three])) + (should= true (sut/pass-includes? #{} [:one :two :three]))) (it "filters excluded tags" - (should= true (pass-excludes? #{} [:one])) - (should= true (pass-excludes? #{} [:two])) - (should= false (pass-excludes? #{:one} [:one])) - (should= true (pass-excludes? #{:one} [:two])) - (should= false (pass-excludes? #{:one :two} [:one :two])) - (should= true (pass-excludes? #{:one :two} [:three :four])) - (should= false (pass-excludes? #{:one :two} [:three :four :one]))) + (should= true (sut/pass-excludes? #{} [:one])) + (should= true (sut/pass-excludes? #{} [:two])) + (should= false (sut/pass-excludes? #{:one} [:one])) + (should= true (sut/pass-excludes? #{:one} [:two])) + (should= false (sut/pass-excludes? #{:one :two} [:one :two])) + (should= true (sut/pass-excludes? #{:one :two} [:three :four])) + (should= false (sut/pass-excludes? #{:one :two} [:three :four :one]))) (it "filters tags" - (should= true (pass-tag-filter? {:includes #{} :excludes #{}} [:one :two :three])) - (should= true (pass-tag-filter? {:includes #{:one} :excludes #{}} [:one :two :three])) - (should= true (pass-tag-filter? {:includes #{:one :two :three} :excludes #{}} [:one :two :three])) - (should= true (pass-tag-filter? {:includes #{} :excludes #{:four}} [:one :two :three])) - (should= false (pass-tag-filter? {:includes #{} :excludes #{:one}} [:one :two :three]))) + (should= true (sut/pass-tag-filter? {:includes #{} :excludes #{}} [:one :two :three])) + (should= true (sut/pass-tag-filter? {:includes #{:one} :excludes #{}} [:one :two :three])) + (should= true (sut/pass-tag-filter? {:includes #{:one :two :three} :excludes #{}} [:one :two :three])) + (should= true (sut/pass-tag-filter? {:includes #{} :excludes #{:four}} [:one :two :three])) + (should= false (sut/pass-tag-filter? {:includes #{} :excludes #{:one}} [:one :two :three]))) (it "describes the filter" - (should= nil (describe-filter {:includes #{} :excludes #{}})) - (should= "Filtering tags. Including: one." (str/trim (describe-filter {:includes #{:one} :excludes #{}}))) - (should= "Filtering tags. Excluding: one." (str/trim (describe-filter {:includes #{} :excludes #{:one}}))) - (should= "Filtering tags. Including: one, two." (str/trim (describe-filter {:includes #{:one :two} :excludes #{}}))) - (should= "Filtering tags. Including: one. Excluding: two." (str/trim (describe-filter {:includes #{:one} :excludes #{:two}})))) + (should= nil (sut/describe-filter {:includes #{} :excludes #{}})) + (should= "Filtering tags. Including: one." (str/trim (sut/describe-filter {:includes #{:one} :excludes #{}}))) + (should= "Filtering tags. Excluding: one." (str/trim (sut/describe-filter {:includes #{} :excludes #{:one}}))) + (should= "Filtering tags. Including: one, two." (str/trim (sut/describe-filter {:includes #{:one :two} :excludes #{}}))) + (should= "Filtering tags. Including: one. Excluding: two." (str/trim (sut/describe-filter {:includes #{:one} :excludes #{:two}})))) #?(:clj (context "with fake runner/reporter" (around [_] - (binding [*runner* (new-standard-runner) - *reporters* (new-silent-reporter) - *ns* (the-ns 'speclj.tags-spec)] + (binding [config/*runner* (standard/new-standard-runner) + config/*reporters* (silent/new-silent-reporter) + *ns* (the-ns 'speclj.tags-spec)] (_))) (it "finds all the tag sets with one context" (let [spec (eval '(describe "foo"))] - (should= [#{}] (tag-sets-for spec))) + (should= [#{}] (sut/tag-sets-for spec))) (let [spec (eval '(describe "foo" (tags :one)))] - (should= [#{:one}] (tag-sets-for spec)))) + (should= [#{:one}] (sut/tag-sets-for spec)))) (it "finds all the tag sets with nested contexts" (let [spec (eval '(describe "foo" (tags :one) (context "child" (tags :two) - (context "grandchild" (tags :three :four)) - (context "grandchild2" (tags :five))) + (context "grandchild" (tags :three :four)) + (context "grandchild2" (tags :five))) (context "child2" (tags :six)))) - tag-sets (tag-sets-for spec)] + tag-sets (sut/tag-sets-for spec)] (should= 5 (count tag-sets)) (should= #{:one} (nth tag-sets 0)) (should= #{:one :two} (nth tag-sets 1)) @@ -74,4 +73,4 @@ )) ) -(run-specs) +(standard/run-specs) diff --git a/src/speclj/config.cljc b/src/speclj/config.cljc index 7999220..d363a05 100644 --- a/src/speclj/config.cljc +++ b/src/speclj/config.cljc @@ -1,5 +1,6 @@ (ns speclj.config - (:require [speclj.platform :refer [dynamically-invoke]])) + (:require [clojure.string :as str] + [speclj.platform :as platform])) (declare ^:dynamic *parent-description*) @@ -49,7 +50,7 @@ [] (let [ns (the-ns 'speclj.config) all-vars (dissoc (ns-interns ns) '*parent-description*) - non-config-keys (filter #(not (.startsWith (name %) "*")) (keys all-vars)) + non-config-keys (remove #(str/starts-with? (name %) "*") (keys all-vars)) config-vars (apply dissoc all-vars non-config-keys)] (reduce #(assoc %1 %2 (deref %2)) {} (vals config-vars)))) @@ -58,36 +59,39 @@ (defn load-runner [name] (try - (dynamically-invoke (str "speclj.run." name) (str "new-" name "-runner")) + (platform/dynamically-invoke (str "speclj.run." name) (str "new-" name "-runner")) (catch #?(:clj java.lang.Exception :cljs :default) e (throw (new #?(:clj java.lang.Exception :cljs js/Error) (str "Failed to load runner: " name) e))))) (defn- load-reporter-by-name [name] (try - (dynamically-invoke (str "speclj.report." name) (str "new-" name "-reporter")) + (platform/dynamically-invoke (str "speclj.report." name) (str "new-" name "-reporter")) (catch #?(:clj java.lang.Exception :cljs :default) e (throw (new #?(:clj java.lang.Exception :cljs js/Error) (str "Failed to load reporter: " name) e))))) -#?(:clj - (defn load-reporter [name-or-object] - (if (instance? (Class/forName "speclj.reporting.Reporter") name-or-object) - name-or-object - (load-reporter-by-name name-or-object))) +(defn- load-reporter-by-name? [name-or-object] + #?(:clj (->> name-or-object + (instance? (Class/forName "speclj.reporting.Reporter")) + not) + :cljs (string? name-or-object))) - :cljs - (defn load-reporter [name-or-object] - (if (string? name-or-object) - (load-reporter-by-name name-or-object) - name-or-object))) - -(defn parse-tags [values] - (loop [result {:includes #{} :excludes #{}} values values] - (if (seq values) - (let [value (name (first values))] - (if (= \~ (first value)) - (recur (update-in result [:excludes] conj (keyword (apply str (rest value)))) (rest values)) - (recur (update-in result [:includes] conj (keyword value)) (rest values)))) - result))) +(defn load-reporter [name-or-object] + (cond-> name-or-object + (load-reporter-by-name? name-or-object) + load-reporter-by-name)) + +(defn- parse-tag [tag] + (let [tag (name tag)] + (if (str/starts-with? tag "~") + [:excludes (str/replace tag #"^~" "")] + [:includes tag]))) + +(defn- with-tag [tag-filter tag] + (let [[flag value] (parse-tag tag)] + (update tag-filter flag conj (keyword value)))) + +(defn parse-tags [tags] + (reduce with-tag {:includes #{} :excludes #{}} tags)) #?(:clj (defn config-mappings [config] @@ -99,7 +103,6 @@ #'*full-stack-trace?* (not (nil? (:stacktrace config))) #'*tag-filter* (parse-tags (:tags config))}) - :cljs (defn config-mappings [_] (throw "Not Supported in ClojureScript"))) @@ -111,6 +114,6 @@ *specs* (:specs config) *color?* (:color config) *omit-pending?* (:omit-pending config) - *full-stack-trace?* (not (nil? (:stacktrace config))) + *full-stack-trace?* (some? (:stacktrace config)) *tag-filter* (parse-tags (:tags config))] (action))) diff --git a/src/speclj/run/standard.cljs b/src/speclj/run/standard.cljs index d65c294..484c3f6 100644 --- a/src/speclj/run/standard.cljs +++ b/src/speclj/run/standard.cljs @@ -1,47 +1,46 @@ (ns speclj.run.standard - (:require [speclj.components] - [speclj.config :refer [active-reporters active-runner default-config default-runner - default-runner-fn with-config]] - [speclj.report.progress] ; so that we can load the default reporter - [speclj.reporting :refer [report-message* report-runs*]] - [speclj.results :refer [fail-count]] - [speclj.running :refer [do-description filter-focused run-and-report run-description]] - [speclj.tags :refer [describe-filter]])) + (:require [speclj.components :as components] + [speclj.config :as config] + [speclj.report.progress] ; so that we can load the default reporter + [speclj.reporting :as reporting] + [speclj.results :as results] + [speclj.running :as running] + [speclj.tags :as tags])) (def counter (atom 0)) (deftype StandardRunner [num descriptions results] - speclj.running/Runner - (run-directories [this directories reporters] + running/Runner + (run-directories [_this _directories _reporters] (js/alert "StandardRunner.run-directories: I don't know how to do this.")) - (submit-description [this description] + (submit-description [_this description] (swap! descriptions conj description)) - (run-description [this description reporters] - (let [run-results (do-description description reporters)] + (run-description [_this description reporters] + (let [run-results (running/do-description description reporters)] (swap! results into run-results))) (run-and-report [this reporters] - (doseq [description (filter-focused @descriptions)] - (run-description this description reporters)) - (report-runs* reporters @results))) + (doseq [description (running/filter-focused @descriptions)] + (running/run-description this description reporters)) + (reporting/report-runs* reporters @results))) (extend-protocol IPrintWithWriter - speclj.run.standard.StandardRunner + StandardRunner (-pr-writer [x writer opts] (-write writer (str "#")) - speclj.components.Description - (-pr-writer [x writer opts] + components/Description + (-pr-writer [x writer _opts] (-write writer (str "#")))) (defn new-standard-runner [] (StandardRunner. (swap! counter inc) (atom []) (atom []))) -(reset! default-runner-fn new-standard-runner) -(reset! default-runner (new-standard-runner)) +(reset! config/default-runner-fn new-standard-runner) +(reset! config/default-runner (new-standard-runner)) (def armed false) (defn run-specs [& configurations] @@ -51,10 +50,10 @@ are evaluated by evaluation the file as a script. Optional configuration parame (run-specs :stacktrace true :color false :reporters [\"documentation\"])" (when armed - (with-config - (merge (dissoc default-config :runner) (apply hash-map configurations)) + (config/with-config + (merge (dissoc config/default-config :runner) (apply hash-map configurations)) (fn [] - (if-let [filter-msg (describe-filter)] - (report-message* (active-reporters) filter-msg)) - (run-and-report (active-runner) (active-reporters)) - (fail-count @(.-results (active-runner))))))) + (if-let [filter-msg (tags/describe-filter)] + (reporting/report-message* (config/active-reporters) filter-msg)) + (running/run-and-report (config/active-runner) (config/active-reporters)) + (results/fail-count @(.-results (config/active-runner))))))) From b0b7a64ea6996b0ca675359c055a7b8a17c65baf Mon Sep 17 00:00:00 2001 From: Brandon Correa <50252804+brandoncorrea@users.noreply.github.com> Date: Sat, 25 May 2024 13:52:24 -0500 Subject: [PATCH 02/16] Merge clj/s standard runners into one cljc file --- src/speclj/config.cljc | 2 +- src/speclj/run/standard.clj | 60 ------------------ src/speclj/run/standard.cljc | 115 +++++++++++++++++++++++++++++++++++ src/speclj/run/standard.cljs | 59 ------------------ 4 files changed, 116 insertions(+), 120 deletions(-) delete mode 100644 src/speclj/run/standard.clj create mode 100644 src/speclj/run/standard.cljc delete mode 100644 src/speclj/run/standard.cljs diff --git a/src/speclj/config.cljc b/src/speclj/config.cljc index d363a05..d066b86 100644 --- a/src/speclj/config.cljc +++ b/src/speclj/config.cljc @@ -100,7 +100,7 @@ #'*specs* (:specs config) #'*color?* (:color config) #'*omit-pending?* (:omit-pending config) - #'*full-stack-trace?* (not (nil? (:stacktrace config))) + #'*full-stack-trace?* (some? (:stacktrace config)) #'*tag-filter* (parse-tags (:tags config))}) :cljs diff --git a/src/speclj/run/standard.clj b/src/speclj/run/standard.clj deleted file mode 100644 index e86629d..0000000 --- a/src/speclj/run/standard.clj +++ /dev/null @@ -1,60 +0,0 @@ -(ns speclj.run.standard - (:require [clojure.java.io :refer [file]] - [fresh.core :refer [clj-files-in]] - [speclj.config :refer [*reporters* *runner* active-reporters active-runner config-mappings - default-config default-runner default-runner-fn]] - [speclj.reporting :refer [report-message* report-runs*]] - [speclj.results :refer [fail-count]] - [speclj.running :refer [do-description filter-focused process-compile-error run-and-report run-description]] - [speclj.tags :refer [describe-filter]]) - (:import (speclj.running Runner))) - -(defn- load-spec [spec-file] - (let [src (slurp (.getCanonicalPath spec-file)) - rdr (-> (java.io.StringReader. src) (clojure.lang.LineNumberingPushbackReader.)) - path (.getAbsolutePath spec-file)] - (clojure.lang.Compiler/load rdr path path))) - -(deftype StandardRunner [descriptions results] - Runner - (run-directories [this directories reporters] - (let [dir-files (map file directories) - files (apply clj-files-in dir-files) - files (sort files)] - (binding [*runner* this *reporters* reporters] - (doseq [file files] - (try - (load-spec file) - (catch java.lang.Throwable e - (process-compile-error this e)))))) - (run-and-report this reporters) - (fail-count @results)) - - (submit-description [this description] - (swap! descriptions conj description)) - - (run-description [this description reporters] - (let [run-results (do-description description reporters)] - (swap! results into run-results))) - - (run-and-report [this reporters] - (doseq [description (filter-focused @descriptions)] - (run-description this description reporters)) - (report-runs* reporters @results))) - -(defn new-standard-runner [] - (StandardRunner. (atom []) (atom []))) - -(reset! default-runner-fn new-standard-runner) - -(defn run-specs [& configurations] - (when (identical? (active-runner) @default-runner) ; Solo file run? - (let [config (apply hash-map configurations) - config (merge (dissoc default-config :runner) config)] - (with-bindings (config-mappings config) - (if-let [filter-msg (describe-filter)] - (report-message* (active-reporters) filter-msg)) - (run-and-report (active-runner) (active-reporters)) - (reset! default-runner (@default-runner-fn)))))) - -(reset! default-runner (@default-runner-fn)) diff --git a/src/speclj/run/standard.cljc b/src/speclj/run/standard.cljc new file mode 100644 index 0000000..f1f2370 --- /dev/null +++ b/src/speclj/run/standard.cljc @@ -0,0 +1,115 @@ +(ns speclj.run.standard + (:require #?(:clj [clojure.java.io :as io]) + #?(:clj [fresh.core :as fresh]) + #?(:cljs [speclj.report.progress]) + #?(:cljs [speclj.components :as components]) + [speclj.config :as config] + [speclj.reporting :as reporting] + [speclj.results :as results] + [speclj.running :as running] + [speclj.tags :as tags]) + #?(:clj (:import (clojure.lang Compiler LineNumberingPushbackReader) + (java.io StringReader)))) + +#?(:cljs (def armed false)) +#?(:cljs (def counter (atom 0))) + +#?(:clj + (do + (defn- file->pushback-reader [file] + (-> file + (.getCanonicalPath) + slurp + (StringReader.) + (LineNumberingPushbackReader.))) + + (defn- load-spec [spec-file] + (let [rdr (file->pushback-reader spec-file) + path (.getAbsolutePath spec-file)] + (Compiler/load rdr path path))) + + (defn- try-load-spec [runner file] + (try + (load-spec file) + (catch Throwable e + (running/process-compile-error runner e)))) + )) + +;; TODO [BAC]: cljs breaks StandardRunner interface. +;; Is num necessary for cljs? +;; Should clj have num as well? +(deftype StandardRunner [#?(:cljs num) descriptions results] + running/Runner + #?(:clj + (run-directories [this directories reporters] + (let [files (->> (map io/file directories) + (apply fresh/clj-files-in) + sort)] + (binding [config/*runner* this + config/*reporters* reporters] + (run! #(try-load-spec this %) files))) + (running/run-and-report this reporters) + (results/fail-count @results)) + :cljs + (run-directories [_this _directories _reporters] + (js/alert "StandardRunner.run-directories: I don't know how to do this."))) + + (submit-description [_this description] + (swap! descriptions conj description)) + + (run-description [_this description reporters] + (let [run-results (running/do-description description reporters)] + (swap! results into run-results))) + + (run-and-report [this reporters] + (doseq [description (running/filter-focused @descriptions)] + (running/run-description this description reporters)) + (reporting/report-runs* reporters @results))) + +#?(:cljs + (extend-protocol IPrintWithWriter + StandardRunner + (-pr-writer [x writer opts] + (-write writer (str "#")) + components/Description + (-pr-writer [x writer _opts] + (-write writer (str "#"))))) + +(defn new-standard-runner [] + (StandardRunner. #?(:cljs (swap! counter inc)) (atom []) (atom []))) + +(reset! config/default-runner-fn new-standard-runner) +(reset! config/default-runner (new-standard-runner)) + +(defn- execute-active-runner [] + (when-let [filter-msg (tags/describe-filter)] + (reporting/report-message* (config/active-reporters) filter-msg)) + (running/run-and-report (config/active-runner) (config/active-reporters))) + +(defn- config-with-defaults [configurations] + (merge (dissoc config/default-config :runner) + (apply hash-map configurations))) + +#?(:clj + (defn run-specs [& configurations] + (when (identical? (config/active-runner) @config/default-runner) ; Solo file run? + (let [config (config-with-defaults configurations)] + (with-bindings (config/config-mappings config) + (execute-active-runner) + (reset! config/default-runner (@config/default-runner-fn)))))) + + :cljs + (defn run-specs [& configurations] + "If evaluated outside the context of a spec run, it will run all the specs that have been evaluated using the default + runner and reporter. A call to this function is typically placed at the end of a spec file so that all the specs + are evaluated by evaluation the file as a script. Optional configuration parameters may be passed in: + + (run-specs :stacktrace true :color false :reporters [\"documentation\"])" + (when armed + (config/with-config + (config-with-defaults configurations) + (fn [] + (execute-active-runner) + (results/fail-count @(.-results (config/active-runner)))))))) diff --git a/src/speclj/run/standard.cljs b/src/speclj/run/standard.cljs deleted file mode 100644 index 484c3f6..0000000 --- a/src/speclj/run/standard.cljs +++ /dev/null @@ -1,59 +0,0 @@ -(ns speclj.run.standard - (:require [speclj.components :as components] - [speclj.config :as config] - [speclj.report.progress] ; so that we can load the default reporter - [speclj.reporting :as reporting] - [speclj.results :as results] - [speclj.running :as running] - [speclj.tags :as tags])) - -(def counter (atom 0)) - -(deftype StandardRunner [num descriptions results] - running/Runner - (run-directories [_this _directories _reporters] - (js/alert "StandardRunner.run-directories: I don't know how to do this.")) - - (submit-description [_this description] - (swap! descriptions conj description)) - - (run-description [_this description reporters] - (let [run-results (running/do-description description reporters)] - (swap! results into run-results))) - - (run-and-report [this reporters] - (doseq [description (running/filter-focused @descriptions)] - (running/run-description this description reporters)) - (reporting/report-runs* reporters @results))) - -(extend-protocol IPrintWithWriter - StandardRunner - (-pr-writer [x writer opts] - (-write writer (str "#")) - components/Description - (-pr-writer [x writer _opts] - (-write writer (str "#")))) - -(defn new-standard-runner [] - (StandardRunner. (swap! counter inc) (atom []) (atom []))) - -(reset! config/default-runner-fn new-standard-runner) -(reset! config/default-runner (new-standard-runner)) -(def armed false) - -(defn run-specs [& configurations] - "If evaluated outside the context of a spec run, it will run all the specs that have been evaluated using the default -runner and reporter. A call to this function is typically placed at the end of a spec file so that all the specs -are evaluated by evaluation the file as a script. Optional configuration parameters may be passed in: - -(run-specs :stacktrace true :color false :reporters [\"documentation\"])" - (when armed - (config/with-config - (merge (dissoc config/default-config :runner) (apply hash-map configurations)) - (fn [] - (if-let [filter-msg (tags/describe-filter)] - (reporting/report-message* (config/active-reporters) filter-msg)) - (running/run-and-report (config/active-runner) (config/active-reporters)) - (results/fail-count @(.-results (config/active-runner))))))) From 819dc36de9578e868734f2707e20ccd4ad40bd7f Mon Sep 17 00:00:00 2001 From: Brandon Correa <50252804+brandoncorrea@users.noreply.github.com> Date: Sat, 25 May 2024 14:36:23 -0500 Subject: [PATCH 03/16] More refactoring around run-specs + run-specs now accepts string or keyword configuration keys --- examples/basics/basic_spec.clj | 8 ++------ examples/basics/calulator_spec.clj | 7 ++----- spec/speclj/report/clojure_test_spec.clj | 6 +++--- spec/speclj/run/standard_spec.clj | 26 +++++++++++++++--------- spec/speclj/running_spec.clj | 8 ++++---- src/speclj/run/standard.cljc | 7 ++++--- 6 files changed, 31 insertions(+), 31 deletions(-) diff --git a/examples/basics/basic_spec.clj b/examples/basics/basic_spec.clj index 0536833..fe216bb 100644 --- a/examples/basics/basic_spec.clj +++ b/examples/basics/basic_spec.clj @@ -1,6 +1,6 @@ (ns basics-spec (:require [speclj.core :refer :all] - [speclj.run.standard :refer [run-specs]])) + [speclj.run.standard :as standard])) ;(describe "Truth" ; @@ -10,7 +10,6 @@ ; (it "is not false" ; (should-not false))) - (declare *the-answer*) (describe "Calculator" @@ -34,7 +33,4 @@ (should= 42 *the-answer*)) ) - -(run-specs) - - +(standard/run-specs) diff --git a/examples/basics/calulator_spec.clj b/examples/basics/calulator_spec.clj index 00926bd..f7bcef8 100644 --- a/examples/basics/calulator_spec.clj +++ b/examples/basics/calulator_spec.clj @@ -1,8 +1,6 @@ (ns basics-spec.calulator_spec (:require [speclj.core :refer :all] - [speclj.run.standard :refer [run-specs]])) - - + [speclj.run.standard :as standard])) (describe "Calculator" @@ -28,5 +26,4 @@ (should= 42 *the-answer*)) ) - -(run-specs) +(standard/run-specs) diff --git a/spec/speclj/report/clojure_test_spec.clj b/spec/speclj/report/clojure_test_spec.clj index d02b34f..76f4451 100644 --- a/spec/speclj/report/clojure_test_spec.clj +++ b/spec/speclj/report/clojure_test_spec.clj @@ -1,5 +1,5 @@ (ns speclj.report.clojure-test-spec - (:require ;cljs-macros + (:require ;cljs-macros [clojure.string :as str] [clojure.test] ;cljs-include [goog.string] ;cljs bug? @@ -8,7 +8,7 @@ [speclj.report.clojure-test :refer [new-clojure-test-reporter]] [speclj.reporting :refer [report-error report-fail report-pass report-pending report-runs]] [speclj.results :refer [error-result fail-result]] - [speclj.run.standard :refer [run-specs]])) + [speclj.run.standard :as standard])) (defmacro with-test-out-str [& body] `(let [s# (new java.io.StringWriter)] @@ -65,4 +65,4 @@ (should= "1 failures, 1 errors." (nth lines 2)))) ) -(run-specs) +(standard/run-specs) diff --git a/spec/speclj/run/standard_spec.clj b/spec/speclj/run/standard_spec.clj index 4730998..9386449 100644 --- a/spec/speclj/run/standard_spec.clj +++ b/spec/speclj/run/standard_spec.clj @@ -1,8 +1,9 @@ (ns speclj.run.standard-spec - (:require [speclj.core :refer [describe it should= with]] - [speclj.report.silent :refer [new-silent-reporter]] - [speclj.run.standard :refer :all] - [speclj.running :refer [run-directories]]) + (:require [speclj.config :as config] + [speclj.core :refer :all] + [speclj.report.silent :as silent] + [speclj.run.standard :as sut] + [speclj.running :as running]) (:import (java.io File))) (defn find-dir @@ -19,22 +20,27 @@ (def focus-dir (.getCanonicalPath (File. examples-dir "focus"))) (describe "StandardRunner" - (with runner (new-standard-runner)) - (with reporters [(new-silent-reporter)]) + (with runner (sut/new-standard-runner)) + (with reporters [(silent/new-silent-reporter)]) (it "returns 0 failures when all tests pass" - (should= 0 (run-directories @runner [prime-factors-dir] @reporters))) + (should= 0 (running/run-directories @runner [prime-factors-dir] @reporters))) (it "returns lots-o failures when running failure example" - (should= 8 (run-directories @runner [failures-dir] @reporters))) + (should= 8 (running/run-directories @runner [failures-dir] @reporters))) (it "limits execution to focused components" - (run-directories @runner [focus-dir] @reporters) + (running/run-directories @runner [focus-dir] @reporters) (should= ["yes-1" "yes-2" "yes-3" "yes-4" "yes-5" "yes-6"] (->> @(.-results @runner) (map #(.-characteristic %)) (map #(.-name %))))) + (it "config with defaults" + (let [defaults (dissoc config/default-config :runner)] + (should= defaults (sut/config-with-defaults [])) + (should= (assoc defaults :foo :bar) (sut/config-with-defaults [:foo :bar])) + (should= (assoc defaults :foo :bar :baz "buzz") (sut/config-with-defaults [:foo :bar "baz" "buzz"])))) ) -(run-specs) +(sut/run-specs) diff --git a/spec/speclj/running_spec.clj b/spec/speclj/running_spec.clj index bc39df7..29efb25 100644 --- a/spec/speclj/running_spec.clj +++ b/spec/speclj/running_spec.clj @@ -1,19 +1,19 @@ (ns speclj.running-spec (:require [speclj.config :refer [*reporters* *runner* *tag-filter*]] [speclj.core :refer [after around before-all context describe - it focus-it should should-fail should-not + it should should-fail should-not should-not-throw should-not= should= tags with with-all]] [speclj.platform :as platform] [speclj.report.silent :refer [new-silent-reporter]] [speclj.results :refer [fail?]] - [speclj.run.standard :refer [new-standard-runner run-specs]] + [speclj.run.standard :as standard] [speclj.running :refer [run-and-report]])) (def bauble (atom nil)) (describe "Running" - (with runner (new-standard-runner)) + (with runner (standard/new-standard-runner)) (around [_] (binding [*runner* @runner *reporters* [(new-silent-reporter)] @@ -83,7 +83,7 @@ `(describe "Dummy" (tags :one) (it "one tag" :filler) (context "Fool" (tags :two) - (it "one, two tag" :filler)))) + (it "one, two tag" :filler)))) (binding [*tag-filter* {:includes #{:one :two} :excludes #{}}] (run-and-report *runner* *reporters*)) (let [results @(.-results *runner*)] diff --git a/src/speclj/run/standard.cljc b/src/speclj/run/standard.cljc index f1f2370..6376b6c 100644 --- a/src/speclj/run/standard.cljc +++ b/src/speclj/run/standard.cljc @@ -88,9 +88,10 @@ (reporting/report-message* (config/active-reporters) filter-msg)) (running/run-and-report (config/active-runner) (config/active-reporters))) -(defn- config-with-defaults [configurations] - (merge (dissoc config/default-config :runner) - (apply hash-map configurations))) +(defn config-with-defaults [configurations] + (as-> (apply hash-map configurations) $ + (update-keys $ keyword) + (merge (dissoc config/default-config :runner) $))) #?(:clj (defn run-specs [& configurations] From 14a50d6824e9b1faa61a5a6849bc7d002f53e5f2 Mon Sep 17 00:00:00 2001 From: Brandon Correa <50252804+brandoncorrea@users.noreply.github.com> Date: Sat, 25 May 2024 14:37:43 -0500 Subject: [PATCH 04/16] Update changelog --- CHANGES.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGES.md b/CHANGES.md index 1b00e87..ec4dbc4 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,3 +1,7 @@ +# 3.4.8 + +* `run-specs` now accepts string keys in addition to keyword keys + # 3.4.7 * fixes bug where `should-throw` would expand string predicates improperly under cljs whitespace optimizations. From 353f78e8a8bb4dbb93f94afb30c9d555ad1531b3 Mon Sep 17 00:00:00 2001 From: Brandon Correa <50252804+brandoncorrea@users.noreply.github.com> Date: Sun, 26 May 2024 14:18:40 -0500 Subject: [PATCH 05/16] Export functions needed by advanced cljs builds --- CHANGES.md | 2 + README.md | 2 +- bin/specs.html | 11 +++-- spec/speclj/config_spec.cljc | 47 +++++++++++----------- spec/speclj/report/documentation_spec.cljc | 9 ++++- spec/speclj/run/standard_spec.cljs | 27 +++++++++++++ spec/speclj/spec_helper.cljc | 8 +++- src/speclj/config.cljc | 2 +- src/speclj/report/documentation.cljc | 28 +++++++------ src/speclj/run/standard.cljc | 13 ++++-- 10 files changed, 98 insertions(+), 51 deletions(-) create mode 100644 spec/speclj/run/standard_spec.cljs diff --git a/CHANGES.md b/CHANGES.md index ec4dbc4..edacd85 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,6 +1,8 @@ # 3.4.8 * `run-specs` now accepts string keys in addition to keyword keys +* js runner executable may use `speclj.run.standard.arm()` instead of `speclj.run.standard.armed = true` +* exports functions used by JavaScript for executing ClojureScript specs # 3.4.7 diff --git a/README.md b/README.md index b3b2b50..96dcdd9 100644 --- a/README.md +++ b/README.md @@ -245,7 +245,7 @@ p.onConsoleMessage = function (x) { p.injectJs(phantom.args[0]); var result = p.evaluate(function () { - speclj.run.standard.armed = true; + speclj.run.standard.arm(); return speclj.run.standard.run_specs( cljs.core.keyword("color"), true ); diff --git a/bin/specs.html b/bin/specs.html index e185d6a..7d1422b 100644 --- a/bin/specs.html +++ b/bin/specs.html @@ -12,7 +12,7 @@ }; // Load all the specs - for(var k in goog.debugLoader_.dependencies_) { + for (var k in goog.debugLoader_.dependencies_) { var dep = goog.debugLoader_.dependencies_[k]; for (var i = 0; i < dep.provides.length; i++) { var ns = dep.provides[i]; @@ -24,10 +24,9 @@ } runSpecsConfigured = function (color, reporter) { - speclj.run.standard.armed = true; + speclj.run.standard.arm(); return speclj.run.standard.run_specs( - cljs.core.keyword("color"), color - , cljs.core.keyword("reporters"), [reporter] + "color", color, "reporters", [reporter] ); }; @@ -36,7 +35,7 @@ } runSpecsFiltered = function (affectedSpecs) { - if(affectedSpecs != null) { + if (affectedSpecs != null) { console.log("Only running affected specs:"); var descriptionAtom = speclj.config.active_runner().descriptions; cljs.core.swap_BANG_(descriptionAtom, function (descriptions) { @@ -66,4 +65,4 @@

Speclj CLJS Specs

runSpecs() - \ No newline at end of file + diff --git a/spec/speclj/config_spec.cljc b/spec/speclj/config_spec.cljc index 934c6c5..ac06777 100644 --- a/spec/speclj/config_spec.cljc +++ b/spec/speclj/config_spec.cljc @@ -1,68 +1,69 @@ (ns speclj.config-spec - (#?(:cljs :require-macros :clj :require) - [speclj.core :refer [describe it should-not= should= should-throw should-not-contain should-be-same]]) - (:require [speclj.config :refer [load-runner load-reporter default-config - parse-tags config-mappings *tag-filter* config-bindings]] + (:require [speclj.core #?(:clj :refer :cljs :refer-macros) [describe context it should-not= should= should-throw should-not-contain should-not-be-nil should-be-same]] + [speclj.spec-helper #?(:clj :refer :cljs :refer-macros) [test-exported-meta]] + [speclj.config :as sut] [speclj.platform :as platform] [speclj.report.progress] [speclj.report.silent] [speclj.run.standard :as standard])) - (describe "Config" (it "dynamically loads StandardRunner" - (let [runner (load-runner "standard")] + (let [runner (sut/load-runner "standard")] (should-not= nil runner) (should= speclj.run.standard.StandardRunner (type runner)))) #?(:clj (it "dynamically loads VigilantRunner" - (let [runner (load-runner "vigilant")] + (let [runner (sut/load-runner "vigilant")] (should-not= nil runner) (should= "speclj.run.vigilant.VigilantRunner" (.getName (type runner)))))) (it "throws exception with unrecognized runner" - (should-throw platform/exception "Failed to load runner: blah" (load-runner "blah"))) + (should-throw platform/exception "Failed to load runner: blah" (sut/load-runner "blah"))) (it "dynamically loads ProgressReporter" - (let [reporter (load-reporter "progress")] + (let [reporter (sut/load-reporter "progress")] (should-not= nil reporter) (should= speclj.report.progress.ProgressReporter (type reporter)))) (it "dynamically loads SilentReporter" - (let [reporter (load-reporter "silent")] - (should-not= nil reporter) + (let [reporter (sut/load-reporter "silent")] + (should-not-be-nil reporter) (should= speclj.report.silent.SilentReporter (type reporter)))) (it "throws exception with unrecognized reporter" - (should-throw platform/exception "Failed to load reporter: blah" (load-reporter "blah"))) + (should-throw platform/exception "Failed to load reporter: blah" (sut/load-reporter "blah"))) (it "can be given a pre-fabricated reporter" (let [pre-fabricated-reporter (speclj.report.silent/new-silent-reporter) - reporter (load-reporter pre-fabricated-reporter)] + reporter (sut/load-reporter pre-fabricated-reporter)] (should-not= nil reporter) (should-be-same reporter pre-fabricated-reporter))) (it "converts tag input to includes/excludes" - (should= {:includes #{} :excludes #{}} (parse-tags [])) - (should= {:includes #{:one} :excludes #{}} (parse-tags [:one])) - (should= {:includes #{:one} :excludes #{}} (parse-tags ["one"])) - (should= {:includes #{:one :two} :excludes #{}} (parse-tags ["one" 'two])) - (should= {:includes #{} :excludes #{:one}} (parse-tags ["~one"])) - (should= {:includes #{} :excludes #{:one :two}} (parse-tags ["~one" "~two"])) - (should= {:includes #{:two} :excludes #{:one}} (parse-tags ["~one" "two"]))) + (should= {:includes #{} :excludes #{}} (sut/parse-tags [])) + (should= {:includes #{:one} :excludes #{}} (sut/parse-tags [:one])) + (should= {:includes #{:one} :excludes #{}} (sut/parse-tags ["one"])) + (should= {:includes #{:one :two} :excludes #{}} (sut/parse-tags ["one" 'two])) + (should= {:includes #{} :excludes #{:one}} (sut/parse-tags ["~one"])) + (should= {:includes #{} :excludes #{:one :two}} (sut/parse-tags ["~one" "~two"])) + (should= {:includes #{:two} :excludes #{:one}} (sut/parse-tags ["~one" "two"]))) #?(:clj (it "should translate tags in config-bindings" - (let [mappings (config-mappings (assoc default-config :tags ["one" "~two"]))] + (let [mappings (sut/config-mappings (assoc sut/default-config :tags ["one" "~two"]))] (should= {:includes #{:one} :excludes #{:two}} - (get mappings #'*tag-filter*))))) + (get mappings #'sut/*tag-filter*))))) #?(:clj (it "doesn't include *parent-description* in config-bindings" - (let [cb (config-bindings)] + (let [cb (sut/config-bindings)] (should-not-contain #'speclj.config/*parent-description* cb)))) + (context "exporting" + (test-exported-meta sut/active-runner) + ) ) (standard/run-specs) diff --git a/spec/speclj/report/documentation_spec.cljc b/spec/speclj/report/documentation_spec.cljc index aa23264..fa0c364 100644 --- a/spec/speclj/report/documentation_spec.cljc +++ b/spec/speclj/report/documentation_spec.cljc @@ -1,16 +1,17 @@ (ns speclj.report.documentation-spec (:require #?(:cljs [goog.string]) ;cljs bug? [speclj.core #?(:clj :refer :cljs :refer-macros) [before context describe it should= with -new-exception -new-failure -new-pending]] + [speclj.spec-helper #?(:clj :refer :cljs :refer-macros) [test-exported-meta]] [speclj.components :refer [new-description new-characteristic install]] [speclj.platform :refer [endl]] - [speclj.report.documentation :refer [new-documentation-reporter]] + [speclj.report.documentation :as sut] [speclj.reporting :refer [report-description report-pass report-pending report-fail report-error red green yellow]] [speclj.results :refer [pass-result fail-result pending-result error-result]] [speclj.run.standard :as standard])) (describe "Speccdoc Reporter" - (with reporter (new-documentation-reporter)) + (with reporter (sut/new-documentation-reporter)) (with description (new-description "Verbosity" false "some-ns")) (it "reports descriptions" @@ -56,6 +57,10 @@ (should= (str (red "- says fail (FAILED)") " " (yellow "[FOCUS]") endl) (with-out-str (report-fail @reporter result))))) + (context "exporting" + (test-exported-meta sut/new-documentation-reporter) + ) + (context "with nested description" (with nested-description (new-description "Nesting" false "some.ns")) (before (install @nested-description @description)) diff --git a/spec/speclj/run/standard_spec.cljs b/spec/speclj/run/standard_spec.cljs new file mode 100644 index 0000000..b1d9db8 --- /dev/null +++ b/spec/speclj/run/standard_spec.cljs @@ -0,0 +1,27 @@ +(ns speclj.run.standard_spec + (:require [speclj.spec-helper :refer-macros [test-exported-meta]] + [speclj.core :refer-macros [after context describe it should= should-fail]] + [speclj.run.standard :as sut])) + +(def initial-armed sut/armed) + +(describe "Standard Runner" + (after (set! sut/armed initial-armed)) + + (context "exporting" + (test-exported-meta sut/run-specs) + (test-exported-meta sut/armed) + (test-exported-meta sut/arm) + (test-exported-meta sut/disarm) + (test-exported-meta sut/new-standard-runner) + ) + + (it "arms and disarms the runner" + (sut/disarm) + (should= false sut/armed) + (sut/arm) + (should= true sut/armed) + (sut/disarm) + (should= false sut/armed)) + + ) diff --git a/spec/speclj/spec_helper.cljc b/spec/speclj/spec_helper.cljc index 3a157da..e757527 100644 --- a/spec/speclj/spec_helper.cljc +++ b/spec/speclj/spec_helper.cljc @@ -1,6 +1,6 @@ (ns speclj.spec-helper (#?(:clj :require :cljs :require-macros) - [speclj.core :refer [-fail]] + [speclj.core :refer [-fail it]] [speclj.platform :refer [try-catch-anything]])) (defmacro run-result [& body] @@ -25,6 +25,12 @@ (= :pass result#) (-fail (str "Unexpected pass: " '~body)) (speclj.platform/failure? result#) (-fail (str "Unexpected failure: " (speclj.platform/error-message result#)))))) +(defmacro test-exported-meta [sym] + `(it '~sym + (let [var# #'~sym] + (when (not= true (:export (meta var#))) + (-fail (str "expected " var# " to ^:export")))))) + (defmacro failure-message [& body] `(let [result# (run-result ~@body)] (if (not (speclj.platform/failure? result#)) diff --git a/src/speclj/config.cljc b/src/speclj/config.cljc index d066b86..823990f 100644 --- a/src/speclj/config.cljc +++ b/src/speclj/config.cljc @@ -18,7 +18,7 @@ (def default-runner (atom nil)) (def default-runner-fn (atom nil)) -(defn active-runner [] +(defn ^:export active-runner [] (if #?(:clj (bound? #'*runner*) :cljs *runner*) *runner* (if-let [runner @default-runner] diff --git a/src/speclj/report/documentation.cljc b/src/speclj/report/documentation.cljc index d5843f6..2fe57a8 100644 --- a/src/speclj/report/documentation.cljc +++ b/src/speclj/report/documentation.cljc @@ -1,6 +1,6 @@ (ns speclj.report.documentation - (:require [speclj.platform :refer [error-message]] - [speclj.report.progress :refer [print-summary]] + (:require [speclj.platform :as platform] + [speclj.report.progress :as progress] [speclj.reporting :refer [green indent red yellow]])) (defn level-of [component] @@ -15,37 +15,39 @@ (deftype DocumentationReporter [] speclj.reporting/Reporter - (report-message [this message] - (println message) (flush)) + (report-message [_this message] + (println message) + (flush)) - (report-description [this description] + (report-description [_this description] (let [level (level-of description)] (when (zero? level) (println)) (println (maybe-focused description (str (indent level (.-name description))))) (flush))) - (report-pass [this result] + (report-pass [_this result] (let [characteristic (.-characteristic result) level (level-of characteristic)] (println (maybe-focused characteristic (green (indent (dec level) "- " (.-name characteristic))))) (flush))) - (report-pending [this result] + (report-pending [_this result] (let [characteristic (.-characteristic result) level (level-of characteristic)] - (println (yellow (indent (dec level) "- " (.-name characteristic) " (PENDING: " (error-message (.-exception result)) ")"))) (flush))) + (println (yellow (indent (dec level) "- " (.-name characteristic) " (PENDING: " (platform/error-message (.-exception result)) ")"))) + (flush))) - (report-fail [this result] + (report-fail [_this result] (let [characteristic (.-characteristic result) level (level-of characteristic)] (println (maybe-focused characteristic (red (indent (dec level) "- " (.-name characteristic) " (FAILED)")))) (flush))) - (report-error [this result] + (report-error [_this result] (println (red (.toString (.-exception result))))) - (report-runs [this results] - (print-summary results))) + (report-runs [_this results] + (progress/print-summary results))) -(defn new-documentation-reporter [] +(defn ^:export new-documentation-reporter [] (DocumentationReporter.)) diff --git a/src/speclj/run/standard.cljc b/src/speclj/run/standard.cljc index 6376b6c..061b2eb 100644 --- a/src/speclj/run/standard.cljc +++ b/src/speclj/run/standard.cljc @@ -11,8 +11,13 @@ #?(:clj (:import (clojure.lang Compiler LineNumberingPushbackReader) (java.io StringReader)))) -#?(:cljs (def armed false)) -#?(:cljs (def counter (atom 0))) +#?(:cljs + (do + (def ^:export armed false) + (def counter (atom 0)) + (defn ^:export arm [] (set! armed true)) + (defn ^:export disarm [] (set! armed false)) + )) #?(:clj (do @@ -77,7 +82,7 @@ (-pr-writer [x writer _opts] (-write writer (str "#"))))) -(defn new-standard-runner [] +(defn ^:export new-standard-runner [] (StandardRunner. #?(:cljs (swap! counter inc)) (atom []) (atom []))) (reset! config/default-runner-fn new-standard-runner) @@ -102,7 +107,7 @@ (reset! config/default-runner (@config/default-runner-fn)))))) :cljs - (defn run-specs [& configurations] + (defn ^:export run-specs [& configurations] "If evaluated outside the context of a spec run, it will run all the specs that have been evaluated using the default runner and reporter. A call to this function is typically placed at the end of a spec file so that all the specs are evaluated by evaluation the file as a script. Optional configuration parameters may be passed in: From ad843a6de9bac3e791286c433ff3d99abbfad0f7 Mon Sep 17 00:00:00 2001 From: Brandon Correa <50252804+brandoncorrea@users.noreply.github.com> Date: Sun, 26 May 2024 17:05:24 -0500 Subject: [PATCH 06/16] Add filter-descriptions to Runners --- CHANGES.md | 1 + spec/speclj/run/standard_spec.clj | 5 ++- spec/speclj/run/standard_spec.cljs | 8 ++-- spec/speclj/run/vigilant_spec.clj | 6 ++- spec/speclj/spec_helper.cljc | 57 ++++++++++++++++++++++++++-- src/speclj/run/standard.cljc | 3 ++ src/speclj/run/vigilant.clj | 60 +++++++++++++++--------------- src/speclj/running.cljc | 21 +++++++---- 8 files changed, 115 insertions(+), 46 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index edacd85..16ed6ce 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -3,6 +3,7 @@ * `run-specs` now accepts string keys in addition to keyword keys * js runner executable may use `speclj.run.standard.arm()` instead of `speclj.run.standard.armed = true` * exports functions used by JavaScript for executing ClojureScript specs +* `Runner` can now `filter-descriptions` based on a collection of namespace strings # 3.4.7 diff --git a/spec/speclj/run/standard_spec.clj b/spec/speclj/run/standard_spec.clj index 9386449..d4c5d5b 100644 --- a/spec/speclj/run/standard_spec.clj +++ b/spec/speclj/run/standard_spec.clj @@ -3,7 +3,8 @@ [speclj.core :refer :all] [speclj.report.silent :as silent] [speclj.run.standard :as sut] - [speclj.running :as running]) + [speclj.running :as running] + [speclj.spec-helper :as spec-helper]) (:import (java.io File))) (defn find-dir @@ -41,6 +42,8 @@ (should= defaults (sut/config-with-defaults [])) (should= (assoc defaults :foo :bar) (sut/config-with-defaults [:foo :bar])) (should= (assoc defaults :foo :bar :baz "buzz") (sut/config-with-defaults [:foo :bar "baz" "buzz"])))) + + (spec-helper/test-description-filtering sut/new-standard-runner) ) (sut/run-specs) diff --git a/spec/speclj/run/standard_spec.cljs b/spec/speclj/run/standard_spec.cljs index b1d9db8..5d5ad96 100644 --- a/spec/speclj/run/standard_spec.cljs +++ b/spec/speclj/run/standard_spec.cljs @@ -1,7 +1,7 @@ (ns speclj.run.standard_spec - (:require [speclj.spec-helper :refer-macros [test-exported-meta]] - [speclj.core :refer-macros [after context describe it should= should-fail]] - [speclj.run.standard :as sut])) + (:require [speclj.core :refer-macros [after context describe it should= should-fail with]] + [speclj.run.standard :as sut] + [speclj.spec-helper :as spec-helper])) (def initial-armed sut/armed) @@ -24,4 +24,6 @@ (sut/disarm) (should= false sut/armed)) + (spec-helper/test-description-filtering sut/new-standard-runner) + ) diff --git a/spec/speclj/run/vigilant_spec.clj b/spec/speclj/run/vigilant_spec.clj index de9f906..ef37646 100644 --- a/spec/speclj/run/vigilant_spec.clj +++ b/spec/speclj/run/vigilant_spec.clj @@ -1,6 +1,7 @@ (ns speclj.run.vigilant-spec (:require [speclj.core :refer :all] - [speclj.run.vigilant :refer :all])) + [speclj.run.vigilant :refer :all] + [speclj.spec-helper :as spec-helper])) (describe "Vigilant Runner" (with runner (new-vigilant-runner)) @@ -8,6 +9,7 @@ (it "can be created" (should= [] @(.results @runner))) + (spec-helper/test-description-filtering new-vigilant-runner) ) -(run-specs) \ No newline at end of file +(run-specs) diff --git a/spec/speclj/spec_helper.cljc b/spec/speclj/spec_helper.cljc index e757527..7dba513 100644 --- a/spec/speclj/spec_helper.cljc +++ b/spec/speclj/spec_helper.cljc @@ -1,7 +1,9 @@ (ns speclj.spec-helper - (#?(:clj :require :cljs :require-macros) - [speclj.core :refer [-fail it]] - [speclj.platform :refer [try-catch-anything]])) + #?(:cljs (:require-macros [speclj.spec-helper :refer [test-description-filtering]])) + (:require [speclj.core #?(:clj :refer :cljs :refer-macros) [context -fail it should= with]] + [speclj.platform #?(:clj :refer :cljs :refer-macros) [try-catch-anything]] + [speclj.components :as components] + [speclj.running :as running])) (defmacro run-result [& body] `(try-catch-anything @@ -36,3 +38,52 @@ (if (not (speclj.platform/failure? result#)) (-fail (str "Expected a failure but got: " result#)) (speclj.platform/error-message result#)))) + +(defmacro test-description-filtering [new-runner-fn] + `(context "filtering descriptions" + + (with runner# (~new-runner-fn)) + + (it "no descriptions by an empty list" + (running/filter-descriptions @runner# []) + (should= [] @(.-descriptions @runner#))) + + (it "filters one description by an empty list" + (running/submit-description @runner# (components/new-description "Gone" false "some.ns")) + (running/filter-descriptions @runner# []) + (should= [] @(.-descriptions @runner#))) + + (it "one description by its own namespace" + (let [one# (components/new-description "One" false "some.ns")] + (running/submit-description @runner# one#) + (running/filter-descriptions @runner# ["some.ns"]) + (should= [one#] @(.-descriptions @runner#)))) + + (it "two descriptions with one matching namespace" + (let [one# (components/new-description "One" false "some.ns") + two# (components/new-description "Two" false "some.other.ns")] + (running/submit-description @runner# one#) + (running/submit-description @runner# two#) + (running/filter-descriptions @runner# ["some.other.ns"]) + (should= [two#] @(.-descriptions @runner#)))) + + (it "three descriptions with two matching namespaces" + (let [one# (components/new-description "One" false "some.ns") + two# (components/new-description "Two" false "some.other.ns") + three# (components/new-description "Three" false "three.ns")] + (running/submit-description @runner# one#) + (running/submit-description @runner# two#) + (running/submit-description @runner# three#) + (running/filter-descriptions @runner# ["three.ns" "some.ns"]) + (should= [one# three#] @(.-descriptions @runner#)))) + + (it "does nothing when filtering by nil" + (let [one# (components/new-description "One" false "some.ns") + two# (components/new-description "Two" false "some.other.ns") + three# (components/new-description "Three" false "three.ns")] + (running/submit-description @runner# one#) + (running/submit-description @runner# two#) + (running/submit-description @runner# three#) + (running/filter-descriptions @runner# nil) + (should= [one# two# three#] @(.-descriptions @runner#)))) + )) diff --git a/src/speclj/run/standard.cljc b/src/speclj/run/standard.cljc index 061b2eb..01684a5 100644 --- a/src/speclj/run/standard.cljc +++ b/src/speclj/run/standard.cljc @@ -62,6 +62,9 @@ (submit-description [_this description] (swap! descriptions conj description)) + (filter-descriptions [_this namespaces] + (swap! descriptions running/descriptions-with-namespaces namespaces)) + (run-description [_this description reporters] (let [run-results (running/do-description description reporters)] (swap! results into run-results))) diff --git a/src/speclj/run/vigilant.clj b/src/speclj/run/vigilant.clj index 0fda69a..4735ece 100644 --- a/src/speclj/run/vigilant.clj +++ b/src/speclj/run/vigilant.clj @@ -1,13 +1,12 @@ (ns speclj.run.vigilant - (:require [clojure.java.io :refer [file]] + (:require [clojure.java.io :as io] [fresh.core :refer [clj-files-in make-fresh ns-to-file]] - [speclj.config :refer [active-reporters active-runner config-bindings]] + [speclj.config :as config] [speclj.platform :refer [current-time endl enter-pressed? format-seconds secs-since]] - [speclj.reporting :refer [report-message* report-runs*]] - [speclj.results :refer [categorize]] - [speclj.running :refer [do-description filter-focused process-compile-error run-and-report run-description]]) - (:import (java.util.concurrent ScheduledThreadPoolExecutor TimeUnit) - (speclj.running Runner))) + [speclj.reporting :as reporting] + [speclj.results :as results] + [speclj.running :as running]) + (:import (java.util.concurrent ScheduledThreadPoolExecutor TimeUnit))) (def start-time (atom 0)) @@ -15,13 +14,13 @@ (set (map #(str (.ns @(.. % characteristic parent))) results))) (defn- report-update [report] - (let [reporters (active-reporters) + (let [reporters (config/active-reporters) reloads (:reloaded report)] (when (seq reloads) - (report-message* reporters (str endl "----- " (str (java.util.Date.) " -----"))) - (report-message* reporters (str "took " (format-seconds (secs-since @start-time)) " to determine file statuses.")) - (report-message* reporters "reloading files:") - (doseq [file reloads] (report-message* reporters (str " " (.getCanonicalPath file)))))) + (reporting/report-message* reporters (str endl "----- " (str (java.util.Date.) " -----"))) + (reporting/report-message* reporters (str "took " (format-seconds (secs-since @start-time)) " to determine file statuses.")) + (reporting/report-message* reporters "reloading files:") + (doseq [file reloads] (reporting/report-message* reporters (str " " (.getCanonicalPath file)))))) true) (defn- reload-files [runner current-results] @@ -38,17 +37,17 @@ (defn- tick [configuration] (with-bindings configuration - (let [runner (active-runner) - reporters (active-reporters)] + (let [runner (config/active-runner) + reporters (config/active-reporters)] (try (reset! start-time (current-time)) (make-fresh (.file-listing runner) (set (apply clj-files-in @(.directories runner))) (partial reload-report runner)) (when (seq @(.descriptions runner)) - (reset! (.previous-failed runner) (:fail (categorize (seq @(.results runner))))) - (run-and-report runner reporters)) + (reset! (.previous-failed runner) (:fail (results/categorize (seq @(.results runner))))) + (running/run-and-report runner reporters)) (catch java.lang.Throwable e - (process-compile-error runner e) - (report-runs* reporters @(.results runner)))) + (running/process-compile-error runner e) + (reporting/report-runs* reporters @(.results runner)))) (reset! (.descriptions runner) []) (reset! (.results runner) [])))) @@ -60,32 +59,35 @@ (defn- listen-for-rerun [configuration] (with-bindings configuration (when (enter-pressed?) - (reset-runner (active-runner))))) + (reset-runner (config/active-runner))))) (deftype VigilantRunner [file-listing results previous-failed directories descriptions] - Runner - (run-directories [this directories reporters] + running/Runner + (run-directories [this directories _reporters] (let [scheduler (ScheduledThreadPoolExecutor. 1) - configuration (config-bindings) + configuration (config/config-bindings) runnable (fn [] (tick configuration)) - dir-files (map file directories)] + dir-files (map io/file directories)] (reset! (.directories this) dir-files) (.scheduleWithFixedDelay scheduler runnable 0 500 TimeUnit/MILLISECONDS) (.scheduleWithFixedDelay scheduler (fn [] (listen-for-rerun configuration)) 0 500 TimeUnit/MILLISECONDS) (.awaitTermination scheduler Long/MAX_VALUE TimeUnit/SECONDS) 0)) - (submit-description [this description] + (submit-description [_this description] (swap! descriptions conj description)) - (run-description [this description reporters] - (let [run-results (do-description description reporters)] + (filter-descriptions [_this namespaces] + (swap! descriptions running/descriptions-with-namespaces namespaces)) + + (run-description [_this description reporters] + (let [run-results (running/do-description description reporters)] (swap! results into run-results))) (run-and-report [this reporters] - (doseq [description (filter-focused @descriptions)] - (run-description this description reporters)) - (report-runs* reporters @results))) + (doseq [description (running/filter-focused @descriptions)] + (running/run-description this description reporters)) + (reporting/report-runs* reporters @results))) (defn new-vigilant-runner [] (VigilantRunner. (atom {}) (atom []) (atom []) (atom nil) (atom []))) diff --git a/src/speclj/running.cljc b/src/speclj/running.cljc index 9dbd9a0..4a614e9 100644 --- a/src/speclj/running.cljc +++ b/src/speclj/running.cljc @@ -59,20 +59,25 @@ (focus-characteristics! component)))) (defn track-focused-characteristics! [characteristics] - (doseq [characteristic characteristics - :when (focused? characteristic)] - (enable-focus-mode! characteristic))) + (->> (filter focused? characteristics) + (run! enable-focus-mode!))) (defn scan-for-focus! [description] - (let [all (->> (tree-seq some? all-children description))] + (let [all (tree-seq some? all-children description)] (track-focused-descriptions! (filter components/is-description? all)) (track-focused-characteristics! (filter components/is-characteristic? all)) description)) (defn filter-focused [descriptions] - (doseq [description descriptions] (scan-for-focus! description)) + (run! scan-for-focus! descriptions) (or (seq (filter focus-mode? descriptions)) descriptions)) +(defn descriptions-with-namespaces [descriptions namespaces] + (if namespaces + (let [ns-set (set namespaces)] + (filter #(contains? ns-set (.-ns %)) descriptions)) + descriptions)) + (defn- eval-components [components] (doseq [component components] ((.-body component)))) @@ -89,7 +94,7 @@ (eval-components afters)))) (defn- reset-withs [withs] - (doseq [with withs] (components/reset-with with))) + (run! components/reset-with withs)) (defn- collect-components [getter description] (loop [description description components []] @@ -122,7 +127,7 @@ (report-result pending-result characteristic start-time reporters e) (report-result fail-result characteristic start-time reporters e))) (finally - (reset-withs withs))))) ;MDM - Possible clojure bug. Inlining reset-withs results in compile error + (reset-withs withs))))) ;MDM - Possible clojure bug. Inlining reset-withs results in compile error (defn- do-characteristics [characteristics reporters] (doall @@ -202,6 +207,6 @@ (defprotocol Runner (run-directories [this directories reporters]) (submit-description [this description]) + (filter-descriptions [this namespaces]) (run-description [this description reporters]) (run-and-report [this reporters])) - From 9486854f4959a5765fe307c6cd14bd20d4d40f73 Mon Sep 17 00:00:00 2001 From: Brandon Correa <50252804+brandoncorrea@users.noreply.github.com> Date: Mon, 27 May 2024 07:45:09 -0500 Subject: [PATCH 07/16] export filter-descriptions to JavaScript and accept ns hash-map instead of ns collection --- spec/speclj/run/standard_spec.cljs | 10 +-- spec/speclj/running_spec.clj | 21 +++-- spec/speclj/spec_helper.cljc | 121 +++++++++++++++++------------ src/speclj/run/standard.cljc | 2 +- src/speclj/run/vigilant.clj | 2 +- src/speclj/running.cljc | 14 ++-- 6 files changed, 101 insertions(+), 69 deletions(-) diff --git a/spec/speclj/run/standard_spec.cljs b/spec/speclj/run/standard_spec.cljs index 5d5ad96..9f72701 100644 --- a/spec/speclj/run/standard_spec.cljs +++ b/spec/speclj/run/standard_spec.cljs @@ -9,11 +9,11 @@ (after (set! sut/armed initial-armed)) (context "exporting" - (test-exported-meta sut/run-specs) - (test-exported-meta sut/armed) - (test-exported-meta sut/arm) - (test-exported-meta sut/disarm) - (test-exported-meta sut/new-standard-runner) + (spec-helper/test-exported-meta sut/run-specs) + (spec-helper/test-exported-meta sut/armed) + (spec-helper/test-exported-meta sut/arm) + (spec-helper/test-exported-meta sut/disarm) + (spec-helper/test-exported-meta sut/new-standard-runner) ) (it "arms and disarms the runner" diff --git a/spec/speclj/running_spec.clj b/spec/speclj/running_spec.clj index 29efb25..8f93a84 100644 --- a/spec/speclj/running_spec.clj +++ b/spec/speclj/running_spec.clj @@ -8,7 +8,8 @@ [speclj.report.silent :refer [new-silent-reporter]] [speclj.results :refer [fail?]] [speclj.run.standard :as standard] - [speclj.running :refer [run-and-report]])) + [speclj.running :as sut] + [speclj.spec-helper :as spec-helper])) (def bauble (atom nil)) @@ -25,7 +26,7 @@ '(describe "Dummy" (it "has a pass" (should (= 1 1))))) - (run-and-report *runner* *reporters*) + (sut/run-and-report *runner* *reporters*) (let [results @(.-results *runner*) result (first results)] (should= 1 (count results)) @@ -37,7 +38,7 @@ '(describe "Dummy" (it "has a fail" (should= 1 2)))) - (run-and-report *runner* *reporters*) + (sut/run-and-report *runner* *reporters*) (let [results @(.-results *runner*) result (first results)] (should= 1 (count results)) @@ -52,7 +53,7 @@ (it "changes the bauble" (reset! bauble :something) (should-fail)))) - (run-and-report *runner* *reporters*) + (sut/run-and-report *runner* *reporters*) (should= nil @bauble)) (it "runs afters with error" @@ -62,7 +63,7 @@ (it "changes the bauble" (reset! bauble :something) (throw (Exception. "blah"))))) - (run-and-report *runner* *reporters*) + (sut/run-and-report *runner* *reporters*) (should= nil @bauble)) (it "doesn't crash when declaring a with named the same as a pre-existing var" @@ -72,7 +73,7 @@ (it "uses the new value of bauble" (should= "foo" @bauble)))] (should-not-throw (eval spec)) - (run-and-report *runner* *reporters*) + (sut/run-and-report *runner* *reporters*) (let [results @(.-results *runner*) result (first results)] (should= 1 (count results)) @@ -85,7 +86,7 @@ (context "Fool" (tags :two) (it "one, two tag" :filler)))) (binding [*tag-filter* {:includes #{:one :two} :excludes #{}}] - (run-and-report *runner* *reporters*)) + (sut/run-and-report *runner* *reporters*)) (let [results @(.-results *runner*)] (should= 1 (count results)) (should= "one, two tag" (.-name (.-characteristic (first results)))))) @@ -97,11 +98,15 @@ (before-all (swap! @foo inc)) (it "check foo" (should= 43 @@foo)))) - (run-and-report *runner* *reporters*) + (sut/run-and-report *runner* *reporters*) (let [results @(.-results *runner*)] (should= 1 (count results)) (should-not (fail? (first results))))) + (context "exporting" + (spec-helper/test-exported-meta sut/filter-descriptions) + ) + ) (describe "namespace" diff --git a/spec/speclj/spec_helper.cljc b/spec/speclj/spec_helper.cljc index 7dba513..9980775 100644 --- a/spec/speclj/spec_helper.cljc +++ b/spec/speclj/spec_helper.cljc @@ -1,5 +1,5 @@ (ns speclj.spec-helper - #?(:cljs (:require-macros [speclj.spec-helper :refer [test-description-filtering]])) + #?(:cljs (:require-macros [speclj.spec-helper :refer [test-exported-meta]])) (:require [speclj.core #?(:clj :refer :cljs :refer-macros) [context -fail it should= with]] [speclj.platform #?(:clj :refer :cljs :refer-macros) [try-catch-anything]] [speclj.components :as components] @@ -39,51 +39,74 @@ (-fail (str "Expected a failure but got: " result#)) (speclj.platform/error-message result#)))) -(defmacro test-description-filtering [new-runner-fn] - `(context "filtering descriptions" - - (with runner# (~new-runner-fn)) - - (it "no descriptions by an empty list" - (running/filter-descriptions @runner# []) - (should= [] @(.-descriptions @runner#))) - - (it "filters one description by an empty list" - (running/submit-description @runner# (components/new-description "Gone" false "some.ns")) - (running/filter-descriptions @runner# []) - (should= [] @(.-descriptions @runner#))) - - (it "one description by its own namespace" - (let [one# (components/new-description "One" false "some.ns")] - (running/submit-description @runner# one#) - (running/filter-descriptions @runner# ["some.ns"]) - (should= [one#] @(.-descriptions @runner#)))) - - (it "two descriptions with one matching namespace" - (let [one# (components/new-description "One" false "some.ns") - two# (components/new-description "Two" false "some.other.ns")] - (running/submit-description @runner# one#) - (running/submit-description @runner# two#) - (running/filter-descriptions @runner# ["some.other.ns"]) - (should= [two#] @(.-descriptions @runner#)))) - - (it "three descriptions with two matching namespaces" - (let [one# (components/new-description "One" false "some.ns") - two# (components/new-description "Two" false "some.other.ns") - three# (components/new-description "Three" false "three.ns")] - (running/submit-description @runner# one#) - (running/submit-description @runner# two#) - (running/submit-description @runner# three#) - (running/filter-descriptions @runner# ["three.ns" "some.ns"]) - (should= [one# three#] @(.-descriptions @runner#)))) - - (it "does nothing when filtering by nil" - (let [one# (components/new-description "One" false "some.ns") - two# (components/new-description "Two" false "some.other.ns") - three# (components/new-description "Three" false "three.ns")] - (running/submit-description @runner# one#) - (running/submit-description @runner# two#) - (running/submit-description @runner# three#) - (running/filter-descriptions @runner# nil) - (should= [one# two# three#] @(.-descriptions @runner#)))) - )) +(defn test-description-filtering [new-runner-fn] + (context "filtering descriptions" + + (with runner (new-runner-fn)) + + (it "no descriptions by an empty map" + (running/filter-descriptions @runner {}) + (should= [] @(.-descriptions @runner))) + + (it "filters one description by an empty map" + (running/submit-description @runner (components/new-description "Gone" false "some.ns")) + (running/filter-descriptions @runner {}) + (should= [] @(.-descriptions @runner))) + + (it "one description by its own namespace" + (let [one (components/new-description "One" false "some.ns")] + (running/submit-description @runner one) + (running/filter-descriptions @runner {"some.ns" true}) + (should= [one] @(.-descriptions @runner)))) + + (it "two descriptions with one matching namespace" + (let [one (components/new-description "One" false "some.ns") + two (components/new-description "Two" false "some.other.ns")] + (running/submit-description @runner one) + (running/submit-description @runner two) + (running/filter-descriptions @runner {"some.other.ns" true}) + (should= [two] @(.-descriptions @runner)))) + + (it "three descriptions with two matching namespaces" + (let [one (components/new-description "One" false "some.ns") + two (components/new-description "Two" false "some.other.ns") + three (components/new-description "Three" false "three.ns")] + (running/submit-description @runner one) + (running/submit-description @runner two) + (running/submit-description @runner three) + (running/filter-descriptions @runner {"three.ns" true "some.ns" true}) + (should= [one three] @(.-descriptions @runner)))) + + (it "namespace is assigned a falsy value" + (let [one (components/new-description "One" false "some.ns") + two (components/new-description "Two" false "some.other.ns") + three (components/new-description "Three" false "three.ns")] + (running/submit-description @runner one) + (running/submit-description @runner two) + (running/submit-description @runner three) + (running/filter-descriptions @runner {"three.ns" true "some.ns" false}) + (should= [three] @(.-descriptions @runner)))) + + (it "does nothing when filtering by nil" + (let [one (components/new-description "One" false "some.ns") + two (components/new-description "Two" false "some.other.ns") + three (components/new-description "Three" false "three.ns")] + (running/submit-description @runner one) + (running/submit-description @runner two) + (running/submit-description @runner three) + (running/filter-descriptions @runner nil) + (should= [one two three] @(.-descriptions @runner)))) + + #?(:cljs + (it "filters by JS object" + (let [one (components/new-description "One" false "some.ns") + two (components/new-description "Two" false "some.other.ns") + three (components/new-description "Three" false "three.ns")] + (running/submit-description @runner one) + (running/submit-description @runner two) + (running/submit-description @runner three) + (running/filter-descriptions @runner (js-obj "three.ns" true "some.ns" true)) + (should= [one three] @(.-descriptions @runner)))) + ) + ) + ) diff --git a/src/speclj/run/standard.cljc b/src/speclj/run/standard.cljc index 01684a5..b66a337 100644 --- a/src/speclj/run/standard.cljc +++ b/src/speclj/run/standard.cljc @@ -62,7 +62,7 @@ (submit-description [_this description] (swap! descriptions conj description)) - (filter-descriptions [_this namespaces] + (-filter-descriptions [_this namespaces] (swap! descriptions running/descriptions-with-namespaces namespaces)) (run-description [_this description reporters] diff --git a/src/speclj/run/vigilant.clj b/src/speclj/run/vigilant.clj index 4735ece..2557b56 100644 --- a/src/speclj/run/vigilant.clj +++ b/src/speclj/run/vigilant.clj @@ -77,7 +77,7 @@ (submit-description [_this description] (swap! descriptions conj description)) - (filter-descriptions [_this namespaces] + (-filter-descriptions [_this namespaces] (swap! descriptions running/descriptions-with-namespaces namespaces)) (run-description [_this description reporters] diff --git a/src/speclj/running.cljc b/src/speclj/running.cljc index 4a614e9..1418f66 100644 --- a/src/speclj/running.cljc +++ b/src/speclj/running.cljc @@ -73,10 +73,7 @@ (or (seq (filter focus-mode? descriptions)) descriptions)) (defn descriptions-with-namespaces [descriptions namespaces] - (if namespaces - (let [ns-set (set namespaces)] - (filter #(contains? ns-set (.-ns %)) descriptions)) - descriptions)) + (cond->> descriptions namespaces (filter #(namespaces (.-ns %))))) (defn- eval-components [components] (doseq [component components] ((.-body component)))) @@ -207,6 +204,13 @@ (defprotocol Runner (run-directories [this directories reporters]) (submit-description [this description]) - (filter-descriptions [this namespaces]) + (-filter-descriptions [this namespaces]) (run-description [this description reporters]) (run-and-report [this reporters])) + +(defn ^:export filter-descriptions + "Protocol method defined as function for JavaScript interoperability" + [runner namespaces] + (->> namespaces + #?(:cljs js->clj) + (-filter-descriptions runner))) From 41fb15a3fd68c8e1ae0008a89198a76ba1a7f24b Mon Sep 17 00:00:00 2001 From: Brandon Correa <50252804+brandoncorrea@users.noreply.github.com> Date: Mon, 27 May 2024 19:31:57 -0500 Subject: [PATCH 08/16] add option for multiple cljs builds --- dev/speclj/dev/cljs.clj | 39 ++++++++++++++++++++++++++++----------- 1 file changed, 28 insertions(+), 11 deletions(-) diff --git a/dev/speclj/dev/cljs.clj b/dev/speclj/dev/cljs.clj index 73c17be..f474b21 100644 --- a/dev/speclj/dev/cljs.clj +++ b/dev/speclj/dev/cljs.clj @@ -4,15 +4,30 @@ (def build-options - {:optimizations :none - :output-to "target/specs.js" - :output-dir "target/cljs" - :cache-analysis true - :source-map true - :pretty-print true - :verbose true - :watch-fn (fn [] (println "Success!")) - }) + {:development {:optimizations :none + :output-to "target/specs.js" + :output-dir "target/cljs" + :cache-analysis true + :source-map true + :pretty-print true + :verbose true + :watch-fn (fn [] (println "Success!")) + } + :ci { + :cache-analysis false + :infer-externs true + :optimizations :advanced + :output-to "target/specs.js" + :output-dir "target/cljs" + :pretty-print false + :verbose false + :watch-fn (fn [] (println "Success!")) + }}) + +(defn ->build-key [build-key] + (case build-key + "ci" :ci + :development)) (defn run-specs [] (let [process (.exec (Runtime/getRuntime) "node bin/speclj.js") @@ -23,5 +38,7 @@ (System/exit (.waitFor process)))) (defn -main [& args] - (api/build "spec" build-options) - (run-specs)) \ No newline at end of file + (let [build-key (->build-key (first args)) + build (get build-options build-key)] + (api/build "spec" build) + (run-specs))) From dac6fc3732853f6614629f04c5455232fab57167 Mon Sep 17 00:00:00 2001 From: Brandon Correa <50252804+brandoncorrea@users.noreply.github.com> Date: Mon, 27 May 2024 19:39:47 -0500 Subject: [PATCH 09/16] Update with and with-all to work with cljs advanced optimizations --- CHANGES.md | 2 +- src/speclj/components.cljc | 90 ++++++++++++++------------------------ src/speclj/core.cljc | 38 +++++----------- src/speclj/running.cljc | 16 ++----- 4 files changed, 50 insertions(+), 96 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 16ed6ce..0e565b7 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -2,8 +2,8 @@ * `run-specs` now accepts string keys in addition to keyword keys * js runner executable may use `speclj.run.standard.arm()` instead of `speclj.run.standard.armed = true` -* exports functions used by JavaScript for executing ClojureScript specs * `Runner` can now `filter-descriptions` based on a collection of namespace strings +* exports and refactors functions used by JavaScript for executing ClojureScript specs under advanced optimizations # 3.4.7 diff --git a/src/speclj/components.cljc b/src/speclj/components.cljc index 267cd54..cfee342 100644 --- a/src/speclj/components.cljc +++ b/src/speclj/components.cljc @@ -6,11 +6,11 @@ #?(:clj (extend-protocol SpecComponent java.lang.Object - (install [this description] (comment "This prohibits multimethod defs, and other stuff. Don't be so stingy! Let it pass.")) + (install [_this _description] (comment "This prohibits multimethod defs, and other stuff. Don't be so stingy! Let it pass.")) nil - (install [this description] (throw (java.lang.Exception. (str "Oops! It looks like you tried to add 'nil' to a spec. That's probably not what you wanted.")))) + (install [_this _description] (throw (java.lang.Exception. (str "Oops! It looks like you tried to add 'nil' to a spec. That's probably not what you wanted.")))) clojure.lang.Var - (install [this description] (comment "Vars are cool. Let them pass.")) + (install [_this _description] (comment "Vars are cool. Let them pass.")) clojure.lang.Seqable (install [this description] (doseq [component (seq this)] (install component description)))) @@ -25,9 +25,9 @@ PersistentVector (install [this description] (doseq [component (seq this)] (install component description))) nil - (install [this description] (throw (ex-info (str "Oops! It looks like you tried to add 'nil' to a spec. That's probably not what you wanted.") {}))) + (install [_this _description] (throw (ex-info (str "Oops! It looks like you tried to add 'nil' to a spec. That's probably not what you wanted.") {}))) object - (install [this description] (comment "Whatever... Let them pass.")))) + (install [_this _description] (comment "Whatever... Let them pass.")))) (deftype Description [name is-focused? has-focus? ns parent children characteristics tags befores before-alls afters after-alls withs with-alls arounds around-alls] SpecComponent @@ -35,7 +35,7 @@ (reset! (.-parent this) description) (swap! (.-children description) conj this)) Object - (toString [this] (str "Description: " \" name \"))) + (toString [_this] (str "Description: " \" name \"))) (defn new-description [name is-focused? ns] (Description. name (atom is-focused?) (atom false) ns (atom nil) (atom []) (atom []) (atom #{}) (atom []) (atom []) (atom []) (atom []) (atom []) (atom []) (atom []) (atom []))) @@ -49,7 +49,7 @@ (reset! (.-parent this) description) (swap! (.-characteristics description) conj this)) Object - (toString [this] (str \" name \"))) + (toString [_this] (str \" name \"))) (defn new-characteristic ([name body is-focused?] (Characteristic. name (atom nil) body (atom is-focused?))) @@ -106,67 +106,43 @@ (defn new-around-all [body] (AroundAll. body)) -#?(:clj - (deftype With [name unique-name body value bang] - SpecComponent - (install [this description] - (swap! (.-withs description) conj this)) - clojure.lang.IDeref - (deref [this] - (when (= ::none @value) - (reset! value (body))) - @value)) - - :cljs - (deftype With [name unique-name body value bang] - SpecComponent - (install [this description] - (swap! (.-withs description) conj this)) - cljs.core/IDeref - (-deref [this] - (when (= ::none @value) - (reset! value (body))) - @value))) +(deftype With [name body set-var! value bang] + SpecComponent + (install [this description] + (swap! (.-withs description) conj this)) + #?(:clj clojure.lang.IDeref :cljs cljs.core/IDeref) + (#?(:clj deref :cljs -deref) [_this] + (when (= ::none @value) + (reset! value (body))) + @value)) (defn reset-with [with] (reset! (.-value with) ::none) - (if (.-bang with) (deref with))) + (when (.-bang with) (deref with))) -(defn new-with [name unique-name body bang] - (let [with (With. name unique-name body (atom ::none) bang)] - (when bang (deref with)) ; TODO - MDM: This is the wrong place to deref. Should do it in body right after arounds. +(defn new-with [name body set-var! bang] + (let [with (With. name body set-var! (atom ::none) bang)] + (when bang (deref with)) ; TODO - MDM: This is the wrong place to deref. Should do it in body right after arounds. with)) -#?(:clj - (deftype WithAll [name unique-name body value bang] - SpecComponent - (install [this description] - (swap! (.-with-alls description) conj this)) - clojure.lang.IDeref - (deref [this] - (when (= ::none @value) - (reset! value (body))) - @value)) - - :cljs - (deftype WithAll [name unique-name body value bang] - SpecComponent - (install [this description] - (swap! (.-with-alls description) conj this)) - cljs.core/IDeref - (-deref [this] - (when (= ::none @value) - (reset! value (body))) - @value))) - -(defn new-with-all [name unique-name body bang] - (let [with-all (WithAll. name unique-name body (atom ::none) bang)] +(deftype WithAll [name body set-var! value bang] + SpecComponent + (install [this description] + (swap! (.-with-alls description) conj this)) + #?(:clj clojure.lang.IDeref :cljs cljs.core/IDeref) + (#?(:clj deref :cljs -deref) [_this] + (when (= ::none @value) + (reset! value (body))) + @value)) + +(defn new-with-all [name body set-var! bang] + (let [with-all (WithAll. name body set-var! (atom ::none) bang)] (when bang (deref with-all)) with-all)) (deftype Tag [name] SpecComponent - (install [this description] + (install [_this description] (swap! (.-tags description) conj name))) (defn new-tag [name] diff --git a/src/speclj/core.cljc b/src/speclj/core.cljc index d8e9bd4..97cb4b8 100644 --- a/src/speclj/core.cljc +++ b/src/speclj/core.cljc @@ -152,25 +152,11 @@ [context & body] `(speclj.components/new-around-all (fn ~context ~@body))) -(def cljs-munge - #?(:clj - (when (find-ns 'cljs.compiler) - (ns-resolve 'cljs.compiler (symbol "munge"))) - :cljs nil)) - (defn ^:no-doc -make-with [name body ctor bang?] - (let [var-name (with-meta (symbol name) {:dynamic true}) - munged-name (if cljs-munge - (with-meta - (symbol - (cljs-munge (str name))) - {:dynamic true}) - var-name) - unique-name (gensym "with")] + (let [var-name (with-meta (symbol name) {:dynamic true})] `(do (declare ~var-name) - (def ~unique-name (~ctor '~munged-name '~unique-name (fn [] ~@body) ~bang?)) - ~unique-name))) + (~ctor '~var-name (fn [] ~@body) (fn [v#] (set! ~var-name v#)) ~bang?)))) (defmacro with "Declares a reference-able symbol that will be lazily evaluated once per characteristic of the containing @@ -295,7 +281,7 @@ `(should= nil ~form)) (defmacro should-contain - "Multi-purpose assertion of containment. Works on strings, regular expressions, sequences, and maps. + "Multipurpose assertion of containment. Works on strings, regular expressions, sequences, and maps. (should-contain \"foo\" \"foobar\") ; looks for sub-string (should-contain #\"hello.*\" \"hello, world\") ; looks for regular expression @@ -321,7 +307,7 @@ :else (throw (-new-exception (wrong-types "should-contain" expected# actual#)))))) (defmacro should-not-contain - "Multi-purpose assertion of non-containment. See should-contain as an example of opposite behavior." + "Multipurpose assertion of non-containment. See should-contain as an example of opposite behavior." [expected actual] `(let [expected# ~expected actual# ~actual] @@ -342,10 +328,10 @@ :else (throw (-new-exception (wrong-types "should-not-contain" expected# actual#)))))) (defmacro should-have-count - "Multi-purpose assertion on (count %). Works on strings, sequences, and maps. + "Multipurpose assertion on (count %). Works on strings, sequences, and maps. (should-have-count 6 \"foobar\") - (should-have-count 2 [1 2]}) + (should-have-count 2 [1 2]) (should-have-count 1 {:foo :bar}) (should-have-count 0 []) (should-have-count 0 nil)" @@ -361,10 +347,10 @@ "Actual coll: " (-to-s coll#)))))))) (defmacro should-not-have-count - "Multi-purpose assertion on (not= (count %)). Works on strings, sequences, and maps. + "Multipurpose assertion on (not= (count %)). Works on strings, sequences, and maps. (should-not-have-count 1 \"foobar\") - (should-not-have-count 1 [1 2]}) + (should-not-have-count 1 [1 2]) (should-not-have-count 42 {:foo :bar}) (should-not-have-count 1 []) (should-not-have-count 1 nil)" @@ -564,7 +550,7 @@ (defmacro should-throw "Asserts that a Throwable is throws by the evaluation of a form. -When an class is passed, it asserts that the thrown Exception is an instance of the class. +When a class is passed, it asserts that the thrown Exception is an instance of the class. There are three options for passing different kinds of predicates: - If a string, assert that the message of the Exception is equal to the string. - If a regex, asserts that the message of the Exception matches the regex. @@ -614,7 +600,7 @@ There are three options for passing different kinds of predicates: (-fail (str "Expected " (-to-s actual#) " to be an instance of: " (-to-s expected-type#) speclj.platform/endl " but was an instance of: " (-to-s actual-type#) " (using isa?)"))))) (defmacro should-not-be-a - "Asserts that the type of the given form does not derived from or equals the expected type" + "Asserts that the type of the given form does not derive from or equal the expected type" [expected-type actual-form] `(let [actual# ~actual-form actual-type# (type actual#) @@ -639,7 +625,7 @@ There are three options for passing different kinds of predicates: `(mapv speclj.components/new-tag ~tag-kws))) (defmacro with-stubs - "Add this to describe/context blocks that use stubs. It will setup a clean recording environment." + "Add this to describe/context blocks that use stubs. It will set up a clean recording environment." [] `(around [it#] (with-redefs [speclj.stub/*stubbed-invocations* (atom [])] @@ -797,7 +783,7 @@ There are three options for passing different kinds of predicates: (should-have-invoked ~var-name options#))))) (defmacro should-not-invoke - "Creates a stub, and binds it to the specified var, evaluates the body, and checks that is was NOT invoked. + "Creates a stub, and binds it to the specified var, evaluates the body, and checks that it was NOT invoked. (should-not-invoke reverse {:with [1 2 3] :return [] :times 2} (reverse [1 2 3])) ; pass (should-not-invoke reverse {:with [1 2 3] :return []} (reverse [1 2 3])) ; fail diff --git a/src/speclj/running.cljc b/src/speclj/running.cljc index 1418f66..a2b7085 100644 --- a/src/speclj/running.cljc +++ b/src/speclj/running.cljc @@ -1,6 +1,5 @@ (ns speclj.running - (:require [clojure.string :as str] - [speclj.components :as components] + (:require [speclj.components :as components] [speclj.config :refer [active-reporters]] [speclj.platform :refer [current-time pending? secs-since]] [speclj.reporting :refer [report-description* report-run]] @@ -157,19 +156,12 @@ :cljs (defn- with-withs-bound [description body] - (let [withs (concat @(.-withs description) @(.-with-alls description)) - ns (str/replace (.-ns description) "-" "_") - var-names (map #(str ns "." (name (.-name %))) withs) - unique-names (map #(str ns "." (name (.-unique-name %))) withs)] - (doseq [[n un] (partition 2 (interleave var-names unique-names))] - (let [code (str n " = " un ";")] - (js* "eval(~{})" code))) + (let [withs (concat @(.-withs description) @(.-with-alls description))] + (run! #((.-set-var! %) %) withs) (try (body) (finally - (doseq [[n] var-names] - (let [code (str n " = null;")] - (js* "eval(~{})" code)))))))) + (run! #((.-set-var! %) nil) withs)))))) (defn- nested-results-for-context [description reporters] (let [results (results-for-context description reporters)] From 1ef1851be0fdeb64386d338e3c8bb1029a3299c7 Mon Sep 17 00:00:00 2001 From: Brandon Correa <50252804+brandoncorrea@users.noreply.github.com> Date: Mon, 27 May 2024 21:04:48 -0500 Subject: [PATCH 10/16] Pass all specs with advanced optimizations --- spec/speclj/config_spec.cljc | 1 + spec/speclj/core_spec.cljc | 34 +++++++++++++-------------- spec/speclj/report/progress_spec.cljc | 25 ++++++++++++-------- src/speclj/report/progress.cljc | 16 ++++++------- src/speclj/report/silent.cljc | 16 ++++++------- 5 files changed, 49 insertions(+), 43 deletions(-) diff --git a/spec/speclj/config_spec.cljc b/spec/speclj/config_spec.cljc index ac06777..c43d779 100644 --- a/spec/speclj/config_spec.cljc +++ b/spec/speclj/config_spec.cljc @@ -63,6 +63,7 @@ (context "exporting" (test-exported-meta sut/active-runner) + (test-exported-meta speclj.report.silent/new-silent-reporter) ) ) diff --git a/spec/speclj/core_spec.cljc b/spec/speclj/core_spec.cljc index 453ce8a..6a1df81 100644 --- a/spec/speclj/core_spec.cljc +++ b/spec/speclj/core_spec.cljc @@ -148,9 +148,9 @@ [ (around-all [context] - (swap! call-count inc) - (binding [*gewgaw* (swap! widget inc)] - (context))) + (swap! call-count inc) + (binding [*gewgaw* (swap! widget inc)] + (context))) (it "executes before the specs" (should= 6 @widget)) @@ -163,14 +163,14 @@ (context "nested" (around-all [context] - (swap! call-count inc) - (swap! widget #(/ % 2)) - (context)) + (swap! call-count inc) + (swap! widget #(/ % 2)) + (context)) (around-all [context] - (swap! call-count inc) - (swap! widget #(- % 2)) - (context)) + (swap! call-count inc) + (swap! widget #(- % 2)) + (context)) (it "executes in the order in which they are defined" (should= 1 @widget)) @@ -182,8 +182,8 @@ (let [widget (atom 6)] [ (around-all [context] - (swap! widget #(- % 2)) - (context)) + (swap! widget #(- % 2)) + (context)) (before-all (swap! widget #(/ % 2))) @@ -199,8 +199,8 @@ (swap! widget #(/ % 2))) (around-all [context] - (swap! widget #(- % 2)) - (context)) + (swap! widget #(- % 2)) + (context)) ) (describe "previous after-all and around-all forms" @@ -211,9 +211,9 @@ (with-all with-all-val 1) (around-all [context] - (should= 1 @with-all-val) - (context) - (should= 1 @with-all-val)) + (should= 1 @with-all-val) + (context) + (should= 1 @with-all-val)) (it "enters after binding with-alls and exits before unbinding" :filler)))) @@ -347,7 +347,7 @@ (describe "with-all" (def lazy-with-all-calls (atom 0)) (with-all with-all-example - (swap! lazy-with-all-calls inc)) + (swap! lazy-with-all-calls inc)) (it "never deref'ed with-all-example" (should= 0 @lazy-with-all-calls)) diff --git a/spec/speclj/report/progress_spec.cljc b/spec/speclj/report/progress_spec.cljc index a7f54b5..2f9099f 100644 --- a/spec/speclj/report/progress_spec.cljc +++ b/spec/speclj/report/progress_spec.cljc @@ -1,18 +1,19 @@ (ns speclj.report.progress-spec - (:require [speclj.core #?(:clj :refer :cljs :refer-macros) [around describe it should should= with -new-exception -new-failure -new-pending]] + (:require [speclj.core #?(:clj :refer :cljs :refer-macros) [around context describe it should should= with -new-exception -new-failure -new-pending]] [clojure.string :as str] #?(:cljs [goog.string]) ;cljs bug? [speclj.components :refer [new-description new-characteristic install]] [speclj.config :refer [*color?* *full-stack-trace?* *omit-pending?*]] [speclj.platform :as platform] - [speclj.report.progress :refer [new-progress-reporter full-name print-summary print-pendings print-errors]] + [speclj.spec-helper :as spec-helper] + [speclj.report.progress :as sut] [speclj.reporting :refer [report-description report-pass report-pending report-fail report-error red green yellow grey report-runs]] [speclj.results :refer [pass-result fail-result pending-result error-result]] [speclj.run.standard :as standard])) (describe "Progress Reporter" - (with reporter (new-progress-reporter)) + (with reporter (sut/new-progress-reporter)) (around [spec] (binding [*color?* false *omit-pending?* false] (spec))) @@ -104,14 +105,14 @@ result2 (pass-result char1 0.02) result3 (pending-result char1 0.003 (-new-pending "Blah")) results [result1 result2 result3] - lines (str/split-lines (with-out-str (print-summary results)))] + lines (str/split-lines (with-out-str (sut/print-summary results)))] (should= (yellow "3 examples, 0 failures, 1 pending") (last lines))))) (it "reports pending summary" (let [description (new-description "Crazy" false "some.ns") char1 (new-characteristic "flips" description "flip" false) result1 (pending-result char1 0.3 (-new-pending "Not Yet Implemented")) - lines (str/split-lines (with-out-str (print-pendings [result1])))] + lines (str/split-lines (with-out-str (sut/print-pendings [result1])))] (should= 6 (count lines)) (should= "" (nth lines 0)) (should= "Pending:" (nth lines 1)) @@ -126,7 +127,7 @@ (let [description (new-description "Crazy" false "some.ns") char1 (new-characteristic "flips" description "flip" false) result1 (pending-result char1 0.3 (-new-pending "Not Yet Implemented")) - printed-results (with-out-str (print-pendings [result1]))] + printed-results (with-out-str (sut/print-pendings [result1]))] (should= "" printed-results)))) (it "reports error run results" @@ -137,15 +138,15 @@ result2 (pass-result char1 0.02) result3 (error-result (-new-exception "blah")) results [result1 result2 result3] - lines (str/split-lines (with-out-str (print-summary results)))] + lines (str/split-lines (with-out-str (sut/print-summary results)))] (should= (red "3 examples, 0 failures, 1 errors") (last lines))))) (it "reports error summary" (binding [*full-stack-trace?* false] (let [description (new-description "Crazy" false "some.ns") - char1 (new-characteristic "flips" description "flip" false) + _char1 (new-characteristic "flips" description "flip" false) result1 (error-result (-new-exception "blah")) - lines (str/split-lines (with-out-str (print-errors [result1])))] + lines (str/split-lines (with-out-str (sut/print-errors [result1])))] (should (> (count lines) 3)) (should= "" (nth lines 0)) (should= "Errors:" (nth lines 1)) @@ -157,7 +158,11 @@ inner (new-description "Inner" false "some.ns") char (new-characteristic "char" inner "char" false)] (install inner outer) - (should= "Outer Inner char" (full-name char)))) + (should= "Outer Inner char" (sut/full-name char)))) + + (context "exporting" + (spec-helper/test-exported-meta sut/new-progress-reporter) + ) ) (standard/run-specs :stacktrace true) diff --git a/src/speclj/report/progress.cljc b/src/speclj/report/progress.cljc index 3400109..7f42010 100644 --- a/src/speclj/report/progress.cljc +++ b/src/speclj/report/progress.cljc @@ -92,22 +92,22 @@ (deftype ProgressReporter [] speclj.reporting/Reporter - (report-message [this message] + (report-message [_this message] (println message) (flush)) - (report-description [this description]) - (report-pass [this result] + (report-description [_this _description]) + (report-pass [_this _result] (print (green ".")) (flush)) - (report-pending [this result] + (report-pending [_this _result] (print (yellow "*")) (flush)) - (report-fail [this result] + (report-fail [_this _result] (print (red "F")) (flush)) - (report-error [this result] + (report-error [_this _result] (print (red "E")) (flush)) - (report-runs [this results] + (report-runs [_this results] (println) (print-summary results))) -(defn new-progress-reporter [] +(defn ^:export new-progress-reporter [] (ProgressReporter.)) (reset! default-reporters [(new-progress-reporter)]) diff --git a/src/speclj/report/silent.cljc b/src/speclj/report/silent.cljc index 70aed73..45cad92 100644 --- a/src/speclj/report/silent.cljc +++ b/src/speclj/report/silent.cljc @@ -3,13 +3,13 @@ (deftype SilentReporter [passes fails results] speclj.reporting/Reporter - (report-message [this message]) - (report-description [this description]) - (report-pass [this result]) - (report-pending [this result]) - (report-fail [this result]) - (report-runs [this results]) - (report-error [this exception])) + (report-message [_this _message]) + (report-description [_this _description]) + (report-pass [_this _result]) + (report-pending [_this _result]) + (report-fail [_this _result]) + (report-runs [_this _results]) + (report-error [_this _exception])) -(defn new-silent-reporter [] +(defn ^:export new-silent-reporter [] (SilentReporter. (atom 0) (atom 0) (atom nil))) From 934d94f7915621636056a6d14a4dd063e3dd5f81 Mon Sep 17 00:00:00 2001 From: Brandon Correa <50252804+brandoncorrea@users.noreply.github.com> Date: Mon, 27 May 2024 22:23:03 -0500 Subject: [PATCH 11/16] Add method to Runner to get-descriptions --- spec/speclj/run/standard_spec.clj | 1 + spec/speclj/run/vigilant_spec.clj | 7 +++---- spec/speclj/running_spec.clj | 1 + spec/speclj/spec_helper.cljc | 16 +++++++++++++++- src/speclj/run/standard.cljc | 2 ++ src/speclj/run/vigilant.clj | 6 ++++-- src/speclj/running.cljc | 4 ++++ 7 files changed, 30 insertions(+), 7 deletions(-) diff --git a/spec/speclj/run/standard_spec.clj b/spec/speclj/run/standard_spec.clj index d4c5d5b..f4149e1 100644 --- a/spec/speclj/run/standard_spec.clj +++ b/spec/speclj/run/standard_spec.clj @@ -43,6 +43,7 @@ (should= (assoc defaults :foo :bar) (sut/config-with-defaults [:foo :bar])) (should= (assoc defaults :foo :bar :baz "buzz") (sut/config-with-defaults [:foo :bar "baz" "buzz"])))) + (spec-helper/test-get-descriptions sut/new-standard-runner) (spec-helper/test-description-filtering sut/new-standard-runner) ) diff --git a/spec/speclj/run/vigilant_spec.clj b/spec/speclj/run/vigilant_spec.clj index ef37646..71bef3f 100644 --- a/spec/speclj/run/vigilant_spec.clj +++ b/spec/speclj/run/vigilant_spec.clj @@ -4,12 +4,11 @@ [speclj.spec-helper :as spec-helper])) (describe "Vigilant Runner" - (with runner (new-vigilant-runner)) + (spec-helper/test-get-descriptions new-vigilant-runner) + (spec-helper/test-description-filtering new-vigilant-runner) (it "can be created" - (should= [] @(.results @runner))) - - (spec-helper/test-description-filtering new-vigilant-runner) + (should= [] @(.results (new-vigilant-runner)))) ) (run-specs) diff --git a/spec/speclj/running_spec.clj b/spec/speclj/running_spec.clj index 8f93a84..44e96d4 100644 --- a/spec/speclj/running_spec.clj +++ b/spec/speclj/running_spec.clj @@ -105,6 +105,7 @@ (context "exporting" (spec-helper/test-exported-meta sut/filter-descriptions) + (spec-helper/test-exported-meta sut/get-descriptions) ) ) diff --git a/spec/speclj/spec_helper.cljc b/spec/speclj/spec_helper.cljc index 9980775..6e28b2d 100644 --- a/spec/speclj/spec_helper.cljc +++ b/spec/speclj/spec_helper.cljc @@ -1,5 +1,5 @@ (ns speclj.spec-helper - #?(:cljs (:require-macros [speclj.spec-helper :refer [test-exported-meta]])) + #?(:cljs (:require-macros [speclj.spec-helper :refer [test-exported-meta test-get-descriptions]])) (:require [speclj.core #?(:clj :refer :cljs :refer-macros) [context -fail it should= with]] [speclj.platform #?(:clj :refer :cljs :refer-macros) [try-catch-anything]] [speclj.components :as components] @@ -110,3 +110,17 @@ ) ) ) + +(defmacro test-get-descriptions [new-runner-fn] + `(it (str '~new-runner-fn " fetches descriptions") + (let [runner# (~new-runner-fn) + one# (components/new-description "One" false "some.ns") + two# (components/new-description "Two" false "some.other.ns") + three# (components/new-description "Three" false "three.ns")] + (should= [] (running/get-descriptions runner#)) + (running/submit-description runner# one#) + (should= [one#] (running/get-descriptions runner#)) + (running/submit-description runner# three#) + (should= [one# three#] (running/get-descriptions runner#)) + (running/submit-description runner# two#) + (should= [one# three# two#] (running/get-descriptions runner#))))) diff --git a/src/speclj/run/standard.cljc b/src/speclj/run/standard.cljc index b66a337..14a32cd 100644 --- a/src/speclj/run/standard.cljc +++ b/src/speclj/run/standard.cljc @@ -59,6 +59,8 @@ (run-directories [_this _directories _reporters] (js/alert "StandardRunner.run-directories: I don't know how to do this."))) + (-get-descriptions [_this] @descriptions) + (submit-description [_this description] (swap! descriptions conj description)) diff --git a/src/speclj/run/vigilant.clj b/src/speclj/run/vigilant.clj index 2557b56..ec998c2 100644 --- a/src/speclj/run/vigilant.clj +++ b/src/speclj/run/vigilant.clj @@ -77,12 +77,14 @@ (submit-description [_this description] (swap! descriptions conj description)) + (-get-descriptions [_this] @descriptions) + (-filter-descriptions [_this namespaces] (swap! descriptions running/descriptions-with-namespaces namespaces)) (run-description [_this description reporters] - (let [run-results (running/do-description description reporters)] - (swap! results into run-results))) + (->> (running/do-description description reporters) + (swap! results into))) (run-and-report [this reporters] (doseq [description (running/filter-focused @descriptions)] diff --git a/src/speclj/running.cljc b/src/speclj/running.cljc index a2b7085..c7ec458 100644 --- a/src/speclj/running.cljc +++ b/src/speclj/running.cljc @@ -197,6 +197,7 @@ (run-directories [this directories reporters]) (submit-description [this description]) (-filter-descriptions [this namespaces]) + (-get-descriptions [this]) (run-description [this description reporters]) (run-and-report [this reporters])) @@ -206,3 +207,6 @@ (->> namespaces #?(:cljs js->clj) (-filter-descriptions runner))) + +(defn ^:export get-descriptions [runner] + (-> runner -get-descriptions into-array)) From 8e01665ea21bb1c3f1e6a4fc8e4d829a0e5221d0 Mon Sep 17 00:00:00 2001 From: Brandon Correa <50252804+brandoncorrea@users.noreply.github.com> Date: Mon, 27 May 2024 22:24:24 -0500 Subject: [PATCH 12/16] Use exported speclj functions over cljs.core methods in js script --- bin/specs.html | 93 +++++++++++++++++++++++--------------------------- 1 file changed, 43 insertions(+), 50 deletions(-) diff --git a/bin/specs.html b/bin/specs.html index 7d1422b..e63025d 100644 --- a/bin/specs.html +++ b/bin/specs.html @@ -1,65 +1,58 @@ - - Speclj Specs - - - - + + + runSpecsFiltered = function (affectedSpecs) { + if (affectedSpecs != null) { + console.log("Only running affected specs:") + var runner = speclj.config.active_runner() + speclj.running.filter_descriptions(runner, affectedSpecs) + speclj.running.get_descriptions(runner) + .forEach((description) => + console.log(" ", description.ns)) + } + return runSpecsConfigured(true, "documentation") + } +

Speclj CLJS Specs

- Typically these specs are run using a headless browser driven by a script. - But you can run them here if you like. - That is, assuming all the cljs has been compiled in development. -
- Open up the browser console: + Typically these specs are run using a headless browser driven by a script. + But you can run them here if you like. + That is, assuming all the cljs has been compiled in development. +
+ Open up the browser console:

     runSpecs()

From f21a20110f910ab06705aee09e203f46b16b4ecd Mon Sep 17 00:00:00 2001
From: Brandon Correa <50252804+brandoncorrea@users.noreply.github.com>
Date: Mon, 27 May 2024 22:29:50 -0500
Subject: [PATCH 13/16] Fix descriptions specs

---
 spec/speclj/spec_helper.cljc | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/spec/speclj/spec_helper.cljc b/spec/speclj/spec_helper.cljc
index 6e28b2d..a18fe1c 100644
--- a/spec/speclj/spec_helper.cljc
+++ b/spec/speclj/spec_helper.cljc
@@ -117,10 +117,10 @@
            one#    (components/new-description "One" false "some.ns")
            two#    (components/new-description "Two" false "some.other.ns")
            three#  (components/new-description "Three" false "three.ns")]
-       (should= [] (running/get-descriptions runner#))
+       (should= [] (vec (running/get-descriptions runner#)))
        (running/submit-description runner# one#)
-       (should= [one#] (running/get-descriptions runner#))
+       (should= [one#] (vec (running/get-descriptions runner#)))
        (running/submit-description runner# three#)
-       (should= [one# three#] (running/get-descriptions runner#))
+       (should= [one# three#] (vec (running/get-descriptions runner#)))
        (running/submit-description runner# two#)
-       (should= [one# three# two#] (running/get-descriptions runner#)))))
+       (should= [one# three# two#] (vec (running/get-descriptions runner#))))))

From 1958292c652749364a098906bcf1a0e6e7eb9948 Mon Sep 17 00:00:00 2001
From: Brandon Correa <50252804+brandoncorrea@users.noreply.github.com>
Date: Mon, 27 May 2024 22:32:06 -0500
Subject: [PATCH 14/16] Run test workflow cljs specs under advanced
 optimizations

---
 .github/workflows/test.yml | 2 +-
 dev/speclj/dev/cljs.clj    | 1 -
 2 files changed, 1 insertion(+), 2 deletions(-)

diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index a497870..1524877 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -40,4 +40,4 @@ jobs:
         run: clojure -M:test:spec
 
       - name: Run ClojureScript Tests
-        run: clojure -M:test:cljs once
+        run: clojure -M:test:cljs ci
diff --git a/dev/speclj/dev/cljs.clj b/dev/speclj/dev/cljs.clj
index f474b21..6121c55 100644
--- a/dev/speclj/dev/cljs.clj
+++ b/dev/speclj/dev/cljs.clj
@@ -15,7 +15,6 @@
                  }
    :ci          {
                  :cache-analysis false
-                 :infer-externs  true
                  :optimizations  :advanced
                  :output-to      "target/specs.js"
                  :output-dir     "target/cljs"

From 2c4c51278ee58cee44c3ce47b5147481f8e0f3fb Mon Sep 17 00:00:00 2001
From: Brandon Correa <50252804+brandoncorrea@users.noreply.github.com>
Date: Mon, 27 May 2024 22:53:50 -0500
Subject: [PATCH 15/16] Update changelog

---
 CHANGES.md | 13 +++++++++----
 1 file changed, 9 insertions(+), 4 deletions(-)

diff --git a/CHANGES.md b/CHANGES.md
index 0e565b7..59f29c9 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -1,9 +1,14 @@
 # 3.4.8
 
-* `run-specs` now accepts string keys in addition to keyword keys
-* js runner executable may use `speclj.run.standard.arm()` instead of `speclj.run.standard.armed = true`
-* `Runner` can now `filter-descriptions` based on a collection of namespace strings
-* exports and refactors functions used by JavaScript for executing ClojureScript specs under advanced optimizations
+* can now be built and executed under `:advanced` ClojureScript optimizations
+  * exports functions needed by JavaScript
+  * refactors functions that would otherwise fail with `:advanced` optimizations
+  * extends `run-specs` to accepts string keys in addition to keyword keys
+  * exports `speclj.run.standard.arm()` function to JavaScript (synonym for `speclj.run.standard.armed = true`)
+  * exports `speclj.run.standard.disarm()` function to JavaScript (synonym for `speclj.run.standard.armed = false`)
+  * `Runner` can now `get-descriptions`
+  * `Runner` can now `filter-descriptions` based on a hash-map of string/boolean namespace pairs
+    * `{"speclj.core" true "speclj.reporting" false"}`
 
 # 3.4.7
 

From 08b77c8b2c2c5512eefe119002a817e289722691 Mon Sep 17 00:00:00 2001
From: Brandon Correa <50252804+brandoncorrea@users.noreply.github.com>
Date: Mon, 27 May 2024 22:58:17 -0500
Subject: [PATCH 16/16] Update README

---
 README.md | 14 ++++++--------
 1 file changed, 6 insertions(+), 8 deletions(-)

diff --git a/README.md b/README.md
index 96dcdd9..eb8df34 100644
--- a/README.md
+++ b/README.md
@@ -32,9 +32,9 @@ Include speclj in your `:dev` profile `:dependencies` and`:plugins`. Then change
 
 ```clojure
 ; - snip
-:dependencies [[org.clojure/clojure "1.11.2"]]
-:profiles {:dev {:dependencies [[speclj "3.4.6"]]}}
-:plugins [[speclj "3.4.6"]]
+:dependencies [[org.clojure/clojure "1.11.3"]]
+:profiles {:dev {:dependencies [[speclj "3.4.8"]]}}
+:plugins [[speclj "3.4.8"]]
 :test-paths ["spec"]
 ```
 
@@ -140,7 +140,7 @@ Add a `spec` alias to your `deps.edn`.
 ```clojure
 {
  :aliases {:spec  {:main-opts ["-m" "speclj.main" "-c"]
-                   :extra-deps  {speclj/speclj {:mvn/version "3.4.6"}}
+                   :extra-deps  {speclj/speclj {:mvn/version "3.4.8"}}
                    :extra-paths ["spec"]}}
  }
 ```
@@ -246,9 +246,7 @@ p.injectJs(phantom.args[0]);
 
 var result = p.evaluate(function () {
   speclj.run.standard.arm();
-  return speclj.run.standard.run_specs(
-     cljs.core.keyword("color"), true
-  );
+  return speclj.run.standard.run_specs("color", true);
 });
 
 phantom.exit(result);
@@ -314,7 +312,7 @@ Here's an example alias for your `deps.edn`.
 ```clojure
 {:aliases {:cov {:main-opts ["-m" "cloverage.coverage" "--runner" ":speclj" "-p" "src" "-s" "spec" ]
                  :extra-deps {cloverage/cloverage {:mvn/version "1.2.4"}
-                              speclj/speclj {:mvn/version "3.4.6"}}}}}
+                              speclj/speclj {:mvn/version "3.4.8"}}}}}
 ```
 
 Sadly, Cloverage doesn't offer a way to pass arguments to the runner (Speclj in this case).  Speclj will use the