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

Fix toMatch when re-using RegExp with 'g' flag #9290

Closed
wants to merge 1 commit into from
Closed

Fix toMatch when re-using RegExp with 'g' flag #9290

wants to merge 1 commit into from

Conversation

mockdeep
Copy link

Summary

Fixes #9283

When testing a regex with the g flag, the regular expression is not
reset between assertions, such that subsequent assertions that should
pass, fail. The test below passes on Jest 23 but fails on 24:

it('matches consistently when re-using a regex with the "g" flag', () => {
	const regex = /foo/g;
	jestExpect('foo').toMatch(regex); // passes
	jestExpect('foo').toMatch(regex); // fails!
});

It appears this behavior was introduced in c3a0167. Previously, Jest
cloned the regex with new RegExp(), which sidestepped the issue by
using a new regex for every assertion. This restores that behavior. The
issue here is due to somewhat confusing behavior in the way that regular
expressions with the g or y flag behave. Internally, the regex
keeps a lastIndex and the next time it is matched against, it
will search from that index, or cycle back to 0 if no match is found:

> regex = /foo/g
/foo/g
> regex.test('foo')
true
> regex.lastIndex
3
> regex.test('foo')
false
> regex.lastIndex
0
> regex.test('foo')
true
> regex.lastIndex
3

Test plan

Added a new test.

@facebook-github-bot
Copy link
Contributor

Hi mockdeep! Thank you for your pull request and welcome to our community. We require contributors to sign our Contributor License Agreement, and we don't seem to have you on file.In order for us to review and merge your code, 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.

If you have received this in error or have any questions, please contact us at cla@fb.com. Thanks!

Fixes #9283

When testing a regex with the `g` flag, the regular expression is not
reset between assertions, such that subsequent assertions that should
pass, fail. The test below passes on Jest 23 but fails on 24:

```ts
it('matches consistently when re-using a regex with the "g" flag', () => {
  const regex = /foo/g;
  jestExpect('foo').toMatch(regex); // passes
  jestExpect('foo').toMatch(regex); // fails!
});
```

It appears this behavior was introduced in c3a0167. Previously, Jest
cloned the regex with `new RegExp()`, which sidestepped the issue by
using a new regex for every assertion. This restores that behavior. The
issue here is due to somewhat confusing behavior in the way that regular
expressions with the `g` or `y` flag behave. Internally, the regex
[keeps a `lastIndex`][1] and the next time it is matched against, it
will search from that index, or cycle back to 0 if no match is found:

```
> regex = /foo/g
/foo/g
> regex.test('foo')
true
> regex.lastIndex
3
> regex.test('foo')
false
> regex.lastIndex
0
> regex.test('foo')
true
> regex.lastIndex
3
```

[1]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/lastIndex
@mockdeep
Copy link
Author

Ah, woops. Just saw that @wsmd beat me to the punch.

@mockdeep mockdeep closed this Dec 10, 2019
@mockdeep mockdeep deleted the rf-regex_fix branch December 10, 2019 05:00
@codecov-io
Copy link

Codecov Report

Merging #9290 into master will decrease coverage by 0.01%.
The diff coverage is n/a.

Impacted file tree graph

@@            Coverage Diff             @@
##           master    #9290      +/-   ##
==========================================
- Coverage   64.98%   64.97%   -0.02%     
==========================================
  Files         278      278              
  Lines       11899    11899              
  Branches     2934     2933       -1     
==========================================
- Hits         7733     7731       -2     
- Misses       3537     3538       +1     
- Partials      629      630       +1
Impacted Files Coverage Δ
packages/expect/src/matchers.ts 96.86% <ø> (ø) ⬆️
packages/expect/src/utils.ts 94.93% <0%> (-1.27%) ⬇️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update b2c8a69...dadc9b8. Read the comment docs.

@github-actions
Copy link

This pull request has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.
Please note this issue tracker is not a help forum. We recommend using StackOverflow or our discord channel for questions.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators May 11, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

toMatch behaves oddly for regex with global flag
3 participants