public void Diff_EfficientArrayDiffHugeArrays_NoStackOverflow() { const int ARRAY_SIZE = 1000; Func <int, int, JToken> hugeArrayFunc = (startIndex, count) => { var builder = new StringBuilder("["); foreach (var i in Enumerable.Range(startIndex, count)) { builder.Append($"{i},"); } builder.Append("]"); return(JToken.Parse(builder.ToString())); }; var jdp = new JsonDiffPatch(); var left = hugeArrayFunc(0, ARRAY_SIZE); var right = hugeArrayFunc(ARRAY_SIZE / 2, ARRAY_SIZE); JToken diff = null; var thread = new Thread(() => diff = jdp.Diff(left, right), 128 * 2014); thread.Start(); thread.Join(); var restored = jdp.Patch(left, diff); Assert.That(JToken.DeepEquals(restored, right)); }
public void SimplePatchTest() { var a1 = new Authentication { AuthProperties = new Dictionary <string, string> { { "Test", "value" } } }; var a2 = new Authentication { AuthProperties = new Dictionary <string, string> { { "Test", "value2" } } }; var jdp = new JsonDiffPatch(); var left = JToken.FromObject(a1); var right = JToken.FromObject(a2); JToken patch = jdp.Diff(left, right); var output = jdp.Patch(left, patch); Assert.Equal(output.ToString(), right.ToString()); }
public static T Patch <T>(this T objOld, JToken patch) { var jdp = new JsonDiffPatch(); JToken left = JToken.FromObject(objOld); var result = jdp.Patch(left, patch); return(result.ToObject <T>()); }
public static Result <T> Merge <T>(this JsonDiffPatch self, T originalObj, T variant1, T variant2) { var res = new Result <T>(); res.original = JToken.FromObject(originalObj); res.variant1 = JToken.FromObject(variant1); res.variant2 = JToken.FromObject(variant2); res.patch2 = self.Diff(res.original, res.variant2); res.mergeOf2Into1 = self.Patch(res.variant1, res.patch2); res.patch1 = self.Diff(res.original, res.variant1); res.mergeOf1Into2 = self.Patch(res.variant2, res.patch1); if (!JToken.DeepEquals(res.mergeOf2Into1, res.mergeOf1Into2)) { res.conflicts = self.Diff(res.mergeOf1Into2, res.mergeOf2Into1); } return(res); }
public void Patch_NestedComplexEditDifferentLeft_Success() { var jdp = new JsonDiffPatch(); var left = JObject.Parse(@"{ ""i"": { ""1"" : 1, ""2"": 2 }, ""j"": [0, 2, 4], ""k"": [1] }"); var right = JObject.Parse(@"{ ""i"": { ""1"" : 1, ""2"": 3 }, ""j"": [0, 2, 3], ""k"": null }"); var patch = jdp.Diff(JObject.Parse(@"{ ""k"": { ""i"": [1] } }"), right); var patched = jdp.Patch(left, patch); Assert.AreEqual(right.ToString(), patched.ToString()); }
public void Patch_ObjectApplyDelete_Success() { var jdp = new JsonDiffPatch(); var left = JObject.Parse(@"{ ""p"" : true }"); var right = JObject.Parse(@"{ }"); var patch = jdp.Diff(left, right); var patched = jdp.Patch(left, patch) as JObject; Assert.IsNotNull(patched, "Patched object"); Assert.AreEqual(0, patched.Properties().Count(), "Property Deleted"); }
public void RelativePatch_NestedArrayAddRemove_Success() { var jdp = new JsonDiffPatch(new Options { ArrayDiff = ArrayDiffMode.Relative }); var left = JObject.Parse(@"{ ""p"" : { ""names"": [""Foo"", ""Bar""], ""numbers"": [5, 10] } }"); var right = JObject.Parse(@"{ ""p"" : { ""names"": [""Foo"", ""Baz""], ""numbers"": [10, 5, 1] } }"); var other = JObject.Parse(@"{ ""p"" : { ""names"": [""Bar"", ""Boop""], ""numbers"": [5, 10, 1] } }"); var patch = jdp.Diff(left, right); var patched = jdp.Patch(left, patch); var expectedPatched = JObject.Parse(@"{ ""p"" : { ""names"": [""Foo"", ""Baz""], ""numbers"": [5, 10, 1]} }"); var patchedOther = jdp.Patch(other, patch); var expectedPatchedOther = JObject.Parse(@"{ ""p"" : { ""names"": [""Boop"", ""Baz""], ""numbers"": [5, 10, 1]} }"); Assert.True(JToken.DeepEquals(expectedPatched, patched)); Assert.True(JToken.DeepEquals(expectedPatchedOther, patchedOther)); }
public void RelativePatch_ArrayAddRemove_Success() { var jdp = new JsonDiffPatch(new Options { ArrayDiff = ArrayDiffMode.Relative }); var left = JObject.Parse(@"{ ""p"" : [1, 2, 3] }"); var right = JObject.Parse(@"{ ""p"" : [2, 3, 4] }"); var other = JObject.Parse(@"{ ""p"" : [2, 1, 6, 7] }"); var patch = jdp.Diff(left, right); var patched = jdp.Patch(left, patch); var expectedPatched = JObject.Parse(@"{ ""p"" : [2, 3, 4] }"); var patchedOther = jdp.Patch(other, patch); var expectedPatchedOther = JObject.Parse(@"{ ""p"" : [2, 6, 7, 4] }"); Assert.True(JToken.DeepEquals(expectedPatched, patched)); Assert.True(JToken.DeepEquals(expectedPatchedOther, patchedOther)); }
private async Task SnapshotAsync(CancellationToken cancellation) { var snapshotRevisionThreshold = _options.SnapshotRevisionThreshold; if (snapshotRevisionThreshold < 0) { snapshotRevisionThreshold = 20; } using (var scope = _serviceProvider.CreateScope()) { var scopedServiceProvider = scope.ServiceProvider; var entityStorageEngine = scopedServiceProvider.GetRequiredService <IEntityStorageEngine>(); var enumerator = default(IAsyncEnumerator <IStream>); try { enumerator = _streamStore.OpenStreamsToSnapshotAsync(snapshotRevisionThreshold, cancellation).GetEnumerator(); while (await enumerator.MoveNext(cancellation)) { var stream = enumerator.Current; if (stream.Snapshot == null && !stream.Commits.Any()) { continue; } var serializedEntity = default(JToken); if (stream.Snapshot == null) { serializedEntity = StreamRoot; } else { serializedEntity = JToken.Parse(CompressionHelper.Unzip(stream.Snapshot.Payload as byte[])); } foreach (var commit in stream.Commits) { serializedEntity = _differ.Patch(serializedEntity, JToken.Parse(CompressionHelper.Unzip(commit.Body as byte[]))); } await stream.AddSnapshotAsync(CompressionHelper.Zip(serializedEntity.ToString()), cancellation); } } finally { enumerator?.Dispose(); } } }
public void ComplexPatchTest() { var obj1 = JsonConvert.DeserializeObject <Workspace>("{\"id\":\"d89c9279-1e45-41a7-9330-c35429509856\",\"parentId\":\"root\",\"Name\":\"magic\",\"Methods\":[\"GET\",\"POST\",\"PUT\",\"DELETE\",\"HEAD\",\"OPTIONS\",\"PATCH\",\"MERGE\",\"COPY\"],\"OpenItemIds\":[\"62b0aa85-9d5c-4fc2-b4cd-d2e80558e08e\",\"7c4a8648-24e1-48e0-b2f9-2e30ab8f2b36\"],\"TempItems\":[],\"Items\":[{\"id\":\"7c4a8648-24e1-48e0-b2f9-2e30ab8f2b36\",\"parentId\":null,\"IsTemporary\":false,\"Properties\":{\"RequestPivotIndex\":0},\"Url\":{\"Base\":\"\",\"Queries\":[]},\"Auth\":{\"AuthType\":0,\"AuthProperties\":{}},\"Body\":{\"BodyType\":0,\"JsonBody\":null,\"XmlBody\":null,\"TextBody\":null,\"FormEncodedData\":[],\"FormDataList\":[],\"BinaryFilePath\":null},\"MockData\":{\"Body\":null,\"StatusCode\":200,\"ContentType\":\"application/json\"},\"Children\":[],\"Headers\":[],\"ChainingRules\":[],\"Type\":1,\"Name\":\"My request\",\"IsExpanded\":false,\"Method\":\"GET\",\"Response\":null},{\"id\":\"fa796649-43a2-4dfb-8a87-01b46382ab14\",\"parentId\":null,\"IsTemporary\":false,\"Properties\":{},\"Url\":{\"Base\":null,\"Queries\":[]},\"Auth\":{\"AuthType\":0,\"AuthProperties\":null},\"Body\":{\"BodyType\":0,\"JsonBody\":null,\"XmlBody\":null,\"TextBody\":null,\"FormEncodedData\":[],\"FormDataList\":[],\"BinaryFilePath\":null},\"MockData\":{\"Body\":null,\"StatusCode\":200,\"ContentType\":\"application/json\"},\"Children\":[{\"id\":\"62b0aa85-9d5c-4fc2-b4cd-d2e80558e08e\",\"parentId\":null,\"IsTemporary\":false,\"Properties\":{\"RequestPivotIndex\":0},\"Url\":{\"Base\":\"44444444444444444444444444444444444?\",\"Queries\":[{\"Key\":\"3333\",\"Value\":\"232424\",\"Enabled\":true,\"Private\":false,\"Type\":0}]},\"Auth\":{\"AuthType\":2,\"AuthProperties\":{\"BasicUsername\":\"asdf\",\"BasicPassword\":\"asdf\",\"DigestUsername\":\"asdf\",\"DigestPassword\":\"asdf\",\"BearerToken\":\"asdf\",\"OAuth2GrantType\":\"authorization_code\",\"OAuth2AccessTokenUrl\":\"asf\",\"OAuth2ClientSecret\":\"asdf\",\"OAuth1ConsumerSecret\":\"asdf\",\"OAuth1ConsumerKey\":\"asdf\"}},\"Body\":{\"BodyType\":0,\"JsonBody\":null,\"XmlBody\":null,\"TextBody\":null,\"FormEncodedData\":[],\"FormDataList\":[],\"BinaryFilePath\":null},\"MockData\":{\"Body\":\"{salfaslkdfj}\",\"StatusCode\":200,\"ContentType\":\"application/json\"},\"Children\":[],\"Headers\":[],\"ChainingRules\":[],\"Type\":1,\"Name\":\"234234\",\"IsExpanded\":false,\"Method\":\"GET\",\"Response\":null}],\"Headers\":[],\"ChainingRules\":[],\"Type\":2,\"Name\":\"Untitled\",\"IsExpanded\":true,\"Method\":\"GET\",\"Response\":null}],\"HistoryItems\":[],\"Environments\":[{\"id\":null,\"parentId\":null,\"Name\":\"Base\",\"EnvironmentType\":1,\"Variables\":[{\"Key\":\"env\",\"Value\":\"value\",\"Enabled\":true,\"Private\":false,\"Type\":3}]}],\"Cookies\":null}"); var obj2 = JsonConvert.DeserializeObject <Workspace>("{\"id\":\"d89c9279-1e45-41a7-9330-c35429509856\",\"parentId\":\"daniel\",\"Name\":\"magic\",\"Methods\":[\"GET\",\"POST\",\"PUT\",\"DELETE\",\"HEAD\",\"OPTIONS\",\"PATCH\",\"MERGE\",\"COPY\"],\"OpenItemIds\":[\"62b0aa85-9d5c-4fc2-b4cd-d2e80558e08e\",\"7c4a8648-24e1-48e0-b2f9-2e30ab8f2b36\"],\"TempItems\":[],\"Items\":[{\"id\":\"7c4a8648-24e1-48e0-b2f9-2e30ab8f2b36\",\"parentId\":null,\"IsTemporary\":false,\"Properties\":{\"RequestPivotIndex\":1},\"Url\":{\"Base\":\"\",\"Queries\":[]},\"Auth\":{\"AuthType\":0,\"AuthProperties\":{}},\"Body\":{\"BodyType\":0,\"JsonBody\":null,\"XmlBody\":null,\"TextBody\":null,\"FormEncodedData\":[],\"FormDataList\":[],\"BinaryFilePath\":null},\"MockData\":{\"Body\":null,\"StatusCode\":200,\"ContentType\":\"application/json\"},\"Children\":[],\"Headers\":[],\"ChainingRules\":[],\"Type\":1,\"Name\":\"My request\",\"IsExpanded\":false,\"Method\":\"GET\",\"Response\":null},{\"id\":\"fa796649-43a2-4dfb-8a87-01b46382ab14\",\"parentId\":null,\"IsTemporary\":false,\"Properties\":{},\"Url\":{\"Base\":null,\"Queries\":[]},\"Auth\":{\"AuthType\":0,\"AuthProperties\":null},\"Body\":{\"BodyType\":0,\"JsonBody\":null,\"XmlBody\":null,\"TextBody\":null,\"FormEncodedData\":[],\"FormDataList\":[],\"BinaryFilePath\":null},\"MockData\":{\"Body\":null,\"StatusCode\":200,\"ContentType\":\"application/json\"},\"Children\":[{\"id\":\"62b0aa85-9d5c-4fc2-b4cd-d2e80558e08e\",\"parentId\":null,\"IsTemporary\":false,\"Properties\":{\"RequestPivotIndex\":0},\"Url\":{\"Base\":\"44444444444444444444444444444444444?\",\"Queries\":[{\"Key\":\"123456\",\"Value\":\"alllllll\",\"Enabled\":false,\"Private\":false,\"Type\":0}]},\"Auth\":{\"AuthType\":2,\"AuthProperties\":{\"BasicUsername\":\"asdf\",\"BasicPassword\":\"asdf\",\"DigestUsername\":\"asdf\",\"DigestPassword\":\"asdf\",\"BearerToken\":\"asdf\",\"OAuth2GrantType\":\"authorization_code\",\"OAuth2AccessTokenUrl\":\"asf\",\"OAuth2ClientSecret\":\"asdf\",\"OAuth1ConsumerSecret\":\"asdf\",\"OAuth1ConsumerKey\":\"asdf\"}},\"Body\":{\"BodyType\":0,\"JsonBody\":null,\"XmlBody\":null,\"TextBody\":null,\"FormEncodedData\":[],\"FormDataList\":[],\"BinaryFilePath\":null},\"MockData\":{\"Body\":\"{salfaslkdfj}\",\"StatusCode\":200,\"ContentType\":\"application/json\"},\"Children\":[],\"Headers\":[],\"ChainingRules\":[],\"Type\":1,\"Name\":\"234234\",\"IsExpanded\":false,\"Method\":\"GET\",\"Response\":null}],\"Headers\":[],\"ChainingRules\":[],\"Type\":2,\"Name\":\"Untitled\",\"IsExpanded\":true,\"Method\":\"GET\",\"Response\":null}],\"HistoryItems\":[],\"Environments\":[{\"id\":null,\"parentId\":null,\"Name\":\"Base\",\"EnvironmentType\":1,\"Variables\":[{\"Key\":\"env\",\"Value\":\"value\",\"Enabled\":true,\"Private\":false,\"Type\":3}]}],\"Cookies\":null}"); var jdp = new JsonDiffPatch(); var left = JToken.FromObject(obj1); var right = JToken.FromObject(obj2); JToken patch = jdp.Diff(left, right); var output = jdp.Patch(left, patch); Assert.Equal(output.ToString(), right.ToString()); }
public void Patch_ObjectApplyEditText_Success() { var jdp = new JsonDiffPatch(); var left = JObject.Parse(@"{ ""p"" : ""bla1h111111111111112312weldjidjoijfoiewjfoiefjefijfoejoijfiwoejfiewjfiwejfowjwifewjfejdewdwdewqwertyqwertifwiejifoiwfei"" }"); var right = JObject.Parse(@"{ ""p"" : ""blah1"" }"); var patch = jdp.Diff(left, right); var patched = jdp.Patch(left, patch) as JObject; Assert.IsNotNull(patched, "Patched object"); Assert.AreEqual(1, patched.Properties().Count(), "Property"); Assert.AreEqual(JTokenType.String, patched.Property("p").Value.Type, "String Type"); Assert.AreEqual("blah1", patched.Property("p").Value.ToString(), "String value"); }
public void Patch_ObjectApplyEdit_Success() { var jdp = new JsonDiffPatch(); var left = JObject.Parse(@"{ ""p"" : false }"); var right = JObject.Parse(@"{ ""p"" : true }"); var patch = jdp.Diff(left, right); var patched = jdp.Patch(left, patch) as JObject; Assert.IsNotNull(patched, "Patched object"); Assert.AreEqual(1, patched.Properties().Count(), "Property"); Assert.AreEqual(JTokenType.Boolean, patched.Property("p").Value.Type); Assert.IsTrue(patched.Property("p").Value.ToObject<bool>(), "Patched Property"); }
public void RelativePatch_ArrayAddRemoveObject_Success() { var jdp = new JsonDiffPatch(new Options { ArrayDiff = ArrayDiffMode.Relative }); var left = JObject.Parse(@"{ ""p"" : [ {""x"": 5}, {""x"": 10} ] }"); var right = JObject.Parse(@"{ ""p"" : [ {""x"": 10}, {""x"": 15}, {""x"": 18} ] }"); var other = JObject.Parse(@"{ ""p"" : [ {""x"": 15}, {""x"": 20} ] }"); var patch = jdp.Diff(left, right); var patched = jdp.Patch(left, patch); var expectedPatched = JObject.Parse(@"{ ""p"" : [ {""x"": 10}, {""x"": 15}, {""x"": 18} ] }"); var patchedOther = jdp.Patch(other, patch); var expectedPatchedOther = JObject.Parse(@"{ ""p"" : [ {""x"": 15}, {""x"": 20}, {""x"": 18}] }"); Assert.True(JToken.DeepEquals(expectedPatched, patched)); var j = patchedOther.ToString(); Assert.True(JToken.DeepEquals(expectedPatchedOther, patchedOther)); }
public void Test1() { var jdp = new JsonDiffPatch(); //var left = JToken.Parse(@"{ ""key"": false, ""text"" :""The program '[3572] dotnet.exe: Program Trace' has exited with code 0 (0x0)."" }"); var left = JToken.Parse(@"{}"); var right = JToken.Parse(@"{ ""key"": true, ""text"" :""The program dotnet '[3572] : Program Traces' has exited with code 0 (0x0)."" }"); JToken patch = jdp.Diff(left, right); Console.WriteLine(patch.ToString()); var output = jdp.Patch(left, patch); Console.WriteLine(output.ToString()); }
private void CalculatePatch(string originalEntity, AuditEntity auditEntity) { var jdp = new JsonDiffPatch(); foreach (var patch in GetPatches(auditEntity.Application, auditEntity.EntityId, auditEntity.EntityType)) { originalEntity = jdp.Patch(originalEntity, patch); } var left = JToken.Parse(originalEntity); var right = JToken.Parse(auditEntity.Entity); var newPatch = jdp.Diff(left, right); auditEntity.Entity = null; auditEntity.Patch = newPatch.ToString(Formatting.None); }
public async Task <string> GetDiff( IHistoryRepository historyRepository, string type, string id, string data) { var historyList = await historyRepository.FindByElementIdAsync(id, type); historyList = historyList.Reverse(); var jdp = new JsonDiffPatch(); string patch = @"{}"; foreach (var history in historyList) { patch = jdp.Patch(patch, history.Diff); } var output = jdp.Diff(patch, data); return(output); }
public void DiffyPatch() { JsonDiffPatch jsonDiff = new JsonDiffPatch(); JToken x = JObject.Parse(File.ReadAllText(@"D:\20170824precios.json")); JToken y = JObject.Parse(File.ReadAllText(@"D:\20170825precios.json")); JToken diff = jsonDiff.Diff(x, y); JToken patch = jsonDiff.Patch(x, diff); try { File.WriteAllText(jsonFilesDirectory + "diff.json", JsonConvert.SerializeObject(diff, Formatting.Indented)); File.WriteAllText(jsonFilesDirectory + "patch.json", JsonConvert.SerializeObject(patch, Formatting.Indented)); } catch (Exception) { throw; } }
public async System.Threading.Tasks.Task SaveAsync(string content, string id, string userId, CheckPointType checkPointType) { var history = await _historyService.GetHistoryAsync(id); var jsonDiffPatch = new JsonDiffPatch(); var left = JToken.Parse("{}"); if (history == null) { history = new HistoryDbModel() { CheckPoints = new List <CheckPoint>(), ElementId = id, }; } else { foreach (var checkpoint in history.CheckPoints) { var patch = JToken.Parse(checkpoint.Patch); left = jsonDiffPatch.Patch(left, patch); } } var checkPoint = new CheckPoint() { Id = Guid.NewGuid().ToString(), UserId = userId, CheckPointType = checkPointType, Hash = Hash(content) }; var lastRight = JToken.Parse(content); checkPoint.Patch = jsonDiffPatch.Diff(left, lastRight).ToString(); await _historyService.AddAsync(id, checkPoint); }
public void Patch_NullLeft_Exception() { var jdp = new JsonDiffPatch(); var patch = JToken.Parse(@"[true]"); JToken result = jdp.Patch(null, patch); Assert.IsNotNull(result); Assert.AreEqual(JTokenType.Boolean, result.Type); Assert.AreEqual(true, result.ToObject<bool>()); }
public void Patch_ArrayPatchRemove_Success() { var jdp = new JsonDiffPatch(new Options { ArrayDiff = ArrayDiffMode.Efficient }); var left = JToken.Parse(@"[1,2,3]"); var right = JToken.Parse(@"[1,2]"); var patch = jdp.Diff(left, right); var patched = jdp.Patch(left, patch); Assert.AreEqual(right.ToString(), patched.ToString()); }
public void Patch_ArrayPatchModify_Success() { var jdp = new JsonDiffPatch(new Options { ArrayDiff = ArrayDiffMode.Efficient }); var left = JToken.Parse(@"[1,3,{""p"":false}]"); var right = JToken.Parse(@"[1,4,{""p"": [1] }]"); var patch = jdp.Diff(left, right); var patched = jdp.Patch(left, patch); Assert.AreEqual(right.ToString(), patched.ToString()); }
public void Patch_ArrayPatchComplex_Success() { var jdp = new JsonDiffPatch(new Options { ArrayDiff = ArrayDiffMode.Efficient }); var left = JToken.Parse(@"{""p"": [1,2,[1],false,""11111"",3,{""p"":false},10,10] }"); var right = JToken.Parse(@"{""p"": [1,2,[1,3],false,""11112"",3,{""p"":true},10,10] }"); var patch = jdp.Diff(left, right); var patched = jdp.Patch(left, patch); Assert.AreEqual(right.ToString(), patched.ToString()); }
public void Patch_ArrayPatchMoving_Success() { var jdp = new JsonDiffPatch(new Options { ArrayDiff = ArrayDiffMode.Efficient }); var left = JToken.Parse(@"[0,1,2,3,4,5,6,7,8,9,10]"); var right = JToken.Parse(@"[10,0,1,7,2,4,5,6,88,9,3]"); var patch = JToken.Parse(@"{ ""8"": [88], ""_t"": ""a"", ""_3"": ["""", 10, 3], ""_7"": ["""", 3, 3], ""_8"": [8, 0, 0], ""_10"": ["""", 0, 3] }"); var patched = jdp.Patch(left, patch); Assert.AreEqual(right.ToString(), patched.ToString()); }
public void Patch_ArrayPatchMoveDeletingNonConsecutive_Success() { var jdp = new JsonDiffPatch(new Options { ArrayDiff = ArrayDiffMode.Efficient }); var left = JToken.Parse(@"[0,1,3,4,5]"); var right = JToken.Parse(@"[0,5,3]"); var patch = JToken.Parse(@"{""_t"": ""a"", ""_1"": [ 1, 0, 0], ""_3"": [4,0, 0],""_4"": [ """", 1, 3 ]}"); var patched = jdp.Patch(left, patch); Assert.AreEqual(right.ToString(), patched.ToString()); }
public void Patch_NestedComplexEdit_Success() { var jdp = new JsonDiffPatch(); var left = JObject.Parse(@"{ ""i"": { ""1"" : 1, ""2"": 2 }, ""j"": [0, 2, 4], ""k"": [1] }"); var right = JObject.Parse(@"{ ""i"": { ""1"" : 1, ""2"": 3 }, ""j"": [0, 2, 3], ""k"": null }"); var patch = jdp.Diff(left, right); var patched = jdp.Patch(left, patch); Assert.AreEqual(right.ToString(), patched.ToString()); }