Skip to content

Commit 89fecbb

Browse files
authored
feat(utils): add scoring logic (#133)
1 parent 3e9711a commit 89fecbb

14 files changed

+310
-187
lines changed

packages/core/src/lib/implementation/collect.spec.ts

+1
Original file line numberDiff line numberDiff line change
@@ -22,5 +22,6 @@ describe('collect', () => {
2222
expect(() =>
2323
reportSchema.omit({ packageName: true, version: true }).parse(report),
2424
).not.toThrow();
25+
expect(report.plugins[0]?.audits[0]?.slug).toBe('audit-1');
2526
});
2627
});

packages/core/src/lib/implementation/persist.spec.ts

+4-4
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
55
import { Report } from '@code-pushup/models';
66
import {
77
MEMFS_VOLUME,
8-
config,
8+
minimalConfig,
9+
minimalReport,
910
persistConfig,
10-
report,
1111
} from '@code-pushup/models/testing';
1212
import { CODE_PUSHUP_DOMAIN, FOOTER_PREFIX } from '@code-pushup/utils';
1313
import { mockConsole, unmockConsole } from '../../../test/console.mock';
@@ -35,8 +35,8 @@ const readReport = (format: 'json' | 'md') => {
3535
}
3636
};
3737

38-
const dummyReport = report();
39-
const dummyConfig = config(outputDir);
38+
const dummyReport = minimalReport();
39+
const dummyConfig = minimalConfig(outputDir);
4040
let logs: string[] = [];
4141

