tests.rs 5.9 KB

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