tests.rs 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  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. use std::char;
  9. use std::u32;
  10. use super::{Url, RelativeSchemeData, SchemeRelativeUrl, OtherSchemeData};
  11. #[test]
  12. fn test_url_parsing() {
  13. for test in parse_test_data(include_str!("urltestdata.txt")).move_iter() {
  14. let Test {
  15. input: input,
  16. base: 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: expected_failure,
  26. } = test;
  27. let base = match Url::parse(base.as_slice(), None) {
  28. Ok(base) => base,
  29. Err(message) => fail!("Error parsing base {}: {}", base, message)
  30. };
  31. let url = Url::parse(input.as_slice(), Some(&base));
  32. if expected_scheme.is_none() {
  33. if url.is_ok() && !expected_failure {
  34. fail!("Expected a parse error for URL {}", input);
  35. }
  36. continue
  37. }
  38. let Url { scheme, scheme_data, query, fragment, .. } = match url {
  39. Ok(url) => url,
  40. Err(message) => {
  41. if expected_failure {
  42. continue
  43. } else {
  44. fail!("Error parsing URL {}: {}", input, message)
  45. }
  46. }
  47. };
  48. macro_rules! assert_eq {
  49. ($a: expr, $b: expr) => {
  50. {
  51. let a = $a;
  52. let b = $b;
  53. if a != b {
  54. if expected_failure {
  55. continue
  56. } else {
  57. fail!("{} != {}", a, b)
  58. }
  59. }
  60. }
  61. }
  62. }
  63. assert_eq!(Some(scheme), expected_scheme);
  64. match scheme_data {
  65. RelativeSchemeData(SchemeRelativeUrl { username, password, host, port, path }) => {
  66. assert_eq!(username, expected_username);
  67. assert_eq!(password, expected_password);
  68. let host = host.serialize();
  69. assert_eq!(host, expected_host)
  70. assert_eq!(port, expected_port);
  71. assert_eq!(Some("/".to_string().append(path.connect("/").as_slice())),
  72. expected_path);
  73. },
  74. OtherSchemeData(scheme_data) => {
  75. assert_eq!(Some(scheme_data), expected_path);
  76. assert_eq!(String::new(), expected_username);
  77. assert_eq!(None, expected_password);
  78. assert_eq!(String::new(), expected_host);
  79. assert_eq!(String::new(), expected_port);
  80. },
  81. }
  82. fn opt_prepend(prefix: &str, opt_s: Option<String>) -> Option<String> {
  83. opt_s.map(|s| prefix.to_string().append(s.as_slice()))
  84. }
  85. assert_eq!(opt_prepend("?", query), expected_query);
  86. assert_eq!(opt_prepend("#", fragment), expected_fragment);
  87. assert!(!expected_failure, "Unexpected success for {}", input);
  88. }
  89. }
  90. struct Test {
  91. input: String,
  92. base: String,
  93. scheme: Option<String>,
  94. username: String,
  95. password: Option<String>,
  96. host: String,
  97. port: String,
  98. path: Option<String>,
  99. query: Option<String>,
  100. fragment: Option<String>,
  101. expected_failure: bool,
  102. }
  103. fn parse_test_data(input: &str) -> Vec<Test> {
  104. let mut tests: Vec<Test> = Vec::new();
  105. for line in input.lines() {
  106. if line == "" || line.starts_with("#") {
  107. continue
  108. }
  109. let mut pieces = line.split(' ').collect::<Vec<&str>>();
  110. let expected_failure = pieces[0] == "XFAIL";
  111. if expected_failure {
  112. pieces.shift();
  113. }
  114. let input = unescape(pieces.shift().unwrap());
  115. let mut test = Test {
  116. input: input,
  117. base: if pieces.is_empty() || pieces[0] == "" {
  118. tests.last().unwrap().base.clone()
  119. } else {
  120. unescape(pieces.shift().unwrap())
  121. },
  122. scheme: None,
  123. username: String::new(),
  124. password: None,
  125. host: String::new(),
  126. port: String::new(),
  127. path: None,
  128. query: None,
  129. fragment: None,
  130. expected_failure: expected_failure,
  131. };
  132. for piece in pieces.move_iter() {
  133. if piece == "" || piece.starts_with("#") {
  134. continue
  135. }
  136. let colon = piece.find(':').unwrap();
  137. let value = unescape(piece.slice_from(colon + 1));
  138. match piece.slice_to(colon) {
  139. "s" => test.scheme = Some(value),
  140. "u" => test.username = value,
  141. "pass" => test.password = Some(value),
  142. "h" => test.host = value,
  143. "port" => test.port = value,
  144. "p" => test.path = Some(value),
  145. "q" => test.query = Some(value),
  146. "f" => test.fragment = Some(value),
  147. _ => fail!("Invalid token")
  148. }
  149. }
  150. tests.push(test)
  151. }
  152. tests
  153. }
  154. fn unescape(input: &str) -> String {
  155. let mut output = String::new();
  156. let mut chars = input.chars();
  157. loop {
  158. match chars.next() {
  159. None => return output,
  160. Some(c) => output.push_char(
  161. if c == '\\' {
  162. match chars.next().unwrap() {
  163. '\\' => '\\',
  164. 'n' => '\n',
  165. 'r' => '\r',
  166. 's' => ' ',
  167. 't' => '\t',
  168. 'f' => '\x0C',
  169. 'u' => {
  170. let mut hex = String::new();
  171. hex.push_char(chars.next().unwrap());
  172. hex.push_char(chars.next().unwrap());
  173. hex.push_char(chars.next().unwrap());
  174. hex.push_char(chars.next().unwrap());
  175. u32::parse_bytes(hex.as_bytes(), 16)
  176. .and_then(char::from_u32).unwrap()
  177. }
  178. _ => fail!("Invalid test data input"),
  179. }
  180. } else {
  181. c
  182. }
  183. )
  184. }
  185. }
  186. }