Skip to content
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

Fix multiple issues on wasm32, and runs url tests in CI #886

Merged
merged 1 commit into from
Apr 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 4 additions & 0 deletions .github/workflows/main.yml
Expand Up @@ -59,7 +59,11 @@ jobs:
- uses: dtolnay/rust-toolchain@stable
with:
targets: wasm32-unknown-unknown
- name: Install wasm-pack
run: curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh
- run: cargo build --target wasm32-unknown-unknown
- run: cd url && wasm-pack test --headless --chrome
- run: cd url && wasm-pack test --headless --firefox

Lint:
runs-on: ubuntu-latest
Expand Down
3 changes: 3 additions & 0 deletions url/Cargo.toml
Expand Up @@ -21,6 +21,9 @@ serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
bencher = "0.1"

[target.'cfg(all(target_arch = "wasm32", target_os = "unknown"))'.dev-dependencies]
wasm-bindgen-test = "0.3"

[dependencies]
form_urlencoded = { version = "1.2.1", path = "../form_urlencoded" }
idna = { version = "0.5.0", path = "../idna" }
Expand Down
6 changes: 5 additions & 1 deletion url/src/lib.rs
Expand Up @@ -154,9 +154,12 @@ use std::borrow::Borrow;
use std::cmp;
use std::fmt::{self, Write};
use std::hash;
#[cfg(any(unix, windows, target_os = "redox", target_os = "wasi"))]
use std::io;
use std::mem;
use std::net::{IpAddr, SocketAddr, ToSocketAddrs};
use std::net::IpAddr;
#[cfg(any(unix, windows, target_os = "redox", target_os = "wasi"))]
use std::net::{SocketAddr, ToSocketAddrs};
use std::ops::{Range, RangeFrom, RangeTo};
use std::path::{Path, PathBuf};
use std::str;
Expand Down Expand Up @@ -1252,6 +1255,7 @@ impl Url {
/// })
/// }
/// ```
#[cfg(any(unix, windows, target_os = "redox", target_os = "wasi"))]
pub fn socket_addrs(
&self,
default_port_number: impl Fn() -> Option<u16>,
Expand Down
47 changes: 28 additions & 19 deletions url/tests/unit.rs
Expand Up @@ -11,9 +11,16 @@
use std::borrow::Cow;
use std::cell::{Cell, RefCell};
use std::net::{Ipv4Addr, Ipv6Addr};
#[cfg(any(unix, windows, target_os = "redox", target_os = "wasi"))]
use std::path::{Path, PathBuf};
use url::{form_urlencoded, Host, Origin, Url};

// https://rustwasm.github.io/wasm-bindgen/wasm-bindgen-test/usage.html
#[cfg(all(target_arch = "wasm32", target_os = "unknown"))]
use wasm_bindgen_test::{wasm_bindgen_test as test, wasm_bindgen_test_configure};
#[cfg(all(target_arch = "wasm32", target_os = "unknown"))]
wasm_bindgen_test_configure!(run_in_browser);

#[test]
fn size() {
use std::mem::size_of;
Expand Down Expand Up @@ -117,6 +124,7 @@ fn test_set_empty_query() {
assert_eq!(base.as_str(), "moz://example.com/path");
}

#[cfg(any(unix, windows, target_os = "redox", target_os = "wasi"))]
macro_rules! assert_from_file_path {
($path: expr) => {
assert_from_file_path!($path, $path)
Expand All @@ -130,6 +138,7 @@ macro_rules! assert_from_file_path {
}

#[test]
#[cfg(any(unix, windows))]
fn new_file_paths() {
if cfg!(unix) {
assert_eq!(Url::from_file_path(Path::new("relative")), Err(()));
Expand Down Expand Up @@ -162,28 +171,28 @@ fn new_path_bad_utf8() {
}

#[test]
#[cfg(windows)]
fn new_path_windows_fun() {
if cfg!(windows) {
assert_from_file_path!(r"C:\foo\bar", "/C:/foo/bar");
assert_from_file_path!("C:\\foo\\ba\0r", "/C:/foo/ba%00r");
assert_from_file_path!(r"C:\foo\bar", "/C:/foo/bar");
assert_from_file_path!("C:\\foo\\ba\0r", "/C:/foo/ba%00r");

// Invalid UTF-8
assert!(Url::parse("file:///C:/foo/ba%80r")
.unwrap()
.to_file_path()
.is_err());
// Invalid UTF-8
assert!(Url::parse("file:///C:/foo/ba%80r")
.unwrap()
.to_file_path()
.is_err());

// test windows canonicalized path
let path = PathBuf::from(r"\\?\C:\foo\bar");
assert!(Url::from_file_path(path).is_ok());
// test windows canonicalized path
let path = PathBuf::from(r"\\?\C:\foo\bar");
assert!(Url::from_file_path(path).is_ok());

// Percent-encoded drive letter
let url = Url::parse("file:///C%3A/foo/bar").unwrap();
assert_eq!(url.to_file_path(), Ok(PathBuf::from(r"C:\foo\bar")));
}
// Percent-encoded drive letter
let url = Url::parse("file:///C%3A/foo/bar").unwrap();
assert_eq!(url.to_file_path(), Ok(PathBuf::from(r"C:\foo\bar")));
}

#[test]
#[cfg(any(unix, windows))]
fn new_directory_paths() {
if cfg!(unix) {
assert_eq!(Url::from_directory_path(Path::new("relative")), Err(()));
Expand Down Expand Up @@ -439,6 +448,7 @@ fn issue_61() {
}

#[test]
#[cfg(any(unix, target_os = "redox", target_os = "wasi"))]
#[cfg(not(windows))]
/// https://github.com/servo/rust-url/issues/197
fn issue_197() {
Expand Down Expand Up @@ -623,6 +633,7 @@ fn test_origin_unicode_serialization() {
}

#[test]
#[cfg(any(unix, windows, target_os = "redox", target_os = "wasi"))]
fn test_socket_addrs() {
use std::net::ToSocketAddrs;

Expand Down Expand Up @@ -804,11 +815,8 @@ fn test_expose_internals() {
}

#[test]
#[cfg(windows)]
fn test_windows_unc_path() {
if !cfg!(windows) {
return;
}

let url = Url::from_file_path(Path::new(r"\\host\share\path\file.txt")).unwrap();
assert_eq!(url.as_str(), "file://host/share/path/file.txt");

Expand Down Expand Up @@ -928,6 +936,7 @@ fn test_url_from_file_path() {
}

/// https://github.com/servo/rust-url/issues/505
#[cfg(any(unix, target_os = "redox", target_os = "wasi"))]
#[cfg(not(windows))]
#[test]
fn test_url_from_file_path() {
Expand Down
126 changes: 86 additions & 40 deletions url/tests/wpt.rs
Expand Up @@ -8,13 +8,62 @@

//! Data-driven tests imported from web-platform-tests

use serde_json::Value;
use std::collections::HashMap;
use std::fmt::Write;
use std::panic;

use serde_json::Value;
#[cfg(all(target_arch = "wasm32", target_os = "unknown"))]
use std::sync::Mutex;
use url::Url;

// https://rustwasm.github.io/wasm-bindgen/wasm-bindgen-test/usage.html
#[cfg(all(target_arch = "wasm32", target_os = "unknown"))]
use wasm_bindgen_test::{console_log, wasm_bindgen_test, wasm_bindgen_test_configure};
#[cfg(all(target_arch = "wasm32", target_os = "unknown"))]
wasm_bindgen_test_configure!(run_in_browser);

// wpt has its own test driver, but we shoe-horn this into wasm_bindgen_test
// which will discard stdout and stderr. So, we make println! go to
// console.log(), so we see failures that do not result in panics.

#[cfg(all(target_arch = "wasm32", target_os = "unknown"))]
static PRINT_BUF: Mutex<Option<String>> = Mutex::new(None);

#[cfg(all(target_arch = "wasm32", target_os = "unknown"))]
macro_rules! print {
($($arg:tt)*) => {
let v = format!($($arg)*);
{
let mut buf = PRINT_BUF.lock().unwrap();
if let Some(buf) = buf.as_mut() {
buf.push_str(&v);
} else {
*buf = Some(v);
}
}
};
}

#[cfg(all(target_arch = "wasm32", target_os = "unknown"))]
macro_rules! println {
() => {
let buf = PRINT_BUF.lock().unwrap().take();
match buf {
Some(buf) => console_log!("{buf}"),
None => console_log!(""),
}
};
($($arg:tt)*) => {
let buf = PRINT_BUF.lock().unwrap().take();
match buf {
Some(buf) => {
let v = format!($($arg)*);
console_log!("{buf}{v}");
},
None => console_log!($($arg)*),
}
}
}

#[derive(Debug, serde::Deserialize)]
struct UrlTest {
input: String,
Expand Down Expand Up @@ -71,6 +120,7 @@ struct SetterTestExpected {
hash: Option<String>,
}

#[cfg_attr(all(target_arch = "wasm32", target_os = "unknown"), wasm_bindgen_test)]
fn main() {
let mut filter = None;
let mut args = std::env::args().skip(1);
Expand Down Expand Up @@ -228,16 +278,16 @@ fn run_url_test(
) -> Result<(), String> {
let base = match base {
Some(base) => {
let base = panic::catch_unwind(|| Url::parse(&base))
.map_err(|_| "panicked while parsing base".to_string())?
.map_err(|e| format!("errored while parsing base: {}", e))?;
let base =
Url::parse(&base).map_err(|e| format!("errored while parsing base: {}", e))?;
Some(base)
}
None => None,
};

let res = panic::catch_unwind(move || Url::options().base_url(base.as_ref()).parse(&input))
.map_err(|_| "panicked while parsing input".to_string())?
let res = Url::options()
.base_url(base.as_ref())
.parse(&input)
.map_err(|e| format!("errored while parsing input: {}", e));

match result {
Expand Down Expand Up @@ -340,38 +390,34 @@ fn run_setter_test(
expected,
}: SetterTest,
) -> Result<(), String> {
let mut url = panic::catch_unwind(|| Url::parse(&href))
.map_err(|_| "panicked while parsing href".to_string())?
.map_err(|e| format!("errored while parsing href: {}", e))?;

let url = panic::catch_unwind(move || {
match kind {
"protocol" => {
url::quirks::set_protocol(&mut url, &new_value).ok();
}
"username" => {
url::quirks::set_username(&mut url, &new_value).ok();
}
"password" => {
url::quirks::set_password(&mut url, &new_value).ok();
}
"host" => {
url::quirks::set_host(&mut url, &new_value).ok();
}
"hostname" => {
url::quirks::set_hostname(&mut url, &new_value).ok();
}
"port" => {
url::quirks::set_port(&mut url, &new_value).ok();
}
"pathname" => url::quirks::set_pathname(&mut url, &new_value),
"search" => url::quirks::set_search(&mut url, &new_value),
"hash" => url::quirks::set_hash(&mut url, &new_value),
_ => panic!("unknown setter kind: {:?}", kind),
};
url
})
.map_err(|_| "panicked while setting value".to_string())?;
let mut url = Url::parse(&href).map_err(|e| format!("errored while parsing href: {}", e))?;

match kind {
"protocol" => {
url::quirks::set_protocol(&mut url, &new_value).ok();
}
"username" => {
url::quirks::set_username(&mut url, &new_value).ok();
}
"password" => {
url::quirks::set_password(&mut url, &new_value).ok();
}
"host" => {
url::quirks::set_host(&mut url, &new_value).ok();
}
"hostname" => {
url::quirks::set_hostname(&mut url, &new_value).ok();
}
"port" => {
url::quirks::set_port(&mut url, &new_value).ok();
}
"pathname" => url::quirks::set_pathname(&mut url, &new_value),
"search" => url::quirks::set_search(&mut url, &new_value),
"hash" => url::quirks::set_hash(&mut url, &new_value),
_ => {
return Err(format!("unknown setter kind: {:?}", kind));
}
}

if let Some(expected_href) = expected.href {
let href = url::quirks::href(&url);
Expand Down