Implement Replace Move and Copy for dynamic objects
This commit is contained in:
parent
ae57844c6a
commit
894574d04e
|
|
@ -359,73 +359,30 @@ namespace Microsoft.AspNet.JsonPatch.Adapters
|
|||
/// <param name="objectToApplyTo">Object to apply the operation to.</param>
|
||||
public void Move([NotNull] Operation operation, [NotNull] object objectToApplyTo)
|
||||
{
|
||||
// get value at from location
|
||||
object valueAtFromLocation = null;
|
||||
var positionAsInteger = -1;
|
||||
var actualFromProperty = operation.from;
|
||||
var valueAtFromLocationResult = GetValueAtLocation(operation.from, objectToApplyTo, operation);
|
||||
|
||||
positionAsInteger = GetNumericEnd(operation.from);
|
||||
|
||||
if (positionAsInteger > -1)
|
||||
{
|
||||
actualFromProperty = operation.from.Substring(0,
|
||||
operation.from.IndexOf('/' + positionAsInteger.ToString()));
|
||||
}
|
||||
|
||||
var patchProperty = FindPropertyAndParent(objectToApplyTo, actualFromProperty);
|
||||
|
||||
// does property at from exist?
|
||||
if (!CheckIfPropertyExists(patchProperty, objectToApplyTo, operation, operation.from))
|
||||
if (valueAtFromLocationResult.HasError)
|
||||
{
|
||||
// Error has already been logged in GetValueAtLocation. We
|
||||
// must return, because remove / add should not be allowed to continue
|
||||
return;
|
||||
}
|
||||
|
||||
// is the path an array (but not a string (= char[]))? In this case,
|
||||
// the path must end with "/position" or "/-", which we already determined before.
|
||||
if (positionAsInteger > -1)
|
||||
{
|
||||
if (IsNonStringArray(patchProperty.Property.PropertyType))
|
||||
{
|
||||
// now, get the generic type of the IList<> from Property type.
|
||||
var genericTypeOfArray = GetIListType(patchProperty.Property.PropertyType);
|
||||
|
||||
// get value (it can be cast, we just checked that)
|
||||
var array = (IList)patchProperty.Property.ValueProvider.GetValue(patchProperty.Parent);
|
||||
|
||||
if (array.Count <= positionAsInteger)
|
||||
{
|
||||
LogError(new JsonPatchError(
|
||||
objectToApplyTo,
|
||||
operation,
|
||||
Resources.FormatInvalidIndexForArrayProperty(operation.op, operation.from)));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
valueAtFromLocation = array[positionAsInteger];
|
||||
}
|
||||
else
|
||||
{
|
||||
LogError(new JsonPatchError(
|
||||
objectToApplyTo,
|
||||
operation,
|
||||
Resources.FormatInvalidPathForArrayProperty(operation.op, operation.from)));
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// no list, just get the value
|
||||
// set the new value
|
||||
valueAtFromLocation = patchProperty.Property.ValueProvider.GetValue(patchProperty.Parent);
|
||||
}
|
||||
|
||||
// remove that value
|
||||
Remove(operation.from, objectToApplyTo, operation);
|
||||
var removeResult = Remove(operation.from, objectToApplyTo, operation);
|
||||
|
||||
if (removeResult.HasError)
|
||||
{
|
||||
// Return => error has already been logged in remove method. We must
|
||||
// return, because add should not be allowed to continue
|
||||
return;
|
||||
}
|
||||
|
||||
// add that value to the path location
|
||||
Add(operation.path, valueAtFromLocation, objectToApplyTo, operation);
|
||||
Add(operation.path,
|
||||
valueAtFromLocationResult.PropertyValue,
|
||||
objectToApplyTo,
|
||||
operation);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -648,7 +605,7 @@ namespace Microsoft.AspNet.JsonPatch.Adapters
|
|||
Resources.FormatInvalidIndexForArrayProperty(
|
||||
operationToReport.op,
|
||||
path)));
|
||||
return null;
|
||||
return new RemovedPropertyTypeResult(null, true);
|
||||
}
|
||||
|
||||
array.RemoveAt(positionAsInteger);
|
||||
|
|
@ -706,8 +663,37 @@ namespace Microsoft.AspNet.JsonPatch.Adapters
|
|||
/// <param name="objectToApplyTo">Object to apply the operation to.</param>
|
||||
public void Replace([NotNull] Operation operation, [NotNull] object objectToApplyTo)
|
||||
{
|
||||
Remove(operation.path, objectToApplyTo, operation);
|
||||
Add(operation.path, operation.value, objectToApplyTo, operation);
|
||||
var removeResult = Remove(operation.path, objectToApplyTo, operation);
|
||||
|
||||
if (removeResult.HasError)
|
||||
{
|
||||
// return => error has already been logged in remove method
|
||||
return;
|
||||
}
|
||||
|
||||
if (!removeResult.HasError && removeResult.ActualType == null)
|
||||
{
|
||||
// the remove operation completed succesfully, but we could not determine the type.
|
||||
LogError(new JsonPatchError(
|
||||
objectToApplyTo,
|
||||
operation,
|
||||
Resources.FormatCannotDeterminePropertyType(operation.from)));
|
||||
return;
|
||||
}
|
||||
|
||||
var conversionResult = ConvertToActualType(removeResult.ActualType, operation.value);
|
||||
|
||||
if (!conversionResult.CanBeConverted)
|
||||
{
|
||||
// invalid value for path
|
||||
LogError(new JsonPatchError(
|
||||
objectToApplyTo,
|
||||
operation,
|
||||
Resources.FormatInvalidValueForProperty(operation.value, operation.path)));
|
||||
return;
|
||||
}
|
||||
|
||||
Add(operation.path, conversionResult.ConvertedInstance, objectToApplyTo, operation);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -734,100 +720,183 @@ namespace Microsoft.AspNet.JsonPatch.Adapters
|
|||
/// <param name="objectToApplyTo">Object to apply the operation to.</param>
|
||||
public void Copy([NotNull] Operation operation, [NotNull] object objectToApplyTo)
|
||||
{
|
||||
// get value at from location
|
||||
object valueAtFromLocation = null;
|
||||
var positionAsInteger = -1;
|
||||
var actualFromProperty = operation.from;
|
||||
// get value at from location and add that value to the path location
|
||||
var valueAtFromLocationResult = GetValueAtLocation(operation.from, objectToApplyTo, operation);
|
||||
|
||||
positionAsInteger = GetNumericEnd(operation.from);
|
||||
|
||||
if (positionAsInteger > -1)
|
||||
{
|
||||
actualFromProperty = operation.from.Substring(0,
|
||||
operation.from.IndexOf('/' + positionAsInteger.ToString()));
|
||||
}
|
||||
|
||||
var patchProperty = FindPropertyAndParent(objectToApplyTo, actualFromProperty);
|
||||
|
||||
// does property at from exist?
|
||||
if (!CheckIfPropertyExists(patchProperty, objectToApplyTo, operation, operation.from))
|
||||
if (valueAtFromLocationResult.HasError)
|
||||
{
|
||||
// Return, error has already been logged in GetValueAtLocation
|
||||
return;
|
||||
}
|
||||
|
||||
// get the property path
|
||||
// is the path an array (but not a string (= char[]))? In this case,
|
||||
// the path must end with "/position" or "/-", which we already determined before.
|
||||
if (positionAsInteger > -1)
|
||||
Add(operation.path,
|
||||
valueAtFromLocationResult.PropertyValue,
|
||||
objectToApplyTo,
|
||||
operation);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Method is used by Copy and Move to avoid duplicate code
|
||||
/// </summary>
|
||||
/// <param name="location">Location where value should be</param>
|
||||
/// <param name="objectToGetValueFrom">Object to inspect for the desired value</param>
|
||||
/// <param name="operationToReport">Operation to report in case of an error</param>
|
||||
/// <returns>GetValueResult containing value and a bool signifying a possible error</returns>
|
||||
private GetValueResult GetValueAtLocation(
|
||||
[NotNull] string location,
|
||||
[NotNull] object objectToGetValueFrom,
|
||||
[NotNull] Operation operationToReport)
|
||||
{
|
||||
// get path result
|
||||
var pathResult = GetActualPropertyPath(
|
||||
location,
|
||||
objectToGetValueFrom,
|
||||
operationToReport);
|
||||
|
||||
if (pathResult == null)
|
||||
{
|
||||
if (IsNonStringArray(patchProperty.Property.PropertyType))
|
||||
return new GetValueResult(null, true);
|
||||
}
|
||||
|
||||
var getAtEndOfList = pathResult.ExecuteAtEnd;
|
||||
var positionAsInteger = pathResult.NumericEnd;
|
||||
var actualPathToProperty = pathResult.PathToProperty;
|
||||
|
||||
var treeAnalysisResult = new ObjectTreeAnalysisResult(
|
||||
objectToGetValueFrom,
|
||||
actualPathToProperty,
|
||||
ContractResolver);
|
||||
|
||||
if (treeAnalysisResult.UseDynamicLogic)
|
||||
{
|
||||
// if it's not an array, we can remove the property from
|
||||
// the dictionary. If it's an array, we need to check the position first.
|
||||
if (getAtEndOfList || positionAsInteger > -1)
|
||||
{
|
||||
// now, get the generic type of the IList<> from Property type.
|
||||
var genericTypeOfArray = GetIListType(patchProperty.Property.PropertyType);
|
||||
var propertyValue = treeAnalysisResult.Container
|
||||
.GetValueForCaseInsensitiveKey(treeAnalysisResult.PropertyPathInParent);
|
||||
|
||||
// get value (it can be cast, we just checked that)
|
||||
var array = (IList)patchProperty.Property.ValueProvider.GetValue(patchProperty.Parent);
|
||||
|
||||
if (array.Count <= positionAsInteger)
|
||||
// we cannot continue when the value is null, because to be able to
|
||||
// continue we need to be able to check if the array is a non-string array
|
||||
if (propertyValue == null)
|
||||
{
|
||||
LogError(new JsonPatchError(
|
||||
objectToApplyTo,
|
||||
operation,
|
||||
Resources.FormatInvalidIndexForArrayProperty(operation.op, operation.from)));
|
||||
|
||||
return;
|
||||
objectToGetValueFrom,
|
||||
operationToReport,
|
||||
Resources.FormatCannotDeterminePropertyType(location)));
|
||||
return new GetValueResult(null, true);
|
||||
}
|
||||
|
||||
valueAtFromLocation = array[positionAsInteger];
|
||||
var typeOfPathProperty = propertyValue.GetType();
|
||||
|
||||
if (!IsNonStringArray(typeOfPathProperty))
|
||||
{
|
||||
LogError(new JsonPatchError(
|
||||
objectToGetValueFrom,
|
||||
operationToReport,
|
||||
Resources.FormatInvalidIndexForArrayProperty(operationToReport.op, location)));
|
||||
return new GetValueResult(null, true);
|
||||
}
|
||||
|
||||
// get the array
|
||||
var array = (IList)treeAnalysisResult.Container.GetValueForCaseInsensitiveKey(
|
||||
treeAnalysisResult.PropertyPathInParent);
|
||||
|
||||
if (positionAsInteger >= array.Count)
|
||||
{
|
||||
LogError(new JsonPatchError(
|
||||
objectToGetValueFrom,
|
||||
operationToReport,
|
||||
Resources.FormatInvalidIndexForArrayProperty(
|
||||
operationToReport.op,
|
||||
location)));
|
||||
return new GetValueResult(null, true);
|
||||
}
|
||||
|
||||
if (getAtEndOfList)
|
||||
{
|
||||
return new GetValueResult(array[array.Count-1], false);
|
||||
}
|
||||
else
|
||||
{
|
||||
return new GetValueResult(array[positionAsInteger], false);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LogError(new JsonPatchError(
|
||||
objectToApplyTo,
|
||||
operation,
|
||||
Resources.FormatInvalidPathForArrayProperty(operation.op, operation.from)));
|
||||
// get the property
|
||||
var propertyValueAtLocation = treeAnalysisResult.Container.GetValueForCaseInsensitiveKey(
|
||||
treeAnalysisResult.PropertyPathInParent);
|
||||
|
||||
return;
|
||||
}
|
||||
return new GetValueResult(propertyValueAtLocation, false);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// no list, just get the value
|
||||
// set the new value
|
||||
valueAtFromLocation = patchProperty.Property.ValueProvider.GetValue(patchProperty.Parent);
|
||||
// not dynamic
|
||||
var patchProperty = treeAnalysisResult.JsonPatchProperty;
|
||||
|
||||
if (getAtEndOfList || positionAsInteger > -1)
|
||||
{
|
||||
if (!IsNonStringArray(patchProperty.Property.PropertyType))
|
||||
{
|
||||
LogError(new JsonPatchError(
|
||||
objectToGetValueFrom,
|
||||
operationToReport,
|
||||
Resources.FormatInvalidIndexForArrayProperty(operationToReport.op, location)));
|
||||
return new GetValueResult(null, true);
|
||||
}
|
||||
|
||||
if (!patchProperty.Property.Readable)
|
||||
{
|
||||
LogError(new JsonPatchError(
|
||||
objectToGetValueFrom,
|
||||
operationToReport,
|
||||
Resources.FormatCannotReadProperty(location)));
|
||||
return new GetValueResult(null, true);
|
||||
}
|
||||
|
||||
var array = (IList)patchProperty.Property.ValueProvider
|
||||
.GetValue(patchProperty.Parent);
|
||||
|
||||
if (positionAsInteger >= array.Count)
|
||||
{
|
||||
LogError(new JsonPatchError(
|
||||
objectToGetValueFrom,
|
||||
operationToReport,
|
||||
Resources.FormatInvalidIndexForArrayProperty(
|
||||
operationToReport.op,
|
||||
location)));
|
||||
return new GetValueResult(null, true);
|
||||
}
|
||||
|
||||
if (getAtEndOfList)
|
||||
{
|
||||
return new GetValueResult(array[array.Count - 1], false);
|
||||
}
|
||||
else
|
||||
{
|
||||
return new GetValueResult(array[positionAsInteger], false);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!patchProperty.Property.Readable)
|
||||
{
|
||||
LogError(new JsonPatchError(
|
||||
objectToGetValueFrom,
|
||||
operationToReport,
|
||||
Resources.FormatCannotReadProperty(
|
||||
location)));
|
||||
return new GetValueResult(null, true);
|
||||
}
|
||||
|
||||
var propertyValueAtLocation = patchProperty.Property.ValueProvider
|
||||
.GetValue(patchProperty.Parent);
|
||||
|
||||
return new GetValueResult(propertyValueAtLocation, false);
|
||||
}
|
||||
}
|
||||
|
||||
// add operation to target location with that value.
|
||||
Add(operation.path, valueAtFromLocation, objectToApplyTo, operation);
|
||||
}
|
||||
|
||||
private bool CheckIfPropertyExists(
|
||||
JsonPatchProperty patchProperty,
|
||||
object objectToApplyTo,
|
||||
Operation operation,
|
||||
string propertyPath)
|
||||
{
|
||||
if (patchProperty == null)
|
||||
{
|
||||
LogError(new JsonPatchError(
|
||||
objectToApplyTo,
|
||||
operation,
|
||||
Resources.FormatPropertyDoesNotExist(propertyPath)));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (patchProperty.Property.Ignored)
|
||||
{
|
||||
LogError(new JsonPatchError(
|
||||
objectToApplyTo,
|
||||
operation,
|
||||
Resources.FormatCannotUpdateProperty(propertyPath)));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private bool IsNonStringArray(Type type)
|
||||
|
|
@ -840,25 +909,6 @@ namespace Microsoft.AspNet.JsonPatch.Adapters
|
|||
return (!(type == typeof(string)) && typeof(IList).GetTypeInfo().IsAssignableFrom(type.GetTypeInfo()));
|
||||
}
|
||||
|
||||
private bool CheckIfPropertyCanBeSet(
|
||||
ConversionResult result,
|
||||
object objectToApplyTo,
|
||||
Operation operation,
|
||||
string path)
|
||||
{
|
||||
if (!result.CanBeConverted)
|
||||
{
|
||||
LogError(new JsonPatchError(
|
||||
objectToApplyTo,
|
||||
operation,
|
||||
Resources.FormatInvalidValueForProperty(result.ConvertedInstance, path)));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private void LogError(JsonPatchError jsonPatchError)
|
||||
{
|
||||
if (LogErrorAction != null)
|
||||
|
|
@ -871,54 +921,6 @@ namespace Microsoft.AspNet.JsonPatch.Adapters
|
|||
}
|
||||
}
|
||||
|
||||
private JsonPatchProperty FindPropertyAndParent(object targetObject, string propertyPath)
|
||||
{
|
||||
try
|
||||
{
|
||||
var splitPath = propertyPath.Split('/');
|
||||
|
||||
// skip the first one if it's empty
|
||||
var startIndex = (string.IsNullOrWhiteSpace(splitPath[0]) ? 1 : 0);
|
||||
|
||||
for (int i = startIndex; i < splitPath.Length; i++)
|
||||
{
|
||||
var jsonContract = (JsonObjectContract)ContractResolver.ResolveContract(targetObject.GetType());
|
||||
|
||||
foreach (var property in jsonContract.Properties)
|
||||
{
|
||||
if (string.Equals(property.PropertyName, splitPath[i], StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
if (i == (splitPath.Length - 1))
|
||||
{
|
||||
return new JsonPatchProperty(property, targetObject);
|
||||
}
|
||||
else
|
||||
{
|
||||
targetObject = property.ValueProvider.GetValue(targetObject);
|
||||
|
||||
// if property is of IList type then get the array index from splitPath and get the
|
||||
// object at the indexed position from the list.
|
||||
if (GetIListType(property.PropertyType) != null)
|
||||
{
|
||||
var index = int.Parse(splitPath[++i]);
|
||||
targetObject = ((IList)targetObject)[index];
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
// will result in JsonPatchException in calling class, as expected
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private ConversionResult ConvertToActualType(Type propertyType, object value)
|
||||
{
|
||||
try
|
||||
|
|
@ -962,20 +964,6 @@ namespace Microsoft.AspNet.JsonPatch.Adapters
|
|||
return false;
|
||||
}
|
||||
|
||||
private int GetNumericEnd(string path)
|
||||
{
|
||||
var possibleIndex = path.Substring(path.LastIndexOf("/") + 1);
|
||||
var castedIndex = -1;
|
||||
|
||||
if (int.TryParse(possibleIndex, out castedIndex))
|
||||
{
|
||||
return castedIndex;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
private ActualPropertyPathResult GetActualPropertyPath(
|
||||
[NotNull] string propertyPath,
|
||||
[NotNull] object objectToApplyTo,
|
||||
|
|
|
|||
|
|
@ -0,0 +1,30 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
namespace Microsoft.AspNet.JsonPatch.Helpers
|
||||
{
|
||||
/// <summary>
|
||||
/// Return value for the helper method used by Copy/Move. Needed to ensure we can make a different
|
||||
/// decision in the calling method when the value is null because it cannot be fetched (HasError = true)
|
||||
/// versus when it actually is null (much like why RemovedPropertyTypeResult is used for returning
|
||||
/// type in the Remove operation).
|
||||
/// </summary>
|
||||
public class GetValueResult
|
||||
{
|
||||
public GetValueResult(object propertyValue, bool hasError)
|
||||
{
|
||||
PropertyValue = propertyValue;
|
||||
HasError = hasError;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The value of the property we're trying to get
|
||||
/// </summary>
|
||||
public object PropertyValue { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// HasError: true when an error occurred, the operation didn't complete succesfully
|
||||
/// </summary>
|
||||
public bool HasError { get; private set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,245 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Dynamic;
|
||||
using Newtonsoft.Json;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNet.JsonPatch.Test.Dynamic
|
||||
{
|
||||
public class CopyOperationTests
|
||||
{
|
||||
[Fact]
|
||||
public void Copy()
|
||||
{
|
||||
dynamic doc = new ExpandoObject();
|
||||
|
||||
doc.StringProperty = "A";
|
||||
doc.AnotherStringProperty = "B";
|
||||
|
||||
JsonPatchDocument patchDoc = new JsonPatchDocument();
|
||||
patchDoc.Copy("StringProperty", "AnotherStringProperty");
|
||||
|
||||
var serialized = JsonConvert.SerializeObject(patchDoc);
|
||||
var deserialized = JsonConvert.DeserializeObject<JsonPatchDocument>(serialized);
|
||||
deserialized.ApplyTo(doc);
|
||||
|
||||
Assert.Equal("A", doc.AnotherStringProperty);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CopyInList()
|
||||
{
|
||||
dynamic doc = new ExpandoObject();
|
||||
doc.IntegerList = new List<int>() { 1, 2, 3 };
|
||||
|
||||
// create patch
|
||||
JsonPatchDocument patchDoc = new JsonPatchDocument();
|
||||
patchDoc.Copy("IntegerList/0", "IntegerList/1");
|
||||
|
||||
var serialized = JsonConvert.SerializeObject(patchDoc);
|
||||
var deserialized = JsonConvert.DeserializeObject<JsonPatchDocument>(serialized);
|
||||
|
||||
deserialized.ApplyTo(doc);
|
||||
|
||||
Assert.Equal(new List<int>() { 1, 1, 2, 3 }, doc.IntegerList);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CopyFromListToEndOfList()
|
||||
{
|
||||
dynamic doc = new ExpandoObject();
|
||||
doc.IntegerList = new List<int>() { 1, 2, 3 };
|
||||
|
||||
// create patch
|
||||
JsonPatchDocument patchDoc = new JsonPatchDocument();
|
||||
patchDoc.Copy("IntegerList/0", "IntegerList/-");
|
||||
|
||||
var serialized = JsonConvert.SerializeObject(patchDoc);
|
||||
var deserialized = JsonConvert.DeserializeObject<JsonPatchDocument>(serialized);
|
||||
deserialized.ApplyTo(doc);
|
||||
|
||||
Assert.Equal(new List<int>() { 1, 2, 3, 1 }, doc.IntegerList);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CopyFromListToNonList()
|
||||
{
|
||||
dynamic doc = new ExpandoObject();
|
||||
doc.IntegerList = new List<int>() { 1, 2, 3 };
|
||||
|
||||
// create patch
|
||||
JsonPatchDocument patchDoc = new JsonPatchDocument();
|
||||
patchDoc.Copy("IntegerList/0", "IntegerValue");
|
||||
|
||||
var serialized = JsonConvert.SerializeObject(patchDoc);
|
||||
var deserialized = JsonConvert.DeserializeObject<JsonPatchDocument>(serialized);
|
||||
|
||||
deserialized.ApplyTo(doc);
|
||||
|
||||
Assert.Equal(1, doc.IntegerValue);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CopyFromNonListToList()
|
||||
{
|
||||
dynamic doc = new ExpandoObject();
|
||||
doc.IntegerValue = 5;
|
||||
doc.IntegerList = new List<int>() { 1, 2, 3 };
|
||||
|
||||
// create patch
|
||||
JsonPatchDocument patchDoc = new JsonPatchDocument();
|
||||
patchDoc.Copy("IntegerValue", "IntegerList/0");
|
||||
|
||||
var serialized = JsonConvert.SerializeObject(patchDoc);
|
||||
var deserialized = JsonConvert.DeserializeObject<JsonPatchDocument>(serialized);
|
||||
deserialized.ApplyTo(doc);
|
||||
|
||||
Assert.Equal(new List<int>() { 5, 1, 2, 3 }, doc.IntegerList);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CopyToEndOfList()
|
||||
{
|
||||
dynamic doc = new ExpandoObject();
|
||||
doc.IntegerValue = 5;
|
||||
doc.IntegerList = new List<int>() { 1, 2, 3 };
|
||||
|
||||
// create patch
|
||||
JsonPatchDocument patchDoc = new JsonPatchDocument();
|
||||
patchDoc.Copy("IntegerValue", "IntegerList/-");
|
||||
|
||||
var serialized = JsonConvert.SerializeObject(patchDoc);
|
||||
var deserialized = JsonConvert.DeserializeObject<JsonPatchDocument>(serialized);
|
||||
|
||||
deserialized.ApplyTo(doc);
|
||||
|
||||
Assert.Equal(new List<int>() { 1, 2, 3, 5 }, doc.IntegerList);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void NestedCopy()
|
||||
{
|
||||
dynamic doc = new ExpandoObject();
|
||||
doc.SimpleDTO = new SimpleDTO()
|
||||
{
|
||||
StringProperty = "A",
|
||||
AnotherStringProperty = "B"
|
||||
};
|
||||
|
||||
// create patch
|
||||
JsonPatchDocument patchDoc = new JsonPatchDocument();
|
||||
patchDoc.Copy("SimpleDTO/StringProperty", "SimpleDTO/AnotherStringProperty");
|
||||
|
||||
var serialized = JsonConvert.SerializeObject(patchDoc);
|
||||
var deserialized = JsonConvert.DeserializeObject<JsonPatchDocument>(serialized);
|
||||
|
||||
deserialized.ApplyTo(doc);
|
||||
|
||||
Assert.Equal("A", doc.SimpleDTO.AnotherStringProperty);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void NestedCopyInList()
|
||||
{
|
||||
dynamic doc = new ExpandoObject();
|
||||
doc.SimpleDTO = new SimpleDTO()
|
||||
{
|
||||
IntegerList = new List<int>() { 1, 2, 3 }
|
||||
};
|
||||
|
||||
// create patch
|
||||
JsonPatchDocument patchDoc = new JsonPatchDocument();
|
||||
patchDoc.Copy("SimpleDTO/IntegerList/0", "SimpleDTO/IntegerList/1");
|
||||
|
||||
var serialized = JsonConvert.SerializeObject(patchDoc);
|
||||
var deserialized = JsonConvert.DeserializeObject<JsonPatchDocument>(serialized);
|
||||
deserialized.ApplyTo(doc);
|
||||
|
||||
Assert.Equal(new List<int>() { 1, 1, 2, 3 }, doc.SimpleDTO.IntegerList);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void NestedCopyFromListToEndOfList()
|
||||
{
|
||||
dynamic doc = new ExpandoObject();
|
||||
doc.SimpleDTO = new SimpleDTO()
|
||||
{
|
||||
IntegerList = new List<int>() { 1, 2, 3 }
|
||||
};
|
||||
|
||||
// create patch
|
||||
JsonPatchDocument patchDoc = new JsonPatchDocument();
|
||||
patchDoc.Copy("SimpleDTO/IntegerList/0", "SimpleDTO/IntegerList/-");
|
||||
|
||||
var serialized = JsonConvert.SerializeObject(patchDoc);
|
||||
var deserialized = JsonConvert.DeserializeObject<JsonPatchDocument>(serialized);
|
||||
|
||||
deserialized.ApplyTo(doc);
|
||||
|
||||
Assert.Equal(new List<int>() { 1, 2, 3, 1 }, doc.SimpleDTO.IntegerList);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void NestedCopyFromListToNonList()
|
||||
{
|
||||
dynamic doc = new ExpandoObject();
|
||||
doc.SimpleDTO = new SimpleDTO()
|
||||
{
|
||||
IntegerList = new List<int>() { 1, 2, 3 }
|
||||
};
|
||||
|
||||
// create patch
|
||||
JsonPatchDocument patchDoc = new JsonPatchDocument();
|
||||
patchDoc.Copy("SimpleDTO/IntegerList/0", "SimpleDTO/IntegerValue");
|
||||
|
||||
var serialized = JsonConvert.SerializeObject(patchDoc);
|
||||
var deserialized = JsonConvert.DeserializeObject<JsonPatchDocument>(serialized);
|
||||
deserialized.ApplyTo(doc);
|
||||
|
||||
Assert.Equal(1, doc.SimpleDTO.IntegerValue);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void NestedCopyFromNonListToList()
|
||||
{
|
||||
dynamic doc = new ExpandoObject();
|
||||
doc.SimpleDTO = new SimpleDTO()
|
||||
{
|
||||
IntegerValue = 5,
|
||||
IntegerList = new List<int>() { 1, 2, 3 }
|
||||
};
|
||||
|
||||
// create patch
|
||||
JsonPatchDocument patchDoc = new JsonPatchDocument();
|
||||
patchDoc.Copy("SimpleDTO/IntegerValue", "SimpleDTO/IntegerList/0");
|
||||
var serialized = JsonConvert.SerializeObject(patchDoc);
|
||||
var deserialized = JsonConvert.DeserializeObject<JsonPatchDocument>(serialized);
|
||||
deserialized.ApplyTo(doc);
|
||||
|
||||
Assert.Equal(new List<int>() { 5, 1, 2, 3 }, doc.SimpleDTO.IntegerList);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void NestedCopyToEndOfList()
|
||||
{
|
||||
dynamic doc = new ExpandoObject();
|
||||
doc.SimpleDTO = new SimpleDTO()
|
||||
{
|
||||
IntegerValue = 5,
|
||||
IntegerList = new List<int>() { 1, 2, 3 }
|
||||
};
|
||||
|
||||
// create patch
|
||||
JsonPatchDocument patchDoc = new JsonPatchDocument();
|
||||
patchDoc.Copy("SimpleDTO/IntegerValue", "SimpleDTO/IntegerList/-");
|
||||
|
||||
var serialized = JsonConvert.SerializeObject(patchDoc);
|
||||
var deserialized = JsonConvert.DeserializeObject<JsonPatchDocument>(serialized);
|
||||
deserialized.ApplyTo(doc);
|
||||
|
||||
Assert.Equal(new List<int>() { 1, 2, 3, 5 }, doc.SimpleDTO.IntegerList);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,268 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System.Collections.Generic;
|
||||
using Newtonsoft.Json;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNet.JsonPatch.Test.Dynamic
|
||||
{
|
||||
public class CopyTypedOperationTests
|
||||
{
|
||||
[Fact]
|
||||
public void Copy()
|
||||
{
|
||||
var doc = new SimpleDTO()
|
||||
{
|
||||
StringProperty = "A",
|
||||
AnotherStringProperty = "B"
|
||||
};
|
||||
|
||||
// create patch
|
||||
JsonPatchDocument patchDoc = new JsonPatchDocument();
|
||||
patchDoc.Copy("StringProperty", "AnotherStringProperty");
|
||||
|
||||
var serialized = JsonConvert.SerializeObject(patchDoc);
|
||||
var deserialized = JsonConvert.DeserializeObject<JsonPatchDocument>(serialized);
|
||||
deserialized.ApplyTo(doc);
|
||||
|
||||
Assert.Equal("A", doc.AnotherStringProperty);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CopyInList()
|
||||
{
|
||||
var doc = new SimpleDTO()
|
||||
{
|
||||
IntegerList = new List<int>() { 1, 2, 3 }
|
||||
};
|
||||
|
||||
// create patch
|
||||
JsonPatchDocument patchDoc = new JsonPatchDocument();
|
||||
patchDoc.Copy("IntegerList/0", "IntegerList/1");
|
||||
|
||||
var serialized = JsonConvert.SerializeObject(patchDoc);
|
||||
var deserialized = JsonConvert.DeserializeObject<JsonPatchDocument>(serialized);
|
||||
|
||||
deserialized.ApplyTo(doc);
|
||||
|
||||
Assert.Equal(new List<int>() { 1, 1, 2, 3 }, doc.IntegerList);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CopyFromListToEndOfList()
|
||||
{
|
||||
var doc = new SimpleDTO()
|
||||
{
|
||||
IntegerList = new List<int>() { 1, 2, 3 }
|
||||
};
|
||||
|
||||
// create patch
|
||||
JsonPatchDocument patchDoc = new JsonPatchDocument();
|
||||
patchDoc.Copy("IntegerList/0", "IntegerList/-");
|
||||
|
||||
var serialized = JsonConvert.SerializeObject(patchDoc);
|
||||
var deserialized = JsonConvert.DeserializeObject<JsonPatchDocument>(serialized);
|
||||
deserialized.ApplyTo(doc);
|
||||
|
||||
Assert.Equal(new List<int>() { 1, 2, 3, 1 }, doc.IntegerList);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CopyFromListToNonList()
|
||||
{
|
||||
var doc = new SimpleDTO()
|
||||
{
|
||||
IntegerList = new List<int>() { 1, 2, 3 }
|
||||
};
|
||||
|
||||
// create patch
|
||||
JsonPatchDocument patchDoc = new JsonPatchDocument();
|
||||
patchDoc.Copy("IntegerList/0", "IntegerValue");
|
||||
|
||||
var serialized = JsonConvert.SerializeObject(patchDoc);
|
||||
var deserialized = JsonConvert.DeserializeObject<JsonPatchDocument>(serialized);
|
||||
|
||||
deserialized.ApplyTo(doc);
|
||||
|
||||
Assert.Equal(1, doc.IntegerValue);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CopyFromNonListToList()
|
||||
{
|
||||
var doc = new SimpleDTO()
|
||||
{
|
||||
IntegerValue = 5,
|
||||
IntegerList = new List<int>() { 1, 2, 3 }
|
||||
};
|
||||
|
||||
// create patch
|
||||
JsonPatchDocument patchDoc = new JsonPatchDocument();
|
||||
patchDoc.Copy("IntegerValue", "IntegerList/0");
|
||||
|
||||
var serialized = JsonConvert.SerializeObject(patchDoc);
|
||||
var deserialized = JsonConvert.DeserializeObject<JsonPatchDocument>(serialized);
|
||||
deserialized.ApplyTo(doc);
|
||||
|
||||
Assert.Equal(new List<int>() { 5, 1, 2, 3 }, doc.IntegerList);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CopyToEndOfList()
|
||||
{
|
||||
var doc = new SimpleDTO()
|
||||
{
|
||||
IntegerValue = 5,
|
||||
IntegerList = new List<int>() { 1, 2, 3 }
|
||||
};
|
||||
|
||||
// create patch
|
||||
JsonPatchDocument patchDoc = new JsonPatchDocument();
|
||||
patchDoc.Copy("IntegerValue", "IntegerList/-");
|
||||
|
||||
var serialized = JsonConvert.SerializeObject(patchDoc);
|
||||
var deserialized = JsonConvert.DeserializeObject<JsonPatchDocument>(serialized);
|
||||
|
||||
deserialized.ApplyTo(doc);
|
||||
|
||||
Assert.Equal(new List<int>() { 1, 2, 3, 5 }, doc.IntegerList);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void NestedCopy()
|
||||
{
|
||||
var doc = new SimpleDTOWithNestedDTO()
|
||||
{
|
||||
SimpleDTO = new SimpleDTO()
|
||||
{
|
||||
StringProperty = "A",
|
||||
AnotherStringProperty = "B"
|
||||
}
|
||||
};
|
||||
|
||||
// create patch
|
||||
JsonPatchDocument patchDoc = new JsonPatchDocument();
|
||||
patchDoc.Copy("SimpleDTO/StringProperty", "SimpleDTO/AnotherStringProperty");
|
||||
|
||||
var serialized = JsonConvert.SerializeObject(patchDoc);
|
||||
var deserialized = JsonConvert.DeserializeObject<JsonPatchDocument>(serialized);
|
||||
|
||||
deserialized.ApplyTo(doc);
|
||||
|
||||
Assert.Equal("A", doc.SimpleDTO.AnotherStringProperty);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void NestedCopyInList()
|
||||
{
|
||||
var doc = new SimpleDTOWithNestedDTO()
|
||||
{
|
||||
SimpleDTO = new SimpleDTO()
|
||||
{
|
||||
IntegerList = new List<int>() { 1, 2, 3 }
|
||||
}
|
||||
};
|
||||
|
||||
// create patch
|
||||
JsonPatchDocument patchDoc = new JsonPatchDocument();
|
||||
patchDoc.Copy("SimpleDTO/IntegerList/0", "SimpleDTO/IntegerList/1");
|
||||
|
||||
var serialized = JsonConvert.SerializeObject(patchDoc);
|
||||
var deserialized = JsonConvert.DeserializeObject<JsonPatchDocument>(serialized);
|
||||
deserialized.ApplyTo(doc);
|
||||
|
||||
Assert.Equal(new List<int>() { 1, 1, 2, 3 }, doc.SimpleDTO.IntegerList);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void NestedCopyFromListToEndOfList()
|
||||
{
|
||||
var doc = new SimpleDTOWithNestedDTO()
|
||||
{
|
||||
SimpleDTO = new SimpleDTO()
|
||||
{
|
||||
IntegerList = new List<int>() { 1, 2, 3 }
|
||||
}
|
||||
};
|
||||
|
||||
// create patch
|
||||
JsonPatchDocument patchDoc = new JsonPatchDocument();
|
||||
patchDoc.Copy("SimpleDTO/IntegerList/0", "SimpleDTO/IntegerList/-");
|
||||
|
||||
var serialized = JsonConvert.SerializeObject(patchDoc);
|
||||
var deserialized = JsonConvert.DeserializeObject<JsonPatchDocument>(serialized);
|
||||
|
||||
deserialized.ApplyTo(doc);
|
||||
|
||||
Assert.Equal(new List<int>() { 1, 2, 3, 1 }, doc.SimpleDTO.IntegerList);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void NestedCopyFromListToNonList()
|
||||
{
|
||||
var doc = new SimpleDTOWithNestedDTO()
|
||||
{
|
||||
SimpleDTO = new SimpleDTO()
|
||||
{
|
||||
IntegerList = new List<int>() { 1, 2, 3 }
|
||||
}
|
||||
};
|
||||
|
||||
// create patch
|
||||
JsonPatchDocument patchDoc = new JsonPatchDocument();
|
||||
patchDoc.Copy("SimpleDTO/IntegerList/0", "SimpleDTO/IntegerValue");
|
||||
|
||||
var serialized = JsonConvert.SerializeObject(patchDoc);
|
||||
var deserialized = JsonConvert.DeserializeObject<JsonPatchDocument>(serialized);
|
||||
deserialized.ApplyTo(doc);
|
||||
|
||||
Assert.Equal(1, doc.SimpleDTO.IntegerValue);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void NestedCopyFromNonListToList()
|
||||
{
|
||||
var doc = new SimpleDTOWithNestedDTO()
|
||||
{
|
||||
SimpleDTO = new SimpleDTO()
|
||||
{
|
||||
IntegerValue = 5,
|
||||
IntegerList = new List<int>() { 1, 2, 3 }
|
||||
}
|
||||
};
|
||||
|
||||
// create patch
|
||||
JsonPatchDocument patchDoc = new JsonPatchDocument();
|
||||
patchDoc.Copy("SimpleDTO/IntegerValue", "SimpleDTO/IntegerList/0");
|
||||
var serialized = JsonConvert.SerializeObject(patchDoc);
|
||||
var deserialized = JsonConvert.DeserializeObject<JsonPatchDocument>(serialized);
|
||||
deserialized.ApplyTo(doc);
|
||||
|
||||
Assert.Equal(new List<int>() { 5, 1, 2, 3 }, doc.SimpleDTO.IntegerList);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void NestedCopyToEndOfList()
|
||||
{
|
||||
var doc = new SimpleDTOWithNestedDTO()
|
||||
{
|
||||
SimpleDTO = new SimpleDTO()
|
||||
{
|
||||
IntegerValue = 5,
|
||||
IntegerList = new List<int>() { 1, 2, 3 }
|
||||
}
|
||||
};
|
||||
|
||||
// create patch
|
||||
JsonPatchDocument patchDoc = new JsonPatchDocument();
|
||||
patchDoc.Copy("SimpleDTO/IntegerValue", "SimpleDTO/IntegerList/-");
|
||||
|
||||
var serialized = JsonConvert.SerializeObject(patchDoc);
|
||||
var deserialized = JsonConvert.DeserializeObject<JsonPatchDocument>(serialized);
|
||||
deserialized.ApplyTo(doc);
|
||||
|
||||
Assert.Equal(new List<int>() { 1, 2, 3, 5 }, doc.SimpleDTO.IntegerList);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,338 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Dynamic;
|
||||
using Newtonsoft.Json;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNet.JsonPatch.Test.Dynamic
|
||||
{
|
||||
public class MoveOperationTests
|
||||
{
|
||||
[Fact]
|
||||
public void Move()
|
||||
{
|
||||
dynamic doc = new ExpandoObject();
|
||||
doc.StringProperty = "A";
|
||||
doc.AnotherStringProperty = "B";
|
||||
|
||||
// create patch
|
||||
JsonPatchDocument patchDoc = new JsonPatchDocument();
|
||||
patchDoc.Move("StringProperty", "AnotherStringProperty");
|
||||
|
||||
var serialized = JsonConvert.SerializeObject(patchDoc);
|
||||
var deserialized = JsonConvert.DeserializeObject<JsonPatchDocument>(serialized);
|
||||
|
||||
deserialized.ApplyTo(doc);
|
||||
|
||||
Assert.Equal("A", doc.AnotherStringProperty);
|
||||
|
||||
var cont = doc as IDictionary<string, object>;
|
||||
object valueFromDictionary;
|
||||
cont.TryGetValue("StringProperty", out valueFromDictionary);
|
||||
Assert.Null(valueFromDictionary);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void MoveToNonExisting()
|
||||
{
|
||||
dynamic doc = new ExpandoObject();
|
||||
doc.StringProperty = "A";
|
||||
|
||||
// create patch
|
||||
JsonPatchDocument patchDoc = new JsonPatchDocument();
|
||||
patchDoc.Move("StringProperty", "AnotherStringProperty");
|
||||
|
||||
var serialized = JsonConvert.SerializeObject(patchDoc);
|
||||
var deserialized = JsonConvert.DeserializeObject<JsonPatchDocument>(serialized);
|
||||
|
||||
deserialized.ApplyTo(doc);
|
||||
|
||||
Assert.Equal("A", doc.AnotherStringProperty);
|
||||
|
||||
var cont = doc as IDictionary<string, object>;
|
||||
object valueFromDictionary;
|
||||
cont.TryGetValue("StringProperty", out valueFromDictionary);
|
||||
Assert.Null(valueFromDictionary);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void MoveDynamicToTyped()
|
||||
{
|
||||
dynamic doc = new ExpandoObject();
|
||||
doc.StringProperty = "A";
|
||||
doc.SimpleDTO = new SimpleDTO() { AnotherStringProperty = "B" };
|
||||
|
||||
// create patch
|
||||
JsonPatchDocument patchDoc = new JsonPatchDocument();
|
||||
patchDoc.Move("StringProperty", "SimpleDTO/AnotherStringProperty");
|
||||
|
||||
var serialized = JsonConvert.SerializeObject(patchDoc);
|
||||
var deserialized = JsonConvert.DeserializeObject<JsonPatchDocument>(serialized);
|
||||
|
||||
deserialized.ApplyTo(doc);
|
||||
|
||||
Assert.Equal("A", doc.SimpleDTO.AnotherStringProperty);
|
||||
|
||||
var cont = doc as IDictionary<string, object>;
|
||||
object valueFromDictionary;
|
||||
cont.TryGetValue("StringProperty", out valueFromDictionary);
|
||||
Assert.Null(valueFromDictionary);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void MoveTypedToDynamic()
|
||||
{
|
||||
dynamic doc = new ExpandoObject();
|
||||
doc.StringProperty = "A";
|
||||
doc.SimpleDTO = new SimpleDTO() { AnotherStringProperty = "B" };
|
||||
|
||||
// create patch
|
||||
JsonPatchDocument patchDoc = new JsonPatchDocument();
|
||||
patchDoc.Move("SimpleDTO/AnotherStringProperty", "StringProperty");
|
||||
|
||||
var serialized = JsonConvert.SerializeObject(patchDoc);
|
||||
var deserialized = JsonConvert.DeserializeObject<JsonPatchDocument>(serialized);
|
||||
|
||||
deserialized.ApplyTo(doc);
|
||||
|
||||
Assert.Equal("B", doc.StringProperty);
|
||||
Assert.Equal(null, doc.SimpleDTO.AnotherStringProperty);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void NestedMove()
|
||||
{
|
||||
dynamic doc = new ExpandoObject();
|
||||
doc.Nested = new SimpleDTO()
|
||||
{
|
||||
StringProperty = "A",
|
||||
AnotherStringProperty = "B"
|
||||
};
|
||||
|
||||
// create patch
|
||||
JsonPatchDocument patchDoc = new JsonPatchDocument();
|
||||
patchDoc.Move("Nested/StringProperty", "Nested/AnotherStringProperty");
|
||||
|
||||
var serialized = JsonConvert.SerializeObject(patchDoc);
|
||||
var deserialized = JsonConvert.DeserializeObject<JsonPatchDocument>(serialized);
|
||||
|
||||
deserialized.ApplyTo(doc);
|
||||
|
||||
Assert.Equal("A", doc.Nested.AnotherStringProperty);
|
||||
Assert.Equal(null, doc.Nested.StringProperty);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void MoveInList()
|
||||
{
|
||||
dynamic doc = new ExpandoObject();
|
||||
doc.IntegerList = new List<int>() { 1, 2, 3 };
|
||||
|
||||
// create patch
|
||||
JsonPatchDocument patchDoc = new JsonPatchDocument();
|
||||
patchDoc.Move("IntegerList/0", "IntegerList/1");
|
||||
|
||||
var serialized = JsonConvert.SerializeObject(patchDoc);
|
||||
var deserialized = JsonConvert.DeserializeObject<JsonPatchDocument>(serialized);
|
||||
|
||||
deserialized.ApplyTo(doc);
|
||||
|
||||
Assert.Equal(new List<int>() { 2, 1, 3 }, doc.IntegerList);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void NestedMoveInList()
|
||||
{
|
||||
dynamic doc = new ExpandoObject();
|
||||
doc.Nested = new SimpleDTO()
|
||||
{
|
||||
IntegerList = new List<int>() { 1, 2, 3 }
|
||||
};
|
||||
|
||||
// create patch
|
||||
JsonPatchDocument patchDoc = new JsonPatchDocument();
|
||||
patchDoc.Move("Nested/IntegerList/0", "Nested/IntegerList/1");
|
||||
|
||||
var serialized = JsonConvert.SerializeObject(patchDoc);
|
||||
var deserialized = JsonConvert.DeserializeObject<JsonPatchDocument>(serialized);
|
||||
|
||||
deserialized.ApplyTo(doc);
|
||||
|
||||
Assert.Equal(new List<int>() { 2, 1, 3 }, doc.Nested.IntegerList);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void MoveFromListToEndOfList()
|
||||
{
|
||||
dynamic doc = new ExpandoObject();
|
||||
doc.IntegerList = new List<int>() { 1, 2, 3 };
|
||||
|
||||
// create patch
|
||||
JsonPatchDocument patchDoc = new JsonPatchDocument();
|
||||
patchDoc.Move("IntegerList/0", "IntegerList/-");
|
||||
|
||||
var serialized = JsonConvert.SerializeObject(patchDoc);
|
||||
var deserialized = JsonConvert.DeserializeObject<JsonPatchDocument>(serialized);
|
||||
deserialized.ApplyTo(doc);
|
||||
|
||||
Assert.Equal(new List<int>() { 2, 3, 1 }, doc.IntegerList);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void NestedMoveFromListToEndOfList()
|
||||
{
|
||||
dynamic doc = new ExpandoObject();
|
||||
doc.Nested = new SimpleDTO()
|
||||
{
|
||||
IntegerList = new List<int>() { 1, 2, 3 }
|
||||
};
|
||||
|
||||
// create patch
|
||||
JsonPatchDocument patchDoc = new JsonPatchDocument();
|
||||
patchDoc.Move("Nested/IntegerList/0", "Nested/IntegerList/-");
|
||||
|
||||
var serialized = JsonConvert.SerializeObject(patchDoc);
|
||||
var deserialized = JsonConvert.DeserializeObject<JsonPatchDocument>(serialized);
|
||||
deserialized.ApplyTo(doc);
|
||||
|
||||
Assert.Equal(new List<int>() { 2, 3, 1 }, doc.Nested.IntegerList);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void MoveFomListToNonList()
|
||||
{
|
||||
dynamic doc = new ExpandoObject();
|
||||
doc.IntegerList = new List<int>() { 1, 2, 3 };
|
||||
|
||||
// create patch
|
||||
JsonPatchDocument patchDoc = new JsonPatchDocument();
|
||||
patchDoc.Move("IntegerList/0", "IntegerValue");
|
||||
|
||||
var serialized = JsonConvert.SerializeObject(patchDoc);
|
||||
var deserialized = JsonConvert.DeserializeObject<JsonPatchDocument>(serialized);
|
||||
|
||||
deserialized.ApplyTo(doc);
|
||||
|
||||
Assert.Equal(new List<int>() { 2, 3 }, doc.IntegerList);
|
||||
Assert.Equal(1, doc.IntegerValue);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void NestedMoveFomListToNonList()
|
||||
{
|
||||
dynamic doc = new ExpandoObject();
|
||||
doc.Nested = new SimpleDTO()
|
||||
{
|
||||
IntegerList = new List<int>() { 1, 2, 3 }
|
||||
};
|
||||
|
||||
// create patch
|
||||
JsonPatchDocument patchDoc = new JsonPatchDocument();
|
||||
patchDoc.Move("Nested/IntegerList/0", "Nested/IntegerValue");
|
||||
|
||||
var serialized = JsonConvert.SerializeObject(patchDoc);
|
||||
var deserialized = JsonConvert.DeserializeObject<JsonPatchDocument>(serialized);
|
||||
|
||||
deserialized.ApplyTo(doc);
|
||||
|
||||
Assert.Equal(new List<int>() { 2, 3 }, doc.Nested.IntegerList);
|
||||
Assert.Equal(1, doc.Nested.IntegerValue);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void MoveFromNonListToList()
|
||||
{
|
||||
dynamic doc = new ExpandoObject();
|
||||
doc.IntegerValue = 5;
|
||||
doc.IntegerList = new List<int>() { 1, 2, 3 };
|
||||
|
||||
// create patch
|
||||
JsonPatchDocument patchDoc = new JsonPatchDocument();
|
||||
patchDoc.Move("IntegerValue", "IntegerList/0");
|
||||
|
||||
var serialized = JsonConvert.SerializeObject(patchDoc);
|
||||
var deserialized = JsonConvert.DeserializeObject<JsonPatchDocument>(serialized);
|
||||
|
||||
deserialized.ApplyTo(doc);
|
||||
|
||||
var cont = doc as IDictionary<string, object>;
|
||||
object valueFromDictionary;
|
||||
cont.TryGetValue("IntegerValue", out valueFromDictionary);
|
||||
Assert.Null(valueFromDictionary);
|
||||
|
||||
Assert.Equal(new List<int>() { 5, 1, 2, 3 }, doc.IntegerList);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void NestedMoveFromNonListToList()
|
||||
{
|
||||
dynamic doc = new ExpandoObject();
|
||||
doc.Nested = new SimpleDTO()
|
||||
{
|
||||
IntegerValue = 5,
|
||||
IntegerList = new List<int>() { 1, 2, 3 }
|
||||
};
|
||||
|
||||
// create patch
|
||||
JsonPatchDocument patchDoc = new JsonPatchDocument();
|
||||
patchDoc.Move("Nested/IntegerValue", "Nested/IntegerList/0");
|
||||
|
||||
var serialized = JsonConvert.SerializeObject(patchDoc);
|
||||
var deserialized = JsonConvert.DeserializeObject<JsonPatchDocument>(serialized);
|
||||
|
||||
deserialized.ApplyTo(doc);
|
||||
|
||||
Assert.Equal(0, doc.Nested.IntegerValue);
|
||||
Assert.Equal(new List<int>() { 5, 1, 2, 3 }, doc.Nested.IntegerList);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void MoveToEndOfList()
|
||||
{
|
||||
dynamic doc = new ExpandoObject();
|
||||
doc.IntegerValue = 5;
|
||||
doc.IntegerList = new List<int>() { 1, 2, 3 };
|
||||
|
||||
// create patch
|
||||
JsonPatchDocument patchDoc = new JsonPatchDocument();
|
||||
patchDoc.Move("IntegerValue", "IntegerList/-");
|
||||
|
||||
var serialized = JsonConvert.SerializeObject(patchDoc);
|
||||
var deserialized = JsonConvert.DeserializeObject<JsonPatchDocument>(serialized);
|
||||
|
||||
deserialized.ApplyTo(doc);
|
||||
|
||||
var cont = doc as IDictionary<string, object>;
|
||||
object valueFromDictionary;
|
||||
cont.TryGetValue("IntegerValue", out valueFromDictionary);
|
||||
Assert.Null(valueFromDictionary);
|
||||
|
||||
Assert.Equal(new List<int>() { 1, 2, 3, 5 }, doc.IntegerList);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void NestedMoveToEndOfList()
|
||||
{
|
||||
dynamic doc = new ExpandoObject();
|
||||
doc.Nested = new SimpleDTO()
|
||||
{
|
||||
IntegerValue = 5,
|
||||
IntegerList = new List<int>() { 1, 2, 3 }
|
||||
};
|
||||
|
||||
// create patch
|
||||
JsonPatchDocument patchDoc = new JsonPatchDocument();
|
||||
patchDoc.Move("Nested/IntegerValue", "Nested/IntegerList/-");
|
||||
|
||||
var serialized = JsonConvert.SerializeObject(patchDoc);
|
||||
var deserialized = JsonConvert.DeserializeObject<JsonPatchDocument>(serialized);
|
||||
|
||||
deserialized.ApplyTo(doc);
|
||||
|
||||
Assert.Equal(0, doc.Nested.IntegerValue);
|
||||
Assert.Equal(new List<int>() { 1, 2, 3, 5 }, doc.Nested.IntegerList);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,138 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System.Collections.Generic;
|
||||
using Newtonsoft.Json;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNet.JsonPatch.Test.Dynamic
|
||||
{
|
||||
public class MoveTypedOperationTests
|
||||
{
|
||||
[Fact]
|
||||
public void Move()
|
||||
{
|
||||
var doc = new SimpleDTO()
|
||||
{
|
||||
StringProperty = "A",
|
||||
AnotherStringProperty = "B"
|
||||
};
|
||||
|
||||
// create patch
|
||||
JsonPatchDocument patchDoc = new JsonPatchDocument();
|
||||
patchDoc.Move("StringProperty", "AnotherStringProperty");
|
||||
|
||||
var serialized = JsonConvert.SerializeObject(patchDoc);
|
||||
var deserialized = JsonConvert.DeserializeObject<JsonPatchDocument>(serialized);
|
||||
|
||||
deserialized.ApplyTo(doc);
|
||||
|
||||
Assert.Equal("A", doc.AnotherStringProperty);
|
||||
Assert.Equal(null, doc.StringProperty);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void MoveInList()
|
||||
{
|
||||
var doc = new SimpleDTO()
|
||||
{
|
||||
IntegerList = new List<int>() { 1, 2, 3 }
|
||||
};
|
||||
|
||||
// create patch
|
||||
JsonPatchDocument patchDoc = new JsonPatchDocument();
|
||||
patchDoc.Move("IntegerList/0", "IntegerList/1");
|
||||
|
||||
var serialized = JsonConvert.SerializeObject(patchDoc);
|
||||
var deserialized = JsonConvert.DeserializeObject<JsonPatchDocument>(serialized);
|
||||
|
||||
deserialized.ApplyTo(doc);
|
||||
|
||||
Assert.Equal(new List<int>() { 2, 1, 3 }, doc.IntegerList);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void MoveFromListToEndOfList()
|
||||
{
|
||||
var doc = new SimpleDTO()
|
||||
{
|
||||
IntegerList = new List<int>() { 1, 2, 3 }
|
||||
};
|
||||
|
||||
// create patch
|
||||
JsonPatchDocument patchDoc = new JsonPatchDocument();
|
||||
patchDoc.Move("IntegerList/0", "IntegerList/-");
|
||||
|
||||
var serialized = JsonConvert.SerializeObject(patchDoc);
|
||||
var deserialized = JsonConvert.DeserializeObject<JsonPatchDocument>(serialized);
|
||||
deserialized.ApplyTo(doc);
|
||||
|
||||
Assert.Equal(new List<int>() { 2, 3, 1 }, doc.IntegerList);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void MoveFomListToNonList()
|
||||
{
|
||||
var doc = new SimpleDTO()
|
||||
{
|
||||
IntegerList = new List<int>() { 1, 2, 3 }
|
||||
};
|
||||
|
||||
// create patch
|
||||
JsonPatchDocument patchDoc = new JsonPatchDocument();
|
||||
patchDoc.Move("IntegerList/0", "IntegerValue");
|
||||
|
||||
var serialized = JsonConvert.SerializeObject(patchDoc);
|
||||
var deserialized = JsonConvert.DeserializeObject<JsonPatchDocument>(serialized);
|
||||
|
||||
deserialized.ApplyTo(doc);
|
||||
|
||||
Assert.Equal(new List<int>() { 2, 3 }, doc.IntegerList);
|
||||
Assert.Equal(1, doc.IntegerValue);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void MoveFromNonListToList()
|
||||
{
|
||||
var doc = new SimpleDTO()
|
||||
{
|
||||
IntegerValue = 5,
|
||||
IntegerList = new List<int>() { 1, 2, 3 }
|
||||
};
|
||||
|
||||
// create patch
|
||||
JsonPatchDocument patchDoc = new JsonPatchDocument();
|
||||
patchDoc.Move("IntegerValue", "IntegerList/0");
|
||||
|
||||
var serialized = JsonConvert.SerializeObject(patchDoc);
|
||||
var deserialized = JsonConvert.DeserializeObject<JsonPatchDocument>(serialized);
|
||||
|
||||
deserialized.ApplyTo(doc);
|
||||
|
||||
Assert.Equal(0, doc.IntegerValue);
|
||||
Assert.Equal(new List<int>() { 5, 1, 2, 3 }, doc.IntegerList);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void MoveToEndOfList()
|
||||
{
|
||||
var doc = new SimpleDTO()
|
||||
{
|
||||
IntegerValue = 5,
|
||||
IntegerList = new List<int>() { 1, 2, 3 }
|
||||
};
|
||||
|
||||
// create patch
|
||||
JsonPatchDocument patchDoc = new JsonPatchDocument();
|
||||
patchDoc.Move("IntegerValue", "IntegerList/-");
|
||||
|
||||
var serialized = JsonConvert.SerializeObject(patchDoc);
|
||||
var deserialized = JsonConvert.DeserializeObject<JsonPatchDocument>(serialized);
|
||||
|
||||
deserialized.ApplyTo(doc);
|
||||
|
||||
Assert.Equal(0, doc.IntegerValue);
|
||||
Assert.Equal(new List<int>() { 1, 2, 3, 5 }, doc.IntegerList);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,242 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Dynamic;
|
||||
using Newtonsoft.Json;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNet.JsonPatch.Test.Dynamic
|
||||
{
|
||||
public class ReplaceOperationTests
|
||||
{
|
||||
[Fact]
|
||||
public void ReplaceGuidTest()
|
||||
{
|
||||
dynamic doc = new SimpleDTO()
|
||||
{
|
||||
GuidValue = Guid.NewGuid()
|
||||
};
|
||||
|
||||
var newGuid = Guid.NewGuid();
|
||||
// create patch
|
||||
JsonPatchDocument patchDoc = new JsonPatchDocument();
|
||||
patchDoc.Replace("GuidValue", newGuid);
|
||||
|
||||
// serialize & deserialize
|
||||
var serialized = JsonConvert.SerializeObject(patchDoc);
|
||||
var deserizalized = JsonConvert.DeserializeObject<JsonPatchDocument>(serialized);
|
||||
|
||||
deserizalized.ApplyTo(doc);
|
||||
|
||||
Assert.Equal(newGuid, doc.GuidValue);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ReplaceGuidTestExpandoObject()
|
||||
{
|
||||
dynamic doc = new ExpandoObject();
|
||||
doc.GuidValue = Guid.NewGuid();
|
||||
|
||||
var newGuid = Guid.NewGuid();
|
||||
// create patch
|
||||
JsonPatchDocument patchDoc = new JsonPatchDocument();
|
||||
patchDoc.Replace("GuidValue", newGuid);
|
||||
|
||||
// serialize & deserialize
|
||||
var serialized = JsonConvert.SerializeObject(patchDoc);
|
||||
var deserizalized = JsonConvert.DeserializeObject<JsonPatchDocument>(serialized);
|
||||
|
||||
deserizalized.ApplyTo(doc);
|
||||
|
||||
Assert.Equal(newGuid, doc.GuidValue);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ReplaceGuidTestExpandoObjectInAnonymous()
|
||||
{
|
||||
dynamic nestedObject = new ExpandoObject();
|
||||
nestedObject.GuidValue = Guid.NewGuid();
|
||||
|
||||
dynamic doc = new
|
||||
{
|
||||
NestedObject = nestedObject
|
||||
};
|
||||
|
||||
var newGuid = Guid.NewGuid();
|
||||
// create patch
|
||||
JsonPatchDocument patchDoc = new JsonPatchDocument();
|
||||
patchDoc.Replace("nestedobject/GuidValue", newGuid);
|
||||
|
||||
// serialize & deserialize
|
||||
var serialized = JsonConvert.SerializeObject(patchDoc);
|
||||
var deserizalized = JsonConvert.DeserializeObject<JsonPatchDocument>(serialized);
|
||||
|
||||
deserizalized.ApplyTo(doc);
|
||||
|
||||
Assert.Equal(newGuid, doc.NestedObject.GuidValue);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ReplaceNestedObjectTest()
|
||||
{
|
||||
dynamic doc = new ExpandoObject();
|
||||
doc.SimpleDTO = new SimpleDTO()
|
||||
{
|
||||
IntegerValue = 5,
|
||||
IntegerList = new List<int>() { 1, 2, 3 }
|
||||
};
|
||||
|
||||
var newDTO = new SimpleDTO()
|
||||
{
|
||||
DoubleValue = 1
|
||||
};
|
||||
|
||||
// create patch
|
||||
JsonPatchDocument patchDoc = new JsonPatchDocument();
|
||||
patchDoc.Replace("SimpleDTO", newDTO);
|
||||
|
||||
// serialize & deserialize
|
||||
var serialized = JsonConvert.SerializeObject(patchDoc);
|
||||
var deserialized = JsonConvert.DeserializeObject<JsonPatchDocument>(serialized);
|
||||
|
||||
deserialized.ApplyTo(doc);
|
||||
|
||||
Assert.Equal(1, doc.SimpleDTO.DoubleValue);
|
||||
Assert.Equal(0, doc.SimpleDTO.IntegerValue);
|
||||
Assert.Equal(null, doc.SimpleDTO.IntegerList);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ReplaceInList()
|
||||
{
|
||||
dynamic doc = new ExpandoObject();
|
||||
doc.IntegerList = new List<int>() { 1, 2, 3 };
|
||||
|
||||
// create patch
|
||||
JsonPatchDocument patchDoc = new JsonPatchDocument();
|
||||
patchDoc.Replace("IntegerList/0", 5);
|
||||
|
||||
var serialized = JsonConvert.SerializeObject(patchDoc);
|
||||
var deserialized = JsonConvert.DeserializeObject<JsonPatchDocument>(serialized);
|
||||
|
||||
deserialized.ApplyTo(doc);
|
||||
|
||||
Assert.Equal(new List<int>() { 5, 2, 3 }, doc.IntegerList);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ReplaceFullList()
|
||||
{
|
||||
dynamic doc = new ExpandoObject();
|
||||
doc.IntegerList = new List<int>() { 1, 2, 3 };
|
||||
|
||||
// create patch
|
||||
JsonPatchDocument patchDoc = new JsonPatchDocument();
|
||||
patchDoc.Replace("IntegerList", new List<int>() { 4, 5, 6 });
|
||||
|
||||
var serialized = JsonConvert.SerializeObject(patchDoc);
|
||||
var deserialized = JsonConvert.DeserializeObject<JsonPatchDocument>(serialized);
|
||||
|
||||
deserialized.ApplyTo(doc);
|
||||
|
||||
Assert.Equal(new List<int>() { 4, 5, 6 }, doc.IntegerList);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ReplaceInListInList()
|
||||
{
|
||||
dynamic doc = new ExpandoObject();
|
||||
doc.SimpleDTOList = new List<SimpleDTO>() {
|
||||
new SimpleDTO() {
|
||||
IntegerList = new List<int>(){1,2,3}
|
||||
}};
|
||||
|
||||
// create patch
|
||||
JsonPatchDocument patchDoc = new JsonPatchDocument();
|
||||
patchDoc.Replace("SimpleDTOList/0/IntegerList/0", 4);
|
||||
|
||||
var serialized = JsonConvert.SerializeObject(patchDoc);
|
||||
var deserialized = JsonConvert.DeserializeObject<JsonPatchDocument>(serialized);
|
||||
|
||||
deserialized.ApplyTo(doc);
|
||||
|
||||
Assert.Equal(4, doc.SimpleDTOList[0].IntegerList[0]);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ReplaceInListInListAtEnd()
|
||||
{
|
||||
dynamic doc = new ExpandoObject();
|
||||
doc.SimpleDTOList = new List<SimpleDTO>() {
|
||||
new SimpleDTO() {
|
||||
IntegerList = new List<int>(){1,2,3}
|
||||
}};
|
||||
|
||||
// create patch
|
||||
JsonPatchDocument patchDoc = new JsonPatchDocument();
|
||||
patchDoc.Replace("SimpleDTOList/0/IntegerList/-", 4);
|
||||
|
||||
var serialized = JsonConvert.SerializeObject(patchDoc);
|
||||
var deserialized = JsonConvert.DeserializeObject<JsonPatchDocument>(serialized);
|
||||
|
||||
deserialized.ApplyTo(doc);
|
||||
|
||||
Assert.Equal(4, doc.SimpleDTOList[0].IntegerList[2]);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ReplaceFullListFromEnumerable()
|
||||
{
|
||||
dynamic doc = new ExpandoObject();
|
||||
doc.IntegerList = new List<int>() { 1, 2, 3 };
|
||||
|
||||
// create patch
|
||||
JsonPatchDocument patchDoc = new JsonPatchDocument();
|
||||
patchDoc.Replace("IntegerList", new List<int>() { 4, 5, 6 });
|
||||
|
||||
var serialized = JsonConvert.SerializeObject(patchDoc);
|
||||
var deserialized = JsonConvert.DeserializeObject<JsonPatchDocument>(serialized);
|
||||
|
||||
deserialized.ApplyTo(doc);
|
||||
Assert.Equal(new List<int>() { 4, 5, 6 }, doc.IntegerList);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ReplaceFullListWithCollection()
|
||||
{
|
||||
dynamic doc = new ExpandoObject();
|
||||
doc.IntegerList = new List<int>() { 1, 2, 3 };
|
||||
|
||||
// create patch
|
||||
JsonPatchDocument patchDoc = new JsonPatchDocument();
|
||||
patchDoc.Replace("IntegerList", new Collection<int>() { 4, 5, 6 });
|
||||
|
||||
var serialized = JsonConvert.SerializeObject(patchDoc);
|
||||
var deserialized = JsonConvert.DeserializeObject<JsonPatchDocument>(serialized);
|
||||
|
||||
deserialized.ApplyTo(doc);
|
||||
|
||||
Assert.Equal(new List<int>() { 4, 5, 6 }, doc.IntegerList);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ReplaceAtEndOfList()
|
||||
{
|
||||
dynamic doc = new ExpandoObject();
|
||||
doc.IntegerList = new List<int>() { 1, 2, 3 };
|
||||
|
||||
// create patch
|
||||
JsonPatchDocument patchDoc = new JsonPatchDocument();
|
||||
patchDoc.Replace("IntegerList/-", 5);
|
||||
|
||||
var serialized = JsonConvert.SerializeObject(patchDoc);
|
||||
var deserialized = JsonConvert.DeserializeObject<JsonPatchDocument>(serialized);
|
||||
deserialized.ApplyTo(doc);
|
||||
|
||||
Assert.Equal(new List<int>() { 1, 2, 5 }, doc.IntegerList);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,191 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
using Newtonsoft.Json;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNet.JsonPatch.Test.Dynamic
|
||||
{
|
||||
public class ReplaceTypedOperationTests
|
||||
{
|
||||
[Fact]
|
||||
public void ReplaceGuidTest()
|
||||
{
|
||||
var doc = new SimpleDTO()
|
||||
{
|
||||
GuidValue = Guid.NewGuid()
|
||||
};
|
||||
|
||||
var newGuid = Guid.NewGuid();
|
||||
// create patch
|
||||
JsonPatchDocument patchDoc = new JsonPatchDocument();
|
||||
patchDoc.Replace("GuidValue", newGuid);
|
||||
|
||||
// serialize & deserialize
|
||||
var serialized = JsonConvert.SerializeObject(patchDoc);
|
||||
var deserizalized = JsonConvert.DeserializeObject<JsonPatchDocument>(serialized);
|
||||
|
||||
deserizalized.ApplyTo(doc);
|
||||
|
||||
Assert.Equal(newGuid, doc.GuidValue);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void SerializeAndReplaceNestedObjectTest()
|
||||
{
|
||||
var doc = new SimpleDTOWithNestedDTO()
|
||||
{
|
||||
SimpleDTO = new SimpleDTO()
|
||||
{
|
||||
IntegerValue = 5,
|
||||
IntegerList = new List<int>() { 1, 2, 3 }
|
||||
}
|
||||
};
|
||||
|
||||
var newDTO = new SimpleDTO()
|
||||
{
|
||||
DoubleValue = 1
|
||||
};
|
||||
|
||||
// create patch
|
||||
JsonPatchDocument patchDoc = new JsonPatchDocument();
|
||||
patchDoc.Replace("SimpleDTO", newDTO);
|
||||
|
||||
// serialize & deserialize
|
||||
var serialized = JsonConvert.SerializeObject(patchDoc);
|
||||
var deserialized = JsonConvert.DeserializeObject<JsonPatchDocument>(serialized);
|
||||
|
||||
deserialized.ApplyTo(doc);
|
||||
|
||||
Assert.Equal(1, doc.SimpleDTO.DoubleValue);
|
||||
Assert.Equal(0, doc.SimpleDTO.IntegerValue);
|
||||
Assert.Equal(null, doc.SimpleDTO.IntegerList);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ReplaceInList()
|
||||
{
|
||||
var doc = new SimpleDTO()
|
||||
{
|
||||
IntegerList = new List<int>() { 1, 2, 3 }
|
||||
};
|
||||
|
||||
// create patch
|
||||
JsonPatchDocument patchDoc = new JsonPatchDocument();
|
||||
patchDoc.Replace("IntegerList/0", 5);
|
||||
|
||||
var serialized = JsonConvert.SerializeObject(patchDoc);
|
||||
var deserialized = JsonConvert.DeserializeObject<JsonPatchDocument>(serialized);
|
||||
|
||||
deserialized.ApplyTo(doc);
|
||||
|
||||
Assert.Equal(new List<int>() { 5, 2, 3 }, doc.IntegerList);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ReplaceFullList()
|
||||
{
|
||||
var doc = new SimpleDTO()
|
||||
{
|
||||
IntegerList = new List<int>() { 1, 2, 3 }
|
||||
};
|
||||
|
||||
// create patch
|
||||
JsonPatchDocument patchDoc = new JsonPatchDocument();
|
||||
patchDoc.Replace("IntegerList", new List<int>() { 4, 5, 6 });
|
||||
|
||||
var serialized = JsonConvert.SerializeObject(patchDoc);
|
||||
var deserialized = JsonConvert.DeserializeObject<JsonPatchDocument>(serialized);
|
||||
|
||||
deserialized.ApplyTo(doc);
|
||||
|
||||
Assert.Equal(new List<int>() { 4, 5, 6 }, doc.IntegerList);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ReplaceInListInList()
|
||||
{
|
||||
var doc = new SimpleDTO()
|
||||
{
|
||||
SimpleDTOList = new List<SimpleDTO>() {
|
||||
new SimpleDTO() {
|
||||
IntegerList = new List<int>(){1,2,3}
|
||||
}}
|
||||
};
|
||||
|
||||
// create patch
|
||||
JsonPatchDocument patchDoc = new JsonPatchDocument();
|
||||
patchDoc.Replace("SimpleDTOList/0/IntegerList/0", 4);
|
||||
|
||||
var serialized = JsonConvert.SerializeObject(patchDoc);
|
||||
var deserialized = JsonConvert.DeserializeObject<JsonPatchDocument>(serialized);
|
||||
|
||||
deserialized.ApplyTo(doc);
|
||||
|
||||
Assert.Equal(4, doc.SimpleDTOList.First().IntegerList.First());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ReplaceFullListFromEnumerable()
|
||||
{
|
||||
var doc = new SimpleDTO()
|
||||
{
|
||||
IntegerList = new List<int>() { 1, 2, 3 }
|
||||
};
|
||||
|
||||
// create patch
|
||||
JsonPatchDocument patchDoc = new JsonPatchDocument();
|
||||
patchDoc.Replace("IntegerList", new List<int>() { 4, 5, 6 });
|
||||
|
||||
var serialized = JsonConvert.SerializeObject(patchDoc);
|
||||
var deserialized = JsonConvert.DeserializeObject<JsonPatchDocument>(serialized);
|
||||
|
||||
deserialized.ApplyTo(doc);
|
||||
|
||||
Assert.Equal(new List<int>() { 4, 5, 6 }, doc.IntegerList);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ReplaceFullListWithCollection()
|
||||
{
|
||||
var doc = new SimpleDTO()
|
||||
{
|
||||
IntegerList = new List<int>() { 1, 2, 3 }
|
||||
};
|
||||
|
||||
// create patch
|
||||
JsonPatchDocument patchDoc = new JsonPatchDocument();
|
||||
patchDoc.Replace("IntegerList", new Collection<int>() { 4, 5, 6 });
|
||||
|
||||
var serialized = JsonConvert.SerializeObject(patchDoc);
|
||||
var deserialized = JsonConvert.DeserializeObject<JsonPatchDocument>(serialized);
|
||||
|
||||
deserialized.ApplyTo(doc);
|
||||
|
||||
Assert.Equal(new List<int>() { 4, 5, 6 }, doc.IntegerList);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ReplaceAtEndOfList()
|
||||
{
|
||||
var doc = new SimpleDTO()
|
||||
{
|
||||
IntegerList = new List<int>() { 1, 2, 3 }
|
||||
};
|
||||
|
||||
// create patch
|
||||
JsonPatchDocument patchDoc = new JsonPatchDocument();
|
||||
patchDoc.Replace("IntegerList/-", 5);
|
||||
|
||||
var serialized = JsonConvert.SerializeObject(patchDoc);
|
||||
var deserialized = JsonConvert.DeserializeObject<JsonPatchDocument>(serialized);
|
||||
deserialized.ApplyTo(doc);
|
||||
|
||||
Assert.Equal(new List<int>() { 1, 2, 5 }, doc.IntegerList);
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue