@neurodevs/ndx-cli 0.1.54 → 0.1.57
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/__tests__/AbstractCommandRunnerTest.d.ts +66 -0
- package/build/__tests__/AbstractCommandRunnerTest.js +264 -0
- package/build/__tests__/AbstractCommandRunnerTest.js.map +1 -0
- package/build/__tests__/modules/CliCommandRunner.test.d.ts +2 -94
- package/build/__tests__/modules/CliCommandRunner.test.js +2 -675
- package/build/__tests__/modules/CliCommandRunner.test.js.map +1 -1
- package/build/__tests__/modules/commands/BindSnippetCommand.test.d.ts +20 -0
- package/build/__tests__/modules/commands/BindSnippetCommand.test.js +111 -0
- package/build/__tests__/modules/commands/BindSnippetCommand.test.js.map +1 -0
- package/build/__tests__/modules/commands/CreateImplCommand.test.d.ts +13 -0
- package/build/__tests__/modules/commands/CreateImplCommand.test.js +112 -0
- package/build/__tests__/modules/commands/CreateImplCommand.test.js.map +1 -0
- package/build/__tests__/modules/commands/CreatePackageCommand.test.d.ts +10 -0
- package/build/__tests__/modules/commands/CreatePackageCommand.test.js +98 -0
- package/build/__tests__/modules/commands/CreatePackageCommand.test.js.map +1 -0
- package/build/__tests__/modules/commands/CreateUiCommand.test.d.ts +22 -0
- package/build/__tests__/modules/commands/CreateUiCommand.test.js +220 -0
- package/build/__tests__/modules/commands/CreateUiCommand.test.js.map +1 -0
- package/build/__tests__/modules/commands/UpgradePackageCommand.test.d.ts +11 -0
- package/build/__tests__/modules/commands/UpgradePackageCommand.test.js +90 -0
- package/build/__tests__/modules/commands/UpgradePackageCommand.test.js.map +1 -0
- package/build/modules/CliCommandRunner.d.ts +4 -2
- package/build/modules/CliCommandRunner.js +18 -7
- package/build/modules/CliCommandRunner.js.map +1 -1
- package/build/modules/commands/BindSnippetCommand.d.ts +16 -0
- package/build/modules/commands/BindSnippetCommand.js +67 -0
- package/build/modules/commands/BindSnippetCommand.js.map +1 -0
- package/package.json +3 -2
- package/src/__tests__/AbstractCommandRunnerTest.ts +321 -0
- package/src/__tests__/modules/CliCommandRunner.test.ts +3 -910
- package/src/__tests__/modules/commands/BindSnippetCommand.test.ts +129 -0
- package/src/__tests__/modules/commands/CreateImplCommand.test.ts +137 -0
- package/src/__tests__/modules/commands/CreatePackageCommand.test.ts +113 -0
- package/src/__tests__/modules/commands/CreateUiCommand.test.ts +297 -0
- package/src/__tests__/modules/commands/UpgradePackageCommand.test.ts +105 -0
- package/src/modules/CliCommandRunner.ts +19 -7
- package/src/modules/commands/BindSnippetCommand.ts +75 -0
|
@@ -1,81 +1,11 @@
|
|
|
1
|
-
import { exec as execSync } from 'child_process'
|
|
2
|
-
import { mkdir, readFile, writeFile } from 'fs/promises'
|
|
3
|
-
import os from 'os'
|
|
4
|
-
import path from 'path'
|
|
5
|
-
import { promisify } from 'util'
|
|
6
1
|
import { test, assert, generateId } from '@sprucelabs/test-utils'
|
|
7
|
-
import {
|
|
8
|
-
callsToExec,
|
|
9
|
-
callsToLog,
|
|
10
|
-
callsToMkdir,
|
|
11
|
-
callsToWriteFile,
|
|
12
|
-
fakeExec,
|
|
13
|
-
fakeLog,
|
|
14
|
-
fakeMkdir,
|
|
15
|
-
fakeReadFile,
|
|
16
|
-
fakeWriteFile,
|
|
17
|
-
resetCallsToExec,
|
|
18
|
-
resetCallsToLog,
|
|
19
|
-
resetCallsToMkdir,
|
|
20
|
-
resetCallsToReadFile,
|
|
21
|
-
resetCallsToWriteFile,
|
|
22
|
-
setFakeReadFileResult,
|
|
23
|
-
} from '@neurodevs/fake-node-core'
|
|
24
|
-
import {
|
|
25
|
-
FakeAutomodule,
|
|
26
|
-
FakeAutopackage,
|
|
27
|
-
ImplAutomodule,
|
|
28
|
-
NpmAutopackage,
|
|
29
|
-
UiAutomodule,
|
|
30
|
-
} from '@neurodevs/meta-node'
|
|
31
|
-
import prompts from 'prompts'
|
|
32
|
-
import CliCommandRunner from '../../modules/CliCommandRunner'
|
|
33
|
-
import fakePrompts, {
|
|
34
|
-
callsToFakePrompts,
|
|
35
|
-
resetCallsToFakePrompts,
|
|
36
|
-
setFakeResponses,
|
|
37
|
-
} from '../../testDoubles/prompts/fakePrompts'
|
|
38
|
-
import AbstractPackageTest from '../AbstractPackageTest'
|
|
2
|
+
import { callsToLog } from '@neurodevs/fake-node-core'
|
|
39
3
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
export default class CliCommandRunnerTest extends AbstractPackageTest {
|
|
43
|
-
private static readonly createImplCommand = 'create.impl'
|
|
44
|
-
private static readonly interfaceName = generateId()
|
|
45
|
-
private static readonly implName = generateId()
|
|
46
|
-
|
|
47
|
-
private static readonly createPackageCommand = 'create.package'
|
|
48
|
-
private static readonly packageName = generateId()
|
|
49
|
-
private static readonly description = generateId()
|
|
50
|
-
private static readonly keywords = [generateId(), generateId()]
|
|
51
|
-
private static readonly githubToken = generateId()
|
|
52
|
-
|
|
53
|
-
private static readonly defaultKeywords = ['nodejs', 'typescript', 'tdd']
|
|
54
|
-
|
|
55
|
-
private static get keywordsWithDefaults() {
|
|
56
|
-
return [...this.defaultKeywords, ...this.keywords]
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
private static readonly createUiCommand = 'create.ui'
|
|
60
|
-
private static readonly componentName = generateId()
|
|
61
|
-
|
|
62
|
-
private static readonly upgradePackageCommand = 'upgrade.package'
|
|
4
|
+
import AbstractCommandRunnerTest from '../AbstractCommandRunnerTest'
|
|
63
5
|
|
|
6
|
+
export default class CliCommandRunnerTest extends AbstractCommandRunnerTest {
|
|
64
7
|
protected static async beforeEach() {
|
|
65
8
|
await super.beforeEach()
|
|
66
|
-
|
|
67
|
-
this.setFakeImplAutomodule()
|
|
68
|
-
this.setFakeUiAutomodule()
|
|
69
|
-
this.setFakeAutopackage()
|
|
70
|
-
|
|
71
|
-
this.setFakeExec()
|
|
72
|
-
this.setFakeLog()
|
|
73
|
-
this.setFakeMkdir()
|
|
74
|
-
this.setFakePrompts()
|
|
75
|
-
this.setFakeReadFile()
|
|
76
|
-
this.setFakeWriteFile()
|
|
77
|
-
|
|
78
|
-
process.env.GITHUB_TOKEN = this.githubToken
|
|
79
9
|
}
|
|
80
10
|
|
|
81
11
|
@test()
|
|
@@ -94,468 +24,6 @@ export default class CliCommandRunnerTest extends AbstractPackageTest {
|
|
|
94
24
|
)
|
|
95
25
|
}
|
|
96
26
|
|
|
97
|
-
@test()
|
|
98
|
-
protected static async createImplCreatesInstance() {
|
|
99
|
-
const instance = await this.runCreateImpl()
|
|
100
|
-
|
|
101
|
-
assert.isTruthy(
|
|
102
|
-
instance,
|
|
103
|
-
`Failed to create instance for ${this.createImplCommand}!`
|
|
104
|
-
)
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
@test()
|
|
108
|
-
protected static async createImplPromptsUserForInput() {
|
|
109
|
-
await this.runCreateImpl()
|
|
110
|
-
|
|
111
|
-
assert.isEqualDeep(
|
|
112
|
-
callsToFakePrompts[0],
|
|
113
|
-
[
|
|
114
|
-
{
|
|
115
|
-
type: 'text',
|
|
116
|
-
name: 'interfaceName',
|
|
117
|
-
message: this.interfaceNameMessage,
|
|
118
|
-
},
|
|
119
|
-
{
|
|
120
|
-
type: 'text',
|
|
121
|
-
name: 'implName',
|
|
122
|
-
message: this.implNameMessage,
|
|
123
|
-
},
|
|
124
|
-
],
|
|
125
|
-
'Did not prompt user for expected input!'
|
|
126
|
-
)
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
@test()
|
|
130
|
-
protected static async createImplDoesNotContinueIfPromptsIsInterrupted() {
|
|
131
|
-
await this.runCreateImpl({
|
|
132
|
-
interfaceName: '',
|
|
133
|
-
implName: '',
|
|
134
|
-
})
|
|
135
|
-
|
|
136
|
-
assert.isEqual(
|
|
137
|
-
FakeAutomodule.numCallsToRun,
|
|
138
|
-
0,
|
|
139
|
-
'Should not have called run on ImplAutomodule!'
|
|
140
|
-
)
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
@test()
|
|
144
|
-
protected static async createImplCreatesTestSaveDirIfNotExists() {
|
|
145
|
-
await this.runCreateImpl()
|
|
146
|
-
|
|
147
|
-
assert.isEqualDeep(
|
|
148
|
-
callsToMkdir[0],
|
|
149
|
-
{ path: this.implTestSaveDir, options: { recursive: true } },
|
|
150
|
-
'Did not create test save dir!'
|
|
151
|
-
)
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
@test()
|
|
155
|
-
protected static async createImplCreatesModuleSaveDirIfNotExists() {
|
|
156
|
-
await this.runCreateImpl()
|
|
157
|
-
|
|
158
|
-
assert.isEqualDeep(
|
|
159
|
-
callsToMkdir[1],
|
|
160
|
-
{ path: this.implModuleSaveDir, options: { recursive: true } },
|
|
161
|
-
'Did not create module save dir!'
|
|
162
|
-
)
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
@test()
|
|
166
|
-
protected static async createImplCreatesFakeSaveDirIfNotExists() {
|
|
167
|
-
await this.runCreateImpl()
|
|
168
|
-
|
|
169
|
-
assert.isEqualDeep(
|
|
170
|
-
callsToMkdir[2],
|
|
171
|
-
{
|
|
172
|
-
path: `src/testDoubles/${this.interfaceName}`,
|
|
173
|
-
options: { recursive: true },
|
|
174
|
-
},
|
|
175
|
-
'Did not create fake save dir!'
|
|
176
|
-
)
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
@test()
|
|
180
|
-
protected static async createImplCreatesImplAutomodule() {
|
|
181
|
-
await this.runCreateImpl()
|
|
182
|
-
|
|
183
|
-
assert.isEqualDeep(
|
|
184
|
-
FakeAutomodule.callsToConstructor[0],
|
|
185
|
-
{
|
|
186
|
-
testSaveDir: this.implTestSaveDir,
|
|
187
|
-
moduleSaveDir: this.implModuleSaveDir,
|
|
188
|
-
fakeSaveDir: this.implFakeSaveDir,
|
|
189
|
-
interfaceName: this.interfaceName,
|
|
190
|
-
implName: this.implName,
|
|
191
|
-
},
|
|
192
|
-
'Did not create ImplAutomodule with expected options!'
|
|
193
|
-
)
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
@test()
|
|
197
|
-
protected static async createImplRunsImplAutomodule() {
|
|
198
|
-
await this.runCreateImpl()
|
|
199
|
-
|
|
200
|
-
assert.isEqual(
|
|
201
|
-
FakeAutomodule.numCallsToRun,
|
|
202
|
-
1,
|
|
203
|
-
'Did not call run on ImplAutomodule!'
|
|
204
|
-
)
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
@test()
|
|
208
|
-
protected static async createPackageCreatesInstance() {
|
|
209
|
-
const instance = await this.runCreatePackage()
|
|
210
|
-
|
|
211
|
-
assert.isTruthy(
|
|
212
|
-
instance,
|
|
213
|
-
`Failed to create instance for ${this.createPackageCommand}!`
|
|
214
|
-
)
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
@test()
|
|
218
|
-
protected static async createPackagePromptsUserForInput() {
|
|
219
|
-
await this.runCreatePackage()
|
|
220
|
-
|
|
221
|
-
assert.isEqualDeep(
|
|
222
|
-
JSON.stringify(callsToFakePrompts[0]),
|
|
223
|
-
JSON.stringify([
|
|
224
|
-
{
|
|
225
|
-
type: 'text',
|
|
226
|
-
name: 'packageName',
|
|
227
|
-
message: this.packageNameMessage,
|
|
228
|
-
},
|
|
229
|
-
{
|
|
230
|
-
type: 'text',
|
|
231
|
-
name: 'description',
|
|
232
|
-
message: this.packageDescriptionMessage,
|
|
233
|
-
},
|
|
234
|
-
{
|
|
235
|
-
type: 'text',
|
|
236
|
-
name: 'keywords',
|
|
237
|
-
message:
|
|
238
|
-
'Enter keywords (comma or space separated, lowercase, optional):',
|
|
239
|
-
initial: '',
|
|
240
|
-
format: (value: string) =>
|
|
241
|
-
value ? this.splitOnCommaOrWhitespace(value) : [],
|
|
242
|
-
},
|
|
243
|
-
]),
|
|
244
|
-
'Did not prompt user for expected input!'
|
|
245
|
-
)
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
@test()
|
|
249
|
-
protected static async createPackageDoesNotContinueIfPromptsIsInterrupted() {
|
|
250
|
-
await this.runCreatePackage({
|
|
251
|
-
packageName: '',
|
|
252
|
-
description: '',
|
|
253
|
-
})
|
|
254
|
-
|
|
255
|
-
assert.isEqual(
|
|
256
|
-
FakeAutopackage.numCallsToRun,
|
|
257
|
-
0,
|
|
258
|
-
'Should not have called run on Autopackage!'
|
|
259
|
-
)
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
@test()
|
|
263
|
-
protected static async createPackageCreatesNpmAutopackage() {
|
|
264
|
-
await this.runCreatePackage()
|
|
265
|
-
|
|
266
|
-
assert.isEqualDeep(
|
|
267
|
-
FakeAutopackage.callsToConstructor[0],
|
|
268
|
-
{
|
|
269
|
-
name: this.packageName,
|
|
270
|
-
description: this.description,
|
|
271
|
-
keywords: this.keywordsWithDefaults,
|
|
272
|
-
gitNamespace: 'neurodevs',
|
|
273
|
-
npmNamespace: 'neurodevs',
|
|
274
|
-
installDir: this.expandHomeDir('~/dev'),
|
|
275
|
-
license: 'MIT',
|
|
276
|
-
author: 'Eric Yates <hello@ericthecurious.com>',
|
|
277
|
-
},
|
|
278
|
-
'Did not create NpmAutopackage with expected options!'
|
|
279
|
-
)
|
|
280
|
-
}
|
|
281
|
-
|
|
282
|
-
@test()
|
|
283
|
-
protected static async createPackageRunsNpmAutopackage() {
|
|
284
|
-
await this.runCreatePackage()
|
|
285
|
-
|
|
286
|
-
assert.isEqual(
|
|
287
|
-
FakeAutopackage.numCallsToRun,
|
|
288
|
-
1,
|
|
289
|
-
'Did not call run on NpmAutopackage!'
|
|
290
|
-
)
|
|
291
|
-
}
|
|
292
|
-
|
|
293
|
-
@test()
|
|
294
|
-
protected static async createUiCreatesInstance() {
|
|
295
|
-
const instance = await this.runCreateUi()
|
|
296
|
-
|
|
297
|
-
assert.isTruthy(
|
|
298
|
-
instance,
|
|
299
|
-
`Failed to create instance for ${this.createUiCommand}!`
|
|
300
|
-
)
|
|
301
|
-
}
|
|
302
|
-
|
|
303
|
-
@test()
|
|
304
|
-
protected static async createUiPromptsInstallDependenciesIfMissing() {
|
|
305
|
-
this.setFakeReadToEmptyPackageJson()
|
|
306
|
-
|
|
307
|
-
await this.runCreateUi()
|
|
308
|
-
|
|
309
|
-
assert.isEqualDeep(
|
|
310
|
-
callsToFakePrompts[0],
|
|
311
|
-
[
|
|
312
|
-
{
|
|
313
|
-
type: 'confirm',
|
|
314
|
-
name: 'shouldInstall',
|
|
315
|
-
message:
|
|
316
|
-
'Some required dependencies are missing! Press Enter to install, or any other key to abort.',
|
|
317
|
-
initial: true,
|
|
318
|
-
},
|
|
319
|
-
],
|
|
320
|
-
'Did not prompt user for expected input!'
|
|
321
|
-
)
|
|
322
|
-
}
|
|
323
|
-
|
|
324
|
-
@test()
|
|
325
|
-
protected static async createUiInstallsDependenciesIfMissing() {
|
|
326
|
-
this.setFakeReadToEmptyPackageJson()
|
|
327
|
-
|
|
328
|
-
await this.runCreateUi({
|
|
329
|
-
shouldInstall: true,
|
|
330
|
-
})
|
|
331
|
-
|
|
332
|
-
assert.isEqualDeep(
|
|
333
|
-
callsToExec[0],
|
|
334
|
-
this.installDependenciesCommand,
|
|
335
|
-
'Did not install dependencies!'
|
|
336
|
-
)
|
|
337
|
-
}
|
|
338
|
-
|
|
339
|
-
@test()
|
|
340
|
-
protected static async createUiInstallsDevDependenciesIfMissing() {
|
|
341
|
-
this.setFakeReadToEmptyPackageJson()
|
|
342
|
-
|
|
343
|
-
await this.runCreateUi({
|
|
344
|
-
shouldInstall: true,
|
|
345
|
-
})
|
|
346
|
-
|
|
347
|
-
assert.isEqualDeep(
|
|
348
|
-
callsToExec[1],
|
|
349
|
-
this.installDevDependenciesCommand,
|
|
350
|
-
'Did not install dependencies!'
|
|
351
|
-
)
|
|
352
|
-
}
|
|
353
|
-
|
|
354
|
-
@test()
|
|
355
|
-
protected static async createUiInstallsIfAnyDepIsMissing() {
|
|
356
|
-
for (const dep of this.allRequiredDependencies) {
|
|
357
|
-
this.setFakeReadToAllInstalledExcept(dep)
|
|
358
|
-
resetCallsToExec()
|
|
359
|
-
|
|
360
|
-
await this.runCreateUi({
|
|
361
|
-
shouldInstall: true,
|
|
362
|
-
})
|
|
363
|
-
|
|
364
|
-
assert.isEqual(
|
|
365
|
-
callsToExec[1],
|
|
366
|
-
this.installDevDependenciesCommand,
|
|
367
|
-
'Should not have installed devDependencies!'
|
|
368
|
-
)
|
|
369
|
-
}
|
|
370
|
-
}
|
|
371
|
-
|
|
372
|
-
@test()
|
|
373
|
-
protected static async createUiUpdatesTsconfigIfDepsWereMissing() {
|
|
374
|
-
this.setFakeReadToEmptyPackageJson()
|
|
375
|
-
this.setFakeReadFileResultToTsconfig()
|
|
376
|
-
|
|
377
|
-
await this.runCreateUi({
|
|
378
|
-
shouldInstall: true,
|
|
379
|
-
})
|
|
380
|
-
|
|
381
|
-
assert.isEqualDeep(
|
|
382
|
-
callsToWriteFile[0],
|
|
383
|
-
{
|
|
384
|
-
file: this.tsconfigPath,
|
|
385
|
-
data: this.updatedTsconfigFile,
|
|
386
|
-
options: undefined,
|
|
387
|
-
},
|
|
388
|
-
'Did not update tsconfig!'
|
|
389
|
-
)
|
|
390
|
-
}
|
|
391
|
-
|
|
392
|
-
@test()
|
|
393
|
-
protected static async createUiCreatesSetupTestsIfDepsWereMissing() {
|
|
394
|
-
this.setFakeReadToEmptyPackageJson()
|
|
395
|
-
|
|
396
|
-
await this.runCreateUi({
|
|
397
|
-
shouldInstall: true,
|
|
398
|
-
})
|
|
399
|
-
|
|
400
|
-
assert.isEqualDeep(
|
|
401
|
-
callsToWriteFile[1],
|
|
402
|
-
{
|
|
403
|
-
file: 'src/__tests__/setupTests.ts',
|
|
404
|
-
data: this.setupTestsFile,
|
|
405
|
-
options: undefined,
|
|
406
|
-
},
|
|
407
|
-
'Did not create setupTests script!'
|
|
408
|
-
)
|
|
409
|
-
}
|
|
410
|
-
|
|
411
|
-
@test()
|
|
412
|
-
protected static async createUiAddsSetupTestsToPackageJsonIfDepsWereMissing() {
|
|
413
|
-
this.setFakeReadToEmptyPackageJson()
|
|
414
|
-
|
|
415
|
-
await this.runCreateUi({
|
|
416
|
-
shouldInstall: true,
|
|
417
|
-
})
|
|
418
|
-
|
|
419
|
-
assert.isEqualDeep(
|
|
420
|
-
callsToWriteFile[2],
|
|
421
|
-
{
|
|
422
|
-
file: 'package.json',
|
|
423
|
-
data: JSON.stringify(
|
|
424
|
-
{
|
|
425
|
-
jest: {
|
|
426
|
-
setupFiles: [
|
|
427
|
-
'<rootDir>/build/__tests__/setupTests.js',
|
|
428
|
-
],
|
|
429
|
-
},
|
|
430
|
-
},
|
|
431
|
-
null,
|
|
432
|
-
4
|
|
433
|
-
),
|
|
434
|
-
options: undefined,
|
|
435
|
-
},
|
|
436
|
-
'Did not update package.json!'
|
|
437
|
-
)
|
|
438
|
-
}
|
|
439
|
-
|
|
440
|
-
@test()
|
|
441
|
-
protected static async createUiRecompilesTypescriptIfDepsWereMissing() {
|
|
442
|
-
this.setFakeReadToEmptyPackageJson()
|
|
443
|
-
|
|
444
|
-
await this.runCreateUi({
|
|
445
|
-
shouldInstall: true,
|
|
446
|
-
})
|
|
447
|
-
|
|
448
|
-
assert.isEqualDeep(
|
|
449
|
-
callsToExec[2],
|
|
450
|
-
'npx tsc',
|
|
451
|
-
'Did not recompile typescript!'
|
|
452
|
-
)
|
|
453
|
-
}
|
|
454
|
-
|
|
455
|
-
@test()
|
|
456
|
-
protected static async createUiDoesNotPromptIfDependenciesAreInstalled() {
|
|
457
|
-
this.setFakeReadToAllInstalled()
|
|
458
|
-
|
|
459
|
-
await this.runCreateUi()
|
|
460
|
-
|
|
461
|
-
assert.isEqual(callsToFakePrompts.length, 1, 'Prompted too many times!')
|
|
462
|
-
}
|
|
463
|
-
|
|
464
|
-
@test()
|
|
465
|
-
protected static async createUiPromptsUserForInput() {
|
|
466
|
-
this.setFakeReadToAllInstalled()
|
|
467
|
-
|
|
468
|
-
await this.runCreateUi()
|
|
469
|
-
|
|
470
|
-
assert.isEqualDeep(
|
|
471
|
-
callsToFakePrompts[0],
|
|
472
|
-
[
|
|
473
|
-
{
|
|
474
|
-
type: 'text',
|
|
475
|
-
name: 'componentName',
|
|
476
|
-
message: this.componentNameMessage,
|
|
477
|
-
},
|
|
478
|
-
],
|
|
479
|
-
'Did not prompt user for expected input!'
|
|
480
|
-
)
|
|
481
|
-
}
|
|
482
|
-
|
|
483
|
-
@test()
|
|
484
|
-
protected static async createUiDoesNotContinueIfPromptsIsInterrupted() {
|
|
485
|
-
await this.runCreateUi({
|
|
486
|
-
componentName: '',
|
|
487
|
-
})
|
|
488
|
-
|
|
489
|
-
assert.isEqual(
|
|
490
|
-
FakeAutomodule.numCallsToRun,
|
|
491
|
-
0,
|
|
492
|
-
'Should not have called run on UiAutomodule!'
|
|
493
|
-
)
|
|
494
|
-
}
|
|
495
|
-
|
|
496
|
-
@test()
|
|
497
|
-
protected static async createUiCreatesTestSaveDirIfNotExists() {
|
|
498
|
-
await this.runCreateUi()
|
|
499
|
-
|
|
500
|
-
assert.isEqualDeep(
|
|
501
|
-
callsToMkdir[0],
|
|
502
|
-
{ path: this.uiTestSaveDir, options: { recursive: true } },
|
|
503
|
-
'Did not create test save dir!'
|
|
504
|
-
)
|
|
505
|
-
}
|
|
506
|
-
|
|
507
|
-
@test()
|
|
508
|
-
protected static async createUiCreatesModuleSaveDirIfNotExists() {
|
|
509
|
-
await this.runCreateUi()
|
|
510
|
-
|
|
511
|
-
assert.isEqualDeep(
|
|
512
|
-
callsToMkdir[1],
|
|
513
|
-
{ path: this.uiModuleSaveDir, options: { recursive: true } },
|
|
514
|
-
'Did not create module save dir!'
|
|
515
|
-
)
|
|
516
|
-
}
|
|
517
|
-
|
|
518
|
-
@test()
|
|
519
|
-
protected static async createUiCreatesFakeSaveDirIfNotExists() {
|
|
520
|
-
await this.runCreateUi()
|
|
521
|
-
|
|
522
|
-
assert.isEqualDeep(
|
|
523
|
-
callsToMkdir[2],
|
|
524
|
-
{
|
|
525
|
-
path: this.uiFakeSaveDir,
|
|
526
|
-
options: { recursive: true },
|
|
527
|
-
},
|
|
528
|
-
'Did not create fake save dir!'
|
|
529
|
-
)
|
|
530
|
-
}
|
|
531
|
-
|
|
532
|
-
@test()
|
|
533
|
-
protected static async createUiCreatesUiAutomodule() {
|
|
534
|
-
await this.runCreateUi()
|
|
535
|
-
|
|
536
|
-
assert.isEqualDeep(
|
|
537
|
-
FakeAutomodule.callsToConstructor[0],
|
|
538
|
-
{
|
|
539
|
-
testSaveDir: this.uiTestSaveDir,
|
|
540
|
-
moduleSaveDir: this.uiModuleSaveDir,
|
|
541
|
-
fakeSaveDir: this.uiFakeSaveDir,
|
|
542
|
-
componentName: this.componentName,
|
|
543
|
-
},
|
|
544
|
-
'Did not create UiAutomodule with expected options!'
|
|
545
|
-
)
|
|
546
|
-
}
|
|
547
|
-
|
|
548
|
-
@test()
|
|
549
|
-
protected static async createUiRunsUiAutomodule() {
|
|
550
|
-
await this.runCreateUi()
|
|
551
|
-
|
|
552
|
-
assert.isEqual(
|
|
553
|
-
FakeAutomodule.numCallsToRun,
|
|
554
|
-
1,
|
|
555
|
-
'Did not call run on UiAutomodule!'
|
|
556
|
-
)
|
|
557
|
-
}
|
|
558
|
-
|
|
559
27
|
@test()
|
|
560
28
|
protected static async helpOutputsHelpTextToConsole() {
|
|
561
29
|
const instance = this.CliCommandRunner(['help'])
|
|
@@ -591,379 +59,4 @@ export default class CliCommandRunnerTest extends AbstractPackageTest {
|
|
|
591
59
|
'Help command should not execute any shell commands!'
|
|
592
60
|
)
|
|
593
61
|
}
|
|
594
|
-
|
|
595
|
-
@test()
|
|
596
|
-
protected static async upgradePackageCreatesInstance() {
|
|
597
|
-
const instance = await this.runUpgradePackage()
|
|
598
|
-
|
|
599
|
-
assert.isTruthy(
|
|
600
|
-
instance,
|
|
601
|
-
`Failed to create instance for ${this.upgradePackageCommand}!`
|
|
602
|
-
)
|
|
603
|
-
}
|
|
604
|
-
|
|
605
|
-
@test()
|
|
606
|
-
protected static async upgradePackageCreatesNpmAutopackage() {
|
|
607
|
-
await this.runUpgradePackage()
|
|
608
|
-
|
|
609
|
-
assert.isEqualDeep(
|
|
610
|
-
FakeAutopackage.callsToConstructor[0],
|
|
611
|
-
{
|
|
612
|
-
...this.infoFromPackageJson,
|
|
613
|
-
name: `${this.packageName}`,
|
|
614
|
-
gitNamespace: 'neurodevs',
|
|
615
|
-
npmNamespace: 'neurodevs',
|
|
616
|
-
installDir: this.expandHomeDir('~/dev'),
|
|
617
|
-
license: 'MIT',
|
|
618
|
-
author: 'Eric Yates <hello@ericthecurious.com>',
|
|
619
|
-
},
|
|
620
|
-
'Did not create NpmAutopackage with expected options!'
|
|
621
|
-
)
|
|
622
|
-
}
|
|
623
|
-
|
|
624
|
-
@test()
|
|
625
|
-
protected static async upgradePackageRunsNpmAutopackage() {
|
|
626
|
-
await this.runUpgradePackage()
|
|
627
|
-
|
|
628
|
-
assert.isEqual(
|
|
629
|
-
FakeAutopackage.numCallsToRun,
|
|
630
|
-
1,
|
|
631
|
-
'Did not call run on NpmAutopackage!'
|
|
632
|
-
)
|
|
633
|
-
}
|
|
634
|
-
|
|
635
|
-
@test()
|
|
636
|
-
protected static async upgradePackageAddsDefaultKeywordsIfMissing() {
|
|
637
|
-
await this.runUpgradePackage({
|
|
638
|
-
name: this.packageName,
|
|
639
|
-
description: this.description,
|
|
640
|
-
keywords: [] as string[],
|
|
641
|
-
})
|
|
642
|
-
|
|
643
|
-
assert.isEqualDeep(
|
|
644
|
-
FakeAutopackage.callsToConstructor[0]?.keywords,
|
|
645
|
-
this.defaultKeywords,
|
|
646
|
-
'Did not add default keywords!'
|
|
647
|
-
)
|
|
648
|
-
}
|
|
649
|
-
|
|
650
|
-
@test()
|
|
651
|
-
protected static async upgradePackageDoesNotOverwriteKeywordsEvenIfDefaultsMissing() {
|
|
652
|
-
const keywords = [generateId(), generateId()]
|
|
653
|
-
|
|
654
|
-
await this.runUpgradePackage({
|
|
655
|
-
name: this.packageName,
|
|
656
|
-
description: this.description,
|
|
657
|
-
keywords,
|
|
658
|
-
})
|
|
659
|
-
|
|
660
|
-
assert.isEqualDeep(
|
|
661
|
-
FakeAutopackage.callsToConstructor[0]?.keywords,
|
|
662
|
-
[...this.defaultKeywords, ...keywords],
|
|
663
|
-
'Should not have overwritten keywords!'
|
|
664
|
-
)
|
|
665
|
-
}
|
|
666
|
-
|
|
667
|
-
@test()
|
|
668
|
-
protected static async upgradePackageExtractsPackageNameFromScopedName() {
|
|
669
|
-
await this.runUpgradePackage({
|
|
670
|
-
name: this.packageName,
|
|
671
|
-
description: this.description,
|
|
672
|
-
keywords: this.keywordsWithDefaults,
|
|
673
|
-
})
|
|
674
|
-
|
|
675
|
-
assert.isEqualDeep(
|
|
676
|
-
FakeAutopackage.callsToConstructor[0]?.name,
|
|
677
|
-
this.packageName,
|
|
678
|
-
'Did not extract package name from scoped name!'
|
|
679
|
-
)
|
|
680
|
-
}
|
|
681
|
-
|
|
682
|
-
private static async runCreateUi(
|
|
683
|
-
responses?: Record<string, string | boolean>
|
|
684
|
-
) {
|
|
685
|
-
setFakeResponses({
|
|
686
|
-
componentName: this.componentName,
|
|
687
|
-
...responses,
|
|
688
|
-
})
|
|
689
|
-
|
|
690
|
-
const instance = this.CliCommandRunner([this.createUiCommand])
|
|
691
|
-
await instance.run()
|
|
692
|
-
|
|
693
|
-
return instance
|
|
694
|
-
}
|
|
695
|
-
|
|
696
|
-
private static setFakeReadFileResultToTsconfig() {
|
|
697
|
-
setFakeReadFileResult(this.tsconfigPath, this.originalTsconfigFile)
|
|
698
|
-
}
|
|
699
|
-
|
|
700
|
-
private static setFakeReadToEmptyPackageJson() {
|
|
701
|
-
setFakeReadFileResult('package.json', '{}')
|
|
702
|
-
}
|
|
703
|
-
|
|
704
|
-
private static setFakeReadToAllInstalledExcept(dep: string) {
|
|
705
|
-
setFakeReadFileResult(
|
|
706
|
-
'package.json',
|
|
707
|
-
this.allInstalled.replace(dep, '')
|
|
708
|
-
)
|
|
709
|
-
}
|
|
710
|
-
|
|
711
|
-
private static setFakeReadToAllInstalled() {
|
|
712
|
-
setFakeReadFileResult('package.json', this.allInstalled)
|
|
713
|
-
}
|
|
714
|
-
|
|
715
|
-
private static setFakePackageJson(
|
|
716
|
-
responses?: Record<string, string | string[]>
|
|
717
|
-
) {
|
|
718
|
-
const infoFromPackageJson = {
|
|
719
|
-
...this.infoFromPackageJson,
|
|
720
|
-
...responses,
|
|
721
|
-
}
|
|
722
|
-
|
|
723
|
-
setFakeReadFileResult(
|
|
724
|
-
'package.json',
|
|
725
|
-
JSON.stringify(infoFromPackageJson)
|
|
726
|
-
)
|
|
727
|
-
|
|
728
|
-
return infoFromPackageJson
|
|
729
|
-
}
|
|
730
|
-
|
|
731
|
-
private static readonly infoFromPackageJson = {
|
|
732
|
-
name: this.packageName,
|
|
733
|
-
description: this.description,
|
|
734
|
-
keywords: this.keywordsWithDefaults,
|
|
735
|
-
}
|
|
736
|
-
|
|
737
|
-
private static readonly allInstalled = `
|
|
738
|
-
{
|
|
739
|
-
"dependencies": {
|
|
740
|
-
"react": "^...",
|
|
741
|
-
"react-dom": "^..."
|
|
742
|
-
},
|
|
743
|
-
"devDependencies": {
|
|
744
|
-
"@types/react": "^...",
|
|
745
|
-
"@types/react-dom": "^...",
|
|
746
|
-
"@types/jsdom": "^...",
|
|
747
|
-
"@testing-library/react": "^...",
|
|
748
|
-
"@testing-library/dom": "^...",
|
|
749
|
-
"@testing-library/jest-dom": "^...",
|
|
750
|
-
"jsdom": "^..."
|
|
751
|
-
}
|
|
752
|
-
}
|
|
753
|
-
`
|
|
754
|
-
|
|
755
|
-
private static readonly allRequiredDependencies = [
|
|
756
|
-
'react',
|
|
757
|
-
'react-dom',
|
|
758
|
-
'@types/react',
|
|
759
|
-
'@types/react-dom',
|
|
760
|
-
'@types/jsdom',
|
|
761
|
-
'@testing-library/react',
|
|
762
|
-
'@testing-library/dom',
|
|
763
|
-
'@testing-library/jest-dom',
|
|
764
|
-
'jsdom',
|
|
765
|
-
]
|
|
766
|
-
|
|
767
|
-
private static readonly installDependenciesCommand =
|
|
768
|
-
'yarn add react react-dom'
|
|
769
|
-
|
|
770
|
-
private static readonly installDevDependenciesCommand =
|
|
771
|
-
'yarn add -D @types/react @types/react-dom @types/jsdom @testing-library/react @testing-library/dom @testing-library/jest-dom jsdom'
|
|
772
|
-
|
|
773
|
-
private static async runCreateImpl(responses?: Record<string, string>) {
|
|
774
|
-
setFakeResponses({
|
|
775
|
-
interfaceName: this.interfaceName,
|
|
776
|
-
implName: this.implName,
|
|
777
|
-
...responses,
|
|
778
|
-
})
|
|
779
|
-
|
|
780
|
-
const instance = this.CliCommandRunner([this.createImplCommand])
|
|
781
|
-
await instance.run()
|
|
782
|
-
|
|
783
|
-
return instance
|
|
784
|
-
}
|
|
785
|
-
|
|
786
|
-
private static async runCreatePackage(responses?: Record<string, string>) {
|
|
787
|
-
setFakeResponses({
|
|
788
|
-
packageName: this.packageName,
|
|
789
|
-
description: this.description,
|
|
790
|
-
keywords: this.keywords,
|
|
791
|
-
...responses,
|
|
792
|
-
})
|
|
793
|
-
|
|
794
|
-
const instance = this.CliCommandRunner([this.createPackageCommand])
|
|
795
|
-
await instance.run()
|
|
796
|
-
|
|
797
|
-
return instance
|
|
798
|
-
}
|
|
799
|
-
|
|
800
|
-
private static async runUpgradePackage(
|
|
801
|
-
responses?: Record<string, string | string[]>
|
|
802
|
-
) {
|
|
803
|
-
this.setFakePackageJson(responses)
|
|
804
|
-
|
|
805
|
-
const instance = this.CliCommandRunner([this.upgradePackageCommand])
|
|
806
|
-
await instance.run()
|
|
807
|
-
|
|
808
|
-
return instance
|
|
809
|
-
}
|
|
810
|
-
|
|
811
|
-
private static expandHomeDir(inputPath: string): string {
|
|
812
|
-
return inputPath.startsWith('~')
|
|
813
|
-
? path.join(os.homedir(), inputPath.slice(1))
|
|
814
|
-
: inputPath
|
|
815
|
-
}
|
|
816
|
-
|
|
817
|
-
private static splitOnCommaOrWhitespace(value: string) {
|
|
818
|
-
return value
|
|
819
|
-
.split(/[\s,]+/)
|
|
820
|
-
.map((v: string) => v.trim())
|
|
821
|
-
.filter(Boolean)
|
|
822
|
-
}
|
|
823
|
-
|
|
824
|
-
private static readonly implTestSaveDir = 'src/__tests__/modules'
|
|
825
|
-
private static readonly implModuleSaveDir = 'src/modules'
|
|
826
|
-
|
|
827
|
-
private static get implFakeSaveDir() {
|
|
828
|
-
return `src/testDoubles/${this.interfaceName}`
|
|
829
|
-
}
|
|
830
|
-
|
|
831
|
-
private static readonly uiTestSaveDir = 'src/__tests__/ui'
|
|
832
|
-
private static readonly uiModuleSaveDir = 'src/ui'
|
|
833
|
-
|
|
834
|
-
private static get uiFakeSaveDir() {
|
|
835
|
-
return `src/testDoubles/${this.componentName}`
|
|
836
|
-
}
|
|
837
|
-
|
|
838
|
-
private static readonly tsconfigPath = 'tsconfig.json'
|
|
839
|
-
private static readonly randomId = generateId()
|
|
840
|
-
|
|
841
|
-
private static readonly originalTsconfigFile = JSON.stringify(
|
|
842
|
-
{
|
|
843
|
-
[this.randomId]: this.randomId,
|
|
844
|
-
compilerOptions: {
|
|
845
|
-
[this.randomId]: this.randomId,
|
|
846
|
-
},
|
|
847
|
-
},
|
|
848
|
-
null,
|
|
849
|
-
4
|
|
850
|
-
)
|
|
851
|
-
|
|
852
|
-
private static readonly updatedTsconfigFile = JSON.stringify(
|
|
853
|
-
{
|
|
854
|
-
[this.randomId]: this.randomId,
|
|
855
|
-
compilerOptions: {
|
|
856
|
-
jsx: 'react-jsx',
|
|
857
|
-
[this.randomId]: this.randomId,
|
|
858
|
-
},
|
|
859
|
-
include: ['src'],
|
|
860
|
-
},
|
|
861
|
-
null,
|
|
862
|
-
4
|
|
863
|
-
)
|
|
864
|
-
|
|
865
|
-
private static setFakeImplAutomodule() {
|
|
866
|
-
ImplAutomodule.Class = FakeAutomodule
|
|
867
|
-
FakeAutomodule.resetTestDouble()
|
|
868
|
-
}
|
|
869
|
-
|
|
870
|
-
private static setFakeUiAutomodule() {
|
|
871
|
-
UiAutomodule.Class = FakeAutomodule
|
|
872
|
-
FakeAutomodule.resetTestDouble()
|
|
873
|
-
}
|
|
874
|
-
|
|
875
|
-
private static setFakeAutopackage() {
|
|
876
|
-
NpmAutopackage.Class = FakeAutopackage
|
|
877
|
-
FakeAutopackage.resetTestDouble()
|
|
878
|
-
}
|
|
879
|
-
|
|
880
|
-
private static setFakeExec() {
|
|
881
|
-
CliCommandRunner.exec = fakeExec as unknown as typeof exec
|
|
882
|
-
resetCallsToExec()
|
|
883
|
-
}
|
|
884
|
-
|
|
885
|
-
private static setFakeLog() {
|
|
886
|
-
CliCommandRunner.log = fakeLog as unknown as typeof CliCommandRunner.log
|
|
887
|
-
resetCallsToLog()
|
|
888
|
-
}
|
|
889
|
-
|
|
890
|
-
private static setFakeMkdir() {
|
|
891
|
-
CliCommandRunner.mkdir = fakeMkdir as unknown as typeof mkdir
|
|
892
|
-
resetCallsToMkdir()
|
|
893
|
-
}
|
|
894
|
-
|
|
895
|
-
private static setFakePrompts() {
|
|
896
|
-
CliCommandRunner.prompts = fakePrompts as unknown as typeof prompts
|
|
897
|
-
resetCallsToFakePrompts()
|
|
898
|
-
}
|
|
899
|
-
|
|
900
|
-
private static setFakeReadFile() {
|
|
901
|
-
CliCommandRunner.readFile = fakeReadFile as unknown as typeof readFile
|
|
902
|
-
resetCallsToReadFile()
|
|
903
|
-
|
|
904
|
-
this.setFakeReadToAllInstalled()
|
|
905
|
-
this.setFakeReadFileResultToTsconfig()
|
|
906
|
-
}
|
|
907
|
-
|
|
908
|
-
private static setFakeWriteFile() {
|
|
909
|
-
CliCommandRunner.writeFile =
|
|
910
|
-
fakeWriteFile as unknown as typeof writeFile
|
|
911
|
-
resetCallsToWriteFile()
|
|
912
|
-
}
|
|
913
|
-
|
|
914
|
-
private static readonly interfaceNameMessage =
|
|
915
|
-
'What should the interface be called? Example: YourInterface'
|
|
916
|
-
|
|
917
|
-
private static readonly implNameMessage =
|
|
918
|
-
'What should the implementation class be called? Example: YourInterfaceImpl'
|
|
919
|
-
|
|
920
|
-
private static readonly packageNameMessage =
|
|
921
|
-
'What should the package be called? Example: useful-package'
|
|
922
|
-
|
|
923
|
-
private static readonly packageDescriptionMessage =
|
|
924
|
-
'What should the package description be? Example: A useful package.'
|
|
925
|
-
|
|
926
|
-
private static readonly componentNameMessage =
|
|
927
|
-
'What should the component be called? Example: YourComponent'
|
|
928
|
-
|
|
929
|
-
private static readonly setupTestsFile = `
|
|
930
|
-
import { JSDOM } from 'jsdom'
|
|
931
|
-
|
|
932
|
-
const jsdom = new JSDOM('<!doctype html><html><body></body></html>', {
|
|
933
|
-
url: 'http://localhost',
|
|
934
|
-
})
|
|
935
|
-
|
|
936
|
-
global.window = jsdom.window as unknown as Window & typeof globalThis
|
|
937
|
-
global.document = jsdom.window.document
|
|
938
|
-
global.navigator = jsdom.window.navigator
|
|
939
|
-
global.HTMLElement = jsdom.window.HTMLElement
|
|
940
|
-
global.getComputedStyle = jsdom.window.getComputedStyle
|
|
941
|
-
|
|
942
|
-
global.ResizeObserver = class {
|
|
943
|
-
public observe() {}
|
|
944
|
-
public unobserve() {}
|
|
945
|
-
public disconnect() {}
|
|
946
|
-
}
|
|
947
|
-
|
|
948
|
-
global.SVGElement = jsdom.window.SVGElement
|
|
949
|
-
`
|
|
950
|
-
|
|
951
|
-
private static readonly helpText = `ndx CLI (Command Line Interface)
|
|
952
|
-
|
|
953
|
-
Available commands:
|
|
954
|
-
|
|
955
|
-
- create.impl Create implementation for interface with test and fake.
|
|
956
|
-
- create.package Create npm package using latest template.
|
|
957
|
-
- create.ui Create React component with test and fake.
|
|
958
|
-
- upgrade.package Upgrade existing npm package to latest template.
|
|
959
|
-
- help, --help, -h Show this help text.
|
|
960
|
-
|
|
961
|
-
Usage:
|
|
962
|
-
|
|
963
|
-
- ndx <command> [options]
|
|
964
|
-
`
|
|
965
|
-
|
|
966
|
-
private static CliCommandRunner(args: string[]) {
|
|
967
|
-
return CliCommandRunner.Create(args)
|
|
968
|
-
}
|
|
969
62
|
}
|