Permalink
Browse files

refactor: Avoid reduce

  • Loading branch information...
honzajavorek committed Dec 20, 2017
1 parent d7bcee4 commit bce660380f24d805628e07410cbf6a1000df2666
Showing with 131 additions and 31 deletions.
  1. +20 −31 src/resolve-hookfiles.coffee
  2. +111 −0 test/unit/resolve-hookfiles-test.coffee
@@ -8,42 +8,31 @@ basename = if process.platform is 'win32' then path.win32.basename else path.bas
# Expand hookfiles - sort files alphabetically and resolve their paths
resolveHookfiles = (hookfiles, cwd = null) ->
return [] if not hookfiles or not hookfiles.length
cwd ?= process.cwd()
return hookfiles.reduce((result, unresolvedPath) ->
resolvedPathsArrays = hookfiles.map((hookfile) ->
# glob.sync does not resolve paths, only glob patterns
if glob.hasMagic(unresolvedPath)
unresolvedPaths = glob.sync(unresolvedPath, {cwd})
if glob.hasMagic(hookfile)
resolvedPaths = glob.sync(hookfile, {cwd}).map((p) -> path.resolve(cwd, p))
else
p = path.resolve(cwd, unresolvedPath)
if fs.existsSync(p)
unresolvedPaths = [p]
else
unresolvedPaths = []
if unresolvedPaths.length == 0
throw new Error("Hook file(s) not found on path: #{unresolvedPath}")
# Gradually append sorted and resolved paths
result.concat unresolvedPaths
# Create a filename / filepath map for easier sorting
# Example:
# [
# { basename: 'filename1.coffee', path: './path/to/filename1.coffee' }
# { basename: 'filename2.coffee', path: './path/to/filename2.coffee' }
# ]
.map((filepath) -> basename: basename(filepath), path: filepath)
# Sort 'em up
.sort((a, b) -> switch
when a.basename < b.basename then -1
when a.basename > b.basename then 1
else 0
)
# Resolve paths to absolute form. Take into account current working dir
.map((item) -> path.resolve(cwd, item.path))
, [] # Start with empty result
resolvedPath = path.resolve(cwd, hookfile)
resolvedPaths = if fs.existsSync(resolvedPath) then [resolvedPath] else []
unless resolvedPaths.length
throw new Error("Could not find any hook file(s) on path: '#{hookfile}'")
return resolvedPaths
)
resolvedPaths = Array.concat.apply([], resolvedPathsArrays)
resolvedPaths = resolvedPaths.sort((p1, p2) ->
[p1, p2] = [basename(p1), basename(p2)]
switch
when p1 < p2 then -1
when p1 > p2 then 1
else 0
)
return resolvedPaths
module.exports = resolveHookfiles
@@ -0,0 +1,111 @@
path = require('path')
{assert} = require('chai')
resolveHookfiles = require('../../src/resolve-hookfiles')
describe('resolveHookfiles()', ->
cwd = path.join(__filename, '..', '..', 'fixtures')
describe('when given no paths', ->
it('produces no results', ->
paths = resolveHookfiles([], cwd = cwd)
assert.deepEqual(paths, [])
)
)
describe('when given existing absolute filenames', ->
it('resolves them into absolute paths', ->
hookfiles = [
path.join(cwd, 'hooks.js'),
path.join(cwd, 'non-js-hooks.rb'),
]
paths = resolveHookfiles(hookfiles, cwd = cwd)
assert.deepEqual(paths, hookfiles)
)
)
describe('when given existing relative filenames', ->
it('resolves them into absolute paths', ->
paths = resolveHookfiles(['./hooks.js', './non-js-hooks.rb'], cwd = cwd)
assert.deepEqual(paths, [
path.join(cwd, 'hooks.js'),
path.join(cwd, 'non-js-hooks.rb'),
])
)
)
describe('when given non-existing filenames', ->
it('throws an error', ->
assert.throws( ->
resolveHookfiles(['./hooks.js', './foo/bar/42'], cwd = cwd)
, './foo/bar/42')
)
)
describe('when given glob pattern resolving to existing files', ->
it('resolves them into absolute paths', ->
paths = resolveHookfiles(['./**/hooks.js'], cwd = cwd)
assert.deepEqual(paths, [
path.join(cwd, 'hooks.js'),
])
)
)
describe('when given glob pattern resolving to no files', ->
it('throws an error', ->
assert.throws( ->
resolveHookfiles(['./**/hooks.js', './**/foo/bar/foobar.js'], cwd = cwd)
, './**/foo/bar/foobar.js')
)
)
describe('when given both globs and filenames', ->
it('resolves them into absolute paths', ->
paths = resolveHookfiles(['./non-js-hooks.rb', './**/hooks.js'], cwd = cwd)
assert.deepEqual(paths, [
path.join(cwd, 'hooks.js'),
path.join(cwd, 'non-js-hooks.rb'),
])
)
it('throws an error on non-existing filenams', ->
assert.throws( ->
resolveHookfiles(['./**/hooks.js', './foo/bar/42'], cwd = cwd)
, './foo/bar/42')
)
it('throws an error on globs resolving to no files', ->
assert.throws( ->
resolveHookfiles(['./hooks.js', './**/foo/bar/foobar.js'], cwd = cwd)
, './**/foo/bar/foobar.js')
)
it('returns the absolute paths alphabetically sorted', ->
paths = resolveHookfiles([
'./**/*_hooks.*',
'./hooks-glob/baz/x.js',
'./hooks-glob/foo/y.js',
'./hooks-glob/bar/z.js',
'./hooks-glob/foo/a.js',
'./hooks-glob/bar/b.js',
'./hooks-glob/baz/c.js',
'./hooks-glob/foo/o.js',
'./hooks-glob/bar/p.js',
], cwd = cwd)
assert.deepEqual(paths, [
path.join(cwd, 'hooks-glob/foo/a.js'),
path.join(cwd, 'hooks-glob/bar/b.js'),
path.join(cwd, 'hooks-glob/baz/c.js'),
path.join(cwd, 'multifile/multifile_hooks.coffee'),
path.join(cwd, 'hooks-glob/foo/o.js'),
path.join(cwd, 'hooks-glob/bar/p.js'),
path.join(cwd, 'test2_hooks.js'),
path.join(cwd, 'test_hooks.coffee'),
path.join(cwd, 'hooks-glob/baz/x.js'),
path.join(cwd, 'hooks-glob/foo/y.js'),
path.join(cwd, 'hooks-glob/bar/z.js'),
])
)
)
)

0 comments on commit bce6603

Please sign in to comment.