first commit
This commit is contained in:
42
node_modules/vows/lib/assert/error.js
generated
vendored
Normal file
42
node_modules/vows/lib/assert/error.js
generated
vendored
Normal file
@ -0,0 +1,42 @@
|
||||
var stylize = require('../vows/console').stylize;
|
||||
var inspect = require('../vows/console').inspect;
|
||||
|
||||
require('assert').AssertionError.prototype.toString = function () {
|
||||
var that = this,
|
||||
source;
|
||||
|
||||
if (this.stack) {
|
||||
source = this.stack.match(/([a-zA-Z0-9._-]+\.(?:js|coffee))(:\d+):\d+/);
|
||||
}
|
||||
|
||||
function parse(str) {
|
||||
var actual = inspect(that.actual, {showHidden: that.actual instanceof Error}),
|
||||
expected;
|
||||
|
||||
if (that.expected instanceof Function) {
|
||||
expected = that.expected.name;
|
||||
}
|
||||
else {
|
||||
expected = inspect(that.expected, {showHidden: that.actual instanceof Error});
|
||||
}
|
||||
|
||||
return str.replace(/{actual}/g, actual).
|
||||
replace(/{operator}/g, stylize(that.operator, 'bold')).
|
||||
replace(/{expected}/g, expected);
|
||||
}
|
||||
|
||||
if (this.message) {
|
||||
var msg = stylize(parse(this.message), 'yellow');
|
||||
if (source) {
|
||||
msg += stylize(' // ' + source[1] + source[2], 'grey');
|
||||
}
|
||||
return msg;
|
||||
} else {
|
||||
return stylize([
|
||||
this.expected,
|
||||
this.operator,
|
||||
this.actual
|
||||
].join(' '), 'yellow');
|
||||
}
|
||||
};
|
||||
|
215
node_modules/vows/lib/assert/macros.js
generated
vendored
Normal file
215
node_modules/vows/lib/assert/macros.js
generated
vendored
Normal file
@ -0,0 +1,215 @@
|
||||
var assert = require('assert'),
|
||||
utils = require('./utils');
|
||||
|
||||
var messages = {
|
||||
'equal' : "expected {expected},\n\tgot\t {actual} ({operator})",
|
||||
'notEqual' : "didn't expect {actual} ({operator})"
|
||||
};
|
||||
messages['strictEqual'] = messages['deepEqual'] = messages['equal'];
|
||||
messages['notStrictEqual'] = messages['notDeepEqual'] = messages['notEqual'];
|
||||
|
||||
for (var key in messages) {
|
||||
assert[key] = (function (key, callback) {
|
||||
return function (actual, expected, message) {
|
||||
callback(actual, expected, message || messages[key]);
|
||||
};
|
||||
})(key, assert[key]);
|
||||
}
|
||||
|
||||
assert.ok = (function (callback) {
|
||||
return function (actual, message) {
|
||||
callback(actual, message || "expected expression to evaluate to {expected}, but was {actual}");
|
||||
};
|
||||
})(assert.ok);
|
||||
|
||||
assert.match = function (actual, expected, message) {
|
||||
if (! expected.test(actual)) {
|
||||
assert.fail(actual, expected, message || "expected {actual} to match {expected}", "match", assert.match);
|
||||
}
|
||||
};
|
||||
assert.matches = assert.match;
|
||||
|
||||
assert.isTrue = function (actual, message) {
|
||||
if (actual !== true) {
|
||||
assert.fail(actual, true, message || "expected {expected}, got {actual}", "===", assert.isTrue);
|
||||
}
|
||||
};
|
||||
assert.isFalse = function (actual, message) {
|
||||
if (actual !== false) {
|
||||
assert.fail(actual, false, message || "expected {expected}, got {actual}", "===", assert.isFalse);
|
||||
}
|
||||
};
|
||||
assert.isZero = function (actual, message) {
|
||||
if (actual !== 0) {
|
||||
assert.fail(actual, 0, message || "expected {expected}, got {actual}", "===", assert.isZero);
|
||||
}
|
||||
};
|
||||
assert.isNotZero = function (actual, message) {
|
||||
if (actual === 0) {
|
||||
assert.fail(actual, 0, message || "expected non-zero value, got {actual}", "===", assert.isNotZero);
|
||||
}
|
||||
};
|
||||
|
||||
assert.greater = function (actual, expected, message) {
|
||||
if (actual <= expected) {
|
||||
assert.fail(actual, expected, message || "expected {actual} to be greater than {expected}", ">", assert.greater);
|
||||
}
|
||||
};
|
||||
assert.lesser = function (actual, expected, message) {
|
||||
if (actual >= expected) {
|
||||
assert.fail(actual, expected, message || "expected {actual} to be lesser than {expected}", "<", assert.lesser);
|
||||
}
|
||||
};
|
||||
|
||||
assert.inDelta = function (actual, expected, delta, message) {
|
||||
var lower = expected - delta;
|
||||
var upper = expected + delta;
|
||||
if (actual < lower || actual > upper) {
|
||||
assert.fail(actual, expected, message || "expected {actual} to be in within *" + delta.toString() + "* of {expected}", null, assert.inDelta);
|
||||
}
|
||||
};
|
||||
|
||||
//
|
||||
// Inclusion
|
||||
//
|
||||
assert.include = function (actual, expected, message) {
|
||||
if ((function (obj) {
|
||||
if (isArray(obj) || isString(obj)) {
|
||||
return obj.indexOf(expected) === -1;
|
||||
} else if (isObject(actual)) {
|
||||
return ! obj.hasOwnProperty(expected);
|
||||
}
|
||||
return false;
|
||||
})(actual)) {
|
||||
assert.fail(actual, expected, message || "expected {actual} to include {expected}", "include", assert.include);
|
||||
}
|
||||
};
|
||||
assert.includes = assert.include;
|
||||
|
||||
assert.deepInclude = function (actual, expected, message) {
|
||||
if (!isArray(actual)) {
|
||||
return assert.include(actual, expected, message);
|
||||
}
|
||||
if (!actual.some(function (item) { return utils.deepEqual(item, expected) })) {
|
||||
assert.fail(actual, expected, message || "expected {actual} to include {expected}", "include", assert.deepInclude);
|
||||
}
|
||||
};
|
||||
assert.deepIncludes = assert.deepInclude;
|
||||
|
||||
//
|
||||
// Length
|
||||
//
|
||||
assert.isEmpty = function (actual, message) {
|
||||
if ((isObject(actual) && Object.keys(actual).length > 0) || actual.length > 0) {
|
||||
assert.fail(actual, 0, message || "expected {actual} to be empty", "length", assert.isEmpty);
|
||||
}
|
||||
};
|
||||
assert.isNotEmpty = function (actual, message) {
|
||||
if ((isObject(actual) && Object.keys(actual).length === 0) || actual.length === 0) {
|
||||
assert.fail(actual, 0, message || "expected {actual} to be not empty", "length", assert.isNotEmpty);
|
||||
}
|
||||
};
|
||||
|
||||
assert.lengthOf = function (actual, expected, message) {
|
||||
if (actual.length !== expected) {
|
||||
assert.fail(actual, expected, message || "expected {actual} to have {expected} element(s)", "length", assert.length);
|
||||
}
|
||||
};
|
||||
|
||||
//
|
||||
// Type
|
||||
//
|
||||
assert.isArray = function (actual, message) {
|
||||
assertTypeOf(actual, 'array', message || "expected {actual} to be an Array", assert.isArray);
|
||||
};
|
||||
assert.isObject = function (actual, message) {
|
||||
assertTypeOf(actual, 'object', message || "expected {actual} to be an Object", assert.isObject);
|
||||
};
|
||||
assert.isNumber = function (actual, message) {
|
||||
if (isNaN(actual)) {
|
||||
assert.fail(actual, 'number', message || "expected {actual} to be of type {expected}", "isNaN", assert.isNumber);
|
||||
} else {
|
||||
assertTypeOf(actual, 'number', message || "expected {actual} to be a Number", assert.isNumber);
|
||||
}
|
||||
};
|
||||
assert.isBoolean = function (actual, message) {
|
||||
if (actual !== true && actual !== false) {
|
||||
assert.fail(actual, 'boolean', message || "expected {actual} to be a Boolean", "===", assert.isBoolean);
|
||||
}
|
||||
};
|
||||
assert.isNaN = function (actual, message) {
|
||||
if (actual === actual) {
|
||||
assert.fail(actual, 'NaN', message || "expected {actual} to be NaN", "===", assert.isNaN);
|
||||
}
|
||||
};
|
||||
assert.isNull = function (actual, message) {
|
||||
if (actual !== null) {
|
||||
assert.fail(actual, null, message || "expected {expected}, got {actual}", "===", assert.isNull);
|
||||
}
|
||||
};
|
||||
assert.isNotNull = function (actual, message) {
|
||||
if (actual === null) {
|
||||
assert.fail(actual, null, message || "expected non-null value, got {actual}", "===", assert.isNotNull);
|
||||
}
|
||||
};
|
||||
assert.isUndefined = function (actual, message) {
|
||||
if (actual !== undefined) {
|
||||
assert.fail(actual, undefined, message || "expected {actual} to be {expected}", "===", assert.isUndefined);
|
||||
}
|
||||
};
|
||||
assert.isDefined = function (actual, message) {
|
||||
if(actual === undefined) {
|
||||
assert.fail(actual, 0, message || "expected {actual} to be defined", "===", assert.isDefined);
|
||||
}
|
||||
};
|
||||
assert.isString = function (actual, message) {
|
||||
assertTypeOf(actual, 'string', message || "expected {actual} to be a String", assert.isString);
|
||||
};
|
||||
assert.isFunction = function (actual, message) {
|
||||
assertTypeOf(actual, 'function', message || "expected {actual} to be a Function", assert.isFunction);
|
||||
};
|
||||
assert.typeOf = function (actual, expected, message) {
|
||||
assertTypeOf(actual, expected, message, assert.typeOf);
|
||||
};
|
||||
assert.instanceOf = function (actual, expected, message) {
|
||||
if (! (actual instanceof expected)) {
|
||||
assert.fail(actual, expected, message || "expected {actual} to be an instance of {expected}", "instanceof", assert.instanceOf);
|
||||
}
|
||||
};
|
||||
|
||||
//
|
||||
// Utility functions
|
||||
//
|
||||
|
||||
function assertTypeOf(actual, expected, message, caller) {
|
||||
if (typeOf(actual) !== expected) {
|
||||
assert.fail(actual, expected, message || "expected {actual} to be of type {expected}", "typeOf", caller);
|
||||
}
|
||||
};
|
||||
|
||||
function isArray (obj) {
|
||||
return Array.isArray(obj);
|
||||
}
|
||||
|
||||
function isString (obj) {
|
||||
return typeof(obj) === 'string' || obj instanceof String;
|
||||
}
|
||||
|
||||
function isObject (obj) {
|
||||
return typeof(obj) === 'object' && obj && !isArray(obj);
|
||||
}
|
||||
|
||||
// A better `typeof`
|
||||
function typeOf(value) {
|
||||
var s = typeof(value),
|
||||
types = [Object, Array, String, RegExp, Number, Function, Boolean, Date];
|
||||
|
||||
if (s === 'object' || s === 'function') {
|
||||
if (value) {
|
||||
types.forEach(function (t) {
|
||||
if (value instanceof t) { s = t.name.toLowerCase() }
|
||||
});
|
||||
} else { s = 'null' }
|
||||
}
|
||||
return s;
|
||||
}
|
77
node_modules/vows/lib/assert/utils.js
generated
vendored
Normal file
77
node_modules/vows/lib/assert/utils.js
generated
vendored
Normal file
@ -0,0 +1,77 @@
|
||||
|
||||
// Taken from node/lib/assert.js
|
||||
exports.deepEqual = function (actual, expected) {
|
||||
if (actual === expected) {
|
||||
return true;
|
||||
|
||||
} else if (Buffer.isBuffer(actual) && Buffer.isBuffer(expected)) {
|
||||
if (actual.length != expected.length) return false;
|
||||
|
||||
for (var i = 0; i < actual.length; i++) {
|
||||
if (actual[i] !== expected[i]) return false;
|
||||
}
|
||||
return true;
|
||||
|
||||
} else if (actual instanceof Date && expected instanceof Date) {
|
||||
return actual.getTime() === expected.getTime();
|
||||
|
||||
} else if (typeof actual != 'object' && typeof expected != 'object') {
|
||||
return actual == expected;
|
||||
|
||||
} else {
|
||||
return objEquiv(actual, expected);
|
||||
}
|
||||
}
|
||||
|
||||
// Taken from node/lib/assert.js
|
||||
exports.notDeepEqual = function (actual, expected, message) {
|
||||
if (exports.deepEqual(actual, expected)) {
|
||||
fail(actual, expected, message, 'notDeepEqual', assert.notDeepEqual);
|
||||
}
|
||||
}
|
||||
|
||||
// Taken from node/lib/assert.js
|
||||
function isUndefinedOrNull(value) {
|
||||
return value === null || value === undefined;
|
||||
}
|
||||
|
||||
// Taken from node/lib/assert.js
|
||||
function isArguments(object) {
|
||||
return Object.prototype.toString.call(object) == '[object Arguments]';
|
||||
}
|
||||
|
||||
// Taken from node/lib/assert.js
|
||||
function objEquiv(a, b) {
|
||||
if (isUndefinedOrNull(a) || isUndefinedOrNull(b))
|
||||
return false;
|
||||
if (a.prototype !== b.prototype) return false;
|
||||
if (isArguments(a)) {
|
||||
if (!isArguments(b)) {
|
||||
return false;
|
||||
}
|
||||
a = pSlice.call(a);
|
||||
b = pSlice.call(b);
|
||||
return exports.deepEqual(a, b);
|
||||
}
|
||||
try {
|
||||
var ka = Object.keys(a),
|
||||
kb = Object.keys(b),
|
||||
key, i;
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
if (ka.length != kb.length)
|
||||
return false;
|
||||
ka.sort();
|
||||
kb.sort();
|
||||
for (i = ka.length - 1; i >= 0; i--) {
|
||||
if (ka[i] != kb[i])
|
||||
return false;
|
||||
}
|
||||
for (i = ka.length - 1; i >= 0; i--) {
|
||||
key = ka[i];
|
||||
if (!exports.deepEqual(a[key], b[key])) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
255
node_modules/vows/lib/vows.js
generated
vendored
Normal file
255
node_modules/vows/lib/vows.js
generated
vendored
Normal file
@ -0,0 +1,255 @@
|
||||
//
|
||||
// Vows.js - asynchronous event-based BDD for node.js
|
||||
//
|
||||
// usage:
|
||||
//
|
||||
// var vows = require('vows');
|
||||
//
|
||||
// vows.describe('Deep Thought').addBatch({
|
||||
// "An instance of DeepThought": {
|
||||
// topic: new DeepThought,
|
||||
//
|
||||
// "should know the answer to the ultimate question of life": function (deepThought) {
|
||||
// assert.equal (deepThought.question('what is the answer to the universe?'), 42);
|
||||
// }
|
||||
// }
|
||||
// }).run();
|
||||
//
|
||||
var util = require('util'),
|
||||
path = require('path'),
|
||||
events = require('events'),
|
||||
vows = exports;
|
||||
|
||||
// Options
|
||||
vows.options = {
|
||||
Emitter: events.EventEmitter,
|
||||
reporter: require('./vows/reporters/dot-matrix'),
|
||||
matcher: /.*/,
|
||||
error: true // Handle "error" event
|
||||
};
|
||||
|
||||
vows.__defineGetter__('reporter', function () {
|
||||
return vows.options.reporter;
|
||||
});
|
||||
|
||||
var stylize = require('./vows/console').stylize;
|
||||
var console = vows.console = require('./vows/console');
|
||||
|
||||
vows.inspect = require('./vows/console').inspect;
|
||||
vows.prepare = require('./vows/extras').prepare;
|
||||
vows.tryEnd = require('./vows/suite').tryEnd;
|
||||
|
||||
//
|
||||
// Assertion Macros & Extensions
|
||||
//
|
||||
require('./assert/error');
|
||||
require('./assert/macros');
|
||||
|
||||
//
|
||||
// Suite constructor
|
||||
//
|
||||
var Suite = require('./vows/suite').Suite;
|
||||
|
||||
//
|
||||
// This function gets added to events.EventEmitter.prototype, by default.
|
||||
// It's essentially a wrapper around `on`, which adds all the specification
|
||||
// goodness.
|
||||
//
|
||||
function addVow(vow) {
|
||||
var batch = vow.batch,
|
||||
event = vow.binding.context.event || 'success',
|
||||
self = this;
|
||||
|
||||
batch.total ++;
|
||||
batch.vows.push(vow);
|
||||
|
||||
// always set a listener on the event
|
||||
this.on(event, function () {
|
||||
var args = Array.prototype.slice.call(arguments);
|
||||
// If the vow is a sub-event then we know it is an
|
||||
// emitted event. So I don't muck with the arguments
|
||||
// However the legacy behavior:
|
||||
// If the callback is expecting two or more arguments,
|
||||
// pass the error as the first (null) and the result after.
|
||||
if (!(this.ctx && this.ctx.isEvent) &&
|
||||
vow.callback.length >= 2 && batch.suite.options.error) {
|
||||
args.unshift(null);
|
||||
}
|
||||
runTest(args, this.ctx);
|
||||
vows.tryEnd(batch);
|
||||
});
|
||||
|
||||
if (event !== 'error') {
|
||||
this.on("error", function (err) {
|
||||
if (vow.callback.length >= 2 || !batch.suite.options.error) {
|
||||
runTest(arguments, this.ctx);
|
||||
} else {
|
||||
output('errored', { type: 'promise', error: err.stack ||
|
||||
err.message || JSON.stringify(err) });
|
||||
}
|
||||
vows.tryEnd(batch);
|
||||
});
|
||||
}
|
||||
|
||||
// in case an event fired before we could listen
|
||||
if (this._vowsEmitedEvents &&
|
||||
this._vowsEmitedEvents.hasOwnProperty(event)) {
|
||||
// make sure no one is messing with me
|
||||
if (Array.isArray(this._vowsEmitedEvents[event])) {
|
||||
// I don't think I need to optimize for one event,
|
||||
// I think it is more important to make sure I check the vow n times
|
||||
self._vowsEmitedEvents[event].forEach(function(args) {
|
||||
runTest(args, self.ctx);
|
||||
});
|
||||
} else {
|
||||
// initial conditions problem
|
||||
throw new Error('_vowsEmitedEvents[' + event + '] is not an Array')
|
||||
}
|
||||
vows.tryEnd(batch);
|
||||
}
|
||||
|
||||
return this;
|
||||
|
||||
function runTest(args, ctx) {
|
||||
if (vow.callback instanceof String) {
|
||||
return output('pending');
|
||||
}
|
||||
|
||||
if (vow.binding.context.isEvent && vow.binding.context.after) {
|
||||
var after = vow.binding.context.after;
|
||||
// only need to check order. I won't get here if the after event
|
||||
// has never been emitted
|
||||
if (self._vowsEmitedEventsOrder.indexOf(after) >
|
||||
self._vowsEmitedEventsOrder.indexOf(event)) {
|
||||
output('broken', event + ' emitted before ' + after);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Run the test, and try to catch `AssertionError`s and other exceptions;
|
||||
// increment counters accordingly.
|
||||
try {
|
||||
vow.callback.apply(ctx === global || !ctx ? vow.binding : ctx, args);
|
||||
output('honored');
|
||||
} catch (e) {
|
||||
if (e.name && e.name.match(/AssertionError/)) {
|
||||
output('broken', e.toString().replace(/\`/g, '`'));
|
||||
} else {
|
||||
output('errored', e.stack || e.message || e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function output(status, exception) {
|
||||
batch[status] ++;
|
||||
vow.status = status;
|
||||
|
||||
if (vow.context && batch.lastContext !== vow.context) {
|
||||
batch.lastContext = vow.context;
|
||||
batch.suite.report(['context', vow.context]);
|
||||
}
|
||||
batch.suite.report(['vow', {
|
||||
title: vow.description,
|
||||
context: vow.context,
|
||||
status: status,
|
||||
exception: exception || null
|
||||
}]);
|
||||
}
|
||||
};
|
||||
|
||||
//
|
||||
// On exit, check that all promises have been fired.
|
||||
// If not, report an error message.
|
||||
//
|
||||
process.on('exit', function () {
|
||||
var results = { honored: 0, broken: 0, errored: 0, pending: 0, total: 0 },
|
||||
failure;
|
||||
|
||||
vows.suites.forEach(function (s) {
|
||||
if ((s.results.total > 0) && (s.results.time === null)) {
|
||||
s.reporter.print('\n\n');
|
||||
s.reporter.report(['error', { error: "Asynchronous Error", suite: s }]);
|
||||
}
|
||||
s.batches.forEach(function (b) {
|
||||
var unFired = [];
|
||||
|
||||
b.vows.forEach(function (vow) {
|
||||
if (! vow.status) {
|
||||
if (unFired.indexOf(vow.context) === -1) {
|
||||
unFired.push(vow.context);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (unFired.length > 0) { util.print('\n') }
|
||||
|
||||
unFired.forEach(function (title) {
|
||||
s.reporter.report(['error', {
|
||||
error: "callback not fired",
|
||||
context: title,
|
||||
batch: b,
|
||||
suite: s
|
||||
}]);
|
||||
});
|
||||
|
||||
if (b.status === 'begin') {
|
||||
failure = true;
|
||||
results.errored ++;
|
||||
results.total ++;
|
||||
}
|
||||
Object.keys(results).forEach(function (k) { results[k] += b[k] });
|
||||
});
|
||||
});
|
||||
if (failure) {
|
||||
util.puts(console.result(results));
|
||||
}
|
||||
});
|
||||
|
||||
vows.suites = [];
|
||||
|
||||
// We need the old emit function so we can hook it
|
||||
// and do magic to deal with events that have fired
|
||||
var oldEmit = vows.options.Emitter.prototype.emit;
|
||||
|
||||
//
|
||||
// Create a new test suite
|
||||
//
|
||||
vows.describe = function (subject) {
|
||||
var suite = new(Suite)(subject);
|
||||
|
||||
this.options.Emitter.prototype.addVow = addVow;
|
||||
// just in case someone emit's before I get to it
|
||||
this.options.Emitter.prototype.emit = function (event) {
|
||||
this._vowsEmitedEvents = this._vowsEmitedEvents || {};
|
||||
this._vowsEmitedEventsOrder = this._vowsEmitedEventsOrder || [];
|
||||
// slice off the event
|
||||
var args = Array.prototype.slice.call(arguments, 1);
|
||||
// if multiple events are fired, add or push
|
||||
if (this._vowsEmitedEvents.hasOwnProperty(event)) {
|
||||
this._vowsEmitedEvents[event].push(args);
|
||||
} else {
|
||||
this._vowsEmitedEvents[event] = [args];
|
||||
}
|
||||
|
||||
// push the event onto a stack so I have an order
|
||||
this._vowsEmitedEventsOrder.push(event);
|
||||
return oldEmit.apply(this, arguments);
|
||||
}
|
||||
this.suites.push(suite);
|
||||
|
||||
//
|
||||
// Add any additional arguments as batches if they're present
|
||||
//
|
||||
if (arguments.length > 1) {
|
||||
for (var i = 1, l = arguments.length; i < l; ++i) {
|
||||
suite.addBatch(arguments[i]);
|
||||
}
|
||||
}
|
||||
|
||||
return suite;
|
||||
};
|
||||
|
||||
|
||||
vows.version = JSON.parse(require('fs')
|
||||
.readFileSync(path.join(__dirname, '..', 'package.json')))
|
||||
.version
|
139
node_modules/vows/lib/vows/console.js
generated
vendored
Normal file
139
node_modules/vows/lib/vows/console.js
generated
vendored
Normal file
@ -0,0 +1,139 @@
|
||||
var eyes = require('eyes').inspector({ stream: null, styles: false });
|
||||
|
||||
// Stylize a string
|
||||
this.stylize = function stylize(str, style) {
|
||||
if (module.exports.nocolor) {
|
||||
return str;
|
||||
}
|
||||
|
||||
var styles = {
|
||||
'bold' : [1, 22],
|
||||
'italic' : [3, 23],
|
||||
'underline' : [4, 24],
|
||||
'cyan' : [96, 39],
|
||||
'yellow' : [33, 39],
|
||||
'green' : [32, 39],
|
||||
'red' : [31, 39],
|
||||
'grey' : [90, 39],
|
||||
'green-hi' : [92, 32],
|
||||
};
|
||||
return '\033[' + styles[style][0] + 'm' + str +
|
||||
'\033[' + styles[style][1] + 'm';
|
||||
};
|
||||
|
||||
var $ = this.$ = function (str) {
|
||||
str = new(String)(str);
|
||||
|
||||
['bold', 'grey', 'yellow', 'red', 'green', 'white', 'cyan', 'italic'].forEach(function (style) {
|
||||
Object.defineProperty(str, style, {
|
||||
get: function () {
|
||||
return exports.$(exports.stylize(this, style));
|
||||
}
|
||||
});
|
||||
});
|
||||
return str;
|
||||
};
|
||||
|
||||
this.puts = function (options) {
|
||||
var stylize = exports.stylize;
|
||||
options.stream || (options.stream = process.stdout);
|
||||
options.tail = options.tail || '';
|
||||
|
||||
return function (args) {
|
||||
args = Array.prototype.slice.call(arguments);
|
||||
if (!options.raw) {
|
||||
args = args.map(function (a) {
|
||||
return a.replace(/`([^`]+)`/g, function (_, capture) { return stylize(capture, 'italic') })
|
||||
.replace(/\*([^*]+)\*/g, function (_, capture) { return stylize(capture, 'bold') });
|
||||
});
|
||||
}
|
||||
return options.stream.write(args.join('\n') + options.tail);
|
||||
};
|
||||
};
|
||||
|
||||
this.result = function (event) {
|
||||
var result = [], buffer = [], time = '', header;
|
||||
var complete = event.honored + event.pending + event.errored + event.broken;
|
||||
var status = (event.errored && 'errored') || (event.broken && 'broken') ||
|
||||
(event.honored && 'honored') || (event.pending && 'pending');
|
||||
|
||||
if (event.total === 0) {
|
||||
return [$("Could not find any tests to run.").bold.red];
|
||||
}
|
||||
|
||||
event.honored && result.push($(event.honored).bold + " honored");
|
||||
event.broken && result.push($(event.broken).bold + " broken");
|
||||
event.errored && result.push($(event.errored).bold + " errored");
|
||||
event.pending && result.push($(event.pending).bold + " pending");
|
||||
|
||||
if (complete < event.total) {
|
||||
result.push($(event.total - complete).bold + " dropped");
|
||||
}
|
||||
|
||||
result = result.join(' ∙ ');
|
||||
|
||||
header = {
|
||||
honored: '✓ ' + $('OK').bold.green,
|
||||
broken: '✗ ' + $('Broken').bold.yellow,
|
||||
errored: '✗ ' + $('Errored').bold.red,
|
||||
pending: '- ' + $('Pending').bold.cyan
|
||||
}[status] + ' » ';
|
||||
|
||||
if (typeof(event.time) === 'number') {
|
||||
time = ' (' + event.time.toFixed(3) + 's)';
|
||||
time = this.stylize(time, 'grey');
|
||||
}
|
||||
buffer.push(header + result + time + '\n');
|
||||
|
||||
return buffer;
|
||||
};
|
||||
|
||||
this.inspect = function inspect(val) {
|
||||
if (module.exports.nocolor) {
|
||||
return eyes(val);
|
||||
}
|
||||
|
||||
return '\033[1m' + eyes(val) + '\033[22m';
|
||||
};
|
||||
|
||||
this.error = function (obj) {
|
||||
var string = '✗ ' + $('Errored ').red + '» ';
|
||||
string += $(obj.error).red.bold + '\n';
|
||||
string += (obj.context ? ' in ' + $(obj.context).red + '\n': '');
|
||||
string += ' in ' + $(obj.suite.subject).red + '\n';
|
||||
string += ' in ' + $(obj.suite._filename).red;
|
||||
|
||||
return string;
|
||||
};
|
||||
|
||||
this.contextText = function (event) {
|
||||
return ' ' + event;
|
||||
};
|
||||
|
||||
this.vowText = function (event) {
|
||||
var buffer = [];
|
||||
|
||||
buffer.push(' ' + {
|
||||
honored: ' ✓ ',
|
||||
broken: ' ✗ ',
|
||||
errored: ' ✗ ',
|
||||
pending: ' - '
|
||||
}[event.status] + this.stylize(event.title, ({
|
||||
honored: 'green',
|
||||
broken: 'yellow',
|
||||
errored: 'red',
|
||||
pending: 'cyan'
|
||||
})[event.status]));
|
||||
|
||||
if (event.status === 'broken') {
|
||||
buffer.push(' » ' + event.exception);
|
||||
} else if (event.status === 'errored') {
|
||||
if (event.exception.type === 'promise') {
|
||||
buffer.push(' » ' + this.stylize("An unexpected error was caught: " +
|
||||
this.stylize(event.exception.error, 'bold'), 'red'));
|
||||
} else {
|
||||
buffer.push(' ' + this.stylize(event.exception, 'red'));
|
||||
}
|
||||
}
|
||||
return buffer.join('\n');
|
||||
};
|
76
node_modules/vows/lib/vows/context.js
generated
vendored
Normal file
76
node_modules/vows/lib/vows/context.js
generated
vendored
Normal file
@ -0,0 +1,76 @@
|
||||
|
||||
this.Context = function (vow, ctx, env) {
|
||||
var that = this;
|
||||
|
||||
this.tests = vow.callback;
|
||||
this.topics = (ctx.topics || []).slice(0);
|
||||
this.emitter = null;
|
||||
this.env = env || {};
|
||||
this.env.context = this;
|
||||
|
||||
this.env.callback = function (/* arguments */) {
|
||||
var ctx = this;
|
||||
var args = Array.prototype.slice.call(arguments);
|
||||
|
||||
var emit = (function (args) {
|
||||
//
|
||||
// Convert callback-style results into events.
|
||||
//
|
||||
if (vow.batch.suite.options.error) {
|
||||
return function () {
|
||||
var e = args.shift();
|
||||
that.emitter.ctx = ctx;
|
||||
// We handle a special case, where the first argument is a
|
||||
// boolean, in which case we treat it as a result, and not
|
||||
// an error. This is useful for `path.exists` and other
|
||||
// functions like it, which only pass a single boolean
|
||||
// parameter instead of the more common (error, result) pair.
|
||||
if (typeof(e) === 'boolean' && args.length === 0) {
|
||||
that.emitter.emit.call(that.emitter, 'success', e);
|
||||
} else {
|
||||
if (e) { that.emitter.emit.apply(that.emitter, ['error', e].concat(args)) }
|
||||
else { that.emitter.emit.apply(that.emitter, ['success'].concat(args)) }
|
||||
}
|
||||
};
|
||||
} else {
|
||||
return function () {
|
||||
that.emitter.ctx = ctx;
|
||||
that.emitter.emit.apply(that.emitter, ['success'].concat(args));
|
||||
};
|
||||
}
|
||||
})(args.slice(0));
|
||||
// If `this.callback` is called synchronously,
|
||||
// the emitter will not have been set yet,
|
||||
// so we defer the emition, that way it'll behave
|
||||
// asynchronously.
|
||||
if (that.emitter) { emit() }
|
||||
else { process.nextTick(emit) }
|
||||
};
|
||||
this.name = vow.description;
|
||||
// events is an alias for on
|
||||
if (this.name === 'events') {
|
||||
this.name = vow.description = 'on';
|
||||
}
|
||||
|
||||
// if this is a sub-event context AND it's context was an event,
|
||||
// then I must enforce event order.
|
||||
// this will not do a good job of handling pin-pong events
|
||||
if (this.name === 'on' && ctx.isEvent) {
|
||||
this.after = ctx.name;
|
||||
}
|
||||
|
||||
if (ctx.name === 'on') {
|
||||
this.isEvent = true;
|
||||
this.event = this.name;
|
||||
this.after = ctx.after;
|
||||
} else {
|
||||
this.isEvent = false;
|
||||
this.event = 'success';
|
||||
}
|
||||
|
||||
this.title = [
|
||||
ctx.title || '',
|
||||
vow.description || ''
|
||||
].join(/^[#.:]/.test(vow.description) ? '' : ' ').trim();
|
||||
};
|
||||
|
29
node_modules/vows/lib/vows/coverage/file.js
generated
vendored
Normal file
29
node_modules/vows/lib/vows/coverage/file.js
generated
vendored
Normal file
@ -0,0 +1,29 @@
|
||||
|
||||
exports.coverage = function (filename, data) {
|
||||
var ret = {
|
||||
filename: filename,
|
||||
coverage: 0,
|
||||
hits: 0,
|
||||
misses: 0,
|
||||
sloc : 0
|
||||
};
|
||||
|
||||
var source = data.source;
|
||||
ret.source = source.map(function (line, num) {
|
||||
num++;
|
||||
|
||||
if (data[num] === 0) {
|
||||
ret.misses++;
|
||||
ret.sloc++;
|
||||
} else if (data[num] !== undefined) {
|
||||
ret.hits++;
|
||||
ret.sloc++;
|
||||
}
|
||||
|
||||
return { line: line, coverage: (data[num] === undefined ? '' : data[num]) };
|
||||
});
|
||||
|
||||
ret.coverage = (ret.hits / ret.sloc) * 100;
|
||||
|
||||
return ret;
|
||||
};
|
2
node_modules/vows/lib/vows/coverage/fragments/coverage-foot.html
generated
vendored
Normal file
2
node_modules/vows/lib/vows/coverage/fragments/coverage-foot.html
generated
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
</body>
|
||||
</html>
|
61
node_modules/vows/lib/vows/coverage/fragments/coverage-head.html
generated
vendored
Normal file
61
node_modules/vows/lib/vows/coverage/fragments/coverage-head.html
generated
vendored
Normal file
@ -0,0 +1,61 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<style type="text/css">
|
||||
.covered {
|
||||
background-color: green;
|
||||
}
|
||||
.uncovered {
|
||||
background-color: red;
|
||||
}
|
||||
.coverage {
|
||||
font-size: 0.8em;
|
||||
color: #333;
|
||||
}
|
||||
.coverage.fullCoverage {
|
||||
background-color:#0f0;
|
||||
color: #111;
|
||||
}
|
||||
.coverage.okCoverage {
|
||||
background-color: orange;
|
||||
}
|
||||
.coverage.poorCoverage {
|
||||
background-color: red;
|
||||
}
|
||||
.code {
|
||||
font-family: "Consolas", "Courier New", Courier, mono;
|
||||
white-space: pre;
|
||||
line-height: 16px;
|
||||
}
|
||||
.collapsed {
|
||||
display: none;
|
||||
}
|
||||
body {
|
||||
margin-left: 20px;
|
||||
margin-top: 8px;
|
||||
background-color: white;
|
||||
color: black;
|
||||
font-size: 16px;
|
||||
}
|
||||
ol {
|
||||
margin-left: 20px;
|
||||
margin-bottom: 40px;
|
||||
width: 800px;
|
||||
line-height: 18px;
|
||||
-moz-box-shadow: 10px 10px 5px #888;
|
||||
-webkit-box-shadow: 10px 10px 5px #888;
|
||||
box-shadow: 10px 10px 5px #888;
|
||||
}
|
||||
</style>
|
||||
<script type="text/javascript">
|
||||
function expando(elem) {
|
||||
// We're skipping the '/n' text element sibling.
|
||||
var olElement= elem.nextSibling.nextSibling;
|
||||
var currentState= olElement.className;
|
||||
if( currentState == "collapsed" ) currentState= "";
|
||||
else currentState= "collapsed";
|
||||
olElement.className= currentState;
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
54
node_modules/vows/lib/vows/coverage/report-html.js
generated
vendored
Normal file
54
node_modules/vows/lib/vows/coverage/report-html.js
generated
vendored
Normal file
@ -0,0 +1,54 @@
|
||||
var util = require('util'),
|
||||
fs = require('fs'),
|
||||
file = require('./file');
|
||||
|
||||
this.name = 'coverage-report-html';
|
||||
|
||||
function getCoverageClass( data ) {
|
||||
var fullCoverage= (data.coverage == 100);
|
||||
var okCoverage= (!fullCoverage && data.coverage >=60);
|
||||
var coverageClass= '';
|
||||
if( fullCoverage ) coverageClass= 'fullCoverage';
|
||||
else if( okCoverage) coverageClass= 'okCoverage';
|
||||
else coverageClass= 'poorCoverage';
|
||||
return coverageClass;
|
||||
}
|
||||
this.report = function (coverageMap) {
|
||||
var out, head, foot;
|
||||
|
||||
try {
|
||||
out = fs.openSync("coverage.html", "w");
|
||||
head = fs.readFileSync(__dirname + "/fragments/coverage-head.html", "utf8");
|
||||
foot = fs.readFileSync(__dirname + "/fragments/coverage-foot.html", "utf8");
|
||||
} catch (error) {
|
||||
util.print("Error: Unable to write to file coverage.html\n");
|
||||
return;
|
||||
}
|
||||
|
||||
fs.writeSync(out, head);
|
||||
|
||||
for (var filename in coverageMap) {
|
||||
if (coverageMap.hasOwnProperty(filename)) {
|
||||
var data = file.coverage(filename, coverageMap[filename]);
|
||||
var coverageClass= getCoverageClass( data );
|
||||
fs.writeSync(out, "<h2>" + filename + "</h2>\n");
|
||||
fs.writeSync(out, '<span class="coverage '+ coverageClass+'">' + "[ hits: " + data.hits);
|
||||
fs.writeSync(out, ", misses: " + data.misses + ", sloc: " + data.sloc);
|
||||
fs.writeSync(out, ", coverage: " + data.coverage.toFixed(2) + "% ]" + "</span> <a href='#' onclick='expando(this)'>[+]</a>\n");
|
||||
fs.writeSync(out, "<ol class='collapsed'>\n");
|
||||
|
||||
for (var i = 0; i < data.source.length; i++) {
|
||||
fs.writeSync(out, ' <li class="code ');
|
||||
fs.writeSync(out, (data.source[i].coverage === 0 ? 'uncovered' : 'covered'));
|
||||
fs.writeSync(out, '" coverage="' + data.source[i].coverage + '">');
|
||||
fs.writeSync(out, data.source[i].line + "</li>\n");
|
||||
}
|
||||
|
||||
fs.writeSync(out, "</ol>\n");
|
||||
fs.writeSync(out, "<hr/>\n");
|
||||
}
|
||||
}
|
||||
|
||||
fs.writeSync(out, foot);
|
||||
fs.close(out);
|
||||
};
|
54
node_modules/vows/lib/vows/coverage/report-json.js
generated
vendored
Normal file
54
node_modules/vows/lib/vows/coverage/report-json.js
generated
vendored
Normal file
@ -0,0 +1,54 @@
|
||||
var util = require('util'),
|
||||
fs = require('fs'),
|
||||
file = require('./file');
|
||||
|
||||
this.name = 'coverage-report-json';
|
||||
|
||||
this.report = function (coverageMap) {
|
||||
var output = {
|
||||
meta: {
|
||||
"generator": "vowsjs",
|
||||
"generated": new Date().toString(),
|
||||
"instrumentation": "node-jscoverage",
|
||||
"file-version": "1.0"
|
||||
},
|
||||
files: [ ],
|
||||
coverage: [ ]
|
||||
};
|
||||
|
||||
|
||||
for (var filename in coverageMap) {
|
||||
if (coverageMap.hasOwnProperty(filename)) {
|
||||
var data = file.coverage(filename, coverageMap[filename]);
|
||||
|
||||
var coverage = {
|
||||
file: filename,
|
||||
coverage: data.coverage.toFixed(2),
|
||||
hits: data.hits,
|
||||
misses: data.misses,
|
||||
sloc: data.sloc,
|
||||
source: { }
|
||||
};
|
||||
|
||||
for (var i = 0; i < data.source.length; i++) {
|
||||
coverage.source[i + 1] = {
|
||||
line: data.source[i].line,
|
||||
coverage: data.source[i].coverage
|
||||
};
|
||||
}
|
||||
|
||||
output.coverage.push(coverage);
|
||||
|
||||
output.files.push(filename);
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
out = fs.openSync("coverage.json", "w");
|
||||
fs.writeSync(out, JSON.stringify(output));
|
||||
fs.close(out);
|
||||
} catch (error) {
|
||||
util.print("Error: Unable to write to file coverage.json\n");
|
||||
return;
|
||||
}
|
||||
};
|
38
node_modules/vows/lib/vows/coverage/report-plain.js
generated
vendored
Normal file
38
node_modules/vows/lib/vows/coverage/report-plain.js
generated
vendored
Normal file
@ -0,0 +1,38 @@
|
||||
var util = require('util'),
|
||||
file = require('./file');
|
||||
|
||||
this.name = 'coverage-report-plain';
|
||||
|
||||
function lpad(str, width) {
|
||||
str = String(str);
|
||||
var n = width - str.length;
|
||||
|
||||
if (n < 1) {
|
||||
return str;
|
||||
}
|
||||
|
||||
while (n--) {
|
||||
str = ' ' + str;
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
|
||||
this.report = function (coverageMap) {
|
||||
for (var filename in coverageMap) {
|
||||
if (coverageMap.hasOwnProperty(filename)) {
|
||||
var data = file.coverage(filename, coverageMap[filename]);
|
||||
|
||||
util.print(filename + ":\n");
|
||||
util.print("[ hits: " + data.hits + ", misses: " + data.misses);
|
||||
util.print(", sloc: " + data.sloc + ", coverage: " + data.coverage.toFixed(2) + "% ]\n");
|
||||
|
||||
for (var i = 0; i < data.source.length; i++) {
|
||||
util.print(lpad(data.source[i].coverage, 5) + " | " + data.source[i].line + "\n");
|
||||
}
|
||||
|
||||
util.print("\n");
|
||||
}
|
||||
}
|
||||
};
|
28
node_modules/vows/lib/vows/extras.js
generated
vendored
Normal file
28
node_modules/vows/lib/vows/extras.js
generated
vendored
Normal file
@ -0,0 +1,28 @@
|
||||
var events = require('events');
|
||||
//
|
||||
// Wrap a Node.js style async function into an EventEmmitter
|
||||
//
|
||||
this.prepare = function (obj, targets) {
|
||||
targets.forEach(function (target) {
|
||||
if (target in obj) {
|
||||
obj[target] = (function (fun) {
|
||||
return function () {
|
||||
var args = Array.prototype.slice.call(arguments);
|
||||
var ee = new(events.EventEmitter);
|
||||
|
||||
args.push(function (err /* [, data] */) {
|
||||
var args = Array.prototype.slice.call(arguments, 1);
|
||||
|
||||
if (err) { ee.emit.apply(ee, ['error', err].concat(args)) }
|
||||
else { ee.emit.apply(ee, ['success'].concat(args)) }
|
||||
});
|
||||
fun.apply(obj, args);
|
||||
|
||||
return ee;
|
||||
};
|
||||
})(obj[target]);
|
||||
}
|
||||
});
|
||||
return obj;
|
||||
};
|
||||
|
67
node_modules/vows/lib/vows/reporters/dot-matrix.js
generated
vendored
Normal file
67
node_modules/vows/lib/vows/reporters/dot-matrix.js
generated
vendored
Normal file
@ -0,0 +1,67 @@
|
||||
var options = { tail: '' },
|
||||
console = require('../../vows/console'),
|
||||
stylize = console.stylize,
|
||||
puts = console.puts(options);
|
||||
//
|
||||
// Console reporter
|
||||
//
|
||||
var messages = [], lastContext;
|
||||
|
||||
this.name = 'dot-matrix';
|
||||
this.setStream = function (s) {
|
||||
options.stream = s;
|
||||
};
|
||||
|
||||
this.reset = function () {
|
||||
messages = [];
|
||||
lastContext = null;
|
||||
};
|
||||
this.report = function (data) {
|
||||
var event = data[1];
|
||||
|
||||
switch (data[0]) {
|
||||
case 'subject':
|
||||
// messages.push(stylize(event, 'underline') + '\n');
|
||||
break;
|
||||
case 'context':
|
||||
break;
|
||||
case 'vow':
|
||||
if (event.status === 'honored') {
|
||||
puts(stylize('·', 'green'));
|
||||
} else if (event.status === 'pending') {
|
||||
puts(stylize('-', 'cyan'));
|
||||
} else {
|
||||
if (lastContext !== event.context) {
|
||||
lastContext = event.context;
|
||||
messages.push(' ' + event.context);
|
||||
}
|
||||
if (event.status === 'broken') {
|
||||
puts(stylize('✗', 'yellow'));
|
||||
messages.push(console.vowText(event));
|
||||
} else if (event.status === 'errored') {
|
||||
puts(stylize('✗', 'red'));
|
||||
messages.push(console.vowText(event));
|
||||
}
|
||||
messages.push('');
|
||||
}
|
||||
break;
|
||||
case 'end':
|
||||
puts(' ');
|
||||
break;
|
||||
case 'finish':
|
||||
if (messages.length) {
|
||||
puts('\n\n' + messages.join('\n'));
|
||||
} else {
|
||||
puts('');
|
||||
}
|
||||
puts(console.result(event).join('\n'));
|
||||
break;
|
||||
case 'error':
|
||||
puts(console.error(event));
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
this.print = function (str) {
|
||||
puts(str);
|
||||
};
|
33
node_modules/vows/lib/vows/reporters/json.js
generated
vendored
Normal file
33
node_modules/vows/lib/vows/reporters/json.js
generated
vendored
Normal file
@ -0,0 +1,33 @@
|
||||
var options = { tail: '\n', raw: true };
|
||||
var console = require('../../vows/console');
|
||||
var puts = console.puts(options);
|
||||
|
||||
//
|
||||
// Console JSON reporter
|
||||
//
|
||||
this.name = 'json';
|
||||
this.setStream = function (s) {
|
||||
options.stream = s;
|
||||
};
|
||||
|
||||
function removeCircularSuite(obj, suite) {
|
||||
var result = {};
|
||||
|
||||
if (typeof obj !== 'object' || obj === null) return obj;
|
||||
|
||||
Object.keys(obj).forEach(function(key) {
|
||||
if (obj[key] === suite) {
|
||||
result[key] = {};
|
||||
} else {
|
||||
result[key] = removeCircularSuite(obj[key], suite || obj.suite);
|
||||
}
|
||||
});
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
this.report = function (obj) {
|
||||
puts(JSON.stringify(removeCircularSuite(obj)));
|
||||
};
|
||||
|
||||
this.print = function (str) {};
|
8
node_modules/vows/lib/vows/reporters/silent.js
generated
vendored
Normal file
8
node_modules/vows/lib/vows/reporters/silent.js
generated
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
//
|
||||
// Silent reporter - "Shhh"
|
||||
//
|
||||
this.name = 'silent';
|
||||
this.reset = function () {};
|
||||
this.report = function () {};
|
||||
this.print = function () {};
|
||||
|
42
node_modules/vows/lib/vows/reporters/spec.js
generated
vendored
Normal file
42
node_modules/vows/lib/vows/reporters/spec.js
generated
vendored
Normal file
@ -0,0 +1,42 @@
|
||||
var util = require('util');
|
||||
|
||||
var options = { tail: '\n' };
|
||||
var console = require('../../vows/console');
|
||||
var stylize = console.stylize,
|
||||
puts = console.puts(options);
|
||||
//
|
||||
// Console reporter
|
||||
//
|
||||
|
||||
this.name = 'spec';
|
||||
this.setStream = function (s) {
|
||||
options.stream = s;
|
||||
};
|
||||
this.report = function (data) {
|
||||
var event = data[1];
|
||||
|
||||
switch (data[0]) {
|
||||
case 'subject':
|
||||
puts('\n♢ ' + stylize(event, 'bold') + '\n');
|
||||
break;
|
||||
case 'context':
|
||||
puts(console.contextText(event));
|
||||
break;
|
||||
case 'vow':
|
||||
puts(console.vowText(event));
|
||||
break;
|
||||
case 'end':
|
||||
util.print('\n');
|
||||
break;
|
||||
case 'finish':
|
||||
puts(console.result(event).join('\n'));
|
||||
break;
|
||||
case 'error':
|
||||
puts(console.error(event));
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
this.print = function (str) {
|
||||
util.print(str);
|
||||
};
|
37
node_modules/vows/lib/vows/reporters/watch.js
generated
vendored
Normal file
37
node_modules/vows/lib/vows/reporters/watch.js
generated
vendored
Normal file
@ -0,0 +1,37 @@
|
||||
var options = {};
|
||||
var console = require('../../vows/console');
|
||||
var spec = require('../../vows/reporters/spec');
|
||||
var stylize = console.stylize,
|
||||
puts = console.puts(options);
|
||||
//
|
||||
// Console reporter
|
||||
//
|
||||
var lastContext;
|
||||
|
||||
this.name = 'watch';
|
||||
this.setStream = function (s) {
|
||||
options.stream = s;
|
||||
};
|
||||
this.reset = function () {
|
||||
lastContext = null;
|
||||
};
|
||||
this.report = function (data) {
|
||||
var event = data[1];
|
||||
|
||||
switch (data[0]) {
|
||||
case 'vow':
|
||||
if (['honored', 'pending'].indexOf(event.status) === -1) {
|
||||
if (lastContext !== event.context) {
|
||||
lastContext = event.context;
|
||||
puts(console.contextText(event.context));
|
||||
}
|
||||
puts(console.vowText(event));
|
||||
puts('');
|
||||
}
|
||||
break;
|
||||
case 'error':
|
||||
puts(console.error(event));
|
||||
break;
|
||||
}
|
||||
};
|
||||
this.print = function (str) {};
|
90
node_modules/vows/lib/vows/reporters/xunit.js
generated
vendored
Normal file
90
node_modules/vows/lib/vows/reporters/xunit.js
generated
vendored
Normal file
@ -0,0 +1,90 @@
|
||||
// xunit outoput for vows, so we can run things under hudson
|
||||
//
|
||||
// The translation to xunit is simple. Most likely more tags/attributes can be
|
||||
// added, see: http://ant.1045680.n5.nabble.com/schema-for-junit-xml-output-td1375274.html
|
||||
//
|
||||
|
||||
var puts = require('util').puts;
|
||||
|
||||
var buffer = [],
|
||||
curSubject = null;
|
||||
|
||||
function xmlEnc(value) {
|
||||
return !value ? value : String(value).replace(/&/g, "&")
|
||||
.replace(/>/g, ">")
|
||||
.replace(/</g, "<")
|
||||
.replace(/"/g, """)
|
||||
.replace(/\u001b\[\d{1,2}m/g, '');
|
||||
}
|
||||
|
||||
function tag(name, attribs, single, content) {
|
||||
var strAttr = [], t, end = '>';
|
||||
for (var attr in attribs) {
|
||||
if (attribs.hasOwnProperty(attr)) {
|
||||
strAttr.push(attr + '="' + xmlEnc(attribs[attr]) + '"');
|
||||
}
|
||||
}
|
||||
if (single) {
|
||||
end = ' />';
|
||||
}
|
||||
if (strAttr.length) {
|
||||
t = '<' + name + ' ' + strAttr.join(' ') + end;
|
||||
} else {
|
||||
t = '<' + name + end;
|
||||
}
|
||||
if (typeof content !== 'undefined') {
|
||||
return t + content + '</' + name + end;
|
||||
}
|
||||
return t;
|
||||
}
|
||||
|
||||
function end(name) {
|
||||
return '</' + name + '>';
|
||||
}
|
||||
|
||||
function cdata(data) {
|
||||
return '<![CDATA[' + xmlEnc(data) + ']]>';
|
||||
}
|
||||
|
||||
this.name = 'xunit';
|
||||
this.report = function (data) {
|
||||
var event = data[1];
|
||||
|
||||
switch (data[0]) {
|
||||
case 'subject':
|
||||
curSubject = event;
|
||||
break;
|
||||
case 'context':
|
||||
break;
|
||||
case 'vow':
|
||||
switch (event.status) {
|
||||
case 'honored':
|
||||
buffer.push(tag('testcase', {classname: curSubject, name: event.context + ': ' + event.title}, true));
|
||||
break;
|
||||
case 'broken':
|
||||
var err = tag('error', {type: 'vows.event.broken', message: 'Broken test'}, false, cdata(event.exception));
|
||||
buffer.push(tag('testcase', {classname: curSubject, name: event.context + ': ' + event.title}, false, err));
|
||||
break;
|
||||
case 'errored':
|
||||
var skip = tag('skipped', {type: 'vows.event.errored', message: 'Errored test'}, false, cdata(event.exception));
|
||||
buffer.push(tag('testcase', {classname: curSubject, name: event.context + ': ' + event.title}, false, skip));
|
||||
break;
|
||||
case 'pending':
|
||||
// nop
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 'end':
|
||||
buffer.push(end('testcase'));
|
||||
break;
|
||||
case 'finish':
|
||||
buffer.unshift(tag('testsuite', {name: 'Vows test', tests: event.total, timestamp: (new Date()).toUTCString(), errors: event.errored, failures: event.broken, skip: event.pending, time: event.time}));
|
||||
buffer.push(end('testsuite'));
|
||||
puts(buffer.join('\n'));
|
||||
break;
|
||||
case 'error':
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
this.print = function (str) { };
|
380
node_modules/vows/lib/vows/suite.js
generated
vendored
Normal file
380
node_modules/vows/lib/vows/suite.js
generated
vendored
Normal file
@ -0,0 +1,380 @@
|
||||
var events = require('events'),
|
||||
path = require('path');
|
||||
|
||||
var vows = require('../vows');
|
||||
var Context = require('../vows/context').Context;
|
||||
|
||||
this.Suite = function (subject) {
|
||||
this.subject = subject;
|
||||
this.matcher = /.*/;
|
||||
this.reporter = require('./reporters/dot-matrix');
|
||||
this.batches = [];
|
||||
this.options = { error: true };
|
||||
this.reset();
|
||||
};
|
||||
|
||||
this.Suite.prototype = new(function () {
|
||||
this.reset = function () {
|
||||
this.results = {
|
||||
honored: 0,
|
||||
broken: 0,
|
||||
errored: 0,
|
||||
pending: 0,
|
||||
total: 0,
|
||||
time: null
|
||||
};
|
||||
this.batches.forEach(function (b) {
|
||||
b.lastContext = null;
|
||||
b.remaining = b._remaining;
|
||||
b.honored = b.broken = b.errored = b.total = b.pending = 0;
|
||||
b.vows.forEach(function (vow) { vow.status = null });
|
||||
b.teardowns = [];
|
||||
});
|
||||
};
|
||||
|
||||
this.addBatch = function (tests) {
|
||||
this.batches.push({
|
||||
tests: tests,
|
||||
suite: this,
|
||||
vows: [],
|
||||
remaining: 0,
|
||||
_remaining: 0,
|
||||
honored: 0,
|
||||
broken: 0,
|
||||
errored: 0,
|
||||
pending: 0,
|
||||
total: 0,
|
||||
teardowns: []
|
||||
});
|
||||
return this;
|
||||
};
|
||||
this.addVows = this.addBatch;
|
||||
|
||||
this.parseBatch = function (batch, matcher) {
|
||||
var tests = batch.tests;
|
||||
|
||||
if ('topic' in tests) {
|
||||
throw new(Error)("missing top-level context.");
|
||||
}
|
||||
// Count the number of vows/promises expected to fire,
|
||||
// so we know when the tests are over.
|
||||
// We match the keys against `matcher`, to decide
|
||||
// whether or not they should be included in the test.
|
||||
// Any key, including assertion function keys can be matched.
|
||||
// If a child matches, then the n parent topics must not be skipped.
|
||||
(function count(tests, _match) {
|
||||
var match = false;
|
||||
|
||||
var keys = Object.keys(tests).filter(function (k) {
|
||||
return k !== 'topic' && k !== 'teardown';
|
||||
});
|
||||
|
||||
for (var i = 0, key; i < keys.length; i++) {
|
||||
key = keys[i];
|
||||
|
||||
// If the parent node, or this one matches.
|
||||
match = _match || matcher.test(key);
|
||||
|
||||
if (typeof(tests[key]) === 'object') {
|
||||
match = count(tests[key], match);
|
||||
} else {
|
||||
if (typeof(tests[key]) === 'string') {
|
||||
tests[key] = new(String)(tests[key]);
|
||||
}
|
||||
if (! match) {
|
||||
tests[key]._skip = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If any of the children matched,
|
||||
// don't skip this node.
|
||||
for (var i = 0; i < keys.length; i++) {
|
||||
if (! tests[keys[i]]._skip) { match = true }
|
||||
}
|
||||
|
||||
if (match) { batch.remaining ++ }
|
||||
else { tests._skip = true }
|
||||
|
||||
return match;
|
||||
})(tests, false);
|
||||
|
||||
batch._remaining = batch.remaining;
|
||||
};
|
||||
|
||||
this.runBatch = function (batch) {
|
||||
var topic,
|
||||
tests = batch.tests,
|
||||
promise = batch.promise = new(events.EventEmitter);
|
||||
|
||||
var that = this;
|
||||
|
||||
batch.status = 'begin';
|
||||
|
||||
// The test runner, it calls itself recursively, passing the
|
||||
// previous context to the inner contexts. This is so the `topic`
|
||||
// functions have access to all the previous context topics in their
|
||||
// arguments list.
|
||||
// It is defined and invoked at the same time.
|
||||
// If it encounters a `topic` function, it waits for the returned
|
||||
// promise to emit (the topic), at which point it runs the functions under it,
|
||||
// passing the topic as an argument.
|
||||
(function run(ctx, lastTopic) {
|
||||
var old = false;
|
||||
topic = ctx.tests.topic;
|
||||
|
||||
if (typeof(topic) === 'function') {
|
||||
if (ctx.isEvent || ctx.name === 'on') {
|
||||
throw new Error('Event context cannot contain a topic');
|
||||
}
|
||||
|
||||
// Run the topic, passing the previous context topics
|
||||
// If topic `throw`s an exception, pass it down as a value
|
||||
try {
|
||||
topic = topic.apply(ctx.env, ctx.topics);
|
||||
}
|
||||
catch (ex) {
|
||||
topic = ex;
|
||||
}
|
||||
|
||||
if (typeof(topic) === 'undefined') { ctx._callback = true }
|
||||
}
|
||||
|
||||
// If this context has a topic, store it in `lastTopic`,
|
||||
// if not, use the last topic, passed down by a parent
|
||||
// context.
|
||||
if (typeof(topic) !== 'undefined' || ctx._callback) {
|
||||
lastTopic = topic;
|
||||
} else {
|
||||
old = true;
|
||||
topic = lastTopic;
|
||||
}
|
||||
|
||||
// If the topic doesn't return an event emitter (such as a promise),
|
||||
// we create it ourselves, and emit the value on the next tick.
|
||||
if (! (topic &&
|
||||
topic.constructor === events.EventEmitter)) {
|
||||
// If the context is a traditional vow, then a topic can ONLY
|
||||
// be an EventEmitter. However if the context is a sub-event
|
||||
// then the topic may be an instanceof EventEmitter
|
||||
if (!ctx.isEvent ||
|
||||
(ctx.isEvent && !(topic instanceof events.EventEmitter))) {
|
||||
|
||||
ctx.emitter = new(events.EventEmitter);
|
||||
|
||||
if (! ctx._callback) {
|
||||
process.nextTick(function (val) {
|
||||
return function () {
|
||||
ctx.emitter.emit("success", val)
|
||||
};
|
||||
}(topic));
|
||||
}
|
||||
// if I have a callback, push the new topic back up to
|
||||
// lastTopic
|
||||
if (ctx._callback) {
|
||||
lastTopic = topic = ctx.emitter;
|
||||
} else {
|
||||
topic = ctx.emitter;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
topic.on(ctx.event, function (val) {
|
||||
// Once the topic fires, add the return value
|
||||
// to the beginning of the topics list, so it
|
||||
// becomes the first argument for the next topic.
|
||||
// If we're using the parent topic, no need to
|
||||
// prepend it to the topics list, or we'll get
|
||||
// duplicates.
|
||||
if (!old || ctx.isEvent) {
|
||||
Array.prototype.unshift.apply(ctx.topics, arguments)
|
||||
};
|
||||
});
|
||||
if (topic.setMaxListeners) { topic.setMaxListeners(Infinity) }
|
||||
// Now run the tests, or sub-contexts
|
||||
Object.keys(ctx.tests).filter(function (k) {
|
||||
return ctx.tests[k] && k !== 'topic' &&
|
||||
k !== 'teardown' && !ctx.tests[k]._skip;
|
||||
}).forEach(function (item) {
|
||||
// Create a new evaluation context,
|
||||
// inheriting from the parent one.
|
||||
var env = Object.create(ctx.env);
|
||||
env.suite = that;
|
||||
|
||||
// Holds the current test or context
|
||||
var vow = Object.create({
|
||||
callback: ctx.tests[item],
|
||||
context: ctx.title,
|
||||
description: item,
|
||||
binding: ctx.env,
|
||||
status: null,
|
||||
batch: batch
|
||||
});
|
||||
|
||||
// If we encounter a function, add it to the callbacks
|
||||
// of the `topic` function, so it'll get called once the
|
||||
// topic fires.
|
||||
// If we encounter an object literal, we recurse, sending it
|
||||
// our current context.
|
||||
if ((typeof(vow.callback) === 'function') ||
|
||||
(vow.callback instanceof String)) {
|
||||
topic.addVow(vow);
|
||||
} else if (typeof(vow.callback) === 'object') {
|
||||
// If there's a setup stage, we have to wait for it to fire,
|
||||
// before calling the inner context.
|
||||
// If the event has already fired, the context is 'on' or
|
||||
// there is no setup stage, just run the inner context
|
||||
// synchronously.
|
||||
if (topic &&
|
||||
ctx.name !== 'on' &&
|
||||
!topic._vowsEmitedEvents.hasOwnProperty(ctx.event)) {
|
||||
topic.on(ctx.event, function (ctx) {
|
||||
return function (val) {
|
||||
return run(new(Context)(vow, ctx, env), lastTopic);
|
||||
};
|
||||
}(ctx));
|
||||
} else {
|
||||
run(new(Context)(vow, ctx, env), lastTopic);
|
||||
}
|
||||
}
|
||||
});
|
||||
// Teardown
|
||||
if (ctx.tests.teardown) {
|
||||
batch.teardowns.push(ctx);
|
||||
}
|
||||
if (! ctx.tests._skip) {
|
||||
batch.remaining --;
|
||||
}
|
||||
// Check if we're done running the tests
|
||||
exports.tryEnd(batch);
|
||||
// This is our initial, empty context
|
||||
})(new(Context)({ callback: tests, context: null, description: null }, {}));
|
||||
return promise;
|
||||
};
|
||||
|
||||
this.report = function () {
|
||||
return this.reporter.report.apply(this.reporter, arguments);
|
||||
};
|
||||
|
||||
this.run = function (options, callback) {
|
||||
var that = this, start;
|
||||
|
||||
options = options || {};
|
||||
|
||||
for (var k in options) { this.options[k] = options[k] }
|
||||
|
||||
this.matcher = this.options.matcher || this.matcher;
|
||||
this.reporter = this.options.reporter || this.reporter;
|
||||
|
||||
this.batches.forEach(function (batch) {
|
||||
that.parseBatch(batch, that.matcher);
|
||||
});
|
||||
|
||||
this.reset();
|
||||
|
||||
start = new(Date);
|
||||
|
||||
if (this.batches.filter(function (b) { return b.remaining > 0 }).length) {
|
||||
this.report(['subject', this.subject]);
|
||||
}
|
||||
|
||||
return (function run(batches) {
|
||||
var batch = batches.shift();
|
||||
|
||||
if (batch) {
|
||||
// If the batch has no vows to run,
|
||||
// go to the next one.
|
||||
if (batch.remaining === 0) {
|
||||
run(batches);
|
||||
} else {
|
||||
that.runBatch(batch).on('end', function () {
|
||||
run(batches);
|
||||
});
|
||||
}
|
||||
} else {
|
||||
that.results.time = (new(Date) - start) / 1000;
|
||||
that.report(['finish', that.results]);
|
||||
|
||||
if (callback) { callback(that.results) }
|
||||
|
||||
if (that.results.honored + that.results.pending === that.results.total) {
|
||||
return 0;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
})(this.batches.slice(0));
|
||||
};
|
||||
|
||||
this.runParallel = function () {};
|
||||
|
||||
this.export = function (module, options) {
|
||||
for (var k in (options || {})) { this.options[k] = options[k] }
|
||||
|
||||
if (require.main === module) {
|
||||
return this.run();
|
||||
} else {
|
||||
return module.exports[this.subject] = this;
|
||||
}
|
||||
};
|
||||
this.exportTo = function (module, options) { // Alias, for JSLint
|
||||
return this.export(module, options);
|
||||
};
|
||||
});
|
||||
|
||||
//
|
||||
// Checks if all the tests in the batch have been run,
|
||||
// and triggers the next batch (if any), by emitting the 'end' event.
|
||||
//
|
||||
this.tryEnd = function (batch) {
|
||||
var result, style, time;
|
||||
|
||||
if (batch.honored + batch.broken + batch.errored + batch.pending === batch.total &&
|
||||
batch.remaining === 0) {
|
||||
|
||||
Object.keys(batch).forEach(function (k) {
|
||||
(k in batch.suite.results) && (batch.suite.results[k] += batch[k]);
|
||||
});
|
||||
|
||||
if (batch.teardowns) {
|
||||
for (var i = batch.teardowns.length - 1, ctx; i >= 0; i--) {
|
||||
runTeardown(batch.teardowns[i]);
|
||||
}
|
||||
|
||||
maybeFinish();
|
||||
}
|
||||
|
||||
function runTeardown(teardown) {
|
||||
var env = Object.create(teardown.env);
|
||||
|
||||
Object.defineProperty(env, "callback", {
|
||||
get: function () {
|
||||
teardown.awaitingCallback = true;
|
||||
|
||||
return function () {
|
||||
teardown.awaitingCallback = false;
|
||||
maybeFinish();
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
teardown.tests.teardown.apply(env, teardown.topics);
|
||||
}
|
||||
|
||||
function maybeFinish() {
|
||||
var pending = batch.teardowns.filter(function (teardown) {
|
||||
return teardown.awaitingCallback;
|
||||
});
|
||||
|
||||
if (pending.length === 0) {
|
||||
finish();
|
||||
}
|
||||
}
|
||||
|
||||
function finish() {
|
||||
batch.status = 'end';
|
||||
batch.suite.report(['end']);
|
||||
batch.promise.emit('end', batch.honored, batch.broken, batch.errored, batch.pending);
|
||||
}
|
||||
}
|
||||
};
|
Reference in New Issue
Block a user