@sprucelabs/spruce-cli 19.1.5 → 19.1.6

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 (33) hide show
  1. package/CHANGELOG.md +4 -0
  2. package/build/__tests__/behavioral/tests/CreatingATest.test.d.ts +0 -2
  3. package/build/__tests__/behavioral/tests/CreatingATest.test.js +75 -147
  4. package/build/__tests__/behavioral/tests/CreatingATest.test.js.map +1 -1
  5. package/build/__tests__/behavioral/tests/RunningTests.test.d.ts +3 -0
  6. package/build/__tests__/behavioral/tests/RunningTests.test.js +99 -43
  7. package/build/__tests__/behavioral/tests/RunningTests.test.js.map +1 -1
  8. package/build/__tests__/behavioral/tests/SelectingAnAbstractTestClass.test.js +3 -1
  9. package/build/__tests__/behavioral/tests/SelectingAnAbstractTestClass.test.js.map +1 -1
  10. package/build/__tests__/implementation/TestRunner.test.d.ts +1 -0
  11. package/build/__tests__/implementation/TestRunner.test.js +22 -10
  12. package/build/__tests__/implementation/TestRunner.test.js.map +1 -1
  13. package/build/features/test/actions/CreateAction.js +13 -29
  14. package/build/features/test/actions/CreateAction.js.map +1 -1
  15. package/build/interfaces/SpyInterface.d.ts +6 -1
  16. package/build/interfaces/SpyInterface.js +1 -1
  17. package/build/interfaces/SpyInterface.js.map +1 -1
  18. package/build/tests/utilities/uiAssert.utility.d.ts +1 -0
  19. package/build/tests/utilities/uiAssert.utility.js +9 -0
  20. package/build/tests/utilities/uiAssert.utility.js.map +1 -1
  21. package/node_modules/@typescript-eslint/parser/package.json +5 -5
  22. package/node_modules/@typescript-eslint/scope-manager/package.json +5 -5
  23. package/node_modules/@typescript-eslint/types/package.json +2 -2
  24. package/node_modules/@typescript-eslint/typescript-estree/package.json +4 -4
  25. package/node_modules/@typescript-eslint/visitor-keys/package.json +3 -3
  26. package/package.json +3 -3
  27. package/src/__tests__/behavioral/tests/CreatingATest.test.ts +8 -47
  28. package/src/__tests__/behavioral/tests/RunningTests.test.ts +34 -14
  29. package/src/__tests__/behavioral/tests/SelectingAnAbstractTestClass.test.ts +2 -2
  30. package/src/__tests__/implementation/TestRunner.test.ts +9 -0
  31. package/src/features/test/actions/CreateAction.ts +13 -32
  32. package/src/interfaces/SpyInterface.ts +15 -3
  33. package/src/tests/utilities/uiAssert.utility.ts +9 -0
@@ -3,6 +3,13 @@ import { errorAssert } from '@sprucelabs/test-utils'
3
3
  import AbstractTestTest from '../../../tests/AbstractTestTest'
4
4
 
