Skip to content

Commit

Permalink
Fix multiple issues on wasm32:
Browse files Browse the repository at this point in the history
* remove `Url::socket_addrs` on wasm32-unknown-unknown (it won't work, those
  platform API calls are not supported)

* disable unit tests which won't work on wasm32-unknown-unknown

* run tests in `wasm_bindgen_test` on wasm32-unknown-unknown

* remove `panic::catch_unwind` from wpt tests, as that conflicts with
  wasm-bindgen's panic handler

* run the tests in CI
  • Loading branch information
micolous committed Apr 3, 2024
1 parent a4dd58b commit d924a2c
Show file tree
Hide file tree
Showing 5 changed files with 126 additions and 60 deletions.
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

0 comments on commit d924a2c

Please sign in to comment.