Skip to content

Commit

Permalink
feat: local types, supporting jest, @jest/globals, vitest (#511)
Browse files Browse the repository at this point in the history
* feat!: local types, supporting jest, @jest/globals, vitest

Moves matcher types back into this package and adds support for
@jest/globals and vitest.

BREAKING CHANGE: Removes the extend-expect script. Users should use
the default import path or one of the new test platform-specific
paths to automatically extend the appropriate "expect" instance.

extend-expect was not documented in the Readme, so this change should
have minimal impact.

Users can now use the following import paths to automatically extend
"expect" for their chosen test platform:

- @testing-library/jest-dom - jest (@types/jest)
- @testing-library/jest-dom/jest-globals - @jest/globals
- @testing-library/jest-dom/vitest - vitest

For example:

import '@testing-library/jest-dom/jest-globals'

Importing from one of the above paths will augment the appropriate
matcher interface for the given test platform, assuming the import
is done in a .ts file that is included in the user's tsconfig.json.

It's also (still) possible to import the matchers directly without
side effects:

import * as matchers from '@testing-library/jest-dom/matchers'

* Update kcd-scripts

BREAKING CHANGE: Drop node < 14
  • Loading branch information
jgoz committed Aug 13, 2023
1 parent d717c66 commit 4b764b9
Show file tree
Hide file tree
Showing 22 changed files with 824 additions and 23 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/validate.yml
Expand Up @@ -16,7 +16,7 @@ jobs:
if: ${{ !contains(github.head_ref, 'all-contributors') }}
strategy:
matrix:
node: [10.14, 12, 14, 15, 16]
node: [14, 16, 18, 20]
runs-on: ubuntu-latest
steps:
- name: ⬇️ Checkout repo
Expand Down
48 changes: 48 additions & 0 deletions README.md
Expand Up @@ -51,7 +51,10 @@ clear to read and to maintain.

- [Installation](#installation)
- [Usage](#usage)
- [With `@jest/globals`](#with-jestglobals)
- [With Vitest](#with-vitest)
- [With TypeScript](#with-typescript)
- [With another Jest-compatible `expect`](#with-another-jest-compatible-expect)
- [Custom matchers](#custom-matchers)
- [`toBeDisabled`](#tobedisabled)
- [`toBeEnabled`](#tobeenabled)
Expand Down Expand Up @@ -128,6 +131,39 @@ import '@testing-library/jest-dom'
setupFilesAfterEnv: ['<rootDir>/jest-setup.js']
```

### With `@jest/globals`

If you are using [`@jest/globals`][jest-globals announcement] with
[`injectGlobals: false`][inject-globals docs], you will need to use a different
import in your tests setup file:

```javascript
// In your own jest-setup.js (or any other name)
import '@testing-library/jest-dom/jest-globals'
```

[jest-globals announcement]:
https://jestjs.io/blog/2020/05/05/jest-26#a-new-way-to-consume-jest---jestglobals
[inject-globals docs]:
https://jestjs.io/docs/configuration#injectglobals-boolean

### With Vitest

If you are using [vitest][], this module will work as-is, but you will need to
use a different import in your tests setup file. This file should be added to
the [`setupFiles`][vitest setupfiles] property in your vitest config:

```javascript
// In your own vitest-setup.js (or any other name)
import '@testing-library/jest-dom/vitest'

// In vitest.config.js add (if you haven't already)
setupFiles: ['./vitest-setup.js']
```

[vitest]: https://vitest.dev/
[vitest setupfiles]: https://vitest.dev/config/#setupfiles

### With TypeScript

If you're using TypeScript, make sure your setup file is a `.ts` and not a `.js`
Expand All @@ -144,6 +180,18 @@ haven't already:
],
```

### With another Jest-compatible `expect`

If you are using a different test runner that is compatible with Jest's `expect`
interface, it might be possible to use it with this library:

```javascript
import * as matchers from '@testing-library/jest-dom/matchers'
import {expect} from 'my-test-runner/expect'

expect.extend(matchers)
```

## Custom matchers

`@testing-library/jest-dom` can work with any library or framework that returns
Expand Down
2 changes: 0 additions & 2 deletions extend-expect.js

This file was deleted.

1 change: 1 addition & 0 deletions jest-globals.d.ts
@@ -0,0 +1 @@
/// <reference path="types/jest-globals.d.ts" />
4 changes: 4 additions & 0 deletions jest-globals.js
@@ -0,0 +1,4 @@
const globals = require('@jest/globals')
const extensions = require('./dist/matchers')

globals.expect.extend(extensions)
3 changes: 3 additions & 0 deletions matchers.d.ts
@@ -0,0 +1,3 @@
import * as matchers from './types/matchers'

export = matchers
57 changes: 50 additions & 7 deletions package.json
Expand Up @@ -3,8 +3,9 @@
"version": "0.0.0-semantically-released",
"description": "Custom jest matchers to test the state of the DOM",
"main": "dist/index.js",
"types": "types/index.d.ts",
"engines": {
"node": ">=8",
"node": ">=14",
"npm": ">=6",
"yarn": ">=1"
},
Expand All @@ -19,8 +20,11 @@
},
"files": [
"dist",
"extend-expect.js",
"matchers.js"
"types",
"*.d.ts",
"jest-globals.js",
"matchers.js",
"vitest.js"
],
"keywords": [
"testing",
Expand All @@ -32,7 +36,6 @@
"license": "MIT",
"dependencies": {
"@babel/runtime": "^7.9.2",
"@types/testing-library__jest-dom": "^5.9.1",
"aria-query": "^5.0.0",
"chalk": "^3.0.0",
"@adobe/css-tools": "^4.0.1",
Expand All @@ -42,16 +45,44 @@
"redent": "^3.0.0"
},
"devDependencies": {
"@jest/globals": "^29.6.2",
"expect": "^29.6.2",
"jest-environment-jsdom-sixteen": "^1.0.3",
"jest-watch-select-projects": "^2.0.0",
"jsdom": "^16.2.1",
"kcd-scripts": "^11.1.0",
"pretty-format": "^25.1.0"
"kcd-scripts": "^14.0.0",
"pretty-format": "^25.1.0",
"vitest": "^0.34.1",
"typescript": "^5.1.6"
},
"peerDependencies": {
"@jest/globals": ">= 28",
"@types/jest": ">= 28",
"jest": ">= 28",
"vitest": ">= 0.32"
},
"peerDependenciesMeta": {
"@jest/globals": {
"optional": true
},
"@types/jest": {
"optional": true
},
"jest": {
"optional": true
},
"vitest": {
"optional": true
}
},
"eslintConfig": {
"extends": "./node_modules/kcd-scripts/eslint.js",
"parserOptions": {
"sourceType": "module",
"ecmaVersion": 2020
},
"rules": {
"@babel/no-invalid-this": "off"
"no-invalid-this": "off"
},
"overrides": [
{
Expand All @@ -61,6 +92,18 @@
"rules": {
"max-lines-per-function": "off"
}
},
{
"files": [
"**/*.d.ts"
],
"rules": {
"@typescript-eslint/no-empty-interface": "off",
"@typescript-eslint/no-explicit-any": "off",
"@typescript-eslint/no-invalid-void-type": "off",
"@typescript-eslint/no-unused-vars": "off",
"@typescript-eslint/triple-slash-reference": "off"
}
}
]
},
Expand Down
3 changes: 0 additions & 3 deletions src/extend-expect.js

This file was deleted.

4 changes: 3 additions & 1 deletion src/index.js
@@ -1 +1,3 @@
import './extend-expect'
import * as extensions from './matchers'

expect.extend(extensions)
2 changes: 1 addition & 1 deletion src/to-be-in-the-document.js
Expand Up @@ -29,7 +29,7 @@ export function toBeInTheDocument(element) {
'',
),
'',
// eslint-disable-next-line @babel/new-cap
// eslint-disable-next-line new-cap
this.utils.RECEIVED_COLOR(this.isNot ? errorFound() : errorNotFound()),
].join('\n')
},
Expand Down
2 changes: 1 addition & 1 deletion src/to-contain-element.js
Expand Up @@ -17,7 +17,7 @@ export function toContainElement(container, element) {
'element',
),
'',
// eslint-disable-next-line @babel/new-cap
// eslint-disable-next-line new-cap
this.utils.RECEIVED_COLOR(`${this.utils.stringify(
container.cloneNode(false),
)} ${
Expand Down
2 changes: 1 addition & 1 deletion src/to-contain-html.js
Expand Up @@ -23,7 +23,7 @@ export function toContainHTML(container, htmlText) {
'',
),
'Expected:',
// eslint-disable-next-line @babel/new-cap
// eslint-disable-next-line new-cap
` ${this.utils.EXPECTED_COLOR(htmlText)}`,
'Received:',
` ${this.utils.printReceived(container.cloneNode(true))}`,
Expand Down
10 changes: 5 additions & 5 deletions src/utils.js
Expand Up @@ -28,7 +28,7 @@ class GenericTypeError extends Error {
'',
),
'',
// eslint-disable-next-line @babel/new-cap
// eslint-disable-next-line new-cap
`${context.utils.RECEIVED_COLOR(
'received',
)} value must ${expectedString}.`,
Expand Down Expand Up @@ -91,9 +91,9 @@ class InvalidCSSError extends Error {
this.message = [
received.message,
'',
// eslint-disable-next-line @babel/new-cap
// eslint-disable-next-line new-cap
context.utils.RECEIVED_COLOR(`Failing css:`),
// eslint-disable-next-line @babel/new-cap
// eslint-disable-next-line new-cap
context.utils.RECEIVED_COLOR(`${received.css}`),
].join('\n')
}
Expand Down Expand Up @@ -137,11 +137,11 @@ function getMessage(
) {
return [
`${matcher}\n`,
// eslint-disable-next-line @babel/new-cap
// eslint-disable-next-line new-cap
`${expectedLabel}:\n${context.utils.EXPECTED_COLOR(
redent(display(context, expectedValue), 2),
)}`,
// eslint-disable-next-line @babel/new-cap
// eslint-disable-next-line new-cap
`${receivedLabel}:\n${context.utils.RECEIVED_COLOR(
redent(display(context, receivedValue), 2),
)}`,
Expand Down
2 changes: 1 addition & 1 deletion tests/setup-env.js
@@ -1,4 +1,4 @@
import {plugins} from 'pretty-format'
import '../src/extend-expect'
import '../src/index'

expect.addSnapshotSerializer(plugins.ConvertAnsi)
7 changes: 7 additions & 0 deletions tsconfig.json
@@ -0,0 +1,7 @@
{
"compilerOptions": {
"strict": true,
"skipLibCheck": true
},
"include": ["*.d.ts", "types"]
}
1 change: 1 addition & 0 deletions types/index.d.ts
@@ -0,0 +1 @@
/// <reference path="jest.d.ts" />
8 changes: 8 additions & 0 deletions types/jest-globals.d.ts
@@ -0,0 +1,8 @@
import {type expect} from '@jest/globals'
import {type TestingLibraryMatchers} from './matchers'

export {}
declare module '@jest/expect' {
export interface Matchers<R extends void | Promise<void>>
extends TestingLibraryMatchers<typeof expect.stringContaining, R> {}
}
10 changes: 10 additions & 0 deletions types/jest.d.ts
@@ -0,0 +1,10 @@
/// <reference types="jest" />

import {type TestingLibraryMatchers} from './matchers'

declare global {
namespace jest {
interface Matchers<R = void, T = {}>
extends TestingLibraryMatchers<typeof expect.stringContaining, R> {}
}
}

0 comments on commit 4b764b9

Please sign in to comment.