Skip to content

Instantly share code, notes, and snippets.

@lonelyelk
Last active March 2, 2016 22:41
Show Gist options
  • Save lonelyelk/9bdb5b3361c8c003f80f to your computer and use it in GitHub Desktop.
Save lonelyelk/9bdb5b3361c8c003f80f to your computer and use it in GitHub Desktop.
ElkReporter for jasmine when running tests in terminal (e.g. node). Made from jasmine standard ConsoleReporter.
/**
* This is modified version of Jasmine.js ConsoleReporter
*/
module.exports = exports = ElkReporter;
function Timer(options) {
options = options || {};
var now = options.now || (function (Date) { return function () { return new Date().getTime(); }; })(Date),
startTime;
this.start = function() {
startTime = now();
};
this.elapsed = function() {
return now() - startTime;
};
}
function ElkReporter(options) {
var print = options.print,
showColors = options.showColors || false,
timer = options.timer || new Timer(),
jasmineCorePath = options.jasmineCorePath,
specCount,
specTrail = '',
failureCount,
failedSpecs = [],
pendingSpecs = [],
ansi = {
green: '\x1B[32m',
red: '\x1B[31m',
yellow: '\x1B[33m',
none: '\x1B[0m'
},
failedSuites = [],
stackFilter = options.stackFilter || defaultStackFilter;
var onComplete = options.onComplete || function() {};
this.jasmineStarted = function() {
specCount = 0;
failureCount = 0;
print('Started');
printNewline();
timer.start();
};
this.jasmineDone = function() {
printNewline();
printNewline();
if(failedSpecs.length > 0) {
print('Failures:');
}
for (var i = 0; i < failedSpecs.length; i++) {
specFailureDetails(failedSpecs[i], i + 1);
}
if (pendingSpecs.length > 0) {
print("Pending:");
}
for(i = 0; i < pendingSpecs.length; i++) {
pendingSpecDetails(pendingSpecs[i], i + 1);
}
if(specCount > 0) {
printNewline();
var specCounts = specCount + ' ' + plural('spec', specCount) + ', ' +
failureCount + ' ' + plural('failure', failureCount);
if (pendingSpecs.length) {
specCounts += ', ' + pendingSpecs.length + ' pending ' + plural('spec', pendingSpecs.length);
}
print(specCounts);
} else {
print('No specs found');
}
printNewline();
var seconds = timer.elapsed() / 1000;
print('Finished in ' + seconds + ' ' + plural('second', seconds));
printNewline();
for(i = 0; i < failedSuites.length; i++) {
suiteFailureDetails(failedSuites[i]);
}
onComplete(failureCount === 0);
};
this.specDone = function(result) {
specCount++;
if (result.status == 'pending') {
pendingSpecs.push(result);
specTrail += colored('yellow', '*');
}
if (result.status == 'passed') {
specTrail += colored('green', '.');
}
if (result.status == 'failed') {
failureCount++;
failedSpecs.push(result);
specTrail += colored('red', 'X');
}
printElk();
};
this.suiteDone = function(result) {
if (result.failedExpectations && result.failedExpectations.length > 0) {
failureCount++;
failedSuites.push(result);
}
};
return this;
function printNewline() {
print('\n');
}
function colored(color, str) {
return showColors ? (ansi[color] + str + ansi.none) : str;
}
function plural(str, count) {
return count == 1 ? str : str + 's';
}
function repeat(thing, times) {
var arr = [];
for (var i = 0; i < times; i++) {
arr.push(thing);
}
return arr;
}
function indent(str, spaces) {
var lines = (str || '').split('\n');
var newArr = [];
for (var i = 0; i < lines.length; i++) {
newArr.push(repeat(' ', spaces).join('') + lines[i]);
}
return newArr.join('\n');
}
function defaultStackFilter(stack) {
var filteredStack = stack.split('\n').filter(function(stackLine) {
return stackLine.indexOf(jasmineCorePath) === -1;
}).join('\n');
return filteredStack;
}
function specFailureDetails(result, failedSpecNumber) {
printNewline();
print(failedSpecNumber + ') ');
print(result.fullName);
for (var i = 0; i < result.failedExpectations.length; i++) {
var failedExpectation = result.failedExpectations[i];
printNewline();
print(indent('Message:', 2));
printNewline();
print(colored('red', indent(failedExpectation.message, 4)));
printNewline();
print(indent('Stack:', 2));
printNewline();
print(indent(stackFilter(failedExpectation.stack), 4));
}
printNewline();
}
function suiteFailureDetails(result) {
for (var i = 0; i < result.failedExpectations.length; i++) {
printNewline();
print(colored('red', 'An error was thrown in an afterAll'));
printNewline();
print(colored('red', 'AfterAll ' + result.failedExpectations[i].message));
}
printNewline();
}
function pendingSpecDetails(result, pendingSpecNumber) {
printNewline();
printNewline();
print(pendingSpecNumber + ') ');
print(result.fullName);
printNewline();
var pendingReason = "No reason given";
if (result.pendingReason && result.pendingReason !== '') {
pendingReason = result.pendingReason;
}
print(indent(colored('yellow', pendingReason), 2));
printNewline();
}
function printElk() {
if (specCount > 1) {
print('\x1b[5A');
}
if (specCount % 2 === 0) {
print(Array(specCount + 1).join(' ') + ' ^^' + eyes() + '^^\n');
print(Array(specCount + 1).join(' ') + ' _____ U\n');
print(specTrail + '~( _ /\n');
print(Array(specCount + 1).join(' ') + ' || ||\n');
print(Array(specCount + 1).join(' ') + ' ^^ ^^\n');
} else {
print(Array(specCount + 1).join(' ') + ' ^^' + eyes() + '^^\n');
print(Array(specCount + 1).join(' ') + ' _____ U\n');
print(specTrail + '`( _ /\n');
print(Array(specCount + 1).join(' ') + ' // \\\\\n');
print(Array(specCount + 1).join(' ') + ' ^^ ^^\n');
}
}
function eyes() {
if (failureCount > 0) {
return colored('red', 'xx');
} else {
return colored('green', '..');
}
}
}
@lonelyelk
Copy link
Author

Usage:

var Jasmine = require('jasmine'),
    jasmine = new Jasmine(),
    util = require('util'),
    ElkReporter = require('./elk_reporter.js'),
    elkReporter = new ElkReporter({
        print: function() {
            process.stdout.write(util.format.apply(this, arguments));
        },
        showColors: true,
        jasmineCorePath: this.jasmineCorePath
    }),
    done = this.async();

jasmine.loadConfigFile('./spec/support/jasmine.json');
jasmine.addReporter(elkReporter);
jasmine.execute();

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment