From 743e6792b44f70fbc842898b13c7d4139892e3f3 Mon Sep 17 00:00:00 2001 From: Volker Mische Date: Wed, 12 Dec 2018 14:55:45 +0100 Subject: [PATCH] feat: implementation of the new `get()` function MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BREAKING CHANGE: `get()` is replacing the `getMany()` function. The API docs for it: > Retrieve several IPLD Nodes at once. - `cids` (`Iterable`): the CIDs of the IPLD Nodes that should be retrieved. Returns an async iterator with the IPLD Nodes that correspond to the given `cids`. Throws an error if a IPLD Node can’t be retrieved. --- src/index.js | 90 ++++++++++++++++++++++++++++-------- test/basics.js | 13 ------ test/ipld-all.js | 69 +++++++++++++++------------- test/ipld-bitcoin.js | 74 +++++++++++------------------- test/ipld-dag-cbor.js | 33 ++++--------- test/ipld-dag-pb.js | 102 +++++++++++++++++++---------------------- test/ipld-eth-block.js | 81 +++++++++++++------------------- test/ipld-git.js | 75 +++++++++++------------------- test/ipld-zcash.js | 74 +++++++++++------------------- 9 files changed, 277 insertions(+), 334 deletions(-) diff --git a/src/index.js b/src/index.js index 690c015..9dfa7d6 100644 --- a/src/index.js +++ b/src/index.js @@ -146,29 +146,56 @@ class IPLDResolver { /** * Get multiple nodes back from an array of CIDs. * - * @param {Array} cids - * @param {function(Error, Array)} callback - * @returns {void} + * @param {Iterable.} cids - The CIDs of the IPLD Nodes that should be retrieved. + * @returns {Iterable.>} - Returns an async iterator with the IPLD Nodes that correspond to the given `cids`. */ - getMany (cids, callback) { - if (!Array.isArray(cids)) { - return callback(new Error('Argument must be an array of CIDs')) + get (cids) { + if (!typical.isIterable(cids) || typical.isString(cids) || + Buffer.isBuffer(cids)) { + throw new Error('`cids` must be an iterable of CIDs') } - this.bs.getMany(cids, (err, blocks) => { - if (err) { - return callback(err) + + let blocks + const next = () => { + // End of iteration if there aren't any blocks left to return + if (cids.length === 0 || + (blocks !== undefined && blocks.length === 0) + ) { + return Promise.resolve({ done: true }) } - map(blocks, (block, mapCallback) => { - // TODO vmx 2018-12-07: Make this one async/await once - // `util.serialize()` is a Promise - this._getFormat(block.cid.codec).then((format) => { - format.util.deserialize(block.data, mapCallback) - }).catch((err) => { - mapCallback(err) - }) - }, - callback) - }) + + return new Promise(async (resolve, reject) => { + // Lazy load block. + // Currntly the BlockService return all nodes as an array. In the + // future this will also be an iterator + if (blocks === undefined) { + const cidsArray = Array.from(cids) + this.bs.getMany(cidsArray, async (err, returnedBlocks) => { + if (err) { + return reject(err) + } + blocks = returnedBlocks + const block = blocks.shift() + try { + const node = await this._deserialize(block) + return resolve({ done: false, value: node }) + } catch (err) { + return reject(err) + } + }) + } else { + const block = blocks.shift() + try { + const node = await this._deserialize(block) + return resolve({ done: false, value: node }) + } catch (err) { + return reject(err) + } + } + }) + } + + return fancyIterator(next) } /** @@ -410,6 +437,29 @@ class IPLDResolver { }) } + /** + * Deserialize a given block + * + * @param {Object} block - The block to deserialize + * @return {Object} = Returns the deserialized node + */ + async _deserialize (block) { + return new Promise((resolve, reject) => { + this._getFormat(block.cid.codec).then((format) => { + // TODO vmx 2018-12-11: Make this one async/await once + // `util.serialize()` is a Promise + format.util.deserialize(block.data, (err, deserialized) => { + if (err) { + return reject(err) + } + return resolve(deserialized) + }) + }).catch((err) => { + return reject(err) + }) + }) + } + /** * Return a CID instance if it is a link. * diff --git a/test/basics.js b/test/basics.js index a88fc46..a6d0eaa 100644 --- a/test/basics.js +++ b/test/basics.js @@ -50,19 +50,6 @@ module.exports = (repo) => { 'No resolver found for codec "blake2b-8"') }) - // TODO vmx 2018-11-29 Change this test to use `get()`. - // it('_get - errors on unknown resolver', (done) => { - // const bs = new BlockService(repo) - // const r = new IPLDResolver({ blockService: bs }) - // // choosing a format that is not supported - // const cid = new CID(1, 'base1', multihash.encode(Buffer.from('abcd', 'hex'), 'sha1')) - // r.get(cid, (err, result) => { - // expect(err).to.exist() - // expect(err.message).to.eql('No resolver found for codec "base1"') - // done() - // }) - // } - it('put - errors on unknown resolver', async () => { const bs = new BlockService(repo) const r = new IPLDResolver({ blockService: bs }) diff --git a/test/ipld-all.js b/test/ipld-all.js index 7b5bd0b..d21a5f0 100644 --- a/test/ipld-all.js +++ b/test/ipld-all.js @@ -8,8 +8,10 @@ */ const chai = require('chai') +const chaiAsProised = require('chai-as-promised') const dirtyChai = require('dirty-chai') const expect = chai.expect +chai.use(chaiAsProised) chai.use(dirtyChai) const dagPB = require('ipld-dag-pb') const dagCBOR = require('ipld-dag-cbor') @@ -104,49 +106,50 @@ describe('IPLD Resolver for dag-cbor + dag-pb', () => { }) }) - describe('getMany', () => { - it('should return nodes correctly', (done) => { - resolver.getMany([cidCbor, cidPb], (err, result) => { - expect(err).to.not.exist() - expect(result.length).to.equal(2) - expect(result).to.deep.equal([nodeCbor, nodePb]) - done() - }) + describe('get', () => { + it('should return nodes correctly', async () => { + const result = resolver.get([cidCbor, cidPb]) + const node1 = await result.first() + expect(node1).to.eql(nodeCbor) + + const node2 = await result.first() + expect(node2).to.eql(nodePb) }) - it('should return nodes in input order', (done) => { - resolver.getMany([cidPb, cidCbor], (err, result) => { - expect(err).to.not.exist() - expect(result.length).to.equal(2) - expect(result).to.deep.equal([nodePb, nodeCbor]) - done() - }) + it('should return nodes in input order', async () => { + const result = resolver.get([cidPb, cidCbor]) + const node1 = await result.first() + expect(node1).to.eql(nodePb) + + const node2 = await result.first() + expect(node2).to.eql(nodeCbor) }) - it('should return error on invalid CID', (done) => { - resolver.getMany([cidCbor, 'invalidcid'], (err, result) => { - expect(err.message).to.equal('Not a valid cid') - expect(result).to.be.undefined() - done() - }) + it('should return error on invalid CID', async () => { + const result = resolver.get([cidCbor, 'invalidcid']) + // TODO vmx 2018-12-11: This should really fail on the second node + // we get, as the first one is valid. This is only possible once + // the `getmany()` call of the BlockService takes and returns an + // iterator and not an array. + await expect(result.next()).to.be.rejectedWith( + 'Not a valid cid') }) - it('should return error on non-existent CID', (done) => { + it('should return error on non-existent CID', async () => { const nonExistentCid = new CID( 'Qma4hjFTnCasJ8PVp3mZbZK5g2vGDT4LByLJ7m8ciyRFZP') - resolver.getMany([cidCbor, nonExistentCid], (err, result) => { - expect(err.message).to.equal('Not Found') - expect(result).to.be.undefined() - done() - }) + const result = resolver.get([cidCbor, nonExistentCid]) + // TODO vmx 2018-12-11: This should really fail on the second node + // we get, as the first one is valid. This is only possible once + // the `getmany()` call of the BlockService takes and returns an + // iterator and not an array. + await expect(result.next()).to.be.rejectedWith( + 'Not Found') }) - it('should return error on invalid input', (done) => { - resolver.getMany('astring', (err, result) => { - expect(err.message).to.equal('Argument must be an array of CIDs') - expect(result).to.be.undefined() - done() - }) + it('should return error on invalid input', () => { + expect(() => resolver.get('astring')).to.throw( + '`cids` must be an iterable of CIDs') }) }) }) diff --git a/test/ipld-bitcoin.js b/test/ipld-bitcoin.js index bf7f6a9..c3c6a75 100644 --- a/test/ipld-bitcoin.js +++ b/test/ipld-bitcoin.js @@ -102,18 +102,6 @@ module.exports = (repo) => { resolver._put(nc.cid, nc.node, cb) }, done) }) - - // TODO vmx 2018-11-30 Change this test to use `get()`. - // it('resolver._get', (done) => { - // resolver.put(node1, { cid: cid1 }, (err) => { - // expect(err).to.not.exist() - // resolver.get(cid1, (err, result) => { - // expect(err).to.not.exist() - // expect(node1.version).to.eql(result.value.version) - // done() - // }) - // }) - // }) }) describe('public api', () => { @@ -139,19 +127,6 @@ module.exports = (repo) => { expect(mh.name).to.equal('sha3-512') }) - // TODO vmx 2018-11-30: Implement getting the whole object properly - // it('root path (same as get)', (done) => { - // resolver.get(cid1, '/', (err, result) => { - // expect(err).to.not.exist() - // - // ipldBitcoin.util.cid(result.value, (err, cid) => { - // expect(err).to.not.exist() - // expect(cid).to.eql(cid1) - // done() - // }) - // }) - // }) - it('resolves value within 1st node scope', async () => { const result = resolver.resolve(cid1, 'version') const node = await result.first() @@ -187,27 +162,34 @@ module.exports = (repo) => { expect(node3.value).to.eql(1) }) - // // TODO vmx 2018-11-30: remove this `get()` call with the new `get()` - // it('resolver.remove', (done) => { - // resolver.put(node1, { cid: cid1 }, (err) => { - // expect(err).to.not.exist() - // resolver.get(cid1, (err, result) => { - // expect(err).to.not.exist() - // expect(result.value.version).to.eql(1) - // remove() - // }) - // }) - // - // function remove () { - // resolver.remove(cid1, (err) => { - // expect(err).to.not.exist() - // resolver.get(cid1, (err) => { - // expect(err).to.exist() - // done() - // }) - // }) - // } - // }) + it('resolver.get round-trip', async () => { + const resultPut = resolver.put([node1], multicodec.BITCOIN_BLOCK) + const cid = await resultPut.first() + const resultGet = resolver.get([cid]) + const node = await resultGet.first() + expect(node).to.deep.equal(node1) + }) + + it('resolver.remove', async () => { + const resultPut = resolver.put([node1], multicodec.BITCOIN_BLOCK) + const cid = await resultPut.first() + const resultGet = resolver.get([cid]) + const sameAsNode1 = await resultGet.first() + expect(sameAsNode1).to.deep.equal(node1) + return remove() + + function remove () { + return new Promise((resolve, reject) => { + resolver.remove(cid, (err) => { + expect(err).to.not.exist() + const resultGet = resolver.get([cid]) + expect(resultGet.next()).to.eventually.be.rejected() + .then(() => resolve()) + .catch((err) => reject(err)) + }) + }) + } + }) }) }) } diff --git a/test/ipld-dag-cbor.js b/test/ipld-dag-cbor.js index 4d99743..5a5d4e1 100644 --- a/test/ipld-dag-cbor.js +++ b/test/ipld-dag-cbor.js @@ -89,18 +89,6 @@ module.exports = (repo) => { resolver._put(nc.cid, nc.node, cb) }, done) }) - - // TODO vmx 2018-11-30 Change this test to use `get()`. - // it('resolver._get', (done) => { - // resolver.put(node1, { cid: cid1 }, (err) => { - // expect(err).to.not.exist() - // resolver._get(cid1, (err, node) => { - // expect(err).to.not.exist() - // expect(node1).to.eql(node) - // done() - // }) - // }) - // }) }) describe('public api', () => { @@ -127,19 +115,6 @@ module.exports = (repo) => { expect(mh.name).to.equal('sha3-512') }) - // TODO vmx 2018-11-30: Implement getting the whole object properly - // it('resolver.get root path', (done) => { - // resolver.get(cid1, '/', (err, result) => { - // expect(err).to.not.exist() - // - // dagCBOR.util.cid(result.value, (err, cid) => { - // expect(err).to.not.exist() - // expect(cid).to.eql(cid1) - // done() - // }) - // }) - // }) - it('resolves value within 1st node scope', async () => { const result = resolver.resolve(cid1, 'someData') const node = await result.first() @@ -193,6 +168,14 @@ module.exports = (repo) => { 'path not available at root') }) + it('resolver.get round-trip', async () => { + const resultPut = resolver.put([node1], multicodec.DAG_CBOR) + const cid = await resultPut.first() + const resultGet = resolver.get([cid]) + const node = await resultGet.first() + expect(node).to.deep.equal(node1) + }) + it('resolver.tree', (done) => { pull( resolver.treeStream(cid3), diff --git a/test/ipld-dag-pb.js b/test/ipld-dag-pb.js index bb2eeaa..6908256 100644 --- a/test/ipld-dag-pb.js +++ b/test/ipld-dag-pb.js @@ -2,8 +2,10 @@ 'use strict' const chai = require('chai') +const chaiAsProised = require('chai-as-promised') const dirtyChai = require('dirty-chai') const expect = chai.expect +chai.use(chaiAsProised) chai.use(dirtyChai) const BlockService = require('ipfs-block-service') const dagPB = require('ipld-dag-pb') @@ -116,17 +118,6 @@ module.exports = (repo) => { resolver._put(nc.cid, nc.node, cb) }, done) }) - - // TODO vmx 2018-11-29 Change this test to use `get()`. - // it('resolver._get', (done) => { - // resolver.put(node1, { cid: cid1 }, (err) => { - // expect(err).to.not.exist() - // resolver._get(cid1, (err, node) => { - // expect(err).to.not.exist() - // done() - // }) - // }) - // }) }) describe('public api', () => { @@ -152,19 +143,6 @@ module.exports = (repo) => { expect(mh.name).to.equal('sha3-512') }) - // TODO vmx 2018-11-29: Change this test to use the new `get()` - // it('resolver.get with empty path', (done) => { - // resolver.get(cid1, '/', (err, result) => { - // expect(err).to.not.exist() - // - // dagPB.util.cid(result.value, (err, cid) => { - // expect(err).to.not.exist() - // expect(cid).to.eql(cid1) - // done() - // }) - // }) - // }) - it('resolves a value within 1st node scope', async () => { const result = resolver.resolve(cid1, 'Data') const node = await result.first() @@ -200,36 +178,52 @@ module.exports = (repo) => { expect(node3.value).to.eql(Buffer.from('I am 1')) }) - // TODO vmx 2018-11-29: Think about if every returned node should contain - // a `cid` field or not - // it('resolver.get value within nested scope (1 level) returns cid of node traversed to', (done) => { - // resolver.get(cid2, 'Links/0/Hash/Data', (err, result) => { - // expect(err).to.not.exist() - // expect(result.cid).to.deep.equal(cid1) - // done() - // }) - // }) - - // TODO vmx 2018-11-29: remove this `get()` call with the new `get()` - // it('resolver.remove', (done) => { - // resolver.put(node1, { cid: cid1 }, (err) => { - // expect(err).to.not.exist() - // resolver.get(cid1, (err, node) => { - // expect(err).to.not.exist() - // remove() - // }) - // }) - // - // function remove () { - // resolver.remove(cid1, (err) => { - // expect(err).to.not.exist() - // resolver.get(cid1, (err) => { - // expect(err).to.exist() - // done() - // }) - // }) - // } - // }) + it('resolver.get round-trip', async () => { + const resultPut = resolver.put([node1], multicodec.DAG_PB) + const cid = await resultPut.first() + const resultGet = resolver.get([cid]) + const node = await resultGet.first() + // `size` is lazy, without a call to it a deep equal check would fail + const _ = node.size // eslint-disable-line no-unused-vars + expect(node).to.deep.equal(node1) + }) + + it('resolver.remove', async () => { + // TODO vmx 2018-12-12: The same repo is used for all tests, there + // seems to be some race condition with inserting and removing items. + // Hence create a unique item for this test. Though the tests + // should really be independent so that there are no race conditions. + const createNode = new Promise((resolve, reject) => { + const data = Buffer.from('a dag-pb node') + dagPB.DAGNode.create(data, (err, node) => { + if (err) { + return reject(err) + } + return resolve(node) + }) + }) + const node = await createNode + const resultPut = resolver.put([node], multicodec.DAG_PB) + const cid = await resultPut.first() + const resultGet = resolver.get([cid]) + const sameAsNode = await resultGet.first() + // `size` is lazy, without a call to it a deep equal check would fail + const _ = sameAsNode.size // eslint-disable-line no-unused-vars + expect(sameAsNode.data).to.deep.equal(node.data) + return remove() + + function remove () { + return new Promise((resolve, reject) => { + resolver.remove(cid, (err) => { + expect(err).to.not.exist() + const resultGet = resolver.get([cid]) + expect(resultGet.next()).to.eventually.be.rejected() + .then(() => resolve()) + .catch((err) => reject(err)) + }) + }) + } + }) }) }) } diff --git a/test/ipld-eth-block.js b/test/ipld-eth-block.js index 72f25fa..4a3c4bd 100644 --- a/test/ipld-eth-block.js +++ b/test/ipld-eth-block.js @@ -59,20 +59,6 @@ module.exports = (repo) => { resolver._put(nc.cid, nc.node, cb) }, done) }) - - // TODO vmx 2018-11-30 Change this test to use `get()`. - // it('resolver._get', (done) => { - // resolver.put(node1, { cid: cid1 }, (err) => { - // expect(err).to.not.exist() - // resolver.get(cid1, (err, result) => { - // expect(err).to.not.exist() - // expect(node1.number.toString('hex')).to.eql('01') - // expect(node1.raw).to.eql(result.value.raw) - // expect(node1.hash()).to.eql(result.value.hash()) - // done() - // }) - // }) - // }) }) describe('public api', () => { @@ -98,19 +84,6 @@ module.exports = (repo) => { expect(mh.name).to.equal('keccak-512') }) - // TODO vmx 2018-11-30: Implement getting the whole object properly - // it('root path (same as get)', (done) => { - // resolver.get(cid1, '/', (err, result) => { - // expect(err).to.not.exist() - // - // ipldEthBlock.util.cid(result.value, (err, cid) => { - // expect(err).to.not.exist() - // expect(cid).to.eql(cid1) - // done() - // }) - // }) - // }) - it('resolves value within 1st node scope', async () => { const result = resolver.resolve(cid1, 'number') const node = await result.first() @@ -146,29 +119,37 @@ module.exports = (repo) => { expect(node3.value.toString('hex')).to.eql('01') }) - // TODO vmx 2018-11-30: remove this `get()` call with the new `get()` - // it('resolver.remove', (done) => { - // resolver.put(node1, { cid: cid1 }, (err) => { - // expect(err).to.not.exist() - // resolver.get(cid1, (err, result) => { - // expect(err).to.not.exist() - // const node = result.value - // expect(node1.raw).to.eql(node.raw) - // expect(node1.hash()).to.eql(node.hash()) - // remove() - // }) - // }) - // - // function remove () { - // resolver.remove(cid1, (err) => { - // expect(err).to.not.exist() - // resolver.get(cid1, (err) => { - // expect(err).to.exist() - // done() - // }) - // }) - // } - // }) + it('resolver.get round-trip', async () => { + const resultPut = resolver.put([node1], multicodec.ETH_BLOCK) + const cid = await resultPut.first() + const resultGet = resolver.get([cid]) + const node = await resultGet.first() + // TODO vmx 2018-12-12: Find out why the full nodes not deep equal + expect(node.raw).to.deep.equal(node1.raw) + }) + + it('resolver.remove', async () => { + const resultPut = resolver.put([node1], multicodec.ETH_BLOCK) + const cid = await resultPut.first() + const resultGet = resolver.get([cid]) + const sameAsNode1 = await resultGet.first() + expect(sameAsNode1.raw).to.deep.equal(node1.raw) + return remove() + + function remove () { + return new Promise((resolve, reject) => { + resolver.remove(cid, (err) => { + expect(err).to.not.exist() + const resultGet = resolver.get([cid]) + expect(resultGet.first()).to.eventually.be.rejected() + // eslint-disable-next-line max-nested-callbacks + .then(() => resolve()) + // eslint-disable-next-line max-nested-callbacks + .catch((err) => reject(err)) + }) + }) + } + }) }) }) } diff --git a/test/ipld-git.js b/test/ipld-git.js index 1111432..a6ba834 100644 --- a/test/ipld-git.js +++ b/test/ipld-git.js @@ -155,18 +155,6 @@ module.exports = (repo) => { resolver._put(nc.cid, nc.node, cb) }, done) }) - - // TODO vmx 2018-11-30 Change this test to use `get()`. - // it('resolver._get', (done) => { - // resolver.put(blobNode, { cid: blobCid }, (err) => { - // expect(err).to.not.exist() - // resolver.get(blobCid, (err, result) => { - // expect(err).to.not.exist() - // expect(blobNode.toString('hex')).to.eql(result.value.toString('hex')) - // done() - // }) - // }) - // }) }) describe('public api', () => { @@ -192,19 +180,6 @@ module.exports = (repo) => { expect(mh.name).to.equal('sha3-512') }) - // TODO vmx 2018-11-30: Implement getting the whole object properly - // it('resolver.get empty path', (done) => { - // resolver.get(blobCid, '', (err, result) => { - // expect(err).to.not.exist() - // - // ipldGit.util.cid(result.value, (err, cid) => { - // expect(err).to.not.exist() - // expect(cid).to.eql(blobCid) - // done() - // }) - // }) - // }) - it('resolves value within 1st node scope', async () => { const result = resolver.resolve(commitCid, 'message') const node = await result.first() @@ -267,28 +242,34 @@ module.exports = (repo) => { expect(last.value).to.eql(blobNode) }) - // // TODO vmx 2018-11-30: remove this `get()` call with the new `get()` - // it('resolver.remove', (done) => { - // resolver.put(blobNode, { cid: blobCid }, (err) => { - // expect(err).to.not.exist() - // resolver.get(blobCid, (err, result) => { - // expect(err).to.not.exist() - // const node = result.value - // expect(blobNode.toString('hex')).to.eql(node.toString('hex')) - // remove() - // }) - // }) - // - // function remove () { - // resolver.remove(blobCid, (err) => { - // expect(err).to.not.exist() - // resolver.get(blobCid, (err) => { - // expect(err).to.exist() - // done() - // }) - // }) - // } - // }) + it('resolver.get round-trip', async () => { + const resultPut = resolver.put([blobNode], multicodec.GIT_RAW) + const cid = await resultPut.first() + const resultGet = resolver.get([cid]) + const node = await resultGet.first() + expect(node).to.deep.equal(blobNode) + }) + + it('resolver.remove', async () => { + const resultPut = resolver.put([blobNode], multicodec.GIT_RAW) + const cid = await resultPut.first() + const resultGet = resolver.get([cid]) + const sameAsBlobNode = await resultGet.first() + expect(sameAsBlobNode).to.deep.equal(blobNode) + return remove() + + function remove () { + return new Promise((resolve, reject) => { + resolver.remove(cid, (err) => { + expect(err).to.not.exist() + const resultGet = resolver.get([cid]) + expect(resultGet.next()).to.eventually.be.rejected() + .then(() => resolve()) + .catch((err) => reject(err)) + }) + }) + } + }) }) }) } diff --git a/test/ipld-zcash.js b/test/ipld-zcash.js index 19b4c39..6c0c7cb 100644 --- a/test/ipld-zcash.js +++ b/test/ipld-zcash.js @@ -107,18 +107,6 @@ module.exports = (repo) => { resolver._put(nc.cid, nc.node, cb) }, done) }) - - // // TODO vmx 2018-11-30 Change this test to use `get()`. - // it('resolver._get', (done) => { - // resolver.put(node1, { cid: cid1 }, (err) => { - // expect(err).to.not.exist() - // resolver.get(cid1, (err, result) => { - // expect(err).to.not.exist() - // expect(node1.version).to.eql(result.value.version) - // done() - // }) - // }) - // }) }) describe('public api', () => { @@ -144,19 +132,6 @@ module.exports = (repo) => { expect(mh.name).to.equal('sha3-512') }) - // // TODO vmx 2018-11-30: Implement getting the whole object properly - // it('root path (same as get)', (done) => { - // resolver.get(cid1, '/', (err, result) => { - // expect(err).to.not.exist() - // - // ipldZcash.util.cid(result.value, (err, cid) => { - // expect(err).to.not.exist() - // expect(cid).to.eql(cid1) - // done() - // }) - // }) - // }) - it('resolves value within 1st node scope', async () => { const result = resolver.resolve(cid1, 'version') const node = await result.first() @@ -192,27 +167,34 @@ module.exports = (repo) => { expect(node3.value).to.eql(1) }) - // // TODO vmx 2018-11-30: remove this `get()` call with the new `get()` - // it('resolver.remove', (done) => { - // resolver.put(node1, { cid: cid1 }, (err) => { - // expect(err).to.not.exist() - // resolver.get(cid1, (err, result) => { - // expect(err).to.not.exist() - // expect(result.value.version).to.eql(1) - // remove() - // }) - // }) - // - // function remove () { - // resolver.remove(cid1, (err) => { - // expect(err).to.not.exist() - // resolver.get(cid1, (err) => { - // expect(err).to.exist() - // done() - // }) - // }) - // } - // }) + it('resolver.get round-trip', async () => { + const resultPut = resolver.put([node1], multicodec.ZCASH_BLOCK) + const cid = await resultPut.first() + const resultGet = resolver.get([cid]) + const node = await resultGet.first() + expect(node.toString()).to.deep.equal(node1.toString()) + }) + + it('resolver.remove', async () => { + const resultPut = resolver.put([node1], multicodec.ZCASH_BLOCK) + const cid = await resultPut.first() + const resultGet = resolver.get([cid]) + const sameAsNode1 = await resultGet.first() + expect(sameAsNode1).to.deep.equal(node1) + return remove() + + function remove () { + return new Promise((resolve, reject) => { + resolver.remove(cid, (err) => { + expect(err).to.not.exist() + const resultGet = resolver.get([cid]) + expect(resultGet.next()).to.eventually.be.rejected() + .then(() => resolve()) + .catch((err) => reject(err)) + }) + }) + } + }) }) }) }