Skip to content

Commit a50cb89

Browse files
authored
wpt: run reference-named files which are themselves tests (#836)
Match the upstream WPT manifest's classification: use its reference-name regex, and only exclude reference-named files whose content has neither a match/mismatch <link> nor testharness.js (RFC #15 makes such files reftests in their own right). Add a --list dry-run flag.
1 parent 15ec2be commit a50cb89

1 file changed

Lines changed: 42 additions & 5 deletions

File tree

‎wpt/runner/src/main.rs‎

Lines changed: 42 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -181,13 +181,42 @@ fn has_suffix_with_test_extension(path_str: &str, suffix: &str) -> bool {
181181
.any(|ext| path_str.ends_with(&format!("{suffix}.{ext}")))
182182
}
183183

184+
/// Matches file stems which the upstream WPT manifest classifies as reference files:
185+
/// `foo-ref`, `foo-notref`, `foo-ref2`, `foo_ref-a`, `ref-foo`, ...
186+
static REFERENCE_NAME_RE: LazyLock<Regex> =
187+
LazyLock::new(|| Regex::new(r"(^|[\-_])(not)?ref[0-9]*([\-_]|$)").unwrap());
188+
189+
/// Reference-named files are still tests in the upstream WPT manifest if their content makes them
190+
/// a reftest (`<link rel=match|mismatch>`, see RFC #15) or a testharness test.
191+
static REFERENCE_IS_TEST_RE: LazyLock<Regex> = LazyLock::new(|| {
192+
Regex::new(
193+
r#"<(?:[A-Za-z_][\w.\-]*:)?link\s[^>]*rel\s*=\s*['"]?(match|mismatch)['"]?[^>]*>|/resources/testharness\.js"#,
194+
)
195+
.unwrap()
196+
});
197+
198+
/// Is the path a reference file (by upstream WPT naming rules) which is *not* also a test?
199+
fn is_non_test_reference(p: &Path) -> bool {
200+
let stem = p
201+
.file_stem()
202+
.map(|s| s.to_string_lossy())
203+
.unwrap_or_default();
204+
let is_ref_name = path_contains_directory(p, "reference") || REFERENCE_NAME_RE.is_match(&stem);
205+
if !is_ref_name {
206+
return false;
207+
}
208+
// Only reference-named files are sniffed, so the extra read is limited to a
209+
// small fraction of the tree.
210+
match fs::read_to_string(p) {
211+
Ok(contents) => !REFERENCE_IS_TEST_RE.is_match(&contents),
212+
Err(_) => true,
213+
}
214+
}
215+
184216
fn filter_path(p: &Path) -> bool {
185217
// let is_tentative = path_buf.ends_with("tentative.html");
186218
let path_str = p.to_string_lossy();
187-
let is_ref = has_suffix_with_test_extension(&path_str, "-ref")
188-
|| path_contains_directory(p, "reference");
189-
// Negative references for mismatch reftests
190-
let is_notref = has_suffix_with_test_extension(&path_str, "-notref");
219+
let is_ref = is_non_test_reference(p);
191220
// Manual tests require human interaction/verification and cannot be run automatically
192221
let is_manual = has_suffix_with_test_extension(&path_str, "-manual");
193222
// `support`, `tools` and `resources` directories contain helper files, not tests
@@ -202,7 +231,7 @@ fn filter_path(p: &Path) -> bool {
202231

203232
let is_dir = p.is_dir();
204233

205-
!(is_ref | is_notref | is_manual | is_support_file | is_blocked | is_dir)
234+
!(is_ref | is_manual | is_support_file | is_blocked | is_dir)
206235
}
207236

208237
fn collect_tests(wpt_dir: &Path) -> Vec<PathBuf> {
@@ -441,6 +470,14 @@ fn main() {
441470
let test_paths = collect_tests(&wpt_dir);
442471
let count = test_paths.len();
443472

473+
// `--list` prints the selected test files (relative to WPT_DIR) without running them
474+
if env::args().any(|arg| arg == "--list") {
475+
for path in &test_paths {
476+
println!("{}", path.strip_prefix(&wpt_dir).unwrap_or(path).display());
477+
}
478+
return;
479+
}
480+
444481
let cargo_dir = Path::new(env!("CARGO_MANIFEST_DIR"));
445482
let out_dir = cargo_dir.parent().unwrap().join("output");
446483
if fs::exists(&out_dir).unwrap() {

0 commit comments

Comments
 (0)