Skip to content

Commit

Permalink
Merge pull request #13 from jskrzypek/feat-traverse-all
Browse files Browse the repository at this point in the history
Traverse all option
  • Loading branch information
manidlou authored Sep 23, 2018
2 parents 6153ed6 + f67a144 commit 28acfba
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 7 deletions.
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@ Usage
- custom `fs`, useful when mocking `fs` object.
- `filter` `<Function>`
- function that gets one argument `fn({path: '', stats: {}})` and returns true to include or false to exclude the item.

- `traverseAll` `<Boolean>`
- traverse all subdirectories, regardless of `filter` option. (When set to `true`, `traverseAll` produces similar behavior to the default behavior prior to v4.0.0. The current default of `traverseAll: false` is equivalent to the old `noRecurseOnFailedFilter: true`).
- **Return:** `<Array<Object>>` `[{path: '', stats: {}}]`

Examples
Expand Down Expand Up @@ -93,7 +94,7 @@ const paths = klawSync('/some/dir', { filter: filterFn})

_**filter based on stats**_

Again here `noRecurseOnFailedFilter` option is not required since we still want to read all directories even though they don't pass the `filter` function, to see if their contents pass the `filter` function.
Here `traverseAll` option is required since we still want to read all directories even if they don't pass the `filter` function, to see if their contents do pass the `filter` function.

```js
const klawSync = require('klaw-sync')
Expand Down
14 changes: 9 additions & 5 deletions klaw-sync.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,16 @@ function klawSync (dir, opts, ls) {
const st = opts.fs.statSync(pi)
const item = {path: pi, stats: st}
const isUnderDepthLimit = (!opts.rootDepth || pi.split(path.sep).length - opts.rootDepth < opts.depthLimit)
const filterResult = opts.filter ? opts.filter(item) : true
const isDirectory = st.isDirectory()
const shouldAdd = filterResult && (isDirectory ? !opts.nodir : !opts.nofile)
const shouldTraverse = isDirectory && isUnderDepthLimit && (opts.traverseAll || filterResult)

if (st.isDirectory()) {
if (!opts.nodir) { if ((opts.filter && opts.filter(item)) || !opts.filter) ls.push(item) }
if (isUnderDepthLimit && ((opts.filter && opts.filter(item)) || !opts.filter)) ls = klawSync(pi, opts, ls)
} else if (!st.isDirectory()) {
if (!opts.nofile) { if ((opts.filter && opts.filter(item)) || !opts.filter) ls.push(item) }
if (shouldAdd) {
ls.push(item)
}
if (shouldTraverse) {
ls = klawSync(pi, opts, ls)
}
}
return ls
Expand Down
49 changes: 49 additions & 0 deletions test/klaw-sync.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -335,4 +335,53 @@ describe('klaw-sync', () => {
assert.deepStrictEqual(items, expected)
}
})
describe('traverse all', function () {
beforeEach(() => {
fs.emptyDirSync(TEST_DIR)
})
it('should honor traverseAll option with no filter & nodir: false', () => {
const expected = ['a', 'a/b', 'a/b/c', 'a/b/c/d.txt', 'a/e.jpg', 'h', 'h/i',
'h/i/j', 'h/i/j/k.txt', 'h/i/l.txt', 'h/i/m.jpg', 't.txt']
testTraverseAll({ nodir: false }, expected)
})
it('should honor traverseAll option with no filter & nodir: true', () => {
const expected = ['a/b/c/d.txt', 'a/e.jpg', 'h/i/j/k.txt', 'h/i/l.txt', 'h/i/m.jpg', 't.txt']
testTraverseAll({ nodir: true }, expected)
})
it('should honor traverseAll option with filter & nodir: true', () => {
const expected = ['a/b/c/d.txt', 'h/i/j/k.txt', 'h/i/l.txt', 't.txt']
const filter = function (item) {
return path.extname(item.path) === '.txt' // no need to greenlight dirs in filter
}
testTraverseAll({ nodir: true, filter }, expected)
})
it('should honor traverseAll option with filter & nodir: false', () => {
const expected = ['a', 'a/b', 'a/b/c', 'a/e.jpg', 'h',
'h/i/j', 'h/i/m.jpg']
const filter = function (item) {
return path.basename(item.path) !== 'i' && path.extname(item.path) !== '.txt'
}
testTraverseAll({ nodir: false, filter }, expected)
})

function testTraverseAll ({ filter, nodir = false } = {}, expected) {
const fixtures = [
'a/b/c/d.txt',
'a/e.jpg',
'h/i/j/k.txt',
'h/i/l.txt',
'h/i/m.jpg',
't.txt'
]
fixtures.forEach(f => {
f = path.join(TEST_DIR, f)
fs.outputFileSync(f, path.basename(f, path.extname(f)))
})

const items = klawSync(TEST_DIR, { traverseAll: true, nodir, filter }).map(i => i.path)
items.sort()
expected = expected.map(item => path.join(path.join(TEST_DIR, item)))
assert.deepStrictEqual(items, expected)
}
})
})

0 comments on commit 28acfba

Please sign in to comment.