Skip to content

Commit

Permalink
update remaining dependencies
Browse files Browse the repository at this point in the history
  • Loading branch information
quantizor committed Jun 11, 2019
1 parent f8f7314 commit dfd4d97
Show file tree
Hide file tree
Showing 11 changed files with 2,593 additions and 3,631 deletions.
21 changes: 2 additions & 19 deletions .eslintrc
Original file line number Diff line number Diff line change
@@ -1,24 +1,7 @@
{
"extends": ["airbnb", "plugin:prettier/recommended"],

"extends": ["prettier"],
"env": {
"jest": true
},

"rules": {
"global-require": "off",
"no-cond-assign": ["error", "except-parens"],
"no-param-reassign": "off",
"no-plusplus": "off",
"no-underscore-dangle": ["error", {
"allow": ["__DO_NOT_USE_OR_YOU_WILL_BE_HAUNTED_BY_SPOOKY_GHOSTS"]
}],
"prettier/prettier": ["error", {
"semi": false,
"singleQuote": true,
"trailingComma": "es5"
}],
"react/jsx-filename-extension": ["error", { "extensions": [".js"] }],
"react/prop-types": ["error", { "skipUndeclared": true }],
}
"parser": "babel-eslint"
}
5 changes: 4 additions & 1 deletion .jest.native.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
{
"preset": "react-native",
"testRegex": "test/native/.*\\.spec\\.js$"
"testRegex": "test/native/.*\\.spec\\.js$",
"transform": {
"^.+\\.js$": "<rootDir>/node_modules/react-native/jest/preprocessor.js"
}
}
35 changes: 18 additions & 17 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
"author": "Michele Bertoli",
"license": "MIT",
"scripts": {
"precommit": "lint-staged",
"test": "yarn test:web && yarn test:native && yarn test:preact && yarn test:ts",
"test:web": "jest",
"test:web:watch": "jest --watch",
Expand All @@ -28,31 +27,28 @@
"@babel/plugin-proposal-object-rest-spread": "^7.0.0",
"@babel/preset-env": "^7.0.0",
"@babel/preset-react": "^7.0.0",
"@testing-library/react": "^8.0.1",
"babel-core": "^7.0.0-bridge.0",
"babel-eslint": "^10.0.1",
"babel-jest": "^24.8.0",
"enzyme": "^3.6.0",
"enzyme-adapter-react-16": "^1.5.0",
"enzyme-to-json": "^3.3.1",
"eslint": "^3.17.1",
"eslint-config-airbnb": "^14.1.0",
"eslint-config-prettier": "^2.9.0",
"eslint-plugin-import": "^2.14.0",
"eslint-plugin-jsx-a11y": "^4.0.0",
"eslint-plugin-prettier": "^2.1.2",
"eslint-plugin-react": "^6.10.0",
"husky": "^0.14.3",
"eslint": "^5.16.0",
"eslint-config-prettier": "^4.3.0",
"husky": "^2.4.0",
"jest": "^24.8.0",
"lint-staged": "^7.2.2",
"lint-staged": "^8.2.0",
"preact": "^8.3.1",
"preact-compat": "^3.18.4",
"preact-render-to-json": "^3.6.6",
"prettier": "^1.14.2",
"react": "^16.5.0",
"react-dom": "^16.5.0",
"react-native": "^0.53.3",
"react-test-renderer": "^16.5.0",
"react-testing-library": "^5.0.1",
"styled-components": "^3.4.5",
"prettier": "^1.18.2",
"react": "^16.8.0",
"react-dom": "^16.8.0",
"react-is": "^16.8.6",
"react-native": "^0.59.9",
"react-test-renderer": "^16.8.0",
"styled-components": "^3",
"typescript": "^3.0.3"
},
"dependencies": {
Expand All @@ -61,6 +57,11 @@
"peerDependencies": {
"styled-components": ">= 2"
},
"husky": {
"hooks": {
"pre-commit": "lint-staged"
}
},
"lint-staged": {
"*.js": [
"eslint --fix",
Expand Down
121 changes: 48 additions & 73 deletions src/toHaveStyleRule.js
Original file line number Diff line number Diff line change
@@ -1,137 +1,112 @@
const { getCSS, matcherTest, buildReturnMessage } = require('./utils')
const { getCSS, matcherTest, buildReturnMessage } = require('./utils');

const shouldDive = node =>
typeof node.dive === 'function' && typeof node.type() !== 'string'
const shouldDive = node => typeof node.dive === 'function' && typeof node.type() !== 'string';

const isTagWithClassName = node =>
node.exists() && node.prop('className') && typeof node.type() === 'string'
const isTagWithClassName = node => node.exists() && node.prop('className') && typeof node.type() === 'string';

const getClassNames = received => {
let className
let className;

if (received) {
if (received.$$typeof === Symbol.for('react.test.json')) {
className = received.props.className || received.props.class
className = received.props.className || received.props.class;
} else if (typeof received.exists === 'function' && received.exists()) {
const tree = shouldDive(received) ? received.dive() : received
const components = tree.findWhere(isTagWithClassName)
const tree = shouldDive(received) ? received.dive() : received;
const components = tree.findWhere(isTagWithClassName);
if (components.length) {
className = components.first().prop('className')
className = components.first().prop('className');
}
} else if (global.Element && received instanceof global.Element) {
className = Array.from(received.classList).join(' ')
className = Array.from(received.classList).join(' ');
}
}

return className ? className.split(/\s/) : []
}
return className ? className.split(/\s/) : [];
};

const hasAtRule = options =>
Object.keys(options).some(option => ['media', 'supports'].includes(option))
const hasAtRule = options => Object.keys(options).some(option => ['media', 'supports'].includes(option));

const getAtRules = (ast, options) => {
const mediaRegex = /(\([a-z-]+:)\s?([a-z0-9.]+\))/g
const mediaRegex = /(\([a-z-]+:)\s?([a-z0-9.]+\))/g;

return Object.keys(options)
.map(option =>
ast.stylesheet.rules
.filter(
rule =>
rule.type === option &&
rule[option] === options[option].replace(mediaRegex, '$1$2')
)
.filter(rule => rule.type === option && rule[option] === options[option].replace(mediaRegex, '$1$2'))
.map(rule => rule.rules)
.reduce((acc, rules) => acc.concat(rules), [])
)
.reduce((acc, rules) => acc.concat(rules), [])
}
.reduce((acc, rules) => acc.concat(rules), []);
};

const getModifiedClassName = (className, modifier = '') => {
const classNameSelector = `.${className}`
let prefix = ''
const classNameSelector = `.${className}`;
let prefix = '';

modifier = modifier.trim()
modifier = modifier.trim();
if (modifier.includes('&')) {
modifier = modifier.replace(/&/g, classNameSelector)
modifier = modifier.replace(/&/g, classNameSelector);
} else {
prefix += classNameSelector
prefix += classNameSelector;
}
const first = modifier[0]
const first = modifier[0];
if (first !== ':' && first !== '[') {
prefix += ' '
prefix += ' ';
}

return `${prefix}${modifier}`.trim()
}
return `${prefix}${modifier}`.trim();
};

