diff --git a/lib/foreach.coffee b/lib/foreach.coffee index 6ef4ba7..bc8ac4f 100755 --- a/lib/foreach.coffee +++ b/lib/foreach.coffee @@ -61,8 +61,7 @@ module.exports = (options)-> new Promise (finish)-> ## Helpers ## ========================================================================== getDirName = (pathParams, filePath)-> - dirInGlob = options.glob.match(/^[^\*\/]*/)[0] - dirInGlob += if dirInGlob then '/' else '' + dirInGlob = options.glob.match(/^[^\*]*/)[0] || '' filePath .replace pathParams.base, '' .replace process.cwd()+"/#{dirInGlob}", '' diff --git a/test/test.coffee b/test/test.coffee index a2a1d71..2ccca69 100644 --- a/test/test.coffee +++ b/test/test.coffee @@ -6,6 +6,23 @@ expect = chai.expect should = chai.should() bin = PATH.resolve 'bin' +parsePlaceholdersResult = (result) -> + parsedResults = { lines: undefined, linesMap: {} } + parsedResults.lines = result.split('\n').filter (validLine)-> validLine + + parsedResults.lines.forEach (resultLine) -> + placeHoldersObj = {} + placeHolders = resultLine.split(' ') + placeHoldersObj.name = placeHolders[0] + placeHoldersObj.ext = placeHolders[1] + placeHoldersObj.base = placeHolders[2] + placeHoldersObj.reldir = placeHolders[3] + placeHoldersObj.path = placeHolders[4] + placeHoldersObj.dir = placeHolders[5] + parsedResults.linesMap[placeHoldersObj.path] = placeHoldersObj + + return parsedResults + suite "ForEach-cli", ()-> suiteSetup (done)-> fs.ensureDir 'test/temp', done @@ -16,11 +33,11 @@ suite "ForEach-cli", ()-> result = fs.readFileSync 'test/temp/one', {encoding:'utf8'} resultLines = result.split('\n').filter (validLine)-> validLine + # Because there is 3, and all of them are within the list of 3. Then each of them makes a line expect(resultLines.length).to.equal 3 - expect(resultLines[0]).to.equal 'foldr.css' - expect(resultLines[1]).to.equal 'main.copy.css' - expect(resultLines[2]).to.equal 'main.css' - + expect(resultLines.find (line) -> line == 'foldr.css').to.be.truthy + expect(resultLines.find (line) -> line == 'main.copy.css').to.be.truthy + expect(resultLines.find (line) -> line == 'main.css').to.be.truthy test "Will execute a given command on all matched files/dirs in a given glob when using positional arguments", ()-> @@ -29,34 +46,139 @@ suite "ForEach-cli", ()-> resultLines = result.split('\n').filter (validLine)-> validLine expect(resultLines.length).to.equal 3 - expect(resultLines[0]).to.equal 'foldr.css' - expect(resultLines[1]).to.equal 'main.copy.css' - expect(resultLines[2]).to.equal 'main.css' + expect(resultLines.find (line) -> line == 'foldr.css').to.be.truthy + expect(resultLines.find (line) -> line == 'main.copy.css').to.be.truthy + expect(resultLines.find (line) -> line == 'main.css').to.be.truthy test "Placeholders can be used in the command which will be dynamically filled according to the subject path", ()-> - execa(bin, ['-g', 'test/samples/sass/css/*', '-x', 'echo "{{name}} {{ext}} {{base}} {{reldir}} {{path}} {{dir}}" >> test/temp/three']).then (err)-> + execa(bin, ['-g', 'test/samples/sass/css/**/*', '-x', 'echo "{{name}} {{ext}} {{base}} {{reldir}} {{path}} {{dir}}" >> test/temp/three']).then (err)-> result = fs.readFileSync 'test/temp/three', {encoding:'utf8'} - resultLines = result.split('\n').filter (validLine)-> validLine - - expect(resultLines.length).to.equal 3 - expect(resultLines[0]).to.equal "foldr .css foldr.css samples/sass/css test/samples/sass/css/foldr.css #{process.cwd()}/test/samples/sass/css" - expect(resultLines[1]).to.equal "main.copy .css main.copy.css samples/sass/css test/samples/sass/css/main.copy.css #{process.cwd()}/test/samples/sass/css" - expect(resultLines[2]).to.equal "main .css main.css samples/sass/css test/samples/sass/css/main.css #{process.cwd()}/test/samples/sass/css" - - - + + parsedResult = parsePlaceholdersResult(result) + + # Check length + expect(parsedResult.lines.length).to.equal 4 + + # Check the paths + [ + ' test/samples/sass/css/foldr.css ', + ' test/samples/sass/css/foldr.css/sub.css ', + ' test/samples/sass/css/main.copy.css ', + ' test/samples/sass/css/main.css ' + ].forEach (path) -> expect(result.includes(path)).to.be.truthy + + + # We are using mapping to make tests pure, as Listr run doesn't gurantee the order of execution + expectedResults = [ + # folder file match + { + path: 'test/samples/sass/css/foldr.css', + name: 'foldr', + ext: '.css', + base: 'foldr.css', + reldir: '', + dir: "#{process.cwd()}/test/samples/sass/css" # because a folder + }, + # ✨ Nested folder, and reldir + { + path: 'test/samples/sass/css/foldr.css/sub.css', + name: 'sub', + ext: '.css', + base: 'sub.css', + reldir: 'foldr.css', + dir: "#{process.cwd()}/test/samples/sass/css/foldr.css" + }, + { + path: 'test/samples/sass/css/main.copy.css', + name: 'main.copy', + ext: '.css', + base: 'main.copy.css', + reldir: '', + dir: "#{process.cwd()}/test/samples/sass/css" + }, + { + path: 'test/samples/sass/css/main.css', + name: 'main', + ext: '.css', + base: 'main.css', + reldir: '', + dir: "#{process.cwd()}/test/samples/sass/css" + } + ] + + for expected in expectedResults + m = parsedResult.linesMap[expected.path] + expect(m.name).to.equal expected.name + expect(m.ext).to.equal expected.ext + expect(m.base).to.equal expected.base + expect(m.reldir).to.equal expected.reldir + expect(m.path).to.equal expected.path + expect(m.dir).to.equal expected.dir + test "Placeholders can be denoted either with dual curly braces or a hash + single curly brace wrap", ()-> - execa(bin, ['-g', 'test/samples/sass/css/*', '-x', 'echo "#{name} #{ext} #{base} #{reldir} #{path} #{dir}" >> test/temp/four']).then (err)-> + execa(bin, ['-g', 'test/samples/sass/css/**/*', '-x', 'echo "#{name} #{ext} #{base} #{reldir} #{path} #{dir}" >> test/temp/four']).then (err)-> result = fs.readFileSync 'test/temp/four', {encoding:'utf8'} - resultLines = result.split('\n').filter (validLine)-> validLine - - expect(resultLines.length).to.equal 3 - expect(resultLines[0]).to.equal "foldr .css foldr.css samples/sass/css test/samples/sass/css/foldr.css #{process.cwd()}/test/samples/sass/css" - expect(resultLines[1]).to.equal "main.copy .css main.copy.css samples/sass/css test/samples/sass/css/main.copy.css #{process.cwd()}/test/samples/sass/css" - expect(resultLines[2]).to.equal "main .css main.css samples/sass/css test/samples/sass/css/main.css #{process.cwd()}/test/samples/sass/css" - + parsedResult = parsePlaceholdersResult(result) + + # Check length + expect(parsedResult.lines.length).to.equal 4 + + # Check the paths + [ + ' test/samples/sass/css/foldr.css ', + ' test/samples/sass/css/foldr.css/sub.css ', + ' test/samples/sass/css/main.copy.css ', + ' test/samples/sass/css/main.css ' + ].forEach (path) -> expect(result.includes(path)).to.be.truthy + + # We are using mapping to make tests pure, as Listr run doesn't gurantee the order of execution + expectedResults = [ + # folder file match + { + path: 'test/samples/sass/css/foldr.css', + name: 'foldr', + ext: '.css', + base: 'foldr.css', + reldir: '', + dir: "#{process.cwd()}/test/samples/sass/css" # because a folder + }, + # ✨ Nested folder, and reldir + { + path: 'test/samples/sass/css/foldr.css/sub.css', + name: 'sub', + ext: '.css', + base: 'sub.css', + reldir: 'foldr.css', + dir: "#{process.cwd()}/test/samples/sass/css/foldr.css" + }, + { + path: 'test/samples/sass/css/main.copy.css', + name: 'main.copy', + ext: '.css', + base: 'main.copy.css', + reldir: '', + dir: "#{process.cwd()}/test/samples/sass/css" + }, + { + path: 'test/samples/sass/css/main.css', + name: 'main', + ext: '.css', + base: 'main.css', + reldir: '', + dir: "#{process.cwd()}/test/samples/sass/css" + } + ] + + for expected in expectedResults + m = parsedResult.linesMap[expected.path] + expect(m.name).to.equal expected.name + expect(m.ext).to.equal expected.ext + expect(m.base).to.equal expected.base + expect(m.reldir).to.equal expected.reldir + expect(m.path).to.equal expected.path + expect(m.dir).to.equal expected.dir test "Will execute a given command on all matched files/dirs in a given glob with ignore option", ()-> @@ -65,9 +187,8 @@ suite "ForEach-cli", ()-> resultLines = result.split('\n').filter (validLine)-> validLine expect(resultLines.length).to.equal 2 - expect(resultLines[0]).to.equal 'foldr.css' - expect(resultLines[1]).to.equal 'main.css' - + expect(resultLines.find (line) -> line == 'foldr.css').to.be.truthy + expect(resultLines.find (line) -> line == 'main.css').to.be.truthy test "Will execute a given command on all matched files in a given glob but ignoring the folders", ()-> @@ -76,26 +197,16 @@ suite "ForEach-cli", ()-> resultLines = result.split('\n').filter (validLine)-> validLine expect(resultLines.length).to.equal 2 - expect(resultLines[0]).to.equal 'main.copy.css' - expect(resultLines[1]).to.equal 'main.css' - + expect(resultLines.find (line) -> line == 'main.copy.css').to.be.truthy + expect(resultLines.find (line) -> line == 'main.css').to.be.truthy test "Will execute a given command on all matched `.css` files in a given glob with ** but ignoring the folders", ()-> execa(bin, ['-g', 'test/samples/sass/css/**/*.css', '--nodir', 'true', '-x', 'echo {{base}} >> test/temp/seven']).then (err)-> result = fs.readFileSync 'test/temp/seven', {encoding:'utf8'} resultLines = result.split('\n').filter (validLine)-> validLine - + expect(resultLines.length).to.equal 3 - expect(resultLines[0]).to.equal 'sub.css' - expect(resultLines[1]).to.equal 'main.copy.css' - expect(resultLines[2]).to.equal 'main.css' - - - - - - - - - + expect(resultLines.find (line) -> line == 'sub.css').to.be.truthy + expect(resultLines.find (line) -> line == 'main.copy.css').to.be.truthy + expect(resultLines.find (line) -> line == 'main.css').to.be.truthy