jest-emotion
Advanced tools
Comparing version 11.0.0-next.7 to 11.0.0-next.10
# jest-emotion | ||
## 11.0.0-next.10 | ||
### Major Changes | ||
- [`b8476e08`](https://github.com/emotion-js/emotion/commit/b8476e08af4a2e8de94a112cb0daf6e8e4d56fe1) [#1600](https://github.com/emotion-js/emotion/pull/1600) Thanks [@mitchellhamilton](https://github.com/mitchellhamilton)! - Rename `jest-emotion` to `@emotion/jest`. Please replace `"snapshotSerializers": ["jest-emotion"]` with `"snapshotSerializers": ["@emotion/jest"]` if you're using the snapshot serializer. Also replace any imports of `jest-emotion` with `@emotion/jest` or use the `@emotion/pkg-renaming` ESLint rule from `@emotion/eslint-plugin`. | ||
## 11.0.0-next.7 | ||
@@ -50,2 +56,8 @@ | ||
## 10.0.25 | ||
### Patch Changes | ||
- [`858c6e70`](https://github.com/emotion-js/emotion/commit/858c6e70e2aa83d159dba00af16f1e34a6d93fd0) [#1648](https://github.com/emotion-js/emotion/pull/1648) Thanks [@ajs139](https://github.com/ajs139)! - Improve support for Enzyme's shallow rendering. | ||
## 10.0.17 | ||
@@ -52,0 +64,0 @@ |
'use strict'; | ||
Object.defineProperty(exports, '__esModule', { value: true }); | ||
function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; } | ||
var _extends = _interopDefault(require('@babel/runtime/helpers/extends')); | ||
var _objectWithoutPropertiesLoose = _interopDefault(require('@babel/runtime/helpers/objectWithoutPropertiesLoose')); | ||
var css = require('css'); | ||
var chalk = _interopDefault(require('chalk')); | ||
var specificity = require('specificity'); | ||
function defaultClassNameReplacer(className, index) { | ||
return "emotion-" + index; | ||
} | ||
var componentSelectorClassNamePattern = /^e[a-zA-Z0-9]+[0-9]+$/; | ||
var replaceClassNames = function replaceClassNames(classNames, styles, code, keys, classNameReplacer) { | ||
if (classNameReplacer === void 0) { | ||
classNameReplacer = defaultClassNameReplacer; | ||
} | ||
var index = 0; | ||
var keyPattern = new RegExp("^(" + keys.join('|') + ")-"); | ||
return classNames.reduce(function (acc, className) { | ||
if (keyPattern.test(className) || componentSelectorClassNamePattern.test(className)) { | ||
var escapedRegex = new RegExp(className.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&'), 'g'); | ||
return acc.replace(escapedRegex, classNameReplacer(className, index++)); | ||
} | ||
return acc; | ||
}, "" + styles + (styles ? '\n\n' : '') + code); | ||
}; | ||
function last(arr) { | ||
return arr.length > 0 ? arr[arr.length - 1] : undefined; | ||
} | ||
function flatMap(arr, iteratee) { | ||
var _ref; | ||
return (_ref = []).concat.apply(_ref, arr.map(iteratee)); | ||
} | ||
function findLast(arr, predicate) { | ||
for (var i = arr.length - 1; i >= 0; i--) { | ||
if (predicate(arr[i])) { | ||
return arr[i]; | ||
} | ||
} | ||
} | ||
var RULE_TYPES = { | ||
media: 'media', | ||
rule: 'rule' | ||
}; | ||
function getClassNames(selectors, classes) { | ||
return classes ? selectors.concat(classes.split(' ')) : selectors; | ||
} | ||
function getClassNamesFromTestRenderer(selectors, _ref2) { | ||
var _ref2$props = _ref2.props, | ||
props = _ref2$props === void 0 ? {} : _ref2$props; | ||
return getClassNames(selectors, props.className || props["class"]); | ||
} | ||
function shouldDive(node) { | ||
return typeof node.dive === 'function' && typeof node.type() !== 'string'; | ||
} | ||
function isTagWithClassName(node) { | ||
return node.prop('className') && typeof node.type() === 'string'; | ||
} | ||
function getClassNamesFromEnzyme(selectors, node) { | ||
// We need to dive if we have selected a styled child from a shallow render | ||
var actualComponent = shouldDive(node) ? node.dive() : node; // Find the first node with a className prop | ||
var components = actualComponent.findWhere(isTagWithClassName); | ||
var classes = components.length && components.first().prop('className'); | ||
return getClassNames(selectors, classes); | ||
} | ||
function getClassNamesFromCheerio(selectors, node) { | ||
var classes = node.attr('class'); | ||
return getClassNames(selectors, classes); | ||
} | ||
function getClassNamesFromDOMElement(selectors, node) { | ||
return getClassNames(selectors, node.getAttribute('class')); | ||
} | ||
function isReactElement(val) { | ||
return val.$$typeof === Symbol["for"]('react.test.json'); | ||
} | ||
function isEmotionCssPropElementType(val) { | ||
return val.$$typeof === Symbol["for"]('react.element') && val.type.$$typeof === Symbol["for"]('react.forward_ref') && val.type.displayName === 'EmotionCssPropInternal'; | ||
} | ||
function isEmotionCssPropEnzymeElement(val) { | ||
return val.$$typeof === Symbol["for"]('react.test.json') && val.type === 'EmotionCssPropInternal'; | ||
} | ||
var domElementPattern = /^((HTML|SVG)\w*)?Element$/; | ||
function isDOMElement(val) { | ||
return val.nodeType === 1 && val.constructor && val.constructor.name && domElementPattern.test(val.constructor.name); | ||
} | ||
function isEnzymeElement(val) { | ||
return typeof val.findWhere === 'function'; | ||
} | ||
function isCheerioElement(val) { | ||
return val.cheerio === '[cheerio object]'; | ||
} | ||
function getClassNamesFromNodes(nodes) { | ||
return nodes.reduce(function (selectors, node) { | ||
if (isReactElement(node)) { | ||
return getClassNamesFromTestRenderer(selectors, node); | ||
} else if (isEnzymeElement(node)) { | ||
return getClassNamesFromEnzyme(selectors, node); | ||
} else if (isCheerioElement(node)) { | ||
return getClassNamesFromCheerio(selectors, node); | ||
} | ||
return getClassNamesFromDOMElement(selectors, node); | ||
}, []); | ||
} | ||
var keyframesPattern = /^@keyframes\s+(animation-[^{\s]+)+/; | ||
var removeCommentPattern = /\/\*[\s\S]*?\*\//g; | ||
var getElementRules = function getElementRules(element) { | ||
var nonSpeedyRule = element.textContent; | ||
if (nonSpeedyRule) { | ||
return [nonSpeedyRule]; | ||
} | ||
if (!element.sheet) { | ||
return []; | ||
} // $FlowFixMe - flow doesn't know about `cssRules` property | ||
return [].slice.call(element.sheet.cssRules).map(function (cssRule) { | ||
return cssRule.cssText; | ||
}); | ||
}; | ||
function getStylesFromClassNames(classNames, elements) { | ||
if (!classNames.length) { | ||
return ''; | ||
} | ||
var keys = getKeys(elements); | ||
if (!keys.length) { | ||
return ''; | ||
} | ||
var targetClassName = classNames.find(function (className) { | ||
return /^e[a-z0-9]+$/.test(className); | ||
}); | ||
var keyPattern = "(" + keys.join('|') + ")-"; | ||
var classNamesRegExp = new RegExp(targetClassName ? "^(" + keyPattern + "|" + targetClassName + ")" : "^" + keyPattern); | ||
var filteredClassNames = classNames.filter(function (className) { | ||
return classNamesRegExp.test(className); | ||
}); | ||
if (!filteredClassNames.length) { | ||
return ''; | ||
} | ||
var selectorPattern = new RegExp('\\.(' + filteredClassNames.join('|') + ')'); | ||
var keyframes = {}; | ||
var styles = ''; | ||
flatMap(elements, getElementRules).forEach(function (rule) { | ||
if (selectorPattern.test(rule)) { | ||
styles += rule; | ||
} | ||
var match = rule.match(keyframesPattern); | ||
if (match !== null) { | ||
var name = match[1]; | ||
if (keyframes[name] === undefined) { | ||
keyframes[name] = ''; | ||
} | ||
keyframes[name] += rule; | ||
} | ||
}); | ||
var keyframeNameKeys = Object.keys(keyframes); | ||
var keyframesStyles = ''; | ||
if (keyframeNameKeys.length) { | ||
var keyframesNamePattern = new RegExp(keyframeNameKeys.join('|'), 'g'); | ||
var keyframesNameCache = {}; | ||
var index = 0; | ||
styles = styles.replace(keyframesNamePattern, function (name) { | ||
if (keyframesNameCache[name] === undefined) { | ||
keyframesNameCache[name] = "animation-" + index++; | ||
keyframesStyles += keyframes[name]; | ||
} | ||
return keyframesNameCache[name]; | ||
}); | ||
keyframesStyles = keyframesStyles.replace(keyframesNamePattern, function (value) { | ||
return keyframesNameCache[value]; | ||
}); | ||
} | ||
return (keyframesStyles + styles).replace(removeCommentPattern, ''); | ||
} | ||
function getStyleElements() { | ||
var elements = Array.from(document.querySelectorAll('style[data-emotion]')); // $FlowFixMe | ||
return elements; | ||
} | ||
var unique = function unique(arr) { | ||
return Array.from(new Set(arr)); | ||
}; | ||
function getKeys(elements) { | ||
var keys = unique(elements.map(function (element) { | ||
return (// $FlowFixMe we know it exists since we query for elements with this attribute | ||
element.getAttribute('data-emotion') | ||
); | ||
})).filter(Boolean); | ||
return keys; | ||
} | ||
function hasClassNames(classNames, selectors, target) { | ||
// selectors is the classNames of specific css rule | ||
return selectors.some(function (selector) { | ||
// if no target, use className of the specific css rule and try to find it | ||
// in the list of received node classNames to make sure this css rule | ||
// applied for root element | ||
if (!target) { | ||
var lastCls = last(selector.split(' ')); | ||
if (!lastCls) { | ||
return false; | ||
} | ||
return classNames.includes(lastCls.slice(1)); | ||
} // check if selector (className) of specific css rule match target | ||
return target instanceof RegExp ? target.test(selector) : selector.includes(target); | ||
}); | ||
} | ||
function getMediaRules(rules, media) { | ||
return rules.filter(function (rule) { | ||
var isMediaMatch = rule.media ? rule.media.replace(/\s/g, '').includes(media.replace(/\s/g, '')) : false; | ||
return rule.type === RULE_TYPES.media && isMediaMatch; | ||
}).reduce(function (mediaRules, mediaRule) { | ||
return mediaRules.concat(mediaRule.rules); | ||
}, []); | ||
} | ||
/* | ||
* Taken from | ||
* https://github.com/facebook/jest/blob/be4bec387d90ac8d6a7596be88bf8e4994bc3ed9/packages/expect/src/jasmine_utils.js#L234 | ||
*/ | ||
function isA(typeName, value) { | ||
return Object.prototype.toString.apply(value) === "[object " + typeName + "]"; | ||
} | ||
/* | ||
* Taken from | ||
* https://github.com/facebook/jest/blob/be4bec387d90ac8d6a7596be88bf8e4994bc3ed9/packages/expect/src/jasmine_utils.js#L36 | ||
*/ | ||
function isAsymmetric(obj) { | ||
return obj && isA('Function', obj.asymmetricMatch); | ||
} | ||
function valueMatches(declaration, value) { | ||
if (value instanceof RegExp) { | ||
return value.test(declaration.value); | ||
} | ||
if (isAsymmetric(value)) { | ||
return value.asymmetricMatch(declaration.value); | ||
} | ||
return value === declaration.value; | ||
} | ||
function toHaveStyleRule(received, property, value, options) { | ||
if (options === void 0) { | ||
options = {}; | ||
} | ||
var _options = options, | ||
target = _options.target, | ||
media = _options.media; | ||
var classNames = getClassNamesFromNodes([received]); | ||
var cssString = getStylesFromClassNames(classNames, getStyleElements()); | ||
var styles = css.parse(cssString); | ||
var preparedRules = styles.stylesheet.rules; | ||
if (media) { | ||
preparedRules = getMediaRules(preparedRules, media); | ||
} | ||
var result = preparedRules.filter(function (rule) { | ||
return rule.type === RULE_TYPES.rule && hasClassNames(classNames, rule.selectors, target); | ||
}).reduce(function (acc, rule) { | ||
var lastMatchingDeclaration = findLast(rule.declarations, function (dec) { | ||
return dec.type === 'declaration' && dec.property === property; | ||
}); | ||
if (!lastMatchingDeclaration) { | ||
return acc; | ||
} | ||
return acc.concat(rule.selectors.map(function (selector) { | ||
return { | ||
selector: selector, | ||
declaration: lastMatchingDeclaration | ||
}; | ||
})); | ||
}, []).sort(function (_ref, _ref2) { | ||
var selectorA = _ref.selector; | ||
var selectorB = _ref2.selector; | ||
return specificity.compare(selectorA, selectorB); | ||
}).pop(); | ||
if (!result) { | ||
return { | ||
pass: false, | ||
message: function message() { | ||
return "Property not found: " + property; | ||
} | ||
}; | ||
} | ||
var declaration = result.declaration; | ||
var pass = valueMatches(declaration, value); | ||
var message = function message() { | ||
return "Expected " + property + (pass ? ' not ' : ' ') + "to match:\n" + (" " + chalk.green(value) + "\n") + 'Received:\n' + (" " + chalk.red(declaration.value)); | ||
}; | ||
return { | ||
pass: pass, | ||
message: message | ||
}; | ||
} | ||
var matchers = { | ||
toHaveStyleRule: toHaveStyleRule | ||
}; | ||
function getNodes(node, nodes) { | ||
if (nodes === void 0) { | ||
nodes = []; | ||
} | ||
if (Array.isArray(node)) { | ||
for (var _iterator = node, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) { | ||
var _ref; | ||
if (_isArray) { | ||
if (_i >= _iterator.length) break; | ||
_ref = _iterator[_i++]; | ||
} else { | ||
_i = _iterator.next(); | ||
if (_i.done) break; | ||
_ref = _i.value; | ||
} | ||
var child = _ref; | ||
getNodes(child, nodes); | ||
} | ||
return nodes; | ||
} | ||
if (node.children) { | ||
for (var _iterator2 = node.children, _isArray2 = Array.isArray(_iterator2), _i2 = 0, _iterator2 = _isArray2 ? _iterator2 : _iterator2[Symbol.iterator]();;) { | ||
var _ref2; | ||
if (_isArray2) { | ||
if (_i2 >= _iterator2.length) break; | ||
_ref2 = _iterator2[_i2++]; | ||
} else { | ||
_i2 = _iterator2.next(); | ||
if (_i2.done) break; | ||
_ref2 = _i2.value; | ||
} | ||
var _child = _ref2; | ||
getNodes(_child, nodes); | ||
} | ||
} | ||
if (typeof node === 'object') { | ||
nodes.push(node); | ||
} | ||
return nodes; | ||
} | ||
function getPrettyStylesFromClassNames(classNames, elements) { | ||
var styles = getStylesFromClassNames(classNames, elements); | ||
var prettyStyles; | ||
try { | ||
prettyStyles = css.stringify(css.parse(styles)); | ||
} catch (e) { | ||
console.error(e); | ||
throw new Error("There was an error parsing the following css: \"" + styles + "\""); | ||
} | ||
return prettyStyles; | ||
} | ||
function filterEmotionProps(props) { | ||
if (props === void 0) { | ||
props = {}; | ||
} | ||
var _props = props, | ||
css = _props.css, | ||
__EMOTION_TYPE_PLEASE_DO_NOT_USE__ = _props.__EMOTION_TYPE_PLEASE_DO_NOT_USE__, | ||
__EMOTION_LABEL_PLEASE_DO_NOT_USE__ = _props.__EMOTION_LABEL_PLEASE_DO_NOT_USE__, | ||
rest = _objectWithoutPropertiesLoose(_props, ["css", "__EMOTION_TYPE_PLEASE_DO_NOT_USE__", "__EMOTION_LABEL_PLEASE_DO_NOT_USE__"]); | ||
rest.css = 'unknown styles'; | ||
return rest; | ||
} | ||
function createSerializer(_temp) { | ||
var _ref3 = _temp === void 0 ? {} : _temp, | ||
classNameReplacer = _ref3.classNameReplacer, | ||
_ref3$DOMElements = _ref3.DOMElements, | ||
DOMElements = _ref3$DOMElements === void 0 ? true : _ref3$DOMElements; | ||
var cache = new WeakSet(); | ||
function print(val, printer) { | ||
if (isEmotionCssPropEnzymeElement(val)) { | ||
return val.children.map(printer).join('\n'); | ||
} | ||
if (isEmotionCssPropElementType(val)) { | ||
return printer(_extends({}, val, { | ||
props: filterEmotionProps(val.props), | ||
type: val.props.__EMOTION_TYPE_PLEASE_DO_NOT_USE__ | ||
})); | ||
} | ||
var nodes = getNodes(val); | ||
var classNames = getClassNamesFromNodes(nodes); | ||
var elements = getStyleElements(); | ||
var styles = getPrettyStylesFromClassNames(classNames, elements); | ||
nodes.forEach(cache.add, cache); | ||
var printedVal = printer(val); | ||
nodes.forEach(cache["delete"], cache); | ||
var keys = getKeys(elements); | ||
return replaceClassNames(classNames, styles, printedVal, keys, classNameReplacer); | ||
} | ||
function test(val) { | ||
return val && (!cache.has(val) && (isReactElement(val) || DOMElements && isDOMElement(val)) || isEmotionCssPropEnzymeElement(val) || isEmotionCssPropElementType(val)); | ||
} | ||
return { | ||
test: test, | ||
print: print | ||
}; | ||
} | ||
var _createSerializer = createSerializer(), | ||
print = _createSerializer.print, | ||
test = _createSerializer.test; | ||
var index = { | ||
print: print, | ||
test: test | ||
}; | ||
exports.createSerializer = createSerializer; | ||
exports.default = index; | ||
exports.matchers = matchers; | ||
exports.print = print; | ||
exports.test = test; | ||
throw new Error('The `jest-emotion` package has been renamed to `@emotion/jest`. Please replace any usage of `jest-emotion` with `@emotion/jest`'); |
"use strict"; | ||
function _interopDefault(ex) { | ||
return ex && "object" == typeof ex && "default" in ex ? ex.default : ex; | ||
} | ||
Object.defineProperty(exports, "__esModule", { | ||
value: !0 | ||
}); | ||
var _extends = _interopDefault(require("@babel/runtime/helpers/extends")), _objectWithoutPropertiesLoose = _interopDefault(require("@babel/runtime/helpers/objectWithoutPropertiesLoose")), css = require("css"), chalk = _interopDefault(require("chalk")), specificity = require("specificity"); | ||
function defaultClassNameReplacer(className, index) { | ||
return "emotion-" + index; | ||
} | ||
var componentSelectorClassNamePattern = /^e[a-zA-Z0-9]+[0-9]+$/, replaceClassNames = function(classNames, styles, code, keys, classNameReplacer) { | ||
void 0 === classNameReplacer && (classNameReplacer = defaultClassNameReplacer); | ||
var index = 0, keyPattern = new RegExp("^(" + keys.join("|") + ")-"); | ||
return classNames.reduce((function(acc, className) { | ||
if (keyPattern.test(className) || componentSelectorClassNamePattern.test(className)) { | ||
var escapedRegex = new RegExp(className.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&"), "g"); | ||
return acc.replace(escapedRegex, classNameReplacer(className, index++)); | ||
} | ||
return acc; | ||
}), styles + (styles ? "\n\n" : "") + code); | ||
}; | ||
function last(arr) { | ||
return arr.length > 0 ? arr[arr.length - 1] : void 0; | ||
} | ||
function flatMap(arr, iteratee) { | ||
var _ref; | ||
return (_ref = []).concat.apply(_ref, arr.map(iteratee)); | ||
} | ||
function findLast(arr, predicate) { | ||
for (var i = arr.length - 1; i >= 0; i--) if (predicate(arr[i])) return arr[i]; | ||
} | ||
var RULE_TYPES = { | ||
media: "media", | ||
rule: "rule" | ||
}; | ||
function getClassNames(selectors, classes) { | ||
return classes ? selectors.concat(classes.split(" ")) : selectors; | ||
} | ||
function getClassNamesFromTestRenderer(selectors, _ref2) { | ||
var _ref2$props = _ref2.props, props = void 0 === _ref2$props ? {} : _ref2$props; | ||
return getClassNames(selectors, props.className || props.class); | ||
} | ||
function shouldDive(node) { | ||
return "function" == typeof node.dive && "string" != typeof node.type(); | ||
} | ||
function isTagWithClassName(node) { | ||
return node.prop("className") && "string" == typeof node.type(); | ||
} | ||
function getClassNamesFromEnzyme(selectors, node) { | ||
var components = (shouldDive(node) ? node.dive() : node).findWhere(isTagWithClassName); | ||
return getClassNames(selectors, components.length && components.first().prop("className")); | ||
} | ||
function getClassNamesFromCheerio(selectors, node) { | ||
return getClassNames(selectors, node.attr("class")); | ||
} | ||
function getClassNamesFromDOMElement(selectors, node) { | ||
return getClassNames(selectors, node.getAttribute("class")); | ||
} | ||
function isReactElement(val) { | ||
return val.$$typeof === Symbol.for("react.test.json"); | ||
} | ||
function isEmotionCssPropElementType(val) { | ||
return val.$$typeof === Symbol.for("react.element") && val.type.$$typeof === Symbol.for("react.forward_ref") && "EmotionCssPropInternal" === val.type.displayName; | ||
} | ||
function isEmotionCssPropEnzymeElement(val) { | ||
return val.$$typeof === Symbol.for("react.test.json") && "EmotionCssPropInternal" === val.type; | ||
} | ||
var domElementPattern = /^((HTML|SVG)\w*)?Element$/; | ||
function isDOMElement(val) { | ||
return 1 === val.nodeType && val.constructor && val.constructor.name && domElementPattern.test(val.constructor.name); | ||
} | ||
function isEnzymeElement(val) { | ||
return "function" == typeof val.findWhere; | ||
} | ||
function isCheerioElement(val) { | ||
return "[cheerio object]" === val.cheerio; | ||
} | ||
function getClassNamesFromNodes(nodes) { | ||
return nodes.reduce((function(selectors, node) { | ||
return isReactElement(node) ? getClassNamesFromTestRenderer(selectors, node) : isEnzymeElement(node) ? getClassNamesFromEnzyme(selectors, node) : isCheerioElement(node) ? getClassNamesFromCheerio(selectors, node) : getClassNamesFromDOMElement(selectors, node); | ||
}), []); | ||
} | ||
var keyframesPattern = /^@keyframes\s+(animation-[^{\s]+)+/, removeCommentPattern = /\/\*[\s\S]*?\*\//g, getElementRules = function(element) { | ||
var nonSpeedyRule = element.textContent; | ||
return nonSpeedyRule ? [ nonSpeedyRule ] : element.sheet ? [].slice.call(element.sheet.cssRules).map((function(cssRule) { | ||
return cssRule.cssText; | ||
})) : []; | ||
}; | ||
function getStylesFromClassNames(classNames, elements) { | ||
if (!classNames.length) return ""; | ||
var keys = getKeys(elements); | ||
if (!keys.length) return ""; | ||
var targetClassName = classNames.find((function(className) { | ||
return /^e[a-z0-9]+$/.test(className); | ||
})), keyPattern = "(" + keys.join("|") + ")-", classNamesRegExp = new RegExp(targetClassName ? "^(" + keyPattern + "|" + targetClassName + ")" : "^" + keyPattern), filteredClassNames = classNames.filter((function(className) { | ||
return classNamesRegExp.test(className); | ||
})); | ||
if (!filteredClassNames.length) return ""; | ||
var selectorPattern = new RegExp("\\.(" + filteredClassNames.join("|") + ")"), keyframes = {}, styles = ""; | ||
flatMap(elements, getElementRules).forEach((function(rule) { | ||
selectorPattern.test(rule) && (styles += rule); | ||
var match = rule.match(keyframesPattern); | ||
if (null !== match) { | ||
var name = match[1]; | ||
void 0 === keyframes[name] && (keyframes[name] = ""), keyframes[name] += rule; | ||
} | ||
})); | ||
var keyframeNameKeys = Object.keys(keyframes), keyframesStyles = ""; | ||
if (keyframeNameKeys.length) { | ||
var keyframesNamePattern = new RegExp(keyframeNameKeys.join("|"), "g"), keyframesNameCache = {}, index = 0; | ||
styles = styles.replace(keyframesNamePattern, (function(name) { | ||
return void 0 === keyframesNameCache[name] && (keyframesNameCache[name] = "animation-" + index++, | ||
keyframesStyles += keyframes[name]), keyframesNameCache[name]; | ||
})), keyframesStyles = keyframesStyles.replace(keyframesNamePattern, (function(value) { | ||
return keyframesNameCache[value]; | ||
})); | ||
} | ||
return (keyframesStyles + styles).replace(removeCommentPattern, ""); | ||
} | ||
function getStyleElements() { | ||
return Array.from(document.querySelectorAll("style[data-emotion]")); | ||
} | ||
var unique = function(arr) { | ||
return Array.from(new Set(arr)); | ||
}; | ||
function getKeys(elements) { | ||
return unique(elements.map((function(element) { | ||
return element.getAttribute("data-emotion"); | ||
}))).filter(Boolean); | ||
} | ||
function hasClassNames(classNames, selectors, target) { | ||
return selectors.some((function(selector) { | ||
if (!target) { | ||
var lastCls = last(selector.split(" ")); | ||
return !!lastCls && classNames.includes(lastCls.slice(1)); | ||
} | ||
return target instanceof RegExp ? target.test(selector) : selector.includes(target); | ||
})); | ||
} | ||
function getMediaRules(rules, media) { | ||
return rules.filter((function(rule) { | ||
var isMediaMatch = !!rule.media && rule.media.replace(/\s/g, "").includes(media.replace(/\s/g, "")); | ||
return rule.type === RULE_TYPES.media && isMediaMatch; | ||
})).reduce((function(mediaRules, mediaRule) { | ||
return mediaRules.concat(mediaRule.rules); | ||
}), []); | ||
} | ||
function isA(typeName, value) { | ||
return Object.prototype.toString.apply(value) === "[object " + typeName + "]"; | ||
} | ||
function isAsymmetric(obj) { | ||
return obj && isA("Function", obj.asymmetricMatch); | ||
} | ||
function valueMatches(declaration, value) { | ||
return value instanceof RegExp ? value.test(declaration.value) : isAsymmetric(value) ? value.asymmetricMatch(declaration.value) : value === declaration.value; | ||
} | ||
function toHaveStyleRule(received, property, value, options) { | ||
void 0 === options && (options = {}); | ||
var _options = options, target = _options.target, media = _options.media, classNames = getClassNamesFromNodes([ received ]), cssString = getStylesFromClassNames(classNames, getStyleElements()), preparedRules = css.parse(cssString).stylesheet.rules; | ||
media && (preparedRules = getMediaRules(preparedRules, media)); | ||
var result = preparedRules.filter((function(rule) { | ||
return rule.type === RULE_TYPES.rule && hasClassNames(classNames, rule.selectors, target); | ||
})).reduce((function(acc, rule) { | ||
var lastMatchingDeclaration = findLast(rule.declarations, (function(dec) { | ||
return "declaration" === dec.type && dec.property === property; | ||
})); | ||
return lastMatchingDeclaration ? acc.concat(rule.selectors.map((function(selector) { | ||
return { | ||
selector: selector, | ||
declaration: lastMatchingDeclaration | ||
}; | ||
}))) : acc; | ||
}), []).sort((function(_ref, _ref2) { | ||
var selectorA = _ref.selector, selectorB = _ref2.selector; | ||
return specificity.compare(selectorA, selectorB); | ||
})).pop(); | ||
if (!result) return { | ||
pass: !1, | ||
message: function() { | ||
return "Property not found: " + property; | ||
} | ||
}; | ||
var declaration = result.declaration, pass = valueMatches(declaration, value); | ||
return { | ||
pass: pass, | ||
message: function() { | ||
return "Expected " + property + (pass ? " not " : " ") + "to match:\n " + chalk.green(value) + "\nReceived:\n " + chalk.red(declaration.value); | ||
} | ||
}; | ||
} | ||
var matchers = { | ||
toHaveStyleRule: toHaveStyleRule | ||
}; | ||
function getNodes(node, nodes) { | ||
if (void 0 === nodes && (nodes = []), Array.isArray(node)) { | ||
var _iterator = node, _isArray = Array.isArray(_iterator), _i = 0; | ||
for (_iterator = _isArray ? _iterator : _iterator[Symbol.iterator](); ;) { | ||
var _ref; | ||
if (_isArray) { | ||
if (_i >= _iterator.length) break; | ||
_ref = _iterator[_i++]; | ||
} else { | ||
if ((_i = _iterator.next()).done) break; | ||
_ref = _i.value; | ||
} | ||
getNodes(_ref, nodes); | ||
} | ||
return nodes; | ||
} | ||
if (node.children) { | ||
var _iterator2 = node.children, _isArray2 = Array.isArray(_iterator2), _i2 = 0; | ||
for (_iterator2 = _isArray2 ? _iterator2 : _iterator2[Symbol.iterator](); ;) { | ||
var _ref2; | ||
if (_isArray2) { | ||
if (_i2 >= _iterator2.length) break; | ||
_ref2 = _iterator2[_i2++]; | ||
} else { | ||
if ((_i2 = _iterator2.next()).done) break; | ||
_ref2 = _i2.value; | ||
} | ||
getNodes(_ref2, nodes); | ||
} | ||
} | ||
return "object" == typeof node && nodes.push(node), nodes; | ||
} | ||
function getPrettyStylesFromClassNames(classNames, elements) { | ||
var prettyStyles, styles = getStylesFromClassNames(classNames, elements); | ||
try { | ||
prettyStyles = css.stringify(css.parse(styles)); | ||
} catch (e) { | ||
throw console.error(e), new Error('There was an error parsing the following css: "' + styles + '"'); | ||
} | ||
return prettyStyles; | ||
} | ||
function filterEmotionProps(props) { | ||
void 0 === props && (props = {}); | ||
var _props = props, rest = (_props.css, _props.__EMOTION_TYPE_PLEASE_DO_NOT_USE__, | ||
_props.__EMOTION_LABEL_PLEASE_DO_NOT_USE__, _objectWithoutPropertiesLoose(_props, [ "css", "__EMOTION_TYPE_PLEASE_DO_NOT_USE__", "__EMOTION_LABEL_PLEASE_DO_NOT_USE__" ])); | ||
return rest.css = "unknown styles", rest; | ||
} | ||
function createSerializer(_temp) { | ||
var _ref3 = void 0 === _temp ? {} : _temp, classNameReplacer = _ref3.classNameReplacer, _ref3$DOMElements = _ref3.DOMElements, DOMElements = void 0 === _ref3$DOMElements || _ref3$DOMElements, cache = new WeakSet; | ||
return { | ||
test: function(val) { | ||
return val && (!cache.has(val) && (isReactElement(val) || DOMElements && isDOMElement(val)) || isEmotionCssPropEnzymeElement(val) || isEmotionCssPropElementType(val)); | ||
}, | ||
print: function(val, printer) { | ||
if (isEmotionCssPropEnzymeElement(val)) return val.children.map(printer).join("\n"); | ||
if (isEmotionCssPropElementType(val)) return printer(_extends({}, val, { | ||
props: filterEmotionProps(val.props), | ||
type: val.props.__EMOTION_TYPE_PLEASE_DO_NOT_USE__ | ||
})); | ||
var nodes = getNodes(val), classNames = getClassNamesFromNodes(nodes), elements = getStyleElements(), styles = getPrettyStylesFromClassNames(classNames, elements); | ||
nodes.forEach(cache.add, cache); | ||
var printedVal = printer(val); | ||
nodes.forEach(cache.delete, cache); | ||
var keys = getKeys(elements); | ||
return replaceClassNames(classNames, styles, printedVal, keys, classNameReplacer); | ||
} | ||
}; | ||
} | ||
var _createSerializer = createSerializer(), print = _createSerializer.print, test = _createSerializer.test, index = { | ||
print: print, | ||
test: test | ||
}; | ||
exports.createSerializer = createSerializer, exports.default = index, exports.matchers = matchers, | ||
exports.print = print, exports.test = test; | ||
throw new Error("The `jest-emotion` package has been renamed to `@emotion/jest`. Please replace any usage of `jest-emotion` with `@emotion/jest`"); |
{ | ||
"name": "jest-emotion", | ||
"version": "11.0.0-next.7", | ||
"version": "11.0.0-next.10", | ||
"description": "Jest utilities for emotion", | ||
@@ -10,26 +10,7 @@ "main": "dist/jest-emotion.cjs.js", | ||
"dist", | ||
"types", | ||
"serializer.js" | ||
], | ||
"scripts": { | ||
"test:typescript": "dtslint types" | ||
"test:typescript": "exit 0" | ||
}, | ||
"dependencies": { | ||
"@babel/runtime": "^7.7.2", | ||
"@types/jest": "^24.0.22", | ||
"chalk": "^2.4.1", | ||
"css": "^2.2.1", | ||
"specificity": "^0.4.1" | ||
}, | ||
"devDependencies": { | ||
"@emotion/core": "^11.0.0-next.7", | ||
"dtslint": "^0.3.0", | ||
"emotion": "^11.0.0-next.0", | ||
"enzyme-to-json": "^3.2.1", | ||
"preact": "^8.2.9", | ||
"preact-render-to-json": "^3.6.6", | ||
"pretty-format": "^22.4.3", | ||
"react": "^16.11.0", | ||
"react-dom": "^16.11.0" | ||
}, | ||
"author": "Kye Hohenberger", | ||
@@ -50,6 +31,3 @@ "homepage": "https://emotion.sh", | ||
"url": "https://github.com/emotion-js/emotion/issues" | ||
}, | ||
"browser": { | ||
"./dist/jest-emotion.cjs.js": "./dist/jest-emotion.browser.cjs.js" | ||
} | ||
} |
122
src/index.js
@@ -1,119 +0,3 @@ | ||
// @flow | ||
import * as css from 'css' | ||
import { replaceClassNames } from './replace-class-names' | ||
import { | ||
getClassNamesFromNodes, | ||
isReactElement, | ||
isEmotionCssPropElementType, | ||
isEmotionCssPropEnzymeElement, | ||
isDOMElement, | ||
getStylesFromClassNames, | ||
getStyleElements, | ||
getKeys | ||
} from './utils' | ||
export { matchers } from './matchers' | ||
function getNodes(node, nodes = []) { | ||
if (Array.isArray(node)) { | ||
for (let child of node) { | ||
getNodes(child, nodes) | ||
} | ||
return nodes | ||
} | ||
if (node.children) { | ||
for (let child of node.children) { | ||
getNodes(child, nodes) | ||
} | ||
} | ||
if (typeof node === 'object') { | ||
nodes.push(node) | ||
} | ||
return nodes | ||
} | ||
function getPrettyStylesFromClassNames( | ||
classNames: Array<string>, | ||
elements: Array<HTMLStyleElement> | ||
) { | ||
let styles = getStylesFromClassNames(classNames, elements) | ||
let prettyStyles | ||
try { | ||
prettyStyles = css.stringify(css.parse(styles)) | ||
} catch (e) { | ||
console.error(e) | ||
throw new Error(`There was an error parsing the following css: "${styles}"`) | ||
} | ||
return prettyStyles | ||
} | ||
type Options = { | ||
classNameReplacer?: (className: string, index: number) => string, | ||
DOMElements?: boolean | ||
} | ||
function filterEmotionProps(props = {}) { | ||
const { | ||
css, | ||
__EMOTION_TYPE_PLEASE_DO_NOT_USE__, | ||
__EMOTION_LABEL_PLEASE_DO_NOT_USE__, | ||
...rest | ||
} = props | ||
rest.css = 'unknown styles' | ||
return rest | ||
} | ||
export function createSerializer({ | ||
classNameReplacer, | ||
DOMElements = true | ||
}: Options = {}) { | ||
let cache = new WeakSet() | ||
function print(val: *, printer: Function) { | ||
if (isEmotionCssPropEnzymeElement(val)) { | ||
return val.children.map(printer).join('\n') | ||
} | ||
if (isEmotionCssPropElementType(val)) { | ||
return printer({ | ||
...val, | ||
props: filterEmotionProps(val.props), | ||
type: val.props.__EMOTION_TYPE_PLEASE_DO_NOT_USE__ | ||
}) | ||
} | ||
const nodes = getNodes(val) | ||
const classNames = getClassNamesFromNodes(nodes) | ||
let elements = getStyleElements() | ||
const styles = getPrettyStylesFromClassNames(classNames, elements) | ||
nodes.forEach(cache.add, cache) | ||
const printedVal = printer(val) | ||
nodes.forEach(cache.delete, cache) | ||
let keys = getKeys(elements) | ||
return replaceClassNames( | ||
classNames, | ||
styles, | ||
printedVal, | ||
keys, | ||
classNameReplacer | ||
) | ||
} | ||
function test(val: *) { | ||
return ( | ||
val && | ||
((!cache.has(val) && | ||
(isReactElement(val) || (DOMElements && isDOMElement(val)))) || | ||
isEmotionCssPropEnzymeElement(val) || | ||
isEmotionCssPropElementType(val)) | ||
) | ||
} | ||
return { test, print } | ||
} | ||
export let { print, test } = createSerializer() | ||
export default { print, test } | ||
throw new Error( | ||
'The `jest-emotion` package has been renamed to `@emotion/jest`. Please replace any usage of `jest-emotion` with `@emotion/jest`' | ||
) |
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
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
No README
QualityPackage does not have a README. This may indicate a failed publish or a low quality package.
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
0
0
5711
7
15
1
0
1
- Removed@babel/runtime@^7.7.2
- Removed@types/jest@^24.0.22
- Removedchalk@^2.4.1
- Removedcss@^2.2.1
- Removedspecificity@^0.4.1
- Removed@babel/runtime@7.25.6(transitive)
- Removed@jest/types@24.9.0(transitive)
- Removed@types/istanbul-lib-coverage@2.0.6(transitive)
- Removed@types/istanbul-lib-report@3.0.3(transitive)
- Removed@types/istanbul-reports@1.1.2(transitive)
- Removed@types/jest@24.9.1(transitive)
- Removed@types/yargs@13.0.12(transitive)
- Removed@types/yargs-parser@21.0.3(transitive)
- Removedansi-regex@4.1.1(transitive)
- Removedansi-styles@3.2.1(transitive)
- Removedatob@2.1.2(transitive)
- Removedchalk@2.4.2(transitive)
- Removedcolor-convert@1.9.3(transitive)
- Removedcolor-name@1.1.3(transitive)
- Removedcss@2.2.4(transitive)
- Removeddecode-uri-component@0.2.2(transitive)
- Removeddiff-sequences@24.9.0(transitive)
- Removedescape-string-regexp@1.0.5(transitive)
- Removedhas-flag@3.0.0(transitive)
- Removedinherits@2.0.4(transitive)
- Removedjest-diff@24.9.0(transitive)
- Removedjest-get-type@24.9.0(transitive)
- Removedpretty-format@24.9.0(transitive)
- Removedreact-is@16.13.1(transitive)
- Removedregenerator-runtime@0.14.1(transitive)
- Removedresolve-url@0.2.1(transitive)
- Removedsource-map@0.6.1(transitive)
- Removedsource-map-resolve@0.5.3(transitive)
- Removedsource-map-url@0.4.1(transitive)
- Removedspecificity@0.4.1(transitive)
- Removedsupports-color@5.5.0(transitive)
- Removedurix@0.1.0(transitive)