4242
const resetFiles = async () => {

packages/core/src/lib/implementation/persist.ts

+11-4
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,12 @@ import { existsSync, mkdirSync } from 'fs';
33
import { stat, writeFile } from 'fs/promises';
44
import { join } from 'path';
55
import { CoreConfig, Report } from '@code-pushup/models';
6-
import { formatBytes, reportToMd, reportToStdout } from '@code-pushup/utils';
6+
import {
7+
formatBytes,
8+
reportToMd,
9+
reportToStdout,
10+
scoreReport,
11+
} from '@code-pushup/utils';
712

813
export class PersistDirError extends Error {
914
constructor(outputDir: string) {
@@ -27,9 +32,10 @@ export async function persistReport(
2732
const outputDir = persist.outputDir;
2833
let { format } = persist;
2934
format = format && format.length !== 0 ? format : ['stdout'];
30-
35+
let scoredReport;
3136
if (format.includes('stdout')) {
32-
reportToStdout(report);
37+
scoredReport = scoreReport(report);
38+
reportToStdout(scoredReport);
3339
}
3440

3541
// collect physical format outputs
@@ -39,7 +45,8 @@ export async function persistReport(
3945
];
4046

4147
if (format.includes('md')) {
42-
results.push({ format: 'md', content: reportToMd(report) });
48+
scoredReport = scoredReport || scoreReport(report);
49+
results.push({ format: 'md', content: reportToMd(scoredReport) });
4350
}
4451

4552
if (!existsSync(outputDir)) {

packages/models/test/fixtures/config.mock.ts

+57-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { CoreConfig } from '../../src';
1+
import { CoreConfig, Report } from '../../src';
22
import { categoryConfigs } from './categories.mock';
33
import { eslintPluginConfig } from './eslint-plugin.mock';
44
import { lighthousePluginConfig } from './lighthouse-plugin.mock';
@@ -23,6 +23,20 @@ export function minimalConfig(
2323
): Omit<CoreConfig, 'upload'> & Required<Pick<CoreConfig, 'upload'>> {
2424
const PLUGIN_1_SLUG = 'plugin-1';
2525
const AUDIT_1_SLUG = 'audit-1';
26+
27+
const plg1 = pluginConfig([auditReport({ slug: AUDIT_1_SLUG })], {
28+
slug: PLUGIN_1_SLUG,
29+
outputDir,
30+
outputFile: `${PLUGIN_1_SLUG}.json`,
31+
});
32+
const { runner, ...reportPlg } = plg1;
33+
reportPlg.audits = reportPlg.audits.map(a => ({
34+
...a,
35+
score: 0,
36+
value: 0,
37+
displayValue: '',
38+
}));
39+
2640
return JSON.parse(
2741
JSON.stringify({
2842
persist: { outputDir },
@@ -56,3 +70,45 @@ export function minimalConfig(
5670
} satisfies Omit<CoreConfig, 'upload'> & Required<Pick<CoreConfig, 'upload'>>),
5771
);
5872
}
73+
74+
export function minimalReport(outputDir = 'tmp'): Report {
75+
const PLUGIN_1_SLUG = 'plugin-1';
76+
const AUDIT_1_SLUG = 'audit-1';
77+
78+
const plg1 = pluginConfig([auditReport({ slug: AUDIT_1_SLUG })], {
79+
slug: PLUGIN_1_SLUG,
80+
outputDir,
81+
outputFile: `${PLUGIN_1_SLUG}.json`,
82+
});
83+
const { runner, ...reportPlg } = plg1;
84+
reportPlg.audits = reportPlg.audits.map(a => ({
85+
...a,
86+
score: 0,
87+
value: 0,
88+
displayValue: '',
89+
}));
90+
91+
return JSON.parse(
92+
JSON.stringify({
93+
packageName: '@code-pushup/core',
94+
version: '0.1.0',
95+
date: 'today',
96+
duration: 42,
97+
categories: [
98+
{
99+
slug: 'category-1',
100+
title: 'Category 1',
101+
refs: [
102+
{
103+
type: 'audit',
104+
plugin: PLUGIN_1_SLUG,
105+
slug: AUDIT_1_SLUG,
106+
weight: 1,
107+
},
108+
],
109+
},
110+
],
111+
plugins: [reportPlg as any],
112+
} satisfies Report),
113+
);
114+
}

packages/models/test/index.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
export * from './memfs';
22
export { report } from './fixtures/report.mock';
3-
export { config, minimalConfig } from './fixtures/config.mock';
3+
export { config, minimalConfig, minimalReport } from './fixtures/config.mock';
44

55
export { eslintPluginConfig } from './fixtures/eslint-plugin.mock';
66
export { lighthousePluginConfig } from './fixtures/lighthouse-plugin.mock';

packages/utils/src/index.ts

+1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
export { ScoredReport, scoreReport } from './lib/scoring';
12
export { verboseUtils } from './lib/verbose-utils';
23
export {
34
CliArgsObject,

packages/utils/src/lib/__snapshots__/report-to-md.spec.ts.snap

+12-12
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,11 @@ _Audits: 52_
1515
1616
|Category|Score|Audits|
1717
|:--:|:--:|:--:|
18-
|Performance|1|2/1|
19-
|Bug prevention|19|16/19|
20-
|Code style|13|13/13|
18+
|Performance|0.9215000000000001|2/1|
19+
|Bug prevention|0.6842105263157895|16/19|
20+
|Code style|0.5384615384615384|13/13|
2121
22-
**Performance 1**
22+
**Performance 0.9215000000000001**
2323
2424
- <details>
2525
<summary>Disallow missing \`key\` props in iterators/collection literals (0) ESLint</summary>
@@ -29,7 +29,7 @@ ESLint rule **jsx-key**, from _react_ plugin.
2929
3030
</details>
3131
32-
**Bug prevention 19**
32+
**Bug prevention 0.6842105263157895**
3333
- <details>
3434
<summary>Disallow assignment operators in conditional expressions (1) ESLint</summary>
3535
undefined
@@ -158,7 +158,7 @@ ESLint rule **exhaustive-deps**, from _react-hooks_ plugin.
158158
159159
</details>
160160
161-
**Code style 13**
161+
**Code style 0.5384615384615384**
162162
- <details>
163163
<summary>Disallow unused variables (1) ESLint</summary>
164164
1 warning
@@ -280,11 +280,11 @@ _Audits: 52_
280280
281281
|Category|Score|Audits|
282282
|:--:|:--:|:--:|
283-
|Performance|1|2/1|
284-
|Bug prevention|19|16/19|
285-
|Code style|13|13/13|
283+
|Performance|0.9215000000000001|2/1|
284+
|Bug prevention|0.6842105263157895|16/19|
285+
|Code style|0.5384615384615384|13/13|
286286
287-
**Performance 1**
287+
**Performance 0.9215000000000001**
288288
289289
- <details>
290290
<summary>Disallow missing \`key\` props in iterators/collection literals (0) ESLint</summary>
@@ -294,7 +294,7 @@ ESLint rule **jsx-key**, from _react_ plugin.
294294
295295
</details>
296296
297-
**Bug prevention 19**
297+
**Bug prevention 0.6842105263157895**
298298
- <details>
299299
<summary>Disallow assignment operators in conditional expressions (1) ESLint</summary>
300300
undefined
@@ -423,7 +423,7 @@ ESLint rule **exhaustive-deps**, from _react-hooks_ plugin.
423423
424424
</details>
425425
426-
**Code style 13**
426+
**Code style 0.5384615384615384**
427427
- <details>
428428
<summary>Disallow unused variables (1) ESLint</summary>
429429
1 warning

packages/utils/src/lib/__snapshots__/report-to-stdout.spec.ts.snap

+9-129
Original file line numberDiff line numberDiff line change
@@ -6,141 +6,21 @@ exports[`report-to-stdout > should contain all sections when using the fixture r
66
Package Name: @code-pushup/core
77
Version: 0.1.0
88
Commit: feat(cli): add logic for markdown report - 7eba125ad5643c2f90cb21389fc3442d786f43f9
9-
[3m[90mDate: 2023-10-18T07:49:45.506Z[39m[23m
10-
[3m[90mDuration: 1652ms[39m[23m
11-
[3m[90mPlugins: 2[39m[23m
12-
[3m[90mAudits: 52[39m[23m
9+
[3m[90mDate: today[39m[23m
10+
[3m[90mDuration: 42ms[39m[23m
11+
[3m[90mPlugins: 1[39m[23m
12+
[3m[90mAudits: 1[39m[23m
1313
---
1414
1515
1616
Category Score Audits
17-
Performance 1 2/1
18-
Bug prevention 19 16/19
19-
Code style 13 13/13
17+
Category 1 0 1/1
2018
2119
22-
Performance 1
23-
- Disallow missing \`key\` props in iterators/collection literals (0)
24-
ESLint rule **jsx-key**, from _react_ plugin.
25-
https://github.com/jsx-eslint/eslint-plugin-react/tree/master/docs/rules/jsx-key.md
26-
27-
Bug prevention 19
28-
- Disallow assignment operators in conditional expressions (1)
29-
ESLint rule **no-cond-assign**.
30-
https://eslint.org/docs/latest/rules/no-cond-assign
31-
32-
- Disallow reassigning \`const\` variables (1)
33-
ESLint rule **no-const-assign**.
34-
https://eslint.org/docs/latest/rules/no-const-assign
35-
36-
- Disallow the use of \`debugger\` (1)
37-
ESLint rule **no-debugger**.
38-
https://eslint.org/docs/latest/rules/no-debugger
39-
40-
- Disallow invalid regular expression strings in \`RegExp\` constructors (1)
41-
ESLint rule **no-invalid-regexp**.
42-
https://eslint.org/docs/latest/rules/no-invalid-regexp
43-
44-
- Disallow the use of undeclared variables unless mentioned in \`/*global */\` comments (1)
45-
ESLint rule **no-undef**.
46-
https://eslint.org/docs/latest/rules/no-undef
47-
48-
- Disallow loops with a body that allows only one iteration (1)
49-
ESLint rule **no-unreachable-loop**.
50-
https://eslint.org/docs/latest/rules/no-unreachable-loop
51-
52-
- Disallow negating the left operand of relational operators (1)
53-
ESLint rule **no-unsafe-negation**.
54-
https://eslint.org/docs/latest/rules/no-unsafe-negation
55-
56-
- Disallow use of optional chaining in contexts where the \`undefined\` value is not allowed (1)
57-
ESLint rule **no-unsafe-optional-chaining**.
58-
https://eslint.org/docs/latest/rules/no-unsafe-optional-chaining
59-
60-
- Require calls to \`isNaN()\` when checking for \`NaN\` (1)
61-
ESLint rule **use-isnan**.
62-
https://eslint.org/docs/latest/rules/use-isnan
63-
64-
- Enforce comparing \`typeof\` expressions against valid strings (1)
65-
ESLint rule **valid-typeof**.
66-
https://eslint.org/docs/latest/rules/valid-typeof
67-
68-
- Require the use of \`===\` and \`!==\` (1)
69-
ESLint rule **eqeqeq**.
70-
https://eslint.org/docs/latest/rules/eqeqeq
71-
72-
- Disallow missing \`key\` props in iterators/collection literals (2)
73-
ESLint rule **jsx-key**, from _react_ plugin.
74-
https://github.com/jsx-eslint/eslint-plugin-react/tree/master/docs/rules/jsx-key.md
75-
76-
- Disallow missing props validation in a React component definition (1)
77-
ESLint rule **prop-types**, from _react_ plugin.
78-
https://github.com/jsx-eslint/eslint-plugin-react/tree/master/docs/rules/prop-types.md
79-
80-
- Disallow missing React when using JSX (1)
81-
ESLint rule **react-in-jsx-scope**, from _react_ plugin.
82-
https://github.com/jsx-eslint/eslint-plugin-react/tree/master/docs/rules/react-in-jsx-scope.md
83-
84-
- enforces the Rules of Hooks (2)
85-
ESLint rule **rules-of-hooks**, from _react-hooks_ plugin.
86-
https://reactjs.org/docs/hooks-rules.html
87-
88-
- verifies the list of dependencies for Hooks like useEffect and similar (2)
89-
ESLint rule **exhaustive-deps**, from _react-hooks_ plugin.
90-
https://github.com/facebook/react/issues/14920
91-
92-
Code style 13
93-
- Disallow unused variables (1)
94-
ESLint rule **no-unused-vars**.
95-
https://eslint.org/docs/latest/rules/no-unused-vars
96-
97-
- Require braces around arrow function bodies (1)
98-
ESLint rule **arrow-body-style**.
99-
https://eslint.org/docs/latest/rules/arrow-body-style
100-
101-
- Enforce camelcase naming convention (1)
102-
ESLint rule **camelcase**.
103-
https://eslint.org/docs/latest/rules/camelcase
104-
105-
- Enforce consistent brace style for all control statements (1)
106-
ESLint rule **curly**.
107-
https://eslint.org/docs/latest/rules/curly
108-
109-
- Require the use of \`===\` and \`!==\` (1)
110-
ESLint rule **eqeqeq**.
111-
https://eslint.org/docs/latest/rules/eqeqeq
112-
113-
- Enforce a maximum number of lines of code in a function (1)
114-
ESLint rule **max-lines-per-function**.
115-
https://eslint.org/docs/latest/rules/max-lines-per-function
116-
117-
- Enforce a maximum number of lines per file (1)
118-
ESLint rule **max-lines**.
119-
https://eslint.org/docs/latest/rules/max-lines
120-
121-
- Require or disallow method and property shorthand syntax for object literals (1)
122-
ESLint rule **object-shorthand**.
123-
https://eslint.org/docs/latest/rules/object-shorthand
124-
125-
- Require using arrow functions for callbacks (1)
126-
ESLint rule **prefer-arrow-callback**.
127-
https://eslint.org/docs/latest/rules/prefer-arrow-callback
128-
129-
- Require \`const\` declarations for variables that are never reassigned after declared (1)
130-
ESLint rule **prefer-const**.
131-
https://eslint.org/docs/latest/rules/prefer-const
132-
133-
- Disallow using Object.assign with an object literal as the first argument and prefer the use of object spread instead (1)
134-
ESLint rule **prefer-object-spread**.
135-
https://eslint.org/docs/latest/rules/prefer-object-spread
136-
137-
- Require or disallow \\"Yoda\\" conditions (1)
138-
ESLint rule **yoda**.
139-
https://eslint.org/docs/latest/rules/yoda
140-
141-
- Require \`let\` or \`const\` instead of \`var\` (1)
142-
ESLint rule **no-var**.
143-
https://eslint.org/docs/latest/rules/no-var
20+
Category 1 0
21+
- Audit Title (1)
22+
audit description
23+
http://www.my-docs.dev
14424
14525
14626
+2-1
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
import { describe } from 'vitest';
22
import { report } from '@code-pushup/models/testing';
33
import { reportToMd } from './report-to-md';
4+
import { scoreReport } from './scoring';
45

56
describe('report-to-md', () => {
67
it('should contain all sections when using the fixture report', () => {
7-
const mdReport = reportToMd(report());
8+
const mdReport = reportToMd(scoreReport(report()));
89
expect(mdReport).toMatchSnapshot(mdReport);
910
});
1011
});

0 commit comments

Comments
 (0)