automaton
Version:
Task automation tool
888 lines (793 loc) • 34.3 kB
JavaScript
/*global describe, it*/
;
var Automaton = require('../');
var removeColors = require('../lib/Logger').removeColors;
var callbackTask = require('./helpers/tasks/callback');
var utils = require('mout');
var expect = require('expect.js');
var Stream = require('stream');
function arrow(msg, depth) {
return utils.string.repeat(' ', depth - 1) + '> ' + msg + '\n';
}
function indent(msg, depth) {
return utils.string.repeat(' ', depth - 1) + msg;
}
module.exports = function (automaton) {
describe('Logging', function () {
it('should return a stream when running tasks', function () {
var ret = automaton
.run({
tasks: []
});
expect(ret).to.be.a(Stream);
});
it('should report tasks with padding correspondent to the depth', function (done) {
var log = '';
automaton
.run({
setup: function (opt, ctx, next) {
ctx.log.infoln('Level 1 task info');
ctx.log.warnln('Level 1 task warn');
ctx.log.successln('Level 1 task success');
ctx.log.errorln('Level 1 task error');
ctx.log.writeln('Level 1 task write');
next();
},
description: 'Level 1 task',
tasks: [
{
task: {
description: 'This should not appear',
tasks: [
{
task: 'callback',
description: null
},
{
task: function (opt, ctx, next) {
ctx.log.infoln('Level 3 task info');
ctx.log.warnln('Level 3 task warn');
ctx.log.successln('Level 3 task success');
ctx.log.errorln('Level 3 task error');
ctx.log.writeln('Level 3 task write');
next();
},
description: 'Level 3 task'
}
]
},
description: null
}
]
}, null, function (err) {
if (err) {
throw err;
}
log = removeColors(log);
expect(log).to.equal(
arrow('Level 1 task', 1) +
indent('Level 1 task info\n', 1) +
indent('Level 1 task warn\n', 1) +
indent('Level 1 task success\n', 1) +
indent('Level 1 task error\n', 1) +
indent('Level 1 task write\n', 1) +
arrow('Level 3 task', 3) +
indent('Level 3 task info\n', 3) +
indent('Level 3 task warn\n', 3) +
indent('Level 3 task success\n', 3) +
indent('Level 3 task error\n', 3) +
indent('Level 3 task write\n', 3)
);
done();
})
.on('data', function (data) { log += data; });
});
it('should log indented errors', function (done) {
var log = '';
automaton.run({
description: 'Root',
tasks: [
{
task: function (opt, ctx, next) {
next(new Error('bleh'));
},
description: 'Level 1'
}
]
}, null, function (err) {
expect(err).to.be.an(Error);
log = removeColors(log);
expect(log).to.equal(
arrow('Root', 1) +
arrow('Level 1', 2) +
indent('bleh\n', 2)
);
done();
})
.on('data', function (data) { log += data; });
});
it('should report running tasks, replacing placeholders in the descripton', function (done) {
var log = '';
automaton
.run({
description: 'foo {{foo}}{{wtf}}',
tasks: []
}, { foo: 'bar' }, function (err) {
if (err) {
throw err;
}
log = removeColors(log);
expect(log).to.equal(
arrow('foo bar', 1)
);
log = '';
automaton
.run({
description: 'wat',
tasks: [
{
task: function (opt, ctx, next) { next(); },
description: function (opt) {
return 'foo ' + opt.foo;
},
}
]
}, { foo: 'bar' }, function (err) {
if (err) {
throw err;
}
log = removeColors(log);
expect(log).to.equal(
arrow('wat', 1) +
arrow('foo bar', 2)
);
done();
})
.on('data', function (data) { log += data; });
})
.on('data', function (data) { log += data; });
});
it('should not report task descriptions if they are null', function (done) {
var log = '';
automaton
.run({
setup: function (opt, ctx, next) {
ctx.log.infoln('Level 1 task info');
ctx.log.warnln('Level 1 task warn');
ctx.log.successln('Level 1 task success');
ctx.log.errorln('Level 1 task error');
next();
},
description: 'Level 1 task',
tasks: [
{
task: function (opt, ctx, next) {
next();
},
description: 'Level 2 task'
},
{
task: {
description: 'This should not appear',
tasks: [
{
task: function (opt, ctx, next) {
ctx.log.infoln('Level 3 task info');
ctx.log.warnln('Level 3 task warn');
ctx.log.successln('Level 3 task success');
ctx.log.errorln('Level 3 task error');
next();
},
description: 'Level 3 task'
}
]
},
description: 'Other level 2 task'
},
{
task: {
tasks: [
{
task: function (opt, ctx, next) { next(); },
description: 'Other level 3 task'
}
]
}
},
{
task: {
name: 'Even other level 2 task',
tasks: [
{
task: function (opt, ctx, next) { next(); }
}
]
}
}
]
}, null, function (err) {
if (err) {
throw err;
}
log = removeColors(log);
expect(log).to.equal(
arrow('Level 1 task', 1) +
indent('Level 1 task info\n', 1) +
indent('Level 1 task warn\n', 1) +
indent('Level 1 task success\n', 1) +
indent('Level 1 task error\n', 1) +
arrow('Level 2 task', 2) +
arrow('Other level 2 task', 2) +
arrow('Level 3 task', 3) +
indent('Level 3 task info\n', 3) +
indent('Level 3 task warn\n', 3) +
indent('Level 3 task success\n', 3) +
indent('Level 3 task error\n', 3) +
arrow('??', 2) +
arrow('Other level 3 task', 3) +
arrow('Even other level 2 task', 2)
);
done();
})
.on('data', function (data) { log += data; });
});
it('should log every arguments passed', function (done) {
var log = '';
var automaton = new Automaton({ debug: true });
automaton
.run({
description: '',
tasks: [
{
task: function (opt, ctx, next) {
ctx.log.info('foo', 'bar');
ctx.log.infoln('foo', 'bar');
ctx.log.warn('foo', 'bar');
ctx.log.warnln('foo', 'bar');
ctx.log.error('foo', 'bar');
ctx.log.errorln('foo', 'bar');
ctx.log.success('foo', 'bar');
ctx.log.successln('foo', 'bar');
ctx.log.write('foo', 'bar');
ctx.log.writeln('foo', 'bar');
ctx.log.debug('foo', 'bar');
ctx.log.debugln('foo', 'bar');
next();
}
}
]
}, null, function (err) {
if (err) {
throw err;
}
log = removeColors(log);
expect(log).to.equal(
arrow('??', 1) +
indent('foo bar', 2) +
indent('foo bar\n', 2) +
indent('foo bar', 2) +
indent('foo bar\n', 2) +
indent('foo bar', 2) +
indent('foo bar\n', 2) +
indent('foo bar', 2) +
indent('foo bar\n', 2) +
indent('foo bar', 2) +
indent('foo bar\n', 2) +
indent('foo bar', 2) +
indent('foo bar\n', 2)
);
done();
})
.on('data', function (data) { log += data; });
});
it('should not throw error when logging types other than strings', function (done) {
var log = '';
automaton
.run({
description: '',
tasks: [
{
task: function (opt, ctx, next) {
ctx.log.infoln({});
ctx.log.infoln(['foo', 'bar']);
ctx.log.infoln(null);
ctx.log.infoln(undefined);
ctx.log.infoln(1);
ctx.log.infoln(true);
ctx.log.warnln({});
ctx.log.warnln(['foo', 'bar']);
ctx.log.warnln(null);
ctx.log.warnln(undefined);
ctx.log.warnln(1);
ctx.log.warnln(true);
ctx.log.successln({});
ctx.log.successln(['foo', 'bar']);
ctx.log.successln(null);
ctx.log.successln(undefined);
ctx.log.successln(1);
ctx.log.successln(true);
ctx.log.errorln({});
ctx.log.errorln(['foo', 'bar']);
ctx.log.errorln(null);
ctx.log.errorln(undefined);
ctx.log.errorln(1);
ctx.log.errorln(true);
//////
ctx.log.info({});
ctx.log.info(['foo', 'bar']);
ctx.log.info(null);
ctx.log.info(undefined);
ctx.log.info(1);
ctx.log.info(true);
ctx.log.warn({});
ctx.log.warn(['foo', 'bar']);
ctx.log.warn(null);
ctx.log.warn(undefined);
ctx.log.warn(1);
ctx.log.warn(true);
ctx.log.success({});
ctx.log.success(['foo', 'bar']);
ctx.log.success(null);
ctx.log.success(undefined);
ctx.log.success(1);
ctx.log.success(true);
ctx.log.error({});
ctx.log.error(['foo', 'bar']);
ctx.log.error(null);
ctx.log.error(undefined);
ctx.log.error(1);
ctx.log.error(true);
next();
}
}
]
}, null, function (err) {
if (err) {
throw err;
}
log = removeColors(log);
expect(log).to.equal(
arrow('??', 1) +
indent('[object Object]\n', 2) +
indent('foo,bar\n', 2) +
indent('null\n', 2) +
indent('undefined\n', 2) +
indent('1\n', 2) +
indent('true\n', 2) +
indent('[object Object]\n', 2) +
indent('foo,bar\n', 2) +
indent('null\n', 2) +
indent('undefined\n', 2) +
indent('1\n', 2) +
indent('true\n', 2) +
indent('[object Object]\n', 2) +
indent('foo,bar\n', 2) +
indent('null\n', 2) +
indent('undefined\n', 2) +
indent('1\n', 2) +
indent('true\n', 2) +
indent('[object Object]\n', 2) +
indent('foo,bar\n', 2) +
indent('null\n', 2) +
indent('undefined\n', 2) +
indent('1\n', 2) +
indent('true\n', 2) +
///////
indent('[object Object]', 2) +
'foo,bar' +
'null' +
'undefined' +
'1' +
'true' +
'[object Object]' +
'foo,bar' +
'null' +
'undefined' +
'1' +
'true' +
'[object Object]' +
'foo,bar' +
'null' +
'undefined' +
'1' +
'true' +
'[object Object]' +
'foo,bar' +
'null' +
'undefined' +
'1' +
'true'
);
done();
})
.on('data', function (data) { log += data; });
});
it('should not indent after a nonln log', function (done) {
var log = '';
automaton
.run({
tasks: [
{
task: function (opt, ctx, next) {
ctx.log.infoln('foo');
ctx.log.info('bar', 'ber');
ctx.log.info('baz');
ctx.log.infoln();
ctx.log.infoln('faa');
next();
}
}
]
}, null, function (err) {
if (err) {
throw err;
}
log = removeColors(log);
expect(log).to.equal(
arrow('??', 1) +
indent('foo\n', 2) +
indent('bar ber', 2) +
'baz' +
indent('\n', 2) +
indent('faa\n', 2)
);
done();
})
.on('data', function (data) { log += data; });
});
it('should indent after a nonln log that ends with a new line', function (done) {
var log = '';
automaton
.run({
tasks: [
{
task: function (opt, ctx, next) {
ctx.log.info('bar\n');
ctx.log.info('test');
next();
}
}
]
}, null, function (err) {
if (err) {
throw err;
}
log = removeColors(log);
expect(log).to.equal(
arrow('??', 1) +
indent('bar\n', 2) +
indent('test', 2)
);
done();
})
.on('data', function (data) { log += data; });
});
it('should indent new lines in the middle of a message', function (done) {
var log = '';
automaton
.run({
tasks: [
{
task: function (opt, ctx, next) {
ctx.log.infoln('foo\nbar\nbaz');
ctx.log.infoln('foo\r\nbar\r\nbaz');
ctx.log.infoln('\r\nbar\r\nbaz');
ctx.log.info('foo');
ctx.log.info('\r\nbar\r\nbaz');
next();
}
}
]
}, null, function (err) {
if (err) {
throw err;
}
log = removeColors(log);
expect(log).to.equal(
arrow('??', 1) +
indent('foo\n', 2) +
indent('bar\n', 2) +
indent('baz\n', 2) +
indent('foo\r\n', 2) +
indent('bar\r\n', 2) +
indent('baz\n', 2) +
indent('\r\n', 2) +
indent('bar\r\n', 2) +
indent('baz\n', 2) +
indent('foo\r\n', 2) +
indent('bar\r\n', 2) +
indent('baz', 2)
);
done();
})
.on('data', function (data) { log += data; });
});
it('should only log debug messages if automaton is in debug mode', function (done) {
var log = '';
automaton
.run({
tasks: [
{
task: function (opt, ctx, next) {
ctx.log.debug('foo');
ctx.log.debugln('foo');
ctx.log.info('bar');
ctx.log.infoln('bar');
next();
}
}
]
}, null, function (err) {
var automaton;
if (err) {
throw err;
}
log = removeColors(log);
expect(log).to.equal(
arrow('??', 1) +
indent('bar', 2) +
indent('bar\n', 2)
);
log = '';
automaton = new Automaton({ debug: true });
automaton
.run({
tasks: [
{
task: function (opt, ctx, next) {
ctx.log.debug('foo');
ctx.log.debugln('foo');
ctx.log.info('bar');
ctx.log.infoln('bar');
next();
}
}
]
}, null, function (err) {
if (err) {
throw err;
}
log = removeColors(log);
expect(log).to.equal(
arrow('??', 1) +
indent('foo', 2) +
indent('foo\n', 2) +
indent('bar', 2) +
indent('bar\n', 2)
);
done();
})
.on('data', function (data) { log += data; });
})
.on('data', function (data) { log += data; });
});
it('should not log messages lower than the verbosity level', function (done) {
var log = '';
var automaton = new Automaton({ verbosity: 1 });
automaton
.run({
setup: function (opt, ctx, next) {
ctx.log.infoln('Level 1 task info');
ctx.log.warnln('Level 1 task warn');
ctx.log.successln('Level 1 task success');
ctx.log.errorln('Level 1 task error');
next();
},
description: 'Level 1 task',
tasks: [
{
task: function (opt, ctx, next) {
next();
},
description: 'Level 2 task'
},
{
task: {
description: 'This should not appear',
tasks: [
{
task: function (opt, ctx, next) {
ctx.log.infoln('Level 3 task info');
ctx.log.warnln('Level 3 task warn');
ctx.log.successln('Level 3 task success');
ctx.log.errorln('Level 3 task error');
next();
},
description: 'Level 3 task'
}
]
},
description: 'Other level 2 task'
},
{
task: {
tasks: [
{
task: function (opt, ctx, next) { next(); },
description: 'Other level 3 task'
}
]
}
},
{
task: {
name: 'Even other level 2 task',
tasks: [
{
task: function (opt, ctx, next) { next(); }
}
]
}
}
]
}, null, function (err) {
if (err) {
throw err;
}
log = removeColors(log);
expect(log).to.equal(
arrow('Level 1 task', 1) +
indent('Level 1 task info\n', 1) +
indent('Level 1 task warn\n', 1) +
indent('Level 1 task success\n', 1) +
indent('Level 1 task error\n', 1)
);
done();
})
.on('data', function (data) { log += data; });
});
it('should remove colors if color option is set to false', function (done) {
var log = '';
var automaton = new Automaton({ color: false });
automaton
.run({
tasks: [
{
task: function (opt, ctx, next) {
ctx.log.info('foo');
ctx.log.infoln('foo'.green);
ctx.log.warn('foo');
ctx.log.warnln('foo');
ctx.log.error('foo'.blue);
ctx.log.errorln('foo');
ctx.log.success('foo');
ctx.log.successln('foo'.yellow);
next();
}
}
]
}, null, function (err) {
if (err) {
throw err;
}
expect(log).to.equal(
arrow('??', 1) +
indent('foo', 2) +
indent('foo\n', 2) +
indent('foo', 2) +
indent('foo\n', 2) +
indent('foo', 2) +
indent('foo\n', 2) +
indent('foo', 2) +
indent('foo\n', 2)
);
done();
})
.on('data', function (data) { log += data; });
});
it('should not log muted tasks', function (done) {
var log = '';
automaton
.run({
tasks: [
// shold log
{
task: function (opt, ctx, next) {
ctx.log.infoln('1');
next();
},
mute: false
},
// should NOT log
{
task: function (opt, ctx, next) {
ctx.log.infoln('2');
next();
},
mute: true
},
// should NOT log
{
task: callbackTask,
options: {
callback: function (opt, ctx) {
ctx.log.infoln('3');
}
},
mute: true
},
// should NOT log
{
task: {
tasks: [
{
task: callbackTask,
options: {
callback: function (opt, ctx) {
ctx.log.infoln('4');
}
}
},
{
task: callbackTask,
options: {
callback: function (opt, ctx) {
ctx.log.infoln('5');
}
},
mute: false
}
]
},
mute: true
},
// should log
{
task: callbackTask,
options: {
callback: function (opt, ctx) {
ctx.log.infoln('6');
}
}
},
// should NOT log
{
task: function (opt, ctx, next) {
ctx.log.infoln('7');
next();
},
mute: '{{foo}}'
},
// should NOT log
{
task: function (opt, ctx, next) {
ctx.log.infoln('8');
next();
},
mute: function (opt, ctx) {
expect(opt).to.be.an('object');
expect(ctx).to.be.an('object');
expect(ctx.log).to.be.an('object');
expect(ctx).to.equal(this);
return opt.foo;
}
},
// should log
{
task: function (opt, ctx, next) {
ctx.log.infoln('9');
next();
},
mute: '{{non-existent}}'
}
]
}, { foo: true, bar: false }, function (err) {
if (err) {
throw err;
}
log = removeColors(log);
expect(log).to.equal(
arrow('??', 1) +
indent('1\n', 2) +
arrow('Callback task', 2) +
arrow('??', 2) +
arrow('Callback task', 2) +
indent('6\n', 3) +
indent('9\n', 2)
);
done();
})
.on('data', function (data) { log += data; });
});
});
};