@neurodevs/meta-node 0.1.0 → 0.3.0

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.
Files changed (29) hide show
  1. package/.vscode/tasks.json +18 -0
  2. package/build/__tests__/modules/NpmAutopackage.test.d.ts +47 -12
  3. package/build/__tests__/modules/NpmAutopackage.test.js +316 -34
  4. package/build/__tests__/modules/NpmAutopackage.test.js.map +1 -1
  5. package/build/index.d.ts +6 -2
  6. package/build/index.js +11 -5
  7. package/build/index.js.map +1 -1
  8. package/build/modules/NpmAutopackage.d.ts +52 -19
  9. package/build/modules/NpmAutopackage.js +223 -45
  10. package/build/modules/NpmAutopackage.js.map +1 -1
  11. package/build/scripts/runAutopackage.js +4 -2
  12. package/build/scripts/runAutopackage.js.map +1 -1
  13. package/build/testDoubles/Autopackage/FakeAutopackage.d.ts +8 -0
  14. package/build/testDoubles/Autopackage/FakeAutopackage.js +18 -0
  15. package/build/testDoubles/Autopackage/FakeAutopackage.js.map +1 -0
  16. package/package.json +5 -1
  17. package/src/__tests__/modules/NpmAutopackage.test.ts +417 -33
  18. package/src/index.ts +9 -3
  19. package/src/modules/NpmAutopackage.ts +277 -48
  20. package/src/scripts/runAutopackage.ts +4 -2
  21. package/src/testDoubles/Autopackage/FakeAutopackage.ts +19 -0
  22. package/build/__tests__/modules/PackageJsonUpdater.test.d.ts +0 -7
  23. package/build/__tests__/modules/PackageJsonUpdater.test.js +0 -63
  24. package/build/__tests__/modules/PackageJsonUpdater.test.js.map +0 -1
  25. package/build/modules/PackageJsonUpdater.d.ts +0 -8
  26. package/build/modules/PackageJsonUpdater.js +0 -10
  27. package/build/modules/PackageJsonUpdater.js.map +0 -1
  28. package/src/__tests__/modules/PackageJsonUpdater.test.ts +0 -23
  29. package/src/modules/PackageJsonUpdater.ts +0 -13
