Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

When keys spec fails, the entire map is printed out (not the summary form) #129

Open
bhb opened this issue Oct 18, 2018 · 2 comments
Open

Comments

@bhb
Copy link
Owner

bhb commented Oct 18, 2018

When a keys spec fails, there is no need to print out the values, and doing so means that a huge map will be printed.

@bhb
Copy link
Owner Author

bhb commented Oct 27, 2018

There isn't a clean way to do this currently, since code to print a value is currently independent of the type of failure (in this case, the failure type is that there are missing keys).

In general, it's not possible to always summarize a map by hiding unimportant values. Consider the case where the user adds a predicate that checks the values of a map - we wouldn't want to hide those values.

However, it is true that for many predicates, it would be fine to summarize the map - if you pass in a large map and the spec expects a vector, there's no need to print all the values.

There's a balance here between making Expound easy to read in a relatively common case of large data structures, but also having a simple set of rules and not getting bogged down in special cases.

@bhb
Copy link
Owner Author

bhb commented Oct 27, 2018

@borkdude's was to write a custom value printer:

(declare my-expound-value-str)

(def expound-opts
  {:show-valid-values? false
   :value-str-fn #'my-expound-value-str
   :print-specs? true})

(defn my-expound-value-str
  "Prints only keys if system map, else defaults to expound."
  [_spec-name form path value]
  (if (and (map? value)
           (every? (fn [ns]
                     (when ns
                       (str/starts-with? ns "dre.app")))
                   (map (fn [k]
                          (and (keyword? k)
                               (namespace k)))
                        (keys value))))
    (str (keys value))
    (#'expound/value-in-context expound-opts _spec-name form path value)))

(defn my-explain-out
  [explain-data]
  ((expound/custom-printer
    expound-opts) explain-data))

(defn activate-specs
  "Check spec asserts and fdefs"
  []
  (alter-var-root #'s/*explain-out*
                  (constantly #'my-explain-out))
  (s/check-asserts true)
  (st/instrument))

A few things to note:

  1. value-in-context is currently private, so it's awkward to use it
  2. The code special-cases an app-specific data structure (just prints the keys) but then falls back to Expound by default

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant