Skip to content

Commit 90d420d

Browse files
fix: reset regexg to prevent regexg with global flags to not match every element (#1116)
1 parent 90fba31 commit 90d420d

File tree

2 files changed

+29
-2
lines changed

2 files changed

+29
-2
lines changed

src/__tests__/matches.js

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,22 @@ test('matchers accept regex', () => {
1515
expect(fuzzyMatches('ABC', node, /ABC/, normalizer)).toBe(true)
1616
})
1717

18+
// https://stackoverflow.com/questions/1520800/why-does-a-regexp-with-global-flag-give-wrong-results
19+
test('a regex with the global flag consistently (re-)finds a match', () => {
20+
const regex = /ABC/g
21+
const spy = jest.spyOn(console, 'warn').mockImplementation()
22+
23+
expect(matches('ABC', node, regex, normalizer)).toBe(true)
24+
expect(fuzzyMatches('ABC', node, regex, normalizer)).toBe(true)
25+
26+
expect(spy).toBeCalledTimes(2)
27+
expect(spy).toHaveBeenCalledWith(
28+
`To match all elements we had to reset the lastIndex of the RegExp because the global flag is enabled. We encourage to remove the global flag from the RegExp.`,
29+
)
30+
31+
console.warn.mockClear()
32+
})
33+
1834
test('matchers accept functions', () => {
1935
expect(matches('ABC', node, text => text === 'ABC', normalizer)).toBe(true)
2036
expect(fuzzyMatches('ABC', node, text => text === 'ABC', normalizer)).toBe(

src/matches.ts

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ function fuzzyMatches(
3636
} else if (typeof matcher === 'function') {
3737
return matcher(normalizedText, node)
3838
} else {
39-
return matcher.test(normalizedText)
39+
return matchRegExp(matcher, normalizedText)
4040
}
4141
}
4242

@@ -56,7 +56,7 @@ function matches(
5656
if (matcher instanceof Function) {
5757
return matcher(normalizedText, node)
5858
} else if (matcher instanceof RegExp) {
59-
return matcher.test(normalizedText)
59+
return matchRegExp(matcher, normalizedText)
6060
} else {
6161
return normalizedText === String(matcher)
6262
}
@@ -111,4 +111,15 @@ function makeNormalizer({
111111
return normalizer
112112
}
113113

114+
function matchRegExp(matcher: RegExp, text: string) {
115+
const match = matcher.test(text)
116+
if (matcher.global && matcher.lastIndex !== 0) {
117+
console.warn(
118+
`To match all elements we had to reset the lastIndex of the RegExp because the global flag is enabled. We encourage to remove the global flag from the RegExp.`,
119+
)
120+
matcher.lastIndex = 0
121+
}
122+
return match
123+
}
124+
114125
export {fuzzyMatches, matches, getDefaultNormalizer, makeNormalizer}

0 commit comments

Comments
 (0)