|
|
@@ -33,20 +33,6 @@ fn check_invariants(url: &Url, name: &str, comment: Option<&str>) -> bool {
|
|
|
passed
|
|
|
}
|
|
|
|
|
|
-struct ExpectedAttributes {
|
|
|
- href: String,
|
|
|
- origin: Option<String>,
|
|
|
- protocol: String,
|
|
|
- username: String,
|
|
|
- password: String,
|
|
|
- host: String,
|
|
|
- hostname: String,
|
|
|
- port: String,
|
|
|
- pathname: String,
|
|
|
- search: String,
|
|
|
- hash: String,
|
|
|
-}
|
|
|
-
|
|
|
trait JsonExt {
|
|
|
fn take_key(&mut self, key: &str) -> Option<Value>;
|
|
|
fn string(self) -> String;
|
|
|
@@ -83,27 +69,11 @@ fn urltestdata() {
|
|
|
}
|
|
|
let base = entry.take_string("base");
|
|
|
let input = entry.take_string("input");
|
|
|
- let expected = if entry.take_key("failure").is_some() {
|
|
|
- Err(())
|
|
|
- } else {
|
|
|
- Ok(ExpectedAttributes {
|
|
|
- href: entry.take_string("href"),
|
|
|
- origin: entry.take_key("origin").map(|s| s.string()),
|
|
|
- protocol: entry.take_string("protocol"),
|
|
|
- username: entry.take_string("username"),
|
|
|
- password: entry.take_string("password"),
|
|
|
- host: entry.take_string("host"),
|
|
|
- hostname: entry.take_string("hostname"),
|
|
|
- port: entry.take_string("port"),
|
|
|
- pathname: entry.take_string("pathname"),
|
|
|
- search: entry.take_string("search"),
|
|
|
- hash: entry.take_string("hash"),
|
|
|
- })
|
|
|
- };
|
|
|
+ let failure = entry.take_key("failure").is_some();
|
|
|
|
|
|
let base = match Url::parse(&base) {
|
|
|
Ok(base) => base,
|
|
|
- Err(_) if expected.is_err() => continue,
|
|
|
+ Err(_) if failure => continue,
|
|
|
Err(message) => {
|
|
|
eprint_failure(
|
|
|
format!(" failed: error parsing base {:?}: {}", base, message),
|
|
|
@@ -115,10 +85,10 @@ fn urltestdata() {
|
|
|
}
|
|
|
};
|
|
|
|
|
|
- let (url, expected) = match (base.join(&input), expected) {
|
|
|
- (Ok(url), Ok(expected)) => (url, expected),
|
|
|
- (Err(_), Err(())) => continue,
|
|
|
- (Err(message), Ok(_)) => {
|
|
|
+ let url = match (base.join(&input), failure) {
|
|
|
+ (Ok(url), false) => url,
|
|
|
+ (Err(_), true) => continue,
|
|
|
+ (Err(message), false) => {
|
|
|
eprint_failure(
|
|
|
format!(" failed: {}", message),
|
|
|
&format!("parse URL for {:?}", input),
|
|
|
@@ -127,7 +97,7 @@ fn urltestdata() {
|
|
|
passed = false;
|
|
|
continue;
|
|
|
}
|
|
|
- (Ok(_), Err(())) => {
|
|
|
+ (Ok(_), true) => {
|
|
|
eprint_failure(
|
|
|
format!(" failed: expected parse error for URL {:?}", input),
|
|
|
&format!("parse URL for {:?}", input),
|
|
|
@@ -140,20 +110,16 @@ fn urltestdata() {
|
|
|
|
|
|
passed &= check_invariants(&url, &format!("invariants for {:?}", input), None);
|
|
|
|
|
|
- macro_rules! assert_attributes {
|
|
|
- ($($attr: ident)+) => {$(test_eq_eprint(
|
|
|
- expected.$attr,
|
|
|
- quirks::$attr(&url),
|
|
|
- &format!("{:?} - {}", input, stringify!($attr)),
|
|
|
+ for &attr in ATTRIBS {
|
|
|
+ passed &= test_eq_eprint(
|
|
|
+ entry.take_string(attr),
|
|
|
+ get(&url, attr),
|
|
|
+ &format!("{:?} - {}", input, attr),
|
|
|
None,
|
|
|
- ))&+}
|
|
|
+ );
|
|
|
}
|
|
|
|
|
|
- passed &= assert_attributes!(
|
|
|
- href protocol username password host hostname port pathname search hash
|
|
|
- );
|
|
|
-
|
|
|
- if let Some(expected_origin) = expected.origin {
|
|
|
+ if let Some(expected_origin) = entry.take_key("origin").map(|s| s.string()) {
|
|
|
passed &= test_eq_eprint(
|
|
|
expected_origin,
|
|
|
&quirks::origin(&url),
|
|
|
@@ -171,57 +137,69 @@ fn setters_tests() {
|
|
|
let mut json = Value::from_str(include_str!("setters_tests.json"))
|
|
|
.expect("JSON parse error in setters_tests.json");
|
|
|
|
|
|
- macro_rules! setter {
|
|
|
- ($attr: expr, $setter: ident) => {{
|
|
|
- let mut tests = json.take_key($attr).unwrap();
|
|
|
- let mut passed = true;
|
|
|
- for mut test in tests.as_array_mut().unwrap().drain(..) {
|
|
|
- let comment = test.take_key("comment").map(|s| s.string());
|
|
|
- let href = test.take_string("href");
|
|
|
- let new_value = test.take_string("new_value");
|
|
|
- let name = format!("{:?}.{} = {:?}", href, $attr, new_value);
|
|
|
- let mut expected = test.take_key("expected").unwrap();
|
|
|
-
|
|
|
- let mut url = Url::parse(&href).unwrap();
|
|
|
- let comment_ref = comment.as_deref();
|
|
|
- passed &= check_invariants(&url, &name, comment_ref);
|
|
|
- let _ = quirks::$setter(&mut url, &new_value);
|
|
|
-
|
|
|
- passed &= assert_attributes!(&name, comment_ref, url, expected,
|
|
|
- href protocol username password host hostname port pathname search hash);
|
|
|
- passed &= check_invariants(&url, &name, comment_ref);
|
|
|
+ let mut passed = true;
|
|
|
+ for &attr in ATTRIBS {
|
|
|
+ if attr == "href" {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ let mut tests = json.take_key(attr).unwrap();
|
|
|
+ for mut test in tests.as_array_mut().unwrap().drain(..) {
|
|
|
+ let comment = test.take_key("comment").map(|s| s.string());
|
|
|
+ let href = test.take_string("href");
|
|
|
+ let new_value = test.take_string("new_value");
|
|
|
+ let name = format!("{:?}.{} = {:?}", href, attr, new_value);
|
|
|
+ let mut expected = test.take_key("expected").unwrap();
|
|
|
+
|
|
|
+ let mut url = Url::parse(&href).unwrap();
|
|
|
+ let comment_ref = comment.as_deref();
|
|
|
+ passed &= check_invariants(&url, &name, comment_ref);
|
|
|
+ let _ = set(&mut url, attr, &new_value);
|
|
|
+
|
|
|
+ for attr in ATTRIBS {
|
|
|
+ if let Some(value) = expected.take_key(attr) {
|
|
|
+ passed &= test_eq_eprint(value.string(), get(&url, attr), &name, comment_ref);
|
|
|
+ };
|
|
|
}
|
|
|
- passed
|
|
|
- }}
|
|
|
- }
|
|
|
|
|
|
- macro_rules! assert_attributes {
|
|
|
- ($name: expr, $comment: expr, $url: expr, $expected: expr, $($attr: ident)+) => {
|
|
|
- $(match $expected.take_key(stringify!($attr)) {
|
|
|
- Some(value) => test_eq_eprint(
|
|
|
- value.string(),
|
|
|
- quirks::$attr(&$url),
|
|
|
- $name,
|
|
|
- $comment,
|
|
|
- ),
|
|
|
- None => true,
|
|
|
- })&+
|
|
|
+ passed &= check_invariants(&url, &name, comment_ref);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- let mut passed = true;
|
|
|
- passed &= setter!("protocol", set_protocol);
|
|
|
- passed &= setter!("username", set_username);
|
|
|
- passed &= setter!("password", set_password);
|
|
|
- passed &= setter!("hostname", set_hostname);
|
|
|
- passed &= setter!("host", set_host);
|
|
|
- passed &= setter!("port", set_port);
|
|
|
- passed &= setter!("pathname", set_pathname);
|
|
|
- passed &= setter!("search", set_search);
|
|
|
- passed &= setter!("hash", set_hash);
|
|
|
assert!(passed);
|
|
|
}
|
|
|
|
|
|
+fn get<'a>(url: &'a Url, attr: &str) -> &'a str {
|
|
|
+ match attr {
|
|
|
+ "href" => quirks::href(url),
|
|
|
+ "protocol" => quirks::protocol(url),
|
|
|
+ "username" => quirks::username(url),
|
|
|
+ "password" => quirks::password(url),
|
|
|
+ "hostname" => quirks::hostname(url),
|
|
|
+ "host" => quirks::host(url),
|
|
|
+ "port" => quirks::port(url),
|
|
|
+ "pathname" => quirks::pathname(url),
|
|
|
+ "search" => quirks::search(url),
|
|
|
+ "hash" => quirks::hash(url),
|
|
|
+ _ => unreachable!(),
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+fn set<'a>(url: &'a mut Url, attr: &str, new: &str) {
|
|
|
+ let _ = match attr {
|
|
|
+ "protocol" => quirks::set_protocol(url, new),
|
|
|
+ "username" => quirks::set_username(url, new),
|
|
|
+ "password" => quirks::set_password(url, new),
|
|
|
+ "hostname" => quirks::set_hostname(url, new),
|
|
|
+ "host" => quirks::set_host(url, new),
|
|
|
+ "port" => quirks::set_port(url, new),
|
|
|
+ "pathname" => Ok(quirks::set_pathname(url, new)),
|
|
|
+ "search" => Ok(quirks::set_search(url, new)),
|
|
|
+ "hash" => Ok(quirks::set_hash(url, new)),
|
|
|
+ _ => unreachable!(),
|
|
|
+ };
|
|
|
+}
|
|
|
+
|
|
|
fn test_eq_eprint(expected: String, actual: &str, name: &str, comment: Option<&str>) -> bool {
|
|
|
if expected == actual {
|
|
|
return true;
|
|
|
@@ -242,3 +220,8 @@ fn eprint_failure(err: String, name: &str, comment: Option<&str>) {
|
|
|
eprintln!("");
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+const ATTRIBS: &[&str] = &[
|
|
|
+ "href", "protocol", "username", "password", "host", "hostname", "port", "pathname", "search",
|
|
|
+ "hash",
|
|
|
+];
|