Skip to content

Commit f47c136

Browse files
committed
test: simplify temporary test fixtures
1 parent 4507ca5 commit f47c136

14 files changed

Lines changed: 80 additions & 110 deletions

File tree

‎packages/rstack/rstack.config.ts‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ define.test(async () => {
77
process.env.NO_COLOR = '1';
88

99
return {
10+
// Temporary projects may contain files that match Rstest's test glob.
11+
exclude: ['**/test-temp-*/**'],
1012
extends: withRslibConfig(),
1113
source: {
1214
tsconfigPath: './tests/tsconfig.json',

‎packages/rstack/tests/cli/fmt/index.test.ts‎

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,10 @@ import { RSTACK_BIN_PATH } from '#test-helpers';
66

77
let projectPath: string;
88

9-
const writeProjectFile = (filePath: string, content: string): string => {
9+
const writeProjectFile = (filePath: string, content: string): void => {
1010
const absolutePath = path.join(projectPath, filePath);
1111
mkdirSync(path.dirname(absolutePath), { recursive: true });
1212
writeFileSync(absolutePath, content);
13-
return absolutePath;
1413
};
1514

1615
const readProjectFile = (filePath: string): string =>
@@ -30,7 +29,9 @@ const runCLI = (args: string[]) => {
3029
const runFmt = (args: string[] = []) => runCLI(['fmt', ...args]);
3130

3231
beforeEach(() => {
33-
projectPath = mkdtempSync(path.join(import.meta.dirname, 'fmt-project-'));
32+
projectPath = mkdtempSync(path.join(import.meta.dirname, 'test-temp-fmt-'));
33+
// Prevent repository-level ignore rules from affecting the fixture.
34+
mkdirSync(path.join(projectPath, '.git'));
3435
writeProjectFile('rstack.config.ts', 'export {};\n');
3536
});
3637

‎packages/rstack/tests/cli/setup/index.test.ts‎

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import { spawnSync } from 'node:child_process';
22
import { existsSync, mkdirSync, mkdtempSync, rmSync, writeFileSync } from 'node:fs';
3-
import { tmpdir } from 'node:os';
43
import path from 'node:path';
54
import { afterEach, beforeEach } from 'rstack/test';
65
import { RSTACK_BIN_PATH, test } from '#test-helpers';
@@ -30,9 +29,11 @@ const runSetup = (args: string[], runCwd: string = cwd) =>
3029
});
3130

3231
beforeEach(() => {
33-
cwd = mkdtempSync(path.join(tmpdir(), 'rstack setup '));
32+
cwd = mkdtempSync(path.join(import.meta.dirname, 'test-temp-rstack setup '));
3433
env = {
3534
...process.env,
35+
// Keep Git from treating the fixture as part of this repository.
36+
GIT_CEILING_DIRECTORIES: import.meta.dirname,
3637
GIT_CONFIG_GLOBAL: path.join(cwd, 'global.gitconfig'),
3738
GIT_CONFIG_NOSYSTEM: '1',
3839
};
@@ -106,7 +107,9 @@ test('installs a custom hooks directory from a nested project', ({ execCli, expe
106107
});
107108

108109
test('skips non-Git directories without creating files', ({ execCli, expect }) => {
109-
expect(execCli('setup', { cwd })).toContain('Git hooks setup skipped: not a Git repository.');
110+
expect(execCli('setup', { cwd, env })).toContain(
111+
'Git hooks setup skipped: not a Git repository.',
112+
);
110113
expect(existsSync(path.join(cwd, '.rstack'))).toBe(false);
111114
});
112115

‎packages/rstack/tests/cli/staged/fmt.test.ts‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ const runStaged = () =>
3535
});
3636

3737
beforeEach(() => {
38-
projectPath = mkdtempSync(path.join(import.meta.dirname, 'staged-fmt-project-'));
38+
projectPath = mkdtempSync(path.join(import.meta.dirname, 'test-temp-staged-fmt-'));
3939
env = {
4040
...process.env,
4141
GIT_CONFIG_GLOBAL: path.join(projectPath, 'global.gitconfig'),

‎packages/rstack/tests/config/reload-app-config/index.test.ts‎

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { rm, writeFile } from 'node:fs/promises';
1+
import { writeFile } from 'node:fs/promises';
22
import path from 'node:path';
33
import { getRandomPort, waitForFile } from '@rstackjs/test-utils';
44
import { test } from '#test-helpers';
@@ -11,8 +11,6 @@ test('should restart dev server and reload config when Rstack config changes', a
1111
const dist2 = await prepareDist('dist-2');
1212
const configFile = path.join(import.meta.dirname, 'test-temp-rstack.config.ts');
1313

14-
await rm(configFile, { force: true });
15-
1614
await writeFile(
1715
configFile,
1816
`import { define } from 'rstack';

‎packages/rstack/tests/exports/lint-subpath/index.test.ts‎

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,5 @@ test('should expose lint APIs from `rstack/lint`', async () => {
77

88
for (const method of commonLintMethods) {
99
expect(lint).toHaveProperty(method);
10-
expect(typeof lint[method]).toBeTruthy();
1110
}
1211
});

‎packages/rstack/tests/exports/test-subpath/index.test.ts‎

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,5 @@ test('should expose test APIs from `rstack/test`', async () => {
77

88
for (const method of commonTestMethods) {
99
expect(test).toHaveProperty(method);
10-
expect(typeof test[method]).toBeTruthy();
1110
}
1211
});

‎packages/rstack/tests/fmt/discoverPaths.test.ts‎

Lines changed: 7 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,14 @@
1-
import { mkdirSync, mkdtempSync, rmSync, symlinkSync, writeFileSync } from 'node:fs';
2-
import { tmpdir } from 'node:os';
1+
import { symlinkSync } from 'node:fs';
32
import path from 'node:path';
43
import { expect, test } from 'rstack/test';
54
import { discoverFmtPaths } from '../../src/fmt/discoverPaths.ts';
6-
7-
const withProject = async (callback: (rootPath: string) => Promise<void>): Promise<void> => {
8-
const rootPath = mkdtempSync(path.join(tmpdir(), 'rstack fmt '));
9-
10-
try {
11-
await callback(rootPath);
12-
} finally {
13-
rmSync(rootPath, { force: true, recursive: true });
14-
}
15-
};
16-
17-
const writeProjectFile = (rootPath: string, filePath: string, content = ''): string => {
18-
const absolutePath = path.join(rootPath, filePath);
19-
mkdirSync(path.dirname(absolutePath), { recursive: true });
20-
writeFileSync(absolutePath, content);
21-
return absolutePath;
22-
};
5+
import { withTempProject, writeProjectFile } from './helpers.ts';
236

247
const relativePaths = (rootPath: string, files: string[]): string[] =>
258
files.map((filePath) => path.relative(rootPath, filePath));
269

2710
test('discovers non-binary files in stable order and skips hard-ignored paths', async () => {
28-
await withProject(async (rootPath) => {
11+
await withTempProject(async (rootPath) => {
2912
writeProjectFile(rootPath, 'b.ts');
3013
writeProjectFile(rootPath, 'a.js');
3114
writeProjectFile(rootPath, 'folder with spaces/c.ts');
@@ -50,7 +33,7 @@ test('discovers non-binary files in stable order and skips hard-ignored paths',
5033
});
5134

5235
test('combines files, directories, and globs without duplicates', async () => {
53-
await withProject(async (rootPath) => {
36+
await withTempProject(async (rootPath) => {
5437
const firstFilePath = writeProjectFile(rootPath, 'src/a.ts');
5538
writeProjectFile(rootPath, 'src/b.js');
5639
writeProjectFile(rootPath, 'test/c.ts');
@@ -90,8 +73,7 @@ test('combines files, directories, and globs without duplicates', async () => {
9073
});
9174

9275
test('applies nested gitignore rules with child negation', async () => {
93-
await withProject(async (rootPath) => {
94-
mkdirSync(path.join(rootPath, '.git'));
76+
await withTempProject(async (rootPath) => {
9577
writeProjectFile(rootPath, '.gitignore', '*.js\ndist/\n');
9678
writeProjectFile(rootPath, 'src/.gitignore', '!keep.js\n');
9779
writeProjectFile(rootPath, 'dist/.gitignore', '!keep.js\n');
@@ -114,8 +96,7 @@ test('applies nested gitignore rules with child negation', async () => {
11496
});
11597

11698
test('lets explicit files bypass gitignore', async () => {
117-
await withProject(async (rootPath) => {
118-
mkdirSync(path.join(rootPath, '.git'));
99+
await withTempProject(async (rootPath) => {
119100
writeProjectFile(rootPath, '.gitignore', '/generated/\n');
120101
const keepPath = writeProjectFile(rootPath, 'generated/keep.ts');
121102
writeProjectFile(rootPath, 'src/index.ts');
@@ -132,7 +113,7 @@ test('lets explicit files bypass gitignore', async () => {
132113
});
133114

134115
test.runIf(process.platform !== 'win32')('does not follow file or directory symlinks', async () => {
135-
await withProject(async (rootPath) => {
116+
await withTempProject(async (rootPath) => {
136117
const targetPath = writeProjectFile(rootPath, 'target/index.ts');
137118
symlinkSync(path.join(rootPath, 'target'), path.join(rootPath, 'linked-directory'));
138119
symlinkSync(targetPath, path.join(rootPath, 'linked-file.ts'));

‎packages/rstack/tests/fmt/discovery.test.ts‎

Lines changed: 5 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,10 @@
1-
import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from 'node:fs';
2-
import { tmpdir } from 'node:os';
1+
import { mkdirSync } from 'node:fs';
32
import path from 'node:path';
43
import { expect, test } from 'rstack/test';
54
import { normalizeFmtConfig } from '../../src/fmt/config.ts';
65
import { discoverFmtFiles } from '../../src/fmt/discovery.ts';
76
import type { FmtConfig } from '../../src/fmt/types.ts';
8-
9-
const withProject = async (callback: (rootPath: string) => Promise<void>): Promise<void> => {
10-
const rootPath = mkdtempSync(path.join(tmpdir(), 'rstack fmt '));
11-
12-
try {
13-
await callback(rootPath);
14-
} finally {
15-
rmSync(rootPath, { force: true, recursive: true });
16-
}
17-
};
18-
19-
const writeProjectFile = (rootPath: string, filePath: string, content = ''): string => {
20-
const absolutePath = path.join(rootPath, filePath);
21-
mkdirSync(path.dirname(absolutePath), { recursive: true });
22-
writeFileSync(absolutePath, content);
23-
return absolutePath;
24-
};
7+
import { withTempProject, writeProjectFile } from './helpers.ts';
258

269
const discover = async (cwd: string, patterns?: string[], config?: FmtConfig, configRoot = cwd) =>
2710
discoverFmtFiles({
@@ -34,7 +17,7 @@ const relativePaths = (rootPath: string, files: Awaited<ReturnType<typeof discov
3417
files.map((file) => path.relative(rootPath, file.path));
3518

3619
test('applies config ignore patterns to discovered and explicit files', async () => {
37-
await withProject(async (rootPath) => {
20+
await withTempProject(async (rootPath) => {
3821
const keepPath = writeProjectFile(rootPath, 'generated/keep.ts');
3922
const blockedPath = writeProjectFile(rootPath, 'generated/blocked.ts');
4023
writeProjectFile(rootPath, 'src/index.ts');
@@ -52,7 +35,7 @@ test('applies config ignore patterns to discovered and explicit files', async ()
5235
});
5336

5437
test('applies config ignore patterns outside the config root', async () => {
55-
await withProject(async (rootPath) => {
38+
await withTempProject(async (rootPath) => {
5639
const configRoot = path.join(rootPath, 'project');
5740
const filePath = writeProjectFile(rootPath, 'shared/index.ts');
5841
mkdirSync(configRoot);
@@ -64,7 +47,7 @@ test('applies config ignore patterns outside the config root', async () => {
6447
});
6548

6649
test('resolves parsers and accepts unknown extensions with an explicit parser', async () => {
67-
await withProject(async (rootPath) => {
50+
await withTempProject(async (rootPath) => {
6851
writeProjectFile(rootPath, 'index.ts');
6952
writeProjectFile(rootPath, 'source.custom');
7053
writeProjectFile(rootPath, 'unknown.extension');
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from 'node:fs';
2+
import path from 'node:path';
3+
4+
export const withTempProject = async (
5+
callback: (rootPath: string) => Promise<void>,
6+
): Promise<void> => {
7+
const rootPath = mkdtempSync(path.join(import.meta.dirname, 'test-temp-fmt-'));
8+
// Prevent repository-level ignore rules from affecting the fixture.
9+
mkdirSync(path.join(rootPath, '.git'));
10+
11+
try {
12+
await callback(rootPath);
13+
} finally {
14+
rmSync(rootPath, { force: true, recursive: true });
15+
}
16+
};
17+
18+
export const writeProjectFile = (rootPath: string, filePath: string, content = ''): string => {
19+
const absolutePath = path.join(rootPath, filePath);
20+
mkdirSync(path.dirname(absolutePath), { recursive: true });
21+
writeFileSync(absolutePath, content);
22+
return absolutePath;
23+
};

0 commit comments

Comments
 (0)