ghostwheel

Hassle-free clojure.spec, automatic generative testing, side effect detection, and evaluation tracing for Clojure(-Script) – https://github.com/gnl/ghostwheel
samueldev 2018-07-16T00:15:25.000003Z

question for @clojurians.net or whoever

samueldev 2018-07-16T00:15:39.000059Z

step 1 of getting started

samueldev 2018-07-16T00:15:41.000004Z

add the artifact to your build configuration

samueldev 2018-07-16T00:15:44.000081Z

in my case, a figwheel project

samueldev 2018-07-16T00:15:59.000071Z

im used to adding deps to the top level :dependencies in my project

samueldev 2018-07-16T00:16:13.000060Z

am i meant to be adding ghostwheel to my :dev build profile deps instead?

samueldev 2018-07-16T02:26:19.000004Z

Additional question: I can't seem to get the syntax correct for a function with no arguments?

samueldev 2018-07-16T02:26:34.000060Z

(>defn navigation-menu
       []
       [? => vector?]
       [:nav#navigation
        [:ul
         [:li [:i.fas.fa-bars]]
         [:li.active "Games"]
         [:li "Explore"]
         [:li "Leaderboards"]
         [:li "Contact"]
         [:li "Login"]]])

samueldev 2018-07-16T02:26:43.000117Z

I thought this is what I'd want but it fails the >defn spec..

wilkerlucio 2018-07-16T02:40:39.000041Z

@samueldev I guess that first ? on the arg declaration shouldn't be there

wilkerlucio 2018-07-16T02:40:53.000081Z

have you tried just [=> vector?]?

samueldev 2018-07-16T02:42:49.000067Z

@wilkerlucio that did it 🙂 thank you!

samueldev 2018-07-16T02:47:42.000069Z

Now I'm getting some interesting (confusing) feedback from (g/check) on my namespace

samueldev 2018-07-16T02:47:44.000086Z

Output:

samueldev 2018-07-16T02:47:45.000072Z

https://puu.sh/AX6NA/dc12728bb1.png

samueldev 2018-07-16T02:48:08.000075Z

(no details are present in the outputted log denoting that there's some kind of spec check failure)

samueldev 2018-07-16T02:48:53.000020Z

(ns website.components
  #:ghostwheel.core{:check      true
                    :num-tests  10
                    :outstrument true}
  (:require [ghostwheel.core :as g :refer [>defn => |]]))

(>defn navigation-menu
       "website nav"
       []
       [=> vector?]
       [:nav#navigation
        [:ul
         [:li [:i.fas.fa-bars]]
         [:li.active "Games"]
         [:li "Explore"]
         [:li "Leaderboards"]
         [:li "Contact"]
         [:li "Login"]]])

(js/console.log (navigation-menu))

(g/check)

2018-07-16T05:16:45.000046Z

No. You're replacing your defns with >defn. If you were to run a build without ghostwheel as a dependency, those macros would be undefined. Ghostwheel does a good job of compiling away to nothing in a production build. Just make sure that your :ghostwheel configuration is only applied to your dev build.

2018-07-16T05:37:59.000099Z

@samueldev What version are you running?

samueldev 2018-07-16T10:46:35.000177Z

0.2.3

gnl 2018-07-16T14:22:39.000039Z

@samueldev Hey, Sam, please confirm that it's the final 0.2.3 version and not a "-SNAPSHOT". I'll look into it in the meantime. On first sight some keywords look invalid, but not sure if that's related – I don't think you can have . in a keyword.

samueldev 2018-07-16T14:29:15.000175Z

that's the reagent shorthand syntax for classes on a dom element

samueldev 2018-07-16T14:29:29.000360Z

https://reagent-project.github.io/

samueldev 2018-07-16T14:29:34.000215Z

(see first example Source)

👍 1
samueldev 2018-07-16T14:30:02.000353Z

and it is the final version, yup 🙂

gnl 2018-07-16T14:30:36.000171Z

Got it, will get back to you a bit later.

gnl 2018-07-16T15:48:41.000449Z

@samueldev I can't reproduce this here, everything checks out fine with 0.2.3, so let's make sure this isn't a stale build/cache issue first. Clean your build, remove .shadow-cljs if you're using it, remove ~/.m2/repository/gnl and try again.

gnl 2018-07-16T15:50:04.000405Z

On a side note – I'd recommend against outstrumenting the whole namespace when you're also checking it. This is a bit of a belt and suspenders situation and most likely you really only need one.

gnl 2018-07-16T15:51:57.000129Z

And regarding the . in keywords – apparently we were both sort of right. It violates the specification as far as I understand it, but the compiler's fine with it and changing that would break too much existing code, so I guess it's fine and likely to remain so. A bit like keywords starting with a number.

2018-07-16T17:55:51.000371Z

I was under the impression that ::g/check just enabled generative testing; not any kind of runtime call-checking. Looking at the docs, I can't find anywhere that outlines exactly what ::g/check does. Why would you recommend against using both? Does ::g/check report contract violations during runtime?

gnl 2018-07-16T18:16:47.000054Z

::g/check doesn't do anything at runtime (differentiating here between runtime and test time). It's the recommended approach, because you get proper code coverage, a much higher likelihood of catching edge cases, and no runtime performance penalty. I don't really use ::g/outstrument or ::g/instrument, but I know people do and it was easy to implement, that's why it's in there. But when they are used, I'd say it makes more sense to use them on a single function basis.

gnl 2018-07-16T18:19:08.000023Z

But point taken on that it's not exactly clear from the documentation what ::g/check does under the hood, precisely. I'll add it to the readme, but the tl;dr is that it generates the test code and is required for the additional checks that (g/check) does.

gnl 2018-07-16T18:24:17.000168Z

Everyone – if you have 2 seconds, please vote here for your preferred gspec operators if you haven't yet: https://clojurians.slack.com/archives/CBGSAMBPW/p1531436074000224 (message is pinned to the channel) I'm not taking anything out, just curious how Clojurians feel about this in general.