]> git.proxmox.com Git - rustc.git/blob - src/vendor/idna/tests/uts46.rs
New upstream version 1.29.0+dfsg1
[rustc.git] / src / vendor / idna / tests / uts46.rs
1 // Copyright 2013-2014 The rust-url developers.
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
9 use std::char;
10 use idna::uts46;
11 use test::TestFn;
12
13 pub fn collect_tests<F: FnMut(String, TestFn)>(add_test: &mut F) {
14 // http://www.unicode.org/Public/idna/latest/IdnaTest.txt
15 for (i, line) in include_str!("IdnaTest.txt").lines().enumerate() {
16 if line == "" || line.starts_with("#") {
17 continue
18 }
19 // Remove comments
20 let mut line = match line.find("#") {
21 Some(index) => &line[0..index],
22 None => line
23 };
24
25 let mut expected_failure = false;
26 if line.starts_with("XFAIL") {
27 expected_failure = true;
28 line = &line[5..line.len()];
29 };
30
31 let mut pieces = line.split(';').map(|x| x.trim()).collect::<Vec<&str>>();
32
33 let test_type = pieces.remove(0);
34 let original = pieces.remove(0);
35 let source = unescape(original);
36 let to_unicode = pieces.remove(0);
37 let to_ascii = pieces.remove(0);
38 let nv8 = if pieces.len() > 0 { pieces.remove(0) } else { "" };
39
40 if expected_failure {
41 continue;
42 }
43
44 let test_name = format!("UTS #46 line {}", i + 1);
45 add_test(test_name, TestFn::dyn_test_fn(move || {
46 let result = uts46::to_ascii(&source, uts46::Flags {
47 use_std3_ascii_rules: true,
48 transitional_processing: test_type == "T",
49 verify_dns_length: true,
50 });
51
52 if to_ascii.starts_with("[") {
53 if to_ascii.starts_with("[C") {
54 // http://unicode.org/reports/tr46/#Deviations
55 // applications that perform IDNA2008 lookup are not required to check
56 // for these contexts
57 return;
58 }
59 if to_ascii == "[V2]" {
60 // Everybody ignores V2
61 // https://github.com/servo/rust-url/pull/240
62 // https://github.com/whatwg/url/issues/53#issuecomment-181528158
63 // http://www.unicode.org/review/pri317/
64 return;
65 }
66 let res = result.ok();
67 assert!(res == None, "Expected error. result: {} | original: {} | source: {}",
68 res.unwrap(), original, source);
69 return;
70 }
71
72 let to_ascii = if to_ascii.len() > 0 {
73 to_ascii.to_string()
74 } else {
75 if to_unicode.len() > 0 {
76 to_unicode.to_string()
77 } else {
78 source.clone()
79 }
80 };
81
82 if nv8 == "NV8" {
83 // This result isn't valid under IDNA2008. Skip it
84 return;
85 }
86
87 assert!(result.is_ok(), "Couldn't parse {} | original: {} | error: {:?}",
88 source, original, result.err());
89 let output = result.ok().unwrap();
90 assert!(output == to_ascii, "result: {} | expected: {} | original: {} | source: {}",
91 output, to_ascii, original, source);
92 }))
93 }
94 }
95
96 fn unescape(input: &str) -> String {
97 let mut output = String::new();
98 let mut chars = input.chars();
99 loop {
100 match chars.next() {
101 None => return output,
102 Some(c) =>
103 if c == '\\' {
104 match chars.next().unwrap() {
105 '\\' => output.push('\\'),
106 'u' => {
107 let c1 = chars.next().unwrap().to_digit(16).unwrap();
108 let c2 = chars.next().unwrap().to_digit(16).unwrap();
109 let c3 = chars.next().unwrap().to_digit(16).unwrap();
110 let c4 = chars.next().unwrap().to_digit(16).unwrap();
111 match char::from_u32(((c1 * 16 + c2) * 16 + c3) * 16 + c4)
112 {
113 Some(c) => output.push(c),
114 None => { output.push_str(&format!("\\u{:X}{:X}{:X}{:X}",c1,c2,c3,c4)); }
115 };
116 }
117 _ => panic!("Invalid test data input"),
118 }
119 } else {
120 output.push(c);
121 }
122 }
123 }
124 }