Skip to content

Commit 2638aa0

Browse files
authored
tests: new typescript WPT runner (denoland#9269)
1 parent ecfda65 commit 2638aa0

16 files changed

+1623
-666
lines changed

.dprintrc.json

+3-1
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,9 @@
3131
"std/node_modules",
3232
"std/hash/_wasm",
3333
"target",
34-
"third_party"
34+
"third_party",
35+
"tools/wpt/expectation.json",
36+
"tools/wpt/manifest.json"
3537
],
3638
"plugins": [
3739
"https://plugins.dprint.dev/typescript-0.33.0.wasm",

.github/workflows/ci.yml

+23-1
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ jobs:
9090
- name: Install Python
9191
uses: actions/setup-python@v1
9292
with:
93-
python-version: "2.7"
93+
python-version: "3.8"
9494
architecture: x64
9595

9696
- name: Install Node
@@ -234,6 +234,28 @@ jobs:
234234
cargo test --locked --doc
235235
cargo test --locked --all-targets
236236
237+
- name: Configure hosts file for WPT (unix)
238+
if: runner.os != 'Windows'
239+
run: ./wpt make-hosts-file | sudo tee -a /etc/hosts
240+
working-directory: test_util/wpt/
241+
242+
- name: Configure hosts file for WPT (windows)
243+
if: runner.os == 'Windows'
244+
working-directory: test_util/wpt/
245+
run: python wpt make-hosts-file | Out-File $env:SystemRoot\System32\drivers\etc\hosts -Encoding ascii -Append
246+
247+
- name: Run web platform tests (release)
248+
if: matrix.kind == 'test_release'
249+
run: |
250+
deno run --unstable --allow-write --allow-read --allow-net --allow-env --allow-run ./tools/wpt.ts setup
251+
deno run --unstable --allow-write --allow-read --allow-net --allow-env --allow-run ./tools/wpt.ts run --quiet --release
252+
253+
- name: Run web platform tests (debug)
254+
if: matrix.kind == 'test_debug'
255+
run: |
256+
deno run --unstable --allow-write --allow-read --allow-net --allow-env --allow-run ./tools/wpt.ts setup
257+
deno run --unstable --allow-write --allow-read --allow-net --allow-env --allow-run ./tools/wpt.ts run --quiet
258+
237259
- name: Run Benchmarks
238260
if: matrix.kind == 'bench'
239261
run: cargo bench

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ gclient_config.py_entries
99
/gh-pages/
1010
/target/
1111
/std/hash/_wasm/target
12+
/tools/wpt/manifest.json
1213

1314
# Files that help ensure VSCode can work but we don't want checked into the
1415
# repo

.gitmodules

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,5 @@
88
shallow = true
99
[submodule "test_util/wpt"]
1010
path = test_util/wpt
11-
url = https://github.com/web-platform-tests/wpt.git
11+
url = https://github.com/denoland/wpt.git
1212
shallow = true

cli/tests/WPT.md

-35
This file was deleted.

cli/tests/integration_tests.rs

-246
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,9 @@ use deno_core::url;
66
use deno_runtime::deno_fetch::reqwest;
77
use deno_runtime::deno_websocket::tokio_tungstenite;
88
use std::io::{BufRead, Write};
9-
use std::path::Path;
10-
use std::path::PathBuf;
119
use std::process::Command;
1210
use tempfile::TempDir;
1311
use test_util as util;
14-
use walkdir::WalkDir;
1512

1613
macro_rules! itest(
1714
($name:ident {$( $key:ident: $value:expr,)*}) => {
@@ -5193,249 +5190,6 @@ fn denort_direct_use_error() {
51935190
assert!(!status.success());
51945191
}
51955192

5196-
fn concat_bundle(
5197-
files: Vec<(PathBuf, String)>,
5198-
bundle_path: &Path,
5199-
init: String,
5200-
) -> String {
5201-
let bundle_url = url::Url::from_file_path(bundle_path).unwrap().to_string();
5202-
5203-
let mut bundle = init.clone();
5204-
let mut bundle_line_count = init.lines().count() as u32;
5205-
let mut source_map = sourcemap::SourceMapBuilder::new(Some(&bundle_url));
5206-
5207-
// In classic workers, `importScripts()` performs an actual import.
5208-
// However, we don't implement that function in Deno as we want to enforce
5209-
// the use of ES6 modules.
5210-
// To work around this, we:
5211-
// 1. Define `importScripts()` as a no-op (code below)
5212-
// 2. Capture its parameter from the source code and add it to the list of
5213-
// files to concatenate. (see `web_platform_tests()`)
5214-
bundle.push_str("function importScripts() {}\n");
5215-
bundle_line_count += 1;
5216-
5217-
for (path, text) in files {
5218-
let path = std::fs::canonicalize(path).unwrap();
5219-
let url = url::Url::from_file_path(path).unwrap().to_string();
5220-
let src_id = source_map.add_source(&url);
5221-
source_map.set_source_contents(src_id, Some(&text));
5222-
5223-
for (line_index, line) in text.lines().enumerate() {
5224-
bundle.push_str(line);
5225-
bundle.push('\n');
5226-
source_map.add_raw(
5227-
bundle_line_count,
5228-
0,
5229-
line_index as u32,
5230-
0,
5231-
Some(src_id),
5232-
None,
5233-
);
5234-
5235-
bundle_line_count += 1;
5236-
}
5237-
bundle.push('\n');
5238-
bundle_line_count += 1;
5239-
}
5240-
5241-
let mut source_map_buf: Vec<u8> = vec![];
5242-
source_map
5243-
.into_sourcemap()
5244-
.to_writer(&mut source_map_buf)
5245-
.unwrap();
5246-
5247-
bundle.push_str("//# sourceMappingURL=data:application/json;base64,");
5248-
let encoded_map = base64::encode(source_map_buf);
5249-
bundle.push_str(&encoded_map);
5250-
5251-
bundle
5252-
}
5253-
5254-
// TODO(lucacasonato): DRY with tsc_config.rs
5255-
/// Convert a jsonc libraries `JsonValue` to a serde `Value`.
5256-
fn jsonc_to_serde(j: jsonc_parser::JsonValue) -> serde_json::Value {
5257-
use jsonc_parser::JsonValue;
5258-
use serde_json::Value;
5259-
use std::str::FromStr;
5260-
match j {
5261-
JsonValue::Array(arr) => {
5262-
let vec = arr.into_iter().map(jsonc_to_serde).collect();
5263-
Value::Array(vec)
5264-
}
5265-
JsonValue::Boolean(bool) => Value::Bool(bool),
5266-
JsonValue::Null => Value::Null,
5267-
JsonValue::Number(num) => {
5268-
let number =
5269-
serde_json::Number::from_str(&num).expect("could not parse number");
5270-
Value::Number(number)
5271-
}
5272-
JsonValue::Object(obj) => {
5273-
let mut map = serde_json::map::Map::new();
5274-
for (key, json_value) in obj.into_iter() {
5275-
map.insert(key, jsonc_to_serde(json_value));
5276-
}
5277-
Value::Object(map)
5278-
}
5279-
JsonValue::String(str) => Value::String(str),
5280-
}
5281-
}
5282-
5283-
#[test]
5284-
fn web_platform_tests() {
5285-
use deno_core::serde::Deserialize;
5286-
5287-
#[derive(Deserialize)]
5288-
#[serde(untagged)]
5289-
enum WptConfig {
5290-
Simple(String),
5291-
#[serde(rename_all = "camelCase")]
5292-
Options {
5293-
name: String,
5294-
expect_fail: Vec<String>,
5295-
},
5296-
}
5297-
5298-
let text =
5299-
std::fs::read_to_string(util::tests_path().join("wpt.jsonc")).unwrap();
5300-
let jsonc = jsonc_parser::parse_to_value(&text).unwrap().unwrap();
5301-
let config: std::collections::HashMap<String, Vec<WptConfig>> =
5302-
deno_core::serde_json::from_value(jsonc_to_serde(jsonc)).unwrap();
5303-
5304-
for (suite_name, includes) in config.into_iter() {
5305-
let suite_path = util::wpt_path().join(suite_name);
5306-
let dir = WalkDir::new(&suite_path)
5307-
.into_iter()
5308-
.filter_map(Result::ok)
5309-
.filter(|e| e.file_type().is_file())
5310-
.filter(|f| {
5311-
let filename = f.file_name().to_str().unwrap();
5312-
filename.ends_with(".any.js")
5313-
|| filename.ends_with(".window.js")
5314-
|| filename.ends_with(".worker.js")
5315-
})
5316-
.filter_map(|f| {
5317-
let path = f
5318-
.path()
5319-
.strip_prefix(&suite_path)
5320-
.unwrap()
5321-
.to_str()
5322-
.unwrap();
5323-
for cfg in &includes {
5324-
match cfg {
5325-
WptConfig::Simple(name) if path.starts_with(name) => {
5326-
return Some((f.path().to_owned(), vec![]))
5327-
}
5328-
WptConfig::Options { name, expect_fail }
5329-
if path.starts_with(name) =>
5330-
{
5331-
return Some((f.path().to_owned(), expect_fail.to_vec()))
5332-
}
5333-
_ => {}
5334-
}
5335-
}
5336-
None
5337-
});
5338-
5339-
let testharness_path = util::wpt_path().join("resources/testharness.js");
5340-
let testharness_text = std::fs::read_to_string(&testharness_path)
5341-
.unwrap()
5342-
.replace("output:true", "output:false");
5343-
let testharnessreporter_path =
5344-
util::tests_path().join("wpt_testharnessconsolereporter.js");
5345-
let testharnessreporter_text =
5346-
std::fs::read_to_string(&testharnessreporter_path).unwrap();
5347-
5348-
for (test_file_path, expect_fail) in dir {
5349-
let test_file_text = std::fs::read_to_string(&test_file_path).unwrap();
5350-
let imports: Vec<(PathBuf, String)> = test_file_text
5351-
.split('\n')
5352-
.into_iter()
5353-
.filter_map(|t| {
5354-
// Hack: we don't implement `importScripts()`, and instead capture the
5355-
// parameter in source code; see `concat_bundle()` for more details.
5356-
if let Some(rest_import_scripts) = t.strip_prefix("importScripts(\"")
5357-
{
5358-
if let Some(import_path) = rest_import_scripts.strip_suffix("\");")
5359-
{
5360-
// The code in `testharness.js` silences the test outputs.
5361-
if import_path != "/resources/testharness.js" {
5362-
return Some(import_path);
5363-
}
5364-
}
5365-
}
5366-
t.strip_prefix("// META: script=")
5367-
})
5368-
.map(|s| {
5369-
let s = if s == "/resources/WebIDLParser.js" {
5370-
"/resources/webidl2/lib/webidl2.js"
5371-
} else {
5372-
s
5373-
};
5374-
if s.starts_with('/') {
5375-
util::wpt_path().join(format!(".{}", s))
5376-
} else {
5377-
test_file_path.parent().unwrap().join(s)
5378-
}
5379-
})
5380-
.map(|path| {
5381-
let text = std::fs::read_to_string(&path).unwrap();
5382-
(path, text)
5383-
})
5384-
.collect();
5385-
5386-
let mut variants: Vec<&str> = test_file_text
5387-
.split('\n')
5388-
.into_iter()
5389-
.filter_map(|t| t.strip_prefix("// META: variant="))
5390-
.collect();
5391-
5392-
if variants.is_empty() {
5393-
variants.push("");
5394-
}
5395-
5396-
for variant in variants {
5397-
let mut files = Vec::with_capacity(3 + imports.len());
5398-
files.push((testharness_path.clone(), testharness_text.clone()));
5399-
files.push((
5400-
testharnessreporter_path.clone(),
5401-
testharnessreporter_text.clone(),
5402-
));
5403-
files.extend(imports.clone());
5404-
files.push((test_file_path.clone(), test_file_text.clone()));
5405-
5406-
let mut file = tempfile::Builder::new()
5407-
.prefix("wpt-bundle-")
5408-
.suffix(".js")
5409-
.rand_bytes(5)
5410-
.tempfile()
5411-
.unwrap();
5412-
5413-
let bundle = concat_bundle(files, file.path(), "".to_string());
5414-
file.write_all(bundle.as_bytes()).unwrap();
5415-
5416-
let child = util::deno_cmd()
5417-
.current_dir(test_file_path.parent().unwrap())
5418-
.arg("run")
5419-
.arg("--location")
5420-
.arg(&format!("http://web-platform-tests/?{}", variant))
5421-
.arg("-A")
5422-
.arg(file.path())
5423-
.arg(deno_core::serde_json::to_string(&expect_fail).unwrap())
5424-
.arg("--quiet")
5425-
.stdin(std::process::Stdio::piped())
5426-
.spawn()
5427-
.unwrap();
5428-
5429-
let output = child.wait_with_output().unwrap();
5430-
if !output.status.success() {
5431-
file.keep().unwrap();
5432-
}
5433-
assert!(output.status.success());
5434-
}
5435-
}
5436-
}
5437-
}
5438-
54395193
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
54405194
async fn test_resolve_dns() {
54415195
use std::collections::BTreeMap;

0 commit comments

Comments
 (0)