ghostwheel

Hassle-free clojure.spec, automatic generative testing, side effect detection, and evaluation tracing for Clojure(-Script) – https://github.com/gnl/ghostwheel
Sen 2018-08-19T03:42:52.000100Z

Found this issue https://github.com/bhauman/lein-figwheel/issues/707

Sen 2018-08-19T03:44:04.000100Z

Still not clear what should I do to use Ghostwheel with Figwheel?

gnl 2018-08-19T18:18:36.000100Z

@armikhalev (::g/check true) doesn't look right, if that's how you're using it, it's not gonna do much: https://github.com/gnl/ghostwheel#testing-specced-functions As for the issue – it's closed, see the second comment, Ghostwheel works fine with Figwheel now. (EDIT: Well, except that changes to the ns metadata often aren't picked up correctly on hot-reload, at least last time I checked. See the link in my comment in the issue you posted.) Also do make sure you're using the newest version – 0.2.3: https://clojars.org/gnl/ghostwheel The failing tests without a proper explanation remind me of an issue in an older version.

Sen 2018-08-19T19:42:06.000100Z

I have tried to enable check in both ways the mentioned (::g/check true) which is as you mention is not correct and as per ReadMe:

#:ghostwheel.core{:check     true
                    :num-tests 10}
  ...)
neither works. The first form (::g/check true) I kinda assumed from the following sentence in ReadMe: There’s no need for this in the function metadata – if you alias Ghostwheel with ghostwheel.core :as g you can just reference the options as ::g/check.

Sen 2018-08-19T19:43:11.000100Z

And yes, I use the latest version 0.2.3

Sen 2018-08-19T19:44:55.000100Z

I think the real problem I'm facing is exactly this you mentioned changes to the ns metadata often aren't picked up correctly on hot-reload, is there a way to make sure that changes are picked up by figwheel?

gnl 2018-08-19T20:31:01.000100Z

@armikhalev Cleaning the build and restarting Figwheel should definitely do it (if that is the problem). If this doesn't work, just post the whole code for a minimal namespace where you think Ghostwheel should work but doesn't.

gnl 2018-08-19T20:35:37.000100Z

@armikhalev And regarding the function level config metadata - you can reference the keys as ::g/check but you still need to attach the metadata correctly either directly to the function name symbol as described here: https://clojure.org/reference/metadata Or via the attr-map parameter to defn: https://clojuredocs.org/clojure.core/defn There are examples of both in the Ghostwheel docs.

Sen 2018-08-19T20:46:06.000100Z

Restarting figwheel doesn't help, well, that's the weird part, sometimes after several attempts, trying to clean build, restarting figwheel, or causing an error just to make sure that figwheel is hot-reloading or even adding (prn (g/check)) - one of those triggers Ghostwheel and I see the errors in console, but I cannot find any pattern that I can repeat the same steps and get it working.

Sen 2018-08-19T20:48:03.000100Z

Here is the relevant part of the code:

(ns my-app.my-code
#:ghostwheel.core{:check     true
                    :num-tests 10}
  (:require [re-frame.core :as re-frame]
            [cljs.spec.alpha :as spec]
            [ghostwheel.core :as g
             :refer [>defn >defn- >fdef => | <- ?]]
            [cljs.pprint :as pp]

))

(>defn foo
       [coll n]
       [(spec/coll-of int? :kind vector?) int?
        => seq?]
       (map n coll))

