Skip to content

Commit

Permalink
feat(snapbox): Add NormalizeMatches for JSON
Browse files Browse the repository at this point in the history
  • Loading branch information
Muscraft committed Sep 1, 2022
1 parent 3ed730d commit f53cd76
Showing 1 changed file with 113 additions and 1 deletion.
114 changes: 113 additions & 1 deletion crates/snapbox/src/data.rs
Expand Up @@ -316,7 +316,13 @@ impl Normalize for NormalizeMatches<'_> {
Data::text(lines)
}
#[cfg(feature = "json")]
DataInner::Json(_) => todo!("unsure of how to do matches here"),
DataInner::Json(value) => {
let mut value = value;
if let DataInner::Json(exp) = &self.pattern.inner {
normalize_value_matches(&mut value, exp, self.substitutions);
}
Data::json(value)
}
}
}
}
Expand All @@ -338,6 +344,36 @@ fn normalize_value(value: &mut serde_json::Value, op: fn(&str) -> String) {
}
}

#[cfg(feature = "structured-data")]
fn normalize_value_matches(
actual: &mut serde_json::Value,
expected: &serde_json::Value,
substitutions: &crate::Substitutions,
) {
use serde_json::Value::*;
match (actual, expected) {
// "{...}" is a wildcard
(act, String(exp)) if exp == "{...}" => {
*act = serde_json::json!("{...}");
}
(String(act), String(exp)) => {
*act = substitutions.normalize(act, exp);
}
(Array(act), Array(exp)) => {
act.iter_mut()
.zip(exp)
.for_each(|(a, e)| normalize_value_matches(a, e, substitutions));
}
(Object(act), Object(exp)) => {
act.iter_mut()
.zip(exp)
.filter(|(a, e)| a.0 == e.0)
.for_each(|(a, e)| normalize_value_matches(a.1, e.1, substitutions));
}
(_, _) => {}
}
}

#[cfg(feature = "detect-encoding")]
fn is_binary(data: &[u8]) -> bool {
match content_inspector::inspect(data) {
Expand Down Expand Up @@ -597,4 +633,80 @@ mod test {
});
assert_eq!(Data::json(new_lines), data);
}

#[test]
#[cfg(feature = "json")]
fn json_normalize_matches_string() {
let exp = json!({"name": "{...}"});
let expected = Data::json(exp);
let actual = json!({"name": "JohnDoe"});
let actual = Data::json(actual).normalize(NormalizeMatches {
substitutions: &Default::default(),
pattern: &expected,
});
if let (DataInner::Json(exp), DataInner::Json(act)) = (expected.inner, actual.inner) {
assert_eq!(exp, act);
}
}

#[test]
#[cfg(feature = "json")]
fn json_normalize_matches_array() {
let exp = json!({"people": "{...}"});
let expected = Data::json(exp);
let actual = json!({
"people": [
{
"name": "JohnDoe",
"nickname": "John",
}
]
});
let actual = Data::json(actual).normalize(NormalizeMatches {
substitutions: &Default::default(),
pattern: &expected,
});
if let (DataInner::Json(exp), DataInner::Json(act)) = (expected.inner, actual.inner) {
assert_eq!(exp, act);
}
}

#[test]
#[cfg(feature = "json")]
fn json_normalize_matches_obj() {
let exp = json!({"people": "{...}"});
let expected = Data::json(exp);
let actual = json!({
"people": {
"name": "JohnDoe",
"nickname": "John",
}
});
let actual = Data::json(actual).normalize(NormalizeMatches {
substitutions: &Default::default(),
pattern: &expected,
});
if let (DataInner::Json(exp), DataInner::Json(act)) = (expected.inner, actual.inner) {
assert_eq!(exp, act);
}
}

#[test]
#[cfg(feature = "json")]
fn json_normalize_matches_diff_order_array() {
let exp = json!({
"people": ["John", "Jane"]
});
let expected = Data::json(exp);
let actual = json!({
"people": ["Jane", "John"]
});
let actual = Data::json(actual).normalize(NormalizeMatches {
substitutions: &Default::default(),
pattern: &expected,
});
if let (DataInner::Json(exp), DataInner::Json(act)) = (expected.inner, actual.inner) {
assert_ne!(exp, act);
}
}
}

0 comments on commit f53cd76

Please sign in to comment.