Skip to content

Commit 748b31e

Browse files
committed
fix: non-jest framework error throwing, make auto-cleanup optional
1 parent 50f2de6 commit 748b31e

File tree

4 files changed

+54
-24
lines changed

4 files changed

+54
-24
lines changed

src/events.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
import {eventMap} from './event-map'
22

3+
/**
4+
* Silence TypeScript errors
5+
* @type {*}
6+
*/
37
const fireEvent = Object.entries(eventMap).reduce(
48
(prev, [eventName, eventFn]) => {
59
prev[eventName] = ((instance, ...props) => {

src/helpers.js

Lines changed: 7 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
import {fireEvent} from "./events";
2-
31
function jestFakeTimersAreEnabled() {
42
/* istanbul ignore else */
53
if (typeof jest !== 'undefined' && jest !== null) {
@@ -16,31 +14,24 @@ function jestFakeTimersAreEnabled() {
1614

1715
const instance = {current: undefined};
1816

19-
/**
20-
* Should not rely directly on `afterEach` without library detection
21-
* @see https://testing-library.com/docs/react-testing-library/setup/#skipping-auto-cleanup
22-
*/
23-
afterEach(() => {
24-
/**
25-
* Behavior should be customizability like it is with `react-testing-library`
26-
* @see https://testing-library.com/docs/react-testing-library/setup/#skipping-auto-cleanup
27-
*/
28-
if (instance.current) fireEvent.sigkill(instance.current);
29-
instance.current = undefined;
30-
})
17+
if (typeof afterEach === 'function') {
18+
afterEach(() => {
19+
instance.current = undefined;
20+
})
21+
}
3122

3223
function getCurrentInstance() {
3324
/**
3425
* Worth mentioning that this deviates from the upstream implementation
35-
* of `dom-testing-library`'s `getDocument`, which throws an error whenever
26+
* of `dom-testing-library`'s `getDocument` in waitFor, which throws an error whenever
3627
* `window` is not defined.
3728
*
3829
* Admittedly, this is another way that `cli-testing-library` will need to figure out
3930
* the right solution to this problem, since there is no omni-present parent `instance`
4031
* in a CLI like there is in a browser. (although FWIW, "process" might work)
4132
*
4233
* Have ideas how to solve? Please let us know:
43-
* https://github.com/crutchcorn/cli-testing-library/issues/2
34+
* https://github.com/crutchcorn/cli-testing-library/issues/
4435
*/
4536
return instance.current
4637
}

src/index.js

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,30 @@
1+
import {cleanup} from "./pure";
2+
3+
// if we're running in a test runner that supports afterEach
4+
// or teardown then we'll automatically run cleanup afterEach test
5+
// this ensures that tests run in isolation from each other
6+
// if you don't like this then set the CTL_SKIP_AUTO_CLEANUP env variable to 'true'.
7+
if (typeof process === 'undefined' || !process.env?.CTL_SKIP_AUTO_CLEANUP) {
8+
// ignore teardown() in code coverage because Jest does not support it
9+
/* istanbul ignore else */
10+
if (typeof afterEach === 'function') {
11+
afterEach(() => {
12+
cleanup();
13+
})
14+
} else if (typeof teardown === 'function') {
15+
// Block is guarded by `typeof` check.
16+
// eslint does not support `typeof` guards.
17+
// eslint-disable-next-line no-undef
18+
teardown(() => {
19+
cleanup()
20+
})
21+
}
22+
}
23+
124
export * from './helpers'
225
export * from './events'
326
export * from './pure'
427
export * from './matches'
528
export * from './mutation-observer'
629
export * from './wait-for'
30+

src/pure.ts

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,15 @@
1-
/**
2-
* I'm not going to pretend to know why `react-testing-library` calls a very similar
3-
* file "pure", but I am familiar enough with the concept of "pure" methods or whatnot
4-
* that I am not confident we are using it here properly. Plz no yell for the name
5-
* but suggestions for alternatives welcome in GH issues 😭🙏💯
6-
*/
71
import childProcess from 'child_process'
82
import stripFinalNewline from 'strip-final-newline'
93
import {RenderOptions, RenderResult, TestInstance} from '../types/pure'
104
import {_runObservers} from './mutation-observer'
115
import {getQueriesForElement} from './get-queries-for-instance'
12-
import {getFireEventForElement} from './events'
6+
import {fireEvent, getFireEventForElement} from './events'
137
import {debounce, setCurrentInstance} from "./helpers";
148
import {getConfig} from "./config";
159

10+
11+
const mountedInstances = new Set<TestInstance>()
12+
1613
async function render(
1714
command: string,
1815
args: string[] = [],
@@ -50,6 +47,8 @@ async function render(
5047
set stdoutStr(val: string) {},
5148
}
5249

50+
mountedInstances.add(execOutputAPI as unknown as TestInstance)
51+
5352
/**
5453
* This method does not throw errors after-the-fact,
5554
* meaning that if post-render errors are thrown,
@@ -127,4 +126,16 @@ async function render(
127126
) as TestInstance as RenderResult
128127
}
129128

130-
export {render}
129+
function cleanup() {
130+
mountedInstances.forEach(cleanupAtInstance)
131+
}
132+
133+
// maybe one day we'll expose this (perhaps even as a utility returned by render).
134+
// but let's wait until someone asks for it.
135+
function cleanupAtInstance(instance: TestInstance) {
136+
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
137+
fireEvent.sigkill(instance)
138+
mountedInstances.delete(instance)
139+
}
140+
141+
export {render, cleanup}

0 commit comments

Comments
 (0)