Skip to content

Commit 62cf711

Browse files
committed
Fix multiple issues on wasm32:
* 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
1 parent 92f356e commit 62cf711

File tree

5 files changed

+126
-60
lines changed

5 files changed

+126
-60
lines changed

.github/workflows/main.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,11 @@ jobs:
5959
- uses: dtolnay/rust-toolchain@stable
6060
with:
6161
targets: wasm32-unknown-unknown
62+
- name: Install wasm-pack
63+
run: curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh
6264
- run: cargo build --target wasm32-unknown-unknown
65+
- run: cd url && wasm-pack test --headless --chrome
66+
- run: cd url && wasm-pack test --headless --firefox
6367

6468
Lint:
6569
runs-on: ubuntu-latest

url/Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ serde = { version = "1.0", features = ["derive"] }
2121
serde_json = "1.0"
2222
bencher = "0.1"
2323

24+
[target.'cfg(all(target_arch = "wasm32", target_os = "unknown"))'.dev-dependencies]
25+
wasm-bindgen-test = "0.3"
26+
2427
[dependencies]
2528
form_urlencoded = { version = "1.2.1", path = "../form_urlencoded" }
2629
idna = { version = "0.5.0", path = "../idna" }

url/src/lib.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,9 +152,12 @@ use std::borrow::Borrow;
152152
use std::cmp;
153153
use std::fmt::{self, Write};
154154
use std::hash;
155+
#[cfg(any(unix, windows, target_os = "redox", target_os = "wasi"))]
155156
use std::io;
156157
use std::mem;
157-
use std::net::{IpAddr, SocketAddr, ToSocketAddrs};
158+
use std::net::IpAddr;
159+
#[cfg(any(unix, windows, target_os = "redox", target_os = "wasi"))]
160+
use std::net::{SocketAddr, ToSocketAddrs};
158161
use std::ops::{Range, RangeFrom, RangeTo};
159162
use std::path::{Path, PathBuf};
160163
use std::str;
@@ -1250,6 +1253,7 @@ impl Url {
12501253
/// })
12511254
/// }
12521255
/// ```
1256+
#[cfg(any(unix, windows, target_os = "redox", target_os = "wasi"))]
12531257
pub fn socket_addrs(
12541258
&self,
12551259
default_port_number: impl Fn() -> Option<u16>,

url/tests/unit.rs

Lines changed: 28 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,16 @@
1111
use std::borrow::Cow;
1212
use std::cell::{Cell, RefCell};
1313
use std::net::{Ipv4Addr, Ipv6Addr};
14+
#[cfg(any(unix, windows, target_os = "redox", target_os = "wasi"))]
1415
use std::path::{Path, PathBuf};
1516
use url::{form_urlencoded, Host, Origin, Url};
1617

18+
// https://rustwasm.github.io/wasm-bindgen/wasm-bindgen-test/usage.html
19+
#[cfg(all(target_arch = "wasm32", target_os = "unknown"))]
20+
use wasm_bindgen_test::{wasm_bindgen_test as test, wasm_bindgen_test_configure};
21+
#[cfg(all(target_arch = "wasm32", target_os = "unknown"))]
22+
wasm_bindgen_test_configure!(run_in_browser);
23+
1724
#[test]
1825
fn size() {
1926
use std::mem::size_of;
@@ -117,6 +124,7 @@ fn test_set_empty_query() {
117124
assert_eq!(base.as_str(), "moz://example.com/path");
118125
}
119126

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

132140
#[test]
141+
#[cfg(any(unix, windows))]
133142
fn new_file_paths() {
134143
if cfg!(unix) {
135144
assert_eq!(Url::from_file_path(Path::new("relative")), Err(()));
@@ -161,28 +170,28 @@ fn new_path_bad_utf8() {
161170
}
162171

163172
#[test]
173+
#[cfg(windows)]
164174
fn new_path_windows_fun() {
165-
if cfg!(windows) {
166-
assert_from_file_path!(r"C:\foo\bar", "/C:/foo/bar");
167-
assert_from_file_path!("C:\\foo\\ba\0r", "/C:/foo/ba%00r");
175+
assert_from_file_path!(r"C:\foo\bar", "/C:/foo/bar");
176+
assert_from_file_path!("C:\\foo\\ba\0r", "/C:/foo/ba%00r");
168177

169-
// Invalid UTF-8
170-
assert!(Url::parse("file:///C:/foo/ba%80r")
171-
.unwrap()
172-
.to_file_path()
173-
.is_err());
178+
// Invalid UTF-8
179+
assert!(Url::parse("file:///C:/foo/ba%80r")
180+
.unwrap()
181+
.to_file_path()
182+
.is_err());
174183

175-
// test windows canonicalized path
176-
let path = PathBuf::from(r"\\?\C:\foo\bar");
177-
assert!(Url::from_file_path(path).is_ok());
184+
// test windows canonicalized path
185+
let path = PathBuf::from(r"\\?\C:\foo\bar");
186+
assert!(Url::from_file_path(path).is_ok());
178187

179-
// Percent-encoded drive letter
180-
let url = Url::parse("file:///C%3A/foo/bar").unwrap();
181-
assert_eq!(url.to_file_path(), Ok(PathBuf::from(r"C:\foo\bar")));
182-
}
188+
// Percent-encoded drive letter
189+
let url = Url::parse("file:///C%3A/foo/bar").unwrap();
190+
assert_eq!(url.to_file_path(), Ok(PathBuf::from(r"C:\foo\bar")));
183191
}
184192

185193
#[test]
194+
#[cfg(any(unix, windows))]
186195
fn new_directory_paths() {
187196
if cfg!(unix) {
188197
assert_eq!(Url::from_directory_path(Path::new("relative")), Err(()));
@@ -438,6 +447,7 @@ fn issue_61() {
438447
}
439448

440449
#[test]
450+
#[cfg(any(unix, target_os = "redox", target_os = "wasi"))]
441451
#[cfg(not(windows))]
442452
/// https://github.com/servo/rust-url/issues/197
443453
fn issue_197() {
@@ -622,6 +632,7 @@ fn test_origin_unicode_serialization() {
622632
}
623633

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

@@ -803,11 +814,8 @@ fn test_expose_internals() {
803814
}
804815

805816
#[test]
817+
#[cfg(windows)]
806818
fn test_windows_unc_path() {
807-
if !cfg!(windows) {
808-
return;
809-
}
810-
811819
let url = Url::from_file_path(Path::new(r"\\host\share\path\file.txt")).unwrap();
812820
assert_eq!(url.as_str(), "file://host/share/path/file.txt");
813821

@@ -927,6 +935,7 @@ fn test_url_from_file_path() {
927935
}
928936

929937
/// https://github.com/servo/rust-url/issues/505
938+
#[cfg(any(unix, target_os = "redox", target_os = "wasi"))]
930939
#[cfg(not(windows))]
931940
#[test]
932941
fn test_url_from_file_path() {

url/tests/wpt.rs

Lines changed: 86 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,62 @@
88

99
//! Data-driven tests imported from web-platform-tests
1010
11+
use serde_json::Value;
1112
use std::collections::HashMap;
1213
use std::fmt::Write;
13-
use std::panic;
14-
15-
use serde_json::Value;
14+
#[cfg(all(target_arch = "wasm32", target_os = "unknown"))]
15+
use std::sync::Mutex;
1616
use url::Url;
1717

18+
// https://rustwasm.github.io/wasm-bindgen/wasm-bindgen-test/usage.html
19+
#[cfg(all(target_arch = "wasm32", target_os = "unknown"))]
20+
use wasm_bindgen_test::{console_log, wasm_bindgen_test, wasm_bindgen_test_configure};
21+
#[cfg(all(target_arch = "wasm32", target_os = "unknown"))]
22+
wasm_bindgen_test_configure!(run_in_browser);
23+
24+
// wpt has its own test driver, but we shoe-horn this into wasm_bindgen_test
25+
// which will discard stdout and stderr. So, we make println! go to
26+
// console.log(), so we see failures that do not result in panics.
27+
28+
#[cfg(all(target_arch = "wasm32", target_os = "unknown"))]
29+
static PRINT_BUF: Mutex<Option<String>> = Mutex::new(None);
30+
31+
#[cfg(all(target_arch = "wasm32", target_os = "unknown"))]
32+
macro_rules! print {
33+
($($arg:tt)*) => {
34+
let v = format!($($arg)*);
35+
{
36+
let mut buf = PRINT_BUF.lock().unwrap();
37+
if let Some(buf) = buf.as_mut() {
38+
buf.push_str(&v);
39+
} else {
40+
*buf = Some(v);
41+
}
42+
}
43+
};
44+
}
45+
46+
#[cfg(all(target_arch = "wasm32", target_os = "unknown"))]
47+
macro_rules! println {
48+
() => {
49+
let buf = PRINT_BUF.lock().unwrap().take();
50+
match buf {
51+
Some(buf) => console_log!("{buf}"),
52+
None => console_log!(""),
53+
}
54+
};
55+
($($arg:tt)*) => {
56+
let buf = PRINT_BUF.lock().unwrap().take();
57+
match buf {
58+
Some(buf) => {
59+
let v = format!($($arg)*);
60+
console_log!("{buf}{v}");
61+
},
62+
None => console_log!($($arg)*),
63+
}
64+
}
65+
}
66+
1867
#[derive(Debug, serde::Deserialize)]
1968
struct UrlTest {
2069
input: String,
@@ -71,6 +120,7 @@ struct SetterTestExpected {
71120
hash: Option<String>,
72121
}
73122

123+
#[cfg_attr(all(target_arch = "wasm32", target_os = "unknown"), wasm_bindgen_test)]
74124
fn main() {
75125
let mut filter = None;
76126
let mut args = std::env::args().skip(1);
@@ -228,16 +278,16 @@ fn run_url_test(
228278
) -> Result<(), String> {
229279
let base = match base {
230280
Some(base) => {
231-
let base = panic::catch_unwind(|| Url::parse(&base))
232-
.map_err(|_| "panicked while parsing base".to_string())?
233-
.map_err(|e| format!("errored while parsing base: {}", e))?;
281+
let base =
282+
Url::parse(&base).map_err(|e| format!("errored while parsing base: {}", e))?;
234283
Some(base)
235284
}
236285
None => None,
237286
};
238287

239-
let res = panic::catch_unwind(move || Url::options().base_url(base.as_ref()).parse(&input))
240-
.map_err(|_| "panicked while parsing input".to_string())?
288+
let res = Url::options()
289+
.base_url(base.as_ref())
290+
.parse(&input)
241291
.map_err(|e| format!("errored while parsing input: {}", e));
242292

243293
match result {
@@ -340,38 +390,34 @@ fn run_setter_test(
340390
expected,
341391
}: SetterTest,
342392
) -> Result<(), String> {
343-
let mut url = panic::catch_unwind(|| Url::parse(&href))
344-
.map_err(|_| "panicked while parsing href".to_string())?
345-
.map_err(|e| format!("errored while parsing href: {}", e))?;
346-
347-
let url = panic::catch_unwind(move || {
348-
match kind {
349-
"protocol" => {
350-
url::quirks::set_protocol(&mut url, &new_value).ok();
351-
}
352-
"username" => {
353-
url::quirks::set_username(&mut url, &new_value).ok();
354-
}
355-
"password" => {
356-
url::quirks::set_password(&mut url, &new_value).ok();
357-
}
358-
"host" => {
359-
url::quirks::set_host(&mut url, &new_value).ok();
360-
}
361-
"hostname" => {
362-
url::quirks::set_hostname(&mut url, &new_value).ok();
363-
}
364-
"port" => {
365-
url::quirks::set_port(&mut url, &new_value).ok();
366-
}
367-
"pathname" => url::quirks::set_pathname(&mut url, &new_value),
368-
"search" => url::quirks::set_search(&mut url, &new_value),
369-
"hash" => url::quirks::set_hash(&mut url, &new_value),
370-
_ => panic!("unknown setter kind: {:?}", kind),
371-
};
372-
url
373-
})
374-
.map_err(|_| "panicked while setting value".to_string())?;
393+
let mut url = Url::parse(&href).map_err(|e| format!("errored while parsing href: {}", e))?;
394+
395+
match kind {
396+
"protocol" => {
397+
url::quirks::set_protocol(&mut url, &new_value).ok();
398+
}
399+
"username" => {
400+
url::quirks::set_username(&mut url, &new_value).ok();
401+
}
402+
"password" => {
403+
url::quirks::set_password(&mut url, &new_value).ok();
404+
}
405+
"host" => {
406+
url::quirks::set_host(&mut url, &new_value).ok();
407+
}
408+
"hostname" => {
409+
url::quirks::set_hostname(&mut url, &new_value).ok();
410+
}
411+
"port" => {
412+
url::quirks::set_port(&mut url, &new_value).ok();
413+
}
414+
"pathname" => url::quirks::set_pathname(&mut url, &new_value),
415+
"search" => url::quirks::set_search(&mut url, &new_value),
416+
"hash" => url::quirks::set_hash(&mut url, &new_value),
417+
_ => {
418+
return Err(format!("unknown setter kind: {:?}", kind));
419+
}
420+
}
375421

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

0 commit comments

Comments
 (0)