88
99//! Data-driven tests
1010
11- use rustc_test as test;
1211use serde_json:: Value ;
1312use std:: str:: FromStr ;
1413use url:: { quirks, Url } ;
1514
16- fn check_invariants ( url : & Url ) {
17- url. check_invariants ( ) . unwrap ( ) ;
15+ fn check_invariants ( url : & Url , name : & str , comment : Option < & str > ) -> bool {
16+ let mut passed = true ;
17+ if let Err ( e) = url. check_invariants ( ) {
18+ passed = false ;
19+ eprint_failure (
20+ format ! ( " failed: invariants checked -> {:?}" , e) ,
21+ name,
22+ comment,
23+ ) ;
24+ }
25+
1826 #[ cfg( feature = "serde" ) ]
1927 {
2028 let bytes = serde_json:: to_vec ( url) . unwrap ( ) ;
2129 let new_url: Url = serde_json:: from_slice ( & bytes) . unwrap ( ) ;
22- assert_eq ! ( url, & new_url) ;
23- }
24- }
25-
26- fn run_parsing ( input : & str , base : & str , expected : Result < ExpectedAttributes , ( ) > ) {
27- let base = match Url :: parse ( & base) {
28- Ok ( base) => base,
29- Err ( _) if expected. is_err ( ) => return ,
30- Err ( message) => panic ! ( "Error parsing base {:?}: {}" , base, message) ,
31- } ;
32- let ( url, expected) = match ( base. join ( & input) , expected) {
33- ( Ok ( url) , Ok ( expected) ) => ( url, expected) ,
34- ( Err ( _) , Err ( ( ) ) ) => return ,
35- ( Err ( message) , Ok ( _) ) => panic ! ( "Error parsing URL {:?}: {}" , input, message) ,
36- ( Ok ( _) , Err ( ( ) ) ) => panic ! ( "Expected a parse error for URL {:?}" , input) ,
37- } ;
38-
39- check_invariants ( & url) ;
40-
41- macro_rules! assert_eq {
42- ( $expected: expr, $got: expr) => { {
43- let expected = $expected;
44- let got = $got;
45- assert!(
46- expected == got,
47- "\n {:?}\n != {}\n {:?}\n for URL {:?}\n " ,
48- got,
49- stringify!( $expected) ,
50- expected,
51- url
52- ) ;
53- } } ;
54- }
55-
56- macro_rules! assert_attributes {
57- ( $( $attr: ident) +) => {
58- {
59- $(
60- assert_eq!( expected. $attr, quirks:: $attr( & url) ) ;
61- ) +
62- }
63- }
30+ passed &= test_eq ( url, & new_url, name, comment) ;
6431 }
6532
66- assert_attributes ! ( href protocol username password host hostname port pathname search hash) ;
67-
68- if let Some ( expected_origin) = expected. origin {
69- assert_eq ! ( expected_origin, quirks:: origin( & url) ) ;
70- }
33+ passed
7134}
7235
7336struct ExpectedAttributes {
@@ -108,10 +71,12 @@ impl JsonExt for Value {
10871 }
10972}
11073
111- fn collect_parsing < F : FnMut ( String , test:: TestFn ) > ( add_test : & mut F ) {
74+ #[ test]
75+ fn urltestdata ( ) {
11276 // Copied form https://github.com/w3c/web-platform-tests/blob/master/url/
11377 let mut json = Value :: from_str ( include_str ! ( "urltestdata.json" ) )
11478 . expect ( "JSON parse error in urltestdata.json" ) ;
79+ let mut passed = true ;
11580 for entry in json. as_array_mut ( ) . unwrap ( ) {
11681 if entry. is_string ( ) {
11782 continue ; // ignore comments
@@ -135,73 +100,145 @@ fn collect_parsing<F: FnMut(String, test::TestFn)>(add_test: &mut F) {
135100 hash : entry. take_string ( "hash" ) ,
136101 } )
137102 } ;
138- add_test (
139- format ! ( "{:?} @ base {:?}" , input, base) ,
140- test:: TestFn :: dyn_test_fn ( move || run_parsing ( & input, & base, expected) ) ,
103+
104+ let base = match Url :: parse ( & base) {
105+ Ok ( base) => base,
106+ Err ( _) if expected. is_err ( ) => continue ,
107+ Err ( message) => {
108+ eprint_failure (
109+ format ! ( " failed: error parsing base {:?}: {}" , base, message) ,
110+ & format ! ( "parse base for {:?}" , input) ,
111+ None ,
112+ ) ;
113+ passed = false ;
114+ continue ;
115+ }
116+ } ;
117+
118+ let ( url, expected) = match ( base. join ( & input) , expected) {
119+ ( Ok ( url) , Ok ( expected) ) => ( url, expected) ,
120+ ( Err ( _) , Err ( ( ) ) ) => continue ,
121+ ( Err ( message) , Ok ( _) ) => {
122+ eprint_failure (
123+ format ! ( " failed: {}" , message) ,
124+ & format ! ( "parse URL for {:?}" , input) ,
125+ None ,
126+ ) ;
127+ passed = false ;
128+ continue ;
129+ }
130+ ( Ok ( _) , Err ( ( ) ) ) => {
131+ eprint_failure (
132+ format ! ( " failed: expected parse error for URL {:?}" , input) ,
133+ & format ! ( "parse URL for {:?}" , input) ,
134+ None ,
135+ ) ;
136+ passed = false ;
137+ continue ;
138+ }
139+ } ;
140+
141+ passed &= check_invariants ( & url, & format ! ( "invariants for {:?}" , input) , None ) ;
142+
143+ macro_rules! assert_attributes {
144+ ( $( $attr: ident) +) => { $( test_eq_eprint(
145+ expected. $attr,
146+ quirks:: $attr( & url) ,
147+ & format!( "{:?} - {}" , input, stringify!( $attr) ) ,
148+ None ,
149+ ) ) &+}
150+ }
151+
152+ passed &= assert_attributes ! (
153+ href protocol username password host hostname port pathname search hash
141154 ) ;
155+
156+ if let Some ( expected_origin) = expected. origin {
157+ passed &= test_eq_eprint (
158+ expected_origin,
159+ & quirks:: origin ( & url) ,
160+ & format ! ( "origin for {:?}" , input) ,
161+ None ,
162+ ) ;
163+ }
142164 }
165+
166+ assert ! ( passed)
143167}
144168
145- fn collect_setters < F > ( add_test : & mut F )
146- where
147- F : FnMut ( String , test:: TestFn ) ,
148- {
169+ #[ test]
170+ fn setters_tests ( ) {
149171 let mut json = Value :: from_str ( include_str ! ( "setters_tests.json" ) )
150172 . expect ( "JSON parse error in setters_tests.json" ) ;
151173
152174 macro_rules! setter {
153175 ( $attr: expr, $setter: ident) => { {
154176 let mut tests = json. take_key( $attr) . unwrap( ) ;
177+ let mut passed = true ;
155178 for mut test in tests. as_array_mut( ) . unwrap( ) . drain( ..) {
156- let comment = test. take_key( "comment" )
157- . map( |s| s. string( ) )
158- . unwrap_or( String :: new( ) ) ;
179+ let comment = test. take_key( "comment" ) . map( |s| s. string( ) ) ;
159180 let href = test. take_string( "href" ) ;
160181 let new_value = test. take_string( "new_value" ) ;
161- let name = format!( "{:?}.{} = {:?} {} " , href, $attr, new_value, comment ) ;
182+ let name = format!( "{:?}.{} = {:?}" , href, $attr, new_value) ;
162183 let mut expected = test. take_key( "expected" ) . unwrap( ) ;
163- add_test( name, test:: TestFn :: dyn_test_fn( move || {
164- let mut url = Url :: parse( & href) . unwrap( ) ;
165- check_invariants( & url) ;
166- let _ = quirks:: $setter( & mut url, & new_value) ;
167- assert_attributes!( url, expected,
168- href protocol username password host hostname port pathname search hash) ;
169- check_invariants( & url) ;
170- } ) )
184+
185+ let mut url = Url :: parse( & href) . unwrap( ) ;
186+ let comment_ref = comment. as_deref( ) ;
187+ passed &= check_invariants( & url, & name, comment_ref) ;
188+ let _ = quirks:: $setter( & mut url, & new_value) ;
189+
190+ passed &= assert_attributes!( & name, comment_ref, url, expected,
191+ href protocol username password host hostname port pathname search hash) ;
192+ passed &= check_invariants( & url, & name, comment_ref) ;
171193 }
194+ passed
172195 } }
173196 }
197+
174198 macro_rules! assert_attributes {
175- ( $url: expr, $expected: expr, $( $attr: ident) +) => {
176- $(
177- if let Some ( value) = $expected. take_key( stringify!( $attr) ) {
178- assert_eq!( quirks:: $attr( & $url) , value. string( ) )
179- }
180- ) +
199+ ( $name: expr, $comment: expr, $url: expr, $expected: expr, $( $attr: ident) +) => {
200+ $( match $expected. take_key( stringify!( $attr) ) {
201+ Some ( value) => test_eq_eprint(
202+ value. string( ) ,
203+ quirks:: $attr( & $url) ,
204+ $name,
205+ $comment,
206+ ) ,
207+ None => true ,
208+ } ) &+
181209 }
182210 }
183- setter ! ( "protocol" , set_protocol) ;
184- setter ! ( "username" , set_username) ;
185- setter ! ( "password" , set_password) ;
186- setter ! ( "hostname" , set_hostname) ;
187- setter ! ( "host" , set_host) ;
188- setter ! ( "port" , set_port) ;
189- setter ! ( "pathname" , set_pathname) ;
190- setter ! ( "search" , set_search) ;
191- setter ! ( "hash" , set_hash) ;
211+
212+ let mut passed = true ;
213+ passed &= setter ! ( "protocol" , set_protocol) ;
214+ passed &= setter ! ( "username" , set_username) ;
215+ passed &= setter ! ( "password" , set_password) ;
216+ passed &= setter ! ( "hostname" , set_hostname) ;
217+ passed &= setter ! ( "host" , set_host) ;
218+ passed &= setter ! ( "port" , set_port) ;
219+ passed &= setter ! ( "pathname" , set_pathname) ;
220+ passed &= setter ! ( "search" , set_search) ;
221+ passed &= setter ! ( "hash" , set_hash) ;
222+ assert ! ( passed) ;
192223}
193224
194- fn main ( ) {
195- let mut tests = Vec :: new ( ) ;
196- {
197- let mut add_one = |name : String , run : test:: TestFn | {
198- tests. push ( test:: TestDescAndFn {
199- desc : test:: TestDesc :: new ( test:: DynTestName ( name) ) ,
200- testfn : run,
201- } )
202- } ;
203- collect_parsing ( & mut add_one) ;
204- collect_setters ( & mut add_one) ;
225+ fn test_eq_eprint ( expected : String , actual : & str , name : & str , comment : Option < & str > ) -> bool {
226+ if expected == actual {
227+ return true ;
228+ }
229+ eprint_failure (
230+ format ! ( "expected: {}\n actual: {}" , expected, actual) ,
231+ name,
232+ comment,
233+ ) ;
234+ false
235+ }
236+
237+ fn eprint_failure ( err : String , name : & str , comment : Option < & str > ) {
238+ eprintln ! ( " test: {}\n {}" , name, err) ;
239+ if let Some ( comment) = comment {
240+ eprintln ! ( "{}\n " , comment) ;
241+ } else {
242+ eprintln ! ( "" ) ;
205243 }
206- test:: test_main ( & std:: env:: args ( ) . collect :: < Vec < _ > > ( ) , tests)
207244}
0 commit comments