1 // Copyright 2013-2014 The rust-url developers.
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.
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("#") {
20 let mut line
= match line
.find("#") {
21 Some(index
) => &line
[0..index
],
25 let mut expected_failure
= false;
26 if line
.starts_with("XFAIL") {
27 expected_failure
= true;
28 line
= &line
[5..line
.len()];
31 let mut pieces
= line
.split('
;'
).map(|x
| x
.trim()).collect
::<Vec
<&str>>();
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 { "" }
;
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,
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
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/
66 let res
= result
.ok();
67 assert
!(res
== None
, "Expected error. result: {} | original: {} | source: {}",
68 res
.unwrap(), original
, source
);
72 let to_ascii
= if to_ascii
.len() > 0 {
75 if to_unicode
.len() > 0 {
76 to_unicode
.to_string()
83 // This result isn't valid under IDNA2008. Skip it
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
);
96 fn unescape(input
: &str) -> String
{
97 let mut output
= String
::new();
98 let mut chars
= input
.chars();
101 None
=> return output
,
104 match chars
.next().unwrap() {
105 '
\\'
=> output
.push('
\\'
),
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
)
113 Some(c
) => output
.push(c
),
114 None
=> { output.push_str(&format!("\\u{:X}{:X}{:X}{:X}
",c1,c2,c3,c4)); }
117 _ => panic!("Invalid test data input
"),