Skip to content

Commit c40bd4f

Browse files
committed
Fix some potentially misleading tests that were passing
1 parent e144dce commit c40bd4f

File tree

2 files changed

+116
-93
lines changed

2 files changed

+116
-93
lines changed

src/modules/preprocessor/__tests__/linker.ts

Lines changed: 93 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,10 @@ import { CircularImportError, ModuleNotFoundError } from '../../errors'
55
import type { SourceFiles } from '../../moduleTypes'
66
import parseProgramsAndConstructImportGraph from '../linker'
77

8-
import * as resolver from '../resolver'
9-
import { assertNodeType, assertTrue } from '../../../utils/testing/misc'
10-
jest.spyOn(resolver, 'default')
8+
import * as parser from '../../../parser/parser'
9+
import { asMockedFunc, assertNodeType, assertTrue } from '../../../utils/testing/misc'
10+
11+
jest.spyOn(parser, 'parse')
1112

1213
beforeEach(() => {
1314
jest.clearAllMocks()
@@ -35,6 +36,22 @@ async function expectError<T extends SourceFiles>(files: T, entrypointFilePath:
3536
return context.errors
3637
}
3738

39+
function checkCallsToParser(yesCalls: string[], noCalls: string[]) {
40+
const { calls } = asMockedFunc(parser.parse).mock
41+
const toPaths = calls.map(([, , options]) => {
42+
const path = options?.sourceFile
43+
return path
44+
})
45+
46+
for (const each of yesCalls) {
47+
expect(toPaths).toContainEqual(each)
48+
}
49+
50+
for (const each of noCalls) {
51+
expect(toPaths).not.toContainEqual(each)
52+
}
53+
}
54+
3855
test('Adds CircularImportError and returns undefined when imports are circular', async () => {
3956
const [error] = await expectError(
4057
{
@@ -63,17 +80,16 @@ test.skip('Longer cycle causes also causes CircularImportError', async () => {
6380
)
6481

6582
expect(error).toBeInstanceOf(CircularImportError)
66-
expect(resolver.default).not.toHaveBeenCalledWith('./e.js')
6783
})
6884

6985
test('Self Circular Imports cause a short circuiting of the linker', async () => {
7086
const [error] = await expectError(
7187
{
72-
'/a.js': 'import { a } from "./a.js";',
73-
'/c.js': `
88+
'/a.js': `
89+
import { a } from "./a.js";
7490
import { b } from "./b.js";
75-
export const c = "c";
7691
`,
92+
'/c.js': `export const c = "c";`,
7793
'/d.js': `
7894
import { a } from "./a.js";
7995
import { c } from "./c.js";
@@ -83,43 +99,9 @@ test('Self Circular Imports cause a short circuiting of the linker', async () =>
8399
)
84100

85101
expect(error).toBeInstanceOf(CircularImportError)
86-
expect(resolver.default).not.toHaveBeenCalledWith('./c.js')
87-
expect(resolver.default).not.toHaveBeenCalledWith('./b.js')
88-
})
89-
90-
test('Parse errors cause a short circuiting of the linker', async () => {
91-
const [error] = await expectError(
92-
{
93-
'/a.js': 'export const a = "a";',
94-
'/b.js': `
95-
import { a } from "./a.js";
96-
export function b() {
97-
return a
98-
}
99-
`,
100-
'/c.js': 'import { b } from "./b.js";'
101-
},
102-
'/b.js'
103-
)
104-
expect(error).toBeInstanceOf(MissingSemicolonError)
105-
expect(resolver.default).not.toHaveBeenCalledWith('./a.js')
106-
})
107-
108-
test('ModuleNotFoundErrors short circuit the linker', async () => {
109-
const [error] = await expectError(
110-
{
111-
'/a.js': 'export const a = "a";',
112-
'/b.js': `
113-
import { c } from './c.js';
114-
import { a } from './a.js';
115-
`,
116-
'/d.js': 'import { b } from "./b.js";'
117-
},
118-
'/d.js'
119-
)
120-
121-
expect(error).toBeInstanceOf(ModuleNotFoundError)
122-
expect(resolver.default).not.toHaveBeenCalledWith('./a.js')
102+
// /b.js is only imported by the error throwing /a.js,
103+
// so it should never be parsed
104+
checkCallsToParser(['/a.js', '/c.js', '/d.js'], ['/b.js'])
123105
})
124106

125107
test('Linker does tree-shaking', async () => {
@@ -133,7 +115,8 @@ test('Linker does tree-shaking', async () => {
133115

134116
expect(errors.length).toEqual(0)
135117
assertTrue(result.ok)
136-
expect(resolver.default).not.toHaveBeenCalledWith('./b.js')
118+
// /a.js doesn't import /b.js, so it should not be parsed
119+
checkCallsToParser(['/a.js'], ['/b.js'])
137120
expect(Object.keys(result.programs)).not.toContain('/b.js')
138121
})
139122

@@ -144,7 +127,7 @@ test('Linker updates the source paths of Import Declaration nodes', async () =>
144127
'/b.js': `import { x } from "./dir0/a.js";
145128
export { x };
146129
`,
147-
'/dir1/c.js': 'import { x } from "../b.js";',
130+
'/dir1/c.js': 'import { x } from "../b.js";'
148131
},
149132
'/dir1/c.js'
150133
)
@@ -160,105 +143,129 @@ test('Linker updates the source paths of Import Declaration nodes', async () =>
160143
})
161144

162145
describe('Test determining verbose errors', () => {
163-
test('Verbose errors is normally false', async () => {
164-
const [, result] = await testCode({
165-
'/a.js': "const a = 0;"
166-
}, '/a.js')
167-
146+
test('Verbose errors is normally false', async () => {
147+
const [, result] = await testCode(
148+
{
149+
'/a.js': 'const a = 0;'
150+
},
151+
'/a.js'
152+
)
153+
168154
assertTrue(result.ok)
169155
assertTrue(!result.verboseErrors)
170156
})
171157

172158
test('Verbose errors enables normally', async () => {
173-
const [, result] = await testCode({
174-
'/a.js': "'enable verbose';"
175-
}, '/a.js')
176-
159+
const [, result] = await testCode(
160+
{
161+
'/a.js': "'enable verbose';"
162+
},
163+
'/a.js'
164+
)
165+
177166
assertTrue(result.ok)
178167
assertTrue(result.verboseErrors)
179168
})
180169

181170
test('Verbose errors does not enable when it is not the entrypoint', async () => {
182-
const [, result] = await testCode({
183-
'/a.js': `
171+
const [, result] = await testCode(
172+
{
173+
'/a.js': `
184174
'enable verbose';
185175
export const a = "a";
186176
`,
187-
'/b.js': "import { a } from './a.js';"
188-
}, '/b.js')
189-
177+
'/b.js': "import { a } from './a.js';"
178+
},
179+
'/b.js'
180+
)
181+
190182
assertTrue(result.ok)
191183
assertTrue(!result.verboseErrors)
192184
})
193185

194186
test('Verbose errors does not enable when it is not the first statement', async () => {
195-
const [, result] = await testCode({
196-
'/a.js': `
187+
const [, result] = await testCode(
188+
{
189+
'/a.js': `
197190
export const a = "a";
198191
'enable verbose';
199-
`,
200-
}, '/a.js')
201-
192+
`
193+
},
194+
'/a.js'
195+
)
196+
202197
assertTrue(result.ok)
203198
assertTrue(!result.verboseErrors)
204199
})
205200

206201
test('Verbose errors does not enable when it is an unknown entrypoint', async () => {
207-
const [, result] = await testCode({
208-
'/a.js': `
202+
const [, result] = await testCode(
203+
{
204+
'/a.js': `
209205
export const a = "a";
210206
'enable verbose';
211-
`,
212-
}, '/d.js' as any)
213-
207+
`
208+
},
209+
'/d.js' as any
210+
)
211+
214212
assertTrue(!result.ok)
215213
assertTrue(!result.verboseErrors)
216214
})
217215

218216
test('Verbose errors enables even if other files have parse errors', async () => {
219-
const [{ errors }, result] = await testCode({
220-
'/a.js': `
217+
const [{ errors }, result] = await testCode(
218+
{
219+
'/a.js': `
221220
'enable verbose';
222221
import { b } from "./b.js";
223222
`,
224-
'/b.js': `export const b = "b"`
225-
}, '/a.js')
226-
223+
'/b.js': `export const b = "b"`
224+
},
225+
'/a.js'
226+
)
227+
227228
assertTrue(!result.ok)
228229
assertTrue(result.verboseErrors)
229230
expect(errors.length).toEqual(1)
230231
expect(errors[0]).toBeInstanceOf(MissingSemicolonError)
231232
})
232233

233234
test('Verbose errors enables even if the entrypoint has parse errors', async () => {
234-
const [{ errors }, result] = await testCode({
235-
'/a.js': `
235+
const [{ errors }, result] = await testCode(
236+
{
237+
'/a.js': `
236238
'enable verbose';
237239
const x = 0
238-
`,
239-
}, '/a.js')
240-
240+
`
241+
},
242+
'/a.js'
243+
)
244+
241245
assertTrue(!result.ok)
242246
assertTrue(result.verboseErrors)
243247
expect(errors.length).toEqual(1)
244248
expect(errors[0]).toBeInstanceOf(MissingSemicolonError)
245249
})
246250

247251
test('Verbose errors enables even if there is a module resolution problem', async () => {
248-
const [{ errors }, result] = await testCode({
249-
'/a.js': `
252+
const [{ errors }, result] = await testCode(
253+
{
254+
'/a.js': `
250255
'enable verbose';
251256
import { b } from "./b.js";
252257
`,
253-
'/b.js': `
258+
'/b.js': `
254259
import { c } from "./c.js";
255260
export { c as b };
256261
`
257-
}, '/a.js')
258-
262+
},
263+
'/a.js'
264+
)
265+
259266
assertTrue(!result.ok)
260267
assertTrue(result.verboseErrors)
261268
expect(errors.length).toEqual(1)
262269
expect(errors[0]).toBeInstanceOf(ModuleNotFoundError)
263270
})
264-
})
271+
})

src/modules/preprocessor/__tests__/preprocessor.ts

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -424,9 +424,17 @@ describe('preprocessFileImports', () => {
424424
it('catches errors thrown by the bundler', async () => {
425425
const context = mockContext(Chapter.SOURCE_4)
426426
const errorToThrow = new Error()
427-
const promise = preprocessFileImports(wrapFiles({
428-
'/a.js': 'const a = 0;',
429-
}), '/a.js', context, {}, () => { throw errorToThrow })
427+
const promise = preprocessFileImports(
428+
wrapFiles({
429+
'/a.js': 'const a = 0;'
430+
}),
431+
'/a.js',
432+
context,
433+
{},
434+
() => {
435+
throw errorToThrow
436+
}
437+
)
430438

431439
await expect(promise).resolves.not.toThrow()
432440
expect(context.errors[0]).toBe(errorToThrow)
@@ -435,10 +443,18 @@ describe('preprocessFileImports', () => {
435443
it('catches import analysis errors', async () => {
436444
const context = mockContext(Chapter.SOURCE_4)
437445
const errorToThrow = new Error()
438-
const promise = preprocessFileImports(wrapFiles({
439-
'/a.js': `import { b } from "./b.js";`,
440-
'/b.js': 'export const a = "b";'
441-
}), '/a.js', context, {}, () => { throw errorToThrow })
446+
const promise = preprocessFileImports(
447+
wrapFiles({
448+
'/a.js': `import { b } from "./b.js";`,
449+
'/b.js': 'export const a = "b";'
450+
}),
451+
'/a.js',
452+
context,
453+
{},
454+
() => {
455+
throw errorToThrow
456+
}
457+
)
442458

443459
await expect(promise).resolves.not.toThrow()
444460
expect(context.errors[0]).toBeInstanceOf(UndefinedImportError)

0 commit comments

Comments
 (0)