Skip to content

Commit f026efd

Browse files
authored
cmd generate-test-cases (#6)
* generate-test-cases * update location * postcss-blank-pseudo: fix selectors with combinators without spaces not being processed * postcss-has-pseudo: ensure selector parser doesn't throw * postcss-blank-pseudo: ignore :blank() * postcss-pseudo-class-any-link : ensure selector parser doesn't throw and fix some bugs * more generated test cases * more generated test cases * more generated test cases * postcss-dir-pseudo-class : fix combinators and support for `:is(:dir(ltr))` (#62) * postcss-dir-pseudo-class : fix combinators * tweak
1 parent 2791310 commit f026efd

File tree

99 files changed

+14584
-200
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

99 files changed

+14584
-200
lines changed

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,8 @@
2929
},
3030
"scripts": {
3131
"build": "npm run build --workspaces --if-present",
32-
"lint": "npm run lint --workspaces --if-present",
32+
"lint": "npm run lint --workspaces --if-present && npm run lint:rollup-config",
33+
"lint:rollup-config": "eslint ./rollup --ext .js --ext .ts --ext .mjs --no-error-on-unmatched-pattern",
3334
"test": "npm run test --workspaces --if-present"
3435
},
3536
"volta": {

packages/base-cli/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
"scripts": {
1818
"build": "tsc",
1919
"clean": "node -e \"fs.rmSync('./dist', { recursive: true, force: true });\"",
20-
"lint": "eslint src/**/*.ts src/**/*.js --no-error-on-unmatched-pattern",
20+
"lint": "eslint ./src --ext .js --ext .ts --ext .mjs --no-error-on-unmatched-pattern",
2121
"prepublishOnly": "npm run clean && npm run build && npm run test",
2222
"stryker": "stryker run --logLevel error",
2323
"test": "node ./test/test.mjs"
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# Generate Test Cases
2+
3+
Similar issues often appear in plugins and this can cause add extra friction
4+
as it is easy to forget a plugin when testing for a new known issue.
5+
6+
## Usage :
7+
8+
```bash
9+
npm run generate --workspace="@csstools/generate-test-cases"
10+
```
11+
12+
## Incorrect CSS in result.css and expect.css
13+
14+
These tests should not be used to force 100% correctness of output CSS.
15+
They are intended to make unknown bugs visible.
16+
17+
Some issues might be unfixable and this is ok.
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
{
2+
"name": "@csstools/generate-test-cases",
3+
"private": true,
4+
"version": "1.0.0",
5+
"description": "PostCSS test case generator",
6+
"type": "module",
7+
"main": "src/index.mjs",
8+
"author": "",
9+
"license": "CC0-1.0",
10+
"scripts": {
11+
"generate": "node ./src/index.mjs",
12+
"lint": "eslint ./src --ext .js --ext .ts --ext .mjs --no-error-on-unmatched-pattern",
13+
"test": "exit 0;"
14+
},
15+
"engines": {
16+
"node": "^12 || ^14 || >=16"
17+
},
18+
"devDependencies": {
19+
"mdn-data": "^2.0.23"
20+
},
21+
"repository": {
22+
"type": "git",
23+
"url": "https://github.com/csstools/postcss-plugins.git",
24+
"directory": "packages/generate-test-cases"
25+
}
26+
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
import * as mdnData from 'mdn-data';
2+
const mdnCSSData = mdnData.default.css;
3+
4+
export function generateDeclarationTestCases(property, value) {
5+
let properties = [];
6+
7+
properties.push(`-webkit-${property}`);
8+
properties.push(`-moz-${property}`);
9+
properties.push(`-ms-${property}`);
10+
properties.push(`-o-${property}`);
11+
properties.push(`--${property}`);
12+
properties.push(`foo-${property}`);
13+
14+
let result = properties.map((x, index) => {
15+
return `.order-${index} {
16+
${x}: ${value};
17+
}`;
18+
}).join('\n\n') + '\n\n';
19+
20+
result = result + `/* ${property}: ${value}; */\n\n`;
21+
22+
result = result + `.content {
23+
content: '${property}: ${value};';
24+
}\n\n`;
25+
26+
if (mdnCSSData.properties[property] && !['discrete', 'notAnimatable'].includes(mdnCSSData.properties[property].animationType)) {
27+
result = result + `.transition {
28+
transition: 1s ${property} ease;
29+
}\n\n`;
30+
}
31+
32+
result = result + `.important {
33+
${property}: ${value} !important;
34+
}\n\n`;
35+
36+
result = result + `@supports (${property}: ${value}) {
37+
.support {
38+
${property}: ${value};
39+
}
40+
}\n`;
41+
42+
result = result + `@keyframes KEYFRAMES {
43+
50% {
44+
${property}: ${value};
45+
}
46+
}\n`;
47+
48+
return result;
49+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import { promises as fsp } from 'fs';
2+
import path from 'path';
3+
import { generateDeclarationTestCases } from './declaration.mjs';
4+
import { generatePropertyTestCases } from './property.mjs';
5+
import { generateSelectorTestCases } from './selector.mjs';
6+
import { generateValueTestCases } from './value.mjs';
7+
8+
export async function generate(genType, pluginDir, seedList) {
9+
switch (genType) {
10+
case 'selector':
11+
await fsp.writeFile(path.join(pluginDir, 'test', 'generated-selector-cases.css'), seedList.map((selector) => {
12+
return generateSelectorTestCases(selector);
13+
}).join('\n'));
14+
break;
15+
16+
case 'value':
17+
await fsp.writeFile(path.join(pluginDir, 'test', 'generated-value-cases.css'), seedList.map((value) => {
18+
return generateValueTestCases(value);
19+
}).join('\n'));
20+
break;
21+
22+
case 'property':
23+
await fsp.writeFile(path.join(pluginDir, 'test', 'generated-property-cases.css'), seedList.map((value) => {
24+
return generatePropertyTestCases(value);
25+
}).join('\n'));
26+
break;
27+
28+
case 'declaration':
29+
await fsp.writeFile(path.join(pluginDir, 'test', 'generated-declaration-cases.css'), seedList.map((pair) => {
30+
return generateDeclarationTestCases(pair[0], pair[1]);
31+
}).join('\n'));
32+
break;
33+
34+
default:
35+
break;
36+
}
37+
}
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
import path from 'path';
2+
import { generate } from './generate.mjs';
3+
4+
(async () => {
5+
await Promise.all(
6+
[
7+
generate(
8+
'selector',
9+
path.join('../../plugins', 'postcss-dir-pseudo-class'),
10+
[
11+
':dir(ltr)',
12+
':dir(rtl)',
13+
],
14+
),
15+
16+
generate(
17+
'selector',
18+
path.join('../../plugins', 'postcss-pseudo-class-any-link'),
19+
[
20+
':any-link',
21+
],
22+
),
23+
24+
generate(
25+
'selector',
26+
path.join('../../plugins', 'postcss-focus-visible'),
27+
[
28+
':focus-visible',
29+
],
30+
),
31+
32+
generate(
33+
'selector',
34+
path.join('../../plugins', 'postcss-focus-within'),
35+
[
36+
':focus-within',
37+
],
38+
),
39+
40+
generate(
41+
'value',
42+
path.join('../../plugins', 'postcss-color-functional-notation'),
43+
[
44+
'rgba(178 34 34 / 1)',
45+
'hsl(120 100% 50% / 1)',
46+
],
47+
),
48+
49+
generate(
50+
'value',
51+
path.join('../../plugins', 'postcss-double-position-gradients'),
52+
[
53+
'linear-gradient(90deg, black 25% 50%, blue 50% 75%)',
54+
],
55+
),
56+
57+
generate(
58+
'value',
59+
path.join('../../plugins', 'postcss-image-set-function'),
60+
[
61+
'image-set(url(img/test.png) 1x, url(img/test-2x.png) 2x)',
62+
],
63+
),
64+
65+
generate(
66+
'declaration',
67+
path.join('../../plugins', 'postcss-place'),
68+
[
69+
['place-content', 'first second'],
70+
],
71+
),
72+
73+
generate(
74+
'declaration',
75+
path.join('../../plugins', 'postcss-logical'),
76+
[
77+
['inset-inline-start', '0'],
78+
],
79+
),
80+
81+
generate(
82+
'declaration',
83+
path.join('../../plugins', 'postcss-overflow-shorthand'),
84+
[
85+
['overflow', 'hidden auto'],
86+
],
87+
),
88+
],
89+
);
90+
})();
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import * as mdnData from 'mdn-data';
2+
const mdnCSSData = mdnData.css;
3+
4+
export function generatePropertyTestCases(property) {
5+
let properties = [];
6+
7+
properties.push(`-webkit-${property}`);
8+
properties.push(`-moz-${property}`);
9+
properties.push(`-ms-${property}`);
10+
properties.push(`-o-${property}`);
11+
properties.push(`--${property}`);
12+
properties.push(`foo-${property}`);
13+
14+
let result = properties.map((x, index) => {
15+
return `.order-${index} {
16+
${x}: ${index};
17+
}`;
18+
}).join('\n\n') + '\n\n';
19+
20+
result = result + `/* ${property} */\n\n`;
21+
22+
result = result + `.content {
23+
content: '${property}';
24+
}\n\n`;
25+
26+
if (mdnCSSData.properties[property] && !['discrete', 'notAnimatable'].includes(mdnCSSData.properties[property].animationType)) {
27+
result = result + `.transition {
28+
transition: 1s ${property} ease;
29+
}\n\n`;
30+
}
31+
32+
result = result + `@supports (${property}: red) {
33+
.support {
34+
${property}: red;
35+
}
36+
}\n`;
37+
38+
result = result + `@keyframes KEYFRAMES {
39+
50% {
40+
${property}: red;
41+
}
42+
}\n`;
43+
44+
return result;
45+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
export function generateSelectorTestCases(selector) {
2+
let selectors = [];
3+
4+
for (const other of [selector, 'button', '.🧑🏾‍🎤', '.foo', '#foo', '__foo', ':--foo', '[foo="baz"]', '*', ':hover', '::before']) {
5+
for (const combinator of ['', ' ' , ' ', '+', ' + ', '~', ' ~ ', '>', ' > ']) {
6+
selectors.push(`${other}${combinator}${selector}`);
7+
selectors.push(`${selector}${combinator}${other}`);
8+
}
9+
10+
selectors.push(`${other}, ${selector}`);
11+
selectors.push(`${selector}, ${other}`);
12+
}
13+
14+
selectors.push(`foo[${selector}]`);
15+
selectors.push(`foo[baz="${selector}"]`);
16+
17+
selectors.push(`:not(${selector})`);
18+
19+
selectors.push(`:${selector}`);
20+
selectors.push(`:--${selector}`);
21+
selectors.push(`__${selector}`);
22+
23+
let result = selectors.map((x, index) => {
24+
return `${x} {
25+
order: ${index};
26+
}`;
27+
}).join('\n\n') + '\n\n';
28+
29+
result = result + `/* ${selector} */\n`;
30+
31+
return result;
32+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
export function generateValueTestCases(value) {
2+
let values = [];
3+
4+
values.push(`${value} !important`);
5+
values.push(`var(1, ${value})`);
6+
values.push(`var(${value}, 1)`);
7+
values.push(`var(${value}, ${value})`);
8+
9+
let result = values.map((x, index) => {
10+
return `.order-${index} {
11+
order: ${x};
12+
}`;
13+
}).join('\n\n') + '\n\n';
14+
15+
result = result + `/* ${value} */\n\n`;
16+
17+
result = result + `:root {
18+
--some-var: ${value};
19+
}\n\n`;
20+
21+
result = result + `.content {
22+
content: '${value}';
23+
}\n\n`;
24+
25+
result = result + `@supports (order: ${value}) {
26+
.support {
27+
order: ${value};
28+
}
29+
}\n`;
30+
31+
return result;
32+
}

0 commit comments

Comments
 (0)