@@ -11,80 +11,378 @@ import NpmAutopackage, {
11
11
  export default class NpmAutopackageTest extends AbstractSpruceTest {
12
12
  private static instance: Autopackage
13
13
 
14
+ private static callsToChdir: string[] = []
15
+ private static callsToExecSync: string[] = []
16
+ private static callsToExistsSync: string[] = []
17
+ private static callsToFetch: { url: string; init: RequestInit }[] = []
18
+ private static callsToReadFileSync: { path: string; options: any }[] = []
19
+ private static callsToWriteFileSync: {
20
+ path: string
21
+ data: any
22
+ options: any
23
+ }[] = []
24
+
14
25
  protected static async beforeEach() {
15
26
  await super.beforeEach()
16
27
 
17
- this.fakeExecToPreventActual()
18
- this.fakeChdirToPreventActual()
28
+ this.fakeChdir()
29
+ this.fakeExecSync()
30
+ this.fakeExistsSync()
31
+ this.fakeFetch()
32
+ this.fakeReadFileSync()
33
+ this.fakeWriteFileSync()
34
+
35
+ process.env.GITHUB_TOKEN = this.githubToken
19
36
 
20
37
  this.instance = await this.NpmAutopackage()
38
+ await this.instance.run()
39
+ }
40
+
41
+ @test()
42
+ protected static async createsInstance() {
43
+ assert.isTruthy(this.instance, 'Failed to create instance!')
44
+ }
45
+
46
+ @test()
47
+ protected static async throwsIfGithubTokenNotSet() {
48
+ delete process.env.GITHUB_TOKEN
49
+
50
+ await assert.doesThrowAsync(
51
+ async () => {
52
+ const instance = await this.NpmAutopackage()
53
+ await instance.run()
54
+ },
55
+ 'Please set process.env.GITHUB_TOKEN!',
56
+ 'Did not throw with missing process.env.GITHUB_TOKEN!'
57
+ )
21
58
  }
22
59
 
23
60
  @test()
24
- protected static async createsNpmAutopackageInstance() {
25
- assert.isTruthy(this.instance, 'Should create an instance!')
61
+ protected static async firstCreateRepoInGithubOrg() {
62
+ assert.isEqualDeep(
63
+ {
64
+ passedUrl: this.callsToFetch[0]?.url,
65
+ passedInit: this.callsToFetch[0]?.init,
66
+ },
67
+ {
68
+ passedUrl: `https://api.github.com/orgs/${this.gitNamespace}/repos`,
69
+ passedInit: {
70
+ method: 'POST',
71
+ headers: {
72
+ Authorization: `token ${this.githubToken}`,
73
+ Accept: 'application/vnd.github+json',
74
+ 'Content-Type': 'application/json',
75
+ },
76
+ body: JSON.stringify({
77
+ name: this.packageName,
78
+ private: false,
79
+ description: this.packageDescription,
80
+ auto_init: true,
81
+ gitignore_template: 'Node',
82
+ license_template: 'mit',
83
+ }),
84
+ },
85
+ },
86
+ 'Did not call fetch as expected!'
87
+ )
26
88
  }
27
89
 
28
90
  @test()
29
- protected static async firstCallsChdirToInstallDir() {
91
+ protected static async secondChdirToInstallDir() {
30
92
  assert.isEqual(
31
93
  this.callsToChdir[0],
32
94
  this.installDir,
33
- 'Should have changed dir!'
95
+ 'Did not change to installDir!'
34
96
  )
35
97
  }
36
98
 
37
99
  @test()
38
- protected static async thenCallsSpruceCreateModule() {
100
+ protected static async thirdGitClone() {
39
101
  assert.isEqual(
40
102
  this.callsToExecSync[0],
103
+ `git clone https://github.com/${this.gitNamespace}/${this.packageName}.git`,
104
+ 'Did not call git clone!'
105
+ )
106
+ }
107
+
108
+ @test()
109
+ protected static async fourthSpruceCreateModule() {
110
+ assert.isEqual(
111
+ this.callsToExecSync[1],
41
112
  this.createModuleCmd,
42
- 'Should have called "spruce create.module"!'
113
+ 'Did not call "spruce create.module"!'
43
114
  )
44
115
  }
45
116
 
46
117
  @test()
47
- protected static async thenCallsChdirToNewlyCreatedDir() {
118
+ protected static async fifthCommitCreatePackage() {
119
+ assert.isEqualDeep(
120
+ this.callsToExecSync.slice(2, 5),
121
+ ['git add .', 'git commit -m "patch: create package"', 'git push'],
122
+ 'Did not commit create package changes!'
123
+ )
124
+ }
125
+
126
+ @test()
127
+ protected static async sixthChdirToPackageDir() {
48
128
  assert.isEqual(
49
129
  this.callsToChdir[1],
50
- `${this.installDir}/${this.packageName}`,
51
- 'Should have changed dir!'
130
+ this.packageDir,
131
+ 'Did not change to packageDir!'
52
132
  )
53
133
  }
54
134
 
55
135
  @test()
56
- protected static async thenSetsUpNewGitRepo() {
136
+ protected static async seventhReadPackageJson() {
137
+ assert.isEqualDeep(this.callsToReadFileSync[0], {
138
+ path: this.packageJsonPath,
139
+ options: { encoding: 'utf-8' },
140
+ })
141
+ }
142
+
143
+ @test()
144
+ protected static async eighthUpdatePackageJson() {
145
+ const actual = this.callsToWriteFileSync[0]
146
+
147
+ const expected = {
148
+ path: this.packageJsonPath,
149
+ data: this.orderJsonKeys(JSON.parse(this.updatedPackageJson), [
150
+ 'name',
151
+ 'version',
152
+ 'description',
153
+ 'keywords',
154
+ 'license',
155
+ 'author',
156
+ 'homepage',
157
+ 'repository',
158
+ 'bugs',
159
+ 'main',
160
+ 'scripts',
161
+ 'dependencies',
162
+ 'devDependencies',
163
+ 'jest',
164
+ 'skill',
165
+ ]),
166
+ options: { encoding: 'utf-8' },
167
+ }
168
+
169
+ const normalize = (s: string) => s.replace(/\s+/g, '').trim()
170
+
57
171
  assert.isEqualDeep(
58
- this.callsToExecSync.slice(1, 5),
172
+ {
173
+ ...actual,
174
+ data: normalize(actual.data),
175
+ },
176
+ {
177
+ ...expected,
178
+ data: normalize(expected.data),
179
+ },
180
+ 'Did not update package.json as expected!'
181
+ )
182
+ }
183
+
184
+ @test()
185
+ protected static async ninthCommitUpdatePackage() {
186
+ assert.isEqualDeep(
187
+ this.callsToExecSync.slice(5, 8),
188
+ ['git add .', 'git commit -m "patch: update package"', 'git push'],
189
+ 'Did not commit update package changes!'
190
+ )
191
+ }
192
+
193
+ @test()
194
+ protected static async tenthAddBuildDirToGitignore() {
195
+ const actual = this.callsToWriteFileSync[1]
196
+
197
+ const expected = {
198
+ path: this.gitignorePath,
199
+ data: '\nbuild/\n',
200
+ options: { encoding: 'utf-8', flag: 'a' },
201
+ }
202
+
203
+ assert.isEqualDeep(
204
+ actual,
205
+ expected,
206
+ 'Did not update .gitignore as expected!'
207
+ )
208
+ }
209
+
210
+ @test()
211
+ protected static async eleventhCommitUpdateGitignore() {
212
+ assert.isEqualDeep(
213
+ this.callsToExecSync.slice(8, 11),
59
214
  [
60
- 'git init',
61
215
  'git add .',
62
- 'git commit -m "patch: create module"',
63
- `git remote add origin "https://github.com/${this.gitNamespace}/${this.packageName}.git"`,
216
+ 'git commit -m "patch: add build dir to gitignore"',
217
+ 'git push',
64
218
  ],
65
- 'Should have called "git init"!'
219
+ 'Did not commit .gitignore changes!'
66
220
  )
67
221
  }
68
222
 
69
223
  @test()
70
- protected static async thenCallsSpruceSetupVscode() {
224
+ protected static async twelfthSpruceSetupVscode() {
71
225
  assert.isEqual(
72
- this.callsToExecSync[5],
73
- 'spruce setup.vscode --all true',
74
- 'Should have called "spruce setup.vscode"!'
226
+ this.callsToExecSync[11],
227
+ NpmAutopackageTest.setupVscodeCmd,
228
+ 'Did not call "spruce setup.vscode"!'
75
229
  )
76
230
  }
77
231
 
78
232
  @test()
79
- protected static async thenGitCommitsVscodeChanges() {
233
+ protected static async lastlyCommitVscodeChanges() {
80
234
  assert.isEqualDeep(
81
- this.callsToExecSync.slice(6, 8),
82
- ['git add .', 'git commit -m "patch: setup vscode"'],
83
- 'Should have committed vscode changes!'
235
+ this.callsToExecSync.slice(12, 15),
236
+ ['git add .', 'git commit -m "patch: setup vscode"', 'git push'],
237
+ 'Did not commit vscode changes!'
238
+ )
239
+ }
240
+
241
+ @test()
242
+ protected static async doesNotCloneRepoIfDone() {
243
+ await this.NpmAutopackage()
244
+
245
+ assert.isEqual(
246
+ this.callsToExecSync.filter(
247
+ (cmd) =>
248
+ cmd ===
249
+ `git clone https://github.com/${this.gitNamespace}/${this.packageName}.git`
250
+ ).length,
251
+ 1,
252
+ 'Did not clone repo once!'
253
+ )
254
+ }
255
+
256
+ @test()
257
+ protected static async doesNotSpruceCreateModuleIfDone() {
258
+ await this.NpmAutopackage()
259
+
260
+ assert.isEqual(
261
+ this.callsToExecSync.filter((cmd) => cmd === this.createModuleCmd)
262
+ .length,
263
+ 1,
264
+ 'Did not call spruce create.module once!'
265
+ )
266
+ }
267
+
268
+ @test()
269
+ protected static async doesNotRunSetupVscodeIfDone() {
270
+ await this.NpmAutopackage()
271
+
272
+ assert.isEqual(
273
+ this.callsToExecSync.filter((cmd) => cmd === this.setupVscodeCmd)
274
+ .length,
275
+ 1,
276
+ 'Did not call spruce setup.vscode once!'
277
+ )
278
+ }
279
+
280
+ @test()
281
+ protected static async doesNotCommitCreatePackageIfDone() {
282
+ await this.NpmAutopackage()
283
+
284
+ assert.isEqual(
285
+ this.callsToExecSync.filter(
286
+ (cmd) => cmd === 'git commit -m "patch: create package"'
287
+ ).length,
288
+ 1,
289
+ 'Did not commit create package changes once!'
290
+ )
291
+ }
292
+
293
+ @test()
294
+ protected static async doesNotCommitUpdatePackageIfDone() {
295
+ await this.NpmAutopackage()
296
+
297
+ assert.isEqual(
298
+ this.callsToExecSync.filter(
299
+ (cmd) => cmd === 'git commit -m "patch: update package"'
300
+ ).length,
301
+ 1,
302
+ 'Did not commit update package changes once!'
84
303
  )
85
304
  }
86
305
 
87
- private static fakeExecToPreventActual() {
306
+ @test()
307
+ protected static async doesNotCommitUpdateGitignoreIfDone() {
308
+ await this.NpmAutopackage()
309
+
310
+ assert.isEqual(
311
+ this.callsToExecSync.filter(
312
+ (cmd) =>
313
+ cmd === 'git commit -m "patch: add build dir to gitignore"'
314
+ ).length,
315
+ 1,
316
+ 'Did not commit gitignore changes once!'
317
+ )
318
+ }
319
+
320
+ @test()
321
+ protected static async doesNotCommitVscodeIfDone() {
322
+ await this.NpmAutopackage()
323
+
324
+ assert.isEqual(
325
+ this.callsToExecSync.filter(
326
+ (cmd) => cmd === 'git commit -m "patch: setup vscode"'
327
+ ).length,
328
+ 1,
329
+ 'Did not commit vscode changes once!'
330
+ )
331
+ }
332
+
333
+ private static get scopedPackage() {
334
+ return `${this.gitNamespace}/${this.packageName}`
335
+ }
336
+
337
+ private static get packageDir() {
338
+ return `${this.installDir}/${this.packageName}`
339
+ }
340
+
341
+ private static get packageJsonPath() {
342
+ return `${this.packageDir}/package.json`
343
+ }
344
+
345
+ private static get gitignorePath() {
346
+ return `${this.packageDir}/.gitignore`
347
+ }
348
+
349
+ private static get createModuleCmd() {
350
+ return `spruce create.module --name "${this.packageName}" --destination "${this.packageDir}" --description "${this.packageDescription}"`
351
+ }
352
+
353
+ private static readonly setupVscodeCmd = 'spruce setup.vscode --all true'
354
+
355
+ private static orderJsonKeys(
356
+ json: Record<string, unknown>,
357
+ keyOrder: string[]
358
+ ) {
359
+ const ordered: Record<string, any> = {}
360
+
361
+ for (const key of keyOrder) {
362
+ if (key in json) {
363
+ ordered[key] = json[key]
364
+ }
365
+ }
366
+
367
+ const remainingKeys = Object.keys(json)
368
+ .filter((k) => !keyOrder.includes(k))
369
+ .sort()
370
+
371
+ for (const key of remainingKeys) {
372
+ ordered[key] = json[key]
373
+ }
374
+
375
+ return JSON.stringify(ordered)
376
+ }
377
+
378
+ private static fakeChdir() {
379
+ NpmAutopackage.chdir = (dir: string) => {
380
+ this.callsToChdir.push(dir)
381
+ }
382
+ this.callsToChdir = []
383
+ }
384
+
385
+ private static fakeExecSync() {
88
386
  // @ts-ignore
89
387
  NpmAutopackage.execSync = (cmd: string) => {
90
388
  this.callsToExecSync.push(cmd)
@@ -92,23 +390,106 @@ export default class NpmAutopackageTest extends AbstractSpruceTest {
92
390
  this.callsToExecSync = []
93
391
  }
94
392
 
95
- private static fakeChdirToPreventActual() {
96
- NpmAutopackage.chdir = (dir: string) => {
97
- this.callsToChdir.push(dir)
393
+ private static fakeExistsSync() {
394
+ // @ts-ignore
395
+ NpmAutopackage.existsSync = (path: string) => {
396
+ if (this.callsToExistsSync.includes(path)) {
397
+ this.callsToExistsSync.push(path)
398
+ return true
399
+ } else {
400
+ this.callsToExistsSync.push(path)
401
+ return false
402
+ }
98
403
  }
99
- this.callsToChdir = []
404
+ this.callsToExistsSync = []
100
405
  }
101
406
 
102
- private static callsToExecSync: string[] = []
103
- private static callsToChdir: string[] = []
407
+ private static fakeFetch() {
408
+ // @ts-ignore
409
+ NpmAutopackage.fetch = async (url: string, init: RequestInit) => {
410
+ this.callsToFetch.push({ url, init })
411
+ }
412
+ this.callsToFetch = []
413
+ }
414
+
415
+ private static fakeReadFileSync() {
416
+ // @ts-ignore
417
+ NpmAutopackage.readFileSync = (path: string, options: any) => {
418
+ this.callsToReadFileSync.push({ path, options })
419
+
420
+ if (path === this.packageJsonPath) {
421
+ if (
422
+ this.callsToReadFileSync.filter(
423
+ ({ path }) => path === this.packageJsonPath
424
+ ).length > 1
425
+ ) {
426
+ return this.updatedPackageJson
427
+ }
428
+ return this.oldPackageJson
429
+ } else if (path === this.gitignorePath) {
430
+ if (
431
+ this.callsToReadFileSync.filter(
432
+ ({ path }) => path === this.gitignorePath
433
+ ).length > 1
434
+ ) {
435
+ return 'node_modules/\n\nbuild/\n'
436
+ }
437
+ return 'node_modules/\n'
438
+ }
439
+ return ''
440
+ }
441
+ this.callsToReadFileSync = []
442
+ }
443
+
444
+ private static get oldPackageJson() {
445
+ return JSON.stringify({
446
+ name: this.packageName,
447
+ description: 'Old description',
448
+ })
449
+ }
450
+
451
+ private static get updatedPackageJson() {
452
+ return JSON.stringify({
453
+ ...JSON.parse(this.oldPackageJson),
454
+ name: `@${this.scopedPackage}`,
455
+ keywords: this.keywords,
456
+ license: this.license,
457
+ author: this.author,
458
+ main: 'build/index.js',
459
+ homepage: `https://github.com/${this.scopedPackage}`,
460
+ repository: {
461
+ type: 'git',
462
+ url: `git+https://github.com/${this.scopedPackage}.git`,
463
+ },
464
+ bugs: {
465
+ url: `https://github.com/${this.scopedPackage}/issues`,
466
+ },
467
+ dependencies: {},
468
+ })
469
+ }
470
+
471
+ private static fakeWriteFileSync() {
472
+ // @ts-ignore
473
+ NpmAutopackage.writeFileSync = (
474
+ path: string,
475
+ data: any,
476
+ options: any
477
+ ) => {
478
+ this.callsToWriteFileSync.push({ path, data, options })
479
+ }
480
+ this.callsToWriteFileSync = []
481
+ }
104
482
 
105
483
  private static readonly packageName = generateId()
106
484
  private static readonly packageDescription = generateId()
107
485
  private static readonly gitNamespace = generateId()
108
486
  private static readonly npmNamespace = generateId()
109
487
  private static readonly installDir = generateId()
488
+ private static readonly keywords = [generateId(), generateId()]
489
+ private static readonly license = generateId()
490
+ private static readonly author = generateId()
110
491
 
111
- private static readonly createModuleCmd = `spruce create.module --name "${this.packageName}" --destination "${this.installDir}/${this.packageName}" --description "${this.packageDescription}"`
492
+ private static readonly githubToken = generateId()
112
493
 
113
494
  private static readonly defaultOptions = {
114
495
  name: this.packageName,
@@ -116,6 +497,9 @@ export default class NpmAutopackageTest extends AbstractSpruceTest {
116
497
  gitNamespace: this.gitNamespace,
117
498
  npmNamespace: this.npmNamespace,
118
499
  installDir: this.installDir,
500
+ keywords: this.keywords,
501
+ license: this.license,
502
+ author: this.author,
119
503
  }
120
504
 
121
505
  private static NpmAutopackage(options?: Partial<AutopackageOptions>) {
package/src/index.ts CHANGED
@@ -19,7 +19,13 @@ export * from './testDoubles/Automodule/FakeAutomodule'
19
19
  export { default as NpmAutopackage } from './modules/NpmAutopackage'
20
20
  export * from './modules/NpmAutopackage'
21
21
 
22
- // PackageJsonUpdater
22
+ export { default as FakeAutopackage } from './testDoubles/Autopackage/FakeAutopackage'
23
+ export * from './testDoubles/Autopackage/FakeAutopackage'
23
24
 
24
- export { default as PackageJsonUpdater } from './modules/PackageJsonUpdater'
25
- export * from './modules/PackageJsonUpdater'
25
+ // fs
26
+
27
+ export { default as fakePathExists } from './testDoubles/fs/fakePathExists'
28
+ export * from './testDoubles/fs/fakePathExists'
29
+
30
+ export { default as fakeWriteFile } from './testDoubles/fs/fakeWriteFile'
31
+ export * from './testDoubles/fs/fakeWriteFile'