Skip to content
This repository has been archived by the owner on Sep 21, 2022. It is now read-only.

Commit

Permalink
fix: support handling of several events for the same test in 'stats'
Browse files Browse the repository at this point in the history
  • Loading branch information
eGavr committed Oct 20, 2016
1 parent 4753c86 commit e013bf4
Show file tree
Hide file tree
Showing 3 changed files with 92 additions and 96 deletions.
3 changes: 2 additions & 1 deletion lib/gemini.js
Expand Up @@ -88,7 +88,8 @@ module.exports = class Gemini extends PassthroughEmitter {

const stats = new RunnerStats(runner);

return runner.run(suiteCollection).thenReturn(stats.get());
return runner.run(suiteCollection)
.then(() => stats.get());
});
}

Expand Down
58 changes: 29 additions & 29 deletions lib/stats.js
Expand Up @@ -2,39 +2,39 @@

const _ = require('lodash');

const Events = require('./constants/events');
const RunnerEvents = require('./constants/events');

/**
* @constructor
* @param {Runner} [runner]
*/
module.exports = function(runner) {
const data = {};
module.exports = class Stats {
constructor(runner) {
this._tests = {};

const add = (key) => {
data[key] = data[key] || 0;
data[key]++;
};

if (runner) {
runner
.on(Events.BEGIN_STATE, _.partial(add, 'total'))
.on(Events.SKIP_STATE, () => {
add('total');
add('skipped');
})
.on(Events.WARNING, _.partial(add, 'warned'))
.on(Events.ERROR, _.partial(add, 'errored'))

.on(Events.UPDATE_RESULT, (res) => {
add(res && res.updated ? 'updated' : 'passed');
})
.on(Events.TEST_RESULT, (res) => {
add(res && res.equal ? 'passed' : 'failed');
});
.on(RunnerEvents.SKIP_STATE, (test) => this._add('skipped', test))
.on(RunnerEvents.WARNING, (test) => this._add('warned', test))
.on(RunnerEvents.ERROR, (test) => this._add('errored', test))
.on(RunnerEvents.UPDATE_RESULT, (test) => this._add(test.updated ? 'updated' : 'passed', test))
.on(RunnerEvents.TEST_RESULT, (test) => this._add(test.equal ? 'passed' : 'failed', test));
}

_add(type, test) {
this._tests[type] = this._tests[type] || [];

this._tests = _.mapValues(this._tests, (fullNames) => _.without(fullNames, test.state.fullName));

this._tests[type].push(test.state.fullName);
}

this.add = add;
get(type) {
const stats = this._getStats();

return type === undefined ? stats : stats[type];
}

this.get = (name) => name === undefined ? data : data[name];
_getStats() {
return _(this._tests)
.mapValues((tests) => tests.length)
.thru((stats) => _.extend(stats, {total: _(stats).values().sum()}))
.omitBy((count) => !count)
.value();
}
};
127 changes: 61 additions & 66 deletions test/unit/stats.js
@@ -1,100 +1,95 @@
'use strict';

const EventEmitter = require('events').EventEmitter;
const inherit = require('inherit');
const RunnerEvents = require('../../lib/constants/events');
const Stats = require('../../lib/stats');

const Stats = require('lib/stats');
const Events = require('lib/constants/events');

describe('stats', () => {
describe('Stats', () => {
let stats;
let runner;

const stubTest = (opts) => {
opts = opts || {};

return {
state: {fullName: opts.name || 'default-name'},
updated: opts.updated,
equal: opts.equal
};
};

beforeEach(() => {
stats = new Stats();
runner = new EventEmitter();
stats = new Stats(runner);
});

it('should return \'undefined\' before adding keys', () => {
assert.isUndefined(stats.get('counter'));
});
it('should count skipped tests', () => {
runner.emit(RunnerEvents.SKIP_STATE, stubTest());

it('should allow to add new key', () => {
stats.add('counter');
assert.equal(stats.get('counter'), 1);
assert.equal(stats.get('skipped'), 1);
});

it('should increment existing keys', () => {
stats.add('counter');
stats.add('counter');
assert.equal(stats.get('counter'), 2);
});
it('should count warned tests', () => {
runner.emit(RunnerEvents.WARNING, stubTest());

it('should return all full stat', () => {
stats.add('counter');
stats.add('counter');
stats.add('counter');
stats.add('counter2');
stats.add('counter3');
stats.add('counter3');
assert.deepEqual(stats.get(), {
counter: 3,
counter2: 1,
counter3: 2
});
assert.equal(stats.get('warned'), 1);
});
});

describe('stats listener', () => {
let stats;
let Runner = inherit(EventEmitter, {});
let runner;
it('should count errored tests', () => {
runner.emit(RunnerEvents.ERROR, stubTest());

beforeEach(() => {
runner = new Runner();
stats = new Stats(runner);
assert.equal(stats.get('errored'), 1);
});

it('should return undefined before triggering any events', () => {
assert.isUndefined(stats.get('total'));
});
it('should count updated tests', () => {
runner.emit(RunnerEvents.UPDATE_RESULT, stubTest({updated: true}));

it('should count on beginState event', () => {
runner.emit(Events.BEGIN_STATE);
assert.equal(stats.get('total'), 1);
assert.equal(stats.get('updated'), 1);
});

it('should count on skipState event', () => {
runner.emit(Events.SKIP_STATE);
assert.equal(stats.get('total'), 1);
assert.equal(stats.get('skipped'), 1);
});
it('should count passed tests on "UPDATE_RESULT" event', () => {
runner.emit(RunnerEvents.UPDATE_RESULT, stubTest({updated: false}));

it('should count on warning event', () => {
runner.emit(Events.WARNING);
assert.equal(stats.get('warned'), 1);
assert.equal(stats.get('passed'), 1);
});

it('should count on error event', () => {
runner.emit(Events.ERROR);
assert.equal(stats.get('errored'), 1);
});
it('should count failed tests on "TEST_RESULT" event', () => {
runner.emit(RunnerEvents.TEST_RESULT, stubTest({equal: false}));

it('should count on updated images', () => {
runner.emit(Events.UPDATE_RESULT, {updated: true});
assert.equal(stats.get('updated'), 1);
assert.equal(stats.get('failed'), 1);
});

it('should count on passed images', () => {
runner.emit(Events.UPDATE_RESULT, {updated: false});
it('should count passed tests on "TEST_RESULT" event', () => {
runner.emit(RunnerEvents.TEST_RESULT, stubTest({equal: true}));

assert.equal(stats.get('passed'), 1);
});

it('should count test passed', () => {
runner.emit(Events.TEST_RESULT, {equal: true});
assert.equal(stats.get('passed'), 1);
it('should count total test count', () => {
runner.emit(RunnerEvents.TEST_RESULT, stubTest({equal: false, name: 'first'}));
runner.emit(RunnerEvents.TEST_RESULT, stubTest({equal: true, name: 'second'}));

assert.equal(stats.get('total'), 2);
});

it('should count test failed', () => {
runner.emit(Events.TEST_RESULT, {equal: false});
assert.equal(stats.get('failed'), 1);
it('should get full stat', () => {
runner.emit(RunnerEvents.ERROR, stubTest({name: 'first'}));
runner.emit(RunnerEvents.TEST_RESULT, stubTest({equal: true, name: 'second'}));

assert.deepEqual(stats.get(), {
total: 2,
errored: 1,
passed: 1
});
});

it('should handle cases when several events were emitted for the same test', () => {
runner.emit(RunnerEvents.SKIP_STATE, stubTest({name: 'some-state'}));
runner.emit(RunnerEvents.ERROR, stubTest({name: 'some-state'}));

assert.deepEqual(stats.get(), {
total: 1,
errored: 1
});
});
});

0 comments on commit e013bf4

Please sign in to comment.