Skip to content

Commit da43e92

Browse files
authored
fix cases where .ratio would end up as NaN (#214)
1 parent 9316d58 commit da43e92

File tree

9 files changed

+189
-7
lines changed

9 files changed

+189
-7
lines changed

src/__fixtures__/trello-20190617.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -381,7 +381,7 @@
381381
"totalUnique": 0,
382382
"unique": {},
383383
"uniquenessRatio": 0,
384-
"ratio": null
384+
"ratio": 0
385385
}
386386
},
387387
"container": {

src/atrules/atrules.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ const analyzeAtRules = ({ atrules, stringifyNode }) => {
6464
...keyframes.count(),
6565
prefixed: {
6666
...prefixedKeyframes.count(),
67-
ratio: prefixedKeyframes.size() / keyframes.size()
67+
ratio: keyframes.size() === 0 ? 0 : prefixedKeyframes.size() / keyframes.size()
6868
}
6969
},
7070
container: containers.count(),

src/atrules/atrules.test.js

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,25 @@ AtRules('analyzes @keyframes', () => {
221221
assert.equal(actual, expected)
222222
})
223223

224+
AtRules('counts ratio correctly when no @keyframes present', () => {
225+
const fixture = `@media (min-width: 0px) {}`
226+
const actual = analyze(fixture)
227+
const expected = {
228+
total: 0,
229+
totalUnique: 0,
230+
unique: {},
231+
uniquenessRatio: 0,
232+
prefixed: {
233+
total: 0,
234+
totalUnique: 0,
235+
unique: {},
236+
uniquenessRatio: 0,
237+
ratio: 0,
238+
},
239+
}
240+
assert.equal(actual.atrules.keyframes, expected)
241+
})
242+
224243
AtRules('analyzes container queries', () => {
225244
// Fixture contains examples from the spec.
226245
// https://drafts.csswg.org/css-contain-3/

src/countable-collection.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
class CountableCollection {
2+
/**
3+
* @param {string[]} initial
4+
*/
25
constructor(initial) {
36
this.items = {}
47
this.total = 0

src/countable-collection.test.js

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
import { suite } from 'uvu';
2+
import * as assert from 'uvu/assert';
3+
import { CountableCollection } from './countable-collection.js'
4+
5+
const CollectionSuite = suite('CountableCollection')
6+
7+
CollectionSuite('counts correctly', () => {
8+
const fixture = new CountableCollection()
9+
fixture.push('a')
10+
fixture.push('a')
11+
fixture.push('b')
12+
fixture.push('b')
13+
fixture.push('c')
14+
fixture.push('d')
15+
const actual = fixture.count()
16+
const expected = {
17+
total: 6,
18+
totalUnique: 4,
19+
unique: {
20+
a: 2,
21+
b: 2,
22+
c: 1,
23+
d: 1,
24+
},
25+
uniquenessRatio: 4 / 6,
26+
}
27+
28+
assert.equal(actual, expected)
29+
})
30+
31+
CollectionSuite('handles empty collections correctly', () => {
32+
const fixture = new CountableCollection()
33+
const actual = fixture.count()
34+
const expected = {
35+
total: 0,
36+
totalUnique: 0,
37+
unique: {},
38+
uniquenessRatio: 0,
39+
}
40+
assert.equal(actual, expected)
41+
})
42+
43+
CollectionSuite('accepts an initial collection', () => {
44+
const fixture = new CountableCollection(['a', 'b'])
45+
fixture.push('a')
46+
fixture.push('a')
47+
fixture.push('b')
48+
fixture.push('b')
49+
fixture.push('c')
50+
fixture.push('d')
51+
const actual = fixture.count()
52+
const expected = {
53+
total: 8,
54+
totalUnique: 4,
55+
unique: {
56+
a: 3,
57+
b: 3,
58+
c: 1,
59+
d: 1,
60+
},
61+
uniquenessRatio: 4 / 8,
62+
}
63+
64+
assert.equal(actual, expected)
65+
})
66+
67+
CollectionSuite.run()

src/rules/rules.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ const analyzeRules = ({ rules }) => {
3939
total: totalRules,
4040
empty: {
4141
total: emptyRules,
42-
ratio: emptyRules / totalRules
42+
ratio: totalRules === 0 ? 0 : emptyRules / totalRules
4343
},
4444
selectors: {
4545
...selectorsPerRule.aggregate(),

src/rules/rules.test.js

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,39 @@ Rules('should count rules', () => {
1313
`).rules.total, 2)
1414
})
1515

16+
Rules('should handle CSS without rules', () => {
17+
const fixture = `@media (min-width: 0px) {}`
18+
const actual = analyze(fixture)
19+
const expected = {
20+
total: 0,
21+
empty: {
22+
total: 0,
23+
ratio: 0
24+
},
25+
selectors: {
26+
min: 0,
27+
max: 0,
28+
mean: 0,
29+
mode: 0,
30+
median: 0,
31+
range: 0,
32+
sum: 0,
33+
items: [],
34+
},
35+
declarations: {
36+
min: 0,
37+
max: 0,
38+
mean: 0,
39+
mode: 0,
40+
median: 0,
41+
range: 0,
42+
sum: 0,
43+
items: [],
44+
},
45+
}
46+
assert.equal(actual.rules, expected)
47+
})
48+
1649
Rules('should count empty rules', () => {
1750
assert.is(1, analyze(`test{}`).rules.empty.total)
1851
assert.is(analyze('@media print {}').rules.empty.total, 0)

src/selectors/selectors.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ const analyzeSelectors = ({ stringifyNode, selectors }) => {
8787
return {
8888
total: totalSelectors,
8989
totalUnique,
90-
uniquenessRatio: totalUnique / totalSelectors,
90+
uniquenessRatio: totalSelectors === 0 ? 0 : totalUnique / totalSelectors,
9191
specificity: {
9292
sum: [aggregatesA.sum, aggregatesB.sum, aggregatesC.sum],
9393
min: minSpecificity,
@@ -104,15 +104,15 @@ const analyzeSelectors = ({ stringifyNode, selectors }) => {
104104
},
105105
id: {
106106
...ids.count(),
107-
ratio: ids.size() / totalSelectors,
107+
ratio: totalSelectors === 0 ? 0 : ids.size() / totalSelectors,
108108
},
109109
accessibility: {
110110
...a11y.count(),
111-
ratio: a11y.size() / totalSelectors,
111+
ratio: totalSelectors === 0 ? 0 : a11y.size() / totalSelectors,
112112
},
113113
keyframes: {
114114
...keyframes.count(),
115-
ratio: keyframes.size() / totalSelectors,
115+
ratio: totalSelectors === 0 ? 0 : keyframes.size() / totalSelectors,
116116
}
117117
}
118118
}

src/selectors/selectors.test.js

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,66 @@ Selectors('are analyzed', () => {
2525
assert.equal(actual, 2)
2626
})
2727

28+
Selectors('handles CSS without selectors', () => {
29+
const fixture = `
30+
@font-face {
31+
font-family: url('/test');
32+
font-family: test;
33+
}
34+
`
35+
const actual = analyze(fixture)
36+
const expected = {
37+
total: 0,
38+
totalUnique: 0,
39+
uniquenessRatio: 0,
40+
specificity: {
41+
sum: [0, 0, 0],
42+
min: undefined,
43+
max: undefined,
44+
mean: [0, 0, 0],
45+
mode: [0, 0, 0],
46+
median: [0, 0, 0],
47+
items: [],
48+
},
49+
complexity: {
50+
min: 0,
51+
max: 0,
52+
mean: 0,
53+
mode: 0,
54+
median: 0,
55+
range: 0,
56+
sum: 0,
57+
total: 0,
58+
totalUnique: 0,
59+
unique: {},
60+
uniquenessRatio: 0,
61+
items: [],
62+
},
63+
id: {
64+
total: 0,
65+
totalUnique: 0,
66+
unique: {},
67+
uniquenessRatio: 0,
68+
ratio: 0,
69+
},
70+
accessibility: {
71+
total: 0,
72+
totalUnique: 0,
73+
unique: {},
74+
uniquenessRatio: 0,
75+
ratio: 0,
76+
},
77+
keyframes: {
78+
total: 0,
79+
totalUnique: 0,
80+
unique: {},
81+
uniquenessRatio: 0,
82+
ratio: 0,
83+
},
84+
}
85+
assert.equal(actual.selectors, expected)
86+
})
87+
2888
Selectors('have their complexity calculated', () => {
2989
const fixture = `
3090
rule {

0 commit comments

Comments
 (0)