@@ -100,7 +100,7 @@ pub enum Error {
100100
101101#[ cfg( test) ]
102102mod describe_compiler_isa {
103- use std:: { convert:: TryFrom , fs:: read_to_string} ;
103+ use std:: { convert:: TryFrom , fs:: { self , read_to_string} } ;
104104
105105 use float_cmp:: { approx_eq, F64Margin } ;
106106 use qcs_api_client_openapi:: models:: { InstructionSetArchitecture , Node } ;
@@ -111,65 +111,61 @@ mod describe_compiler_isa {
111111 /// Compare two JSON values and make sure they are equivalent while allowing for some precision
112112 /// loss in numbers.
113113 ///
114- /// Return Ok if equivalent, or tuple containing the differing elements.
115- fn json_is_equivalent < ' a > (
116- first : & ' a Value ,
117- second : & ' a Value ,
118- ) -> Result < ( ) , ( & ' a Value , & ' a Value ) > {
119- let equal = match ( first, second) {
120- ( Value :: Number ( first_num) , Value :: Number ( second_num) ) => {
121- if !first_num. is_f64 ( ) || !second_num. is_f64 ( ) {
122- first_num == second_num
114+ /// Panics if there is any inequality.
115+ fn assert_json_is_equivalent < ' a > (
116+ expected : & ' a Value ,
117+ actual : & ' a Value ,
118+ ) {
119+ assert_json_is_equivalent_inner ( expected, actual, "" ) ;
120+ }
121+
122+ fn assert_json_is_equivalent_inner < ' a > (
123+ expected : & ' a Value ,
124+ actual : & ' a Value ,
125+ path : & str ,
126+ ) {
127+ match ( expected, actual) {
128+ ( Value :: Number ( expected_num) , Value :: Number ( actual_num) ) => {
129+ if !expected_num. is_f64 ( ) || !actual_num. is_f64 ( ) {
130+ assert_eq ! ( expected_num, actual_num, "path '{}': non-f64 numeric inequality: expected: {}, actual: {}" , path, expected_num, actual_num) ;
123131 } else {
124- let first_f64 = first_num . as_f64 ( ) . unwrap ( ) ;
125- let second_f64 = second_num . as_f64 ( ) . unwrap ( ) ;
126- approx_eq ! (
132+ let expected_f64 = expected_num . as_f64 ( ) . unwrap ( ) ;
133+ let actual_f64 = actual_num . as_f64 ( ) . unwrap ( ) ;
134+ assert ! ( approx_eq!(
127135 f64 ,
128- first_f64 ,
129- second_f64 ,
136+ expected_f64 ,
137+ actual_f64 ,
130138 F64Margin {
131139 ulps: 1 ,
132140 epsilon: 0.000_000_1
133141 }
134- )
142+ ) , "path '{}': numeric inequality out of range: expected: {}, actual: {}" , path , expected_f64 , actual_f64 ) ;
135143 }
136144 }
137- ( Value :: Object ( first_map) , Value :: Object ( second_map) ) => {
138- let mut found_missing = false ;
139- for ( key, first_value) in first_map {
140- let second_value = second_map. get ( key) ;
141- if second_value. is_none ( ) {
142- found_missing = true ;
145+ ( Value :: Object ( expected_map) , Value :: Object ( actual_map) ) => {
146+
147+ let mut expected_key_missing_from_actual = None ;
148+ for ( key, expected_value) in expected_map {
149+ let actual_value = actual_map. get ( key) ;
150+ if actual_value. is_none ( ) {
151+ expected_key_missing_from_actual = Some ( key) ;
143152 break ;
144153 }
145- let cmp = json_is_equivalent ( first_value, second_value. unwrap ( ) ) ;
146- cmp?;
154+ assert_json_is_equivalent_inner ( expected_value, actual_value. unwrap ( ) , & ( format ! ( "{}.{}" , path, key) ) ) ;
155+ }
156+ assert ! ( expected_key_missing_from_actual. is_none( ) , "path '{}': expected map has key not in actual map: {}" , path, expected_key_missing_from_actual. unwrap( ) ) ;
157+ for ( key, _) in actual_map {
158+ assert ! ( expected_map. contains_key( key) , "path '{}': actual map has key not in expected map: {}" , path, key) ;
147159 }
148- !found_missing
149- }
150- ( Value :: Array ( first_array) , Value :: Array ( second_array) )
151- if first_array. len ( ) != second_array. len ( ) =>
152- {
153- false
154160 }
155- ( Value :: Array ( first_array) , Value :: Array ( second_array) ) => {
156- let error = first_array. iter ( ) . zip ( second_array) . find (
157- |( first_value, second_value) | -> bool {
158- json_is_equivalent ( first_value, second_value) . is_err ( )
159- } ,
160- ) ;
161- if let Some ( values) = error {
162- return Err ( values) ;
161+ ( Value :: Array ( expected_array) , Value :: Array ( actual_array) ) => {
162+ assert ! ( expected_array. len( ) == actual_array. len( ) , "expected array has more elements than actual array" ) ;
163+ for ( index, ( expected_value, actual_value) ) in expected_array. iter ( ) . zip ( actual_array) . enumerate ( ) {
164+ assert_json_is_equivalent_inner ( expected_value, actual_value, & ( format ! ( "{}[{}]" , path, index) ) ) ;
163165 }
164- true
165166 }
166- ( first , second ) => first == second ,
167+ ( expected , actual ) => assert_eq ! ( expected , actual , "path '{}': inequality: expected: {:?}, actual: {:?}" , path , expected , actual ) ,
167168 } ;
168- if equal {
169- Ok ( ( ) )
170- } else {
171- Err ( ( first, second) )
172- }
173169 }
174170
175171 #[ test]
@@ -197,8 +193,8 @@ mod describe_compiler_isa {
197193
198194 let serialized =
199195 serde_json:: to_value ( compiler_isa) . expect ( "Unable to serialize CompilerIsa" ) ;
200- let result = json_is_equivalent ( & serialized , & expected ) ;
201- result . expect ( "JSON was not equivalent" ) ;
196+
197+ assert_json_is_equivalent ( & expected , & serialized ) ;
202198 }
203199
204200 #[ test]
@@ -242,7 +238,6 @@ mod describe_compiler_isa {
242238 let serialized_without_dead = serde_json:: to_value ( compiler_isa_excluding_dead)
243239 . expect ( "Unable to serialize CompilerIsa" ) ;
244240
245- let result = json_is_equivalent ( & serialized, & serialized_without_dead) ;
246- result. expect ( "JSON was not equivalent" ) ;
241+ assert_json_is_equivalent ( & serialized, & serialized_without_dead) ;
247242 }
248243}
0 commit comments