/* globals describe, it */ import * as codec from '../src/codecs/json.js' import { sha256 as hasher } from '../src/hashes/sha2.js' import * as main from '../src/block.js' import { walk } from '../src/traversal.js' import { fromString } from '../src/bytes.js' import { assert } from 'aegir/chai' /** @typedef {import('../src/cid.js').CID} CID */ // from dag-pb, simplified /** * @param {Uint8Array} data * @param {{Hash:CID, Name:string, Tsize:number}[]} links * @returns {{Data:Uint8Array, Links:{Hash:CID, Name:string, Tsize:number}[]}} */ function createNode (data, links) { return { Data: data, Links: links } } /** * @param {string} name * @param {number} size * @param {CID} cid * @returns {{Hash:CID, Name:string, Tsize:number}} */ function createLink (name, size, cid) { return { Hash: cid, Name: name, Tsize: size } } describe('traversal', () => { describe('walk', async () => { // Forming the following DAG for testing // A // / \ // B C // / \ / \ // D D D E const linksE = /** @type {[]} */([]) const valueE = createNode(fromString('string E qacdswa'), linksE) const blockE = await main.encode({ value: valueE, codec, hasher }) const cidE = blockE.cid const linksD = /** @type {[]} */([]) const valueD = createNode(fromString('string D zasa'), linksD) const blockD = await main.encode({ value: valueD, codec, hasher }) const cidD = blockD.cid const linksC = [createLink('link1', 100, cidD), createLink('link2', 100, cidE)] const valueC = createNode(fromString('string C zxc'), linksC) const blockC = await main.encode({ value: valueC, codec, hasher }) const cidC = blockC.cid const linksB = [createLink('link1', 100, cidD), createLink('link2', 100, cidD)] const valueB = createNode(fromString('string B lpokjiasd'), linksB) const blockB = await main.encode({ value: valueB, codec, hasher }) const cidB = blockB.cid const linksA = [createLink('link1', 100, cidB), createLink('link2', 100, cidC)] const valueA = createNode(fromString('string A qwertcfdgshaa'), linksA) const blockA = await main.encode({ value: valueA, codec, hasher }) const cidA = blockA.cid /** * @param {CID} cid */ const load = async (cid) => { if (cid.equals(cidE)) { return blockE } if (cid.equals(cidD)) { return blockD } if (cid.equals(cidC)) { return blockC } if (cid.equals(cidB)) { return blockB } if (cid.equals(cidA)) { return blockA } return null } /** * @param {typeof load} load * @param {string[]} arr */ const loadWrapper = (load, arr = []) => /** * @param {CID} cid */ (cid) => { arr.push(cid.toString()) return load(cid) } it('block with no links', async () => { // Test Case 1 // Input DAG // D // // Expect load to be called with D const expectedCallArray = [cidD.toString()] /** @type {string[]} */ const callArray = [] await walk({ cid: cidD, load: loadWrapper(load, callArray) }) expectedCallArray.forEach((value, index) => { assert.deepStrictEqual(value, callArray[index]) }) }) it('block with links', async () => { // Test Case 2 // Input // C // / \ // D E // // Expect load to be called with C, then D, then E const expectedCallArray = [cidC.toString(), cidD.toString(), cidE.toString()] /** @type {string[]} */ const callArray = [] await walk({ cid: cidC, load: loadWrapper(load, callArray) }) expectedCallArray.forEach((value, index) => { assert.deepStrictEqual(value, callArray[index]) }) }) it('block with matching links', async () => { // Test Case 3 // Input // B // / \ // D D // // Expect load to be called with B, then D const expectedCallArray = [cidB.toString(), cidD.toString()] /** @type {string[]} */ const callArray = [] await walk({ cid: cidB, load: loadWrapper(load, callArray) }) expectedCallArray.forEach((value, index) => { assert.deepStrictEqual(value, callArray[index]) }) }) it('depth first with duplicated block', async () => { // Test Case 4 // Input // A // / \ // B C // / \ / \ // D D D E // // Expect load to be called with A, then B, then D, then C, then E const expectedCallArray = [ cidA.toString(), cidB.toString(), cidD.toString(), cidC.toString(), cidE.toString() ] /** @type {string[]} */ const callArray = [] await walk({ cid: cidA, load: loadWrapper(load, callArray) }) expectedCallArray.forEach((value, index) => { assert.deepStrictEqual(value, callArray[index]) }) }) it('null return', async () => { /** @type {[]} */ const links = [] const value = createNode(fromString('test'), links) const block = await main.encode({ value, codec, hasher }) const cid = block.cid const expectedCallArray = [cid.toString()] /** @type {string[]} */ const callArray = [] await walk({ cid, load: loadWrapper(load, callArray) }) expectedCallArray.forEach((value, index) => { assert.deepStrictEqual(value, callArray[index]) }) }) }) })