Merge pull request #43 from adam-mccoy/master

Fix obscure bug with array sorting
master
William Bishop 2023-01-16 16:29:11 -06:00 committed by GitHub
commit 88937bdf8e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 50 additions and 6 deletions

View File

@ -1,3 +1,4 @@
using System.Linq;
using JsonDiffPatchDotNet.Formatters.JsonPatch;
using Newtonsoft.Json.Linq;
using NUnit.Framework;
@ -123,6 +124,49 @@ namespace JsonDiffPatchDotNet.UnitTests
}
[Test]
public void Format_SortsRemoveOperations_Success()
{
const string patchJson = @"
{
""a"": {
""a"": [0,0,0],
""b"": [0,0,0],
""c"": {
""a"": {
""a"": [0,0,0],
""b"": [0,0,0],
""c"": [0,0,0],
""d"": [0,0,0],
""e"": [0,0,0],
""f"": [0,0,0]
}
}
},
""b"": [0,0,0],
""c"": [0,0,0],
""d"": [0,0,0],
""e"": [0,0,0],
""f"": [0,0,0],
""g"": [0,0,0],
""h"": [0,0,0],
""i"": {
""a"": {
""a"": {
""_t"": ""a"",
""_0"": [0,0,0],
""_1"": [0,0,0]
}
}
}
}
";
var patch = JToken.Parse(patchJson);
var operations = Formatter.Format(patch);
var paths = operations.Select(o => o.Path).ToList();
// removal of the array item at index 1 should come before the item at index 0
Assert.Less(paths.IndexOf("/i/a/a/1"), paths.IndexOf("/i/a/a/0"));
public void Format_EscapeOfJsonPointer_Success()
{
var left = JObject.Parse(@"{ ""a/b"": ""a"", ""a~b"": ""ab"", ""a/~b"": ""abb"",""a/b/c~"": ""abc"" }");

View File

@ -101,8 +101,8 @@ namespace JsonDiffPatchDotNet.Formatters.JsonPatch
var removeOpsOtherOps = PartitionRemoveOps(result);
var removeOps = removeOpsOtherOps[0];
var otherOps = removeOpsOtherOps[1];
Array.Sort(removeOps, new RemoveOperationComparer());
return removeOps.Concat(otherOps).ToList();
var removeOpsReverse = removeOps.OrderBy(x => x.Path, new PathComparer());
return removeOpsReverse.Concat(otherOps).ToList();
}
private IList<Operation[]> PartitionRemoveOps(IList<Operation> result)
@ -116,15 +116,15 @@ namespace JsonDiffPatchDotNet.Formatters.JsonPatch
return new List<Operation[]> {left.ToArray(), right.ToArray()};
}
private class RemoveOperationComparer : IComparer<Operation>
private class PathComparer : IComparer<string>
{
public int Compare(Operation a, Operation b)
public int Compare(string a, string b)
{
if (a == null) throw new ArgumentNullException(nameof(a));
if (b == null) throw new ArgumentNullException(nameof(b));
var splitA = a.Path.Split('/');
var splitB = b.Path.Split('/');
var splitA = a.Split('/');
var splitB = b.Split('/');
return splitA.Length != splitB.Length
? splitA.Length - splitB.Length