Skip to content

Commit 87d449e

Browse files
committed
chore: tests that mock the fs
1 parent 05594da commit 87d449e

8 files changed

+276
-9
lines changed

packages/cta-engine/tests/config-file.test.ts

+27-2
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,19 @@
1-
import { describe, expect, it } from 'vitest'
1+
import { beforeEach, describe, expect, it, vi } from 'vitest'
2+
import { fs, vol } from 'memfs'
23
import { resolve } from 'node:path'
34

4-
import { writeConfigFile } from '../src/config-file.js'
5+
import { readConfigFile, writeConfigFile } from '../src/config-file.js'
56
import { CONFIG_FILE } from '../src/constants.js'
67

78
import type { AddOn, Environment, Framework, Options } from '../src/types.js'
89

10+
vi.mock('node:fs', () => fs)
11+
vi.mock('node:fs/promises', () => fs.promises)
12+
13+
beforeEach(() => {
14+
vol.reset()
15+
})
16+
917
describe('writeConfigFile', () => {
1018
it('should write the config file', async () => {
1119
const options = {
@@ -37,3 +45,20 @@ describe('writeConfigFile', () => {
3745
await writeConfigFile(env, targetDir, options)
3846
})
3947
})
48+
49+
describe('readConfigFile', () => {
50+
it('should read the config file', async () => {
51+
const persistedOptions = {
52+
version: 1,
53+
framework: 'react-cra',
54+
existingAddOns: ['add-on-1'],
55+
}
56+
vol.mkdirSync('/test')
57+
vol.writeFileSync(
58+
resolve('/test', CONFIG_FILE),
59+
JSON.stringify(persistedOptions, null, 2),
60+
)
61+
const config = await readConfigFile('/test')
62+
expect(config).toEqual(persistedOptions)
63+
})
64+
})

packages/cta-engine/tests/create-app.test.ts

-1
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,6 @@ describe('createApp', () => {
138138
},
139139
)
140140

141-
console.log(output.commands)
142141
expect(output.files['/src/test2.txt']).toEqual('hello')
143142
expect(output.commands.some(({ command }) => command === 'echo')).toBe(true)
144143
})

packages/cta-engine/tests/environment.test.ts

+71-2
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,31 @@
1-
import { describe, expect, it } from 'vitest'
1+
import { beforeEach, describe, expect, it, vi } from 'vitest'
2+
import { fs, vol } from 'memfs'
23

3-
import { createMemoryEnvironment } from '../src/environment.js'
4+
vi.mock('node:fs', () => fs)
5+
vi.mock('node:fs/promises', () => fs.promises)
6+
7+
beforeEach(() => {
8+
vol.reset()
9+
})
10+
11+
import {
12+
createMemoryEnvironment,
13+
createDefaultEnvironment,
14+
} from '../src/environment.js'
415

516
describe('createMemoryEnvironment', () => {
617
it('should handle basic file operations', async () => {
718
const { environment, output } = createMemoryEnvironment()
819

920
environment.startRun()
21+
22+
await environment.writeFile('/test.txt', 'test')
23+
24+
environment.deleteFile('/test.txt')
25+
expect(environment.exists('/test.txt')).toBe(false)
26+
1027
await environment.writeFile('/test.txt', 'test')
28+
1129
environment.finishRun()
1230

1331
expect(output.files['/test.txt']).toEqual('test')
@@ -25,3 +43,54 @@ describe('createMemoryEnvironment', () => {
2543
expect(output.commands[0].args).toEqual(['test'])
2644
})
2745
})
46+
47+
describe('createDefaultEnvironment', () => {
48+
it('should create a default environment', async () => {
49+
const environment = createDefaultEnvironment()
50+
expect(environment).toBeDefined()
51+
})
52+
53+
it('should write to the file system', async () => {
54+
const environment = createDefaultEnvironment()
55+
environment.startRun()
56+
await environment.writeFile('/test.txt', 'test')
57+
await environment.appendFile('/test.txt', 'test2')
58+
await environment.copyFile('/test.txt', '/test2.txt')
59+
environment.finishRun()
60+
61+
expect(fs.readFileSync('/test.txt', 'utf8')).toEqual('testtest2')
62+
})
63+
64+
it('should allow deletes', async () => {
65+
const environment = createDefaultEnvironment()
66+
await environment.writeFile('/test.txt', 'test')
67+
expect(fs.readFileSync('/test.txt', 'utf8')).toEqual('test')
68+
await environment.deleteFile('/test.txt')
69+
expect(environment.exists('/test.txt')).toBe(false)
70+
})
71+
72+
it('should record errors', async () => {
73+
const environment = createDefaultEnvironment()
74+
environment.startRun()
75+
await environment.execute('command-that-does-not-exist', ['test'], '')
76+
environment.finishRun()
77+
expect(environment.getErrors()).toEqual([
78+
'Command "command-that-does-not-exist test" did not run successfully. Please run this manually in your project.',
79+
])
80+
})
81+
82+
it('should have UI methods', async () => {
83+
const environment = createDefaultEnvironment()
84+
environment.startRun()
85+
environment.intro('test')
86+
environment.outro('test')
87+
environment.info('test')
88+
environment.error('test')
89+
environment.warn('test')
90+
const s = environment.spinner()
91+
s.start('foo')
92+
s.stop('bar')
93+
environment.finishRun()
94+
expect(await environment.confirm('test')).toEqual(true)
95+
})
96+
})

packages/cta-engine/tests/file-helper.test.ts

+55-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,19 @@
1-
import { describe, expect, it } from 'vitest'
1+
import { beforeEach, describe, expect, it, vi } from 'vitest'
2+
import { fs, vol } from 'memfs'
23

3-
import { relativePath } from '../src/file-helpers.js'
4+
import {
5+
findFilesRecursively,
6+
isDirectory,
7+
readFileHelper,
8+
relativePath,
9+
} from '../src/file-helpers.js'
10+
11+
vi.mock('node:fs', () => fs)
12+
vi.mock('node:fs/promises', () => fs.promises)
13+
14+
beforeEach(() => {
15+
vol.reset()
16+
})
417

518
describe('relativePath', () => {
619
it('relative path with the same directory', () => {
@@ -35,3 +48,43 @@ describe('relativePath', () => {
3548
).toBe('../integrations/tanstack-query/layout.tsx')
3649
})
3750
})
51+
52+
describe('readFileHelper', () => {
53+
it('should read a file', async () => {
54+
vol.mkdirSync('/src')
55+
fs.writeFileSync('/src/test.txt', 'Hello')
56+
expect(readFileHelper('/src/test.txt')).toBe('Hello')
57+
})
58+
it('should read a binary file', async () => {
59+
vol.mkdirSync('/src')
60+
fs.writeFileSync('/src/test.jpg', 'Hello')
61+
expect(readFileHelper('/src/test.jpg')).toBe('base64::SGVsbG8=')
62+
})
63+
})
64+
65+
describe('isDirectory', () => {
66+
it('should check on files and directories', () => {
67+
vol.mkdirSync('/src')
68+
fs.writeFileSync('/src/test.txt', 'Hello')
69+
expect(isDirectory('/src/test.txt')).toBe(false)
70+
expect(isDirectory('/src')).toBe(true)
71+
})
72+
})
73+
74+
describe('findFilesRecursively', () => {
75+
it('find files recursively', () => {
76+
vol.mkdirSync('/src/subdir/subdir2', { recursive: true })
77+
fs.writeFileSync('/src/test.txt', 'Hello')
78+
fs.writeFileSync('/src/subdir/test.txt', 'Hello')
79+
fs.writeFileSync('/src/subdir/subdir2/test.txt', 'Hello')
80+
81+
const files = {}
82+
findFilesRecursively('/src', files)
83+
84+
expect(Object.keys(files)).toEqual([
85+
'/src/subdir/subdir2/test.txt',
86+
'/src/subdir/test.txt',
87+
'/src/test.txt',
88+
])
89+
})
90+
})
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
import { beforeEach, describe, expect, it, vi } from 'vitest'
2+
import { fs, vol } from 'memfs'
3+
4+
import {
5+
getFrameworks,
6+
getFrameworkById,
7+
getFrameworkByName,
8+
registerFramework,
9+
} from '../src/frameworks.js'
10+
11+
vi.mock('node:fs', () => fs)
12+
vi.mock('node:fs/promises', () => fs.promises)
13+
14+
beforeEach(() => {
15+
vol.reset()
16+
})
17+
18+
describe('registerFramework', () => {
19+
it('should register a framework', async () => {
20+
const addOnPackageJSON = {
21+
id: 'test',
22+
name: 'Test',
23+
description: 'Test',
24+
version: '1.0.0',
25+
}
26+
const basePackageJSON = {
27+
name: 'Test',
28+
version: '1.0.0',
29+
}
30+
31+
vol.mkdirSync('/test/add-ons/test/assets', { recursive: true })
32+
vol.writeFileSync(
33+
'/test/add-ons/test/info.json',
34+
JSON.stringify({
35+
id: 'test',
36+
name: 'Test',
37+
description: 'Test',
38+
version: '1.0.0',
39+
}),
40+
)
41+
vol.writeFileSync(
42+
'/test/add-ons/test/package.json',
43+
JSON.stringify({
44+
id: 'test',
45+
name: 'Test',
46+
description: 'Test',
47+
version: '1.0.0',
48+
}),
49+
)
50+
vol.writeFileSync(
51+
'/test/add-ons/test/assets/package.json',
52+
JSON.stringify(addOnPackageJSON),
53+
)
54+
vol.writeFileSync('/test/add-ons/test/README.md', 'foo')
55+
vol.mkdirSync('/test/project/base/assets', { recursive: true })
56+
vol.writeFileSync(
57+
'/test/project/base/package.json',
58+
JSON.stringify(basePackageJSON),
59+
)
60+
vol.writeFileSync(
61+
'/test/project/packages.json',
62+
JSON.stringify({
63+
typescript: {},
64+
}),
65+
)
66+
67+
registerFramework({
68+
id: 'test',
69+
name: 'Test',
70+
addOnsDirectories: ['/test/add-ons'],
71+
description: 'Test',
72+
version: '1.0.0',
73+
baseDirectory: '/test/project',
74+
examplesDirectory: '/test/examples',
75+
})
76+
77+
const f = getFrameworkById('test')!
78+
79+
const baseFiles = await f.getFiles()
80+
expect(baseFiles).toEqual(['./package.json'])
81+
82+
const fileContents = await f.getFileContents('./package.json')
83+
expect(fileContents).toEqual(JSON.stringify(basePackageJSON))
84+
85+
const addOns = await f.getAddOns()
86+
const addOnFiles = await addOns[0].getFiles()
87+
expect(addOnFiles).toEqual(['./package.json'])
88+
89+
const addOnFileContents = await addOns[0].getFileContents('./package.json')
90+
expect(addOnFileContents).toEqual(JSON.stringify(addOnPackageJSON))
91+
92+
expect(getFrameworkByName('Test')).not.toBeUndefined()
93+
expect(getFrameworks().length).toEqual(1)
94+
})
95+
})
+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import { describe, expect, it } from 'vitest'
2+
3+
import { createApp } from '../src/index.js'
4+
5+
describe('index', () => {
6+
it('should be a test', () => {
7+
expect(createApp).toBeDefined()
8+
})
9+
})

packages/cta-engine/tests/template-file.test.ts

-2
Original file line numberDiff line numberDiff line change
@@ -154,8 +154,6 @@ describe('createTemplateFile', () => {
154154
)
155155
environment.finishRun()
156156

157-
console.log(output.files['/test/test.txt'])
158-
159157
expect(output.files['/test/test.txt']).toEqual('/test')
160158
})
161159

packages/cta-engine/vitest.config.ts

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import { defineConfig } from 'vitest/config'
2+
import path from 'node:path'
3+
4+
export default defineConfig({
5+
test: {
6+
deps: {
7+
moduleDirectories: ['node_modules', path.resolve('../../packages')],
8+
},
9+
coverage: {
10+
exclude: [
11+
'node_modules',
12+
'dist',
13+
'build',
14+
'**/types.ts',
15+
'vitest.config.ts',
16+
],
17+
},
18+
},
19+
})

0 commit comments

Comments
 (0)