- Notifications
You must be signed in to change notification settings - Fork7
bensu/cljs-react-test
Folders and files
Name | Name | Last commit message | Last commit date | |
---|---|---|---|---|
Repository files navigation
(:require [cljs-react-test.simulate :as sim] [cljs-react-test.utils :as tu])
It is not trivial to get the dependecies right when adding librariesthat depend on different versions of React (addons vs no addons). The followingvery explicit configuration should work:
(:dependencies [cljs-react-test"0.1.4-SNAPSHOT"] [cljsjs/react-with-addons"15.2.0-0"] [cljsjs/react-dom"15.2.0-0":exclusions [cljsjs/react]])
A thin wrapper aroundReact.addons.TestUtils.It provides convenient access to their Simulate Events inClojureScript in a more idiomatic way. All ofReact's Synthetic Eventshave their corresponding action in kebab-case, removing the "on":
Simulate.onChange(target, data)(change target data)Simulate.onDrop(target, data)(drop target data)
All arguments can be passed as ClojureScript objects and they will beconverted to JS objects viaclj->js
.
Note: Right now all functions take two arguments, even those that don'tneed the second one:
Simulate.onClick(target)(click target) ;; Will raise a warning(click target nil) ;; Correct Way
This will be corrected in the next version.
It also offers a couple of convenient fixture functions in thecljs-react-test.utils
namespace such asnew-container!
andunmount!
.
This guide uses
om
which is deprecated in favor ofom.next
For an example using raw React, look attest/basic.cljs
in this repository
We will be testing anOm component thattakes a name as input and displays it. We start by requiringcljs-react-test.utils
,cljs-react-test.simulate
, anddommy.core
,and our usual namespaces:
(nscljs-react-test.basic (:require [cljs.test:refer-macros [deftest testing is are use-fixtures]] [cljs-react-test.utils:as tu] [cljs-react-test.simulate:as sim] [dommy.core:as dommy:refer-macros [sel1 sel]] [om.core:as om:include-macrostrue] [om.dom:as dom:include-macrostrue]))
We create avar
where we will put a DOM object to act as containerfor our application and a fixture function that starts it, runs thetests, and then tears down React's rendering tree:
(def ^:dynamicc)(use-fixtures:each (fn [test-fn] (binding [c (tu/new-container!)] (test-fn) (tu/unmount! c))))
Note: this fixture will not work with asynchronous tests.
We write the simplest component we can think of:
(defntest-component [data owner] (om/component (dom/divnil (dom/pnil"Enter your name:") (dom/input #js {:onChange #(om/update! data:name (.. % -target -value)):value (:name data)}) (dom/pnil (str"Your name is:" (:name data))))))
And then we test it assuming there is a DOM Element atc
:
(deftestname-component (testing"The initial state is displayed" (let [app-state (atom {:name"Arya"}) _ (om/root test-component app-state {:target c}) display-node (second (sel c [:p])) input-node (sel1 c [:input])] (is (re-find#"Arya" (.-innerHTML display-node))) (testing"and when there is new input, it changes the state" (sim/change input-node {:target {:value"Nymeria"}}) (om.core/render-all) (is (="Nymeria" (:name @app-state))) (is (re-find#"Nymeria" (.-innerHTML display-node)))))))
Notice the structure of test:
- Set up the initial state in
app-state
. - Start the application with
om/root
intoc
. - Test the initial rendering.
- Simulate events and then force a re-render with
om/render-all
. - Test the changes both in the state and in the rendering tree.
- Go back to 4
First download the repo:
git clone https://github.com/bensu/cljs-react-testcd cljs-react-tests
And then run the tests withdoo:
lein with-profile test doo slimer test
Or if you want to use PhantomJS:
lein with-profile test doo phantom test
Or use the alias defined inproject.clj
which uses SlimerJS:
lein test
I've had a better experience with SlimerJS than with PhantomJS.
We need to run the tests in a different profile since the libraryitself shouldn't depend onom
but the tests do.
Pull requests, issues, and feedback welcome.
Copyright © 2016 Sebastian Bensusan
Distributed under the Eclipse Public License either version 1.0 or (atyour option) any later version.