@projectwallace/css-analyzer 5.0.0-alpha.1 → 5.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/analyzer.cjs +1 -1
- package/dist/analyzer.cjs.map +1 -1
- package/dist/analyzer.modern.js +2 -0
- package/dist/analyzer.modern.js.map +1 -0
- package/dist/analyzer.module.js +1 -1
- package/dist/analyzer.module.js.map +1 -1
- package/dist/analyzer.umd.js +1 -1
- package/dist/analyzer.umd.js.map +1 -1
- package/package.json +10 -10
- package/dist/analyzer.js +0 -2
- package/dist/analyzer.js.map +0 -1
- package/src/aggregate-collection.js +0 -113
- package/src/aggregate-collection.test.js +0 -47
- package/src/atrules/atrules.js +0 -76
- package/src/atrules/atrules.test.js +0 -289
- package/src/context-collection.js +0 -36
- package/src/countable-collection.js +0 -46
- package/src/declarations/declarations.js +0 -46
- package/src/declarations/declarations.test.js +0 -113
- package/src/index.js +0 -259
- package/src/index.test.js +0 -60
- package/src/properties/properties.js +0 -48
- package/src/properties/properties.test.js +0 -138
- package/src/rules/rules.js +0 -57
- package/src/rules/rules.test.js +0 -247
- package/src/selectors/complexity.test.js +0 -123
- package/src/selectors/selectors.js +0 -122
- package/src/selectors/selectors.test.js +0 -189
- package/src/selectors/specificity.js +0 -201
- package/src/selectors/specificity.test.js +0 -247
- package/src/smoke.test.js +0 -39
- package/src/stylesheet/stylesheet.test.js +0 -88
- package/src/values/animations.js +0 -53
- package/src/values/animations.test.js +0 -154
- package/src/values/box-shadows.test.js +0 -82
- package/src/values/colors.js +0 -192
- package/src/values/colors.test.js +0 -804
- package/src/values/font-families.js +0 -98
- package/src/values/font-families.test.js +0 -119
- package/src/values/font-sizes.js +0 -92
- package/src/values/font-sizes.test.js +0 -120
- package/src/values/text-shadows.test.js +0 -93
- package/src/values/units.test.js +0 -72
- package/src/values/values.js +0 -30
- package/src/values/vendor-prefix.js +0 -45
- package/src/values/vendor-prefix.test.js +0 -64
- package/src/values/z-index.test.js +0 -54
- package/src/vendor-prefix.js +0 -16
package/src/rules/rules.test.js
DELETED
|
@@ -1,247 +0,0 @@
|
|
|
1
|
-
import { suite } from 'uvu';
|
|
2
|
-
import * as assert from 'uvu/assert';
|
|
3
|
-
import { analyze } from '../index.js'
|
|
4
|
-
|
|
5
|
-
const Rules = suite('Rules')
|
|
6
|
-
|
|
7
|
-
Rules('should count rules', () => {
|
|
8
|
-
assert.is(analyze(`
|
|
9
|
-
html {
|
|
10
|
-
color: black;
|
|
11
|
-
}
|
|
12
|
-
test {}
|
|
13
|
-
`).rules.total, 2)
|
|
14
|
-
})
|
|
15
|
-
|
|
16
|
-
Rules('should count empty rules', () => {
|
|
17
|
-
assert.is(1, analyze(`test{}`).rules.empty.total)
|
|
18
|
-
assert.is(analyze('@media print {}').rules.empty.total, 0)
|
|
19
|
-
assert.is(analyze(`
|
|
20
|
-
@media print {
|
|
21
|
-
empty {}
|
|
22
|
-
}
|
|
23
|
-
`).rules.empty.total, 1)
|
|
24
|
-
assert.is(analyze('test { color: red; }').rules.empty.total, 0)
|
|
25
|
-
})
|
|
26
|
-
|
|
27
|
-
Rules('calculate the minimum selectors', () => {
|
|
28
|
-
assert.is(analyze(`
|
|
29
|
-
html {}
|
|
30
|
-
a,
|
|
31
|
-
b {}
|
|
32
|
-
`).rules.selectors.min, 1)
|
|
33
|
-
})
|
|
34
|
-
|
|
35
|
-
Rules('calculate the maximum selectors', () => {
|
|
36
|
-
assert.is(analyze(`
|
|
37
|
-
html {}
|
|
38
|
-
a,
|
|
39
|
-
b {}
|
|
40
|
-
`).rules.selectors.max, 2)
|
|
41
|
-
})
|
|
42
|
-
|
|
43
|
-
Rules('calculate the mode of selectors', () => {
|
|
44
|
-
assert.is(analyze(`
|
|
45
|
-
html {}
|
|
46
|
-
a,
|
|
47
|
-
b {}
|
|
48
|
-
x {}
|
|
49
|
-
`).rules.selectors.mode, 1)
|
|
50
|
-
})
|
|
51
|
-
|
|
52
|
-
Rules('calculate the mean of selectors', () => {
|
|
53
|
-
assert.is(analyze(`
|
|
54
|
-
html {}
|
|
55
|
-
a,
|
|
56
|
-
b {}
|
|
57
|
-
`).rules.selectors.mean, 1.5)
|
|
58
|
-
})
|
|
59
|
-
|
|
60
|
-
Rules('calculate the median of selectors', () => {
|
|
61
|
-
assert.is(analyze(`
|
|
62
|
-
html {}
|
|
63
|
-
a,
|
|
64
|
-
b {}
|
|
65
|
-
`).rules.selectors.median, 1.5)
|
|
66
|
-
})
|
|
67
|
-
|
|
68
|
-
Rules('calculate the range of selectors', () => {
|
|
69
|
-
assert.is(analyze(`
|
|
70
|
-
html {}
|
|
71
|
-
|
|
72
|
-
a,
|
|
73
|
-
b {}
|
|
74
|
-
|
|
75
|
-
a,
|
|
76
|
-
b,
|
|
77
|
-
c {}
|
|
78
|
-
`).rules.selectors.range, 2)
|
|
79
|
-
})
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
Rules('calculate the minimum declarations', () => {
|
|
83
|
-
assert.is(analyze(`
|
|
84
|
-
html {}
|
|
85
|
-
test {
|
|
86
|
-
color: red;
|
|
87
|
-
}
|
|
88
|
-
`).rules.declarations.min, 0)
|
|
89
|
-
assert.is(analyze('@media print {}').rules.declarations.min, 0)
|
|
90
|
-
})
|
|
91
|
-
|
|
92
|
-
Rules('calculate the maximum declarations', () => {
|
|
93
|
-
assert.is(analyze(`
|
|
94
|
-
html {}
|
|
95
|
-
test {
|
|
96
|
-
a: 1;
|
|
97
|
-
b: 2;
|
|
98
|
-
c: 3;
|
|
99
|
-
}
|
|
100
|
-
`).rules.declarations.max, 3)
|
|
101
|
-
|
|
102
|
-
assert.is(analyze(`
|
|
103
|
-
html {}
|
|
104
|
-
test {
|
|
105
|
-
a: 1;
|
|
106
|
-
b: 2;
|
|
107
|
-
c: 3;
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
@media print {
|
|
111
|
-
test {
|
|
112
|
-
a: 1;
|
|
113
|
-
b: 2;
|
|
114
|
-
c: 3;
|
|
115
|
-
d: 4;
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
`).rules.declarations.max, 4)
|
|
119
|
-
})
|
|
120
|
-
|
|
121
|
-
Rules('calculate the mode of declarations', () => {
|
|
122
|
-
assert.is(analyze(`
|
|
123
|
-
html {
|
|
124
|
-
a: 1;
|
|
125
|
-
}
|
|
126
|
-
test {
|
|
127
|
-
a: 1;
|
|
128
|
-
}
|
|
129
|
-
test {
|
|
130
|
-
a: 1;
|
|
131
|
-
b: 2;
|
|
132
|
-
}
|
|
133
|
-
`).rules.declarations.mode, 1)
|
|
134
|
-
})
|
|
135
|
-
|
|
136
|
-
Rules('calculate the mean of declarations', () => {
|
|
137
|
-
assert.is(analyze(`
|
|
138
|
-
html {
|
|
139
|
-
a: 1;
|
|
140
|
-
}
|
|
141
|
-
a {
|
|
142
|
-
a: 1;
|
|
143
|
-
b: 2;
|
|
144
|
-
}
|
|
145
|
-
b {
|
|
146
|
-
a: 1;
|
|
147
|
-
b: 2;
|
|
148
|
-
c: 3;
|
|
149
|
-
}
|
|
150
|
-
`).rules.declarations.mean, 2)
|
|
151
|
-
})
|
|
152
|
-
|
|
153
|
-
Rules('calculate the median of declarations', () => {
|
|
154
|
-
assert.is(analyze(`
|
|
155
|
-
html {
|
|
156
|
-
a: 1;
|
|
157
|
-
}
|
|
158
|
-
a {
|
|
159
|
-
a: 1;
|
|
160
|
-
b: 2;
|
|
161
|
-
}
|
|
162
|
-
b {
|
|
163
|
-
a: 1;
|
|
164
|
-
b: 2;
|
|
165
|
-
c: 3;
|
|
166
|
-
}
|
|
167
|
-
`).rules.declarations.median, 2)
|
|
168
|
-
})
|
|
169
|
-
|
|
170
|
-
Rules('calculate the range of declarations', () => {
|
|
171
|
-
assert.is(analyze(`
|
|
172
|
-
html {
|
|
173
|
-
a: 1;
|
|
174
|
-
}
|
|
175
|
-
a {
|
|
176
|
-
a: 1;
|
|
177
|
-
b: 2;
|
|
178
|
-
}
|
|
179
|
-
b {
|
|
180
|
-
a: 1;
|
|
181
|
-
b: 2;
|
|
182
|
-
c: 3;
|
|
183
|
-
}
|
|
184
|
-
`).rules.declarations.range, 2)
|
|
185
|
-
})
|
|
186
|
-
|
|
187
|
-
Rules('return a list of declaration counts per rule', () => {
|
|
188
|
-
const actual = analyze(`
|
|
189
|
-
html {
|
|
190
|
-
a: 1;
|
|
191
|
-
}
|
|
192
|
-
a {
|
|
193
|
-
a: 1;
|
|
194
|
-
b: 2;
|
|
195
|
-
}
|
|
196
|
-
b {
|
|
197
|
-
a: 1;
|
|
198
|
-
b: 2;
|
|
199
|
-
c: 3;
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
@media print {
|
|
203
|
-
@supports (display: grid) {
|
|
204
|
-
c {
|
|
205
|
-
a: 1;
|
|
206
|
-
b: 2;
|
|
207
|
-
}
|
|
208
|
-
d {}
|
|
209
|
-
}
|
|
210
|
-
}
|
|
211
|
-
`).rules.declarations.items
|
|
212
|
-
const expected = [1, 2, 3, 2, 0]
|
|
213
|
-
assert.equal(actual, expected)
|
|
214
|
-
})
|
|
215
|
-
|
|
216
|
-
Rules('return a list of selectors counts per rule', () => {
|
|
217
|
-
const actual = analyze(`
|
|
218
|
-
x {
|
|
219
|
-
a: 1;
|
|
220
|
-
}
|
|
221
|
-
a,
|
|
222
|
-
b {
|
|
223
|
-
a: 1;
|
|
224
|
-
b: 2;
|
|
225
|
-
}
|
|
226
|
-
c,
|
|
227
|
-
d,
|
|
228
|
-
e {
|
|
229
|
-
a: 1;
|
|
230
|
-
b: 2;
|
|
231
|
-
c: 3;
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
@media print {
|
|
235
|
-
@supports (display: grid) {
|
|
236
|
-
f {
|
|
237
|
-
a: 1;
|
|
238
|
-
b: 2;
|
|
239
|
-
}
|
|
240
|
-
}
|
|
241
|
-
}
|
|
242
|
-
`).rules.declarations.items
|
|
243
|
-
const expected = [1, 2, 3, 2]
|
|
244
|
-
assert.equal(actual, expected)
|
|
245
|
-
})
|
|
246
|
-
|
|
247
|
-
Rules.run()
|
|
@@ -1,123 +0,0 @@
|
|
|
1
|
-
import { suite } from 'uvu'
|
|
2
|
-
import * as assert from 'uvu/assert'
|
|
3
|
-
import { analyze } from '../index.js'
|
|
4
|
-
|
|
5
|
-
const Complexity = suite('Selector Complexity')
|
|
6
|
-
|
|
7
|
-
const fixture = `
|
|
8
|
-
*,
|
|
9
|
-
* + *,
|
|
10
|
-
a,
|
|
11
|
-
a b,
|
|
12
|
-
a + b,
|
|
13
|
-
a ~ b,
|
|
14
|
-
#id,
|
|
15
|
-
.className,
|
|
16
|
-
[attr],
|
|
17
|
-
[attr=value],
|
|
18
|
-
:where(#id, .class),
|
|
19
|
-
main > :is(h1, h2) {}
|
|
20
|
-
`
|
|
21
|
-
|
|
22
|
-
Complexity('calculates complexity', () => {
|
|
23
|
-
const actual = analyze(fixture).selectors.complexity.items
|
|
24
|
-
const expected = [
|
|
25
|
-
1,
|
|
26
|
-
3,
|
|
27
|
-
1,
|
|
28
|
-
3,
|
|
29
|
-
3,
|
|
30
|
-
3,
|
|
31
|
-
1,
|
|
32
|
-
1,
|
|
33
|
-
1,
|
|
34
|
-
2,
|
|
35
|
-
3,
|
|
36
|
-
5,
|
|
37
|
-
]
|
|
38
|
-
|
|
39
|
-
assert.equal(actual, expected)
|
|
40
|
-
})
|
|
41
|
-
|
|
42
|
-
Complexity('calculates complexity uniqueness', () => {
|
|
43
|
-
const actual = analyze(fixture).selectors.complexity
|
|
44
|
-
const expected = {
|
|
45
|
-
'1': 5,
|
|
46
|
-
'2': 1,
|
|
47
|
-
'3': 5,
|
|
48
|
-
'5': 1
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
assert.is(actual.totalUnique, 4)
|
|
52
|
-
assert.is(actual.uniquenessRatio, 4 / 12)
|
|
53
|
-
assert.equal(actual.unique, expected)
|
|
54
|
-
})
|
|
55
|
-
|
|
56
|
-
Complexity('calculates the lowest complexity', () => {
|
|
57
|
-
const fixture = `
|
|
58
|
-
#test,
|
|
59
|
-
.me,
|
|
60
|
-
now,
|
|
61
|
-
[crazy] ~ .selector > for [no|="good"] {}
|
|
62
|
-
`
|
|
63
|
-
const actual = analyze(fixture).selectors.complexity.min
|
|
64
|
-
assert.equal(actual, 1)
|
|
65
|
-
})
|
|
66
|
-
|
|
67
|
-
Complexity('calculates the highest complexity', () => {
|
|
68
|
-
const fixture = `
|
|
69
|
-
#test,
|
|
70
|
-
.me,
|
|
71
|
-
now,
|
|
72
|
-
[crazy] ~ .selector > for [no|="good"] {}
|
|
73
|
-
`
|
|
74
|
-
const actual = analyze(fixture).selectors.complexity.max
|
|
75
|
-
assert.equal(actual, 8)
|
|
76
|
-
})
|
|
77
|
-
|
|
78
|
-
Complexity('calculates the complexity mean', () => {
|
|
79
|
-
const fixture = `
|
|
80
|
-
#test,
|
|
81
|
-
.me,
|
|
82
|
-
now,
|
|
83
|
-
[crazy] ~ .selector > for [no|="good"] {}
|
|
84
|
-
`
|
|
85
|
-
const result = analyze(fixture)
|
|
86
|
-
const actual = result.selectors.complexity.mean
|
|
87
|
-
assert.equal(actual, (1 + 1 + 1 + 8) / 4)
|
|
88
|
-
})
|
|
89
|
-
|
|
90
|
-
Complexity('calculates the complexity mode', () => {
|
|
91
|
-
const fixture = `
|
|
92
|
-
#test,
|
|
93
|
-
.me,
|
|
94
|
-
now,
|
|
95
|
-
[crazy] ~ .selector > for [no|="good"] {}
|
|
96
|
-
`
|
|
97
|
-
const actual = analyze(fixture).selectors.complexity.mode
|
|
98
|
-
assert.equal(actual, 1)
|
|
99
|
-
})
|
|
100
|
-
|
|
101
|
-
Complexity('calculates the complexity median', () => {
|
|
102
|
-
const fixture = `
|
|
103
|
-
#test,
|
|
104
|
-
.me,
|
|
105
|
-
now,
|
|
106
|
-
[crazy] ~ .selector > check {}
|
|
107
|
-
`
|
|
108
|
-
const actual = analyze(fixture).selectors.complexity.median
|
|
109
|
-
assert.equal(actual, 1)
|
|
110
|
-
})
|
|
111
|
-
|
|
112
|
-
Complexity('calculates total complexity', () => {
|
|
113
|
-
const fixture = `
|
|
114
|
-
#test,
|
|
115
|
-
.me,
|
|
116
|
-
now,
|
|
117
|
-
[crazy] ~ .selector > for [no|="good"] {}
|
|
118
|
-
`
|
|
119
|
-
const actual = analyze(fixture).selectors.complexity.sum
|
|
120
|
-
assert.equal(actual, 11)
|
|
121
|
-
})
|
|
122
|
-
|
|
123
|
-
Complexity.run()
|
|
@@ -1,122 +0,0 @@
|
|
|
1
|
-
import { analyzeSpecificity, compareSpecificity } from './specificity.js'
|
|
2
|
-
import { AggregateCollection } from '../aggregate-collection.js'
|
|
3
|
-
import { CountableCollection } from '../countable-collection.js'
|
|
4
|
-
|
|
5
|
-
/** @typedef {[number, number, number]} Specificity */
|
|
6
|
-
|
|
7
|
-
const analyzeSelectors = ({ stringifyNode, selectors }) => {
|
|
8
|
-
const counts = Object.create(null)
|
|
9
|
-
const cache = Object.create(null)
|
|
10
|
-
const totalSelectors = selectors.length
|
|
11
|
-
|
|
12
|
-
/** @type Specificity|undefined */
|
|
13
|
-
let maxSpecificity
|
|
14
|
-
/** @type Specificity|undefined */
|
|
15
|
-
let minSpecificity
|
|
16
|
-
let specificityA = new AggregateCollection(totalSelectors)
|
|
17
|
-
let specificityB = new AggregateCollection(totalSelectors)
|
|
18
|
-
let specificityC = new AggregateCollection(totalSelectors)
|
|
19
|
-
let totalUnique = 0
|
|
20
|
-
const complexityAggregator = new AggregateCollection(totalSelectors);
|
|
21
|
-
|
|
22
|
-
const specificities = []
|
|
23
|
-
const complexities = []
|
|
24
|
-
const ids = new CountableCollection()
|
|
25
|
-
const a11y = new CountableCollection()
|
|
26
|
-
const keyframes = new CountableCollection()
|
|
27
|
-
|
|
28
|
-
for (let i = 0; i < totalSelectors; i++) {
|
|
29
|
-
const node = selectors[i];
|
|
30
|
-
const value = stringifyNode(node)
|
|
31
|
-
|
|
32
|
-
if (node.isKeyframeSelector) {
|
|
33
|
-
keyframes.push(value)
|
|
34
|
-
// Do not attempt to further analyze <keyframe-selectors>
|
|
35
|
-
continue
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
const { specificity, complexity, isId, isA11y } = cache[value] || analyzeSpecificity(node)
|
|
39
|
-
|
|
40
|
-
if (isId) {
|
|
41
|
-
ids.push(value)
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
if (isA11y) {
|
|
45
|
-
a11y.push(value)
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
if (!cache[value]) {
|
|
49
|
-
cache[value] = { complexity, specificity, isId, isA11y }
|
|
50
|
-
totalUnique++
|
|
51
|
-
counts[value] = 1
|
|
52
|
-
} else {
|
|
53
|
-
counts[value]++
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
complexityAggregator.add(complexity)
|
|
57
|
-
|
|
58
|
-
if (maxSpecificity === undefined) {
|
|
59
|
-
maxSpecificity = specificity
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
if (minSpecificity === undefined) {
|
|
63
|
-
minSpecificity = specificity
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
specificityA.add(specificity[0])
|
|
67
|
-
specificityB.add(specificity[1])
|
|
68
|
-
specificityC.add(specificity[2])
|
|
69
|
-
|
|
70
|
-
if (minSpecificity !== undefined && compareSpecificity(minSpecificity, specificity) < 0) {
|
|
71
|
-
minSpecificity = specificity
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
if (maxSpecificity !== undefined && compareSpecificity(maxSpecificity, specificity) > 0) {
|
|
75
|
-
maxSpecificity = specificity
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
specificities.push(specificity)
|
|
79
|
-
complexities.push(complexity)
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
const aggregatesA = specificityA.aggregate()
|
|
83
|
-
const aggregatesB = specificityB.aggregate()
|
|
84
|
-
const aggregatesC = specificityC.aggregate()
|
|
85
|
-
const complexityCount = new CountableCollection(complexities).count()
|
|
86
|
-
|
|
87
|
-
return {
|
|
88
|
-
total: totalSelectors,
|
|
89
|
-
totalUnique,
|
|
90
|
-
uniquenessRatio: totalUnique / totalSelectors,
|
|
91
|
-
specificity: {
|
|
92
|
-
sum: [aggregatesA.sum, aggregatesB.sum, aggregatesC.sum],
|
|
93
|
-
min: minSpecificity,
|
|
94
|
-
max: maxSpecificity,
|
|
95
|
-
mean: [aggregatesA.mean, aggregatesB.mean, aggregatesC.mean],
|
|
96
|
-
mode: [aggregatesA.mode, aggregatesB.mode, aggregatesC.mode],
|
|
97
|
-
median: [aggregatesA.median, aggregatesB.median, aggregatesC.median],
|
|
98
|
-
items: specificities
|
|
99
|
-
},
|
|
100
|
-
complexity: {
|
|
101
|
-
...complexityAggregator.aggregate(),
|
|
102
|
-
...complexityCount,
|
|
103
|
-
items: complexities,
|
|
104
|
-
},
|
|
105
|
-
id: {
|
|
106
|
-
...ids.count(),
|
|
107
|
-
ratio: ids.size() / totalSelectors,
|
|
108
|
-
},
|
|
109
|
-
accessibility: {
|
|
110
|
-
...a11y.count(),
|
|
111
|
-
ratio: a11y.size() / totalSelectors,
|
|
112
|
-
},
|
|
113
|
-
keyframes: {
|
|
114
|
-
...keyframes.count(),
|
|
115
|
-
ratio: keyframes.size() / totalSelectors,
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
export {
|
|
121
|
-
analyzeSelectors
|
|
122
|
-
}
|
|
@@ -1,189 +0,0 @@
|
|
|
1
|
-
import { suite } from 'uvu'
|
|
2
|
-
import * as assert from 'uvu/assert'
|
|
3
|
-
import { analyze } from '../index.js'
|
|
4
|
-
|
|
5
|
-
const Selectors = suite('Selectors')
|
|
6
|
-
|
|
7
|
-
Selectors('are analyzed', () => {
|
|
8
|
-
const fixture = `
|
|
9
|
-
rule {
|
|
10
|
-
color: green;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
@media print {
|
|
14
|
-
@media (min-width: 1000px) {
|
|
15
|
-
@supports (display: grid) {
|
|
16
|
-
another-rule {
|
|
17
|
-
color: purple;
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
`
|
|
23
|
-
const actual = analyze(fixture).selectors.total
|
|
24
|
-
|
|
25
|
-
assert.equal(actual, 2)
|
|
26
|
-
})
|
|
27
|
-
|
|
28
|
-
Selectors('have their complexity calculated', () => {
|
|
29
|
-
const fixture = `
|
|
30
|
-
rule {
|
|
31
|
-
color: green;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
@media print {
|
|
35
|
-
@media (min-width: 1000px) {
|
|
36
|
-
@supports (display: grid) {
|
|
37
|
-
another-rule {
|
|
38
|
-
color: purple;
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
`
|
|
44
|
-
const actual = analyze(fixture).selectors.complexity.items
|
|
45
|
-
const expected = [1, 1]
|
|
46
|
-
|
|
47
|
-
assert.equal(actual, expected)
|
|
48
|
-
})
|
|
49
|
-
|
|
50
|
-
Selectors('have their specificity calculated', () => {
|
|
51
|
-
const fixture = `
|
|
52
|
-
rule {
|
|
53
|
-
color: green;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
@media print {
|
|
57
|
-
@media (min-width: 1000px) {
|
|
58
|
-
@supports (display: grid) {
|
|
59
|
-
another-rule {
|
|
60
|
-
color: purple;
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
`
|
|
66
|
-
const actual = analyze(fixture)
|
|
67
|
-
const expected = [
|
|
68
|
-
[0, 0, 1,],
|
|
69
|
-
[0, 0, 1,]
|
|
70
|
-
]
|
|
71
|
-
|
|
72
|
-
assert.equal(actual.selectors.specificity.items, expected)
|
|
73
|
-
assert.equal(actual.selectors.total, 2)
|
|
74
|
-
})
|
|
75
|
-
|
|
76
|
-
Selectors('calculates selector uniqueness', () => {
|
|
77
|
-
const fixture = `
|
|
78
|
-
a {}
|
|
79
|
-
b {}
|
|
80
|
-
|
|
81
|
-
@media print {
|
|
82
|
-
b {}
|
|
83
|
-
c {}
|
|
84
|
-
}
|
|
85
|
-
`
|
|
86
|
-
const actual = analyze(fixture).selectors
|
|
87
|
-
|
|
88
|
-
assert.is(actual.total, 4)
|
|
89
|
-
assert.is(actual.totalUnique, 3)
|
|
90
|
-
assert.is(actual.uniquenessRatio, 3 / 4)
|
|
91
|
-
})
|
|
92
|
-
|
|
93
|
-
Selectors('counts <keyframes-selector>s', () => {
|
|
94
|
-
const fixture = `
|
|
95
|
-
myElement1 {
|
|
96
|
-
opacity: 1;
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
@keyframes test1 {
|
|
100
|
-
from {
|
|
101
|
-
opacity: 1;
|
|
102
|
-
}
|
|
103
|
-
50% {
|
|
104
|
-
opacity: 0;
|
|
105
|
-
}
|
|
106
|
-
to {
|
|
107
|
-
opacity: 1;
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
@media only screen {
|
|
112
|
-
myElement2 {
|
|
113
|
-
opacity: 1;
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
@keyframes test2 {
|
|
117
|
-
from {
|
|
118
|
-
opacity: 0.1;
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
`
|
|
123
|
-
const result = analyze(fixture)
|
|
124
|
-
const actual = result.selectors
|
|
125
|
-
assert.is(actual.total, 6)
|
|
126
|
-
assert.equal(actual.keyframes, {
|
|
127
|
-
total: 4,
|
|
128
|
-
totalUnique: 3,
|
|
129
|
-
unique: {
|
|
130
|
-
from: 2,
|
|
131
|
-
to: 1,
|
|
132
|
-
'50%': 1
|
|
133
|
-
},
|
|
134
|
-
uniquenessRatio: 3 / 4,
|
|
135
|
-
ratio: 4 / 6
|
|
136
|
-
})
|
|
137
|
-
})
|
|
138
|
-
|
|
139
|
-
Selectors('counts ID selectors', () => {
|
|
140
|
-
const fixture = `
|
|
141
|
-
#myId,
|
|
142
|
-
#myId,
|
|
143
|
-
element#id,
|
|
144
|
-
#multiple #ids { }
|
|
145
|
-
|
|
146
|
-
/* Not an ID */
|
|
147
|
-
[href="#hash"] { }
|
|
148
|
-
`
|
|
149
|
-
const actual = analyze(fixture).selectors.id
|
|
150
|
-
const expected = {
|
|
151
|
-
total: 4,
|
|
152
|
-
totalUnique: 3,
|
|
153
|
-
unique: {
|
|
154
|
-
'#myId': 2,
|
|
155
|
-
'element#id': 1,
|
|
156
|
-
'#multiple #ids': 1,
|
|
157
|
-
},
|
|
158
|
-
uniquenessRatio: 3 / 4,
|
|
159
|
-
ratio: 4 / 5
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
assert.equal(actual, expected)
|
|
163
|
-
})
|
|
164
|
-
|
|
165
|
-
Selectors('counts Accessibility selectors', () => {
|
|
166
|
-
const fixture = `
|
|
167
|
-
[aria-hidden],
|
|
168
|
-
img[role="presentation"] {}
|
|
169
|
-
|
|
170
|
-
/* false positives */
|
|
171
|
-
img[loading="lazy"],
|
|
172
|
-
[hidden] {}
|
|
173
|
-
`
|
|
174
|
-
const actual = analyze(fixture).selectors.accessibility
|
|
175
|
-
const expected = {
|
|
176
|
-
total: 2,
|
|
177
|
-
totalUnique: 2,
|
|
178
|
-
unique: {
|
|
179
|
-
'[aria-hidden]': 1,
|
|
180
|
-
'img[role="presentation"]': 1,
|
|
181
|
-
},
|
|
182
|
-
uniquenessRatio: 1 / 1,
|
|
183
|
-
ratio: 2 / 4
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
assert.equal(actual, expected)
|
|
187
|
-
})
|
|
188
|
-
|
|
189
|
-
Selectors.run()
|