-
Notifications
You must be signed in to change notification settings - Fork 3.4k
test: add unit tests for trace processing helpers #2514
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -7,13 +7,29 @@ | |||||||||||||
| import assert from 'node:assert'; | ||||||||||||||
| import {describe, it} from 'node:test'; | ||||||||||||||
|
|
||||||||||||||
| import type { | ||||||||||||||
| InsightName, | ||||||||||||||
| TraceParseError, | ||||||||||||||
| TraceResult, | ||||||||||||||
| } from '../../src/trace-processing/parse.js'; | ||||||||||||||
| import { | ||||||||||||||
| getInsightOutput, | ||||||||||||||
| getTraceSummary, | ||||||||||||||
| parseRawTraceBuffer, | ||||||||||||||
| traceResultIsSuccess, | ||||||||||||||
| } from '../../src/trace-processing/parse.js'; | ||||||||||||||
|
|
||||||||||||||
| import {loadTraceAsBuffer} from './fixtures/load.js'; | ||||||||||||||
|
|
||||||||||||||
| async function parseTrace(fileName: string): Promise<TraceResult> { | ||||||||||||||
| const rawData = loadTraceAsBuffer(fileName); | ||||||||||||||
| const result = await parseRawTraceBuffer(rawData); | ||||||||||||||
| if (!traceResultIsSuccess(result)) { | ||||||||||||||
| assert.fail(`Unexpected trace parse error: ${result.error}`); | ||||||||||||||
| } | ||||||||||||||
| return result; | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| describe('Trace parsing', async () => { | ||||||||||||||
| it('can parse a Uint8Array from Tracing.stop())', async () => { | ||||||||||||||
| const rawData = loadTraceAsBuffer('basic-trace.json.gz'); | ||||||||||||||
|
|
@@ -44,4 +60,112 @@ describe('Trace parsing', async () => { | |||||||||||||
| error: 'No buffer was provided.', | ||||||||||||||
| }); | ||||||||||||||
| }); | ||||||||||||||
|
|
||||||||||||||
| it('will return a message if the buffer decodes to an empty string', async () => { | ||||||||||||||
| const result = await parseRawTraceBuffer(new Uint8Array()); | ||||||||||||||
| assert.deepEqual(result, { | ||||||||||||||
| error: 'Decoding the trace buffer returned an empty string.', | ||||||||||||||
| }); | ||||||||||||||
| }); | ||||||||||||||
|
|
||||||||||||||
| it('will return a message if the buffer is not valid JSON', async () => { | ||||||||||||||
| const result = await parseRawTraceBuffer( | ||||||||||||||
| new TextEncoder().encode('this is not valid JSON'), | ||||||||||||||
| ); | ||||||||||||||
| if (traceResultIsSuccess(result)) { | ||||||||||||||
| assert.fail('Expected a parse error for invalid JSON input.'); | ||||||||||||||
| } | ||||||||||||||
| assert.match(result.error, /JSON/); | ||||||||||||||
|
Comment on lines
+75
to
+78
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||
| }); | ||||||||||||||
|
|
||||||||||||||
| it('will return a message if the JSON is not a valid trace', async () => { | ||||||||||||||
| const result = await parseRawTraceBuffer( | ||||||||||||||
| new TextEncoder().encode('{"notATrace": true}'), | ||||||||||||||
| ); | ||||||||||||||
| if (traceResultIsSuccess(result)) { | ||||||||||||||
| assert.fail('Expected a parse error for a non-trace JSON input.'); | ||||||||||||||
| } | ||||||||||||||
| assert.ok(result.error.length > 0); | ||||||||||||||
|
Comment on lines
+85
to
+88
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||
| }); | ||||||||||||||
| }); | ||||||||||||||
|
|
||||||||||||||
| describe('traceResultIsSuccess', () => { | ||||||||||||||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. For this function we should just use a object that mimics the trace, so we can control it. |
||||||||||||||
| it('returns true for the result of a successful parse', async () => { | ||||||||||||||
| const rawData = loadTraceAsBuffer('basic-trace.json.gz'); | ||||||||||||||
| const result = await parseRawTraceBuffer(rawData); | ||||||||||||||
| assert.strictEqual(traceResultIsSuccess(result), true); | ||||||||||||||
| }); | ||||||||||||||
|
|
||||||||||||||
| it('returns true for a trace result without insights', async () => { | ||||||||||||||
| const result = await parseTrace('basic-trace.json.gz'); | ||||||||||||||
| const withoutInsights: TraceResult = { | ||||||||||||||
| parsedTrace: result.parsedTrace, | ||||||||||||||
| insights: null, | ||||||||||||||
| }; | ||||||||||||||
| assert.strictEqual(traceResultIsSuccess(withoutInsights), true); | ||||||||||||||
| }); | ||||||||||||||
|
|
||||||||||||||
| it('returns false for the result of a failed parse', async () => { | ||||||||||||||
| const result = await parseRawTraceBuffer(undefined); | ||||||||||||||
| assert.strictEqual(traceResultIsSuccess(result), false); | ||||||||||||||
| }); | ||||||||||||||
|
|
||||||||||||||
| it('returns false for a parse error object', () => { | ||||||||||||||
| const error: TraceParseError = {error: 'Something went wrong.'}; | ||||||||||||||
| assert.strictEqual(traceResultIsSuccess(error), false); | ||||||||||||||
| }); | ||||||||||||||
|
|
||||||||||||||
| it('checks for the parsedTrace key, not the error message contents', () => { | ||||||||||||||
| const error: TraceParseError = {error: 'parsedTrace'}; | ||||||||||||||
| assert.strictEqual(traceResultIsSuccess(error), false); | ||||||||||||||
| }); | ||||||||||||||
|
Comment on lines
+118
to
+121
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||
| }); | ||||||||||||||
|
|
||||||||||||||
| describe('getInsightOutput', () => { | ||||||||||||||
| it('returns the formatted output for a known insight', async () => { | ||||||||||||||
| const result = await parseTrace('web-dev-with-commit.json.gz'); | ||||||||||||||
| const insight = getInsightOutput(result, 'NAVIGATION_0', 'LCPBreakdown'); | ||||||||||||||
| if ('error' in insight) { | ||||||||||||||
| assert.fail(`Unexpected insight error: ${insight.error}`); | ||||||||||||||
| } | ||||||||||||||
|
Comment on lines
+128
to
+130
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||
| assert.match(insight.output, /Insight Title: LCP breakdown/); | ||||||||||||||
| }); | ||||||||||||||
|
|
||||||||||||||
| it('returns an error if the trace has no insights', async () => { | ||||||||||||||
| const result = await parseTrace('web-dev-with-commit.json.gz'); | ||||||||||||||
| const withoutInsights: TraceResult = { | ||||||||||||||
| parsedTrace: result.parsedTrace, | ||||||||||||||
| insights: null, | ||||||||||||||
| }; | ||||||||||||||
| const insight = getInsightOutput( | ||||||||||||||
| withoutInsights, | ||||||||||||||
| 'NAVIGATION_0', | ||||||||||||||
| 'LCPBreakdown', | ||||||||||||||
| ); | ||||||||||||||
| assert.deepEqual(insight, { | ||||||||||||||
| error: 'No Performance insights are available for this trace.', | ||||||||||||||
| }); | ||||||||||||||
| }); | ||||||||||||||
|
|
||||||||||||||
| it('returns an error for an unknown insight set id', async () => { | ||||||||||||||
| const result = await parseTrace('web-dev-with-commit.json.gz'); | ||||||||||||||
| const insight = getInsightOutput(result, 'NOT_A_SET_ID', 'LCPBreakdown'); | ||||||||||||||
| assert.deepEqual(insight, { | ||||||||||||||
| error: | ||||||||||||||
| 'No Performance Insights for the given insight set id. Only use ids given in the "Available insight sets" list.', | ||||||||||||||
| }); | ||||||||||||||
| }); | ||||||||||||||
|
|
||||||||||||||
| it('returns an error for an unknown insight name', async () => { | ||||||||||||||
| const result = await parseTrace('web-dev-with-commit.json.gz'); | ||||||||||||||
| const insight = getInsightOutput( | ||||||||||||||
| result, | ||||||||||||||
| 'NAVIGATION_0', | ||||||||||||||
| 'NotARealInsight' as InsightName, | ||||||||||||||
| ); | ||||||||||||||
| assert.deepEqual(insight, { | ||||||||||||||
| error: | ||||||||||||||
| 'No Insight with the name NotARealInsight found. Double check the name you provided is accurate and try again.', | ||||||||||||||
| }); | ||||||||||||||
| }); | ||||||||||||||
| }); | ||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.