Skip to content

Commit e798657

Browse files
committed
expose parse_coverage helper
1 parent 4443395 commit e798657

File tree

5 files changed

+77
-14
lines changed

5 files changed

+77
-14
lines changed

README.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,11 +36,14 @@ npm install @projectwallace/css-code-coverage
3636
// { start: 0, end: 46 }
3737
// ]
3838
// }
39+
import { parse_coverage } from '@projectwallace/css-code-coverage'
40+
3941
let files = await fs.glob('./css-coverage/**/*.json')
4042
let coverage_data = []
43+
4144
for (let file of files) {
4245
let json_content = await fs.readFile(file, 'urf-8')
43-
coverage_data.push(JSON.parse(json_content))
46+
coverage_data.push(...parse_coverage(json_content))
4447
}
4548
```
4649

src/index.test.ts

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,3 +196,45 @@ test.describe('from coverage data downloaded directly from the browser as JSON',
196196
)
197197
})
198198
})
199+
200+
test('handles empty input', () => {
201+
let result = calculate_coverage([], html_parser)
202+
expect(result.total_files_found).toBe(0)
203+
expect(result.total_bytes).toBe(0)
204+
expect(result.used_bytes).toBe(0)
205+
expect(result.unused_bytes).toBe(0)
206+
expect(result.total_lines).toBe(0)
207+
expect(result.covered_lines).toBe(0)
208+
expect(result.uncovered_lines).toBe(0)
209+
expect(result.line_coverage_ratio).toBe(0)
210+
expect(result.total_stylesheets).toBe(0)
211+
expect(result.coverage_per_stylesheet).toEqual([])
212+
})
213+
214+
test.describe('garbage input', () => {
215+
test('garbage Array', () => {
216+
expect(() =>
217+
calculate_coverage(
218+
[
219+
{
220+
test: 1,
221+
garbage: true,
222+
},
223+
] as unknown as Coverage[],
224+
html_parser,
225+
),
226+
).toThrow('No valid coverage data found')
227+
})
228+
229+
test('garbage Object', () => {
230+
expect(() =>
231+
calculate_coverage(
232+
{
233+
test: 1,
234+
garbage: true,
235+
} as unknown as Coverage[],
236+
html_parser,
237+
),
238+
).toThrow('No valid coverage data found')
239+
})
240+
})

src/index.ts

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import type { Coverage, Range } from './parse-coverage.ts'
1+
import { is_valid_coverage, type Coverage, type Range } from './parse-coverage.ts'
22
import { prettify } from './prettify.ts'
33
import { deduplicate_entries } from './decuplicate.ts'
44
import { filter_coverage } from './filter-entries.ts'
@@ -28,6 +28,11 @@ export type CoverageResult = CoverageData & {
2828
coverage_per_stylesheet: StylesheetCoverage[]
2929
}
3030

31+
function ratio(fraction: number, total: number) {
32+
if (total === 0) return 0
33+
return fraction / total
34+
}
35+
3136
/**
3237
* @description
3338
* CSS Code Coverage calculation
@@ -41,6 +46,11 @@ export type CoverageResult = CoverageData & {
4146
*/
4247
export function calculate_coverage(coverage: Coverage[], parse_html: Parser): CoverageResult {
4348
let total_files_found = coverage.length
49+
50+
if (!is_valid_coverage(coverage)) {
51+
throw new TypeError('No valid coverage data found')
52+
}
53+
4454
let filtered_coverage = filter_coverage(coverage, parse_html)
4555
let prettified_coverage = prettify(filtered_coverage)
4656
let deduplicated = deduplicate_entries(prettified_coverage)
@@ -114,8 +124,8 @@ export function calculate_coverage(coverage: Coverage[], parse_html: Parser): Co
114124
unused_bytes: file_total_bytes - file_bytes_covered,
115125
used_bytes: file_bytes_covered,
116126
total_bytes: file_total_bytes,
117-
line_coverage_ratio: file_lines_covered / total_file_lines,
118-
byte_coverage_ratio: file_bytes_covered / file_total_bytes,
127+
line_coverage_ratio: ratio(file_lines_covered, total_file_lines),
128+
byte_coverage_ratio: ratio(file_bytes_covered, file_total_bytes),
119129
line_coverage,
120130
total_lines: total_file_lines,
121131
covered_lines: file_lines_covered,
@@ -154,9 +164,13 @@ export function calculate_coverage(coverage: Coverage[], parse_html: Parser): Co
154164
covered_lines: total_covered_lines,
155165
unused_bytes: total_unused_bytes,
156166
uncovered_lines: total_uncovered_lines,
157-
byte_coverage_ratio: total_used_bytes / total_bytes,
158-
line_coverage_ratio: total_covered_lines / total_lines,
167+
byte_coverage_ratio: ratio(total_used_bytes, total_bytes),
168+
line_coverage_ratio: ratio(total_covered_lines, total_lines),
159169
coverage_per_stylesheet,
160170
total_stylesheets: coverage_per_stylesheet.length,
161171
}
162172
}
173+
174+
export type { Coverage, Range } from './parse-coverage.ts'
175+
export { parse_coverage } from './parse-coverage.ts'
176+
export type { Parser } from './types.ts'

src/parse-coverage.test.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { test, expect } from '@playwright/test'
2-
import { parse_json } from './parse-coverage.ts'
2+
import { parse_coverage } from './parse-coverage.ts'
33

44
test('parses valid JSON', () => {
55
let input = `
@@ -13,7 +13,7 @@ test('parses valid JSON', () => {
1313
}
1414
]
1515
`
16-
let result = parse_json(input)
16+
let result = parse_coverage(input)
1717
expect(result).toEqual([
1818
{
1919
url: 'example.com',
@@ -34,7 +34,7 @@ test('allows entries without text', () => {
3434
}
3535
]
3636
`
37-
let result = parse_json(input)
37+
let result = parse_coverage(input)
3838
expect(result).toEqual([
3939
{
4040
url: 'example.com',
@@ -45,7 +45,7 @@ test('allows entries without text', () => {
4545

4646
test('returns empty array for invalid JSON', () => {
4747
let input = `invalid json`
48-
let result = parse_json(input)
48+
let result = parse_coverage(input)
4949
expect(result).toEqual([])
5050
})
5151

@@ -60,6 +60,6 @@ test('returns empty array for JSON not matching schema', () => {
6060
}
6161
]
6262
`
63-
let result = parse_json(input)
63+
let result = parse_coverage(input)
6464
expect(result).toEqual([])
6565
})

src/parse-coverage.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,15 @@ let CoverageSchema = v.array(
2424
}),
2525
)
2626

27-
export function parse_json(input: string) {
27+
export function is_valid_coverage(input: unknown): boolean {
28+
let result = v.safeParse(CoverageSchema, input)
29+
return result.success
30+
}
31+
32+
export function parse_coverage(input: string) {
2833
try {
2934
let parse_result = JSON.parse(input)
30-
v.parse(CoverageSchema, parse_result)
31-
return parse_result as Coverage[]
35+
return is_valid_coverage(parse_result) ? (parse_result as Coverage[]) : ([] as Coverage[])
3236
} catch {
3337
return [] as Coverage[]
3438
}

0 commit comments

Comments
 (0)