Skip to content

Commit e144dce

Browse files
committed
Add some missing tests to modules preprocessor
1 parent 995a43e commit e144dce

File tree

2 files changed

+151
-1
lines changed

2 files changed

+151
-1
lines changed

src/modules/preprocessor/__tests__/linker.ts

Lines changed: 127 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import type { SourceFiles } from '../../moduleTypes'
66
import parseProgramsAndConstructImportGraph from '../linker'
77

88
import * as resolver from '../resolver'
9-
import { assertTrue } from '../../../utils/testing/misc'
9+
import { assertNodeType, assertTrue } from '../../../utils/testing/misc'
1010
jest.spyOn(resolver, 'default')
1111

1212
beforeEach(() => {
@@ -136,3 +136,129 @@ test('Linker does tree-shaking', async () => {
136136
expect(resolver.default).not.toHaveBeenCalledWith('./b.js')
137137
expect(Object.keys(result.programs)).not.toContain('/b.js')
138138
})
139+
140+
test('Linker updates the source paths of Import Declaration nodes', async () => {
141+
const [, result] = await testCode(
142+
{
143+
'/dir0/a.js': 'export const x = 0;',
144+
'/b.js': `import { x } from "./dir0/a.js";
145+
export { x };
146+
`,
147+
'/dir1/c.js': 'import { x } from "../b.js";',
148+
},
149+
'/dir1/c.js'
150+
)
151+
152+
assertTrue(result.ok)
153+
const [bNode] = result.programs['/b.js'].body
154+
assertNodeType('ImportDeclaration', bNode)
155+
expect(bNode.source.value).toEqual('/dir0/a.js')
156+
157+
const [cNode] = result.programs['/dir1/c.js'].body
158+
assertNodeType('ImportDeclaration', cNode)
159+
expect(cNode.source.value).toEqual('/b.js')
160+
})
161+
162+
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+
168+
assertTrue(result.ok)
169+
assertTrue(!result.verboseErrors)
170+
})
171+
172+
test('Verbose errors enables normally', async () => {
173+
const [, result] = await testCode({
174+
'/a.js': "'enable verbose';"
175+
}, '/a.js')
176+
177+
assertTrue(result.ok)
178+
assertTrue(result.verboseErrors)
179+
})
180+
181+
test('Verbose errors does not enable when it is not the entrypoint', async () => {
182+
const [, result] = await testCode({
183+
'/a.js': `
184+
'enable verbose';
185+
export const a = "a";
186+
`,
187+
'/b.js': "import { a } from './a.js';"
188+
}, '/b.js')
189+
190+
assertTrue(result.ok)
191+
assertTrue(!result.verboseErrors)
192+
})
193+
194+
test('Verbose errors does not enable when it is not the first statement', async () => {
195+
const [, result] = await testCode({
196+
'/a.js': `
197+
export const a = "a";
198+
'enable verbose';
199+
`,
200+
}, '/a.js')
201+
202+
assertTrue(result.ok)
203+
assertTrue(!result.verboseErrors)
204+
})
205+
206+
test('Verbose errors does not enable when it is an unknown entrypoint', async () => {
207+
const [, result] = await testCode({
208+
'/a.js': `
209+
export const a = "a";
210+
'enable verbose';
211+
`,
212+
}, '/d.js' as any)
213+
214+
assertTrue(!result.ok)
215+
assertTrue(!result.verboseErrors)
216+
})
217+
218+
test('Verbose errors enables even if other files have parse errors', async () => {
219+
const [{ errors }, result] = await testCode({
220+
'/a.js': `
221+
'enable verbose';
222+
import { b } from "./b.js";
223+
`,
224+
'/b.js': `export const b = "b"`
225+
}, '/a.js')
226+
227+
assertTrue(!result.ok)
228+
assertTrue(result.verboseErrors)
229+
expect(errors.length).toEqual(1)
230+
expect(errors[0]).toBeInstanceOf(MissingSemicolonError)
231+
})
232+
233+
test('Verbose errors enables even if the entrypoint has parse errors', async () => {
234+
const [{ errors }, result] = await testCode({
235+
'/a.js': `
236+
'enable verbose';
237+
const x = 0
238+
`,
239+
}, '/a.js')
240+
241+
assertTrue(!result.ok)
242+
assertTrue(result.verboseErrors)
243+
expect(errors.length).toEqual(1)
244+
expect(errors[0]).toBeInstanceOf(MissingSemicolonError)
245+
})
246+
247+
test('Verbose errors enables even if there is a module resolution problem', async () => {
248+
const [{ errors }, result] = await testCode({
249+
'/a.js': `
250+
'enable verbose';
251+
import { b } from "./b.js";
252+
`,
253+
'/b.js': `
254+
import { c } from "./c.js";
255+
export { c as b };
256+
`
257+
}, '/a.js')
258+
259+
assertTrue(!result.ok)
260+
assertTrue(result.verboseErrors)
261+
expect(errors.length).toEqual(1)
262+
expect(errors[0]).toBeInstanceOf(ModuleNotFoundError)
263+
})
264+
})

src/modules/preprocessor/__tests__/preprocessor.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import {
1313
defaultExportLookupName
1414
} from '../../../stdlib/localImport.prelude'
1515
import type { SourceFiles } from '../../moduleTypes'
16+
import { UndefinedImportError } from '../../errors'
1617

1718
jest.mock('../../loader/loaders')
1819

@@ -419,4 +420,27 @@ describe('preprocessFileImports', () => {
419420

420421
assertASTsAreEquivalent(actualProgram, expectedCode)
421422
})
423+
424+
it('catches errors thrown by the bundler', async () => {
425+
const context = mockContext(Chapter.SOURCE_4)
426+
const errorToThrow = new Error()
427+
const promise = preprocessFileImports(wrapFiles({
428+
'/a.js': 'const a = 0;',
429+
}), '/a.js', context, {}, () => { throw errorToThrow })
430+
431+
await expect(promise).resolves.not.toThrow()
432+
expect(context.errors[0]).toBe(errorToThrow)
433+
})
434+
435+
it('catches import analysis errors', async () => {
436+
const context = mockContext(Chapter.SOURCE_4)
437+
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 })
442+
443+
await expect(promise).resolves.not.toThrow()
444+
expect(context.errors[0]).toBeInstanceOf(UndefinedImportError)
445+
})
422446
})

0 commit comments

Comments
 (0)