@@ -338,6 +338,16 @@ pub fn get_well_known_properties() -> HashMap<String, Value> {
338
338
}
339
339
340
340
#[ must_use]
341
+ /// Performs a comparison of two JSON Values if the expected is a strict subset of the actual
342
+ ///
343
+ /// # Arguments
344
+ ///
345
+ /// * `expected` - The expected value
346
+ /// * `actual` - The actual value
347
+ ///
348
+ /// # Returns
349
+ ///
350
+ /// An array of top level properties that differ, if any
341
351
pub fn get_diff ( expected : & Value , actual : & Value ) -> Vec < String > {
342
352
let mut diff_properties: Vec < String > = Vec :: new ( ) ;
343
353
if expected. is_null ( ) {
@@ -373,34 +383,28 @@ pub fn get_diff(expected: &Value, actual: &Value) -> Vec<String> {
373
383
continue ;
374
384
}
375
385
376
- match actual. as_object ( ) {
377
- Some ( actual_object) => {
378
- if actual_object . contains_key ( key ) {
379
- if value . is_array ( ) {
380
- if !actual [ key ] . is_array ( ) {
381
- info ! ( "diff: {} is not an array" , actual [ key] ) ;
386
+ if let Some ( actual_object ) = actual. as_object ( ) {
387
+ if actual_object. contains_key ( key ) {
388
+ if let Some ( value_array ) = value . as_array ( ) {
389
+ if let Some ( actual_array ) = actual [ key ] . as_array ( ) {
390
+ if !is_same_array ( value_array , actual_array ) {
391
+ info ! ( "diff: arrays differ for { key}" ) ;
382
392
diff_properties. push ( key. to_string ( ) ) ;
383
393
}
384
- else {
385
- if !is_same_array ( & value. as_array ( ) . unwrap ( ) , & actual[ key] . as_array ( ) . unwrap ( ) ) {
386
- info ! ( "diff: arrays differ for {key}" ) ;
387
- diff_properties. push ( key. to_string ( ) ) ;
388
- }
389
- }
390
- }
391
- else if value != & actual[ key] {
394
+ } else {
395
+ info ! ( "diff: {} is not an array" , actual[ key] ) ;
392
396
diff_properties. push ( key. to_string ( ) ) ;
393
397
}
394
- }
395
- else {
396
- info ! ( "diff: {key} missing" ) ;
398
+ } else if value != & actual[ key] {
397
399
diff_properties. push ( key. to_string ( ) ) ;
398
400
}
399
- } ,
400
- None => {
401
- info ! ( "diff: {key} not object" ) ;
401
+ } else {
402
+ info ! ( "diff: {key} missing" ) ;
402
403
diff_properties. push ( key. to_string ( ) ) ;
403
- } ,
404
+ }
405
+ } else {
406
+ info ! ( "diff: {key} not object" ) ;
407
+ diff_properties. push ( key. to_string ( ) ) ;
404
408
}
405
409
}
406
410
}
@@ -417,7 +421,7 @@ fn is_same_array(expected: &Vec<Value>, actual: &Vec<Value>) -> bool {
417
421
}
418
422
419
423
for item in expected {
420
- if !array_contains ( & actual, & item) {
424
+ if !array_contains ( actual, item) {
421
425
info ! ( "diff: actual array missing expected element" ) ;
422
426
return false ;
423
427
}
@@ -428,57 +432,43 @@ fn is_same_array(expected: &Vec<Value>, actual: &Vec<Value>) -> bool {
428
432
429
433
fn array_contains ( array : & Vec < Value > , find : & Value ) -> bool {
430
434
for item in array {
431
- if find. is_boolean ( ) && item. is_boolean ( ) {
432
- if find. as_bool ( ) . unwrap ( ) == item. as_bool ( ) . unwrap ( ) {
433
- return true ;
434
- }
435
+ if find. is_boolean ( ) && item. is_boolean ( ) && find. as_bool ( ) . unwrap ( ) == item. as_bool ( ) . unwrap ( ) {
436
+ return true ;
435
437
}
436
438
437
- if find. is_f64 ( ) && item. is_f64 ( ) {
438
- if find. as_f64 ( ) . unwrap ( ) == item. as_f64 ( ) . unwrap ( ) {
439
- return true ;
440
- }
439
+ if find. is_f64 ( ) && item. is_f64 ( ) && ( find. as_f64 ( ) . unwrap ( ) - item. as_f64 ( ) . unwrap ( ) ) . abs ( ) < 0.1 {
440
+ return true ;
441
441
}
442
442
443
- if find. is_i64 ( ) && item. is_i64 ( ) {
444
- if find. as_i64 ( ) . unwrap ( ) == item. as_i64 ( ) . unwrap ( ) {
445
- return true ;
446
- }
443
+ if find. is_i64 ( ) && item. is_i64 ( ) && find. as_i64 ( ) . unwrap ( ) == item. as_i64 ( ) . unwrap ( ) {
444
+ return true ;
447
445
}
448
446
449
447
if find. is_null ( ) && item. is_null ( ) {
450
448
return true ;
451
449
}
452
450
453
- if find. is_number ( ) && item. is_number ( ) {
454
- if find. as_number ( ) . unwrap ( ) == item. as_number ( ) . unwrap ( ) {
455
- return true ;
456
- }
451
+ if find. is_number ( ) && item. is_number ( ) && find. as_number ( ) . unwrap ( ) == item. as_number ( ) . unwrap ( ) {
452
+ return true ;
457
453
}
458
454
459
- if find. is_string ( ) && item. is_string ( ) {
460
- if find. as_str ( ) . unwrap ( ) == item. as_str ( ) . unwrap ( ) {
461
- return true ;
462
- }
455
+ if find. is_string ( ) && item. is_string ( ) && find. as_str ( ) . unwrap ( ) == item. as_str ( ) . unwrap ( ) {
456
+ return true ;
463
457
}
464
458
465
- if find. is_u64 ( ) && item. is_u64 ( ) {
466
- if find. as_u64 ( ) . unwrap ( ) == item. as_u64 ( ) . unwrap ( ) {
467
- return true ;
468
- }
459
+ if find. is_u64 ( ) && item. is_u64 ( ) && find. as_u64 ( ) . unwrap ( ) == item. as_u64 ( ) . unwrap ( ) {
460
+ return true ;
469
461
}
470
462
471
463
if find. is_object ( ) && item. is_object ( ) {
472
464
let obj_diff = get_diff ( find, item) ;
473
- if obj_diff. len ( ) == 0 {
465
+ if obj_diff. is_empty ( ) {
474
466
return true ;
475
467
}
476
468
}
477
469
478
- if find. is_array ( ) && item. is_array ( ) {
479
- if array_contains ( item. as_array ( ) . unwrap ( ) , find) {
480
- return true ;
481
- }
470
+ if find. is_array ( ) && item. is_array ( ) && array_contains ( item. as_array ( ) . unwrap ( ) , find) {
471
+ return true ;
482
472
}
483
473
}
484
474
0 commit comments