Skip to content

Commit af9783d

Browse files
author
Sébastien Henau
committed
tests: add capture warnings tests
1 parent 7f6198a commit af9783d

File tree

1 file changed

+117
-10
lines changed

1 file changed

+117
-10
lines changed

packages/vue/tests/flareVue.test.ts

Lines changed: 117 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,23 @@ import { flareVue } from '../src/flareVue';
55
import type { FlareVueContext, FlareVueOptions } from '../src/types';
66

77
const mockReport = vi.fn();
8+
const mockReportMessage = vi.fn();
89

910
vi.mock('@flareapp/js', () => ({
1011
flare: {
1112
report: (...args: unknown[]) => mockReport(...args),
13+
reportMessage: (...args: unknown[]) => mockReportMessage(...args),
1214
},
1315
}));
1416

15-
function createMockApp(initialHandler?: (...args: unknown[]) => void) {
17+
function createMockApp(options?: {
18+
errorHandler?: (...args: unknown[]) => void;
19+
warnHandler?: (...args: unknown[]) => void;
20+
}) {
1621
return {
1722
config: {
18-
errorHandler: initialHandler ?? undefined,
23+
errorHandler: options?.errorHandler ?? undefined,
24+
warnHandler: options?.warnHandler ?? undefined,
1925
},
2026
};
2127
}
@@ -45,6 +51,7 @@ function callHandler(
4551

4652
beforeEach(() => {
4753
mockReport.mockReset();
54+
mockReportMessage.mockReset();
4855
});
4956

5057
describe('flareVue', () => {
@@ -143,7 +150,7 @@ describe('flareVue', () => {
143150

144151
test('calls initial error handler if one exists', () => {
145152
const initialHandler = vi.fn();
146-
const app = createMockApp(initialHandler);
153+
const app = createMockApp({ errorHandler: initialHandler });
147154
(flareVue as Function)(app);
148155

149156
const error = new Error('test');
@@ -157,7 +164,7 @@ describe('flareVue', () => {
157164

158165
test('passes original error (not converted) to initial handler', () => {
159166
const initialHandler = vi.fn();
160-
const app = createMockApp(initialHandler);
167+
const app = createMockApp({ errorHandler: initialHandler });
161168
(flareVue as Function)(app);
162169

163170
app.config.errorHandler!('string error', null, 'setup function');
@@ -167,7 +174,7 @@ describe('flareVue', () => {
167174

168175
test('does not throw when initial error handler exists', () => {
169176
const initialHandler = vi.fn();
170-
const app = createMockApp(initialHandler);
177+
const app = createMockApp({ errorHandler: initialHandler });
171178
(flareVue as Function)(app);
172179

173180
expect(() => {
@@ -198,7 +205,7 @@ describe('flareVue', () => {
198205
const initialHandler = vi.fn(() => callOrder.push('initialHandler'));
199206
mockReport.mockImplementation(() => callOrder.push('report'));
200207

201-
const app = createMockApp(initialHandler);
208+
const app = createMockApp({ errorHandler: initialHandler });
202209
(flareVue as Function)(app);
203210

204211
app.config.errorHandler!(new Error('test'), null, 'setup function');
@@ -236,7 +243,7 @@ describe('flareVue', () => {
236243

237244
test('reports each error independently when called multiple times', () => {
238245
const initialHandler = vi.fn();
239-
const app = createMockApp(initialHandler);
246+
const app = createMockApp({ errorHandler: initialHandler });
240247
(flareVue as Function)(app);
241248

242249
const error1 = new Error('first');
@@ -253,7 +260,7 @@ describe('flareVue', () => {
253260

254261
test('does not call initial handler when flare.report() throws', () => {
255262
const initialHandler = vi.fn();
256-
const app = createMockApp(initialHandler);
263+
const app = createMockApp({ errorHandler: initialHandler });
257264
(flareVue as Function)(app);
258265

259266
mockReport.mockImplementation(() => {
@@ -503,7 +510,7 @@ describe('flareVue', () => {
503510
const beforeSubmit = vi.fn((params: { context: FlareVueContext }) => params.context);
504511
const afterSubmit = vi.fn();
505512

506-
const app = createMockApp(initialHandler);
513+
const app = createMockApp({ errorHandler: initialHandler });
507514
(flareVue as Function)(app, { beforeEvaluate, beforeSubmit, afterSubmit } satisfies FlareVueOptions);
508515

509516
app.config.errorHandler!(new Error('first'), null, 'setup function');
@@ -521,11 +528,111 @@ describe('flareVue', () => {
521528
mockReport.mockImplementation(() => callOrder.push('report'));
522529
const afterSubmit = vi.fn(() => callOrder.push('afterSubmit'));
523530

524-
const app = createMockApp(initialHandler);
531+
const app = createMockApp({ errorHandler: initialHandler });
525532
(flareVue as Function)(app, { afterSubmit } satisfies FlareVueOptions);
526533

527534
app.config.errorHandler!(new Error('test'), null, 'setup function');
528535

529536
expect(callOrder).toEqual(['report', 'afterSubmit', 'initialHandler']);
530537
});
531538
});
539+
540+
describe('flareVue captureWarnings', () => {
541+
test('does not set warnHandler when captureWarnings is not set', () => {
542+
const app = createMockApp();
543+
(flareVue as Function)(app);
544+
545+
expect(app.config.warnHandler).toBeUndefined();
546+
});
547+
548+
test('does not set warnHandler when captureWarnings is false', () => {
549+
const app = createMockApp();
550+
(flareVue as Function)(app, { captureWarnings: false } satisfies FlareVueOptions);
551+
552+
expect(app.config.warnHandler).toBeUndefined();
553+
});
554+
555+
test('sets warnHandler when captureWarnings is true', () => {
556+
const app = createMockApp();
557+
(flareVue as Function)(app, { captureWarnings: true } satisfies FlareVueOptions);
558+
559+
expect(typeof app.config.warnHandler).toBe('function');
560+
});
561+
562+
test('reports warning via flare.reportMessage with message, context, and VueWarning exception class', () => {
563+
const app = createMockApp();
564+
(flareVue as Function)(app, { captureWarnings: true } satisfies FlareVueOptions);
565+
566+
const instance = createMockInstance('Counter');
567+
app.config.warnHandler!('Invalid prop type', instance, 'found in\n---> <Counter>');
568+
569+
expect(mockReportMessage).toHaveBeenCalledOnce();
570+
expect(mockReportMessage).toHaveBeenCalledWith(
571+
'Invalid prop type',
572+
{ vue: { message: 'Invalid prop type', componentName: 'Counter', trace: 'found in\n---> <Counter>' } },
573+
'VueWarning'
574+
);
575+
});
576+
577+
test('context includes component name and trace', () => {
578+
const app = createMockApp();
579+
(flareVue as Function)(app, { captureWarnings: true } satisfies FlareVueOptions);
580+
581+
const instance = createMockInstance('UserProfile');
582+
const trace = 'found in\n---> <UserProfile> at src/UserProfile.vue\n <App> at src/App.vue';
583+
app.config.warnHandler!('Missing required prop', instance, trace);
584+
585+
const context = mockReportMessage.mock.calls[0][1];
586+
expect(context.vue.componentName).toBe('UserProfile');
587+
expect(context.vue.trace).toBe(trace);
588+
expect(context.vue.message).toBe('Missing required prop');
589+
});
590+
591+
test('uses AnonymousComponent when instance is null', () => {
592+
const app = createMockApp();
593+
(flareVue as Function)(app, { captureWarnings: true } satisfies FlareVueOptions);
594+
595+
app.config.warnHandler!('Some warning', null, '');
596+
597+
const context = mockReportMessage.mock.calls[0][1];
598+
expect(context.vue.componentName).toBe('AnonymousComponent');
599+
});
600+
601+
test('calls initial warn handler after reporting', () => {
602+
const initialWarnHandler = vi.fn();
603+
const app = createMockApp({ warnHandler: initialWarnHandler });
604+
(flareVue as Function)(app, { captureWarnings: true } satisfies FlareVueOptions);
605+
606+
const instance = createMockInstance('Counter');
607+
app.config.warnHandler!('Invalid prop', instance, 'trace');
608+
609+
expect(mockReportMessage).toHaveBeenCalledOnce();
610+
expect(initialWarnHandler).toHaveBeenCalledOnce();
611+
expect(initialWarnHandler).toHaveBeenCalledWith('Invalid prop', instance, 'trace');
612+
});
613+
614+
test('calls initial warn handler after flare.reportMessage', () => {
615+
const callOrder: string[] = [];
616+
const initialWarnHandler = vi.fn(() => callOrder.push('initialWarnHandler'));
617+
mockReportMessage.mockImplementation(() => callOrder.push('reportMessage'));
618+
619+
const app = createMockApp({ warnHandler: initialWarnHandler });
620+
(flareVue as Function)(app, { captureWarnings: true } satisfies FlareVueOptions);
621+
622+
app.config.warnHandler!('Warning', null, '');
623+
624+
expect(callOrder).toEqual(['reportMessage', 'initialWarnHandler']);
625+
});
626+
627+
test('reports each warning independently', () => {
628+
const app = createMockApp();
629+
(flareVue as Function)(app, { captureWarnings: true } satisfies FlareVueOptions);
630+
631+
app.config.warnHandler!('First warning', null, 'trace1');
632+
app.config.warnHandler!('Second warning', null, 'trace2');
633+
634+
expect(mockReportMessage).toHaveBeenCalledTimes(2);
635+
expect(mockReportMessage.mock.calls[0][0]).toBe('First warning');
636+
expect(mockReportMessage.mock.calls[1][0]).toBe('Second warning');
637+
});
638+
});

0 commit comments

Comments
 (0)