Skip to content
New issue

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

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

Already on GitHub? # to your account

Allow arbitrary exception validation by passing a predicate function #132

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions spec/cljx/speclj/should_spec.cljx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
should= should== -to-s -new-throwable -new-exception]]
[speclj.spec-helper :refer [should-fail! should-pass! failure-message]]
)
(:require [speclj.platform :refer [endl exception type-name throwable]]
(:require [speclj.platform :refer [endl error-message exception type-name throwable]]
[speclj.run.standard :refer [run-specs]]))

(describe "Should Assertions: "
Expand Down Expand Up @@ -374,9 +374,15 @@
(should-fail! (should-throw exception "My message" (throw (-new-exception "Not my message"))))
(should-fail! (should-throw exception "My message" (throw (throwable "My message"))))
(should-fail! (should-throw exception "My message" (+ 1 1)))
(should= (str "Expected exception message didn't match" endl "Expected: \"My message\"" endl " got: \"Not my message\" (using =)")
(should= (str "Expected exception predicate didn't match" endl "Expected: \"My message\"" endl " got: \"Not my message\" (using =)")
(failure-message (should-throw exception "My message" (throw (-new-exception "Not my message"))))))

(it "should-throw can test an exception by calling a passed function"
(should-pass! (should-throw exception #(empty? (speclj.platform/error-message %)) (throw (-new-exception ""))))
(should-fail! (should-throw exception #((not (empty? (speclj.platform/error-message %))) (throw (-new-exception "")))))
(should= (str "Expected exception predicate didn't match" endl "Expected: true" endl " got: \"Not my message\" (using =)")
(failure-message (should-throw exception #(speclj.platform/error-message %) (throw (-new-exception "Not my message"))))))

(it "should-not-throw tests that nothing was thrown"
(should-pass! (should-not-throw (+ 1 1)))
(should-fail! (should-not-throw (throw (-new-throwable "error"))))
Expand Down
21 changes: 15 additions & 6 deletions src/clj/speclj/core.clj
Original file line number Diff line number Diff line change
Expand Up @@ -367,7 +367,10 @@
(defmacro should-throw
"Asserts that a Throwable is throws by the evaluation of a form.
When an class is passed, it assets that the thrown Exception is an instance of the class.
When a string is also passed, it asserts that the message of the Exception is equal to the string."
There are three options for passing different kinds of predicates:
- If a string, assert that the message of the Exception is equal to the string.
- If a regex, assertsthat the message of the Exception matches the regex.
- If a function, assert that calling the function on the Exception returns a truthy value."
([form] `(should-throw speclj.platform/throwable ~form))
([throwable-type form]
`(try
Expand All @@ -378,14 +381,20 @@ When a string is also passed, it asserts that the message of the Exception is eq
(speclj.platform/failure? e#) (throw e#)
(not (isa? (type e#) ~throwable-type)) (throw (-create-should-throw-failure ~throwable-type e# '~form))
:else e#))))
([throwable-type message form]
([throwable-type predicate form]
`(let [e# (should-throw ~throwable-type ~form)
regex# ~(if cljs? `js/RegExp `java.util.regex.Pattern)]
(try
(if (instance? regex# ~message)
(should-not-be-nil (re-find ~message (speclj.platform/error-message e#)))
(should= ~message (speclj.platform/error-message e#)))
(catch ~(if cljs? ':default 'Throwable) f# (-fail (str "Expected exception message didn't match" speclj.platform/endl (speclj.platform/error-message f#))))))))
(cond (instance? regex# ~predicate)
(should-not-be-nil (re-find ~predicate (speclj.platform/error-message e#)))

(instance? clojure.lang.IFn ~predicate)
(should= true (~predicate e#))

:else
(should= ~predicate (speclj.platform/error-message e#)))

(catch ~(if cljs? ':default 'Throwable) f# (-fail (str "Expected exception predicate didn't match" speclj.platform/endl (speclj.platform/error-message f#))))))))

(defmacro should-not-throw
"Asserts that nothing is thrown by the evaluation of a form."
Expand Down