Skip to content

Implement QUnit callbacks event listener style #422

@JamesMGreene

Description

@JamesMGreene

Open for discussion!

I would like to change the QUnit core logging callbacks (e.g. QUnit.done, etc.) to utilize [theoretical] on, off, and emit methods.

Although we can leave the current callback functions around temporarily for deprecation's sake, the new preferred usage would be as follows (using suggested names):

  • QUnit.begin(fn)
    • QUnit.on('run.start', fn)
  • QUnit.moduleStart(fn)
    • QUnit.on('module.start', fn)
  • QUnit.testStart(fn)
    • QUnit.on('test.start', fn)
  • QUnit.log(fn)
    • QUnit.on('assert', fn)
  • QUnit.testDone(fn)
    • QUnit.on('test.done', fn)
  • QUnit.moduleDone(fn)
    • QUnit.on('module.done', fn)
  • QUnit.done(fn)
    • QUnit.on('run.done', fn)

This change would bring with it all of the usual benefits of an EventEmitter-style setup:

  • on:
    • Listeners can be added — current
    • Listeners for custom events can be added, e.g. for use in QUnit addons — new
  • off:
    • Listeners can be removed — new
  • emit:
    • Listeners can be manually triggered, e.g. for use in QUnit addons — new

One more important functionality I would prefer to add is the equivalent of a stopPropagation method (or flag, or return value) that would allow a listener to prevent subsequently added listeners from being triggered. The use case here would again be primarily for QUnit addons.

For example, in QUnit Composite, I would like to do something like the following:

(function(QUnit) {

// Custom event for QUnit Composite
QUnit.on('suite.start', function(data) {
    // log data about a SUITE starting rather than confusing it with a test starting
});

// Custom event for QUnit Composite
QUnit.on('suite.done', function(data) {
    // log data about a SUITE ending rather than confusing it with a test ending
});

QUnit.on('test.start', function(data) {
    if (executingCompositeSuite) {
        QUnit.emit('suite.start', data);
        // Prevent all subsequently added 'test.start' listeners from being triggered
        return false;  // example of a "stopPropagation" functionality via return value
    }
});

QUnit.on('test.done', function(data) {
    if (executingCompositeSuite) {
        QUnit.emit('suite.done', data);
        // Prevent all subsequently added 'test.done' listeners from being triggered
        return false;  // example of a "stopPropagation" functionality via return value
    }
});

// For illustration only; this code already exists [in better form] in PR #408
var executingCompositeSuite = false;
QUnit.extend(QUnit, {
    testSuites: function(suites) {
        // When the first `test` in this set of `suites` starts (i.e. in `setup`), set:
        // executingCompositeSuite = true;

        // Run tests
        // ...

        // When the last `test` in this set of `suites` ends (i.e. in `teardown`), set:
        // executingCompositeSuite = false;
    }
});

})(QUnit);

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions