@platform/state
Version:
A small, simple, strongly typed, [rx/observable] state-machine.
465 lines (464 loc) • 23.3 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
var test_1 = require("../test");
var _1 = require(".");
var create = _1.TreeQuery.create;
describe('TreeQuery', function () {
describe('create', function () {
it('with root (default node type)', function () {
var root = { id: 'root' };
var query = create(root);
(0, test_1.expect)(query.root).to.equal(root);
(0, test_1.expect)(query.namespace).to.eql('');
});
it('with root (specific node type)', function () {
var root = { id: 'root', count: 0 };
var query = create(root);
(0, test_1.expect)(query.root).to.equal(root);
(0, test_1.expect)(query.namespace).to.eql('');
});
it('with namespace', function () {
var test = function (namespace, expected) {
var root = { id: 'root' };
var query = create({ root: root, namespace: namespace });
(0, test_1.expect)(query.namespace).to.eql(expected);
};
test('', '');
test(' ', '');
test('foo', 'foo');
test(' foo ', 'foo');
});
});
describe('children (static)', function () {
it('no arguments', function () {
var count = 0;
var res = _1.TreeQuery.children(undefined, function () { return count++; });
(0, test_1.expect)(res).to.eql([]);
(0, test_1.expect)(count).to.eql(1);
});
it('no childen => empty array (and assigns by default)', function () {
var node = { id: 'root' };
(0, test_1.expect)(node.children).to.eql(undefined);
var res = _1.TreeQuery.children(node);
(0, test_1.expect)(res).to.eql([]);
(0, test_1.expect)(node.children).to.equal(res);
});
it('no childen => empty array (and does not assign)', function () {
var node = { id: 'root' };
(0, test_1.expect)(node.children).to.eql(undefined);
var res1 = _1.TreeQuery.children(node, { assign: false });
(0, test_1.expect)(res1).to.eql([]);
(0, test_1.expect)(node.children).to.equal(undefined);
var res2 = _1.TreeQuery.children(node, undefined, { assign: false });
(0, test_1.expect)(res2).to.eql([]);
(0, test_1.expect)(node.children).to.equal(undefined);
});
it('returns child array (instance)', function () {
var node = { id: 'root', children: [{ id: 'child' }] };
(0, test_1.expect)(_1.TreeQuery.children(node)).to.eql([{ id: 'child' }]);
});
it('runs visitor function', function () {
var node = { id: 'root', children: [{ id: 'child-1' }, { id: 'child-2' }] };
var visits = [];
_1.TreeQuery.children(node, function (children) { return children.forEach(function (child) { return visits.push(child); }); });
(0, test_1.expect)(visits.map(function (c) { return c.id; })).to.eql(['child-1', 'child-2']);
});
});
describe('hasChild (static)', function () {
var root = { id: 'A', children: [{ id: 'B' }, { id: 'C' }] };
it('does have child', function () {
(0, test_1.expect)(_1.TreeQuery.hasChild(root, 'B')).to.eql(true);
(0, test_1.expect)(_1.TreeQuery.hasChild(root, 'C')).to.eql(true);
(0, test_1.expect)(_1.TreeQuery.hasChild(root, { id: 'C' })).to.eql(true);
});
it('does not have child', function () {
(0, test_1.expect)(_1.TreeQuery.hasChild(root, 'A')).to.eql(false);
(0, test_1.expect)(_1.TreeQuery.hasChild(root, 'NO_MATCH')).to.eql(false);
(0, test_1.expect)(_1.TreeQuery.hasChild(root, undefined)).to.eql(false);
(0, test_1.expect)(_1.TreeQuery.hasChild(undefined, undefined)).to.eql(false);
});
});
describe('walkDown', function () {
it('walkDown from root', function () {
var tree = {
id: 'root',
children: [{ id: 'child-1' }, { id: 'child-2' }],
};
var query = create(tree);
var items = [];
query.walkDown(function (e) { return items.push(e); });
(0, test_1.expect)(items.length).to.eql(3);
(0, test_1.expect)(items[0].node).to.equal(tree);
(0, test_1.expect)(items[1].node).to.equal(tree.children && tree.children[0]);
(0, test_1.expect)(items[2].node).to.equal(tree.children && tree.children[1]);
(0, test_1.expect)(items.every(function (m) { return m.namespace === ''; })).to.eql(true);
});
it('walkDown from root (with namespace)', function () {
var tree = {
id: 'ns:root',
children: [{ id: 'ns:child-1' }, { id: 'ns:child-2' }],
};
var query = create(tree);
var items = [];
query.walkDown(function (e) { return items.push(e); });
(0, test_1.expect)(items.length).to.eql(3);
(0, test_1.expect)(items.every(function (m) { return m.namespace === 'ns'; })).to.eql(true);
(0, test_1.expect)(items[0].key).to.equal('root');
(0, test_1.expect)(items[0].id).to.equal('ns:root');
(0, test_1.expect)(items[0].node.id).to.equal('ns:root');
(0, test_1.expect)(items[1].key).to.equal('child-1');
(0, test_1.expect)(items[1].id).to.equal('ns:child-1');
(0, test_1.expect)(items[1].node.id).to.equal('ns:child-1');
(0, test_1.expect)(items[2].key).to.equal('child-2');
(0, test_1.expect)(items[2].id).to.equal('ns:child-2');
(0, test_1.expect)(items[2].node.id).to.equal('ns:child-2');
});
it('walkDown: skip (children)', function () {
var tree = {
id: 'root',
children: [
{ id: 'child-1', children: [{ id: 'child-1.1' }, { id: 'child-1.1' }] },
{ id: 'child-2' },
],
};
var query = create(tree);
var nodes = [];
query.walkDown(function (e) {
nodes.push(e.node);
if (e.node.id === 'child-1') {
e.skip();
}
});
(0, test_1.expect)(nodes.length).to.eql(3);
(0, test_1.expect)(nodes[0].id).to.eql('root');
(0, test_1.expect)(nodes[1].id).to.eql('child-1');
(0, test_1.expect)(nodes[2].id).to.eql('child-2');
});
it('walkDown: stop mid-way', function () {
var root = {
id: 'root',
children: [{ id: 'child-1' }, { id: 'child-2', children: [{ id: 'child-2.1' }] }],
};
var state = create(root);
var walked = [];
state.walkDown(function (e) {
walked.push(e);
if (e.id === 'child-1') {
e.stop();
}
});
(0, test_1.expect)(walked.length).to.eql(2);
(0, test_1.expect)(walked[0].id).to.eql('root');
(0, test_1.expect)(walked[1].id).to.eql('child-1');
});
it('walkDown: passes level/parent to visitor', function () {
var grandchild = { id: 'grandchild' };
var child = { id: 'child', children: [grandchild] };
var root = { id: 'root', children: [child] };
var query = create(root);
var items = [];
query.walkDown(function (e) { return items.push(e); });
(0, test_1.expect)(items.length).to.eql(3);
(0, test_1.expect)(items[0].level).to.eql(0);
(0, test_1.expect)(items[1].level).to.eql(1);
(0, test_1.expect)(items[2].level).to.eql(2);
(0, test_1.expect)(items[0].parent).to.eql(undefined);
(0, test_1.expect)(items[1].parent).to.eql(root);
(0, test_1.expect)(items[2].parent).to.eql(child);
});
it('walkDown: passes index to visitor (sibling position)', function () {
var root = {
id: 'root',
children: [{ id: 'child-1' }, { id: 'child-2' }],
};
var query = create(root);
var items = [];
query.walkDown(function (e) { return items.push(e); });
(0, test_1.expect)(items[0].index).to.eql(-1);
(0, test_1.expect)(items[1].index).to.eql(0);
(0, test_1.expect)(items[2].index).to.eql(1);
});
it('walkDown: does not walk down into child namespace', function () {
var _a;
var root = {
id: 'ns1:root',
children: [{ id: 'ns1:child-1' }, { id: 'ns1:child-2', children: [{ id: 'ns2:foo' }] }],
};
var query = create({ root: root, namespace: 'ns1' });
(0, test_1.expect)(query.namespace).to.eql('ns1');
(0, test_1.expect)((_a = create(root).findById('ns2:foo')) === null || _a === void 0 ? void 0 : _a.id).to.eql('ns2:foo');
var walked = [];
query.walkDown(function (e) { return walked.push(e); });
var ids = walked.map(function (e) { return e.id; });
(0, test_1.expect)(ids.length).to.eql(3);
(0, test_1.expect)(ids.includes('ns2:foo')).to.eql(false);
});
});
describe('walkUp', function () {
it('walkUp: to root', function () {
var tree = {
id: 'root',
children: [{ id: 'child-1' }, { id: 'child-2', children: [{ id: 'grandchild-1' }] }],
};
var query = create(tree);
var start = query.findById('grandchild-1');
var items = [];
query.walkUp(start, function (e) { return items.push(e); });
(0, test_1.expect)(items.length).to.eql(3);
(0, test_1.expect)(items.map(function (e) { return e.node.id; })).to.eql(['grandchild-1', 'child-2', 'root']);
(0, test_1.expect)(items.every(function (m) { return m.namespace === ''; })).to.eql(true);
(0, test_1.expect)(items[0].parent && items[0].parent.id).to.eql('child-2');
(0, test_1.expect)(items[1].parent && items[1].parent.id).to.eql('root');
(0, test_1.expect)(items[2].parent && items[2].parent.id).to.eql(undefined);
(0, test_1.expect)(items[0].index).to.eql(0);
(0, test_1.expect)(items[1].index).to.eql(1);
(0, test_1.expect)(items[2].index).to.eql(-1);
});
it('walkUp: to root (with namespace)', function () {
var tree = {
id: 'ns:root',
children: [
{ id: 'ns:child-1' },
{ id: 'ns:child-2', children: [{ id: 'ns:grandchild-1' }] },
],
};
var query = create(tree);
var start = query.findById('ns:grandchild-1');
var items = [];
query.walkUp(start, function (e) { return items.push(e); });
(0, test_1.expect)(items.length).to.eql(3);
(0, test_1.expect)(items.every(function (m) { return m.namespace === 'ns'; })).to.eql(true);
(0, test_1.expect)(items.map(function (e) { return e.key; })).to.eql(['grandchild-1', 'child-2', 'root']);
(0, test_1.expect)(items.map(function (e) { return e.node.id; })).to.eql(['ns:grandchild-1', 'ns:child-2', 'ns:root']);
});
it('walkUp: stop mid-way', function () {
var tree = {
id: 'root',
children: [{ id: 'child-1' }, { id: 'child-2', children: [{ id: 'grandchild-1' }] }],
};
var query = create(tree);
var start = query.findById('grandchild-1');
var list = [];
query.walkUp(start, function (e) {
list.push(e);
if (e.node.id === 'child-2') {
e.stop();
}
});
(0, test_1.expect)(list.length).to.eql(2);
(0, test_1.expect)(list.map(function (e) { return e.id; })).to.eql(['grandchild-1', 'child-2']);
});
it('walkUp: startAt not found', function () {
var tree = {
id: 'root',
children: [{ id: 'child-1' }, { id: 'child-2', children: [{ id: 'grandchild-1' }] }],
};
var query = create(tree);
var test = function (startAt) {
var walked = [];
query.walkUp(startAt, function (e) { return walked.push(e); });
(0, test_1.expect)(walked).to.eql([]);
};
test();
test('404');
test({ id: '404' });
});
it('walkUp: passes level (from start of ascent)', function () {
var tree = {
id: 'root',
children: [{ id: 'child-1' }, { id: 'child-2', children: [{ id: 'grandchild-1' }] }],
};
var query = create(tree);
var walked = [];
query.walkUp('grandchild-1', function (e) { return walked.push(e); });
(0, test_1.expect)(walked.map(function (e) { return e.level; })).to.eql([0, 1, 2]);
});
it('walkUp: does not walk up into parent namespace', function () {
var tree = {
id: 'ns1:root',
children: [
{ id: 'ns1:child-1' },
{ id: 'ns2:child-2', children: [{ id: 'ns2:child-2.1' }] },
],
};
var root = create(tree).findById('ns2:child-2');
var child = create(tree).findById('ns2:child-2.1');
(0, test_1.expect)(child).to.exist;
var query = create({ root: root, namespace: 'ns2' });
var test = function (startAt) {
var walked = [];
query.walkUp(startAt, function (e) { return walked.push(e); });
(0, test_1.expect)(walked.map(function (e) { return e.key; })).to.eql(['child-2.1', 'child-2']);
};
test(child);
test(child === null || child === void 0 ? void 0 : child.id);
test('child-2.1');
});
});
describe('find', function () {
it('no namespace', function () {
var tree = {
id: 'root',
children: [{ id: 'child-1' }, { id: 'child-2', children: [{ id: 'child-3' }] }],
};
var query = create(tree);
var res1 = query.find(function (e) { return e.node.id === 'child-3'; });
var res2 = query.find(function (e) { return e.node.id === 'NO_EXIT'; });
(0, test_1.expect)(res1).to.eql({ id: 'child-3' });
(0, test_1.expect)(res2).to.eql(undefined);
});
it('with namespace', function () {
var tree = {
id: 'ns:root',
children: [{ id: 'child-1' }, { id: 'ns:child-2', children: [{ id: 'ns:child-3' }] }],
};
var query = create(tree);
var res1a = query.find(function (e) { return e.namespace === 'ns' && e.key === 'child-3'; });
var res1b = query.find(function (e) { return e.id === 'ns:child-3'; });
var res2 = query.find(function (e) { return e.namespace === 'foo' && e.key === 'child-3'; });
(0, test_1.expect)(res1a).to.eql({ id: 'ns:child-3' });
(0, test_1.expect)(res1b).to.eql({ id: 'ns:child-3' });
(0, test_1.expect)(res2).to.eql(undefined);
});
it('root with namespace', function () {
var tree = {
id: 'root',
children: [
{ id: 'child-1' },
{ id: 'ns:child-2', children: [{ id: 'ns:child-2.1' }, { id: 'ns:child-2.1' }] },
],
};
var query = create(tree);
var res = query.find(function (e) { return e.namespace === 'ns'; });
(0, test_1.expect)(res === null || res === void 0 ? void 0 : res.id).to.eql('ns:child-2');
});
});
describe('findById', function () {
it('no namespace', function () {
var tree = {
id: 'root',
children: [{ id: 'child-1' }, { id: 'child-2', children: [{ id: 'child-3' }] }],
};
var query = create(tree);
var res1 = query.findById('child-3');
var res2 = query.findById('NO_EXIST');
var res3 = query.findById(undefined);
var res4 = query.findById({ id: 'child-2' });
(0, test_1.expect)(res1).to.eql({ id: 'child-3' });
(0, test_1.expect)(res2).to.eql(undefined);
(0, test_1.expect)(res3).to.eql(undefined);
(0, test_1.expect)(res4).to.eql({ id: 'child-2', children: [{ id: 'child-3' }] });
});
it('within namespace', function () {
var _a, _b, _c, _d, _e, _f, _g, _h, _j;
var root = {
id: 'ns1:root',
children: [{ id: 'ns1:child-1' }, { id: 'ns2:child-2' }, { id: 'foo' }],
};
var query = create({ root: root });
var ns1 = create({ root: root, namespace: 'ns1' });
(0, test_1.expect)((_a = query.findById('root')) === null || _a === void 0 ? void 0 : _a.id).to.eql('ns1:root');
(0, test_1.expect)(query.findById('foo:root')).to.eql(undefined);
(0, test_1.expect)((_b = query.findById('ns1:root')) === null || _b === void 0 ? void 0 : _b.id).to.eql('ns1:root');
(0, test_1.expect)((_c = query.findById('ns1:child-1')) === null || _c === void 0 ? void 0 : _c.id).to.eql('ns1:child-1');
(0, test_1.expect)((_d = query.findById('ns2:child-2')) === null || _d === void 0 ? void 0 : _d.id).to.eql('ns2:child-2');
(0, test_1.expect)((_e = query.findById('foo')) === null || _e === void 0 ? void 0 : _e.id).to.eql('foo');
(0, test_1.expect)((_f = ns1.findById('root')) === null || _f === void 0 ? void 0 : _f.id).to.eql('ns1:root');
(0, test_1.expect)((_g = ns1.findById('ns1:root')) === null || _g === void 0 ? void 0 : _g.id).to.eql('ns1:root');
(0, test_1.expect)(ns1.findById('foo:root')).to.eql(undefined);
(0, test_1.expect)(ns1.findById('404')).to.eql(undefined);
(0, test_1.expect)(ns1.findById('ns1:404')).to.eql(undefined);
(0, test_1.expect)((_h = ns1.findById('child-1')) === null || _h === void 0 ? void 0 : _h.id).to.eql('ns1:child-1');
(0, test_1.expect)((_j = ns1.findById('ns1:child-1')) === null || _j === void 0 ? void 0 : _j.id).to.eql('ns1:child-1');
(0, test_1.expect)(ns1.findById('child-2')).to.eql(undefined);
(0, test_1.expect)(ns1.findById('ns2:child-2')).to.eql(undefined);
(0, test_1.expect)(ns1.findById('foo')).to.eql(undefined);
});
});
describe('parent', function () {
it('has a parent', function () {
var grandchild = { id: 'grandchild' };
var child = { id: 'child', children: [grandchild] };
var root = { id: 'root', children: [child] };
var query = create(root);
(0, test_1.expect)(query.parent(child)).to.equal(root);
(0, test_1.expect)(query.parent(grandchild)).to.equal(child);
});
it('has no parent', function () {
var grandchild = { id: 'grandchild' };
var child = { id: 'child', children: [grandchild] };
var root = { id: 'root', children: [] };
var query = create(root);
(0, test_1.expect)(query.parent(child)).to.equal(undefined);
(0, test_1.expect)(query.parent(grandchild)).to.equal(undefined);
});
});
describe('ancestor', function () {
var tree = {
id: 'root',
children: [{ id: 'child-1' }, { id: 'child-2', children: [{ id: 'child-3' }] }],
};
it('matches self (first)', function () {
var query = create(tree);
var node = query.findById('child-3');
var res = query.ancestor(node, function (e) { return e.node.id === 'child-3'; });
(0, test_1.expect)(res && res.id).to.eql('child-3');
});
it('finds matching ancestor', function () {
var query = create(tree);
var node = query.findById('child-3');
var res1 = query.ancestor(node, function (e) { return e.node.id === 'child-2'; });
var res2 = query.ancestor(node, function (e) { return e.node.id === 'root'; });
(0, test_1.expect)(res1 && res1.id).to.eql('child-2');
(0, test_1.expect)(res2 && res2.id).to.eql('root');
});
it('no match', function () {
var query = create(tree);
var node = query.findById('root');
var res = query.ancestor(node, function (e) { return e.node.id === 'child-1'; });
(0, test_1.expect)(res).to.eql(undefined);
});
});
describe('depth', function () {
var root = {
id: 'A',
children: [{ id: 'B' }, { id: 'C', children: [{ id: 'D' }] }],
};
it('retrieves depth', function () {
var query = create(root);
(0, test_1.expect)(query.depth('A')).to.eql(0);
(0, test_1.expect)(query.depth({ id: 'A' })).to.eql(0);
(0, test_1.expect)(query.depth('B')).to.eql(1);
(0, test_1.expect)(query.depth('C')).to.eql(1);
(0, test_1.expect)(query.depth('D')).to.eql(2);
(0, test_1.expect)(query.depth({ id: 'D' })).to.eql(2);
});
it('-1', function () {
var query = create({ id: 'root' });
(0, test_1.expect)(query.depth('C')).to.eql(-1);
(0, test_1.expect)(query.depth(undefined)).to.eql(-1);
(0, test_1.expect)(query.depth('NO_EXIST')).to.eql(-1);
(0, test_1.expect)(query.depth({ id: 'NO_EXIST' })).to.eql(-1);
});
});
describe('exists', function () {
var tree = {
id: 'root',
children: [{ id: 'child-1' }, { id: 'child-2', children: [{ id: 'child-3' }] }],
};
it('exists', function () {
var query = create(tree);
(0, test_1.expect)(query.exists('root')).to.eql(true);
(0, test_1.expect)(query.exists('child-3')).to.eql(true);
(0, test_1.expect)(query.exists({ id: 'root' })).to.eql(true);
(0, test_1.expect)(query.exists({ id: 'child-3' })).to.eql(true);
(0, test_1.expect)(query.exists(function (e) { return e.id === 'child-3'; })).to.eql(true);
});
it('does not exist', function () {
var query = create(tree);
(0, test_1.expect)(query.exists('404')).to.eql(false);
(0, test_1.expect)(query.exists({ id: '404' })).to.eql(false);
(0, test_1.expect)(query.exists(function (e) { return e.id === '404'; })).to.eql(false);
});
});
});