Skip to content

Commit 1337db0

Browse files
authored
feat: Add location stub utility (#28)
* feat: Add `location` stub from prerenderer as a utility * fix: Setup `globalThis.location` & support class methods * test: Add tests for locationStub utility
1 parent 6cfff8b commit 1337db0

File tree

3 files changed

+55
-0
lines changed

3 files changed

+55
-0
lines changed

src/prerender.d.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,5 @@ export default function prerender(
1313
vnode: VNode,
1414
options?: PrerenderOptions
1515
): Promise<PrerenderResult>;
16+
17+
export function locationStub(path: string): void;

src/prerender.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,3 +40,20 @@ export default async function prerender(vnode, options) {
4040
vnodeHook = null;
4141
}
4242
}
43+
44+
/**
45+
* Update `location` to current URL so routers can use things like `location.pathname`
46+
*
47+
* @param {string} path - current URL path
48+
*/
49+
export function locationStub(path) {
50+
globalThis.location = {};
51+
const u = new URL(path, 'http://localhost');
52+
for (const i in u) {
53+
try {
54+
globalThis.location[i] = /to[A-Z]/.test(i)
55+
? u[i].bind(u)
56+
: String(u[i]);
57+
} catch {}
58+
}
59+
}

test/location-stub.test.js

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import { describe, it, beforeEach, expect } from '@jest/globals';
2+
import { locationStub } from '../src/prerender.js';
3+
4+
describe('location-stub', () => {
5+
beforeEach(() => {
6+
if (globalThis.location) {
7+
delete globalThis.location;
8+
}
9+
});
10+
11+
it('Contains all Location instance properties', () => {
12+
locationStub('/foo/bar?baz=qux#quux');
13+
14+
[
15+
// 'ancestorOrigins', // Not supported by FireFox and sees little use, but we could add an empty val if it's needed
16+
'hash',
17+
'host',
18+
'hostname',
19+
'href',
20+
'origin',
21+
'pathname',
22+
'port',
23+
'protocol',
24+
'search',
25+
].forEach(key => {
26+
expect(globalThis.location).toHaveProperty(key);
27+
});
28+
});
29+
30+
// Do we need to support `assign`, `reload`, and/or `replace`?
31+
it('Support bound methods', () => {
32+
locationStub('/foo/bar?baz=qux#quux');
33+
34+
expect(globalThis.location.toString()).toBe('http://localhost/foo/bar?baz=qux#quux');
35+
});
36+
});

0 commit comments

Comments
 (0)