Skip to content

Commit 204082f

Browse files
author
Sébastien Henau
committed
tests: add flareVue tests
1 parent 01e07a5 commit 204082f

File tree

1 file changed

+250
-0
lines changed

1 file changed

+250
-0
lines changed

packages/vue/tests/flareVue.test.ts

Lines changed: 250 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { beforeEach, describe, expect, test, vi } from 'vitest';
22
import type { ComponentPublicInstance } from 'vue';
33

44
import { flareVue } from '../src/flareVue';
5+
import type { FlareVueContext, FlareVueOptions } from '../src/types';
56

67
const mockReport = vi.fn();
78

@@ -239,4 +240,253 @@ describe('flareVue', () => {
239240
app.config.errorHandler!(new Error('original'), null, 'setup function');
240241
}).toThrow('report failed');
241242
});
243+
244+
test('works without options', () => {
245+
const app = createMockApp();
246+
(flareVue as Function)(app);
247+
248+
callHandler(app, new Error('test'), null, 'setup function');
249+
250+
expect(mockReport).toHaveBeenCalledOnce();
251+
});
252+
253+
test('calls beforeEvaluate before building context and reporting', () => {
254+
const callOrder: string[] = [];
255+
256+
const beforeEvaluate = vi.fn(() => callOrder.push('beforeEvaluate'));
257+
mockReport.mockImplementation(() => callOrder.push('report'));
258+
259+
const app = createMockApp();
260+
(flareVue as Function)(app, { beforeEvaluate } satisfies FlareVueOptions);
261+
262+
callHandler(app, new Error('test'), null, 'setup function');
263+
264+
expect(beforeEvaluate).toHaveBeenCalledOnce();
265+
expect(callOrder).toEqual(['beforeEvaluate', 'report']);
266+
});
267+
268+
test('calls beforeEvaluate with error, instance, and info', () => {
269+
const beforeEvaluate = vi.fn();
270+
271+
const app = createMockApp();
272+
(flareVue as Function)(app, { beforeEvaluate } satisfies FlareVueOptions);
273+
274+
const error = new Error('test');
275+
const instance = createMockInstance('MyComponent');
276+
277+
callHandler(app, error, instance, 'setup function');
278+
279+
expect(beforeEvaluate.mock.calls[0][0].error).toBe(error);
280+
expect(beforeEvaluate.mock.calls[0][0].instance).toBe(instance);
281+
expect(beforeEvaluate.mock.calls[0][0].info).toBe('setup function');
282+
});
283+
284+
test('passes the converted error (not raw value) to beforeEvaluate', () => {
285+
const beforeEvaluate = vi.fn();
286+
287+
const app = createMockApp();
288+
(flareVue as Function)(app, { beforeEvaluate } satisfies FlareVueOptions);
289+
290+
callHandler(app, 'string error', null, 'setup function');
291+
292+
expect(beforeEvaluate.mock.calls[0][0].error).toBeInstanceOf(Error);
293+
expect(beforeEvaluate.mock.calls[0][0].error.message).toBe('string error');
294+
});
295+
296+
test('calls beforeSubmit after beforeEvaluate and before reporting', () => {
297+
const callOrder: string[] = [];
298+
299+
const beforeEvaluate = vi.fn(() => callOrder.push('beforeEvaluate'));
300+
const beforeSubmit = vi.fn((params: { context: FlareVueContext }) => {
301+
callOrder.push('beforeSubmit');
302+
return params.context;
303+
});
304+
mockReport.mockImplementation(() => callOrder.push('report'));
305+
306+
const app = createMockApp();
307+
(flareVue as Function)(app, { beforeEvaluate, beforeSubmit } satisfies FlareVueOptions);
308+
309+
callHandler(app, new Error('test'), null, 'setup function');
310+
311+
expect(beforeSubmit).toHaveBeenCalledOnce();
312+
expect(callOrder).toEqual(['beforeEvaluate', 'beforeSubmit', 'report']);
313+
});
314+
315+
test('calls beforeSubmit with error, instance, info, and context', () => {
316+
const beforeSubmit = vi.fn(
317+
(params: { error: Error; instance: unknown; info: string; context: FlareVueContext }) => params.context
318+
);
319+
320+
const app = createMockApp();
321+
(flareVue as Function)(app, { beforeSubmit } satisfies FlareVueOptions);
322+
323+
const error = new Error('test');
324+
const instance = createMockInstance('MyComponent');
325+
326+
callHandler(app, error, instance, 'render function');
327+
328+
expect(beforeSubmit.mock.calls[0][0].error).toBe(error);
329+
expect(beforeSubmit.mock.calls[0][0].instance).toBe(instance);
330+
expect(beforeSubmit.mock.calls[0][0].info).toBe('render function');
331+
expect(beforeSubmit.mock.calls[0][0].context.vue.componentName).toBe('MyComponent');
332+
expect(beforeSubmit.mock.calls[0][0].context.vue.componentHierarchy).toEqual(['MyComponent']);
333+
});
334+
335+
test('beforeSubmit can modify the context before reporting', () => {
336+
const customHierarchy = ['Custom', 'Modified'];
337+
const beforeSubmit = vi.fn(({ context }: { context: FlareVueContext }) => ({
338+
...context,
339+
vue: {
340+
...context.vue,
341+
componentHierarchy: customHierarchy,
342+
},
343+
}));
344+
345+
const app = createMockApp();
346+
(flareVue as Function)(app, { beforeSubmit } satisfies FlareVueOptions);
347+
348+
callHandler(app, new Error('test'), createMockInstance('MyComponent'), 'setup function');
349+
350+
const reportedContext = mockReport.mock.calls[0][1];
351+
expect(reportedContext.vue.componentHierarchy).toBe(customHierarchy);
352+
});
353+
354+
test('uses original context when beforeSubmit does not return', () => {
355+
const beforeSubmit = vi.fn(() => {
356+
// user forgot to return context
357+
});
358+
359+
const app = createMockApp();
360+
// @ts-expect-error - intentionally testing a user mistake where beforeSubmit does not return
361+
(flareVue as Function)(app, { beforeSubmit });
362+
363+
callHandler(app, new Error('test'), createMockInstance('MyComponent'), 'setup function');
364+
365+
expect(beforeSubmit).toHaveBeenCalledOnce();
366+
const reportedContext = mockReport.mock.calls[0][1];
367+
expect(reportedContext.vue.componentName).toBe('MyComponent');
368+
});
369+
370+
test('calls afterSubmit after reporting', () => {
371+
const callOrder: string[] = [];
372+
373+
mockReport.mockImplementation(() => callOrder.push('report'));
374+
const afterSubmit = vi.fn(() => {
375+
callOrder.push('afterSubmit');
376+
});
377+
378+
const app = createMockApp();
379+
(flareVue as Function)(app, { afterSubmit } satisfies FlareVueOptions);
380+
381+
const error = new Error('test');
382+
const instance = createMockInstance('MyComponent');
383+
384+
callHandler(app, error, instance, 'render function');
385+
386+
expect(afterSubmit).toHaveBeenCalledOnce();
387+
expect(afterSubmit.mock.calls[0][0].error).toBe(error);
388+
expect(afterSubmit.mock.calls[0][0].instance).toBe(instance);
389+
expect(afterSubmit.mock.calls[0][0].info).toBe('render function');
390+
expect(afterSubmit.mock.calls[0][0].context.vue.componentHierarchy).toBeInstanceOf(Array);
391+
expect(callOrder).toEqual(['report', 'afterSubmit']);
392+
});
393+
394+
test('beforeSubmit modified context is passed to afterSubmit', () => {
395+
const customHierarchy = ['Custom', 'Modified'];
396+
const beforeSubmit = vi.fn(({ context }: { context: FlareVueContext }) => ({
397+
...context,
398+
vue: {
399+
...context.vue,
400+
componentHierarchy: customHierarchy,
401+
},
402+
}));
403+
const afterSubmit = vi.fn();
404+
405+
const app = createMockApp();
406+
(flareVue as Function)(app, { beforeSubmit, afterSubmit } satisfies FlareVueOptions);
407+
408+
callHandler(app, new Error('test'), createMockInstance('MyComponent'), 'setup function');
409+
410+
expect(afterSubmit.mock.calls[0][0].context.vue.componentHierarchy).toBe(customHierarchy);
411+
});
412+
413+
test('beforeEvaluate throwing prevents reporting and propagates', () => {
414+
const beforeEvaluate = vi.fn(() => {
415+
throw new Error('beforeEvaluate error');
416+
});
417+
418+
const app = createMockApp();
419+
(flareVue as Function)(app, { beforeEvaluate } satisfies FlareVueOptions);
420+
421+
expect(() => {
422+
app.config.errorHandler!(new Error('test'), null, 'setup function');
423+
}).toThrow('beforeEvaluate error');
424+
425+
expect(beforeEvaluate).toHaveBeenCalledOnce();
426+
expect(mockReport).not.toHaveBeenCalled();
427+
});
428+
429+
test('beforeSubmit throwing prevents reporting and propagates', () => {
430+
const beforeSubmit = vi.fn(() => {
431+
throw new Error('beforeSubmit error');
432+
});
433+
434+
const app = createMockApp();
435+
(flareVue as Function)(app, { beforeSubmit } satisfies FlareVueOptions);
436+
437+
expect(() => {
438+
app.config.errorHandler!(new Error('test'), null, 'setup function');
439+
}).toThrow('beforeSubmit error');
440+
441+
expect(beforeSubmit).toHaveBeenCalledOnce();
442+
expect(mockReport).not.toHaveBeenCalled();
443+
});
444+
445+
test('afterSubmit throwing propagates after reporting', () => {
446+
const afterSubmit = vi.fn(() => {
447+
throw new Error('afterSubmit error');
448+
});
449+
450+
const app = createMockApp();
451+
(flareVue as Function)(app, { afterSubmit } satisfies FlareVueOptions);
452+
453+
expect(() => {
454+
app.config.errorHandler!(new Error('test'), null, 'setup function');
455+
}).toThrow('afterSubmit error');
456+
457+
expect(afterSubmit).toHaveBeenCalledOnce();
458+
expect(mockReport).toHaveBeenCalledOnce();
459+
});
460+
461+
test('callbacks fire for each error when called multiple times', () => {
462+
const initialHandler = vi.fn();
463+
const beforeEvaluate = vi.fn();
464+
const beforeSubmit = vi.fn((params: { context: FlareVueContext }) => params.context);
465+
const afterSubmit = vi.fn();
466+
467+
const app = createMockApp(initialHandler);
468+
(flareVue as Function)(app, { beforeEvaluate, beforeSubmit, afterSubmit } satisfies FlareVueOptions);
469+
470+
app.config.errorHandler!(new Error('first'), null, 'setup function');
471+
app.config.errorHandler!(new Error('second'), null, 'render function');
472+
473+
expect(beforeEvaluate).toHaveBeenCalledTimes(2);
474+
expect(beforeSubmit).toHaveBeenCalledTimes(2);
475+
expect(afterSubmit).toHaveBeenCalledTimes(2);
476+
});
477+
478+
test('afterSubmit is called before initial error handler', () => {
479+
const callOrder: string[] = [];
480+
481+
const initialHandler = vi.fn(() => callOrder.push('initialHandler'));
482+
mockReport.mockImplementation(() => callOrder.push('report'));
483+
const afterSubmit = vi.fn(() => callOrder.push('afterSubmit'));
484+
485+
const app = createMockApp(initialHandler);
486+
(flareVue as Function)(app, { afterSubmit } satisfies FlareVueOptions);
487+
488+
app.config.errorHandler!(new Error('test'), null, 'setup function');
489+
490+
expect(callOrder).toEqual(['report', 'afterSubmit', 'initialHandler']);
491+
});
242492
});

0 commit comments

Comments
 (0)