Skip to content

Commit 53432e5

Browse files
committed
[BREAKING CHANGE] Restore most consumer back-compat with v1
In light of the shift in direction per #133, I'm reverting (most of) cce0e4d so as to allow the next release to more similar to the previous, and to make upgrading easy, allowing most reporters to keep working with very minimal changes (if any). Instead, I'll focus on migrating consumers of js-reporters to use TAP tools directly where available, and to otherwise reduce use of js-reporters to purely the adapting and piping to TapReporter. * Revert `RunStart.testCounts` > `RunStart.counts` (idem RunEnd). * Revert `TestStart.suitName` > `TestStart.parentName` (idem TestEnd). * Revert Test allowing Test as child, restore Suite. This un-fixes #126, which will be declined. Frameworks adapted to TAP by js-reporters will not supported nested tests. Frameworks directly providing TAP 13 can one of several strategies to express relationships in a backwards-compatible manner, e.g. like we do in js-reporters by flattening with '>' symbol, or through indentation or through other manners proposed in TestAnything/testanything.github.io#36. Refer to #133 for questions about how to support TAP.
1 parent 4d81c00 commit 53432e5

12 files changed

+287
-193
lines changed

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ runner.on('testEnd', (test) => {
6161
});
6262

6363
runner.on('runEnd', (run) => {
64-
const counts = run.counts;
64+
const counts = run.testCounts;
6565

6666
console.log('Testsuite status: %s', run.status);
6767
console.log('Total %d tests: %d passed, %d failed, %d skipped',

lib/adapters/JasmineAdapter.js

+17-16
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ module.exports = class JasmineAdapter extends EventEmitter {
1515

1616
this.suiteChildren = {};
1717
this.suiteEnds = [];
18+
this.suiteStarts = {};
1819
this.testStarts = {};
1920
this.testEnds = {};
2021

@@ -55,7 +56,7 @@ module.exports = class JasmineAdapter extends EventEmitter {
5556

5657
return {
5758
name: testStart.name,
58-
parentName: testStart.parentName,
59+
suiteName: testStart.suiteName,
5960
fullName: testStart.fullName.slice(),
6061
status: (result.status === 'pending') ? 'skipped' : result.status,
6162
// TODO: Jasmine 3.4+ has result.duration, use it.
@@ -85,15 +86,18 @@ module.exports = class JasmineAdapter extends EventEmitter {
8586
this.suiteChildren[result.id] = [];
8687

8788
result.children.forEach((child) => {
88-
this.testStarts[child.id] = {
89-
name: child.description,
90-
parentName: name,
91-
fullName: [...fullName, child.description]
92-
};
93-
9489
if (child.id.indexOf('suite') === 0) {
90+
this.suiteStarts[child.id] = {
91+
name: child.description,
92+
fullName: [...fullName, child.description]
93+
};
9594
this.processSuite(child, fullName.slice(), parentIds.slice());
9695
} else {
96+
this.testStarts[child.id] = {
97+
name: child.description,
98+
suiteName: name,
99+
fullName: [...fullName, child.description]
100+
};
97101
// Update flat list of test children
98102
parentIds.forEach((id) => {
99103
this.suiteChildren[id].push(child.id);
@@ -108,13 +112,10 @@ module.exports = class JasmineAdapter extends EventEmitter {
108112
const helperData = helpers.aggregateTests(tests);
109113
return {
110114
name: testStart.name,
111-
parentName: testStart.parentName,
112115
fullName: testStart.fullName,
113116
// Jasmine has result.status, but does not propagate 'todo' or 'skipped'
114117
status: helperData.status,
115-
runtime: result.duration || helperData.runtime,
116-
errors: [],
117-
assertions: []
118+
runtime: result.duration || helperData.runtime
118119
};
119120
}
120121

@@ -131,14 +132,14 @@ module.exports = class JasmineAdapter extends EventEmitter {
131132

132133
this.emit('runStart', {
133134
name: null,
134-
counts: {
135+
testCounts: {
135136
total: total
136137
}
137138
});
138139
}
139140

140141
onSuiteStarted (result) {
141-
this.emit('testStart', this.testStarts[result.id]);
142+
this.emit('suiteStart', this.suiteStarts[result.id]);
142143
}
143144

144145
onSpecStarted (result) {
@@ -152,9 +153,9 @@ module.exports = class JasmineAdapter extends EventEmitter {
152153
}
153154

154155
onSuiteDone (result) {
155-
const suiteEnd = this.createSuiteEnd(this.testStarts[result.id], result);
156+
const suiteEnd = this.createSuiteEnd(this.suiteStarts[result.id], result);
156157
this.suiteEnds.push(suiteEnd);
157-
this.emit('testEnd', suiteEnd);
158+
this.emit('suiteEnd', suiteEnd);
158159
}
159160

160161
onJasmineDone (doneInfo) {
@@ -164,7 +165,7 @@ module.exports = class JasmineAdapter extends EventEmitter {
164165
this.emit('runEnd', {
165166
name: null,
166167
status: helperData.status,
167-
counts: helperData.counts,
168+
testCounts: helperData.testCounts,
168169
runtime: helperData.runtime
169170
});
170171
}

lib/adapters/MochaAdapter.js

+13-17
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@ module.exports = class MochaAdapter extends EventEmitter {
3535
convertToSuiteStart (mochaSuite) {
3636
return {
3737
name: mochaSuite.title,
38-
parentName: (mochaSuite.parent && !mochaSuite.parent.root) ? mochaSuite.parent.title : null,
3938
fullName: this.titlePath(mochaSuite)
4039
};
4140
}
@@ -47,25 +46,22 @@ module.exports = class MochaAdapter extends EventEmitter {
4746

4847
return {
4948
name: mochaSuite.title,
50-
parentName: (mochaSuite.parent && !mochaSuite.parent.root) ? mochaSuite.parent.title : null,
5149
fullName: this.titlePath(mochaSuite),
5250
status: helperData.status,
53-
runtime: helperData.runtime,
54-
errors: [],
55-
assertions: []
51+
runtime: helperData.runtime
5652
};
5753
}
5854

5955
convertTest (mochaTest) {
60-
let parentName;
56+
let suiteName;
6157
let fullName;
6258
if (!mochaTest.parent.root) {
63-
parentName = mochaTest.parent.title;
59+
suiteName = mochaTest.parent.title;
6460
fullName = this.titlePath(mochaTest.parent);
6561
// Add also the test name.
6662
fullName.push(mochaTest.title);
6763
} else {
68-
parentName = null;
64+
suiteName = null;
6965
fullName = [mochaTest.title];
7066
}
7167

@@ -85,7 +81,7 @@ module.exports = class MochaAdapter extends EventEmitter {
8581

8682
return {
8783
name: mochaTest.title,
88-
parentName,
84+
suiteName,
8985
fullName,
9086
status,
9187
runtime,
@@ -96,7 +92,7 @@ module.exports = class MochaAdapter extends EventEmitter {
9692
// It is a "test start".
9793
return {
9894
name: mochaTest.title,
99-
parentName,
95+
suiteName,
10096
fullName
10197
};
10298
}
@@ -130,15 +126,15 @@ module.exports = class MochaAdapter extends EventEmitter {
130126
});
131127
this.emit('runStart', {
132128
name: null,
133-
counts: {
129+
testCounts: {
134130
total: total
135131
}
136132
});
137133
}
138134

139135
onSuite (mochaSuite) {
140136
if (!mochaSuite.root) {
141-
this.emit('testStart', this.convertToSuiteStart(mochaSuite));
137+
this.emit('suiteStart', this.convertToSuiteStart(mochaSuite));
142138
}
143139
}
144140

@@ -175,19 +171,19 @@ module.exports = class MochaAdapter extends EventEmitter {
175171

176172
onSuiteEnd (mochaSuite) {
177173
if (!mochaSuite.root) {
178-
const testEnd = this.convertToSuiteEnd(mochaSuite);
179-
this.emit('testEnd', testEnd);
174+
const suiteEnd = this.convertToSuiteEnd(mochaSuite);
175+
this.emit('suiteEnd', suiteEnd);
180176
this.finalCounts.total++;
181-
this.finalCounts[testEnd.status]++;
182-
this.finalRuntime += testEnd.runtime || 0;
177+
this.finalCounts[suiteEnd.status]++;
178+
this.finalRuntime += suiteEnd.runtime || 0;
183179
}
184180
}
185181

186182
onEnd (details) {
187183
this.emit('runEnd', {
188184
name: null,
189185
status: this.finalCounts.failed > 0 ? 'failed' : 'passed',
190-
counts: this.finalCounts,
186+
testCounts: this.finalCounts,
191187
runtime: this.finalRuntime
192188
});
193189
}

lib/adapters/QUnitAdapter.js

+21-22
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,10 @@ module.exports = class QUnitAdapter extends EventEmitter {
2828
QUnit.done(this.onDone.bind(this));
2929
}
3030

31-
prepTestEnd (parentName, parentNames, details) {
31+
prepTestEnd (suiteName, parentNames, details) {
3232
const testEnd = this.testEnds[details.testId] = {
3333
name: details.name,
34-
parentName: parentName,
34+
suiteName: suiteName,
3535
fullName: [...parentNames, details.name],
3636
// Placeholders, populated by onTestDone() and onLog()
3737
status: null,
@@ -45,22 +45,18 @@ module.exports = class QUnitAdapter extends EventEmitter {
4545
processModule (qunitModule) {
4646
const fullName = qunitModule.name.split(this.delim);
4747
const name = fullName.slice(-1)[0];
48-
const parentName = fullName.length >= 2 ? fullName.slice(-2, -1)[0] : null;
4948

5049
const childTests = qunitModule.tests.map((details) => {
5150
return this.prepTestEnd(name, fullName, details);
5251
});
5352

5453
return {
55-
testEnd: {
54+
suiteEnd: {
5655
name,
57-
parentName,
5856
fullName,
5957
// Placeholders, populated by emitTests()
6058
status: null,
61-
runtime: null,
62-
errors: [],
63-
assertions: []
59+
runtime: null
6460
},
6561
childTests,
6662
childModules: []
@@ -83,7 +79,7 @@ module.exports = class QUnitAdapter extends EventEmitter {
8379
modules = this.QUnit.config.modules;
8480
}
8581

86-
// Prepare all testEnd leafs
82+
// Prepare all suiteEnd leafs
8783
modules = modules.map(this.processModule.bind(this));
8884

8985
// For CRI, each module will be represented as a wrapper test
@@ -94,10 +90,10 @@ module.exports = class QUnitAdapter extends EventEmitter {
9490
// module and add the current module to it as a child, among the test leafs.
9591
const globalModules = [];
9692
modules.forEach((mod) => {
97-
if (mod.testEnd.parentName !== null) {
98-
const parentFullName = mod.testEnd.fullName.slice(0, -1);
93+
if (mod.suiteEnd.fullName.length > 1) {
94+
const parentFullName = mod.suiteEnd.fullName.slice(0, -1);
9995
modules.forEach((otherMod) => {
100-
if (otherMod.testEnd.fullName.join(this.delim) === parentFullName.join(this.delim)) {
96+
if (otherMod.suiteEnd.fullName.join(this.delim) === parentFullName.join(this.delim)) {
10197
otherMod.childModules.push(mod);
10298
}
10399
});
@@ -115,7 +111,10 @@ module.exports = class QUnitAdapter extends EventEmitter {
115111
});
116112

117113
const emitModule = (mod) => {
118-
this.emit('testStart', helpers.createTestStart(mod.testEnd));
114+
this.emit('suiteStart', {
115+
name: mod.suiteEnd.name,
116+
fullName: mod.suiteEnd.fullName.slice()
117+
});
119118

120119
mod.childTests.forEach((testEnd) => {
121120
this.emit('testStart', helpers.createTestStart(testEnd));
@@ -125,18 +124,18 @@ module.exports = class QUnitAdapter extends EventEmitter {
125124

126125
// This is non-recursive and can be because we emit modules in the original
127126
// depth-first execution order. We fill in the status/runtime placeholders
128-
// for the testEnd object of a nested module, and then later a parent module
129-
// follows and sees that child testEnd object by reference and can propagate
127+
// for the suiteEnd object of a nested module, and then later a parent module
128+
// follows and sees that child suiteEnd object by reference and can propagate
130129
// and aggregate the information further.
131130
const helperData = helpers.aggregateTests([
132131
...mod.childTests,
133-
...mod.childModules.map(child => child.testEnd)
132+
...mod.childModules.map(child => child.suiteEnd)
134133
]);
135-
mod.testEnd.status = helperData.status;
136-
mod.testEnd.runtime = helperData.runtime;
134+
mod.suiteEnd.status = helperData.status;
135+
mod.suiteEnd.runtime = helperData.runtime;
137136

138-
this.moduleEnds.push(mod.testEnd);
139-
this.emit('testEnd', mod.testEnd);
137+
this.moduleEnds.push(mod.suiteEnd);
138+
this.emit('suiteEnd', mod.suiteEnd);
140139
};
141140
this.globalModules.forEach(emitModule);
142141
}
@@ -146,7 +145,7 @@ module.exports = class QUnitAdapter extends EventEmitter {
146145

147146
this.emit('runStart', {
148147
name: null,
149-
counts: {
148+
testCounts: {
150149
total: this.totalBegin
151150
}
152151
});
@@ -199,7 +198,7 @@ module.exports = class QUnitAdapter extends EventEmitter {
199198
this.emit('runEnd', {
200199
name: null,
201200
status: helperData.status,
202-
counts: helperData.counts,
201+
testCounts: helperData.testCounts,
203202
runtime: details.runtime || null
204203
});
205204
}

lib/helpers.js

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
function aggregateTests (all) {
2-
const counts = {
2+
const testCounts = {
33
passed: all.filter((test) => test.status === 'passed').length,
44
failed: all.filter((test) => test.status === 'failed').length,
55
skipped: all.filter((test) => test.status === 'skipped').length,
66
todo: all.filter((test) => test.status === 'todo').length,
77
total: all.length
88
};
9-
const status = counts.failed ? 'failed' : 'passed';
9+
const status = testCounts.failed ? 'failed' : 'passed';
1010

1111
let runtime = 0;
1212
all.forEach((test) => {
@@ -15,15 +15,15 @@ function aggregateTests (all) {
1515

1616
return {
1717
status,
18-
counts,
18+
testCounts,
1919
runtime
2020
};
2121
}
2222

2323
function createTestStart (testEnd) {
2424
return {
2525
name: testEnd.name,
26-
parentName: testEnd.parentName,
26+
suiteName: testEnd.suiteName,
2727
fullName: testEnd.fullName.slice()
2828
};
2929
}

0 commit comments

Comments
 (0)