Add tests that describe the CRDT

This commit is contained in:
haad 2016-03-11 14:12:40 +01:00
parent 6c9f35181c
commit d53b4e80f6

View File

@ -7,6 +7,7 @@ const assert = require('assert');
const ipfsDaemon = require('orbit-common/lib/ipfs-daemon');
const ipfsAPI = require('orbit-common/lib/ipfs-api-promised');
const List = require('../src/list/OrbitList');
const List2 = require('../src/list/List');
const Node = require('../src/list/OrbitNode');
const startIpfs = async (() => {
@ -306,11 +307,9 @@ describe('OrbitList', async(function() {
const lastItem = list1.items[list1.items.length - 1];
assert.equal(list1.items.length, 7);
assert.equal(lastItem.next.length, 2);
assert.equal(lastItem.next.length, 1);
assert.equal(lastItem.next[0].compactId, 'A.3.0');
assert.equal(lastItem.next[0].hash, 'QmRnSuNkgqVFMDwdCNMQ83CR3SAWEkAms3zJyP6Pw9bkx4');
assert.equal(lastItem.next[1].compactId, 'B.0.1');
assert.equal(lastItem.next[1].hash, 'QmVmkwMoz4vnvHQwvFwqaoWCrjonsPpyJ6i436Zajht5ao');
assert.equal(lastItem.next[0].hash, 'QmbHkdCAcDnqBmjWEttEJ96cjhXUHx7b4fR3QyE3YYpczL');
done();
}));
@ -361,11 +360,14 @@ describe('OrbitList', async(function() {
list1.add("helloA3")
assert.equal(list1._currentBatch.length, 2);
assert.equal(list1._currentBatch[1].next.length, 2);
assert.equal(list1._currentBatch[1].next.length, 1);
assert.equal(list1._currentBatch[1].next[0].compactId, 'A.1.0');
assert.equal(list1._currentBatch[1].next[0].hash, 'QmcMUW2F6wqoNtsiV2gXXTvEzXGM9xexN1mgyCLH4LXJ51');
assert.equal(list1._currentBatch[1].next[1].compactId, 'B.0.1');
assert.equal(list1._currentBatch[1].next[1].hash, 'QmVmkwMoz4vnvHQwvFwqaoWCrjonsPpyJ6i436Zajht5ao');
assert.equal(list1._currentBatch[0].next.length, 2);
assert.equal(list1._currentBatch[0].next[0].compactId, 'B.0.1');
assert.equal(list1._currentBatch[0].next[0].hash, 'QmVmkwMoz4vnvHQwvFwqaoWCrjonsPpyJ6i436Zajht5ao');
assert.equal(list1._currentBatch[0].next[1].compactId, 'A.0.0');
assert.equal(list1._currentBatch[0].next[1].hash, 'QmYTUeiK82guFDyB9tJgHZuBpNkUqNyFBuajYrCsaxPXvW');
done();
}));
@ -388,11 +390,9 @@ describe('OrbitList', async(function() {
const lastItem = list1.items[list1.items.length - 1];
assert.equal(list1.items.length, 7);
assert.equal(lastItem.next.length, 2);
assert.equal(lastItem.next.length, 1);
assert.equal(lastItem.next[0].compactId, 'A.2.0');
assert.equal(lastItem.next[0].hash, 'QmTS2p5VTk5WkbtjAVC5ALk6NiYinyAWAmet2EhCBCLKmf');
assert.equal(lastItem.next[1].compactId, 'B.0.1');
assert.equal(lastItem.next[1].hash, 'QmVmkwMoz4vnvHQwvFwqaoWCrjonsPpyJ6i436Zajht5ao');
assert.equal(lastItem.next[0].hash, 'QmbKQRZC9HTNSDVypeAudJbDdBuT3DAYRvyREvm6CupKrQ');
done();
}));
@ -426,13 +426,9 @@ describe('OrbitList', async(function() {
const lastItem = list1.items[list1.items.length - 1];
assert.equal(list1.items.length, 11);
assert.equal(lastItem.next.length, 4);
assert.equal(lastItem.next.length, 2);
assert.equal(lastItem.next[1].compactId, 'A.4.0');
assert.equal(lastItem.next[1].hash, 'QmXXKZDrWAFPUiCdBLJ378xJDBkjdwbVhAqovo6dwChoqx');
assert.equal(lastItem.next[3].compactId, 'B.0.1');
assert.equal(lastItem.next[3].hash, 'QmVmkwMoz4vnvHQwvFwqaoWCrjonsPpyJ6i436Zajht5ao');
assert.equal(lastItem.next[2].compactId, 'C.0.0');
assert.equal(lastItem.next[2].hash, 'QmTPfJRsLKPmxYrd82p16mry6vYTMoMFTH2jSbYVR8KvgD');
assert.equal(lastItem.next[1].hash, 'QmWPqc6XCK1TCVSz9rayHWQjeMFQEKWhk6VD1ZAU8Vhio7');
assert.equal(lastItem.next[0].compactId, 'D.0.2');
assert.equal(lastItem.next[0].hash, 'QmVT3DvmggXq3AdVK7JBfF4Jit3xpbgqP8dFK7TePtit4B');
done();
@ -619,24 +615,7 @@ describe('OrbitList', async(function() {
done();
}));
it('joins itself', async((done) => {
const list1 = new List(ipfs, 'A');
list1.add("helloA1")
list1.add("helloA2")
list1.add("helloA3")
list1.join(list1);
assert.equal(list1.id, 'A');
assert.equal(list1.seq, 1);
assert.equal(list1.ver, 0);
assert.equal(list1.items.length, 3);
assert.equal(list1.items[0].ver, 0);
assert.equal(list1.items[1].ver, 1);
assert.equal(list1.items[2].ver, 2);
done();
}));
it('fetches items from history', async((done) => {
it('fetches items from history on join', async((done) => {
const list1 = new List(ipfs, 'A');
const list2 = new List(ipfs, 'AAA');
@ -707,10 +686,55 @@ describe('OrbitList', async(function() {
});
describe('_findHeads', () => {
it('TODO', (done) => {
describe('findHeads', () => {
it('finds the next head', async((done) => {
const list1 = new List(ipfs, 'A');
const list2 = new List(ipfs, 'B');
const list3 = new List(ipfs, 'C');
list1.add("helloA1")
list1.add("helloA2")
list2.add("helloB1")
list2.add("helloB2")
list1.join(list2);
list1.add("helloA3")
list1.add("helloA4")
list3.add("helloC1")
list3.add("helloC2")
list2.join(list3);
list2.add("helloB3")
list1.join(list2);
list1.add("helloA5")
list1.add("helloA6")
const heads = List2.findHeads(list1.items)
assert.equal(heads.length, 1);
assert.equal(heads[0].compactId, 'A.2.1');
done();
});
}));
it('finds the next heads', async((done) => {
const list1 = new List(ipfs, 'A');
const list2 = new List(ipfs, 'B');
const list3 = new List(ipfs, 'C');
list1.add("helloA1")
list1.add("helloA2")
list2.add("helloB1")
list2.add("helloB2")
list1.join(list2);
list1.add("helloA3")
list1.add("helloA4")
list3.add("helloC1")
list3.add("helloC2")
list2.join(list3);
list2.add("helloB3")
list1.join(list2);
const heads = List2.findHeads(list1.items)
assert.equal(heads.length, 2);
assert.equal(heads[0].compactId, 'B.1.0');
assert.equal(heads[1].compactId, 'A.1.1');
done();
}));
});
describe('_isReferencedInChain', () => {
@ -719,4 +743,102 @@ describe('OrbitList', async(function() {
});
});
describe('is a CRDT', () => {
it('join is associative', async((done) => {
let list1 = new List(ipfs, 'A');
let list2 = new List(ipfs, 'B');
let list3 = new List(ipfs, 'C');
list1.add("helloA1")
list1.add("helloA2")
list2.add("helloB1")
list2.add("helloB2")
list3.add("helloC1")
list3.add("helloC2")
// a + (b + c)
list2.join(list3);
list1.join(list2);
const res1 = list1.items.map((e) => e.compactId).join(", ");
list1 = new List(ipfs, 'A');
list2 = new List(ipfs, 'B');
list3 = new List(ipfs, 'C');
list1.add("helloA1")
list1.add("helloA2")
list2.add("helloB1")
list2.add("helloB2")
list3.add("helloC1")
list3.add("helloC2")
// (a + b) + c
list1.join(list2);
list1.join(list3);
const res2 = list1.items.map((e) => e.compactId).join(", ");
// associativity: a + (b + c) == (a + b) + c
assert.equal(res1, res2);
done();
}));
it('join is commutative', async((done) => {
let list1 = new List(ipfs, 'A');
let list2 = new List(ipfs, 'B');
list1.add("helloA1")
list1.add("helloA2")
list2.join(list1);
list2.add("helloB1")
list2.add("helloB2")
// b + a
list2.join(list1);
const res1 = list2.items.map((e) => e.compactId).join(", ");
list1 = new List(ipfs, 'A');
list2 = new List(ipfs, 'B');
list1.add("helloA1")
list1.add("helloA2")
list2.join(list1);
list2.add("helloB1")
list2.add("helloB2")
// a + b
list1.join(list2);
const res2 = list1.items.map((e) => e.compactId).join(", ");
// commutativity: a + (b + c) == (a + b) + c
assert.equal(res1, res2);
done();
}));
it('join is idempotent', async((done) => {
const list1 = new List(ipfs, 'A');
list1.add("helloA1")
list1.add("helloA2")
list1.add("helloA3")
const list2 = new List(ipfs, 'A');
list2.add("helloA1")
list2.add("helloA2")
list2.add("helloA3")
// idempotence: a + a = a
list1.join(list2);
assert.equal(list1.id, 'A');
assert.equal(list1.seq, 1);
assert.equal(list1.ver, 0);
assert.equal(list1.items.length, 3);
assert.equal(list1.items[0].ver, 0);
assert.equal(list1.items[1].ver, 1);
assert.equal(list1.items[2].ver, 2);
done();
}));
});
}));