diff --git a/README.md b/README.md index 10afc35..9615a7e 100644 --- a/README.md +++ b/README.md @@ -348,6 +348,7 @@ test('it works', () => { The `toHaveStyleRule` matcher is useful to test if a given rule is applied to a component. The first argument is the expected property, the second is the expected value which can be a String, RegExp, Jest asymmetric matcher or `undefined`. +When used with a negated ".not" modifier the second argument is optional and can be omitted. ```js const Button = styled.button` @@ -362,8 +363,9 @@ test('it applies default styles', () => { expect(tree).toHaveStyleRule('color', 'red') expect(tree).toHaveStyleRule('border', '0.05em solid black') expect(tree).toHaveStyleRule('cursor', 'pointer') - expect(tree).toHaveStyleRule('opacity', undefined) // equivalent of the following + expect(tree).not.toHaveStyleRule('opacity') // equivalent of the following two expect(tree).not.toHaveStyleRule('opacity', expect.any(String)) + expect(tree).toHaveStyleRule('opacity', undefined) }) test('it applies styles according to passed props', () => { diff --git a/src/native/toHaveStyleRule.js b/src/native/toHaveStyleRule.js index 73da958..9c076bd 100644 --- a/src/native/toHaveStyleRule.js +++ b/src/native/toHaveStyleRule.js @@ -16,7 +16,9 @@ function toHaveStyleRule(component, property, expected) { */ const mergedStyles = styles.reduce((acc, item) => ({ ...acc, ...item }), {}) const received = mergedStyles[camelCasedProperty] - const pass = matcherTest(received, expected) + const matches = matcherTest(received, expected) + // if expected value is not passed and we have a negated ".not" modifier we need to flip our assertion + const pass = !expected && this.isNot ? !matches : matches return { pass, diff --git a/src/toHaveStyleRule.js b/src/toHaveStyleRule.js index 5fbf30a..9ff6d5e 100644 --- a/src/toHaveStyleRule.js +++ b/src/toHaveStyleRule.js @@ -101,13 +101,13 @@ const getDeclaration = (rule, property) => const getDeclarations = (rules, property) => rules.map(rule => getDeclaration(rule, property)).filter(Boolean) -const normalizeOptions = (options) => +const normalizeOptions = options => options.modifier - ? Object.assign( - {}, - options, - { modifier: Array.isArray(options.modifier) ? options.modifier.join('') : options.modifier }, - ) + ? Object.assign({}, options, { + modifier: Array.isArray(options.modifier) + ? options.modifier.join('') + : options.modifier, + }) : options function toHaveStyleRule(component, property, expected, options = {}) { @@ -123,7 +123,9 @@ function toHaveStyleRule(component, property, expected, options = {}) { const declarations = getDeclarations(rules, property) const declaration = declarations.pop() || {} const received = declaration.value - const pass = matcherTest(received, expected) + const matches = matcherTest(received, expected) + // if expected value is not passed and we have a negated ".not" modifier we need to flip our assertion + const pass = !expected && this.isNot ? !matches : matches return { pass, diff --git a/test/native/toHaveStyleRule.spec.js b/test/native/toHaveStyleRule.spec.js index 8d55603..379f571 100644 --- a/test/native/toHaveStyleRule.spec.js +++ b/test/native/toHaveStyleRule.spec.js @@ -78,6 +78,20 @@ test('undefined', () => { ) }) +test('negated ".not" modifier with no value', () => { + const Button = styled.Text` + ${({ transparent }) => !transparent && 'background-color: papayawhip;'}; + ` + + expect(renderer.create(