Reputation: 1
Note, related How to test if jQuery 3.0 beta is Promises/A+ compatible in browser?
For example, at promises-tests one of the tests is found at promises-tests/lib/tests/2.1.2.js
"use strict";
var assert = require("assert");
var testFulfilled = require("./helpers/testThreeCases").testFulfilled;
var adapter = global.adapter;
var deferred = adapter.deferred;
var dummy = { dummy: "dummy" }; // we fulfill or reject with this when we don't intend to test against it
describe("2.1.2.1: When fulfilled, a promise: must not transition to any other state.", function () {
testFulfilled(dummy, function (promise, done) {
var onFulfilledCalled = false;
promise.then(function onFulfilled() {
onFulfilledCalled = true;
}, function onRejected() {
assert.strictEqual(onFulfilledCalled, false);
done();
});
setTimeout(done, 100);
});
specify("trying to fulfill then immediately reject", function (done) {
var d = deferred();
var onFulfilledCalled = false;
d.promise.then(function onFulfilled() {
onFulfilledCalled = true;
}, function onRejected() {
assert.strictEqual(onFulfilledCalled, false);
done();
});
d.resolve(dummy);
d.reject(dummy);
setTimeout(done, 100);
});
specify("trying to fulfill then reject, delayed", function (done) {
var d = deferred();
var onFulfilledCalled = false;
d.promise.then(function onFulfilled() {
onFulfilledCalled = true;
}, function onRejected() {
assert.strictEqual(onFulfilledCalled, false);
done();
});
setTimeout(function () {
d.resolve(dummy);
d.reject(dummy);
}, 50);
setTimeout(done, 100);
});
specify("trying to fulfill immediately then reject delayed", function (done) {
var d = deferred();
var onFulfilledCalled = false;
d.promise.then(function onFulfilled() {
onFulfilledCalled = true;
}, function onRejected() {
assert.strictEqual(onFulfilledCalled, false);
done();
});
d.resolve(dummy);
setTimeout(function () {
d.reject(dummy);
}, 50);
setTimeout(done, 100);
});
});
Requirement:
The ability to run the test in the browser without reliance on node.js
, a server, or installing libraries?
Question:
How can this test be converted to a version using native methods available at browsers, for example Console
methods; that is, substitution of console.assert()
or other native method available at window
for describe()
and specify()
?
Upvotes: 0
Views: 72
Reputation: 21926
I still think this is a terrible idea, but here's a (trivial) example:
var assert = {};
assert.equals = function(expected, value, msg) {
var message = msg || "Test ";
try {
expected == value;
console.log(message, "passed");
catch (e) {
console.log(message, "failed", e);
}
};
Now repeat for >, <, ===,
ranges, exceptions when they're expected, specific exceptions (e.g. TypeError, SyntaxError), typeof
, instanceof
, other types (built-ins, constructed), problematic values like NaN
and null
, etc.
console.assert
There are some problems with console.assert
. First, its non-standard and may not behave identically across platforms. Second, there is, AFAIK, no good way to abstract it: you'd end up doing just as much work as the above solution using console.log
unless you use eval and string arguments:
function assert(str, msg) {
try {
console.assert(eval(str), msg);
catch (e) {
console.log(msg, " failed:", e);
}
}
assert("3 === 4", "Three equals four"); // logs the assertion failure.
Needless to say, I do not recommend this, as manually constructing the strings is error-prone, eval
(even though safe in this case) is a notorious perf killer, and not using eval
means using a parser and bam we're right back to the library bit.
Seriously, as you go down this road you will think of more and more things you want to be in there (see my list above) and you will realize you are writing a library when you could have used one.
Per your question in the comments below, many testing libraries (e.g. mocha, jasmine) use a format like this:
wrapper('name of the thing being tested', function(done) {
innerWrapper('description of the test', function(done) {
assert(someAssertion);
});
innerWrapper('some other test for that function', function(done) {
assert(somethingElse);
someAsyncFunction().then(function(value) {
assert(somethingAboutValue);
done();
});
});
});
The 'wrapper', 'innerWrapper', and 'assert' are added by including the testing library in the code or running the command (for cli) i.e. 'mocha tests.js' instead of 'node tests.js'. The setup may or may not use the inner functions to specify subtests. 'Done' is an argument to the callback that can be used to signal the end of an async test.
QUnit is a little simpler in its API, but not too far off.
Those for the most part are names for the same things: functions that wrap a test condition to make sure that correct messages are logged, or exceptions caught, or async gets a chance to finish. The assert tests the actual condition to be evaluated. The adapter reference means wrapping the jQuery deferred constructor to match the API in the spec.
Upvotes: 1