Skip to content

Commit 06b791c

Browse files
authored
tests: Improve unit testing around LocationFull and LocationLite (#59)
1 parent 87825b2 commit 06b791c

File tree

2 files changed

+291
-255
lines changed

2 files changed

+291
-255
lines changed

src/lib/core/LocationFull.test.ts

Lines changed: 24 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -1,51 +1,21 @@
1-
import { afterEach, beforeAll, beforeEach, describe, expect, test, vi } from "vitest";
1+
import { afterEach, beforeEach, describe, expect, test, vi } from "vitest";
22
import { LocationFull } from "./LocationFull.js";
33
import type { State, Location } from "$lib/types.js";
4-
import { joinPaths } from "./RouterEngine.svelte.js";
4+
import { setupBrowserMocks, ALL_HASHES } from "../../testing/test-utils.js";
55

66
describe("LocationFull", () => {
77
const initialUrl = "http://example.com/";
8-
let interceptedState: State;
9-
const pushStateMock = vi.fn((state, _, url) => {
10-
url = !url.startsWith('http://') ? joinPaths(initialUrl, url) : url;
11-
globalThis.window.location.href = new URL(url).href;
12-
interceptedState = state;
13-
});
14-
const replaceStateMock = vi.fn((state, _, url) => {
15-
url = !url.startsWith('http://') ? joinPaths(initialUrl, url) : url;
16-
globalThis.window.location.href = new URL(url).href;
17-
interceptedState = state;
18-
});
198
let location: Location;
20-
let _href: string;
21-
beforeAll(() => {
22-
// @ts-expect-error Many missing features.
23-
globalThis.window.location = {
24-
get href() {
25-
return _href;
26-
},
27-
set href(value) {
28-
_href = value;
29-
}
30-
};
31-
// @ts-expect-error Many missing features.
32-
globalThis.window.history = {
33-
get state() {
34-
return interceptedState;
35-
},
36-
pushState: pushStateMock,
37-
replaceState: replaceStateMock
38-
};
39-
});
9+
let browserMocks: ReturnType<typeof setupBrowserMocks>;
10+
4011
beforeEach(() => {
41-
globalThis.window.location.href = initialUrl;
42-
interceptedState = { path: undefined, hash: {} };
43-
pushStateMock.mockReset();
44-
replaceStateMock.mockReset();
12+
browserMocks = setupBrowserMocks(initialUrl);
4513
location = new LocationFull();
4614
});
15+
4716
afterEach(() => {
4817
location.dispose();
18+
browserMocks.cleanup();
4919
});
5020
describe('constructor', () => {
5121
test("Should create a new instance with the expected default values.", () => {
@@ -60,7 +30,7 @@ describe("LocationFull", () => {
6030
const unSub = location.on('beforeNavigate', callback);
6131

6232
// Act.
63-
globalThis.window.history.pushState(null, '', 'http://example.com/other');
33+
browserMocks.history.pushState(null, '', 'http://example.com/other');
6434

6535
// Assert.
6636
expect(callback).toHaveBeenCalledOnce();
@@ -77,7 +47,7 @@ describe("LocationFull", () => {
7747
unSub();
7848

7949
// Assert.
80-
globalThis.window.history.pushState(null, '', 'http://example.com/other');
50+
browserMocks.history.pushState(null, '', 'http://example.com/other');
8151
expect(callback).not.toHaveBeenCalled();
8252
});
8353
test("Should not affect other handlers when unregistering one of the event handlers.", () => {
@@ -91,7 +61,7 @@ describe("LocationFull", () => {
9161
unSub1();
9262

9363
// Assert.
94-
globalThis.window.history.pushState(null, '', 'http://example.com/other');
64+
browserMocks.history.pushState(null, '', 'http://example.com/other');
9565
expect(callback1).not.toHaveBeenCalled();
9666
expect(callback2).toHaveBeenCalledOnce();
9767

@@ -115,7 +85,7 @@ describe("LocationFull", () => {
11585

11686
// Act.
11787
// @ts-expect-error stateFn cannot enumerate history.
118-
globalThis.window.history[stateFn](state, '', 'http://example.com/other');
88+
browserMocks.history[stateFn](state, '', 'http://example.com/other');
11989

12090
// Assert.
12191
expect(callback).toHaveBeenCalledWith({
@@ -137,7 +107,7 @@ describe("LocationFull", () => {
137107
const unSub2 = location.on('beforeNavigate', callback);
138108

139109
// Act.
140-
globalThis.window.history.pushState(null, '', 'http://example.com/other');
110+
browserMocks.history.pushState(null, '', 'http://example.com/other');
141111

142112
// Assert.
143113
expect(callback).toHaveBeenCalledWith({
@@ -161,7 +131,7 @@ describe("LocationFull", () => {
161131
const unSub3 = location.on('beforeNavigate', callback);
162132

163133
// Act.
164-
globalThis.window.history.pushState(null, '', 'http://example.com/other');
134+
browserMocks.history.pushState(null, '', 'http://example.com/other');
165135

166136
// Assert.
167137
expect(callback).toHaveBeenCalledWith({
@@ -190,11 +160,11 @@ describe("LocationFull", () => {
190160
const unSub = location.on('beforeNavigate', callback);
191161

192162
// Act.
193-
globalThis.window.history[stateFn](null, '', 'http://example.com/other');
163+
browserMocks.history[stateFn](null, '', 'http://example.com/other');
194164

195165
// Assert.
196166
expect(callback).toHaveBeenCalledOnce();
197-
expect(globalThis.window.history.state).deep.equal(state);
167+
expect(browserMocks.history.state).deep.equal(state);
198168

199169
// Cleanup.
200170
unSub();
@@ -206,7 +176,7 @@ describe("LocationFull", () => {
206176
const unSub2 = location.on('navigationCancelled', callback);
207177

208178
// Act.
209-
globalThis.window.history.pushState(null, '', 'http://example.com/other');
179+
browserMocks.history.pushState(null, '', 'http://example.com/other');
210180

211181
// Assert.
212182
expect(callback).toHaveBeenCalledOnce();
@@ -224,7 +194,7 @@ describe("LocationFull", () => {
224194
const unSub2 = location.on('navigationCancelled', callback);
225195

226196
// Act.
227-
globalThis.window.history.pushState(state, '', 'http://example.com/other');
197+
browserMocks.history.pushState(state, '', 'http://example.com/other');
228198

229199
// Assert.
230200
expect(callback).toHaveBeenCalledWith({ url: 'http://example.com/other', cause: 'test', method: 'push', state });
@@ -243,7 +213,7 @@ describe("LocationFull", () => {
243213
const newUrl = "http://example.com/new";
244214

245215
// Act.
246-
globalThis.window.history[fn](null, '', newUrl);
216+
browserMocks.history[fn](null, '', newUrl);
247217

248218
// Assert.
249219
expect(location.url.href).toBe(newUrl);
@@ -258,11 +228,11 @@ describe("LocationFull", () => {
258228
const state: State = { path: { test: 'value' }, hash: { single: '/abc', p1: '/def' } };
259229

260230
// Act.
261-
globalThis.window.history[fn](state, '', 'http://example.com/new');
231+
browserMocks.history[fn](state, '', 'http://example.com/new');
262232

263233
// Assert.
264-
expect(location.getState(false)).toEqual(state.path);
265-
expect(location.getState(true)).toEqual(state.hash.single);
234+
expect(location.getState(ALL_HASHES.path)).toEqual(state.path);
235+
expect(location.getState(ALL_HASHES.single)).toEqual(state.hash.single);
266236
expect(location.getState('p1')).toEqual(state.hash.p1);
267237
});
268238
});
@@ -273,14 +243,14 @@ describe("LocationFull", () => {
273243
])("Should preserve the previous valid state whenever %s is called with non-conformant state.", (stateFn) => {
274244
// Arrange.
275245
const validState = { path: { test: 'value' }, hash: {} };
276-
globalThis.window.history[stateFn](validState, '', 'http://example.com/');
246+
browserMocks.history[stateFn](validState, '', 'http://example.com/');
277247
const state = { test: 'value' };
278248

279249
// Act.
280-
globalThis.window.history[stateFn](state, '', 'http://example.com/other');
250+
browserMocks.history[stateFn](state, '', 'http://example.com/other');
281251

282252
// Assert.
283-
expect(globalThis.window.history.state).deep.equals(validState);
253+
expect(browserMocks.history.state).deep.equals(validState);
284254
});
285255
});
286256
});

0 commit comments

Comments
 (0)