فهرست منبع

Test harness for setters.

Simon Sapin 10 سال پیش
والد
کامیت
92eb5a6b3b
2فایلهای تغییر یافته به همراه121 افزوده شده و 39 حذف شده
  1. 100 39
      tests/data.rs
  2. 21 0
      tests/setters_tests.json

+ 100 - 39
tests/data.rs

@@ -12,11 +12,11 @@ extern crate rustc_serialize;
 extern crate test;
 extern crate url;
 
-use rustc_serialize::json::Json;
-use url::{Url, Position};
+use rustc_serialize::json::{self, Json};
+use url::{Url, quirks};
 
 
-fn run_parsing(input: String, base: String, expected: Result<ParsingTestCase, ()>) {
+fn run_parsing(input: String, base: String, expected: Result<ExpectedAttributes, ()>) {
     let base = match Url::parse(&base) {
         Ok(base) => base,
         Err(message) => panic!("Error parsing base {:?}: {}", base, message)
@@ -41,30 +41,24 @@ fn run_parsing(input: String, base: String, expected: Result<ParsingTestCase, ()
         }
     }
 
-    assert_eq!(expected.href, url.as_str());
-    if let Some(expected_origin) = expected.origin {
-        assert_eq!(expected_origin, url.origin().unicode_serialization());
+    macro_rules! assert_attributes {
+        ($($attr: ident)+) => {
+            {
+                $(
+                    assert_eq!(expected.$attr, quirks::$attr(&url));
+                )+;
+            }
+        }
     }
-    assert_eq!(expected.protocol, &url.as_str()[..url.scheme().len() + ":".len()]);
-    assert_eq!(expected.username, url.username());
-    assert_eq!(expected.password, url.password().unwrap_or(""));
-    assert_eq!(expected.host, &url[Position::BeforeHost..Position::AfterPort]);
-    assert_eq!(expected.hostname, url.host_str().unwrap_or(""));
-    assert_eq!(expected.port, &url[Position::BeforePort..Position::AfterPort]);
-    assert_eq!(expected.pathname, url.path());
-    assert_eq!(expected.search, trim(&url[Position::AfterPath..Position::AfterQuery]));
-    assert_eq!(expected.hash, trim(&url[Position::AfterQuery..]));
-}
 
-fn trim(s: &str) -> &str {
-    if s.len() == 1 {
-        ""
-    } else {
-        s
+    assert_attributes!(href protocol username password host hostname port pathname search hash);
+
+    if let Some(expected_origin) = expected.origin {
+        assert_eq!(expected_origin, quirks::origin(&url));
     }
 }
 
-struct ParsingTestCase {
+struct ExpectedAttributes {
     href: String,
     origin: Option<String>,
     protocol: String,
@@ -78,32 +72,56 @@ struct ParsingTestCase {
     hash: String,
 }
 
+trait JsonExt {
+    fn take(&mut self, key: &str) -> Option<Json>;
+    fn object(self) -> json::Object;
+    fn string(self) -> String;
+    fn take_string(&mut self, key: &str) -> String;
+}
+
+impl JsonExt for Json {
+    fn take(&mut self, key: &str) -> Option<Json> {
+        self.as_object_mut().unwrap().remove(key)
+    }
+
+    fn object(self) -> json::Object {
+        if let Json::Object(o) = self { o } else { panic!("Not a Json::Object") }
+    }
+
+    fn string(self) -> String {
+        if let Json::String(s) = self { s } else { panic!("Not a Json::String") }
+    }
+
+    fn take_string(&mut self, key: &str) -> String {
+        self.take(key).unwrap().string()
+    }
+}
+
 fn collect_parsing<F: FnMut(String, test::TestFn)>(add_test: &mut F) {
     // Copied form https://github.com/w3c/web-platform-tests/blob/master/url/
-    let json = Json::from_str(include_str!("urltestdata.json"))
+    let mut json = Json::from_str(include_str!("urltestdata.json"))
         .expect("JSON parse error in urltestdata.json");
-    for entry in json.as_array().unwrap() {
+    for entry in json.as_array_mut().unwrap() {
         if entry.is_string() {
             continue  // ignore comments
         }
-        let string = |key| entry.find(key).unwrap().as_string().unwrap().to_owned();
-        let base = string("base");
-        let input = string("input");
+        let base = entry.take_string("base");
+        let input = entry.take_string("input");
         let expected = if entry.find("failure").is_some() {
             Err(())
         } else {
-            Ok(ParsingTestCase {
-                href: string("href"),
-                origin: entry.find("origin").map(|j| j.as_string().unwrap().to_owned()),
-                protocol: string("protocol"),
-                username: string("username"),
-                password: string("password"),
-                host: string("host"),
-                hostname: string("hostname"),
-                port: string("port"),
-                pathname: string("pathname"),
-                search: string("search"),
-                hash: string("hash"),
+            Ok(ExpectedAttributes {
+                href: entry.take_string("href"),
+                origin: entry.take("origin").map(Json::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"),
             })
         };
         add_test(format!("{:?} @ base {:?}", input, base),
@@ -111,6 +129,48 @@ fn collect_parsing<F: FnMut(String, test::TestFn)>(add_test: &mut F) {
     }
 }
 
+fn collect_setters<F>(add_test: &mut F) where F: FnMut(String, test::TestFn) {
+    let mut json = Json::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($attr).unwrap();
+            for mut test in tests.as_array_mut().unwrap().drain(..) {
+                let comment = test.take("comment").map(Json::string).unwrap_or(String::new());
+                let href = test.take_string("href");
+                let new_value = test.take_string("new_value");
+                let name = format!("{:?}.{} = {:?} {}", href, $attr, new_value, comment);
+                let mut expected = test.take("expected").unwrap();
+                add_test(name, test::TestFn::dyn_test_fn(move || {
+                    let mut url = Url::parse(&href).unwrap();
+                    let _ = quirks::$setter(&mut url, &new_value);
+                    assert_attributes!(url, expected,
+                        href protocol username password host hostname port pathname search hash);
+                }))
+            }
+        }}
+    }
+    macro_rules! assert_attributes {
+        ($url: expr, $expected: expr, $($attr: ident)+) => {
+            $(
+                if let Some(value) = $expected.take(stringify!($attr)) {
+                    assert_eq!(quirks::$attr(&$url), value.string())
+                }
+            )+
+        }
+    }
+    setter!("protocol", set_protocol);
+    setter!("username", set_username);
+    setter!("password", set_password);
+    setter!("hostname", set_hostname);
+    setter!("host", set_host);
+    setter!("port", set_port);
+    setter!("pathname", set_pathname);
+    setter!("search", set_search);
+    setter!("hash", set_hash);
+}
+
 fn main() {
     let mut tests = Vec::new();
     {
@@ -125,6 +185,7 @@ fn main() {
             })
         };
         collect_parsing(&mut add_one);
+        collect_setters(&mut add_one);
     }
     test::test_main(&std::env::args().collect::<Vec<_>>(), tests)
 }

+ 21 - 0
tests/setters_tests.json

@@ -0,0 +1,21 @@
+{
+    "protocol": [
+        {
+            "comment": "The empty scheme is not a valid scheme.",
+            "href": "http://example.net",
+            "new_value": "",
+            "expected": {
+                "href": "http://example.net/",
+                "protocol": "http:"
+            }
+        }
+    ],
+    "username": [],
+    "password": [],
+    "host": [],
+    "hostname": [],
+    "port": [],
+    "pathname": [],
+    "search": [],
+    "hash": []
+}