mirror of
https://github.com/orbitdb/orbitdb.git
synced 2025-03-30 15:08:28 +00:00
488 lines
13 KiB
JavaScript
488 lines
13 KiB
JavaScript
import { strictEqual, deepStrictEqual } from 'assert'
|
|
import rimraf from 'rimraf'
|
|
import { Log } from '../src/log.js'
|
|
import IdentityProvider from 'orbit-db-identity-provider'
|
|
import Keystore from '../src/Keystore.js'
|
|
import LogCreator from './utils/log-creator.js'
|
|
import all from 'it-all'
|
|
|
|
// Test utils
|
|
import { config, testAPIs, startIpfs, stopIpfs } from 'orbit-db-test-utils'
|
|
import { identityKeys, signingKeys } from './fixtures/orbit-db-identity-keys.js'
|
|
|
|
const { sync: rmrf } = rimraf
|
|
const { createIdentity } = IdentityProvider
|
|
const { createLogWithSixteenEntries } = LogCreator
|
|
|
|
Object.keys(testAPIs).forEach((IPFS) => {
|
|
describe('Log - Iterator (' + IPFS + ')', function () {
|
|
this.timeout(config.timeout)
|
|
|
|
let ipfs
|
|
let ipfsd
|
|
let keystore, signingKeystore
|
|
let testIdentity, testIdentity2, testIdentity3
|
|
|
|
before(async () => {
|
|
keystore = new Keystore('./keys_1')
|
|
await keystore.open()
|
|
for (const [key, value] of Object.entries(identityKeys)) {
|
|
await keystore.addKey(key, value)
|
|
}
|
|
|
|
signingKeystore = new Keystore('./keys_2')
|
|
await signingKeystore.open()
|
|
for (const [key, value] of Object.entries(signingKeys)) {
|
|
await signingKeystore.addKey(key, value)
|
|
}
|
|
|
|
testIdentity = await createIdentity({ id: 'userA', keystore, signingKeystore })
|
|
testIdentity2 = await createIdentity({ id: 'userB', keystore, signingKeystore })
|
|
testIdentity3 = await createIdentity({ id: 'userC', keystore, signingKeystore })
|
|
ipfsd = await startIpfs(IPFS, config.defaultIpfsConfig)
|
|
ipfs = ipfsd.api
|
|
})
|
|
|
|
after(async () => {
|
|
if (ipfsd) {
|
|
await stopIpfs(ipfsd)
|
|
}
|
|
if (keystore) {
|
|
await keystore.close()
|
|
}
|
|
if (signingKeystore) {
|
|
await signingKeystore.close()
|
|
}
|
|
rmrf('./keys_1')
|
|
rmrf('./keys_2')
|
|
})
|
|
|
|
describe('Basic iterator functionality', async () => {
|
|
let log1
|
|
let startHash
|
|
const hashes = []
|
|
const logSize = 100
|
|
|
|
beforeEach(async () => {
|
|
log1 = await Log(testIdentity, { logId: 'X' })
|
|
|
|
for (let i = 0; i < logSize; i++) {
|
|
const entry = await log1.append('entry' + i)
|
|
hashes.push([entry.hash, hashes.length])
|
|
}
|
|
|
|
// entry67
|
|
// startHash = 'zdpuAxCuaH2R7AYKZ6ZBeeA94v3FgmHZ8wCfDy7pLVcoc3zSo'
|
|
startHash = hashes[67][0]
|
|
strictEqual(startHash, hashes[67][0])
|
|
})
|
|
|
|
it('returns length with lte and amount', async () => {
|
|
const amount = 10
|
|
|
|
const it = log1.iterator({
|
|
lte: startHash,
|
|
amount
|
|
})
|
|
|
|
const result = await all(it)
|
|
|
|
strictEqual([...result].length, 10)
|
|
})
|
|
|
|
it('returns entries with lte and amount', async () => {
|
|
const amount = 10
|
|
|
|
const it = log1.iterator({
|
|
lte: startHash,
|
|
amount
|
|
})
|
|
|
|
let i = 0
|
|
for await (const entry of it) {
|
|
strictEqual(entry.payload, 'entry' + (67 - i++))
|
|
}
|
|
|
|
strictEqual(i, amount)
|
|
})
|
|
|
|
it('returns length with lt and amount', async () => {
|
|
const amount = 10
|
|
|
|
const it = log1.iterator({
|
|
lt: startHash,
|
|
amount
|
|
})
|
|
|
|
const result = await all(it)
|
|
|
|
strictEqual([...result].length, amount)
|
|
})
|
|
|
|
it('returns entries with lt and amount', async () => {
|
|
const amount = 10
|
|
|
|
const it = log1.iterator({
|
|
lt: startHash,
|
|
amount
|
|
})
|
|
|
|
let i = 0
|
|
for await (const entry of it) {
|
|
strictEqual(entry.payload, 'entry' + (66 - i++))
|
|
}
|
|
|
|
strictEqual(i, amount)
|
|
})
|
|
|
|
it('returns correct length with gt and amount', async () => {
|
|
const amount = 5
|
|
|
|
const it = log1.iterator({
|
|
gt: startHash,
|
|
amount
|
|
})
|
|
|
|
let i = 0
|
|
for await (const entry of it) {
|
|
strictEqual(entry.payload, 'entry' + (73 - i++))
|
|
}
|
|
|
|
strictEqual(i, amount)
|
|
})
|
|
|
|
it('returns length with gte and amount', async () => {
|
|
const amount = 12
|
|
|
|
const it = log1.iterator({
|
|
gte: startHash,
|
|
amount
|
|
})
|
|
|
|
const result = await all(it)
|
|
|
|
strictEqual([...result].length, amount)
|
|
})
|
|
|
|
it('returns entries with gte and amount', async () => {
|
|
const amount = 12
|
|
|
|
const it = log1.iterator({
|
|
gte: startHash,
|
|
amount
|
|
})
|
|
|
|
let i = 0
|
|
for await (const entry of it) {
|
|
strictEqual(entry.payload, 'entry' + (79 - i++))
|
|
}
|
|
|
|
strictEqual(i, amount)
|
|
})
|
|
|
|
it('iterates with lt and gt', async () => {
|
|
const expectedHashes = hashes.slice().slice(0, 12).map(e => e[0])
|
|
const it = log1.iterator({
|
|
gt: expectedHashes[0],
|
|
lt: expectedHashes[expectedHashes.length - 1]
|
|
})
|
|
const result = await all(it)
|
|
const hashes_ = await Promise.all([...result.reverse()].map(e => e.hash))
|
|
|
|
strictEqual(hashes_.length, 10)
|
|
|
|
let i = 0
|
|
for (const h of hashes_) {
|
|
strictEqual(expectedHashes[i + 1], h)
|
|
i++
|
|
}
|
|
strictEqual(i, 10)
|
|
})
|
|
|
|
it('iterates with lt and gte', async () => {
|
|
const expectedHashes = hashes.slice().slice(0, 26).map(e => e[0])
|
|
const it = log1.iterator({
|
|
gte: expectedHashes[0],
|
|
lt: expectedHashes[expectedHashes.length - 1]
|
|
})
|
|
const result = await all(it)
|
|
const hashes_ = await Promise.all([...result].map(e => e.hash))
|
|
|
|
strictEqual(hashes_.length, 25)
|
|
strictEqual(hashes_.indexOf(expectedHashes[0]), 24)
|
|
strictEqual(hashes_.indexOf(expectedHashes[expectedHashes.length - 1]), -1)
|
|
strictEqual(hashes_.indexOf(expectedHashes[expectedHashes.length - 2]), 0)
|
|
|
|
let i = 0
|
|
for (const h of hashes_) {
|
|
strictEqual(expectedHashes[expectedHashes.length - 2 - i], h)
|
|
i++
|
|
}
|
|
strictEqual(i, 25)
|
|
})
|
|
|
|
it('iterates with lte and gt', async () => {
|
|
const expectedHashes = hashes.slice().slice(0, 5).map(e => e[0])
|
|
const it = log1.iterator({
|
|
gt: expectedHashes[0],
|
|
lte: expectedHashes[expectedHashes.length - 1]
|
|
})
|
|
const result = await all(it)
|
|
const hashes_ = await Promise.all([...result].map(e => e.hash))
|
|
|
|
strictEqual(hashes_.length, 4)
|
|
strictEqual(hashes_.indexOf(expectedHashes[0]), -1)
|
|
strictEqual(hashes_.indexOf(expectedHashes[expectedHashes.length - 1]), 0)
|
|
strictEqual(hashes_.indexOf(expectedHashes[expectedHashes.length - 2]), 1)
|
|
strictEqual(hashes_.indexOf(expectedHashes[expectedHashes.length - 3]), 2)
|
|
strictEqual(hashes_.indexOf(expectedHashes[expectedHashes.length - 4]), 3)
|
|
})
|
|
|
|
it('iterates with lte and gte', async () => {
|
|
const expectedHashes = hashes.slice().slice(0, 10).map(e => e[0])
|
|
const it = log1.iterator({
|
|
gte: expectedHashes[0],
|
|
lte: expectedHashes[expectedHashes.length - 1]
|
|
})
|
|
const result = await all(it)
|
|
const hashes_ = await Promise.all([...result].map(e => e.hash))
|
|
|
|
strictEqual(hashes_.length, 10)
|
|
strictEqual(hashes_.indexOf(expectedHashes[0]), 9)
|
|
strictEqual(hashes_.indexOf(expectedHashes[expectedHashes.length - 1]), 0)
|
|
|
|
let i = 0
|
|
for (const h of hashes_) {
|
|
strictEqual(expectedHashes[expectedHashes.length - 1 - i], h)
|
|
i++
|
|
}
|
|
strictEqual(i, 10)
|
|
})
|
|
|
|
it('iterates the full log by default', async () => {
|
|
const expectedHashes = hashes.slice().map(e => e[0])
|
|
const it = log1.iterator({})
|
|
const result = await all(it)
|
|
const hashes_ = await Promise.all([...result].map(e => e.hash))
|
|
|
|
strictEqual(hashes_.length, logSize)
|
|
|
|
let i = 0
|
|
for (const h of hashes_) {
|
|
strictEqual(expectedHashes[expectedHashes.length - 1 - i], h)
|
|
i++
|
|
}
|
|
|
|
strictEqual(i, logSize)
|
|
})
|
|
|
|
it('iterates the full log with gte and lte and amount', async () => {
|
|
const expectedHashes = hashes.slice().map(e => e[0])
|
|
const it = log1.iterator({
|
|
gte: expectedHashes[0],
|
|
lte: expectedHashes[expectedHashes.length - 1],
|
|
amount: logSize
|
|
})
|
|
const result = await all(it)
|
|
const hashes_ = await Promise.all([...result].map(e => e.hash))
|
|
|
|
strictEqual(hashes_.length, logSize)
|
|
|
|
let i = 0
|
|
for (const h of hashes_) {
|
|
strictEqual(expectedHashes[expectedHashes.length - 1 - i], h)
|
|
i++
|
|
}
|
|
|
|
strictEqual(i, logSize)
|
|
})
|
|
|
|
it('returns length with gt and default amount', async () => {
|
|
const it = log1.iterator({
|
|
gt: startHash
|
|
})
|
|
|
|
const result = await all(it)
|
|
|
|
strictEqual([...result].length, 32)
|
|
})
|
|
|
|
it('returns entries with gt and default amount', async () => {
|
|
const it = log1.iterator({
|
|
gt: startHash
|
|
})
|
|
|
|
let i = 0
|
|
for await (const entry of it) {
|
|
strictEqual(entry.payload, 'entry' + (logSize - 1 - i++))
|
|
}
|
|
|
|
strictEqual(i, 32)
|
|
})
|
|
|
|
it('returns length with gte and default amount', async () => {
|
|
const it = await log1.iterator({
|
|
gte: startHash
|
|
})
|
|
|
|
const result = await all(it)
|
|
|
|
strictEqual([...result].length, 33)
|
|
})
|
|
|
|
it('returns entries with gte and default amount', async () => {
|
|
const it = log1.iterator({
|
|
gte: startHash
|
|
})
|
|
|
|
let i = 0
|
|
for await (const entry of it) {
|
|
strictEqual(entry.payload, 'entry' + (logSize - 1 - i++))
|
|
}
|
|
|
|
strictEqual(i, 33)
|
|
})
|
|
|
|
it('returns length with lt and default amount value', async () => {
|
|
const it = log1.iterator({
|
|
lt: startHash
|
|
})
|
|
|
|
const result = await all(it)
|
|
|
|
strictEqual([...result].length, 67)
|
|
})
|
|
|
|
it('returns entries with lt and default amount value', async () => {
|
|
const it = log1.iterator({
|
|
lt: startHash
|
|
})
|
|
|
|
let i = 0
|
|
for await (const entry of it) {
|
|
strictEqual(entry.payload, 'entry' + (66 - i++))
|
|
}
|
|
strictEqual(i, 67)
|
|
})
|
|
|
|
it('returns length with lte and default amount value', async () => {
|
|
const it = log1.iterator({
|
|
lte: startHash
|
|
})
|
|
|
|
const result = await all(it)
|
|
|
|
strictEqual([...result].length, 68)
|
|
})
|
|
|
|
it('returns entries with lte and default amount value', async () => {
|
|
const it = log1.iterator({
|
|
lte: startHash
|
|
})
|
|
|
|
let i = 0
|
|
for await (const entry of it) {
|
|
strictEqual(entry.payload, 'entry' + (67 - i++))
|
|
}
|
|
|
|
strictEqual(i, 68)
|
|
})
|
|
|
|
it('returns zero entries when amount is 0', async () => {
|
|
const it = log1.iterator({
|
|
amount: 0
|
|
})
|
|
|
|
let i = 0
|
|
for await (const entry of it) { // eslint-disable-line no-unused-vars
|
|
i++
|
|
}
|
|
|
|
strictEqual(i, 0)
|
|
})
|
|
})
|
|
|
|
describe('Iteration over forked/joined logs', async () => {
|
|
let fixture, identities, heads
|
|
|
|
before(async () => {
|
|
identities = [testIdentity3, testIdentity2, testIdentity3, testIdentity]
|
|
fixture = await createLogWithSixteenEntries(Log, ipfs, identities)
|
|
heads = await fixture.log.heads()
|
|
})
|
|
|
|
it('returns the full length from all heads', async () => {
|
|
const it = fixture.log.iterator({
|
|
lte: heads
|
|
})
|
|
|
|
const result = await all(it)
|
|
|
|
strictEqual([...result].length, 16)
|
|
})
|
|
|
|
it('returns partial entries from all heads', async () => {
|
|
const it = fixture.log.iterator({
|
|
lte: heads,
|
|
amount: 6
|
|
})
|
|
|
|
const result = await all(it)
|
|
|
|
deepStrictEqual([...result].map(e => e.payload),
|
|
['entryA10', 'entryA9', 'entryA8', 'entryA7', 'entryC0', 'entryA6'])
|
|
})
|
|
|
|
it('returns partial logs from single heads #1', async () => {
|
|
const it = fixture.log.iterator({
|
|
lte: [heads[0]]
|
|
})
|
|
|
|
const result = await all(it)
|
|
|
|
strictEqual([...result].length, 10)
|
|
})
|
|
|
|
it('returns partial logs from single heads #2', async () => {
|
|
const it = fixture.log.iterator({
|
|
lte: [heads[1]]
|
|
})
|
|
|
|
const result = await all(it)
|
|
|
|
strictEqual([...result].length, 11)
|
|
})
|
|
|
|
it('throws error if lte not a string or array of entries', async () => {
|
|
let errMsg
|
|
|
|
try {
|
|
const it = fixture.log.iterator({
|
|
lte: false
|
|
})
|
|
await all(it)
|
|
} catch (e) {
|
|
errMsg = e.message
|
|
}
|
|
|
|
strictEqual(errMsg, 'lte must be a string or an array of Entries')
|
|
})
|
|
|
|
it('throws error if lt not a string or array of entries', async () => {
|
|
let errMsg
|
|
|
|
try {
|
|
const it = fixture.log.iterator({
|
|
lt: {}
|
|
})
|
|
await all(it)
|
|
} catch (e) {
|
|
errMsg = e.message
|
|
}
|
|
|
|
strictEqual(errMsg, 'lt must be a string or an array of Entries')
|
|
})
|
|
})
|
|
})
|
|
})
|