Skip to content

Commit

Permalink
Auto-discover new WPT as they are added
Browse files Browse the repository at this point in the history
  • Loading branch information
npaun committed Jan 13, 2025
1 parent 213a256 commit 0d8f380
Show file tree
Hide file tree
Showing 5 changed files with 372 additions and 300 deletions.
101 changes: 85 additions & 16 deletions build/wpt_test.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -9,34 +9,88 @@

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

def wpt_test(name, wpt_directory, test_js):
test_gen_rule = "{}@_wpt_test_gen".format(name)
_wpt_test_gen(
name = test_gen_rule,
def wpt_test(name, wpt_directory, test_config):
js_test_gen_rule = "{}@_wpt_js_test_gen".format(name)
_wpt_js_test_gen(
name = js_test_gen_rule,
test_name = name,
wpt_directory = wpt_directory,
test_js = test_js,
test_config = test_config,
)

wd_test_gen_rule = "{}@_wpt_wd_test_gen".format(name)
_wpt_wd_test_gen(
name = wd_test_gen_rule,
test_name = name,
wpt_directory = wpt_directory,
test_config = test_config,
test_js_generated = js_test_gen_rule,
)

wd_test(
name = "{}".format(name),
src = test_gen_rule,
src = wd_test_gen_rule,
args = ["--experimental"],
data = [
"//src/wpt:wpt-test-harness",
test_js,
test_config,
js_test_gen_rule,
wpt_directory,
"//src/workerd/io:trimmed-supported-compatibility-date.txt",
],
)

def _wpt_test_gen_impl(ctx):
def _wpt_js_test_gen_impl(ctx):
src = ctx.actions.declare_file("{}-test.generated.js".format(ctx.attr.test_name))
ctx.actions.write(
output = src,
content = WPT_JS_TEST_TEMPLATE.format(
test_config = ctx.file.test_config.basename,
cases = generate_external_cases(ctx.attr.wpt_directory.files),
),
)

return DefaultInfo(
files = depset([src]),
)

def generate_external_cases(files):
result = []

for file in files.to_list():
if file.extension == "js":
entry = """export const {} = run(config, '{}');""".format(test_case_name(file.basename), file.basename)
else:
continue
result.append(entry)

return "\n".join(result)

def test_case_name(filename):
words = (filename
.removesuffix(".js")
.removesuffix(".any")
.replace(".", "-")
.split("-"))

return words[0] + "".join([word.capitalize() for word in words[1:]])

WPT_JS_TEST_TEMPLATE = """// This file is autogenerated by wpt_test.bzl
// DO NOT EDIT.
import {{ run }} from 'wpt:harness';
import config from '{test_config}';
{cases}
"""

def _wpt_wd_test_gen_impl(ctx):
src = ctx.actions.declare_file("{}.wd-test".format(ctx.attr.test_name))
ctx.actions.write(
output = src,
content = WPT_TEST_TEMPLATE.format(
content = WPT_WD_TEST_TEMPLATE.format(
test_name = ctx.attr.test_name,
test_js = wd_relative_path(ctx.file.test_js),
test_config = ctx.file.test_config.basename,
test_js_generated = wd_relative_path(ctx.file.test_js_generated),
modules = generate_external_modules(ctx.attr.wpt_directory.files),
),
)
Expand All @@ -45,14 +99,15 @@ def _wpt_test_gen_impl(ctx):
files = depset([src]),
)

WPT_TEST_TEMPLATE = """
WPT_WD_TEST_TEMPLATE = """
using Workerd = import "/workerd/workerd.capnp";
const unitTests :Workerd.Config = (
services = [
( name = "{test_name}",
worker = (
modules = [
(name = "worker", esModule = embed "{test_js}"),
(name = "worker", esModule = embed "{test_js_generated}"),
(name = "{test_config}", esModule = embed "{test_config}"),
(name = "wpt:harness", esModule = embed "../../../../../workerd/src/wpt/harness.js"),
{modules}
],
Expand Down Expand Up @@ -102,14 +157,28 @@ def generate_external_modules(files):

return ",\n".join(result)

_wpt_test_gen = rule(
implementation = _wpt_test_gen_impl,
_wpt_wd_test_gen = rule(
implementation = _wpt_wd_test_gen_impl,
attrs = {
# A string to use as the test name. Used in the wd-test filename and the worker's name
"test_name": attr.string(),
# A file group representing a directory of wpt tests. All files in the group will be embedded.
"wpt_directory": attr.label(),
# A JS file containing the test configuration.
"test_config": attr.label(allow_single_file = True),
# An auto-generated JS file containing the test logic.
"test_js_generated": attr.label(allow_single_file = True),
},
)

_wpt_js_test_gen = rule(
implementation = _wpt_js_test_gen_impl,
attrs = {
# A string to use as the test name. Used in the wd-test filename and the worker's name
"test_name": attr.string(),
# A file group representing a directory of wpt tests. All files in the group will be embedded.
"wpt_directory": attr.label(),
# A JS file containing the actual test logic.
"test_js": attr.label(allow_single_file = True),
# A JS file containing the test configuration.
"test_config": attr.label(allow_single_file = True),
},
)
2 changes: 1 addition & 1 deletion src/workerd/api/wpt/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,6 @@ load("//:build/wpt_test.bzl", "wpt_test")

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

0 comments on commit 0d8f380

Please sign in to comment.