Fork me on GitHub
#shadow-cljs
<
2021-09-09
>
Franklin08:09:01

I'm trying to run tests for a speced cljs function using karma... it seems trickier than I expected I'm getting an error that looks like this

--------------------------------------------------------------------------------
  23 | 
  24 | (defn ^:export run
  25 |   [karma]
  26 |   (-> (stest/enumerate-namespace 'quagga.utils.components.share-modal.events) stest/check)
---------^----------------------------------------------------------------------
Encountered error when macroexpanding cljs.spec.test.alpha/check.
Error in phase :compile-syntax-check
RuntimeException: No such namespace: stest
Here's how I'm running the test; not sure if its' the correct way to do it
(defn ^:export run
  [karma]
  (-> (stest/enumerate-namespace 'quagga.utils.components.share-modal.events) stest/check)
  (karma/run-tests karma
                   'quagga.utils.components.account-select.events-test
                   'quagga.components.dataview.table.events-test
                   'quagga.utils.components.share-modal.events-test))

Franklin10:09:51

I've also imported/required stest

[clojure.spec.test.alpha :as stest]

thheller20:09:36

should be fine assuming thats actually in the ns :require of that file

Franklin08:09:28

still having trouble running spec tests. Do you have some/any pointers on how I can run generative tests? @U05224H0W

thheller08:09:06

as always can't provide much help without seeing code

Franklin08:09:23

I have a test runner namespace that looks like this

(defn ^:export run
  [karma]
  (stest/abbrev-result (first (stest/check `ranged-rand)))
  (karma/run-tests karma
                   'quagga.utils-test
                   'quagga.utils.components.account-select.events-test
                   'quagga.components.dataview.table.events-test
                   'quagga.utils.components.share-modal.events-test
                   'quagga.components.organization.profile.events-test
                   'quagga.components.organization.user-management.events-test
                   'quagga.components.dataview.table.views-test
                   'quagga.components.dataview.table.utils-test
                   'quagga.components.dataview.table.subs-test
                   'quagga.utils.views.wrap-header-and-footer-test
                   'quagga.components.dataview.subs-test
                   'quagga.components.dataview.utils-test
                   'quagga.utils.views.walkthrough-test
                   'quagga.utils.components.share-modal.views-test
                   'quagga.utils.views.confirm-modal-test
                   'quagga.utils.components.new-project-modal.views-test
                   'quagga.components.dataview.charts.views-test))

Franklin08:09:34

all the tests run fine... no errors

Franklin08:09:57

but the (stest/abbrev-result (first (stest/check ranged-rand))) is set up, on purpose to fail

thheller08:09:59

don't know what karma/run-tests is

thheller08:09:12

don't know what build config you are using

thheller08:09:21

don't know how you actually run the build output

thheller08:09:26

looks to me like you are running the tests separate from the generative test?

thheller08:09:51

I mean why is this (stest/check ranged-rand)` in the run function and not some test?

Franklin08:09:00

yes... but that's probably because I don't really know the right way to run the generative tests yet

Franklin08:09:23

karma/run-tests comes from [jx.reporter.karma :as karma :include-macros true]

Franklin08:09:49

which is a dependency in my package.json as karma-junit-reporter

Franklin08:09:20

on the console, running the generative test looks like this

> (stest/abbrev-result (first (stest/check `ranged-rand)))
{:spec (fspec :args (and (cat :start int? :end int?) (fn* [p1__34241#] (< (:start p1__34241#) (:end p1__34241#)))) :ret int? :fn (and (fn* [p1__34242#] (>= (:ret p1__34242#) (-> p1__34242# :args :start))) (fn* [p1__34243#] (< (:ret p1__34243#) (-> p1__34243# :args :end))))), :sym cljs.user/ranged-rand, :failure {:cljs.spec.alpha/problems [{:path [:fn], :pred (cljs.core/fn [%] (cljs.core/>= (:ret %) (cljs.core/-> % :args :start))), :val {:args {:start 0, :end 4}, :ret -2}, :via [], :in []}], :cljs.spec.alpha/spec #object[cljs.spec.alpha.t_cljs$spec$alpha38456], :cljs.spec.alpha/value {:args {:start 0, :end 4}, :ret -2}, :cljs.spec.test.alpha/args (0 4), :cljs.spec.test.alpha/val {:args {:start 0, :end 4}, :ret -2}, :cljs.spec.alpha/failure :check-failed}}

Franklin08:09:24

so it fails ok/as expected

thheller08:09:28

don't know what that is or does but the way I'd go about it is

thheller08:09:49

(deftest my-gen-test (stest/check `ranged-rand))

thheller08:09:09

and do whatever you need to do to assert the result so the deftest actually fails

Franklin08:09:35

cool... I'll try this both in my tests and in the console and see how it goes

Franklin08:09:25

so, it seems the test is actually registered with cljs-test

> (deftest my-gen-test (stest/check `ranged-rand))
#'cljs.user/my-gen-test
cljs.user=> (require '[cljs.test :as test :refer-macros [run-tests] :refer [report]])
nil
cljs.user=> (run-tests)

Testing cljs.user

Ran 1 tests containing 0 assertions.
0 failures, 0 errors.
nil
> (deftest my-gen-test2 (stest/check `ranged-rand))
#'cljs.user/my-gen-test2
> (run-tests)

Testing cljs.user

Ran 2 tests containing 0 assertions.
0 failures, 0 errors.
nil
cljs.user=> 

Franklin08:09:41

but the issue seems to be that there aren't any assertions in it

Franklin08:09:26

I guess I can check the return value of (stest/check `ranged-rand) and if it's an empty vector then the test has passed

Franklin08:09:44

so (is (= [] (stest/check `ranged-rand))

Franklin08:09:39

ok.. yeah 😃 :thumbsup: that works

FAIL in (my-gen-test2) (repl-input.cljs:1:27)
expected: (= [] (stest/check (quote cljs.user/ranged-rand)))
  actual: (not (= [] [{:spec #object[cljs.spec.alpha.t_cljs$spec$alpha38994], :clojure.spec.test.check/ret {:shrunk {:total-nodes-visited 5, :depth 4, :pass? false, :result #error {:message "Specification-based check failed", :data {:cljs.spec.alpha/problems [{:path [:fn], :pred (cljs.core/fn [%] (cljs.core/>= (:ret %) (cljs.core/-> % :args :start))), :val {:args {:start 0, :end 2}, :ret -1}, :via [], :in []}], :cljs.spec.alpha/spec #object[cljs.spec.alpha.t_cljs$spec$alpha38456], :cljs.spec.alpha/value {:args {:start 0, :end 2}, :ret -1}, :cljs.spec.test.alpha/args (0 2), :cljs.spec.test.alpha/val {:args {:start 0, :end 2}, :ret -1}, :cljs.spec.alpha/failure :check-failed}}, :result-data {:clojure.test.check.properties/error #error {:message "Specification-based check failed", :data {:cljs.spec.alpha/problems [{:path [:fn], :pred (cljs.core/fn [%] (cljs.core/>= (:ret %) (cljs.core/-> % :args :start))), :val {:args {:start 0, :end 2}, :ret -1}, :via [], :in []}], :cljs.spec.alpha/spec #object[cljs.spec.alpha.t_cljs$spec$alpha38456], :cljs.spec.alpha/value {:args {:start 0, :end 2}, :ret -1}, :cljs.spec.test.alpha/args (0 2), :cljs.spec.test.alpha/val {:args {:start 0, :end 2}, :ret -1}, :cljs.spec.alpha/failure :check-failed}}}, :time-shrinking-ms 3, :smallest [(0 2)]}, :failed-after-ms 6, :num-tests 3, :seed 1631261832504, :fail [(9 13)], :result #error {:message "Specification-based check failed", :data {:cljs.spec.alpha/problems [{:path [:fn], :pred (cljs.core/fn [%] (cljs.core/>= (:ret %) (cljs.core/-> % :args :start))), :val {:args {:start 9, :end 13}, :ret 6}, :via [], :in []}], :cljs.spec.alpha/spec #object[cljs.spec.alpha.t_cljs$spec$alpha38456], :cljs.spec.alpha/value {:args {:start 9, :end 13}, :ret 6}, :cljs.spec.test.alpha/args (9 13), :cljs.spec.test.alpha/val {:args {:start 9, :end 13}, :ret 6}, :cljs.spec.alpha/failure :check-failed}}, :result-data {:clojure.test.check.properties/error #error {:message "Specification-based check failed", :data {:cljs.spec.alpha/problems [{:path [:fn], :pred (cljs.core/fn [%] (cljs.core/>= (:ret %) (cljs.core/-> % :args :start))), :val {:args {:start 9, :end 13}, :ret 6}, :via [], :in []}], :cljs.spec.alpha/spec #object[cljs.spec.alpha.t_cljs$spec$alpha38456], :cljs.spec.alpha/value {:args {:start 9, :end 13}, :ret 6}, :cljs.spec.test.alpha/args (9 13), :cljs.spec.test.alpha/val {:args {:start 9, :end 13}, :ret 6}, :cljs.spec.alpha/failure :check-failed}}}, :failing-size 2, :pass? false}, :sym cljs.user/ranged-rand, :failure #error {:message "Specification-based check failed", :data {:cljs.spec.alpha/problems [{:path [:fn], :pred (cljs.core/fn [%] (cljs.core/>= (:ret %) (cljs.core/-> % :args :start))), :val {:args {:start 0, :end 2}, :ret -1}, :via [], :in []}], :cljs.spec.alpha/spec #object[cljs.spec.alpha.t_cljs$spec$alpha38456], :cljs.spec.alpha/value {:args {:start 0, :end 2}, :ret -1}, :cljs.spec.test.alpha/args (0 2), :cljs.spec.test.alpha/val {:args {:start 0, :end 2}, :ret -1}, :cljs.spec.alpha/failure :check-failed}}}]))

Ran 2 tests containing 1 assertions.
1 fail

thheller08:09:56

I guess the clojure.test.check.results/pass? is supposed to do this

Franklin08:09:12

doesn't really seem to report failures if I don't check if result is = to [ ].... but I think I'll just work with this for now

thheller08:09:35

(deftest my-gen-test2
  (ctcr/pass? (stest/check `ranged-rand)))

👍 2
thheller08:09:59

or rather

(deftest my-gen-test2
  (is (ctcr/pass? (stest/check `ranged-rand))))

👍 2
thheller08:09:10

really just need something that takes the actual result you get and gets the info you need out

thheller08:09:25

either can write that function yourself or use something from test.check

thheller08:09:31

I'm not sure what you are supposed to use

Franklin08:09:33

I'll just write a custom function... I'm satisfied with what I have already 😄

thheller08:09:15

there most likely is something to do this. just might need to dig through some test.check sources or api docs

👍 2
Franklin08:09:56

any clue as to how I can get it to work?

Chase18:09:31

I have a leiningen/shadow-cljs full stack app built from a luminus template. I am getting this shadow-cljs warning when doing a release build:

WARNING: You required cljs-devtools library in a project which is currently compiled with :optimizations :advanced.
remote:                 You should remove this library from non-dev builds completely because it impedes dead code elimination.
remote:                 The best way is to use :preloads compiler option: .

Chase18:09:30

Part of the project.clj file that luminus gave me is this:

:profiles                                                                                                               
  {:uberjar {:omit-source true                                                                                            
                                                                                                                          
             :prep-tasks ["compile" ["run" "-m" "shadow.cljs.devtools.cli" "release" "app"]]                              
             :aot :all                                                                                                    
             :uberjar-name "ai.jar"                                                                                       
             :source-paths ["env/prod/clj"  "env/prod/cljs"]                                                              
             :resource-paths ["env/prod/resources"]}                                                                      
                                                                                                                          
   :dev           [:project/dev :profiles/dev]                                                                            
   :test          [:project/dev :project/test :profiles/test]                                                             
                                                                                                                          
   :project/dev  {:jvm-opts ["-Dconf=dev-config.edn"]                                                                     
                  :dependencies [[binaryage/devtools "1.0.3"]                                                             
                                 [cider/piggieback "0.5.2"]                                                               
                                 [org.clojure/tools.namespace "1.1.0"]                                                    
                                 [pjstadig/humane-test-output "0.11.0"]                                                   
                                 [prone "2021-04-23"]                                                                     
                                 [re-frisk "1.5.1"]                                                                       
                                 [ring/ring-devel "1.9.4"]                                                                
                                 [ring/ring-mock "0.4.0"]]                                                                
                  :plugins      [[com.jakemccrary/lein-test-refresh "0.24.1"]                                             
                                 [jonase/eastwood "0.3.5"]                                                                
                                 [cider/cider-nrepl "0.26.0"]]                                                            
                                                                                                                          
                                                                                                                          
                  :source-paths ["env/dev/clj"  "env/dev/cljs" "test/cljs"]                                               
                  :resource-paths ["env/dev/resources"]                                                                   
                  :repl-options {:init-ns user                                                                            
                                 :timeout 120000}                                                                         
                  :injections [(require 'pjstadig.humane-test-output)                                                     
                               (pjstadig.humane-test-output/activate!)]} 
and the shadow-cljs.edn file has this:
:builds                                                                                                                  
        {:app                                                                                                             
               {:target     :browser                                                                                      
                :output-dir "target/cljsbuild/public/js"                                                                  
                :asset-path "/js"                                                                                         
                :modules    {:app {:entries []}}                                                                    
                :devtools   {:watch-dir "resources/public"                                                                
                             :preloads  [re-frisk.preload]}                                                               
                :dev        {:closure-defines {"re_frame.trace.trace_enabled_QMARK_" true}}                               
                :release    {:compiler-options {:optimimizations :advanced}}}                                             
         :test {:target  :node-test, :output-to "target/test/test.js"                                                     
                :autorun true}}                                                                                           
 :lein  {:profile "+dev"}} 
So my build process is running this: shadow-cljs - running: lein with-profile +dev run -m shadow.cljs.devtools.cli --npm release app which is the problem because calling on that lein +dev is including the stuff I don't want in release. The uberjar profile in the project.clj file is not telling it to add that +dev part in the :prep-tasks commands so how do I get that honored?

thheller20:09:26

dependencies do not decide what ends up in your build

thheller20:09:29

the config looks fine

thheller20:09:46

I'm guessing you are requiring something from devtools.* somerwhere in your code?

Chase20:09:58

Yes, but it's in /env/dev/app.cljs which is a source path only called for in the lein :project/dev profile which is why I thought it was shadow-cljs pulling in when calling that lein +dev command

thheller20:09:20

if you need per build or per task profiles just use lein itself

thheller20:09:03

but I consider it an anti-pattern to switch the source paths like that so I'd recommend setting things up properly so you don't have to do this

Chase20:09:06

Interesting. This is just a standard luminus template build so unfortunately I'm not too familiar with it's approach yet but it's probably something that should be brought to their attention.

Chase20:09:41

I have to step away but I'll work on this more later. Thanks for the help!

thheller20:09:20

this pattern of your "main" namespace in 2 variants depending on the env should be avoided

thheller20:09:42

just have one variant used by dev and release and then setup the extra stuff you need in a namespace included via :preloads (or just including those things directly via preloads)

thheller20:09:32

haven't looked at luminus in a long while.