Skip to content
This repository has been archived by the owner on Aug 11, 2021. It is now read-only.

100% (line) coverage. #9

Merged
merged 10 commits into from
Apr 19, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -149,12 +149,27 @@ Asynchronously adds an array of block instances to the underlying repo.
#### bs.getBlock(multihash, callback(err, block))

Asynchronously returns the block whose content multihash matches `multihash`.
Returns an error (`err.code === 'ENOENT'`) if the block does not exist.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice :)


If the block could not be found, expect `err.code` to be `'ENOENT'`.

#### bs.getBlocks(multihashes, callback(err, blocks))

Asynchronously returns the blocks whose content multihashes match the array
`multihashes`.

`blocks` is an object that maps each `multihash` to an object of the form

```js
{
err: Error
block: Block
}
```

Expect `blocks[multihash].err.code === 'ENOENT'` and `blocks[multihash].block
=== null` if a block did not exist.

*Does not guarantee atomicity.*

#### bs.deleteBlock(multihash, callback(err))
Expand Down
43 changes: 23 additions & 20 deletions src/block-service.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,15 @@ function BlockService (ipfsRepo, exchange) {
}

this.getBlock = (multihash, extension, callback) => {
if (!multihash) {
return callback(new Error('Invalid multihash'))
}

if (typeof extension === 'function') {
callback = extension
extension = undefined
}

if (!multihash) {
return callback(new Error('Invalid multihash'))
}

ipfsRepo.datastore.createReadStream(multihash, extension)
.pipe(bl((err, data) => {
if (err) { return callback(err) }
Expand All @@ -43,50 +43,53 @@ function BlockService (ipfsRepo, exchange) {
}

this.getBlocks = (multihashes, extension, callback) => {
if (!Array.isArray(multihashes)) {
return callback(new Error('Invalid batch of multihashes'))
}

if (typeof extension === 'function') {
callback = extension
extension = undefined
}

const blocks = []
if (!Array.isArray(multihashes)) {
return callback(new Error('Invalid batch of multihashes'))
}

var results = {}

async.each(multihashes, (multihash, next) => {
this.getBlock(multihash, extension, (err, block) => {
if (err) { return next(err) }
blocks.push(block)
results[multihash] = {
err: err,
block: block
}
next()
})
}, (err) => {
callback(err, blocks)
callback(err, results)
})
}

this.deleteBlock = (multihash, extension, callback) => {
if (!multihash) {
return callback(new Error('Invalid multihash'))
}

if (typeof extension === 'function') {
callback = extension
extension = undefined
}

if (!multihash) {
return callback(new Error('Invalid multihash'))
}

ipfsRepo.datastore.remove(multihash, extension, callback)
}

this.deleteBlocks = (multihashes, extension, callback) => {
if (!Array.isArray(multihashes)) {
return callback('Invalid batch of multihashes')
}

if (typeof extension === 'function') {
callback = extension
extension = undefined
}

if (!Array.isArray(multihashes)) {
return callback(new Error('Invalid batch of multihashes'))
}

async.each(multihashes, (multihash, next) => {
this.deleteBlock(multihash, extension, next)
}, (err) => {
Expand Down
93 changes: 90 additions & 3 deletions test/block-service-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ module.exports = (repo) => {
done()
})

it('store a block', (done) => {
it('store and get a block', (done) => {
const b = new Block('A random data block')
bs.addBlock(b, (err) => {
expect(err).to.not.exist
Expand All @@ -28,7 +28,7 @@ module.exports = (repo) => {
})
})

it('store a block, with custom extension', (done) => {
it('store and get a block, with custom extension', (done) => {
const b = new Block('A random data block', 'ext')
bs.addBlock(b, (err) => {
expect(err).to.not.exist
Expand Down Expand Up @@ -60,6 +60,79 @@ module.exports = (repo) => {
})
})

it('addBlocks: bad invocation', (done) => {
const b1 = new Block('1')

bs.addBlocks(b1, (err) => {
expect(err).to.be.an('error')
done()
})
})

it('getBlock: bad invocation', (done) => {
bs.getBlock(null, (err) => {
expect(err).to.be.an('error')
done()
})
})

it('getBlocks: bad invocation', (done) => {
bs.getBlocks(null, 'protobuf', (err) => {
expect(err).to.be.an('error')
done()
})
})

it('get many blocks', (done) => {
const b1 = new Block('1')
const b2 = new Block('2')
const b3 = new Block('3')

bs.addBlocks([b1, b2, b3], (err) => {
expect(err).to.not.exist

bs.getBlocks([b1.key, b2.key, b3.key], (err, blocks) => {
expect(err).to.not.exist
expect(Object.keys(blocks)).to.have.lengthOf(3)
expect(blocks[b1.key]).to.exist
expect(blocks[b1.key].err).to.not.exist
expect(blocks[b1.key].block.data).to.deep.equal(b1.data)
expect(blocks[b2.key]).to.exist
expect(blocks[b2.key].err).to.not.exist
expect(blocks[b2.key].block.data).to.deep.equal(b2.data)
expect(blocks[b3.key]).to.exist
expect(blocks[b3.key].err).to.not.exist
expect(blocks[b3.key].block.data).to.deep.equal(b3.data)
done()
})
})
})

it('get many blocks: partial success', (done) => {
const b1 = new Block('a1')
const b2 = new Block('a2')
const b3 = new Block('a3')

bs.addBlocks([b1, b3], (err) => {
expect(err).to.not.exist

bs.getBlocks([b1.key, b2.key, b3.key], (err, blocks) => {
expect(err).to.not.exist
expect(Object.keys(blocks)).to.have.lengthOf(3)
expect(blocks[b1.key]).to.exist
expect(blocks[b1.key].err).to.not.exist
expect(blocks[b1.key].block.data).to.deep.equal(b1.data)
expect(blocks[b2.key]).to.exist
expect(blocks[b2.key].err).to.exist
expect(blocks[b2.key].block).to.not.exist
expect(blocks[b3.key]).to.exist
expect(blocks[b3.key].err).to.not.exist
expect(blocks[b3.key].block.data).to.deep.equal(b3.data)
done()
})
})
})

it('delete a block', (done) => {
const b = new Block('Will not live that much')
bs.addBlock(b, (err) => {
Expand All @@ -74,6 +147,13 @@ module.exports = (repo) => {
})
})

it('deleteBlock: bad invocation', (done) => {
bs.deleteBlock(null, (err) => {
expect(err).to.be.an('error')
done()
})
})

it('delete a block, with custom extension', (done) => {
const b = new Block('Will not live that much', 'ext')
bs.addBlock(b, (err) => {
Expand Down Expand Up @@ -101,10 +181,17 @@ module.exports = (repo) => {
const b2 = new Block('2')
const b3 = new Block('3')

bs.deleteBlocks([b1, b2, b3], (err) => {
bs.deleteBlocks([b1, b2, b3], 'data', (err) => {
expect(err).to.not.exist
done()
})
})

it('deleteBlocks: bad invocation', (done) => {
bs.deleteBlocks(null, (err) => {
expect(err).to.be.an('error')
done()
})
})
})
}
7 changes: 7 additions & 0 deletions test/block.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,13 @@ describe('block', () => {
expect(b.extension).to.be.eql('data')
})

it('create /wo new', () => {
const b = Block('random-data')
expect(b.key).to.exist
expect(b.data).to.exist
expect(b.extension).to.be.eql('data')
})

it('fail to create an empty block', () => {
expect(() => new Block()).to.throw()
})
Expand Down