Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Extend functionality of the toHaveStyleRule matcher #1110

Merged
merged 22 commits into from Jan 4, 2019

Conversation

Werter12
Copy link
Contributor

What and Why:
Fixed bug #1109 . Added additional param options for toHaveStyleRule matcher with properties target and media which will help developers to test their components with better accessibility (the style rule will be more accessible for testing). target - will help to access style rule inside hover, focus or to nested html element. media - will help to access css rule in the media queries.

Checklist:

  • Code complete
  • Tests
  • Documentation

@Werter12 Werter12 changed the title Extend functionality of toHaveStyleRule Extend functionality of the toHaveStyleRule matcher Dec 14, 2018
@codecov
Copy link

codecov bot commented Dec 14, 2018

Codecov Report

Merging #1110 into master will increase coverage by 0.01%.
The diff coverage is 100%.

Impacted Files Coverage Δ
packages/jest-emotion/src/utils.js 98.71% <100%> (+0.16%) ⬆️
packages/jest-emotion/src/matchers.js 96.15% <100%> (+0.91%) ⬆️


it('matches styles on the nested component or html element', () => {
const Svg = styled('svg')`
width: 100%;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I were to set a color here, fill: blue;, which is overridden later to fill: green; and the test checks for 'blue' will the tests still pass even though the end visual result is a green fill?

Copy link
Contributor Author

@Werter12 Werter12 Dec 15, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The test check for fill: blue will fail. The fill would be green.

Copy link
Member

@emmatown emmatown Dec 16, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you add a test for that?

this was a reply to #1110 (comment) but GitHub shows replies from reviews strangely

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member

@emmatown emmatown Dec 17, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think that tests it, that looks like it's only declaring the fill property once.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mitchellhamilton lets have a chat in slack, I have sent you a message there

.reduce((decs, rule) => Object.assign([], decs, rule.declarations), [])
let preparedRules = styles.stylesheet.rules
if (media.length > 1) {
if (shortMediaRegExp.test(media) || longMediaRegExp.test(media)) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will longMediaRegExp break when more than one and clause is preset?

@media screen and (min-width: 30em) and (orientation: landscape)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just checked this scenario and it is passed. But I think we can get rid of longMediaRegExp because it is don't extend shortMediaRegExp properly and a invalid media can pass this check by adding () and () pattern

/**
* RegExp for long media statement with and
* @type {RegExp}
*/
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you remove these comments? They aren't really helpful since you can see that it's a regex and the variable name says what it's for.

+media: string;
+rule: string;
}
export const RULE_TYPES: IRuleType = {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you remove this interface? flow can infer what the type is so it's not necessary and it doesn't really help anything.

.toJSON()

expect(tree).toHaveStyleRule('color', 'yellow', { target: 'hover' })
expect(tree).toHaveStyleRule('color', 'black', { target: 'focus' })
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These targets seem confusing, why are they hover and focus, as a consumer I would expect target to accept a css selector so I would expect this to target html elements named hover and focus.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree I will replace it on ':hover' and ':focus'

if (target === '') {
return classNames.includes(selector.slice(1))
}
return selector.includes(target)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you add a comment here explaining what's happening?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've added comments in the code what is going on in this function. Should I add comments here in discussion?

value: *,
options?: { target?: string, media?: string } = {}
) {
const { target = '', media = '' } = options
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's no need for the default values here, leave them as undefined and handle undefined instead of an empty string where necessary.

@@ -23,6 +26,8 @@ function isAsymmetric(obj) {
return obj && isA('Function', obj.asymmetricMatch)
}

const mediaRegExp = /\([a-z-]+:\s[a-z0-9.]+\)/
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would this work with @media only screen or something else like that?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mitchellhamilton I've change regexp to make media with screen property pass

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't just mean screen, it was an example, I meant all the media types(https://developer.mozilla.org/en-US/docs/Web/CSS/Media_Queries/Using_media_queries#Media_types) and I'd prefer that the media types aren't hardcoded.


it('matches styles on the nested component or html element', () => {
const Svg = styled('svg')`
width: 100%;
Copy link
Member

@emmatown emmatown Dec 16, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you add a test for that?

this was a reply to #1110 (comment) but GitHub shows replies from reviews strangely

Copy link
Member

@emmatown emmatown left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you install the latest version of yarn, merge from master, checkout the current yarn.lock on master and run yarn?

.reduce((decs, rule) => Object.assign([], decs, rule.declarations), [])
let preparedRules = styles.stylesheet.rules
if (media) {
if (mediaRegExp.test(media)) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't really get the point of this, why do we need to check if the media query is valid at all? jest-emotion is really for stopping regressions so people should test components in a browser so they'll know if their media query is valid or not. I'd rather remove the check so that we don't have to maintain that regex.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okey

@emmatown
Copy link
Member

Also could you add a test like this

let tree = renderer
  .create(
    <div
      className={css`
        color: green;
        color: hotpink;
      `}
    />
  )
  .toJSON();
expect(tree).not.toHaveStyleRule("color", "green");
expect(tree).toHaveStyleRule("color", "hotpink");

Copy link
Member

@emmatown emmatown left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants