-
Notifications
You must be signed in to change notification settings - Fork 15
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(models): create reportsDiff schema
- Loading branch information
1 parent
09a7ab0
commit 75dc8aa
Showing
4 changed files
with
215 additions
and
11 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
import { type ZodTypeAny, z } from 'zod'; | ||
import { | ||
auditDisplayValueSchema, | ||
auditOutputSchema, | ||
auditValueSchema, | ||
} from './audit-output'; | ||
import { commitSchema } from './commit'; | ||
import { | ||
executionMetaSchema, | ||
packageVersionSchema, | ||
scoreSchema, | ||
slugSchema, | ||
titleSchema, | ||
} from './implementation/schemas'; | ||
import { pluginMetaSchema } from './plugin-config'; | ||
|
||
function makeComparisonSchema<T extends ZodTypeAny>(schema: T) { | ||
return z.object({ | ||
before: schema, | ||
after: schema, | ||
}); | ||
} | ||
|
||
const scorableMetaSchema = z.object({ slug: slugSchema, title: titleSchema }); | ||
const scorableWithPluginMetaSchema = scorableMetaSchema.merge( | ||
z.object({ | ||
plugin: pluginMetaSchema.pick({ slug: true, title: true }), | ||
}), | ||
); | ||
|
||
const scorableDiffSchema = scorableMetaSchema.merge( | ||
z.object({ | ||
scores: makeComparisonSchema(scoreSchema).merge( | ||
z.object({ diff: z.number().min(-1).max(1) }), | ||
), | ||
}), | ||
); | ||
const scorableWithPluginDiffSchema = scorableDiffSchema.merge( | ||
scorableWithPluginMetaSchema, | ||
); | ||
|
||
const categoryDiffSchema = scorableDiffSchema; | ||
const groupDiffSchema = scorableWithPluginDiffSchema; | ||
const auditDiffSchema = scorableWithPluginDiffSchema.merge( | ||
z.object({ | ||
values: makeComparisonSchema(auditValueSchema).merge( | ||
z.object({ diff: z.number().int() }), | ||
), | ||
displayValues: makeComparisonSchema(auditDisplayValueSchema), | ||
}), | ||
); | ||
|
||
const categoryResultSchema = scorableMetaSchema.merge( | ||
z.object({ score: scoreSchema }), | ||
); | ||
const groupResultSchema = scorableWithPluginMetaSchema.merge( | ||
z.object({ score: scoreSchema }), | ||
); | ||
const auditResultSchema = scorableWithPluginMetaSchema.merge( | ||
auditOutputSchema.pick({ score: true, value: true, displayValue: true }), | ||
); | ||
|
||
export const reportsDiffSchema = z | ||
.object({ | ||
commits: makeComparisonSchema(commitSchema).nullable(), | ||
categories: z.object({ | ||
changed: z.array(categoryDiffSchema), | ||
unchanged: z.array(categoryResultSchema), | ||
added: z.array(categoryResultSchema), | ||
removed: z.array(categoryResultSchema), | ||
}), | ||
groups: z.object({ | ||
changed: z.array(groupDiffSchema), | ||
unchanged: z.array(groupResultSchema), | ||
added: z.array(groupResultSchema), | ||
removed: z.array(groupResultSchema), | ||
}), | ||
audits: z.object({ | ||
changed: z.array(auditDiffSchema), | ||
unchanged: z.array(auditResultSchema), | ||
added: z.array(auditResultSchema), | ||
removed: z.array(auditResultSchema), | ||
}), | ||
}) | ||
.merge( | ||
packageVersionSchema({ | ||
versionDescription: 'NPM version of the CLI', | ||
required: true, | ||
}), | ||
) | ||
.merge( | ||
executionMetaSchema({ | ||
descriptionDate: 'Start date and time of the compare run', | ||
descriptionDuration: 'Duration of the compare run in ms', | ||
}), | ||
); | ||
|
||
export type ReportsDiff = z.infer<typeof reportsDiffSchema>; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
import { type ReportsDiff, reportsDiffSchema } from './reports-diff'; | ||
|
||
describe('reportsDiffSchema', () => { | ||
it('should parse valid reports diff', () => { | ||
expect(() => | ||
reportsDiffSchema.parse({ | ||
commits: { | ||
before: { | ||
hash: 'abcdef0123456789abcdef0123456789abcdef01', | ||
message: 'Do stuff', | ||
author: 'John Doe', | ||
date: new Date('2023-03-07T23:00:00+01:00'), | ||
}, | ||
after: { | ||
hash: '0123456789abcdef0123456789abcdef01234567', | ||
message: 'Fix stuff', | ||
author: 'Jane Doe', | ||
date: new Date(), | ||
}, | ||
}, | ||
date: new Date().toISOString(), | ||
duration: 42, | ||
packageName: '@code-pushup/core', | ||
version: '1.2.3', | ||
categories: { | ||
changed: [ | ||
{ | ||
slug: 'perf', | ||
title: 'Performance', | ||
scores: { before: 0.7, after: 0.66, diff: -0.04 }, | ||
}, | ||
], | ||
unchanged: [{ slug: 'a11y', title: 'Accessibility', score: 1 }], | ||
added: [], | ||
removed: [], | ||
}, | ||
groups: { | ||
changed: [], | ||
unchanged: [], | ||
added: [], | ||
removed: [ | ||
{ | ||
slug: 'problems', | ||
title: 'Problems', | ||
plugin: { slug: 'eslint', title: 'ESLint' }, | ||
score: 0.8, | ||
}, | ||
], | ||
}, | ||
audits: { | ||
changed: [ | ||
{ | ||
slug: 'lcp', | ||
title: 'Largest Contentful Paint', | ||
plugin: { slug: 'lighthouse', title: 'Lighthouse' }, | ||
scores: { | ||
before: 0.9, | ||
after: 0.7, | ||
diff: -0.2, | ||
}, | ||
values: { | ||
before: 1810, | ||
after: 1920, | ||
diff: 110, | ||
}, | ||
displayValues: { | ||
before: '1.8 s', | ||
after: '1.9 s', | ||
}, | ||
}, | ||
], | ||
unchanged: [ | ||
{ | ||
slug: 'image-alt', | ||
title: 'Image elements have `[alt]` attributes', | ||
plugin: { slug: 'lighthouse', title: 'Lighthouse' }, | ||
score: 1, | ||
value: 0, | ||
}, | ||
], | ||
added: [ | ||
{ | ||
slug: 'document-title', | ||
title: 'Document has a `<title>` element', | ||
plugin: { slug: 'lighthouse', title: 'Lighthouse' }, | ||
score: 1, | ||
value: 0, | ||
}, | ||
], | ||
removed: [], | ||
}, | ||
} satisfies ReportsDiff), | ||
).not.toThrow(); | ||
}); | ||
}); |