Skip to content

Commit

Permalink
fix: reset regexg to prevent regexg with global flags to not match ev…
Browse files Browse the repository at this point in the history
…ery element (#1116)
  • Loading branch information
timdeschryver committed Mar 23, 2022
1 parent 90fba31 commit 90d420d
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 2 deletions.
16 changes: 16 additions & 0 deletions src/__tests__/matches.js
Expand Up @@ -15,6 +15,22 @@ test('matchers accept regex', () => {
expect(fuzzyMatches('ABC', node, /ABC/, normalizer)).toBe(true)
})

// https://stackoverflow.com/questions/1520800/why-does-a-regexp-with-global-flag-give-wrong-results
test('a regex with the global flag consistently (re-)finds a match', () => {
const regex = /ABC/g
const spy = jest.spyOn(console, 'warn').mockImplementation()

expect(matches('ABC', node, regex, normalizer)).toBe(true)
expect(fuzzyMatches('ABC', node, regex, normalizer)).toBe(true)

expect(spy).toBeCalledTimes(2)
expect(spy).toHaveBeenCalledWith(
`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.`,
)

console.warn.mockClear()
})

test('matchers accept functions', () => {
expect(matches('ABC', node, text => text === 'ABC', normalizer)).toBe(true)
expect(fuzzyMatches('ABC', node, text => text === 'ABC', normalizer)).toBe(
Expand Down
15 changes: 13 additions & 2 deletions src/matches.ts
Expand Up @@ -36,7 +36,7 @@ function fuzzyMatches(
} else if (typeof matcher === 'function') {
return matcher(normalizedText, node)
} else {
return matcher.test(normalizedText)
return matchRegExp(matcher, normalizedText)
}
}

Expand All @@ -56,7 +56,7 @@ function matches(
if (matcher instanceof Function) {
return matcher(normalizedText, node)
} else if (matcher instanceof RegExp) {
return matcher.test(normalizedText)
return matchRegExp(matcher, normalizedText)
} else {
return normalizedText === String(matcher)
}
Expand Down Expand Up @@ -111,4 +111,15 @@ function makeNormalizer({
return normalizer
}

function matchRegExp(matcher: RegExp, text: string) {
const match = matcher.test(text)
if (matcher.global && matcher.lastIndex !== 0) {
console.warn(
`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.`,
)
matcher.lastIndex = 0
}
return match
}

export {fuzzyMatches, matches, getDefaultNormalizer, makeNormalizer}

0 comments on commit 90d420d

Please sign in to comment.