Add module-contextual 'test' function
Nobody has claimed this yet.
- Dominant language
- JavaScript
- Stars
- 4k
- Forks
- 773
- PR merge metrics
- No merged PRs in 30d
Description
(this is a restatement of https://github.com/jquery/qunit/pull/670#discussion_r26321413 , which itself referenced a discussion from https://github.com/jquery/qunit/pull/670#issuecomment-78513676 )
7be1d6c38cac4370bafdb17b10f0f4dee576bd12 introduced the QUnit.module( name, callback ) signature, which immediately invokes a callback to allow for definition of nested modules. However, doing so requires using global QUnit.module and/or QUnit.test functions: https://jsfiddle.net/k9af94x7/
This is ugly, and bad for the same reasons as use of global assertions like QUnit.equal instead of contextual assertions like assert.equal. We're fixing the assertions issue, and should do the same with module and test by making them accessible from either context or arguments of the module callback, while fulfilling some goals to the maximum possible extent:
- Intuitively-readable invocations, possibly paradigm-dependent (e.g., use of BDD names)
- Maximum similarity between
moduleandtestcallbacks, for future iterative convergence - Separation of concerns (e.g., no properties on
assertthat do not pertain to assertions, since we might want to allow integrating external assertion libraries)
My ideal vision would fully integrate the two functions, allowing code like:
// Note the second parameter
QUnit.test("grandparent", (assert, test) => {
// `test` is destructurable, and contains helpers like beforeEach.
// Those that are functions have signatures analogous to `test` itself.
// Also present is environment, so users never need deal with `this`.
test.beforeEach((assert, test) => { test.environment.ready = true; });
// Any test can contain assertions, even those that would traditionally be modules.
// But only child tests interact with beforeEach/afterEach.
assert.strictEqual(test.environment.ready, undefined);
test("uncle", (assert, { environment }) => {
assert.strictEqual(environment.ready, true);
});
// As noted in https://github.com/jquery/qunit/pull/670#issuecomment-78513676 ,
// a significant current difference between `module` and `test` is their
// (a)synchronicity.
// We can make that explicit (names subject to bikeshedding, but I think
// defaulting to async will make for the smoothest transition.
test.immediate("parent", (assert, test) => {
test("child", (assert, test) => {
assert.strictEqual(test.environment.ready, true)
});
});
});
However, if the above is a bit much, then I suppose we can just add module and test properties to the argument passed to module callbacks:
QUnit.module( "module b", function( hooks ) {
hooks.test( "a basic test example 2", function( assert ) {
assert.ok( true, "this test is fine" );
});
hooks.module( "nested module b.1", function( hooks ) {
hooks.test( "a basic test example 3", function( assert ) {
assert.ok( true, "this test is fine" );
});
});
});
Note that module is already incompatible with test, because arguments passed to their respective callbacks differ (respectively, moduleFns—a.k.a. hooks—vs. assert).
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reading the existing QUnit.module and QUnit.test callback APIs, then review pull request 670 and the linked discussion about contextual assertions. Done means agreeing on a concrete module-contextual API and documenting its intended callback behavior; the issue currently presents multiple possible designs rather than a settled scope.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- javascript
- Domain
- testing-qa
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 20/100