UNPKG

graph-crdt

Version:
427 lines (302 loc) 13.8 kB
'use strict'; var _toConsumableArray2 = require('babel-runtime/helpers/toConsumableArray'); var _toConsumableArray3 = _interopRequireDefault(_toConsumableArray2); var _slicedToArray2 = require('babel-runtime/helpers/slicedToArray'); var _slicedToArray3 = _interopRequireDefault(_slicedToArray2); var _stringify = require('babel-runtime/core-js/json/stringify'); var _stringify2 = _interopRequireDefault(_stringify); var _defineProperty2 = require('babel-runtime/helpers/defineProperty'); var _defineProperty3 = _interopRequireDefault(_defineProperty2); var _expect = require('expect'); var _expect2 = _interopRequireDefault(_expect); var _Graph = require('../Graph'); var _Graph2 = _interopRequireDefault(_Graph); var _Node = require('../Node'); var _Node2 = _interopRequireDefault(_Node); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } describe('Graph static method', function () { describe('source()', function () { it('uses the input as it\'s data source', function () { var node = _Node2.default.create({ uid: 'member' }); var graph = _Graph2.default.create(); node.merge({ data: true }); graph.merge((0, _defineProperty3.default)({}, node, node)); var copy = _Graph2.default.source(graph.toJSON()); (0, _expect2.default)(copy.value('member').value('data')).toBe(true); }); it('sources nested POJOs into nodes', function () { var node = _Node2.default.create(); node.merge({ data: true }); var copy = JSON.parse((0, _stringify2.default)(node)); var graph = _Graph2.default.source({ // "copy" is a plain object. 'placeholder': copy }); var _map = [].concat((0, _toConsumableArray3.default)(graph)).map(function (_ref) { var _ref2 = (0, _slicedToArray3.default)(_ref, 1), key = _ref2[0]; return key; }), _map2 = (0, _slicedToArray3.default)(_map, 1), key = _map2[0]; (0, _expect2.default)(graph.value(key)).toBeA(_Node2.default); }); }); }); /* eslint-env mocha */ describe('A graph', function () { var graph = void 0; beforeEach(function () { graph = new _Graph2.default(); }); it('is initialized empty', function () { var keys = [].concat((0, _toConsumableArray3.default)(graph)).map(function (_ref3) { var _ref4 = (0, _slicedToArray3.default)(_ref3, 1), key = _ref4[0]; return key; }); (0, _expect2.default)(keys.length).toBe(0); }); it('returns the nodes when `toJSON` is called', function () { var node = _Node2.default.create({ uid: 'unique id' }); node.merge({ data: 'intact' }); graph.merge((0, _defineProperty3.default)({}, node, node)); var string = (0, _stringify2.default)(graph); (0, _expect2.default)(string).toContain('unique id'); (0, _expect2.default)(string).toContain('intact'); }); describe('iterator()', function () { it('lists all the node indices', function () { var _graph$merge3; var first = _Node2.default.create({ uid: 'first' }); var second = _Node2.default.create({ uid: 'second' }); graph.merge((_graph$merge3 = {}, (0, _defineProperty3.default)(_graph$merge3, first, first), (0, _defineProperty3.default)(_graph$merge3, second, second), _graph$merge3)); var entries = [].concat((0, _toConsumableArray3.default)(graph)); (0, _expect2.default)(entries).toEqual([['first', first], ['second', second]]); }); }); describe('read()', function () { var node = void 0; beforeEach(function () { node = _Node2.default.create({ uid: 'dave' }); graph.merge((0, _defineProperty3.default)({}, node, node)); }); it('returns existing nodes', function () { var result = graph.value(node.toString()); (0, _expect2.default)(result.meta()).toContain({ uid: String(node) }); }); it('returns null for non-existent nodes', function () { var result = graph.value('potato'); (0, _expect2.default)(result).toBe(null); }); }); describe('merge()', function () { var node1 = void 0, node2 = void 0, subgraph = void 0; beforeEach(function () { var _Graph$source; node1 = _Node2.default.create(); node2 = _Node2.default.create(); subgraph = _Graph2.default.source((_Graph$source = {}, (0, _defineProperty3.default)(_Graph$source, node1, node1), (0, _defineProperty3.default)(_Graph$source, node2, node2), _Graph$source)); }); it('ensures the subgraph is a Graph instance', function () { var _node1$meta = node1.meta(), uid = _node1$meta.uid; node1.merge({ value: 'preserved' }); graph.merge((0, _defineProperty3.default)({}, uid, node1)); var result = graph.value(uid); (0, _expect2.default)(result.snapshot()).toEqual(node1.snapshot()); }); it('adds all the items in the subgraph', function () { graph.merge(subgraph); var keys = [].concat((0, _toConsumableArray3.default)(graph)).map(function (_ref5) { var _ref6 = (0, _slicedToArray3.default)(_ref5, 1), key = _ref6[0]; return key; }); (0, _expect2.default)(keys).toContain(node1.toString()); (0, _expect2.default)(keys).toContain(node2.toString()); }); it('assumes sub-objects are already formatted', function () { node1.merge({ data: 'preserved' }); graph.merge((0, _defineProperty3.default)({}, node1, node1.toJSON())); var result = graph.value(node1.toString()); (0, _expect2.default)(result.value('data')).toBe('preserved'); }); it('adds node copies, not originals', function () { var _node1$meta2 = node1.meta(), uid = _node1$meta2.uid; node1.merge({ isNode1: true }); graph.merge((0, _defineProperty3.default)({}, node1, node1)); var copied = graph.value(uid); (0, _expect2.default)(copied.snapshot()).toEqual({ isNode1: true }); (0, _expect2.default)(copied).toNotBe(node1); }); it('returns the update delta', function () { var _graph$merge8 = graph.merge((0, _defineProperty3.default)({}, node2, node2)), update = _graph$merge8.update; (0, _expect2.default)([].concat((0, _toConsumableArray3.default)(update))).toEqual([[String(node2), node2]]); }); it('emits an `update` delta graph on change', function () { var spy = (0, _expect.createSpy)(); graph.on('update', spy); var _graph$merge10 = graph.merge((0, _defineProperty3.default)({}, node1, node1)), update = _graph$merge10.update; (0, _expect2.default)(spy).toHaveBeenCalledWith(update); }); it('returns the history delta', function () { var data = new _Node2.default({ uid: 'existing' }); var update = new _Node2.default({ uid: 'existing' }); data.merge({ old: true }); data.meta('old').state = 1; update.merge({ old: false }); update.meta('old').state = 2; graph.merge((0, _defineProperty3.default)({}, data, data)); var _graph$merge13 = graph.merge((0, _defineProperty3.default)({}, update, update)), history = _graph$merge13.history; var node = history.value('existing'); (0, _expect2.default)(node).toBeA(_Node2.default); (0, _expect2.default)(node.snapshot()).toEqual({ old: true }); }); it('emits a `history` graph delta', function () { var spy = (0, _expect.createSpy)(); graph.on('history', spy); var node = new _Node2.default({ uid: 'node' }); var update = new _Node2.default({ uid: 'node' }); graph.merge((0, _defineProperty3.default)({}, node, node)); var _graph$merge16 = graph.merge((0, _defineProperty3.default)({}, update, update)), history = _graph$merge16.history; (0, _expect2.default)(spy).toHaveBeenCalledWith(history); }); it('uses Graph#new to create deltas', function () { var spy = (0, _expect.spyOn)(graph, 'new').andCall(function () { var graph = new _Graph2.default(); graph.viaNew = true; return graph; }); var _graph$merge18 = graph.merge({}), update = _graph$merge18.update, history = _graph$merge18.history; (0, _expect2.default)(update).toContain({ viaNew: true }); (0, _expect2.default)(history).toContain({ viaNew: true }); spy.restore(); }); }); describe('new()', function () { var node = void 0; beforeEach(function () { node = new _Node2.default(); }); it('returns a new graph', function () { graph.merge((0, _defineProperty3.default)({}, node, node)); var copy = graph.new(); (0, _expect2.default)(copy).toBeA(_Graph2.default); // Must be a copy. (0, _expect2.default)(copy).toNotBe(graph); }); }); describe('rebase()', function () { var target = void 0; beforeEach(function () { target = new _Graph2.default(); }); it('returns a graph', function () { var result = graph.rebase(target); (0, _expect2.default)(result).toBeA(_Graph2.default); (0, _expect2.default)(result).toNotBe(graph); (0, _expect2.default)(result).toNotBe(target); }); it('contains all the state of the target', function () { var node = _Node2.default.from({ existing: true }); target.merge((0, _defineProperty3.default)({}, node, node)); var result = graph.rebase(target); (0, _expect2.default)([].concat((0, _toConsumableArray3.default)(result))).toEqual([].concat((0, _toConsumableArray3.default)(target))); }); it('contains all the graph state', function () { var node = _Node2.default.from({ existing: true }); graph.merge((0, _defineProperty3.default)({}, node, node)); var result = graph.rebase(target); (0, _expect2.default)([].concat((0, _toConsumableArray3.default)(result))).toEqual([].concat((0, _toConsumableArray3.default)(graph))); }); it('rebases every node', function () { var node = _Node2.default.from({ existing: true }); graph.merge((0, _defineProperty3.default)({}, node, node)); target.merge((0, _defineProperty3.default)({}, node, node)); var spy = (0, _expect.spyOn)(graph.value(node), 'rebase').andCallThrough(); graph.rebase(target); (0, _expect2.default)(spy).toHaveBeenCalled(); }); it('uses the rebased node in the new graph', function () { var node = new _Node2.default(); var current = node.new(); var old = node.new(); old.merge({ old: true }); current.merge({ old: false }); graph.merge((0, _defineProperty3.default)({}, node, current)); target.merge((0, _defineProperty3.default)({}, node, old)); var result = graph.rebase(target).value(node.meta().uid); (0, _expect2.default)(result.value('old')).toBe(false); (0, _expect2.default)(result.state('old')).toBe(2); }); }); describe('overlap()', function () { var target = void 0; beforeEach(function () { target = new _Graph2.default(); }); it('returns a new graph', function () { var result = graph.overlap(target); (0, _expect2.default)(result).toBeA(_Graph2.default); (0, _expect2.default)(result).toNotBe(graph); (0, _expect2.default)(result).toNotBe(target); }); it('contains no nodes if the target is empty', function () { var node = new _Node2.default(); graph.merge((0, _defineProperty3.default)({}, node, node)); var result = graph.overlap(target); (0, _expect2.default)([].concat((0, _toConsumableArray3.default)(result))).toEqual([]); }); it('contains no nodes if the source is empty', function () { var node = new _Node2.default(); target.merge((0, _defineProperty3.default)({}, node, node)); var result = graph.overlap(target); (0, _expect2.default)([].concat((0, _toConsumableArray3.default)(result))).toEqual([]); }); it('contains nodes shared by both graphs', function () { var node1 = new _Node2.default(); var node2 = new _Node2.default({ uid: String(node1) }); graph.merge((0, _defineProperty3.default)({}, node1, node1)); target.merge((0, _defineProperty3.default)({}, node2, node2)); var result = graph.overlap(target); (0, _expect2.default)([].concat((0, _toConsumableArray3.default)(result))).toEqual([].concat((0, _toConsumableArray3.default)(graph))); }); it('only contains overlapping node fields', function () { var node1 = new _Node2.default({ uid: 'tweets' }); var node2 = new _Node2.default({ uid: 'tweets' }); node1.merge({ node1: true, shared: true }); node2.merge({ node2: true, shared: true }); graph.merge((0, _defineProperty3.default)({}, node1, node1)); target.merge((0, _defineProperty3.default)({}, node2, node2)); var result = graph.overlap(target); var _node1$meta3 = node1.meta(), uid = _node1$meta3.uid; (0, _expect2.default)([].concat((0, _toConsumableArray3.default)(result.value(uid)))).toEqual([['shared', true]]); }); it('uses the values from the source graph', function () { var node1 = new _Node2.default({ uid: 'node' }); var node2 = new _Node2.default({ uid: 'node' }); node1.merge({ shared: 'source' }); node2.merge({ shared: 'target' }); graph.merge((0, _defineProperty3.default)({}, node1, node1)); target.merge((0, _defineProperty3.default)({}, node2, node2)); var result = graph.overlap(target); var _node1$meta4 = node1.meta(), uid = _node1$meta4.uid; (0, _expect2.default)(result.value(uid).value('shared')).toBe('source'); }); }); });