Skip to content

Commit

Permalink
Merge pull request #61 from circleci/add-new-assertions-methods
Browse files Browse the repository at this point in the history
Add called-once-with-args? and called-at-least-once-with-args? to bond/assertions
  • Loading branch information
Andrewwelton authored Aug 18, 2021
2 parents 6fe01e6 + c09aa79 commit 0d389cf
Showing 5 changed files with 101 additions and 23 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -4,6 +4,10 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [0.6.0]
### Added
- New assertions `called-once-with-args?` and `called-at-least-once-with-args?`.

## [0.5.0]
### Removed
- Support for ClojureScript. Please pin to 0.4.0 if you need it.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -4,7 +4,7 @@ Bond [![CircleCI Status](https://circleci.com/gh/circleci/bond.png?style=badge)]
Bond is a spying and stubbing library, primarily intended for tests.

```clojure
[circleci/bond "0.5.0"]
[circleci/bond "0.6.0"]
```

```clojure
2 changes: 1 addition & 1 deletion project.clj
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
(defproject circleci/bond "0.5.0"
(defproject circleci/bond "0.6.0"
:description "Spying library for testing"
:license {:name "Eclipse Public License"
:url "http://www.eclipse.org/legal/epl-v10.html"}
18 changes: 17 additions & 1 deletion src/bond/assertions.clj
Original file line number Diff line number Diff line change
@@ -14,6 +14,22 @@
(defn called-with-args?
"An assertion to check if `f` was called with `vargs`.
`vargs` should be a vector of args [args-first-call args-second-call ...] to allow for the checking of multiple calls of `f`."
`vargs` should be a vector of args [args-first-call args-second-call ...] to allow for the checking of multiple calls of `f`.
Note that this method asserts about every call to `f`."
[f vargs]
(= vargs (->> f bond/calls (mapv :args))))

(defn called-once-with-args?
"An assertion to check if `f` was called with `args` strictly once.
`args` should be a vector/coll of args [arg1 arg2 arg3] to compare directly to the value of `:args` from `bond/calls`"
[f args]
(called-with-args? f [args]))

(defn called-at-least-once-with-args?
"An assertion to check if `f` has been called at least once with `args`.
`args` should be a vector/coll of args [arg1 arg2 {:arg3 arg3}] to compare directly to the value of `:args` from `bond/calls`"
[f args]
(boolean (some (fn [call] (= (:args call) args))
(bond/calls f))))
98 changes: 78 additions & 20 deletions test/bond/assertions_test.clj
Original file line number Diff line number Diff line change
@@ -7,13 +7,13 @@
(deftest called?-works
(testing "a spy was called directly"
(bond/with-spy [target/foo]
(let [_ (target/foo 1)]
(is (assertions/called? target/foo)))))
(target/foo 1)
(is (assertions/called? target/foo))))

(testing "a spy was called indirectly"
(bond/with-spy [target/foo]
(let [_ (target/foo-caller 1)]
(is (assertions/called? target/foo)))))
(target/foo-caller 1)
(is (assertions/called? target/foo))))

(testing "a spy was not called"
(bond/with-spy [target/foo]
@@ -26,17 +26,17 @@
(deftest called-times?-works
(testing "the number of times a spy was called"
(bond/with-spy [target/foo]
(let [_ (target/foo-caller 1)]
(is (assertions/called-times? target/foo 1 )))
(let [_ (target/foo 2)]
(is (assertions/called-times? target/foo 2)))))
(target/foo-caller 1)
(is (assertions/called-times? target/foo 1))
(target/foo 2)
(is (assertions/called-times? target/foo 2))))

(testing "the number of times a spy was not called"
(bond/with-spy [target/foo]
(let [_ (target/foo-caller 1)]
(is (not (assertions/called-times? target/foo 2))))
(let [_ (target/foo-caller 2)]
(is (not (assertions/called-times? target/foo 1))))))
(target/foo-caller 1)
(is (not (assertions/called-times? target/foo 2)))
(target/foo-caller 2)
(is (not (assertions/called-times? target/foo 1)))))

(testing "called-times? fails when its argument is not spied"
(is (thrown? IllegalArgumentException
@@ -46,18 +46,76 @@
(testing "an assertion for calling a spy with args"
(bond/with-spy [target/foo
target/bar]
(let [_ (target/foo-caller 1)]
(is (assertions/called-with-args? target/foo [[1]]))
(is (not (assertions/called-with-args? target/foo [[2]])))
(is (not (assertions/called-with-args? target/bar [[1]])))
(is (not (assertions/called-with-args? target/foo [[1 2]]))))))
(target/foo-caller 1)
(is (assertions/called-with-args? target/foo [[1]]))
(is (not (assertions/called-with-args? target/foo [[2]])))
(is (not (assertions/called-with-args? target/bar [[1]])))
(is (not (assertions/called-with-args? target/foo [[1 2]])))))

(testing "an assertion for calling a spy multiple times with args"
(bond/with-spy [target/foo]
(let [_ (do (target/foo-caller 1)
(target/foo-caller 2))]
(is (assertions/called-with-args? target/foo [[1] [2]])))))
(target/foo-caller 1)
(target/foo-caller 2)
(is (assertions/called-with-args? target/foo [[1] [2]]))))

(testing "called-with-args? fails when its argument is not spied"
(is (thrown? IllegalArgumentException
(assertions/called-with-args? target/foo [])))))

(deftest called-once-with-args?-works
(testing "an assertion for calling a spy once with args"
(bond/with-spy [target/foo]
(target/foo 1)
(is (assertions/called-once-with-args? target/foo [1]))
(is (not (assertions/called-once-with-args? target/foo [2])))))

(testing "an assertion for calling a spy twice with args"
(bond/with-spy [target/foo]
(target/foo 1)
(target/foo 2)
(is (not (assertions/called-once-with-args? target/foo [1])))
(is (not (assertions/called-once-with-args? target/foo [2])))))

(testing "an assertion for calling a spy indirectly once with args"
(bond/with-spy [target/foo]
(target/foo-caller 1)
(is (assertions/called-once-with-args? target/foo [1]))
(is (not (assertions/called-once-with-args? target/foo [2])))))

(testing "an assertion for a spy that was not called"
(bond/with-spy [target/foo]
(is (not (assertions/called-once-with-args? target/foo [])))))

(testing "called-once-with-args? fails when its argument is not spied"
(is (thrown? IllegalArgumentException
(assertions/called-once-with-args? target/foo [])))))

(deftest called-at-least-once-with-args?-works
(testing "an assertion for calling a spy multiple times"
(bond/with-spy [target/foo]
(target/foo 1)
(target/foo 2)
(is (assertions/called-at-least-once-with-args? target/foo [1]))
(is (assertions/called-at-least-once-with-args? target/foo [2]))
(is (not (assertions/called-at-least-once-with-args? target/foo [3])))))

(testing "an assertion for calling a spy multiple times with the same value"
(bond/with-spy [target/foo]
(target/foo 1)
(target/foo 1)
(is (assertions/called-at-least-once-with-args? target/foo [1]))
(is (not (assertions/called-at-least-once-with-args? target/foo [2])))))

(testing "an assertion for calling a spy once"
(bond/with-spy [target/foo]
(target/foo 1)
(is (assertions/called-at-least-once-with-args? target/foo [1]))
(is (not (assertions/called-at-least-once-with-args? target/foo [2])))))

(testing "an assertion for a spy that was not called"
(bond/with-spy [target/foo]
(is (not (assertions/called-at-least-once-with-args? target/foo [])))))

(testing "called-at-least-once-with-args? fails when its argument is not spied"
(is (thrown? IllegalArgumentException
(assertions/called-at-least-once-with-args? target/foo [])))))

0 comments on commit 0d389cf

Please sign in to comment.