forked from Lundalogik/lime-elements
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathvitest-setup.ts
More file actions
142 lines (125 loc) · 4.66 KB
/
vitest-setup.ts
File metadata and controls
142 lines (125 loc) · 4.66 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
/* eslint-disable @typescript-eslint/no-unused-vars */
// Load Stencil custom matchers (toEqualHtml, toHaveAttribute, etc.)
import '@stencil/vitest';
// Load Stencil components (built by stencil-test before Vitest runs)
await import('./dist/lime-elements/lime-elements.esm.js');
// Set default language for translation lookups in components
if (document?.documentElement && !document.documentElement.lang) {
document.documentElement.lang = 'en';
}
// Set window.location for URL resolution in link plugins
if (
typeof window !== 'undefined' &&
(!window.location.hostname || window.location.hostname === '')
) {
Object.defineProperty(window, 'location', {
value: new URL('http://localhost:3333'),
writable: true,
});
}
// Mock localStorage for tests (used by config.ts)
if (globalThis.localStorage === undefined) {
const store: Record<string, string> = {};
globalThis.localStorage = {
getItem: (key: string) => store[key] ?? null,
setItem: (key: string, value: string) => {
store[key] = value;
},
removeItem: (key: string) => {
delete store[key];
},
clear: () => {
for (const k of Object.keys(store)) delete store[k];
},
get length() {
return Object.keys(store).length;
},
key: (index: number) => Object.keys(store)[index] ?? null,
} as Storage;
}
// Reset localStorage store before every test to prevent cross-test leakage
import { beforeEach } from 'vitest';
beforeEach(() => {
globalThis.localStorage?.clear();
});
// Mock IntersectionObserver for tests
if (!global.IntersectionObserver) {
global.IntersectionObserver = class IntersectionObserver {
constructor(
_callback: IntersectionObserverCallback,
_options?: IntersectionObserverInit
) {}
observe(_target: Element): void {}
unobserve(_target: Element): void {}
disconnect(): void {}
readonly root: Element | null = null;
readonly rootMargin: string = '';
readonly thresholds: ReadonlyArray<number> = [];
takeRecords(): IntersectionObserverEntry[] {
return [];
}
} as any;
}
// Mock fetch for icon/asset requests (mock-doc has no real network)
const EMPTY_SVG =
'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"></svg>';
const originalFetch =
globalThis.fetch ??
((() => {
throw new TypeError('fetch is not available in this environment');
}) as typeof fetch);
globalThis.fetch = async (input: RequestInfo | URL, init?: RequestInit) => {
const url = typeof input === 'string' ? input : input.toString();
if (url.endsWith('.svg') || url.startsWith('assets/')) {
return new Response(EMPTY_SVG, {
status: 200,
headers: { 'Content-Type': 'image/svg+xml' },
});
}
return originalFetch(input, init);
};
// Patch DOMParser to handle SVG (mock-doc only supports text/html)
if (globalThis.DOMParser) {
const OriginalDOMParser = globalThis.DOMParser;
globalThis.DOMParser = class extends OriginalDOMParser {
parseFromString(str: string, type: DOMParserSupportedType): Document {
if (type === 'image/svg+xml') {
// Parse as HTML but wrap result so documentElement.tagName is 'svg'
const doc = super.parseFromString(str, 'text/html');
const svg = doc.querySelector('svg');
if (svg) {
const svgDoc = super.parseFromString(
'<svg></svg>',
'text/html'
);
// Replace the documentElement to make validation pass
Object.defineProperty(svgDoc, 'documentElement', {
get: () => svg,
});
return svgDoc;
}
// No <svg> root found — return an empty SVG document rather
// than delegating to the unsupported image/svg+xml type.
return super.parseFromString('<svg></svg>', 'text/html');
}
return super.parseFromString(str, type);
}
} as any;
}
// Mock ResizeObserver for tests
if (!global.ResizeObserver) {
global.ResizeObserver = class ResizeObserver {
constructor(_callback: ResizeObserverCallback) {
// Mock implementation - just store the callback
}
observe(_target: Element): void {
// Mock implementation
}
unobserve(_target: Element): void {
// Mock implementation
}
disconnect(): void {
// Mock implementation
}
};
}