jasmine-istanbul-reporter
Version:
Jasmine report plugin that scrapes test pages for istanbul coverage stats and writes them to a set of files for eventual conversion to LCOV, Cobertura, etc.
315 lines (308 loc) • 16 kB
JavaScript
var sinon = require('sinon');
var assert = require('assert');
var path = require('path');
var utilities = require('./utilities');
var JasmineReporterIstanbul = require('../index.js');
var subject;
var browser = require('../lib/browser');
var fileSystem = require('../lib/file-system');
var uuid = require('uuid');
var expectedObject = {
expectedFunction: function expectedFunction() {
}
};
describe('jasmine-istanbul-reporter', function () {
describe('#constructor', function () {
describe('when called with no options', function () {
it('rejects it with an appropriate message (selenium web driver is required)', function (done) {
try {
new JasmineReporterIstanbul()
}
catch (error) {
assert.notEqual(error, undefined);
assert.equal(error.name, 'ArgumentError');
done();
}
});
});
describe('when called with invalid options', function () {
describe('when called with a list of functions that is not an array', function () {
it('rejects them with an appropriate message', function (done) {
try {
new JasmineReporterIstanbul({functionBindingList: null})
}
catch (error) {
assert.notEqual(error, undefined);
assert.equal(error.name, 'ArgumentError');
done();
}
});
});
describe('when called with a list of functions that is an array, but is not filled with function bindings', function () {
it('rejects them with an appropriate message', function (done) {
try {
new JasmineReporterIstanbul({functionBindingList: [undefined]})
}
catch (error) {
assert.notEqual(error, undefined);
assert.equal(error.name, 'ArgumentError');
done();
}
});
});
describe('when called with base output directory that is not a string', function () {
it('rejects it with an appropriate message', function (done) {
try {
new JasmineReporterIstanbul({outputPath: null})
}
catch (error) {
assert.notEqual(error, undefined);
assert.equal(error.name, 'ArgumentError');
done();
}
});
});
describe('when with a null or missing driver (it\'s required', function () {
it('rejects it with an appropriate message', function (done) {
try {
new JasmineReporterIstanbul({driver: null})
}
catch (error) {
assert.notEqual(error, undefined);
assert.equal(error.name, 'ArgumentError');
done();
}
});
});
});
describe('when called with valid options', function () {
beforeEach(function (done) {
sinon.spy(expectedObject, 'expectedFunction');
sinon.stub(browser, 'setDriver');
subject = new JasmineReporterIstanbul({
outputPath: '.',
functionBindingList: [{"expectedFunction": expectedObject}],
driver: {}
});
done();
});
it('sets the driver for its underlying browser abstraction', function (done) {
sinon.assert.calledWith(browser.setDriver, {});
done();
});
it('wraps the provided function bindings with its own preserveCoverage function', function (done) {
assert.equal(expectedObject.expectedFunction, subject.preserveCoverage);
done();
});
describe('#preserveCoverage', function () {
describe('when called via its wrapped method name', function () {
describe('with any number of arguments', function () {
describe('and no underlying script failures', function () {
beforeEach(function (done) {
sinon.stub(browser, 'executeScript', function (script, callback) {
return callback(null, {coverageDummy: 'whonko'});
});
expectedObject.expectedFunction('some arg 1', 'some arg 2');
done();
});
it('makes a request to grab the coverage object from the page', function (done) {
sinon.assert.calledWith(browser.executeScript, 'return __coverage__;');
done();
});
it('calls the original, expected function with those arguments', function (done) {
sinon.assert.calledWithMatch(expectedObject.expectedFunction.originalFunction, 'some arg 1', 'some arg 2');
done();
});
it('makes a request to store the coverage object back on the page, using the original coverage object', function (done) {
var coverageString = JSON.stringify({coverageDummy: 'whonko'});
var coverageSetString = '__coverage__ = JSON.parse(\'' + coverageString + '\');';
sinon.assert.calledWith(browser.executeScript, coverageSetString);
done();
});
afterEach(function (done) {
browser.executeScript.restore();
done();
})
});
describe('and a script failure while getting coverage object', function () {
beforeEach(function (done) {
sinon.stub(browser, 'executeScript');
browser.executeScript.onFirstCall().callsArgWith(1, "whonko");
done();
});
it('fails with an appropriate error', function (done) {
try {
expectedObject.expectedFunction('some arg 1', 'some arg 2');
}
catch (error) {
assert.notEqual(error, undefined);
assert.equal(error, 'whonko');
done();
}
});
afterEach(function (done) {
browser.executeScript.restore();
done();
});
});
describe('and a script failure while setting coverage object', function () {
beforeEach(function (done) {
var stub = sinon.stub(browser, 'executeScript');
stub.onFirstCall().callsArgWith(1, null, {coverageDummy: 'whonko'});
stub.onSecondCall().callsArgWith(1, "whinko");
done();
});
it('calls the original, expected function with those arguments', function (done) {
try {
expectedObject.expectedFunction('some arg 1', 'some arg 2');
}
catch (error) {
assert.notEqual(error, undefined);
assert.equal(error, 'whinko');
done();
}
});
afterEach(function (done) {
browser.executeScript.restore();
done();
});
});
});
});
});
describe('#specDone', function () {
beforeEach(function (done) {
sinon.stub(console, 'info');
done();
});
describe('whether or not coverage is available or not', function () {
beforeEach(function (done) {
sinon.stub(browser, 'executeScript');
subject.specDone({jasmineResult: "success"});
done();
});
it('logs a somewhat appropriate message stating that it has started', function (done) {
sinon.assert.calledWithMatch(console.info, /^attempting.*?coverage.*?/i);
done();
});
it('makes a call to gather coverage from the test', function (done) {
sinon.assert.calledWith(browser.executeScript, 'return __coverage__;');
done();
});
afterEach(function (done) {
browser.executeScript.restore();
done();
});
});
describe('and coverage is available', function () {
describe('and valid', function () {
beforeEach(function (done) {
sinon.stub(browser, 'executeScript', function (script, callback) {
return callback(null, {coverageDummy: 'whonko'});
});
done();
});
describe('and file can be written to disk without error', function () {
beforeEach(function (done) {
sinon.stub(fileSystem, 'writeJsonToFile').callsArgWith(2, null);
sinon.stub(uuid, 'v4').returns('whinko');
subject.specDone({jasmineResult: "success"});
done();
});
it('writes the coverage object to a file path that is a combination of the outputPath and a uuid', function (done) {
sinon.assert.calledWith(fileSystem.writeJsonToFile, {coverageDummy: 'whonko'}, path.join('.', 'whinko.json'));
done();
});
it('logs a success message, which includes the file path', function (done) {
sinon.assert.calledWithMatch(console.info, /^succeeded.*?coverage.*?whinko\.json$/i);
done();
});
afterEach(function (done) {
uuid.v4.restore();
fileSystem.writeJsonToFile.restore();
done();
});
});
describe('and the file fails to write to disk', function () {
beforeEach(function (done) {
sinon.stub(fileSystem, 'writeJsonToFile').callsArgWith(2, "error");
sinon.stub(uuid, 'v4').returns('whenko');
subject.specDone({jasmineResult: "success"});
done();
});
it('logs a failure message, which includes the file path', function (done) {
sinon.assert.calledWithMatch(console.info, /^failed.*?coverage.*?whenko\.json$/i);
done();
});
it('doesn\'t log anything indicating a success', function (done) {
sinon.assert.neverCalledWithMatch(console.info, /^succeeded.*?.coverage/i);
done();
});
afterEach(function (done) {
uuid.v4.restore();
fileSystem.writeJsonToFile.restore();
done();
});
});
afterEach(function (done) {
browser.executeScript.restore();
done();
});
});
describe('and invalid', function () {
beforeEach(function (done) {
sinon.stub(browser, 'executeScript', function (script, callback) {
return callback(null, undefined);
});
subject.specDone({jasmineResult: "success"});
done();
});
it('logs a somewhat appropriate message stating that it failed to gather coverage', function (done) {
sinon.assert.calledWithMatch(console.info, /^failed.*?coverage.*?/i);
done();
});
afterEach(function (done) {
browser.executeScript.restore();
done();
});
});
});
describe('and coverage is not available', function () {
beforeEach(function (done) {
sinon.stub(fileSystem, 'writeJsonToFile').callsArgWith(2, null);
sinon.stub(browser, 'executeScript', function (script, callback) {
return callback("error");
});
done();
});
it('logs a somewhat appropriate message stating that it failed to gather coverage', function (done) {
subject.specDone({jasmineResult: "success"});
sinon.assert.calledWithMatch(console.info, /^failed.*?coverage.*?/i);
done();
});
it('doesn\t try to write the coverage to disk', function (done) {
sinon.assert.notCalled(fileSystem.writeJsonToFile);
done();
});
afterEach(function (done) {
fileSystem.writeJsonToFile.restore();
browser.executeScript.restore();
done();
});
});
afterEach(function (done) {
console.info.restore();
done();
});
});
afterEach(function (done) {
expectedObject = {
expectedFunction: function expectedFunction() {
}
};
browser.setDriver.restore();
done();
});
});
});
});