Skip to content

Commit 29c39ef

Browse files
authored
test(utils): extend unit tests
1 parent 1d5e3ad commit 29c39ef

File tree

3 files changed

+239
-1
lines changed

3 files changed

+239
-1
lines changed

packages/utils/src/lib/formatting.unit.test.ts

+5
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ describe('pluralize', () => {
4444
describe('formatBytes', () => {
4545
it.each([
4646
[0, '0 B'],
47+
[-1, '0 B'],
4748
[1000, '1000 B'],
4849
[10_000, '9.77 kB'],
4950
[10_000_000, '9.54 MB'],
@@ -81,6 +82,10 @@ describe('formatDuration', () => {
8182
])('should log correctly formatted duration for %s', (ms, displayValue) => {
8283
expect(formatDuration(ms)).toBe(displayValue);
8384
});
85+
86+
it('should log formatted duration with 1 digit after the decimal point', () => {
87+
expect(formatDuration(120.255_555, 1)).toBe('120.3 ms');
88+
});
8489
});
8590

8691
describe('formatDate', () => {

packages/utils/src/lib/reports/utils.unit.test.ts

+208-1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import {
1313
compareCategoryAuditsAndGroups,
1414
compareIssueSeverity,
1515
compareIssues,
16+
countCategoryAudits,
1617
countWeightedRefs,
1718
formatDiffNumber,
1819
formatReportScore,
@@ -53,6 +54,12 @@ describe('formatScoreWithColor', () => {
5354
it('should skip round value and optionally skip bold formatting', () => {
5455
expect(formatScoreWithColor(0.123).toString()).toBe('🔴 **12**');
5556
});
57+
58+
it('should skip bold formatting', () => {
59+
expect(formatScoreWithColor(0.123, { skipBold: true }).toString()).toBe(
60+
'🔴 12',
61+
);
62+
});
5663
});
5764

5865
describe('colorByScoreDiff', () => {
@@ -119,6 +126,54 @@ describe('countWeightedRefs', () => {
119126
]),
120127
).toBe(1);
121128
});
129+
130+
it('should include multiple weighted references', () => {
131+
expect(
132+
countWeightedRefs([
133+
{
134+
slug: 'a1',
135+
weight: 0.5,
136+
plugin: 'a',
137+
type: 'audit',
138+
},
139+
{
140+
slug: 'a2',
141+
weight: 0.3,
142+
plugin: 'a',
143+
type: 'audit',
144+
},
145+
{
146+
slug: 'a3',
147+
weight: 0.2,
148+
plugin: 'a',
149+
type: 'audit',
150+
},
151+
]),
152+
).toBe(1);
153+
});
154+
155+
it('should return 0 when all weights are 0', () => {
156+
expect(
157+
countWeightedRefs([
158+
{
159+
slug: 'a1',
160+
weight: 0,
161+
plugin: 'a',
162+
type: 'audit',
163+
},
164+
{
165+
slug: 'a2',
166+
weight: 0,
167+
plugin: 'a',
168+
type: 'audit',
169+
},
170+
]),
171+
).toBe(0);
172+
});
173+
174+
it('should handle cases when no weights are provided', () => {
175+
expect(countWeightedRefs([])).toBe(0);
176+
});
122177
});
123178

124179
describe('compareIssueSeverity', () => {
@@ -234,14 +289,30 @@ describe('sortAudits', () => {
234289
});
235290

236291
describe('getPluginNameFromSlug', () => {
237-
it('should return plugin name', () => {
292+
it('should return plugin title', () => {
238293
const plugins = [
239294
{ slug: 'plugin-a', title: 'Plugin A' },
240295
{ slug: 'plugin-b', title: 'Plugin B' },
241296
] as ScoredReport['plugins'];
242297
expect(getPluginNameFromSlug('plugin-a', plugins)).toBe('Plugin A');
243298
expect(getPluginNameFromSlug('plugin-b', plugins)).toBe('Plugin B');
244299
});
300+
301+
it('should return plugin slug when plugin title is an empty string', () => {
302+
expect(
303+
getPluginNameFromSlug('plugin-a', [
304+
{ slug: 'plugin-a', title: '' },
305+
] as ScoredReport['plugins']),
306+
).toBe('plugin-a');
307+
});
308+
309+
it('should return provided slug when plugin slug and title are empty strings', () => {
310+
expect(
311+
getPluginNameFromSlug('plugin-a', [
312+
{ slug: '', title: '' },
313+
] as ScoredReport['plugins']),
314+
).toBe('plugin-a');
315+
});
245316
});
246317

247318
describe('sortAuditIssues', () => {
@@ -476,6 +547,7 @@ describe('formatValueChange', () => {
476547
[{ before: 600, after: 450, diff: -150 }, '↓ −25 %'],
477548
[{ before: 1, after: 3, diff: 2 }, '↑ +200 %'],
478549
[{ before: 0, after: 2, diff: 2 }, '↑ +∞ %'],
550+
[{ before: 0, after: -2, diff: -2 }, '↓ −∞ %'],
479551
[{ before: 100, after: 101, diff: 1 }, '↑ +1 %'],
480552
[{ before: 1000, after: 1001, diff: 1 }, '↑ +0.1 %'],
481553
[{ before: 500, after: 499, diff: -1 }, '↓ −0.2 %'],
@@ -492,3 +564,138 @@ describe('formatValueChange', () => {
492564
},
493565
);
494566
});
567+
568+
describe('countCategoryAudits', () => {
569+
it('should count single audit references', () => {
570+
expect(
571+
countCategoryAudits(
572+
[
573+
{
574+
type: 'audit',
575+
plugin: 'coverage',
576+
slug: 'function-coverage',
577+
weight: 1,
578+
},
579+
],
580+
[],
581+
),
582+
).toBe(1);
583+
});
584+
585+
it('should count audits in a group', () => {
586+
expect(
587+
countCategoryAudits(
588+
[
589+
{
590+
type: 'group',
591+
plugin: 'coverage',
592+
slug: 'code-coverage',
593+
weight: 1,
594+
},
595+
],
596+
[
597+
{
598+
slug: 'coverage',
599+
groups: [
600+
{
601+
slug: 'code-coverage',
602+
refs: [
603+
{ slug: 'branch-coverage', weight: 0.33 },
604+
{ slug: 'function-coverage', weight: 0.33 },
605+
{ slug: 'line-coverage', weight: 0.33 },
606+
],
607+
},
608+
],
609+
},
610+
] as ScoredReport['plugins'],
611+
),
612+
).toBe(3);
613+
});
614+
615+
it('should handle mixed audit and group references', () => {
616+
expect(
617+
countCategoryAudits(
618+
[
619+
{
620+
type: 'audit',
621+
plugin: 'lighthouse',
622+
slug: 'is-on-https',
623+
weight: 1,
624+
},
625+
{
626+
type: 'group',
627+
plugin: 'coverage',
628+
slug: 'code-coverage',
629+
weight: 1,
630+
},
631+
],
632+
[
633+
{
634+
slug: 'coverage',
635+
groups: [
636+
{
637+
slug: 'code-coverage',
638+
refs: [
639+
{ slug: 'branch-coverage', weight: 0.5 },
640+
{ slug: 'line-coverage', weight: 0.5 },
641+
],
642+
},
643+
],
644+
},
645+
] as ScoredReport['plugins'],
646+
),
647+
).toBe(3);
648+
});
649+
650+
it('should return 0 when a group is not found', () => {
651+
expect(
652+
countCategoryAudits(
653+
[
654+
{
655+
type: 'group',
656+
plugin: 'plugin-A',
657+
slug: 'missing-group',
658+
weight: 1,
659+
},
660+
],
661+
[
662+
{
663+
slug: 'plugin-A',
664+
groups: [
665+
{
666+
slug: 'code-coverage',
667+
refs: [
668+
{ slug: 'branch-coverage', weight: 0.5 },
669+
{ slug: 'line-coverage', weight: 0.5 },
670+
],
671+
},
672+
],
673+
},
674+
] as ScoredReport['plugins'],
675+
),
676+
).toBe(0);
677+
});
678+
679+
it.each([[[]], [undefined]])(
680+
'should return 0 when plugin groups are %p and no single audit references are provided',
681+
groups => {
682+
expect(
683+
countCategoryAudits(
684+
[
685+
{
686+
type: 'group',
687+
plugin: 'coverage',
688+
slug: 'code-coverage',
689+
weight: 1,
690+
},
691+
],
692+
[{ slug: 'coverage', groups: groups }] as ScoredReport['plugins'],
693+
),
694+
).toBe(0);
695+
},
696+
);
697+
698+
it('should return 0 when no audits or groups are present', () => {
699+
expect(countCategoryAudits([], [])).toBe(0);
700+
});
701+
});

packages/utils/src/lib/transform.unit.test.ts

+26
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,13 @@ describe('toArray', () => {
2525
it('should leave array value unchanged', () => {
2626
expect(toArray(['*.ts', '*.js'])).toEqual(['*.ts', '*.js']);
2727
});
28+
29+
it('should handle nested arrays', () => {
30+
expect(toArray([['*.ts', '*.js'], ['*.json']])).toEqual([
31+
['*.ts', '*.js'],
32+
['*.json'],
33+
]);
34+
});
2835
});
2936

3037
describe('objectToKeys', () => {
@@ -37,6 +44,14 @@ describe('objectToKeys', () => {
3744
const keys: never[] = objectToKeys({});
3845
expect(keys).toEqual([]);
3946
});
47+
48+
it('should transform nested object into array of keys', () => {
49+
const keys = objectToKeys({
50+
prop1: 1,
51+
nestedProp1: { nestedKey1: 1 },
52+
});
53+
expect(keys).toEqual(['prop1', 'nestedProp1']);
54+
});
4055
});
4156

4257
describe('objectFromEntries', () => {
@@ -73,6 +88,17 @@ describe('objectToEntries', () => {
7388
const keys: [never, never][] = objectToEntries({});
7489
expect(keys).toEqual([]);
7590
});
91+
92+
it('should transform nested object into array of entries', () => {
93+
const keys = objectToEntries({
94+
prop1: 1,
95+
nestedProp1: { nestedKey1: 1 },
96+
});
97+
expect(keys).toEqual([
98+
['prop1', 1],
99+
['nestedProp1', { nestedKey1: 1 }],
100+
]);
101+
});
76102
});
77103

78104
describe('countOccurrences', () => {

0 commit comments

Comments
 (0)