Skip to content
This repository was archived by the owner on Aug 12, 2020. It is now read-only.

Commit 651f113

Browse files
pgtedaviddias
authored andcommitted
fix: stop export visitor from trying to resolve leaf object (#130)
* fixing recursive get, stopping visitor from trying to resolve leaf objects * fixed typo on comment * test for exporting deeply nested dirs
1 parent e1c6c9e commit 651f113

File tree

4 files changed

+131
-0
lines changed

4 files changed

+131
-0
lines changed

src/exporter/index.js

+11
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,17 @@ module.exports = (hash, ipldResolver, options) => {
2121
options = options || {}
2222

2323
function visitor (item) {
24+
if (!item.hash) {
25+
// having no hash means that this visitor got a file object
26+
// which needs no further resolving.
27+
// No further resolving means that the visitor does not
28+
// need to do anyting else, so he's returning
29+
// an empty stream
30+
31+
// TODO: perhaps change the pull streams construct.
32+
// Instead of traversing with a visitor, consider recursing.
33+
return pull.empty()
34+
}
2435
return pull(
2536
ipldResolver.getStream(new CID(item.hash)),
2637
pull.map((node) => switchType(

test/browser.js

+1
Original file line numberDiff line numberDiff line change
@@ -59,4 +59,5 @@ describe('IPFS data importing tests on the Browser', function () {
5959
require('./test-importer')(repo)
6060
require('./test-import-export')(repo)
6161
require('./test-hash-parity-with-go-ipfs')(repo)
62+
require('./test-nested-dir-import-export')(repo)
6263
})

test/node.js

+1
Original file line numberDiff line numberDiff line change
@@ -44,4 +44,5 @@ describe('IPFS UnixFS Engine', () => {
4444
require('./test-importer')(repo)
4545
require('./test-import-export')(repo)
4646
require('./test-hash-parity-with-go-ipfs')(repo)
47+
require('./test-nested-dir-import-export')(repo)
4748
})

test/test-nested-dir-import-export.js

+118
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
/* eslint-env mocha */
2+
'use strict'
3+
4+
const expect = require('chai').expect
5+
const BlockService = require('ipfs-block-service')
6+
const IPLDResolver = require('ipld-resolver')
7+
const pull = require('pull-stream')
8+
const mh = require('multihashes')
9+
const map = require('async/map')
10+
11+
const unixFSEngine = require('./../')
12+
13+
module.exports = (repo) => {
14+
describe('import adn export big nested dir', () => {
15+
const rootHash = 'QmdCrquDwd7RfZ6GCZFEVADwe8uyyw1YmF9mtAB7etDgmK'
16+
let ipldResolver
17+
18+
before(() => {
19+
const bs = new BlockService(repo)
20+
ipldResolver = new IPLDResolver(bs)
21+
})
22+
23+
it('imports', (done) => {
24+
pull(
25+
pull.values([
26+
{ path: 'a/b/c/d/e', content: pull.values([new Buffer('banana')]) },
27+
{ path: 'a/b/c/d/f', content: pull.values([new Buffer('strawberry')]) },
28+
{ path: 'a/b/g', content: pull.values([new Buffer('ice')]) },
29+
{ path: 'a/b/h', content: pull.values([new Buffer('cream')]) }
30+
]),
31+
unixFSEngine.importer(ipldResolver),
32+
pull.collect((err, files) => {
33+
expect(err).to.not.exist
34+
expect(files.map(normalizeNode).sort(byPath)).to.be.eql([
35+
{ path: 'a/b/h',
36+
multihash: 'QmWHMpCtdNjemT2F3SjyrmnBXQXwEohaZd4apcbFBhbFRC' },
37+
{ path: 'a/b/g',
38+
multihash: 'QmQGwYzzTPcbqTiy2Nbp88gqqBqCWY4QZGfen45LFZkD5n' },
39+
{ path: 'a/b/c/d/f',
40+
multihash: 'QmNVHs2dy7AjGUotsubWVncRsD3SpRXm8MgmCCQTVdVACz' },
41+
{ path: 'a/b/c/d/e',
42+
multihash: 'QmYPbDKwc7oneCcEc6BcRSN5GXthTGWUCd19bTCyP9u3vH' },
43+
{ path: 'a/b/c/d',
44+
multihash: 'QmQGDXr3ysARM38n7h79Tx7yD3YxuzcnZ1naG71WMojPoj' },
45+
{ path: 'a/b/c',
46+
multihash: 'QmYTVcjYpN3hQLtJstCPE8hhEacAYjWAuTmmAAXoonamuE' },
47+
{ path: 'a/b',
48+
multihash: 'QmWyWYxq1GD9fEyckf5LrJv8hMW35CwfWwzDBp8bTw3NQj' },
49+
{ path: 'a',
50+
multihash: rootHash }
51+
])
52+
done()
53+
})
54+
)
55+
})
56+
57+
it('exports', done => {
58+
pull(
59+
unixFSEngine.exporter(rootHash, ipldResolver),
60+
pull.collect((err, files) => {
61+
expect(err).to.not.exist
62+
map(
63+
files,
64+
(file, callback) => {
65+
if (file.content) {
66+
pull(
67+
file.content,
68+
pull.collect(mapFile(file, callback))
69+
)
70+
} else {
71+
callback(null, { path: file.path })
72+
}
73+
},
74+
(err, files) => {
75+
expect(err).to.not.exist
76+
expect(files.filter(fileHasContent).sort(byPath)).to.eql([
77+
{ path: 'QmdCrquDwd7RfZ6GCZFEVADwe8uyyw1YmF9mtAB7etDgmK/b/h',
78+
content: 'cream' },
79+
{ path: 'QmdCrquDwd7RfZ6GCZFEVADwe8uyyw1YmF9mtAB7etDgmK/b/g',
80+
content: 'ice' },
81+
{ path: 'QmdCrquDwd7RfZ6GCZFEVADwe8uyyw1YmF9mtAB7etDgmK/b/c/d/f',
82+
content: 'strawberry' },
83+
{ path: 'QmdCrquDwd7RfZ6GCZFEVADwe8uyyw1YmF9mtAB7etDgmK/b/c/d/e',
84+
content: 'banana' }
85+
])
86+
done()
87+
})
88+
})
89+
)
90+
91+
function mapFile (file, callback) {
92+
return (err, fileContent) => {
93+
callback(err, fileContent && {
94+
path: file.path,
95+
content: fileContent.toString()
96+
})
97+
}
98+
}
99+
})
100+
})
101+
}
102+
103+
function normalizeNode (node) {
104+
return {
105+
path: node.path,
106+
multihash: mh.toB58String(node.multihash)
107+
}
108+
}
109+
110+
function fileHasContent (file) {
111+
return Boolean(file.content)
112+
}
113+
114+
function byPath (a, b) {
115+
if (a.path > b.path) return -1
116+
if (a.path < b.path) return 1
117+
return 0
118+
}

0 commit comments

Comments
 (0)