mirror of
https://github.com/orbitdb/orbitdb.git
synced 2025-03-30 15:08:28 +00:00

Use immutable ipfs-log. Simplify internals. Remove obsolete dependencies. Update dependencies. Use @dignifiedquire's mapSeries for Promises. Split tests to individual stores. Improve tests. Fix build process. Build size down to 121kb. Fix benchmarks and examples. Move Cache to Stores (and to its own module).
429 lines
14 KiB
JavaScript
429 lines
14 KiB
JavaScript
'use strict'
|
|
|
|
const assert = require('assert')
|
|
const rmrf = require('rimraf')
|
|
const mapSeries = require('./promise-map-series')
|
|
const OrbitDB = require('../src/OrbitDB')
|
|
const hasIpfsApiWithPubsub = require('./test-utils').hasIpfsApiWithPubsub
|
|
const first = require('./test-utils').first
|
|
const last = require('./test-utils').last
|
|
const config = require('./test-config')
|
|
|
|
config.daemons.forEach((IpfsDaemon) => {
|
|
|
|
describe('orbit-db - Feed', function() {
|
|
this.timeout(config.timeout)
|
|
|
|
let ipfs, client1, client2, db
|
|
|
|
before(function (done) {
|
|
rmrf.sync(config.defaultIpfsDirectory)
|
|
rmrf.sync(config.defaultOrbitDBDirectory)
|
|
ipfs = new IpfsDaemon()
|
|
ipfs.on('error', done)
|
|
ipfs.on('ready', () => {
|
|
assert.equal(hasIpfsApiWithPubsub(ipfs), true)
|
|
client1 = new OrbitDB(ipfs, 'A')
|
|
client2 = new OrbitDB(ipfs, 'B')
|
|
done()
|
|
})
|
|
})
|
|
|
|
after(() => {
|
|
if(client1) client1.disconnect()
|
|
if(client2) client2.disconnect()
|
|
ipfs.stop()
|
|
rmrf.sync(config.defaultOrbitDBDirectory)
|
|
rmrf.sync(config.defaultIpfsDirectory)
|
|
})
|
|
|
|
describe('Feed', function() {
|
|
it('returns the added entry\'s hash, 1 entry', () => {
|
|
db = client1.feed(config.dbname, { replicate: false, maxHistory: 0 })
|
|
return db.add('hello1')
|
|
.then((hash) => {
|
|
const items = db.iterator({ limit: -1 }).collect()
|
|
assert.notEqual(hash, null)
|
|
assert.equal(hash, last(items).hash)
|
|
assert.equal(items.length, 1)
|
|
})
|
|
})
|
|
|
|
it('returns the added entry\'s hash, 2 entries', () => {
|
|
const prevHash = db.iterator().collect()[0].hash
|
|
return db.add('hello2')
|
|
.then((hash) => {
|
|
const items = db.iterator({ limit: -1 }).collect()
|
|
assert.equal(items.length, 2)
|
|
assert.notEqual(hash, null)
|
|
assert.notEqual(hash, prevHash)
|
|
assert.equal(hash, last(items).hash)
|
|
})
|
|
})
|
|
|
|
it('adds five items', () => {
|
|
db = client1.feed(config.dbname, { replicate: false, maxHistory: 0 })
|
|
return mapSeries([1, 2, 3, 4, 5], (i) => db.add('hello' + i))
|
|
.then(() => {
|
|
const items = db.iterator({ limit: -1 }).collect()
|
|
assert.equal(items.length, 5)
|
|
assert.equal(first(items.map((f) => f.payload.value)), 'hello1')
|
|
assert.equal(last(items.map((f) => f.payload.value)), 'hello5')
|
|
})
|
|
})
|
|
|
|
it('adds an item that is > 256 bytes', () => {
|
|
db = client1.feed(config.dbname, { replicate: false, maxHistory: 0 })
|
|
|
|
let msg = new Buffer(1024)
|
|
msg.fill('a')
|
|
return db.add(msg.toString())
|
|
.then((hash) => {
|
|
assert.notEqual(hash, null)
|
|
assert.equal(hash.startsWith('Qm'), true)
|
|
assert.equal(hash.length, 46)
|
|
})
|
|
})
|
|
|
|
it('deletes an item when only one item in the database', () => {
|
|
db = client1.feed(config.dbname, { replicate: false, maxHistory: 0 })
|
|
|
|
return db.add('hello3')
|
|
.then((hash) => db.remove(hash))
|
|
.then((delopHash) => {
|
|
const items = db.iterator().collect()
|
|
assert.equal(delopHash.startsWith('Qm'), true)
|
|
assert.equal(items.length, 0)
|
|
})
|
|
})
|
|
|
|
it('deletes an item when two items in the database', () => {
|
|
db = client1.feed(config.dbname, { replicate: false, maxHistory: 0 })
|
|
|
|
return db.add('hello1')
|
|
.then(() => db.add('hello2'))
|
|
.then((hash) => db.remove(hash))
|
|
.then(() => {
|
|
const items = db.iterator({ limit: -1 }).collect()
|
|
assert.equal(items.length, 1)
|
|
assert.equal(first(items).payload.value, 'hello1')
|
|
})
|
|
})
|
|
|
|
it('deletes an item between adds', () => {
|
|
db = client1.feed(config.dbname, { replicate: false, maxHistory: 0 })
|
|
|
|
let hash
|
|
return db.add('hello1')
|
|
.then((res) => hash = res)
|
|
.then(() => db.add('hello2'))
|
|
.then(() => db.remove(hash))
|
|
.then(() => db.add('hello3'))
|
|
.then(() => {
|
|
const items = db.iterator({ limit: -1 }).collect()
|
|
assert.equal(items.length, 2)
|
|
|
|
const firstItem = first(items)
|
|
const secondItem = items[1]
|
|
assert.equal(firstItem.hash.startsWith('Qm'), true)
|
|
assert.equal(firstItem.payload.key, null)
|
|
assert.equal(firstItem.payload.value, 'hello2')
|
|
assert.equal(secondItem.payload.value, 'hello3')
|
|
})
|
|
})
|
|
})
|
|
|
|
describe('Iterator', function() {
|
|
let items = []
|
|
const itemCount = 5
|
|
|
|
beforeEach(() => {
|
|
items = []
|
|
db = client1.feed(config.dbname, { replicate: false, maxHistory: 0 })
|
|
return mapSeries([0, 1, 2, 3, 4], (i) => db.add('hello' + i))
|
|
.then((res) => items = res)
|
|
})
|
|
|
|
describe('Defaults', function() {
|
|
it('returns an iterator', () => {
|
|
const iter = db.iterator()
|
|
const next = iter.next().value
|
|
assert.notEqual(iter, null)
|
|
assert.notEqual(next, null)
|
|
})
|
|
|
|
it('returns an item with the correct structure', () => {
|
|
const iter = db.iterator()
|
|
const next = iter.next().value
|
|
assert.notEqual(next, null)
|
|
assert.equal(next.hash.startsWith('Qm'), true)
|
|
assert.equal(next.payload.key, null)
|
|
assert.equal(next.payload.value, 'hello4')
|
|
})
|
|
|
|
it('implements Iterator interface', () => {
|
|
const iter = db.iterator({ limit: -1 })
|
|
let messages = []
|
|
|
|
for(let i of iter)
|
|
messages.push(i.key)
|
|
|
|
assert.equal(messages.length, items.length)
|
|
})
|
|
|
|
it('returns 1 item as default', () => {
|
|
const iter = db.iterator()
|
|
const first = iter.next().value
|
|
const second = iter.next().value
|
|
assert.equal(first.hash, items[items.length - 1])
|
|
assert.equal(second, null)
|
|
assert.equal(first.payload.value, 'hello4')
|
|
})
|
|
|
|
it('returns items in the correct order', () => {
|
|
const amount = 3
|
|
const iter = db.iterator({ limit: amount })
|
|
let i = items.length - amount
|
|
for(let item of iter) {
|
|
assert.equal(item.payload.value, 'hello' + i)
|
|
i ++
|
|
}
|
|
})
|
|
})
|
|
|
|
describe('Collect', function() {
|
|
it('returns all items', () => {
|
|
const messages = db.iterator({ limit: -1 }).collect()
|
|
assert.equal(messages.length, items.length)
|
|
assert.equal(messages[0].payload.value, 'hello0')
|
|
assert.equal(messages[messages.length - 1].payload.value, 'hello4')
|
|
})
|
|
|
|
it('returns 1 item', () => {
|
|
const messages = db.iterator().collect()
|
|
assert.equal(messages.length, 1)
|
|
})
|
|
|
|
it('returns 3 items', () => {
|
|
const messages = db.iterator({ limit: 3 }).collect()
|
|
assert.equal(messages.length, 3)
|
|
})
|
|
})
|
|
|
|
describe('Options: limit', function() {
|
|
it('returns 1 item when limit is 0', () => {
|
|
const iter = db.iterator({ limit: 1 })
|
|
const first = iter.next().value
|
|
const second = iter.next().value
|
|
assert.equal(first.hash, last(items))
|
|
assert.equal(second, null)
|
|
})
|
|
|
|
it('returns 1 item when limit is 1', () => {
|
|
const iter = db.iterator({ limit: 1 })
|
|
const first = iter.next().value
|
|
const second = iter.next().value
|
|
assert.equal(first.hash, last(items))
|
|
assert.equal(second, null)
|
|
})
|
|
|
|
it('returns 3 items', () => {
|
|
const iter = db.iterator({ limit: 3 })
|
|
const first = iter.next().value
|
|
const second = iter.next().value
|
|
const third = iter.next().value
|
|
const fourth = iter.next().value
|
|
assert.equal(first.hash, items[items.length - 3])
|
|
assert.equal(second.hash, items[items.length - 2])
|
|
assert.equal(third.hash, items[items.length - 1])
|
|
assert.equal(fourth, null)
|
|
})
|
|
|
|
it('returns all items', () => {
|
|
const messages = db.iterator({ limit: -1 })
|
|
.collect()
|
|
.map((e) => e.hash)
|
|
|
|
messages.reverse()
|
|
assert.equal(messages.length, items.length)
|
|
assert.equal(messages[0], items[items.length - 1])
|
|
})
|
|
|
|
it('returns all items when limit is bigger than -1', () => {
|
|
const messages = db.iterator({ limit: -300 })
|
|
.collect()
|
|
.map((e) => e.hash)
|
|
|
|
assert.equal(messages.length, items.length)
|
|
assert.equal(messages[0], items[0])
|
|
})
|
|
|
|
it('returns all items when limit is bigger than number of items', () => {
|
|
const messages = db.iterator({ limit: 300 })
|
|
.collect()
|
|
.map((e) => e.hash)
|
|
|
|
assert.equal(messages.length, items.length)
|
|
assert.equal(messages[0], items[0])
|
|
})
|
|
})
|
|
|
|
describe('Option: ranges', function() {
|
|
describe('gt & gte', function() {
|
|
it('returns 1 item when gte is the head', () => {
|
|
const messages = db.iterator({ gte: last(items), limit: -1 })
|
|
.collect()
|
|
.map((e) => e.hash)
|
|
|
|
assert.equal(messages.length, 1)
|
|
assert.equal(messages[0], last(items))
|
|
})
|
|
|
|
it('returns 0 items when gt is the head', () => {
|
|
const messages = db.iterator({ gt: last(items) }).collect()
|
|
assert.equal(messages.length, 0)
|
|
})
|
|
|
|
it('returns 2 item when gte is defined', () => {
|
|
const gte = items[items.length - 2]
|
|
const messages = db.iterator({ gte: gte, limit: -1 })
|
|
.collect()
|
|
.map((e) => e.hash)
|
|
|
|
assert.equal(messages.length, 2)
|
|
assert.equal(messages[0], items[items.length - 2])
|
|
assert.equal(messages[1], items[items.length - 1])
|
|
})
|
|
|
|
it('returns all items when gte is the root item', () => {
|
|
const messages = db.iterator({ gte: items[0], limit: -1 })
|
|
.collect()
|
|
.map((e) => e.hash)
|
|
|
|
assert.equal(messages.length, items.length)
|
|
assert.equal(messages[0], items[0])
|
|
assert.equal(messages[messages.length - 1], last(items))
|
|
})
|
|
|
|
it('returns items when gt is the root item', () => {
|
|
const messages = db.iterator({ gt: items[0], limit: -1 })
|
|
.collect()
|
|
.map((e) => e.hash)
|
|
|
|
assert.equal(messages.length, itemCount - 1)
|
|
assert.equal(messages[0], items[1])
|
|
assert.equal(messages[3], last(items))
|
|
})
|
|
|
|
it('returns items when gt is defined', () => {
|
|
const messages = db.iterator({ limit: -1})
|
|
.collect()
|
|
.map((e) => e.hash)
|
|
|
|
const gt = messages[2]
|
|
|
|
const messages2 = db.iterator({ gt: gt, limit: 100 })
|
|
.collect()
|
|
.map((e) => e.hash)
|
|
|
|
assert.equal(messages2.length, 2)
|
|
assert.equal(messages2[0], messages[messages.length - 2])
|
|
assert.equal(messages2[1], messages[messages.length - 1])
|
|
})
|
|
})
|
|
|
|
describe('lt & lte', function() {
|
|
it('returns one item after head when lt is the head', () => {
|
|
const messages = db.iterator({ lt: last(items) })
|
|
.collect()
|
|
.map((e) => e.hash)
|
|
|
|
assert.equal(messages.length, 1)
|
|
assert.equal(messages[0], items[items.length - 2])
|
|
})
|
|
|
|
it('returns all items when lt is head and limit is -1', () => {
|
|
const messages = db.iterator({ lt: last(items), limit: -1 })
|
|
.collect()
|
|
.map((e) => e.hash)
|
|
|
|
assert.equal(messages.length, items.length - 1)
|
|
assert.equal(messages[0], items[0])
|
|
assert.equal(messages[messages.length - 1], items[items.length - 2])
|
|
})
|
|
|
|
it('returns 3 items when lt is head and limit is 3', () => {
|
|
const messages = db.iterator({ lt: last(items), limit: 3 })
|
|
.collect()
|
|
.map((e) => e.hash)
|
|
|
|
assert.equal(messages.length, 3)
|
|
assert.equal(messages[0], items[items.length - 4])
|
|
assert.equal(messages[2], items[items.length - 2])
|
|
})
|
|
|
|
it('returns null when lt is the root item', () => {
|
|
const messages = db.iterator({ lt: items[0] }).collect()
|
|
assert.equal(messages.length, 0)
|
|
})
|
|
|
|
it('returns one item when lte is the root item', () => {
|
|
const messages = db.iterator({ lte: items[0] })
|
|
.collect()
|
|
.map((e) => e.hash)
|
|
|
|
assert.equal(messages.length, 1)
|
|
assert.equal(messages[0], items[0])
|
|
})
|
|
|
|
it('returns all items when lte is the head', () => {
|
|
const messages = db.iterator({ lte: last(items), limit: -1 })
|
|
.collect()
|
|
.map((e) => e.hash)
|
|
|
|
assert.equal(messages.length, itemCount)
|
|
assert.equal(messages[0], items[0])
|
|
assert.equal(messages[4], last(items))
|
|
})
|
|
|
|
it('returns 3 items when lte is the head', () => {
|
|
const messages = db.iterator({ lte: last(items), limit: 3 })
|
|
.collect()
|
|
.map((e) => e.hash)
|
|
|
|
assert.equal(messages.length, 3)
|
|
assert.equal(messages[0], items[items.length - 3])
|
|
assert.equal(messages[1], items[items.length - 2])
|
|
assert.equal(messages[2], last(items))
|
|
})
|
|
})
|
|
})
|
|
})
|
|
|
|
describe('sync', () => {
|
|
const options = {
|
|
replicate: false,
|
|
}
|
|
|
|
it('syncs databases', (done) => {
|
|
const db1 = client1.feed(config.dbname, options)
|
|
const db2 = client2.feed(config.dbname, options)
|
|
db2.events.on('write', (dbname, hash, entry, heads) => {
|
|
assert.equal(db1.iterator({ limit: -1 }).collect().length, 0)
|
|
db1.sync(heads)
|
|
})
|
|
|
|
db1.events.on('synced', () => {
|
|
const items = db1.iterator({ limit: -1 }).collect()
|
|
assert.equal(items.length, 1)
|
|
assert.equal(items[0].payload.value, 'hello2')
|
|
done()
|
|
})
|
|
|
|
db2.add('hello2')
|
|
.catch(done)
|
|
})
|
|
})
|
|
})
|
|
})
|