Last active
December 1, 2017 09:00
-
-
Save gilesbradshaw/a6afbbde512daeec9c9f48516d636a89 to your computer and use it in GitHub Desktop.
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
it('observes a tree', marbles((m) => { | |
const a = { | |
children: [ | |
{ | |
children: [ | |
{ | |
name: 'esau', | |
}, | |
{ | |
name: 'jacob', | |
}, | |
], | |
name: 'isaac', | |
}, | |
{ | |
name: 'ishmael', | |
}, | |
], | |
name: 'abraham', | |
}; | |
/* eslint-disable sort-keys */ | |
const b = { | |
name: 'abraham', | |
parent: null, | |
children: [ | |
{ | |
name: 'isaac', | |
parent: { | |
name: 'abraham', | |
parent: null, | |
}, | |
children: [ | |
{ | |
name: 'esau', | |
parent: { | |
name: 'isaac', | |
parent: { | |
name: 'abraham', | |
parent: null, | |
}, | |
}, | |
}, | |
{ | |
name: 'jacob', | |
parent: { | |
name: 'isaac', | |
parent: { | |
name: 'abraham', | |
parent: null, | |
}, | |
children: [ | |
{ | |
name: 'esau', | |
parent: { | |
name: 'isaac', | |
parent: { | |
name: 'abraham', | |
parent: null, | |
}, | |
}, | |
}, | |
], | |
}, | |
}, | |
], | |
}, | |
{ | |
name: 'ishmael', | |
parent: { | |
name: 'abraham', | |
parent: null, | |
children: [ | |
{ | |
name: 'isaac', | |
parent: { | |
name: 'abraham', | |
parent: null, | |
}, | |
children: [ | |
{ | |
name: 'esau', | |
parent: { | |
name: 'isaac', | |
parent: { | |
name: 'abraham', | |
parent: null, | |
}, | |
}, | |
}, | |
{ | |
name: 'jacob', | |
parent: { | |
name: 'isaac', | |
parent: { | |
name: 'abraham', | |
parent: null, | |
}, | |
children: [ | |
{ | |
name: 'esau', | |
parent: { | |
name: 'isaac', | |
parent: { | |
name: 'abraham', | |
parent: null, | |
}, | |
}, | |
}, | |
], | |
}, | |
}, | |
], | |
}, | |
], | |
}, | |
}, | |
], | |
}; | |
/* eslint-enable sort-keys */ | |
// given a func to make tree nodes observable | |
// process all the nodes in a tree and emit the result | |
const roller = func => | |
(object, parent) => | |
func(object, parent).concatMap( | |
(result) => { | |
if (!object.children) { | |
return Rx.Observable.of(result); | |
} | |
return object.children | |
.reduce( | |
(acc, child) => | |
acc.concatMap( | |
_parent => | |
roller(func)(child, _parent) | |
.map( | |
funced => | |
({ | |
..._parent, | |
children: [ | |
...(_parent.children || []), | |
funced, | |
], | |
}), | |
), | |
), | |
Rx.Observable.of(result), | |
); | |
}, | |
); | |
// take a node without it's children and make a observable from it and it's parent | |
// it real life this is where the node is processed, saved to the database etc | |
const func = ({ children, ...rest }, parent = null) => | |
Rx.Observable.of({ | |
...rest, | |
parent, | |
}); | |
// using func this should emit the tree unchanged. | |
m.expect( | |
roller(func)(a), | |
).toBeObservable( | |
'(b|', | |
{ b }, | |
); | |
})); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment