From 90ff07334fc71f62cf4780abf2d8504d3a8d7b4c Mon Sep 17 00:00:00 2001 From: David Dias Date: Mon, 3 Oct 2016 07:58:33 +0100 Subject: [PATCH] test: let the testing begin --- src/index.js | 141 +++++++++++++++++++- src/ipld-resolver.js | 137 -------------------- src/{resolve.js => old-resolve.js} | 0 test/browser.js | 9 +- test/node.js | 8 +- test/{ipld-tests.js => old-ipld-tests.js} | 2 +- test/test-ipld-all-together-now.js | 8 ++ test/test-ipld-dag-cbor.js | 2 + test/test-ipld-dag-pb.js | 149 ++++++++++++++++++++++ test/test-ipld-eth-block.js | 2 + 10 files changed, 309 insertions(+), 149 deletions(-) delete mode 100644 src/ipld-resolver.js rename src/{resolve.js => old-resolve.js} (100%) rename test/{ipld-tests.js => old-ipld-tests.js} (99%) create mode 100644 test/test-ipld-all-together-now.js create mode 100644 test/test-ipld-dag-cbor.js create mode 100644 test/test-ipld-dag-pb.js create mode 100644 test/test-ipld-eth-block.js diff --git a/src/index.js b/src/index.js index 38f7dc3..d091b8b 100644 --- a/src/index.js +++ b/src/index.js @@ -1,4 +1,141 @@ 'use strict' -exports.IPLDService = require('./ipld-service') -exports.resolve = require('./resolve') +// const isIPFS = require('is-ipfs') +const Block = require('ipfs-block') +// const ipld = require('ipld-dag-cbor') +const pull = require('pull-stream') +const traverse = require('pull-traverse') +// const mh = require('multihashes') +const dagPB = require('ipld-dag-pb') + +const utils = require('./utils') + +module.exports = class IPLDResolver { + constructor (blockService) { + // TODO instead of throwing, just create an in-memory + // block-service, so it is nice for demos + if (!blockService) { + throw new Error('IPLDService requires a BlockService instance') + } + + this.bs = blockService + this.resolvers = {} + this.support(dagPB.resolver.multicodec, dagPB.DAGNode, dagPB.resolver) + } + + // Adds support for an IPLD format + // default ones are dag-pb and dag-cbor + support (multicodec, type, resolver) { + this.resolvers[multicodec] = { + resolver: resolver, + Type: type + } + } + + resolve (cid, path) { + // TODO + } + + put (node, callback) { + callback = callback || noop + pull( + pull.values([node]), + this.putStream(callback) + ) + } + + putStream (callback) { + callback = callback || noop + + return pull( + pull.map((node) => { + return { + block: new Block(node.serialize()), + cid: node.cid() + } + }), + this.bs.putStream(), + pull.onEnd(callback) + ) + } + + get (cid, callback) { + pull( + this.getStream(cid), + pull.collect((err, res) => { + if (err) { + return callback(err) + } + callback(null, res[0]) + }) + ) + } + + getStream (cid) { + return pull( + this.bs.getStream(cid), + pull.map((block) => { + if (this.resolvers[cid.codec]) { + const node = new this.resolvers[cid.codec].Type() + node.deserialize(block.data) + return node + } else { // multicodec unknown, send back raw data + return block.data + } + }) + ) + } + + getRecursive (cid, callback) { + pull( + this.getRecursiveStream(cid), + pull.collect(callback) + ) + } + + getRecursiveStream (cid) { + return pull( + this.getStream(cid), + pull.map((node) => { + traverse.widthFirst(node, (node) => { + return pull( + pull.values(utils.getKeys(node)), + pull.map((link) => this.getStream(link)), + pull.flatten() + ) + }) + }), + pull.flatten() + ) + } + + remove (cids, callback) { + this.bs.delete(cids, callback) + } +} + +function noop () {} + +/* +function normalizeKey (key) { + let res + const isMhash = isIPFS.multihash(key) + const isPath = isIPFS.path(key) + + if (!isMhash && !isPath) { + return null + } + + if (isMhash) { + res = key + } else if (isPath) { + res = key.replace('/ipfs/', '') + } + + if (typeof res === 'string') { + return mh.fromB58String(res) + } + + return res +} +*/ diff --git a/src/ipld-resolver.js b/src/ipld-resolver.js deleted file mode 100644 index 869c6ec..0000000 --- a/src/ipld-resolver.js +++ /dev/null @@ -1,137 +0,0 @@ -'use strict' - -// const isIPFS = require('is-ipfs') -const Block = require('ipfs-block') -// const ipld = require('ipld-dag-cbor') -const pull = require('pull-stream') -const traverse = require('pull-traverse') -// const mh = require('multihashes') -const dagPB = require('ipld-dag-pb') - -const utils = require('./utils') - -module.exports = class IPLDResolver { - constructor (blockService) { - // TODO instead of throwing, just create an in-memory - // block-service, so it is nice for demos - if (!blockService) { - throw new Error('IPLDService requires a BlockService instance') - } - - this.bs = blockService - this.resolvers = {} - this.support(dagPB.resolver.multicodec, dagPB.resolver) - } - - // Adds support for an IPLD format - // default ones are dag-pb and dag-cbor - support (multicodec, resolver) { - this.resolvers[multicodec] = resolver - } - - resolve (cid, path) { - // TODO - } - - put (node, callback) { - callback = callback || noop - pull( - pull.values([node]), - this.putStream(callback) - ) - } - - putStream (callback) { - callback = callback || noop - - return pull( - pull.map((node) => { - return { - block: new Block(node.serialize()), - cid: node.cid() - } - }), - this.bs.putStream(), - pull.onEnd(callback) - ) - } - - get (cid, callback) { - pull( - this.getStream(cid), - pull.collect((err, res) => { - if (err) { - return callback(err) - } - callback(null, res[0]) - }) - ) - } - - getStream (cid) { - return pull( - this.bs.getStream(cid), - pull.map((block) => { - // TODO - // deserialize this block into the format described by the CID - // if the multicodec is not known (i.e we don't have a deserializer) - // send back the raw data - - // old -> ipld.unmarshal(block.data) - }) - ) - } - - getRecursive (cid, callback) { - pull( - this.getRecursiveStream(cid), - pull.collect(callback) - ) - } - - getRecursiveStream (cid) { - return pull( - this.getStream(cid), - pull.map((node) => { - traverse.widthFirst(node, (node) => { - return pull( - pull.values(utils.getKeys(node)), - pull.map((link) => this.getStream(link)), - pull.flatten() - ) - }) - }), - pull.flatten() - ) - } - - remove (cids, callback) { - this.bs.delete(cids, callback) - } -} - -function noop () {} - -/* -function normalizeKey (key) { - let res - const isMhash = isIPFS.multihash(key) - const isPath = isIPFS.path(key) - - if (!isMhash && !isPath) { - return null - } - - if (isMhash) { - res = key - } else if (isPath) { - res = key.replace('/ipfs/', '') - } - - if (typeof res === 'string') { - return mh.fromB58String(res) - } - - return res -} -*/ diff --git a/src/resolve.js b/src/old-resolve.js similarity index 100% rename from src/resolve.js rename to src/old-resolve.js diff --git a/test/browser.js b/test/browser.js index 02576cf..cbd8946 100644 --- a/test/browser.js +++ b/test/browser.js @@ -8,8 +8,6 @@ const IPFSRepo = require('ipfs-repo') const pull = require('pull-stream') const repoContext = require.context('buffer!./example-repo', true) -const tests = require('./ipld-tests') - const idb = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || @@ -18,7 +16,7 @@ const idb = window.indexedDB || idb.deleteDatabase('ipfs') idb.deleteDatabase('ipfs/blocks') -describe('ipfs merkle dag browser tests', function () { +describe('Browser', function () { before(function (done) { this.timeout(10000) @@ -49,6 +47,7 @@ describe('ipfs merkle dag browser tests', function () { }, done) }) - const repo = new IPFSRepo('ipfs', {stores: Store}) - tests(repo) + const repo = new IPFSRepo('ipfs', { stores: Store }) + + require('./test-ipld-dag-pb')(repo) }) diff --git a/test/node.js b/test/node.js index d316e9d..081b5df 100644 --- a/test/node.js +++ b/test/node.js @@ -7,9 +7,7 @@ const expect = require('chai').expect const IPFSRepo = require('ipfs-repo') const Store = require('fs-pull-blob-store') -const tests = require('./ipld-tests') - -describe('node test blocks', () => { +describe('Node.js', () => { const repoExample = process.cwd() + '/test/example-repo' const repoTests = process.cwd() + '/test/repo-just-for-test' + Date.now() @@ -30,5 +28,7 @@ describe('node test blocks', () => { const repo = new IPFSRepo(repoTests, {stores: Store}) - tests(repo) + require('./test-ipld-dag-pb')(repo) + // require('./test-ipld-dag-cbor')(repo) + // require('./test-ipld-eth-block')(repo) }) diff --git a/test/ipld-tests.js b/test/old-ipld-tests.js similarity index 99% rename from test/ipld-tests.js rename to test/old-ipld-tests.js index ef0f4f2..f616901 100644 --- a/test/ipld-tests.js +++ b/test/old-ipld-tests.js @@ -15,7 +15,7 @@ module.exports = (repo) => { const bs = new BlockService(repo) const ipldService = new IPLDService(bs) - describe('IPLDService', () => { + describe('IPLD Resolver (old tests)', () => { it('throws when not passed a repo', () => { expect(() => new IPLDService()).to.throw(/requires a BlockService/) }) diff --git a/test/test-ipld-all-together-now.js b/test/test-ipld-all-together-now.js new file mode 100644 index 0000000..76095b0 --- /dev/null +++ b/test/test-ipld-all-together-now.js @@ -0,0 +1,8 @@ +/* eslint-env mocha */ +'use strict' + +/* + * Test different types of data structures living together + * & + * Test data made of mixed data structures! + */ diff --git a/test/test-ipld-dag-cbor.js b/test/test-ipld-dag-cbor.js new file mode 100644 index 0000000..98e1f9c --- /dev/null +++ b/test/test-ipld-dag-cbor.js @@ -0,0 +1,2 @@ +/* eslint-env mocha */ +'use strict' diff --git a/test/test-ipld-dag-pb.js b/test/test-ipld-dag-pb.js new file mode 100644 index 0000000..3c3eb1c --- /dev/null +++ b/test/test-ipld-dag-pb.js @@ -0,0 +1,149 @@ +/* eslint-env mocha */ +'use strict' + +const expect = require('chai').expect +const BlockService = require('ipfs-block-service') +const dagPB = require('ipld-dag-pb') +const multihash = require('multihashing') +const series = require('async/series') +const pull = require('pull-stream') + +const IPLDResolver = require('../src') + +module.exports = (repo) => { + const bs = new BlockService(repo) + const resolver = new IPLDResolver(bs) + + describe('IPLD Resolver with dag-pb (MerkleDAG Protobuf)', () => { + before(() => { + // Create a bunch o nodes to be used + }) + + it('throws when not passed a repo', () => { + expect(() => new IPLDResolver()).to.throw(/requires a BlockService/) + }) + + it.skip('resolver.put', (done) => { + /* + const node = { + name: 'hello.txt', + size: 11 + } + + ipldService.put(node, done) + */ + }) + + it.skip('resolver.putStream', (done) => { + /* + pull( + pull.values([ + {name: 'pull.txt', size: 12} + ]), + ipldService.putStream(done) + ) + */ + }) + + it.skip('resolver.get', (done) => { + /* + const node = { + name: 'world.txt', + size: 11 + } + + ipldService.put(node, (err) => { + expect(err).to.not.exist + + const mh = multihash(ipld.marshal(node), 'sha2-256') + + ipldService.get(mh, (err, fetchedNode) => { + expect(err).to.not.exist + expect(node).to.deep.equal(fetchedNode) + done() + }) + }) + */ + }) + + it.skip('resolver.getStream', (done) => { + /* + const node = { + name: 'put.txt', + size: 15 + } + const mh = multihash(ipld.marshal(node), 'sha2-256') + pull( + pull.values([node]), + ipldService.putStream(read) + ) + + function read (err) { + expect(err).to.not.exist + pull( + ipldService.getStream(mh), + pull.collect((err, res) => { + expect(err).to.not.exist + expect(res[0]).to.be.eql(node) + done() + }) + ) + } + */ + }) + + it.skip('resolver.getRecursive', (done) => { + // 1 -> 2 -> 3 + /* + const node1 = {data: '1'} + const node2 = {data: '2'} + const node3 = {data: '3'} + + node2.ref = { + '/': ipld.multihash(ipld.marshal(node3)) + } + + node1.ref = { + '/': ipld.multihash(ipld.marshal(node2)) + } + + series([ + (cb) => ipldService.put(node1, cb), + (cb) => ipldService.put(node2, cb), + (cb) => ipldService.put(node3, cb), + (cb) => { + const mh = multihash(ipld.marshal(node1), 'sha2-256') + ipldService.getRecursive(mh, (err, nodes) => { + expect(err).to.not.exist + expect(nodes).to.have.length(3) + cb() + }) + } + ], (err) => { + expect(err).to.not.exist + done() + }) + */ + }) + + it.skip('resolver.remove', (done) => { + /* + const node = {data: 'short lived node'} + const mh = multihash(ipld.marshal(node), 'sha2-256') + + series([ + (cb) => ipldService.put(node, cb), + (cb) => ipldService.get(mh, cb), + (cb) => ipldService.remove(mh, cb), + (cb) => ipldService.get(mh, (err) => { + expect(err).to.exist + cb() + }) + ], done) + */ + }) + }) + + describe('IPLD Path Resolver', () => { + }) +} diff --git a/test/test-ipld-eth-block.js b/test/test-ipld-eth-block.js new file mode 100644 index 0000000..98e1f9c --- /dev/null +++ b/test/test-ipld-eth-block.js @@ -0,0 +1,2 @@ +/* eslint-env mocha */ +'use strict'