diff --git a/src/Marvin.JsonPatch.Test/ExpandoObjectAdapterTests.cs b/src/Marvin.JsonPatch.Test/ExpandoObjectAdapterTests.cs index efdac41..a2aeec9 100644 --- a/src/Marvin.JsonPatch.Test/ExpandoObjectAdapterTests.cs +++ b/src/Marvin.JsonPatch.Test/ExpandoObjectAdapterTests.cs @@ -13,21 +13,21 @@ namespace Marvin.JsonPatch.Test public class ExpandoObjectAdapterTests { - [TestMethod] - public void Remove() - { - dynamic doc = new ExpandoObject(); - doc.StringProperty = "A"; + //[TestMethod] + //public void Remove() + //{ + // dynamic doc = new ExpandoObject(); + // doc.StringProperty = "A"; - // create patch - JsonPatchDocument patchDoc = new JsonPatchDocument(); - patchDoc.Remove("StringProperty"); + // // create patch + // JsonPatchDocument patchDoc = new JsonPatchDocument(); + // patchDoc.Remove("StringProperty"); - patchDoc.ApplyTo(doc, new ExpandoObjectAdapter()); + // patchDoc.ApplyTo(doc, new ExpandoObjectAdapter()); - Assert.AreEqual(null, doc.StringProperty); + // Assert.AreEqual(null, doc.StringProperty); - } + //} } } diff --git a/src/Marvin.JsonPatch.Test/Marvin.JsonPatch.Test.csproj b/src/Marvin.JsonPatch.Test/Marvin.JsonPatch.Test.csproj index ff59f76..9d0933b 100644 --- a/src/Marvin.JsonPatch.Test/Marvin.JsonPatch.Test.csproj +++ b/src/Marvin.JsonPatch.Test/Marvin.JsonPatch.Test.csproj @@ -56,9 +56,12 @@ + + + diff --git a/src/Marvin.JsonPatch.Test/NestedDTO.cs b/src/Marvin.JsonPatch.Test/NestedDTO.cs new file mode 100644 index 0000000..59cff42 --- /dev/null +++ b/src/Marvin.JsonPatch.Test/NestedDTO.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Marvin.JsonPatch.Test +{ + public class NestedDTO + { + public string StringProperty { get; set; } + } +} diff --git a/src/Marvin.JsonPatch.Test/NestedObjectTests.cs b/src/Marvin.JsonPatch.Test/NestedObjectTests.cs new file mode 100644 index 0000000..90b6c04 --- /dev/null +++ b/src/Marvin.JsonPatch.Test/NestedObjectTests.cs @@ -0,0 +1,890 @@ +using Marvin.JsonPatch.Exceptions; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Marvin.JsonPatch.Test +{ + [TestClass] + public class NestedObjectTests + { + + [TestMethod] + public void ReplacePropertyInNestedObject() + { + var doc = new SimpleDTOWithNestedDTO() + { + IntegerValue = 1 + + }; + + // create patch + JsonPatchDocument patchDoc = new JsonPatchDocument(); + patchDoc.Replace(o => o.NestedDTO.StringProperty, "B"); + + patchDoc.ApplyTo(doc); + + Assert.AreEqual("B", doc.NestedDTO.StringProperty); + + } + + + [TestMethod] + public void ReplaceNestedObject() + { + var doc = new SimpleDTOWithNestedDTO() + { + IntegerValue = 1 + + }; + + var newNested = new NestedDTO() { StringProperty = "B" }; + + // create patch + JsonPatchDocument patchDoc = new JsonPatchDocument(); + patchDoc.Replace(o => o.NestedDTO, newNested); + + patchDoc.ApplyTo(doc); + + + Assert.AreEqual(newNested, doc.NestedDTO); + Assert.AreEqual("B", doc.NestedDTO.StringProperty); + + } + + + [TestMethod] + public void AddResultsInReplace() + { + var doc = new SimpleDTOWithNestedDTO() + { + SimpleDTO = new SimpleDTO() + { + StringProperty = "A" + } + }; + + // create patch + JsonPatchDocument patchDoc = new JsonPatchDocument(); + patchDoc.Add(o => o.SimpleDTO.StringProperty, "B"); + + patchDoc.ApplyTo(doc); + + Assert.AreEqual("B", doc.SimpleDTO.StringProperty); + + } + + + [TestMethod] + public void AddToList() + { + var doc = new SimpleDTOWithNestedDTO() + { + SimpleDTO = new SimpleDTO() + { + IntegerList = new List() { 1, 2, 3 } + } + }; + + + // create patch + JsonPatchDocument patchDoc = new JsonPatchDocument(); + patchDoc.Add(o => o.SimpleDTO.IntegerList, 4, 0); + + patchDoc.ApplyTo(doc); + + CollectionAssert.AreEquivalent(new List() { 4, 1, 2, 3 }, doc.SimpleDTO.IntegerList); + } + + + [TestMethod] + public void AddToListInvalidPositionTooLarge() + { + var doc = new SimpleDTOWithNestedDTO() + { + SimpleDTO = new SimpleDTO() + { + IntegerList = new List() { 1, 2, 3 } + } + } + ; + + // create patch + JsonPatchDocument patchDoc = new JsonPatchDocument(); + patchDoc.Add(o => o.SimpleDTO.IntegerList, 4, 3); + + + try + { + patchDoc.ApplyTo(doc); + + // if we get here, we should fail b/c no exception was thrown + Assert.Fail(); + + } + catch (JsonPatchException) { } + + } + + + [TestMethod] + public void AddToListInvalidPositionTooSmall() + { + + var doc = new SimpleDTOWithNestedDTO() + { + SimpleDTO = new SimpleDTO() + { + IntegerList = new List() { 1, 2, 3 } + } + }; + + + + // create patch + JsonPatchDocument patchDoc = new JsonPatchDocument(); + patchDoc.Add(o => o.SimpleDTO.IntegerList, 4, -1); + + try + { + patchDoc.ApplyTo(doc); + + // if we get here, we should fail b/c no exception was thrown + Assert.Fail(); + + } + catch (JsonPatchException) + { + } + + + + } + + [TestMethod] + public void AddToListAppend() + { + var doc = new SimpleDTOWithNestedDTO() + { + SimpleDTO = new SimpleDTO() + { + IntegerList = new List() { 1, 2, 3 } + } + }; + + + // create patch + JsonPatchDocument patchDoc = new JsonPatchDocument(); + patchDoc.Add(o => o.SimpleDTO.IntegerList, 4); + + patchDoc.ApplyTo(doc); + + CollectionAssert.AreEquivalent(new List() { 1, 2, 3, 4 }, doc.SimpleDTO.IntegerList); + + } + + + [TestMethod] + public void Remove() + { + var doc = new SimpleDTOWithNestedDTO() + { + SimpleDTO = new SimpleDTO() + { + StringProperty = "A" + } + }; + + // create patch + JsonPatchDocument patchDoc = new JsonPatchDocument(); + patchDoc.Remove(o => o.SimpleDTO.StringProperty); + + patchDoc.ApplyTo(doc); + + Assert.AreEqual(null, doc.SimpleDTO.StringProperty); + + } + + + + [TestMethod] + public void RemoveFromList() + { + var doc = new SimpleDTOWithNestedDTO() + { + SimpleDTO = new SimpleDTO() + { + IntegerList = new List() { 1, 2, 3 } + } + }; + + + // create patch + JsonPatchDocument patchDoc = new JsonPatchDocument(); + patchDoc.Remove(o => o.SimpleDTO.IntegerList, 2); + + patchDoc.ApplyTo(doc); + + CollectionAssert.AreEquivalent(new List() { 1, 2 }, doc.SimpleDTO.IntegerList); + } + + + [TestMethod] + public void RemoveFromListInvalidPositionTooLarge() + { + var doc = new SimpleDTOWithNestedDTO() + { + SimpleDTO = new SimpleDTO() + { + IntegerList = new List() { 1, 2, 3 } + } + }; + + // create patch + JsonPatchDocument patchDoc = new JsonPatchDocument(); + patchDoc.Remove(o => o.SimpleDTO.IntegerList, 3); + + + try + { + patchDoc.ApplyTo(doc); + + // if we get here, we should fail b/c no exception was thrown + Assert.Fail(); + + } + catch (JsonPatchException) { } + + } + + + [TestMethod] + public void RemoveFromListInvalidPositionTooSmall() + { + + var doc = new SimpleDTOWithNestedDTO() + { + SimpleDTO = new SimpleDTO() + { + IntegerList = new List() { 1, 2, 3 } + } + } + ; + + // create patch + JsonPatchDocument patchDoc = new JsonPatchDocument(); + patchDoc.Remove(o => o.SimpleDTO.IntegerList, -1); + + try + { + patchDoc.ApplyTo(doc); + + // if we get here, we should fail b/c no exception was thrown + Assert.Fail(); + + } + catch (JsonPatchException) + { + } + + } + + + [TestMethod] + public void RemoveFromEndOfList() + { + var doc = new SimpleDTOWithNestedDTO() + { + SimpleDTO = new SimpleDTO() + { + IntegerList = new List() { 1, 2, 3 } + } + }; + + // create patch + JsonPatchDocument patchDoc = new JsonPatchDocument(); + patchDoc.Remove(o => o.SimpleDTO.IntegerList); + + patchDoc.ApplyTo(doc); + + CollectionAssert.AreEquivalent(new List() { 1, 2 }, doc.SimpleDTO.IntegerList); + + } + + + [TestMethod] + public void Replace() + { + var doc = new SimpleDTOWithNestedDTO() + { + SimpleDTO = new SimpleDTO() + { + StringProperty = "A", + DecimalValue = 10 + } + }; + + // create patch + JsonPatchDocument patchDoc = new JsonPatchDocument(); + patchDoc.Replace(o => o.SimpleDTO.StringProperty, "B"); + // patchDoc.Replace(o => o.DecimalValue, 12); + patchDoc.Replace(o => o.SimpleDTO.DecimalValue, 12); + + patchDoc.ApplyTo(doc); + + Assert.AreEqual("B", doc.SimpleDTO.StringProperty); + Assert.AreEqual(12, doc.SimpleDTO.DecimalValue); + + + + } + + + + + [TestMethod] + public void SerializationTests() + { + var doc = new SimpleDTOWithNestedDTO() + { + SimpleDTO = new SimpleDTO() + { + StringProperty = "A", + DecimalValue = 10, + DoubleValue = 10, + FloatValue = 10, + IntegerValue = 10 + } + }; + + // create patch + JsonPatchDocument patchDoc = new JsonPatchDocument(); + patchDoc.Replace(o => o.SimpleDTO.StringProperty, "B"); + patchDoc.Replace(o => o.SimpleDTO.DecimalValue, 12); + patchDoc.Replace(o => o.SimpleDTO.DoubleValue, 12); + patchDoc.Replace(o => o.SimpleDTO.FloatValue, 12); + patchDoc.Replace(o => o.SimpleDTO.IntegerValue, 12); + + + + // serialize & deserialize + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserizalized = JsonConvert.DeserializeObject>(serialized); + + + deserizalized.ApplyTo(doc); + + Assert.AreEqual("B", doc.SimpleDTO.StringProperty); + Assert.AreEqual(12, doc.SimpleDTO.DecimalValue); + Assert.AreEqual(12, doc.SimpleDTO.DoubleValue); + Assert.AreEqual(12, doc.SimpleDTO.FloatValue); + Assert.AreEqual(12, doc.SimpleDTO.IntegerValue); + + } + + [TestMethod] + public void ReplaceInList() + { + var doc = new SimpleDTOWithNestedDTO() + { + SimpleDTO = new SimpleDTO() + { + IntegerList = new List() { 1, 2, 3 } + } + }; + + // create patch + JsonPatchDocument patchDoc = new JsonPatchDocument(); + patchDoc.Replace(o => o.SimpleDTO.IntegerList, 5, 0); + + patchDoc.ApplyTo(doc); + + + CollectionAssert.AreEquivalent(new List() { 5, 2, 3 }, doc.SimpleDTO.IntegerList); + + } + + + + [TestMethod] + public void ReplaceFullList() + { + var doc = new SimpleDTOWithNestedDTO() + { + SimpleDTO = new SimpleDTO() + { + IntegerList = new List() { 1, 2, 3 } + } + }; + + // create patch + JsonPatchDocument patchDoc = new JsonPatchDocument(); + patchDoc.Replace>(o => o.SimpleDTO.IntegerList, new List() { 4, 5, 6 }); + + patchDoc.ApplyTo(doc); + + + CollectionAssert.AreEquivalent(new List() { 4, 5, 6 }, doc.SimpleDTO.IntegerList); + + } + + + + [TestMethod] + public void ReplaceFullListFromEnumerable() + { + var doc = new SimpleDTOWithNestedDTO() + { + SimpleDTO = new SimpleDTO() + { + IntegerList = new List() { 1, 2, 3 } + } + }; + + // create patch + JsonPatchDocument patchDoc = new JsonPatchDocument(); + patchDoc.Replace>(o => o.SimpleDTO.IntegerList, new List() { 4, 5, 6 }); + + patchDoc.ApplyTo(doc); + + + CollectionAssert.AreEquivalent(new List() { 4, 5, 6 }, doc.SimpleDTO.IntegerList); + + } + + + + [TestMethod] + public void ReplaceFullListWithCollection() + { + var doc = new SimpleDTOWithNestedDTO() + { + SimpleDTO = new SimpleDTO() + { + IntegerList = new List() { 1, 2, 3 } + } + }; + + // create patch + JsonPatchDocument patchDoc = new JsonPatchDocument(); + patchDoc.Replace>(o => o.SimpleDTO.IntegerList, new Collection() { 4, 5, 6 }); + + + try + { + // should trhow an exception due to list/collection cast. + + patchDoc.ApplyTo(doc); + + // if we get here, we should fail b/c no exception was thrown + Assert.Fail(); + + } + catch (JsonPatchException) + { + } + + } + + + + [TestMethod] + public void ReplaceAtEndOfList() + { + var doc = new SimpleDTOWithNestedDTO() + { + SimpleDTO = new SimpleDTO() + { + IntegerList = new List() { 1, 2, 3 } + } + }; + + // create patch + JsonPatchDocument patchDoc = new JsonPatchDocument(); + patchDoc.Replace(o => o.SimpleDTO.IntegerList, 5); + + patchDoc.ApplyTo(doc); + + + CollectionAssert.AreEquivalent(new List() { 1, 2, 5 }, doc.SimpleDTO.IntegerList); + + } + + [TestMethod] + public void ReplaceInListInvalidInvalidPositionTooLarge() + { + var doc = new SimpleDTOWithNestedDTO() + { + SimpleDTO = new SimpleDTO() + { + IntegerList = new List() { 1, 2, 3 } + } + }; + + // create patch + JsonPatchDocument patchDoc = new JsonPatchDocument(); + patchDoc.Replace(o => o.SimpleDTO.IntegerList, 5, 3); + + + try + { + patchDoc.ApplyTo(doc); + + // if we get here, we should fail b/c no exception was thrown + Assert.Fail(); + + } + catch (JsonPatchException) { } + + } + + + [TestMethod] + public void ReplaceInListInvalidPositionTooSmall() + { + + + var doc = new SimpleDTOWithNestedDTO() + { + SimpleDTO = new SimpleDTO() + { + IntegerList = new List() { 1, 2, 3 } + } + }; + + // create patch + JsonPatchDocument patchDoc = new JsonPatchDocument(); + patchDoc.Replace(o => o.SimpleDTO.IntegerList, 5, -1); + + try + { + patchDoc.ApplyTo(doc); + + // if we get here, we should fail b/c no exception was thrown + Assert.Fail(); + + } + catch (JsonPatchException) + { + } + + } + + + + + + [TestMethod] + public void Copy() + { + var doc = new SimpleDTOWithNestedDTO() + { + SimpleDTO = new SimpleDTO() + { + StringProperty = "A", + AnotherStringProperty = "B" + } + }; + + // create patch + JsonPatchDocument patchDoc = new JsonPatchDocument(); + patchDoc.Copy(o => o.SimpleDTO.StringProperty, o => o.SimpleDTO.AnotherStringProperty); + + patchDoc.ApplyTo(doc); + + Assert.AreEqual("A", doc.SimpleDTO.AnotherStringProperty); + + } + + + + [TestMethod] + public void CopyInList() + { + var doc = new SimpleDTOWithNestedDTO() + { + SimpleDTO = new SimpleDTO() + { + IntegerList = new List() { 1, 2, 3 } + } + }; + + // create patch + JsonPatchDocument patchDoc = new JsonPatchDocument(); + patchDoc.Copy(o => o.SimpleDTO.IntegerList, 0, o => o.SimpleDTO.IntegerList, 1); + + patchDoc.ApplyTo(doc); + + CollectionAssert.AreEquivalent(new List() { 1, 1, 2, 3 }, doc.SimpleDTO.IntegerList); + } + + + [TestMethod] + public void CopyFromListToEndOfList() + { + var doc = new SimpleDTOWithNestedDTO() + { + SimpleDTO = new SimpleDTO() + { + IntegerList = new List() { 1, 2, 3 } + } + }; + + // create patch + JsonPatchDocument patchDoc = new JsonPatchDocument(); + patchDoc.Copy(o => o.SimpleDTO.IntegerList, 0, o => o.SimpleDTO.IntegerList); + + patchDoc.ApplyTo(doc); + + CollectionAssert.AreEquivalent(new List() { 1, 2, 3, 1 }, doc.SimpleDTO.IntegerList); + } + + + + + [TestMethod] + public void CopyFromListToNonList() + { + var doc = new SimpleDTOWithNestedDTO() + { + SimpleDTO = new SimpleDTO() + { + IntegerList = new List() { 1, 2, 3 } + } + }; + + // create patch + JsonPatchDocument patchDoc = new JsonPatchDocument(); + patchDoc.Copy(o => o.SimpleDTO.IntegerList, 0, o => o.SimpleDTO.IntegerValue); + + patchDoc.ApplyTo(doc); + + Assert.AreEqual(1, doc.SimpleDTO.IntegerValue); + } + + + [TestMethod] + public void CopyFromNonListToList() + { + var doc = new SimpleDTOWithNestedDTO() + { + SimpleDTO = new SimpleDTO() + { + IntegerValue = 5, + IntegerList = new List() { 1, 2, 3 } + } + }; + + // create patch + JsonPatchDocument patchDoc = new JsonPatchDocument(); + patchDoc.Copy(o => o.SimpleDTO.IntegerValue, o => o.SimpleDTO.IntegerList, 0); + + patchDoc.ApplyTo(doc); + + CollectionAssert.AreEqual(new List() { 5, 1, 2, 3 }, doc.SimpleDTO.IntegerList); + } + + + + + [TestMethod] + public void CopyToEndOfList() + { + var doc = new SimpleDTOWithNestedDTO() + { + SimpleDTO = new SimpleDTO() + { + IntegerValue = 5, + IntegerList = new List() { 1, 2, 3 } + } + }; + + // create patch + JsonPatchDocument patchDoc = new JsonPatchDocument(); + patchDoc.Copy(o => o.SimpleDTO.IntegerValue, o => o.SimpleDTO.IntegerList); + + patchDoc.ApplyTo(doc); + + + CollectionAssert.AreEquivalent(new List() { 1, 2, 3, 5 }, doc.SimpleDTO.IntegerList); + + } + + + [TestMethod] + public void Move() + { + var doc = new SimpleDTOWithNestedDTO() + { + SimpleDTO = new SimpleDTO() + { + StringProperty = "A", + AnotherStringProperty = "B" + } + }; + + // create patch + JsonPatchDocument patchDoc = new JsonPatchDocument(); + patchDoc.Move(o => o.SimpleDTO.StringProperty, o => o.SimpleDTO.AnotherStringProperty); + + patchDoc.ApplyTo(doc); + + Assert.AreEqual("A", doc.SimpleDTO.AnotherStringProperty); + Assert.AreEqual(null, doc.SimpleDTO.StringProperty); + } + + + + + + [TestMethod] + public void MoveInList() + { + var doc = new SimpleDTOWithNestedDTO() + { + SimpleDTO = new SimpleDTO() + { + IntegerList = new List() { 1, 2, 3 } + } + }; + + // create patch + JsonPatchDocument patchDoc = new JsonPatchDocument(); + patchDoc.Move(o => o.SimpleDTO.IntegerList, 0, o => o.SimpleDTO.IntegerList, 1); + + patchDoc.ApplyTo(doc); + + CollectionAssert.AreEquivalent(new List() { 2, 1, 3 }, doc.SimpleDTO.IntegerList); + } + + [TestMethod] + public void MoveFromListToEndOfList() + { + var doc = new SimpleDTOWithNestedDTO() + { + SimpleDTO = new SimpleDTO() + { + IntegerList = new List() { 1, 2, 3 } + } + }; + + // create patch + JsonPatchDocument patchDoc = new JsonPatchDocument(); + patchDoc.Move(o => o.SimpleDTO.IntegerList, 0, o => o.SimpleDTO.IntegerList); + + patchDoc.ApplyTo(doc); + + CollectionAssert.AreEquivalent(new List() { 2, 3, 1 }, doc.SimpleDTO.IntegerList); + } + + + + + + [TestMethod] + public void MoveFomListToNonList() + { + var doc = new SimpleDTOWithNestedDTO() + { + SimpleDTO = new SimpleDTO() + { + IntegerList = new List() { 1, 2, 3 } + } + }; + + // create patch + JsonPatchDocument patchDoc = new JsonPatchDocument(); + patchDoc.Move(o => o.SimpleDTO.IntegerList, 0, o => o.SimpleDTO.IntegerValue); + + patchDoc.ApplyTo(doc); + + CollectionAssert.AreEquivalent(new List() { 2, 3 }, doc.SimpleDTO.IntegerList); + Assert.AreEqual(1, doc.SimpleDTO.IntegerValue); + } + + [TestMethod] + public void MoveFomListToNonListBetweenHierarchy() + { + var doc = new SimpleDTOWithNestedDTO() + { + SimpleDTO = new SimpleDTO() + { + IntegerList = new List() { 1, 2, 3 } + } + }; + + // create patch + JsonPatchDocument patchDoc = new JsonPatchDocument(); + patchDoc.Move(o => o.SimpleDTO.IntegerList, 0, o => o.IntegerValue); + + patchDoc.ApplyTo(doc); + + CollectionAssert.AreEquivalent(new List() { 2, 3 }, doc.SimpleDTO.IntegerList); + Assert.AreEqual(1, doc.IntegerValue); + } + + + [TestMethod] + public void MoveFromNonListToList() + { + var doc = new SimpleDTOWithNestedDTO() + { + SimpleDTO = new SimpleDTO() + { + IntegerValue = 5, + IntegerList = new List() { 1, 2, 3 } + } + }; + + // create patch + JsonPatchDocument patchDoc = new JsonPatchDocument(); + patchDoc.Move(o => o.SimpleDTO.IntegerValue, o => o.SimpleDTO.IntegerList, 0); + + patchDoc.ApplyTo(doc); + + Assert.AreEqual(0, doc.IntegerValue); + CollectionAssert.AreEqual(new List() { 5, 1, 2, 3 }, doc.SimpleDTO.IntegerList); + } + + + + + + + + [TestMethod] + public void MoveToEndOfList() + { + var doc = new SimpleDTOWithNestedDTO() + { + SimpleDTO = new SimpleDTO() + { + IntegerValue = 5, + IntegerList = new List() { 1, 2, 3 } + } + }; + + // create patch + JsonPatchDocument patchDoc = new JsonPatchDocument(); + patchDoc.Move(o => o.SimpleDTO.IntegerValue, o => o.SimpleDTO.IntegerList); + + patchDoc.ApplyTo(doc); + + Assert.AreEqual(0, doc.IntegerValue); + CollectionAssert.AreEquivalent(new List() { 1, 2, 3, 5 }, doc.SimpleDTO.IntegerList); + + } + + + + + + + + } +} diff --git a/src/Marvin.JsonPatch/Adapters/ExpandoObjectAdapter.cs b/src/Marvin.JsonPatch/Adapters/ExpandoObjectAdapter.cs index b61c970..d73d3bf 100644 --- a/src/Marvin.JsonPatch/Adapters/ExpandoObjectAdapter.cs +++ b/src/Marvin.JsonPatch/Adapters/ExpandoObjectAdapter.cs @@ -11,133 +11,133 @@ namespace Marvin.JsonPatch.Adapters { - public class ExpandoObjectAdapter : IDynamicObjectAdapter - { - - public void Add(Operations.Operation operation, ExpandoObject objectToApplyTo) - { - throw new NotImplementedException(); - } - - public void Copy(Operations.Operation operation, ExpandoObject objectToApplyTo) - { - throw new NotImplementedException(); - } - - public void Move(Operations.Operation operation, ExpandoObject objectToApplyTo) - { - throw new NotImplementedException(); - } - - public void Remove(Operations.Operation operation, ExpandoObject objectToApplyTo) - { - Remove(operation.path, objectToApplyTo, operation); - } - - /// - /// Remove is used by various operations (eg: remove, move, ...), yet through different operations; - /// This method allows code reuse yet reporting the correct operation on error - /// - private void Remove(string path, ExpandoObject objectToApplyTo, Operation operationToReport) - { - - bool removeFromList = false; - int positionAsInteger = -1; - string actualPathToProperty = path; - - if (path.EndsWith("/-")) - { - removeFromList = true; - actualPathToProperty = path.Substring(0, path.Length - 2); - } - else - { - positionAsInteger = PropertyHelpers.GetNumericEnd(path); - - if (positionAsInteger > -1) - { - actualPathToProperty = path.Substring(0, - path.IndexOf('/' + positionAsInteger.ToString())); - } - } - - - // does the target location exist? - if (!(PropertyHelpers.CheckIfPropertyExists(objectToApplyTo, actualPathToProperty))) - { - throw new JsonPatchException(operationToReport, - string.Format("Patch failed: property at location path: {0} does not exist", path), - objectToApplyTo); - } - - // get the property, and remove it - in this case, for DTO's, that means setting - // it to null or its default value; in case of an array, remove at provided index - // or at the end. - - PropertyInfo pathProperty = PropertyHelpers.FindProperty(objectToApplyTo, actualPathToProperty); - - - if (removeFromList || positionAsInteger > -1) - { - - var isNonStringArray = !(pathProperty.PropertyType == typeof(string)) - && typeof(IList).IsAssignableFrom(pathProperty.PropertyType); - - // what if it's an array but there's no position?? - if (isNonStringArray) - { - // now, get the generic type of the enumerable - var genericTypeOfArray = PropertyHelpers.GetEnumerableType(pathProperty.PropertyType); - - // get value (it can be cast, we just checked that) - var array = PropertyHelpers.GetValue(pathProperty, objectToApplyTo) as IList; - - if (removeFromList) - { - array.RemoveAt(array.Count - 1); - } - else - { - if (positionAsInteger < array.Count) - { - array.RemoveAt(positionAsInteger); - } - else - { - throw new JsonPatchException(operationToReport, - string.Format("Patch failed: provided path is invalid for array property type at location path: {0}: position larger than array size", - path), - objectToApplyTo); - } - } - - } - else - { - throw new JsonPatchException(operationToReport, - string.Format("Patch failed: provided path is invalid for array property type at location path: {0}: expected array", - path), - objectToApplyTo); - } - } - else - { - - // setting the value to "null" will use the default value in case of value types, and - // null in case of reference types - PropertyHelpers.SetValue(pathProperty, objectToApplyTo, null); - } - - } - - public void Replace(Operations.Operation operation, ExpandoObject objectToApplyTo) - { - throw new NotImplementedException(); - } - - public void Test(Operations.Operation operation, ExpandoObject objectToApplyTo) - { - throw new NotImplementedException(); - } - } + //public class ExpandoObjectAdapter : IDynamicObjectAdapter + //{ + + // public void Add(Operations.Operation operation, ExpandoObject objectToApplyTo) + // { + // throw new NotImplementedException(); + // } + + // public void Copy(Operations.Operation operation, ExpandoObject objectToApplyTo) + // { + // throw new NotImplementedException(); + // } + + // public void Move(Operations.Operation operation, ExpandoObject objectToApplyTo) + // { + // throw new NotImplementedException(); + // } + + // public void Remove(Operations.Operation operation, ExpandoObject objectToApplyTo) + // { + // Remove(operation.path, objectToApplyTo, operation); + // } + + // /// + // /// Remove is used by various operations (eg: remove, move, ...), yet through different operations; + // /// This method allows code reuse yet reporting the correct operation on error + // /// + // private void Remove(string path, ExpandoObject objectToApplyTo, Operation operationToReport) + // { + + // bool removeFromList = false; + // int positionAsInteger = -1; + // string actualPathToProperty = path; + + // if (path.EndsWith("/-")) + // { + // removeFromList = true; + // actualPathToProperty = path.Substring(0, path.Length - 2); + // } + // else + // { + // positionAsInteger = PropertyHelpers.GetNumericEnd(path); + + // if (positionAsInteger > -1) + // { + // actualPathToProperty = path.Substring(0, + // path.IndexOf('/' + positionAsInteger.ToString())); + // } + // } + + + // // does the target location exist? + // if (!(PropertyHelpers.CheckIfPropertyExists(objectToApplyTo, actualPathToProperty))) + // { + // throw new JsonPatchException(operationToReport, + // string.Format("Patch failed: property at location path: {0} does not exist", path), + // objectToApplyTo); + // } + + // // get the property, and remove it - in this case, for DTO's, that means setting + // // it to null or its default value; in case of an array, remove at provided index + // // or at the end. + + // PropertyInfo pathProperty = PropertyHelpers.FindProperty(objectToApplyTo, actualPathToProperty); + + + // if (removeFromList || positionAsInteger > -1) + // { + + // var isNonStringArray = !(pathProperty.PropertyType == typeof(string)) + // && typeof(IList).IsAssignableFrom(pathProperty.PropertyType); + + // // what if it's an array but there's no position?? + // if (isNonStringArray) + // { + // // now, get the generic type of the enumerable + // var genericTypeOfArray = PropertyHelpers.GetEnumerableType(pathProperty.PropertyType); + + // // get value (it can be cast, we just checked that) + // var array = PropertyHelpers.GetValue(pathProperty, objectToApplyTo) as IList; + + // if (removeFromList) + // { + // array.RemoveAt(array.Count - 1); + // } + // else + // { + // if (positionAsInteger < array.Count) + // { + // array.RemoveAt(positionAsInteger); + // } + // else + // { + // throw new JsonPatchException(operationToReport, + // string.Format("Patch failed: provided path is invalid for array property type at location path: {0}: position larger than array size", + // path), + // objectToApplyTo); + // } + // } + + // } + // else + // { + // throw new JsonPatchException(operationToReport, + // string.Format("Patch failed: provided path is invalid for array property type at location path: {0}: expected array", + // path), + // objectToApplyTo); + // } + // } + // else + // { + + // // setting the value to "null" will use the default value in case of value types, and + // // null in case of reference types + // PropertyHelpers.SetValue(pathProperty, objectToApplyTo, null); + // } + + // } + + // public void Replace(Operations.Operation operation, ExpandoObject objectToApplyTo) + // { + // throw new NotImplementedException(); + // } + + // public void Test(Operations.Operation operation, ExpandoObject objectToApplyTo) + // { + // throw new NotImplementedException(); + // } + //} } diff --git a/src/Marvin.JsonPatch/Adapters/IObjectAdapter.cs b/src/Marvin.JsonPatch/Adapters/IObjectAdapter.cs index a0b1f3e..8b25bae 100644 --- a/src/Marvin.JsonPatch/Adapters/IObjectAdapter.cs +++ b/src/Marvin.JsonPatch/Adapters/IObjectAdapter.cs @@ -21,14 +21,14 @@ public interface IObjectAdapter } // TO BE IMPLEMENTED - public interface IDynamicObjectAdapter - where T : class - { - void Add(Marvin.JsonPatch.Operations.Operation operation, T objectToApplyTo); - void Copy(Marvin.JsonPatch.Operations.Operation operation, T objectToApplyTo); - void Move(Marvin.JsonPatch.Operations.Operation operation, T objectToApplyTo); - void Remove(Marvin.JsonPatch.Operations.Operation operation, T objectToApplyTo); - void Replace(Marvin.JsonPatch.Operations.Operation operation, T objectToApplyTo); - void Test(Marvin.JsonPatch.Operations.Operation operation, T objectToApplyTo); - } + //public interface IDynamicObjectAdapter + // where T : class + //{ + // void Add(Marvin.JsonPatch.Operations.Operation operation, T objectToApplyTo); + // void Copy(Marvin.JsonPatch.Operations.Operation operation, T objectToApplyTo); + // void Move(Marvin.JsonPatch.Operations.Operation operation, T objectToApplyTo); + // void Remove(Marvin.JsonPatch.Operations.Operation operation, T objectToApplyTo); + // void Replace(Marvin.JsonPatch.Operations.Operation operation, T objectToApplyTo); + // void Test(Marvin.JsonPatch.Operations.Operation operation, T objectToApplyTo); + //} } diff --git a/src/Marvin.JsonPatch/Adapters/SimpleObjectAdapter.cs b/src/Marvin.JsonPatch/Adapters/SimpleObjectAdapter.cs index 2fb630c..4dfd80b 100644 --- a/src/Marvin.JsonPatch/Adapters/SimpleObjectAdapter.cs +++ b/src/Marvin.JsonPatch/Adapters/SimpleObjectAdapter.cs @@ -165,7 +165,7 @@ private void Add(string path, object value, T objectToApplyTo, Operation oper // get value (it can be cast, we just checked that) - var array = PropertyHelpers.GetValue(pathProperty, objectToApplyTo) as IList; + var array = PropertyHelpers.GetValue(pathProperty, objectToApplyTo, actualPathToProperty) as IList; if (appendList) { @@ -205,8 +205,8 @@ private void Add(string path, object value, T objectToApplyTo, Operation oper objectToApplyTo); } - // set the new value - PropertyHelpers.SetValue(pathProperty, objectToApplyTo, value); + // set the new value. Include the path, as it might be a property on a nested property + PropertyHelpers.SetValue(pathProperty, objectToApplyTo, actualPathToProperty, value); } } @@ -277,7 +277,7 @@ public void Move(Operation operation, T objectToApplyTo) var genericTypeOfArray = PropertyHelpers.GetEnumerableType(fromProperty.PropertyType); // get value (it can be cast, we just checked that) - var array = PropertyHelpers.GetValue(fromProperty, objectToApplyTo) as IList; + var array = PropertyHelpers.GetValue(fromProperty, objectToApplyTo, actualFromProperty) as IList; if (array.Count <= positionAsInteger) { @@ -304,7 +304,7 @@ public void Move(Operation operation, T objectToApplyTo) // set the new value - valueAtFromLocation = PropertyHelpers.GetValue(fromProperty, objectToApplyTo); + valueAtFromLocation = PropertyHelpers.GetValue(fromProperty, objectToApplyTo, actualFromProperty); } @@ -382,7 +382,7 @@ private void Remove(string path, T objectToApplyTo, Operation operationToRepo PropertyInfo pathProperty = PropertyHelpers.FindProperty(objectToApplyTo, actualPathToProperty); - + if (removeFromList || positionAsInteger > -1) { @@ -395,8 +395,9 @@ private void Remove(string path, T objectToApplyTo, Operation operationToRepo // now, get the generic type of the enumerable var genericTypeOfArray = PropertyHelpers.GetEnumerableType(pathProperty.PropertyType); + // TODO: nested! // get value (it can be cast, we just checked that) - var array = PropertyHelpers.GetValue(pathProperty, objectToApplyTo) as IList; + var array = PropertyHelpers.GetValue(pathProperty, objectToApplyTo, actualPathToProperty) as IList; if (removeFromList) { @@ -431,7 +432,7 @@ private void Remove(string path, T objectToApplyTo, Operation operationToRepo // setting the value to "null" will use the default value in case of value types, and // null in case of reference types - PropertyHelpers.SetValue(pathProperty, objectToApplyTo, null); + PropertyHelpers.SetValue(pathProperty, objectToApplyTo, actualPathToProperty, null); } } @@ -533,7 +534,7 @@ public void Test(Operation operation, T objectToApplyTo) typeOfFinalPropertyAtPathLocation = PropertyHelpers.GetEnumerableType(pathProperty.PropertyType); // get value (it can be cast, we just checked that) - var array = PropertyHelpers.GetValue(pathProperty, objectToApplyTo) as IList; + var array = PropertyHelpers.GetValue(pathProperty, objectToApplyTo, actualPathProperty) as IList; if (array.Count <= positionInPathAsInteger) { @@ -557,7 +558,7 @@ public void Test(Operation operation, T objectToApplyTo) else { // no list, just get the value - valueAtPathLocation = PropertyHelpers.GetValue(pathProperty, objectToApplyTo); + valueAtPathLocation = PropertyHelpers.GetValue(pathProperty, objectToApplyTo, actualPathProperty); typeOfFinalPropertyAtPathLocation = pathProperty.PropertyType; } @@ -672,7 +673,7 @@ public void Copy(Operation operation, T objectToApplyTo) var genericTypeOfArray = PropertyHelpers.GetEnumerableType(fromProperty.PropertyType); // get value (it can be cast, we just checked that) - var array = PropertyHelpers.GetValue(fromProperty, objectToApplyTo) as IList; + var array = PropertyHelpers.GetValue(fromProperty, objectToApplyTo, actualFromProperty) as IList; if (array.Count <= positionAsInteger) { @@ -699,7 +700,7 @@ public void Copy(Operation operation, T objectToApplyTo) // set the new value - valueAtFromLocation = PropertyHelpers.GetValue(fromProperty, objectToApplyTo); + valueAtFromLocation = PropertyHelpers.GetValue(fromProperty, objectToApplyTo, actualFromProperty); } diff --git a/src/Marvin.JsonPatch/Exceptions/JsonPatchException.cs b/src/Marvin.JsonPatch/Exceptions/JsonPatchException.cs index 81c5c2b..f1d1fb5 100644 --- a/src/Marvin.JsonPatch/Exceptions/JsonPatchException.cs +++ b/src/Marvin.JsonPatch/Exceptions/JsonPatchException.cs @@ -15,7 +15,7 @@ namespace Marvin.JsonPatch.Exceptions { public class JsonPatchException : Exception { - public Operation FailedOperation { get; private set; } + // public Operation FailedOperation { get; private set; } public object AffectedObject { get; private set; } private string _message = ""; @@ -27,23 +27,23 @@ public override string Message } } - + public JsonPatchException() { } - public JsonPatchException(Operation operation) - { - FailedOperation = operation; - } + //public JsonPatchException(Operation operation) + //{ + // FailedOperation = operation; + //} - public JsonPatchException(Operation operation, string message, object affectedObject) - { - FailedOperation = operation; - _message = message; - AffectedObject = affectedObject; - } + //public JsonPatchException(Operation operation, string message, object affectedObject) + //{ + // FailedOperation = operation; + // _message = message; + // AffectedObject = affectedObject; + //} } diff --git a/src/Marvin.JsonPatch/Helpers/PropertyHelpers.cs b/src/Marvin.JsonPatch/Helpers/PropertyHelpers.cs index 7fa9ab4..2da1f00 100644 --- a/src/Marvin.JsonPatch/Helpers/PropertyHelpers.cs +++ b/src/Marvin.JsonPatch/Helpers/PropertyHelpers.cs @@ -17,42 +17,27 @@ namespace Marvin.JsonPatch.Helpers { internal static class PropertyHelpers { - public static bool FindAndSetProperty(object targetObject, string propertyPath, object value) + + public static bool SetValue(PropertyInfo propertyToSet, object targetObject, string pathToProperty, object value) { - try - { + // it is possible the path refers to a nested property. In that case, we need to + // set on a different target object: the nested object. - string[] bits = propertyPath.Split('/'); - // skip the first one if it's empty + string[] splitPath = pathToProperty.Split('/'); - int startIndex = (string.IsNullOrWhiteSpace(bits[0]) ? 1 : 0); + // skip the first one if it's empty + int startIndex = (string.IsNullOrWhiteSpace(splitPath[0]) ? 1 : 0); + for (int i = startIndex; i < splitPath.Length - 1; i++) + { + PropertyInfo propertyInfoToGet = targetObject.GetType().GetProperty(splitPath[i] + , BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Instance); + targetObject = propertyInfoToGet.GetValue(targetObject, null); + } - for (int i = startIndex; i < bits.Length - 1; i++) - { - PropertyInfo propertyToGet = targetObject.GetType().GetProperty(bits[i]); - targetObject = propertyToGet.GetValue(targetObject, null); - } - - PropertyInfo propertyToSet = targetObject.GetType().GetProperty(bits.Last(), - BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Instance); - - - PropertyHelpers.SetValue(propertyToSet, targetObject, value); - // propertyToSet.SetValue(targetObject, value, null); - - return true; - - } - catch (Exception) - { - return false; - } - } + - public static bool SetValue(PropertyInfo propertyToSet, object targetObject, object value) - { if (value == null) { // then, set it. @@ -71,8 +56,24 @@ public static bool SetValue(PropertyInfo propertyToSet, object targetObject, obj return true; } - public static object GetValue(PropertyInfo propertyToGet, object targetObject) + public static object GetValue(PropertyInfo propertyToGet, object targetObject, string pathToProperty) { + // it is possible the path refers to a nested property. In that case, we need to + // get from a different target object: the nested object. + + string[] splitPath = pathToProperty.Split('/'); + + // skip the first one if it's empty + int startIndex = (string.IsNullOrWhiteSpace(splitPath[0]) ? 1 : 0); + + for (int i = startIndex; i < splitPath.Length - 1; i++) + { + PropertyInfo propertyInfoToGet = targetObject.GetType().GetProperty(splitPath[i] + , BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Instance); + targetObject = propertyInfoToGet.GetValue(targetObject, null); + } + + return propertyToGet.GetValue(targetObject, null); } @@ -89,7 +90,8 @@ public static bool CheckIfPropertyExists(object targetObject, string propertyPat for (int i = startIndex; i < splitPath.Length - 1; i++) { - PropertyInfo propertyInfoToGet = targetObject.GetType().GetProperty(splitPath[i]); + PropertyInfo propertyInfoToGet = targetObject.GetType().GetProperty(splitPath[i] + , BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Instance); targetObject = propertyInfoToGet.GetValue(targetObject, null); } @@ -129,7 +131,8 @@ public static PropertyInfo FindProperty(object targetObject, string propertyPath for (int i = startIndex; i < splitPath.Length - 1; i++) { - PropertyInfo propertyToGet = targetObject.GetType().GetProperty(splitPath[i]); + PropertyInfo propertyToGet = targetObject.GetType().GetProperty(splitPath[i] + , BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Instance); targetObject = propertyToGet.GetValue(targetObject, null); } diff --git a/src/Marvin.JsonPatch/JsonPatchDocument.cs b/src/Marvin.JsonPatch/JsonPatchDocument.cs index 2087153..1adfc99 100644 --- a/src/Marvin.JsonPatch/JsonPatchDocument.cs +++ b/src/Marvin.JsonPatch/JsonPatchDocument.cs @@ -30,108 +30,108 @@ namespace Marvin.JsonPatch /// The "application/json-patch+json" media type is used to identify such /// patch documents." /// - public class JsonPatchDocument - { - public List Operations { get; set; } - - - public JsonPatchDocument() - { - Operations = new List(); - } - - /// - /// Add operation. Will result in, for example, - /// { "op": "add", "path": "/a/b/c", "value": [ "foo", "bar" ] } - /// - /// - /// - /// - public JsonPatchDocument Add(string path, object value) - { - Operations.Add(new Operation("add", path, null, value)); - return this; - } - - - /// - /// Remove value at target location. Will result in, for example, - /// { "op": "remove", "path": "/a/b/c" } - /// - /// - /// - /// - public JsonPatchDocument Remove(string path) - { - Operations.Add(new Operation("remove", path, null,null)); - return this; - } - - /// - /// Replace value. Will result in, for example, - /// { "op": "replace", "path": "/a/b/c", "value": 42 } - /// - /// - /// - /// - public JsonPatchDocument Replace(string path, object value) - { - Operations.Add(new Operation("replace", path, null, value)); - return this; - } - - - /// - /// Removes value at specified location and add it to the target location. Will result in, for example: - /// { "op": "move", "from": "/a/b/c", "path": "/a/b/d" } - /// - /// - /// - /// - public JsonPatchDocument Move(string from, string path) - { - Operations.Add(new Operation("move", path, from, null)); - return this; - } - - /// - /// Copy the value at specified location to the target location. Willr esult in, for example: - /// { "op": "copy", "from": "/a/b/c", "path": "/a/b/e" } - /// - /// - /// - /// - public JsonPatchDocument Copy(string from, string path) - { - Operations.Add(new Operation("copy", path, from, null)); - return this; - } - - - ///// - ///// Tests that a value at the target location is equal to a specified value. - ///// Currently not implemented! - ///// - ///// - ///// - ///// - //public JsonPatchDocument Test(string path, object value) - //{ - // throw new NotImplementedException(); - //} - - - - public void ApplyTo(T objectToApplyTo, IDynamicObjectAdapter adapter) where T: class - { - - // apply each operation in order - foreach (var op in Operations) - { - op.Apply(objectToApplyTo, adapter); - } - - } - - } + //public class JsonPatchDocument + //{ + // public List Operations { get; set; } + + + // public JsonPatchDocument() + // { + // Operations = new List(); + // } + + // /// + // /// Add operation. Will result in, for example, + // /// { "op": "add", "path": "/a/b/c", "value": [ "foo", "bar" ] } + // /// + // /// + // /// + // /// + // public JsonPatchDocument Add(string path, object value) + // { + // Operations.Add(new Operation("add", path, null, value)); + // return this; + // } + + + // /// + // /// Remove value at target location. Will result in, for example, + // /// { "op": "remove", "path": "/a/b/c" } + // /// + // /// + // /// + // /// + // public JsonPatchDocument Remove(string path) + // { + // Operations.Add(new Operation("remove", path, null,null)); + // return this; + // } + + // /// + // /// Replace value. Will result in, for example, + // /// { "op": "replace", "path": "/a/b/c", "value": 42 } + // /// + // /// + // /// + // /// + // public JsonPatchDocument Replace(string path, object value) + // { + // Operations.Add(new Operation("replace", path, null, value)); + // return this; + // } + + + // /// + // /// Removes value at specified location and add it to the target location. Will result in, for example: + // /// { "op": "move", "from": "/a/b/c", "path": "/a/b/d" } + // /// + // /// + // /// + // /// + // public JsonPatchDocument Move(string from, string path) + // { + // Operations.Add(new Operation("move", path, from, null)); + // return this; + // } + + // /// + // /// Copy the value at specified location to the target location. Willr esult in, for example: + // /// { "op": "copy", "from": "/a/b/c", "path": "/a/b/e" } + // /// + // /// + // /// + // /// + // public JsonPatchDocument Copy(string from, string path) + // { + // Operations.Add(new Operation("copy", path, from, null)); + // return this; + // } + + + // ///// + // ///// Tests that a value at the target location is equal to a specified value. + // ///// Currently not implemented! + // ///// + // ///// + // ///// + // ///// + // //public JsonPatchDocument Test(string path, object value) + // //{ + // // throw new NotImplementedException(); + // //} + + + + // public void ApplyTo(T objectToApplyTo, IDynamicObjectAdapter adapter) where T: class + // { + + // // apply each operation in order + // foreach (var op in Operations) + // { + // op.Apply(objectToApplyTo, adapter); + // } + + // } + + //} } diff --git a/src/Marvin.JsonPatch/Operations/Operation.cs b/src/Marvin.JsonPatch/Operations/Operation.cs index b9db433..5f5a21e 100644 --- a/src/Marvin.JsonPatch/Operations/Operation.cs +++ b/src/Marvin.JsonPatch/Operations/Operation.cs @@ -17,66 +17,66 @@ namespace Marvin.JsonPatch.Operations { - public class Operation : OperationBase - { - [JsonProperty("value")] - public object value { get; set; } - - - public Operation() - { - - } - - - - public Operation(string op, string path, string from) - : base(op, path, from) - { - - } - public Operation(string op, string path, string from, object value) - : base (op, path, from) - { - - this.value = value; - } - - - public void Apply(T objectToApplyTo, IDynamicObjectAdapter adapter) where T : class - { - switch (OperationType) - { - case OperationType.Add: - adapter.Add(this, objectToApplyTo); - break; - case OperationType.Remove: - adapter.Remove(this, objectToApplyTo); - break; - case OperationType.Replace: - adapter.Replace(this, objectToApplyTo); - break; - case OperationType.Move: - adapter.Move(this, objectToApplyTo); - break; - case OperationType.Copy: - adapter.Copy(this, objectToApplyTo); - break; - case OperationType.Test: - adapter.Test(this, objectToApplyTo); - break; - default: - break; - } - } - - public bool ShouldSerializevalue() - { - return (OperationType == Operations.OperationType.Add - || OperationType == OperationType.Replace - || OperationType == OperationType.Test); - } - } + //public class Operation : OperationBase + //{ + // [JsonProperty("value")] + // public object value { get; set; } + + + // public Operation() + // { + + // } + + + + // public Operation(string op, string path, string from) + // : base(op, path, from) + // { + + // } + // public Operation(string op, string path, string from, object value) + // : base(op, path, from) + // { + + // this.value = value; + // } + + + // public void Apply(T objectToApplyTo, IDynamicObjectAdapter adapter) where T : class + // { + // switch (OperationType) + // { + // case OperationType.Add: + // adapter.Add(this, objectToApplyTo); + // break; + // case OperationType.Remove: + // adapter.Remove(this, objectToApplyTo); + // break; + // case OperationType.Replace: + // adapter.Replace(this, objectToApplyTo); + // break; + // case OperationType.Move: + // adapter.Move(this, objectToApplyTo); + // break; + // case OperationType.Copy: + // adapter.Copy(this, objectToApplyTo); + // break; + // case OperationType.Test: + // adapter.Test(this, objectToApplyTo); + // break; + // default: + // break; + // } + // } + + // public bool ShouldSerializevalue() + // { + // return (OperationType == Operations.OperationType.Add + // || OperationType == OperationType.Replace + // || OperationType == OperationType.Test); + // } + //}