bhb / expound

Human-optimized error messages for clojure.spec
Eclipse Public License 1.0
924 stars 24 forks source link

Feature inquiry: a convenience function for validating a value against a spec #214

Closed aviflax closed 3 years ago

aviflax commented 3 years ago

I feel like I’ve written variations on this fn across a bunch of projects:

(defn valid?!
  [spec val error-prefix]
  (when-not (s/valid? spec val)
    (throw (ex-info (str error-prefix ": " (expound/expound-str spec val {:print-specs? false}))
                    (s/explain-data spec val)))))

so I’m wondering whether this, or something similar, might be a good idea to include in Expound?

I’d be happy to submit a PR, if so.

Thank you!

bhb commented 3 years ago

@aviflax Thanks for the idea, I appreciate it!

At least for now, I'm going to keep Expound focused on just improving the spec error messages. This is method is useful, but I think it's a better fit for a separate library.

aviflax commented 3 years ago

Sure, that makes sense. Thanks for considering it and the gracious feedback!

devurandom commented 1 year ago

For reference, in case someone finds it useful, here is a clojure.test helper I wrote to make the "diff" of spec validations readable without having to litter my test code with (is (= "Success!\n" (expound/expound-str :my/spec x))):

(require [clojure.test :refer :all])
(require [expound.alpha :as expound])
(require [clojure.spec.alpha :as s])

(defmethod assert-expr 'valid?
  [message [_ spec actual]]
  `(do-report
     {:type     (if (s/valid? ~spec ~actual) :pass :fail)
      :message  ~message
      :expected "Success!\n"
      :actual   (expound/expound-str ~spec ~actual)}))

(declare handler)

(deftest example-test
  (testing "that response is valid"
    (let [{:keys [body]} (handler {:body-params {:sample "input"}})]
      (is (valid? :my/spec body)))))

At least in Cursive / IntelliJ this displays well.

bhb commented 1 year ago

@devurandom Nice!