@tanstack/cta-cli 0.10.0-alpha.19 → 0.10.0-alpha.21

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.
@@ -0,0 +1,97 @@
1
+ import { describe, it, expect, vi } from 'vitest'
2
+
3
+ import * as clack from '@clack/prompts'
4
+
5
+ import { createUIEnvironment } from '../src/ui-environment.js'
6
+
7
+ vi.mock('@clack/prompts')
8
+
9
+ // @ts-expect-error
10
+ vi.spyOn(process, 'exit').mockImplementation(() => {})
11
+
12
+ describe('createUIEnvironment', () => {
13
+ it('should create a silent UI environment', () => {
14
+ const environment = createUIEnvironment('test', true)
15
+ expect(environment.appName).toBe('test')
16
+ })
17
+
18
+ it('should handle intro', () => {
19
+ const environment = createUIEnvironment('test', false)
20
+ const spy = vi
21
+ .spyOn(clack, 'intro')
22
+ .mockImplementation(async () => undefined)
23
+ environment.intro('test')
24
+ expect(spy).toHaveBeenCalledWith('test')
25
+ })
26
+
27
+ it('should handle outro', () => {
28
+ const environment = createUIEnvironment('test', false)
29
+ const spy = vi
30
+ .spyOn(clack, 'outro')
31
+ .mockImplementation(async () => undefined)
32
+ environment.outro('test')
33
+ expect(spy).toHaveBeenCalledWith('test')
34
+ })
35
+
36
+ it('should handle info', () => {
37
+ const environment = createUIEnvironment('test', false)
38
+ const spy = vi
39
+ .spyOn(clack.log, 'info')
40
+ .mockImplementation(async () => undefined)
41
+ environment.info('test')
42
+ expect(spy).toHaveBeenCalled()
43
+ })
44
+
45
+ it('should handle error', () => {
46
+ const environment = createUIEnvironment('test', false)
47
+ const spy = vi
48
+ .spyOn(clack.log, 'error')
49
+ .mockImplementation(async () => undefined)
50
+ environment.error('test')
51
+ expect(spy).toHaveBeenCalled()
52
+ })
53
+
54
+ it('should handle warn', () => {
55
+ const environment = createUIEnvironment('test', false)
56
+ const spy = vi
57
+ .spyOn(clack.log, 'warn')
58
+ .mockImplementation(async () => undefined)
59
+ environment.warn('test')
60
+ expect(spy).toHaveBeenCalled()
61
+ })
62
+
63
+ it('should handle confirm', async () => {
64
+ const environment = createUIEnvironment('test', false)
65
+ const spy = vi.spyOn(clack, 'confirm').mockImplementation(async () => true)
66
+ const isCancelSpy = vi
67
+ .spyOn(clack, 'isCancel')
68
+ .mockImplementation(() => false)
69
+ const result = await environment.confirm('test')
70
+ expect(spy).toHaveBeenCalled()
71
+ expect(isCancelSpy).toHaveBeenCalled()
72
+ expect(result).toBe(true)
73
+ })
74
+
75
+ it('should handle confirm', async () => {
76
+ const environment = createUIEnvironment('test', false)
77
+ const spy = vi.spyOn(clack, 'confirm').mockImplementation(async () => true)
78
+ const isCancelSpy = vi
79
+ .spyOn(clack, 'isCancel')
80
+ .mockImplementation(() => true)
81
+ await environment.confirm('test')
82
+ expect(spy).toHaveBeenCalled()
83
+ expect(isCancelSpy).toHaveBeenCalled()
84
+ })
85
+
86
+ it('should handle spinner', async () => {
87
+ const environment = createUIEnvironment('test', false)
88
+ // @ts-expect-error
89
+ const spy = vi.spyOn(clack, 'spinner').mockImplementation(async () => ({
90
+ start: (_msg?: string) => {},
91
+ stop: (_msg?: string) => {},
92
+ message: (_msg?: string) => {},
93
+ }))
94
+ const result = await environment.spinner()
95
+ expect(spy).toHaveBeenCalled()
96
+ })
97
+ })
@@ -0,0 +1,233 @@
1
+ import { describe, it, expect, vi } from 'vitest'
2
+
3
+ import * as clack from '@clack/prompts'
4
+
5
+ import {
6
+ getProjectName,
7
+ selectAddOns,
8
+ selectGit,
9
+ selectPackageManager,
10
+ selectRouterType,
11
+ selectTailwind,
12
+ selectToolchain,
13
+ } from '../src/ui-prompts'
14
+ import { FILE_ROUTER } from '@tanstack/cta-engine'
15
+
16
+ import type { AddOn, Framework } from '@tanstack/cta-engine'
17
+
18
+ vi.mock('@clack/prompts')
19
+
20
+ vi.spyOn(process, 'exit').mockImplementation((number) => {
21
+ throw new Error(`process.exit: ${number}`)
22
+ })
23
+
24
+ describe('getProjectName', () => {
25
+ it('should return the project name', async () => {
26
+ vi.spyOn(clack, 'text').mockImplementation(async () => 'my-app')
27
+ vi.spyOn(clack, 'isCancel').mockImplementation(() => false)
28
+
29
+ const projectName = await getProjectName()
30
+ expect(projectName).toBe('my-app')
31
+ })
32
+
33
+ it('should exit on cancel', async () => {
34
+ vi.spyOn(clack, 'text').mockImplementation(async () => 'Cancelled')
35
+ vi.spyOn(clack, 'isCancel').mockImplementation(() => true)
36
+
37
+ await expect(getProjectName()).rejects.toThrowError(/exit/)
38
+ })
39
+ })
40
+
41
+ describe('selectRouterType', () => {
42
+ it('should select the file router', async () => {
43
+ vi.spyOn(clack, 'select').mockImplementation(async () => 'file-router')
44
+ vi.spyOn(clack, 'isCancel').mockImplementation(() => false)
45
+
46
+ const routerType = await selectRouterType()
47
+ expect(routerType).toBe(FILE_ROUTER)
48
+ })
49
+
50
+ it('should exit on cancel', async () => {
51
+ vi.spyOn(clack, 'select').mockImplementation(async () => 'Cancelled')
52
+ vi.spyOn(clack, 'isCancel').mockImplementation(() => true)
53
+
54
+ await expect(() => selectRouterType()).rejects.toThrowError(/exit/)
55
+ })
56
+ })
57
+
58
+ describe('selectTailwind', () => {
59
+ it('should select tailwind', async () => {
60
+ vi.spyOn(clack, 'confirm').mockImplementation(async () => true)
61
+ vi.spyOn(clack, 'isCancel').mockImplementation(() => false)
62
+
63
+ const tailwind = await selectTailwind()
64
+ expect(tailwind).toBe(true)
65
+ })
66
+
67
+ it('should exit on cancel', async () => {
68
+ vi.spyOn(clack, 'confirm').mockImplementation(async () =>
69
+ Symbol.for('cancel'),
70
+ )
71
+ vi.spyOn(clack, 'isCancel').mockImplementation(() => true)
72
+
73
+ await expect(selectTailwind()).rejects.toThrowError(/exit/)
74
+ })
75
+ })
76
+
77
+ describe('selectPackageManager', () => {
78
+ it('should select pnpm', async () => {
79
+ vi.spyOn(clack, 'select').mockImplementation(async () => 'pnpm')
80
+ vi.spyOn(clack, 'isCancel').mockImplementation(() => false)
81
+
82
+ const packageManager = await selectPackageManager()
83
+ expect(packageManager).toBe('pnpm')
84
+ })
85
+
86
+ it('should exit on cancel', async () => {
87
+ vi.spyOn(clack, 'select').mockImplementation(async () =>
88
+ Symbol.for('cancel'),
89
+ )
90
+ vi.spyOn(clack, 'isCancel').mockImplementation(() => true)
91
+
92
+ await expect(selectPackageManager()).rejects.toThrowError(/exit/)
93
+ })
94
+ })
95
+
96
+ describe('selectAddOns', () => {
97
+ it('should select some add-ons', async () => {
98
+ vi.spyOn(clack, 'multiselect').mockImplementation(async () => ['add-on-1'])
99
+ vi.spyOn(clack, 'isCancel').mockImplementation(() => false)
100
+
101
+ const packageManager = await selectAddOns(
102
+ {
103
+ getAddOns: () =>
104
+ [
105
+ {
106
+ id: 'add-on-1',
107
+ name: 'Add-on 1',
108
+ description: 'Add-on 1 description',
109
+ type: 'add-on',
110
+ modes: ['file-router'],
111
+ },
112
+ ] as Array<AddOn>,
113
+ } as Framework,
114
+ 'file-router',
115
+ 'add-on',
116
+ 'Select add-ons',
117
+ )
118
+ expect(packageManager).toEqual(['add-on-1'])
119
+ })
120
+
121
+ it('should exit on cancel', async () => {
122
+ vi.spyOn(clack, 'select').mockImplementation(async () =>
123
+ Symbol.for('cancel'),
124
+ )
125
+ vi.spyOn(clack, 'isCancel').mockImplementation(() => true)
126
+
127
+ await expect(
128
+ selectAddOns(
129
+ {
130
+ getAddOns: () =>
131
+ [
132
+ {
133
+ id: 'add-on-1',
134
+ name: 'Add-on 1',
135
+ description: 'Add-on 1 description',
136
+ type: 'add-on',
137
+ modes: ['file-router'],
138
+ },
139
+ ] as Array<AddOn>,
140
+ } as Framework,
141
+ 'file-router',
142
+ 'add-on',
143
+ 'Select add-ons',
144
+ ),
145
+ ).rejects.toThrowError(/exit/)
146
+ })
147
+ })
148
+
149
+ describe('selectGit', () => {
150
+ it('should select git', async () => {
151
+ vi.spyOn(clack, 'confirm').mockImplementation(async () => true)
152
+ vi.spyOn(clack, 'isCancel').mockImplementation(() => false)
153
+
154
+ const git = await selectGit()
155
+ expect(git).toBe(true)
156
+ })
157
+
158
+ it('should exit on cancel', async () => {
159
+ vi.spyOn(clack, 'confirm').mockImplementation(async () =>
160
+ Symbol.for('cancel'),
161
+ )
162
+ vi.spyOn(clack, 'isCancel').mockImplementation(() => true)
163
+
164
+ await expect(selectGit()).rejects.toThrowError(/exit/)
165
+ })
166
+ })
167
+
168
+ describe('selectToolchain', () => {
169
+ it('should select a toolchain', async () => {
170
+ vi.spyOn(clack, 'select').mockImplementation(async () => 'biome')
171
+ vi.spyOn(clack, 'isCancel').mockImplementation(() => false)
172
+
173
+ const packageManager = await selectToolchain({
174
+ getAddOns: () =>
175
+ [
176
+ {
177
+ id: 'biome',
178
+ name: 'Biome',
179
+ description: 'Biome description',
180
+ type: 'toolchain',
181
+ modes: ['file-router'],
182
+ },
183
+ ] as Array<AddOn>,
184
+ } as Framework)
185
+ expect(packageManager).toEqual('biome')
186
+ })
187
+ it('should select a toolchain', async () => {
188
+ const selectSpy = vi
189
+ .spyOn(clack, 'select')
190
+ .mockImplementation(async () => 'biome')
191
+ vi.spyOn(clack, 'isCancel').mockImplementation(() => false)
192
+
193
+ const packageManager = await selectToolchain(
194
+ {
195
+ getAddOns: () =>
196
+ [
197
+ {
198
+ id: 'biome',
199
+ name: 'Biome',
200
+ description: 'Biome description',
201
+ type: 'toolchain',
202
+ modes: ['file-router'],
203
+ },
204
+ ] as Array<AddOn>,
205
+ } as Framework,
206
+ 'biome',
207
+ )
208
+ expect(packageManager).toEqual('biome')
209
+ expect(selectSpy).not.toHaveBeenCalled()
210
+ })
211
+
212
+ it('should exit on cancel', async () => {
213
+ vi.spyOn(clack, 'select').mockImplementation(async () =>
214
+ Symbol.for('cancel'),
215
+ )
216
+ vi.spyOn(clack, 'isCancel').mockImplementation(() => true)
217
+
218
+ await expect(
219
+ selectToolchain({
220
+ getAddOns: () =>
221
+ [
222
+ {
223
+ id: 'biome',
224
+ name: 'Biome',
225
+ description: 'Biome description',
226
+ type: 'toolchain',
227
+ modes: ['file-router'],
228
+ },
229
+ ] as Array<AddOn>,
230
+ } as Framework),
231
+ ).rejects.toThrowError(/exit/)
232
+ })
233
+ })
@@ -0,0 +1,7 @@
1
+ import { defineConfig } from 'vitest/config'
2
+
3
+ export default defineConfig({
4
+ test: {
5
+ setupFiles: ['./tests/setupVitest.js'],
6
+ },
7
+ })