idna.rs 3.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. extern crate url;
  2. use std::ascii::AsciiExt;
  3. use std::char;
  4. use url::idna::domain_to_ascii_options;
  5. #[test]
  6. fn test_uts46() {
  7. // http://www.unicode.org/Public/idna/latest/IdnaTest.txt
  8. for line in include_str!("IdnaTest.txt").lines() {
  9. if line == "" || line.starts_with("#") {
  10. continue
  11. }
  12. // Remove comments
  13. let mut line = match line.find("#") {
  14. Some(index) => &line[0..index],
  15. None => line
  16. };
  17. let mut expected_failure = false;
  18. if line.starts_with("XFAIL") {
  19. expected_failure = true;
  20. line = &line[5..line.len()];
  21. };
  22. let mut pieces = line.split(';').map(|x| x.trim()).collect::<Vec<&str>>();
  23. let testType = pieces.remove(0);
  24. let original = pieces.remove(0);
  25. let source = unescape(original);
  26. let toUnicode = pieces.remove(0);
  27. let toAscii = pieces.remove(0);
  28. let nv8 = pieces.len() > 0;
  29. if expected_failure {
  30. continue;
  31. }
  32. let result = domain_to_ascii_options(&source, true, testType != "N");
  33. let res = result.ok();
  34. if toAscii.starts_with("[") {
  35. //assert!(res == None, "Expected error. result: {} | original: {} | source: {}", res.unwrap(), original, source);
  36. continue;
  37. }
  38. let toAscii = if toAscii.len() > 0 {
  39. toAscii.to_string()
  40. } else {
  41. if toUnicode.len() > 0 {
  42. toUnicode.to_string()
  43. } else {
  44. source.clone()
  45. }
  46. };
  47. assert!(res != None, "Couldn't parse {} ", source);
  48. let output = res.unwrap();
  49. assert!(output == toAscii.to_ascii_lowercase(), "result: {} | expected: {} | original: {} | source: {}", output, toAscii, original, source);
  50. }
  51. }
  52. fn unescape(input: &str) -> String {
  53. let mut output = String::new();
  54. let mut chars = input.chars();
  55. loop {
  56. match chars.next() {
  57. None => return output,
  58. Some(c) =>
  59. if c == '\\' {
  60. match chars.next().unwrap() {
  61. '\\' => output.push('\\'),
  62. 'u' => {
  63. let c1 = chars.next().unwrap().to_digit(16).unwrap();
  64. let c2 = chars.next().unwrap().to_digit(16).unwrap();
  65. let c3 = chars.next().unwrap().to_digit(16).unwrap();
  66. let c4 = chars.next().unwrap().to_digit(16).unwrap();
  67. match char::from_u32((((c1 * 16 + c2) * 16 + c3) * 16 + c4))
  68. {
  69. Some(c) => output.push(c),
  70. None => { output.push_str(&format!("\\u{:X}{:X}{:X}{:X}",c1,c2,c3,c4)); }
  71. };
  72. }
  73. _ => panic!("Invalid test data input"),
  74. }
  75. } else {
  76. output.push(c);
  77. }
  78. }
  79. }
  80. }