Skip to content

Commit 861fded

Browse files
committed
Implement a simple synchroneous wast harness;
1 parent 548de7e commit 861fded

File tree

5 files changed

+460
-274
lines changed

5 files changed

+460
-274
lines changed

test/README.md

Lines changed: 47 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,50 @@
1-
This directory contains the WebAssembly test suite. It is split into two directories:
1+
This directory contains the WebAssembly test suite. It is split into two
2+
directories:
23

34
* [`core/`](core/), tests for the core semantics
4-
* [`js-api/`](js-api/), tests for the JavaScript API
5+
* [`js-api/`](js-api/), tests for the JavaScript API. These tests can be run in
6+
a pure JavaScript environment, that is, a JS shell (like v8 or spidermonkey's
7+
shells). A small [harness](js-api/README.md) is needed, but it is very easy
8+
to implement.
9+
* [`html/`](html/), tests for the JavaScript API necessitating a DOM
10+
environment (a full browser).
511

6-
A list of to-do's can be found [here](Todo.md).
12+
A [landing page](out/index.html) contains a condensed version made of all
13+
these tests, converted to HTML.
14+
15+
A list of to-do's can be found [here](Todo.md).
16+
17+
## Multi-stage testing
18+
19+
The wast tests can be converted to JavaScript, and the JavaScript tests
20+
to HTML tests, using the `build.py` script. It will create a `out/` directory
21+
(checked in in this repository, to be able to use it from github pages),
22+
containing subdirectories with expanded tests, as well as a landing page for
23+
runnning all of them in HTML.
24+
25+
The HTML tests are just [Web Platform Tests](http://testthewebforward.org)
26+
using the
27+
[testharness.js](http://testthewebforward.org/docs/testharness-library.html)
28+
library.
29+
30+
Each wast test gets its equivalent JS test, and each JS test (including wast
31+
test) gets its equivalent WPT, to be easily run in browser vendors' automation.
32+
33+
## Procedure for adding a new test
34+
35+
- put the test in the right directory according to the above (top) description.
36+
- ideally, commit here so the actual content commit and build commit are
37+
separated.
38+
- re-run `build.py` so that the landing page is updated and all the cascading
39+
happens.
40+
- re-commit here, if necessary.
41+
42+
## Local HTTP serving of the repository
43+
44+
From the root of your clone of this repository:
45+
46+
```
47+
python -m SimpleHTTPServer 8000
48+
```
49+
50+
Then open your favorite browser and browse to `http://localhost:8000/test/out`.

test/build.py

Lines changed: 35 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -51,47 +51,15 @@ def ensure_clean_initial_state():
5151

5252
# JS harness.
5353
def replace_js_harness(js_file):
54-
"""
55-
Hack: remove the harness lines generated by the spec interpreter, to later
56-
replace them by our own harness.
57-
58-
As an alternative, the spec interpreter could take an option that the
59-
harness needs or needs not be generated, which would be cleaner.
60-
"""
6154
test_func_name = os.path.basename(js_file).replace('.', '_').replace('-', '_')
6255

63-
lines = """(function {}() {{
64-
65-
var $$;""".format(test_func_name).split('\n')
66-
67-
LAST_IGNORED_FUNCTION = 'function assert_return_nan(action) {'
68-
69-
ignoring = True
70-
reached_end = False
71-
72-
# Three states machine:
73-
# - ignoring = True and reached_end = False: ignore the line
74-
# - ignoring = True and reached_end = True: last line to be ignored
75-
# - ignoring = False: include the line
76-
56+
content = ["(function {}() {{".format(test_func_name)]
7757
with open(js_file, 'r') as f:
78-
for l in f.readlines():
79-
l = l.rstrip()
80-
if ignoring:
81-
if reached_end:
82-
if l == '}':
83-
ignoring = False
84-
else:
85-
if l == LAST_IGNORED_FUNCTION:
86-
reached_end = True
87-
else:
88-
lines.append(l)
89-
90-
lines.append('')
91-
lines.append('})();')
58+
content += f.readlines()
59+
content.append('})();')
9260

9361
with open(js_file, 'w') as f:
94-
f.write('\n'.join(lines))
62+
f.write('\n'.join(content))
9563

9664
def convert_wast_to_js():
9765
"""Compile all the wast files to JS and store the results in the JS dir."""
@@ -103,7 +71,7 @@ def convert_wast_to_js():
10371
print('Compiling {} to JS...'.format(wast_file))
10472
js_filename = os.path.basename(wast_file) + '.js'
10573
js_file = os.path.join(OUT_JS_DIR, js_filename)
106-
result = run(WASM_EXEC, wast_file, '-o', js_file)
74+
result = run(WASM_EXEC, wast_file, '-h', '-o', js_file)
10775
if result.returncode != 0:
10876
print('Error when compiling {} to JS: {}', wast_file, result.stdout)
10977

@@ -117,17 +85,27 @@ def build_js():
11785
for js_file in glob.glob(os.path.join(JS_DIR, '*.js')):
11886
shutil.copy(js_file, OUT_JS_DIR)
11987

120-
HTML_HEADER = """
121-
<!doctype html>
122-
<title>WebAssembly Web Platform Test</title>
123-
<link rel=author href=mailto:bbouvier@mozilla.com title=bnjbvr>
124-
<script src={PREFIX}lib/testharness.js></script>
125-
<script src={PREFIX}lib/testharnessreport.js></script>
126-
<script src={PREFIX}lib/index.js></script>
127-
<script src={PREFIX}lib/wasm-constants.js></script>
128-
<script src={PREFIX}lib/wasm-module-builder.js></script>
129-
130-
<div id=log></div>
88+
HTML_HEADER = """<!doctype html>
89+
<html>
90+
<head>
91+
<meta charset="UTF-8">
92+
<title>WebAssembly Web Platform Test</title>
93+
<link rel=author href=mailto:bbouvier@mozilla.com title=bnjbvr>
94+
</head>
95+
<body>
96+
97+
<script src={PREFIX}lib/testharness.js></script>
98+
<script src={PREFIX}lib/testharnessreport.js></script>
99+
<script src={PREFIX}lib/index.js></script>
100+
<script src={PREFIX}lib/wasm-constants.js></script>
101+
<script src={PREFIX}lib/wasm-module-builder.js></script>
102+
103+
<div id=log></div>
104+
"""
105+
106+
HTML_BOTTOM = """
107+
</body>
108+
</html>
131109
"""
132110

133111
def build_html_from_js(src_dir):
@@ -142,22 +120,28 @@ def build_html_from_js(src_dir):
142120
html_file = os.path.join(OUT_HTML_DIR, html_filename)
143121
with open(html_file, 'w+') as f:
144122
content = HTML_HEADER.replace('{PREFIX}', '../../')
145-
content += "<script src=../js/{SCRIPT}></script>".replace('{SCRIPT}', js_filename)
123+
content += " <script src=../js/{SCRIPT}></script>".replace('{SCRIPT}', js_filename)
124+
content += HTML_BOTTOM
146125
f.write(content)
147126
return files
148127

149128
def build_html():
150129
print("Building HTML tests...")
151130

152131
print('Building WPT tests from pure JS tests...')
153-
js_files = build_html_from_js(OUT_JS_DIR) + build_html_from_js(HTML_DIR)
132+
js_files = build_html_from_js(OUT_JS_DIR)
133+
134+
print('Building WPT tests from HTML JS tests...')
135+
js_files += build_html_from_js(HTML_DIR)
154136

155137
print('Building front page containing all the HTML tests...')
156138
front_page = os.path.join(OUT_DIR, 'index.html')
157139
with open(front_page, 'w+') as f:
158140
content = HTML_HEADER.replace('{PREFIX}', '../')
159141
for filename in js_files:
160-
content += "<script src=./js/{SCRIPT}></script>\n".replace('{SCRIPT}', filename)
142+
content += " <script src=./js/{SCRIPT}></script>\n".replace('{SCRIPT}', filename)
143+
content += " <script>reinitializeRegistry();</script>\n"
144+
content += HTML_BOTTOM
161145
f.write(content)
162146

163147
if __name__ == '__main__':

test/js-api/README.md

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,18 @@
1-
This directory contains tests specific to the JavaScript API to WebAssembly, as described in [JS.md](https://github.com/WebAssembly/design/blob/master/JS.md).
1+
This directory contains tests specific to the JavaScript API to WebAssembly, as
2+
described in [JS.md](https://github.com/WebAssembly/design/blob/master/JS.md).
3+
4+
## Harness
5+
6+
These tests can be run in a pure JS environment (JS shell), provided a few
7+
libraries and functions emulating the
8+
[testharness.js](http://testthewebforward.org/docs/testharness-library.html)
9+
library.
10+
11+
- The `../lib/index.js`, `../lib/wasm-constants.js` and
12+
`../lib/wasm-module-builder.js` must be imported first.
13+
- A function `test(function, description)` that tries to run the function under
14+
a try/catch and maybe asserts in case of failure.
15+
- A function `promise_test(function, description)` where `function` returns a
16+
`Promise` run by `promise_test`; a rejection means a failure here.
17+
- Assertion functions: `assert_equals(x, y)`, `assert_true(x)`,
18+
`assert_false(x)`, `assert_unreached()`.

0 commit comments

Comments
 (0)