wpt.rs 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. // Copyright 2013-2014 Simon Sapin.
  2. //
  3. // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
  4. // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
  5. // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
  6. // option. This file may not be copied, modified, or distributed
  7. // except according to those terms.
  8. //! Tests copied form https://github.com/w3c/web-platform-tests/blob/master/url/
  9. extern crate test;
  10. extern crate url;
  11. use std::char;
  12. use url::Url;
  13. fn run_one(entry: Entry) {
  14. let Entry {
  15. input,
  16. base,
  17. scheme: expected_scheme,
  18. username: expected_username,
  19. password: expected_password,
  20. host: expected_host,
  21. port: expected_port,
  22. path: expected_path,
  23. query: expected_query,
  24. fragment: expected_fragment,
  25. expected_failure,
  26. } = entry;
  27. let base = match Url::parse(&base) {
  28. Ok(base) => base,
  29. Err(message) => panic!("Error parsing base {}: {}", base, message)
  30. };
  31. let expecting_err = expected_scheme.is_none() ^ expected_failure;
  32. let url = match base.join(&input) {
  33. Ok(url) => url,
  34. Err(reason) => {
  35. assert!(expecting_err, "Error parsing URL {}: {}", input, reason);
  36. return
  37. }
  38. };
  39. assert!(!expecting_err, "Expected a parse error for URL {}", input);
  40. macro_rules! assert_eq {
  41. ($a: expr, $b: expr) => {
  42. {
  43. let a = $a;
  44. let b = $b;
  45. if a != b {
  46. if expected_failure {
  47. return
  48. } else {
  49. panic!("{:?} != {:?} for {:?}", a, b, url)
  50. }
  51. }
  52. }
  53. }
  54. }
  55. assert_eq!(Some(url.scheme().to_owned()), expected_scheme);
  56. assert_eq!(url.username(), expected_username);
  57. assert_eq!(url.password().map(|s| s.to_owned()), expected_password);
  58. assert_eq!(url.host_str().unwrap_or("").to_owned(), expected_host);
  59. assert_eq!(url.port(), expected_port);
  60. assert_eq!(Some(url.path().to_owned()), expected_path);
  61. assert_eq!(url.query().map(|s| format!("?{}", s)), expected_query);
  62. assert_eq!(url.fragment().map(|s| format!("#{}", s)), expected_fragment);
  63. assert!(!expected_failure, "Unexpected success for {}", input);
  64. }
  65. struct Entry {
  66. input: String,
  67. base: String,
  68. scheme: Option<String>,
  69. username: String,
  70. password: Option<String>,
  71. host: String,
  72. port: Option<u16>,
  73. path: Option<String>,
  74. query: Option<String>,
  75. fragment: Option<String>,
  76. expected_failure: bool,
  77. }
  78. fn parse_test_data(input: &str) -> Vec<Entry> {
  79. let mut tests: Vec<Entry> = Vec::new();
  80. for line in input.lines() {
  81. if line == "" || line.starts_with("#") {
  82. continue
  83. }
  84. let mut pieces = line.split(' ').collect::<Vec<&str>>();
  85. let expected_failure = pieces[0] == "XFAIL";
  86. if expected_failure {
  87. pieces.remove(0);
  88. }
  89. let input = unescape(pieces.remove(0));
  90. let mut test = Entry {
  91. input: input,
  92. base: if pieces.is_empty() || pieces[0] == "" {
  93. tests.last().unwrap().base.clone()
  94. } else {
  95. unescape(pieces.remove(0))
  96. },
  97. scheme: None,
  98. username: String::new(),
  99. password: None,
  100. host: String::new(),
  101. port: None,
  102. path: None,
  103. query: None,
  104. fragment: None,
  105. expected_failure: expected_failure,
  106. };
  107. for piece in pieces {
  108. if piece == "" || piece.starts_with("#") {
  109. continue
  110. }
  111. let colon = piece.find(':').unwrap();
  112. let value = unescape(&piece[colon + 1..]);
  113. match &piece[..colon] {
  114. "s" => test.scheme = Some(value),
  115. "u" => test.username = value,
  116. "pass" => test.password = Some(value),
  117. "h" => test.host = value,
  118. "port" => test.port = Some(value.parse().unwrap()),
  119. "p" => test.path = Some(value),
  120. "q" => test.query = Some(value),
  121. "f" => test.fragment = Some(value),
  122. _ => panic!("Invalid token")
  123. }
  124. }
  125. tests.push(test)
  126. }
  127. tests
  128. }
  129. fn unescape(input: &str) -> String {
  130. let mut output = String::new();
  131. let mut chars = input.chars();
  132. loop {
  133. match chars.next() {
  134. None => return output,
  135. Some(c) => output.push(
  136. if c == '\\' {
  137. match chars.next().unwrap() {
  138. '\\' => '\\',
  139. 'n' => '\n',
  140. 'r' => '\r',
  141. 's' => ' ',
  142. 't' => '\t',
  143. 'f' => '\x0C',
  144. 'u' => {
  145. char::from_u32((((
  146. chars.next().unwrap().to_digit(16).unwrap()) * 16 +
  147. chars.next().unwrap().to_digit(16).unwrap()) * 16 +
  148. chars.next().unwrap().to_digit(16).unwrap()) * 16 +
  149. chars.next().unwrap().to_digit(16).unwrap()).unwrap()
  150. }
  151. _ => panic!("Invalid test data input"),
  152. }
  153. } else {
  154. c
  155. }
  156. )
  157. }
  158. }
  159. }
  160. fn make_test(entry: Entry) -> test::TestDescAndFn {
  161. test::TestDescAndFn {
  162. desc: test::TestDesc {
  163. name: test::DynTestName(format!("{:?} base {:?}", entry.input, entry.base)),
  164. ignore: false,
  165. should_panic: test::ShouldPanic::No,
  166. },
  167. testfn: test::TestFn::dyn_test_fn(move || run_one(entry)),
  168. }
  169. }
  170. fn main() {
  171. test::test_main(
  172. &std::env::args().collect::<Vec<_>>(),
  173. parse_test_data(include_str!("urltestdata.txt")).into_iter().map(make_test).collect(),
  174. )
  175. }