From c3f19a8ec1641614aa9edbd05a88e957d43df371 Mon Sep 17 00:00:00 2001 From: Ed Page Date: Sat, 21 Sep 2024 20:12:36 -0500 Subject: [PATCH] refactor(test): Migrate validate_upload to snapbox for json comparisons --- crates/cargo-test-support/src/compare.rs | 76 ------------------------ crates/cargo-test-support/src/publish.rs | 9 +-- 2 files changed, 3 insertions(+), 82 deletions(-) diff --git a/crates/cargo-test-support/src/compare.rs b/crates/cargo-test-support/src/compare.rs index cb40eebc5c1..5b5d4b6ce85 100644 --- a/crates/cargo-test-support/src/compare.rs +++ b/crates/cargo-test-support/src/compare.rs @@ -45,7 +45,6 @@ use crate::cross_compile::try_alternate; use crate::paths; use crate::{diff, rustc_host}; use anyhow::{bail, Result}; -use serde_json::Value; use std::fmt; use std::path::Path; use std::str; @@ -654,81 +653,6 @@ pub(crate) fn match_with_without( } } -/// Compares JSON object for approximate equality. -/// You can use `[..]` wildcard in strings (useful for OS-dependent things such -/// as paths). You can use a `"{...}"` string literal as a wildcard for -/// arbitrary nested JSON (useful for parts of object emitted by other programs -/// (e.g., rustc) rather than Cargo itself). -pub(crate) fn find_json_mismatch( - expected: &Value, - actual: &Value, - cwd: Option<&Path>, -) -> Result<()> { - match find_json_mismatch_r(expected, actual, cwd) { - Some((expected_part, actual_part)) => bail!( - "JSON mismatch\nExpected:\n{}\nWas:\n{}\nExpected part:\n{}\nActual part:\n{}\n", - serde_json::to_string_pretty(expected).unwrap(), - serde_json::to_string_pretty(&actual).unwrap(), - serde_json::to_string_pretty(expected_part).unwrap(), - serde_json::to_string_pretty(actual_part).unwrap(), - ), - None => Ok(()), - } -} - -fn find_json_mismatch_r<'a>( - expected: &'a Value, - actual: &'a Value, - cwd: Option<&Path>, -) -> Option<(&'a Value, &'a Value)> { - use serde_json::Value::*; - match (expected, actual) { - (&Number(ref l), &Number(ref r)) if l == r => None, - (&Bool(l), &Bool(r)) if l == r => None, - (&String(ref l), _) if l == "{...}" => None, - (&String(ref l), &String(ref r)) => { - if match_exact(l, r, "", "", cwd).is_err() { - Some((expected, actual)) - } else { - None - } - } - (&Array(ref l), &Array(ref r)) => { - if l.len() != r.len() { - return Some((expected, actual)); - } - - l.iter() - .zip(r.iter()) - .filter_map(|(l, r)| find_json_mismatch_r(l, r, cwd)) - .next() - } - (&Object(ref l), &Object(ref r)) => { - let mut expected_entries = l.iter(); - let mut actual_entries = r.iter(); - - loop { - match (expected_entries.next(), actual_entries.next()) { - (None, None) => return None, - (Some((expected_key, expected_value)), Some((actual_key, actual_value))) - if expected_key == actual_key => - { - if let mismatch @ Some(_) = - find_json_mismatch_r(expected_value, actual_value, cwd) - { - return mismatch; - } - } - _ => return Some((expected, actual)), - } - } - } - (&Null, &Null) => None, - // Magic string literal `"{...}"` acts as wildcard for any sub-JSON. - _ => Some((expected, actual)), - } -} - /// A single line string that supports `[..]` wildcard matching. pub(crate) struct WildStr<'a> { has_meta: bool, diff --git a/crates/cargo-test-support/src/publish.rs b/crates/cargo-test-support/src/publish.rs index a673c466b94..b47c73b3808 100644 --- a/crates/cargo-test-support/src/publish.rs +++ b/crates/cargo-test-support/src/publish.rs @@ -57,9 +57,10 @@ //! ); //! ``` -use crate::compare::{assert_match_exact, find_json_mismatch}; +use crate::compare::assert_match_exact; use crate::registry::{self, alt_api_path, FeatureMap}; use flate2::read::GzDecoder; +use snapbox::prelude::*; use std::collections::{HashMap, HashSet}; use std::fs; use std::fs::File; @@ -133,12 +134,8 @@ fn _validate_upload( let json_sz = read_le_u32(&mut f).expect("read json length"); let mut json_bytes = vec![0; json_sz as usize]; f.read_exact(&mut json_bytes).expect("read JSON data"); - let actual_json = serde_json::from_slice(&json_bytes).expect("uploaded JSON should be valid"); - let expected_json = serde_json::from_str(expected_json).expect("expected JSON does not parse"); - if let Err(e) = find_json_mismatch(&expected_json, &actual_json, None) { - panic!("{}", e); - } + snapbox::assert_data_eq!(json_bytes, expected_json.is_json()); // 32-bit little-endian integer of length of crate file. let crate_sz = read_le_u32(&mut f).expect("read crate length");