Skip to content

Commit dce6459

Browse files
committed
Spec: Rewrite current proposal into a formal specification
Rewrite the current proposal into a formal specification using normative language. I've converted this file from Markdown to AsciiDoc to enable important navigation and rich-text features that make long-form documents easier to comprehend and link to. Such as an automatic table of contents, section numbering, and "note" blocks for non-normative notes. Added: * Write a new "Terminology" section, with examples to explain how these terms relate to QUnit, Mocha, Jasmine, JUnit and xUnit. * Write down the ordering requirements for events (previously missing). * Write a new "Runner API" section, basically just `on()`. * Write a new "Reporter API" section, basically just `init()`. Changed: * Clarify that Event data is treated as plain objects. Use of private utility classes is allowed, but not required. * Fix type of TestEnd "suite" name to be `string|undefined` since tests under the global suite have undefined as their suite name. Removed: * Remove any sentences about when events emit in relation to execution, so that there is no guruantee or promise of being able to influence or observe test execution by non-standard itself. This is important as otherwise testing frameworks or adapters could not conform to the standard if they use child processes or web workers, or if e.g. a proxy reporter forwards the events over a socket to a server or remote control client where then other reporters can be plugged in. * Remove sentence about deleting `actual` and `expected` properties after emitting TestEnd events "to avoid leaking memory". This was never done in practice and appears to not be an issue in most reporters so long as callbacks just let objects naturally get garbage-collected. * Remove any implied inheritance or other relation between TestStart/TestEnd and SuiteStart/SuiteEnd. This felt confusing because these are not defined as actual classes, and actually were not strictly supersets either because SuiteStart defined a list of TestStart and SuiteStart objects, whereas SuiteEnd is and should be given a list of TestEnd and SuiteEnd objects.
1 parent f9ddcd1 commit dce6459

File tree

7 files changed

+455
-247
lines changed

7 files changed

+455
-247
lines changed

.mailmap

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
Florentin Simion <[email protected]>
2+
Jiahao Guo <[email protected]>
3+
Trent Willis <[email protected]>
4+

README.md

Lines changed: 48 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# js-reporters
22

