Comparing version 1.4.1 to 1.4.2
{ | ||
"name": "ipfs-log", | ||
"version": "1.4.1", | ||
"version": "1.4.2", | ||
"description": "Append-only log for IPFS", | ||
@@ -23,7 +23,7 @@ "main": "src/log.js", | ||
"idb-plus-blob-store": "^1.1.2", | ||
"ipfs": "^0.5.0", | ||
"ipfs-api": "^4.0.2", | ||
"ipfsd-ctl": "^0.13.0", | ||
"ipfs": "^0.6.1", | ||
"ipfs-api": "^4.1.0", | ||
"ipfsd-ctl": "^0.14.0", | ||
"json-loader": "^0.5.4", | ||
"libp2p-ipfs-browser": "^0.2.0", | ||
"libp2p-ipfs-browser": "^0.4.0", | ||
"logplease": "^1.2.6", | ||
@@ -30,0 +30,0 @@ "mocha": "^2.4.5", |
@@ -8,240 +8,263 @@ 'use strict'; | ||
const Entry = require('../src/entry'); | ||
// const ipfsd = require('ipfsd-ctl'); | ||
const IPFS = require('ipfs') | ||
const ipfsd = require('ipfsd-ctl'); | ||
let ipfs; | ||
let ipfs, ipfsDaemon; | ||
const IpfsApis = [{ | ||
// js-ipfs | ||
start: () => { | ||
return new Promise((resolve, reject) => { | ||
const IPFS = require('ipfs') | ||
const ipfs = new IPFS(); | ||
resolve(ipfs); | ||
// ipfs.goOnline((err) => { | ||
// if(err) | ||
// reject(err); | ||
// else | ||
// resolve(ipfs); | ||
// }); | ||
}); | ||
}, | ||
stop: () => Promise.resolve() | ||
// stop: () => new Promise((resolve, reject) => ipfs.goOffline(resolve)) | ||
}, { | ||
// js-ipfs-api via local daemon | ||
start: () => { | ||
return new Promise((resolve, reject) => { | ||
ipfsd.disposableApi((err, ipfs) => { | ||
if(err) console.error(err); | ||
resolve(ipfs); | ||
}); | ||
// ipfsd.local((err, node) => { | ||
// if(err) reject(err); | ||
// ipfsDaemon = node; | ||
// ipfsDaemon.startDaemon((err, ipfs) => { | ||
// if(err) reject(err); | ||
// resolve(ipfs); | ||
// }); | ||
// }); | ||
}); | ||
}, | ||
stop: () => Promise.resolve() | ||
// stop: () => new Promise((resolve, reject) => ipfsDaemon.stopDaemon(resolve)) | ||
}]; | ||
const startIpfs = () => { | ||
return new Promise((resolve, reject) => { | ||
// Use disposable ipfs api with a local daemon | ||
// ipfsd.disposableApi((err, ipfs) => { | ||
// if(err) console.error(err); | ||
// resolve(ipfs); | ||
// }); | ||
// Use a local running daemon | ||
// ipfsd.local((err, node) => { | ||
// if(err) reject(err); | ||
// node.startDaemon((err, ipfs) => { | ||
// if(err) reject(err); | ||
// resolve(ipfs); | ||
// }); | ||
// }); | ||
// Use js-ipfs daemon | ||
const ipfs = new IPFS(); | ||
ipfs.goOnline(() => { | ||
resolve(ipfs) | ||
}) | ||
}); | ||
}; | ||
IpfsApis.forEach(function(ipfsApi) { | ||
describe('Entry', function() { | ||
this.timeout(20000); | ||
before(async((done) => { | ||
try { | ||
// ipfs = await(startIpfs()); | ||
ipfs = new IPFS(); | ||
} catch(e) { | ||
console.log(e); | ||
assert.equals(e, null); | ||
} | ||
this.timeout(2000); | ||
done(); | ||
})); | ||
describe('create', () => { | ||
it('creates a an empty entry', async((done) => { | ||
const expectedHash = 'QmfAouPZ2Cu3Cjbjm63RVeWJt6L9QjTSyFLe9SK5dWXN1j'; | ||
const entry = await(Entry.create(ipfs)); | ||
assert.equal(entry.payload, null); | ||
assert.equal(entry.next.length, 0); | ||
assert.equal(entry.hash, expectedHash); | ||
describe('Entry', function() { | ||
this.timeout(40000); | ||
before(async((done) => { | ||
try { | ||
ipfs = await(ipfsApi.start()); | ||
} catch(e) { | ||
console.log(e); | ||
assert.equal(e, null); | ||
} | ||
this.timeout(2000); | ||
done(); | ||
})); | ||
it('creates a entry with payload', async((done) => { | ||
const expectedHash = 'QmP2wHv43QtH3aCj4pUXeoVmkdtqNBVtx5bfYyNSH6LmXG'; | ||
const payload = 'hello world'; | ||
const entry = await(Entry.create(ipfs, payload)); | ||
assert.equal(entry.payload, payload); | ||
assert.equal(entry.next.length, 0); | ||
assert.equal(entry.hash, expectedHash); | ||
after(async((done) => { | ||
await(ipfsApi.stop()); | ||
done(); | ||
})); | ||
it('creates a entry with payload and next', async((done) => { | ||
const expectedHash = 'QmW94BLFbGNbaPjgGasX1rV9aYdE2qxnQnUBf9PbLkiBUo'; | ||
const payload1 = 'hello world'; | ||
const payload2 = 'hello again'; | ||
const entry1 = await(Entry.create(ipfs, payload1)); | ||
const entry2 = await(Entry.create(ipfs, payload2, entry1)); | ||
assert.equal(entry2.payload, payload2); | ||
assert.equal(entry2.next.length, 1); | ||
assert.equal(entry2.hash, expectedHash); | ||
done(); | ||
})); | ||
describe('create', () => { | ||
it('creates a an empty entry', async((done) => { | ||
const expectedHash = 'QmfAouPZ2Cu3Cjbjm63RVeWJt6L9QjTSyFLe9SK5dWXN1j'; | ||
// console.log(ipfs) | ||
const entry = await(Entry.create(ipfs)); | ||
assert.equal(entry.payload, null); | ||
assert.equal(entry.next.length, 0); | ||
assert.equal(entry.hash, expectedHash); | ||
done(); | ||
})); | ||
it('`next` parameter can be a string', async((done) => { | ||
const entry1 = await(Entry.create(ipfs, null)); | ||
const entry2 = await(Entry.create(ipfs, null, entry1.hash)); | ||
assert.equal(typeof entry2.next[0] === 'string', true); | ||
done(); | ||
})); | ||
it('creates a entry with payload', async((done) => { | ||
const expectedHash = 'QmP2wHv43QtH3aCj4pUXeoVmkdtqNBVtx5bfYyNSH6LmXG'; | ||
const payload = 'hello world'; | ||
const entry = await(Entry.create(ipfs, payload)); | ||
assert.equal(entry.payload, payload); | ||
assert.equal(entry.next.length, 0); | ||
assert.equal(entry.hash, expectedHash); | ||
done(); | ||
})); | ||
it('`next` parameter can be an instance of Entry', async((done) => { | ||
const entry1 = await(Entry.create(ipfs, null)); | ||
const entry2 = await(Entry.create(ipfs, null, entry1)); | ||
assert.equal(typeof entry2.next[0] === 'string', true); | ||
done(); | ||
})); | ||
it('creates a entry with payload and next', async((done) => { | ||
const expectedHash = 'QmW94BLFbGNbaPjgGasX1rV9aYdE2qxnQnUBf9PbLkiBUo'; | ||
const payload1 = 'hello world'; | ||
const payload2 = 'hello again'; | ||
const entry1 = await(Entry.create(ipfs, payload1)); | ||
const entry2 = await(Entry.create(ipfs, payload2, entry1)); | ||
assert.equal(entry2.payload, payload2); | ||
assert.equal(entry2.next.length, 1); | ||
assert.equal(entry2.hash, expectedHash); | ||
done(); | ||
})); | ||
it('throws an error if ipfs is not defined', async((done) => { | ||
try { | ||
const entry = await(Entry.create()); | ||
} catch(e) { | ||
assert.equal(e.message, 'Entry requires ipfs instance'); | ||
} | ||
done(); | ||
})); | ||
}); | ||
it('`next` parameter can be a string', async((done) => { | ||
const entry1 = await(Entry.create(ipfs, null)); | ||
const entry2 = await(Entry.create(ipfs, null, entry1.hash)); | ||
assert.equal(typeof entry2.next[0] === 'string', true); | ||
done(); | ||
})); | ||
describe('fromIpfsHash', () => { | ||
it('creates a entry from ipfs hash', async((done) => { | ||
const expectedHash = 'QmW94BLFbGNbaPjgGasX1rV9aYdE2qxnQnUBf9PbLkiBUo'; | ||
const payload1 = 'hello world'; | ||
const payload2 = 'hello again'; | ||
const entry1 = await(Entry.create(ipfs, payload1)); | ||
const entry2 = await(Entry.create(ipfs, payload2, entry1)); | ||
const final = await(Entry.fromIpfsHash(ipfs, entry2.hash)); | ||
assert.equal(final.payload, payload2); | ||
assert.equal(final.next.length, 1); | ||
assert.equal(final.next[0], entry1.hash); | ||
assert.equal(final.hash, expectedHash); | ||
done(); | ||
})); | ||
it('`next` parameter can be an instance of Entry', async((done) => { | ||
const entry1 = await(Entry.create(ipfs, null)); | ||
const entry2 = await(Entry.create(ipfs, null, entry1)); | ||
assert.equal(typeof entry2.next[0] === 'string', true); | ||
done(); | ||
})); | ||
it('throws an error if ipfs is not present', async((done) => { | ||
try { | ||
const entry = await(Entry.fromIpfsHash()); | ||
} catch(e) { | ||
assert.equal(e.message, 'Entry requires ipfs instance'); | ||
} | ||
done(); | ||
})); | ||
it('throws an error if ipfs is not defined', async((done) => { | ||
try { | ||
const entry = await(Entry.create()); | ||
} catch(e) { | ||
assert.equal(e.message, 'Entry requires ipfs instance'); | ||
} | ||
done(); | ||
})); | ||
}); | ||
it('throws an error if hash is undefined', async((done) => { | ||
try { | ||
const entry = await(Entry.fromIpfsHash(ipfs)); | ||
} catch(e) { | ||
assert.equal(e.message, 'Invalid hash: undefined'); | ||
} | ||
done(); | ||
})); | ||
}); | ||
describe('fromIpfsHash', () => { | ||
it('creates a entry from ipfs hash', async((done) => { | ||
const expectedHash = 'QmW94BLFbGNbaPjgGasX1rV9aYdE2qxnQnUBf9PbLkiBUo'; | ||
const payload1 = 'hello world'; | ||
const payload2 = 'hello again'; | ||
const entry1 = await(Entry.create(ipfs, payload1)); | ||
const entry2 = await(Entry.create(ipfs, payload2, entry1)); | ||
const final = await(Entry.fromIpfsHash(ipfs, entry2.hash)); | ||
assert.equal(final.payload, payload2); | ||
assert.equal(final.next.length, 1); | ||
assert.equal(final.next[0], entry1.hash); | ||
assert.equal(final.hash, expectedHash); | ||
done(); | ||
})); | ||
describe('hasChild', () => { | ||
it('returns true if entry has a child', async((done) => { | ||
const payload1 = 'hello world'; | ||
const payload2 = 'hello again'; | ||
const entry1 = await(Entry.create(ipfs, payload1)); | ||
const entry2 = await(Entry.create(ipfs, payload2, entry1)); | ||
assert.equal(entry2.hasChild(entry1), true); | ||
done(); | ||
})); | ||
it('throws an error if ipfs is not present', async((done) => { | ||
try { | ||
const entry = await(Entry.fromIpfsHash()); | ||
} catch(e) { | ||
assert.equal(e.message, 'Entry requires ipfs instance'); | ||
} | ||
done(); | ||
})); | ||
it('returns false if entry does not have a child', async((done) => { | ||
const payload1 = 'hello world'; | ||
const payload2 = 'hello again'; | ||
const entry1 = await(Entry.create(ipfs, payload1)); | ||
const entry2 = await(Entry.create(ipfs, payload2)); | ||
const entry3 = await(Entry.create(ipfs, payload2, entry2)); | ||
assert.equal(entry2.hasChild(entry1), false); | ||
assert.equal(entry3.hasChild(entry1), false); | ||
assert.equal(entry3.hasChild(entry2), true); | ||
done(); | ||
})); | ||
}); | ||
it('throws an error if hash is undefined', async((done) => { | ||
try { | ||
const entry = await(Entry.fromIpfsHash(ipfs)); | ||
} catch(e) { | ||
assert.equal(e.message, 'Invalid hash: undefined'); | ||
} | ||
done(); | ||
})); | ||
}); | ||
describe('getIpfsHash', () => { | ||
it('returns an ipfs hash', async((done) => { | ||
const expectedHash = 'QmfAouPZ2Cu3Cjbjm63RVeWJt6L9QjTSyFLe9SK5dWXN1j'; | ||
const entry = await(Entry.create(ipfs)); | ||
const hash = await(Entry.getIpfsHash(ipfs, entry)); | ||
assert.equal(hash, expectedHash); | ||
done(); | ||
})); | ||
}); | ||
describe('hasChild', () => { | ||
it('returns true if entry has a child', async((done) => { | ||
const payload1 = 'hello world'; | ||
const payload2 = 'hello again'; | ||
const entry1 = await(Entry.create(ipfs, payload1)); | ||
const entry2 = await(Entry.create(ipfs, payload2, entry1)); | ||
assert.equal(entry2.hasChild(entry1), true); | ||
done(); | ||
})); | ||
describe('asJson', () => { | ||
it('returns the entry as json with empty values', async((done) => { | ||
const payload = 'hello world'; | ||
const entry = await(Entry.create(ipfs, payload)); | ||
assert.notEqual(entry.asJson, null); | ||
assert.equal(entry.asJson.payload, payload); | ||
assert.equal(entry.asJson.next.length, 0); | ||
done(); | ||
})); | ||
it('returns false if entry does not have a child', async((done) => { | ||
const payload1 = 'hello world'; | ||
const payload2 = 'hello again'; | ||
const entry1 = await(Entry.create(ipfs, payload1)); | ||
const entry2 = await(Entry.create(ipfs, payload2)); | ||
const entry3 = await(Entry.create(ipfs, payload2, entry2)); | ||
assert.equal(entry2.hasChild(entry1), false); | ||
assert.equal(entry3.hasChild(entry1), false); | ||
assert.equal(entry3.hasChild(entry2), true); | ||
done(); | ||
})); | ||
}); | ||
it('returns the entry as json with values', async((done) => { | ||
const payload = 'hello world'; | ||
const entry1 = await(Entry.create(ipfs, payload)); | ||
const entry2 = await(Entry.create(ipfs, payload, entry1)); | ||
assert.equal(typeof entry2.next[0] === 'string', true); | ||
assert.notEqual(entry2.asJson, null); | ||
assert.equal(entry2.asJson.payload, payload); | ||
assert.equal(entry2.asJson.next.length, 1); | ||
assert.equal(entry2.asJson.next[0], entry1.hash); | ||
done(); | ||
})); | ||
describe('getIpfsHash', () => { | ||
it('returns an ipfs hash', async((done) => { | ||
const expectedHash = 'QmfAouPZ2Cu3Cjbjm63RVeWJt6L9QjTSyFLe9SK5dWXN1j'; | ||
const entry = await(Entry.create(ipfs)); | ||
const hash = await(Entry.getIpfsHash(ipfs, entry)); | ||
assert.equal(hash, expectedHash); | ||
done(); | ||
})); | ||
}); | ||
it('returns entry as json with values when next is a hash', async((done) => { | ||
const payload = 'hello world'; | ||
const entry1 = await(Entry.create(ipfs, payload)); | ||
const entry2 = await(Entry.create(ipfs, payload, [entry1.hash])); | ||
assert.equal(typeof entry2.next[0] === 'string', true); | ||
assert.notEqual(entry2.asJson, null); | ||
assert.equal(entry2.asJson.payload, payload); | ||
assert.equal(entry2.asJson.next.length, 1); | ||
assert.equal(entry2.asJson.next[0], entry1.hash); | ||
done(); | ||
})); | ||
}); | ||
describe('asJson', () => { | ||
it('returns the entry as json with empty values', async((done) => { | ||
const payload = 'hello world'; | ||
const entry = await(Entry.create(ipfs, payload)); | ||
assert.notEqual(entry.asJson, null); | ||
assert.equal(entry.asJson.payload, payload); | ||
assert.equal(entry.asJson.next.length, 0); | ||
done(); | ||
})); | ||
describe('equals', () => { | ||
it('entrys are equal when the payload is the same', async((done) => { | ||
const payload = 'hello world 1'; | ||
const entry1 = await(Entry.create(ipfs, payload)); | ||
const entry2 = await(Entry.create(ipfs, payload)); | ||
assert.equal(Entry.equals(entry1, entry2), true); | ||
done(); | ||
})); | ||
it('returns the entry as json with values', async((done) => { | ||
const payload = 'hello world'; | ||
const entry1 = await(Entry.create(ipfs, payload)); | ||
const entry2 = await(Entry.create(ipfs, payload, entry1)); | ||
assert.equal(typeof entry2.next[0] === 'string', true); | ||
assert.notEqual(entry2.asJson, null); | ||
assert.equal(entry2.asJson.payload, payload); | ||
assert.equal(entry2.asJson.next.length, 1); | ||
assert.equal(entry2.asJson.next[0], entry1.hash); | ||
done(); | ||
})); | ||
it('entrys are not equal when the payload is different', async((done) => { | ||
const payload1 = 'hello world 1'; | ||
const payload2 = 'hello world 2'; | ||
const entry1 = await(Entry.create(ipfs, payload1)); | ||
const entry2 = await(Entry.create(ipfs, payload2)); | ||
assert.equal(Entry.equals(entry1, entry2), false); | ||
done(); | ||
})); | ||
it('returns entry as json with values when next is a hash', async((done) => { | ||
const payload = 'hello world'; | ||
const entry1 = await(Entry.create(ipfs, payload)); | ||
const entry2 = await(Entry.create(ipfs, payload, [entry1.hash])); | ||
assert.equal(typeof entry2.next[0] === 'string', true); | ||
assert.notEqual(entry2.asJson, null); | ||
assert.equal(entry2.asJson.payload, payload); | ||
assert.equal(entry2.asJson.next.length, 1); | ||
assert.equal(entry2.asJson.next[0], entry1.hash); | ||
done(); | ||
})); | ||
}); | ||
it('entrys are equal when next references and payloads are the same', async((done) => { | ||
const payload = 'hello world 1'; | ||
const entry1 = await(Entry.create(ipfs, payload)); | ||
const entry2 = await(Entry.create(ipfs, null, entry1)); | ||
const entry3 = await(Entry.create(ipfs, null, entry1)); | ||
assert.equal(Entry.equals(entry2, entry3), true); | ||
done(); | ||
})); | ||
describe('equals', () => { | ||
it('entrys are equal when the payload is the same', async((done) => { | ||
const payload = 'hello world 1'; | ||
const entry1 = await(Entry.create(ipfs, payload)); | ||
const entry2 = await(Entry.create(ipfs, payload)); | ||
assert.equal(Entry.equals(entry1, entry2), true); | ||
done(); | ||
})); | ||
it('entrys are not equal when next references are not the same', async((done) => { | ||
const payload1 = 'hello world 1'; | ||
const payload2 = 'hello world 2'; | ||
const entry1 = await(Entry.create(ipfs, payload1)); | ||
const entry2 = await(Entry.create(ipfs, payload2)); | ||
const entry3 = await(Entry.create(ipfs, null, entry1)); | ||
const entry4 = await(Entry.create(ipfs, null, entry2)); | ||
assert.equal(Entry.equals(entry3, entry4), false); | ||
done(); | ||
})); | ||
it('entrys are not equal when the payload is different', async((done) => { | ||
const payload1 = 'hello world 1'; | ||
const payload2 = 'hello world 2'; | ||
const entry1 = await(Entry.create(ipfs, payload1)); | ||
const entry2 = await(Entry.create(ipfs, payload2)); | ||
assert.equal(Entry.equals(entry1, entry2), false); | ||
done(); | ||
})); | ||
it('entrys are equal when next references and payloads are the same', async((done) => { | ||
const payload = 'hello world 1'; | ||
const entry1 = await(Entry.create(ipfs, payload)); | ||
const entry2 = await(Entry.create(ipfs, null, entry1)); | ||
const entry3 = await(Entry.create(ipfs, null, entry1)); | ||
assert.equal(Entry.equals(entry2, entry3), true); | ||
done(); | ||
})); | ||
it('entrys are not equal when next references are not the same', async((done) => { | ||
const payload1 = 'hello world 1'; | ||
const payload2 = 'hello world 2'; | ||
const entry1 = await(Entry.create(ipfs, payload1)); | ||
const entry2 = await(Entry.create(ipfs, payload2)); | ||
const entry3 = await(Entry.create(ipfs, null, entry1)); | ||
const entry4 = await(Entry.create(ipfs, null, entry2)); | ||
assert.equal(Entry.equals(entry3, entry4), false); | ||
done(); | ||
})); | ||
}); | ||
}); | ||
}); |
1331
test/log.spec.js
@@ -9,98 +9,87 @@ 'use strict'; | ||
const Entry = require('../src/entry'); | ||
// const ipfsd = require('ipfsd-ctl'); | ||
const IPFS = require('ipfs') | ||
const ipfsd = require('ipfsd-ctl'); | ||
let ipfs, entry; | ||
let ipfs, ipfsDaemon; | ||
const IpfsApis = [{ | ||
// js-ipfs | ||
start: () => { | ||
return new Promise((resolve, reject) => { | ||
const IPFS = require('ipfs') | ||
const ipfs = new IPFS(); | ||
// ipfs.goOnline(() => resolve(ipfs)); | ||
resolve(ipfs); | ||
}); | ||
}, | ||
stop: () => Promise.resolve() | ||
// stop: () => new Promise((resolve, reject) => ipfs.goOffline(resolve)) | ||
}, { | ||
// js-ipfs-api via local daemon | ||
start: () => { | ||
return new Promise((resolve, reject) => { | ||
ipfsd.disposableApi((err, ipfs) => { | ||
if(err) console.error(err); | ||
resolve(ipfs); | ||
}); | ||
// ipfsd.local((err, node) => { | ||
// if(err) reject(err); | ||
// ipfsDaemon = node; | ||
// ipfsDaemon.startDaemon((err, ipfs) => { | ||
// if(err) reject(err); | ||
// resolve(ipfs); | ||
// }); | ||
// }); | ||
}); | ||
}, | ||
stop: () => Promise.resolve() | ||
// stop: () => new Promise((resolve, reject) => ipfsDaemon.stopDaemon(resolve)) | ||
}]; | ||
const startIpfs = () => { | ||
return new Promise((resolve, reject) => { | ||
// Use disposable ipfs api with a local daemon | ||
// ipfsd.disposableApi((err, ipfs) => { | ||
// if(err) console.error(err); | ||
// resolve(ipfs); | ||
// }); | ||
// Use a local running daemon | ||
// ipfsd.local((err, node) => { | ||
// if(err) reject(err); | ||
// node.startDaemon((err, ipfs) => { | ||
// if(err) reject(err); | ||
// resolve(ipfs); | ||
// }); | ||
// }); | ||
// Use js-ipfs daemon | ||
const ipfs = new IPFS(); | ||
ipfs.goOnline(() => { | ||
resolve(ipfs) | ||
}) | ||
}); | ||
}; | ||
IpfsApis.forEach(function(ipfsApi) { | ||
describe('Log', async(function() { | ||
// this.timeout(20000); | ||
before(async((done) => { | ||
try { | ||
// ipfs = await(startIpfs()); | ||
ipfs = new IPFS(); | ||
} catch(e) { | ||
console.log(e); | ||
assert.equal(e, null); | ||
} | ||
this.timeout(2000); | ||
done(); | ||
})); | ||
describe('create', async(() => { | ||
it('creates an empty log', async((done) => { | ||
const log = new Log(ipfs, 'A'); | ||
assert.equal(log.id, 'A'); | ||
assert.equal(log._items instanceof Array, true); | ||
assert.equal(log._items.length, 0); | ||
assert.equal(log._currentBatch instanceof Array, true); | ||
assert.equal(log._currentBatch.length, 0); | ||
assert.equal(log._ipfs, ipfs); | ||
assert.equal(log.hash, null); | ||
done(); | ||
})); | ||
it('throws an error if ipfs is not defined', async((done) => { | ||
describe('Log', function() { | ||
this.timeout(40000); | ||
before(async((done) => { | ||
try { | ||
const log = new Log(); | ||
ipfs = await(ipfsApi.start()); | ||
} catch(e) { | ||
assert.equal(e.message, 'Ipfs instance not defined'); | ||
console.log(e); | ||
assert.equal(e, null); | ||
} | ||
this.timeout(2000); | ||
done(); | ||
})); | ||
it('throws an error if id is not defined', async((done) => { | ||
try { | ||
const log = new Log(ipfs); | ||
} catch(e) { | ||
assert.equal(e.message, 'id is not defined'); | ||
} | ||
after(async((done) => { | ||
await(ipfsApi.stop()); | ||
done(); | ||
})); | ||
})); | ||
describe('serialize', async(() => { | ||
let log; | ||
const expectedData = { | ||
id: "A", | ||
items: [ | ||
'QmRMUN4WJdpYydRLpbipaNoLQNXiw9ifRpPht5APaLFqrR', | ||
'Qmcpgub1qRG5XHed1qNciwb74uasUhQVEhP35oaZZ7UWbi', | ||
'QmQM4Xg6EGGGEKRYu3jX3cpTcXK53XvSgQpxZd2qGY1L2V' | ||
] | ||
}; | ||
describe('create', async(() => { | ||
it('creates an empty log', async((done) => { | ||
const log = new Log(ipfs, 'A'); | ||
assert.equal(log.id, 'A'); | ||
assert.equal(log._items instanceof Array, true); | ||
assert.equal(log._items.length, 0); | ||
assert.equal(log._currentBatch instanceof Array, true); | ||
assert.equal(log._currentBatch.length, 0); | ||
assert.equal(log._ipfs, ipfs); | ||
assert.equal(log.hash, null); | ||
done(); | ||
})); | ||
beforeEach(async((done) => { | ||
log = new Log(ipfs, 'A'); | ||
await(log.add("one")); | ||
await(log.add("two")); | ||
await(log.add("three")); | ||
done(); | ||
})); | ||
it('throws an error if ipfs is not defined', async((done) => { | ||
try { | ||
const log = new Log(); | ||
} catch(e) { | ||
assert.equal(e.message, 'Ipfs instance not defined'); | ||
} | ||
done(); | ||
})); | ||
describe('snapshot', async(() => { | ||
it('returns the current batch of items', async((done) => { | ||
assert.equal(JSON.stringify(log.snapshot), JSON.stringify(expectedData)); | ||
it('throws an error if id is not defined', async((done) => { | ||
try { | ||
const log = new Log(ipfs); | ||
} catch(e) { | ||
assert.equal(e.message, 'id is not defined'); | ||
} | ||
done(); | ||
@@ -110,683 +99,711 @@ })); | ||
describe('fromSnapshot', () => { | ||
it('creates a log from a snapshot', async((done) => { | ||
const str = JSON.stringify(log.snapshot, null, 2) | ||
const res = await(Log.fromJson(ipfs, JSON.parse(str))); | ||
assert.equal(res.items.length, 3); | ||
assert.equal(res.items[0].hash, expectedData.items[0]); | ||
assert.equal(res.items[1].hash, expectedData.items[1]); | ||
assert.equal(res.items[2].hash, expectedData.items[2]); | ||
describe('serialize', async(() => { | ||
let log; | ||
const expectedData = { | ||
id: "A", | ||
items: [ | ||
'QmRMUN4WJdpYydRLpbipaNoLQNXiw9ifRpPht5APaLFqrR', | ||
'Qmcpgub1qRG5XHed1qNciwb74uasUhQVEhP35oaZZ7UWbi', | ||
'QmQM4Xg6EGGGEKRYu3jX3cpTcXK53XvSgQpxZd2qGY1L2V' | ||
] | ||
}; | ||
beforeEach(async((done) => { | ||
log = new Log(ipfs, 'A'); | ||
await(log.add("one")); | ||
await(log.add("two")); | ||
await(log.add("three")); | ||
done(); | ||
})); | ||
}); | ||
describe('getIpfsHash', async(() => { | ||
it('returns the log as ipfs hash', async((done) => { | ||
const expectedHash = 'QmaRz4njJX2W8QYwWLa1jhEbYUdJhhqibsBbnRYuWgr1r7'; | ||
const log = new Log(ipfs, 'A'); | ||
const hash = await(Log.getIpfsHash(ipfs, log)); | ||
assert.equal(hash, expectedHash); | ||
done(); | ||
describe('snapshot', async(() => { | ||
it('returns the current batch of items', async((done) => { | ||
assert.equal(JSON.stringify(log.snapshot), JSON.stringify(expectedData)); | ||
done(); | ||
})); | ||
})); | ||
it('log serialized to ipfs contains the correct data', async((done) => { | ||
const expectedData = { id: "A", items: [] }; | ||
// const expectedData = { | ||
// Data: '{"id":"A","items":[]}', | ||
// Links: [], | ||
// "Hash":"QmaRz4njJX2W8QYwWLa1jhEbYUdJhhqibsBbnRYuWgr1r7", | ||
// "Size":23 | ||
// }; | ||
const log = new Log(ipfs, 'A'); | ||
const hash = await(Log.getIpfsHash(ipfs, log)); | ||
const res = await(ipfs.object.get(hash, { enc: 'base58' })); | ||
const result = JSON.parse(res.toJSON().Data); | ||
// assert.equal(JSON.stringify(res.toJSON().Data), JSON.stringify(expectedData)); | ||
assert.equal(result.id, expectedData.id); | ||
assert.equal(result.items.length, expectedData.items.length); | ||
done(); | ||
describe('fromSnapshot', () => { | ||
it('creates a log from a snapshot', async((done) => { | ||
const str = JSON.stringify(log.snapshot, null, 2) | ||
const res = await(Log.fromJson(ipfs, JSON.parse(str))); | ||
assert.equal(res.items.length, 3); | ||
assert.equal(res.items[0].hash, expectedData.items[0]); | ||
assert.equal(res.items[1].hash, expectedData.items[1]); | ||
assert.equal(res.items[2].hash, expectedData.items[2]); | ||
done(); | ||
})); | ||
}); | ||
describe('getIpfsHash', async(() => { | ||
it('returns the log as ipfs hash', async((done) => { | ||
const expectedHash = 'QmaRz4njJX2W8QYwWLa1jhEbYUdJhhqibsBbnRYuWgr1r7'; | ||
const log = new Log(ipfs, 'A'); | ||
const hash = await(Log.getIpfsHash(ipfs, log)); | ||
assert.equal(hash, expectedHash); | ||
done(); | ||
})); | ||
it('log serialized to ipfs contains the correct data', async((done) => { | ||
const expectedData = { id: "A", items: [] }; | ||
// const expectedData = { | ||
// Data: '{"id":"A","items":[]}', | ||
// Links: [], | ||
// "Hash":"QmaRz4njJX2W8QYwWLa1jhEbYUdJhhqibsBbnRYuWgr1r7", | ||
// "Size":23 | ||
// }; | ||
const log = new Log(ipfs, 'A'); | ||
const hash = await(Log.getIpfsHash(ipfs, log)); | ||
const res = await(ipfs.object.get(hash, { enc: 'base58' })); | ||
const result = JSON.parse(res.toJSON().Data); | ||
// assert.equal(JSON.stringify(res.toJSON().Data), JSON.stringify(expectedData)); | ||
assert.equal(result.id, expectedData.id); | ||
assert.equal(result.items.length, expectedData.items.length); | ||
done(); | ||
})); | ||
it('throws an error if ipfs is not defined', async((done) => { | ||
try { | ||
const log = new Log(ipfs, 'A'); | ||
const hash = await(Log.getIpfsHash(null, log)); | ||
} catch(e) { | ||
assert.equal(e.message, 'Ipfs instance not defined'); | ||
} | ||
done(); | ||
})); | ||
})); | ||
it('throws an error if ipfs is not defined', async((done) => { | ||
try { | ||
describe('fromIpfsHash', async(() => { | ||
it('creates an empty log from ipfs hash', async((done) => { | ||
const expectedData = { id: "A", items: [] }; | ||
const log = new Log(ipfs, 'A'); | ||
const hash = await(Log.getIpfsHash(null, log)); | ||
} catch(e) { | ||
assert.equal(e.message, 'Ipfs instance not defined'); | ||
} | ||
done(); | ||
const hash = await(Log.getIpfsHash(ipfs, log)); | ||
const res = await(Log.fromIpfsHash(ipfs, hash)); | ||
assert.equal(JSON.stringify(res.snapshot), JSON.stringify(expectedData)); | ||
done(); | ||
})); | ||
it('creates a log from ipfs hash', async((done) => { | ||
const hash = await(Log.getIpfsHash(ipfs, log)); | ||
const res = await(Log.fromIpfsHash(ipfs, hash)); | ||
assert.equal(res.items.length, 3); | ||
assert.equal(res.items[0].hash, expectedData.items[0]); | ||
assert.equal(res.items[1].hash, expectedData.items[1]); | ||
assert.equal(res.items[2].hash, expectedData.items[2]); | ||
done(); | ||
})); | ||
})); | ||
})); | ||
describe('fromIpfsHash', async(() => { | ||
it('creates an empty log from ipfs hash', async((done) => { | ||
const expectedData = { id: "A", items: [] }; | ||
describe('items', () => { | ||
it('returns all entrys in the log', async((done) => { | ||
const log = new Log(ipfs, 'A'); | ||
const hash = await(Log.getIpfsHash(ipfs, log)); | ||
const res = await(Log.fromIpfsHash(ipfs, hash)); | ||
assert.equal(JSON.stringify(res.snapshot), JSON.stringify(expectedData)); | ||
let items = log.items; | ||
assert.equal(log.items instanceof Array, true); | ||
assert.equal(log.items.length, 0); | ||
await(log.add("hello1")); | ||
await(log.add("hello2")); | ||
await(log.add("hello3")); | ||
assert.equal(log.items instanceof Array, true); | ||
assert.equal(log.items.length, 3); | ||
assert.equal(log.items[0].payload, 'hello1'); | ||
assert.equal(log.items[1].payload, 'hello2'); | ||
assert.equal(log.items[2].payload, 'hello3'); | ||
assert.equal(log._items.length, 0); | ||
assert.equal(log._currentBatch.length, 3); | ||
done(); | ||
})); | ||
it('creates a log from ipfs hash', async((done) => { | ||
const hash = await(Log.getIpfsHash(ipfs, log)); | ||
const res = await(Log.fromIpfsHash(ipfs, hash)); | ||
assert.equal(res.items.length, 3); | ||
assert.equal(res.items[0].hash, expectedData.items[0]); | ||
assert.equal(res.items[1].hash, expectedData.items[1]); | ||
assert.equal(res.items[2].hash, expectedData.items[2]); | ||
it('returns all entrys from current batch and all known entrys', async((done) => { | ||
const log = new Log(ipfs, 'A'); | ||
let items = log.items; | ||
assert.equal(log.items instanceof Array, true); | ||
assert.equal(log.items.length, 0); | ||
await(log.add("hello1")); | ||
await(log.add("hello2")); | ||
log._commit(); | ||
await(log.add("hello3")); | ||
assert.equal(log.items instanceof Array, true); | ||
assert.equal(log.items.length, 3); | ||
assert.equal(log.items[0].payload, 'hello1'); | ||
assert.equal(log.items[1].payload, 'hello2'); | ||
assert.equal(log.items[2].payload, 'hello3'); | ||
assert.equal(log._items.length, 2); | ||
assert.equal(log._currentBatch.length, 1); | ||
done(); | ||
})); | ||
})); | ||
})); | ||
}); | ||
describe('items', () => { | ||
it('returns all entrys in the log', async((done) => { | ||
const log = new Log(ipfs, 'A'); | ||
let items = log.items; | ||
assert.equal(log.items instanceof Array, true); | ||
assert.equal(log.items.length, 0); | ||
await(log.add("hello1")); | ||
await(log.add("hello2")); | ||
await(log.add("hello3")); | ||
assert.equal(log.items instanceof Array, true); | ||
assert.equal(log.items.length, 3); | ||
assert.equal(log.items[0].payload, 'hello1'); | ||
assert.equal(log.items[1].payload, 'hello2'); | ||
assert.equal(log.items[2].payload, 'hello3'); | ||
assert.equal(log._items.length, 0); | ||
assert.equal(log._currentBatch.length, 3); | ||
done(); | ||
})); | ||
describe('add', () => { | ||
it('adds an item to an empty log', async((done) => { | ||
const log = new Log(ipfs, 'A'); | ||
await(log.add("hello1")); | ||
const item = log.items[0]; | ||
assert.equal(log.items.length, 1); | ||
assert.equal(log._currentBatch.length, 1); | ||
assert.equal(log._items.length, 0); | ||
assert.equal(item, log._currentBatch[0]); | ||
assert.equal(item.payload, 'hello1'); | ||
done(); | ||
})); | ||
it('returns all entrys from current batch and all known entrys', async((done) => { | ||
const log = new Log(ipfs, 'A'); | ||
let items = log.items; | ||
assert.equal(log.items instanceof Array, true); | ||
assert.equal(log.items.length, 0); | ||
await(log.add("hello1")); | ||
await(log.add("hello2")); | ||
log._commit(); | ||
await(log.add("hello3")); | ||
it('adds 100 items to a log', async((done) => { | ||
const log = new Log(ipfs, 'A'); | ||
const amount = 100; | ||
assert.equal(log.items instanceof Array, true); | ||
assert.equal(log.items.length, 3); | ||
assert.equal(log.items[0].payload, 'hello1'); | ||
assert.equal(log.items[1].payload, 'hello2'); | ||
assert.equal(log.items[2].payload, 'hello3'); | ||
assert.equal(log._items.length, 2); | ||
assert.equal(log._currentBatch.length, 1); | ||
done(); | ||
})); | ||
}); | ||
for(let i = 1; i <= amount; i ++) { | ||
await(log.add("hello" + i)); | ||
} | ||
describe('add', () => { | ||
it('adds an item to an empty log', async((done) => { | ||
const log = new Log(ipfs, 'A'); | ||
await(log.add("hello1")); | ||
const item = log.items[0]; | ||
assert.equal(log.items.length, 1); | ||
assert.equal(log._currentBatch.length, 1); | ||
assert.equal(log._items.length, 0); | ||
assert.equal(item, log._currentBatch[0]); | ||
assert.equal(item.payload, 'hello1'); | ||
done(); | ||
})); | ||
const last = _.last(log.items); | ||
assert.equal(log.items.length, amount); | ||
assert.equal(last.payload, 'hello' + amount); | ||
assert.notEqual(last.next.length, 0); | ||
it('adds 100 items to a log', async((done) => { | ||
const log = new Log(ipfs, 'A'); | ||
const amount = 100; | ||
done(); | ||
})); | ||
for(let i = 1; i <= amount; i ++) { | ||
await(log.add("hello" + i)); | ||
} | ||
it('commits the log after batch size was reached', async((done) => { | ||
const log = new Log(ipfs, 'A'); | ||
const last = _.last(log.items); | ||
assert.equal(log.items.length, amount); | ||
assert.equal(last.payload, 'hello' + amount); | ||
assert.notEqual(last.next.length, 0); | ||
for(let i = 1; i <= Log.batchSize; i ++) { | ||
await(log.add("hello" + i)); | ||
} | ||
done(); | ||
})); | ||
assert.equal(log.items.length, Log.batchSize); | ||
assert.equal(log._currentBatch.length, Log.batchSize); | ||
assert.equal(log._items.length, 0); | ||
it('commits the log after batch size was reached', async((done) => { | ||
const log = new Log(ipfs, 'A'); | ||
const item = _.last(log.items); | ||
assert.equal(log.items.length, Log.batchSize); | ||
assert.equal(item.payload, 'hello' + Log.batchSize); | ||
assert.notEqual(item.next.length, 0); | ||
for(let i = 1; i <= Log.batchSize; i ++) { | ||
await(log.add("hello" + i)); | ||
} | ||
done(); | ||
})); | ||
}); | ||
assert.equal(log.items.length, Log.batchSize); | ||
assert.equal(log._currentBatch.length, Log.batchSize); | ||
assert.equal(log._items.length, 0); | ||
describe('join', () => { | ||
let log1, log2, log3, log4; | ||
const item = _.last(log.items); | ||
assert.equal(log.items.length, Log.batchSize); | ||
assert.equal(item.payload, 'hello' + Log.batchSize); | ||
assert.notEqual(item.next.length, 0); | ||
beforeEach(async((done) => { | ||
log1 = new Log(ipfs, 'A'); | ||
log2 = new Log(ipfs, 'B'); | ||
log3 = new Log(ipfs, 'C'); | ||
log4 = new Log(ipfs, 'D'); | ||
done(); | ||
})); | ||
done(); | ||
})); | ||
}); | ||
it('joins only unique items', async((done) => { | ||
await(log1.add("helloA1")); | ||
await(log1.add("helloA2")); | ||
await(log2.add("helloB1")); | ||
await(log2.add("helloB2")); | ||
await(log1.join(log2)); | ||
await(log1.join(log2)); | ||
describe('join', () => { | ||
let log1, log2, log3, log4; | ||
assert.equal(log1.items.length, 4); | ||
assert.equal(log1.items[0].hash, 'QmUEH5SEuRZhZ7RETwEX2df2BtTR2xUYZR3qBrhjnxqocb'); | ||
assert.equal(log1.items[1].hash, 'Qma1PaYbyW1rZA4npPnuJzA3ov5Je4N9cvAn2p6Ju1iPQS'); | ||
assert.equal(log1.items[2].hash, 'QmdZwCR96sP61aaTbcLj9DXy9EaiMhTXLRrTxPSXpcZCct'); | ||
assert.equal(log1.items[3].hash, 'QmR3jTmVNQGfq4m6sDk2koFHFkSRMxJqSjrTHU293yyWMv'); | ||
beforeEach(async((done) => { | ||
log1 = new Log(ipfs, 'A'); | ||
log2 = new Log(ipfs, 'B'); | ||
log3 = new Log(ipfs, 'C'); | ||
log4 = new Log(ipfs, 'D'); | ||
done(); | ||
})); | ||
const last = _.last(log1.items); | ||
assert.equal(last.next.length, 1); | ||
assert.equal(last.next[0], 'QmdZwCR96sP61aaTbcLj9DXy9EaiMhTXLRrTxPSXpcZCct'); | ||
done(); | ||
})); | ||
it('joins only unique items', async((done) => { | ||
await(log1.add("helloA1")); | ||
await(log1.add("helloA2")); | ||
await(log2.add("helloB1")); | ||
await(log2.add("helloB2")); | ||
await(log1.join(log2)); | ||
await(log1.join(log2)); | ||
it('joins logs two ways', async((done) => { | ||
await(log1.add("helloA1")); | ||
await(log1.add("helloA2")); | ||
await(log2.add("helloB1")); | ||
await(log2.add("helloB2")); | ||
await(log1.join(log2)); | ||
await(log2.join(log1)); | ||
assert.equal(log1.items.length, 4); | ||
assert.equal(log1.items[0].hash, 'QmUEH5SEuRZhZ7RETwEX2df2BtTR2xUYZR3qBrhjnxqocb'); | ||
assert.equal(log1.items[1].hash, 'Qma1PaYbyW1rZA4npPnuJzA3ov5Je4N9cvAn2p6Ju1iPQS'); | ||
assert.equal(log1.items[2].hash, 'QmdZwCR96sP61aaTbcLj9DXy9EaiMhTXLRrTxPSXpcZCct'); | ||
assert.equal(log1.items[3].hash, 'QmR3jTmVNQGfq4m6sDk2koFHFkSRMxJqSjrTHU293yyWMv'); | ||
const lastItem1 = _.last(log1.items); | ||
assert.equal(log1._currentBatch.length, 0); | ||
assert.equal(log1._items.length, 4); | ||
assert.equal(lastItem1.payload, 'helloB2'); | ||
const last = _.last(log1.items); | ||
assert.equal(last.next.length, 1); | ||
assert.equal(last.next[0], 'QmdZwCR96sP61aaTbcLj9DXy9EaiMhTXLRrTxPSXpcZCct'); | ||
done(); | ||
})); | ||
const lastItem2 = _.last(log2.items); | ||
assert.equal(log2._currentBatch.length, 0); | ||
assert.equal(log2._items.length, 4); | ||
assert.equal(lastItem2.payload, 'helloA2'); | ||
done(); | ||
})); | ||
it('joins logs two ways', async((done) => { | ||
await(log1.add("helloA1")); | ||
await(log1.add("helloA2")); | ||
await(log2.add("helloB1")); | ||
await(log2.add("helloB2")); | ||
await(log1.join(log2)); | ||
await(log2.join(log1)); | ||
it('joins logs twice', async((done) => { | ||
await(log1.add("helloA1")); | ||
await(log2.add("helloB1")); | ||
await(log2.join(log1)); | ||
await(log1.add("helloA2")); | ||
await(log2.add("helloB2")); | ||
await(log2.join(log1)); | ||
const lastItem1 = _.last(log1.items); | ||
assert.equal(log1._currentBatch.length, 0); | ||
assert.equal(log1._items.length, 4); | ||
assert.equal(lastItem1.payload, 'helloB2'); | ||
const secondItem = log2.items[1]; | ||
const lastItem = _.last(log2.items); | ||
const lastItem2 = _.last(log2.items); | ||
assert.equal(log2._currentBatch.length, 0); | ||
assert.equal(log2._items.length, 4); | ||
assert.equal(lastItem2.payload, 'helloA2'); | ||
done(); | ||
})); | ||
assert.equal(log2._currentBatch.length, 0); | ||
assert.equal(log2._items.length, 4); | ||
assert.equal(secondItem.payload, 'helloA1'); | ||
assert.equal(lastItem.payload, 'helloA2'); | ||
done(); | ||
})); | ||
it('joins logs twice', async((done) => { | ||
await(log1.add("helloA1")); | ||
await(log2.add("helloB1")); | ||
await(log2.join(log1)); | ||
await(log1.add("helloA2")); | ||
await(log2.add("helloB2")); | ||
await(log2.join(log1)); | ||
it('joins 4 logs to one', async((done) => { | ||
await(log1.add("helloA1")); | ||
await(log1.add("helloA2")); | ||
await(log2.add("helloB1")); | ||
await(log2.add("helloB2")); | ||
await(log3.add("helloC1")); | ||
await(log3.add("helloC2")); | ||
await(log4.add("helloD1")); | ||
await(log4.add("helloD2")); | ||
await(log1.join(log2)); | ||
await(log1.join(log3)); | ||
await(log1.join(log4)); | ||
const secondItem = log2.items[1]; | ||
const lastItem = _.last(log2.items); | ||
const secondItem = log1.items[1]; | ||
const lastItem = _.last(log1.items); | ||
assert.equal(log2._currentBatch.length, 0); | ||
assert.equal(log2._items.length, 4); | ||
assert.equal(secondItem.payload, 'helloA1'); | ||
assert.equal(lastItem.payload, 'helloA2'); | ||
done(); | ||
})); | ||
assert.equal(log1._currentBatch.length, 0); | ||
assert.equal(log1._items.length, 8); | ||
assert.equal(secondItem.payload, 'helloA2'); | ||
assert.equal(lastItem.payload, 'helloD2'); | ||
done(); | ||
})); | ||
it('joins 4 logs to one', async((done) => { | ||
await(log1.add("helloA1")); | ||
await(log1.add("helloA2")); | ||
await(log2.add("helloB1")); | ||
await(log2.add("helloB2")); | ||
await(log3.add("helloC1")); | ||
await(log3.add("helloC2")); | ||
await(log4.add("helloD1")); | ||
await(log4.add("helloD2")); | ||
await(log1.join(log2)); | ||
await(log1.join(log3)); | ||
await(log1.join(log4)); | ||
it('joins logs from 4 logs', async((done) => { | ||
await(log1.add("helloA1")); | ||
await(log1.join(log2)); | ||
await(log2.add("helloB1")); | ||
await(log2.join(log1)); | ||
await(log1.add("helloA2")); | ||
await(log2.add("helloB2")); | ||
await(log1.join(log3)); | ||
await(log3.join(log1)); | ||
await(log3.add("helloC1")); | ||
await(log4.add("helloD1")); | ||
await(log3.add("helloC2")); | ||
await(log4.add("helloD2")); | ||
await(log1.join(log3)); | ||
await(log1.join(log2)); | ||
await(log4.join(log2)); | ||
await(log4.join(log1)); | ||
await(log4.join(log3)); | ||
await(log4.add("helloD3")); | ||
await(log4.add("helloD4")); | ||
const secondItem = log4.items[1]; | ||
const lastItem1 = _.last(log4._items); | ||
const lastItem2 = _.last(log4.items); | ||
assert.equal(log4._currentBatch.length, 2); | ||
assert.equal(log4._items.length, 8); | ||
assert.equal(secondItem.payload, 'helloD2'); | ||
assert.equal(lastItem1.payload, 'helloC2'); | ||
assert.equal(lastItem2.payload, 'helloD4'); | ||
done(); | ||
})); | ||
const secondItem = log1.items[1]; | ||
const lastItem = _.last(log1.items); | ||
it('fetches items from history on join', async((done) => { | ||
const count = 32; | ||
for(let i = 1; i < count + 1; i ++) { | ||
await(log1.add("first " + i)); | ||
await(log2.add("second " + i)); | ||
} | ||
assert.equal(log1._currentBatch.length, 0); | ||
assert.equal(log1._items.length, 8); | ||
assert.equal(secondItem.payload, 'helloA2'); | ||
assert.equal(lastItem.payload, 'helloD2'); | ||
done(); | ||
})); | ||
const hash1 = await(Log.getIpfsHash(ipfs, log1)); | ||
const hash2 = await(Log.getIpfsHash(ipfs, log2)); | ||
it('joins logs from 4 logs', async((done) => { | ||
await(log1.add("helloA1")); | ||
await(log1.join(log2)); | ||
await(log2.add("helloB1")); | ||
await(log2.join(log1)); | ||
await(log1.add("helloA2")); | ||
await(log2.add("helloB2")); | ||
await(log1.join(log3)); | ||
await(log3.join(log1)); | ||
await(log3.add("helloC1")); | ||
await(log4.add("helloD1")); | ||
await(log3.add("helloC2")); | ||
await(log4.add("helloD2")); | ||
await(log1.join(log3)); | ||
await(log1.join(log2)); | ||
await(log4.join(log2)); | ||
await(log4.join(log1)); | ||
await(log4.join(log3)); | ||
await(log4.add("helloD3")); | ||
await(log4.add("helloD4")); | ||
const secondItem = log4.items[1]; | ||
const lastItem1 = _.last(log4._items); | ||
const lastItem2 = _.last(log4.items); | ||
assert.equal(log4._currentBatch.length, 2); | ||
assert.equal(log4._items.length, 8); | ||
assert.equal(secondItem.payload, 'helloD2'); | ||
assert.equal(lastItem1.payload, 'helloC2'); | ||
assert.equal(lastItem2.payload, 'helloD4'); | ||
done(); | ||
})); | ||
const other1 = await(Log.fromIpfsHash(ipfs, hash1)); | ||
const other2 = await(Log.fromIpfsHash(ipfs, hash2)); | ||
await(log3.join(other1)); | ||
it('fetches items from history on join', async((done) => { | ||
const count = 32; | ||
for(let i = 1; i < count + 1; i ++) { | ||
await(log1.add("first " + i)); | ||
await(log2.add("second " + i)); | ||
} | ||
assert.equal(_.includes(log3.items.map((a) => a.hash), undefined), false); | ||
assert.equal(log3.items.length, count); | ||
assert.equal(log3.items[0].payload, "first 1"); | ||
assert.equal(_.last(log3.items).payload, "first " + count); | ||
const hash1 = await(Log.getIpfsHash(ipfs, log1)); | ||
const hash2 = await(Log.getIpfsHash(ipfs, log2)); | ||
await(log3.join(other2)); | ||
assert.equal(log3.items.length, count * 2); | ||
assert.equal(log3.items[0].payload, "second 1"); | ||
assert.equal(_.last(log3.items).payload, "second " + count); | ||
done(); | ||
})); | ||
const other1 = await(Log.fromIpfsHash(ipfs, hash1)); | ||
const other2 = await(Log.fromIpfsHash(ipfs, hash2)); | ||
await(log3.join(other1)); | ||
it('orders fetched items correctly', async((done) => { | ||
const count = Log.batchSize * 3; | ||
for(let i = 1; i < (count * 2) + 1; i ++) | ||
await(log1.add("first " + i)); | ||
assert.equal(_.includes(log3.items.map((a) => a.hash), undefined), false); | ||
assert.equal(log3.items.length, count); | ||
assert.equal(log3.items[0].payload, "first 1"); | ||
assert.equal(_.last(log3.items).payload, "first " + count); | ||
const hash1 = await(Log.getIpfsHash(ipfs, log1)); | ||
const other1 = await(Log.fromIpfsHash(ipfs, hash1)); | ||
await(log3.join(other1)); | ||
await(log3.join(other2)); | ||
assert.equal(log3.items.length, count * 2); | ||
assert.equal(log3.items[0].payload, "second 1"); | ||
assert.equal(_.last(log3.items).payload, "second " + count); | ||
done(); | ||
})); | ||
assert.equal(log3.items[0].payload, "first 1"); | ||
assert.equal(log3.items[log3.items.length - 1].payload, "first " + count * 2); | ||
assert.equal(log3.items.length, count * 2); | ||
it('orders fetched items correctly', async((done) => { | ||
const count = Log.batchSize * 3; | ||
for(let i = 1; i < (count * 2) + 1; i ++) | ||
await(log1.add("first " + i)); | ||
// Second batch | ||
for(let i = 1; i < count + 1; i ++) | ||
await(log2.add("second " + i)); | ||
const hash1 = await(Log.getIpfsHash(ipfs, log1)); | ||
const other1 = await(Log.fromIpfsHash(ipfs, hash1)); | ||
await(log3.join(other1)); | ||
const hash2 = await(Log.getIpfsHash(ipfs, log2)); | ||
const other2 = await(Log.fromIpfsHash(ipfs, hash2)); | ||
await(log3.join(other2)); | ||
assert.equal(log3.items[0].payload, "first 1"); | ||
assert.equal(log3.items[log3.items.length - 1].payload, "first " + count * 2); | ||
assert.equal(log3.items.length, count * 2); | ||
assert.equal(log3.items.length, count + count * 2); | ||
assert.equal(log3.items[0].payload, "second 1"); | ||
assert.equal(log3.items[1].payload, "second 2"); | ||
assert.equal(_.last(log3.items).payload, "second " + count); | ||
done(); | ||
})); | ||
}); | ||
// Second batch | ||
for(let i = 1; i < count + 1; i ++) | ||
await(log2.add("second " + i)); | ||
describe('_fetchRecursive', () => { | ||
it('returns two items when neither are in the log', async((done) => { | ||
const log1 = new Log(ipfs, 'A'); | ||
const entry1 = await(Entry.create(ipfs, 'one')) | ||
const entry2 = await(Entry.create(ipfs, 'two', entry1)) | ||
const items = await(log1._fetchRecursive(ipfs, entry2.hash, [], 1000, 0)); | ||
assert.equal(items.length, 2); | ||
assert.equal(items[0].hash, 'QmRMUN4WJdpYydRLpbipaNoLQNXiw9ifRpPht5APaLFqrR'); | ||
assert.equal(items[1].hash, 'Qmcpgub1qRG5XHed1qNciwb74uasUhQVEhP35oaZZ7UWbi'); | ||
done(); | ||
})); | ||
const hash2 = await(Log.getIpfsHash(ipfs, log2)); | ||
const other2 = await(Log.fromIpfsHash(ipfs, hash2)); | ||
await(log3.join(other2)); | ||
it('returns three items when none are in the log', async((done) => { | ||
const log1 = new Log(ipfs, 'A'); | ||
const entry1 = await(Entry.create(ipfs, 'one')) | ||
const entry2 = await(Entry.create(ipfs, 'two', entry1)) | ||
const entry3 = await(Entry.create(ipfs, 'three', entry2)) | ||
const items = await(log1._fetchRecursive(ipfs, entry3.hash, [], 1000, 0)); | ||
assert.equal(items.length, 3); | ||
assert.equal(items[0].hash, 'QmRMUN4WJdpYydRLpbipaNoLQNXiw9ifRpPht5APaLFqrR'); | ||
assert.equal(items[1].hash, 'Qmcpgub1qRG5XHed1qNciwb74uasUhQVEhP35oaZZ7UWbi'); | ||
assert.equal(items[2].hash, 'QmQM4Xg6EGGGEKRYu3jX3cpTcXK53XvSgQpxZd2qGY1L2V'); | ||
done(); | ||
})); | ||
assert.equal(log3.items.length, count + count * 2); | ||
assert.equal(log3.items[0].payload, "second 1"); | ||
assert.equal(log3.items[1].payload, "second 2"); | ||
assert.equal(_.last(log3.items).payload, "second " + count); | ||
done(); | ||
})); | ||
}); | ||
it('returns all items when none are in the log', async((done) => { | ||
const log1 = new Log(ipfs, 'A'); | ||
let entrys = []; | ||
const amount = Log.batchSize * 4; | ||
for(let i = 1; i <= amount; i ++) { | ||
const prev = _.last(entrys); | ||
const n = await(Entry.create(ipfs, 'entry' + i, prev ? prev : null)) | ||
entrys.push(n); | ||
} | ||
describe('_fetchRecursive', () => { | ||
it('returns two items when neither are in the log', async((done) => { | ||
const log1 = new Log(ipfs, 'A'); | ||
const entry1 = await(Entry.create(ipfs, 'one')) | ||
const entry2 = await(Entry.create(ipfs, 'two', entry1)) | ||
const items = await(log1._fetchRecursive(ipfs, entry2.hash, [], 1000, 0)); | ||
assert.equal(items.length, 2); | ||
assert.equal(items[0].hash, 'QmRMUN4WJdpYydRLpbipaNoLQNXiw9ifRpPht5APaLFqrR'); | ||
assert.equal(items[1].hash, 'Qmcpgub1qRG5XHed1qNciwb74uasUhQVEhP35oaZZ7UWbi'); | ||
done(); | ||
})); | ||
const items = await(log1._fetchRecursive(ipfs, _.last(entrys).hash, [], 1000, 0)); | ||
assert.equal(items.length, amount); | ||
assert.equal(items[0].hash, entrys[0].hash); | ||
assert.equal(_.last(items).hash, _.last(entrys).hash); | ||
done(); | ||
})); | ||
it('returns three items when none are in the log', async((done) => { | ||
const log1 = new Log(ipfs, 'A'); | ||
const entry1 = await(Entry.create(ipfs, 'one')) | ||
const entry2 = await(Entry.create(ipfs, 'two', entry1)) | ||
const entry3 = await(Entry.create(ipfs, 'three', entry2)) | ||
const items = await(log1._fetchRecursive(ipfs, entry3.hash, [], 1000, 0)); | ||
assert.equal(items.length, 3); | ||
assert.equal(items[0].hash, 'QmRMUN4WJdpYydRLpbipaNoLQNXiw9ifRpPht5APaLFqrR'); | ||
assert.equal(items[1].hash, 'Qmcpgub1qRG5XHed1qNciwb74uasUhQVEhP35oaZZ7UWbi'); | ||
assert.equal(items[2].hash, 'QmQM4Xg6EGGGEKRYu3jX3cpTcXK53XvSgQpxZd2qGY1L2V'); | ||
done(); | ||
})); | ||
it('returns only the items that are not in the log', async((done) => { | ||
const log1 = new Log(ipfs, 'A'); | ||
const entry1 = await(log1.add('one')) | ||
const entry2 = await(Entry.create(ipfs, 'two', entry1)) | ||
const entry3 = await(Entry.create(ipfs, 'three', entry2)) | ||
const allHashes = log1.items.map((a) => a.hash); | ||
const items = await(log1._fetchRecursive(ipfs, entry3.hash, allHashes, 1000, 0)); | ||
assert.equal(items.length, 2); | ||
assert.equal(items[0].hash, 'Qmcpgub1qRG5XHed1qNciwb74uasUhQVEhP35oaZZ7UWbi'); | ||
assert.equal(items[1].hash, 'QmQM4Xg6EGGGEKRYu3jX3cpTcXK53XvSgQpxZd2qGY1L2V'); | ||
done(); | ||
})); | ||
}); | ||
it('returns all items when none are in the log', async((done) => { | ||
const log1 = new Log(ipfs, 'A'); | ||
let entrys = []; | ||
const amount = Log.batchSize * 4; | ||
for(let i = 1; i <= amount; i ++) { | ||
const prev = _.last(entrys); | ||
const n = await(Entry.create(ipfs, 'entry' + i, prev ? prev : null)) | ||
entrys.push(n); | ||
} | ||
describe('findHeads', () => { | ||
it('finds one head after one item', async((done) => { | ||
const log1 = new Log(ipfs, 'A'); | ||
const log2 = new Log(ipfs, 'B'); | ||
const log3 = new Log(ipfs, 'C'); | ||
const items = await(log1._fetchRecursive(ipfs, _.last(entrys).hash, [], 1000, 0)); | ||
assert.equal(items.length, amount); | ||
assert.equal(items[0].hash, entrys[0].hash); | ||
assert.equal(_.last(items).hash, _.last(entrys).hash); | ||
done(); | ||
})); | ||
await(log1.add("helloA1")); | ||
it('returns only the items that are not in the log', async((done) => { | ||
const log1 = new Log(ipfs, 'A'); | ||
const entry1 = await(log1.add('one')) | ||
const entry2 = await(Entry.create(ipfs, 'two', entry1)) | ||
const entry3 = await(Entry.create(ipfs, 'three', entry2)) | ||
const allHashes = log1.items.map((a) => a.hash); | ||
const items = await(log1._fetchRecursive(ipfs, entry3.hash, allHashes, 1000, 0)); | ||
assert.equal(items.length, 2); | ||
assert.equal(items[0].hash, 'Qmcpgub1qRG5XHed1qNciwb74uasUhQVEhP35oaZZ7UWbi'); | ||
assert.equal(items[1].hash, 'QmQM4Xg6EGGGEKRYu3jX3cpTcXK53XvSgQpxZd2qGY1L2V'); | ||
done(); | ||
})); | ||
}); | ||
// const heads = Log.findHeads(log1) | ||
const heads = log1._heads; | ||
assert.equal(heads.length, 1); | ||
assert.equal(heads[0], 'QmUEH5SEuRZhZ7RETwEX2df2BtTR2xUYZR3qBrhjnxqocb'); | ||
done(); | ||
})); | ||
describe('findHeads', () => { | ||
it('finds one head after one item', async((done) => { | ||
const log1 = new Log(ipfs, 'A'); | ||
const log2 = new Log(ipfs, 'B'); | ||
const log3 = new Log(ipfs, 'C'); | ||
it('finds one head after two items', async((done) => { | ||
const log1 = new Log(ipfs, 'A'); | ||
const log2 = new Log(ipfs, 'B'); | ||
const log3 = new Log(ipfs, 'C'); | ||
await(log1.add("helloA1")); | ||
await(log1.add("helloA1")); | ||
await(log1.add("helloA2")); | ||
// const heads = Log.findHeads(log1) | ||
const heads = log1._heads; | ||
assert.equal(heads.length, 1); | ||
assert.equal(heads[0], 'QmUEH5SEuRZhZ7RETwEX2df2BtTR2xUYZR3qBrhjnxqocb'); | ||
done(); | ||
})); | ||
// const heads = Log.findHeads(log1) | ||
const heads = log1._heads; | ||
assert.equal(heads.length, 1); | ||
assert.equal(heads[0], 'Qma1PaYbyW1rZA4npPnuJzA3ov5Je4N9cvAn2p6Ju1iPQS'); | ||
done(); | ||
})); | ||
it('finds one head after two items', async((done) => { | ||
const log1 = new Log(ipfs, 'A'); | ||
const log2 = new Log(ipfs, 'B'); | ||
const log3 = new Log(ipfs, 'C'); | ||
it('finds two heads after a join', async((done) => { | ||
const log1 = new Log(ipfs, 'A'); | ||
const log2 = new Log(ipfs, 'B'); | ||
await(log1.add("helloA1")); | ||
await(log1.add("helloA2")); | ||
await(log1.add("helloA1")); | ||
const expectedHead1 = await(log1.add("helloA2")); | ||
// const heads = Log.findHeads(log1) | ||
const heads = log1._heads; | ||
assert.equal(heads.length, 1); | ||
assert.equal(heads[0], 'Qma1PaYbyW1rZA4npPnuJzA3ov5Je4N9cvAn2p6Ju1iPQS'); | ||
done(); | ||
})); | ||
await(log2.add("helloB1")); | ||
const expectedHead2 = await(log2.add("helloB2")); | ||
it('finds two heads after a join', async((done) => { | ||
const log1 = new Log(ipfs, 'A'); | ||
const log2 = new Log(ipfs, 'B'); | ||
await(log1.join(log2)); | ||
await(log1.add("helloA1")); | ||
const expectedHead1 = await(log1.add("helloA2")); | ||
// const heads = Log.findHeads(log1) | ||
const heads = log1._heads; | ||
assert.equal(heads.length, 2); | ||
assert.equal(heads[0], expectedHead2.hash); | ||
assert.equal(heads[1], expectedHead1.hash); | ||
done(); | ||
})); | ||
await(log2.add("helloB1")); | ||
const expectedHead2 = await(log2.add("helloB2")); | ||
it('finds one head after two joins', async((done) => { | ||
const log1 = new Log(ipfs, 'A'); | ||
const log2 = new Log(ipfs, 'B'); | ||
await(log1.join(log2)); | ||
await(log1.add("helloA1")); | ||
await(log1.add("helloA2")); | ||
await(log2.add("helloB1")); | ||
await(log2.add("helloB2")); | ||
await(log1.join(log2)); | ||
await(log1.add("helloA3")); | ||
const expectedHead = await(log1.add("helloA4")); | ||
await(log1.join(log2)); | ||
// const heads = Log.findHeads(log1) | ||
const heads = log1._heads; | ||
assert.equal(heads.length, 2); | ||
assert.equal(heads[0], expectedHead2.hash); | ||
assert.equal(heads[1], expectedHead1.hash); | ||
done(); | ||
})); | ||
// const heads = Log.findHeads(log1) | ||
const heads = log1._heads; | ||
assert.equal(heads.length, 1); | ||
assert.equal(heads[0], expectedHead.hash); | ||
done(); | ||
})); | ||
it('finds one head after two joins', async((done) => { | ||
const log1 = new Log(ipfs, 'A'); | ||
const log2 = new Log(ipfs, 'B'); | ||
it('finds two heads after three joins', async((done) => { | ||
const log1 = new Log(ipfs, 'A'); | ||
const log2 = new Log(ipfs, 'B'); | ||
const log3 = new Log(ipfs, 'C'); | ||
await(log1.add("helloA1")); | ||
await(log1.add("helloA2")); | ||
await(log2.add("helloB1")); | ||
await(log2.add("helloB2")); | ||
await(log1.join(log2)); | ||
await(log1.add("helloA3")); | ||
const expectedHead = await(log1.add("helloA4")); | ||
await(log1.join(log2)); | ||
await(log1.add("helloA1")); | ||
await(log1.add("helloA2")); | ||
await(log2.add("helloB1")); | ||
await(log2.add("helloB2")); | ||
await(log1.join(log2)); | ||
await(log1.add("helloA3")); | ||
const expectedHead1 = await(log1.add("helloA4")); | ||
await(log3.add("helloC1")); | ||
await(log3.add("helloC2")); | ||
await(log2.join(log3)); | ||
const expectedHead2 = await(log2.add("helloB3")); | ||
await(log1.join(log2)); | ||
// const heads = Log.findHeads(log1) | ||
const heads = log1._heads; | ||
assert.equal(heads.length, 1); | ||
assert.equal(heads[0], expectedHead.hash); | ||
done(); | ||
})); | ||
// const heads = Log.findHeads(log1) | ||
const heads = log1._heads; | ||
assert.equal(heads.length, 2); | ||
assert.equal(heads[0], expectedHead2.hash); | ||
assert.equal(heads[1], expectedHead1.hash); | ||
done(); | ||
})); | ||
it('finds two heads after three joins', async((done) => { | ||
const log1 = new Log(ipfs, 'A'); | ||
const log2 = new Log(ipfs, 'B'); | ||
const log3 = new Log(ipfs, 'C'); | ||
it('finds three heads after three joins', async((done) => { | ||
const log1 = new Log(ipfs, 'A'); | ||
const log2 = new Log(ipfs, 'B'); | ||
const log3 = new Log(ipfs, 'C'); | ||
await(log1.add("helloA1")); | ||
await(log1.add("helloA2")); | ||
await(log2.add("helloB1")); | ||
await(log2.add("helloB2")); | ||
await(log1.join(log2)); | ||
await(log1.add("helloA3")); | ||
const expectedHead1 = await(log1.add("helloA4")); | ||
await(log3.add("helloC1")); | ||
await(log3.add("helloC2")); | ||
await(log2.join(log3)); | ||
const expectedHead2 = await(log2.add("helloB3")); | ||
await(log1.join(log2)); | ||
await(log1.add("helloA1")); | ||
await(log1.add("helloA2")); | ||
await(log2.add("helloB1")); | ||
await(log2.add("helloB2")); | ||
await(log1.join(log2)); | ||
await(log1.add("helloA3")); | ||
const expectedHead1 = await(log1.add("helloA4")); | ||
await(log3.add("helloC1")); | ||
const expectedHead2 = await(log2.add("helloB3")); | ||
const expectedHead3 = await(log3.add("helloC2")); | ||
await(log1.join(log2)); | ||
await(log1.join(log3)); | ||
// const heads = Log.findHeads(log1) | ||
const heads = log1._heads; | ||
assert.equal(heads.length, 2); | ||
assert.equal(heads[0], expectedHead2.hash); | ||
assert.equal(heads[1], expectedHead1.hash); | ||
done(); | ||
})); | ||
// const heads = Log.findHeads(log1) | ||
const heads = log1._heads; | ||
assert.equal(heads.length, 3); | ||
assert.equal(heads[0], expectedHead3.hash); | ||
assert.equal(heads[1], expectedHead2.hash); | ||
assert.equal(heads[2], expectedHead1.hash); | ||
done(); | ||
})); | ||
}); | ||
it('finds three heads after three joins', async((done) => { | ||
const log1 = new Log(ipfs, 'A'); | ||
const log2 = new Log(ipfs, 'B'); | ||
const log3 = new Log(ipfs, 'C'); | ||
describe('isReferencedInChain', () => { | ||
it('returns true if another entry in the log references the given entry', async((done) => { | ||
const log = new Log(ipfs, 'A'); | ||
const entry1 = await(log.add('one')); | ||
const entry2 = await(log.add('two')); | ||
const res = Log.isReferencedInChain(log, entry1); | ||
assert.equal(res, true) | ||
done(); | ||
})); | ||
await(log1.add("helloA1")); | ||
await(log1.add("helloA2")); | ||
await(log2.add("helloB1")); | ||
await(log2.add("helloB2")); | ||
await(log1.join(log2)); | ||
await(log1.add("helloA3")); | ||
const expectedHead1 = await(log1.add("helloA4")); | ||
await(log3.add("helloC1")); | ||
const expectedHead2 = await(log2.add("helloB3")); | ||
const expectedHead3 = await(log3.add("helloC2")); | ||
await(log1.join(log2)); | ||
await(log1.join(log3)); | ||
it('returns false if no other entry in the log references the given entry', async((done) => { | ||
const log = new Log(ipfs, 'A'); | ||
const entry1 = await(log.add('one')); | ||
const entry2 = await(log.add('two')); | ||
const res = Log.isReferencedInChain(log, entry2); | ||
assert.equal(res, false) | ||
done(); | ||
})); | ||
}); | ||
// const heads = Log.findHeads(log1) | ||
const heads = log1._heads; | ||
assert.equal(heads.length, 3); | ||
assert.equal(heads[0], expectedHead3.hash); | ||
assert.equal(heads[1], expectedHead2.hash); | ||
assert.equal(heads[2], expectedHead1.hash); | ||
done(); | ||
})); | ||
}); | ||
describe('_commit', () => { | ||
it('moves entrys from current batch to all known entrys', async((done) => { | ||
const log = new Log(ipfs, 'A'); | ||
const entry1 = await(log.add('one')); | ||
const entry2 = await(log.add('two')); | ||
describe('isReferencedInChain', () => { | ||
it('returns true if another entry in the log references the given entry', async((done) => { | ||
const log = new Log(ipfs, 'A'); | ||
const entry1 = await(log.add('one')); | ||
const entry2 = await(log.add('two')); | ||
const res = Log.isReferencedInChain(log, entry1); | ||
assert.equal(res, true) | ||
done(); | ||
})); | ||
assert.equal(log._items.length, 0) | ||
assert.equal(log._currentBatch.length, 2) | ||
it('returns false if no other entry in the log references the given entry', async((done) => { | ||
const log = new Log(ipfs, 'A'); | ||
const entry1 = await(log.add('one')); | ||
const entry2 = await(log.add('two')); | ||
const res = Log.isReferencedInChain(log, entry2); | ||
assert.equal(res, false) | ||
done(); | ||
})); | ||
}); | ||
log._commit(); | ||
describe('_commit', () => { | ||
it('moves entrys from current batch to all known entrys', async((done) => { | ||
const log = new Log(ipfs, 'A'); | ||
const entry1 = await(log.add('one')); | ||
const entry2 = await(log.add('two')); | ||
assert.equal(log._items.length, 2) | ||
assert.equal(log._currentBatch.length, 0) | ||
done(); | ||
})); | ||
}); | ||
assert.equal(log._items.length, 0) | ||
assert.equal(log._currentBatch.length, 2) | ||
describe('_insert', () => { | ||
it('insert entry to the log before current batch if parent is in current bathc', async((done) => { | ||
const log = new Log(ipfs, 'A'); | ||
const entry1 = await(log.add('one')); | ||
const entry2 = await(log.add('two')); | ||
const entry3 = await(Entry.create(ipfs, 'three', entry1)) | ||
log._insert(entry3); | ||
assert.equal(log.items.length, 3) | ||
assert.equal(log.items[0].payload, 'three') | ||
assert.equal(log._items.length, 1) | ||
assert.equal(log._items[0].payload, 'three') | ||
done(); | ||
})); | ||
log._commit(); | ||
it('insert to the log after the parent when parent is not in the current batch', async((done) => { | ||
const log = new Log(ipfs, 'A'); | ||
const entry1 = await(log.add('one')); | ||
const entry2 = await(log.add('two')); | ||
const entry3 = await(Entry.create(ipfs, 'three', entry1)) | ||
log._commit(); | ||
log._insert(entry3); | ||
assert.equal(log.items.length, 3) | ||
assert.equal(log.items[1].payload, 'three') | ||
done(); | ||
})); | ||
}); | ||
assert.equal(log._items.length, 2) | ||
assert.equal(log._currentBatch.length, 0) | ||
done(); | ||
})); | ||
}); | ||
describe('is a CRDT', () => { | ||
let log1, log2, log3; | ||
describe('_insert', () => { | ||
it('insert entry to the log before current batch if parent is in current bathc', async((done) => { | ||
const log = new Log(ipfs, 'A'); | ||
const entry1 = await(log.add('one')); | ||
const entry2 = await(log.add('two')); | ||
const entry3 = await(Entry.create(ipfs, 'three', entry1)) | ||
log._insert(entry3); | ||
assert.equal(log.items.length, 3) | ||
assert.equal(log.items[0].payload, 'three') | ||
assert.equal(log._items.length, 1) | ||
assert.equal(log._items[0].payload, 'three') | ||
done(); | ||
})); | ||
beforeEach(async((done) => { | ||
log1 = new Log(ipfs, 'A'); | ||
log2 = new Log(ipfs, 'B'); | ||
log3 = new Log(ipfs, 'C'); | ||
done(); | ||
})); | ||
it('insert to the log after the parent when parent is not in the current batch', async((done) => { | ||
const log = new Log(ipfs, 'A'); | ||
const entry1 = await(log.add('one')); | ||
const entry2 = await(log.add('two')); | ||
const entry3 = await(Entry.create(ipfs, 'three', entry1)) | ||
log._commit(); | ||
log._insert(entry3); | ||
assert.equal(log.items.length, 3) | ||
assert.equal(log.items[1].payload, 'three') | ||
done(); | ||
})); | ||
}); | ||
it('join is associative', async((done) => { | ||
await(log1.add("helloA1")); | ||
await(log1.add("helloA2")); | ||
await(log2.add("helloB1")); | ||
await(log2.add("helloB2")); | ||
await(log3.add("helloC1")); | ||
await(log3.add("helloC2")); | ||
describe('is a CRDT', () => { | ||
let log1, log2, log3; | ||
// a + (b + c) | ||
await(log2.join(log3)); | ||
await(log1.join(log2)); | ||
beforeEach(async((done) => { | ||
log1 = new Log(ipfs, 'A'); | ||
log2 = new Log(ipfs, 'B'); | ||
log3 = new Log(ipfs, 'C'); | ||
done(); | ||
})); | ||
const res1 = log1.items.map((e) => e.hash).join(","); | ||
it('join is associative', async((done) => { | ||
await(log1.add("helloA1")); | ||
await(log1.add("helloA2")); | ||
await(log2.add("helloB1")); | ||
await(log2.add("helloB2")); | ||
await(log3.add("helloC1")); | ||
await(log3.add("helloC2")); | ||
log1 = new Log(ipfs, 'A'); | ||
log2 = new Log(ipfs, 'B'); | ||
log3 = new Log(ipfs, 'C'); | ||
await(log1.add("helloA1")); | ||
await(log1.add("helloA2")); | ||
await(log2.add("helloB1")); | ||
await(log2.add("helloB2")); | ||
await(log3.add("helloC1")); | ||
await(log3.add("helloC2")); | ||
// a + (b + c) | ||
await(log2.join(log3)); | ||
await(log1.join(log2)); | ||
// (a + b) + c | ||
await(log1.join(log2)); | ||
await(log1.join(log3)); | ||
const res1 = log1.items.map((e) => e.hash).join(","); | ||
const res2 = log1.items.map((e) => e.hash).join(","); | ||
log1 = new Log(ipfs, 'A'); | ||
log2 = new Log(ipfs, 'B'); | ||
log3 = new Log(ipfs, 'C'); | ||
await(log1.add("helloA1")); | ||
await(log1.add("helloA2")); | ||
await(log2.add("helloB1")); | ||
await(log2.add("helloB2")); | ||
await(log3.add("helloC1")); | ||
await(log3.add("helloC2")); | ||
// associativity: a + (b + c) == (a + b) + c | ||
const len = (46 + 1) * 6- 1; // 46 == ipfs hash, +1 == .join(","), * 4 == number of items, -1 == last item doesn't get a ',' from .join | ||
assert.equal(res1.length, len) | ||
assert.equal(res2.length, len) | ||
assert.equal(res1, res2); | ||
done(); | ||
})); | ||
// (a + b) + c | ||
await(log1.join(log2)); | ||
await(log1.join(log3)); | ||
it('join is commutative', async((done) => { | ||
await(log1.add("helloA1")); | ||
await(log1.add("helloA2")); | ||
await(log2.join(log1)); | ||
await(log2.add("helloB1")); | ||
await(log2.add("helloB2")); | ||
const res2 = log1.items.map((e) => e.hash).join(","); | ||
// b + a | ||
await(log2.join(log1)); | ||
// associativity: a + (b + c) == (a + b) + c | ||
const len = (46 + 1) * 6- 1; // 46 == ipfs hash, +1 == .join(","), * 4 == number of items, -1 == last item doesn't get a ',' from .join | ||
assert.equal(res1.length, len) | ||
assert.equal(res2.length, len) | ||
assert.equal(res1, res2); | ||
done(); | ||
})); | ||
const res1 = log2.items.map((e) => e.hash).join(","); | ||
it('join is commutative', async((done) => { | ||
await(log1.add("helloA1")); | ||
await(log1.add("helloA2")); | ||
await(log2.join(log1)); | ||
await(log2.add("helloB1")); | ||
await(log2.add("helloB2")); | ||
log1 = new Log(ipfs, 'A'); | ||
log2 = new Log(ipfs, 'B'); | ||
await(log1.add("helloA1")) | ||
await(log1.add("helloA2")) | ||
await(log2.join(log1)) | ||
await(log2.add("helloB1")) | ||
await(log2.add("helloB2")) | ||
// b + a | ||
await(log2.join(log1)); | ||
// a + b | ||
await(log1.join(log2)); | ||
const res1 = log2.items.map((e) => e.hash).join(","); | ||
const res2 = log1.items.map((e) => e.hash).join(","); | ||
log1 = new Log(ipfs, 'A'); | ||
log2 = new Log(ipfs, 'B'); | ||
await(log1.add("helloA1")) | ||
await(log1.add("helloA2")) | ||
await(log2.join(log1)) | ||
await(log2.add("helloB1")) | ||
await(log2.add("helloB2")) | ||
// commutativity: a + (b + c) == (a + b) + c | ||
const len = (46 + 1) * 4 - 1; // 46 == ipfs hash length, +1 == .join(","), * 4 == number of items, -1 == last item doesn't get a ',' from .join | ||
assert.equal(res1.length, len) | ||
assert.equal(res2.length, len) | ||
assert.equal(res1, res2); | ||
done(); | ||
})); | ||
// a + b | ||
await(log1.join(log2)); | ||
const res2 = log1.items.map((e) => e.hash).join(","); | ||
it('join is idempotent', async((done) => { | ||
await(log1.add("helloA1")); | ||
await(log1.add("helloA2")); | ||
await(log1.add("helloA3")); | ||
await(log2.add("helloA1")); | ||
await(log2.add("helloA2")); | ||
await(log2.add("helloA3")); | ||
// commutativity: a + (b + c) == (a + b) + c | ||
const len = (46 + 1) * 4 - 1; // 46 == ipfs hash length, +1 == .join(","), * 4 == number of items, -1 == last item doesn't get a ',' from .join | ||
assert.equal(res1.length, len) | ||
assert.equal(res2.length, len) | ||
assert.equal(res1, res2); | ||
done(); | ||
})); | ||
// idempotence: a + a = a | ||
await(log1.join(log2)); | ||
assert.equal(log1.id, 'A'); | ||
assert.equal(log1.items.length, 3); | ||
done(); | ||
})); | ||
}); | ||
}); | ||
it('join is idempotent', async((done) => { | ||
await(log1.add("helloA1")); | ||
await(log1.add("helloA2")); | ||
await(log1.add("helloA3")); | ||
await(log2.add("helloA1")); | ||
await(log2.add("helloA2")); | ||
await(log2.add("helloA3")); | ||
// idempotence: a + a = a | ||
await(log1.join(log2)); | ||
assert.equal(log1.id, 'A'); | ||
assert.equal(log1.items.length, 3); | ||
done(); | ||
})); | ||
}); | ||
})); | ||
}); |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
5192661
3236