jest-styled-components
Advanced tools
Comparing version 4.0.0-6 to 4.0.0-7
{ | ||
"name": "jest-styled-components", | ||
"version": "4.0.0-6", | ||
"version": "4.0.0-7", | ||
"description": "Jest utilities for Styled Components", | ||
@@ -5,0 +5,0 @@ "main": "./src/index.js", |
const css = require('css') | ||
const { printReceived, printExpected } = require('jest-matcher-utils') | ||
const { getCSS } = require('../utils') | ||
const { getCSS, hasRule } = require('../utils') | ||
const getClassName = (received) => { | ||
const getClassNames = (received) => { | ||
let className = '' | ||
@@ -14,12 +14,16 @@ | ||
return `.${className.split(/\s/).pop()}` | ||
return className.split(/\s/) | ||
} | ||
const getRules = (ast, className) => ast.stylesheet.rules.filter( | ||
rule => rule.type === 'rule' && rule.selectors.includes(className) | ||
const getRules = (ast, classNames) => ast.stylesheet.rules.filter( | ||
rule => rule.type === 'rule' && hasRule(classNames, rule.selectors) | ||
) | ||
const getDeclarations = (rule, property) => rule.declarations.filter( | ||
const getDeclaration = (rule, property) => rule.declarations.filter( | ||
declaration => declaration.type === 'declaration' && | ||
declaration.property === property | ||
)[0] | ||
const getDeclarations = (rules, property) => rules.map( | ||
rule => getDeclaration(rule, property) | ||
) | ||
@@ -32,7 +36,7 @@ | ||
function toHaveStyleRule(received, property, value) { | ||
const className = getClassName(received) | ||
const toHaveStyleRule = (received, property, value) => { | ||
const classNames = getClassNames(received) | ||
const styles = getCSS() | ||
const ast = css.parse(styles) | ||
const rules = getRules(ast, className) | ||
const rules = getRules(ast, classNames) | ||
@@ -43,3 +47,3 @@ if (!rules.length) { | ||
const declarations = getDeclarations(rules[0], property) | ||
const declarations = getDeclarations(rules, property) | ||
@@ -50,3 +54,3 @@ if (!declarations.length) { | ||
const declaration = declarations[0] | ||
const declaration = declarations.pop() | ||
@@ -53,0 +57,0 @@ const message = |
const css = require('css') | ||
const { getCSS, getClassNames } = require('../utils') | ||
const { getCSS, getClassNames, hasRule } = require('../utils') | ||
const getComponentIDs = () => { | ||
const styles = getCSS() | ||
const ast = css.parse(styles) | ||
return ast.stylesheet.rules | ||
.filter(rule => rule.type === 'comment') | ||
.reduce((acc, rule) => acc.concat(rule.comment.split(':')[1].trim()), []) | ||
} | ||
const filterRules = classNames => rule => rule.type === 'rule' && | ||
hasRule(classNames, rule.selectors) && rule.declarations.length | ||
const excludeComponentIDs = componentIDs => className => !componentIDs.includes(className) | ||
const filterRules = classNames => (rule) => { | ||
if (rule.type === 'rule') { | ||
const className = rule.selectors[0].split(/:| /)[0] | ||
return classNames.includes(className.substring(1)) && rule.declarations.length | ||
} | ||
return false | ||
} | ||
const getAtRules = (ast, filter) => ( | ||
@@ -42,5 +26,5 @@ ast.stylesheet.rules | ||
const rules = ast.stylesheet.rules.filter(filter) | ||
const mediaQueries = getAtRules(ast, filter) | ||
const atRules = getAtRules(ast, filter) | ||
ast.stylesheet.rules = rules.concat(mediaQueries) | ||
ast.stylesheet.rules = rules.concat(atRules) | ||
@@ -50,11 +34,15 @@ return css.stringify(ast) | ||
const replaceClassNames = (classNames, output) => ( | ||
classNames | ||
.reverse() | ||
.reduce((acc, selector, index) => acc.replace(new RegExp(selector, 'g'), `c${index}`), output) | ||
) | ||
const replaceClassNames = (classNames, styles, code) => { | ||
let index = 0 | ||
return classNames.reduce( | ||
(acc, className) => { | ||
if (styles.indexOf(className) > -1) { | ||
return acc.replace(new RegExp(className, 'g'), `c${index++}`) | ||
} | ||
const removeComponentIDs = (componentIDs, output) => ( | ||
componentIDs.reduce((acc, componentID) => acc.replace(`${componentID} `, ''), output) | ||
) | ||
return acc.replace(new RegExp(`${className}\\s`, 'g'), '') | ||
}, | ||
`${styles}${code}` | ||
) | ||
} | ||
@@ -64,3 +52,4 @@ const styleSheetSerializer = { | ||
test(val) { | ||
return val && !val.withStyles && val.$$typeof === Symbol.for('react.test.json') | ||
return val && !val.withStyles && | ||
val.$$typeof === Symbol.for('react.test.json') | ||
}, | ||
@@ -71,13 +60,7 @@ | ||
const componentIDs = getComponentIDs() | ||
const classNames = getClassNames(val).filter(excludeComponentIDs(componentIDs)) | ||
const styles = classNames.length ? `${getStyles(classNames)}\n\n` : '' | ||
const classNames = getClassNames(val) | ||
const styles = classNames.length ? `${getStyles(classNames)}\n\n` : null | ||
const code = print(val) | ||
let output = `${styles}${code}` | ||
output = replaceClassNames(classNames, output) | ||
output = removeComponentIDs(componentIDs, output) | ||
return output | ||
return styles ? replaceClassNames(classNames, styles, code) : code | ||
}, | ||
@@ -84,0 +67,0 @@ |
@@ -6,3 +6,2 @@ const { ServerStyleSheet } = require('styled-components') | ||
// styled-components >=2.0.0 | ||
function isOverV2() { | ||
@@ -12,4 +11,2 @@ return Boolean(ServerStyleSheet) | ||
module.exports.isOverV2 = isOverV2 | ||
function isServer() { | ||
@@ -19,4 +16,2 @@ return typeof document === 'undefined' | ||
module.exports.isServer = isServer | ||
function parseCSSfromHTML(html) { | ||
@@ -31,4 +26,2 @@ let css = '' | ||
module.exports.parseCSSfromHTML = parseCSSfromHTML | ||
function getCSS() { | ||
@@ -44,13 +37,14 @@ const overV2 = isOverV2() | ||
module.exports.getCSS = getCSS | ||
function getClassNames(node) { | ||
const classNames = [] | ||
if (node.children) { | ||
node.children.reverse().forEach(child => ( | ||
Array.prototype.push.apply(classNames, getClassNames(child)) | ||
node.children.slice().reverse().forEach(child => ( | ||
Array.prototype.unshift.apply(classNames, getClassNames(child)) | ||
)) | ||
} | ||
if (node.props && node.props.className) { | ||
Array.prototype.push.apply(classNames, node.props.className.split(' ')) | ||
Array.prototype.unshift.apply( | ||
classNames, | ||
node.props.className.split(/\s/) | ||
) | ||
} | ||
@@ -60,2 +54,16 @@ return classNames | ||
module.exports.getClassNames = getClassNames | ||
function hasRule(classNames, selectors) { | ||
return classNames.some( | ||
className => selectors.some(selector => selector.indexOf(className) > -1) | ||
) | ||
} | ||
module.exports = { | ||
isOverV2, | ||
isServer, | ||
parseCSSfromHTML, | ||
getCSS, | ||
getClassNames, | ||
hasRule, | ||
} | ||
257
13261