diff --git a/.all-contributorsrc b/.all-contributorsrc
index d1af374a..22c26d55 100644
--- a/.all-contributorsrc
+++ b/.all-contributorsrc
@@ -273,6 +273,15 @@
"name": "Jean Chung",
"avatar_url": "https://avatars0.githubusercontent.com/u/10778036?v=4",
"profile": "https://github.com/jeanchung",
+ "contributions": [
+ "code",
+ "test"
+ ],
+ {
+ "login": "CarlaTeo",
+ "name": "CarlaTeo",
+ "avatar_url": "https://avatars3.githubusercontent.com/u/9220147?v=4",
+ "profile": "https://github.com/CarlaTeo",
"contributions": [
"code",
"test"
diff --git a/README.md b/README.md
index 616969e9..9e7baf61 100644
--- a/README.md
+++ b/README.md
@@ -21,7 +21,7 @@
[![version][version-badge]][package] [![downloads][downloads-badge]][npmtrends]
[![MIT License][license-badge]][license]
-[](#contributors-)
+[](#contributors-)
[![PRs Welcome][prs-badge]][prs] [![Code of Conduct][coc-badge]][coc]
[![Watch on GitHub][github-watch-badge]][github-watch]
@@ -1075,6 +1075,7 @@ Thanks goes to these people ([emoji key][emojis]):
 Jaga Santagostino 🐛 ⚠️ 📖 |
+  Carla Teodoro 💻 ⚠️ |
diff --git a/src/__tests__/to-have-style.js b/src/__tests__/to-have-style.js
index 95949958..35b77256 100644
--- a/src/__tests__/to-have-style.js
+++ b/src/__tests__/to-have-style.js
@@ -15,6 +15,7 @@ describe('.toHaveStyle', () => {
background-color: black;
color: white;
float: left;
+ transition: opacity 0.2s ease-out, top 0.3s cubic-bezier(1.175, 0.885, 0.32, 1.275);
}
`
document.body.appendChild(style)
@@ -30,6 +31,11 @@ describe('.toHaveStyle', () => {
background-color: blue;
color: white;
`)
+
+ expect(container.querySelector('.label')).toHaveStyle(
+ 'transition: opacity 0.2s ease-out, top 0.3s cubic-bezier(1.175, 0.885, 0.32, 1.275)',
+ )
+
expect(container.querySelector('.label')).toHaveStyle(
'background-color:blue;color:white',
)
@@ -53,6 +59,7 @@ describe('.toHaveStyle', () => {
background-color: black;
color: white;
float: left;
+ transition: opacity 0.2s ease-out, top 0.3s cubic-bezier(1.175, 0.885, 0.32, 1.275);
}
`
document.body.appendChild(style)
@@ -63,16 +70,24 @@ describe('.toHaveStyle', () => {
'font-weight: bold',
),
).toThrowError()
+
expect(() =>
expect(container.querySelector('.label')).not.toHaveStyle('color: white'),
).toThrowError()
+ expect(() =>
+ expect(container.querySelector('.label')).toHaveStyle(
+ 'transition: all 0.7s ease, width 1.0s cubic-bezier(3, 4, 5, 6);',
+ ),
+ ).toThrowError()
+
// Make sure the test fails if the css syntax is not valid
expect(() =>
expect(container.querySelector('.label')).not.toHaveStyle(
'font-weight bold',
),
).toThrowError()
+
expect(() =>
expect(container.querySelector('.label')).toHaveStyle('color white'),
).toThrowError()
@@ -96,4 +111,27 @@ describe('.toHaveStyle', () => {
`)
expect(queryByTestId('color-example')).toHaveStyle('border: 1px solid #fff')
})
+
+ test('handles different color declaration formats', () => {
+ const {queryByTestId} = render(`
+ Hello World
+ `)
+
+ expect(queryByTestId('color-example')).toHaveStyle('color: #000000')
+ expect(queryByTestId('color-example')).toHaveStyle(
+ 'background-color: rgba(0, 0, 0, 1)',
+ )
+ })
+
+ test('handles nonexistent styles', () => {
+ const {container} = render(`
+
+ Hello World
+
+ `)
+
+ expect(container.querySelector('.label')).not.toHaveStyle(
+ 'whatever: anything',
+ )
+ })
})
diff --git a/src/to-have-style.js b/src/to-have-style.js
index d3c6966a..6552f67e 100644
--- a/src/to-have-style.js
+++ b/src/to-have-style.js
@@ -1,17 +1,19 @@
import {matcherHint} from 'jest-matcher-utils'
import jestDiff from 'jest-diff'
import chalk from 'chalk'
-import {checkHtmlElement, checkValidCSS} from './utils'
+import {checkHtmlElement, parseCSS} from './utils'
function getStyleDeclaration(document, css) {
+ const styles = {}
+
+ // The next block is necessary to normalize colors
const copy = document.createElement('div')
- copy.style = css
- const styles = copy.style
+ Object.keys(css).forEach(property => {
+ copy.style[property] = css[property]
+ styles[property] = copy.style[property]
+ })
- return Array.from(styles).reduce(
- (acc, name) => ({...acc, [name]: styles[name]}),
- {},
- )
+ return styles
}
function isSubset(styles, computedStyle) {
@@ -47,10 +49,10 @@ function expectedDiff(expected, computedStyles) {
export function toHaveStyle(htmlElement, css) {
checkHtmlElement(htmlElement, toHaveStyle, this)
- checkValidCSS(css, toHaveStyle, this)
+ const parsedCSS = parseCSS(css, toHaveStyle, this)
const {getComputedStyle} = htmlElement.ownerDocument.defaultView
- const expected = getStyleDeclaration(htmlElement.ownerDocument, css)
+ const expected = getStyleDeclaration(htmlElement.ownerDocument, parsedCSS)
const received = getComputedStyle(htmlElement)
return {
diff --git a/src/utils.js b/src/utils.js
index 99c37907..1647fd29 100644
--- a/src/utils.js
+++ b/src/utils.js
@@ -79,7 +79,7 @@ class InvalidCSSError extends Error {
}
}
-function checkValidCSS(css, ...args) {
+function parseCSS(css, ...args) {
const ast = parse(`selector { ${css} }`, {silent: true}).stylesheet
if (ast.parsingErrors && ast.parsingErrors.length > 0) {
@@ -93,6 +93,14 @@ function checkValidCSS(css, ...args) {
...args,
)
}
+
+ const parsedRules = ast.rules[0].declarations
+ .filter(d => d.type === 'declaration')
+ .reduce(
+ (obj, {property, value}) => Object.assign(obj, {[property]: value}),
+ {},
+ )
+ return parsedRules
}
function display(value) {
@@ -187,7 +195,7 @@ function compareArraysAsSet(a, b) {
export {
HtmlElementTypeError,
checkHtmlElement,
- checkValidCSS,
+ parseCSS,
deprecate,
getMessage,
matches,