Created
July 29, 2015 08:27
-
-
Save AndrewSav/9b5df0d2610c5f5cdc77 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using Newtonsoft.Json.Linq; | |
namespace Aghub.WebApi.Tests | |
{ | |
public class JsonCompare | |
{ | |
public static void PrintDiff(JToken x, JToken y) | |
{ | |
if (x == null && y == null) | |
{ | |
return; | |
} | |
if (x == null) | |
{ | |
Console.WriteLine($"{y.Path} left object is null"); | |
return; | |
} | |
if (y == null) | |
{ | |
Console.WriteLine($"{y.Path} right object is null"); | |
return; | |
} | |
if (x.Type != y.Type) | |
{ | |
Console.WriteLine($"{x.Path} left is of {x.Type} right is of {y.Type}"); | |
} | |
switch (x.Type) | |
{ | |
case JTokenType.None: | |
case JTokenType.Undefined: | |
case JTokenType.Null: | |
return; | |
case JTokenType.Object: | |
JObject xObj = (JObject)x; | |
JObject yObj = (JObject)y; | |
List<string> onlyOnTheRight = yObj.Properties().Select(i => i.Name).Except(xObj.Properties().Select(i => i.Name)).ToList(); | |
List<string> onlyOnTheLeft = xObj.Properties().Select(i => i.Name).Except(yObj.Properties().Select(i => i.Name)).ToList(); | |
List<string> common = xObj.Properties().Select(i => i.Name).Intersect(yObj.Properties().Select(i => i.Name)).ToList(); | |
foreach (string prop in onlyOnTheLeft) | |
{ | |
Console.WriteLine($"{x.Path} property {prop} is only on the left"); | |
} | |
foreach (string prop in onlyOnTheRight) | |
{ | |
Console.WriteLine($"{x.Path} property {prop} is only on the right"); | |
} | |
foreach (string prop in common) | |
{ | |
PrintDiff(xObj.Property(prop), yObj.Property(prop)); | |
} | |
return; | |
case JTokenType.Array: | |
var xArray = (JArray)x; | |
var yArray = (JArray)y; | |
for (int i = 0; i < xArray.Count && i < yArray.Count; i++) | |
{ | |
PrintDiff(xArray[i], yArray[i]); | |
} | |
if (xArray.Count != yArray.Count) | |
{ | |
Console.WriteLine($"{x.Path} left has {xArray.Count} elements right has {yArray.Count} elements"); | |
} | |
return; | |
case JTokenType.Property: | |
JProperty xProp = ((JProperty)x); | |
JProperty yProp = ((JProperty)y); | |
int compareTo = string.Compare(xProp.Name, yProp.Name, StringComparison.Ordinal); | |
if (compareTo != 0) | |
{ | |
Console.WriteLine($"{x.Path} left property is {xProp.Name} and right property is {yProp.Name}"); | |
} | |
else | |
{ | |
PrintDiff(xProp.Value, yProp.Value); | |
} | |
return; | |
case JTokenType.Integer: | |
case JTokenType.Float: | |
case JTokenType.String: | |
case JTokenType.Boolean: | |
case JTokenType.Date: | |
if (!((JValue)x).Value.Equals(((JValue)y).Value)) | |
{ | |
Console.WriteLine($"{x.Path} left:{((JValue)x).Value} right:{((JValue)y).Value}"); | |
} | |
return; | |
case JTokenType.Bytes: | |
byte[] xBytes = x.Value<byte[]>(); | |
byte[] yBytes = y.Value<byte[]>(); | |
if (xBytes.Length != yBytes.Length) | |
{ | |
Console.WriteLine($"{x.Path} left length:{xBytes.Length} right length:{yBytes.Length}"); | |
} | |
else | |
{ | |
for (int i = 0; i < xBytes.Length && i < yBytes.Length; i++) | |
{ | |
if (xBytes[i] != yBytes[i]) | |
{ | |
Console.WriteLine($"{x.Path} left and right are different"); | |
} | |
} | |
} | |
return; | |
case JTokenType.Raw: | |
case JTokenType.Comment: | |
case JTokenType.Constructor: | |
throw new ArgumentOutOfRangeException(); | |
default: | |
throw new ArgumentOutOfRangeException(); | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment