Skip to content

Instantly share code, notes, and snippets.

@gilesbradshaw
Last active December 1, 2017 09:00
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gilesbradshaw/a6afbbde512daeec9c9f48516d636a89 to your computer and use it in GitHub Desktop.
Save gilesbradshaw/a6afbbde512daeec9c9f48516d636a89 to your computer and use it in GitHub Desktop.
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