Skip to content

Commit

Permalink
Add docs about matchers and how to add a custom matcher
Browse files Browse the repository at this point in the history
- Update changelog (including previous missing `setup-mocks` fix)
  • Loading branch information
jo-sm committed May 26, 2023
1 parent 7469979 commit e668d83
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 1 deletion.
13 changes: 13 additions & 0 deletions changelog.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,18 @@
# Changelog

# Next

## Features
- [Allow users to define their own matchers.](https://github.com/pitch-io/cljest/pull/27)

## Improvements
- [Allow aliases to be defined in `cljest.edn` so that Jest can use it when getting the classpath.](https://github.com/pitch-io/cljest/pull/27)

## Bugfixes
- [Always reinstantiate mocks for each test case when using `setup-mocks`.](https://github.com/pitch-io/cljest/pull/28)
- [Fix matcher negation.](https://github.com/pitch-io/cljest/pull/27)


# 1.0.0

## Features
Expand Down
3 changes: 2 additions & 1 deletion docs/component-tests.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,9 @@ Okay, how do we test it? To test it, we need to render our component and simulat
Looking at the above, you'll notice a few things:

- We're rendering our component, `main/the-bakery`, very similarly to how we do in our normal code, and you don't need to keep a reference to it later. Instead, `h.dom/get-by` (and other query functions) use the ["screen"](https://testing-library.com/docs/queries/about#screen), the `document.body`, when looking for elements.
- We queried by text rather than a testing ID. Whenever possible, it's best to query for elements by their ARIA role, text, or something visible or spec defined, and query by the test ID as a last resort. https://testing-library.com/docs/queries/about#priority
- We queried by text rather than a testing ID. Whenever possible, it's best to query for elements by their ARIA role, text, or something visible or spec defined, and query by the test ID as a last resort. For some details about when to use which queries, see the [`testing-library` query priority docs](https://testing-library.com/docs/queries/about#priority).
- We're testing the component from the end user's perspective. We don't know that internally it's using `use-state`, and for all we know, it could be using `re-frame` or another state management library.
- We're using a matcher to assert that the element is visible, which is coming from `cljest.matchers`. For more details about matchers, please see the [`cljest.matchers` namespace](https://github.com/pitch-io/cljest/blob/master/cljest/src/cljest/matchers.cljs) and the [matchers docs](./matchers.md).

## Going further - more cookies!!

Expand Down
58 changes: 58 additions & 0 deletions docs/matchers.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# Matchers

[Matchers are the way Jest deals with assertions](https://jestjs.io/docs/using-matchers), and are the functions that are defined on `expect`:

```js
// `toBe` is the matcher here
expect(1).toBe(1);
```

`cljest` has some built-in matchers, primarily coming from [`jest-dom`](https://github.com/testing-library/jest-dom), and is extendable, allowing for you to define your own custom matchers in your code without needing to include them in `cljest` directly.

# How do I use matchers?

Matchers act just like another assertion: you wrap it in `is` and Jest will assert when it's called:

```clj
(require '[cljest.core :refer [it is]]
'[cljest.helpers.dom :as h.dom]
'[cljest.matchers :as m]
'[uix.core :refer [$ defui]])

(defui my-cool-component
[]
($ :div.blue "hello world"))

(it "should have the `blue` class when initially rendered"
(h.dom/render ($ my-cool-component))
(is (m/has-class? (h.dom/get-by :text "hello world") "blue")))
```

If you don't wrap your matcher in `is`, you'll get an error; matchers must be wrapped in `is` to work.

## Negation

Matchers can also be negated using `not`:

```clj
(it "should not have the `red` class when initially rendered"
(h.dom/render ($ my-cool-component))
(is (not (m/has-class? (h.dom/get-by :text "hello world") "red"))))
```

# Built-in matchers

By default, `cljest` includes matchers from [`jest-dom`](https://github.com/testing-library/jest-dom), such as `toBeVisible`, `toHaveClass`, `toBeValid`, as well as a few assertions for `spy` calls like `called-with?`. These matchers live in [`cljest.matchers`](https://github.com/pitch-io/cljest/blob/master/cljest/src/cljest/matchers.cljs), and so for more details about which matchers are available, please look at the defined matchers in the `cljest.matchers` namespace.

# How do I make my own matcher?

In the event there's a matcher you'd like to use that's not included in `cljest`, you can use the macro `cljest.matcher/defmatcher` to define your matcher. This macro is like `def`, and takes the symbol (like `has-class?`) and the underlying matcher name (like `toHaveClass`):

```clj
(ns app.custom-matchers
(:require-macros [cljest.matchers :refer [defmatcher]]))

(defmatcher has-class? "toHaveClass")
```

That's all you need to do! The rest is handled internally, including support negation, and basically this macro defines a function that has some metadata that's used during compilation to treat it as a matcher rather than a non-matcher assertion inside of `is`.
1 change: 1 addition & 0 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ For more details, as well as details about getting started and configuration, pl
[Migrating from `cljs.test` to `cljest` and differences](./docs/migrating.md)<br />
[Unit tests](./docs/unit-tests.md)<br />
[Component tests](./docs/component-tests.md)<br />
[Matchers](./docs/matchers.md)<br />
[Mocking](./docs/mocking.md)<br />
[Async code](./docs/async.md)<br />
[General API docs](./docs/api.md)<br />
Expand Down

0 comments on commit e668d83

Please sign in to comment.