Skip to content

Commit 352dd22

Browse files
committed
fixup! test: add test for Project
1 parent f7a05de commit 352dd22

File tree

1 file changed

+123
-7
lines changed

1 file changed

+123
-7
lines changed

packages/codegen/src/project.test.ts

Lines changed: 123 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { access, chmod, writeFile } from 'node:fs/promises';
1+
import { access, chmod, rm, writeFile } from 'node:fs/promises';
22
import { TsConfigFileNotFoundError } from '@css-modules-kit/core';
33
import dedent from 'dedent';
44
import { describe, expect, test } from 'vitest';
@@ -48,7 +48,7 @@ test('isWildcardMatchedFile', async () => {
4848
});
4949

5050
describe('addFile', () => {
51-
test('The diagnostics of the added file are reported and .d.ts file is emitted', async () => {
51+
test('The diagnostics of the added file are reported, and .d.ts file is emitted', async () => {
5252
const iff = await createIFF({
5353
'tsconfig.json': '{}',
5454
'src': {},
@@ -85,7 +85,7 @@ describe('addFile', () => {
8585
await project.emitDtsFiles();
8686
await expect(access(iff.join('generated/src/a.module.css.d.ts'))).resolves.not.toThrow();
8787
});
88-
test('Adding a file may resolve diagnostics in files that import it directly or indirectly', async () => {
88+
test('changes diagnostics in files that import it directly or indirectly', async () => {
8989
// This test case suggests the following facts:
9090
// - The check stage cache for files that directly import the added file should be invalidated.
9191
// - The check stage cache for files that indirectly import the added file should also be invalidated.
@@ -123,7 +123,7 @@ describe('addFile', () => {
123123
project.addFile(iff.join('src/a.module.css'));
124124
expect(formatDiagnostics(project.getDiagnostics(), iff.rootDir)).toMatchInlineSnapshot(`[]`);
125125
});
126-
test('Adding a file may change the resolution results of import specifiers in other files', async () => {
126+
test('changes the resolution results of import specifiers in other files', async () => {
127127
// This test case suggests the following facts:
128128
// - The check stage cache for files that import other files should be invalidated.
129129
// - Only independent files that do not import any other files can keep the check stage cache.
@@ -163,7 +163,7 @@ describe('addFile', () => {
163163
});
164164

165165
describe('updateFile', () => {
166-
test('The new diagnostics of the changed file are reported and new .d.ts file is emitted', async () => {
166+
test('The new diagnostics of the changed file are reported, and new .d.ts file is emitted', async () => {
167167
const iff = await createIFF({
168168
'tsconfig.json': '{}',
169169
'src/a.module.css': '',
@@ -220,8 +220,9 @@ describe('updateFile', () => {
220220
]
221221
`);
222222
});
223-
test('Changing a file may resolve diagnostics in files that import it directly or indirectly', async () => {
223+
test('changes diagnostics in files that import it directly or indirectly', async () => {
224224
// This test case suggests the following facts:
225+
// - The resolution cache should be invalidated.
225226
// - The check stage cache for files that directly import the changed file should be invalidated.
226227
// - The check stage cache for files that indirectly import the changed file should also be invalidated.
227228
const iff = await createIFF({
@@ -264,7 +265,122 @@ describe('updateFile', () => {
264265
});
265266
});
266267

267-
describe.todo('deleteFile', () => {});
268+
describe('removeFile', () => {
269+
test('The diagnostics of the removed file are not reported, and .d.ts file is not emitted', async () => {
270+
const iff = await createIFF({
271+
'tsconfig.json': '{}',
272+
'src/a.module.css': '.a_1 {',
273+
});
274+
const project = createProject({ project: iff.rootDir });
275+
276+
// Even if the file is deleted, diagnostics will not change until notified by `removeFile`.
277+
await rm(iff.join('src/a.module.css'));
278+
expect(formatDiagnostics(project.getDiagnostics(), iff.rootDir)).toMatchInlineSnapshot(`
279+
[
280+
{
281+
"category": "error",
282+
"fileName": "<rootDir>/src/a.module.css",
283+
"length": 1,
284+
"start": {
285+
"column": 1,
286+
"line": 1,
287+
},
288+
"text": "Unclosed block",
289+
},
290+
]
291+
`);
292+
293+
project.removeFile(iff.join('src/a.module.css'));
294+
expect(formatDiagnostics(project.getDiagnostics(), iff.rootDir)).toMatchInlineSnapshot(`
295+
[
296+
{
297+
"category": "error",
298+
"text": "The file specified in tsconfig.json not found.",
299+
},
300+
]
301+
`);
302+
303+
await project.emitDtsFiles();
304+
await expect(access(iff.join('generated/src/a.module.css.d.ts'))).rejects.toThrow();
305+
});
306+
test('changes diagnostics in files that import it directly or indirectly', async () => {
307+
// This test case suggests the following facts:
308+
// - The check stage cache for files that directly import the changed file should be invalidated.
309+
// - The check stage cache for files that indirectly import the changed file should also be invalidated.
310+
const iff = await createIFF({
311+
'tsconfig.json': '{}',
312+
'src/a.module.css': '@value a_1: red;',
313+
'src/b.module.css': '@import "./a.module.css";', // directly
314+
'src/c.module.css': '@value a_1 from "./b.module.css";', // indirectly
315+
});
316+
const project = createProject({ project: iff.rootDir });
317+
expect(formatDiagnostics(project.getDiagnostics(), iff.rootDir)).toMatchInlineSnapshot(`[]`);
318+
await rm(iff.join('src/a.module.css'));
319+
project.removeFile(iff.join('src/a.module.css'));
320+
expect(formatDiagnostics(project.getDiagnostics(), iff.rootDir)).toMatchInlineSnapshot(`
321+
[
322+
{
323+
"category": "error",
324+
"fileName": "<rootDir>/src/b.module.css",
325+
"length": 14,
326+
"start": {
327+
"column": 10,
328+
"line": 1,
329+
},
330+
"text": "Cannot import module './a.module.css'",
331+
},
332+
{
333+
"category": "error",
334+
"fileName": "<rootDir>/src/c.module.css",
335+
"length": 3,
336+
"start": {
337+
"column": 8,
338+
"line": 1,
339+
},
340+
"text": "Module './b.module.css' has no exported token 'a_1'.",
341+
},
342+
]
343+
`);
344+
});
345+
test('changes the resolution results of import specifiers in other files', async () => {
346+
// This test case suggests the following facts:
347+
// - The resolution cache should be invalidated.
348+
// - The check stage cache for files that import the removed file should be invalidated.
349+
const iff = await createIFF({
350+
'tsconfig.json': dedent`
351+
{
352+
"compilerOptions": {
353+
"paths": {
354+
"@/a.module.css": ["src/a-1.module.css", "src/a-2.module.css"]
355+
}
356+
}
357+
}
358+
`,
359+
'src/a-1.module.css': '@value a_1: red;',
360+
'src/a-2.module.css': '@value a_2: red;',
361+
'src/b.module.css': '@import "@/a.module.css";',
362+
'src/c.module.css': '@value a_2 from "./b.module.css";',
363+
});
364+
const project = createProject({ project: iff.rootDir });
365+
expect(formatDiagnostics(project.getDiagnostics(), iff.rootDir)).toMatchInlineSnapshot(`
366+
[
367+
{
368+
"category": "error",
369+
"fileName": "<rootDir>/src/c.module.css",
370+
"length": 3,
371+
"start": {
372+
"column": 8,
373+
"line": 1,
374+
},
375+
"text": "Module './b.module.css' has no exported token 'a_2'.",
376+
},
377+
]
378+
`);
379+
await rm(iff.join('src/a-1.module.css'));
380+
project.removeFile(iff.join('src/a-1.module.css'));
381+
expect(formatDiagnostics(project.getDiagnostics(), iff.rootDir)).toMatchInlineSnapshot(`[]`);
382+
});
383+
});
268384

269385
describe('getDiagnostics', () => {
270386
test('returns empty array when no diagnostics', async () => {

0 commit comments

Comments
 (0)