Skip to content

Commit 94c3159

Browse files
authored
fix: support import rstest in node_modules (#547)
1 parent a1fa969 commit 94c3159

File tree

8 files changed

+138
-15
lines changed

8 files changed

+138
-15
lines changed
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import { expect, it } from '@rstest/core';
2+
import 'rstest-import';
3+
4+
it('should run setup correctly', async () => {
5+
expect(process.env.A).toBe('A');
6+
});
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import { beforeAll, describe, expect, it, rs } from '@rstest/core';
2+
3+
beforeAll(() => {
4+
process.env.A = 'A';
5+
});
6+
7+
describe('wrap test', () => {
8+
it('should run', () => {
9+
const fn = rs.fn(() => 'hello');
10+
11+
expect(fn()).toBe('hello');
12+
expect('call it').toBe('call it');
13+
});
14+
15+
it.todo('should not run', () => {
16+
expect(1 + 1).toBe(3);
17+
});
18+
});
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"private": true,
3+
"name": "@rstest/tests-rstest-import",
4+
"main": "index.js",
5+
"type": "module",
6+
"sideEffects": true,
7+
"version": "1.0.0",
8+
"devDependencies": {
9+
"@rstest/core": "workspace:*"
10+
}
11+
}

e2e/runner/test/runner.test.ts

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import { dirname, join } from 'node:path';
2+
import { fileURLToPath } from 'node:url';
3+
import { it } from '@rstest/core';
4+
import { prepareFixtures, runRstestCli } from '../../scripts/';
5+
6+
const __filename = fileURLToPath(import.meta.url);
7+
8+
const __dirname = dirname(__filename);
9+
10+
it('should import rstest correctly in node_modules', async () => {
11+
await prepareFixtures({
12+
fixturesPath: join(__dirname, './fixtures/test-rstest-import'),
13+
fixturesTargetPath: join(
14+
__dirname,
15+
'./fixtures/node_modules/rstest-import',
16+
),
17+
});
18+
const { expectExecSuccess, expectLog } = await runRstestCli({
19+
command: 'rstest',
20+
args: ['run', 'runner.test.ts'],
21+
options: {
22+
nodeOptions: {
23+
cwd: join(__dirname, 'fixtures'),
24+
},
25+
},
26+
});
27+
await expectExecSuccess();
28+
expectLog('Tests 2 passed | 1 todo');
29+
});

e2e/watch/index.test.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,15 @@
11
import path from 'node:path';
22
import { fileURLToPath } from 'node:url';
3-
import { describe, expect, it } from '@rstest/core';
3+
import { describe, expect, it, rs } from '@rstest/core';
44
import { prepareFixtures, runRstestCli } from '../scripts';
55

66
const __filename = fileURLToPath(import.meta.url);
77
const __dirname = path.dirname(__filename);
88

9+
rs.setConfig({
10+
retry: 3,
11+
});
12+
913
describe('watch', () => {
1014
it('test files should be ran when create / update / delete', async () => {
1115
const { fs } = await prepareFixtures({

packages/core/src/runtime/api/index.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ export const createRstestRuntime = (
4040

4141
const rstest = createRstestUtilities(workerState);
4242

43-
return {
43+
const runtime = {
4444
runner,
4545
api: {
4646
...runnerAPI,
@@ -50,4 +50,8 @@ export const createRstestRuntime = (
5050
rs: rstest,
5151
},
5252
};
53+
54+
globalThis.RSTEST_API = runtime.api;
55+
56+
return runtime;
5357
};

packages/core/src/runtime/api/public.ts

Lines changed: 58 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,61 @@ import type { Rstest, RstestUtilities } from '../../types';
33
export type { Assertion } from '../../types/expect';
44
export type { Mock } from '../../types/mock';
55

6-
export declare const expect: Rstest['expect'];
7-
export declare const assert: Rstest['assert'];
8-
export declare const it: Rstest['it'];
9-
export declare const test: Rstest['test'];
10-
export declare const describe: Rstest['describe'];
11-
export declare const beforeAll: Rstest['beforeAll'];
12-
export declare const afterAll: Rstest['afterAll'];
13-
export declare const beforeEach: Rstest['beforeEach'];
14-
export declare const afterEach: Rstest['afterEach'];
15-
export declare const rstest: RstestUtilities;
16-
export declare const rs: RstestUtilities;
17-
export declare const onTestFinished: Rstest['onTestFinished'];
18-
export declare const onTestFailed: Rstest['onTestFailed'];
6+
declare global {
7+
var RSTEST_API: Rstest | undefined;
8+
}
9+
10+
const check = (name: keyof Rstest) => {
11+
if (!globalThis.RSTEST_API?.[name]) {
12+
throw new Error(
13+
`Rstest API '${name}' is not registered yet, please make sure you are running in a rstest environment.`,
14+
);
15+
}
16+
};
17+
18+
const wrapRstestAPI = <T extends keyof Omit<Rstest, 'rstest' | 'rs'>>(
19+
name: T,
20+
): Rstest[T] => {
21+
const fn = (...args: Parameters<Rstest[T]>) => {
22+
check(name);
23+
return globalThis.RSTEST_API![name].call(
24+
globalThis.RSTEST_API![name],
25+
// @ts-expect-error
26+
...args,
27+
);
28+
};
29+
30+
return new Proxy(fn, {
31+
get(_target, key, receiver) {
32+
check(name);
33+
return Reflect.get(globalThis.RSTEST_API?.[name] || {}, key, receiver);
34+
},
35+
}) as Rstest[T];
36+
};
37+
38+
const wrapRstestUtilitiesAPI = <T extends keyof Pick<Rstest, 'rstest' | 'rs'>>(
39+
name: T,
40+
): Rstest[T] => {
41+
return new Proxy({} as Rstest[T], {
42+
get(_target, key, receiver) {
43+
check(name);
44+
return Reflect.get(globalThis.RSTEST_API?.[name] || {}, key, receiver);
45+
},
46+
});
47+
};
48+
49+
export const expect: Rstest['expect'] = wrapRstestAPI('expect');
50+
export const assert: Rstest['assert'] = wrapRstestAPI('assert');
51+
export const it: Rstest['it'] = wrapRstestAPI('it');
52+
export const test: Rstest['test'] = wrapRstestAPI('test');
53+
export const describe: Rstest['describe'] = wrapRstestAPI('describe');
54+
export const beforeAll: Rstest['beforeAll'] = wrapRstestAPI('beforeAll');
55+
export const afterAll: Rstest['afterAll'] = wrapRstestAPI('afterAll');
56+
export const beforeEach: Rstest['beforeEach'] = wrapRstestAPI('beforeEach');
57+
export const afterEach: Rstest['afterEach'] = wrapRstestAPI('afterEach');
58+
export const rstest: RstestUtilities = wrapRstestUtilitiesAPI('rstest');
59+
export const rs: RstestUtilities = wrapRstestUtilitiesAPI('rs');
60+
export const onTestFinished: Rstest['onTestFinished'] =
61+
wrapRstestAPI('onTestFinished');
62+
export const onTestFailed: Rstest['onTestFailed'] =
63+
wrapRstestAPI('onTestFailed');

pnpm-lock.yaml

Lines changed: 6 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)