5
5
  export default class RunningTestsTest extends AbstractTestTest {
6
+ private static hasCreatedTest: any
7
+
8
+ protected static async beforeEach(): Promise<void> {
9
+ await super.beforeEach()
10
+ this.hasCreatedTest = false
11
+ }
12
+
6
13
  @test()
7
14
  protected static async hasTestAction() {
8
15
  await this.Cli()
@@ -12,35 +19,24 @@ export default class RunningTestsTest extends AbstractTestTest {
12
19
  @test()
13
20
  protected static async runningTestsActuallyRunsTests() {
14
21
  await this.installTests()
15
- const creationPromise = this.Action('test', 'create').execute({
16
- type: 'behavioral',
22
+
23
+ const creationResults = await this.createTest({
17
24
  nameReadable: 'Can book appointment',
18
25
  nameCamel: 'canBookAppointment',
19
26
  namePascal: 'CanBookAppointment',
20
27
  })
21
28
 
22
- await this.waitForInput()
23
- await this.ui.sendInput('')
24
-
25
- const creationResults = await creationPromise
26
-
27
29
  const file = creationResults.files?.[0]
28
30
  assert.isTruthy(file)
29
31
 
30
32
  this.fixBadTest(file.path)
31
33
 
32
- const promise = this.Action('test', 'create').execute({
33
- type: 'behavioral',
34
+ await this.createTest({
34
35
  nameReadable: 'Can cancel appointment',
35
36
  nameCamel: 'canCancelAppointment',
36
37
  namePascal: 'CanCancelAppointment',
37
38
  })
38
39
 
39
- await this.waitForInput()
40
- await this.ui.sendInput('')
41
-
42
- await promise
43
-
44
40
  await this.Service('build').build()
45
41
 
46
42
  const results = await this.Action('test', 'test').execute({
@@ -66,4 +62,28 @@ export default class RunningTestsTest extends AbstractTestTest {
66
62
  totalTodo: 0,
67
63
  })
68
64
  }
65
+
66
+ private static async createTest(options: {
67
+ nameReadable: string
68
+ nameCamel: string
69
+ namePascal: string
70
+ }) {
71
+ const creationPromise = this.Action('test', 'create').execute({
72
+ type: 'behavioral',
73
+ ...options,
74
+ })
75
+
76
+ if (this.hasCreatedTest) {
77
+ await this.waitForInput()
78
+ await this.ui.sendInput({ path: '.' })
79
+ }
80
+
81
+ this.hasCreatedTest = true
82
+
83
+ await this.waitForInput()
84
+ await this.ui.sendInput('')
85
+
86
+ const creationResults = await creationPromise
87
+ return creationResults
88
+ }
69
89
  }
@@ -42,14 +42,14 @@ export default class SelectingAnAbstractTestClassTest extends AbstractTestTest {
42
42
  @test()
43
43
  protected static async canSelectAbstractClassWhileSelectingSubDir() {
44
44
  const testDir = this.resolvePath('src', '__tests__', 'behavioral', 'taco')
45
+
45
46
  diskUtil.createDir(testDir)
46
47
 
47
48
  await this.installAndCopyTestFiles()
48
49
 
49
50
  const { promise } = await this.invokeCreateActionAndWaitForInput()
50
51
 
51
- await this.ui.sendInput('taco')
52
-
52
+ await this.ui.sendInput({ path: 'taco' })
53
53
  await this.waitForInput()
54
54
 
55
55
  this.selectOptionBasedOnLabel('AbstractBananaTestDifferentThanFileName')
@@ -8,9 +8,11 @@ import { CliInterface } from '../../types/cli.types'
8
8
 
9
9
  export default class TestRunnerTest extends AbstractTestTest {
10
10
  protected static testRunner: TestRunner
11
+ private static hasCreatedTest: boolean
11
12
 
12
13
  protected static async beforeEach() {
13
14
  await super.beforeEach()
15
+ this.hasCreatedTest = false
14
16
  this.testRunner = new TestRunner({
15
17
  cwd: this.cwd,
16
18
  commandService: this.Service('command'),
@@ -143,6 +145,13 @@ export default class TestRunnerTest extends AbstractTestTest {
143
145
  })
144
146
 
145
147
  await this.waitForInput()
148
+ if (this.hasCreatedTest) {
149
+ await this.ui.sendInput('')
150
+ await this.waitForInput()
151
+ }
152
+
153
+ this.hasCreatedTest = true
154
+
146
155
  await this.ui.sendInput('')
147
156
 
148
157
  const results = await promise
@@ -38,10 +38,7 @@ export default class CreateAction extends AbstractAction<OptionsSchema> {
38
38
  const candidates = await testFeature.buildParentClassCandidates()
39
39
 
40
40
  if (diskUtil.doesDirExist(resolvedDestination)) {
41
- resolvedDestination = await this.promptForSubDir(
42
- resolvedDestination,
43
- type
44
- )
41
+ resolvedDestination = await this.promptForSubDir(resolvedDestination)
45
42
  }
46
43
 
47
44
  if (candidates.length > 0) {
@@ -70,34 +67,18 @@ export default class CreateAction extends AbstractAction<OptionsSchema> {
70
67
  hints: ["run `spruce test` in your skill when you're ready!"],
71
68
  }
72
69
  }
73
- private async promptForSubDir(resolvedDestination: string, type: string) {
74
- const subdirs = diskUtil
75
- .readDir(resolvedDestination)
76
- .filter((d) =>
77
- diskUtil.isDir(diskUtil.resolvePath(resolvedDestination, d))
78
- )
79
-
80
- if (subdirs.length > 0) {
81
- const match = await this.ui.prompt({
82
- type: 'select',
83
- label: 'Where should I write this test?',
84
- isRequired: true,
85
- options: {
86
- choices: [
87
- {
88
- value: '.',
89
- label: `${type}`,
90
- },
91
- ...subdirs.map((dir) => ({
92
- value: `${dir}`,
93
- label: `${type}/${dir}`,
94
- })),
95
- ],
96
- },
97
- })
98
-
99
- resolvedDestination = diskUtil.resolvePath(resolvedDestination, match)
100
- }
70
+ private async promptForSubDir(resolvedDestination: string) {
71
+ const match = await this.ui.prompt({
72
+ type: 'directory',
73
+ label: 'Where should I write this test?',
74
+ isRequired: true,
75
+ defaultValue: {
76
+ path: diskUtil.resolvePath(resolvedDestination),
77
+ },
78
+ })
79
+
80
+ resolvedDestination = diskUtil.resolvePath(resolvedDestination, match.path)
81
+
101
82
  return resolvedDestination
102
83
  }
103
84
 
@@ -91,11 +91,17 @@ export default class SpyInterface implements GraphicsInterface {
91
91
  return this.invocations[this.invocations.length - 1]
92
92
  }
93
93
 
94
- public async sendInput(input: string | string[]): Promise<void> {
94
+ public async sendInput(input: Input): Promise<void> {
95
95
  this.trackInvocation('sendInput', input)
96
96
 
97
97
  this.optionallyRenderLine(
98
- `Sending input: "${input.length > 0 ? input : 'ENTER'}"`
98
+ `Sending input: "${
99
+ (input as FilePromptInput).path
100
+ ? (input as FilePromptInput).path
101
+ : (input as string).length > 0
102
+ ? input
103
+ : 'ENTER'
104
+ }"`
99
105
  )
100
106
 
101
107
  if (this.waitForEnterResolver) {
@@ -114,7 +120,7 @@ export default class SpyInterface implements GraphicsInterface {
114
120
 
115
121
  resolver(
116
122
  input === '\n' ||
117
- input.length === 0 ||
123
+ (input as string).length === 0 ||
118
124
  (typeof input === 'string' && input.toLowerCase() === 'y')
119
125
  )
120
126
  } else {
@@ -360,3 +366,9 @@ export default class SpyInterface implements GraphicsInterface {
360
366
  this.trackInvocation('clearBelowCursor')
361
367
  }
362
368
  }
369
+
370
+ type FilePromptInput = {
371
+ path: string
372
+ }
373
+
374
+ type Input = string | string[] | FilePromptInput
@@ -36,6 +36,15 @@ const uiAssert = {
36
36
  })
37
37
  },
38
38
 
39
+ assertRendersDirectorySelect(ui: SpyInterface, defaultValue: string) {
40
+ const last = ui.getLastInvocation()
41
+
42
+ assert.doesInclude(last.options, {
43
+ type: 'directory',
44
+ defaultValue: { path: defaultValue },
45
+ })
46
+ },
47
+
39
48
  async assertRendersConfirmWriteFile(ui: SpyInterface) {
40
49
  await ui.waitForInput()
41
50