diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 09:22:09 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 09:22:09 +0000 |
commit | 43a97878ce14b72f0981164f87f2e35e14151312 (patch) | |
tree | 620249daf56c0258faa40cbdcf9cfba06de2a846 /testing/web-platform/tests/docs/writing-tests/idlharness.md | |
parent | Initial commit. (diff) | |
download | firefox-43a97878ce14b72f0981164f87f2e35e14151312.tar.xz firefox-43a97878ce14b72f0981164f87f2e35e14151312.zip |
Adding upstream version 110.0.1.upstream/110.0.1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'testing/web-platform/tests/docs/writing-tests/idlharness.md')
-rw-r--r-- | testing/web-platform/tests/docs/writing-tests/idlharness.md | 101 |
1 files changed, 101 insertions, 0 deletions
diff --git a/testing/web-platform/tests/docs/writing-tests/idlharness.md b/testing/web-platform/tests/docs/writing-tests/idlharness.md new file mode 100644 index 0000000000..e2abce0a48 --- /dev/null +++ b/testing/web-platform/tests/docs/writing-tests/idlharness.md @@ -0,0 +1,101 @@ +# IDL Tests (idlharness.js) + +## Introduction ## + +`idlharness.js` generates tests for Web IDL fragments, using the +[JavaScript Tests (`testharness.js`)](testharness.md) infrastructure. You typically want to use +`.any.js` or `.window.js` for this to avoid having to write unnessary boilerplate. + +## Adding IDL fragments + +Web IDL is automatically scraped from specifications and added to the `/interfaces/` directory. See +the [README](https://github.com/web-platform-tests/wpt/blob/master/interfaces/README.md) there for +details. + +## Testing IDL fragments + +For example, the Fetch API's IDL is tested in +[`/fetch/api/idlharness.any.js`](https://github.com/web-platform-tests/wpt/blob/master/fetch/api/idlharness.any.js): +```js +// META: global=window,worker +// META: script=/resources/WebIDLParser.js +// META: script=/resources/idlharness.js +// META: timeout=long + +idl_test( + ['fetch'], + ['referrer-policy', 'html', 'dom'], + idl_array => { + idl_array.add_objects({ + Headers: ["new Headers()"], + Request: ["new Request('about:blank')"], + Response: ["new Response()"], + }); + if (self.GLOBAL.isWindow()) { + idl_array.add_objects({ Window: ['window'] }); + } else if (self.GLOBAL.isWorker()) { + idl_array.add_objects({ WorkerGlobalScope: ['self'] }); + } + } +); +``` +Note how it includes `/resources/WebIDLParser.js` and `/resources/idlharness.js` in addition to +`testharness.js` and `testharnessreport.js` (automatically included due to usage of `.any.js`). +These are needed to make the `idl_test` function work. + +The `idl_test` function takes three arguments: + +* _srcs_: a list of specifications whose IDL you want to test. The names here need to match the filenames (excluding the extension) in `/interfaces/`. +* _deps_: a list of specifications the IDL listed in _srcs_ depends upon. Be careful to list them in the order that the dependencies are revealed. +* _setup_func_: a function or async function that takes care of creating the various objects that you want to test. + +## Methods of `IdlArray` ## + +`IdlArray` objects can be obtained through the _setup_func_ argument of `idl_test`. Anything not +documented in this section should be considered an implementation detail, and outside callers should +not use it. + +### `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 +`[LegacyNoInterfaceObject]` 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. |