Skip to content

Commit

Permalink
Use more real-world examples (web-platform-tests#196)
Browse files Browse the repository at this point in the history
* Use more real-world examples

Just assert_true(true) is not so helpful in understanding how one is supposed to use this API.

Also document step_func_done.

* Change timeout back to 2000

* Say something about timeouts needing to be long
  • Loading branch information
zcorpan authored and jgraham committed May 24, 2016
1 parent 73f526d commit 203ba1c
Showing 1 changed file with 60 additions and 23 deletions.
83 changes: 60 additions & 23 deletions docs/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,17 +37,21 @@ are complete", below.

## Synchronous Tests ##

To create a synchronous test use the test() function:
To create a synchronous test use the `test()` function:

```js
test(test_function, name, properties)
```

`test_function` is a function that contains the code to test. For example a
trivial passing test would be:
trivial test for the DOM
[`hasFeature()`](https://dom.spec.whatwg.org/#dom-domimplementation-hasfeature)
method (which is defined to always return true) would be:

```js
test(function() {assert_true(true)}, "assert_true with true")
test(function() {
assert_true(document.implementation.hasFeature());
}, "hasFeature() with no arguments")
```

The function passed in is run in the `test()` call.
Expand All @@ -63,38 +67,48 @@ a test may depend on one or more events or other callbacks. The API provided
for testing these features is intended to be rather low-level but hopefully
applicable to many situations.

To create a test, one starts by getting a Test object using async_test:
To create a test, one starts by getting a `Test` object using `async_test`:

```js
async_test(name, properties)
```

e.g.
var t = async_test("Simple async test")

```js
var t = async_test("DOMContentLoaded")
```

Assertions can be added to the test by calling the step method of the test
object with a function containing the test assertions:

```js
t.step(function() {assert_true(true)});
document.addEventListener("DOMContentLoaded", function() {
t.step(function() {
assert_true(e.bubbles, "bubbles should be true");
});
});
```

When all the steps are complete, the done() method must be called:
When all the steps are complete, the `done()` method must be called:

```js
t.done();
```

As a convenience, async_test can also takes a function as first argument.
As a convenience, `async_test` can also takes a function as first argument.
This function is called with the test object as both its `this` object and
first argument. The above example can be rewritten as:

```js
async_test(function(t) {
object.some_event = function() {
t.step(function (){assert_true(true); t.done();});
};
}, "Simple async test");
document.addEventListener("DOMContentLoaded", function() {
t.step(function() {
assert_true(e.bubbles, "bubbles should be true");
});
t.done();
});
}, "DOMContentLoaded");
```

which avoids cluttering the global scope with references to async
Expand All @@ -103,18 +117,31 @@ tests instances.
The properties argument is identical to that for `test()`.

In many cases it is convenient to run a step in response to an event or a
callback. A convenient method of doing this is through the step_func method
callback. A convenient method of doing this is through the `step_func` method
which returns a function that, when called runs a test step. For example

```js
object.some_event = t.step_func(function(e) {assert_true(e.a)});
document.addEventListener("DOMContentLoaded", t.step_func(function() {
assert_true(e.bubbles, "bubbles should be true");
t.done();
});
```
As a further convenience, the `step_func` that calls `done()` can instead
use `step_func_done`, as follows:
```js
document.addEventListener("DOMContentLoaded", t.step_func_done(function() {
assert_true(e.bubbles, "bubbles should be true");
});
```
For asynchronous callbacks that should never execute, `unreached_func` can
be used. For example:
```js
object.some_event = t.unreached_func("some_event should not fire");
document.documentElement.addEventListener("DOMContentLoaded",
t.unreached_func("DOMContentLoaded should not be fired on the document element"));
```
Keep in mind that other tests could start executing before an Asynchronous
Expand Down Expand Up @@ -276,11 +303,13 @@ function on the test object. All registered callbacks will be run as soon as
the test result is known. For example
```js
test(function() {
window.some_global = "example";
this.add_cleanup(function() {delete window.some_global});
assert_true(false);
});
test(function() {
var element = document.createElement("div");
element.setAttribute("id", "null");
document.body.appendChild(element);
this.add_cleanup(function() { document.body.removeChild(element) });
assert_equals(document.getElementById(null), element);
}, "Calling document.getElementById with a null argument.");
```
## Timeouts in Tests ##
Expand All @@ -298,9 +327,14 @@ that only passes if some event is *not* fired). In this case it is
must use the `step_timeout` function:
```js
var t = async_test("Some test that does something after a timeout");

t.step_timeout(function() {assert_true(true); this.done()}, 2000);
async_test(function(t) {
var gotEvent = false;
document.addEventListener("DOMContentLoaded", t.step_func(function() {
assert_false(gotEvent, "Unexpected DOMContentLoaded event");
gotEvent = true;
t.step_timeout(function() { t.done(); }, 2000);
});
}, "Only one DOMContentLoaded");
```
The difference between `setTimeout` and `step_timeout` is that the
Expand All @@ -309,6 +343,9 @@ delay; e.g., in the above case a timeout multiplier of 2 would cause a
pause of 4000ms before calling the callback. This makes it less likely
to produce unstable results in slow configurations.
Note that timeouts generally need to be a few seconds long in order to
produce stable results in all test environments.
For single-page tests, `step_timeout` is also available as a global
function.
Expand Down

0 comments on commit 203ba1c

Please sign in to comment.