Page
Library
Module
Module type
Parameter
Class
Class type
Source
Melange bindings for Jest and jest-dom.
Based on @glennsl/bs-jest and bs-jest-dom.
Most of what's commonly used is very stable. But the more js-y parts should be considered experimental, such as mocking and some of the expects that don't transfer well, or just don't make sense for testing idiomatic Reason/OCaml code but could be useful for testing js interop.
require.*
ExpectJs
. Some functionality does not make sense in a typed language, or is not possible to implement sensibly in ML.MockJs
module as it's very quirky to use with native code. A separate native from-scratch implementation might suddenly appear as Mock
.JestJs
. It's mostly implemented, but experimental and largely untested.open Jest;
describe("Expect", () => {
open Expect;
test("toBe", () =>
expect(1 + 2) |> toBe(3))
});
describe("Expect.Operators", () => {
open Expect;
open! Expect.Operators;
test("==", () =>
expect(1 + 2) === 3)
}
);
See the jest tests or the jest-dom tests for more examples.
Install opam package manager.
Then:
opam install melange-jest
The bindings support the following versions of the jest
npm package, which should be installed separately:
"devDependencies": {
"jest": "^26.5.2"
}
If you want to use jest-dom
, you will need the following npm package:
"devDependencies": {
"@testing-library/jest-dom": "^5.10.0"
}
Add melange-jest.jest
to the libraries
field in your dune
file:
; ...
(libraries melange-jest.jest)
; ...
If you need jest-dom
, add melange-jest.jest-dom
to the libraries
in your dune
file:
; ...
(libraries melange-jest.jest melange-jest.jest-dom)
; ...
Put tests in a __tests__
directory and use the suffix *test.ml
/*test.re
(Make sure to use valid module names. e.g. <name>_test.re
is valid while <name>.test.re
is not). When compiled they will be put in a __tests__
directory under lib
, with a *test.js
suffix, ready to be picked up when you run jest
. If you're not already familiar with Jest, see the Jest documentation.
One very important difference from Jest is that assertions are not imperative. That is, expect(1 + 2) |> toBe(3)
, for example, will not "execute" the assertion then and there. It will instead return an assertion
value which must be returned from the test function. Only after the test function has completed will the returned assertion be checked. Any other assertions will be ignored, but unless you explicitly ignore them, it will produce compiler warnings about unused values. This means there can be at most one assertion per test. But it also means there must be at least one assertion per test. You can't forget an assertion in a branch, and think the test passes when in fact it doesn't even test anything. It will also force you to write simple tests that are easy to understand and refactor, and will give you more information about what's wrong when something does go wrong.
At first sight this may still seem very limiting, and if you write very imperative code it really is, but I'd argue the real problem then is the imperative code. There are however some workarounds that can alleviate this:
expect((this, that)) |> toBe((3, 4))
testAll
function to generate tests based on a list of datadescribe
and/or beforeAll
to do setup for a group of tests. Code written in OCaml/Reason is immutable by default. Take advantage of it.For the moment, please refer to Jest.mli.
__tests__
folder is being ignored by DuneBy default, Dune will ignore folders starting with underscore, so to add __tests__
as part of the sources, one has to indicate it explicitly.
In a dune
file:
(dirs :standard __tests__)
Cannot use import statement outside a module
If you encounter the error SyntaxError: Cannot use import statement outside a module
, it may be that you are trying to run Jest tests with es6
files generated by Melange.
As Melange allows to have generate both es6
and commonjs
outputs in the same project, to solve this issue you can add a melange.emit
stanza that only generates commonjs
files, for testing purposes.
In a dune
file:
(melange.emit
(target test)
(module_systems commonjs)
...
)
Then, configure Jest rootDir
to point to the output folder (see jest.config.js for an example).
git clone https://github.com/melange-community/melange-jest.git
cd melange-jest
make install
Then build and run tests with make test
, run the tests in watch mode with make test-watch
.
toThrowException
, toThrowMessage
and toThrowMessageRe
as they relied on assumptions about BuckleScript internals that no longer hold.Expect.toContainEqual
Expect.toMatchInlineSnapshot
Todo.test
describe
callbacks by explicitly returning undefined
(otherwise BuckleScript will return something else like ()
, which is represented as 0
)Jest.advanceTimersByTime
, which is basically just an alias of Jest.runTimersToTime
Expect.not__
for transitional compatibility with Reason syntax change of "unkeywording" not
by mangling it into not_
, and not_
into not__
and so on.afterAllPromise
too.bs-platform
4.0.7 (Thanks Bob!)MockJs.new0
, new1
and new2
timeout
argument to testAsync
and testPromise
functionsbeforeEachAsync
, beforeEachPromise
, afterEachAsync
and afterEachPromise
beforeAllAsync
, beforeAllPromise
, afterAllAsync
and afterAllPromise
reasonml-community/bs-jest
to glennsl/bs-jest
bs-jest
to @glennsl/bs-jest
toThrowException
test
function from jestnot_ |> toBeLessThanEqual
testAll
, Only.testAll
, Skip.testAll
that generates tests from a list of inputsfail
expectFn