|
1 |
| -use crate::ds::key_node::KeyNode; |
2 |
| -use crate::ds::mismatch::Mismatch; |
3 |
| -use serde_json::Map; |
4 |
| -use serde_json::Value; |
5 | 1 | use std::collections::HashMap;
|
6 | 2 | use std::collections::HashSet;
|
7 | 3 |
|
| 4 | +use serde_json::Map; |
| 5 | +use serde_json::Value; |
| 6 | + |
| 7 | +use crate::constants::Message; |
| 8 | +use crate::ds::key_node::KeyNode; |
| 9 | +use crate::ds::mismatch::Mismatch; |
| 10 | + |
| 11 | +pub fn compare_jsons(a: &str, b: &str) -> Result<Mismatch, Message> { |
| 12 | + let value1 = match serde_json::from_str(a) { |
| 13 | + Ok(val1) => val1, |
| 14 | + Err(_) => return Err(Message::JSON1), |
| 15 | + }; |
| 16 | + let value2 = match serde_json::from_str(b) { |
| 17 | + Ok(val2) => val2, |
| 18 | + Err(_) => return Err(Message::JSON2), |
| 19 | + }; |
| 20 | + Ok(match_json(&value1, &value2)) |
| 21 | +} |
| 22 | + |
8 | 23 | pub fn match_json(value1: &Value, value2: &Value) -> Mismatch {
|
9 | 24 | match (value1, value2) {
|
10 | 25 | (Value::Object(a), Value::Object(b)) => {
|
@@ -102,3 +117,157 @@ fn intersect_maps(
|
102 | 117 | };
|
103 | 118 | (left, right, intersection)
|
104 | 119 | }
|
| 120 | + |
| 121 | +#[cfg(test)] |
| 122 | +mod tests { |
| 123 | + use super::*; |
| 124 | + use maplit::hashmap; |
| 125 | + use serde_json::json; |
| 126 | + |
| 127 | + #[test] |
| 128 | + fn nested_diff() { |
| 129 | + let data1 = r#"{ |
| 130 | + "a":"b", |
| 131 | + "b":{ |
| 132 | + "c":{ |
| 133 | + "d":true, |
| 134 | + "e":5, |
| 135 | + "f":9, |
| 136 | + "h":{ |
| 137 | + "i":true, |
| 138 | + "j":false |
| 139 | + } |
| 140 | + } |
| 141 | + } |
| 142 | + }"#; |
| 143 | + let data2 = r#"{ |
| 144 | + "a":"b", |
| 145 | + "b":{ |
| 146 | + "c":{ |
| 147 | + "d":true, |
| 148 | + "e":6, |
| 149 | + "g":0, |
| 150 | + "h":{ |
| 151 | + "i":false, |
| 152 | + "k":false |
| 153 | + } |
| 154 | + } |
| 155 | + } |
| 156 | + }"#; |
| 157 | + |
| 158 | + let expected_left = KeyNode::Node(hashmap! { |
| 159 | + "b".to_string() => KeyNode::Node(hashmap! { |
| 160 | + "c".to_string() => KeyNode::Node(hashmap! { |
| 161 | + "f".to_string() => KeyNode::Nil, |
| 162 | + "h".to_string() => KeyNode::Node( hashmap! { |
| 163 | + "j".to_string() => KeyNode::Nil, |
| 164 | + } |
| 165 | + ), |
| 166 | + } |
| 167 | + ), |
| 168 | + }), |
| 169 | + }); |
| 170 | + let expected_right = KeyNode::Node(hashmap! { |
| 171 | + "b".to_string() => KeyNode::Node(hashmap! { |
| 172 | + "c".to_string() => KeyNode::Node(hashmap! { |
| 173 | + "g".to_string() => KeyNode::Nil, |
| 174 | + "h".to_string() => KeyNode::Node(hashmap! { |
| 175 | + "k".to_string() => KeyNode::Nil, |
| 176 | + } |
| 177 | + ) |
| 178 | + } |
| 179 | + ) |
| 180 | + } |
| 181 | + ) |
| 182 | + }); |
| 183 | + let expected_uneq = KeyNode::Node(hashmap! { |
| 184 | + "b".to_string() => KeyNode::Node(hashmap! { |
| 185 | + "c".to_string() => KeyNode::Node(hashmap! { |
| 186 | + "e".to_string() => KeyNode::Value(json!(5), json!(6)), |
| 187 | + "h".to_string() => KeyNode::Node(hashmap! { |
| 188 | + "i".to_string() => KeyNode::Value(json!(true), json!(false)), |
| 189 | + } |
| 190 | + ) |
| 191 | + } |
| 192 | + ) |
| 193 | + } |
| 194 | + ) |
| 195 | + }); |
| 196 | + let expected = Mismatch::new(expected_left, expected_right, expected_uneq); |
| 197 | + |
| 198 | + let mismatch = compare_jsons(data1, data2).unwrap(); |
| 199 | + assert_eq!(mismatch, expected, "Diff was incorrect."); |
| 200 | + } |
| 201 | + |
| 202 | + #[test] |
| 203 | + fn no_diff() { |
| 204 | + let data1 = r#"{ |
| 205 | + "a":"b", |
| 206 | + "b":{ |
| 207 | + "c":{ |
| 208 | + "d":true, |
| 209 | + "e":5, |
| 210 | + "f":9, |
| 211 | + "h":{ |
| 212 | + "i":true, |
| 213 | + "j":false |
| 214 | + } |
| 215 | + } |
| 216 | + } |
| 217 | + }"#; |
| 218 | + let data2 = r#"{ |
| 219 | + "a":"b", |
| 220 | + "b":{ |
| 221 | + "c":{ |
| 222 | + "d":true, |
| 223 | + "e":5, |
| 224 | + "f":9, |
| 225 | + "h":{ |
| 226 | + "i":true, |
| 227 | + "j":false |
| 228 | + } |
| 229 | + } |
| 230 | + } |
| 231 | + }"#; |
| 232 | + |
| 233 | + assert_eq!( |
| 234 | + compare_jsons(data1, data2).unwrap(), |
| 235 | + Mismatch::new(KeyNode::Nil, KeyNode::Nil, KeyNode::Nil) |
| 236 | + ); |
| 237 | + } |
| 238 | + |
| 239 | + #[test] |
| 240 | + fn no_json() { |
| 241 | + let data1 = r#"{}"#; |
| 242 | + let data2 = r#"{}"#; |
| 243 | + |
| 244 | + assert_eq!( |
| 245 | + compare_jsons(data1, data2).unwrap(), |
| 246 | + Mismatch::new(KeyNode::Nil, KeyNode::Nil, KeyNode::Nil) |
| 247 | + ); |
| 248 | + } |
| 249 | + |
| 250 | + #[test] |
| 251 | + fn parse_err_source_one() { |
| 252 | + let invalid_json1 = r#"{invalid: json}"#; |
| 253 | + let valid_json2 = r#"{"a":"b"}"#; |
| 254 | + match compare_jsons(invalid_json1, valid_json2) { |
| 255 | + Ok(_) => panic!("This shouldn't be an Ok"), |
| 256 | + Err(err) => { |
| 257 | + assert_eq!(Message::JSON1, err); |
| 258 | + } |
| 259 | + }; |
| 260 | + } |
| 261 | + |
| 262 | + #[test] |
| 263 | + fn parse_err_source_two() { |
| 264 | + let valid_json1 = r#"{"a":"b"}"#; |
| 265 | + let invalid_json2 = r#"{invalid: json}"#; |
| 266 | + match compare_jsons(valid_json1, invalid_json2) { |
| 267 | + Ok(_) => panic!("This shouldn't be an Ok"), |
| 268 | + Err(err) => { |
| 269 | + assert_eq!(Message::JSON2, err); |
| 270 | + } |
| 271 | + }; |
| 272 | + } |
| 273 | +} |
0 commit comments