Fix circular selector detection in t.like()
The previous implementation tracked each object, even if not circular. Update to use a stack. Fixes #3205.
This commit is contained in:
parent
c988e27400
commit
6398772595
2 changed files with 17 additions and 10 deletions
|
|
@ -16,13 +16,7 @@ export function isLikeSelector(selector) {
|
|||
|
||||
export const CIRCULAR_SELECTOR = new Error('Encountered a circular selector');
|
||||
|
||||
export function selectComparable(actual, selector, circular = new Set()) {
|
||||
if (circular.has(selector)) {
|
||||
throw CIRCULAR_SELECTOR;
|
||||
}
|
||||
|
||||
circular.add(selector);
|
||||
|
||||
export function selectComparable(actual, selector, circular = [selector]) {
|
||||
if (isPrimitive(actual)) {
|
||||
return actual;
|
||||
}
|
||||
|
|
@ -31,9 +25,17 @@ export function selectComparable(actual, selector, circular = new Set()) {
|
|||
const enumerableKeys = Reflect.ownKeys(selector).filter(key => Reflect.getOwnPropertyDescriptor(selector, key).enumerable);
|
||||
for (const key of enumerableKeys) {
|
||||
const subselector = Reflect.get(selector, key);
|
||||
comparable[key] = isLikeSelector(subselector)
|
||||
? selectComparable(Reflect.get(actual, key), subselector, circular)
|
||||
: Reflect.get(actual, key);
|
||||
if (isLikeSelector(subselector)) {
|
||||
if (circular.includes(subselector)) {
|
||||
throw CIRCULAR_SELECTOR;
|
||||
}
|
||||
|
||||
circular.push(subselector);
|
||||
comparable[key] = selectComparable(Reflect.get(actual, key), subselector, circular);
|
||||
circular.pop();
|
||||
} else {
|
||||
comparable[key] = Reflect.get(actual, key);
|
||||
}
|
||||
}
|
||||
|
||||
return comparable;
|
||||
|
|
|
|||
|
|
@ -741,6 +741,11 @@ test('.like()', t => {
|
|||
return assertions.like(specimen, selector);
|
||||
});
|
||||
|
||||
passes(t, () => {
|
||||
const array = ['c1', 'c2'];
|
||||
return assertions.like({a: 'a', b: 'b', c: ['c1', 'c2'], d: ['c1', 'c2']}, {b: 'b', d: array, c: array});
|
||||
});
|
||||
|
||||
failsWith(t, () => {
|
||||
const likePattern = {
|
||||
a: 'a',
|
||||
|
|
|
|||
Loading…
Reference in a new issue