/
importer.spec.ts
146 lines (133 loc) · 4.48 KB
/
importer.spec.ts
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
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
import * as fakers from '../__helpers__/fakers'
import { Importer, __requireModule } from './importer'
const moduleNotFound = (mod: string) => {
const err: any = new Error(`Module not found: ${mod}.`)
err.code = 'MODULE_NOT_FOUND'
throw err
}
const fakeFullPath = (mod: string) => `/root/${mod}.js`
const requireModule = jest.fn((mod) => (mod in modules ? modules[mod]() : moduleNotFound(mod)))
const resolveModule = jest.fn((mod) => (mod in modules ? fakeFullPath(mod) : moduleNotFound(mod)))
__requireModule(requireModule as any, resolveModule)
let modules!: { [key: string]: () => any }
beforeEach(() => {
modules = {}
requireModule.mockClear()
resolveModule.mockClear()
})
describe('instance', () => {
it('should create a singleton', () => {
const v1 = Importer.instance
const v2 = Importer.instance
expect(Importer.instance).toBeInstanceOf(Importer)
expect(v1).toBe(v2)
})
})
describe('tryThese', () => {
it('should try until it finds one existing', () => {
modules = {
success: () => 'ok',
}
expect(new Importer().tryThese('missing1', 'missing2', 'success')).toMatchInlineSnapshot(`
Object {
"exists": true,
"exports": "ok",
"given": "success",
"path": "/root/success.js",
}
`)
})
it('should return the error when one is failing', () => {
modules = {
fail1: () => {
throw new Error('foo')
},
success: () => 'ok',
}
const res = new Importer().tryThese('missing1', 'fail1', 'success')
expect(res).toMatchObject({
exists: true,
error: expect.any(Error),
given: 'fail1',
path: fakeFullPath('fail1'),
})
expect(res).not.toHaveProperty('exports')
expect((res as any).error.message).toMatch(/\bfoo\b/)
})
})
describe('tryTheseOr', () => {
it('should try until it find one not failing', () => {
expect(new Importer().tryTheseOr(['fail1', 'fail2', 'success'])).toBeUndefined()
expect(new Importer().tryTheseOr(['fail1', 'fail2', 'success'], 'foo')).toBe('foo')
modules = {
success: () => 'ok',
}
expect(new Importer().tryTheseOr(['fail1', 'fail2', 'success'])).toBe('ok')
modules.fail2 = () => {
throw new Error('foo')
}
expect(new Importer().tryTheseOr(['fail1', 'fail2', 'success'], 'bar', true)).toBe('bar')
})
it('should fail if one is throwing', () => {
modules = {
success: () => 'ok',
fail2: () => {
throw new Error('foo')
},
}
expect(() => new Importer().tryTheseOr(['fail1', 'fail2', 'success'], 'bar')).toThrow(/\bfoo\b/)
})
})
describe('patcher', () => {
const patch1 = jest.fn((mod) => ({ ...mod, p1: true }))
const patch2 = jest.fn((mod) => ({ ...mod, p2: true }))
it('should apply patches correctly', () => {
const imp = new Importer({ foo: [patch1, patch2] })
modules = {
foo: () => ({ foo: true }),
bar: () => ({ bar: true }),
}
expect(imp.tryTheseOr('foo')).toEqual({ foo: true, p1: true, p2: true })
expect(imp.tryTheseOr('foo')).toEqual({ foo: true, p1: true, p2: true })
expect(imp.tryTheseOr('bar')).toEqual({ bar: true })
// ensure cache has been used
expect(patch1).toHaveBeenCalledTimes(1)
expect(patch2).toHaveBeenCalledTimes(1)
})
})
describe('babelCore', () => {
it('should be @babel/core', () => {
modules = {
'@babel/core': () => '@babel/core',
}
expect(new Importer().babelCore(fakers.importReason())).toBe('@babel/core')
})
it('should fail with correct error message', () => {
expect(() => new Importer().babelCore(fakers.importReason())).toThrowErrorMatchingInlineSnapshot(`
"Unable to load the module \\"@babel/core\\". [[BECAUSE]] To fix it:
↳ install \\"@babel/core\\": \`npm i -D @babel/core\` (or \`yarn add --dev @babel/core\`)"
`)
})
})
describe('babelJest', () => {
it('should be babel-jest', () => {
modules = {
'babel-jest': () => 'babel-jest',
}
expect(new Importer().babelJest(fakers.importReason())).toBe('babel-jest')
})
it('should fail with correct error message', () => {
expect(() => new Importer().babelJest(fakers.importReason())).toThrowErrorMatchingInlineSnapshot(`
"Unable to load the module \\"babel-jest\\". [[BECAUSE]] To fix it:
↳ install \\"babel-jest\\": \`npm i -D babel-jest\` (or \`yarn add --dev babel-jest\`)"
`)
})
})
describe('typescript', () => {
it('should be typescript', () => {
modules = {
typescript: () => 'typescript',
}
expect(new Importer().typescript(fakers.importReason(), 'typescript')).toBe('typescript')
})
})