-
Notifications
You must be signed in to change notification settings - Fork 31.9k
Expand file tree
/
Copy pathjest-setup-after-env.ts
More file actions
131 lines (115 loc) · 4.33 KB
/
Copy pathjest-setup-after-env.ts
File metadata and controls
131 lines (115 loc) · 4.33 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
import * as matchers from 'jest-extended'
import { installGate } from './lib/gate/runtime'
expect.extend(matchers)
// Installs the `_test_gate` global that `// @gate` pragmas compile to, and
// wraps `it`/`test` so a gate on a `describe` reaches the tests inside it.
// See test/lib/gate/runtime.ts.
installGate()
// Patch jscodeshift testUtils to normalize line endings (fixes Windows CRLF issues)
// The issue: jscodeshift's printer (recast) outputs CRLF on Windows, but test fixtures use LF
// We need to patch both defineTest (which uses internal closure references) and runInlineTest
if (process.platform === 'win32') {
try {
const testUtils = require('jscodeshift/dist/testUtils')
const fs = require('fs')
const path = require('path')
// Helper to normalize line endings
// - Convert CRLF to LF
// - Remove trailing whitespace from each line (not meaningful for code)
// - Ensure exactly one trailing newline (POSIX convention for text files)
// Using \n*$ to handle case where transform output has no trailing newline
const normalizeLF = (str: string) =>
str
.replace(/\r\n/g, '\n')
.replace(/[ \t]+$/gm, '')
.replace(/\n*$/, '\n')
// Patch runInlineTest to normalize both transform output and expected
testUtils.runInlineTest = function (
module: any,
options: any,
input: any,
expectedOutput: string,
testOptions?: any
) {
// Normalize input source
const normalizedInput =
typeof input === 'object' && input.source
? { ...input, source: normalizeLF(input.source) }
: input
// Normalize expected output
const normalizedExpected = normalizeLF(expectedOutput)
// Run the transform and normalize its output for comparison
const output = testUtils.applyTransform(
module,
options,
normalizedInput,
testOptions
)
const normalizedOutput =
typeof output === 'string' ? normalizeLF(output) : output
// Do the comparison ourselves instead of letting the original do it
// eslint-disable-next-line jest/no-standalone-expect -- called from within test blocks
expect(normalizedOutput).toEqual(normalizedExpected)
return normalizedOutput
}
// Replace defineTest entirely since it uses internal closure references
// that bypass our exports patch
testUtils.defineTest = function (
dirName: string,
transformName: string,
options: any,
testFilePrefix?: string,
testOptions?: { parser?: string }
) {
const testName = testFilePrefix
? `transforms correctly using "${testFilePrefix}" data`
: 'transforms correctly'
describe(transformName, () => {
it(testName, () => {
const fixtureDir = path.join(dirName, '..', '__testfixtures__')
const prefix = testFilePrefix || transformName
const module = require(path.join(dirName, '..', transformName))
// Determine file extension based on parser option
const parser = testOptions?.parser || module.parser
const extension =
parser === 'ts' ? 'ts' : parser === 'tsx' ? 'tsx' : 'js'
const inputPath = path.join(
fixtureDir,
`${prefix}.input.${extension}`
)
const outputPath = path.join(
fixtureDir,
`${prefix}.output.${extension}`
)
const source = normalizeLF(fs.readFileSync(inputPath, 'utf8'))
const expectedOutput = normalizeLF(
fs.readFileSync(outputPath, 'utf8')
)
testUtils.runInlineTest(
module,
options,
{ path: inputPath, source },
expectedOutput,
testOptions
)
})
})
}
} catch {
// jscodeshift not available, skip patching
}
}
// A default max-timeout of 90 seconds is allowed
// per test we should aim to bring this down though
jest.setTimeout((process.platform === 'win32' ? 180 : 60) * 1000)
// Polyfill for `using` https://www.typescriptlang.org/docs/handbook/release-notes/typescript-5-2.html
if (!Symbol.dispose) {
Object.defineProperty(Symbol, 'dispose', {
value: Symbol('Symbol.dispose'),
})
}
if (!Symbol.asyncDispose) {
Object.defineProperty(Symbol, 'asyncDispose', {
value: Symbol('Symbol.asyncDispose'),
})
}