(>defn addition
       [a b]
       [pos-int? pos-int? => int? | #(> % a) #(> % b)]
       (+ a b))


(>defn ranged-rand
       "I lifted straight from the clojure.spec guide"
       [start end]
       [int? int? | #(< start end)
        => int? | #(>= % start) #(< % end)]
       (+ start (long (rand (- end start)))))

(g/check)

Sen 2018-08-19T20:50:46.000100Z

and in my project file I have:

(defproject my-app "0.1.0-SNAPSHOT"
  :dependencies [[org.clojure/clojure "1.9.0"]
                 [org.clojure/clojurescript "1.10.238"]
                 [org.clojure/test.check "0.9.0"]
                 [reagent "0.7.0"]
                 [re-frame "0.10.5"]
                 [secretary "1.2.3"]
                 [venantius/accountant "0.2.4"]
                 [ns-tracker "0.3.1"]
                 [gnl/ghostwheel "0.2.3"]
                 [day8.re-frame/http-fx "0.1.6"]
                 [day8.re-frame/test "0.1.5"]
                 [cljs-ajax "0.7.3"]]

  :plugins [[lein-cljsbuild "1.1.7"]]

  :min-lein-version "2.5.3"

  :source-paths ["src/clj"]

  :clean-targets ^{:protect false} ["resources/public/js/compiled" "target"]

  :figwheel {:css-dirs ["resources/public/css"]
             :ring-handler my-app.dev-server/handler}

  :repl-options {:nrepl-middleware [cider.piggieback/wrap-cljs-repl]}

  :aliases {"dev" ["do" "clean"
                   ["pdo" ["figwheel" "dev"]]]
            "build" ["with-profile" "+prod,-dev" "do"
                     ["clean"]
                     ["cljsbuild" "once" "min"]]}

  :profiles
  {:dev
   {:dependencies [[binaryage/devtools "0.9.10"]
                   [figwheel-sidecar "0.5.16"]
                   [day8.re-frame/tracing "0.5.1"]
                   [cider/piggieback "0.3.1"]
                   [day8.re-frame/re-frame-10x "0.3.3"]]

    :plugins      [[lein-figwheel "0.5.16"]
                   [lein-doo "0.1.8"]
                   [lein-pdo "0.1.1"]]}
   :prod {
          :dependencies [[day8.re-frame/tracing-stubs "0.5.1"]]}}

  :doo {:build "test"}

  :cljsbuild
  {:builds
   [{:id           "dev"
     :source-paths ["src/cljs"]
     :figwheel     {:on-jsload "my-app.core/mount-root"}
     :compiler     {:main                 my-app.core
                    :output-to            "resources/public/js/compiled/app.js"
                    :output-dir           "resources/public/js/compiled/out"
                    :asset-path           "/js/compiled/out"
                    :source-map-timestamp true
                    :closure-defines      {"re_frame.trace.trace_enabled_QMARK_" true,
                                           "day8.re_frame.tracing.trace_enabled_QMARK_"  true,
                                           goog.DEBUG true}
                    :preloads             [day8.re-frame-10x.preload, devtools.preload]
                    :external-config      {:ghostwheel {}
                                           :devtools/config {:features-to-install [:formatters :hints]}}}}

    {:id           "min"
     :source-paths ["src/cljs"]
     :compiler     {:main            my-app.core
                    :output-to       "resources/public/js/compiled/app.js"
                    :optimizations   :advanced
                    :closure-defines {goog.DEBUG false}
                    :pretty-print    false}}

    {:id           "test"
     :source-paths ["src/cljs" "test/cljs"]
     :compiler     {:main          my-app.runner
                    :output-to     "resources/public/js/compiled/test.js"
                    :output-dir    "resources/public/js/compiled/test/out"
                    :optimizations :none
                    }}

    ]})

Sen 2018-08-19T21:00:07.000100Z

ok, for some reason now I can reproduce one behavior, namely I run lein clean and then lein figwheel dev, open browser console and can see the Ghostwheel showing errors. But still they are empty, with seemingly correct code taken from Readme.

danielgrosse 2018-08-19T21:36:01.000100Z

I tried to implement the examples of the Spec documentation, but the higher order function gives me a side effect warning, is this correct? Did I also wrote the spec in the right way?

danielgrosse 2018-08-19T21:37:13.000100Z

gnl 2018-08-20T08:40:29.000100Z

@danielgrosse adder probably gives you a side effect warning because you mistyped and left the such-that predicate out of the gspec square brackets.

danielgrosse 2018-08-20T08:42:27.000100Z

How would this line be converted to the ghostwheel syntax #(= (-> % :args :x) ((:ret %) 0))

gnl 2018-08-20T08:44:03.000100Z

#(= x (% 0))