@caweb/cli 1.4.1 → 1.4.3
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/README.md +38 -12
- package/bin/css-audit/.editorconfig +12 -0
- package/bin/css-audit/.github/workflows/build-report.yml +46 -0
- package/bin/css-audit/.github/workflows/merge-trunk-to-report.yml +17 -0
- package/bin/css-audit/.github/workflows/node.yaml +32 -0
- package/bin/css-audit/.nvmrc +1 -0
- package/bin/css-audit/README.md +131 -0
- package/bin/css-audit/css-audit.config.js +13 -0
- package/bin/css-audit/index.js +38 -0
- package/bin/css-audit/package-lock.json +6689 -0
- package/bin/css-audit/package.json +56 -0
- package/bin/css-audit/public/.gitkeep +1 -0
- package/bin/css-audit/src/__tests__/alphas.js +128 -0
- package/bin/css-audit/src/__tests__/colors.js +115 -0
- package/bin/css-audit/src/__tests__/display-none.js +52 -0
- package/bin/css-audit/src/__tests__/important.js +88 -0
- package/bin/css-audit/src/__tests__/media-queries.js +84 -0
- package/bin/css-audit/src/__tests__/property-values.js +55 -0
- package/bin/css-audit/src/__tests__/run.js +25 -0
- package/bin/css-audit/src/__tests__/selectors.js +66 -0
- package/bin/css-audit/src/audits/alphas.js +70 -0
- package/bin/css-audit/src/audits/colors.js +83 -0
- package/bin/css-audit/src/audits/display-none.js +39 -0
- package/bin/css-audit/src/audits/important.js +60 -0
- package/bin/css-audit/src/audits/media-queries.js +96 -0
- package/bin/css-audit/src/audits/property-values.js +65 -0
- package/bin/css-audit/src/audits/selectors.js +67 -0
- package/bin/css-audit/src/audits/typography.js +41 -0
- package/bin/css-audit/src/formats/cli-table.js +81 -0
- package/bin/css-audit/src/formats/html/_audit-alpha.twig +23 -0
- package/bin/css-audit/src/formats/html/_audit-colors.twig +23 -0
- package/bin/css-audit/src/formats/html/_audit-default.twig +24 -0
- package/bin/css-audit/src/formats/html/index.twig +88 -0
- package/bin/css-audit/src/formats/html/style.css +341 -0
- package/bin/css-audit/src/formats/html.js +52 -0
- package/bin/css-audit/src/formats/json.js +9 -0
- package/bin/css-audit/src/run.js +76 -0
- package/bin/css-audit/src/utils/__tests__/cli.js +70 -0
- package/bin/css-audit/src/utils/__tests__/example-config.config.js +12 -0
- package/bin/css-audit/src/utils/__tests__/get-specificity.js +39 -0
- package/bin/css-audit/src/utils/cli.js +133 -0
- package/bin/css-audit/src/utils/format-report.js +37 -0
- package/bin/css-audit/src/utils/get-specificity.js +97 -0
- package/bin/css-audit/src/utils/get-values-count.js +17 -0
- package/commands/audit.js +135 -0
- package/commands/index.js +7 -4
- package/commands/webpack/webpack.js +133 -0
- package/configs/css-audit.config.cjs +9 -0
- package/configs/webpack.config.js +126 -78
- package/docs/CREDITS.MD +5 -0
- package/docs/ROADMAP.MD +6 -5
- package/lib/cli.js +13 -4
- package/lib/helpers.js +3 -0
- package/package.json +15 -8
- package/commands/build.js +0 -80
- package/commands/serve.js +0 -94
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "css-audit",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "",
|
|
5
|
+
"main": "index.js",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"css-audit": "node ./index.js",
|
|
8
|
+
"lint:js": "eslint src",
|
|
9
|
+
"format:js": "prettier src/**/*.js *.js --write",
|
|
10
|
+
"test": "jest"
|
|
11
|
+
},
|
|
12
|
+
"author": "WordPress CSS Contributors",
|
|
13
|
+
"license": "GPL-2.0-or-later",
|
|
14
|
+
"dependencies": {
|
|
15
|
+
"@wordpress/eslint-plugin": "9.0.4",
|
|
16
|
+
"@wordpress/prettier-config": "1.0.3",
|
|
17
|
+
"chalk": "4.1.1",
|
|
18
|
+
"cli-table3": "0.6.0",
|
|
19
|
+
"cosmiconfig": "7.0.0",
|
|
20
|
+
"css-tree": "1.1.3",
|
|
21
|
+
"cssom": "0.4.4",
|
|
22
|
+
"eslint": "7.26.0",
|
|
23
|
+
"fs-extra": "10.0.0",
|
|
24
|
+
"glob": "7.1.7",
|
|
25
|
+
"minimist": "1.2.6",
|
|
26
|
+
"postcss": "8.2.15",
|
|
27
|
+
"postcss-values-parser": "5.0.0",
|
|
28
|
+
"prettier": "npm:wp-prettier@^2.0.5",
|
|
29
|
+
"tinycolor2": "1.4.2"
|
|
30
|
+
},
|
|
31
|
+
"eslintConfig": {
|
|
32
|
+
"extends": [
|
|
33
|
+
"plugin:@wordpress/eslint-plugin/esnext",
|
|
34
|
+
"plugin:prettier/recommended"
|
|
35
|
+
],
|
|
36
|
+
"rules": {
|
|
37
|
+
"no-console": "off"
|
|
38
|
+
},
|
|
39
|
+
"env": {
|
|
40
|
+
"node": true,
|
|
41
|
+
"jest": true
|
|
42
|
+
}
|
|
43
|
+
},
|
|
44
|
+
"jest": {
|
|
45
|
+
"modulePathIgnorePatterns": [
|
|
46
|
+
"fixtures",
|
|
47
|
+
".config.js"
|
|
48
|
+
]
|
|
49
|
+
},
|
|
50
|
+
"prettier": "@wordpress/prettier-config",
|
|
51
|
+
"devDependencies": {
|
|
52
|
+
"handlebars": "4.7.7",
|
|
53
|
+
"jest": "26.6.3",
|
|
54
|
+
"twing": "5.0.2"
|
|
55
|
+
}
|
|
56
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
const audit = require( '../audits/alphas' );
|
|
2
|
+
|
|
3
|
+
function getResultValue( results, key ) {
|
|
4
|
+
const { value } = results.find( ( { id } ) => key === id );
|
|
5
|
+
return value;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
describe( 'Audit: Alphas', () => {
|
|
9
|
+
it( 'should return no values when no transparent colors are used', () => {
|
|
10
|
+
const files = [
|
|
11
|
+
{
|
|
12
|
+
name: 'a.css',
|
|
13
|
+
content: `body { font-size: 1em; line-height: 1.6; color: red }`,
|
|
14
|
+
},
|
|
15
|
+
];
|
|
16
|
+
const { results } = audit( files );
|
|
17
|
+
expect( getResultValue( results, 'unique' ) ).toBe( 0 );
|
|
18
|
+
} );
|
|
19
|
+
|
|
20
|
+
it( 'should count the number of alpha values in a file', () => {
|
|
21
|
+
const files = [
|
|
22
|
+
{
|
|
23
|
+
name: 'a.css',
|
|
24
|
+
content: `body { color: rgba(0, 0, 0, 0.3); }`,
|
|
25
|
+
},
|
|
26
|
+
];
|
|
27
|
+
const { results } = audit( files );
|
|
28
|
+
expect( getResultValue( results, 'unique' ) ).toBe( 1 );
|
|
29
|
+
} );
|
|
30
|
+
|
|
31
|
+
it( 'should find values across rulesets', () => {
|
|
32
|
+
const files = [
|
|
33
|
+
{
|
|
34
|
+
name: 'a.css',
|
|
35
|
+
content: `h1 { color: rgba(52, 0, 182, 0.95); }
|
|
36
|
+
h2 { color: rgba(206, 234, 196, .95); }
|
|
37
|
+
h3 { color: rgba( 119, 255, 214, 0.125); }
|
|
38
|
+
h4 { color: rgba(201, 15, 59, .875); }
|
|
39
|
+
h4 { color: rgba(0, 0, 0, 1); }`,
|
|
40
|
+
},
|
|
41
|
+
];
|
|
42
|
+
const { results } = audit( files );
|
|
43
|
+
expect( getResultValue( results, 'unique' ) ).toBe( 4 );
|
|
44
|
+
expect( getResultValue( results, 'unique-colors' ) ).toBe( 5 );
|
|
45
|
+
expect( getResultValue( results, 'all-alphas' ) ).toEqual( [
|
|
46
|
+
{
|
|
47
|
+
count: 2,
|
|
48
|
+
name: 0.95,
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
count: 1,
|
|
52
|
+
name: 0.125,
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
count: 1,
|
|
56
|
+
name: 0.875,
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
count: 1,
|
|
60
|
+
name: 1,
|
|
61
|
+
},
|
|
62
|
+
] );
|
|
63
|
+
expect( getResultValue( results, 'all-colors' ) ).toEqual( [
|
|
64
|
+
'rgba( 119, 255, 214, 0.125)',
|
|
65
|
+
'rgba(0, 0, 0, 1)',
|
|
66
|
+
'rgba(201, 15, 59, .875)',
|
|
67
|
+
'rgba(206, 234, 196, .95)',
|
|
68
|
+
'rgba(52, 0, 182, 0.95)',
|
|
69
|
+
] );
|
|
70
|
+
} );
|
|
71
|
+
|
|
72
|
+
it( 'should find values in all color functions', () => {
|
|
73
|
+
const files = [
|
|
74
|
+
{
|
|
75
|
+
name: 'a.css',
|
|
76
|
+
content: `h1 { color: hsla(95, 55%, 46%, 0.9); }
|
|
77
|
+
h2 { color: hsl(290, 72%, 24%, .333); }
|
|
78
|
+
h3 { color: rgb(41, 194, 191, 1); }
|
|
79
|
+
h4 { color: hsl(198 92 20 / 0.5); }
|
|
80
|
+
h5 { color: rgb(13 1 26 / 0.05); }`,
|
|
81
|
+
},
|
|
82
|
+
];
|
|
83
|
+
const { results } = audit( files );
|
|
84
|
+
expect( getResultValue( results, 'unique' ) ).toBe( 5 );
|
|
85
|
+
expect( getResultValue( results, 'unique-colors' ) ).toBe( 5 );
|
|
86
|
+
expect( getResultValue( results, 'all-alphas' ) ).toEqual( [
|
|
87
|
+
{
|
|
88
|
+
count: 1,
|
|
89
|
+
name: 0.9,
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
count: 1,
|
|
93
|
+
name: 0.333,
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
count: 1,
|
|
97
|
+
name: 1,
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
count: 1,
|
|
101
|
+
name: 0.5,
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
count: 1,
|
|
105
|
+
name: 0.05,
|
|
106
|
+
},
|
|
107
|
+
] );
|
|
108
|
+
expect( getResultValue( results, 'all-colors' ) ).toEqual( [
|
|
109
|
+
'hsl(198 92 20 / 0.5)',
|
|
110
|
+
'hsl(290, 72%, 24%, .333)',
|
|
111
|
+
'hsla(95, 55%, 46%, 0.9)',
|
|
112
|
+
'rgb(13 1 26 / 0.05)',
|
|
113
|
+
'rgb(41, 194, 191, 1)',
|
|
114
|
+
] );
|
|
115
|
+
} );
|
|
116
|
+
|
|
117
|
+
it( 'should count alphas in shorthand properties', () => {
|
|
118
|
+
const files = [
|
|
119
|
+
{
|
|
120
|
+
name: 'a.css',
|
|
121
|
+
content: `body { border: 3px solid rgba(0, 0, 0, 0.5); }`,
|
|
122
|
+
},
|
|
123
|
+
];
|
|
124
|
+
const { results } = audit( files );
|
|
125
|
+
const { value } = results.find( ( { id } ) => 'unique' === id );
|
|
126
|
+
expect( value ).toBe( 1 );
|
|
127
|
+
} );
|
|
128
|
+
} );
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
const audit = require( '../audits/colors' );
|
|
2
|
+
|
|
3
|
+
describe( 'Audit: Colors', () => {
|
|
4
|
+
it( 'should return no colors when no colors are used', () => {
|
|
5
|
+
const files = [
|
|
6
|
+
{
|
|
7
|
+
name: 'a.css',
|
|
8
|
+
content: `body { font-size: 1em; line-height: 1.6; }`,
|
|
9
|
+
},
|
|
10
|
+
];
|
|
11
|
+
const { results } = audit( files );
|
|
12
|
+
const { value } = results.find( ( { id } ) => 'unique' === id );
|
|
13
|
+
expect( value ).toBe( 0 );
|
|
14
|
+
} );
|
|
15
|
+
|
|
16
|
+
it( 'should ignore colors in non-color properties', () => {
|
|
17
|
+
const files = [
|
|
18
|
+
{
|
|
19
|
+
name: 'a.css',
|
|
20
|
+
content: `body { background-image: url('logo-white.png'); }`,
|
|
21
|
+
},
|
|
22
|
+
];
|
|
23
|
+
const { results } = audit( files );
|
|
24
|
+
const { value } = results.find( ( { id } ) => 'unique' === id );
|
|
25
|
+
expect( value ).toBe( 0 );
|
|
26
|
+
} );
|
|
27
|
+
|
|
28
|
+
it( 'should handle filter values', () => {
|
|
29
|
+
const files = [
|
|
30
|
+
{
|
|
31
|
+
name: 'a.css',
|
|
32
|
+
content: `img { filter: alpha(opacity=60); }`,
|
|
33
|
+
},
|
|
34
|
+
];
|
|
35
|
+
const { results } = audit( files );
|
|
36
|
+
const { value } = results.find( ( { id } ) => 'unique' === id );
|
|
37
|
+
expect( value ).toBe( 0 );
|
|
38
|
+
} );
|
|
39
|
+
|
|
40
|
+
it( 'should count colors in shorthand properties', () => {
|
|
41
|
+
const files = [
|
|
42
|
+
{
|
|
43
|
+
name: 'a.css',
|
|
44
|
+
content: `body { border: 3px solid red; }`,
|
|
45
|
+
},
|
|
46
|
+
];
|
|
47
|
+
const { results } = audit( files );
|
|
48
|
+
const { value } = results.find( ( { id } ) => 'unique' === id );
|
|
49
|
+
expect( value ).toBe( 1 );
|
|
50
|
+
} );
|
|
51
|
+
|
|
52
|
+
it( 'should count the number of colors in a file', () => {
|
|
53
|
+
const files = [
|
|
54
|
+
{
|
|
55
|
+
name: 'a.css',
|
|
56
|
+
content: `body { color: #0ff; }`,
|
|
57
|
+
},
|
|
58
|
+
];
|
|
59
|
+
const { results } = audit( files );
|
|
60
|
+
const { value } = results.find( ( { id } ) => 'unique' === id );
|
|
61
|
+
expect( value ).toBe( 1 );
|
|
62
|
+
} );
|
|
63
|
+
|
|
64
|
+
it( 'should count the number of colors in two files', () => {
|
|
65
|
+
const files = [
|
|
66
|
+
{
|
|
67
|
+
name: 'a.css',
|
|
68
|
+
content: `body { color: #0ff; }`,
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
name: 'b.css',
|
|
72
|
+
content: `body { color: rgba(0,0,0,0.5); }`,
|
|
73
|
+
},
|
|
74
|
+
];
|
|
75
|
+
const { results } = audit( files );
|
|
76
|
+
const { value } = results.find( ( { id } ) => 'unique' === id );
|
|
77
|
+
expect( value ).toBe( 2 );
|
|
78
|
+
} );
|
|
79
|
+
|
|
80
|
+
it( 'should sort the most used colors', () => {
|
|
81
|
+
const files = [
|
|
82
|
+
{
|
|
83
|
+
name: 'a.css',
|
|
84
|
+
content: `h1 { color: red; }
|
|
85
|
+
h2 { color: pink; }
|
|
86
|
+
h3 { color: pink; }
|
|
87
|
+
h4 { color: blue; }
|
|
88
|
+
h5 { color: cyan; }
|
|
89
|
+
h6 { color: lightgreen; }`,
|
|
90
|
+
},
|
|
91
|
+
];
|
|
92
|
+
const { results } = audit( files );
|
|
93
|
+
const { value } = results.find( ( { id } ) => 'top-10-colors' === id );
|
|
94
|
+
expect( value[ 0 ].name ).toBe( 'pink' );
|
|
95
|
+
} );
|
|
96
|
+
|
|
97
|
+
it( 'should sort the least used colors', () => {
|
|
98
|
+
const files = [
|
|
99
|
+
{
|
|
100
|
+
name: 'a.css',
|
|
101
|
+
content: `h1 { color: red; }
|
|
102
|
+
h2 { color: pink; }
|
|
103
|
+
h3 { color: red; }
|
|
104
|
+
h4 { color: blue; }
|
|
105
|
+
h5 { color: blue; }
|
|
106
|
+
h6 { color: red; }`,
|
|
107
|
+
},
|
|
108
|
+
];
|
|
109
|
+
const { results } = audit( files );
|
|
110
|
+
const { value } = results.find(
|
|
111
|
+
( { id } ) => 'bottom-10-colors' === id
|
|
112
|
+
);
|
|
113
|
+
expect( value[ 0 ].name ).toBe( 'pink' );
|
|
114
|
+
} );
|
|
115
|
+
} );
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
const audit = require( '../audits/display-none' );
|
|
2
|
+
|
|
3
|
+
describe( 'Audit: Display None', () => {
|
|
4
|
+
it( 'should return nothing when display:none is not used', () => {
|
|
5
|
+
const files = [
|
|
6
|
+
{
|
|
7
|
+
name: 'a.css',
|
|
8
|
+
content: `body { font-size: 1em; line-height: 1.6; }`,
|
|
9
|
+
},
|
|
10
|
+
];
|
|
11
|
+
const { results } = audit( files );
|
|
12
|
+
const { value } = results.find( ( { id } ) => 'count' === id );
|
|
13
|
+
expect( value ).toBe( 0 );
|
|
14
|
+
} );
|
|
15
|
+
|
|
16
|
+
it( 'should count the number of display:none in a file', () => {
|
|
17
|
+
const files = [
|
|
18
|
+
{
|
|
19
|
+
name: 'a.css',
|
|
20
|
+
content: `body { display: none; }`,
|
|
21
|
+
},
|
|
22
|
+
];
|
|
23
|
+
const { results } = audit( files );
|
|
24
|
+
const { value } = results.find( ( { id } ) => 'count' === id );
|
|
25
|
+
expect( value ).toBe( 1 );
|
|
26
|
+
} );
|
|
27
|
+
|
|
28
|
+
it( 'should count the number of display:none in two files', () => {
|
|
29
|
+
const files = [
|
|
30
|
+
{
|
|
31
|
+
name: 'a.css',
|
|
32
|
+
content: `body { padding: 20px; display:none; }`,
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
name: 'b.css',
|
|
36
|
+
content: `body.hidden { display: none; }`,
|
|
37
|
+
},
|
|
38
|
+
];
|
|
39
|
+
const { results } = audit( files );
|
|
40
|
+
const { value: count } = results.find( ( { id } ) => 'count' === id );
|
|
41
|
+
expect( count ).toBe( 2 );
|
|
42
|
+
|
|
43
|
+
const { value: instances } = results.find(
|
|
44
|
+
( { id } ) => 'instances' === id
|
|
45
|
+
);
|
|
46
|
+
expect( instances ).toEqual( [
|
|
47
|
+
// Per line count looks for line breaks, so 1 is correct here.
|
|
48
|
+
{ file: 'a.css', selector: 'body' },
|
|
49
|
+
{ file: 'b.css', selector: 'body.hidden' },
|
|
50
|
+
] );
|
|
51
|
+
} );
|
|
52
|
+
} );
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
const audit = require( '../audits/important' );
|
|
2
|
+
|
|
3
|
+
describe( 'Audit: Important', () => {
|
|
4
|
+
it( 'should return nothing when important is not used', () => {
|
|
5
|
+
const files = [
|
|
6
|
+
{
|
|
7
|
+
name: 'a.css',
|
|
8
|
+
content: `body { font-size: 1em; line-height: 1.6; }`,
|
|
9
|
+
},
|
|
10
|
+
];
|
|
11
|
+
const { results } = audit( files );
|
|
12
|
+
const { value } = results.find( ( { id } ) => 'count' === id );
|
|
13
|
+
expect( value ).toBe( 0 );
|
|
14
|
+
} );
|
|
15
|
+
|
|
16
|
+
it( 'should ignore the word important in values', () => {
|
|
17
|
+
const files = [
|
|
18
|
+
{
|
|
19
|
+
name: 'a.css',
|
|
20
|
+
content: `body { background-image: url('important-logo.png'); }`,
|
|
21
|
+
},
|
|
22
|
+
];
|
|
23
|
+
const { results } = audit( files );
|
|
24
|
+
const { value } = results.find( ( { id } ) => 'count' === id );
|
|
25
|
+
expect( value ).toBe( 0 );
|
|
26
|
+
} );
|
|
27
|
+
|
|
28
|
+
it( 'should count the number of !important in a file', () => {
|
|
29
|
+
const files = [
|
|
30
|
+
{
|
|
31
|
+
name: 'a.css',
|
|
32
|
+
content: `body { color: #0ff !important; }`,
|
|
33
|
+
},
|
|
34
|
+
];
|
|
35
|
+
const { results } = audit( files );
|
|
36
|
+
const { value } = results.find( ( { id } ) => 'count' === id );
|
|
37
|
+
expect( value ).toBe( 1 );
|
|
38
|
+
} );
|
|
39
|
+
|
|
40
|
+
it( 'should count the number of !important in two files', () => {
|
|
41
|
+
const files = [
|
|
42
|
+
{
|
|
43
|
+
name: 'a.css',
|
|
44
|
+
content: `body { padding: 20px; margin-bottom: 10px !important; }`,
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
name: 'b.css',
|
|
48
|
+
content: `body { color: red !important; }`,
|
|
49
|
+
},
|
|
50
|
+
];
|
|
51
|
+
const { results } = audit( files );
|
|
52
|
+
const { value: count } = results.find( ( { id } ) => 'count' === id );
|
|
53
|
+
expect( count ).toBe( 2 );
|
|
54
|
+
|
|
55
|
+
const { value: countFile } = results.find(
|
|
56
|
+
( { id } ) => 'count-per-file' === id
|
|
57
|
+
);
|
|
58
|
+
expect( countFile ).toEqual( [
|
|
59
|
+
// Per line count looks for line breaks, so 1 is correct here.
|
|
60
|
+
{ name: 'a.css', count: 1, perLine: 1 },
|
|
61
|
+
{ name: 'b.css', count: 1, perLine: 1 },
|
|
62
|
+
] );
|
|
63
|
+
} );
|
|
64
|
+
|
|
65
|
+
it( 'should sort the properties that most use !important', () => {
|
|
66
|
+
const files = [
|
|
67
|
+
{
|
|
68
|
+
name: 'a.css',
|
|
69
|
+
content: `
|
|
70
|
+
h1 {
|
|
71
|
+
font-size: 2em !important;
|
|
72
|
+
letter-spacing: 1px;
|
|
73
|
+
text-transform: uppercase !important;
|
|
74
|
+
}
|
|
75
|
+
h2 {
|
|
76
|
+
font-size: 2em !important;
|
|
77
|
+
letter-spacing: 1px;
|
|
78
|
+
text-transform: uppercase;
|
|
79
|
+
}`,
|
|
80
|
+
},
|
|
81
|
+
];
|
|
82
|
+
const { results } = audit( files );
|
|
83
|
+
const { value } = results.find(
|
|
84
|
+
( { id } ) => 'top-10-properties' === id
|
|
85
|
+
);
|
|
86
|
+
expect( value[ 0 ].name ).toBe( 'font-size' );
|
|
87
|
+
} );
|
|
88
|
+
} );
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
const audit = require( '../audits/media-queries' );
|
|
2
|
+
|
|
3
|
+
describe( 'Audit: Media Queries', () => {
|
|
4
|
+
it( 'should return nothing when no media queries are used', () => {
|
|
5
|
+
const files = [
|
|
6
|
+
{
|
|
7
|
+
name: 'a.css',
|
|
8
|
+
content: `body { font-size: 1em; line-height: 1.6; }`,
|
|
9
|
+
},
|
|
10
|
+
];
|
|
11
|
+
const { results } = audit( files );
|
|
12
|
+
const { value } = results.find( ( { id } ) => 'count' === id );
|
|
13
|
+
expect( value ).toBe( 0 );
|
|
14
|
+
} );
|
|
15
|
+
|
|
16
|
+
it( 'should count the number of media queries', () => {
|
|
17
|
+
const files = [
|
|
18
|
+
{
|
|
19
|
+
name: 'a.css',
|
|
20
|
+
content: `body { font-size: 1em; line-height: 1.6; }
|
|
21
|
+
@media (max-width:30rem) { body { font-size: 2em; } }`,
|
|
22
|
+
},
|
|
23
|
+
];
|
|
24
|
+
const { results } = audit( files );
|
|
25
|
+
const { value } = results.find( ( { id } ) => 'count' === id );
|
|
26
|
+
expect( value ).toBe( 1 );
|
|
27
|
+
} );
|
|
28
|
+
|
|
29
|
+
it( 'should count multiple media queries', () => {
|
|
30
|
+
const files = [
|
|
31
|
+
{
|
|
32
|
+
name: 'a.css',
|
|
33
|
+
content: `body { font-size: 1em; line-height: 1.6; }
|
|
34
|
+
@media (max-width: 30rem) { body { font-size: 2em; } }
|
|
35
|
+
@media screen and (max-width: 20rem) { body { font-size: 1.5em; } }
|
|
36
|
+
@media (max-width: 20rem) { body { font-size: 1.5em; } }`,
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
name: 'b.css',
|
|
40
|
+
content: `body { font-size: 1em; line-height: 1.6; }
|
|
41
|
+
@media (max-width: 15rem) { body { font-size: 2em; } }
|
|
42
|
+
@media (max-width: 20rem) { body { font-size: 1.5em; } }`,
|
|
43
|
+
},
|
|
44
|
+
];
|
|
45
|
+
const { results } = audit( files );
|
|
46
|
+
const { value: count } = results.find( ( { id } ) => 'count' === id );
|
|
47
|
+
expect( count ).toBe( 5 );
|
|
48
|
+
} );
|
|
49
|
+
|
|
50
|
+
it( 'should track different sizes in media queries', () => {
|
|
51
|
+
const files = [
|
|
52
|
+
{
|
|
53
|
+
name: 'a.css',
|
|
54
|
+
content: `body { font-size: 1em; line-height: 1.6; }
|
|
55
|
+
@media (max-width: 30rem) { body { font-size: 2em; } }
|
|
56
|
+
@media screen and (max-width: 20rem) { body { font-size: 1.5em; } }
|
|
57
|
+
@media (max-width: 20rem) { body { font-size: 1.5em; } }`,
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
name: 'b.css',
|
|
61
|
+
content: `body { font-size: 1em; line-height: 1.6; }
|
|
62
|
+
@media (max-width: 15rem) { body { font-size: 2em; } }
|
|
63
|
+
@media (max-width: 20rem) { body { font-size: 1.5em; } }`,
|
|
64
|
+
},
|
|
65
|
+
];
|
|
66
|
+
const { results } = audit( files );
|
|
67
|
+
const { value: uniqueQueries } = results.find(
|
|
68
|
+
( { id } ) => 'count-unique-queries' === id
|
|
69
|
+
);
|
|
70
|
+
expect( uniqueQueries ).toBe( 4 );
|
|
71
|
+
|
|
72
|
+
const { value: topQueries } = results.find(
|
|
73
|
+
( { id } ) => 'top-10-queries' === id
|
|
74
|
+
);
|
|
75
|
+
expect( topQueries[ 0 ].count ).toBe( 2 );
|
|
76
|
+
expect( topQueries[ 0 ].name ).toBe( '(max-width:20rem)' );
|
|
77
|
+
|
|
78
|
+
const { value: topSizes } = results.find(
|
|
79
|
+
( { id } ) => 'top-10-sizes' === id
|
|
80
|
+
);
|
|
81
|
+
expect( topSizes[ 0 ].count ).toBe( 3 );
|
|
82
|
+
expect( topSizes[ 0 ].name ).toBe( '20rem' );
|
|
83
|
+
} );
|
|
84
|
+
} );
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
const audit = require( '../audits/property-values' );
|
|
2
|
+
|
|
3
|
+
describe( 'Audit: Property Values', () => {
|
|
4
|
+
it( 'should return nothing if no properties are set', () => {
|
|
5
|
+
const files = [
|
|
6
|
+
{
|
|
7
|
+
name: 'a.css',
|
|
8
|
+
content: `body { font-size: 1em; line-height: 1.6; }`,
|
|
9
|
+
},
|
|
10
|
+
];
|
|
11
|
+
const { results } = audit( files );
|
|
12
|
+
expect( results ).toHaveLength( 0 );
|
|
13
|
+
} );
|
|
14
|
+
|
|
15
|
+
it( 'should return nothing if the requested property is not used', () => {
|
|
16
|
+
const files = [
|
|
17
|
+
{
|
|
18
|
+
name: 'a.css',
|
|
19
|
+
content: `body { font-size: 1em; line-height: 1.6; }`,
|
|
20
|
+
},
|
|
21
|
+
];
|
|
22
|
+
const { results } = audit( files, [ 'padding' ] );
|
|
23
|
+
const { value } = results.find( ( { id } ) => 'count' === id );
|
|
24
|
+
expect( value ).toBe( 0 );
|
|
25
|
+
} );
|
|
26
|
+
|
|
27
|
+
it( 'should count number of properties', () => {
|
|
28
|
+
const files = [
|
|
29
|
+
{
|
|
30
|
+
name: 'a.css',
|
|
31
|
+
content: `.box { padding: 10px; }
|
|
32
|
+
.box-small { padding: 5px; }`,
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
name: 'b.css',
|
|
36
|
+
content: `.spacy-box { padding: 20px; }
|
|
37
|
+
.spacy-box-small { padding: 10px; }`,
|
|
38
|
+
},
|
|
39
|
+
];
|
|
40
|
+
const { results } = audit( files, [ 'padding' ] );
|
|
41
|
+
const { value: count } = results.find( ( { id } ) => 'count' === id );
|
|
42
|
+
expect( count ).toBe( 4 );
|
|
43
|
+
|
|
44
|
+
const { value: unique } = results.find(
|
|
45
|
+
( { id } ) => 'count-unique' === id
|
|
46
|
+
);
|
|
47
|
+
expect( unique ).toBe( 3 );
|
|
48
|
+
|
|
49
|
+
const { value: topValues } = results.find(
|
|
50
|
+
( { id } ) => 'top-10-values' === id
|
|
51
|
+
);
|
|
52
|
+
expect( topValues[ 0 ].count ).toBe( 2 );
|
|
53
|
+
expect( topValues[ 0 ].name ).toBe( '10px' );
|
|
54
|
+
} );
|
|
55
|
+
} );
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
const { runAudits } = require( '../run' );
|
|
2
|
+
const { getConfig } = require( '../utils/cli' );
|
|
3
|
+
|
|
4
|
+
describe( 'Run the audits', () => {
|
|
5
|
+
it( 'should output the JSON format from a configuration object', () => {
|
|
6
|
+
const configSrc = getConfig( process.env.NODE_ENV );
|
|
7
|
+
|
|
8
|
+
const result = runAudits( [
|
|
9
|
+
{
|
|
10
|
+
name: 'a.css',
|
|
11
|
+
content: `body { font-size: 1em !important; line-height: 1.6; }`,
|
|
12
|
+
},
|
|
13
|
+
] );
|
|
14
|
+
|
|
15
|
+
configSrc.audits.forEach( ( audit ) => {
|
|
16
|
+
if ( Array.isArray( audit ) ) {
|
|
17
|
+
audit[ 1 ].split( ',' ).forEach( ( property ) => {
|
|
18
|
+
expect( result ).toContain( property );
|
|
19
|
+
} );
|
|
20
|
+
} else {
|
|
21
|
+
expect( result ).toContain( audit );
|
|
22
|
+
}
|
|
23
|
+
} );
|
|
24
|
+
} );
|
|
25
|
+
} );
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
const audit = require( '../audits/selectors' );
|
|
2
|
+
|
|
3
|
+
describe( 'Audit: Selectors', () => {
|
|
4
|
+
it( 'should count the number of selectors used', () => {
|
|
5
|
+
const files = [
|
|
6
|
+
{
|
|
7
|
+
name: 'a.css',
|
|
8
|
+
content: `body { color: white; }
|
|
9
|
+
p#test { color: white; }
|
|
10
|
+
div { color: white; }
|
|
11
|
+
.class { color: white; }`,
|
|
12
|
+
},
|
|
13
|
+
];
|
|
14
|
+
const { results } = audit( files );
|
|
15
|
+
const { value } = results.find( ( { id } ) => 'count' === id );
|
|
16
|
+
expect( value ).toBe( 4 );
|
|
17
|
+
} );
|
|
18
|
+
|
|
19
|
+
it( 'should count the number of selectors that contain IDs', () => {
|
|
20
|
+
const files = [
|
|
21
|
+
{
|
|
22
|
+
name: 'a.css',
|
|
23
|
+
content: `body { color: white; }
|
|
24
|
+
p#test { color: white; }
|
|
25
|
+
div { color: white; }
|
|
26
|
+
.class { color: white; }`,
|
|
27
|
+
},
|
|
28
|
+
];
|
|
29
|
+
const { results } = audit( files );
|
|
30
|
+
const { value } = results.find( ( { id } ) => 'count-with-ids' === id );
|
|
31
|
+
expect( value ).toBe( 1 );
|
|
32
|
+
} );
|
|
33
|
+
|
|
34
|
+
it( 'should calculate and sort based on selector specificity', () => {
|
|
35
|
+
const files = [
|
|
36
|
+
{
|
|
37
|
+
name: 'a.css',
|
|
38
|
+
content: `body { color: white; }
|
|
39
|
+
p#test { color: white; }
|
|
40
|
+
div { color: white; }
|
|
41
|
+
span, .class { color: white; }`,
|
|
42
|
+
},
|
|
43
|
+
];
|
|
44
|
+
const { results } = audit( files );
|
|
45
|
+
const { value } = results.find(
|
|
46
|
+
( { id } ) => 'top-10-selectors' === id
|
|
47
|
+
);
|
|
48
|
+
expect( value[ 0 ].selector ).toBe( 'p#test' );
|
|
49
|
+
expect( value[ 0 ].sum ).toBe( 101 );
|
|
50
|
+
expect( value[ 1 ].selector ).toBe( '.class' );
|
|
51
|
+
expect( value[ 1 ].sum ).toBe( 10 );
|
|
52
|
+
} );
|
|
53
|
+
|
|
54
|
+
it( 'should not double-count :not selectors', () => {
|
|
55
|
+
const files = [
|
|
56
|
+
{
|
|
57
|
+
name: 'a.css',
|
|
58
|
+
content: `body { color: white; }
|
|
59
|
+
p:not(.class) { color: white; }`,
|
|
60
|
+
},
|
|
61
|
+
];
|
|
62
|
+
const { results } = audit( files );
|
|
63
|
+
const { value } = results.find( ( { id } ) => 'count' === id );
|
|
64
|
+
expect( value ).toBe( 2 );
|
|
65
|
+
} );
|
|
66
|
+
} );
|