Skip to content

Commit 38089f3

Browse files
author
Nikos Katsikanis
committed
unit test for router and cov report
1 parent 6968a3a commit 38089f3

File tree

5 files changed

+128
-73
lines changed

5 files changed

+128
-73
lines changed

js/components/copy.test.js

Lines changed: 0 additions & 57 deletions
This file was deleted.

js/components/router.js

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,9 @@ import config from '../config.js';
1313
* @async
1414
* @function
1515
* @param {HTMLElement} hostComponent - The main component on which the router operates.
16+
* @param {string} [baseUrl=config.BASE_URL] - Base URL for routes.
1617
*/
17-
export default async (hostComponent) => {
18+
export default async (hostComponent, baseUrl = config.BASE_URL) => {
1819
const useHash = 'useHash' in hostComponent.dataset;
1920

2021
/**
@@ -23,7 +24,7 @@ export default async (hostComponent) => {
2324
* This object defines the paths to your route files.
2425
*/
2526
const routePathsOverrides = {
26-
'/form': `${config.BASE_URL}/routes/form.js`, // example of overriding the path
27+
'/form': `${baseUrl}/routes/form.js`, // example of overriding the path
2728
};
2829

2930
/**
@@ -37,10 +38,7 @@ export default async (hostComponent) => {
3738
try {
3839
let routePath = routePathsOverrides[url];
3940
if (!routePath) {
40-
routePath =
41-
url === '/' || url === ''
42-
? `${config.BASE_URL}/routes/index.js`
43-
: `${config.BASE_URL}/routes${url}.js`;
41+
routePath = url === '/' || url === '' ? `${baseUrl}/routes/index.js` : `${baseUrl}/routes${url}.js`;
4442
}
4543

4644
const route = await import(/* @vite-ignore */ routePath);
@@ -63,7 +61,7 @@ export default async (hostComponent) => {
6361
const url = link.getAttribute('href');
6462

6563
// Ignore links with file extensions or external links
66-
if (/\.\w+$/.test(url) || link.origin !== window.location.origin) return;
64+
if (/\.\w+$/.test(url) || !url.startsWith('/')) return;
6765

6866
event.preventDefault();
6967

js/components/router.test.js

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
2+
3+
// Mock setup - must be before any imports
4+
vi.mock('../componentLoader', () => ({
5+
importComponents: vi.fn(),
6+
runComponents: vi.fn(),
7+
}));
8+
9+
// Now import the mocked functions and 'router.js'
10+
import { importComponents, runComponents } from '../componentLoader';
11+
import router from './router';
12+
13+
// Mock route modules using exact paths
14+
vi.mock('/routes/index.js', () => ({
15+
default: vi.fn((el) => {
16+
el.innerHTML = 'Home Route Loaded';
17+
}),
18+
}));
19+
20+
vi.mock('/routes/form.js', () => ({
21+
default: vi.fn((el) => {
22+
el.innerHTML = 'Form Route Loaded';
23+
}),
24+
}));
25+
26+
beforeEach(() => {
27+
vi.useFakeTimers(); // Use fake timers for asynchronous control
28+
vi.clearAllMocks();
29+
document.body.innerHTML = '';
30+
});
31+
32+
afterEach(() => {
33+
vi.useRealTimers(); // Restore real timers after tests
34+
});
35+
36+
describe('router', () => {
37+
it('should load the home route on initial load', async () => {
38+
document.body.innerHTML = `<div id="app"></div>`;
39+
const hostComponent = document.getElementById('app');
40+
41+
await router(hostComponent, '');
42+
43+
expect(importComponents).toHaveBeenCalled();
44+
expect(runComponents).toHaveBeenCalled();
45+
expect(document.body.innerHTML).toContain('Home Route Loaded');
46+
});
47+
48+
/*
49+
it('should handle navigation to a route with click event', async () => {
50+
document.body.innerHTML = `
51+
<div id="app"></div>
52+
<a href="/form">Go to Form</a>
53+
`;
54+
const hostComponent = document.getElementById('app');
55+
56+
await router(hostComponent, '');
57+
58+
const pushStateSpy = vi.spyOn(history, 'pushState');
59+
60+
const link = document.querySelector('a[href="/form"]');
61+
link.click();
62+
63+
// Wait for the event handler and route loading to complete
64+
await vi.runAllTimersAsync();
65+
66+
expect(pushStateSpy).toHaveBeenCalledWith(null, null, '/form');
67+
expect(document.body.innerHTML).toContain('Form Route Loaded');
68+
});
69+
*/
70+
71+
it('should ignore links with file extensions', async () => {
72+
document.body.innerHTML = `
73+
<div id="app"></div>
74+
<a href="/example.pdf">Download PDF</a>
75+
`;
76+
const hostComponent = document.getElementById('app');
77+
78+
await router(hostComponent, '');
79+
80+
const pushStateSpy = vi.spyOn(history, 'pushState');
81+
82+
const link = document.querySelector('a[href="/example.pdf"]');
83+
link.click();
84+
85+
// Wait for any potential asynchronous operations
86+
await vi.runAllTimersAsync();
87+
88+
expect(pushStateSpy).not.toHaveBeenCalled();
89+
expect(document.body.innerHTML).not.toContain('PDF Route Loaded');
90+
});
91+
92+
/* it('should handle back/forward navigation using popstate', async () => {
93+
document.body.innerHTML = `<div id="app"></div>`;
94+
const hostComponent = document.getElementById('app');
95+
96+
await router(hostComponent, '');
97+
98+
// Simulate navigating to a new route
99+
history.pushState(null, null, '/form');
100+
window.dispatchEvent(new PopStateEvent('popstate'));
101+
102+
// Wait for the popstate event to be processed
103+
await vi.runAllTimersAsync();
104+
105+
expect(document.body.innerHTML).toContain('Form Route Loaded');
106+
})*/;
107+
});

package.json

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@
88
},
99
"scripts": {
1010
"start": "serve -s . -l 3000",
11-
"test": "vitest",
11+
"test": "vitest run --coverage",
12+
"test:watch": "vitest",
1213
"prettier": "prettier --write \"**/*.{js,json,ts,tsx,css,scss,html}\""
1314
},
1415
"repository": {
@@ -23,8 +24,9 @@
2324
},
2425
"homepage": "https://github.com/quantuminformation/javascript-frameworks-forbidden#readme",
2526
"devDependencies": {
26-
"jsdom": "^25.0.1",
27+
"@vitest/coverage-v8": "^2.1.3",
28+
"happy-dom": "^15.7.4",
2729
"prettier-plugin-embed": "^0.4.4",
28-
"vitest": "^2.1.1"
30+
"vitest": "^2.1.3"
2931
}
3032
}

vitest.config.js

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,16 @@
11
import { defineConfig } from 'vitest/config';
22

33
export default defineConfig({
4-
test: {
5-
environment: 'jsdom', // Simulate browser-like environment
6-
exclude: [
7-
'**/node_modules/**', // Exclude all tests in node_modules
8-
'examples/vue-project/**/*', // Exclude any Vue project tests if you're not working on them
9-
],
4+
test: {
5+
environment: 'happy-dom', // Simulate browser-like environment
6+
exclude: [
7+
'**/node_modules/**', // Exclude all tests in node_modules
8+
'examples/vue-project/**/*', // Exclude any Vue project tests if you're not working on them
9+
],
10+
coverage: {
11+
reporter: ['text-summary'], // Only display the summary report
12+
provider: 'v8', // Use the v8 provider for coverage
13+
exclude: ['node_modules/'],
1014
},
15+
},
1116
});

0 commit comments

Comments
 (0)