Skip to content

Commit f584025

Browse files
authored
[breaking] v5 support (#249)
* [breaking] v5 support haven't managed to get the preact ones to work yet... doesn't seem like preact 10 is ready enough yet and for preact-compat the createContext implementation is actually in a separate package so not sure how to fake it being part of preact-compat * little futureproofing for upcoming releases * clean up garbage between tests * reset stylesheet for all tests * v7.0.0-beta.0 * preact 10 support * fix web tests
1 parent a652a08 commit f584025

16 files changed

+456
-647
lines changed

.jest.preact.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
{
22
"moduleNameMapper": {
3-
"^react$": "preact-compat"
3+
"^react$": "preact/compat"
44
},
5+
"setupFilesAfterEnv": ["<rootDir>/test/preact/setup.js"],
6+
"snapshotSerializers": ["enzyme-to-json/serializer"],
57
"testRegex": "test/preact/.*\\.spec\\.js$"
68
}

package.json

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "jest-styled-components",
3-
"version": "6.3.1",
3+
"version": "7.0.0-beta.0",
44
"description": "Jest utilities for Styled Components",
55
"main": "./src/index.js",
66
"typings": "./typings/index.d.ts",
@@ -32,30 +32,30 @@
3232
"babel-eslint": "^10.0.1",
3333
"babel-jest": "^24.8.0",
3434
"enzyme": "^3.6.0",
35+
"enzyme-adapter-preact-pure": "^1.13.4",
3536
"enzyme-adapter-react-16": "^1.5.0",
3637
"enzyme-to-json": "^3.3.1",
3738
"eslint": "^5.16.0",
3839
"eslint-config-prettier": "^4.3.0",
3940
"husky": "^2.4.0",
4041
"jest": "^24.8.0",
4142
"lint-staged": "^8.2.0",
42-
"preact": "^8.3.1",
43-
"preact-compat": "^3.18.4",
43+
"preact": "^10.0.0-beta.2",
4444
"preact-render-to-json": "^3.6.6",
4545
"prettier": "^1.18.2",
4646
"react": "^16.8.0",
4747
"react-dom": "^16.8.0",
4848
"react-is": "^16.8.6",
4949
"react-native": "^0.59.9",
5050
"react-test-renderer": "^16.8.0",
51-
"styled-components": "^3",
51+
"styled-components": "beta",
5252
"typescript": "^3.0.3"
5353
},
5454
"dependencies": {
5555
"css": "^2.2.4"
5656
},
5757
"peerDependencies": {
58-
"styled-components": ">= 2"
58+
"styled-components": ">= 5 || >= 5.0.0-alpha.0 || >= 5.0.0-beta.0"
5959
},
6060
"husky": {
6161
"hooks": {

src/index.js

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
const toHaveStyleRule = require('./toHaveStyleRule')
2-
const styleSheetSerializer = require('./styleSheetSerializer')
3-
const { resetStyleSheet } = require('./utils')
1+
const toHaveStyleRule = require('./toHaveStyleRule');
2+
const styleSheetSerializer = require('./styleSheetSerializer');
3+
const { resetStyleSheet } = require('./utils');
44

5-
resetStyleSheet()
5+
global.beforeEach(resetStyleSheet);
66

7-
expect.addSnapshotSerializer(styleSheetSerializer)
8-
expect.extend({ toHaveStyleRule })
7+
expect.addSnapshotSerializer(styleSheetSerializer);
8+
expect.extend({ toHaveStyleRule });

src/styleSheetSerializer.js

Lines changed: 61 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -1,154 +1,128 @@
1-
const css = require('css')
2-
const { getCSS, getHashes } = require('./utils')
1+
const css = require('css');
2+
const { getCSS, getHashes } = require('./utils');
33

4-
const KEY = '__jest-styled-components__'
4+
const KEY = '__jest-styled-components__';
55

66
const getNodes = (node, nodes = []) => {
77
if (typeof node === 'object') {
8-
nodes.push(node)
8+
nodes.push(node);
99
}
1010

1111
if (node.children) {
12-
Array.from(node.children).forEach(child => getNodes(child, nodes))
12+
Array.from(node.children).forEach(child => getNodes(child, nodes));
1313
}
1414

15-
return nodes
16-
}
15+
return nodes;
16+
};
1717

18-
const markNodes = nodes => nodes.forEach(node => (node[KEY] = true))
18+
const markNodes = nodes => nodes.forEach(node => (node[KEY] = true));
1919

20-
const getClassNamesFromDOM = node => Array.from(node.classList)
20+
const getClassNamesFromDOM = node => Array.from(node.classList);
2121
const getClassNamesFromProps = node => {
22-
const classNameProp = node.props && (node.props.class || node.props.className)
22+
const classNameProp = node.props && (node.props.class || node.props.className);
2323

2424
if (classNameProp) {
25-
return classNameProp.trim().split(/\s+/)
25+
return classNameProp.trim().split(/\s+/);
2626
}
2727

28-
return []
29-
}
28+
return [];
29+
};
3030

