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

Pass jest-diff options to fix a11 y issues#12576 #13362

Open
wants to merge 22 commits into
base: main
Choose a base branch
from

Conversation

grazirs
Copy link

@grazirs grazirs commented Oct 3, 2022

Summary

This PR is a first step to solve #12576. The proposed solution was to let the user pass a DiffOptions to the configs, allowing them to set their own color choices. However, accessing the config where the default colors are used would require deep refactoring.

As a first approach, with this PR we let the user pass a MatcherHintOptions and DiffOptions in the expect state with expect.setState, and we make sure the default colors are used only if the user didn't overwrite them.

There are some methods where the default colors are still being used because passing a MatcherHintOptions or DiffOptions to them would require deep refactoring.

The affected files are:

  • packages/jest-each/src/validation.ts
  • packages/jest-snapshot/*
  • packages/expect/src/spyMatchers.ts

Test plan

These changes are not affecting the current behavior of the code or breaking any test, so no new tests have been added.

@facebook-github-bot
Copy link
Contributor

Hi @grazirs!

Thank you for your pull request and welcome to our community.

Action Required

In order to merge any pull request (code, docs, etc.), we require contributors to sign our Contributor License Agreement, and we don't seem to have one on file for you.

Process

In order for us to review and merge your suggested changes, please sign at https://code.facebook.com/cla. If you are contributing on behalf of someone else (eg your employer), the individual CLA may not be sufficient and your employer may need to sign the corporate CLA.

Once the CLA is signed, our tooling will perform checks and validations. Afterwards, the pull request will be tagged with CLA signed. The tagging process may take up to 1 hour after signing. Please give it that time before contacting us about it.

If you have received this in error or have any questions, please contact us at [email protected]. Thanks!

@facebook-github-bot
Copy link
Contributor

Thank you for signing our Contributor License Agreement. We can now accept your code for this (and any) Meta Open Source project. Thanks!

Copy link
Contributor

@mrazauskas mrazauskas left a comment

Choose a reason for hiding this comment

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

Thanks for working on this. Looks very interesting.

I think unit tests should be added to make sure there is no regression in the future.

packages/expect/src/types.ts Outdated Show resolved Hide resolved
packages/expect/src/types.ts Outdated Show resolved Hide resolved
packages/jest-matcher-utils/src/index.ts Outdated Show resolved Hide resolved
packages/jest-matcher-utils/src/index.ts Outdated Show resolved Hide resolved
@SimenB
Copy link
Member

SimenB commented Oct 3, 2022

This is a great start, thanks for working on it! I have no comments beyond the ones left by @mrazauskas 👍

And yeah, tests that assert options passed through are respected seems reasonable. This PR brings down overall code coverage - while admittedly it's not super high currently, this PR should quite easily be able to keep the status quo 🙂

@grazirs grazirs marked this pull request as draft October 9, 2022 14:25
@grazirs
Copy link
Author

grazirs commented Oct 9, 2022

Hi @SimenB and @mrazauskas, thanks for your suggestions.
I started working on the tests for matcher-utils, and I'd like to have your feedback on the approach I want to have.
Basically for each test already existing in matcher-utils, after all the assertions, I additionally assert that every function I changed in this PR is called with the color options passed by the user.

Here's an example of how it would look like for a test of the toBe matcher in packages/expect/src/__tests__/matchers.test.js:

const matcherUtils = require('jest-matcher-utils');
const chalk = require('chalk');
const {stringify} = require('jest-matcher-utils');
const {expect: jestExpect} = require('../');

const matcherHintOptions = {
  expectedColor: chalk.yellow,
  noDim: true,
  receivedColor: chalk.magenta,
  secondArgumentColor: chalk.yellow,
};
const diffOptions = {
  aColor: chalk.bgHex('#0000FF'),
  bColor: chalk.magenta,
  noDim: true,
};

expect.setState({diffOptions, matcherHintOptions});

const registerSpies = () => {
  return {
    matcherHint: jest.spyOn(matcherUtils, 'matcherHint'),
    printDiffOrStringify: jest.spyOn(matcherUtils, 'printDiffOrStringify'),
    printExpected: jest.spyOn(matcherUtils, 'printExpected'),
    printReceived: jest.spyOn(matcherUtils, 'printReceived'),
  };
};

const expectUserColorsAreUsed = (
  matcherHint,
  printExpected,
  printReceived,
  printDiffOrStringify,
) => {
  matcherHint.mock.calls.forEach(call => {
    const passedOptions = call[3];
    Object.keys(matcherHintOptions).forEach(key => {
      expect(matcherHintOptions[key]).toEqual(passedOptions[key]);
    });
  });

  printExpected.mock.calls.forEach(call =>
    expect(call[1]).toEqual(diffOptions.aColor),
  );

  printReceived.mock.calls.forEach(call =>
    expect(call[1]).toEqual(diffOptions.bColor),
  );

  printDiffOrStringify.mock.calls.forEach(call =>
    expect(call[5]).toEqual(diffOptions),
  );
};

[
  [1, 2],
   ...
  [-0, +0],
].forEach(([a, b]) => {
  it(`fails for: ${stringify(a)} and ${stringify(b)}`, () => {
    const {matcherHint, printExpected, printReceived, printDiffOrStringify} =
      registerSpies();

    expect(() => jestExpect(a).toBe(b)).toThrowErrorMatchingSnapshot();

    expectUserColorsAreUsed(
      matcherHint,
      printExpected,
      printReceived,
      printDiffOrStringify,
    );
  });
});

I would do the same in all the matchers and test where styled strings are printed.

To ensure that there are no hardcoded colors used somewhere, I'm not passing the default colors in the matcher's state. This will make the snapshots update, as the output of the tests will have a different style.

As I wrote in the PR description, there are some matchers that cannot be updated in this PR, therefore their tests will not be updated.

@SimenB
Copy link
Member

SimenB commented Oct 11, 2022

I would do the same in all the matchers and test where styled strings are printed.

To ensure that there are no hardcoded colors used somewhere, I'm not passing the default colors in the matcher's state. This will make the snapshots update, as the output of the tests will have a different style.

That seems reasonable to me!

@grazirs
Copy link
Author

grazirs commented Oct 31, 2022

Hi @SimenB @mrazauskas! Are there any updates on this?

@@ -1,295 +1,295 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`.rejects fails for promise that resolves 1`] = `
<d>expect(</><r>received</><d>).</>rejects<d>.</>toBe<d>()</>
expect(received</>).rejects.toBe()
Copy link
Member

Choose a reason for hiding this comment

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

seems the escape sequences are off now

Comment on lines 87 to 88
const receivedColor = options.receivedColor ?? RECEIVED_COLOR;
const expectedColor = options.receivedColor ?? EXPECTED_COLOR;
Copy link
Member

@SimenB SimenB Nov 6, 2022

Choose a reason for hiding this comment

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

We already have this.utils.RECEIVED_COLOR and this.utils.EXPECTED_COLOR already. I wonder if we should add the configured colors to this.utils a bit more cleanly, and then use that ourselves instead of checking within every single matcher?

Copy link
Member

Choose a reason for hiding this comment

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

See #13567 - if this PR makes sure to tweak matcher context instead of looking through options in every matcher, it should in theory be easier for all matchers to use the correct colors.

@github-actions
Copy link

This PR is stale because it has been open 90 days with no activity. Remove stale label or comment or this will be closed in 30 days.

@github-actions github-actions bot added the Stale label Apr 14, 2023
@github-actions
Copy link

This PR was closed because it has been stalled for 30 days with no activity. Please open a new PR if the issue is still relevant, linking to this one.

@github-actions github-actions bot closed this May 14, 2023
@SimenB SimenB reopened this May 15, 2023
@linux-foundation-easycla
Copy link

linux-foundation-easycla bot commented May 15, 2023

CLA Signed

The committers listed above are authorized under a signed CLA.

@SimenB SimenB added Pinned and removed Stale labels May 15, 2023
@grazirs grazirs force-pushed the pass-jest-diff-options-to-fix-A11Y-issues#12576 branch from c0f56d7 to 5d97465 Compare September 8, 2023 21:21
@netlify
Copy link

netlify bot commented Sep 8, 2023

Deploy Preview for jestjs ready!

Built without sensitive environment variables

Name Link
🔨 Latest commit 094f16b
🔍 Latest deploy log https://app.netlify.com/sites/jestjs/deploys/64fc4b40218de70008761463
😎 Deploy Preview https://deploy-preview-13362--jestjs.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site configuration.

@grazirs
Copy link
Author

grazirs commented Sep 9, 2023

Hi @SimenB and @mrazauskas . I synced my branch with main and resolved the conflicts. All the tests are passing on my machine (node 16.20.0 on macOS) but the snapshot are failing on the CI. Any idea on what it might be?

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

Successfully merging this pull request may close these issues.

None yet

4 participants