mirror of
https://github.com/servo/servo.git
synced 2025-06-24 00:54:32 +01:00
- Update CSS tests to revision e05bfd5e30ed662c2f8a353577003f8eed230180. - Update web-platform-tests to revision a052787dd5c069a340031011196b73affbd68cd9.
128 lines
5.9 KiB
Markdown
128 lines
5.9 KiB
Markdown
## Introduction ##
|
|
|
|
`idlharness.js` automatically generates browser tests for WebIDL interfaces, using
|
|
the testharness.js framework. To use, first include the following:
|
|
|
|
```html
|
|
<script src=/resources/testharness.js></script>
|
|
<script src=/resources/testharnessreport.js></script>
|
|
<script src=/resources/WebIDLParser.js></script>
|
|
<script src=/resources/idlharness.js></script>
|
|
```
|
|
|
|
Then you'll need some type of IDLs. Here's some script that can be run on a
|
|
spec written in HTML, which will grab all the elements with `class="idl"`,
|
|
concatenate them, and replace the body so you can copy-paste:
|
|
|
|
```js
|
|
var s = "";
|
|
[].forEach.call(document.getElementsByClassName("idl"), function(idl) {
|
|
//https://www.w3.org/Bugs/Public/show_bug.cgi?id=14914
|
|
if (!idl.classList.contains("extract"))
|
|
{
|
|
s += idl.textContent + "\n\n";
|
|
}
|
|
});
|
|
document.body.innerHTML = '<pre></pre>';
|
|
document.body.firstChild.textContent = s;
|
|
```
|
|
|
|
Once you have that, put it in your script somehow. The easiest way is to
|
|
embed it literally in an HTML file with `<script type=text/plain>` or similar,
|
|
so that you don't have to do any escaping. Another possibility is to put it
|
|
in a separate .idl file that's fetched via XHR or similar. Sample usage:
|
|
|
|
```js
|
|
var idl_array = new IdlArray();
|
|
idl_array.add_untested_idls("interface Node { readonly attribute DOMString nodeName; };");
|
|
idl_array.add_idls("interface Document : Node { readonly attribute DOMString URL; };");
|
|
idl_array.add_objects({Document: ["document"]});
|
|
idl_array.test();
|
|
```
|
|
|
|
This tests that `window.Document` exists and meets all the requirements of
|
|
WebIDL. It also tests that window.document (the result of evaluating the
|
|
string "document") has URL and nodeName properties that behave as they
|
|
should, and otherwise meets WebIDL's requirements for an object whose
|
|
primary interface is Document. It does not test that window.Node exists,
|
|
which is what you want if the Node interface is already tested in some other
|
|
specification's suite and your specification only extends or refers to it.
|
|
Of course, each IDL string can define many different things, and calls to
|
|
add_objects() can register many different objects for different interfaces:
|
|
this is a very simple example.
|
|
|
|
## Public methods of IdlArray ##
|
|
|
|
IdlArray objects can be obtained with `new IdlArray()`. Anything not
|
|
documented in this section should be considered an implementation detail,
|
|
and outside callers should not use it.
|
|
|
|
### `add_idls(idl_string)`
|
|
Parses `idl_string` (throwing on parse error) and adds the results to the
|
|
IdlArray. All the definitions will be tested when you run test(). If
|
|
some of the definitions refer to other definitions, those must be present
|
|
too. For instance, if `idl_string` says that `Document` inherits from `Node`,
|
|
the `Node` interface must also have been provided in some call to `add_idls()`
|
|
or `add_untested_idls()`.
|
|
|
|
### `add_untested_idls(idl_string)`
|
|
Like `add_idls()`, but the definitions will not be tested. If an untested
|
|
interface is added and then extended with a tested partial interface, the
|
|
members of the partial interface will still be tested. Also, all the
|
|
members will still be tested for objects added with `add_objects()`, because
|
|
you probably want to test that (for instance) window.document has all the
|
|
properties from `Node`, not just `Document`, even if the `Node` interface itself
|
|
is tested in a different test suite.
|
|
|
|
### `add_objects(dict)`
|
|
`dict` should be an object whose keys are the names of interfaces or
|
|
exceptions, and whose values are arrays of strings. When an interface or
|
|
exception is tested, every string registered for it with `add_objects()`
|
|
will be evaluated, and tests will be run on the result to verify that it
|
|
correctly implements that interface or exception. This is the only way to
|
|
test anything about `[NoInterfaceObject]` interfaces, and there are many
|
|
tests that can't be run on any interface without an object to fiddle with.
|
|
|
|
The interface has to be the *primary* interface of all the objects
|
|
provided. For example, don't pass `{Node: ["document"]}`, but rather
|
|
`{Document: ["document"]}`. Assuming the `Document` interface was declared to
|
|
inherit from `Node`, this will automatically test that document implements
|
|
the `Node` interface too.
|
|
|
|
Warning: methods will be called on any provided objects, in a manner that
|
|
WebIDL requires be safe. For instance, if a method has mandatory
|
|
arguments, the test suite will try calling it with too few arguments to
|
|
see if it throws an exception. If an implementation incorrectly runs the
|
|
function instead of throwing, this might have side effects, possibly even
|
|
preventing the test suite from running correctly.
|
|
|
|
### `prevent_multiple_testing(name)`
|
|
This is a niche method for use in case you're testing many objects that
|
|
implement the same interfaces, and don't want to retest the same
|
|
interfaces every single time. For instance, HTML defines many interfaces
|
|
that all inherit from `HTMLElement`, so the HTML test suite has something
|
|
like
|
|
|
|
```js
|
|
.add_objects({
|
|
HTMLHtmlElement: ['document.documentElement'],
|
|
HTMLHeadElement: ['document.head'],
|
|
HTMLBodyElement: ['document.body'],
|
|
...
|
|
})
|
|
```
|
|
|
|
and so on for dozens of element types. This would mean that it would
|
|
retest that each and every one of those elements implements `HTMLElement`,
|
|
`Element`, and `Node`, which would be thousands of basically redundant tests.
|
|
The test suite therefore calls `prevent_multiple_testing("HTMLElement")`.
|
|
This means that once one object has been tested to implement `HTMLElement`
|
|
and its ancestors, no other object will be. Thus in the example code
|
|
above, the harness would test that `document.documentElement` correctly
|
|
implements `HTMLHtmlElement`, `HTMLElement`, `Element`, and `Node`; but
|
|
`document.head` would only be tested for `HTMLHeadElement`, and so on for
|
|
further objects.
|
|
|
|
### `test()`
|
|
Run all tests. This should be called after you've called all other
|
|
methods to add IDLs and objects.
|