Skip to content

Commit e847f96

Browse files
committed
fix dist packaging and align test layout
Prevent test files from leaking into published output and move data specs under `test` so build and test typechecking stay in sync. Made-with: Cursor
1 parent 60f9b30 commit e847f96

File tree

10 files changed

+145
-87
lines changed

10 files changed

+145
-87
lines changed

.changeset/fuzzy-pens-repair.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
"@solidjs/router": patch
3+
---
4+
5+
Fix the published package contents so `dist` no longer includes mirrored `src`, `test`, or co-located spec files.
6+
7+
Also move the data tests under `test/` and align the test TypeScript config with that layout so `test:types` continues to pass cleanly.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
],
3030
"sideEffects": false,
3131
"scripts": {
32-
"build": "tsc && rollup -c",
32+
"build": "rm -rf dist && tsc && rollup -c",
3333
"prepublishOnly": "npm run build",
3434
"test": "vitest run && npm run test:types",
3535
"test:watch": "vitest",

test/data.spec.tsx

Lines changed: 96 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@ import {
22
ErrorBoundary,
33
ParentProps,
44
Suspense,
5-
catchError,
65
createRoot,
76
createSignal
87
} from "solid-js";
98
import { render } from "solid-js/web";
9+
import { vi } from "vitest";
1010
import { createAsync } from "../src/data/createAsync.js";
1111
import { awaitPromise } from "./helpers.js";
1212

@@ -22,36 +22,76 @@ async function getError(arg?: any): Promise<any> {
2222
}
2323

2424
describe("createAsync should", () => {
25-
test("return 'fallback'", () => {
26-
createRoot(() => {
27-
const data = createAsync(() => getText());
28-
setTimeout(() => expect(data()).toBe("fallback"), 1);
29-
});
25+
test("return 'fallback'", async () => {
26+
let dispose!: () => void;
27+
try {
28+
await new Promise<void>(resolve => {
29+
createRoot(cleanup => {
30+
dispose = cleanup;
31+
const data = createAsync(() => getText());
32+
setTimeout(() => {
33+
expect(data()).toBe("fallback");
34+
resolve();
35+
}, 1);
36+
});
37+
});
38+
} finally {
39+
dispose?.();
40+
}
3041
});
31-
test("return 'text'", () => {
32-
createRoot(() => {
33-
const data = createAsync(() => getText("text"));
34-
setTimeout(() => expect(data()).toBe("text"), 1);
35-
});
42+
test("return 'text'", async () => {
43+
let dispose!: () => void;
44+
try {
45+
await new Promise<void>(resolve => {
46+
createRoot(cleanup => {
47+
dispose = cleanup;
48+
const data = createAsync(() => getText("text"));
49+
setTimeout(() => {
50+
expect(data()).toBe("text");
51+
resolve();
52+
}, 1);
53+
});
54+
});
55+
} finally {
56+
dispose?.();
57+
}
3658
});
37-
test("initial error to be caught ", () => {
38-
createRoot(() => {
59+
test("initial error to be caught ", async () => {
60+
const consoleError = vi.spyOn(console, "error").mockImplementation(() => {});
61+
const dispose = render(() => {
3962
const data = createAsync(() => getError());
40-
setTimeout(() => catchError(data, err => expect(err).toBeInstanceOf(Error)), 1);
41-
});
63+
64+
return (
65+
<ErrorBoundary fallback={<div id="childError" />}>
66+
<Suspense>{data()}</Suspense>
67+
</ErrorBoundary>
68+
);
69+
}, document.body);
70+
71+
try {
72+
await awaitPromise();
73+
expect(document.getElementById("childError")).not.toBeNull();
74+
} finally {
75+
consoleError.mockRestore();
76+
document.body.innerHTML = "";
77+
dispose();
78+
}
4279
});
43-
test("catch error after arg change - initial valid", () =>
44-
createRoot(async dispose => {
45-
async function throwWhenError(arg: string): Promise<string> {
46-
if (arg === "error") throw new Error("error");
47-
return arg;
48-
}
49-
50-
const [arg, setArg] = createSignal("");
51-
function Child() {
52-
const data = createAsync(() => throwWhenError(arg()));
53-
54-
return (
80+
test("catch error after arg change - initial valid", async () => {
81+
async function throwWhenError(arg: string): Promise<string> {
82+
if (arg === "error") throw new Error("error");
83+
return arg;
84+
}
85+
86+
let setArg!: (value: string) => string;
87+
const dispose = render(() => {
88+
const [arg, updateArg] = createSignal("");
89+
setArg = updateArg;
90+
91+
const data = createAsync(() => throwWhenError(arg()));
92+
93+
return (
94+
<Parent>
5595
<div id="child">
5696
<ErrorBoundary
5797
fallback={(_, reset) => (
@@ -72,48 +112,45 @@ describe("createAsync should", () => {
72112
</Suspense>
73113
</ErrorBoundary>
74114
</div>
75-
);
76-
}
77-
await render(
78-
() => (
79-
<Parent>
80-
<Child />
81-
</Parent>
82-
),
83-
document.body
115+
</Parent>
84116
);
117+
}, document.body);
118+
119+
try {
85120
const childErrorElement = () => document.getElementById("childError");
86121
const parentErrorElement = document.getElementById("parentError");
87122
expect(childErrorElement()).toBeNull();
88123
expect(parentErrorElement).toBeNull();
124+
89125
setArg("error");
90126
await awaitPromise();
91127

92-
// after changing the arg the error should still be caught by the Child's ErrorBoundary
93128
expect(childErrorElement()).not.toBeNull();
94129
expect(parentErrorElement).toBeNull();
95130

96-
//reset ErrorBoundary
97131
document.getElementById("reset")?.click();
98132

99133
expect(childErrorElement()).toBeNull();
100134
await awaitPromise();
101-
const dataEl = () => document.getElementById("data");
102135

103-
expect(dataEl()).not.toBeNull();
136+
expect(document.getElementById("data")).not.toBeNull();
104137
expect(document.getElementById("data")?.innerHTML).toBe("true");
105138
expect(document.getElementById("latest")?.innerHTML).toBe("true");
106-
139+
} finally {
107140
document.body.innerHTML = "";
108141
dispose();
109-
}));
110-
test("catch consecutive error after initial error change to be caught after arg change", () =>
111-
createRoot(async cleanup => {
112-
const [arg, setArg] = createSignal("error");
113-
function Child() {
114-
const data = createAsync(() => getError(arg()));
115-
116-
return (
142+
}
143+
});
144+
test("catch consecutive error after initial error change to be caught after arg change", async () => {
145+
let setArg!: (value: string) => string;
146+
const dispose = render(() => {
147+
const [arg, updateArg] = createSignal("error");
148+
setArg = updateArg;
149+
150+
const data = createAsync(() => getError(arg()));
151+
152+
return (
153+
<Parent>
117154
<div id="child">
118155
<ErrorBoundary
119156
fallback={(_, reset) => (
@@ -125,32 +162,28 @@ describe("createAsync should", () => {
125162
<Suspense>{data()}</Suspense>
126163
</ErrorBoundary>
127164
</div>
128-
);
129-
}
130-
await render(
131-
() => (
132-
<Parent>
133-
<Child />
134-
</Parent>
135-
),
136-
document.body
165+
</Parent>
137166
);
167+
}, document.body);
138168

139-
// Child's ErrorBoundary should catch the error
169+
try {
170+
await awaitPromise();
140171
expect(document.getElementById("childError")).not.toBeNull();
141172
expect(document.getElementById("parentError")).toBeNull();
173+
142174
setArg("error_2");
143175
await awaitPromise();
144-
// after changing the arg the error should still be caught by the Child's ErrorBoundary
176+
145177
expect(document.getElementById("childError")).not.toBeNull();
146178
expect(document.getElementById("parentError")).toBeNull();
147179

148180
document.getElementById("reset")?.click();
149181
await awaitPromise();
150182
expect(document.getElementById("childError")).not.toBeNull();
151183
expect(document.getElementById("parentError")).toBeNull();
152-
184+
} finally {
153185
document.body.innerHTML = "";
154-
cleanup();
155-
}));
186+
dispose();
187+
}
188+
});
156189
});
Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,26 @@
11
import { createRoot } from "solid-js";
22
import { vi } from "vitest";
3-
import { action, useAction, useSubmission, useSubmissions, actions } from "./action.js";
4-
import type { RouterContext } from "../types.js";
5-
import { createMockRouter } from "../../test/helpers.js";
6-
7-
vi.mock("../src/utils.js", () => ({
8-
mockBase: "https://action"
9-
}));
3+
import {
4+
action,
5+
useAction,
6+
useSubmission,
7+
useSubmissions,
8+
actions
9+
} from "../../src/data/action.js";
10+
import type { RouterContext } from "../../src/types.js";
11+
import { createMockRouter } from "../helpers.js";
12+
13+
vi.mock("../../src/utils.js", async importOriginal => {
14+
const actual = await importOriginal<typeof import("../../src/utils.js")>();
15+
return {
16+
...actual,
17+
mockBase: "https://action"
18+
};
19+
});
1020

1121
let mockRouterContext: RouterContext;
1222

13-
vi.mock("../routing.js", () => ({
23+
vi.mock("../../src/routing.js", () => ({
1424
useRouter: () => mockRouterContext,
1525
createRouterContext: () => createMockRouter(),
1626
RouterContextObj: {},
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { createRoot } from "solid-js";
22
import { vi } from "vitest";
3-
import { createAsync, createAsyncStore } from "./createAsync.js";
3+
import { createAsync, createAsyncStore } from "../../src/data/createAsync.js";
44

55
vi.mock("solid-js", async () => {
66
const actual = await vi.importActual("solid-js");
Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
11
import { createRoot, createSignal } from "solid-js";
22
import { vi } from "vitest";
3-
import { setupNativeEvents } from "./events.js";
4-
import type { RouterContext } from "../types.js";
5-
import { createMockRouter } from "../../test/helpers.js";
3+
import { setupNativeEvents } from "../../src/data/events.js";
4+
import type { RouterContext } from "../../src/types.js";
5+
import { createMockRouter } from "../helpers.js";
66

7-
vi.mock("../src/data/action.js", () => ({
7+
vi.mock("../../src/data/action.js", () => ({
88
actions: new Map()
99
}));
1010

11-
import { actions } from "./action.js";
11+
import { actions } from "../../src/data/action.js";
1212

13-
vi.mock("../src/utils.js", () => ({
13+
vi.mock("../../src/utils.js", () => ({
1414
mockBase: "https://action"
1515
}));
1616

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,17 @@
11
import { createRoot } from "solid-js";
22
import { vi } from "vitest";
3-
import { query, revalidate, cacheKeyOp, hashKey, cache } from "./query.js";
4-
import { createMockRouter } from "../../test/helpers.js";
3+
import {
4+
query,
5+
revalidate,
6+
cacheKeyOp,
7+
hashKey,
8+
cache
9+
} from "../../src/data/query.js";
10+
import { createMockRouter } from "../helpers.js";
511

612
const mockRouter = createMockRouter();
713

8-
vi.mock("../routing.js", () => ({
14+
vi.mock("../../src/routing.js", () => ({
915
useRouter: () => mockRouter,
1016
useNavigate: () => vi.fn(),
1117
getIntent: () => "navigate",
@@ -229,7 +235,7 @@ describe("revalidate", () => {
229235
expect(result1).toBe("data-1");
230236
expect(callCount).toBe(1);
231237

232-
await revalidate(); // Force revalidation and wait for transition
238+
await revalidate();
233239
vi.runAllTimers();
234240

235241
const result2 = await cachedFn();
@@ -385,7 +391,7 @@ describe("cacheKeyOp should", () => {
385391
operationCount++;
386392
});
387393

388-
expect(operationCount).toBe(2); // Should match both query1[1] and query1[2]
394+
expect(operationCount).toBe(2);
389395
});
390396
});
391397
});
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { redirect, reload, json } from "./response.js";
1+
import { redirect, reload, json } from "../../src/data/response.js";
22

33
describe("redirect", () => {
44
test("should create redirect response with default `302` status", () => {

tsconfig.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,11 @@
77
"strict": true,
88
"jsx": "preserve",
99
"jsxImportSource": "solid-js",
10+
"rootDir": "./src",
1011
"outDir": "./dist",
1112
"module": "NodeNext",
1213
"skipLibCheck": true
1314
},
1415
"include": ["./src"],
15-
"exclude": ["node_modules/"]
16+
"exclude": ["node_modules/", "src/**/*.spec.ts"]
1617
}

tsconfig.test.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@
22
"extends": "./tsconfig.json",
33
"compilerOptions": {
44
"noEmit": true,
5-
"skipLibCheck": true
5+
"skipLibCheck": true,
6+
"rootDir": "."
67
},
78
"include": ["test"],
89
"exclude": ["node_modules"]

0 commit comments

Comments
 (0)