3131
const getClassNames = nodes =>
3232
nodes.reduce((classNames, node) => {
33-
let newClassNames = null
33+
let newClassNames = null;
3434

3535
if (global.Element && node instanceof global.Element) {
36-
newClassNames = getClassNamesFromDOM(node)
36+
newClassNames = getClassNamesFromDOM(node);
3737
} else {
38-
newClassNames = getClassNamesFromProps(node)
38+
newClassNames = getClassNamesFromProps(node);
3939
}
4040

41-
newClassNames.forEach(className => classNames.add(className))
41+
newClassNames.forEach(className => classNames.add(className));
4242

43-
return classNames
44-
}, new Set())
43+
return classNames;
44+
}, new Set());
4545

46-
const filterClassNames = (classNames, hashes) =>
47-
classNames.filter(className => hashes.includes(className))
46+
const filterClassNames = (classNames, hashes) => classNames.filter(className => hashes.includes(className));
4847

4948
const includesClassNames = (classNames, selectors) =>
50-
classNames.some(className =>
51-
selectors.some(selector => selector.includes(className))
52-
)
49+
classNames.some(className => selectors.some(selector => selector.includes(className)));
5350

5451
const filterRules = classNames => rule =>
55-
rule.type === 'rule' &&
56-
includesClassNames(classNames, rule.selectors) &&
57-
rule.declarations.length
52+
rule.type === 'rule' && includesClassNames(classNames, rule.selectors) && rule.declarations.length;
5853

5954
const getAtRules = (ast, filter) =>
6055
ast.stylesheet.rules
6156
.filter(rule => rule.type === 'media' || rule.type === 'supports')
6257
.reduce((acc, atRule) => {
63-
atRule.rules = atRule.rules.filter(filter)
58+
atRule.rules = atRule.rules.filter(filter);
6459

65-
if (atRule.rules.length) {
66-
return acc.concat(atRule)
67-
}
68-
69-
return acc
70-
}, [])
60+
return acc.concat(atRule);
61+
}, []);
7162

7263
const getStyle = classNames => {
73-
const ast = getCSS()
74-
const filter = filterRules(classNames)
75-
const rules = ast.stylesheet.rules.filter(filter)
76-
const atRules = getAtRules(ast, filter)
64+
const ast = getCSS();
65+
const filter = filterRules(classNames);
66+
const rules = ast.stylesheet.rules.filter(filter);
67+
const atRules = getAtRules(ast, filter);
7768

78-
ast.stylesheet.rules = rules.concat(atRules)
69+
ast.stylesheet.rules = rules.concat(atRules);
7970

80-
return css.stringify(ast)
81-
}
71+
return css.stringify(ast);
72+
};
8273

