Skip to content

Commit d4d55c6

Browse files
committed
feat(generator): Generator only adds missing features
1 parent 3a19247 commit d4d55c6

File tree

2 files changed

+331
-69
lines changed

2 files changed

+331
-69
lines changed

__tests__/generator.spec.js

Lines changed: 244 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,6 @@ const mockApi = {
1818
hasPlugin: jest.fn()
1919
}
2020
beforeEach(() => {
21-
// Reset mock status
22-
jest.clearAllMocks()
23-
})
24-
25-
test('extends gitignore if it exists', () => {
2621
fs.readFileSync.mockImplementation((path, encoding) => {
2722
// Check that utf8 encoding is set
2823
expect(encoding).toBe('utf8')
@@ -32,59 +27,259 @@ test('extends gitignore if it exists', () => {
3227
// return mock content
3328
return 'existing_content'
3429
})
35-
// Mock existence of .gitignore
36-
fs.existsSync = jest.fn(path => path === 'apiResolve_./.gitignore')
37-
// Run the generator with mock api
38-
generator(mockApi)
39-
// Run the onCreateComplete callback
40-
completionCb()
41-
// New .gitignore should have been written
42-
expect(fs.writeFileSync).toBeCalledWith(
43-
'apiResolve_./.gitignore',
44-
'existing_content\n#Electron-builder output\n/dist_electron'
45-
)
30+
// Reset mock status
31+
jest.clearAllMocks()
4632
})
47-
test("doesn't modify .gitignore if it doesn't exist", () => {
48-
// Mock lack of .gitignore
49-
fs.existsSync = jest.fn(path => !(path === 'apiResolve_./.gitignore'))
50-
// Run the generator with mock api
51-
generator(mockApi)
52-
// Run the onCreateComplete callback
53-
completionCb()
54-
// New .gitignore should not have been read from or written
55-
expect(fs.writeFileSync).not.toBeCalledWith(
56-
'apiResolve_./.gitignore',
57-
'existing_content\n#Electron-builder output\n/dist_electron'
33+
34+
describe('.gitignore', () => {
35+
test('extends gitignore if it exists', () => {
36+
// Mock existence of .gitignore
37+
fs.existsSync = jest.fn(path => path === 'apiResolve_./.gitignore')
38+
// Run the generator with mock api
39+
generator(mockApi)
40+
// Run the onCreateComplete callback
41+
completionCb()
42+
// New .gitignore should have been written
43+
expect(fs.writeFileSync).toBeCalledWith(
44+
'apiResolve_./.gitignore',
45+
'existing_content\n#Electron-builder output\n/dist_electron'
46+
)
47+
})
48+
49+
test("doesn't modify .gitignore if it doesn't exist", () => {
50+
// Mock lack of .gitignore
51+
fs.existsSync = jest.fn(path => !(path === 'apiResolve_./.gitignore'))
52+
// Run the generator with mock api
53+
generator(mockApi)
54+
// Run the onCreateComplete callback
55+
completionCb()
56+
// New .gitignore should not have been read from or written
57+
expect(fs.writeFileSync).not.toBeCalledWith(
58+
'apiResolve_./.gitignore',
59+
expect.any(String)
60+
)
61+
expect(fs.readFileSync).not.toBeCalledWith(
62+
'apiResolve_./.gitignore',
63+
expect.any(String)
64+
)
65+
// Only index and background should have been written
66+
expect(fs.writeFileSync).toHaveBeenCalledTimes(2)
67+
})
68+
69+
test.each(['#Electron-builder output', '/dist_electron'])(
70+
'does not modify .gitignore if it has "%s"',
71+
existing => {
72+
fs.readFileSync.mockImplementation((path, encoding) => {
73+
// Check that utf8 encoding is set
74+
expect(encoding).toBe('utf8')
75+
if (path === 'apiResolve_./package.json') {
76+
return JSON.stringify({ scripts: {} })
77+
}
78+
// return mock content
79+
return `ignore-this\n${existing}\nignore-that`
80+
})
81+
82+
// Mock existence of .gitignore
83+
fs.existsSync = jest.fn(path => path === 'apiResolve_./.gitignore')
84+
// Run the generator with mock api
85+
generator(mockApi)
86+
// Run the onCreateComplete callback
87+
completionCb()
88+
// New .gitignore should not have been written
89+
expect(fs.writeFileSync).not.toBeCalledWith(
90+
'apiResolve_./.gitignore',
91+
expect.any(String)
92+
)
93+
// Only index should have been written
94+
expect(fs.writeFileSync).toHaveBeenCalledTimes(1)
95+
}
5896
)
59-
expect(fs.readFileSync).not.toBeCalledWith('apiResolve_./.gitignore', 'utf8')
60-
// Only index should have been written
61-
expect(fs.writeFileSync).toHaveBeenCalledTimes(1)
6297
})
6398

64-
test('Adds electron-builder install-app-deps to postInstall', () => {
65-
generator(mockApi)
66-
completionCb()
67-
expect(pkg.scripts.postinstall).toBe('electron-builder install-app-deps')
99+
describe('index.html', () => {
100+
test.each([
101+
// None
102+
'',
103+
// Node_modules path
104+
` <% if (VUE_APP_NODE_MODULES_PATH !== "false") { %><script>require('module').globalPaths.push('<%= VUE_APP_NODE_MODULES_PATH %>')</script><% } %>\n`,
105+
// Base URL
106+
` <% if (BASE_URL === './') { %><base href="app://./" /><% } %>\n`,
107+
// Both
108+
` <% if (BASE_URL === './') { %><base href="app://./" /><% } %>
109+
<% if (VUE_APP_NODE_MODULES_PATH !== "false") { %><script>require('module').globalPaths.push('<%= VUE_APP_NODE_MODULES_PATH %>')</script><% } %>\n`
110+
])('Only add missing tags to index.html', existing => {
111+
// Disable .gitignore modification
112+
fs.existsSync.mockReturnValueOnce(false)
113+
fs.readFileSync.mockImplementation((path, encoding) => {
114+
// Check that utf8 encoding is set
115+
expect(encoding).toBe('utf8')
116+
if (path === 'apiResolve_./package.json') {
117+
return JSON.stringify({ scripts: {} })
118+
}
119+
// return mock content
120+
return `<head>\n${existing} </head>`
121+
})
122+
123+
// Run the generator with mock api
124+
generator(mockApi)
125+
// Run the onCreateComplete callback
126+
completionCb()
127+
128+
const index = fs.writeFileSync.mock.calls[0][1]
129+
// Opening and closing tags still exist
130+
expect(index.match(/^\s*?<head.*?>\s*?$/gm).length).toBe(1)
131+
expect(index.match(/^\s*?<\/head.*?>\s*?$/gm).length).toBe(1)
132+
// Each tag exists once
133+
expect(
134+
index.match(
135+
// Base URL
136+
/<% if \(BASE_URL === '\.\/'\) { %><base href="app:\/\/\.\/" \/><% } %>/g
137+
).length
138+
).toBe(1)
139+
expect(
140+
index.match(
141+
// Node_modules path
142+
/<% if \(VUE_APP_NODE_MODULES_PATH !== "false"\) { %><script>require\('module'\)\.globalPaths\.push\('<%= VUE_APP_NODE_MODULES_PATH %>'\)<\/script><% } %>/g
143+
).length
144+
).toBe(1)
145+
})
68146
})
69147

70-
test('Adds on to existing postinstall script instead of replacing', () => {
71-
fs.readFileSync.mockImplementation((path, encoding) => {
72-
// Check that utf8 encoding is set
73-
expect(encoding).toBe('utf8')
74-
// Mock existing postinstall script in app's package.json
75-
if (path === 'apiResolve_./package.json') {
76-
return JSON.stringify({
77-
scripts: { postinstall: 'existingTask' }
78-
})
148+
describe('background.js', () => {
149+
test.each([false, true])(
150+
'Background file is not added if it exists',
151+
usesTS => {
152+
const file = `src/background.${usesTS ? 'ts' : 'js'}`
153+
// Mock having typescript
154+
mockApi.hasPlugin.mockImplementationOnce(
155+
plugin => plugin === 'typescript' && usesTS
156+
)
157+
// Mock existence of background file
158+
fs.existsSync.mockImplementation(path => path === `apiResolve_./${file}`)
159+
generator(mockApi)
160+
completionCb()
161+
expect(mockApi.render).not.toBeCalled()
79162
}
80-
// return mock content
81-
return 'existing_content'
163+
)
164+
165+
test.each([
166+
'(process.env.WEBPACK_DEV_SERVER_URL as string)',
167+
'let mainWindow: any'
168+
])('Types are not re-added for "%s"', background => {
169+
// Mock typescript existence
170+
mockApi.hasPlugin.mockImplementationOnce(plugin => plugin === 'typescript')
171+
// Mock background file existence
172+
fs.existsSync.mockImplementation(
173+
file => file === 'apiResolve_./src/background.js'
174+
)
175+
fs.readFileSync.mockImplementation((path, encoding) => {
176+
// Check that utf8 encoding is set
177+
expect(encoding).toBe('utf8')
178+
// Mock existing postinstall script in app's package.json
179+
if (path === 'apiResolve_./package.json') {
180+
return JSON.stringify({
181+
scripts: {}
182+
})
183+
}
184+
// return mock content
185+
return background
186+
})
187+
generator(mockApi)
188+
completionCb()
189+
expect(fs.writeFileSync).toBeCalledWith(
190+
'apiResolve_./src/background.ts',
191+
background
192+
)
82193
})
83194

84-
generator(mockApi)
85-
completionCb()
195+
test.each([false, true])(
196+
'Background has node module path added if it does not exist',
197+
usesTS => {
198+
const file = `src/background.${usesTS ? 'ts' : 'js'}`
199+
// Mock having typescript
200+
mockApi.hasPlugin.mockImplementationOnce(
201+
plugin => plugin === 'typescript' && usesTS
202+
)
203+
// Mock not having node path added
204+
fs.readFileSync.mockImplementation((path, encoding) => {
205+
// Check that utf8 encoding is set
206+
expect(encoding).toBe('utf8')
207+
if (path === 'apiResolve_./package.json') {
208+
return JSON.stringify({ scripts: {} })
209+
}
210+
// return mock content
211+
return `const isDevelopment = process.env.NODE_ENV !== 'production'
212+
existing_content`
213+
})
214+
// Mock existence of background file
215+
fs.existsSync.mockImplementation(path => path === `apiResolve_./${file}`)
216+
generator(mockApi)
217+
completionCb()
218+
expect(mockApi.render).not.toBeCalled()
219+
expect(fs.writeFileSync).toBeCalledWith(
220+
`apiResolve_./${file}`,
221+
`const isDevelopment = process.env.NODE_ENV !== 'production'
222+
if (isDevelopment) {
223+
// Don't load any native (external) modules until the following line is run:
224+
require('module').globalPaths.push(process.env.NODE_MODULES_PATH)
225+
}
86226
87-
expect(pkg.scripts.postinstall).toBe(
88-
'existingTask && electron-builder install-app-deps'
227+
existing_content`
228+
)
229+
}
89230
)
90231
})
232+
233+
describe('package.json', () => {
234+
test('Adds electron-builder install-app-deps to postInstall', () => {
235+
generator(mockApi)
236+
completionCb()
237+
expect(pkg.scripts.postinstall).toBe('electron-builder install-app-deps')
238+
})
239+
240+
test('Adds on to existing postinstall script instead of replacing', () => {
241+
fs.readFileSync.mockImplementation((path, encoding) => {
242+
// Check that utf8 encoding is set
243+
expect(encoding).toBe('utf8')
244+
// Mock existing postinstall script in app's package.json
245+
if (path === 'apiResolve_./package.json') {
246+
return JSON.stringify({
247+
scripts: { postinstall: 'existingTask' }
248+
})
249+
}
250+
// return mock content
251+
return 'existing_content'
252+
})
253+
254+
generator(mockApi)
255+
completionCb()
256+
257+
expect(pkg.scripts.postinstall).toBe(
258+
'existingTask && electron-builder install-app-deps'
259+
)
260+
})
261+
262+
test('Does not add install-app-deps multiple times', () => {
263+
fs.readFileSync.mockImplementation((path, encoding) => {
264+
// Check that utf8 encoding is set
265+
expect(encoding).toBe('utf8')
266+
// Mock existing postinstall script in app's package.json
267+
if (path === 'apiResolve_./package.json') {
268+
return JSON.stringify({
269+
scripts: {
270+
postinstall: 'existingTask && electron-builder install-app-deps'
271+
}
272+
})
273+
}
274+
// return mock content
275+
return 'existing_content'
276+
})
277+
278+
generator(mockApi)
279+
completionCb()
280+
281+
expect(pkg.scripts.postinstall).toBe(
282+
'existingTask && electron-builder install-app-deps'
283+
)
284+
})
285+
})

0 commit comments

Comments
 (0)