-
Notifications
You must be signed in to change notification settings - Fork 291
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
POC for basic web platform test integration #2585
base: main
Are you sure you want to change the base?
Changes from all commits
3b2bd0f
bbaa3dc
b474e8c
37c95b4
cb0ca9a
d76d618
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
filegroup( | ||
name = "url", | ||
srcs = glob( | ||
include = ["url/**/*"], | ||
allow_empty = True, | ||
), | ||
visibility = ["//visibility:public"], | ||
) | ||
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
load("//:build/wd_test.bzl", "wd_test") | ||
load("//src/workerd/api/wpt:generate-tests.bzl", "gen_wpt_tests") | ||
|
||
gen_wpt_tests(glob(["**/*.js"])) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Some documentation comments around this would be helpful. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
load("@bazel_skylib//rules:write_file.bzl", "write_file") | ||
load("//:build/wd_test.bzl", "wd_test") | ||
|
||
# 0 - name of the service | ||
# 1 - es module file path (ex: url-test for url-test.js) | ||
# 2 - external modules required for the test suite to succeed | ||
# 3 - current date in YYYY-MM-DD format | ||
WPT_TEST_TEMPLATE = """ | ||
using Workerd = import "/workerd/workerd.capnp"; | ||
|
||
const unitTests :Workerd.Config = ( | ||
services = [ | ||
( name = "{}", | ||
worker = ( | ||
modules = [ | ||
(name = "worker", esModule = embed "{}.js"), | ||
(name = "harness", esModule = embed "../../../../../workerd/src/wpt/harness.js"), | ||
{} | ||
], | ||
bindings = [ | ||
(name = "wpt", service = "wpt"), | ||
], | ||
compatibilityDate = "{}", | ||
compatibilityFlags = ["nodejs_compat_v2", "experimental"], | ||
) | ||
), | ||
( | ||
name = "wpt", | ||
disk = ".", | ||
) | ||
], | ||
);""" | ||
|
||
def _current_date_impl(repository_ctx): | ||
result = repository_ctx.execute(["date", "+%Y-%m-%d"]) | ||
if result.return_code != 0: | ||
fail("Failed to get current date") | ||
|
||
current_date = result.stdout.strip() | ||
|
||
repository_ctx.file("BUILD", "") | ||
repository_ctx.file("date.bzl", "CURRENT_DATE = '%s'" % current_date) | ||
|
||
current_date = repository_rule( | ||
implementation = _current_date_impl, | ||
local = True, | ||
) | ||
|
||
# Example: generate_wd_test_file("url-test") | ||
def generate_wd_test_file(name, modules = ""): | ||
return WPT_TEST_TEMPLATE.format(name, name, modules, current_date()) | ||
|
||
def generate_external_modules(directory): | ||
""" | ||
Generates a string for all files in the given directory in the specified format. | ||
Example for a JS file: | ||
(name = "url-origin.any.js", esModule = embed "../../../../../wpt/url/url-origin.any.js"), | ||
Example for a JSON file: | ||
(name = "resources/urltestdata.json", json = embed "../../../../../wpt/url/resources/urltestdata.json"), | ||
""" | ||
files = native.glob([directory + "/**/*"], allow_empty = True) | ||
result = [] | ||
|
||
for file in files: | ||
file_name = file.split("/")[-1] | ||
file_path = "../" * 5 + file # Creates the "../../../../../" prefix | ||
|
||
if file_name.endswith(".js"): | ||
entry = """(name = {}, esModule = embed "{}"),""".format(file_name, file_path) | ||
elif file_name.endswith(".json"): | ||
entry = """(name = {}, json = embed "{}"),""".format(file_name, file_path) | ||
else: | ||
# For other file types, you can add more conditions or skip them | ||
continue | ||
|
||
result.append(entry) | ||
|
||
return result.join("") | ||
|
||
def gen_wpt_tests(files): | ||
for file in files: | ||
# For url-test.js, it should be url. | ||
# We'll use this to check wpt/ folder and load necessary files. | ||
wpt_directory = file.removesuffix("-test.js") | ||
name = file.removesuffix(".js") | ||
src = "{}.wd-test".format(name) | ||
modules = generate_external_modules("@wpt//:" + wpt_directory) | ||
write_file( | ||
name = name + "@rule", | ||
out = src, | ||
content = [generate_wd_test_file(name, modules)], | ||
) | ||
wd_test( | ||
name = name, | ||
src = src, | ||
args = ["--experimental"], | ||
data = [ | ||
file, | ||
"//src/wpt:wpt-test-harness", | ||
"@wpt//:url", | ||
], | ||
) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
import * as harness from 'harness'; | ||
|
||
export const urlConstructor = { | ||
async test() { | ||
harness.prepare(); | ||
await import('url-constructor.any.js'); | ||
harness.validate(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Side note: Our workerd tests could benefit from having a There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I suppose we could have a pattern like...
Where the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah sounds like a good idea |
||
}, | ||
}; | ||
|
||
export const urlOrigin = { | ||
async test() { | ||
harness.prepare(); | ||
await import('url-origin.any.js'); | ||
harness.validate(); | ||
}, | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
filegroup( | ||
name = "wpt-test-harness", | ||
srcs = glob( | ||
include = ["**/*"], | ||
allow_empty = True, | ||
), | ||
visibility = ["//visibility:public"], | ||
) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
import { strictEqual } from 'node:assert'; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Side note... let's try not to forget adding the copyright headers to these (speaking to myself here mostly) |
||
|
||
globalThis.fetch = async (url) => { | ||
const { default: data } = await import(url); | ||
return { | ||
async json() { | ||
return data; | ||
}, | ||
}; | ||
}; | ||
|
||
globalThis.promise_test = (callback) => { | ||
callback(); | ||
}; | ||
|
||
globalThis.assert_equals = (a, b, c) => { | ||
strictEqual(a, b, c); | ||
}; | ||
|
||
globalThis.test = (callback, message) => { | ||
try { | ||
callback(); | ||
} catch (err) { | ||
globalThis.errors.push(new AggregateError([err], message)); | ||
} | ||
}; | ||
|
||
globalThis.errors = []; | ||
|
||
export function prepare() { | ||
globalThis.errors = []; | ||
} | ||
|
||
export function validate() { | ||
if (globalThis.errors.length > 0) { | ||
for (const err of globalThis.errors) { | ||
console.error(err); | ||
} | ||
throw new Error('Test failed'); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We would need to export filegroups for each of the web platform test groups we want... we don't need to export filegroups for everything since most of the wpts will never be relevant