8374
const getClassNamesFromSelectorsByHashes = (classNames, hashes) => {
84-
const ast = getCSS()
85-
const filter = filterRules(classNames)
86-
const rules = ast.stylesheet.rules.filter(filter)
75+
const ast = getCSS();
76+
const filter = filterRules(classNames);
77+
const rules = ast.stylesheet.rules.filter(filter);
8778

88-
const selectors = rules.map(rule => rule.selectors)
89-
const classNamesIncludingFromSelectors = new Set(classNames)
79+
const selectors = rules.map(rule => rule.selectors);
80+
const classNamesIncludingFromSelectors = new Set(classNames);
9081
const addHashFromSelectorListToClassNames = hash =>
91-
selectors.forEach(
92-
selectorList =>
93-
selectorList[0].includes(hash) &&
94-
classNamesIncludingFromSelectors.add(hash)
95-
)
82+
selectors.forEach(selectorList => selectorList[0].includes(hash) && classNamesIncludingFromSelectors.add(hash));
9683

97-
hashes.forEach(addHashFromSelectorListToClassNames)
84+
hashes.forEach(addHashFromSelectorListToClassNames);
9885

99-
return [...classNamesIncludingFromSelectors]
100-
}
86+
return [...classNamesIncludingFromSelectors];
87+
};
10188

10289
const replaceClassNames = (result, classNames, style) =>
10390
classNames
10491
.filter(className => style.includes(className))
105-
.reduce(
106-
(acc, className, index) =>
107-
acc.replace(new RegExp(className, 'g'), `c${index++}`),
108-
result
109-
)
92+
.reduce((acc, className, index) => acc.replace(new RegExp(className, 'g'), `c${index++}`), result);
11093

11194
const replaceHashes = (result, hashes) =>
11295
hashes.reduce(
113-
(acc, className) =>
114-
acc.replace(
115-
new RegExp(`((class|className)="[^"]*?)${className}\\s?([^"]*")`, 'g'),
116-
'$1$3'
117-
),
96+
(acc, className) => acc.replace(new RegExp(`((class|className)="[^"]*?)${className}\\s?([^"]*")`, 'g'), '$1$3'),
11897
result
119-
)
98+
);
12099

121-
const styleSheetSerializer = {
100+
module.exports = {
122101
test(val) {
123102
return (
124103
val &&
125104
!val[KEY] &&
126-
(val.$$typeof === Symbol.for('react.test.json') ||
127-
(global.Element && val instanceof global.Element))
128-
)
105+
(val.$$typeof === Symbol.for('react.test.json') || (global.Element && val instanceof global.Element))
106+
);
129107
},
130108

131109
print(val, print) {
132-
const nodes = getNodes(val)
133-
markNodes(nodes)
110+
const nodes = getNodes(val);
111+
markNodes(nodes);
134112

135-
const hashes = getHashes()
136-
let classNames = [...getClassNames(nodes)]
137-
classNames = filterClassNames(classNames, hashes)
113+
const hashes = getHashes();
138114

139-
const style = getStyle(classNames)
140-
const classNamesToReplace = getClassNamesFromSelectorsByHashes(
141-
classNames,
142-
hashes
143-
)
144-
const code = print(val)
115+
let classNames = [...getClassNames(nodes)];
116+
classNames = filterClassNames(classNames, hashes);
145117

146-
let result = `${style}${style ? '\n\n' : ''}${code}`
147-
result = replaceClassNames(result, classNamesToReplace, style)
148-
result = replaceHashes(result, hashes)
118+
const style = getStyle(classNames);
119+
const classNamesToReplace = getClassNamesFromSelectorsByHashes(classNames, hashes);
120+
const code = print(val);
149121

150-
return result
151-
},
152-
}
122+
let result = `${style}${style ? '\n\n' : ''}${code}`;
123+
result = replaceClassNames(result, classNamesToReplace, style);
124+
result = replaceHashes(result, hashes);
153125

154-
module.exports = styleSheetSerializer
126+
return result;
127+
},
128+
};

0 commit comments

Comments
 (0)