Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/bloodyowl/rescript-test
A lightweight test framework for ReScript
https://github.com/bloodyowl/rescript-test
Last synced: about 10 hours ago
JSON representation
A lightweight test framework for ReScript
- Host: GitHub
- URL: https://github.com/bloodyowl/rescript-test
- Owner: bloodyowl
- License: mit
- Created: 2020-11-09T08:14:46.000Z (about 4 years ago)
- Default Branch: main
- Last Pushed: 2024-05-06T07:53:04.000Z (9 months ago)
- Last Synced: 2024-11-25T18:43:23.446Z (2 months ago)
- Language: ReScript
- Homepage: https://bloodyowl.github.io/rescript-test/
- Size: 1.06 MB
- Stars: 78
- Watchers: 3
- Forks: 9
- Open Issues: 7
-
Metadata Files:
- Readme: README.md
- Changelog: HISTORY.md
- Funding: .github/FUNDING.yml
- License: MIT-LICENSE
Awesome Lists containing this project
- awesome-luooooob - bloodyowl/rescript-test - A lightweight test framework for ReScript (ReScript)
- awesome-list - rescript-test
README
# ReScriptTest
> A lightweight test framework for ReScript
Check out the **[documentation](https://bloodyowl.github.io/rescript-test/)**!
## Installation
Run the following in your console:
```console
$ yarn add --dev rescript-test
```Then add `rescript-test` to your `bsconfig.json`'s `bs-dev-dependencies`:
```diff
{
"bs-dev-dependencies": [
+ "rescript-test",
]
}
```## Usage
```console
$ # All tests
$ retest 'test/**/*.bs.js'
$ # Single file
$ retest 'test/MyTest.bs.js'
```## Testing with DOM
The test framework can simulate a browser using [JSDOM](https://github.com/jsdom/jsdom), to activate it, simply add the `--with-dom` option.
```console
$ # All tests
$ retest --with-dom 'test/**/*.bs.js'
$ # Single file
$ retest --with-dom 'test/MyTest.bs.js'
```## Basics
```rescript
open Testlet intEqual = (~message=?, a: int, b: int) =>
assertion(~message?, ~operator="intEqual", (a, b) => a === b, a, b)let stringEqual = (~message=?, a: string, b: string) =>
assertion(~message?, ~operator="stringEqual", (a, b) => a == b, a, b)test("Equals", () => {
let a = 1
let b = 1
intEqual(a, b)
})let isCharCode = (a, b) => {
a->String.charCodeAt(0) === b
}test("Custom comparator", () => {
let a = "a"assertion(~message="Char code should match", ~operator="isCharCode", isCharCode, a, 97.0)
assertion(~message="Char code should match", ~operator="isCharCode", isCharCode, a, 98.0)
})type user = {username: string, id: string}
let userEq = (a, b) => a.id === b.id
let userEqual = (~message=?, a: user, b: user) =>
assertion(~message?, ~operator="userEqual", userEq, a, b)test("DeepEquals", () => {
let a = {username: "user", id: "a"}
let b = {username: "user", id: "a"}
stringEqual(a.username, b.username)
userEqual(a, b)
})
```Outputs:
```sh
1/4: Equals
PASS - No message
2/4: Custom comparator
PASS - Char code should match
FAIL - Char code should match
---
operator: isCharCode
left: a
right: 98
...
3/4: DeepEquals
PASS - No message
PASS - No message
4/4: Async
PASS - No message# Ran 4 tests (6 assertions)
# 3 passed
# 1 failed
```## API
### Tests
- `test(name, body)`
- `createTestWith(~setup: unit => 'a, ~teardown: 'a => unit=?` -> `test`
- `testAsync(name, body)`
- `createTestAsyncWith(~setup: unit => 'a, ~teardown: 'a => unit=?, name, body: ('a, cb) => unit)` -> `testAsync`### Operators
- `throws(func, ~message: string=?, ~test: exn => bool=?)`
- `doesNotThrow(func, ~message: string=?)`
- `assertion(comparator, a, b, ~operator: string=?, ~message: string=?)`
- `pass()`
- `fail()`
- `todo(string)`### Creating assertion shorthands
```rescript
let stringMapEqual = (~message=?, a, b) =>
assertion(
~message?,
~operator="stringMapEqual",
(a, b) => Belt.Map.String.eq(a, b, (a, b) => a === b),
a,
b,
)
```Generic equal/deepEqual (not recommended)
Those that be useful to transition from an existing testing library, but we do not recommend polymorphic checks.
```reason
let equal = (~message=?, a, b) => assertion(~message?, ~operator="equal", (a, b) => a === b, a, b)let deepEqual = (~message=?, a, b) =>
assertion(~message?, ~operator="deepEqual", (a, b) => a == b, a, b)
```### Create tests with setup and teardown
The `setup` function returns a clean context for the test, the `teardown` function resets it.
```rescript
let testWithRef = createTestWith(~setup=() => ref(0), ~teardown=someRef => someRef := 0)testWithRef("Setup & teardown", someRef => {
incr(someRef)
equal(someRef.contents, 1)
})
```If you want to test with React, you can add the following helper as your test utility file:
```rescript
@bs.val external window: {..} = "window"
@bs.send external remove: Dom.element => unit = "remove"let createContainer = () => {
let containerElement: Dom.element = window["document"]["createElement"]("div")
let _ = window["document"]["body"]["appendChild"](containerElement)
containerElement
}let cleanupContainer = container => {
ReactDOM.unmountComponentAtNode(container)
remove(container)
}let testWithReact = createTestWith(~setup=createContainer, ~teardown=cleanupContainer)
let testAsyncWithReact = createTestAsyncWith(~setup=createContainer, ~teardown=cleanupContainer)
```And then use it:
```rescript
testWithReact("Can render", container => {
act(() =>
ReactDOMRe.render(
{"hello"->React.string},
container,
)
)let div = container->DOM.findBySelectorAndTextContent("div", "hello")
isTrue(div->Option.isSome)
})
```### Async assertion count plan
```rescript
testAsync("My test", (cb) => (
// your tests
cb(~planned=2, ())
))
```### Env file
Add a `retest.env.js` to your project root directory for any setup.