33
[![Build Status](https://travis-ci.org/js-reporters/js-reporters.svg?branch=master)](https://travis-ci.org/js-reporters/js-reporters)
4+
[![Chat on Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/qunitjs/qunit)
45
[![npm](https://img.shields.io/npm/dm/js-reporters.svg)](https://www.npmjs.com/package/js-reporters)
56
[![npm](https://img.shields.io/npm/v/js-reporters.svg)](https://www.npmjs.com/package/js-reporters)
67
[![npm](https://img.shields.io/npm/l/js-reporters.svg?maxAge=2592000)](https://www.npmjs.com/package/js-reporters)
@@ -11,33 +12,42 @@ The Common Reporter Interface (CRI) for JavaScript Testing Frameworks.
1112
|----------------------------|----------------------------------|
1213
| ![](img/situation-now.png) | ![](img/situation-expected.png) |
1314

15+
## Specification
16+
17+
**See [Common Reporter Interface](spec/cri-draft.adoc) for the latest version of the specification.**
18+
19+
See also:
20+
21+
* [example](docs/example.md), illustrates how reporting works in practice.
22+
* [frameworks](docs/frameworks.md), studies various popular testing frameworks.
23+
* **[Integrations](#integrations)**, a list of real-world implementations.
24+
25+
Help with AsciiDoc (used for the standard document):
26+
27+
* [AsciiDoc Syntax Quick Reference](https://asciidoctor.org/docs/asciidoc-syntax-quick-reference/)
28+
* [AsciiDoc User Manual](https://asciidoctor.org/docs/user-manual/)
29+
* [AsciiDoc cheatsheet](https://powerman.name/doc/asciidoc)
1430

1531
## Background
1632

17-
In 2014, the [QUnit](https://qunitjs.com/) team started [discussing](https://github.com/qunitjs/qunit/issues/531) the possibility of interoperability between JavaScript test frameworks such as QUnit, Mocha, Jasmine, Intern, Buster, etc. The "Common Reporter Interface" would be an allow integrations for output formats and communication bridges to be shared between frameworks. This would also benefit high-level consumers of these frameworks such as Karma, BrowserStack, SauceLabs, Testling, by having a standard machine-readable interface.
33+
In 2014, the [QUnit](https://qunitjs.com/) team started [discussing](https://github.com/qunitjs/qunit/issues/531) the possibility of interoperability between JavaScript testing frameworks such as QUnit, Mocha, Jasmine, Intern, Buster, etc. The "Common Reporter Interface" would be an allow integrations for output formats and communication bridges to be shared between frameworks. This would also benefit high-level consumers of these frameworks such as Karma, BrowserStack, SauceLabs, Testling, by having a standard machine-readable interface.
1834

1935
Our mission is to deliver:
2036

2137
- a common JavaScript API, e.g. based on EventEmitter featuring `.on()` and `.off()`.
2238
- a minimum viable set of events with standardized event names and event data.
2339
- a minimum viable set of concepts behind those events to allow consumers to set expectations (e.g. define what "pass", "fail", "skip", "todo", and "pending" mean).
24-
- work with participating test frameworks to support the Common Reporter Interface.
40+
- work with participating testing frameworks to support the Common Reporter Interface.
2541

2642
Would _you_ be interested in discussing this with us further? Please join in!
2743

28-
https://github.com/js-reporters/js-reporters/issues/
44+
* [Join the Chat room](https://gitter.im/qunitjs/qunit)
45+
* [Browse open issues](https://github.com/js-reporters/js-reporters/issues/)
46+
* [Help frameworks and runners implement the spec](#cross-project-coordination)
2947

30-
## Specification
48+
## js-reporters Package
3149

32-
See [CRI Specification](docs/cri-draft.md).
33-
34-
### Details
35-
36-
For details please check out the [docs](docs/) and especially the [example](docs/example.md) which presents a testsuite and its reporting data based on the standard presented above.
37-
38-
For implementation examples please check [Usage of the adapters](#usage-of-the-adapters) and [Integrations](#integrations).
39-
40-
## Usage
50+
### Usage
4151

4252
Listen to the events and receive the emitted data:
4353

@@ -46,11 +56,11 @@ Listen to the events and receive the emitted data:
4656
const runner = JsReporters.autoRegister();
4757

4858
// Listen to the same events for any testing framework.
49-
runner.on('testEnd', function(test) {
59+
runner.on('testEnd', function (test) {
5060
console.log('Test %s has errors:', test.fullname.join(' '), test.errors);
5161
});
5262

53-
runner.on('runEnd', function(globalSuite) {
63+
runner.on('runEnd', function (globalSuite) {
5464
const testCounts = globalSuite.testCounts;
5565

5666
console.log('Testsuite status: %s', globalSuite.status);
@@ -72,43 +82,41 @@ JsReporters.TapReporter.init(runner);
7282

7383
**autoRegister()**
7484

75-
Auto registers one of the existing adapters by checking for existing testing frameworks in the global scope and returns the runner to attach event listeners. If no framework is found, it will throw an `Error`.
85+
Automatically detects which testing framework you use and attaches any adapters as needed, and returns a compatible runner object. If no framework is found, it will throw an `Error`.
7686

7787
```js
7888
JsReporters.autoRegister();
7989
```
8090

8191
## Integrations
8292

83-
- [browserstack-runner](https://github.com/browserstack/browserstack-runner/blob/master/lib/_patch/reporter.js)
84-
85-
## Differences
86-
87-
This section is dedicated to explain the limitations of the adapters in respect to the standard.
93+
Runners:
8894

89-
The only limitation is the emitting order, which is not done in source order:
95+
* [QUnit](https://qunitjs.com/), natively since [QUnit 2.2](https://github.com/qunitjs/qunit/releases/2.2.0).
96+
* Jasmine, via [js-reporters JasmineAdapter](lib/adapters/JasmineAdapter.js).
97+
* Mocha, via [js-reporters MochaAdapter](lib/adapters/MochaAdapter.js).
9098

91-
- Jasmine: the emitting order of the tests will be the one from Jasmine
92-
- Mocha: the emitting order of the tests will be the one from Mocha
93-
- QUnit: the emitting order is done in suite order, which means if there is a suite that contains tests and other suites, it emits the start of the suite and then emits its tests and only after it emits the other suites, even if the tests were the last in source order
99+
Reporters:
94100

95-
If you want to know more about each testing framework and about their emitting order, please checkout the [frameworks](docs/frameworks.md) document.
101+
* [TAP](lib/reporters/TapReporter), implements the [Test Anything Protocol](https://testanything.org/) for command-line output.
102+
* [browserstack-runner](https://github.com/browserstack/browserstack-runner/blob/0.9.1/lib/_patch/reporter.js), runs JavaScript unit tests remotely in multiple browsers, summarize the results by browser, and fail or pass the continuous integration build accordingly.
103+
* _Add your own, and let us know!_
96104

97-
## Cross-Reference Issues
105+
## Cross-project coordination
98106

99-
### Unit Testing Frameworks
107+
Testing frameworks:
100108

101-
- https://github.com/qunitjs/qunit/issues/531 (original discussion)
102-
- https://github.com/visionmedia/mocha/issues/1326
103-
- https://github.com/pivotal/jasmine/issues/659
104-
- https://github.com/theintern/intern/issues/257
105-
- https://github.com/busterjs/buster/issues/419
106-
- https://github.com/caolan/nodeunit/issues/276
107-
- https://github.com/flatiron/vows/issues/313
109+
* [QUnit issue](https://github.com/qunitjs/qunit/issues/531) (Done!)
110+
* [Mocha issue](https://github.com/visionmedia/mocha/issues/1326) (pending…)
111+
* [Jasmine issue](https://github.com/pivotal/jasmine/issues/659) (pending…)
112+
* [Intern issue](https://github.com/theintern/intern/issues/257) (pending…)
113+
* [Vows issue](https://github.com/flatiron/vows/issues/313) (pending…)
114+
* [Buster issue](https://github.com/busterjs/buster/issues/419) (Discontinued.)
115+
* [Nodeunit issue](https://github.com/caolan/nodeunit/issues/276) (Discontinued.)
108116

109-
### Consuming Services
117+
Reporters and proxy layers:
110118

111-
- https://github.com/browserstack/browserstack-runner/issues/92
112-
- https://github.com/axemclion/grunt-saucelabs/issues/164
113-
- https://github.com/karma-runner/karma/issues/1183
114-
- https://github.com/substack/testling/issues/93
119+
* [BrowserStack](https://github.com/browserstack/browserstack-runner/issues/92) (Done!)
120+
* [Karma](https://github.com/karma-runner/karma/issues/1183) (pending…)
121+
* [grunt-saucelabs](https://github.com/axemclion/grunt-saucelabs/issues/164) (pending…)
122+
* [Testling](https://github.com/substack/testling/issues/93) (pending…)

authors.js

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
const cp = require('child_process');
2+
3+
function getAuthors () {
4+
const orderedAuthors = cp.execFileSync(
5+
'git',
6+
['log', '--format=%aN', '--reverse'],
7+
{ encoding: 'utf-8' }
8+
);
9+
const unique = orderedAuthors
10+
.trim()
11+
.split('\n')
12+
.filter((author, i, arr) => arr.indexOf(author) === i);
13+
14+
unique[unique.length - 1] = 'and ' + unique[unique.length - 1];
15+
16+
return unique.join(', ') + '.';
17+
}
18+
19+
process.stdout.write(getAuthors() + '\n');

lib/Data.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -129,8 +129,8 @@ class SuiteStart {
129129
/**
130130
* @param {String} name
131131
* @param {String[]} fullName
132-
* @param {Test[]} tests
133-
* @param {Suite[]} childSuites
132+
* @param {TestStart[]} tests
133+
* @param {SuiteStart[]} childSuites
134134
*/
135135
constructor (name, fullName, tests, childSuites, testCounts) {
136136
this.name = name;
@@ -145,8 +145,8 @@ class SuiteEnd {
145145
/**
146146
* @param {String} name
147147
* @param {String[]} fullName
148-
* @param {Test[]} tests
149-
* @param {Suite[]} childSuites
148+
* @param {TestEnd[]} tests
149+
* @param {SuiteEnd[]} childSuites
150150
* @param {String} status
151151
* @param {Object} testCounts
152152
* @param {Number} testCounts.passed

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
"Release",
3939
"Reporter",
4040
"Test",
41+
"Spec",
4142
"Docs"
4243
]
4344
}

0 commit comments

Comments
 (0)