Skip to content

Instantly share code, notes, and snippets.

@AndrewSav
Created July 29, 2015 08:27
Show Gist options
  • Save AndrewSav/9b5df0d2610c5f5cdc77 to your computer and use it in GitHub Desktop.
Save AndrewSav/9b5df0d2610c5f5cdc77 to your computer and use it in GitHub Desktop.
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