Skip to content

Commit d1121bd

Browse files
committed
Test: Convert test suite from Mocha to QUnit
It even found a bug, due to QUnit's deepEqual being stricter it seems. The 'assertions' arrays of TestEnd objects contains Assertion objects, but our test fixture is saying it expects an array of plain objects. This discrepancy was previously tolerated. I've switched the offending assertion to use propEqual() for now, as I don't to touch any actual source code or expected test values in this refactor.
1 parent c12d8cb commit d1121bd

File tree

11 files changed

+163
-239
lines changed

11 files changed

+163
-239
lines changed

package-lock.json

Lines changed: 0 additions & 46 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,11 @@
1414
"scripts": {
1515
"lint": "semistandard",
1616
"test": "npm run lint && npm run test-unit && npm run test-integration",
17-
"test-unit": "mocha --recursive test/unit/",
18-
"test-integration": "mocha test/integration/adapters.js",
19-
"test-versions": "mocha test/versions/versions.js"
17+
"test-unit": "qunit 'test/unit/*.js'",
18+
"test-integration": "qunit test/integration/adapters.js",
19+
"test-versions": "qunit test/versions/versions.js"
2020
},
2121
"devDependencies": {
22-
"chai": "^3.5.0",
2322
"chalk": "^1.1.3",
2423
"commitplease": "3.1.0",
2524
"jasmine": "2.5.1",
@@ -28,8 +27,7 @@
2827
"qunitjs": "1.23.1",
2928
"semistandard": "14.2.3",
3029
"semver": "^7.3.2",
31-
"sinon": "^1.17.4",
32-
"sinon-chai": "^2.8.0"
30+
"sinon": "^1.17.4"
3331
},
3432
"commitplease": {
3533
"nohook": true,
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.

test/integration/adapters-run.js

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
const path = require('path');
22
const JsReporters = require('../../');
33

4-
const testDir = path.join(__dirname, '../fixtures');
4+
const testDir = path.join(__dirname, '../fixtures/integration');
55

66
function rerequire (file) {
77
const resolved = require.resolve(file);
@@ -19,7 +19,7 @@ module.exports = {
1919
const jasmine = new Jasmine();
2020

2121
jasmine.loadConfig({
22-
spec_dir: 'test/fixtures',
22+
spec_dir: 'test/fixtures/integration',
2323
spec_files: ['jasmine.js']
2424
});
2525

@@ -43,7 +43,8 @@ module.exports = {
4343
QUnit.load();
4444
},
4545
QUnit: function (attachListeners) {
46-
const QUnit = require('qunit');
46+
// Get a reporter context independent of the integration test suite itself
47+
const QUnit = rerequire('qunit');
4748
global.QUnit = QUnit;
4849
QUnit.config.autorun = false;
4950

test/integration/adapters.js

Lines changed: 60 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
/* eslint-env mocha */
1+
/* eslint-env qunit */
22
/* eslint-disable no-unused-expressions */
33

4-
const expect = require('chai').expect;
4+
const { test } = QUnit;
55
const refData = require('./reference-data.js');
66
const runAdapters = require('./adapters-run.js');
77

@@ -150,21 +150,10 @@ function getTestCountsEnd (refSuite) {
150150
total: refSuite.tests.length
151151
};
152152

153-
testCounts.passed += refSuite.tests.filter(function (test) {
154-
return test.status === 'passed';
155-
}).length;
156-
157-
testCounts.failed += refSuite.tests.filter(function (test) {
158-
return test.status === 'failed';
159-
}).length;
160-
161-
testCounts.skipped += refSuite.tests.filter(function (test) {
162-
return test.status === 'skipped';
163-
}).length;
164-
165-
testCounts.todo += refSuite.tests.filter(function (test) {
166-
return test.status === 'todo';
167-
}).length;
153+
testCounts.passed += refSuite.tests.filter(test => test.status === 'passed').length;
154+
testCounts.failed += refSuite.tests.filter(test => test.status === 'failed').length;
155+
testCounts.skipped += refSuite.tests.filter(test => test.status === 'skipped').length;
156+
testCounts.todo += refSuite.tests.filter(test => test.status === 'todo').length;
168157

169158
refSuite.childSuites.forEach(function (childSuite) {
170159
const childTestCounts = getTestCountsEnd(childSuite);
@@ -179,106 +168,89 @@ function getTestCountsEnd (refSuite) {
179168
return testCounts;
180169
}
181170

182-
describe('Adapters integration', function () {
171+
QUnit.module('Adapters integration', function () {
183172
Object.keys(runAdapters).forEach(function (adapter) {
184-
describe(adapter + ' adapter', function () {
173+
QUnit.module(adapter + ' adapter', hooks => {
185174
const keys = ['passed', 'actual', 'expected', 'message', 'stack', 'todo'];
186175

187-
before(function (done) {
176+
hooks.before(assert => {
177+
const done = assert.async();
188178
collectedData = [];
189179
runAdapters[adapter](_attachListeners.bind(null, done));
190180
});
191181

192-
it('tests runtime should be a number', function () {
193-
collectedData.forEach(function (value) {
182+
test('Event "testEnd" runtime property', assert => {
183+
collectedData.forEach(value => {
194184
if (value[0] === 'testEnd' && value[1].status !== 'skipped') {
195-
expect(value[1].runtime).to.be.a('number');
185+
assert.equal(typeof value[1].runtime, 'number');
196186
}
197187
});
198188
});
199189

200-
it('testing tests errors prop', function () {
201-
const refTestsEnd = refData.filter(function (value) {
202-
return value[0] === 'testEnd';
203-
});
190+
test('Event "testEnd" errors property', assert => {
191+
const refTestsEnd = refData.filter(value => value[0] === 'testEnd');
192+
const testsEnd = collectedData.filter(value => value[0] === 'testEnd');
204193

205-
const testsEnd = collectedData.filter(function (value) {
206-
return value[0] === 'testEnd';
207-
});
208-
209-
refTestsEnd.forEach(function (value, index) {
194+
refTestsEnd.forEach((value, index) => {
210195
const refTest = value[1];
211196
const test = testsEnd[index][1];
212197

213198
if (refTest.status === 'passed' || refTest.status === 'skipped') {
214-
expect(test.errors).to.be.deep.equal(refTest.errors);
199+
assert.deepEqual(test.errors, refTest.errors);
215200
} else {
216-
expect(test.errors).to.have.lengthOf(refTest.errors.length);
201+
assert.equal(test.errors.length, refTest.errors.length);
217202

218-
test.errors.forEach(function (error) {
219-
expect(error).to.have.all.keys(keys);
203+
test.errors.forEach(error => {
204+
assert.deepEqual(Object.keys(error), keys);
220205

221-
expect(error.passed).to.be.false;
222-
expect(error.message).to.be.a('string');
223-
expect(error.stack).to.be.a('string');
206+
assert.false(error.passed);
207+
assert.strictEqual(typeof error.message, 'string');
208+
assert.strictEqual(typeof error.stack, 'string');
224209
});
225210
}
226211
});
227212
});
228213

229-
it('testing tests assertions prop', function () {
230-
const refTestsEnd = refData.filter(function (value) {
231-
return value[0] === 'testEnd';
232-
});
214+
test('Event "testEnd" assertions property', assert => {
215+
const refTestsEnd = refData.filter(value => value[0] === 'testEnd');
216+
const testsEnd = collectedData.filter(value => value[0] === 'testEnd');
233217

234-
const testsEnd = collectedData.filter(function (value) {
235-
return value[0] === 'testEnd';
236-
});
237-
238-
refTestsEnd.forEach(function (value, index) {
218+
refTestsEnd.forEach((value, index) => {
239219
const refTest = value[1];
240220
const test = testsEnd[index][1];
241221

242222
// Expect to contain the correct number of assertions, only for
243223
// test frameworks that provide all assertions.
244224
if (adapter !== 'Mocha') {
245-
expect(test.assertions).to.have.lengthOf(refTest.assertions.length);
225+
assert.strictEqual(test.assertions.length, refTest.assertions.length);
246226
}
247227

248-
const passedAssertions = test.assertions.filter(function (assertion) {
249-
return assertion.passed;
250-
});
251-
252-
const failedAssertions = test.assertions.filter(function (assertion) {
253-
return !assertion.passed;
254-
});
228+
const passedAssertions = test.assertions.filter(assertion => assertion.passed);
229+
const failedAssertions = test.assertions.filter(assertion => !assertion.passed);
255230

256-
passedAssertions.forEach(function (assertion) {
257-
expect(assertion).to.have.all.keys(keys);
231+
passedAssertions.forEach(assertion => {
232+
assert.deepEqual(Object.keys(assertion), keys);
258233

259-
expect(assertion.passed).to.be.true;
260-
expect(assertion.message).to.be.a('string');
261-
expect(assertion.stack).to.be.undefined;
234+
assert.true(assertion.passed);
235+
assert.strictEqual(typeof assertion.message, 'string');
236+
assert.strictEqual(assertion.stack, undefined);
262237
});
263238

264-
failedAssertions.forEach(function (assertion) {
265-
expect(assertion).to.have.all.keys(keys);
239+
failedAssertions.forEach(assertion => {
240+
assert.deepEqual(Object.keys(assertion), keys);
266241

267-
expect(assertion.passed).to.be.false;
268-
expect(assertion.message).to.be.a('string');
269-
expect(assertion.stack).to.be.a('string');
242+
assert.false(assertion.passed);
243+
assert.strictEqual(typeof assertion.message, 'string');
244+
assert.strictEqual(typeof assertion.stack, 'string');
270245
});
271246
});
272247
});
273248

274-
refData.forEach(function (value, index) {
275-
const testDescription = value[2];
249+
refData.forEach((value, index) => {
250+
const [refEvent, refTestItem, refTestDescription] = value;
276251

277-
it(testDescription, function () {
278-
const refEvent = value[0];
279-
const refTestItem = value[1];
280-
const event = collectedData[index][0];
281-
const testItem = collectedData[index][1];
252+
test(refTestDescription, assert => {
253+
const [event, testItem] = collectedData[index];
282254

283255
// Set tests runtime to 0 to match the reference tests runtime.
284256
if (event === 'testEnd' && testItem.status !== 'skipped') {
@@ -310,33 +282,37 @@ describe('Adapters integration', function () {
310282

311283
// Verify suite self-setting props.
312284
if (event === 'suiteStart' || event === 'runStart') {
313-
expect(testItem.status).to.be.undefined;
314-
expect(testItem.runtime).to.be.undefined;
285+
assert.strictEqual(testItem.status, undefined);
286+
assert.strictEqual(testItem.runtime, undefined);
315287

316-
expect(testItem.testCounts).to.be.deep
317-
.equal(getTestCountsStart(refTestItem));
288+
assert.deepEqual(testItem.testCounts, getTestCountsStart(refTestItem));
318289
}
319290

320291
// Verify suite self-setting props.
321292
if (event === 'suiteEnd' || event === 'runEnd') {
322293
const refStatus = value[3];
323294

324-
expect(testItem.status).to.be.equal(refStatus);
295+
assert.strictEqual(testItem.status, refStatus);
325296

326297
if (testItem.status !== 'skipped') {
327-
expect(testItem.runtime).to.be.a('number');
298+
assert.strictEqual(typeof testItem.runtime, 'number');
328299
// Set suites runtime to 0, to pass the deep equal assertion.
329300
_setSuitesRuntime(testItem);
330301
} else {
331-
expect(testItem.runtime).to.be.undefined;
302+
assert.strictEqual(testItem.runtime, undefined);
332303
}
333304

334-
expect(testItem.testCounts).to.be.deep
335-
.equal(getTestCountsEnd(refTestItem));
305+
assert.deepEqual(testItem.testCounts, getTestCountsEnd(refTestItem));
336306
}
337307

338-
expect(event).equal(refEvent);
339-
expect(testItem).to.be.deep.equal(refTestItem);
308+
assert.strictEqual(event, refEvent);
309+
310+
// FIXME: Ref data has TestEnd#assertions as plain objects instead of Assertion objects.
311+
// > not ok 6 Adapters integration > Jasmine adapter > global test ends
312+
// actual : assertions: [ Assertion { passed: true, … } ]
313+
// expected: assertions: [ { passed: true, … } ]
314+
// assert.deepEqual(testItem, refTestItem);
315+
assert.propEqual(testItem, refTestItem);
340316
});
341317
});
342318
});

0 commit comments

Comments
 (0)