@lou.codes/test
Version:
✅ Equality test with enforced readability
290 lines (228 loc) • 6.12 kB
Markdown
<img id="logo" alt="@lou.codes/test" src="https://lou.codes/logos/lou_codes_test.svg" height="128" />
![Coverage][coverage-badge] ![License][license-badge]
![NPM Version][npm-version-badge] ![Open Issues][open-issues-badge]
![Size][size-badge]
✅ Equality test with enforced readability, based on the concept of
[][riteway] and inspired by [uvu][uvu].
Install `@lou.codes/tests` as a dev dependency:
```bash
pnpm add -D @lou.codes/test
npm install -D @lou.codes/test
yarn add --dev @lou.codes/test
```
Add a `test` script to `package.json`:
```json
{
"scripts": {
"test": "test"
}
}
```
<details>
<summary>Add TypeScript support</summary>
To support TypeScript, install [tsx][tsx] as a dev dependency:
```bash
pnpm add -D tsx
npm install -D tsx
yarn add --dev tsx
```
And update `package.json`:
```json
{
"scripts": {
"test": "NODE_OPTIONS='--import tsx' test"
}
}
```
</details>
<details>
<summary>Add coverage</summary>
To add coverage, install `c8` as a dev dependency:
```bash
pnpm add -D c8
npm install -D c8
yarn add --dev c8
```
And update `package.json`:
```json
{
"scripts": {
"test": "c8 test"
}
}
```
If you added TypeScript support, then update `package.json` like this instead:
And update `package.json`:
```json
{
"scripts": {
"test": "NODE_OPTIONS='--import tsx' c8 test"
}
}
```
</details>
Run tests:
```bash
pnpm test
npm test
yarn test
```
Import `@lou.codes/test` using the `npm:` prefix, and use it directly:
```typescript
import { evaluate } from "npm:@lou.codes/test";
import { add } from "../src/add.js";
evaluate({
given: "a 1 and a 2",
must: "return 3",
received: () => add(2)(1),
wanted: () => 3,
}).then(console.log);
```
Import `@lou.codes/test` using [esm.sh][esm.sh], and use it directly:
```html
<script type="module">
import { evaluate } from "https://esm.sh/@lou.codes/test";
import { add } from "../src/add.js";
evaluate({
given: "a 1 and a 2",
must: "return 3",
received: () => add(2)(1),
wanted: () => 3,
}).then(console.log);
</script>
```
```typescript
import type { Tests } from "@lou.codes/test";
import { add } from "../src/add.js";
export default [
{
given: "a 1 and a 2",
must: "return 3",
received: () => add(2)(1),
wanted: () => 3,
},
{
given: "a 1 and a -2",
must: "return -1",
received: () => add(-2)(1),
wanted: () => -1,
},
] satisfies Tests<number>;
```
```javascript
import { add } from "../src/add.js";
/** @satisfies {import("@lou.codes/test").Tests<number>} */
export default [
{
given: "a 1 and a 2",
must: "return 3",
received: () => add(2)(1),
wanted: () => 3,
},
{
given: "a 1 and a -2",
must: "return -1",
received: () => add(-2)(1),
wanted: () => -1,
},
];
```
Instead of exporting an `Array` of `Test` as `default`, the export can also be a
single `Test`:
```typescript
import type { Test } from "@lou.codes/test";
import { add } from "../src/add.js";
export default {
given: "a 1 and a 2",
must: "return 3",
received: () => add(2)(1),
wanted: () => 3,
} satisfies Test<number>;
```
Or multiple exports with different tests:
```typescript
import type { Test } from "@lou.codes/test";
import { add } from "../src/add.js";
export const test1: Test<number> = {
given: "a 1 and a 2",
must: "return 3",
received: () => add(2)(1),
wanted: () => 3,
};
export const test2: Test<number> = {
given: "a 1 and a -2",
must: "return -1",
received: () => add(-2)(1),
wanted: () => -1,
};
```
It can also be used directly without the `test` bin by importing the different
utils directly (like with the Deno and Browser examples above):
```typescript
import { evaluate } from "@lou.codes/test";
import { customFormatter } from "./customFormatter.js";
evaluate({
given: "a 1 and a 2",
must: "return 3",
received: () => add(2)(1),
wanted: () => 3,
}).then(customFormatter);
```
`@lou.codes/tests` provides a default output for the tests. It looks like this:
```txt
❯ ./tests/example.test.ts
× Given a 1 and a 2, must return 3, but…
└ it has the wrong value. Wanted 3 but received 4.
```
And if the wanted/received type is more complex, like an object, then the output
goes into details about the error:
```txt
❯ ./tests/example.test.ts
× Given an object, must add a single property, but…
├ foo.bar has the wrong value. Wanted 1 but received 2.
├ foo.baz.1 is missing.
└ bar was set with the value "bar".
```
But developers can choose to run `test` directly and use their own formatter, as
it was pointed out in the previous section.
- 📝 [Documentation][documentation]: TypeDoc generated documentation.
- ⏳ [Changelog][changelog]: List of changes between versions.
- ✅ [Tests Coverage][coverage]: Coveralls page with tests coverage.
<!-- Reference -->
[]:
https://github.com/loucyx/lou.codes/blob/main/packages/@lou.codes/test/CHANGELOG.md
[]:
https://img.shields.io/coveralls/github/loucyx/lou.codes.svg?label=Test+Coverage&labelColor=666&color=0a8
[]: https://coveralls.io/github/loucyx/lou.codes
[]: https://lou.codes/libraries/lou_codes_create_package/
[]: https://lou.codes/libraries/lou_codes_test/
[]: https://esm.sh
[]:
https://img.shields.io/npm/l/@lou.codes/test.svg?label=License&labelColor=666&color=0a8
[]:
https://img.shields.io/npm/v/@lou.codes/test.svg?label=NPM+Version&labelColor=666&color=0a8
[]:
https://img.shields.io/github/issues/loucyx/lou.codes.svg?label=Issues&labelColor=666&color=0a8
[]:
https://img.shields.io/badge/dynamic/json?label=Bundle+Size&labelColor=666&color=0a8&suffix=KiB&query=%24.size&url=https%3A%2F%2Fraw.githubusercontent.com%2Floucyx%2Flou.codes%2Fmain%2Fpackages%2F%40lou.codes%2Ftest%2Fpackage.json
[]: https://github.com/ericelliott/riteway
[]: https://npm.im/tsx
[]: https://github.com/lukeed/uvu