diff --git a/index.js b/index.js index fdddc763..16a95f01 100644 --- a/index.js +++ b/index.js @@ -9,6 +9,9 @@ var Liftoff = require('liftoff'); var tildify = require('tildify'); var interpret = require('interpret'); var v8flags = require('v8flags'); +var merge = require('lodash.merge'); +var sortBy = require('lodash.sortby'); +var isString = require('lodash.isstring'); var findRange = require('semver-greatest-satisfied-range'); var exit = require('./lib/shared/exit'); var cliOptions = require('./lib/shared/cliOptions'); @@ -34,6 +37,18 @@ var cli = new Liftoff({ completions: completion, extensions: interpret.jsVariants, v8flags: v8flags, + configFiles: { + '.gulp': { + home: { + path: '~', + extensions: interpret.extensions, + }, + cwd: { + path: '.', + extensions: interpret.extensions, + }, + }, + }, }); var usage = @@ -82,6 +97,12 @@ module.exports = run; // The actual logic function handleArguments(env) { + + var configFilePaths = sortBy(env.configFiles['.gulp'], ['home', 'cwd']); + configFilePaths.filter(isString).forEach(function(filePath) { + merge(opts, require(filePath)); + }); + if (opts.help) { console.log(parser.help()); exit(0); diff --git a/lib/versioned/^3.7.0/index.js b/lib/versioned/^3.7.0/index.js index 58fc9727..4879095e 100644 --- a/lib/versioned/^3.7.0/index.js +++ b/lib/versioned/^3.7.0/index.js @@ -4,6 +4,7 @@ var chalk = require('chalk'); var log = require('gulplog'); var stdout = require('mute-stdout'); var tildify = require('tildify'); +var isString = require('lodash.isstring'); var taskTree = require('./taskTree'); var logTasks = require('../../shared/log/tasks'); @@ -38,7 +39,11 @@ function execute(opts, env) { } if (opts.tasks) { var tree = taskTree(gulpInst.tasks); - tree.label = 'Tasks for ' + chalk.magenta(tildify(env.configPath)); + if (opts.description && isString(opts.description)) { + tree.label = opts.description; + } else { + tree.label = 'Tasks for ' + chalk.magenta(tildify(env.configPath)); + } return logTasks(tree, opts.depth, function(task) { return gulpInst.tasks[task].fn; }); diff --git a/lib/versioned/^4.0.0-alpha.1/index.js b/lib/versioned/^4.0.0-alpha.1/index.js index 0d942a8e..1eb91b06 100644 --- a/lib/versioned/^4.0.0-alpha.1/index.js +++ b/lib/versioned/^4.0.0-alpha.1/index.js @@ -6,6 +6,7 @@ var log = require('gulplog'); var chalk = require('chalk'); var stdout = require('mute-stdout'); var tildify = require('tildify'); +var isString = require('lodash.isstring'); var exit = require('../../shared/exit'); @@ -42,10 +43,13 @@ function execute(opts, env) { return logTasksSimple(gulpInst.tree()); } if (opts.tasks) { - var tree = { - label: 'Tasks for ' + chalk.magenta(tildify(env.configPath)), - nodes: gulpInst.tree({ deep: true }), - }; + var tree = {}; + if (opts.description && isString(opts.description)) { + tree.label = opts.description; + } else { + tree.label = 'Tasks for ' + chalk.magenta(tildify(env.configPath)); + } + tree.nodes = gulpInst.tree({ deep: true }); return logTasks(tree, opts.depth, function(taskname) { return gulpInst.task(taskname); }); diff --git a/lib/versioned/^4.0.0-alpha.2/index.js b/lib/versioned/^4.0.0-alpha.2/index.js index d7430c75..63c85b49 100644 --- a/lib/versioned/^4.0.0-alpha.2/index.js +++ b/lib/versioned/^4.0.0-alpha.2/index.js @@ -6,6 +6,7 @@ var log = require('gulplog'); var chalk = require('chalk'); var stdout = require('mute-stdout'); var tildify = require('tildify'); +var isString = require('lodash.isstring'); var exit = require('../../shared/exit'); @@ -48,13 +49,21 @@ function execute(opts, env) { } if (opts.tasks) { tree = gulpInst.tree({ deep: true }); - tree.label = 'Tasks for ' + chalk.magenta(tildify(env.configPath)); + if (opts.description && isString(opts.description)) { + tree.label = opts.description; + } else { + tree.label = 'Tasks for ' + chalk.magenta(tildify(env.configPath)); + } return logTasks(tree, opts.depth, getTask(gulpInst)); } if (opts.tasksJson) { tree = gulpInst.tree({ deep: true }); - tree.label = 'Tasks for ' + tildify(env.configPath); + if (opts.description && isString(opts.description)) { + tree.label = opts.description; + } else { + tree.label = 'Tasks for ' + tildify(env.configPath); + } var output = JSON.stringify(tree); diff --git a/lib/versioned/^4.0.0/index.js b/lib/versioned/^4.0.0/index.js index b3146801..d434827c 100644 --- a/lib/versioned/^4.0.0/index.js +++ b/lib/versioned/^4.0.0/index.js @@ -6,6 +6,7 @@ var log = require('gulplog'); var chalk = require('chalk'); var stdout = require('mute-stdout'); var tildify = require('tildify'); +var isString = require('lodash.isstring'); var exit = require('../../shared/exit'); @@ -48,13 +49,21 @@ function execute(opts, env) { } if (opts.tasks) { tree = gulpInst.tree({ deep: true }); - tree.label = 'Tasks for ' + chalk.magenta(tildify(env.configPath)); + if (opts.description && isString(opts.description)) { + tree.label = opts.description; + } else { + tree.label = 'Tasks for ' + chalk.magenta(tildify(env.configPath)); + } return logTasks(tree, opts.depth, getTask(gulpInst)); } if (opts.tasksJson) { tree = gulpInst.tree({ deep: true }); - tree.label = 'Tasks for ' + tildify(env.configPath); + if (opts.description && isString(opts.description)) { + tree.label = opts.description; + } else { + tree.label = 'Tasks for ' + tildify(env.configPath); + } var output = JSON.stringify(tree); diff --git a/package.json b/package.json index ff5f257a..226846cf 100644 --- a/package.json +++ b/package.json @@ -36,10 +36,11 @@ "fancy-log": "^1.1.0", "gulplog": "^1.0.0", "interpret": "^1.0.0", - "liftoff": "^2.1.0", + "liftoff": "^2.3.0", "lodash.isfunction": "^3.0.8", "lodash.isplainobject": "^4.0.4", "lodash.isstring": "^4.0.1", + "lodash.merge": "^4.5.1", "lodash.sortby": "^4.5.0", "matchdep": "^1.0.0", "mute-stdout": "^1.0.0", diff --git a/test/config.js b/test/config.js new file mode 100644 index 00000000..1a42a8fe --- /dev/null +++ b/test/config.js @@ -0,0 +1,67 @@ +'use strict'; + +var lab = exports.lab = require('lab').script(); +var expect = require('code').expect; +var path = require('path'); +var fs = require('fs'); + +var skipLines = require('./tools/skip-lines'); +var eraseTime = require('./tools/erase-time'); +var runner = require('./tools/run-gulp'); + +var fixturesDir = path.join(__dirname, 'fixtures', 'config'); +var expectedDir = path.join(__dirname, 'expected', 'config'); + +lab.experiment('gulp configuration', function() { + + lab.test('Should configure with a .gulp.* file in cwd', + function(done) { + runner({ verbose: false }) + .basedir(fixturesDir) + .chdir('foo/bar') + .gulp('--tasks') + .run(cb); + + function cb(err, stdout) { + var expected = fs.readFileSync(path.join(expectedDir, 'output0.txt'), + 'utf-8'); + stdout = eraseTime(stdout); + expect(stdout).to.equal(expected); + done(err); + } + }); + + lab.test('Should configure with a .gulp.* file in cwd found up', + function(done) { + runner({ verbose: false }) + .basedir(fixturesDir) + .chdir('foo/bar/baz') + .gulp('--tasks') + .run(cb); + + function cb(err, stdout) { + var expected = fs.readFileSync(path.join(expectedDir, 'output0.txt'), + 'utf-8'); + stdout = eraseTime(skipLines(stdout, 1)); + expect(stdout).to.equal(expected); + done(err); + } + }); + + lab.test('Should configure with a .gulp.* file in cwd by --cwd', + function(done) { + runner({ verbose: false }) + .basedir(fixturesDir) + .chdir('qux') + .gulp('--tasks', '--gulpfile ../foo/bar/gulpfile.js', '--cwd .') + .run(cb); + + function cb(err, stdout) { + var expected = fs.readFileSync(path.join(expectedDir, 'output1.txt'), + 'utf-8'); + stdout = eraseTime(stdout); + expect(stdout).to.equal(expected); + done(err); + } + }); +}); diff --git a/test/expected/flags-tasks/by-unwrap-and-not-by-unwrap.txt b/test/expected/by-unwrap-and-not-by-unwrap.txt similarity index 96% rename from test/expected/flags-tasks/by-unwrap-and-not-by-unwrap.txt rename to test/expected/by-unwrap-and-not-by-unwrap.txt index 5545c810..22de5a7f 100644 --- a/test/expected/flags-tasks/by-unwrap-and-not-by-unwrap.txt +++ b/test/expected/by-unwrap-and-not-by-unwrap.txt @@ -1,4 +1,4 @@ -gulp-cli/test +gulp-cli/test/fixtures ├─┬ default │ └─┬ │ ├── task1 diff --git a/test/expected/config/output0.txt b/test/expected/config/output0.txt new file mode 100644 index 00000000..0ce27694 --- /dev/null +++ b/test/expected/config/output0.txt @@ -0,0 +1,2 @@ +Description by .gulp.json in directory foo/bar +└── default diff --git a/test/expected/config/output1.txt b/test/expected/config/output1.txt new file mode 100644 index 00000000..ad72767c --- /dev/null +++ b/test/expected/config/output1.txt @@ -0,0 +1,2 @@ +description by .gulp.js in directory qux +└── default diff --git a/test/expected/flags-tasks-json.json b/test/expected/flags-tasks-json.json index f98bdd98..d22a0e65 100644 --- a/test/expected/flags-tasks-json.json +++ b/test/expected/flags-tasks-json.json @@ -1 +1 @@ -{"label":"Tasks for {{path}}","nodes":[{"label":"test1","type":"task","nodes":[{"label":"","type":"function","branch":true,"nodes":[{"label":"noop","type":"function","nodes":[]}]}]},{"label":"test2","type":"task","nodes":[{"label":"","type":"function","branch":true,"nodes":[{"label":"test1","type":"task","nodes":[{"label":"","type":"function","branch":true,"nodes":[{"label":"noop","type":"function","nodes":[]}]}]},{"label":"noop","type":"function","nodes":[]}]}]},{"label":"test3","type":"task","nodes":[{"label":"","type":"function","branch":true,"nodes":[{"label":"described","type":"function","nodes":[]}]}]},{"label":"test4","type":"task","nodes":[{"label":"","type":"function","branch":true,"nodes":[{"label":"errorFunction","type":"function","nodes":[]},{"label":"anon","type":"function","nodes":[]}]}]},{"label":"default","type":"task","nodes":[{"label":"","type":"function","branch":true,"nodes":[{"label":"test1","type":"task","nodes":[{"label":"","type":"function","branch":true,"nodes":[{"label":"noop","type":"function","nodes":[]}]}]},{"label":"test3","type":"task","nodes":[{"label":"","type":"function","branch":true,"nodes":[{"label":"described","type":"function","nodes":[]}]}]},{"label":"noop","type":"function","nodes":[]}]}]}]} +{"label":"gulp-cli/test/fixtures/gulpfiles","nodes":[{"label":"test1","type":"task","nodes":[{"label":"","type":"function","branch":true,"nodes":[{"label":"noop","type":"function","nodes":[]}]}]},{"label":"test2","type":"task","nodes":[{"label":"","type":"function","branch":true,"nodes":[{"label":"test1","type":"task","nodes":[{"label":"","type":"function","branch":true,"nodes":[{"label":"noop","type":"function","nodes":[]}]}]},{"label":"noop","type":"function","nodes":[]}]}]},{"label":"test3","type":"task","nodes":[{"label":"","type":"function","branch":true,"nodes":[{"label":"described","type":"function","nodes":[]}]}]},{"label":"test4","type":"task","nodes":[{"label":"","type":"function","branch":true,"nodes":[{"label":"errorFunction","type":"function","nodes":[]},{"label":"anon","type":"function","nodes":[]}]}]},{"label":"default","type":"task","nodes":[{"label":"","type":"function","branch":true,"nodes":[{"label":"test1","type":"task","nodes":[{"label":"","type":"function","branch":true,"nodes":[{"label":"noop","type":"function","nodes":[]}]}]},{"label":"test3","type":"task","nodes":[{"label":"","type":"function","branch":true,"nodes":[{"label":"described","type":"function","nodes":[]}]}]},{"label":"noop","type":"function","nodes":[]}]}]}]} diff --git a/test/expected/flags-tasks.txt b/test/expected/flags-tasks.txt index 6413c332..cdfe8041 100644 --- a/test/expected/flags-tasks.txt +++ b/test/expected/flags-tasks.txt @@ -1,4 +1,4 @@ -gulp-cli/test +gulp-cli/test/fixtures/gulpfiles ├─┬ default │ └─┬ │ ├─┬ test1 diff --git a/test/expected/tasks-as-exports.txt b/test/expected/tasks-as-exports.txt index e8214270..8c825148 100644 --- a/test/expected/tasks-as-exports.txt +++ b/test/expected/tasks-as-exports.txt @@ -1,4 +1,4 @@ -gulp-cli/test +gulp-cli/test/fixtures/gulpfiles ├── build ├── clean └─┬ dist diff --git a/test/expected/flags-tasks/with-desc-and-flags.txt b/test/expected/with-desc-and-flags.txt similarity index 97% rename from test/expected/flags-tasks/with-desc-and-flags.txt rename to test/expected/with-desc-and-flags.txt index 3c76e6d7..6d65313d 100644 --- a/test/expected/flags-tasks/with-desc-and-flags.txt +++ b/test/expected/with-desc-and-flags.txt @@ -1,4 +1,4 @@ -gulp-cli/test +gulp-cli/test/fixtures ├─┬ build Build all the things! │ │ --dev …un-minified │ │ --production …compressed into single bundle diff --git a/test/exports-as-tasks.js b/test/exports-as-tasks.js index 96533ad5..46601f05 100644 --- a/test/exports-as-tasks.js +++ b/test/exports-as-tasks.js @@ -1,26 +1,31 @@ 'use strict'; var lab = exports.lab = require('lab').script(); -var code = require('code'); +var expect = require('code').expect; var fs = require('fs'); -var child = require('child_process'); +var path = require('path'); +var skipLines = require('./tools/skip-lines'); +var eraseTime = require('./tools/erase-time'); +var runner = require('./tools/run-gulp'); -var output = fs.readFileSync(__dirname + '/expected/tasks-as-exports.txt', 'utf8').replace(/(\r\n|\n|\r)/gm,'\n'); +var expectedDir = path.join(__dirname, 'expected'); // Long timeout is required because parse time is slow lab.experiment('exports as tasks', { timeout: 0 }, function() { lab.test('prints the task list', function(done) { + runner({ verbose: false }) + .gulp('--tasks', + '--gulpfile ./fixtures/gulpfiles/gulpfile-exports.babel.js') + .run(cb); - child.exec('node ' + __dirname + '/../bin/gulp.js --tasks --gulpfile "./test/fixtures/gulpfile-exports.babel.js"', function(err, stdout) { - code.expect(stdout).to.contain('Tasks for'); - stdout = stdout.replace(/\\/g, '/').split('Tasks for')[1].split('\n'); - var outputArray = output.split('\n'); - for (var i = 0; i < stdout.length; i++) { - code.expect(stdout[i]).to.contain(outputArray[i]); - } - done(err); - }); + function cb(err, stdout) { + var filepath = path.join(expectedDir, 'tasks-as-exports.txt'); + var expected = fs.readFileSync(filepath, 'utf-8'); + stdout = eraseTime(skipLines(stdout, 2)); + expect(stdout).to.equal(expected); + done(); + } }); }); diff --git a/test/fixtures/.gulp.json b/test/fixtures/.gulp.json new file mode 100644 index 00000000..6aad6e7f --- /dev/null +++ b/test/fixtures/.gulp.json @@ -0,0 +1,3 @@ +{ + "description" : "gulp-cli/test/fixtures" +} diff --git a/test/fixtures/config/foo/bar/.gulp.json b/test/fixtures/config/foo/bar/.gulp.json new file mode 100644 index 00000000..186db419 --- /dev/null +++ b/test/fixtures/config/foo/bar/.gulp.json @@ -0,0 +1,3 @@ +{ + "description": "Description by .gulp.json in directory foo/bar" +} diff --git a/test/fixtures/config/foo/bar/baz/.gulp.babel.js b/test/fixtures/config/foo/bar/baz/.gulp.babel.js new file mode 100644 index 00000000..4e6e98c4 --- /dev/null +++ b/test/fixtures/config/foo/bar/baz/.gulp.babel.js @@ -0,0 +1,3 @@ +// jscs:disable + +exports.description = 'DESCRIPTION BY .gulp.babel.js in directory foo/bar/baz' diff --git a/test/fixtures/config/foo/bar/gulpfile.js b/test/fixtures/config/foo/bar/gulpfile.js new file mode 100644 index 00000000..42466b03 --- /dev/null +++ b/test/fixtures/config/foo/bar/gulpfile.js @@ -0,0 +1,7 @@ +'use strict'; + +var gulp = require('gulp'); + +gulp.task('default', function(done) { + done(); +}); diff --git a/test/fixtures/config/qux/.gulp.js b/test/fixtures/config/qux/.gulp.js new file mode 100644 index 00000000..5af0785a --- /dev/null +++ b/test/fixtures/config/qux/.gulp.js @@ -0,0 +1,5 @@ +'use strict'; + +module.exports = { + description: 'description by .gulp.js in directory qux', +}; diff --git a/test/fixtures/gulpfiles/.gulp.json b/test/fixtures/gulpfiles/.gulp.json new file mode 100644 index 00000000..65158fad --- /dev/null +++ b/test/fixtures/gulpfiles/.gulp.json @@ -0,0 +1,3 @@ +{ + "description" : "gulp-cli/test/fixtures/gulpfiles" +} diff --git a/test/fixtures/flags-tasks/by-unwrap-and-not-by-unwrap.js b/test/fixtures/gulpfiles/by-unwrap-and-not-by-unwrap.js similarity index 100% rename from test/fixtures/flags-tasks/by-unwrap-and-not-by-unwrap.js rename to test/fixtures/gulpfiles/by-unwrap-and-not-by-unwrap.js diff --git a/test/fixtures/gulpfile-2.js b/test/fixtures/gulpfiles/gulpfile-2.js similarity index 100% rename from test/fixtures/gulpfile-2.js rename to test/fixtures/gulpfiles/gulpfile-2.js diff --git a/test/fixtures/gulpfile-3.8.10.js b/test/fixtures/gulpfiles/gulpfile-3.8.10.js similarity index 100% rename from test/fixtures/gulpfile-3.8.10.js rename to test/fixtures/gulpfiles/gulpfile-3.8.10.js diff --git a/test/fixtures/gulpfile-exports.babel.js b/test/fixtures/gulpfiles/gulpfile-exports.babel.js similarity index 100% rename from test/fixtures/gulpfile-exports.babel.js rename to test/fixtures/gulpfiles/gulpfile-exports.babel.js diff --git a/test/fixtures/gulpfile.js b/test/fixtures/gulpfiles/gulpfile.js similarity index 100% rename from test/fixtures/gulpfile.js rename to test/fixtures/gulpfiles/gulpfile.js diff --git a/test/fixtures/flags-tasks/with-desc-and-flags.js b/test/fixtures/gulpfiles/with-desc-and-flags.js similarity index 100% rename from test/fixtures/flags-tasks/with-desc-and-flags.js rename to test/fixtures/gulpfiles/with-desc-and-flags.js diff --git a/test/flags-continue.js b/test/flags-continue.js index 7b7eb6cb..3288fbb1 100644 --- a/test/flags-continue.js +++ b/test/flags-continue.js @@ -8,7 +8,7 @@ var child = require('child_process'); lab.experiment('flag: --continue', function() { lab.test('continues execution when flag is set', function(done) { - child.exec('node ' + __dirname + '/../bin/gulp.js test4 --continue --cwd ./test/fixtures', function(err, stdout, stderr) { + child.exec('node ' + __dirname + '/../bin/gulp.js test4 --continue --cwd ./test/fixtures/gulpfiles', function(err, stdout, stderr) { code.expect(stdout).to.contain('Starting \'errorFunction\''); code.expect(stderr).to.contain('\'errorFunction\' errored after'); stdout = stdout.replace(/\\/g, '/').split('\n'); @@ -19,7 +19,7 @@ lab.experiment('flag: --continue', function() { }); lab.test('stops execution when flag is not set', function(done) { - child.exec('node ' + __dirname + '/../bin/gulp.js test4 --cwd ./test/fixtures', function(err, stdout, stderr) { + child.exec('node ' + __dirname + '/../bin/gulp.js test4 --cwd ./test/fixtures/gulpfiles', function(err, stdout, stderr) { code.expect(stdout).to.contain('Starting \'errorFunction\''); code.expect(stderr).to.contain('\'errorFunction\' errored after'); code.expect(stdout[4]).to.not.contain('Starting \'anon\''); diff --git a/test/flags-gulpfile.js b/test/flags-gulpfile.js index 8c45e9ff..5142bf75 100644 --- a/test/flags-gulpfile.js +++ b/test/flags-gulpfile.js @@ -8,9 +8,9 @@ var child = require('child_process'); lab.experiment('flag: --gulpfile', function() { lab.test('Manually set path of gulpfile', function(done) { - child.exec('node ' + __dirname + '/../bin/gulp.js --gulpfile "./test/fixtures/gulpfile-2.js"', function(err, stdout) { + child.exec('node ' + __dirname + '/../bin/gulp.js --gulpfile "./test/fixtures/gulpfiles/gulpfile-2.js"', function(err, stdout) { stdout = stdout.replace(/\\/g, '/').split('\n'); - code.expect(stdout[1]).to.contain('test/fixtures/gulpfile-2.js'); + code.expect(stdout[1]).to.contain('test/fixtures/gulpfiles/gulpfile-2.js'); code.expect(stdout[5]).to.contain('Finished \'default\''); done(err); }); diff --git a/test/flags-help.js b/test/flags-help.js index edf91a50..fe9b4ed1 100644 --- a/test/flags-help.js +++ b/test/flags-help.js @@ -11,7 +11,7 @@ var outfile = path.resolve(__dirname, 'output/flags-help.out'); var output = fs.readFileSync(__dirname + '/expected/flags-help.txt', 'utf8').replace(/(\r\n|\n|\r)\s?/gm,'\n'); -lab.experiment('flag: help', function() { +lab.experiment('flag: --help', function() { lab.before(function(done) { fs.mkdirpSync(path.resolve(__dirname, 'output')); @@ -24,7 +24,7 @@ lab.experiment('flag: help', function() { }); lab.test('shows help using --help', function(done) { - child.exec('node ' + __dirname + '/../bin/gulp.js --help --cwd ./test/fixtures > ' + outfile, function(err) { + child.exec('node ' + __dirname + '/../bin/gulp.js --help --cwd ./test/fixtures/gulpfiles > ' + outfile, function(err) { var stdout = fs.readFileSync(outfile, { encoding: 'utf8' }); code.expect(stdout.replace(/(\r\n|\n|\r)\s?/gm,'\n')).to.equals(output); done(err); @@ -32,7 +32,7 @@ lab.experiment('flag: help', function() { }); lab.test('shows help using short --h', function(done) { - child.exec('node ' + __dirname + '/../bin/gulp.js --h --cwd ./test/fixtures > ' + outfile, function(err) { + child.exec('node ' + __dirname + '/../bin/gulp.js --h --cwd ./test/fixtures/gulpfiles > ' + outfile, function(err) { var stdout = fs.readFileSync(outfile, { encoding: 'utf8' }); code.expect(stdout.replace(/(\r\n|\n|\r)\s?/gm,'\n')).to.equals(output); done(err); diff --git a/test/flags-require.js b/test/flags-require.js index c62aad6e..1017bcf6 100644 --- a/test/flags-require.js +++ b/test/flags-require.js @@ -7,15 +7,15 @@ var child = require('child_process'); lab.experiment('flag: --require', function() { lab.test('requires module before running gulpfile', function(done) { - child.exec('node ' + __dirname + '/../bin/gulp.js --require ./test-module.js --cwd ./test/fixtures', function(err, stdout) { + child.exec('node ' + __dirname + '/../bin/gulp.js --require ../test-module.js --cwd ./test/fixtures/gulpfiles', function(err, stdout) { stdout = stdout.replace(/\\/g, '/').split('\n'); code.expect(stdout[0]).to.equal('inside test module'); - code.expect(stdout[1]).to.contain('Requiring external module ./test-module.js'); + code.expect(stdout[1]).to.contain('Requiring external module ../test-module.js'); done(err); }); }); lab.test('errors if module doesn\'t exist', function(done) { - child.exec('node ' + __dirname + '/../bin/gulp.js --require ./null-module.js --cwd ./test/fixtures', function(err, stdout, stderr) { + child.exec('node ' + __dirname + '/../bin/gulp.js --require ./null-module.js --cwd ./test/fixtures/gulpfiles', function(err, stdout, stderr) { stderr = stderr.replace(/\\/g, '/').split('\n'); code.expect(stderr[0]).to.contain('Failed to load external module ./null-module.js'); done(err); diff --git a/test/flags-silent.js b/test/flags-silent.js index 70b99a05..e97073c4 100644 --- a/test/flags-silent.js +++ b/test/flags-silent.js @@ -8,7 +8,7 @@ var child = require('child_process'); lab.experiment('flag: --silent', function() { lab.test('prints nothing when silent flag is set', function(done) { - child.exec('node ' + __dirname + '/../bin/gulp.js --silent --cwd ./test/fixtures', function(err, stdout) { + child.exec('node ' + __dirname + '/../bin/gulp.js --silent --cwd ./test/fixtures/gulpfiles', function(err, stdout) { code.expect(stdout).to.equal(''); done(err); }); diff --git a/test/flags-tasks-json.js b/test/flags-tasks-json.js index 90027ea5..707e181b 100644 --- a/test/flags-tasks-json.js +++ b/test/flags-tasks-json.js @@ -1,26 +1,26 @@ 'use strict'; +var lab = exports.lab = require('lab').script(); +var expect = require('code').expect; var fs = require('fs-extra'); var path = require('path'); -var tildify = require('tildify'); -var lab = exports.lab = require('lab').script(); -var code = require('code'); +var skipLines = require('./tools/skip-lines'); +var runner = require('./tools/run-gulp'); -var child = require('child_process'); -var output = require('./expected/flags-tasks-json.json'); +var expected = require(path.join(__dirname, 'expected/flags-tasks-json.json')); lab.experiment('flag: --tasks-json', function() { - var outputString = JSON.stringify(output).replace(/{{path}}/, tildify(path.join(__dirname, 'fixtures/gulpfile.js')).replace(/\\/g, '\\\\')); - var expected = JSON.parse(outputString); - lab.test('prints the task list with no args', function(done) { - child.exec('node ' + __dirname + '/../bin/gulp.js --tasks-json --gulpfile "./test/fixtures/gulpfile.js" ', function(err, stdout) { - stdout = stdout.split('\n'); - var parsedJson = JSON.parse(stdout[1]); - code.expect(parsedJson).to.deep.equal(expected); - done(err); - }); + runner({ verbose: false }) + .gulp('--tasks-json --gulpfile ./fixtures/gulpfiles/gulpfile.js') + .run(cb); + + function cb(err, stdout) { + stdout = skipLines(stdout, 1); + expect(JSON.parse(stdout)).to.deep.equal(expected); + done(); + } }); lab.test('writes the task list to file with path', function(done) { @@ -29,13 +29,19 @@ lab.experiment('flag: --tasks-json', function() { return done(err); } - child.exec('node ' + __dirname + '/../bin/gulp.js --tasks-json "../output/tasks.json" --gulpfile "./test/fixtures/gulpfile.js" ', function(err) { + runner({ verbose: false }) + .gulp('--tasks-json ../../output/tasks.json', + '--gulpfile fixtures/gulpfiles/gulpfile.js') + .run(cb); + + function cb(err) { var file = fs.readFileSync(__dirname + '/output/tasks.json', 'utf8'); var parsedJson = JSON.parse(file); - code.expect(parsedJson).to.deep.equal(expected); + expect(parsedJson).to.deep.equal(expected); fs.removeSync(__dirname + '/output/'); done(err); - }); + } }); }); + }); diff --git a/test/flags-task-simple.js b/test/flags-tasks-simple.js similarity index 89% rename from test/flags-task-simple.js rename to test/flags-tasks-simple.js index daf6917b..fd0e9bc5 100644 --- a/test/flags-task-simple.js +++ b/test/flags-tasks-simple.js @@ -11,7 +11,7 @@ var output = fs.readFileSync(__dirname + '/expected/flags-tasks-simple.txt', 'ut lab.experiment('flag: --tasks-simple', function() { lab.test('prints the task list in simple format', function(done) { - child.exec('node ' + __dirname + '/../bin/gulp.js --tasks-simple --cwd ./test/fixtures', function(err, stdout) { + child.exec('node ' + __dirname + '/../bin/gulp.js --tasks-simple --cwd ./test/fixtures/gulpfiles', function(err, stdout) { code.expect(stdout).to.equal(output); done(err); }); diff --git a/test/flags-tasks.js b/test/flags-tasks.js index 1ee263e0..0a9d1354 100644 --- a/test/flags-tasks.js +++ b/test/flags-tasks.js @@ -1,57 +1,62 @@ 'use strict'; var lab = exports.lab = require('lab').script(); -var code = require('code'); +var expect = require('code').expect; var fs = require('fs'); var path = require('path'); -var child = require('child_process'); +var skipLines = require('./tools/skip-lines'); +var eraseTime = require('./tools/erase-time'); +var runner = require('./tools/run-gulp'); -var expectedFiles = [ - path.join(__dirname, 'expected/flags-tasks.txt'), - path.join(__dirname, 'expected/flags-tasks/with-desc-and-flags.txt'), - path.join(__dirname, 'expected/flags-tasks/by-unwrap-and-not-by-unwrap.txt'), -]; - -var outputs = []; -expectedFiles.forEach(function(file, i) { - outputs[i] = fs.readFileSync(file, 'utf8').replace(/(\r\n|\n|\r)/gm,'\n'); -}); +var expectedDir = path.join(__dirname, 'expected'); lab.experiment('flag: --tasks', function() { lab.test('prints the task list', function(done) { - child.exec('node ' + __dirname + '/../bin/gulp.js --tasks --cwd ./test/fixtures', function(err, stdout) { - code.expect(stdout).to.contain('Tasks for'); - stdout = stdout.replace(/\\/g, '/').split('Tasks for')[1].split('\n'); - var outputArray = outputs[0].split('\n'); - for (var i = 0; i < stdout.length; i++) { - code.expect(stdout[i]).to.contain(outputArray[i]); - } - done(err); - }); + runner({ verbose: false }) + .gulp('--tasks --cwd ./fixtures/gulpfiles') + .run(cb); + + function cb(err, stdout) { + var filepath = path.join(expectedDir, 'flags-tasks.txt'); + var expected = fs.readFileSync(filepath, 'utf-8'); + stdout = eraseTime(skipLines(stdout, 1)); + expect(stdout).to.equal(expected); + done(); + } }); - lab.test('prints the task list with description and flags', function(done) { - child.exec('node ' + __dirname + '/../bin/gulp.js --tasks --gulpfile ./test/fixtures/flags-tasks/with-desc-and-flags.js --cwd ./test/fixtures', function(err, stdout) { - code.expect(stdout).to.contain('Tasks for'); - stdout = stdout.replace(/\\/g, '/').split('Tasks for')[1].split('\n'); - var outputArray = outputs[1].split('\n'); - for (var i = 0; i < stdout.length; i++) { - code.expect(stdout[i]).to.contain(outputArray[i]); - } - done(err); - }); + lab.test('print the task list with description and flags', function(done) { + runner({ verbose: false }) + .gulp('--tasks', + '--gulpfile ./fixtures/gulpfiles/with-desc-and-flags.js', + '--cwd ./fixtures') + .run(cb); + + function cb(err, stdout) { + var filepath = path.join(expectedDir, 'with-desc-and-flags.txt'); + var expected = fs.readFileSync(filepath, 'utf-8'); + stdout = eraseTime(skipLines(stdout, 1)); + expect(stdout).to.equal(expected); + done(); + } }); - lab.test('prints the task list by gulp.task(s).unwrap and gulp.task(s)', function(done) { - child.exec('node ' + __dirname + '/../bin/gulp.js --tasks --gulpfile ./test/fixtures/flags-tasks/by-unwrap-and-not-by-unwrap.js --cwd ./test/fixtures', function(err, stdout) { - code.expect(stdout).to.contain('Tasks for'); - stdout = stdout.replace(/\\/g, '/').split('Tasks for')[1].split('\n'); - var outputArray = outputs[2].split('\n'); - for (var i = 0; i < stdout.length; i++) { - code.expect(stdout[i]).to.contain(outputArray[i]); - } - done(err); - }); + lab.test('print the task list by gulp.task(s).unwrap and gulp.task(s)', + function(done) { + runner({ verbose: false }) + .gulp('--tasks', + '--gulpfile ./fixtures/gulpfiles/by-unwrap-and-not-by-unwrap.js', + '--cwd ./fixtures') + .run(cb); + + function cb(err, stdout) { + var filepath = path.join(expectedDir, 'by-unwrap-and-not-by-unwrap.txt'); + var expected = fs.readFileSync(filepath, 'utf-8'); + stdout = eraseTime(skipLines(stdout, 1)); + expect(stdout).to.equal(expected); + done(); + } }); + }); diff --git a/test/flags-version.js b/test/flags-version.js index 952db389..d30cd40d 100644 --- a/test/flags-version.js +++ b/test/flags-version.js @@ -11,7 +11,7 @@ var gulpVersion = require('gulp/package.json').version; lab.experiment('flag: --version', function() { lab.test('prints the version of CLI and local gulp', function(done) { - child.exec('node ' + __dirname + '/../bin/gulp.js --version --cwd ./test/fixtures', function(err, stdout) { + child.exec('node ' + __dirname + '/../bin/gulp.js --version --cwd ./test/fixtures/gulpfiles', function(err, stdout) { code.expect(stdout).to.contain('CLI version ' + cliVersion); code.expect(stdout).to.contain('Local version ' + gulpVersion); done(err); diff --git a/test/tools/erase-time.js b/test/tools/erase-time.js new file mode 100644 index 00000000..444c4412 --- /dev/null +++ b/test/tools/erase-time.js @@ -0,0 +1,5 @@ +'use strict'; + +module.exports = function(text) { + return ('\n' + text).replace(/(\r\n|\r|\n)\[[0-9:]{8}\] /g, '\n').slice(1); +}; diff --git a/test/tools/run-gulp.js b/test/tools/run-gulp.js new file mode 100644 index 00000000..1354a114 --- /dev/null +++ b/test/tools/run-gulp.js @@ -0,0 +1,91 @@ +'use strict'; + +var child = require('child_process'); +var path = require('path'); +var os = require('os'); + + +var cmdsep = '; '; +var escapeBs = path.join; + +if (os.platform() === 'win32') { + cmdsep = ' & '; + escapeBs = function() { + var pth = path.join.apply(path, arguments); + return pth.replace(/\\/g, '\\\\'); + }; +} + + +var regexpInsEol = new RegExp(cmdsep, 'g'); + +function insertEol(cmd) { + return cmd.replace(regexpInsEol, cmdsep + '\n'); +} + + +var gulpPath = path.join(__dirname, '../../bin/gulp.js'); + +module.exports = function(opt) { + opt = opt || {}; + var inst = {}; + inst.basedir = basedirFn; + inst.chdir = chdirFn; + inst.gulp = gulpFn; + inst._command = ''; + inst._verbose = !!opt.verbose; + inst._basedir = path.join(__dirname, '..'); // Test directory + return inst; + + function basedirFn(dir) { + inst._basedir = dir; + return { + chdir: chdirFn, + gulp: gulpFn, + }; + } + + function chdirFn(dir) { + inst._command = 'cd ' + escapeBs(dir); + return { gulp: gulpFn }; + } + + function gulpFn(/*...args*/) { + if (inst._command) { + inst._command += cmdsep; + } + inst._command += 'node ' + escapeBs(gulpPath); + for (var i = 0, n = arguments.length; i < n; i++) { + inst._command += ' ' + arguments[i]; + } + return { run: runFn }; + } + + function runFn(cb) { + var cmd = ''; + if (inst._basedir) { + cmd += 'cd ' + escapeBs(path.resolve(inst._basedir)) + cmdsep; + } + cmd += inst._command; + + if (!inst._verbose) { + child.exec(cmd, cb); + inst._command = ''; + return; + } + + console.log('---- command'); + console.log(insertEol(cmd)); + child.exec(cmd, function(err, stdout, stderr) { + console.log('---- error'); + console.log(err); + console.log('---- stdout'); + console.log(stdout); + console.log('---- stderr'); + console.log(stderr); + console.log('----.'); + cb(err, stdout, stderr); + inst._command = ''; + }); + } +}; diff --git a/test/tools/skip-lines.js b/test/tools/skip-lines.js new file mode 100644 index 00000000..83171784 --- /dev/null +++ b/test/tools/skip-lines.js @@ -0,0 +1,13 @@ +'use strict'; + +module.exports = function(text, nskip) { + text = text.replace(/(\r\n|\r|\n)/gm, '\n'); + for (var i = 0; i < nskip; i++) { + var index = text.indexOf('\n'); + if (index < 0) { + return ''; + } + text = text.slice(index + 1); + } + return text; +}; diff --git a/test/tools/test/erase-time-test.js b/test/tools/test/erase-time-test.js new file mode 100644 index 00000000..5b1883c3 --- /dev/null +++ b/test/tools/test/erase-time-test.js @@ -0,0 +1,31 @@ +'use strict'; + +var eraseTime = require('../erase-time'); + +var lab = exports.lab = require('lab').script(); +var expect = require('code').expect; + +lab.experiment('erase time', function() { + + lab.test('an empty string', function(done) { + expect(eraseTime('')).to.equals(''); + done(); + }); + + lab.test('a string with no time', function(done) { + expect(eraseTime(' foo \n bar \n baz ')).to.equals(' foo \n bar \n baz '); + done(); + }); + + lab.test('a string with time', function(done) { + expect(eraseTime('[10:20:30] foo \n[10:20:30] bar \n[10:20:30] baz ')) + .to.equals(' foo \n bar \n baz '); + done(); + }); + + lab.test('a string with time and various eol', function(done) { + expect(eraseTime('[10:20:30] foo \r\n[10:20:30] bar \r[10:20:30] baz ')) + .to.equals(' foo \n bar \n baz '); + done(); + }); +}); diff --git a/test/tools/test/gulpfile.js b/test/tools/test/gulpfile.js new file mode 100644 index 00000000..dc13a5a3 --- /dev/null +++ b/test/tools/test/gulpfile.js @@ -0,0 +1,15 @@ +'use strict'; + +var gulp = require('gulp'); + +function fn1(done) { + done(); +} + +function fn2(done) { + done(); +} + +gulp.task('task1', fn1); +gulp.task('task2', fn2); +gulp.task('default', gulp.series('task1', 'task2')); diff --git a/test/tools/test/run-gulp-test.js b/test/tools/test/run-gulp-test.js new file mode 100644 index 00000000..b8b5432a --- /dev/null +++ b/test/tools/test/run-gulp-test.js @@ -0,0 +1,73 @@ +'use strict'; + +var lab = exports.lab = require('lab').script(); +var expect = require('code').expect; +var path = require('path'); + +var runner = require('../run-gulp'); + +lab.experiment('run gulp', { timeout: 0 }, function() { + + lab.test('Should not share properties', function(done) { + var r1 = runner(); + var r2 = runner(); + + r2._verbose = !r1._verbose; + r2._basedir = __dirname; + r2._command = 'xxxx'; + + expect(r1._verbose).not.to.equal(r2._verbose); + expect(r1._basedir).not.to.equal(r2._basedir); + expect(r1._command).not.to.equal(r2._command); + done(); + }); + + lab.test('Should run gulp (verbose)', function(done) { + runner({ verbose: true }) + .basedir(path.join(__dirname, '..')) + .chdir('test') + .gulp('--tasks-simple') + .run(cb); + + function cb(err, stdout) { + expect(stdout).to.equal('task1\ntask2\ndefault\n'); + done(); + } + }); + + lab.test('Should run gulp --cwd (verbose)', function(done) { + runner({ verbose: true }) + .gulp('--tasks-simple --cwd tools/test') + .run(cb); + + function cb(err, stdout) { + expect(stdout).to.equal('task1\ntask2\ndefault\n'); + done(); + } + }); + + lab.test('Should run gulp', function(done) { + runner() + .chdir('tools/test') + .gulp('--tasks-simple') + .run(cb); + + function cb(err, stdout) { + expect(stdout).to.equal('task1\ntask2\ndefault\n'); + done(); + } + }); + + lab.test('Should run gulp --cwd', function(done) { + runner() + .gulp('--tasks-simple --cwd tools/test') + .run(cb); + + function cb(err, stdout) { + expect(stdout).to.equal('task1\ntask2\ndefault\n'); + done(); + } + }); + +}); + diff --git a/test/tools/test/skip-line-test.js b/test/tools/test/skip-line-test.js new file mode 100644 index 00000000..3ba5074f --- /dev/null +++ b/test/tools/test/skip-line-test.js @@ -0,0 +1,31 @@ +'use strict'; + +var skipLines = require('../skip-lines'); + +var lab = exports.lab = require('lab').script(); +var expect = require('code').expect; + +lab.experiment('skip lines', function() { + + lab.test('an empty string', function(done) { + expect(skipLines('', 0)).to.equal(''); + expect(skipLines('', 1)).to.equal(''); + expect(skipLines('', 2)).to.equal(''); + done(); + }); + + lab.test('an string which has single line', function(done) { + expect(skipLines('single line', 0)).to.equal('single line'); + expect(skipLines('single line', 1)).to.equal(''); + expect(skipLines('single line', 2)).to.equal(''); + done(); + }); + + lab.test('an string which has multiple lines', function(done) { + expect(skipLines('foo\nbar\nbaz', 0)).to.equal('foo\nbar\nbaz'); + expect(skipLines('foo\nbar\nbaz', 1)).to.equal('bar\nbaz'); + expect(skipLines('foo\nbar\nbaz', 2)).to.equal('baz'); + done(); + }); + +});