diff --git a/src/dynamic_component.rs b/src/dynamic_component.rs index 058a25491..9461a42cf 100644 --- a/src/dynamic_component.rs +++ b/src/dynamic_component.rs @@ -116,7 +116,7 @@ fn dynamic_properties_to_result_vec( JsonValue::Array(values) => { let mut vec = Vec::with_capacity(values.len()); for value in values { - vec.extend_from_slice(&dynamic_properties_to_result_vec(value)?); + vec.extend(dynamic_properties_to_result_vec(value)?); } Ok(vec) } @@ -132,30 +132,35 @@ mod tests { #[test] fn test_dynamic_properties_to_result_vec() { - let mut properties = JsonValue::String(r#"{"a": 1}"#.to_string()); - assert_eq!( - dynamic_properties_to_result_vec(properties.clone()).unwrap(), - vec![JsonValue::Object( - serde_json::from_str(r#"{"a": 1}"#).unwrap() - )] - ); - - properties = JsonValue::Array(vec![JsonValue::String(r#"{"a": 1}"#.to_string())]); - assert_eq!( - dynamic_properties_to_result_vec(properties.clone()).unwrap(), - vec![serde_json::json!({"a": 1})] - ); - - properties = JsonValue::Object(serde_json::from_str(r#"{"a": 1}"#).unwrap()); + for properties in [ + serde_json::json!({"a": 1}), + serde_json::json!(r#"{"a": 1}"#), + serde_json::json!([r#"{"a": 1}"#]), + ] { + assert_eq!( + dynamic_properties_to_result_vec(properties).unwrap(), + vec![serde_json::json!({"a": 1})] + ); + } + let properties = serde_json::json!([ + [], + [{"first": {"nested": [1, 2]}}, [r#"{"second": 2}"#]], + r#"[{"third": 3}, []]"#, + {"fourth": 4} + ]); assert_eq!( - dynamic_properties_to_result_vec(properties.clone()).unwrap(), - vec![JsonValue::Object( - serde_json::from_str(r#"{"a": 1}"#).unwrap() - )] + JsonValue::Array(dynamic_properties_to_result_vec(properties).unwrap()), + serde_json::json!([ + {"first": {"nested": [1, 2]}}, {"second": 2}, {"third": 3}, {"fourth": 4} + ]) ); - - properties = JsonValue::Null; - assert!(dynamic_properties_to_result_vec(properties).is_err()); + for invalid in [ + JsonValue::Null, + serde_json::json!([{}, [null]]), + serde_json::json!(["{"]), + ] { + assert!(dynamic_properties_to_result_vec(invalid).is_err()); + } } #[test] diff --git a/src/webserver/single_or_vec.rs b/src/webserver/single_or_vec.rs index 394445170..ae87a8f80 100644 --- a/src/webserver/single_or_vec.rs +++ b/src/webserver/single_or_vec.rs @@ -63,7 +63,7 @@ impl SingleOrVec { (Self::Single(old), Self::Single(new)) => *old = new, (old, mut new) => { let mut v = old.take_vec(); - v.extend_from_slice(&new.take_vec()); + v.extend(new.take_vec()); *old = Self::Vec(v); } } @@ -122,6 +122,25 @@ mod single_or_vec_tests { ); } + #[test] + fn merges_preserve_scalar_replacement_and_array_order() { + let single = |s: &str| SingleOrVec::Single(s.into()); + let array = + |values: &[&str]| SingleOrVec::Vec(values.iter().map(|s| (*s).into()).collect()); + for (mut old, new, expected) in [ + (single("old"), single("new"), single("new")), + (single("a"), array(&["b", "c"]), array(&["a", "b", "c"])), + (array(&["a", "b"]), single("c"), array(&["a", "b", "c"])), + (array(&["a"]), array(&["b", "c"]), array(&["a", "b", "c"])), + (single("a"), array(&[]), array(&["a"])), + (array(&[]), single("b"), array(&["b"])), + (array(&[]), array(&[]), array(&[])), + ] { + old.merge(new); + assert_eq!(old, expected); + } + } + #[test] fn first_str_returns_first_value() { assert_eq!(SingleOrVec::Single("a".to_string()).first_str(), "a");