Islands in a test: rendered as a session renders them, on the test's own thread, without a server, a stream or a browser.
(with-open [h (test/harness #(app uid) {:uid uid})]
(is (str/includes? (test/render! h) "Clicked 0 times"))
((test/action h "app/counter" :click) {})
(is (str/includes? (test/render! h) "Clicked 1 times")))
A harness holds what its islands hold, as a session does: the resources they read, their state, their action tokens. Closing it unmounts them, so their resources start to linger, and their tokens are revoked.
Renders run in the scope of the thread calling render!, as a session's run
in the scope of the request that created it: bind what the route's
middleware would with scoping around them. An island using a cookie state
(co.multiply.tropical.cookie) renders its default.
Islands in a test: rendered as a session renders them, on the test's own
thread, without a server, a stream or a browser.
```clojure
(with-open [h (test/harness #(app uid) {:uid uid})]
(is (str/includes? (test/render! h) "Clicked 0 times"))
((test/action h "app/counter" :click) {})
(is (str/includes? (test/render! h) "Clicked 1 times")))
```
A harness holds what its islands hold, as a session does: the resources they
read, their state, their action tokens. Closing it unmounts them, so their
resources start to linger, and their tokens are revoked.
Renders run in the scope of the thread calling `render!`, as a session's run
in the scope of the request that created it: bind what the route's
middleware would with `scoping` around them. An island using a cookie state
(`co.multiply.tropical.cookie`) renders its default.(action {:keys [rt uid request]} path k)The action that the mounted island at path renders under k
(use-action), as a fn that invokes it, or nil if the island doesn't render
it now. path is the island's id, the path of slots from the root, such as
"app/messages/message.17": mounted lists them.
The fn takes the signals, and for an action taking a value (:value), the
value. They pass through JSON as the browser's would, so the handler gets
string keys. It returns what the handler returned: a map of signals, nil, or
a navigation (action/navigation has its script). An action whose island has
stopped rendering it since throws, its token revoked.
The action that the mounted island at `path` renders under `k` (`use-action`), as a fn that invokes it, or nil if the island doesn't render it now. `path` is the island's id, the path of slots from the root, such as `"app/messages/message.17"`: `mounted` lists them. The fn takes the signals, and for an action taking a value (`:value`), the value. They pass through JSON as the browser's would, so the handler gets string keys. It returns what the handler returned: a map of signals, nil, or a navigation (`action/navigation` has its script). An action whose island has stopped rendering it since throws, its token revoked.
(failures {:keys [!failures]})The renders that threw, since the harness was made, in order: each
{:island id :error e}.
The renders that threw, since the harness was made, in order: each
`{:island id :error e}`.(harness root)(harness root {:keys [uid tab error-view request] :or {uid "user" tab "tab"}})A session's islands under root, for a test: an island's Call, such as
(app uid), or a fn of no arguments returning one, called for each render.
Render them with render!, and close the harness, as with-open does, to
unmount them.
opts:
:uid, the session's user, which use-session returns and actions are
bound to; "user" by default. :tab, the session's tab.:error-view, (fn [id e] hiccup), rendered in place of an island whose
render throws, as the app's is. The default is the library's. failures
has the exceptions either way.:request, the Ring request that created the session, which
use-session returns, and the one an action's handler gets from
action/request, which in a session is the action's own. Without one,
action/request throws, as it does outside an action.A session's islands under `root`, for a test: an island's `Call`, such as `(app uid)`, or a fn of no arguments returning one, called for each render. Render them with `render!`, and close the harness, as `with-open` does, to unmount them. `opts`: - `:uid`, the session's user, which `use-session` returns and actions are bound to; `"user"` by default. `:tab`, the session's tab. - `:error-view`, `(fn [id e] hiccup)`, rendered in place of an island whose render throws, as the app's is. The default is the library's. `failures` has the exceptions either way. - `:request`, the Ring request that created the session, which `use-session` returns, and the one an action's handler gets from `action/request`, which in a session is the action's own. Without one, `action/request` throws, as it does outside an action.
(mounted {:keys [rt]})The ids of the mounted islands: the paths of slots from the root.
The ids of the mounted islands: the paths of slots from the root.
(render! h)(render! {:keys [rt inbox root]} {:keys [wait-ms] :or {wait-ms 1000}})Renders what changed since the last render, the whole tree the first time, and returns the HTML of the whole tree, as the page would show it.
While an island's read is still pending (hooks/pending), as an observe
whose source hasn't emitted yet, it waits for the reads to land and renders
again, for up to :wait-ms in all, 1000 by default. With {:wait-ms 0} it
renders once, so a test sees what the island shows while it waits.
Renders what changed since the last render, the whole tree the first time,
and returns the HTML of the whole tree, as the page would show it.
While an island's read is still pending (`hooks/pending`), as an `observe`
whose source hasn't emitted yet, it waits for the reads to land and renders
again, for up to `:wait-ms` in all, 1000 by default. With `{:wait-ms 0}` it
renders once, so a test sees what the island shows while it waits.cljdoc builds & hosts documentation for Clojure/Script libraries
| Ctrl+k | Jump to recent docs |
| ← | Move to previous article |
| → | Move to next article |
| Ctrl+/ | Jump to the search field |