Fork me on GitHub

FYI, its pretty easy to generate a string generator of min/max length using: #(sgen/fmap str/join (sgen/vector (sgen/char-alphanumeric) min max))


Hi! When I start shadow-cljs with :browser-test , insead of :app, my spec instrumentation doesn't work. The specs work with (exercise fully-qualified-ns/spec), but I can't instrument functions either through code or repl. Any ideas?


Is something from the test namespaces requiring the files containing the specs?


Yes. I also have an instrument command in that namespace and also tried it through REPL while in that namespace


I can even copy the specs into REPL, run the instrument command there and it's not working


This is probably something with your code. We have specs on test ns's running with :browser-test, and there's nothing special about the invocation/setup:

(stest/instrument `ns/component)


It's worth noting that the instrument call must happen after the fdef, so mind the namespaces loading order


I just drop-in replaced it with orchestra-cljs.spec.test and it works


yes, the instrument calls are after the fdefs


So with orchestra it works, but no idea why it doesn't with normal spec. It's hard to debug when you don't get an error, it just doesn't work 😞

Oliver George22:11:13

I find myself wringing my hands when writing specs in my CLJS code. Particularly choosing namespaces for my specs. I'd like something like (s/def ::list-options/options (s/coll-of ::option)) to mean (s/def :current-ns.list-options/options (s/coll-of ::option)) where the alias isn't defined in the current ns.


I've found it convenient to always define specs as ::foo, and reference specs with ::foo or ::x/foo. It eliminates a lot of bikeshedding and subtle bugs. I want it to fail when the ns alias isn't defined.


Oh, I see what you mean. You could just move the dot segments to the other side of the slash, e.g., ::list-options.options.

Oliver George04:11:45

That works sometimes but for s/keys you need the name part to match so it's the namespace part which needs to be adaptable/unique.


Ah, yeah, if you're using unnamespaced keywords


i wanted a similar thing for db enums so i made it.

(defn enum
  (let [key-ns (namespace value)
        last-dot (.lastIndexOf key-ns ".")
        model (subs key-ns 0 last-dot)
        spec-name (subs key-ns (inc last-dot))
        type-name (str/replace (str model "-" spec-name) "-" "_")
        spec-kw (keyword (str "my-app.spec." model "s") spec-name)
        enum-value (name value)]
    (if (s/valid? spec-kw enum-value)
      (convert-enum type-name enum-value)
      (throw (ex-info "invalid enum value"
                      {:type ::invalid-enum
                       :data (s/explain-data spec-kw enum-value)})))))
this validates keywords like :my-model.status/ok against ::my-model/status to see if "ok" is a valid value

Oliver George22:11:24

Or something similar and less complected of course.

Oliver George22:11:13

Perhaps something like clojure.core/alias for CLJS would solve the problem.