Skip to content

Commit c65f4aa

Browse files
committed
Auto-discover new WPT as they are added
1 parent 213a256 commit c65f4aa

File tree

5 files changed

+372
-300
lines changed

5 files changed

+372
-300
lines changed

build/wpt_test.bzl

+85-16
Original file line numberDiff line numberDiff line change
@@ -9,34 +9,88 @@
99

1010
load("//:build/wd_test.bzl", "wd_test")
1111

12-
def wpt_test(name, wpt_directory, test_js):
13-
test_gen_rule = "{}@_wpt_test_gen".format(name)
14-
_wpt_test_gen(
15-
name = test_gen_rule,
12+
def wpt_test(name, wpt_directory, test_config):
13+
js_test_gen_rule = "{}@_wpt_js_test_gen".format(name)
14+
_wpt_js_test_gen(
15+
name = js_test_gen_rule,
1616
test_name = name,
1717
wpt_directory = wpt_directory,
18-
test_js = test_js,
18+
test_config = test_config,
19+
)
20+
21+
wd_test_gen_rule = "{}@_wpt_wd_test_gen".format(name)
22+
_wpt_wd_test_gen(
23+
name = wd_test_gen_rule,
24+
test_name = name,
25+
wpt_directory = wpt_directory,
26+
test_config = test_config,
27+
test_js_generated = js_test_gen_rule,
1928
)
2029

2130
wd_test(
2231
name = "{}".format(name),
23-
src = test_gen_rule,
32+
src = wd_test_gen_rule,
2433
args = ["--experimental"],
2534
data = [
2635
"//src/wpt:wpt-test-harness",
27-
test_js,
36+
test_config,
37+
js_test_gen_rule,
2838
wpt_directory,
2939
"//src/workerd/io:trimmed-supported-compatibility-date.txt",
3040
],
3141
)
3242

33-
def _wpt_test_gen_impl(ctx):
43+
def _wpt_js_test_gen_impl(ctx):
44+
src = ctx.actions.declare_file("{}-test.generated.js".format(ctx.attr.test_name))
45+
ctx.actions.write(
46+
output = src,
47+
content = WPT_JS_TEST_TEMPLATE.format(
48+
test_config = ctx.file.test_config.basename,
49+
cases = generate_external_cases(ctx.attr.wpt_directory.files),
50+
),
51+
)
52+
53+
return DefaultInfo(
54+
files = depset([src]),
55+
)
56+
57+
def generate_external_cases(files):
58+
result = []
59+
60+
for file in files.to_list():
61+
if file.extension == "js":
62+
entry = """export const {} = run(config, '{}');""".format(test_case_name(file.basename), file.basename)
63+
else:
64+
continue
65+
result.append(entry)
66+
67+
return "\n".join(result)
68+
69+
def test_case_name(filename):
70+
words = (filename
71+
.removesuffix(".js")
72+
.removesuffix(".any")
73+
.replace(".", "-")
74+
.split("-"))
75+
76+
return words[0] + "".join([word.capitalize() for word in words[1:]])
77+
78+
WPT_JS_TEST_TEMPLATE = """// This file is autogenerated by wpt_test.bzl
79+
// DO NOT EDIT.
80+
import {{ run }} from 'wpt:harness';
81+
import config from '{test_config}';
82+
83+
{cases}
84+
"""
85+
86+
def _wpt_wd_test_gen_impl(ctx):
3487
src = ctx.actions.declare_file("{}.wd-test".format(ctx.attr.test_name))
3588
ctx.actions.write(
3689
output = src,
37-
content = WPT_TEST_TEMPLATE.format(
90+
content = WPT_WD_TEST_TEMPLATE.format(
3891
test_name = ctx.attr.test_name,
39-
test_js = wd_relative_path(ctx.file.test_js),
92+
test_config = ctx.file.test_config.basename,
93+
test_js_generated = wd_relative_path(ctx.file.test_js_generated),
4094
modules = generate_external_modules(ctx.attr.wpt_directory.files),
4195
),
4296
)
@@ -45,14 +99,15 @@ def _wpt_test_gen_impl(ctx):
4599
files = depset([src]),
46100
)
47101

48-
WPT_TEST_TEMPLATE = """
102+
WPT_WD_TEST_TEMPLATE = """
49103
using Workerd = import "/workerd/workerd.capnp";
50104
const unitTests :Workerd.Config = (
51105
services = [
52106
( name = "{test_name}",
53107
worker = (
54108
modules = [
55-
(name = "worker", esModule = embed "{test_js}"),
109+
(name = "worker", esModule = embed "{test_js_generated}"),
110+
(name = "{test_config}", esModule = embed "{test_config}"),
56111
(name = "wpt:harness", esModule = embed "../../../../../workerd/src/wpt/harness.js"),
57112
{modules}
58113
],
@@ -102,14 +157,28 @@ def generate_external_modules(files):
102157

103158
return ",\n".join(result)
104159

105-
_wpt_test_gen = rule(
106-
implementation = _wpt_test_gen_impl,
160+
_wpt_wd_test_gen = rule(
161+
implementation = _wpt_wd_test_gen_impl,
162+
attrs = {
163+
# A string to use as the test name. Used in the wd-test filename and the worker's name
164+
"test_name": attr.string(),
165+
# A file group representing a directory of wpt tests. All files in the group will be embedded.
166+
"wpt_directory": attr.label(),
167+
# A JS file containing the test configuration.
168+
"test_config": attr.label(allow_single_file = True),
169+
# An auto-generated JS file containing the test logic.
170+
"test_js_generated": attr.label(allow_single_file = True),
171+
},
172+
)
173+
174+
_wpt_js_test_gen = rule(
175+
implementation = _wpt_js_test_gen_impl,
107176
attrs = {
108177
# A string to use as the test name. Used in the wd-test filename and the worker's name
109178
"test_name": attr.string(),
110179
# A file group representing a directory of wpt tests. All files in the group will be embedded.
111180
"wpt_directory": attr.label(),
112-
# A JS file containing the actual test logic.
113-
"test_js": attr.label(allow_single_file = True),
181+
# A JS file containing the test configuration.
182+
"test_config": attr.label(allow_single_file = True),
114183
},
115184
)

src/workerd/api/wpt/BUILD.bazel

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,6 @@ load("//:build/wpt_test.bzl", "wpt_test")
66

77
[wpt_test(
88
name = file.replace("-test.js", ""),
9-
test_js = file,
9+
test_config = file,
1010
wpt_directory = "@wpt//:{}".format(file.replace("-test.js", "")),
1111
) for file in glob(["*-test.js"])]

0 commit comments

Comments
 (0)