Testing

It is possible to write and execute unit tests using Planck.

Let's say you have a namespace with a function you'd like to test.

(ns foo.core) (defn square [x] (+ x x)) 

You can test foo.core by writing a test namespace:

(ns foo.core-test (:require [cljs.test :refer-macros [deftest is]] [foo.core])) (deftest test-square (is (= 0 (foo.core/square 0))) (is (= 9 (foo.core/square 3)))) 

Then you can run the unit tests using run-tests:

cljs.user=> (cljs.test/run-tests 'foo.core-test) Testing foo.core-test FAIL in (test-square) (:5:1) expected: (= 9 (foo.core/square 3)) actual: (not (= 9 6)) Ran 1 tests containing 2 assertions. 1 failures, 0 errors. nil 

If you fix the definition of square to make use of * instead of +, then you can run the tests again and see thing they pass:

cljs.user=> (cljs.test/run-tests 'foo.core-test) Testing foo.core-test Ran 1 tests containing 2 assertions. 0 failures, 0 errors. nil 

Custom Asserts

The cljs.test library provides a mechanism for writing custom asserts that can be used with the is macro—in the form of an assert-expr defmulti.

To define your own assert, simply provide a defmethod for cljs.test$macros/assert-expr. Here's an example:

If you evaluate (is (char? nil)) you will get a cryptic error report:

ERROR in () (isUnicodeChar@file:269:12) expected: (char? nil) actual: #object[TypeError TypeError: null is not an object (evaluating 'ch.length')] 

You can define a custom assert for this situation:

(defmethod cljs.test$macros/assert-expr 'char? [menv msg form] (let [arg (second form) result (and (not (nil? arg)) (char? arg))] `(do (if ~result (cljs.test/do-report {:type :pass :message ~msg :expected '~form :actual (list '~'char? ~arg)}) (cljs.test/do-report {:type :fail :message ~msg :expected '~form :actual (list '~'not (list '~'char? ~arg))})) ~result))) 

With this, (is (char? nil)) yields:

FAIL in () (eval@[native code]:NaN:NaN) expected: (char? nil) actual: (not (char? nil))