Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/borkdude/respeced
Testing library for clojure.spec fdefs
https://github.com/borkdude/respeced
clojure clojure-spec testing
Last synced: 7 days ago
JSON representation
Testing library for clojure.spec fdefs
- Host: GitHub
- URL: https://github.com/borkdude/respeced
- Owner: borkdude
- License: epl-1.0
- Created: 2018-12-06T19:52:37.000Z (almost 6 years ago)
- Default Branch: master
- Last Pushed: 2022-10-29T12:19:37.000Z (about 2 years ago)
- Last Synced: 2024-05-01T20:30:08.791Z (6 months ago)
- Topics: clojure, clojure-spec, testing
- Language: Clojure
- Homepage:
- Size: 41 KB
- Stars: 51
- Watchers: 4
- Forks: 3
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE
Awesome Lists containing this project
README
# respeced
[![CircleCI](https://circleci.com/gh/borkdude/respeced/tree/master.svg?style=svg)](https://circleci.com/gh/borkdude/respeced/tree/master)
[![Clojars Project](https://img.shields.io/clojars/v/respeced.svg)](https://clojars.org/respeced)
[![cljdoc badge](https://cljdoc.org/badge/respeced/respeced)](https://cljdoc.org/d/respeced/respeced/CURRENT)Testing library for clojure.spec fdefs.
## Rationale
This library helps verify that [spec](https://clojure.org/about/spec) `fdefs` do
what they are supposed to do:- throw errors on non-valid arguments and return values
- not throw on valid arguments and return valuesA good illustration of the intended usage of this library can be seen in tests
for the
[speculative](https://github.com/slipset/speculative/blob/master/test/speculative/core_test.cljc)
library, where this library originated from.Respeced fully supports Clojure, ClojureScript and self-hosted ClojureScript.
## Installation
### deps.edn
```
respeced/respeced {:mvn/version "0.1.2"}
```### leiningen
```
[respeced "0.1.2"]
```## API
### `with-instrumentation`
Instrument a function in the scope of a body. Restores instrumentation state,
i.e. unstruments after the call only when the function was not instrumented
before the call.Example call:
```clojure
(with-instrumentation `foo (foo 1 2 3))
```### `with-unstrumentation`
Unstrument a function in the scope of a body. Restores instrumentation state,
i.e. only re-instruments after the call when the function was instrumented
before the call.Example call:
```clojure
(with-unstrumentation `foo (foo 1 2 3))
```### `caught?`
Returns `true` if body throws spec error for instrumented fn.Example call:
```clojure
(deftest my-fdef-works
(with-instrumentation `foo
(is (caught? `foo (foo :some-wrong-argument))))
```### `check-call`
Applies args to function resolved by symbol. Checks `:args`, `:ret` and `:fn`
specs. Returns return value of call if succeeded, else throws.Example call:
```clojure
(is (= [4 5 6] (check-call `foo [1 2 3])))
```### `check`
Like `clojure.spec.test.alpha/check` with third arg for passing
`clojure.test.check` options.Example call:
```clojure
(check `foo {} {:num-tests 10})
```### `successful?`
Returns `true` if all `clojure.spec.test.alpha/check` tests have `pass?` `true`.Example call:
```clojure
(successful? (check `foo {} {:num-tests 10}))
```## Example usage
``` clojure
$ clj -Sdeps '{:deps {respeced/respeced {:mvn/version "0.1.2"}}}'
Clojure 1.10user=> (require '[respeced.test :as rt])
niluser=> (require '[clojure.spec.alpha :as s])
niluser=> (s/fdef foo :args (s/cat :n number?) :ret number?)
user/foo;; this function has the wrong return value according to the spec:
user=> (defn foo [n] "ret")
#'user/foo;; rt/check-call helps with checking `:ret` and `:fn` specs:
user=> (rt/check-call `foo [1])
Execution error - invalid arguments to respeced.test$do_check_call/invokeStatic at (test.cljc:138).
"ret" - failed: number? at: [:ret];; change the spec:
user=> (s/fdef foo :args (s/cat :n number?) :ret string?)
user/foo;; no error anymore:
user=> (rt/check-call `foo [1])
"ret";; instrument a function within a scope:
user=> (rt/with-instrumentation `foo (foo "a"))
Execution error - invalid arguments to user/foo at (REPL:1).
"a" - failed: number? at: [:n];; not instrumented:
user=> (foo "a")
"ret";; `rt/check` has a third arg for passing `clojure.test.check` options:
user=> (rt/check `foo nil {:num-tests 1})
generatively testing user/foo
({:spec #object[clojure.spec.alpha$fspec_impl$reify__2524 0x72bd06ca "clojure.spec.alpha$fspec_impl$reify__2524@72bd06ca"], :clojure.spec.test.check/ret {:result true, :pass? true, :num-tests 1, :time-elapsed-ms 1, :seed 1541249961647}, :sym user/foo});; validate if generative test was successful:
user=> (rt/successful? *1)
trueuser=>
```## Tests
Requires [babashka](https://github.com/babashka/babashka#installation).
The tests can be called with an optional `deps.edn` alias argument to
specify the Clojure(Script) version to load, e.g.`bb clj-tests :1.10`
### All tests
`bb test`
### Clojure
`bb clj-tests`
### ClojureScript`bb cljs-tests`
## LicenseCopyright © 2018-2022 Michiel Borkent
Distributed under the EPL License, same as Clojure. See LICENSE.