lodash-walk-object
Version:
Walk all properties deep in object with lodash help
211 lines • 6 kB
JavaScript
import { walk } from './lodash-walk-object';
describe('circular reference semantics', () => {
it('does not report ordinary sibling objects as circular', () => {
const input = {
a: {
child: 1,
},
b: {
child: 2,
},
};
const result = walk.Object(input, () => { }, {
checkCircural: true,
walkGetters: false,
});
expect(result.circs).toEqual([]);
});
it('does not report a shared object in sibling branches as circular', () => {
const shared = {
child: 1,
};
const input = {
a: shared,
b: shared,
};
const visitedPaths = [];
const result = walk.Object(input, (_value, path) => {
visitedPaths.push(path);
}, {
checkCircural: true,
walkGetters: false,
});
expect(result.circs).toEqual([
{
circuralTargetPath: 'a',
pathToObj: 'b',
},
]);
expect(visitedPaths).toContain('a.child');
});
it('does not report a deeply shared object as circular', () => {
const shared = {
value: 123,
};
const input = {
left: {
nested: shared,
},
right: {
nested: shared,
},
};
const result = walk.Object(input, () => { }, {
checkCircural: true,
walkGetters: false,
});
expect(result.circs).toEqual([
{
circuralTargetPath: 'left.nested',
pathToObj: 'right.nested',
},
]);
});
it('still detects a direct self-reference', () => {
const input = {
name: 'root',
};
input.self = input;
const result = walk.Object(input, () => { }, {
checkCircural: true,
walkGetters: false,
});
expect(result.circs).toEqual([
{
pathToObj: 'self',
circuralTargetPath: '',
},
]);
});
it('still detects a reference to an active ancestor', () => {
const parent = {
name: 'parent',
};
const child = {
name: 'child',
parent,
};
parent.child = child;
const result = walk.Object(parent, () => { }, {
checkCircural: true,
walkGetters: false,
});
expect(result.circs).toContainEqual({
pathToObj: 'child.parent',
circuralTargetPath: '',
});
});
it('detects a cycle through several levels', () => {
const first = {
name: 'first',
};
const second = {
name: 'second',
};
const third = {
name: 'third',
};
first.next = second;
second.next = third;
third.next = first;
const result = walk.Object(first, () => { }, {
checkCircural: true,
walkGetters: false,
});
expect(result.circs).toContainEqual({
pathToObj: 'next.next.next',
circuralTargetPath: '',
});
});
it('walks a shared object once for each non-circular path', () => {
const shared = {
nested: {
value: 123,
},
};
const input = {
first: shared,
second: shared,
third: shared,
};
const valuePaths = [];
walk.Object(input, (_value, path) => {
if (path.endsWith('.nested.value')) {
valuePaths.push(path);
}
}, {
checkCircural: true,
walkGetters: false,
});
expect(valuePaths).toEqual(['first.nested.value']);
});
});
describe('circular reference semantics sharded objects', () => {
it('does not report a shared object in sibling branches as circular', () => {
const shared = {
child: 1,
};
const input = {
a: shared,
b: shared,
};
const visitedPaths = [];
const result = walk.Object(input, (_value, path) => {
visitedPaths.push(path);
}, {
checkCircural: true,
walkGetters: false,
considerSharedObjects: true,
});
expect(result.circs).toEqual([]);
expect(visitedPaths).toContain('a.child');
expect(visitedPaths).toContain('b.child');
});
it('does not report a deeply shared object as circular', () => {
const shared = {
value: 123,
};
const input = {
left: {
nested: shared,
},
right: {
nested: shared,
},
};
const result = walk.Object(input, () => { }, {
checkCircural: true,
walkGetters: false,
considerSharedObjects: true,
});
expect(result.circs).toEqual([]);
});
it('walks a shared object once for each non-circular path', () => {
const shared = {
nested: {
value: 123,
},
};
const input = {
first: shared,
second: shared,
third: shared,
};
const valuePaths = [];
walk.Object(input, (_value, path) => {
if (path.endsWith('.nested.value')) {
valuePaths.push(path);
}
}, {
checkCircural: true,
walkGetters: false,
considerSharedObjects: true,
});
expect(valuePaths).toEqual([
'first.nested.value',
'second.nested.value',
'third.nested.value',
]);
});
});
//# sourceMappingURL=circural-refs.test.js.map