Commit a75739e2 by Arian Stolwijk

Fix cli options and make the cli better testable with require()

Nothing is directly written to stdout/stderr but is passed in an event
emitter, so when testing we can use that.

This way of testing the cli has the advantage that we don't need to exec
for all tests.
parent 2c21fd7b
#!/usr/bin/env node #!/usr/bin/env node
require('../lib/cli')(process.argv.slice(2)); var cli = require('../lib/cli')(process.argv.slice(2));
cli.on('log', function(msg){
console.log(msg);
});
cli.on('error', function(msg){
console.error(msg);
});
cli.on('warn', function(msg){
console.warn(msg);
});
var watch = require('node-watch'), var watch = require('node-watch'),
render = require('./render'), render = require('./render'),
path = require('path'), path = require('path'),
Emitter = require('events').EventEmitter,
cwd = process.cwd(); cwd = process.cwd();
var optimist = require('optimist') var optimist = require('optimist')
...@@ -40,13 +41,14 @@ var optimist = require('optimist') ...@@ -40,13 +41,14 @@ var optimist = require('optimist')
// throttle function, used so when multiple files change at the same time // throttle function, used so when multiple files change at the same time
// (e.g. git pull) the files are only compiled once. // (e.g. git pull) the files are only compiled once.
function throttle(fn, args) { function throttle(fn) {
var timer; var timer;
var args = Array.prototype.slice.call(arguments, 1);
return function() { return function() {
var self = this; var self = this;
clearTimeout(timer); clearTimeout(timer);
timer = setTimeout(function() { timer = setTimeout(function() {
fn.call(self, args); fn.apply(self, args);
}, 20); }, 20);
}; };
} }
...@@ -64,6 +66,10 @@ exports = module.exports = function(args) { ...@@ -64,6 +66,10 @@ exports = module.exports = function(args) {
return; return;
} }
var emitter = new Emitter();
emitter.on('error', function(){});
var options = { var options = {
stdout: argv.stdout stdout: argv.stdout
}; };
...@@ -76,22 +82,22 @@ exports = module.exports = function(args) { ...@@ -76,22 +82,22 @@ exports = module.exports = function(args) {
} }
// make sure it's an array // make sure it's an array
if (!Array.isArray(options['include-path'])) { options.includePaths = argv['include-paths'];
options['include-paths'] = options.includePaths = [options['include-path']]; if (!Array.isArray(options.includePaths)) {
options.includePaths = [options.includePaths];
} }
options.includePaths = options['include-paths'];
// if it's an array, make it a string // if it's an array, make it a string
if (Array.isArray(options['output-style'])) { options.outputStyle = argv['output-style'];
options['output-style'] = options['output-style'][0]; if (Array.isArray(options.outputStyle)) {
options.outputStyle = options.outputStyle[0];
} }
options.outputStyle = options['output-style'];
// if it's an array, make it a string // if it's an array, make it a string
if (Array.isArray(options['source-comments'])) { options.sourceComments = argv['source-comments'];
options['source-comments'] = options['source-comments'][0]; if (Array.isArray(options.sourceComments)) {
options.sourceComments = options.sourceComments[0];
} }
options.sourceComments = options['source-comments'];
if (argv.w) { if (argv.w) {
...@@ -104,10 +110,10 @@ exports = module.exports = function(args) { ...@@ -104,10 +110,10 @@ exports = module.exports = function(args) {
} }
watchDir.push(inFile) watchDir.push(inFile)
var throttledRender = throttle(render, options); var throttledRender = throttle(render, options, emitter);
watch(watchDir, function(file){ watch(watchDir, function(file){
console.warn('=> changed: '.grey + file.blue); emitter.emit('warn', '=> changed: '.grey + file.blue);
if (isSassFile(file)) { if (isSassFile(file)) {
throttledRender(); throttledRender();
} }
...@@ -116,8 +122,10 @@ exports = module.exports = function(args) { ...@@ -116,8 +122,10 @@ exports = module.exports = function(args) {
throttledRender(); throttledRender();
} else { } else {
render(options); render(options, emitter);
} }
return emitter;
}; };
exports.optimist = optimist; exports.optimist = optimist;
...@@ -5,7 +5,7 @@ var sass = require('../sass'), ...@@ -5,7 +5,7 @@ var sass = require('../sass'),
var cwd = process.cwd(); var cwd = process.cwd();
function render(options) { function render(options, emitter) {
sass.render({ sass.render({
file: options.inFile, file: options.inFile,
...@@ -14,19 +14,21 @@ function render(options) { ...@@ -14,19 +14,21 @@ function render(options) {
sourceComments: options.sourceComments, sourceComments: options.sourceComments,
success: function(css) { success: function(css) {
console.warn('Rendering Complete, saving .css file...'.green); emitter.emit('warn', 'Rendering Complete, saving .css file...'.green);
fs.writeFile(options.outFile, css, function(err) { fs.writeFile(options.outFile, css, function(err) {
if (err) return console.error(('Error: ' + err).red); if (err) return emitter.emit('error', ('Error: ' + err).red);
console.warn(('Wrote CSS to ' + options.outFile).green); emitter.emit('warn', ('Wrote CSS to ' + options.outFile).green);
}); });
if (options.stdout) { if (options.stdout) {
console.log(css); emitter.emit('log', css);
} }
emitter.emit('render', css);
}, },
error: function(error) { error: function(error) {
console.error(error); emitter.emit('error', error);
} }
}); });
} }
......
...@@ -3,6 +3,7 @@ var path = require('path'), ...@@ -3,6 +3,7 @@ var path = require('path'),
fs = require('fs'), fs = require('fs'),
exec = require('child_process').exec, exec = require('child_process').exec,
sass = require(path.join(__dirname, '..', 'sass')), sass = require(path.join(__dirname, '..', 'sass')),
cli = require(path.join(__dirname, '..', 'lib', 'cli')),
cliPath = path.resolve(__dirname, '..', 'bin', 'node-sass'), cliPath = path.resolve(__dirname, '..', 'bin', 'node-sass'),
sampleFilename = path.resolve(__dirname, 'sample.scss'); sampleFilename = path.resolve(__dirname, 'sample.scss');
...@@ -44,4 +45,17 @@ describe('cli', function() { ...@@ -44,4 +45,17 @@ describe('cli', function() {
}); });
}); });
}); });
it('should compile with --include-paths option', function(done){
var emitter = cli(['--include-paths', __dirname + '/lib', __dirname + '/include_path.scss']);
emitter.on('error', function(err){
done(err);
});
emitter.on('render', function(css){
assert.equal(css.trim(), 'body {\n background: red; }');
done();
});
});
}); });
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment