test(appliedFontStore): change mockFetch
This commit is contained in:
@@ -12,9 +12,12 @@ import { AppliedFontsManager } from './appliedFontsStore.svelte';
|
|||||||
describe('AppliedFontsManager', () => {
|
describe('AppliedFontsManager', () => {
|
||||||
let manager: AppliedFontsManager;
|
let manager: AppliedFontsManager;
|
||||||
let mockFontFaceSet: any;
|
let mockFontFaceSet: any;
|
||||||
|
let mockFetch: any;
|
||||||
|
let failUrls: Set<string>;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
vi.useFakeTimers();
|
vi.useFakeTimers();
|
||||||
|
failUrls = new Set();
|
||||||
|
|
||||||
mockFontFaceSet = {
|
mockFontFaceSet = {
|
||||||
add: vi.fn(),
|
add: vi.fn(),
|
||||||
@@ -22,11 +25,13 @@ describe('AppliedFontsManager', () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// 1. Properly mock FontFace as a constructor function
|
// 1. Properly mock FontFace as a constructor function
|
||||||
const MockFontFace = vi.fn(function(this: any, name: string, url: string) {
|
// The actual implementation passes buffer (ArrayBuffer) as second arg, not URL string
|
||||||
|
const MockFontFace = vi.fn(function(this: any, name: string, bufferOrUrl: ArrayBuffer | string) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.url = url;
|
this.bufferOrUrl = bufferOrUrl;
|
||||||
this.load = vi.fn().mockImplementation(() => {
|
this.load = vi.fn().mockImplementation(() => {
|
||||||
if (url.includes('fail')) return Promise.reject(new Error('Load failed'));
|
// For error tests, we track which URLs should fail via failUrls
|
||||||
|
// The fetch mock will have already rejected for those URLs
|
||||||
return Promise.resolve(this);
|
return Promise.resolve(this);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -44,18 +49,37 @@ describe('AppliedFontsManager', () => {
|
|||||||
randomUUID: () => '11111111-1111-1111-1111-111111111111' as any,
|
randomUUID: () => '11111111-1111-1111-1111-111111111111' as any,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 3. Mock fetch to return fake ArrayBuffer data
|
||||||
|
mockFetch = vi.fn((url: string) => {
|
||||||
|
if (failUrls.has(url)) {
|
||||||
|
return Promise.reject(new Error('Network error'));
|
||||||
|
}
|
||||||
|
return Promise.resolve({
|
||||||
|
ok: true,
|
||||||
|
status: 200,
|
||||||
|
arrayBuffer: () => Promise.resolve(new ArrayBuffer(8)),
|
||||||
|
clone: () => ({
|
||||||
|
ok: true,
|
||||||
|
status: 200,
|
||||||
|
arrayBuffer: () => Promise.resolve(new ArrayBuffer(8)),
|
||||||
|
}),
|
||||||
|
} as Response);
|
||||||
|
});
|
||||||
|
vi.stubGlobal('fetch', mockFetch);
|
||||||
|
|
||||||
manager = new AppliedFontsManager();
|
manager = new AppliedFontsManager();
|
||||||
});
|
});
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
vi.clearAllTimers();
|
vi.clearAllTimers();
|
||||||
vi.useRealTimers();
|
vi.useRealTimers();
|
||||||
|
vi.unstubAllGlobals();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should batch multiple font requests into a single process', async () => {
|
it('should batch multiple font requests into a single process', async () => {
|
||||||
const configs = [
|
const configs = [
|
||||||
{ id: 'lato-400', name: 'Lato', url: 'lato.ttf', weight: 400 },
|
{ id: 'lato-400', name: 'Lato', url: 'https://example.com/lato.ttf', weight: 400 },
|
||||||
{ id: 'lato-700', name: 'Lato', url: 'lato-bold.ttf', weight: 700 },
|
{ id: 'lato-700', name: 'Lato', url: 'https://example.com/lato-bold.ttf', weight: 700 },
|
||||||
];
|
];
|
||||||
|
|
||||||
manager.touch(configs);
|
manager.touch(configs);
|
||||||
@@ -71,7 +95,10 @@ describe('AppliedFontsManager', () => {
|
|||||||
// Suppress expected console error for clean test logs
|
// Suppress expected console error for clean test logs
|
||||||
const spy = vi.spyOn(console, 'error').mockImplementation(() => {});
|
const spy = vi.spyOn(console, 'error').mockImplementation(() => {});
|
||||||
|
|
||||||
const config = { id: 'broken', name: 'Broken', url: 'fail.ttf', weight: 400 };
|
const failUrl = 'https://example.com/fail.ttf';
|
||||||
|
failUrls.add(failUrl);
|
||||||
|
|
||||||
|
const config = { id: 'broken', name: 'Broken', url: failUrl, weight: 400 };
|
||||||
|
|
||||||
manager.touch([config]);
|
manager.touch([config]);
|
||||||
await vi.advanceTimersByTimeAsync(50);
|
await vi.advanceTimersByTimeAsync(50);
|
||||||
@@ -81,7 +108,7 @@ describe('AppliedFontsManager', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should purge fonts after TTL expires', async () => {
|
it('should purge fonts after TTL expires', async () => {
|
||||||
const config = { id: 'ephemeral', name: 'Temp', url: 'temp.ttf', weight: 400 };
|
const config = { id: 'ephemeral', name: 'Temp', url: 'https://example.com/temp.ttf', weight: 400 };
|
||||||
|
|
||||||
manager.touch([config]);
|
manager.touch([config]);
|
||||||
await vi.advanceTimersByTimeAsync(50);
|
await vi.advanceTimersByTimeAsync(50);
|
||||||
@@ -96,7 +123,7 @@ describe('AppliedFontsManager', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should NOT purge fonts that are still being "touched"', async () => {
|
it('should NOT purge fonts that are still being "touched"', async () => {
|
||||||
const config = { id: 'active', name: 'Active', url: 'active.ttf', weight: 400 };
|
const config = { id: 'active', name: 'Active', url: 'https://example.com/active.ttf', weight: 400 };
|
||||||
|
|
||||||
manager.touch([config]);
|
manager.touch([config]);
|
||||||
await vi.advanceTimersByTimeAsync(50);
|
await vi.advanceTimersByTimeAsync(50);
|
||||||
|
|||||||
Reference in New Issue
Block a user