![Earl](https://raw.githubusercontent.com/krzkaczor/earl/master/docs/images/gh-cover.png)
Ergonomic, modern and type-safe assertion library
Brings good parts of Jest back to good ol' Mocha
Installation
npm install --save-dev earljs
Example
import { expect } from 'earljs'
const response = await apiCall()
expect(response).toEqual({ body: { trimmed: true, timestamp: expect.any() } })
Motivation
I used to love mocha + chai combo, but as time flew, I felt it's limiting. Other projects like Jest shown that there is
room for innovation in this space. With last version published 2 years ago, Chai
seems abandoned. Furthermore, as
TypeScript becomes more and more popular, it became evident that some things about writing assertions could be improved.
Earl is an effort to bring a little bit of innovation in the space of assertion libraries.
Why not just Jest?
I really enjoy some of the Jest's features — that's what inspired this library in the first place. However, I really
hate others. Simply put, Jest feels too magical and
full of bugs for my
taste. Lots of its complexity comes from the features that I don't even care about like modules mocking or test
parallelization. On the other hand, I always enjoyed simplicity and confidence that Mocha provides.
Features
Powerful Matchers
Matchers can be values like expect.anything()
and can be combined with toEqual
. Allowing, for example to easily
assert not fully deterministic objects. Unlike chai-subset
using this asserts much more info about actual object
shape.
expect({
abc: 'abc',
timestamp: '05/02/2020 @ 8:09am (UTC)',
}).toEqual({ abc: 'abc', timestamp: expect.anyString() })
Type-safe (support for TypeScript) and goes well with static analysis
expect(5).toEqual('abc')
AutoFix (experimental)
Automatically fix expected (if omitted) values to match actual. Option to force fix existing values. Works with
different matchers.
Implementation requires stack traces with correct sourcemaps - available in 99% environments. This feature is inspired
by Jest's inline snapshots.
expect(serverResponse).toEqual()
expect(serverResponse).toEqual({ users: [{ name: 'Kris Kaczor' }] })
Driven by you
Yes you! This document presents current best thinking behind this project. Help us to guide it's future development! If
you like what you see give us a 🌟. Don't hesitate to create issue in this project or reach out me directly on twitter
(@krzkaczor).
API
Validators
toEqual
- performs deep equality check, ensures type equality, supports additional matcherstoLooseEqual
- like toEqual but without type checkingtoThrow(expectedErrorMsg?: string)
- checks if expected error was threw. Requires checked value to be a
parameterless function.
Matchers
These should be used with toEqual
.
anything
- matches anythinga(class)
- matches any instance of a class. Works as expected with primitives like String, Number etc. Use
a(Object)
to match any object (won't match null)stringContaining(substring)
- matches any string containing given substring
Modifiers
not
- will make expectation fail when it should succeed and succeed when it should fail
Project state
I would call the current state a Minimal MVP ;) All of the features mentioned above work but are very limited. There are
only 2 matchers currently, autofix relies on raw text manipulation.
All of this will be improved after initial round of feedback.
Future plans:
Batteries included
Re-implements most common chai
matchers and makes them part of the core.
Future ideas:
- Sinon like features out of the box? Creating spies is super common.
- Maybe support for type-level tests in TS?
Extendable
TypeSafe Chai style plugins with additional matchers etc. Matchers can (and should!) implement support for autofix.
Pretty, readable output for failed assertions
Contributors ✨
Thanks goes to these wonderful people (emoji key):
Contributions of any kind welcome!
Earl logo by @sz-piotr
License
Krzysztof Kaczor MIT