public void AbleToAddObjectListItemThenApplyViaPatch() { var testObj = TestClass.CreateSimpleInstance(); testObj.PopulateObjectListOnTestClass(); var updatedTestObj = TestClass.CreateSimpleInstance(); updatedTestObj.PopulateObjectListOnTestClass(); updatedTestObj.ListOfObjectProperty.Add(new TestClass { StringProperty = "added" }); var diff = ObjectDiffPatch.GenerateDiff(testObj, updatedTestObj); var updatePatch = diff.NewValues.ToString(); var objToUpdate = TestClass.CreateSimpleInstance(); objToUpdate.PopulateObjectListOnTestClass(); var updatedObj = ObjectDiffPatch.PatchObject(objToUpdate, updatePatch); Assert.Equal(updatedTestObj.ListOfObjectProperty.Count, updatedObj.ListOfObjectProperty.Count); var addedListItem = updatedObj.ListOfObjectProperty.SingleOrDefault(obj => obj != null && obj.StringProperty == "added"); Assert.NotNull(addedListItem); }
public void GetConfig() { #region Test Data string email = "*****@*****.**"; string pass = "******"; JObject expectedResponse = JObject.Parse(System.IO.File.ReadAllText(@"C:\Users\e.kovalenko\Visual Studio 2017\Projects\UITestDirest2\ApiTestDirect2\Resources\Json responses\GetConfig.json")); #endregion string resposeOut; //получаем токин пользователя [email protected] ApiHelper.Login(BaseUrlApi, email, pass, out resposeOut); //звапрашиваем GetConfig для пользователя [email protected] JObject actualResponse; ApiHelper.GetConfig(BaseUrlApi, resposeOut, out actualResponse); var resultDif = ObjectDiffPatch.GenerateDiff(expectedResponse, actualResponse); if (!resultDif.AreEqual) { Log.Error(String.Format("\r\nExpected response \r\n {0}\r\n\r\nActual response \r\n{1}\r\n", expectedResponse, actualResponse)); } Assert.IsTrue(resultDif.AreEqual, String.Format("Expected response and Actual response see in log.\nOldValues:\n{0}\nNewValues:\n{1}", resultDif.OldValues, resultDif.NewValues)); }
public void AbleToDiffAndPathListOfObjects() { var testObj = TestClass.CreateSimpleInstance(); testObj.ListOfObjectProperty = new List <TestClass> (); testObj.ListOfObjectProperty.Add(new TestClass { StringProperty = "one", IntProperty = 1 }); testObj.ListOfObjectProperty.Add(new TestClass { StringProperty = "two", IntProperty = 2, Map = new Dictionary <string, string> { { "m1", "1" }, { "m2", "2" } } }); testObj.ListOfObjectProperty.Add(new TestClass { StringProperty = "three", IntProperty = 3, Map = new Dictionary <string, string> { { "m1", "1" } } }); testObj.ListOfObjectProperty.Add(new TestClass { StringProperty = "four", IntProperty = 4 }); var snapshot = ObjectDiffPatch.Snapshot(testObj); testObj.ListOfObjectProperty.Add(testObj.ListOfObjectProperty[0]); testObj.ListOfObjectProperty.RemoveAt(0); var diff = ObjectDiffPatch.GenerateDiff(snapshot, testObj); var revertedObj = ObjectDiffPatch.PatchObject(testObj, diff.OldValues.ToString()); Assert.Equal("one", revertedObj.ListOfObjectProperty[0].StringProperty); Assert.Equal("two", revertedObj.ListOfObjectProperty[1].StringProperty); }
public void AbleToHandleCircularReferences_All() { CircularObject original = new CircularObject(); original.AddChild(); original.AddChild(); original.FirstChild.AddChild(); var snapshot = ObjectDiffPatch.Snapshot(original).ToString(); ObjectDiffPatch.DefaultSerializerSettings.PreserveReferencesHandling = Newtonsoft.Json.PreserveReferencesHandling.All; // see http://www.newtonsoft.com/json/help/html/PreserveReferencesHandlingObject.htm var snapshotWithRefs = ObjectDiffPatch.Snapshot(original).ToString(); Assert.NotEqual(snapshot, snapshotWithRefs); var updated = ObjectDiffPatch.PatchObject(new CircularObject(), snapshotWithRefs); // they should be equal Assert.Equal(Newtonsoft.Json.JsonConvert.SerializeObject(updated, ObjectDiffPatch.DefaultSerializerSettings), Newtonsoft.Json.JsonConvert.SerializeObject(original, ObjectDiffPatch.DefaultSerializerSettings)); Assert.NotNull(updated.FirstChild); Assert.NotNull(updated.FirstChild.Parent); Assert.NotNull(updated.FirstChild.FirstChild); // revertBack var diff = ObjectDiffPatch.GenerateDiff(original, new CircularObject()); updated = ObjectDiffPatch.PatchObject(original, diff.NewValues); //ensure everything is alright Assert.Null(updated.FirstChild); Assert.Null(updated.Parent); Assert.Null(updated.Children); }
public void AbleToDiffEqualObjects() { var source = TestClass.CreateSimpleInstance(); var target = TestClass.CreateSimpleInstance(); var diff = ObjectDiffPatch.GenerateDiff(source, target); Assert.True(diff.AreEqual); }
public void AbleToDiffAndPathDictionary() { var testObj = TestClass.CreateSimpleInstance(); testObj.Map = new Dictionary <string, string> (); testObj.Map.Add("1", "one"); testObj.Map.Add("2", "two"); testObj.Map.Add("3", "three"); testObj.Map.Add("4", "four"); testObj.Childs = new Dictionary <string, TestClass> (); testObj.Childs.Add("c1", new TestClass { StringProperty = "one", IntProperty = 1 }); testObj.Childs.Add("c2", new TestClass { StringProperty = "two", IntProperty = 2 }); testObj.Childs.Add("c3", new TestClass { StringProperty = "three", IntProperty = 3 }); var snapshot = ObjectDiffPatch.Snapshot(testObj); testObj.Map["2"] = "updated string"; testObj.Map.Remove("3"); testObj.Map.Remove("4"); testObj.Map.Add("5", "five"); testObj.Map.Add("6", "six"); testObj.Childs["c1"].IntProperty = 2; testObj.Childs["c2"].StringProperty = "updated string"; testObj.Childs["c2"].IntProperty = 100; testObj.Map.Remove("c3"); testObj.Childs.Add("c4", TestClass.CreateSimpleInstance()); testObj.Childs.Add("c5", TestClass.CreateSimpleInstance()); var diff = ObjectDiffPatch.GenerateDiff(snapshot, testObj); var revertedObj = ObjectDiffPatch.PatchObject(testObj, diff.OldValues.ToString()); Assert.Equal("one", revertedObj.Map["1"]); Assert.Equal("two", revertedObj.Map["2"]); Assert.Equal("three", revertedObj.Map["3"]); Assert.Equal("four", revertedObj.Map["4"]); Assert.False(revertedObj.Map.ContainsKey("5")); Assert.False(revertedObj.Map.ContainsKey("6")); Assert.Equal("one", revertedObj.Childs["c1"].StringProperty); Assert.Equal(1, revertedObj.Childs["c1"].IntProperty); Assert.Equal("two", revertedObj.Childs["c2"].StringProperty); Assert.Equal(2, revertedObj.Childs["c2"].IntProperty); Assert.Equal("three", revertedObj.Childs["c3"].StringProperty); Assert.False(revertedObj.Map.ContainsKey("c4")); Assert.False(revertedObj.Map.ContainsKey("c5")); }
public void AbleToDiffDoubleProperty() { var source = TestClass.CreateSimpleInstance(); var target = TestClass.CreateSimpleInstance(); source.DoubleProperty = 123; target.DoubleProperty = 234; var diff = ObjectDiffPatch.GenerateDiff(source, target); Assert.False(diff.AreEqual); }
public void AbleToDiffStringPropertyWithTargetNull() { var source = TestClass.CreateSimpleInstance(); var target = TestClass.CreateSimpleInstance(); source.StringProperty = null; target.StringProperty = "123"; var diff = ObjectDiffPatch.GenerateDiff(source, target); Assert.False(diff.AreEqual); }
public void AbleToCompareWithNull() { var testObj = TestClass.CreateSimpleInstance(); var diff = ObjectDiffPatch.GenerateDiff(testObj, null); Assert.Equal(diff.OldValues.Value <string> ("StringProperty"), testObj.StringProperty); Assert.Null(diff.NewValues); diff = ObjectDiffPatch.GenerateDiff(null, testObj); Assert.Equal(diff.NewValues.Value <string> ("StringProperty"), testObj.StringProperty); Assert.Null(diff.OldValues); }
static void Main(string[] args) { var originalObj = File.ReadAllText("source.json"); var updatedObj = File.ReadAllText("target.json"); var diff = ObjectDiffPatch.GenerateDiff(JsonConvert.DeserializeObject(originalObj.ToString()), JsonConvert.DeserializeObject(updatedObj.ToString())); // original properties values Console.WriteLine(diff.OldValues.ToString()); // updated properties values Console.WriteLine(diff.NewValues.ToString()); }
public void AbleToDiffListOfStringsWithSourceNull() { var source = TestClass.CreateSimpleInstance(); var target = TestClass.CreateSimpleInstance(); source.ListOfStringProperty = new List <string> { "1", "2" }; target.ListOfStringProperty = null; var diff = ObjectDiffPatch.GenerateDiff(source, target); Assert.False(diff.AreEqual); }
public void AbleToDiffListOfDouble() { var source = TestClass.CreateSimpleInstance(); var target = TestClass.CreateSimpleInstance(); source.ListOfDoubleProperty = new List <double> { 1, 2, 3 }; target.ListOfDoubleProperty = new List <double> { 1, 2, 4 }; var diff = ObjectDiffPatch.GenerateDiff(source, target); Assert.False(diff.AreEqual); }
public void GetRegistrationJurisdictions() { #region Test Data JObject expectedResponse = JObject.Parse(System.IO.File.ReadAllText(jsonResponses + "GetRegistrationJurisdictions.json")); #endregion JObject actualResponse; APIHelper.GetRegistrationJurisdictions(BaseUrlApi, out actualResponse); var resultDif = ObjectDiffPatch.GenerateDiff(expectedResponse, actualResponse); if (!resultDif.AreEqual) { Log.Error(String.Format("\r\nExpected response \r\n {0}\r\n\r\nActual response \r\n{1}\r\n", expectedResponse, actualResponse)); } Assert.IsTrue(resultDif.AreEqual, String.Format("Expected response and Actual response see in log.\nOldValues:\n{0}\nNewValues:\n{1}", resultDif.OldValues, resultDif.NewValues)); }
public void AbleToSnapshotSimpleObject() { var testObj = TestClass.CreateSimpleInstance(); var snapshot = ObjectDiffPatch.Snapshot(testObj); // update the original instance testObj.StringProperty = "this is an updated string"; var diff = ObjectDiffPatch.GenerateDiff(snapshot, testObj); Assert.Equal(diff.NewValues.Value <string> ("StringProperty"), testObj.StringProperty); Assert.Equal(diff.OldValues.Value <string> ("StringProperty"), snapshot.Value <string> ("StringProperty")); diff = ObjectDiffPatch.GenerateDiff(snapshot, ObjectDiffPatch.Snapshot(testObj)); Assert.Equal(diff.NewValues.Value <string> ("StringProperty"), testObj.StringProperty); Assert.Equal(diff.OldValues.Value <string> ("StringProperty"), snapshot.Value <string> ("StringProperty")); }
public void GetPaymentMethods(string authority, string country) { #region Test Data Dictionary <string, string> expList = new Dictionary <string, string>(); expList.Add("mena_AE", System.IO.File.ReadAllText(jsonResponses + "GetPaymentMethods.authority=mena.country=AE.json", Encoding.Default)); JObject expectedResponse = JObject.Parse(expList[authority + "_" + country]); #endregion JObject actualResponse; APIHelper.GetPaymentMethods(BaseUrlApi, authority, country, out actualResponse); var resultDif = ObjectDiffPatch.GenerateDiff(expectedResponse, actualResponse); if (!resultDif.AreEqual) { Log.Error(String.Format("\r\nExpected response \r\n {0}\r\n\r\nActual response \r\n{1}\r\n", expectedResponse, actualResponse)); } Assert.IsTrue(resultDif.AreEqual, String.Format("Expected response and Actual response see in log.\nOldValues:\n{0}\nNewValues:\n{1}", resultDif.OldValues, resultDif.NewValues)); }
public void GetTradingAccountSetupRealProfi(string authority, string country, string platform) { #region Test Data Dictionary <string, string> expList = new Dictionary <string, string>(); expList.Add("mena_AE_mt4m", System.IO.File.ReadAllText(jsonResponses + "GetTradingAccountSetupRealProfi.authority=mena.country=AE.platform=mt4m.json", Encoding.Default)); expList.Add("mena_AE_xtrader", System.IO.File.ReadAllText(jsonResponses + "GetTradingAccountSetupRealProfi.authority=mena.country=AE.platform=xtrader.json", Encoding.Default)); JObject expectedResponse = JObject.Parse(expList[authority + "_" + country + "_" + platform]); #endregion JObject actualResponse; ApiHelper.GetTradingAccountSetup(BaseUrlApi, "true", "true", authority, country, platform, out actualResponse); var resultDif = ObjectDiffPatch.GenerateDiff(expectedResponse, actualResponse); if (!resultDif.AreEqual) { Log.Error(String.Format("\r\nExpected response \r\n {0}\r\n\r\nActual response \r\n{1}\r\n", expectedResponse, actualResponse)); } Assert.IsTrue(resultDif.AreEqual, String.Format("Expected response and Actual response see in log.\nOldValues:\n{0}\nNewValues:\n{1}", resultDif.OldValues, resultDif.NewValues)); }
public void AbleToDiffAndPatchSimpleObject() { var testObj = GetSimpleTestObject(); var updatedTestObj = GetSimpleTestObject(); updatedTestObj.StringProperty = "this is an updated string"; updatedTestObj.IntProperty = 5678; updatedTestObj.DoubleProperty = 123.456; var diff = ObjectDiffPatch.GenerateDiff(testObj, updatedTestObj); var revertPatch = JsonConvert.SerializeObject(diff.OldValues); var revertedObj = ObjectDiffPatch.PatchObject(updatedTestObj, revertPatch); Assert.AreEqual(testObj.StringProperty, revertedObj.StringProperty); Assert.AreEqual(testObj.IntProperty, revertedObj.IntProperty); Assert.AreEqual(testObj.DoubleProperty, revertedObj.DoubleProperty); }
public void AbleToDiffAndPatchSimpleObject() { var testObj = TestClass.CreateSimpleInstance(); var updatedTestObj = TestClass.CreateSimpleInstance(); updatedTestObj.StringProperty = "this is an updated string"; updatedTestObj.IntProperty = 5678; updatedTestObj.DoubleProperty = 123.456; var diff = ObjectDiffPatch.GenerateDiff(testObj, updatedTestObj); var revertPatch = diff.OldValues.ToString(); var revertedObj = ObjectDiffPatch.PatchObject(updatedTestObj, revertPatch); Assert.Equal(testObj.StringProperty, revertedObj.StringProperty); Assert.Equal(testObj.IntProperty, revertedObj.IntProperty); Assert.Equal(testObj.DoubleProperty, revertedObj.DoubleProperty); }
public void AbleToHandleCircularReferences_Ignore() { CircularObject original = new CircularObject(); original.AddChild(); original.AddChild(); original.FirstChild.AddChild(); var snapshot = ObjectDiffPatch.Snapshot(original).ToString(); ObjectDiffPatch.DefaultSerializerSettings.PreserveReferencesHandling = Newtonsoft.Json.PreserveReferencesHandling.All; var snapshotWithRefs = ObjectDiffPatch.Snapshot(original).ToString(); Assert.NotEqual(snapshot, snapshotWithRefs); var updated = ObjectDiffPatch.PatchObject(new CircularObject(), snapshotWithRefs); // they should be different, since all circular references are ignored! Assert.NotEqual(updated, original); }
public void GetCurrency(string currency, string authority) { #region Test Data Dictionary <string, string> expList = new Dictionary <string, string>(); expList.Add("EUR_mena", "{\"data\": [{\"key\":\"EUR\",\"vaultOptions\":[{\"server\":\"nf.test4\",\"group\":\"FXHQVAE\",\"authority\":\"mena\"}]}]}"); expList.Add("USD_mena", "{\"data\": [{\"key\":\"USD\",\"vaultOptions\":[{\"server\":\"nf.test4\",\"group\":\"FXHQVAD\",\"authority\":\"mena\"}]}]}"); expList.Add("GBP_mena", "{\"data\": [{\"key\":\"GBP\",\"vaultOptions\":[{\"server\":\"nf.test4\",\"group\":\"FXHQVAP\",\"authority\":\"mena\"}]}]}"); JObject expectedResponse = JObject.Parse(expList[currency + "_" + authority]); #endregion JObject actualResponse; APIHelper.GetCurrency(BaseUrlApi, currency, authority, out actualResponse); var resultDif = ObjectDiffPatch.GenerateDiff(expectedResponse, actualResponse); if (!resultDif.AreEqual) { Log.Error(String.Format("\r\nExpected response \r\n {0}\r\n\r\nActual response \r\n{1}\r\n", expectedResponse, actualResponse)); } Assert.IsTrue(resultDif.AreEqual, String.Format("Expected response and Actual response see in log.\nOldValues:\n{0}\nNewValues:\n{1}", resultDif.OldValues, resultDif.NewValues)); }
public void AbleToDeleteObjectListItemThenRevertViaPatch() { var testObj = GetSimpleTestObject(); PopulateObjectListOnTestClass(testObj); var updatedTestObj = GetSimpleTestObject(); PopulateObjectListOnTestClass(updatedTestObj); updatedTestObj.ListOfObjectProperty.RemoveAt(1); Assert.AreNotEqual(testObj.ListOfObjectProperty.Count, updatedTestObj.ListOfObjectProperty.Count); var diff = ObjectDiffPatch.GenerateDiff(testObj, updatedTestObj); var revertPatch = JsonConvert.SerializeObject(diff.OldValues); var revertedObj = ObjectDiffPatch.PatchObject(updatedTestObj, revertPatch); Assert.AreEqual(testObj.ListOfObjectProperty.Count, revertedObj.ListOfObjectProperty.Count); }
public void AbleToDeleteObjectListItemThenRevertViaPatch() { var testObj = TestClass.CreateSimpleInstance(); testObj.PopulateObjectListOnTestClass(); var updatedTestObj = TestClass.CreateSimpleInstance(); updatedTestObj.PopulateObjectListOnTestClass(); updatedTestObj.ListOfObjectProperty.RemoveAt(1); Assert.NotEqual(testObj.ListOfObjectProperty.Count, updatedTestObj.ListOfObjectProperty.Count); var diff = ObjectDiffPatch.GenerateDiff(testObj, updatedTestObj); var revertPatch = diff.OldValues.ToString(); var revertedObj = ObjectDiffPatch.PatchObject(updatedTestObj, revertPatch); Assert.Equal(testObj.ListOfObjectProperty.Count, revertedObj.ListOfObjectProperty.Count); }
public void GetCurrencies(string vault) { #region Test Data Dictionary <string, string> expList = new Dictionary <string, string>(); expList.Add("true", System.IO.File.ReadAllText(jsonResponses + "GetCurrencies.vault=true.json")); JObject expectedResponse = JObject.Parse(expList[vault]); #endregion JObject actualResponse; APIHelper.GetCurrencies(BaseUrlApi, vault, out actualResponse); var resultDif = ObjectDiffPatch.GenerateDiff(expectedResponse, actualResponse); if (!resultDif.AreEqual) { Log.Error(String.Format("\r\nExpected response \r\n {0}\r\n\r\nActual response \r\n{1}\r\n", expectedResponse, actualResponse)); } Assert.IsTrue(resultDif.AreEqual, String.Format("Expected response and Actual response see in log.\nOldValues:\n{0}\nNewValues:\n{1}", resultDif.OldValues, resultDif.NewValues)); }
public void AbleToDeleteStringListItemThenRevertViaPatch() { var testObj = GetSimpleTestObject(); PopulateStringListOnTestClass(testObj); var updatedTestObj = GetSimpleTestObject(); PopulateStringListOnTestClass(updatedTestObj); updatedTestObj.ListOfStringProperty.Remove("list"); CollectionAssert.AreNotEqual(testObj.ListOfStringProperty, updatedTestObj.ListOfStringProperty); var diff = ObjectDiffPatch.GenerateDiff(testObj, updatedTestObj); var revertPatch = JsonConvert.SerializeObject(diff.OldValues); var revertedObj = ObjectDiffPatch.PatchObject(updatedTestObj, revertPatch); CollectionAssert.AreEqual(testObj.ListOfStringProperty, revertedObj.ListOfStringProperty); }
public void AbleToHandleCollectionHoldingInterfaceReferences() { ObjectDiffPatch.DefaultSerializerSettings.TypeNameHandling = Newtonsoft.Json.TypeNameHandling.Objects; var original = new TestCollection(); original.List.Add(TestClass.CreateSimpleInstance()); var changedValue = TestClass.CreateSimpleInstance(); changedValue.StringProperty = "Other Value"; var updated = new TestCollection(); updated.List.Add(changedValue); var diff = ObjectDiffPatch.GenerateDiff(original, updated); Assert.False(diff.AreEqual); var patchedUpdated = ObjectDiffPatch.PatchObject(original, diff.NewValues); Assert.Equal(patchedUpdated.List.ElementAt(0).StringProperty, changedValue.StringProperty); }
public TEntity Modify(object id, dynamic bm) { if (bm.id == null || bm.id.ToString() != id.ToString()) { throw new KeyNotFoundException("Keys do not match."); } var dest = Find(id); if (dest == null) { throw new KeyNotFoundException("Item with the key given was not found."); } Ds.Context.Entry <TEntity>(dest).State = EntityState.Detached; var patched = ObjectDiffPatch.PatchObject <TEntity>(dest, bm); if (!CanWrite(patched)) { throw new UnauthorizedAccessException("Not Authorized."); } Ds.Context.Entry <TEntity>(patched).State = EntityState.Modified; return(patched); }
public void AbleToEditObjectInListThenRevertViaPatch() { var testObj = TestClass.CreateSimpleInstance(); testObj.PopulateObjectListOnTestClass(); var updatedTestObj = TestClass.CreateSimpleInstance(); updatedTestObj.PopulateObjectListOnTestClass(); updatedTestObj.ListOfObjectProperty[2].IntProperty = 30; updatedTestObj.ListOfObjectProperty[2].StringProperty = "this is an update to the last object in the list"; updatedTestObj.ListOfObjectProperty[2].DoubleProperty = 33.333; var diff = ObjectDiffPatch.GenerateDiff(testObj, updatedTestObj); var revertPatch = diff.OldValues.ToString(); var revertedObj = ObjectDiffPatch.PatchObject(updatedTestObj, revertPatch); Assert.Equal(testObj.ListOfObjectProperty[2].IntProperty, revertedObj.ListOfObjectProperty[2].IntProperty); Assert.Equal(testObj.ListOfObjectProperty[2].StringProperty, revertedObj.ListOfObjectProperty[2].StringProperty); Assert.Equal(testObj.ListOfObjectProperty[2].DoubleProperty, revertedObj.ListOfObjectProperty[2].DoubleProperty); }
public void AbleToEditObjectInListThenRevertViaPatch() { var testObj = GetSimpleTestObject(); PopulateObjectListOnTestClass(testObj); var updatedTestObj = GetSimpleTestObject(); PopulateObjectListOnTestClass(updatedTestObj); updatedTestObj.ListOfObjectProperty[2].IntProperty = 30; updatedTestObj.ListOfObjectProperty[2].StringProperty = "this is an update to the last object in the list"; updatedTestObj.ListOfObjectProperty[2].DoubleProperty = 33.333; var diff = ObjectDiffPatch.GenerateDiff(testObj, updatedTestObj); var revertPatch = JsonConvert.SerializeObject(diff.OldValues); var revertedObj = ObjectDiffPatch.PatchObject(updatedTestObj, revertPatch); Assert.AreEqual(testObj.ListOfObjectProperty[2].IntProperty, revertedObj.ListOfObjectProperty[2].IntProperty); Assert.AreEqual(testObj.ListOfObjectProperty[2].StringProperty, revertedObj.ListOfObjectProperty[2].StringProperty); Assert.AreEqual(testObj.ListOfObjectProperty[2].DoubleProperty, revertedObj.ListOfObjectProperty[2].DoubleProperty); }
private static void AssertSameObject(JObject expected, JObject actual) { var diff = ObjectDiffPatch.GenerateDiff(expected, actual); Assert.True(diff.ActualValues == null && diff.ExpectedValues == null, "Expected:\n" + diff.ExpectedValues + "\nActual:\n" + diff.ActualValues); }
public T UpdateObject <T>(T original, T updated) where T : class { var diffs = ObjectDiffPatch.GenerateDiff(original, updated); return(ObjectDiffPatch.PatchObject(original, diffs.NewValues)); }