From 75f8899ee31ebccbe1a7364689e74bbea124cd64 Mon Sep 17 00:00:00 2001 From: David Dias Date: Fri, 21 Oct 2016 07:38:47 +0100 Subject: [PATCH 1/5] feat: block API updated to use CID --- package.json | 4 ++-- src/block.js | 21 +++++++++++++-------- 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/package.json b/package.json index 69c877b1..c391a1a3 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "interface-ipfs-core", "version": "0.15.0", "description": "A test suite and interface you can use to implement a IPFS core interface.", - "main": "lib/index.js", + "main": "src/index.js", "jsnext:main": "src/index.js", "scripts": { "test": "exit(0)", @@ -51,4 +51,4 @@ "greenkeeperio-bot ", "nginnever " ] -} \ No newline at end of file +} diff --git a/src/block.js b/src/block.js index 7512bb01..e9ea2ac0 100644 --- a/src/block.js +++ b/src/block.js @@ -6,6 +6,7 @@ const expect = require('chai').expect const Block = require('ipfs-block') const multihash = require('multihashes') +const CID = require('cids') module.exports = (common) => { describe('.block', () => { @@ -34,11 +35,12 @@ module.exports = (common) => { describe('callback API', () => { it('.put a buffer', (done) => { const expectedHash = 'QmPv52ekjS75L4JmHpXVeuJ5uX2ecSfSZo88NSyxwA3rAQ' + const cid = new CID(expectedHash) const blob = Buffer('blorb') - ipfs.block.put(blob, (err, block) => { + ipfs.block.put(blob, cid, (err, block) => { expect(err).to.not.exist - expect(block.key).to.eql(multihash.fromB58String(expectedHash)) + expect(block.key('sha2-256')).to.eql(multihash.fromB58String(expectedHash)) expect(block).to.have.a.property('data', blob) done() }) @@ -46,11 +48,12 @@ module.exports = (common) => { it('.put a block', (done) => { const expectedHash = 'QmPv52ekjS75L4JmHpXVeuJ5uX2ecSfSZo88NSyxwA3rAQ' + const cid = new CID(expectedHash) const blob = new Block(new Buffer('blorb')) - ipfs.block.put(blob, (err, block) => { + ipfs.block.put(blob, cid, (err, block) => { expect(err).to.not.exist - expect(block.key).to.eql(multihash.fromB58String(expectedHash)) + expect(block.key('sha2-256')).to.eql(multihash.fromB58String(expectedHash)) expect(block.data).to.eql(new Buffer('blorb')) done() }) @@ -59,17 +62,18 @@ module.exports = (common) => { it('.put error with array of blocks', () => { const blob = Buffer('blorb') - ipfs.block.put([blob, blob], (err) => { + ipfs.block.put([blob, blob], 'fake cids', (err) => { expect(err).to.be.an.instanceof(Error) }) }) it('block.get', (done) => { const hash = 'QmPv52ekjS75L4JmHpXVeuJ5uX2ecSfSZo88NSyxwA3rAQ' + const cid = new CID(hash) - ipfs.block.get(hash, (err, block) => { + ipfs.block.get(cid, (err, block) => { expect(err).to.not.exist - expect(block.key).to.eql(multihash.fromB58String(hash)) + expect(block.key('sha2-256')).to.eql(cid.multihash) expect(block.data).to.eql(new Buffer('blorb')) done() }) @@ -77,8 +81,9 @@ module.exports = (common) => { it('block.stat', (done) => { const hash = 'QmPv52ekjS75L4JmHpXVeuJ5uX2ecSfSZo88NSyxwA3rAQ' + const cid = new CID(hash) - ipfs.block.stat(hash, (err, stats) => { + ipfs.block.stat(cid, (err, stats) => { expect(err).to.not.exist expect(stats).to.have.property('key') expect(stats).to.have.property('size') From 9850c4a1cdb73b33e8fc704f939e7c1a7c0ef798 Mon Sep 17 00:00:00 2001 From: David Dias Date: Fri, 21 Oct 2016 07:56:02 +0100 Subject: [PATCH 2/5] feat: ensure backwards compatibility at the block API --- src/block.js | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/src/block.js b/src/block.js index e9ea2ac0..ed434722 100644 --- a/src/block.js +++ b/src/block.js @@ -59,6 +59,18 @@ module.exports = (common) => { }) }) + it('.put a block (without using CID, legacy mode)', (done) => { + const expectedHash = 'QmPv52ekjS75L4JmHpXVeuJ5uX2ecSfSZo88NSyxwA3rAQ' + const blob = new Block(new Buffer('blorb')) + + ipfs.block.put(blob, (err, block) => { + expect(err).to.not.exist + expect(block.key('sha2-256')).to.eql(multihash.fromB58String(expectedHash)) + expect(block.data).to.eql(new Buffer('blorb')) + done() + }) + }) + it('.put error with array of blocks', () => { const blob = Buffer('blorb') @@ -79,6 +91,17 @@ module.exports = (common) => { }) }) + it('block.get (without using CID, legacy mode)', (done) => { + const hash = 'QmPv52ekjS75L4JmHpXVeuJ5uX2ecSfSZo88NSyxwA3rAQ' + + ipfs.block.get(hash, (err, block) => { + expect(err).to.not.exist + expect(block.key('sha2-256')).to.eql(multihash.fromB58String(hash)) + expect(block.data).to.eql(new Buffer('blorb')) + done() + }) + }) + it('block.stat', (done) => { const hash = 'QmPv52ekjS75L4JmHpXVeuJ5uX2ecSfSZo88NSyxwA3rAQ' const cid = new CID(hash) From 8dad5228b65ec588eceb1bc8b8819cc8738fbdfb Mon Sep 17 00:00:00 2001 From: David Dias Date: Fri, 21 Oct 2016 08:46:33 +0100 Subject: [PATCH 3/5] feat: adjustments to the ipld-dag-pb format --- src/object.js | 30 +++++++++++++++++------------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/src/object.js b/src/object.js index 39c71c4c..120917e0 100644 --- a/src/object.js +++ b/src/object.js @@ -4,7 +4,8 @@ 'use strict' const expect = require('chai').expect -const DAGNode = require('ipfs-merkle-dag').DAGNode +const dagPB = require('ipld-dag-pb') +const DAGNode = dagPB.DAGNode const bs58 = require('bs58') module.exports = (common) => { @@ -89,7 +90,7 @@ module.exports = (common) => { it('of protobuf encoded buffer', (done) => { const dNode = new DAGNode(new Buffer('Some data')) - const buf = dNode.marshal() + const buf = dagPB.util.serialize(dNode) ipfs.object.put(buf, { enc: 'protobuf' }, (err, node) => { expect(err).to.not.exist @@ -185,8 +186,8 @@ module.exports = (common) => { ipfs.object.get(node1.multihash(), (err, node2) => { expect(err).to.not.exist - // because js-ipfs-api can't infer if the returned Data is Buffer - // or String + // because js-ipfs-api can't infer if the + // returned Data is Buffer or String if (typeof node2.data === 'string') { node2.data = new Buffer(node2.data) } @@ -488,12 +489,13 @@ module.exports = (common) => { let testNode let testNodeWithLink let testLink - before((done) => { - const obj = { - Data: new Buffer('patch test object'), - Links: [] - } + const obj = { + Data: new Buffer('patch test object'), + Links: [] + } + + before((done) => { ipfs.object.put(obj, (err, node) => { expect(err).to.not.exist testNode = node @@ -502,12 +504,14 @@ module.exports = (common) => { }) it('.addLink', (done) => { - const dNode1 = testNode.copy() + const dNode1 = new DAGNode(obj.Data, obj.Links) const dNode2 = new DAGNode(new Buffer('some other node')) - // note: we need to put the linked obj, otherwise IPFS won't timeout - // cause it needs the node to get its size + + // note: we need to put the linked obj, otherwise IPFS won't + // timeout. Reason: it needs the node to get its size ipfs.object.put(dNode2, (err) => { expect(err).to.not.exist + dNode1.addNodeLink('link-to-node', dNode2) ipfs.object.patch.addLink(testNode.multihash(), dNode1.links[0], (err, node3) => { @@ -667,7 +671,7 @@ module.exports = (common) => { }) it('.addLink', () => { - const dNode1 = testNode.copy() + const dNode1 = dagPB.util.deserialize(dagPB.util.serialize(testNode)) const dNode2 = new DAGNode(new Buffer('some other node')) // note: we need to put the linked obj, otherwise IPFS won't timeout // cause it needs the node to get its size From f76f4b6fce9397f8ca63d6d044b9a42cde0d255c Mon Sep 17 00:00:00 2001 From: David Dias Date: Mon, 24 Oct 2016 15:26:29 +0200 Subject: [PATCH 4/5] docs: add base dag API interface --- API/dag/README.md | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 API/dag/README.md diff --git a/API/dag/README.md b/API/dag/README.md new file mode 100644 index 00000000..ae5e3be0 --- /dev/null +++ b/API/dag/README.md @@ -0,0 +1,34 @@ +dag API +======= + +#### `dag.put` + +> Store an IPLD format node + +##### `Go` **WIP** + +##### `JavaScript` - ipfs.dag.put(dagNode, formatMulticodec, hashAlg, callback) + +`dagNode` - a DAG node that follows one of the supported IPLD formats. + +`formatMulticodec` - The IPLD format multicodec. + +`hashAlg` - The hash algorithm to be used over the serialized dagNode. + +`callback` must follow `function (err) {}` signature, where `err` is an error if the operation was not successful. + +If no `callback` is passed, a [promise][] is returned. + +#### `dag.get` + +> Retrieve an IPLD format node + +##### `Go` **WIP** + +##### `JavaScript` - ipfs.object.get(cid, callback) + +`cid` is a [CID][https://github.com/ipfs/js-cid] instance. + +`callback` must follow `function (err, dagNode) {}` signature, where `err` is an error if the operation was not successful and `dagNode` is the IPLD format DAG node retrieved. + +If no `callback` is passed, a [promise][] is returned. From 4281d6f3f9310348ab0f9b5b9532e234836720f2 Mon Sep 17 00:00:00 2001 From: David Dias Date: Thu, 27 Oct 2016 12:23:44 +0200 Subject: [PATCH 5/5] migrate object tests to use dagNode async API --- package.json | 14 +- src/object.js | 892 ++++++++++++++++++++++++++++++++------------------ src/swarm.js | 2 +- 3 files changed, 582 insertions(+), 326 deletions(-) diff --git a/package.json b/package.json index c391a1a3..c24bf558 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "interface-ipfs-core", "version": "0.15.0", "description": "A test suite and interface you can use to implement a IPFS core interface.", - "main": "src/index.js", + "main": "lib/index.js", "jsnext:main": "src/index.js", "scripts": { "test": "exit(0)", @@ -28,19 +28,19 @@ }, "homepage": "https://github.com/ipfs/interface-ipfs-core#readme", "dependencies": { + "async": "^2.1.2", "bl": "^1.1.2", "bs58": "^3.0.0", "chai": "^3.5.0", - "concat-stream": "^1.5.1", + "concat-stream": "^1.5.2", "detect-node": "^2.0.3", - "ipfs-block": "^0.3.0", - "ipfs-merkle-dag": "^0.7.0", + "ipfs-block": "^0.4.0", + "ipld-dag-pb": "^0.1.3", "multihashes": "^0.2.2", - "readable-stream": "1.1.13", - "run-series": "^1.1.4" + "readable-stream": "1.1.13" }, "devDependencies": { - "aegir": "^8.0.0" + "aegir": "^8.1.2" }, "contributors": [ "David Dias ", diff --git a/src/object.js b/src/object.js index 120917e0..0e3e0bcf 100644 --- a/src/object.js +++ b/src/object.js @@ -7,9 +7,10 @@ const expect = require('chai').expect const dagPB = require('ipld-dag-pb') const DAGNode = dagPB.DAGNode const bs58 = require('bs58') +const series = require('async/series') module.exports = (common) => { - describe('.object', () => { + describe.only('.object', () => { let ipfs before(function (done) { @@ -35,8 +36,11 @@ module.exports = (common) => { it('no layout', (done) => { ipfs.object.new((err, node) => { expect(err).to.not.exist - expect(node.toJSON().Hash).to.equal('QmdfTbBqBPQ7VNxZEYEj14VmRuZBkqFbiwReogJgS1zR1n') - done() + node.toJSON((err, obj) => { + expect(err).to.not.exist + expect(obj.Hash).to.equal('QmdfTbBqBPQ7VNxZEYEj14VmRuZBkqFbiwReogJgS1zR1n') + done() + }) }) }) }) @@ -50,11 +54,13 @@ module.exports = (common) => { ipfs.object.put(obj, (err, node) => { expect(err).to.not.exist - const nodeJSON = node.toJSON() - expect(obj.Data).to.deep.equal(nodeJSON.Data) - expect(obj.Links).to.deep.equal(nodeJSON.Links) - expect(nodeJSON.Hash).to.equal('QmPb5f92FxKPYdT3QNBd1GKiL4tZUXUrzF4Hkpdr3Gf1gK') - done() + node.toJSON((err, nodeJSON) => { + expect(err).to.not.exist + expect(obj.Data).to.deep.equal(nodeJSON.Data) + expect(obj.Links).to.deep.equal(nodeJSON.Links) + expect(nodeJSON.Hash).to.equal('QmPb5f92FxKPYdT3QNBd1GKiL4tZUXUrzF4Hkpdr3Gf1gK') + done() + }) }) }) @@ -73,43 +79,69 @@ module.exports = (common) => { ipfs.object.put(buf, { enc: 'json' }, (err, node) => { expect(err).to.not.exist - const nodeJSON = node.toJSON() + node.toJSON((err, nodeJSON) => { + expect(err).to.not.exist - // because js-ipfs-api can't - // infer if the returned Data is Buffer or String - if (typeof node.data === 'string') { - node.data = new Buffer(node.data) - } + // because js-ipfs-api can't + // infer if the returned Data is Buffer or String + if (typeof node.data === 'string') { + node.data = new Buffer(node.data) + } - expect(obj.Data).to.deep.equal(node.data) - expect(obj.Links).to.deep.equal(nodeJSON.Links) - expect(nodeJSON.Hash).to.equal('QmPb5f92FxKPYdT3QNBd1GKiL4tZUXUrzF4Hkpdr3Gf1gK') - done() + expect(obj.Data).to.deep.equal(node.data) + expect(obj.Links).to.deep.equal(nodeJSON.Links) + expect(nodeJSON.Hash).to.equal('QmPb5f92FxKPYdT3QNBd1GKiL4tZUXUrzF4Hkpdr3Gf1gK') + done() + }) }) }) it('of protobuf encoded buffer', (done) => { - const dNode = new DAGNode(new Buffer('Some data')) - const buf = dagPB.util.serialize(dNode) - - ipfs.object.put(buf, { enc: 'protobuf' }, (err, node) => { - expect(err).to.not.exist - expect(dNode.data).to.deep.equal(node.data) - expect(dNode.links).to.deep.equal(node.links) - expect(dNode.multihash()).to.deep.equal(node.multihash()) - done() - }) + const node = new DAGNode(new Buffer('Some data')) + let serialized + let multihash + + series([ + (cb) => { + node.multihash((err, _multihash) => { + expect(err).to.not.exist + multihash = _multihash + cb() + }) + }, + (cb) => { + dagPB.util.serialize(node, (err, _serialized) => { + expect(err).to.not.exist + serialized = _serialized + cb() + }) + }, + (cb) => { + ipfs.object.put(serialized, { enc: 'protobuf' }, (err, storedNode) => { + expect(err).to.not.exist + expect(node.data).to.deep.equal(node.data) + expect(node.links).to.deep.equal(node.links) + storedNode.multihash((err, _multihash) => { + expect(err).to.not.exist + expect(multihash).to.eql(_multihash) + cb() + }) + }) + } + ], done) }) it('of buffer treated as Data field', (done) => { const data = new Buffer('Some data') ipfs.object.put(data, (err, node) => { expect(err).to.not.exist - const nodeJSON = node.toJSON() - expect(data).to.deep.equal(nodeJSON.Data) - expect([]).to.deep.equal(nodeJSON.Links) - expect(nodeJSON.Hash).to.equal('QmPb5f92FxKPYdT3QNBd1GKiL4tZUXUrzF4Hkpdr3Gf1gK') - done() + node.toJSON((err, nodeJSON) => { + expect(err).to.not.exist + expect(data).to.deep.equal(nodeJSON.Data) + expect([]).to.deep.equal(nodeJSON.Links) + expect(nodeJSON.Hash).to.equal('QmPb5f92FxKPYdT3QNBd1GKiL4tZUXUrzF4Hkpdr3Gf1gK') + done() + }) }) }) @@ -120,7 +152,6 @@ module.exports = (common) => { expect(err).to.not.exist expect(dNode.data).to.deep.equal(node.data) expect(dNode.links).to.deep.equal(node.links) - expect(dNode.multihash()).to.deep.equal(node.multihash()) done() }) }) @@ -135,115 +166,215 @@ module.exports = (common) => { it('DAGNode with some DAGLinks', (done) => { const dNode1 = new DAGNode(new Buffer('Some data 1')) const dNode2 = new DAGNode(new Buffer('Some data 2')) - dNode1.addNodeLink('some-link', dNode2) - - ipfs.object.put(dNode1, (err, node) => { + dNode1.addNodeLink('some-link', dNode2, (err) => { expect(err).to.not.exist - expect(dNode1.data).to.deep.equal(node.data) - expect( - dNode1.links.map((l) => l.toJSON()) - ).to.deep.equal( - node.links.map((l) => l.toJSON()) - ) - expect(dNode1.multihash()).to.deep.equal(node.multihash()) - done() + ipfs.object.put(dNode1, (err, node) => { + expect(err).to.not.exist + expect(dNode1.data).to.deep.equal(node.data) + expect( + dNode1.links.map((l) => l.toJSON()) + ).to.deep.equal( + node.links.map((l) => l.toJSON()) + ) + done() + }) }) }) }) describe('.get', () => { it('with multihash', (done) => { - const testObj = { + const obj = { Data: new Buffer('get test object'), Links: [] } - ipfs.object.put(testObj, (err, node1) => { - expect(err).to.not.exist + let node1 + let node1Multihash + let node2 - ipfs.object.get(node1.multihash(), (err, node2) => { - expect(err).to.not.exist - // because js-ipfs-api can't infer if the returned Data is Buffer - // or String - if (typeof node2.data === 'string') { - node2.data = new Buffer(node2.data) - } - expect(node1.multihash()).to.deep.equal(node2.multihash()) + series([ + (cb) => { + ipfs.object.put(obj, (err, node) => { + expect(err).to.not.exist + node1 = node + cb() + }) + }, + (cb) => { + node1.multihash((err, multihash) => { + expect(err).to.not.exist + node1Multihash = multihash + cb() + }) + }, + (cb) => { + ipfs.object.get(node1Multihash, (err, node) => { + expect(err).to.not.exist + node2 = node + + // because js-ipfs-api can't infer if the + // returned Data is Buffer or String + if (typeof node2.data === 'string') { + node2.data = new Buffer(node2.data) + } + cb() + }) + }, + (cb) => { expect(node1.data).to.deep.equal(node2.data) expect(node1.links).to.deep.equal(node2.links) - done() - }) - }) + node2.multihash((err, multihash) => { + expect(err).to.not.exist + expect(node1Multihash).to.deep.equal(multihash) + cb() + }) + } + ], done) }) it('with multihash (+ links)', (done) => { - const dNode1 = new DAGNode(new Buffer('Some data 1')) - const dNode2 = new DAGNode(new Buffer('Some data 2')) - dNode1.addNodeLink('some-link', dNode2) - - ipfs.object.put(dNode1, (err, node1) => { - expect(err).to.not.exist - - ipfs.object.get(node1.multihash(), (err, node2) => { - expect(err).to.not.exist - // because js-ipfs-api can't infer if the - // returned Data is Buffer or String - if (typeof node2.data === 'string') { - node2.data = new Buffer(node2.data) - } - expect(node1.multihash()).to.deep.equal(node2.multihash()) - expect(node1.data).to.deep.equal(node2.data) - done() - }) - }) + const node1 = new DAGNode(new Buffer('Some data 1')) + const node2 = new DAGNode(new Buffer('Some data 2')) + let node1Multihash + let node1Retrieved + + series([ + (cb) => { + node1.addNodeLink('some-link', node2, cb) + }, + (cb) => { + ipfs.object.put(node1, (err, node) => { + expect(err).to.not.exist + cb() + }) + }, + (cb) => { + node1.multihash((err, multihash) => { + expect(err).to.not.exist + node1Multihash = multihash + cb() + }) + }, + (cb) => { + ipfs.object.get(node1Multihash, (err, node) => { + expect(err).to.not.exist + node1Retrieved = node + // because js-ipfs-api can't infer if the + // returned Data is Buffer or String + if (typeof node1Retrieved.data === 'string') { + node1Retrieved.data = new Buffer(node1Retrieved.data) + } + cb() + }) + }, + (cb) => { + expect(node1.data).to.deep.equal(node1Retrieved.data) + node1Retrieved.multihash((err, multihash) => { + expect(err).to.not.exist + expect(node1Multihash).to.deep.equal(multihash) + cb() + }) + } + ], done) }) it('with multihash base58 encoded', (done) => { - const testObj = { + const obj = { Data: new Buffer('get test object'), Links: [] } - ipfs.object.put(testObj, (err, node1) => { - expect(err).to.not.exist + let node1a + let node1Multihash + let node1b - ipfs.object.get(bs58.encode(node1.multihash()), { enc: 'base58' }, (err, node2) => { - expect(err).to.not.exist - // because js-ipfs-api can't infer if the returned Data is Buffer - // or String - if (typeof node2.data === 'string') { - node2.data = new Buffer(node2.data) - } - expect(node1.multihash()).to.deep.equal(node2.multihash()) - expect(node1.data).to.deep.equal(node2.data) - expect(node1.links).to.deep.equal(node2.links) - done() - }) - }) + series([ + (cb) => { + ipfs.object.put(obj, (err, node) => { + expect(err).to.not.exist + node1a = node + cb() + }) + }, + (cb) => { + node1a.multihash((err, multihash) => { + expect(err).to.not.exist + node1Multihash = multihash + cb() + }) + }, + (cb) => { + ipfs.object.get(node1Multihash, { enc: 'base58' }, (err, node) => { + expect(err).to.not.exist + // because js-ipfs-api can't infer if the + // returned Data is Buffer or String + if (typeof node.data === 'string') { + node.data = new Buffer(node.data) + } + node1b = node + cb() + }) + }, + (cb) => { + node1b.multihash((err, multihash) => { + expect(err).to.not.exist + expect(node1Multihash).to.eql(multihash) + expect(node1a.data).to.eql(node1b.data) + expect(node1a.links).to.eql(node1b.links) + cb() + }) + } + ], done) }) it('with multihash base58 encoded toString', (done) => { - const testObj = { + const obj = { Data: new Buffer('get test object'), Links: [] } - ipfs.object.put(testObj, (err, node1) => { - expect(err).to.not.exist + let node1a + let node1Multihash + let node1b - ipfs.object.get(bs58.encode(node1.multihash()).toString(), { enc: 'base58' }, (err, node2) => { - expect(err).to.not.exist - // because js-ipfs-api can't infer if the returned Data is Buffer - // or String - if (typeof node2.data === 'string') { - node2.data = new Buffer(node2.data) - } - expect(node1.multihash()).to.deep.equal(node2.multihash()) - expect(node1.data).to.deep.equal(node2.data) - expect(node1.links).to.deep.equal(node2.links) - done() - }) - }) + series([ + (cb) => { + ipfs.object.put(obj, (err, node) => { + expect(err).to.not.exist + node1a = node + cb() + }) + }, + (cb) => { + node1a.multihash((err, multihash) => { + expect(err).to.not.exist + node1Multihash = multihash + cb() + }) + }, + (cb) => { + ipfs.object.get(bs58.encode(node1Multihash).toString(), { enc: 'base58' }, (err, node) => { + expect(err).to.not.exist + // because js-ipfs-api can't infer if the + // returned Data is Buffer or String + if (typeof node.data === 'string') { + node.data = new Buffer(node.data) + } + node1b = node + cb() + }) + }, + (cb) => { + node1b.multihash((err, multihash) => { + expect(err).to.not.exist + expect(node1Multihash).to.eql(multihash) + expect(node1a.data).to.eql(node1b.data) + expect(node1a.links).to.eql(node1b.links) + cb() + }) + } + ], done) }) }) @@ -257,15 +388,19 @@ module.exports = (common) => { ipfs.object.put(testObj, (err, node) => { expect(err).to.not.exist - ipfs.object.data(node.multihash(), (err, data) => { + node.multihash((err, multihash) => { expect(err).to.not.exist - // because js-ipfs-api can't infer - // if the returned Data is Buffer or String - if (typeof data === 'string') { - data = new Buffer(data) - } - expect(node.data).to.deep.equal(data) - done() + ipfs.object.data(multihash, (err, data) => { + expect(err).to.not.exist + + // because js-ipfs-api can't infer + // if the returned Data is Buffer or String + if (typeof data === 'string') { + data = new Buffer(data) + } + expect(node.data).to.deep.equal(data) + done() + }) }) }) }) @@ -279,15 +414,20 @@ module.exports = (common) => { ipfs.object.put(testObj, (err, node) => { expect(err).to.not.exist - ipfs.object.data(bs58.encode(node.multihash()), { enc: 'base58' }, (err, data) => { + node.multihash((err, multihash) => { expect(err).to.not.exist - // because js-ipfs-api can't infer - // if the returned Data is Buffer or String - if (typeof data === 'string') { - data = new Buffer(data) - } - expect(node.data).to.deep.equal(data) - done() + + ipfs.object.data(bs58.encode(multihash), { enc: 'base58' }, (err, data) => { + expect(err).to.not.exist + + // because js-ipfs-api can't infer + // if the returned Data is Buffer or String + if (typeof data === 'string') { + data = new Buffer(data) + } + expect(node.data).to.deep.equal(data) + done() + }) }) }) }) @@ -301,15 +441,20 @@ module.exports = (common) => { ipfs.object.put(testObj, (err, node) => { expect(err).to.not.exist - ipfs.object.data(bs58.encode(node.multihash()).toString(), { enc: 'base58' }, (err, data) => { + node.multihash((err, multihash) => { expect(err).to.not.exist - // because js-ipfs-api can't infer if the returned Data is Buffer - // or String - if (typeof data === 'string') { - data = new Buffer(data) - } - expect(node.data).to.deep.equal(data) - done() + + ipfs.object.data(bs58.encode(multihash).toString(), { enc: 'base58' }, (err, data) => { + expect(err).to.not.exist + + // because js-ipfs-api can't infer if the + // returned Data is Buffer or String + if (typeof data === 'string') { + data = new Buffer(data) + } + expect(node.data).to.deep.equal(data) + done() + }) }) }) }) @@ -324,27 +469,36 @@ module.exports = (common) => { ipfs.object.put(testObj, (err, node) => { expect(err).to.not.exist - - ipfs.object.links(node.multihash(), (err, links) => { + node.multihash((err, multihash) => { expect(err).to.not.exist - expect(node.links).to.deep.equal(links) - done() + + ipfs.object.links(multihash, (err, links) => { + expect(err).to.not.exist + expect(node.links).to.deep.equal(links) + done() + }) }) }) }) it('with multihash (+ links)', (done) => { - const dNode1 = new DAGNode(new Buffer('Some data 1')) - const dNode2 = new DAGNode(new Buffer('Some data 2')) - dNode1.addNodeLink('some-link', dNode2) + const node1 = new DAGNode(new Buffer('Some data 1')) + const node2 = new DAGNode(new Buffer('Some data 2')) - ipfs.object.put(dNode1, (err, node) => { + node1.addNodeLink('some-link', node2, (err) => { expect(err).to.not.exist - ipfs.object.links(node.multihash(), (err, links) => { + ipfs.object.put(node1, (err, node) => { expect(err).to.not.exist - expect(node.links[0].toJSON()).to.deep.equal(links[0].toJSON()) - done() + node.multihash((err, multihash) => { + expect(err).to.not.exist + + ipfs.object.links(multihash, (err, links) => { + expect(err).to.not.exist + expect(node.links[0].toJSON()).to.deep.equal(links[0].toJSON()) + done() + }) + }) }) }) }) @@ -357,11 +511,14 @@ module.exports = (common) => { ipfs.object.put(testObj, (err, node) => { expect(err).to.not.exist - - ipfs.object.links(bs58.encode(node.multihash()), { enc: 'base58' }, (err, links) => { + node.multihash((err, multihash) => { expect(err).to.not.exist - expect(node.links).to.deep.equal(links) - done() + + ipfs.object.links(bs58.encode(multihash), { enc: 'base58' }, (err, links) => { + expect(err).to.not.exist + expect(node.links).to.deep.equal(links) + done() + }) }) }) }) @@ -374,11 +531,14 @@ module.exports = (common) => { ipfs.object.put(testObj, (err, node) => { expect(err).to.not.exist - - ipfs.object.links(bs58.encode(node.multihash()).toString(), { enc: 'base58' }, (err, links) => { + node.multihash((err, multihash) => { expect(err).to.not.exist - expect(node.links).to.deep.equal(links) - done() + + ipfs.object.links(bs58.encode(multihash), { enc: 'base58' }, (err, links) => { + expect(err).to.not.exist + expect(node.links).to.deep.equal(links) + done() + }) }) }) }) @@ -394,42 +554,50 @@ module.exports = (common) => { ipfs.object.put(testObj, (err, node) => { expect(err).to.not.exist - ipfs.object.stat(node.multihash(), (err, stats) => { + node.multihash((err, multihash) => { expect(err).to.not.exist - const expected = { - Hash: 'QmNggDXca24S6cMPEYHZjeuc4QRmofkRrAEqVL3Ms2sdJZ', - NumLinks: 0, - BlockSize: 17, - LinksSize: 2, - DataSize: 15, - CumulativeSize: 17 - } - expect(expected).to.deep.equal(stats) - done() + + ipfs.object.stat(multihash, (err, stats) => { + expect(err).to.not.exist + const expected = { + Hash: 'QmNggDXca24S6cMPEYHZjeuc4QRmofkRrAEqVL3Ms2sdJZ', + NumLinks: 0, + BlockSize: 17, + LinksSize: 2, + DataSize: 15, + CumulativeSize: 17 + } + expect(expected).to.deep.equal(stats) + done() + }) }) }) }) it('with multihash (+ Links)', (done) => { - const dNode1 = new DAGNode(new Buffer('Some data 1')) - const dNode2 = new DAGNode(new Buffer('Some data 2')) - dNode1.addNodeLink('some-link', dNode2) - - ipfs.object.put(dNode1, (err, node) => { + const node1 = new DAGNode(new Buffer('Some data 1')) + const node2 = new DAGNode(new Buffer('Some data 2')) + node1.addNodeLink('some-link', node2, (err) => { expect(err).to.not.exist - ipfs.object.stat(node.multihash(), (err, stats) => { + ipfs.object.put(node1, (err, node) => { expect(err).to.not.exist - const expected = { - Hash: 'QmPR7W4kaADkAo4GKEVVPQN81EDUFCHJtqejQZ5dEG7pBC', - NumLinks: 1, - BlockSize: 64, - LinksSize: 53, - DataSize: 11, - CumulativeSize: 77 - } - expect(expected).to.deep.equal(stats) - done() + node.multihash((err, multihash) => { + expect(err).to.not.exist + ipfs.object.stat(multihash, (err, stats) => { + expect(err).to.not.exist + const expected = { + Hash: 'QmPR7W4kaADkAo4GKEVVPQN81EDUFCHJtqejQZ5dEG7pBC', + NumLinks: 1, + BlockSize: 64, + LinksSize: 53, + DataSize: 11, + CumulativeSize: 77 + } + expect(expected).to.deep.equal(stats) + done() + }) + }) }) }) }) @@ -443,18 +611,22 @@ module.exports = (common) => { ipfs.object.put(testObj, (err, node) => { expect(err).to.not.exist - ipfs.object.stat(bs58.encode(node.multihash()), { enc: 'base58' }, (err, stats) => { + node.multihash((err, multihash) => { expect(err).to.not.exist - const expected = { - Hash: 'QmNggDXca24S6cMPEYHZjeuc4QRmofkRrAEqVL3Ms2sdJZ', - NumLinks: 0, - BlockSize: 17, - LinksSize: 2, - DataSize: 15, - CumulativeSize: 17 - } - expect(expected).to.deep.equal(stats) - done() + + ipfs.object.stat(bs58.encode(multihash), { enc: 'base58' }, (err, stats) => { + expect(err).to.not.exist + const expected = { + Hash: 'QmNggDXca24S6cMPEYHZjeuc4QRmofkRrAEqVL3Ms2sdJZ', + NumLinks: 0, + BlockSize: 17, + LinksSize: 2, + DataSize: 15, + CumulativeSize: 17 + } + expect(expected).to.deep.equal(stats) + done() + }) }) }) }) @@ -468,26 +640,30 @@ module.exports = (common) => { ipfs.object.put(testObj, (err, node) => { expect(err).to.not.exist - ipfs.object.stat(bs58.encode(node.multihash()).toString(), { enc: 'base58' }, (err, stats) => { + node.multihash((err, multihash) => { expect(err).to.not.exist - const expected = { - Hash: 'QmNggDXca24S6cMPEYHZjeuc4QRmofkRrAEqVL3Ms2sdJZ', - NumLinks: 0, - BlockSize: 17, - LinksSize: 2, - DataSize: 15, - CumulativeSize: 17 - } - expect(expected).to.deep.equal(stats) - done() + + ipfs.object.stat(bs58.encode(multihash).toString(), { enc: 'base58' }, (err, stats) => { + expect(err).to.not.exist + const expected = { + Hash: 'QmNggDXca24S6cMPEYHZjeuc4QRmofkRrAEqVL3Ms2sdJZ', + NumLinks: 0, + BlockSize: 17, + LinksSize: 2, + DataSize: 15, + CumulativeSize: 17 + } + expect(expected).to.deep.equal(stats) + done() + }) }) }) }) }) describe('.patch', () => { - let testNode - let testNodeWithLink + let testNodeMultihash + let testNodeWithLinkMultihash let testLink const obj = { @@ -498,133 +674,167 @@ module.exports = (common) => { before((done) => { ipfs.object.put(obj, (err, node) => { expect(err).to.not.exist - testNode = node - done() + node.multihash((err, multihash) => { + expect(err).to.not.exist + testNodeMultihash = multihash + done() + }) }) }) it('.addLink', (done) => { - const dNode1 = new DAGNode(obj.Data, obj.Links) - const dNode2 = new DAGNode(new Buffer('some other node')) + const node1 = new DAGNode(obj.Data, obj.Links) + const node2 = new DAGNode(new Buffer('some other node')) + let node1Multihash + + series([ + (cb) => { + // note: we need to put the linked obj, otherwise IPFS won't + // timeout. Reason: it needs the node to get its size + ipfs.object.put(node2, cb) + }, + (cb) => { + node1.addNodeLink('link-to-node', node2, cb) + }, + (cb) => { + node1.multihash((err, multihash) => { + expect(err).to.not.exist + node1Multihash = multihash + cb() + }) + }, + (cb) => { + ipfs.object.patch.addLink(testNodeMultihash, node1.links[0], (err, node) => { + expect(err).to.not.exist + node.multihash((err, multihash) => { + expect(err).to.not.exist + expect(node1Multihash).to.eql(multihash) + testNodeWithLinkMultihash = multihash + testLink = node1.links[0] + cb() + }) + }) + } + ], done) + }) - // note: we need to put the linked obj, otherwise IPFS won't - // timeout. Reason: it needs the node to get its size - ipfs.object.put(dNode2, (err) => { + it('.rmLink', (done) => { + ipfs.object.patch.rmLink(testNodeWithLinkMultihash, testLink, (err, node) => { expect(err).to.not.exist - - dNode1.addNodeLink('link-to-node', dNode2) - - ipfs.object.patch.addLink(testNode.multihash(), dNode1.links[0], (err, node3) => { + node.multihash((err, multihash) => { expect(err).to.not.exist - expect(dNode1.multihash()).to.deep.equal(node3.multihash()) - testNodeWithLink = node3 - testLink = dNode1.links[0] + expect(multihash).to.not.deep.equal(testNodeWithLinkMultihash) done() }) }) }) - it('.rmLink', (done) => { - ipfs.object.patch.rmLink(testNodeWithLink.multihash(), testLink, (err, node) => { - expect(err).to.not.exist - expect(node.multihash()).to.deep.equal(testNode.multihash()) - done() - }) - }) - it('.appendData', (done) => { - ipfs.object.patch.appendData(testNode.multihash(), new Buffer('append'), (err, node) => { + ipfs.object.patch.appendData(testNodeMultihash, new Buffer('append'), (err, node) => { expect(err).to.not.exist - expect(node.multihash()).to.not.deep.equal(testNode.multihash()) - done() + node.multihash((err, multihash) => { + expect(err).to.not.exist + expect(multihash).to.not.deep.equal(testNodeMultihash) + done() + }) }) }) it('.setData', (done) => { - ipfs.object.patch.appendData(testNode.multihash(), new Buffer('set'), (err, node) => { + ipfs.object.patch.appendData(testNodeMultihash, new Buffer('set'), (err, node) => { expect(err).to.not.exist - expect(node.multihash()).to.not.deep.equal(testNode.multihash()) - done() + node.multihash((err, multihash) => { + expect(err).to.not.exist + expect(multihash).to.not.deep.equal(testNodeMultihash) + done() + }) }) }) }) }) describe('promise API', () => { - it('object.new', () => { - return ipfs.object.new() + it('object.new', (done) => { + ipfs.object.new() .then((node) => { - expect(node.toJSON().Hash).to.equal('QmdfTbBqBPQ7VNxZEYEj14VmRuZBkqFbiwReogJgS1zR1n') + node.toJSON((err, nodeJSON) => { + expect(err).to.not.exist + expect(nodeJSON.Hash).to.equal('QmdfTbBqBPQ7VNxZEYEj14VmRuZBkqFbiwReogJgS1zR1n') + done() + }) }) }) - it('object.put', () => { + it('object.put', (done) => { const obj = { Data: new Buffer('Some data'), Links: [] } - return ipfs.object.put(obj) + ipfs.object.put(obj) .then((node) => { - const nodeJSON = node.toJSON() - expect(obj.Data).to.deep.equal(nodeJSON.Data) - expect(obj.Links).to.deep.equal(nodeJSON.Links) - expect(nodeJSON.Hash).to.equal('QmPb5f92FxKPYdT3QNBd1GKiL4tZUXUrzF4Hkpdr3Gf1gK') + node.toJSON((err, nodeJSON) => { + expect(err).to.not.exist + expect(obj.Data).to.deep.equal(nodeJSON.Data) + expect(obj.Links).to.deep.equal(nodeJSON.Links) + expect(nodeJSON.Hash).to.equal('QmPb5f92FxKPYdT3QNBd1GKiL4tZUXUrzF4Hkpdr3Gf1gK') + done() + }) }) }) - it('object.get', () => { + it('object.get', (done) => { const testObj = { Data: new Buffer('get test object'), Links: [] } - return ipfs.object.put(testObj) + ipfs.object.put(testObj) .then((node1) => { - return ipfs.object.get(node1.multihash()) - .then((node2) => { - // because js-ipfs-api can't infer if the returned Data is Buffer - // or String - if (typeof node2.data === 'string') { - node2.data = new Buffer(node2.data) - } - expect(node1.multihash()).to.deep.equal(node2.multihash()) - expect(node1.data).to.deep.equal(node2.data) - expect(node1.links).to.deep.equal(node2.links) - }) + node1.multihash((err, multihash) => { + expect(err).to.not.exist + ipfs.object.get(multihash) + .then((node2) => { + // because js-ipfs-api can't infer if the + // returned Data is Buffer or String + if (typeof node2.data === 'string') { + node2.data = new Buffer(node2.data) + } + + expect(node1.data).to.deep.equal(node2.data) + expect(node1.links).to.deep.equal(node2.links) + done() + }) + }) }) }) - it('object.data', () => { + it('object.data', (done) => { const testObj = { Data: new Buffer('get test object'), Links: [] } - return ipfs.object.put(testObj) + ipfs.object.put(testObj) .then((node) => { - return ipfs.object.data(node.multihash()) - .then((data) => { - // because js-ipfs-api can't infer - // if the returned Data is Buffer or String - if (typeof data === 'string') { - data = new Buffer(data) - } - expect(node.data).to.deep.equal(data) - }) + node.multihash((err, multihash) => { + expect(err).to.not.exist + ipfs.object.data(multihash) + .then((data) => { + // because js-ipfs-api can't infer + // if the returned Data is Buffer or String + if (typeof data === 'string') { + data = new Buffer(data) + } + expect(node.data).to.deep.equal(data) + done() + }) + }) }) }) it('object.stat', () => { - const testObj = { - Data: new Buffer('get test object'), - Links: [] - } - - return ipfs.object.put(testObj) - .then((node) => { - return ipfs.object.stat(node.multihash()) - }) + return ipfs.object.stat('QmNggDXca24S6cMPEYHZjeuc4QRmofkRrAEqVL3Ms2sdJZ') .then((stats) => { const expected = { Hash: 'QmNggDXca24S6cMPEYHZjeuc4QRmofkRrAEqVL3Ms2sdJZ', @@ -638,79 +848,125 @@ module.exports = (common) => { }) }) - it('object.links', () => { + it('object.links', (done) => { const testObj = { Data: new Buffer('get test object'), Links: [] } - return ipfs.object.put(testObj) + ipfs.object.put(testObj) .then((node) => { - return ipfs.object.links(node.multihash()) - .then((links) => { - expect(node.links).to.deep.equal(links) - }) + node.multihash((err, multihash) => { + expect(err).to.not.exist + ipfs.object.links(multihash) + .then((links) => { + expect(node.links).to.deep.equal(links) + done() + }) + }) }) }) describe('object.patch', () => { - let testNode - let testNodeWithLink + let testNodeMultihash + let testNodeWithLinkMultihash let testLink - before(() => { - const obj = { - Data: new Buffer('patch test object'), - Links: [] - } + const obj = { + Data: new Buffer('patch test object'), + Links: [] + } - return ipfs.object.put(obj) - .then((node) => { - testNode = node + before((done) => { + ipfs.object.put(obj, (err, node) => { + expect(err).to.not.exist + node.multihash((err, multihash) => { + expect(err).to.not.exist + testNodeMultihash = multihash + done() }) + }) }) - it('.addLink', () => { - const dNode1 = dagPB.util.deserialize(dagPB.util.serialize(testNode)) - const dNode2 = new DAGNode(new Buffer('some other node')) - // note: we need to put the linked obj, otherwise IPFS won't timeout - // cause it needs the node to get its size - return ipfs.object.put(dNode2) - .then(() => { - dNode1.addNodeLink('link-to-node', dNode2) - - return ipfs.object.patch - .addLink(testNode.multihash(), dNode1.links[0]) - .then((node3) => { - expect(dNode1.multihash()).to.deep.equal(node3.multihash()) - testNodeWithLink = node3 - testLink = dNode1.links[0] + it('.addLink', (done) => { + const node1 = new DAGNode(obj.Data, obj.Links) + const node2 = new DAGNode(new Buffer('some other node')) + let node1Multihash + + series([ + (cb) => { + // note: we need to put the linked obj, otherwise IPFS won't + // timeout. Reason: it needs the node to get its size + ipfs.object.put(node2, cb) + }, + (cb) => { + node1.addNodeLink('link-to-node', node2, cb) + }, + (cb) => { + node1.multihash((err, multihash) => { + expect(err).to.not.exist + node1Multihash = multihash + cb() + }) + }, + (cb) => { + ipfs.object.patch.addLink(testNodeMultihash, node1.links[0]) + .then((node) => { + node.multihash((err, multihash) => { + expect(err).to.not.exist + expect(node1Multihash).to.eql(multihash) + testNodeWithLinkMultihash = multihash + testLink = node1.links[0] + cb() + }) }) - }) + .catch((err) => { + expect(err).to.not.exist + }) + } + ], done) }) - it('.rmLink', () => { - return ipfs.object.patch - .rmLink(testNodeWithLink.multihash(), testLink) + it('.rmLink', (done) => { + ipfs.object.patch.rmLink(testNodeWithLinkMultihash, testLink) .then((node) => { - expect(node.multihash()).to.deep.equal(testNode.multihash()) + node.multihash((err, multihash) => { + expect(err).to.not.exist + expect(multihash).to.not.deep.equal(testNodeWithLinkMultihash) + done() + }) + }) + .catch((err) => { + expect(err).to.not.exist }) }) - it('.appendData', () => { - return ipfs.object.patch - .appendData(testNode.multihash(), new Buffer('append')) + it('.appendData', (done) => { + ipfs.object.patch.appendData(testNodeMultihash, new Buffer('append')) .then((node) => { - expect(node.multihash()).to.not.deep.equal(testNode.multihash()) + node.multihash((err, multihash) => { + expect(err).to.not.exist + expect(multihash).to.not.deep.equal(testNodeMultihash) + done() + }) + }) + .catch((err) => { + expect(err).to.not.exist }) }) - it('.setData', () => { - return ipfs.object.patch - .appendData(testNode.multihash(), new Buffer('set')) + it('.setData', (done) => { + ipfs.object.patch.appendData(testNodeMultihash, new Buffer('set')) .then((node) => { - expect(node.multihash()).to.not.deep.equal(testNode.multihash()) + node.multihash((err, multihash) => { + expect(err).to.not.exist + expect(multihash).to.not.deep.equal(testNodeMultihash) + done() + }) }) + .catch((err) => { + expect(err).to.not.exist + }) }) }) }) diff --git a/src/swarm.js b/src/swarm.js index e0864d3e..7d51af8f 100644 --- a/src/swarm.js +++ b/src/swarm.js @@ -4,7 +4,7 @@ 'use strict' const expect = require('chai').expect -const series = require('run-series') +const series = require('async/series') module.exports = (common) => { describe('.swarm', () => {