@sprucelabs/spruce-cli 19.1.4 → 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.
- package/CHANGELOG.md +8 -0
- package/build/__tests__/behavioral/schemas/SettingUpSchemasForModuleDistribution.test.js +1 -2
- package/build/__tests__/behavioral/schemas/SettingUpSchemasForModuleDistribution.test.js.map +1 -1
- package/build/__tests__/behavioral/tests/CreatingATest.test.d.ts +0 -2
- package/build/__tests__/behavioral/tests/CreatingATest.test.js +75 -147
- package/build/__tests__/behavioral/tests/CreatingATest.test.js.map +1 -1
- package/build/__tests__/behavioral/tests/RunningTests.test.d.ts +3 -0
- package/build/__tests__/behavioral/tests/RunningTests.test.js +99 -43
- package/build/__tests__/behavioral/tests/RunningTests.test.js.map +1 -1
- package/build/__tests__/behavioral/tests/SelectingAnAbstractTestClass.test.js +3 -1
- package/build/__tests__/behavioral/tests/SelectingAnAbstractTestClass.test.js.map +1 -1
- package/build/__tests__/implementation/TestRunner.test.d.ts +1 -0
- package/build/__tests__/implementation/TestRunner.test.js +22 -10
- package/build/__tests__/implementation/TestRunner.test.js.map +1 -1
- package/build/features/test/actions/CreateAction.js +13 -29
- package/build/features/test/actions/CreateAction.js.map +1 -1
- package/build/features/vscode/VsCodeFeature.js +1 -1
- package/build/features/vscode/VsCodeFeature.js.map +1 -1
- package/build/interfaces/SpyInterface.d.ts +6 -1
- package/build/interfaces/SpyInterface.js +1 -1
- package/build/interfaces/SpyInterface.js.map +1 -1
- package/build/interfaces/TerminalInterface.js +3 -1
- package/build/interfaces/TerminalInterface.js.map +1 -1
- package/build/tests/utilities/uiAssert.utility.d.ts +1 -0
- package/build/tests/utilities/uiAssert.utility.js +9 -0
- package/build/tests/utilities/uiAssert.utility.js.map +1 -1
- package/build/widgets/types/window.types.js +2 -0
- package/build/widgets/types/window.types.js.map +1 -1
- package/node_modules/@typescript-eslint/parser/dist/parser.d.ts.map +1 -1
- package/node_modules/@typescript-eslint/parser/dist/parser.js +5 -1
- package/node_modules/@typescript-eslint/parser/dist/parser.js.map +1 -1
- package/node_modules/@typescript-eslint/parser/package.json +5 -5
- package/node_modules/@typescript-eslint/scope-manager/package.json +5 -5
- package/node_modules/@typescript-eslint/types/package.json +2 -2
- package/node_modules/@typescript-eslint/typescript-estree/package.json +4 -4
- package/node_modules/@typescript-eslint/visitor-keys/package.json +3 -3
- package/package.json +30 -30
- package/src/__tests__/behavioral/tests/CreatingATest.test.ts +8 -47
- package/src/__tests__/behavioral/tests/RunningTests.test.ts +34 -14
- package/src/__tests__/behavioral/tests/SelectingAnAbstractTestClass.test.ts +2 -2
- package/src/__tests__/implementation/TestRunner.test.ts +9 -0
- package/src/features/test/actions/CreateAction.ts +13 -32
- package/src/interfaces/SpyInterface.ts +15 -3
- package/src/tests/utilities/uiAssert.utility.ts +9 -0
|
@@ -59,33 +59,12 @@ export default class CreatingBehavioralTestsTest extends AbstractTestTest {
|
|
|
59
59
|
testType
|
|
60
60
|
)
|
|
61
61
|
|
|
62
|
-
uiAssert.
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
await this.waitAndSelectSubClass()
|
|
67
|
-
|
|
68
|
-
await promise
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
@test()
|
|
72
|
-
protected static async listsManyDirsIfExistInsideTestDir() {
|
|
73
|
-
await this.installTests()
|
|
74
|
-
|
|
75
|
-
const dirs = ['dir1', 'dir2', 'dir3']
|
|
76
|
-
|
|
77
|
-
for (const dir of dirs) {
|
|
78
|
-
this.createTestSubDir('behavioral', dir)
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
const { promise } = await this.installAndStartTestActionAndWaitForInput()
|
|
82
|
-
|
|
83
|
-
for (const dir of dirs) {
|
|
84
|
-
uiAssert.assertSelectRenderChoice(this.ui, `${dir}`, `behavioral/${dir}`)
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
await this.ui.sendInput('.')
|
|
62
|
+
uiAssert.assertRendersDirectorySelect(
|
|
63
|
+
this.ui,
|
|
64
|
+
this.resolvePath('src', '__tests__', testType)
|
|
65
|
+
)
|
|
88
66
|
|
|
67
|
+
await this.ui.sendInput('')
|
|
89
68
|
await this.waitAndSelectSubClass()
|
|
90
69
|
|
|
91
70
|
await promise
|
|
@@ -95,13 +74,13 @@ export default class CreatingBehavioralTestsTest extends AbstractTestTest {
|
|
|
95
74
|
@test('can select sub dir 2', 'test-2')
|
|
96
75
|
protected static async selectingAnOptionRendersToSubDir(dirName: string) {
|
|
97
76
|
await this.installTests()
|
|
98
|
-
this.createTestSubDir('behavioral', dirName)
|
|
77
|
+
const dir = this.createTestSubDir('behavioral', dirName)
|
|
99
78
|
|
|
100
79
|
const { promise } = await this.installAndStartTestActionAndWaitForInput(
|
|
101
80
|
'behavioral'
|
|
102
81
|
)
|
|
103
82
|
|
|
104
|
-
await this.ui.sendInput(
|
|
83
|
+
await this.ui.sendInput({ path: dir })
|
|
105
84
|
|
|
106
85
|
await this.waitAndSelectSubClass()
|
|
107
86
|
|
|
@@ -118,25 +97,6 @@ export default class CreatingBehavioralTestsTest extends AbstractTestTest {
|
|
|
118
97
|
assert.isEqual(expectedPath, results.files?.[0]?.path)
|
|
119
98
|
}
|
|
120
99
|
|
|
121
|
-
@test()
|
|
122
|
-
protected static async doesNotListFiles() {
|
|
123
|
-
await this.installTests()
|
|
124
|
-
this.createTestSubDir('behavioral', 'subdir')
|
|
125
|
-
|
|
126
|
-
const file = this.resolveTestDir('behavioral', 'test.ts')
|
|
127
|
-
diskUtil.writeFile(file, 'what the!?')
|
|
128
|
-
|
|
129
|
-
await this.installAndStartTestActionAndWaitForInput()
|
|
130
|
-
|
|
131
|
-
uiAssert.assertSelectDidNotRenderChoice(
|
|
132
|
-
this.ui,
|
|
133
|
-
'test',
|
|
134
|
-
`behavioral/test/test.ts`
|
|
135
|
-
)
|
|
136
|
-
|
|
137
|
-
this.ui.reset()
|
|
138
|
-
}
|
|
139
|
-
|
|
140
100
|
@test()
|
|
141
101
|
protected static async allTestsComeFakedToStart() {
|
|
142
102
|
const testFile = await this.createTestAndGetFile()
|
|
@@ -147,6 +107,7 @@ export default class CreatingBehavioralTestsTest extends AbstractTestTest {
|
|
|
147
107
|
private static createTestSubDir(...testDirs: string[]) {
|
|
148
108
|
const newDir = this.resolveTestDir(...testDirs)
|
|
149
109
|
diskUtil.createDir(newDir)
|
|
110
|
+
return newDir
|
|
150
111
|
}
|
|
151
112
|
|
|
152
113
|
private static resolveTestDir(...testDirs: string[]) {
|
|
@@ -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
|
-
|
|
16
|
-
|
|
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
|
-
|
|
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
|
|
74
|
-
const
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
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:
|
|
94
|
+
public async sendInput(input: Input): Promise<void> {
|
|
95
95
|
this.trackInvocation('sendInput', input)
|
|
96
96
|
|
|
97
97
|
this.optionallyRenderLine(
|
|
98
|
-
`Sending input: "${
|
|
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
|
|