@exodus/test 1.0.0-rc.24 → 1.0.0-rc.25
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/index.js +59 -21
- package/package.json +4 -1
- package/src/dark.cjs +2 -4
- package/src/engine.js +19 -0
- package/src/engine.node.cjs +38 -0
- package/src/engine.select.cjs +1 -0
- package/src/jest.config.js +4 -1
- package/src/jest.fn.js +1 -2
- package/src/jest.js +12 -6
- package/src/jest.mock.js +10 -13
- package/src/jest.snapshot.js +20 -27
- package/src/jest.timers.js +1 -2
- package/src/tape.js +1 -3
- package/src/version.js +2 -2
package/bin/index.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
import { spawn } from 'node:child_process'
|
|
4
|
+
import { once } from 'node:events'
|
|
4
5
|
import { fileURLToPath } from 'node:url'
|
|
5
6
|
import { basename, dirname, resolve } from 'node:path'
|
|
6
7
|
import { createRequire } from 'node:module'
|
|
@@ -25,6 +26,7 @@ function parseOptions() {
|
|
|
25
26
|
only: false,
|
|
26
27
|
passWithNoTests: false,
|
|
27
28
|
writeSnapshots: false,
|
|
29
|
+
pure: false,
|
|
28
30
|
debug: { files: false },
|
|
29
31
|
}
|
|
30
32
|
|
|
@@ -79,6 +81,9 @@ function parseOptions() {
|
|
|
79
81
|
case '--forceExit':
|
|
80
82
|
options.forceExit = true
|
|
81
83
|
break
|
|
84
|
+
case '--pure':
|
|
85
|
+
options.pure = true
|
|
86
|
+
break
|
|
82
87
|
case '--debug-files':
|
|
83
88
|
options.debug.files = true
|
|
84
89
|
break
|
|
@@ -108,26 +113,36 @@ const resolveImport = import.meta.resolve && ((query) => fileURLToPath(import.me
|
|
|
108
113
|
const c8 = resolveRequire('c8/bin/c8.js')
|
|
109
114
|
if (resolveImport) assert.equal(c8, resolveImport('c8/bin/c8.js'))
|
|
110
115
|
|
|
111
|
-
const args = [
|
|
116
|
+
const args = []
|
|
117
|
+
if (options.pure) {
|
|
118
|
+
const requiresNodeCoverage = options.coverage && options.coverageEngine === 'node'
|
|
119
|
+
assert(!requiresNodeCoverage, 'Can not use "node" coverage engine with --pure')
|
|
120
|
+
assert(!options.writeSnapshots, 'Can not use write snapshots with --pure')
|
|
121
|
+
assert(!options.forceExit, 'Can not use --force-exit with --pure') // TODO
|
|
122
|
+
assert(!options.watch, 'Can not use --watch with --pure')
|
|
123
|
+
assert(!options.only, 'Can not use --only with --pure') // TODO
|
|
124
|
+
} else {
|
|
125
|
+
args.push('--test', '--no-warnings=ExperimentalWarning', '--test-reporter=spec')
|
|
126
|
+
|
|
127
|
+
if (haveModuleMocks) args.push('--experimental-test-module-mocks')
|
|
128
|
+
if (haveSnapshots) args.push('--experimental-test-snapshots')
|
|
129
|
+
|
|
130
|
+
if (options.writeSnapshots) {
|
|
131
|
+
assert(haveSnapshots, 'For snapshots, use Node.js >=22.3.0')
|
|
132
|
+
args.push('--test-update-snapshots')
|
|
133
|
+
}
|
|
112
134
|
|
|
113
|
-
if (
|
|
114
|
-
|
|
135
|
+
if (options.forceExit) {
|
|
136
|
+
assert(haveForceExit, 'For forceExit, use Node.js >= 20.14.0')
|
|
137
|
+
args.push('--test-force-exit')
|
|
138
|
+
}
|
|
115
139
|
|
|
116
|
-
if (options.
|
|
117
|
-
|
|
118
|
-
args.push('--test-update-snapshots')
|
|
119
|
-
}
|
|
140
|
+
if (options.watch) args.push('--watch')
|
|
141
|
+
if (options.only) args.push('--test-only')
|
|
120
142
|
|
|
121
|
-
|
|
122
|
-
assert(haveForceExit, 'For forceExit, use Node.js >= 20.14.0')
|
|
123
|
-
args.push('--test-force-exit')
|
|
143
|
+
args.push('--expose-internals') // this is unoptimal and hopefully temporary, see rationale in src/dark.cjs
|
|
124
144
|
}
|
|
125
145
|
|
|
126
|
-
if (options.watch) args.push('--watch')
|
|
127
|
-
if (options.only) args.push('--test-only')
|
|
128
|
-
|
|
129
|
-
args.push('--expose-internals') // this is unoptimal and hopefully temporary, see rationale in src/dark.cjs
|
|
130
|
-
|
|
131
146
|
if (options.coverage) {
|
|
132
147
|
if (options.coverageEngine === 'node') {
|
|
133
148
|
args.push('--experimental-test-coverage')
|
|
@@ -176,6 +191,7 @@ if (options.jest) {
|
|
|
176
191
|
patterns.push(...(Array.isArray(config.testMatch) ? config.testMatch : [config.testMatch]))
|
|
177
192
|
}
|
|
178
193
|
|
|
194
|
+
if (config.passWithNoTests) options.passWithNoTests = true
|
|
179
195
|
const testRegex = config.testRegex ? new RegExp(config.testRegex, 'u') : null
|
|
180
196
|
const ignoreRegexes = config.testPathIgnorePatterns.map((x) => new RegExp(x, 'u'))
|
|
181
197
|
if (testRegex || ignoreRegexes.length > 0) {
|
|
@@ -260,14 +276,36 @@ if (tsTests.length > 0 && !options.esbuild) {
|
|
|
260
276
|
console.warn(`Flag --typescript has been used, but there were no TypeScript tests found!`)
|
|
261
277
|
}
|
|
262
278
|
|
|
263
|
-
assert(files.length > 0) // otherwise we can run recursively
|
|
264
|
-
args.push(...files)
|
|
265
|
-
|
|
266
279
|
if (!Object.hasOwn(process.env, 'NODE_ENV')) process.env.NODE_ENV = 'test'
|
|
267
280
|
|
|
281
|
+
assert(files.length > 0) // otherwise we can run recursively
|
|
268
282
|
assert(program && ['node', c8].includes(program))
|
|
269
|
-
const node = spawn(program, args, { stdio: 'inherit' })
|
|
270
283
|
|
|
271
|
-
|
|
284
|
+
if (options.pure) {
|
|
285
|
+
process.env.EXODUS_TEST_CONTEXT = 'pure'
|
|
286
|
+
console.warn(
|
|
287
|
+
'--pure mode is experimental and may not work an expected / might be removed at any time'
|
|
288
|
+
)
|
|
289
|
+
const failures = []
|
|
290
|
+
for (const file of files) {
|
|
291
|
+
const node = spawn(program, [...args, file], { stdio: 'inherit' })
|
|
292
|
+
const [code] = await once(node, 'close')
|
|
293
|
+
if (code !== 0) failures.push(file)
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
if (failures.length > 0) process.exitCode = 1
|
|
297
|
+
console.log(
|
|
298
|
+
failures === 0
|
|
299
|
+
? `All ${files.length} test suites passed`
|
|
300
|
+
: `Test suites failed: ${failures.length} / ${files.length}`
|
|
301
|
+
)
|
|
302
|
+
if (failures.length > 0) {
|
|
303
|
+
console.log('Failed test suites:')
|
|
304
|
+
for (const file of failures) console.log(` ${file}`) // joining with \n can get truncated, too big
|
|
305
|
+
}
|
|
306
|
+
} else {
|
|
307
|
+
process.env.EXODUS_TEST_CONTEXT = 'node --test'
|
|
308
|
+
const node = spawn(program, [...args, ...files], { stdio: 'inherit' })
|
|
309
|
+
const [code] = await once(node, 'close')
|
|
272
310
|
process.exitCode = code
|
|
273
|
-
}
|
|
311
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@exodus/test",
|
|
3
|
-
"version": "1.0.0-rc.
|
|
3
|
+
"version": "1.0.0-rc.25",
|
|
4
4
|
"author": "Exodus Movement, Inc.",
|
|
5
5
|
"description": "A test suite runner",
|
|
6
6
|
"homepage": "https://github.com/ExodusMovement/test",
|
|
@@ -37,6 +37,9 @@
|
|
|
37
37
|
"bin/babel.cjs",
|
|
38
38
|
"bin/jest.js",
|
|
39
39
|
"src/dark.cjs",
|
|
40
|
+
"src/engine.js",
|
|
41
|
+
"src/engine.node.cjs",
|
|
42
|
+
"src/engine.select.cjs",
|
|
40
43
|
"src/jest.js",
|
|
41
44
|
"src/jest.config.js",
|
|
42
45
|
"src/jest.environment.js",
|
package/src/dark.cjs
CHANGED
|
@@ -1,7 +1,3 @@
|
|
|
1
|
-
const { fileURLToPath } = require('node:url')
|
|
2
|
-
|
|
3
|
-
const mayBeUrlToPath = (str) => (str.startsWith('file://') ? fileURLToPath(str) : str)
|
|
4
|
-
|
|
5
1
|
let locForNextTest
|
|
6
2
|
|
|
7
3
|
const installLocationInNextTest = function (loc) {
|
|
@@ -26,6 +22,8 @@ function createCallerLocationHook() {
|
|
|
26
22
|
|
|
27
23
|
try {
|
|
28
24
|
const { Test } = require('node:internal/test_runner/test')
|
|
25
|
+
const { fileURLToPath } = require('node:url')
|
|
26
|
+
const mayBeUrlToPath = (str) => (str.startsWith('file://') ? fileURLToPath(str) : str)
|
|
29
27
|
const locStorage = new Map()
|
|
30
28
|
Object.defineProperty(Test.prototype, 'loc', {
|
|
31
29
|
get() {
|
package/src/engine.js
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import engine from './engine.select.cjs' // need to be sync for non-preloaded imports into cjs
|
|
2
|
+
|
|
3
|
+
const { assert, assertLoose } = engine
|
|
4
|
+
export { assert, assertLoose }
|
|
5
|
+
|
|
6
|
+
const { mock, describe, test, beforeEach, afterEach, before, after } = engine
|
|
7
|
+
export { mock, describe, test, beforeEach, afterEach, before, after }
|
|
8
|
+
|
|
9
|
+
const { builtinModules, syncBuiltinESMExports } = engine
|
|
10
|
+
export { builtinModules, syncBuiltinESMExports }
|
|
11
|
+
|
|
12
|
+
const { utilFormat, isPromise, nodeVersion } = engine
|
|
13
|
+
export { utilFormat, isPromise, nodeVersion }
|
|
14
|
+
|
|
15
|
+
const { baseFile, relativeRequire, isTopLevelESM } = engine
|
|
16
|
+
export { baseFile, relativeRequire, isTopLevelESM }
|
|
17
|
+
|
|
18
|
+
const { snapshot, readSnapshot, setSnapshotSerializers, setSnapshotResolver } = engine
|
|
19
|
+
export { snapshot, readSnapshot, setSnapshotSerializers, setSnapshotResolver }
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
const assert = require('node:assert/strict')
|
|
2
|
+
const assertLoose = require('node:assert')
|
|
3
|
+
const { types, format: utilFormat } = require('node:util')
|
|
4
|
+
const { existsSync, readFileSync } = require('node:fs')
|
|
5
|
+
const { normalize, basename, dirname, join: pathJoin } = require('node:path')
|
|
6
|
+
const { createRequire, builtinModules, syncBuiltinESMExports } = require('node:module')
|
|
7
|
+
const nodeTest = require('node:test')
|
|
8
|
+
|
|
9
|
+
const { mock, describe, test, beforeEach, afterEach, before, after } = nodeTest
|
|
10
|
+
|
|
11
|
+
const isPromise = types.isPromise
|
|
12
|
+
const nodeVersion = process.versions.node
|
|
13
|
+
|
|
14
|
+
const files = process.argv.slice(1)
|
|
15
|
+
const baseFile = files.length === 1 && existsSync(files[0]) ? normalize(files[0]) : undefined
|
|
16
|
+
const relativeRequire = baseFile ? createRequire(baseFile) : require
|
|
17
|
+
const isTopLevelESM = () => !baseFile || !Object.hasOwn(relativeRequire.cache, baseFile) // assume ESM otherwise
|
|
18
|
+
|
|
19
|
+
const snapshot = nodeTest.snapshot
|
|
20
|
+
let snapshotResolver = (dir, name) => [dir, `${name}.snapshot`] // default per Node.js docs
|
|
21
|
+
const resolveSnapshot = (f) => pathJoin(...snapshotResolver(dirname(f), basename(f)))
|
|
22
|
+
const readSnapshot = (f = baseFile) => (f ? readFileSync(resolveSnapshot(f), 'utf8') : null)
|
|
23
|
+
const setSnapshotSerializers = (list) => snapshot?.setDefaultSnapshotSerializers(list)
|
|
24
|
+
const setSnapshotResolver = (fn) => {
|
|
25
|
+
snapshotResolver = fn
|
|
26
|
+
snapshot?.setResolveSnapshotPath(resolveSnapshot)
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/* eslint-disable unicorn/no-useless-spread */
|
|
30
|
+
module.exports = {
|
|
31
|
+
...{ assert, assertLoose },
|
|
32
|
+
...{ mock, describe, test, beforeEach, afterEach, before, after },
|
|
33
|
+
...{ builtinModules, syncBuiltinESMExports },
|
|
34
|
+
...{ utilFormat, isPromise, nodeVersion },
|
|
35
|
+
...{ baseFile, relativeRequire, isTopLevelESM },
|
|
36
|
+
...{ snapshot, readSnapshot, setSnapshotSerializers, setSnapshotResolver },
|
|
37
|
+
}
|
|
38
|
+
/* eslint-enable unicorn/no-useless-spread */
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
module.exports = require('./engine.node.cjs')
|
package/src/jest.config.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
// Not using ./engine.js yet, might pass / embed already loaded config instead
|
|
1
2
|
import assert from 'node:assert/strict'
|
|
2
3
|
import { readFile } from 'node:fs/promises'
|
|
3
4
|
import { existsSync } from 'node:fs'
|
|
@@ -54,6 +55,7 @@ const normalizeJestConfig = (config) => ({
|
|
|
54
55
|
testEnvironment: 'node',
|
|
55
56
|
testTimeout: 5000,
|
|
56
57
|
testPathIgnorePatterns: [],
|
|
58
|
+
passWithNoTests: false,
|
|
57
59
|
snapshotSerializers: [],
|
|
58
60
|
injectGlobals: true,
|
|
59
61
|
maxConcurrency: 5,
|
|
@@ -76,7 +78,8 @@ const normalizeJestConfig = (config) => ({
|
|
|
76
78
|
function verifyJestConfig(c) {
|
|
77
79
|
assert(!configUsed, 'Can not apply new config as the current one was already used')
|
|
78
80
|
|
|
79
|
-
|
|
81
|
+
const nodeEnvs = new Set(['ts-jest', 'ts-jest/presets/js-with-ts'])
|
|
82
|
+
if (!Object.hasOwn(specialEnvironments, c.testEnvironment) && !nodeEnvs.has(c.testEnvironment)) {
|
|
80
83
|
assert.equal(c.testEnvironment, 'node', 'Only "node" testEnvironment is supported')
|
|
81
84
|
}
|
|
82
85
|
|
package/src/jest.fn.js
CHANGED
package/src/jest.js
CHANGED
|
@@ -1,6 +1,12 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import {
|
|
2
|
+
describe as nodeDescribe,
|
|
3
|
+
test as nodeTest,
|
|
4
|
+
afterEach,
|
|
5
|
+
after,
|
|
6
|
+
assert,
|
|
7
|
+
utilFormat,
|
|
8
|
+
isPromise,
|
|
9
|
+
} from './engine.js'
|
|
4
10
|
import { jestConfig } from './jest.config.js'
|
|
5
11
|
import { jestFunctionMocks } from './jest.fn.js'
|
|
6
12
|
import { jestModuleMocks } from './jest.mock.js'
|
|
@@ -75,7 +81,7 @@ const makeEach =
|
|
|
75
81
|
|
|
76
82
|
if (Array.isArray(args)) {
|
|
77
83
|
const length = [...name.replaceAll('%%', '').matchAll(/%[psdifjo]/gu)].length
|
|
78
|
-
if (length > 0) name =
|
|
84
|
+
if (length > 0) name = utilFormat(name, ...args.slice(0, length).map(formatArg))
|
|
79
85
|
}
|
|
80
86
|
|
|
81
87
|
impl(name, () => (Array.isArray(args) ? fn(...args) : fn(args)))
|
|
@@ -122,7 +128,7 @@ const testRaw = (callerLocation, testBase, name, fn, testTimeout) => {
|
|
|
122
128
|
return testBase(name, { timeout }, async (t) => {
|
|
123
129
|
const res = fn()
|
|
124
130
|
assert(
|
|
125
|
-
|
|
131
|
+
isPromise(res),
|
|
126
132
|
`Test "${t.fullName}" did not return a Promise or supply a callback, which is required in force-exit mode.
|
|
127
133
|
For tests to not end abruptly, use either async functions (recommended), Promises, or specify callbacks to test() / it().
|
|
128
134
|
Also, using expect.assertions() to ensure the planned number of assertions is being called is advised for async code.`
|
|
@@ -184,4 +190,4 @@ const jest = {
|
|
|
184
190
|
|
|
185
191
|
export { jest, describe, test, test as it }
|
|
186
192
|
export { expect } from 'expect'
|
|
187
|
-
export { beforeEach, afterEach, before as beforeAll, after as afterAll } from '
|
|
193
|
+
export { beforeEach, afterEach, before as beforeAll, after as afterAll } from './engine.js'
|
package/src/jest.mock.js
CHANGED
|
@@ -1,19 +1,18 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
import {
|
|
2
|
+
mock,
|
|
3
|
+
assert,
|
|
4
|
+
baseFile,
|
|
5
|
+
relativeRequire as require,
|
|
6
|
+
isTopLevelESM,
|
|
7
|
+
builtinModules,
|
|
8
|
+
syncBuiltinESMExports,
|
|
9
|
+
} from './engine.js'
|
|
6
10
|
import { jestfn } from './jest.fn.js'
|
|
7
11
|
import { makeEsbuildMockable } from './dark.cjs'
|
|
8
12
|
|
|
9
|
-
const files = process.argv.slice(1)
|
|
10
|
-
const baseUrl = files.length === 1 && existsSync(files[0]) ? normalize(files[0]) : undefined
|
|
11
13
|
const mapMocks = new Map()
|
|
12
14
|
const mapActual = new Map()
|
|
13
15
|
|
|
14
|
-
const require = createRequire(baseUrl || import.meta.url)
|
|
15
|
-
const isTopLevelESM = () => !baseUrl || !Object.hasOwn(require.cache, baseUrl) // assume ESM otherwise
|
|
16
|
-
|
|
17
16
|
export const jestModuleMocks = {
|
|
18
17
|
mock: jestmock,
|
|
19
18
|
createMockFromModule: (name) => mockClone(requireActual(name)),
|
|
@@ -22,10 +21,8 @@ export const jestModuleMocks = {
|
|
|
22
21
|
resetModules,
|
|
23
22
|
}
|
|
24
23
|
|
|
25
|
-
export const relativeRequire = require
|
|
26
|
-
|
|
27
24
|
export function resolveModule(name) {
|
|
28
|
-
assert(
|
|
25
|
+
assert(baseFile || /^[@a-zA-Z]/u.test(name), 'Mocking relative paths is not possible')
|
|
29
26
|
const unprefixed = name.replace(/^node:/, '')
|
|
30
27
|
if (builtinModules.includes(unprefixed)) return unprefixed
|
|
31
28
|
return require.resolve(name)
|
package/src/jest.snapshot.js
CHANGED
|
@@ -1,25 +1,24 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
1
|
+
import {
|
|
2
|
+
beforeEach,
|
|
3
|
+
assert,
|
|
4
|
+
setSnapshotResolver,
|
|
5
|
+
setSnapshotSerializers,
|
|
6
|
+
readSnapshot,
|
|
7
|
+
relativeRequire,
|
|
8
|
+
} from './engine.js'
|
|
3
9
|
import { expect } from 'expect'
|
|
4
10
|
import { format, plugins as builtinPlugins } from 'pretty-format'
|
|
5
|
-
import assert from 'node:assert/strict'
|
|
6
|
-
import { basename, dirname, join, normalize } from 'node:path'
|
|
7
|
-
import { readFileSync } from 'node:fs'
|
|
8
11
|
import { jestConfig } from './jest.config.js'
|
|
9
|
-
import { relativeRequire } from './jest.mock.js'
|
|
10
12
|
import { getTestNamePath } from './dark.cjs'
|
|
11
13
|
|
|
12
14
|
const { snapshotFormat, snapshotSerializers } = jestConfig()
|
|
13
15
|
const plugins = Object.values(builtinPlugins)
|
|
14
16
|
const serialize = (val) => format(val, { ...snapshotFormat, plugins }).replaceAll(/\r\n|\r/gu, '\n')
|
|
15
|
-
const resolveSnapshot = (f) => join(dirname(f), '__snapshots__', `${basename(f)}.snap`)
|
|
16
17
|
|
|
17
18
|
let serializersAreSetup = false
|
|
18
|
-
let snapshotsAreJest
|
|
19
|
+
let snapshotsAreJest = false
|
|
19
20
|
|
|
20
21
|
// For manually loading the snapshot
|
|
21
|
-
const files = process.argv.slice(1)
|
|
22
|
-
const snapshotLocation = files.length === 1 ? resolveSnapshot(normalize(files[0])) : undefined
|
|
23
22
|
const nameCounts = new Map()
|
|
24
23
|
let snapshotText
|
|
25
24
|
|
|
@@ -32,20 +31,11 @@ function maybeSetupSerializers() {
|
|
|
32
31
|
|
|
33
32
|
// We want to setup snapshots to behave like jest only when first used from jest API
|
|
34
33
|
function maybeSetupJestSnapshots() {
|
|
35
|
-
if (snapshotsAreJest
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
assert(snapshot, 'snapshots require Node.js >=22.3.0')
|
|
41
|
-
snapshot.setDefaultSnapshotSerializers([serialize])
|
|
42
|
-
snapshot.setResolveSnapshotPath(resolveSnapshot)
|
|
43
|
-
snapshotsAreJest = true
|
|
44
|
-
} catch {
|
|
45
|
-
snapshotsAreJest = false
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
return snapshotsAreJest
|
|
34
|
+
if (snapshotsAreJest) return
|
|
35
|
+
setSnapshotResolver((dir, name) => [dir, '__snapshots__', `${name}.snap`])
|
|
36
|
+
setSnapshotSerializers([serialize])
|
|
37
|
+
maybeSetupSerializers()
|
|
38
|
+
snapshotsAreJest = true
|
|
49
39
|
}
|
|
50
40
|
|
|
51
41
|
const wrap = (check) => {
|
|
@@ -118,11 +108,14 @@ const snapOnDisk = (orig, matcher) => {
|
|
|
118
108
|
const obj = matcher ? { ...orig, ...matcher } : orig
|
|
119
109
|
const escape = (str) => str.replaceAll(/([\\`])/gu, '\\$1')
|
|
120
110
|
|
|
121
|
-
|
|
111
|
+
maybeSetupJestSnapshots()
|
|
112
|
+
|
|
113
|
+
if (!context?.assert?.snapshot) {
|
|
122
114
|
// We don't have native snapshots, polyfill reading
|
|
123
|
-
if (
|
|
115
|
+
if (snapshotText !== null) {
|
|
124
116
|
try {
|
|
125
|
-
|
|
117
|
+
const snapshotRaw = readSnapshot()
|
|
118
|
+
snapshotText = snapshotRaw ? `\n${snapshotRaw}\n` : null // we'll search wrapped in \n
|
|
126
119
|
} catch {
|
|
127
120
|
snapshotText = null
|
|
128
121
|
}
|
package/src/jest.timers.js
CHANGED
package/src/tape.js
CHANGED
package/src/version.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import assert from '
|
|
1
|
+
import { assert, nodeVersion } from './engine.js'
|
|
2
2
|
|
|
3
|
-
const [major, minor, patch] =
|
|
3
|
+
const [major, minor, patch] = nodeVersion.split('.').map(Number)
|
|
4
4
|
assert(major !== 21, 'Node.js 21.x is deprecated!') // reached EOL, no reason to even test
|
|
5
5
|
// older versions are glitchy with before/after on top-level, which is a deal-breaker
|
|
6
6
|
// 20.7.0 is fine for node:test but broken with tsx, so we bump to 20.8.0
|