-
-
Notifications
You must be signed in to change notification settings - Fork 28
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
3 changed files
with
146 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,129 @@ | ||
import { collect } from './collect'; | ||
|
||
interface Type { | ||
children?: Type[]; | ||
} | ||
|
||
const getChildren = (obj: Type) => obj?.children || []; | ||
|
||
describe('@daffodil/core | collect', () => { | ||
let root: Type; | ||
let obj00: Type; | ||
let obj01: Type; | ||
let obj10: Type; | ||
let obj11: Type; | ||
let obj20: Type; | ||
let obj21: Type; | ||
let obj30: Type; | ||
let obj31: Type; | ||
let result: Type[]; | ||
|
||
beforeEach(() => { | ||
obj30 = {}; | ||
obj31 = {}; | ||
obj20 = {}; | ||
obj21 = { | ||
children: [obj30, obj31], | ||
}; | ||
obj10 = { | ||
children: [obj20], | ||
}; | ||
obj11 = { | ||
children: [obj21], | ||
}; | ||
obj00 = { | ||
children: [obj10, obj11], | ||
}; | ||
obj01 = {}; | ||
root = { | ||
children: [obj00, obj01], | ||
}; | ||
}); | ||
|
||
describe('when depth is not specified', () => { | ||
beforeEach(() => { | ||
result = collect(root, getChildren); | ||
}); | ||
|
||
it('should return the root and all children', () => { | ||
expect(result).toContain(root); | ||
expect(result).toContain(obj00); | ||
expect(result).toContain(obj01); | ||
expect(result).toContain(obj10); | ||
expect(result).toContain(obj11); | ||
expect(result).toContain(obj20); | ||
expect(result).toContain(obj21); | ||
expect(result).toContain(obj30); | ||
expect(result).toContain(obj31); | ||
}); | ||
}); | ||
|
||
describe('when depth is equal to the depth of the tree', () => { | ||
beforeEach(() => { | ||
result = collect(root, getChildren, 3); | ||
}); | ||
|
||
it('should return the root and all children', () => { | ||
expect(result).toContain(root); | ||
expect(result).toContain(obj00); | ||
expect(result).toContain(obj01); | ||
expect(result).toContain(obj10); | ||
expect(result).toContain(obj11); | ||
expect(result).toContain(obj20); | ||
expect(result).toContain(obj21); | ||
expect(result).toContain(obj30); | ||
expect(result).toContain(obj31); | ||
}); | ||
}); | ||
|
||
describe('when depth is more than the depth of the tree', () => { | ||
beforeEach(() => { | ||
result = collect(root, getChildren, 5); | ||
}); | ||
|
||
it('should return the root and all children', () => { | ||
expect(result).toContain(root); | ||
expect(result).toContain(obj00); | ||
expect(result).toContain(obj01); | ||
expect(result).toContain(obj10); | ||
expect(result).toContain(obj11); | ||
expect(result).toContain(obj20); | ||
expect(result).toContain(obj21); | ||
expect(result).toContain(obj30); | ||
expect(result).toContain(obj31); | ||
}); | ||
}); | ||
|
||
describe('when depth is less than the depth of the tree', () => { | ||
beforeEach(() => { | ||
result = collect(root, getChildren, 2); | ||
}); | ||
|
||
it('should return the root and all children up to the specified depth', () => { | ||
expect(result).toContain(root); | ||
expect(result).toContain(obj00); | ||
expect(result).toContain(obj01); | ||
expect(result).toContain(obj10); | ||
expect(result).toContain(obj11); | ||
expect(result).toContain(obj20); | ||
expect(result).toContain(obj21); | ||
}); | ||
|
||
describe('and there is a circular reference', () => { | ||
beforeEach(() => { | ||
obj00.children = [...obj00.children, root]; | ||
result = collect(root, getChildren, 2); | ||
}); | ||
|
||
it('should return the root and all children up to the specified depth and should not infinitely recurse', () => { | ||
expect(result).toContain(root); | ||
expect(result).toContain(obj00); | ||
expect(result).toContain(obj01); | ||
expect(result).toContain(obj10); | ||
expect(result).toContain(obj11); | ||
expect(result).toContain(obj20); | ||
expect(result).toContain(obj21); | ||
}); | ||
}); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
/** | ||
* Recurses through a tree, collecting each element in that tree and returning it in an array. | ||
* The value of getKey should be a field that contains a list of the same type of object. | ||
* Accepts an optional depth argument which will limit the traversal. This should be used for trees with circular references. | ||
*/ | ||
export const collect = <T>(obj: T, getChildren: (val: T) => T[], depth?: number): T[] => | ||
!depth || depth > 0 | ||
? [obj].concat(...getChildren(obj).map((child) => collect(child, getChildren, depth - 1))) | ||
: [obj]; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,13 +1,14 @@ | ||
export * from './long-arithmetic'; | ||
export { collect } from './collect'; | ||
export { daffAdd } from './long-arithmetic'; | ||
export { daffSubtract } from './long-arithmetic'; | ||
export { daffMultiply } from './long-arithmetic'; | ||
export { daffArrayToDict } from './array-to-dict'; | ||
export { daffDivide } from './long-arithmetic'; | ||
export { daffMultiply } from './long-arithmetic'; | ||
export { daffSubtract } from './long-arithmetic'; | ||
export { randomSlice } from './random-slice'; | ||
export { randomSubset } from './random-subset'; | ||
export { range } from './range'; | ||
export { sample } from './sample'; | ||
export { shallowCompare } from './shallow-compare'; | ||
export { shuffle } from './shuffle'; | ||
export { randomSubset } from './random-subset'; | ||
export { randomSlice } from './random-slice'; | ||
export { daffArrayToDict } from './array-to-dict'; | ||
export { sample } from './sample'; | ||
export { unique } from './unique'; | ||
export * from './long-arithmetic'; |