const hasClassNames = (classNames, selectors, options) =>
classNames.some(className =>
selectors.includes(getModifiedClassName(className, options.modifier))
)
classNames.some(className => selectors.includes(getModifiedClassName(className, options.modifier)));

const getRules = (ast, classNames, options) => {
const rules = hasAtRule(options)
? getAtRules(ast, options)
: ast.stylesheet.rules

return rules.filter(
rule =>
rule.type === 'rule' && hasClassNames(classNames, rule.selectors, options)
)
}
const rules = hasAtRule(options) ? getAtRules(ast, options) : ast.stylesheet.rules;

return rules.filter(rule => rule.type === 'rule' && hasClassNames(classNames, rule.selectors, options));
};

const handleMissingRules = options => ({
pass: false,
message: () =>
`No style rules found on passed Component${
Object.keys(options).length
? ` using options:\n${JSON.stringify(options)}`
: ''
Object.keys(options).length ? ` using options:\n${JSON.stringify(options)}` : ''
}`,
})
});

const getDeclaration = (rule, property) =>
rule.declarations
.filter(
declaration =>
declaration.type === 'declaration' && declaration.property === property
)
.pop()
.filter(declaration => declaration.type === 'declaration' && declaration.property === property)
.pop();

const getDeclarations = (rules, property) =>
rules.map(rule => getDeclaration(rule, property)).filter(Boolean)
const getDeclarations = (rules, property) => rules.map(rule => getDeclaration(rule, property)).filter(Boolean);

const normalizeOptions = options =>
options.modifier
? Object.assign({}, options, {
modifier: Array.isArray(options.modifier)
? options.modifier.join('')
: options.modifier,
modifier: Array.isArray(options.modifier) ? options.modifier.join('') : options.modifier,
})
: options
: options;

function toHaveStyleRule(component, property, expected, options = {}) {
const classNames = getClassNames(component)
const ast = getCSS()
const normalizedOptions = normalizeOptions(options)
const rules = getRules(ast, classNames, normalizedOptions)
const classNames = getClassNames(component);
const ast = getCSS();
const normalizedOptions = normalizeOptions(options);
const rules = getRules(ast, classNames, normalizedOptions);

if (!rules.length) {
return handleMissingRules(normalizedOptions)
return handleMissingRules(normalizedOptions);
}

const declarations = getDeclarations(rules, property)
const declaration = declarations.pop() || {}
const received = declaration.value
const pass =
!received && !expected && this.isNot
? false
: matcherTest(received, expected)
const declarations = getDeclarations(rules, property);
const declaration = declarations.pop() || {};
const received = declaration.value;
const pass = !received && !expected && this.isNot ? false : matcherTest(received, expected);

return {
pass,
message: buildReturnMessage(this.utils, pass, property, received, expected),
}
};
}

module.exports = toHaveStyleRule
module.exports = toHaveStyleRule;
Loading

0 comments on commit dfd4d97

Please sign in to comment.