jest-styled-components
Advanced tools
Comparing version 3.1.5 to 3.2.0
{ | ||
"name": "jest-styled-components", | ||
"version": "3.1.5", | ||
"version": "3.2.0", | ||
"description": "Jest utilities for Styled Components", | ||
@@ -5,0 +5,0 @@ "main": "./src/index.js", |
@@ -1,95 +0,59 @@ | ||
/* eslint-disable one-var, no-useless-escape, no-underscore-dangle, no-nested-ternary */ | ||
const { | ||
printReceived, | ||
printExpected, | ||
} = require('jest-matcher-utils') | ||
const css = require('css') | ||
const { printReceived, printExpected } = require('jest-matcher-utils') | ||
const styleSheet = require('styled-components/lib/models/StyleSheet') | ||
const { getCSS } = require('../utils') | ||
/** | ||
* Finds the generated class name from a rendered StyledComponent. | ||
* @param {Object} received A rendered StyledComponent. | ||
* @return {String} The generated class name. | ||
*/ | ||
const findClassName = (received) => { | ||
const getClassName = (received) => { | ||
let className = '' | ||
const component = received.component || received | ||
if (received.$$typeof === Symbol.for('react.test.json')) { | ||
className = received.props.className | ||
} else if (typeof received.prop === 'function') { | ||
className = received.find('[className]').first().prop('className') | ||
} | ||
if (component.$$typeof === Symbol.for('react.test.json')) { | ||
// react test renderer | ||
className = component.props.className | ||
} else if (received.node) { | ||
if (received.node.$$typeof === Symbol.for('react.element')) { | ||
// enzyme's shallow | ||
className = received.node.props.className | ||
} else { | ||
// enzyme's mount | ||
const renderedComponent = received.node._reactInternalInstance._renderedComponent | ||
return `.${className.split(/\s/).pop()}` | ||
} | ||
className = (renderedComponent._instance && renderedComponent._instance.state) | ||
? renderedComponent._instance.state.generatedClassName | ||
: renderedComponent._currentElement.props.className | ||
} | ||
} | ||
// styled components adds the className on the end. | ||
className = className.split(' ').pop() | ||
const getRules = (ast, className) => ast.stylesheet.rules.filter( | ||
rule => rule.type === 'rule' && rule.selectors.includes(className) | ||
) | ||
if (received.modifier) { | ||
className += received.modifier | ||
const getDeclarations = (rule, property) => rule.declarations.filter( | ||
declaration => declaration.type === 'declaration' && | ||
declaration.property === property | ||
) | ||
const die = property => ({ | ||
pass: false, | ||
message: `Property not found: ${printReceived(property)}`, | ||
}) | ||
function toHaveStyleRule(received, property, value) { | ||
const className = getClassName(received) | ||
const styles = getCSS(styleSheet) | ||
const ast = css.parse(styles) | ||
const rules = getRules(ast, className) | ||
if (!rules.length) { | ||
return die(property) | ||
} | ||
return className | ||
} | ||
/** | ||
* Tests component to see if it has the correct value for a specific CSS rule. | ||
* @param {Object} received Rendered component in unit test. | ||
* @param {String} selector The CSS rule. | ||
* @param {String|RegExp} value The CSS value. | ||
* @return {Object} Object for expect to pass or not pass. | ||
*/ | ||
const toHaveStyleRule = (received, selector, value) => { | ||
try { | ||
const className = findClassName(received) | ||
const css = getCSS(styleSheet) | ||
const styles = new RegExp(`${className}[\\s]?{([^}]*)`, 'g').exec(css) | ||
const capture = new RegExp(`${selector}:[\\s]*([^;]+)`, 'g') | ||
const declarations = getDeclarations(rules[0], property) | ||
if (styles && styles[1].match(capture)) { | ||
const values = styles[1].match(capture).map(r => r.replace(capture, '$1').trim()) | ||
if (!declarations.length) { | ||
return die(property) | ||
} | ||
if ( | ||
values && | ||
values.some((v) => { | ||
if (value instanceof RegExp) { | ||
return v.match(value) | ||
} | ||
const declaration = declarations[0] | ||
return v === value | ||
}) | ||
) { | ||
return { // Passed | ||
message: () => (` | ||
${printExpected(`Expected component to have ${selector} matching ${value}`)} | ||
`), | ||
pass: true, | ||
} | ||
} | ||
} | ||
const message = | ||
'Expected:\n' + | ||
` ${printExpected(`${property}: ${value}`)}\n` + | ||
'Received:\n' + | ||
` ${printReceived(`${property}: ${declaration.value}`)}` | ||
return { // Failed -- wrong value | ||
message: () => (` | ||
${printExpected(`Expected ${className} to have ${selector} matching ${value}`)}\n | ||
${printReceived(`But received, ${styles[1] || css}`)} | ||
`), | ||
pass: false, | ||
} | ||
} catch (e) { | ||
return { // Failed -- not rendered correctly | ||
message: () => (` | ||
${printExpected(`Expected ${received} to be a component from react-test-renderer, or a mounted enzyme component.`)}\n | ||
${printReceived(`But had an error, ${e}`)} | ||
`), | ||
pass: false, | ||
} | ||
return { | ||
pass: value === declaration.value, | ||
message, | ||
} | ||
@@ -96,0 +60,0 @@ } |
@@ -18,3 +18,3 @@ const { ServerStyleSheet } = require('styled-components') | ||
function parseCSSfromHTML (html) { | ||
function parseCSSfromHTML(html) { | ||
let css = '' | ||
@@ -37,3 +37,2 @@ let matches | ||
} | ||
return styleSheet.rules().map(rule => rule.cssText).join('\n') | ||
@@ -40,0 +39,0 @@ } |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
14391
275