Support DynamicObject types (#99)

Addresses #38
This commit is contained in:
Jass Bagga 2017-08-24 15:11:01 -07:00 committed by GitHub
parent d4b64af0e6
commit 3d6a8615de
41 changed files with 1950 additions and 1208 deletions

View File

@ -0,0 +1,211 @@
// 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.Reflection;
using System.Runtime.CompilerServices;
using Microsoft.CSharp.RuntimeBinder;
using Newtonsoft.Json.Serialization;
using CSharpBinder = Microsoft.CSharp.RuntimeBinder;
namespace Microsoft.AspNetCore.JsonPatch.Internal
{
public class DynamicObjectAdapter : IAdapter
{
public bool TryAdd(
object target,
string segment,
IContractResolver contractResolver,
object value,
out string errorMessage)
{
if (!TrySetDynamicObjectProperty(target, contractResolver, segment, value, out errorMessage))
{
return false;
}
errorMessage = null;
return true;
}
public bool TryGet(
object target,
string segment,
IContractResolver contractResolver,
out object value,
out string errorMessage)
{
if (!TryGetDynamicObjectProperty(target, contractResolver, segment, out value, out errorMessage))
{
value = null;
return false;
}
errorMessage = null;
return true;
}
public bool TryRemove(
object target,
string segment,
IContractResolver contractResolver,
out string errorMessage)
{
if (!TryGetDynamicObjectProperty(target, contractResolver, segment, out var property, out errorMessage))
{
return false;
}
// Setting the value to "null" will use the default value in case of value types, and
// null in case of reference types
object value = null;
if (property.GetType().GetTypeInfo().IsValueType
&& Nullable.GetUnderlyingType(property.GetType()) == null)
{
value = Activator.CreateInstance(property.GetType());
}
if (!TrySetDynamicObjectProperty(target, contractResolver, segment, value, out errorMessage))
{
return false;
}
errorMessage = null;
return true;
}
public bool TryReplace(
object target,
string segment,
IContractResolver contractResolver,
object value,
out string errorMessage)
{
if (!TryGetDynamicObjectProperty(target, contractResolver, segment, out var property, out errorMessage))
{
return false;
}
if (!TryConvertValue(value, property.GetType(), out var convertedValue))
{
errorMessage = Resources.FormatInvalidValueForProperty(value);
return false;
}
if (!TrySetDynamicObjectProperty(target, contractResolver, segment, convertedValue, out errorMessage))
{
return false;
}
errorMessage = null;
return true;
}
public bool TryTraverse(
object target,
string segment,
IContractResolver contractResolver,
out object nextTarget,
out string errorMessage)
{
if (!TryGetDynamicObjectProperty(target, contractResolver, segment, out var property, out errorMessage))
{
nextTarget = null;
return false;
}
else
{
nextTarget = property;
errorMessage = null;
return true;
}
}
private bool TryGetDynamicObjectProperty(
object target,
IContractResolver contractResolver,
string segment,
out object value,
out string errorMessage)
{
var jsonDynamicContract = (JsonDynamicContract)contractResolver.ResolveContract(target.GetType());
var propertyName = jsonDynamicContract.PropertyNameResolver(segment);
var binder = CSharpBinder.Binder.GetMember(
CSharpBinderFlags.None,
propertyName,
target.GetType(),
new List<CSharpArgumentInfo>
{
CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null)
});
var callsite = CallSite<Func<CallSite, object, object>>.Create(binder);
try
{
value = callsite.Target(callsite, target);
errorMessage = null;
return true;
}
catch (RuntimeBinderException)
{
value = null;
errorMessage = Resources.FormatTargetLocationAtPathSegmentNotFound(segment);
return false;
}
}
private bool TrySetDynamicObjectProperty(
object target,
IContractResolver contractResolver,
string segment,
object value,
out string errorMessage)
{
var jsonDynamicContract = (JsonDynamicContract)contractResolver.ResolveContract(target.GetType());
var propertyName = jsonDynamicContract.PropertyNameResolver(segment);
var binder = CSharpBinder.Binder.SetMember(
CSharpBinderFlags.None,
propertyName,
target.GetType(),
new List<CSharpArgumentInfo>
{
CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null),
CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null)
});
var callsite = CallSite<Func<CallSite, object, object, object>>.Create(binder);
try
{
callsite.Target(callsite, target, value);
errorMessage = null;
return true;
}
catch (RuntimeBinderException)
{
errorMessage = Resources.FormatTargetLocationAtPathSegmentNotFound(segment);
return false;
}
}
private bool TryConvertValue(object value, Type propertyType, out object convertedValue)
{
var conversionResult = ConversionResultProvider.ConvertTo(value, propertyType);
if (!conversionResult.CanBeConverted)
{
convertedValue = null;
return false;
}
convertedValue = conversionResult.ConvertedInstance;
return true;
}
}
}

View File

@ -15,13 +15,8 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal
public ObjectVisitor(ParsedPath path, IContractResolver contractResolver) public ObjectVisitor(ParsedPath path, IContractResolver contractResolver)
{ {
if (contractResolver == null)
{
throw new ArgumentNullException(nameof(contractResolver));
}
_path = path; _path = path;
_contractResolver = contractResolver; _contractResolver = contractResolver ?? throw new ArgumentNullException(nameof(contractResolver));
} }
public bool TryVisit(ref object target, out IAdapter adapter, out string errorMessage) public bool TryVisit(ref object target, out IAdapter adapter, out string errorMessage)
@ -38,8 +33,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal
// Traverse until the penultimate segment to get the target object and adapter // Traverse until the penultimate segment to get the target object and adapter
for (var i = 0; i < _path.Segments.Count - 1; i++) for (var i = 0; i < _path.Segments.Count - 1; i++)
{ {
object next; if (!adapter.TryTraverse(target, _path.Segments[i], _contractResolver, out var next, out errorMessage))
if (!adapter.TryTraverse(target, _path.Segments[i], _contractResolver, out next, out errorMessage))
{ {
adapter = null; adapter = null;
return false; return false;
@ -59,6 +53,10 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal
{ {
return new ExpandoObjectAdapter(); return new ExpandoObjectAdapter();
} }
else if (targetObject is IDynamicMetaObjectProvider)
{
return new DynamicObjectAdapter();
}
else if (targetObject is IDictionary) else if (targetObject is IDictionary)
{ {
return new DictionaryAdapter(); return new DictionaryAdapter();

View File

@ -10,277 +10,243 @@ namespace Microsoft.AspNetCore.JsonPatch
private static readonly ResourceManager _resourceManager private static readonly ResourceManager _resourceManager
= new ResourceManager("Microsoft.AspNetCore.JsonPatch.Resources", typeof(Resources).GetTypeInfo().Assembly); = new ResourceManager("Microsoft.AspNetCore.JsonPatch.Resources", typeof(Resources).GetTypeInfo().Assembly);
/// <summary>
/// The type of the property at path '{0}' could not be determined.
/// </summary>
internal static string CannotDeterminePropertyType
{
get { return GetString("CannotDeterminePropertyType"); }
}
/// <summary>
/// The type of the property at path '{0}' could not be determined.
/// </summary>
internal static string FormatCannotDeterminePropertyType(object p0)
{
return string.Format(CultureInfo.CurrentCulture, GetString("CannotDeterminePropertyType"), p0);
}
/// <summary> /// <summary>
/// The property at '{0}' could not be copied. /// The property at '{0}' could not be copied.
/// </summary> /// </summary>
internal static string CannotCannotCopyProperty internal static string CannotCopyProperty
{ {
get { return GetString("CannotCannotCopyProperty"); } get => GetString("CannotCopyProperty");
} }
/// <summary> /// <summary>
/// The property at '{0}' could not be copied. /// The property at '{0}' could not be copied.
/// </summary> /// </summary>
internal static string FormatCannotCopyProperty(object p0) internal static string FormatCannotCopyProperty(object p0)
=> string.Format(CultureInfo.CurrentCulture, GetString("CannotCopyProperty"), p0);
/// <summary>
/// The type of the property at path '{0}' could not be determined.
/// </summary>
internal static string CannotDeterminePropertyType
{ {
return string.Format(CultureInfo.CurrentCulture, GetString("CannotCannotCopyProperty"), p0); get => GetString("CannotDeterminePropertyType");
} }
/// <summary>
/// The type of the property at path '{0}' could not be determined.
/// </summary>
internal static string FormatCannotDeterminePropertyType(object p0)
=> string.Format(CultureInfo.CurrentCulture, GetString("CannotDeterminePropertyType"), p0);
/// <summary> /// <summary>
/// The '{0}' operation at path '{1}' could not be performed. /// The '{0}' operation at path '{1}' could not be performed.
/// </summary> /// </summary>
internal static string CannotPerformOperation internal static string CannotPerformOperation
{ {
get { return GetString("CannotPerformOperation"); } get => GetString("CannotPerformOperation");
} }
/// <summary> /// <summary>
/// The '{0}' operation at path '{1}' could not be performed. /// The '{0}' operation at path '{1}' could not be performed.
/// </summary> /// </summary>
internal static string FormatCannotPerformOperation(object p0, object p1) internal static string FormatCannotPerformOperation(object p0, object p1)
{ => string.Format(CultureInfo.CurrentCulture, GetString("CannotPerformOperation"), p0, p1);
return string.Format(CultureInfo.CurrentCulture, GetString("CannotPerformOperation"), p0, p1);
}
/// <summary> /// <summary>
/// The property at '{0}' could not be read. /// The property at '{0}' could not be read.
/// </summary> /// </summary>
internal static string CannotReadProperty internal static string CannotReadProperty
{ {
get { return GetString("CannotReadProperty"); } get => GetString("CannotReadProperty");
} }
/// <summary> /// <summary>
/// The property at '{0}' could not be read. /// The property at '{0}' could not be read.
/// </summary> /// </summary>
internal static string FormatCannotReadProperty(object p0) internal static string FormatCannotReadProperty(object p0)
{ => string.Format(CultureInfo.CurrentCulture, GetString("CannotReadProperty"), p0);
return string.Format(CultureInfo.CurrentCulture, GetString("CannotReadProperty"), p0);
}
/// <summary> /// <summary>
/// The property at path '{0}' could not be updated. /// The property at path '{0}' could not be updated.
/// </summary> /// </summary>
internal static string CannotUpdateProperty internal static string CannotUpdateProperty
{ {
get { return GetString("CannotUpdateProperty"); } get => GetString("CannotUpdateProperty");
} }
/// <summary> /// <summary>
/// The property at path '{0}' could not be updated. /// The property at path '{0}' could not be updated.
/// </summary> /// </summary>
internal static string FormatCannotUpdateProperty(object p0) internal static string FormatCannotUpdateProperty(object p0)
{ => string.Format(CultureInfo.CurrentCulture, GetString("CannotUpdateProperty"), p0);
return string.Format(CultureInfo.CurrentCulture, GetString("CannotUpdateProperty"), p0);
}
/// <summary> /// <summary>
/// The index value provided by path segment '{0}' is out of bounds of the array size. /// The index value provided by path segment '{0}' is out of bounds of the array size.
/// </summary> /// </summary>
internal static string IndexOutOfBounds internal static string IndexOutOfBounds
{ {
get { return GetString("IndexOutOfBounds"); } get => GetString("IndexOutOfBounds");
} }
/// <summary> /// <summary>
/// The index value provided by path segment '{0}' is out of bounds of the array size. /// The index value provided by path segment '{0}' is out of bounds of the array size.
/// </summary> /// </summary>
internal static string FormatIndexOutOfBounds(object p0) internal static string FormatIndexOutOfBounds(object p0)
{ => string.Format(CultureInfo.CurrentCulture, GetString("IndexOutOfBounds"), p0);
return string.Format(CultureInfo.CurrentCulture, GetString("IndexOutOfBounds"), p0);
}
/// <summary> /// <summary>
/// The path segment '{0}' is invalid for an array index. /// The path segment '{0}' is invalid for an array index.
/// </summary> /// </summary>
internal static string InvalidIndexValue internal static string InvalidIndexValue
{ {
get { return GetString("InvalidIndexValue"); } get => GetString("InvalidIndexValue");
} }
/// <summary> /// <summary>
/// The path segment '{0}' is invalid for an array index. /// The path segment '{0}' is invalid for an array index.
/// </summary> /// </summary>
internal static string FormatInvalidIndexValue(object p0) internal static string FormatInvalidIndexValue(object p0)
{ => string.Format(CultureInfo.CurrentCulture, GetString("InvalidIndexValue"), p0);
return string.Format(CultureInfo.CurrentCulture, GetString("InvalidIndexValue"), p0);
}
/// <summary> /// <summary>
/// The type '{0}' was malformed and could not be parsed. /// The type '{0}' was malformed and could not be parsed.
/// </summary> /// </summary>
internal static string InvalidJsonPatchDocument internal static string InvalidJsonPatchDocument
{ {
get { return GetString("InvalidJsonPatchDocument"); } get => GetString("InvalidJsonPatchDocument");
} }
/// <summary> /// <summary>
/// The type '{0}' was malformed and could not be parsed. /// The type '{0}' was malformed and could not be parsed.
/// </summary> /// </summary>
internal static string FormatInvalidJsonPatchDocument(object p0) internal static string FormatInvalidJsonPatchDocument(object p0)
{ => string.Format(CultureInfo.CurrentCulture, GetString("InvalidJsonPatchDocument"), p0);
return string.Format(CultureInfo.CurrentCulture, GetString("InvalidJsonPatchDocument"), p0);
}
/// <summary> /// <summary>
/// Invalid JsonPatch operation '{0}'. /// Invalid JsonPatch operation '{0}'.
/// </summary> /// </summary>
internal static string InvalidJsonPatchOperation internal static string InvalidJsonPatchOperation
{ {
get { return GetString("InvalidJsonPatchOperation"); } get => GetString("InvalidJsonPatchOperation");
} }
/// <summary> /// <summary>
/// Invalid JsonPatch operation '{0}'. /// Invalid JsonPatch operation '{0}'.
/// </summary> /// </summary>
internal static string FormatInvalidJsonPatchOperation(object p0) internal static string FormatInvalidJsonPatchOperation(object p0)
{ => string.Format(CultureInfo.CurrentCulture, GetString("InvalidJsonPatchOperation"), p0);
return string.Format(CultureInfo.CurrentCulture, GetString("InvalidJsonPatchOperation"), p0);
}
/// <summary> /// <summary>
/// The provided string '{0}' is an invalid path. /// The provided string '{0}' is an invalid path.
/// </summary> /// </summary>
internal static string InvalidValueForPath internal static string InvalidValueForPath
{ {
get { return GetString("InvalidValueForPath"); } get => GetString("InvalidValueForPath");
} }
/// <summary> /// <summary>
/// The provided string '{0}' is an invalid path. /// The provided string '{0}' is an invalid path.
/// </summary> /// </summary>
internal static string FormatInvalidValueForPath(object p0) internal static string FormatInvalidValueForPath(object p0)
{ => string.Format(CultureInfo.CurrentCulture, GetString("InvalidValueForPath"), p0);
return string.Format(CultureInfo.CurrentCulture, GetString("InvalidValueForPath"), p0);
}
/// <summary> /// <summary>
/// The value '{0}' is invalid for target location. /// The value '{0}' is invalid for target location.
/// </summary> /// </summary>
internal static string InvalidValueForProperty internal static string InvalidValueForProperty
{ {
get { return GetString("InvalidValueForProperty"); } get => GetString("InvalidValueForProperty");
} }
/// <summary> /// <summary>
/// The value '{0}' is invalid for target location. /// The value '{0}' is invalid for target location.
/// </summary> /// </summary>
internal static string FormatInvalidValueForProperty(object p0) internal static string FormatInvalidValueForProperty(object p0)
{ => string.Format(CultureInfo.CurrentCulture, GetString("InvalidValueForProperty"), p0);
return string.Format(CultureInfo.CurrentCulture, GetString("InvalidValueForProperty"), p0);
}
/// <summary> /// <summary>
/// '{0}' must be of type '{1}'. /// '{0}' must be of type '{1}'.
/// </summary> /// </summary>
internal static string ParameterMustMatchType internal static string ParameterMustMatchType
{ {
get { return GetString("ParameterMustMatchType"); } get => GetString("ParameterMustMatchType");
} }
/// <summary> /// <summary>
/// '{0}' must be of type '{1}'. /// '{0}' must be of type '{1}'.
/// </summary> /// </summary>
internal static string FormatParameterMustMatchType(object p0, object p1) internal static string FormatParameterMustMatchType(object p0, object p1)
{ => string.Format(CultureInfo.CurrentCulture, GetString("ParameterMustMatchType"), p0, p1);
return string.Format(CultureInfo.CurrentCulture, GetString("ParameterMustMatchType"), p0, p1);
}
/// <summary> /// <summary>
/// The type '{0}' which is an array is not supported for json patch operations as it has a fixed size. /// The type '{0}' which is an array is not supported for json patch operations as it has a fixed size.
/// </summary> /// </summary>
internal static string PatchNotSupportedForArrays internal static string PatchNotSupportedForArrays
{ {
get { return GetString("PatchNotSupportedForArrays"); } get => GetString("PatchNotSupportedForArrays");
} }
/// <summary> /// <summary>
/// The type '{0}' which is an array is not supported for json patch operations as it has a fixed size. /// The type '{0}' which is an array is not supported for json patch operations as it has a fixed size.
/// </summary> /// </summary>
internal static string FormatPatchNotSupportedForArrays(object p0) internal static string FormatPatchNotSupportedForArrays(object p0)
{ => string.Format(CultureInfo.CurrentCulture, GetString("PatchNotSupportedForArrays"), p0);
return string.Format(CultureInfo.CurrentCulture, GetString("PatchNotSupportedForArrays"), p0);
}
/// <summary> /// <summary>
/// The type '{0}' which is a non generic list is not supported for json patch operations. Only generic list types are supported. /// The type '{0}' which is a non generic list is not supported for json patch operations. Only generic list types are supported.
/// </summary> /// </summary>
internal static string PatchNotSupportedForNonGenericLists internal static string PatchNotSupportedForNonGenericLists
{ {
get { return GetString("PatchNotSupportedForNonGenericLists"); } get => GetString("PatchNotSupportedForNonGenericLists");
} }
/// <summary> /// <summary>
/// The type '{0}' which is a non generic list is not supported for json patch operations. Only generic list types are supported. /// The type '{0}' which is a non generic list is not supported for json patch operations. Only generic list types are supported.
/// </summary> /// </summary>
internal static string FormatPatchNotSupportedForNonGenericLists(object p0) internal static string FormatPatchNotSupportedForNonGenericLists(object p0)
{ => string.Format(CultureInfo.CurrentCulture, GetString("PatchNotSupportedForNonGenericLists"), p0);
return string.Format(CultureInfo.CurrentCulture, GetString("PatchNotSupportedForNonGenericLists"), p0);
}
/// <summary> /// <summary>
/// The target location specified by path segment '{0}' was not found. /// The target location specified by path segment '{0}' was not found.
/// </summary> /// </summary>
internal static string TargetLocationAtPathSegmentNotFound internal static string TargetLocationAtPathSegmentNotFound
{ {
get { return GetString("TargetLocationAtPathSegmentNotFound"); } get => GetString("TargetLocationAtPathSegmentNotFound");
} }
/// <summary> /// <summary>
/// The target location specified by path segment '{0}' was not found. /// The target location specified by path segment '{0}' was not found.
/// </summary> /// </summary>
internal static string FormatTargetLocationAtPathSegmentNotFound(object p0) internal static string FormatTargetLocationAtPathSegmentNotFound(object p0)
{ => string.Format(CultureInfo.CurrentCulture, GetString("TargetLocationAtPathSegmentNotFound"), p0);
return string.Format(CultureInfo.CurrentCulture, GetString("TargetLocationAtPathSegmentNotFound"), p0);
}
/// <summary> /// <summary>
/// For operation '{0}', the target location specified by path '{1}' was not found. /// For operation '{0}', the target location specified by path '{1}' was not found.
/// </summary> /// </summary>
internal static string TargetLocationNotFound internal static string TargetLocationNotFound
{ {
get { return GetString("TargetLocationNotFound"); } get => GetString("TargetLocationNotFound");
} }
/// <summary> /// <summary>
/// For operation '{0}', the target location specified by path '{1}' was not found. /// For operation '{0}', the target location specified by path '{1}' was not found.
/// </summary> /// </summary>
internal static string FormatTargetLocationNotFound(object p0, object p1) internal static string FormatTargetLocationNotFound(object p0, object p1)
{ => string.Format(CultureInfo.CurrentCulture, GetString("TargetLocationNotFound"), p0, p1);
return string.Format(CultureInfo.CurrentCulture, GetString("TargetLocationNotFound"), p0, p1);
}
/// <summary> /// <summary>
/// The test operation is not supported. /// The test operation is not supported.
/// </summary> /// </summary>
internal static string TestOperationNotSupported internal static string TestOperationNotSupported
{ {
get { return GetString("TestOperationNotSupported"); } get => GetString("TestOperationNotSupported");
} }
/// <summary> /// <summary>
/// The test operation is not supported. /// The test operation is not supported.
/// </summary> /// </summary>
internal static string FormatTestOperationNotSupported() internal static string FormatTestOperationNotSupported()
{ => GetString("TestOperationNotSupported");
return GetString("TestOperationNotSupported");
}
private static string GetString(string name, params string[] formatterNames) private static string GetString(string name, params string[] formatterNames)
{ {

View File

@ -20,10 +20,9 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal
dictionary[nameKey] = "Mike"; dictionary[nameKey] = "Mike";
var dictionaryAdapter = new DictionaryAdapter(); var dictionaryAdapter = new DictionaryAdapter();
var resolver = new Mock<IContractResolver>(MockBehavior.Strict); var resolver = new Mock<IContractResolver>(MockBehavior.Strict);
string message = null;
// Act // Act
var addStatus = dictionaryAdapter.TryAdd(dictionary, nameKey, resolver.Object, "James", out message); var addStatus = dictionaryAdapter.TryAdd(dictionary, nameKey, resolver.Object, "James", out var message);
// Assert // Assert
Assert.True(addStatus); Assert.True(addStatus);
@ -38,12 +37,11 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal
// Arrange // Arrange
var dictionaryAdapter = new DictionaryAdapter(); var dictionaryAdapter = new DictionaryAdapter();
var resolver = new Mock<IContractResolver>(MockBehavior.Strict); var resolver = new Mock<IContractResolver>(MockBehavior.Strict);
string message = null;
var nameKey = "Name"; var nameKey = "Name";
var dictionary = new Dictionary<string, object>(StringComparer.Ordinal); var dictionary = new Dictionary<string, object>(StringComparer.Ordinal);
// Act // Act
var addStatus = dictionaryAdapter.TryAdd(dictionary, nameKey, resolver.Object, "James", out message); var addStatus = dictionaryAdapter.TryAdd(dictionary, nameKey, resolver.Object, "James", out var message);
// Assert // Assert
Assert.True(addStatus); Assert.True(addStatus);
@ -52,8 +50,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal
Assert.Equal("James", dictionary[nameKey]); Assert.Equal("James", dictionary[nameKey]);
// Act // Act
object outValue = null; addStatus = dictionaryAdapter.TryGet(dictionary, nameKey.ToUpper(), resolver.Object, out var outValue, out message);
addStatus = dictionaryAdapter.TryGet(dictionary, nameKey.ToUpper(), resolver.Object, out outValue, out message);
// Assert // Assert
Assert.True(addStatus); Assert.True(addStatus);
@ -67,12 +64,11 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal
// Arrange // Arrange
var dictionaryAdapter = new DictionaryAdapter(); var dictionaryAdapter = new DictionaryAdapter();
var resolver = new Mock<IContractResolver>(MockBehavior.Strict); var resolver = new Mock<IContractResolver>(MockBehavior.Strict);
string message = null;
var nameKey = "Name"; var nameKey = "Name";
var dictionary = new Dictionary<string, object>(StringComparer.Ordinal); var dictionary = new Dictionary<string, object>(StringComparer.Ordinal);
// Act // Act
var addStatus = dictionaryAdapter.TryAdd(dictionary, nameKey, resolver.Object, "James", out message); var addStatus = dictionaryAdapter.TryAdd(dictionary, nameKey, resolver.Object, "James", out var message);
// Assert // Assert
Assert.True(addStatus); Assert.True(addStatus);
@ -81,8 +77,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal
Assert.Equal("James", dictionary[nameKey]); Assert.Equal("James", dictionary[nameKey]);
// Act // Act
object outValue = null; addStatus = dictionaryAdapter.TryGet(dictionary, nameKey, resolver.Object, out var outValue, out message);
addStatus = dictionaryAdapter.TryGet(dictionary, nameKey, resolver.Object, out outValue, out message);
// Assert // Assert
Assert.True(addStatus); Assert.True(addStatus);
@ -99,10 +94,9 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal
dictionary.Add(nameKey, "Mike"); dictionary.Add(nameKey, "Mike");
var dictionaryAdapter = new DictionaryAdapter(); var dictionaryAdapter = new DictionaryAdapter();
var resolver = new Mock<IContractResolver>(MockBehavior.Strict); var resolver = new Mock<IContractResolver>(MockBehavior.Strict);
string message = null;
// Act // Act
var replaceStatus = dictionaryAdapter.TryReplace(dictionary, nameKey, resolver.Object, "James", out message); var replaceStatus = dictionaryAdapter.TryReplace(dictionary, nameKey, resolver.Object, "James", out var message);
// Assert // Assert
Assert.True(replaceStatus); Assert.True(replaceStatus);
@ -119,10 +113,9 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal
var dictionary = new Dictionary<string, object>(StringComparer.Ordinal); var dictionary = new Dictionary<string, object>(StringComparer.Ordinal);
var dictionaryAdapter = new DictionaryAdapter(); var dictionaryAdapter = new DictionaryAdapter();
var resolver = new Mock<IContractResolver>(MockBehavior.Strict); var resolver = new Mock<IContractResolver>(MockBehavior.Strict);
string message = null;
// Act // Act
var replaceStatus = dictionaryAdapter.TryReplace(dictionary, nameKey, resolver.Object, "Mike", out message); var replaceStatus = dictionaryAdapter.TryReplace(dictionary, nameKey, resolver.Object, "Mike", out var message);
// Assert // Assert
Assert.False(replaceStatus); Assert.False(replaceStatus);
@ -140,10 +133,9 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal
var dictionary = new Dictionary<string, object>(StringComparer.Ordinal); var dictionary = new Dictionary<string, object>(StringComparer.Ordinal);
var dictionaryAdapter = new DictionaryAdapter(); var dictionaryAdapter = new DictionaryAdapter();
var resolver = new Mock<IContractResolver>(MockBehavior.Strict); var resolver = new Mock<IContractResolver>(MockBehavior.Strict);
string message = null;
// Act // Act
var removeStatus = dictionaryAdapter.TryRemove(dictionary, nameKey, resolver.Object, out message); var removeStatus = dictionaryAdapter.TryRemove(dictionary, nameKey, resolver.Object, out var message);
// Assert // Assert
Assert.False(removeStatus); Assert.False(removeStatus);
@ -162,10 +154,9 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal
dictionary[nameKey] = "James"; dictionary[nameKey] = "James";
var dictionaryAdapter = new DictionaryAdapter(); var dictionaryAdapter = new DictionaryAdapter();
var resolver = new Mock<IContractResolver>(MockBehavior.Strict); var resolver = new Mock<IContractResolver>(MockBehavior.Strict);
string message = null;
// Act // Act
var removeStatus = dictionaryAdapter.TryRemove(dictionary, nameKey, resolver.Object, out message); var removeStatus = dictionaryAdapter.TryRemove(dictionary, nameKey, resolver.Object, out var message);
//Assert //Assert
Assert.True(removeStatus); Assert.True(removeStatus);

View File

@ -8,7 +8,7 @@ using Microsoft.AspNetCore.JsonPatch.Exceptions;
using Newtonsoft.Json; using Newtonsoft.Json;
using Xunit; using Xunit;
namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic namespace Microsoft.AspNetCore.JsonPatch.Internal
{ {
public class AddOperationTests public class AddOperationTests
{ {
@ -86,7 +86,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic
dynamic doc = new dynamic doc = new
{ {
Test = 1, Test = 1,
nested = new NestedDTO() nested = new NestedObject()
}; };
// create patch // create patch
@ -111,7 +111,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic
dynamic doc = new dynamic doc = new
{ {
Test = 1, Test = 1,
nested = new NestedDTO() nested = new NestedObject()
}; };
// create patch // create patch
@ -152,7 +152,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic
[Fact] [Fact]
public void AddNewPropertyToExpandoOjectInTypedObject() public void AddNewPropertyToExpandoOjectInTypedObject()
{ {
var doc = new NestedDTO() var doc = new NestedObject()
{ {
DynamicProperty = new ExpandoObject() DynamicProperty = new ExpandoObject()
}; };
@ -175,7 +175,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic
dynamic dynamicProperty = new ExpandoObject(); dynamic dynamicProperty = new ExpandoObject();
dynamicProperty.StringProperty = "A"; dynamicProperty.StringProperty = "A";
var doc = new NestedDTO() var doc = new NestedObject()
{ {
DynamicProperty = dynamicProperty DynamicProperty = dynamicProperty
}; };
@ -284,7 +284,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic
public void AddResultsShouldReplaceInNestedInDynamic() public void AddResultsShouldReplaceInNestedInDynamic()
{ {
dynamic doc = new ExpandoObject(); dynamic doc = new ExpandoObject();
doc.Nested = new NestedDTO(); doc.Nested = new NestedObject();
doc.Nested.DynamicProperty = new ExpandoObject(); doc.Nested.DynamicProperty = new ExpandoObject();
doc.Nested.DynamicProperty.InBetweenFirst = new ExpandoObject(); doc.Nested.DynamicProperty.InBetweenFirst = new ExpandoObject();
doc.Nested.DynamicProperty.InBetweenFirst.InBetweenSecond = new ExpandoObject(); doc.Nested.DynamicProperty.InBetweenFirst.InBetweenSecond = new ExpandoObject();
@ -319,7 +319,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic
// the root of the document, nor a member of an existing object, nor a // the root of the document, nor a member of an existing object, nor a
// member of an existing array. // member of an existing array.
var doc = new NestedDTO() var doc = new NestedObject()
{ {
DynamicProperty = new ExpandoObject() DynamicProperty = new ExpandoObject()
}; };

View File

@ -6,14 +6,14 @@ using Microsoft.AspNetCore.JsonPatch.Exceptions;
using Newtonsoft.Json; using Newtonsoft.Json;
using Xunit; using Xunit;
namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic namespace Microsoft.AspNetCore.JsonPatch.Internal
{ {
public class AddTypedOperationTests public class AddTypedOperationTests
{ {
[Fact] [Fact]
public void AddToListNegativePosition() public void AddToListNegativePosition()
{ {
var doc = new SimpleDTO() var doc = new SimpleObject()
{ {
IntegerList = new List<int>() { 1, 2, 3 } IntegerList = new List<int>() { 1, 2, 3 }
}; };
@ -37,11 +37,11 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic
[Fact] [Fact]
public void AddToListInList() public void AddToListInList()
{ {
var doc = new SimpleDTOWithNestedDTO() var doc = new SimpleObjectWithNestedObject()
{ {
ListOfSimpleDTO = new List<SimpleDTO>() ListOfSimpleObject = new List<SimpleObject>()
{ {
new SimpleDTO() new SimpleObject()
{ {
IntegerList = new List<int>() { 1, 2, 3 } IntegerList = new List<int>() { 1, 2, 3 }
} }
@ -50,23 +50,23 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic
// create patch // create patch
var patchDoc = new JsonPatchDocument(); var patchDoc = new JsonPatchDocument();
patchDoc.Add("ListOfSimpleDTO/0/IntegerList/0", 4); patchDoc.Add("ListOfSimpleObject/0/IntegerList/0", 4);
var serialized = JsonConvert.SerializeObject(patchDoc); var serialized = JsonConvert.SerializeObject(patchDoc);
var deserialized = JsonConvert.DeserializeObject<JsonPatchDocument>(serialized); var deserialized = JsonConvert.DeserializeObject<JsonPatchDocument>(serialized);
deserialized.ApplyTo(doc); deserialized.ApplyTo(doc);
Assert.Equal(new List<int>() { 4, 1, 2, 3 }, doc.ListOfSimpleDTO[0].IntegerList); Assert.Equal(new List<int>() { 4, 1, 2, 3 }, doc.ListOfSimpleObject[0].IntegerList);
} }
[Fact] [Fact]
public void AddToListInListInvalidPositionTooSmall() public void AddToListInListInvalidPositionTooSmall()
{ {
var doc = new SimpleDTOWithNestedDTO() var doc = new SimpleObjectWithNestedObject()
{ {
ListOfSimpleDTO = new List<SimpleDTO>() ListOfSimpleObject = new List<SimpleObject>()
{ {
new SimpleDTO() new SimpleObject()
{ {
IntegerList = new List<int>() { 1, 2, 3 } IntegerList = new List<int>() { 1, 2, 3 }
} }
@ -75,7 +75,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic
// create patch // create patch
var patchDoc = new JsonPatchDocument(); var patchDoc = new JsonPatchDocument();
patchDoc.Add("ListOfSimpleDTO/-1/IntegerList/0", 4); patchDoc.Add("ListOfSimpleObject/-1/IntegerList/0", 4);
var serialized = JsonConvert.SerializeObject(patchDoc); var serialized = JsonConvert.SerializeObject(patchDoc);
var deserialized = JsonConvert.DeserializeObject<JsonPatchDocument>(serialized); var deserialized = JsonConvert.DeserializeObject<JsonPatchDocument>(serialized);
@ -92,11 +92,11 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic
[Fact] [Fact]
public void AddToListInListInvalidPositionTooLarge() public void AddToListInListInvalidPositionTooLarge()
{ {
var doc = new SimpleDTOWithNestedDTO() var doc = new SimpleObjectWithNestedObject()
{ {
ListOfSimpleDTO = new List<SimpleDTO>() ListOfSimpleObject = new List<SimpleObject>()
{ {
new SimpleDTO() new SimpleObject()
{ {
IntegerList = new List<int>() { 1, 2, 3 } IntegerList = new List<int>() { 1, 2, 3 }
} }
@ -104,7 +104,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic
}; };
// create patch // create patch
var patchDoc = new JsonPatchDocument(); var patchDoc = new JsonPatchDocument();
patchDoc.Add("ListOfSimpleDTO/20/IntegerList/0", 4); patchDoc.Add("ListOfSimpleObject/20/IntegerList/0", 4);
var serialized = JsonConvert.SerializeObject(patchDoc); var serialized = JsonConvert.SerializeObject(patchDoc);
var deserialized = JsonConvert.DeserializeObject<JsonPatchDocument>(serialized); var deserialized = JsonConvert.DeserializeObject<JsonPatchDocument>(serialized);

View File

@ -6,7 +6,7 @@ using System.Dynamic;
using Newtonsoft.Json; using Newtonsoft.Json;
using Xunit; using Xunit;
namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic namespace Microsoft.AspNetCore.JsonPatch.Internal
{ {
public class CopyOperationTests public class CopyOperationTests
{ {
@ -122,7 +122,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic
public void NestedCopy() public void NestedCopy()
{ {
dynamic doc = new ExpandoObject(); dynamic doc = new ExpandoObject();
doc.SimpleDTO = new SimpleDTO() doc.SimpleObject = new SimpleObject()
{ {
StringProperty = "A", StringProperty = "A",
AnotherStringProperty = "B" AnotherStringProperty = "B"
@ -130,82 +130,82 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic
// create patch // create patch
var patchDoc = new JsonPatchDocument(); var patchDoc = new JsonPatchDocument();
patchDoc.Copy("SimpleDTO/StringProperty", "SimpleDTO/AnotherStringProperty"); patchDoc.Copy("SimpleObject/StringProperty", "SimpleObject/AnotherStringProperty");
var serialized = JsonConvert.SerializeObject(patchDoc); var serialized = JsonConvert.SerializeObject(patchDoc);
var deserialized = JsonConvert.DeserializeObject<JsonPatchDocument>(serialized); var deserialized = JsonConvert.DeserializeObject<JsonPatchDocument>(serialized);
deserialized.ApplyTo(doc); deserialized.ApplyTo(doc);
Assert.Equal("A", doc.SimpleDTO.AnotherStringProperty); Assert.Equal("A", doc.SimpleObject.AnotherStringProperty);
} }
[Fact] [Fact]
public void NestedCopyInList() public void NestedCopyInList()
{ {
dynamic doc = new ExpandoObject(); dynamic doc = new ExpandoObject();
doc.SimpleDTO = new SimpleDTO() doc.SimpleObject = new SimpleObject()
{ {
IntegerList = new List<int>() { 1, 2, 3 } IntegerList = new List<int>() { 1, 2, 3 }
}; };
// create patch // create patch
var patchDoc = new JsonPatchDocument(); var patchDoc = new JsonPatchDocument();
patchDoc.Copy("SimpleDTO/IntegerList/0", "SimpleDTO/IntegerList/1"); patchDoc.Copy("SimpleObject/IntegerList/0", "SimpleObject/IntegerList/1");
var serialized = JsonConvert.SerializeObject(patchDoc); var serialized = JsonConvert.SerializeObject(patchDoc);
var deserialized = JsonConvert.DeserializeObject<JsonPatchDocument>(serialized); var deserialized = JsonConvert.DeserializeObject<JsonPatchDocument>(serialized);
deserialized.ApplyTo(doc); deserialized.ApplyTo(doc);
Assert.Equal(new List<int>() { 1, 1, 2, 3 }, doc.SimpleDTO.IntegerList); Assert.Equal(new List<int>() { 1, 1, 2, 3 }, doc.SimpleObject.IntegerList);
} }
[Fact] [Fact]
public void NestedCopyFromListToEndOfList() public void NestedCopyFromListToEndOfList()
{ {
dynamic doc = new ExpandoObject(); dynamic doc = new ExpandoObject();
doc.SimpleDTO = new SimpleDTO() doc.SimpleObject = new SimpleObject()
{ {
IntegerList = new List<int>() { 1, 2, 3 } IntegerList = new List<int>() { 1, 2, 3 }
}; };
// create patch // create patch
var patchDoc = new JsonPatchDocument(); var patchDoc = new JsonPatchDocument();
patchDoc.Copy("SimpleDTO/IntegerList/0", "SimpleDTO/IntegerList/-"); patchDoc.Copy("SimpleObject/IntegerList/0", "SimpleObject/IntegerList/-");
var serialized = JsonConvert.SerializeObject(patchDoc); var serialized = JsonConvert.SerializeObject(patchDoc);
var deserialized = JsonConvert.DeserializeObject<JsonPatchDocument>(serialized); var deserialized = JsonConvert.DeserializeObject<JsonPatchDocument>(serialized);
deserialized.ApplyTo(doc); deserialized.ApplyTo(doc);
Assert.Equal(new List<int>() { 1, 2, 3, 1 }, doc.SimpleDTO.IntegerList); Assert.Equal(new List<int>() { 1, 2, 3, 1 }, doc.SimpleObject.IntegerList);
} }
[Fact] [Fact]
public void NestedCopyFromListToNonList() public void NestedCopyFromListToNonList()
{ {
dynamic doc = new ExpandoObject(); dynamic doc = new ExpandoObject();
doc.SimpleDTO = new SimpleDTO() doc.SimpleObject = new SimpleObject()
{ {
IntegerList = new List<int>() { 1, 2, 3 } IntegerList = new List<int>() { 1, 2, 3 }
}; };
// create patch // create patch
var patchDoc = new JsonPatchDocument(); var patchDoc = new JsonPatchDocument();
patchDoc.Copy("SimpleDTO/IntegerList/0", "SimpleDTO/IntegerValue"); patchDoc.Copy("SimpleObject/IntegerList/0", "SimpleObject/IntegerValue");
var serialized = JsonConvert.SerializeObject(patchDoc); var serialized = JsonConvert.SerializeObject(patchDoc);
var deserialized = JsonConvert.DeserializeObject<JsonPatchDocument>(serialized); var deserialized = JsonConvert.DeserializeObject<JsonPatchDocument>(serialized);
deserialized.ApplyTo(doc); deserialized.ApplyTo(doc);
Assert.Equal(1, doc.SimpleDTO.IntegerValue); Assert.Equal(1, doc.SimpleObject.IntegerValue);
} }
[Fact] [Fact]
public void NestedCopyFromNonListToList() public void NestedCopyFromNonListToList()
{ {
dynamic doc = new ExpandoObject(); dynamic doc = new ExpandoObject();
doc.SimpleDTO = new SimpleDTO() doc.SimpleObject = new SimpleObject()
{ {
IntegerValue = 5, IntegerValue = 5,
IntegerList = new List<int>() { 1, 2, 3 } IntegerList = new List<int>() { 1, 2, 3 }
@ -213,19 +213,19 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic
// create patch // create patch
var patchDoc = new JsonPatchDocument(); var patchDoc = new JsonPatchDocument();
patchDoc.Copy("SimpleDTO/IntegerValue", "SimpleDTO/IntegerList/0"); patchDoc.Copy("SimpleObject/IntegerValue", "SimpleObject/IntegerList/0");
var serialized = JsonConvert.SerializeObject(patchDoc); var serialized = JsonConvert.SerializeObject(patchDoc);
var deserialized = JsonConvert.DeserializeObject<JsonPatchDocument>(serialized); var deserialized = JsonConvert.DeserializeObject<JsonPatchDocument>(serialized);
deserialized.ApplyTo(doc); deserialized.ApplyTo(doc);
Assert.Equal(new List<int>() { 5, 1, 2, 3 }, doc.SimpleDTO.IntegerList); Assert.Equal(new List<int>() { 5, 1, 2, 3 }, doc.SimpleObject.IntegerList);
} }
[Fact] [Fact]
public void NestedCopyToEndOfList() public void NestedCopyToEndOfList()
{ {
dynamic doc = new ExpandoObject(); dynamic doc = new ExpandoObject();
doc.SimpleDTO = new SimpleDTO() doc.SimpleObject = new SimpleObject()
{ {
IntegerValue = 5, IntegerValue = 5,
IntegerList = new List<int>() { 1, 2, 3 } IntegerList = new List<int>() { 1, 2, 3 }
@ -233,13 +233,13 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic
// create patch // create patch
var patchDoc = new JsonPatchDocument(); var patchDoc = new JsonPatchDocument();
patchDoc.Copy("SimpleDTO/IntegerValue", "SimpleDTO/IntegerList/-"); patchDoc.Copy("SimpleObject/IntegerValue", "SimpleObject/IntegerList/-");
var serialized = JsonConvert.SerializeObject(patchDoc); var serialized = JsonConvert.SerializeObject(patchDoc);
var deserialized = JsonConvert.DeserializeObject<JsonPatchDocument>(serialized); var deserialized = JsonConvert.DeserializeObject<JsonPatchDocument>(serialized);
deserialized.ApplyTo(doc); deserialized.ApplyTo(doc);
Assert.Equal(new List<int>() { 1, 2, 3, 5 }, doc.SimpleDTO.IntegerList); Assert.Equal(new List<int>() { 1, 2, 3, 5 }, doc.SimpleObject.IntegerList);
} }
} }
} }

View File

@ -5,14 +5,14 @@ using System.Collections.Generic;
using Newtonsoft.Json; using Newtonsoft.Json;
using Xunit; using Xunit;
namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic namespace Microsoft.AspNetCore.JsonPatch.Internal
{ {
public class CopyTypedOperationTests public class CopyTypedOperationTests
{ {
[Fact] [Fact]
public void Copy() public void Copy()
{ {
var doc = new SimpleDTO() var doc = new SimpleObject()
{ {
StringProperty = "A", StringProperty = "A",
AnotherStringProperty = "B" AnotherStringProperty = "B"
@ -32,7 +32,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic
[Fact] [Fact]
public void CopyInList() public void CopyInList()
{ {
var doc = new SimpleDTO() var doc = new SimpleObject()
{ {
IntegerList = new List<int>() { 1, 2, 3 } IntegerList = new List<int>() { 1, 2, 3 }
}; };
@ -52,7 +52,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic
[Fact] [Fact]
public void CopyFromListToEndOfList() public void CopyFromListToEndOfList()
{ {
var doc = new SimpleDTO() var doc = new SimpleObject()
{ {
IntegerList = new List<int>() { 1, 2, 3 } IntegerList = new List<int>() { 1, 2, 3 }
}; };
@ -71,7 +71,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic
[Fact] [Fact]
public void CopyFromListToNonList() public void CopyFromListToNonList()
{ {
var doc = new SimpleDTO() var doc = new SimpleObject()
{ {
IntegerList = new List<int>() { 1, 2, 3 } IntegerList = new List<int>() { 1, 2, 3 }
}; };
@ -91,7 +91,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic
[Fact] [Fact]
public void CopyFromNonListToList() public void CopyFromNonListToList()
{ {
var doc = new SimpleDTO() var doc = new SimpleObject()
{ {
IntegerValue = 5, IntegerValue = 5,
IntegerList = new List<int>() { 1, 2, 3 } IntegerList = new List<int>() { 1, 2, 3 }
@ -111,7 +111,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic
[Fact] [Fact]
public void CopyToEndOfList() public void CopyToEndOfList()
{ {
var doc = new SimpleDTO() var doc = new SimpleObject()
{ {
IntegerValue = 5, IntegerValue = 5,
IntegerList = new List<int>() { 1, 2, 3 } IntegerList = new List<int>() { 1, 2, 3 }
@ -132,9 +132,9 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic
[Fact] [Fact]
public void NestedCopy() public void NestedCopy()
{ {
var doc = new SimpleDTOWithNestedDTO() var doc = new SimpleObjectWithNestedObject()
{ {
SimpleDTO = new SimpleDTO() SimpleObject = new SimpleObject()
{ {
StringProperty = "A", StringProperty = "A",
AnotherStringProperty = "B" AnotherStringProperty = "B"
@ -143,22 +143,22 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic
// create patch // create patch
var patchDoc = new JsonPatchDocument(); var patchDoc = new JsonPatchDocument();
patchDoc.Copy("SimpleDTO/StringProperty", "SimpleDTO/AnotherStringProperty"); patchDoc.Copy("SimpleObject/StringProperty", "SimpleObject/AnotherStringProperty");
var serialized = JsonConvert.SerializeObject(patchDoc); var serialized = JsonConvert.SerializeObject(patchDoc);
var deserialized = JsonConvert.DeserializeObject<JsonPatchDocument>(serialized); var deserialized = JsonConvert.DeserializeObject<JsonPatchDocument>(serialized);
deserialized.ApplyTo(doc); deserialized.ApplyTo(doc);
Assert.Equal("A", doc.SimpleDTO.AnotherStringProperty); Assert.Equal("A", doc.SimpleObject.AnotherStringProperty);
} }
[Fact] [Fact]
public void NestedCopyInList() public void NestedCopyInList()
{ {
var doc = new SimpleDTOWithNestedDTO() var doc = new SimpleObjectWithNestedObject()
{ {
SimpleDTO = new SimpleDTO() SimpleObject = new SimpleObject()
{ {
IntegerList = new List<int>() { 1, 2, 3 } IntegerList = new List<int>() { 1, 2, 3 }
} }
@ -166,21 +166,21 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic
// create patch // create patch
var patchDoc = new JsonPatchDocument(); var patchDoc = new JsonPatchDocument();
patchDoc.Copy("SimpleDTO/IntegerList/0", "SimpleDTO/IntegerList/1"); patchDoc.Copy("SimpleObject/IntegerList/0", "SimpleObject/IntegerList/1");
var serialized = JsonConvert.SerializeObject(patchDoc); var serialized = JsonConvert.SerializeObject(patchDoc);
var deserialized = JsonConvert.DeserializeObject<JsonPatchDocument>(serialized); var deserialized = JsonConvert.DeserializeObject<JsonPatchDocument>(serialized);
deserialized.ApplyTo(doc); deserialized.ApplyTo(doc);
Assert.Equal(new List<int>() { 1, 1, 2, 3 }, doc.SimpleDTO.IntegerList); Assert.Equal(new List<int>() { 1, 1, 2, 3 }, doc.SimpleObject.IntegerList);
} }
[Fact] [Fact]
public void NestedCopyFromListToEndOfList() public void NestedCopyFromListToEndOfList()
{ {
var doc = new SimpleDTOWithNestedDTO() var doc = new SimpleObjectWithNestedObject()
{ {
SimpleDTO = new SimpleDTO() SimpleObject = new SimpleObject()
{ {
IntegerList = new List<int>() { 1, 2, 3 } IntegerList = new List<int>() { 1, 2, 3 }
} }
@ -188,22 +188,22 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic
// create patch // create patch
var patchDoc = new JsonPatchDocument(); var patchDoc = new JsonPatchDocument();
patchDoc.Copy("SimpleDTO/IntegerList/0", "SimpleDTO/IntegerList/-"); patchDoc.Copy("SimpleObject/IntegerList/0", "SimpleObject/IntegerList/-");
var serialized = JsonConvert.SerializeObject(patchDoc); var serialized = JsonConvert.SerializeObject(patchDoc);
var deserialized = JsonConvert.DeserializeObject<JsonPatchDocument>(serialized); var deserialized = JsonConvert.DeserializeObject<JsonPatchDocument>(serialized);
deserialized.ApplyTo(doc); deserialized.ApplyTo(doc);
Assert.Equal(new List<int>() { 1, 2, 3, 1 }, doc.SimpleDTO.IntegerList); Assert.Equal(new List<int>() { 1, 2, 3, 1 }, doc.SimpleObject.IntegerList);
} }
[Fact] [Fact]
public void NestedCopyFromListToNonList() public void NestedCopyFromListToNonList()
{ {
var doc = new SimpleDTOWithNestedDTO() var doc = new SimpleObjectWithNestedObject()
{ {
SimpleDTO = new SimpleDTO() SimpleObject = new SimpleObject()
{ {
IntegerList = new List<int>() { 1, 2, 3 } IntegerList = new List<int>() { 1, 2, 3 }
} }
@ -211,21 +211,21 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic
// create patch // create patch
var patchDoc = new JsonPatchDocument(); var patchDoc = new JsonPatchDocument();
patchDoc.Copy("SimpleDTO/IntegerList/0", "SimpleDTO/IntegerValue"); patchDoc.Copy("SimpleObject/IntegerList/0", "SimpleObject/IntegerValue");
var serialized = JsonConvert.SerializeObject(patchDoc); var serialized = JsonConvert.SerializeObject(patchDoc);
var deserialized = JsonConvert.DeserializeObject<JsonPatchDocument>(serialized); var deserialized = JsonConvert.DeserializeObject<JsonPatchDocument>(serialized);
deserialized.ApplyTo(doc); deserialized.ApplyTo(doc);
Assert.Equal(1, doc.SimpleDTO.IntegerValue); Assert.Equal(1, doc.SimpleObject.IntegerValue);
} }
[Fact] [Fact]
public void NestedCopyFromNonListToList() public void NestedCopyFromNonListToList()
{ {
var doc = new SimpleDTOWithNestedDTO() var doc = new SimpleObjectWithNestedObject()
{ {
SimpleDTO = new SimpleDTO() SimpleObject = new SimpleObject()
{ {
IntegerValue = 5, IntegerValue = 5,
IntegerList = new List<int>() { 1, 2, 3 } IntegerList = new List<int>() { 1, 2, 3 }
@ -234,20 +234,20 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic
// create patch // create patch
var patchDoc = new JsonPatchDocument(); var patchDoc = new JsonPatchDocument();
patchDoc.Copy("SimpleDTO/IntegerValue", "SimpleDTO/IntegerList/0"); patchDoc.Copy("SimpleObject/IntegerValue", "SimpleObject/IntegerList/0");
var serialized = JsonConvert.SerializeObject(patchDoc); var serialized = JsonConvert.SerializeObject(patchDoc);
var deserialized = JsonConvert.DeserializeObject<JsonPatchDocument>(serialized); var deserialized = JsonConvert.DeserializeObject<JsonPatchDocument>(serialized);
deserialized.ApplyTo(doc); deserialized.ApplyTo(doc);
Assert.Equal(new List<int>() { 5, 1, 2, 3 }, doc.SimpleDTO.IntegerList); Assert.Equal(new List<int>() { 5, 1, 2, 3 }, doc.SimpleObject.IntegerList);
} }
[Fact] [Fact]
public void NestedCopyToEndOfList() public void NestedCopyToEndOfList()
{ {
var doc = new SimpleDTOWithNestedDTO() var doc = new SimpleObjectWithNestedObject()
{ {
SimpleDTO = new SimpleDTO() SimpleObject = new SimpleObject()
{ {
IntegerValue = 5, IntegerValue = 5,
IntegerList = new List<int>() { 1, 2, 3 } IntegerList = new List<int>() { 1, 2, 3 }
@ -256,13 +256,13 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic
// create patch // create patch
var patchDoc = new JsonPatchDocument(); var patchDoc = new JsonPatchDocument();
patchDoc.Copy("SimpleDTO/IntegerValue", "SimpleDTO/IntegerList/-"); patchDoc.Copy("SimpleObject/IntegerValue", "SimpleObject/IntegerList/-");
var serialized = JsonConvert.SerializeObject(patchDoc); var serialized = JsonConvert.SerializeObject(patchDoc);
var deserialized = JsonConvert.DeserializeObject<JsonPatchDocument>(serialized); var deserialized = JsonConvert.DeserializeObject<JsonPatchDocument>(serialized);
deserialized.ApplyTo(doc); deserialized.ApplyTo(doc);
Assert.Equal(new List<int>() { 1, 2, 3, 5 }, doc.SimpleDTO.IntegerList); Assert.Equal(new List<int>() { 1, 2, 3, 5 }, doc.SimpleObject.IntegerList);
} }
} }
} }

View File

@ -0,0 +1,10 @@
// 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.AspNetCore.JsonPatch.Internal
{
public class InheritedObject : SimpleObject
{
public string AdditionalStringProperty { get; set; }
}
}

View File

@ -6,7 +6,7 @@ using System.Dynamic;
using Newtonsoft.Json; using Newtonsoft.Json;
using Xunit; using Xunit;
namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic namespace Microsoft.AspNetCore.JsonPatch.Internal
{ {
public class MoveOperationTests public class MoveOperationTests
{ {
@ -29,7 +29,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic
Assert.Equal("A", doc.AnotherStringProperty); Assert.Equal("A", doc.AnotherStringProperty);
var cont = doc as IDictionary<string, object>; var cont = doc as IDictionary<string, object>;
cont.TryGetValue("StringProperty", out var valueFromDictionary); cont.TryGetValue("StringProperty", out object valueFromDictionary);
Assert.Null(valueFromDictionary); Assert.Null(valueFromDictionary);
} }
@ -60,7 +60,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic
{ {
dynamic doc = new ExpandoObject(); dynamic doc = new ExpandoObject();
doc.StringProperty = "A"; doc.StringProperty = "A";
doc.SimpleDTO = new SimpleDTO() { AnotherStringProperty = "B" }; doc.SimpleDTO = new SimpleObject() { AnotherStringProperty = "B" };
// create patch // create patch
var patchDoc = new JsonPatchDocument(); var patchDoc = new JsonPatchDocument();
@ -74,7 +74,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic
Assert.Equal("A", doc.SimpleDTO.AnotherStringProperty); Assert.Equal("A", doc.SimpleDTO.AnotherStringProperty);
var cont = doc as IDictionary<string, object>; var cont = doc as IDictionary<string, object>;
cont.TryGetValue("StringProperty", out var valueFromDictionary); cont.TryGetValue("StringProperty", out object valueFromDictionary);
Assert.Null(valueFromDictionary); Assert.Null(valueFromDictionary);
} }
@ -83,7 +83,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic
{ {
dynamic doc = new ExpandoObject(); dynamic doc = new ExpandoObject();
doc.StringProperty = "A"; doc.StringProperty = "A";
doc.SimpleDTO = new SimpleDTO() { AnotherStringProperty = "B" }; doc.SimpleDTO = new SimpleObject() { AnotherStringProperty = "B" };
// create patch // create patch
var patchDoc = new JsonPatchDocument(); var patchDoc = new JsonPatchDocument();
@ -102,7 +102,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic
public void NestedMove() public void NestedMove()
{ {
dynamic doc = new ExpandoObject(); dynamic doc = new ExpandoObject();
doc.Nested = new SimpleDTO() doc.Nested = new SimpleObject()
{ {
StringProperty = "A", StringProperty = "A",
AnotherStringProperty = "B" AnotherStringProperty = "B"
@ -143,7 +143,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic
public void NestedMoveInList() public void NestedMoveInList()
{ {
dynamic doc = new ExpandoObject(); dynamic doc = new ExpandoObject();
doc.Nested = new SimpleDTO() doc.Nested = new SimpleObject()
{ {
IntegerList = new List<int>() { 1, 2, 3 } IntegerList = new List<int>() { 1, 2, 3 }
}; };
@ -181,7 +181,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic
public void NestedMoveFromListToEndOfList() public void NestedMoveFromListToEndOfList()
{ {
dynamic doc = new ExpandoObject(); dynamic doc = new ExpandoObject();
doc.Nested = new SimpleDTO() doc.Nested = new SimpleObject()
{ {
IntegerList = new List<int>() { 1, 2, 3 } IntegerList = new List<int>() { 1, 2, 3 }
}; };
@ -220,7 +220,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic
public void NestedMoveFomListToNonList() public void NestedMoveFomListToNonList()
{ {
dynamic doc = new ExpandoObject(); dynamic doc = new ExpandoObject();
doc.Nested = new SimpleDTO() doc.Nested = new SimpleObject()
{ {
IntegerList = new List<int>() { 1, 2, 3 } IntegerList = new List<int>() { 1, 2, 3 }
}; };
@ -255,7 +255,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic
deserialized.ApplyTo(doc); deserialized.ApplyTo(doc);
var cont = doc as IDictionary<string, object>; var cont = doc as IDictionary<string, object>;
cont.TryGetValue("IntegerValue", out var valueFromDictionary); cont.TryGetValue("IntegerValue", out object valueFromDictionary);
Assert.Null(valueFromDictionary); Assert.Null(valueFromDictionary);
Assert.Equal(new List<int>() { 5, 1, 2, 3 }, doc.IntegerList); Assert.Equal(new List<int>() { 5, 1, 2, 3 }, doc.IntegerList);
@ -265,7 +265,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic
public void NestedMoveFromNonListToList() public void NestedMoveFromNonListToList()
{ {
dynamic doc = new ExpandoObject(); dynamic doc = new ExpandoObject();
doc.Nested = new SimpleDTO() doc.Nested = new SimpleObject()
{ {
IntegerValue = 5, IntegerValue = 5,
IntegerList = new List<int>() { 1, 2, 3 } IntegerList = new List<int>() { 1, 2, 3 }
@ -311,7 +311,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic
public void NestedMoveToEndOfList() public void NestedMoveToEndOfList()
{ {
dynamic doc = new ExpandoObject(); dynamic doc = new ExpandoObject();
doc.Nested = new SimpleDTO() doc.Nested = new SimpleObject()
{ {
IntegerValue = 5, IntegerValue = 5,
IntegerList = new List<int>() { 1, 2, 3 } IntegerList = new List<int>() { 1, 2, 3 }

View File

@ -5,14 +5,14 @@ using System.Collections.Generic;
using Newtonsoft.Json; using Newtonsoft.Json;
using Xunit; using Xunit;
namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic namespace Microsoft.AspNetCore.JsonPatch.Internal
{ {
public class MoveTypedOperationTests public class MoveTypedOperationTests
{ {
[Fact] [Fact]
public void Move() public void Move()
{ {
var doc = new SimpleDTO() var doc = new SimpleObject()
{ {
StringProperty = "A", StringProperty = "A",
AnotherStringProperty = "B" AnotherStringProperty = "B"
@ -34,7 +34,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic
[Fact] [Fact]
public void MoveInList() public void MoveInList()
{ {
var doc = new SimpleDTO() var doc = new SimpleObject()
{ {
IntegerList = new List<int>() { 1, 2, 3 } IntegerList = new List<int>() { 1, 2, 3 }
}; };
@ -54,7 +54,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic
[Fact] [Fact]
public void MoveFromListToEndOfList() public void MoveFromListToEndOfList()
{ {
var doc = new SimpleDTO() var doc = new SimpleObject()
{ {
IntegerList = new List<int>() { 1, 2, 3 } IntegerList = new List<int>() { 1, 2, 3 }
}; };
@ -73,7 +73,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic
[Fact] [Fact]
public void MoveFomListToNonList() public void MoveFomListToNonList()
{ {
var doc = new SimpleDTO() var doc = new SimpleObject()
{ {
IntegerList = new List<int>() { 1, 2, 3 } IntegerList = new List<int>() { 1, 2, 3 }
}; };
@ -94,7 +94,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic
[Fact] [Fact]
public void MoveFromNonListToList() public void MoveFromNonListToList()
{ {
var doc = new SimpleDTO() var doc = new SimpleObject()
{ {
IntegerValue = 5, IntegerValue = 5,
IntegerList = new List<int>() { 1, 2, 3 } IntegerList = new List<int>() { 1, 2, 3 }
@ -116,7 +116,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic
[Fact] [Fact]
public void MoveToEndOfList() public void MoveToEndOfList()
{ {
var doc = new SimpleDTO() var doc = new SimpleObject()
{ {
IntegerValue = 5, IntegerValue = 5,
IntegerList = new List<int>() { 1, 2, 3 } IntegerList = new List<int>() { 1, 2, 3 }

View File

@ -1,9 +1,9 @@
// Copyright (c) .NET Foundation. All rights reserved. // 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. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic namespace Microsoft.AspNetCore.JsonPatch.Internal
{ {
public class NestedDTO public class NestedObject
{ {
public string StringProperty { get; set; } public string StringProperty { get; set; }
public dynamic DynamicProperty { get; set; } public dynamic DynamicProperty { get; set; }

View File

@ -5,7 +5,7 @@ using Microsoft.AspNetCore.JsonPatch.Exceptions;
using Newtonsoft.Json; using Newtonsoft.Json;
using Xunit; using Xunit;
namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic namespace Microsoft.AspNetCore.JsonPatch.Internal
{ {
public class PatchDocumentTests public class PatchDocumentTests
{ {
@ -51,7 +51,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic
[Fact] [Fact]
public void NonGenericPatchDocToGenericMustSerialize() public void NonGenericPatchDocToGenericMustSerialize()
{ {
var doc = new SimpleDTO() var doc = new SimpleObject()
{ {
StringProperty = "A", StringProperty = "A",
AnotherStringProperty = "B" AnotherStringProperty = "B"
@ -61,7 +61,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic
patchDoc.Copy("StringProperty", "AnotherStringProperty"); patchDoc.Copy("StringProperty", "AnotherStringProperty");
var serialized = JsonConvert.SerializeObject(patchDoc); var serialized = JsonConvert.SerializeObject(patchDoc);
var deserialized = JsonConvert.DeserializeObject<JsonPatchDocument<SimpleDTO>>(serialized); var deserialized = JsonConvert.DeserializeObject<JsonPatchDocument<SimpleObject>>(serialized);
deserialized.ApplyTo(doc); deserialized.ApplyTo(doc);
@ -71,14 +71,14 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic
[Fact] [Fact]
public void GenericPatchDocToNonGenericMustSerialize() public void GenericPatchDocToNonGenericMustSerialize()
{ {
var doc = new SimpleDTO() var doc = new SimpleObject()
{ {
StringProperty = "A", StringProperty = "A",
AnotherStringProperty = "B" AnotherStringProperty = "B"
}; };
var patchDocTyped = new JsonPatchDocument<SimpleDTO>(); var patchDocTyped = new JsonPatchDocument<SimpleObject>();
patchDocTyped.Copy<string>(o => o.StringProperty, o => o.AnotherStringProperty); patchDocTyped.Copy(o => o.StringProperty, o => o.AnotherStringProperty);
var patchDocUntyped = new JsonPatchDocument(); var patchDocUntyped = new JsonPatchDocument();
patchDocUntyped.Copy("StringProperty", "AnotherStringProperty"); patchDocUntyped.Copy("StringProperty", "AnotherStringProperty");

View File

@ -7,7 +7,7 @@ using Microsoft.AspNetCore.JsonPatch.Exceptions;
using Newtonsoft.Json; using Newtonsoft.Json;
using Xunit; using Xunit;
namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic namespace Microsoft.AspNetCore.JsonPatch.Internal
{ {
public class RemoveOperationTests public class RemoveOperationTests
{ {
@ -73,7 +73,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic
deserialized.ApplyTo(obj); deserialized.ApplyTo(obj);
var cont = obj as IDictionary<string, object>; var cont = obj as IDictionary<string, object>;
cont.TryGetValue("Test", out var valueFromDictionary); cont.TryGetValue("Test", out object valueFromDictionary);
Assert.Null(valueFromDictionary); Assert.Null(valueFromDictionary);
} }
@ -94,9 +94,11 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic
{ {
deserialized.ApplyTo(obj); deserialized.ApplyTo(obj);
}); });
Assert.Equal( Assert.Equal(
string.Format("The target location specified by path segment '{0}' was not found.", string.Format(
"test"), "The target location specified by path segment '{0}' was not found.",
"test"),
exception.Message); exception.Message);
} }
@ -117,7 +119,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic
deserialized.ApplyTo(obj); deserialized.ApplyTo(obj);
var cont = obj as IDictionary<string, object>; var cont = obj as IDictionary<string, object>;
cont.TryGetValue("Test", out var valueFromDictionary); cont.TryGetValue("Test", out object valueFromDictionary);
Assert.Null(valueFromDictionary); Assert.Null(valueFromDictionary);
} }
@ -139,8 +141,11 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic
{ {
deserialized.ApplyTo(obj); deserialized.ApplyTo(obj);
}); });
Assert.Equal( Assert.Equal(
string.Format("The target location specified by path segment '{0}' was not found.", "test"), string.Format(
"The target location specified by path segment '{0}' was not found.",
"test"),
exception.Message); exception.Message);
} }
@ -148,7 +153,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic
public void NestedRemove() public void NestedRemove()
{ {
dynamic doc = new ExpandoObject(); dynamic doc = new ExpandoObject();
doc.SimpleDTO = new SimpleDTO() doc.SimpleDTO = new SimpleObject()
{ {
StringProperty = "A" StringProperty = "A"
}; };
@ -168,14 +173,14 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic
public void NestedRemove_MixedCase_ThrowsPathNotFoundException() public void NestedRemove_MixedCase_ThrowsPathNotFoundException()
{ {
dynamic doc = new ExpandoObject(); dynamic doc = new ExpandoObject();
doc.SimpleDTO = new SimpleDTO() doc.SimpleObject = new SimpleObject()
{ {
StringProperty = "A" StringProperty = "A"
}; };
// create patch // create patch
var patchDoc = new JsonPatchDocument(); var patchDoc = new JsonPatchDocument();
patchDoc.Remove("Simpledto/stringProperty"); patchDoc.Remove("Simpleobject/stringProperty");
var serialized = JsonConvert.SerializeObject(patchDoc); var serialized = JsonConvert.SerializeObject(patchDoc);
var deserialized = JsonConvert.DeserializeObject<JsonPatchDocument>(serialized); var deserialized = JsonConvert.DeserializeObject<JsonPatchDocument>(serialized);
@ -184,10 +189,12 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic
{ {
deserialized.ApplyTo(doc); deserialized.ApplyTo(doc);
}); });
Assert.Equal( Assert.Equal(
string.Format("For operation '{0}', the target location specified by path '{1}' was not found.", string.Format(
"remove", "For operation '{0}', the target location specified by path '{1}' was not found.",
"/Simpledto/stringProperty"), "remove",
"/Simpleobject/stringProperty"),
exception.Message); exception.Message);
} }
@ -195,7 +202,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic
public void NestedRemoveFromList() public void NestedRemoveFromList()
{ {
dynamic doc = new ExpandoObject(); dynamic doc = new ExpandoObject();
doc.SimpleDTO = new SimpleDTO() doc.SimpleDTO = new SimpleObject()
{ {
IntegerList = new List<int>() { 1, 2, 3 } IntegerList = new List<int>() { 1, 2, 3 }
}; };
@ -213,10 +220,10 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic
} }
[Fact] [Fact]
public void NestedRemoveFromListMixedCase() public void NestedRemoveFromList_MixedCase()
{ {
dynamic doc = new ExpandoObject(); dynamic doc = new ExpandoObject();
doc.SimpleDTO = new SimpleDTO() doc.SimpleDTO = new SimpleObject()
{ {
IntegerList = new List<int>() { 1, 2, 3 } IntegerList = new List<int>() { 1, 2, 3 }
}; };
@ -237,7 +244,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic
public void NestedRemoveFromListInvalidPositionTooLarge() public void NestedRemoveFromListInvalidPositionTooLarge()
{ {
dynamic doc = new ExpandoObject(); dynamic doc = new ExpandoObject();
doc.SimpleDTO = new SimpleDTO() doc.SimpleDTO = new SimpleObject()
{ {
IntegerList = new List<int>() { 1, 2, 3 } IntegerList = new List<int>() { 1, 2, 3 }
}; };
@ -262,7 +269,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic
public void NestedRemoveFromListInvalidPositionTooSmall() public void NestedRemoveFromListInvalidPositionTooSmall()
{ {
dynamic doc = new ExpandoObject(); dynamic doc = new ExpandoObject();
doc.SimpleDTO = new SimpleDTO() doc.SimpleDTO = new SimpleObject()
{ {
IntegerList = new List<int>() { 1, 2, 3 } IntegerList = new List<int>() { 1, 2, 3 }
}; };
@ -287,7 +294,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic
public void NestedRemoveFromEndOfList() public void NestedRemoveFromEndOfList()
{ {
dynamic doc = new ExpandoObject(); dynamic doc = new ExpandoObject();
doc.SimpleDTO = new SimpleDTO() doc.SimpleDTO = new SimpleObject()
{ {
IntegerList = new List<int>() { 1, 2, 3 } IntegerList = new List<int>() { 1, 2, 3 }
}; };

View File

@ -6,14 +6,14 @@ using Microsoft.AspNetCore.JsonPatch.Exceptions;
using Newtonsoft.Json; using Newtonsoft.Json;
using Xunit; using Xunit;
namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic namespace Microsoft.AspNetCore.JsonPatch.Internal
{ {
public class RemoveTypedOperationTests public class RemoveTypedOperationTests
{ {
[Fact] [Fact]
public void Remove() public void Remove()
{ {
var doc = new SimpleDTO() var doc = new SimpleObject()
{ {
StringProperty = "A" StringProperty = "A"
}; };
@ -33,7 +33,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic
[Fact] [Fact]
public void RemoveFromList() public void RemoveFromList()
{ {
var doc = new SimpleDTO() var doc = new SimpleObject()
{ {
IntegerList = new List<int>() { 1, 2, 3 } IntegerList = new List<int>() { 1, 2, 3 }
}; };
@ -53,7 +53,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic
[Fact] [Fact]
public void RemoveFromListInvalidPositionTooLarge() public void RemoveFromListInvalidPositionTooLarge()
{ {
var doc = new SimpleDTO() var doc = new SimpleObject()
{ {
IntegerList = new List<int>() { 1, 2, 3 } IntegerList = new List<int>() { 1, 2, 3 }
}; };
@ -77,7 +77,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic
[Fact] [Fact]
public void RemoveFromListInvalidPositionTooSmall() public void RemoveFromListInvalidPositionTooSmall()
{ {
var doc = new SimpleDTO() var doc = new SimpleObject()
{ {
IntegerList = new List<int>() { 1, 2, 3 } IntegerList = new List<int>() { 1, 2, 3 }
}; };
@ -101,7 +101,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic
[Fact] [Fact]
public void RemoveFromEndOfList() public void RemoveFromEndOfList()
{ {
var doc = new SimpleDTO() var doc = new SimpleObject()
{ {
IntegerList = new List<int>() { 1, 2, 3 } IntegerList = new List<int>() { 1, 2, 3 }
}; };
@ -121,9 +121,9 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic
[Fact] [Fact]
public void NestedRemove() public void NestedRemove()
{ {
var doc = new SimpleDTOWithNestedDTO() var doc = new SimpleObjectWithNestedObject()
{ {
SimpleDTO = new SimpleDTO() SimpleObject = new SimpleObject()
{ {
StringProperty = "A" StringProperty = "A"
} }
@ -131,22 +131,22 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic
// create patch // create patch
var patchDoc = new JsonPatchDocument(); var patchDoc = new JsonPatchDocument();
patchDoc.Remove("SimpleDTO/StringProperty"); patchDoc.Remove("SimpleObject/StringProperty");
var serialized = JsonConvert.SerializeObject(patchDoc); var serialized = JsonConvert.SerializeObject(patchDoc);
var deserialized = JsonConvert.DeserializeObject<JsonPatchDocument>(serialized); var deserialized = JsonConvert.DeserializeObject<JsonPatchDocument>(serialized);
deserialized.ApplyTo(doc); deserialized.ApplyTo(doc);
Assert.Null(doc.SimpleDTO.StringProperty); Assert.Null(doc.SimpleObject.StringProperty);
} }
[Fact] [Fact]
public void NestedRemoveFromList() public void NestedRemoveFromList()
{ {
var doc = new SimpleDTOWithNestedDTO() var doc = new SimpleObjectWithNestedObject()
{ {
SimpleDTO = new SimpleDTO() SimpleObject = new SimpleObject()
{ {
IntegerList = new List<int>() { 1, 2, 3 } IntegerList = new List<int>() { 1, 2, 3 }
} }
@ -154,22 +154,22 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic
// create patch // create patch
var patchDoc = new JsonPatchDocument(); var patchDoc = new JsonPatchDocument();
patchDoc.Remove("SimpleDTO/IntegerList/2"); patchDoc.Remove("SimpleObject/IntegerList/2");
var serialized = JsonConvert.SerializeObject(patchDoc); var serialized = JsonConvert.SerializeObject(patchDoc);
var deserialized = JsonConvert.DeserializeObject<JsonPatchDocument>(serialized); var deserialized = JsonConvert.DeserializeObject<JsonPatchDocument>(serialized);
deserialized.ApplyTo(doc); deserialized.ApplyTo(doc);
Assert.Equal(new List<int>() { 1, 2 }, doc.SimpleDTO.IntegerList); Assert.Equal(new List<int>() { 1, 2 }, doc.SimpleObject.IntegerList);
} }
[Fact] [Fact]
public void NestedRemoveFromListInvalidPositionTooLarge() public void NestedRemoveFromListInvalidPositionTooLarge()
{ {
var doc = new SimpleDTOWithNestedDTO() var doc = new SimpleObjectWithNestedObject()
{ {
SimpleDTO = new SimpleDTO() SimpleObject = new SimpleObject()
{ {
IntegerList = new List<int>() { 1, 2, 3 } IntegerList = new List<int>() { 1, 2, 3 }
} }
@ -177,7 +177,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic
// create patch // create patch
var patchDoc = new JsonPatchDocument(); var patchDoc = new JsonPatchDocument();
patchDoc.Remove("SimpleDTO/IntegerList/3"); patchDoc.Remove("SimpleObject/IntegerList/3");
var serialized = JsonConvert.SerializeObject(patchDoc); var serialized = JsonConvert.SerializeObject(patchDoc);
var deserialized = JsonConvert.DeserializeObject<JsonPatchDocument>(serialized); var deserialized = JsonConvert.DeserializeObject<JsonPatchDocument>(serialized);
@ -194,9 +194,9 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic
[Fact] [Fact]
public void NestedRemoveFromListInvalidPositionTooSmall() public void NestedRemoveFromListInvalidPositionTooSmall()
{ {
var doc = new SimpleDTOWithNestedDTO() var doc = new SimpleObjectWithNestedObject()
{ {
SimpleDTO = new SimpleDTO() SimpleObject = new SimpleObject()
{ {
IntegerList = new List<int>() { 1, 2, 3 } IntegerList = new List<int>() { 1, 2, 3 }
} }
@ -204,7 +204,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic
// create patch // create patch
var patchDoc = new JsonPatchDocument(); var patchDoc = new JsonPatchDocument();
patchDoc.Remove("SimpleDTO/IntegerList/-1"); patchDoc.Remove("SimpleObject/IntegerList/-1");
var serialized = JsonConvert.SerializeObject(patchDoc); var serialized = JsonConvert.SerializeObject(patchDoc);
var deserialized = JsonConvert.DeserializeObject<JsonPatchDocument>(serialized); var deserialized = JsonConvert.DeserializeObject<JsonPatchDocument>(serialized);
@ -221,9 +221,9 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic
[Fact] [Fact]
public void NestedRemoveFromEndOfList() public void NestedRemoveFromEndOfList()
{ {
var doc = new SimpleDTOWithNestedDTO() var doc = new SimpleObjectWithNestedObject()
{ {
SimpleDTO = new SimpleDTO() SimpleObject = new SimpleObject()
{ {
IntegerList = new List<int>() { 1, 2, 3 } IntegerList = new List<int>() { 1, 2, 3 }
} }
@ -231,14 +231,14 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic
// create patch // create patch
var patchDoc = new JsonPatchDocument(); var patchDoc = new JsonPatchDocument();
patchDoc.Remove("SimpleDTO/IntegerList/-"); patchDoc.Remove("SimpleObject/IntegerList/-");
var serialized = JsonConvert.SerializeObject(patchDoc); var serialized = JsonConvert.SerializeObject(patchDoc);
var deserialized = JsonConvert.DeserializeObject<JsonPatchDocument>(serialized); var deserialized = JsonConvert.DeserializeObject<JsonPatchDocument>(serialized);
deserialized.ApplyTo(doc); deserialized.ApplyTo(doc);
Assert.Equal(new List<int>() { 1, 2 }, doc.SimpleDTO.IntegerList); Assert.Equal(new List<int>() { 1, 2 }, doc.SimpleObject.IntegerList);
} }
} }
} }

View File

@ -9,21 +9,21 @@ using Newtonsoft.Json;
using Newtonsoft.Json.Linq; using Newtonsoft.Json.Linq;
using Xunit; using Xunit;
namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic namespace Microsoft.AspNetCore.JsonPatch.Internal
{ {
public class ReplaceOperationTests public class ReplaceOperationTests
{ {
[Fact] [Fact]
public void ReplaceGuidTest() public void ReplaceGuidTest()
{ {
dynamic doc = new SimpleDTO() dynamic doc = new SimpleObject()
{ {
GuidValue = Guid.NewGuid() GuidValue = Guid.NewGuid()
}; };
var newGuid = Guid.NewGuid(); var newGuid = Guid.NewGuid();
// create patch // create patch
JsonPatchDocument patchDoc = new JsonPatchDocument(); var patchDoc = new JsonPatchDocument();
patchDoc.Replace("GuidValue", newGuid); patchDoc.Replace("GuidValue", newGuid);
// serialize & deserialize // serialize & deserialize
@ -43,7 +43,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic
var newGuid = Guid.NewGuid(); var newGuid = Guid.NewGuid();
// create patch // create patch
JsonPatchDocument patchDoc = new JsonPatchDocument(); var patchDoc = new JsonPatchDocument();
patchDoc.Replace("GuidValue", newGuid); patchDoc.Replace("GuidValue", newGuid);
// serialize & deserialize // serialize & deserialize
@ -68,7 +68,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic
var newGuid = Guid.NewGuid(); var newGuid = Guid.NewGuid();
// create patch // create patch
JsonPatchDocument patchDoc = new JsonPatchDocument(); var patchDoc = new JsonPatchDocument();
patchDoc.Replace("nestedobject/GuidValue", newGuid); patchDoc.Replace("nestedobject/GuidValue", newGuid);
// serialize & deserialize // serialize & deserialize
@ -84,19 +84,19 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic
public void ReplaceNestedObjectTest() public void ReplaceNestedObjectTest()
{ {
dynamic doc = new ExpandoObject(); dynamic doc = new ExpandoObject();
doc.SimpleDTO = new SimpleDTO() doc.SimpleDTO = new SimpleObject()
{ {
IntegerValue = 5, IntegerValue = 5,
IntegerList = new List<int>() { 1, 2, 3 } IntegerList = new List<int>() { 1, 2, 3 }
}; };
var newDTO = new SimpleDTO() var newDTO = new SimpleObject()
{ {
DoubleValue = 1 DoubleValue = 1
}; };
// create patch // create patch
JsonPatchDocument patchDoc = new JsonPatchDocument(); var patchDoc = new JsonPatchDocument();
patchDoc.Replace("SimpleDTO", newDTO); patchDoc.Replace("SimpleDTO", newDTO);
// serialize & deserialize // serialize & deserialize
@ -117,7 +117,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic
doc.IntegerList = new List<int>() { 1, 2, 3 }; doc.IntegerList = new List<int>() { 1, 2, 3 };
// create patch // create patch
JsonPatchDocument patchDoc = new JsonPatchDocument(); var patchDoc = new JsonPatchDocument();
patchDoc.Replace("IntegerList/0", 5); patchDoc.Replace("IntegerList/0", 5);
var serialized = JsonConvert.SerializeObject(patchDoc); var serialized = JsonConvert.SerializeObject(patchDoc);
@ -135,7 +135,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic
doc.IntegerList = new List<int>() { 1, 2, 3 }; doc.IntegerList = new List<int>() { 1, 2, 3 };
// create patch // create patch
JsonPatchDocument patchDoc = new JsonPatchDocument(); var patchDoc = new JsonPatchDocument();
patchDoc.Replace("IntegerList", new List<int>() { 4, 5, 6 }); patchDoc.Replace("IntegerList", new List<int>() { 4, 5, 6 });
var serialized = JsonConvert.SerializeObject(patchDoc); var serialized = JsonConvert.SerializeObject(patchDoc);
@ -150,13 +150,13 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic
public void ReplaceInListInList() public void ReplaceInListInList()
{ {
dynamic doc = new ExpandoObject(); dynamic doc = new ExpandoObject();
doc.SimpleDTOList = new List<SimpleDTO>() { doc.SimpleDTOList = new List<SimpleObject>() {
new SimpleDTO() { new SimpleObject() {
IntegerList = new List<int>(){1,2,3} IntegerList = new List<int>(){1,2,3}
}}; }};
// create patch // create patch
JsonPatchDocument patchDoc = new JsonPatchDocument(); var patchDoc = new JsonPatchDocument();
patchDoc.Replace("SimpleDTOList/0/IntegerList/0", 4); patchDoc.Replace("SimpleDTOList/0/IntegerList/0", 4);
var serialized = JsonConvert.SerializeObject(patchDoc); var serialized = JsonConvert.SerializeObject(patchDoc);
@ -171,13 +171,13 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic
public void ReplaceInListInListAtEnd() public void ReplaceInListInListAtEnd()
{ {
dynamic doc = new ExpandoObject(); dynamic doc = new ExpandoObject();
doc.SimpleDTOList = new List<SimpleDTO>() { doc.SimpleDTOList = new List<SimpleObject>() {
new SimpleDTO() { new SimpleObject() {
IntegerList = new List<int>(){1,2,3} IntegerList = new List<int>(){1,2,3}
}}; }};
// create patch // create patch
JsonPatchDocument patchDoc = new JsonPatchDocument(); var patchDoc = new JsonPatchDocument();
patchDoc.Replace("SimpleDTOList/0/IntegerList/-", 4); patchDoc.Replace("SimpleDTOList/0/IntegerList/-", 4);
var serialized = JsonConvert.SerializeObject(patchDoc); var serialized = JsonConvert.SerializeObject(patchDoc);
@ -195,7 +195,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic
doc.IntegerList = new List<int>() { 1, 2, 3 }; doc.IntegerList = new List<int>() { 1, 2, 3 };
// create patch // create patch
JsonPatchDocument patchDoc = new JsonPatchDocument(); var patchDoc = new JsonPatchDocument();
patchDoc.Replace("IntegerList", new List<int>() { 4, 5, 6 }); patchDoc.Replace("IntegerList", new List<int>() { 4, 5, 6 });
var serialized = JsonConvert.SerializeObject(patchDoc); var serialized = JsonConvert.SerializeObject(patchDoc);
@ -213,7 +213,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic
doc.IntegerList = new List<int>() { 1, 2, 3 }; doc.IntegerList = new List<int>() { 1, 2, 3 };
// create patch // create patch
JsonPatchDocument patchDoc = new JsonPatchDocument(); var patchDoc = new JsonPatchDocument();
patchDoc.Replace("IntegerList", new Collection<int>() { 4, 5, 6 }); patchDoc.Replace("IntegerList", new Collection<int>() { 4, 5, 6 });
var serialized = JsonConvert.SerializeObject(patchDoc); var serialized = JsonConvert.SerializeObject(patchDoc);
@ -231,7 +231,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic
doc.IntegerList = new List<int>() { 1, 2, 3 }; doc.IntegerList = new List<int>() { 1, 2, 3 };
// create patch // create patch
JsonPatchDocument patchDoc = new JsonPatchDocument(); var patchDoc = new JsonPatchDocument();
patchDoc.Replace("IntegerList/-", 5); patchDoc.Replace("IntegerList/-", 5);
var serialized = JsonConvert.SerializeObject(patchDoc); var serialized = JsonConvert.SerializeObject(patchDoc);

View File

@ -8,21 +8,21 @@ using System.Linq;
using Newtonsoft.Json; using Newtonsoft.Json;
using Xunit; using Xunit;
namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic namespace Microsoft.AspNetCore.JsonPatch.Internal
{ {
public class ReplaceTypedOperationTests public class ReplaceTypedOperationTests
{ {
[Fact] [Fact]
public void ReplaceGuidTest() public void ReplaceGuidTest()
{ {
var doc = new SimpleDTO() var doc = new SimpleObject()
{ {
GuidValue = Guid.NewGuid() GuidValue = Guid.NewGuid()
}; };
var newGuid = Guid.NewGuid(); var newGuid = Guid.NewGuid();
// create patch // create patch
JsonPatchDocument patchDoc = new JsonPatchDocument(); var patchDoc = new JsonPatchDocument();
patchDoc.Replace("GuidValue", newGuid); patchDoc.Replace("GuidValue", newGuid);
// serialize & deserialize // serialize & deserialize
@ -37,23 +37,23 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic
[Fact] [Fact]
public void SerializeAndReplaceNestedObjectTest() public void SerializeAndReplaceNestedObjectTest()
{ {
var doc = new SimpleDTOWithNestedDTO() var doc = new SimpleObjectWithNestedObject()
{ {
SimpleDTO = new SimpleDTO() SimpleObject = new SimpleObject()
{ {
IntegerValue = 5, IntegerValue = 5,
IntegerList = new List<int>() { 1, 2, 3 } IntegerList = new List<int>() { 1, 2, 3 }
} }
}; };
var newDTO = new SimpleDTO() var newDTO = new SimpleObject()
{ {
DoubleValue = 1 DoubleValue = 1
}; };
// create patch // create patch
JsonPatchDocument patchDoc = new JsonPatchDocument(); var patchDoc = new JsonPatchDocument();
patchDoc.Replace("SimpleDTO", newDTO); patchDoc.Replace("SimpleObject", newDTO);
// serialize & deserialize // serialize & deserialize
var serialized = JsonConvert.SerializeObject(patchDoc); var serialized = JsonConvert.SerializeObject(patchDoc);
@ -61,21 +61,21 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic
deserialized.ApplyTo(doc); deserialized.ApplyTo(doc);
Assert.Equal(1, doc.SimpleDTO.DoubleValue); Assert.Equal(1, doc.SimpleObject.DoubleValue);
Assert.Equal(0, doc.SimpleDTO.IntegerValue); Assert.Equal(0, doc.SimpleObject.IntegerValue);
Assert.Null(doc.SimpleDTO.IntegerList); Assert.Null(doc.SimpleObject.IntegerList);
} }
[Fact] [Fact]
public void ReplaceInList() public void ReplaceInList()
{ {
var doc = new SimpleDTO() var doc = new SimpleObject()
{ {
IntegerList = new List<int>() { 1, 2, 3 } IntegerList = new List<int>() { 1, 2, 3 }
}; };
// create patch // create patch
JsonPatchDocument patchDoc = new JsonPatchDocument(); var patchDoc = new JsonPatchDocument();
patchDoc.Replace("IntegerList/0", 5); patchDoc.Replace("IntegerList/0", 5);
var serialized = JsonConvert.SerializeObject(patchDoc); var serialized = JsonConvert.SerializeObject(patchDoc);
@ -89,13 +89,13 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic
[Fact] [Fact]
public void ReplaceFullList() public void ReplaceFullList()
{ {
var doc = new SimpleDTO() var doc = new SimpleObject()
{ {
IntegerList = new List<int>() { 1, 2, 3 } IntegerList = new List<int>() { 1, 2, 3 }
}; };
// create patch // create patch
JsonPatchDocument patchDoc = new JsonPatchDocument(); var patchDoc = new JsonPatchDocument();
patchDoc.Replace("IntegerList", new List<int>() { 4, 5, 6 }); patchDoc.Replace("IntegerList", new List<int>() { 4, 5, 6 });
var serialized = JsonConvert.SerializeObject(patchDoc); var serialized = JsonConvert.SerializeObject(patchDoc);
@ -109,36 +109,36 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic
[Fact] [Fact]
public void ReplaceInListInList() public void ReplaceInListInList()
{ {
var doc = new SimpleDTO() var doc = new SimpleObject()
{ {
SimpleDTOList = new List<SimpleDTO>() { SimpleObjectList = new List<SimpleObject>() {
new SimpleDTO() { new SimpleObject() {
IntegerList = new List<int>(){1,2,3} IntegerList = new List<int>(){1,2,3}
}} }}
}; };
// create patch // create patch
JsonPatchDocument patchDoc = new JsonPatchDocument(); var patchDoc = new JsonPatchDocument();
patchDoc.Replace("SimpleDTOList/0/IntegerList/0", 4); patchDoc.Replace("SimpleObjectList/0/IntegerList/0", 4);
var serialized = JsonConvert.SerializeObject(patchDoc); var serialized = JsonConvert.SerializeObject(patchDoc);
var deserialized = JsonConvert.DeserializeObject<JsonPatchDocument>(serialized); var deserialized = JsonConvert.DeserializeObject<JsonPatchDocument>(serialized);
deserialized.ApplyTo(doc); deserialized.ApplyTo(doc);
Assert.Equal(4, doc.SimpleDTOList.First().IntegerList.First()); Assert.Equal(4, doc.SimpleObjectList.First().IntegerList.First());
} }
[Fact] [Fact]
public void ReplaceFullListFromEnumerable() public void ReplaceFullListFromEnumerable()
{ {
var doc = new SimpleDTO() var doc = new SimpleObject()
{ {
IntegerList = new List<int>() { 1, 2, 3 } IntegerList = new List<int>() { 1, 2, 3 }
}; };
// create patch // create patch
JsonPatchDocument patchDoc = new JsonPatchDocument(); var patchDoc = new JsonPatchDocument();
patchDoc.Replace("IntegerList", new List<int>() { 4, 5, 6 }); patchDoc.Replace("IntegerList", new List<int>() { 4, 5, 6 });
var serialized = JsonConvert.SerializeObject(patchDoc); var serialized = JsonConvert.SerializeObject(patchDoc);
@ -152,13 +152,13 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic
[Fact] [Fact]
public void ReplaceFullListWithCollection() public void ReplaceFullListWithCollection()
{ {
var doc = new SimpleDTO() var doc = new SimpleObject()
{ {
IntegerList = new List<int>() { 1, 2, 3 } IntegerList = new List<int>() { 1, 2, 3 }
}; };
// create patch // create patch
JsonPatchDocument patchDoc = new JsonPatchDocument(); var patchDoc = new JsonPatchDocument();
patchDoc.Replace("IntegerList", new Collection<int>() { 4, 5, 6 }); patchDoc.Replace("IntegerList", new Collection<int>() { 4, 5, 6 });
var serialized = JsonConvert.SerializeObject(patchDoc); var serialized = JsonConvert.SerializeObject(patchDoc);
@ -172,13 +172,13 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic
[Fact] [Fact]
public void ReplaceAtEndOfList() public void ReplaceAtEndOfList()
{ {
var doc = new SimpleDTO() var doc = new SimpleObject()
{ {
IntegerList = new List<int>() { 1, 2, 3 } IntegerList = new List<int>() { 1, 2, 3 }
}; };
// create patch // create patch
JsonPatchDocument patchDoc = new JsonPatchDocument(); var patchDoc = new JsonPatchDocument();
patchDoc.Replace("IntegerList/-", 5); patchDoc.Replace("IntegerList/-", 5);
var serialized = JsonConvert.SerializeObject(patchDoc); var serialized = JsonConvert.SerializeObject(patchDoc);

View File

@ -1,22 +0,0 @@
// 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;
namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic
{
public class SimpleDTOWithNestedDTO
{
public int IntegerValue { get; set; }
public NestedDTO NestedDTO { get; set; }
public SimpleDTO SimpleDTO { get; set; }
public List<SimpleDTO> ListOfSimpleDTO { get; set; }
public SimpleDTOWithNestedDTO()
{
NestedDTO = new NestedDTO();
SimpleDTO = new SimpleDTO();
ListOfSimpleDTO = new List<SimpleDTO>();
}
}
}

View File

@ -4,11 +4,11 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic namespace Microsoft.AspNetCore.JsonPatch.Internal
{ {
public class SimpleDTO public class SimpleObject
{ {
public List<SimpleDTO> SimpleDTOList { get; set; } public List<SimpleObject> SimpleObjectList { get; set; }
public List<int> IntegerList { get; set; } public List<int> IntegerList { get; set; }
public int IntegerValue { get; set; } public int IntegerValue { get; set; }
public string StringProperty { get; set; } public string StringProperty { get; set; }

View File

@ -0,0 +1,22 @@
// 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;
namespace Microsoft.AspNetCore.JsonPatch.Internal
{
public class SimpleObjectWithNestedObject
{
public int IntegerValue { get; set; }
public NestedObject NestedObject { get; set; }
public SimpleObject SimpleObject { get; set; }
public List<SimpleObject> ListOfSimpleObject { get; set; }
public SimpleObjectWithNestedObject()
{
NestedObject = new NestedObject();
SimpleObject = new SimpleObject();
ListOfSimpleObject = new List<SimpleObject>();
}
}
}

View File

@ -0,0 +1,231 @@
// 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.Serialization;
using Xunit;
namespace Microsoft.AspNetCore.JsonPatch.Internal
{
public class DynamicObjectAdapterTest
{
[Fact]
public void TryAdd_AddsNewProperty()
{
// Arrange
var adapter = new DynamicObjectAdapter();
dynamic target = new DynamicTestObject();
var segment = "NewProperty";
var resolver = new DefaultContractResolver();
// Act
var status = adapter.TryAdd(target, segment, resolver, "new", out string errorMessage);
// Assert
Assert.True(status);
Assert.Null(errorMessage);
Assert.Equal("new", target.NewProperty);
}
[Fact]
public void TryAdd_ReplacesExistingPropertyValue()
{
// Arrange
var adapter = new DynamicObjectAdapter();
dynamic target = new DynamicTestObject();
target.List = new List<int>() { 1, 2, 3 };
var value = new List<string>() { "stringValue1", "stringValue2" };
var segment = "List";
var resolver = new DefaultContractResolver();
// Act
var status = adapter.TryAdd(target, segment, resolver, value, out string errorMessage);
// Assert
Assert.True(status);
Assert.Null(errorMessage);
Assert.Equal(value, target.List);
}
[Fact]
public void TryGet_GetsPropertyValue_ForExistingProperty()
{
// Arrange
var adapter = new DynamicObjectAdapter();
dynamic target = new DynamicTestObject();
var segment = "NewProperty";
var resolver = new DefaultContractResolver();
// Act 1
var addStatus = adapter.TryAdd(target, segment, resolver, "new", out string errorMessage);
// Assert 1
Assert.True(addStatus);
Assert.Null(errorMessage);
Assert.Equal("new", target.NewProperty);
// Act 2
var getStatus = adapter.TryGet(target, segment, resolver, out object getValue, out string getErrorMessage);
// Assert 2
Assert.True(getStatus);
Assert.Null(getErrorMessage);
Assert.Equal(getValue, target.NewProperty);
}
[Fact]
public void TryGet_ThrowsPathNotFoundException_ForNonExistingProperty()
{
// Arrange
var adapter = new DynamicObjectAdapter();
dynamic target = new DynamicTestObject();
var segment = "NewProperty";
var resolver = new DefaultContractResolver();
// Act
var getStatus = adapter.TryGet(target, segment, resolver, out object getValue, out string getErrorMessage);
// Assert
Assert.False(getStatus);
Assert.Null(getValue);
Assert.Equal($"The target location specified by path segment '{segment}' was not found.", getErrorMessage);
}
[Fact]
public void TryTraverse_FindsNextTarget()
{
// Arrange
var adapter = new DynamicObjectAdapter();
dynamic target = new DynamicTestObject();
target.NestedObject = new DynamicTestObject();
target.NestedObject.NewProperty = "A";
var segment = "NestedObject";
var resolver = new DefaultContractResolver();
// Act
var status = adapter.TryTraverse(target, segment, resolver, out object nextTarget, out string errorMessage);
// Assert
Assert.True(status);
Assert.Null(errorMessage);
Assert.Equal(target.NestedObject, nextTarget);
}
[Fact]
public void TryTraverse_ThrowsPathNotFoundException_ForNonExistingProperty()
{
// Arrange
var adapter = new DynamicObjectAdapter();
dynamic target = new DynamicTestObject();
target.NestedObject = new DynamicTestObject();
var segment = "NewProperty";
var resolver = new DefaultContractResolver();
// Act
var status = adapter.TryTraverse(target.NestedObject, segment, resolver, out object nextTarget, out string errorMessage);
// Assert
Assert.False(status);
Assert.Equal($"The target location specified by path segment '{segment}' was not found.", errorMessage);
}
[Fact]
public void TryReplace_ReplacesPropertyValue()
{
// Arrange
var adapter = new DynamicObjectAdapter();
dynamic target = new DynamicTestObject();
target.NewProperty = new object();
var segment = "NewProperty";
var resolver = new DefaultContractResolver();
// Act
var status = adapter.TryReplace(target, segment, resolver, "new", out string errorMessage);
// Assert
Assert.True(status);
Assert.Null(errorMessage);
Assert.Equal("new", target.NewProperty);
}
[Fact]
public void TryReplace_ThrowsPathNotFoundException_ForNonExistingProperty()
{
// Arrange
var adapter = new DynamicObjectAdapter();
dynamic target = new DynamicTestObject();
var segment = "NewProperty";
var resolver = new DefaultContractResolver();
// Act
var status = adapter.TryReplace(target, segment, resolver, "test", out string errorMessage);
// Assert
Assert.False(status);
Assert.Equal($"The target location specified by path segment '{segment}' was not found.", errorMessage);
}
[Fact]
public void TryReplace_ThrowsPropertyInvalidException_IfNewValueIsNotTheSameTypeAsInitialValue()
{
// Arrange
var adapter = new DynamicObjectAdapter();
dynamic target = new DynamicTestObject();
target.NewProperty = 1;
var segment = "NewProperty";
var resolver = new DefaultContractResolver();
// Act
var status = adapter.TryReplace(target, segment, resolver, "test", out string errorMessage);
// Assert
Assert.False(status);
Assert.Equal($"The value 'test' is invalid for target location.", errorMessage);
}
[Theory]
[InlineData(1, 0)]
[InlineData("new", null)]
public void TryRemove_SetsPropertyToDefaultOrNull(object value, object expectedValue)
{
// Arrange
var adapter = new DynamicObjectAdapter();
dynamic target = new DynamicTestObject();
var segment = "NewProperty";
var resolver = new DefaultContractResolver();
// Act 1
var addStatus = adapter.TryAdd(target, segment, resolver, value, out string errorMessage);
// Assert 1
Assert.True(addStatus);
Assert.Null(errorMessage);
Assert.Equal(value, target.NewProperty);
// Act 2
var removeStatus = adapter.TryRemove(target, segment, resolver, out string removeErrorMessage);
// Assert 2
Assert.True(removeStatus);
Assert.Null(removeErrorMessage);
Assert.Equal(expectedValue, target.NewProperty);
}
[Fact]
public void TryRemove_ThrowsPathNotFoundException_ForNonExistingProperty()
{
// Arrange
var adapter = new DynamicObjectAdapter();
dynamic target = new DynamicTestObject();
var segment = "NewProperty";
var resolver = new DefaultContractResolver();
// Act
var removeStatus = adapter.TryRemove(target, segment, resolver, out string removeErrorMessage);
// Assert
Assert.False(removeStatus);
Assert.Equal($"The target location specified by path segment '{segment}' was not found.", removeErrorMessage);
}
}
}

View File

@ -0,0 +1,87 @@
// 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;
namespace Microsoft.AspNetCore.JsonPatch.Internal
{
public class DynamicTestObject : DynamicObject
{
private Dictionary<string, object> _dictionary = new Dictionary<string, object>();
public object this[string key] { get => ((IDictionary<string, object>)_dictionary)[key]; set => ((IDictionary<string, object>)_dictionary)[key] = value; }
public ICollection<string> Keys => ((IDictionary<string, object>)_dictionary).Keys;
public ICollection<object> Values => ((IDictionary<string, object>)_dictionary).Values;
public int Count => ((IDictionary<string, object>)_dictionary).Count;
public bool IsReadOnly => ((IDictionary<string, object>)_dictionary).IsReadOnly;
public void Add(string key, object value)
{
((IDictionary<string, object>)_dictionary).Add(key, value);
}
public void Add(KeyValuePair<string, object> item)
{
((IDictionary<string, object>)_dictionary).Add(item);
}
public void Clear()
{
((IDictionary<string, object>)_dictionary).Clear();
}
public bool Contains(KeyValuePair<string, object> item)
{
return ((IDictionary<string, object>)_dictionary).Contains(item);
}
public bool ContainsKey(string key)
{
return ((IDictionary<string, object>)_dictionary).ContainsKey(key);
}
public void CopyTo(KeyValuePair<string, object>[] array, int arrayIndex)
{
((IDictionary<string, object>)_dictionary).CopyTo(array, arrayIndex);
}
public IEnumerator<KeyValuePair<string, object>> GetEnumerator()
{
return ((IDictionary<string, object>)_dictionary).GetEnumerator();
}
public bool Remove(string key)
{
return ((IDictionary<string, object>)_dictionary).Remove(key);
}
public bool Remove(KeyValuePair<string, object> item)
{
return ((IDictionary<string, object>)_dictionary).Remove(item);
}
public bool TryGetValue(string key, out object value)
{
return ((IDictionary<string, object>)_dictionary).TryGetValue(key, out value);
}
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
var name = binder.Name;
return TryGetValue(name, out result);
}
public override bool TrySetMember(SetMemberBinder binder, object value)
{
_dictionary[binder.Name] = value;
return true;
}
}
}

View File

@ -3,7 +3,7 @@
namespace Microsoft.AspNetCore.JsonPatch namespace Microsoft.AspNetCore.JsonPatch
{ {
public class InheritedDTO : SimpleDTO public class InheritedObject : SimpleObject
{ {
public string AdditionalStringProperty { get; set; } public string AdditionalStringProperty { get; set; }
} }

View File

@ -0,0 +1,263 @@
// 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 Microsoft.AspNetCore.JsonPatch.Exceptions;
using Xunit;
namespace Microsoft.AspNetCore.JsonPatch.Internal
{
public class DynamicObjectIntegrationTests
{
[Fact]
public void AddResults_ShouldReplaceExistingPropertyValue_InNestedDynamicObject()
{
// Arrange
dynamic dynamicTestObject = new DynamicTestObject();
dynamicTestObject.Nested = new NestedObject();
dynamicTestObject.Nested.DynamicProperty = new DynamicTestObject();
dynamicTestObject.Nested.DynamicProperty.InBetweenFirst = new DynamicTestObject();
dynamicTestObject.Nested.DynamicProperty.InBetweenFirst.InBetweenSecond = new DynamicTestObject();
dynamicTestObject.Nested.DynamicProperty.InBetweenFirst.InBetweenSecond.StringProperty = "A";
var patchDoc = new JsonPatchDocument();
patchDoc.Add("/Nested/DynamicProperty/InBetweenFirst/InBetweenSecond/StringProperty", "B");
// Act
patchDoc.ApplyTo(dynamicTestObject);
// Assert
Assert.Equal("B", dynamicTestObject.Nested.DynamicProperty.InBetweenFirst.InBetweenSecond.StringProperty);
}
[Fact]
public void ShouldNotBeAbleToAdd_ToNonExistingProperty_ThatIsNotTheRoot()
{
//Adding to a Nonexistent Target
//
// An example target JSON document:
// { "foo": "bar" }
// A JSON Patch document:
// [
// { "op": "add", "path": "/baz/bat", "value": "qux" }
// ]
// This JSON Patch document, applied to the target JSON document above,
// would result in an error (therefore, it would not be applied),
// because the "add" operation's target location that references neither
// the root of the document, nor a member of an existing object, nor a
// member of an existing array.
// Arrange
var nestedObject = new NestedObject()
{
DynamicProperty = new DynamicTestObject()
};
var patchDoc = new JsonPatchDocument();
patchDoc.Add("DynamicProperty/OtherProperty/IntProperty", 1);
// Act
var exception = Assert.Throws<JsonPatchException>(() =>
{
patchDoc.ApplyTo(nestedObject);
});
// Assert
Assert.Equal(
string.Format(
"The target location specified by path segment '{0}' was not found.",
"OtherProperty"),
exception.Message);
}
[Fact]
public void CopyProperties_InNestedDynamicObject()
{
// Arrange
dynamic dynamicTestObject = new DynamicTestObject();
dynamicTestObject.NestedDynamicObject = new DynamicTestObject();
dynamicTestObject.NestedDynamicObject.StringProperty = "A";
dynamicTestObject.NestedDynamicObject.AnotherStringProperty = "B";
var patchDoc = new JsonPatchDocument();
patchDoc.Copy("NestedDynamicObject/StringProperty", "NestedDynamicObject/AnotherStringProperty");
// Act
patchDoc.ApplyTo(dynamicTestObject);
// Assert
Assert.Equal("A", dynamicTestObject.NestedDynamicObject.AnotherStringProperty);
}
[Fact]
public void MoveToNonExistingProperty_InDynamicObject_ShouldAddNewProperty()
{
// Arrange
dynamic dynamicTestObject = new DynamicTestObject();
dynamicTestObject.StringProperty = "A";
var patchDoc = new JsonPatchDocument();
patchDoc.Move("StringProperty", "AnotherStringProperty");
// Act
patchDoc.ApplyTo(dynamicTestObject);
dynamicTestObject.TryGetValue("StringProperty", out object valueFromDictionary);
// Assert
Assert.Equal("A", dynamicTestObject.AnotherStringProperty);
Assert.Null(valueFromDictionary);
}
[Fact]
public void MovePropertyValue_FromDynamicObject_ToTypedObject()
{
// Arrange
dynamic dynamicTestObject = new DynamicTestObject();
dynamicTestObject.StringProperty = "A";
dynamicTestObject.SimpleObject = new SimpleObject() { AnotherStringProperty = "B" };
var patchDoc = new JsonPatchDocument();
patchDoc.Move("StringProperty", "SimpleObject/AnotherStringProperty");
// Act
patchDoc.ApplyTo(dynamicTestObject);
dynamicTestObject.TryGetValue("StringProperty", out object valueFromDictionary);
// Assert
Assert.Equal("A", dynamicTestObject.SimpleObject.AnotherStringProperty);
Assert.Null(valueFromDictionary);
}
[Fact]
public void MovePropertyValue_FromListToNonList_InNestedTypedObject_InDynamicObject()
{
// Arrange
dynamic dynamicTestObject = new DynamicTestObject();
dynamicTestObject.Nested = new SimpleObject()
{
IntegerList = new List<int>() { 1, 2, 3 }
};
var patchDoc = new JsonPatchDocument();
patchDoc.Move("Nested/IntegerList/0", "Nested/IntegerValue");
// Act
patchDoc.ApplyTo(dynamicTestObject);
// Assert
Assert.Equal(new List<int>() { 2, 3 }, dynamicTestObject.Nested.IntegerList);
Assert.Equal(1, dynamicTestObject.Nested.IntegerValue);
}
[Fact]
public void RemoveNestedProperty_FromDynamicObject()
{
// Arrange
dynamic dynamicTestObject = new DynamicTestObject();
dynamicTestObject.Test = new DynamicTestObject();
dynamicTestObject.Test.AnotherTest = "A";
var patchDoc = new JsonPatchDocument();
patchDoc.Remove("Test");
// Act
patchDoc.ApplyTo(dynamicTestObject);
dynamicTestObject.TryGetValue("Test", out object valueFromDictionary);
// Assert
Assert.Null(valueFromDictionary);
}
[Fact]
public void RemoveFromNestedObject_InDynamicObject_MixedCase_ThrowsPathNotFoundException()
{
// Arrange
dynamic dynamicTestObject = new DynamicTestObject();
dynamicTestObject.SimpleObject = new SimpleObject()
{
StringProperty = "A"
};
var patchDoc = new JsonPatchDocument();
patchDoc.Remove("Simpleobject/stringProperty");
// Act
var exception = Assert.Throws<JsonPatchException>(() =>
{
patchDoc.ApplyTo(dynamicTestObject);
});
// Assert
Assert.Equal(
string.Format("The target location specified by path segment '{0}' was not found.",
"Simpleobject"),
exception.Message);
}
[Fact]
public void RemoveFromList_NestedInDynamicObject()
{
// Arrange
dynamic dynamicTestObject = new DynamicTestObject();
dynamicTestObject.SimpleObject = new SimpleObject()
{
IntegerList = new List<int>() { 1, 2, 3 }
};
var patchDoc = new JsonPatchDocument();
patchDoc.Remove("SimpleObject/IntegerList/2");
// Act
patchDoc.ApplyTo(dynamicTestObject);
// Assert
Assert.Equal(new List<int>() { 1, 2 }, dynamicTestObject.SimpleObject.IntegerList);
}
[Fact]
public void ReplaceNestedTypedObject_InDynamicObject()
{
// Arrange
dynamic dynamicTestObject = new DynamicTestObject();
dynamicTestObject.SimpleObject = new SimpleObject()
{
IntegerValue = 5,
IntegerList = new List<int>() { 1, 2, 3 }
};
var newObject = new SimpleObject()
{
DoubleValue = 1
};
var patchDoc = new JsonPatchDocument();
patchDoc.Replace("SimpleObject", newObject);
// Act
patchDoc.ApplyTo(dynamicTestObject);
// Assert
Assert.Equal(1, dynamicTestObject.SimpleObject.DoubleValue);
Assert.Equal(0, dynamicTestObject.SimpleObject.IntegerValue);
Assert.Null(dynamicTestObject.SimpleObject.IntegerList);
}
[Fact]
public void ReplaceFullList_InDynamicObject()
{
// Arrange
dynamic dynamicTestObject = new DynamicTestObject();
dynamicTestObject.IntegerList = new List<int>() { 1, 2, 3 };
var patchDoc = new JsonPatchDocument();
patchDoc.Replace("IntegerList", new List<int>() { 4, 5, 6 });
// Act
patchDoc.ApplyTo(dynamicTestObject);
// Assert
Assert.Equal(new List<int>() { 4, 5, 6 }, dynamicTestObject.IntegerList);
}
}
}

View File

@ -14,14 +14,14 @@ namespace Microsoft.AspNetCore.JsonPatch
[Fact] [Fact]
public void Add_WithExpression_RespectsJsonPropertyName_ForModelProperty() public void Add_WithExpression_RespectsJsonPropertyName_ForModelProperty()
{ {
var patchDoc = new JsonPatchDocument<JsonPropertyDTO>(); var patchDoc = new JsonPatchDocument<JsonPropertyObject>();
patchDoc.Add(p => p.Name, "John"); patchDoc.Add(p => p.Name, "John");
var serialized = JsonConvert.SerializeObject(patchDoc); var serialized = JsonConvert.SerializeObject(patchDoc);
// serialized value should have "AnotherName" as path // serialized value should have "AnotherName" as path
// deserialize to a JsonPatchDocument<JsonPropertyWithAnotherNameDTO> to check // deserialize to a JsonPatchDocument<JsonPropertyWithAnotherNameDTO> to check
var deserialized = var deserialized =
JsonConvert.DeserializeObject<JsonPatchDocument<JsonPropertyWithAnotherNameDTO>>(serialized); JsonConvert.DeserializeObject<JsonPatchDocument<JsonPropertyWithAnotherNameObject>>(serialized);
// get path // get path
var pathToCheck = deserialized.Operations.First().path; var pathToCheck = deserialized.Operations.First().path;
@ -65,19 +65,19 @@ namespace Microsoft.AspNetCore.JsonPatch
[Fact] [Fact]
public void Add_WithExpression_RespectsJsonPropertyName_WhenApplyingToDifferentlyTypedClassWithPropertyMatchingJsonPropertyName() public void Add_WithExpression_RespectsJsonPropertyName_WhenApplyingToDifferentlyTypedClassWithPropertyMatchingJsonPropertyName()
{ {
var patchDocToSerialize = new JsonPatchDocument<JsonPropertyDTO>(); var patchDocToSerialize = new JsonPatchDocument<JsonPropertyObject>();
patchDocToSerialize.Add(p => p.Name, "John"); patchDocToSerialize.Add(p => p.Name, "John");
// the patchdoc will deserialize to "anothername". We should thus be able to apply // the patchdoc will deserialize to "anothername". We should thus be able to apply
// it to a class that HAS that other property name. // it to a class that HAS that other property name.
var doc = new JsonPropertyWithAnotherNameDTO() var doc = new JsonPropertyWithAnotherNameObject()
{ {
AnotherName = "InitialValue" AnotherName = "InitialValue"
}; };
var serialized = JsonConvert.SerializeObject(patchDocToSerialize); var serialized = JsonConvert.SerializeObject(patchDocToSerialize);
var deserialized = var deserialized =
JsonConvert.DeserializeObject<JsonPatchDocument<JsonPropertyWithAnotherNameDTO>> JsonConvert.DeserializeObject<JsonPatchDocument<JsonPropertyWithAnotherNameObject>>
(serialized); (serialized);
deserialized.ApplyTo(doc); deserialized.ApplyTo(doc);
@ -88,21 +88,21 @@ namespace Microsoft.AspNetCore.JsonPatch
[Fact] [Fact]
public void Add_WithExpression_RespectsJsonPropertyName_WhenApplyingToSameTypedClassWithMatchingJsonPropertyName() public void Add_WithExpression_RespectsJsonPropertyName_WhenApplyingToSameTypedClassWithMatchingJsonPropertyName()
{ {
var patchDocToSerialize = new JsonPatchDocument<JsonPropertyDTO>(); var patchDocToSerialize = new JsonPatchDocument<JsonPropertyObject>();
patchDocToSerialize.Add(p => p.Name, "John"); patchDocToSerialize.Add(p => p.Name, "John");
// the patchdoc will deserialize to "anothername". As JsonPropertyDTO has // the patchdoc will deserialize to "anothername". As JsonPropertyDTO has
// a JsonProperty signifying that "Name" should be deseriallized from "AnotherName", // a JsonProperty signifying that "Name" should be deseriallized from "AnotherName",
// we should be able to apply the patchDoc. // we should be able to apply the patchDoc.
var doc = new JsonPropertyDTO() var doc = new JsonPropertyObject()
{ {
Name = "InitialValue" Name = "InitialValue"
}; };
var serialized = JsonConvert.SerializeObject(patchDocToSerialize); var serialized = JsonConvert.SerializeObject(patchDocToSerialize);
var deserialized = var deserialized =
JsonConvert.DeserializeObject<JsonPatchDocument<JsonPropertyDTO>> JsonConvert.DeserializeObject<JsonPatchDocument<JsonPropertyObject>>
(serialized); (serialized);
deserialized.ApplyTo(doc); deserialized.ApplyTo(doc);
@ -113,7 +113,7 @@ namespace Microsoft.AspNetCore.JsonPatch
[Fact] [Fact]
public void Add_OnApplyFromJson_RespectsJsonPropertyNameOnJsonDocument() public void Add_OnApplyFromJson_RespectsJsonPropertyNameOnJsonDocument()
{ {
var doc = new JsonPropertyDTO() var doc = new JsonPropertyObject()
{ {
Name = "InitialValue" Name = "InitialValue"
}; };
@ -121,7 +121,7 @@ namespace Microsoft.AspNetCore.JsonPatch
// serialization should serialize to "AnotherName" // serialization should serialize to "AnotherName"
var serialized = "[{\"value\":\"Kevin\",\"path\":\"/AnotherName\",\"op\":\"add\"}]"; var serialized = "[{\"value\":\"Kevin\",\"path\":\"/AnotherName\",\"op\":\"add\"}]";
var deserialized = var deserialized =
JsonConvert.DeserializeObject<JsonPatchDocument<JsonPropertyDTO>>(serialized); JsonConvert.DeserializeObject<JsonPatchDocument<JsonPropertyObject>>(serialized);
deserialized.ApplyTo(doc); deserialized.ApplyTo(doc);
@ -131,7 +131,7 @@ namespace Microsoft.AspNetCore.JsonPatch
[Fact] [Fact]
public void Remove_OnApplyFromJson_RespectsJsonPropertyNameOnJsonDocument() public void Remove_OnApplyFromJson_RespectsJsonPropertyNameOnJsonDocument()
{ {
var doc = new JsonPropertyDTO() var doc = new JsonPropertyObject()
{ {
Name = "InitialValue" Name = "InitialValue"
}; };
@ -139,7 +139,7 @@ namespace Microsoft.AspNetCore.JsonPatch
// serialization should serialize to "AnotherName" // serialization should serialize to "AnotherName"
var serialized = "[{\"path\":\"/AnotherName\",\"op\":\"remove\"}]"; var serialized = "[{\"path\":\"/AnotherName\",\"op\":\"remove\"}]";
var deserialized = var deserialized =
JsonConvert.DeserializeObject<JsonPatchDocument<JsonPropertyDTO>>(serialized); JsonConvert.DeserializeObject<JsonPatchDocument<JsonPropertyObject>>(serialized);
deserialized.ApplyTo(doc); deserialized.ApplyTo(doc);
@ -149,7 +149,7 @@ namespace Microsoft.AspNetCore.JsonPatch
[Fact] [Fact]
public void Add_OnApplyFromJson_RespectsInheritedJsonPropertyNameOnJsonDocument() public void Add_OnApplyFromJson_RespectsInheritedJsonPropertyNameOnJsonDocument()
{ {
var doc = new JsonPropertyWithInheritanceDTO() var doc = new JsonPropertyWithInheritanceObject()
{ {
Name = "InitialName" Name = "InitialName"
}; };
@ -157,7 +157,7 @@ namespace Microsoft.AspNetCore.JsonPatch
// serialization should serialize to "AnotherName" // serialization should serialize to "AnotherName"
var serialized = "[{\"value\":\"Kevin\",\"path\":\"/AnotherName\",\"op\":\"add\"}]"; var serialized = "[{\"value\":\"Kevin\",\"path\":\"/AnotherName\",\"op\":\"add\"}]";
var deserialized = var deserialized =
JsonConvert.DeserializeObject<JsonPatchDocument<JsonPropertyWithInheritanceDTO>>(serialized); JsonConvert.DeserializeObject<JsonPatchDocument<JsonPropertyWithInheritanceObject>>(serialized);
deserialized.ApplyTo(doc); deserialized.ApplyTo(doc);
@ -167,14 +167,14 @@ namespace Microsoft.AspNetCore.JsonPatch
[Fact] [Fact]
public void Add_WithExpression_RespectsJsonPropertyName_ForInheritedModelProperty() public void Add_WithExpression_RespectsJsonPropertyName_ForInheritedModelProperty()
{ {
var patchDoc = new JsonPatchDocument<JsonPropertyWithInheritanceDTO>(); var patchDoc = new JsonPatchDocument<JsonPropertyWithInheritanceObject>();
patchDoc.Add(p => p.Name, "John"); patchDoc.Add(p => p.Name, "John");
var serialized = JsonConvert.SerializeObject(patchDoc); var serialized = JsonConvert.SerializeObject(patchDoc);
// serialized value should have "AnotherName" as path // serialized value should have "AnotherName" as path
// deserialize to a JsonPatchDocument<JsonPropertyWithAnotherNameDTO> to check // deserialize to a JsonPatchDocument<JsonPropertyWithAnotherNameDTO> to check
var deserialized = var deserialized =
JsonConvert.DeserializeObject<JsonPatchDocument<JsonPropertyWithAnotherNameDTO>>(serialized); JsonConvert.DeserializeObject<JsonPatchDocument<JsonPropertyWithAnotherNameObject>>(serialized);
// get path // get path
var pathToCheck = deserialized.Operations.First().path; var pathToCheck = deserialized.Operations.First().path;
@ -184,10 +184,10 @@ namespace Microsoft.AspNetCore.JsonPatch
[Fact] [Fact]
public void Add_OnApplyFromJson_EscapingHandledOnComplexJsonPropertyNameOnJsonDocument() public void Add_OnApplyFromJson_EscapingHandledOnComplexJsonPropertyNameOnJsonDocument()
{ {
var doc = new JsonPropertyComplexNameDTO() var doc = new JsonPropertyComplexNameObject()
{ {
FooSlashBars = "InitialName", FooSlashBars = "InitialName",
FooSlashTilde = new SimpleDTO FooSlashTilde = new SimpleObject
{ {
StringProperty = "Initial Value" StringProperty = "Initial Value"
} }
@ -196,7 +196,7 @@ namespace Microsoft.AspNetCore.JsonPatch
// serialization should serialize to "AnotherName" // serialization should serialize to "AnotherName"
var serialized = "[{\"value\":\"Kevin\",\"path\":\"/foo~1bar~0\",\"op\":\"add\"},{\"value\":\"Final Value\",\"path\":\"/foo~1~0/StringProperty\",\"op\":\"replace\"}]"; var serialized = "[{\"value\":\"Kevin\",\"path\":\"/foo~1bar~0\",\"op\":\"add\"},{\"value\":\"Final Value\",\"path\":\"/foo~1~0/StringProperty\",\"op\":\"replace\"}]";
var deserialized = var deserialized =
JsonConvert.DeserializeObject<JsonPatchDocument<JsonPropertyComplexNameDTO>>(serialized); JsonConvert.DeserializeObject<JsonPatchDocument<JsonPropertyComplexNameObject>>(serialized);
deserialized.ApplyTo(doc); deserialized.ApplyTo(doc);

View File

@ -5,12 +5,12 @@ using Newtonsoft.Json;
namespace Microsoft.AspNetCore.JsonPatch namespace Microsoft.AspNetCore.JsonPatch
{ {
public class JsonPropertyComplexNameDTO public class JsonPropertyComplexNameObject
{ {
[JsonProperty("foo/bar~")] [JsonProperty("foo/bar~")]
public string FooSlashBars { get; set; } public string FooSlashBars { get; set; }
[JsonProperty("foo/~")] [JsonProperty("foo/~")]
public SimpleDTO FooSlashTilde { get; set; } public SimpleObject FooSlashTilde { get; set; }
} }
} }

View File

@ -5,7 +5,7 @@ using Newtonsoft.Json;
namespace Microsoft.AspNetCore.JsonPatch namespace Microsoft.AspNetCore.JsonPatch
{ {
public class JsonPropertyDTO public class JsonPropertyObject
{ {
[JsonProperty("AnotherName")] [JsonProperty("AnotherName")]
public string Name { get; set; } public string Name { get; set; }

View File

@ -3,7 +3,7 @@
namespace Microsoft.AspNetCore.JsonPatch namespace Microsoft.AspNetCore.JsonPatch
{ {
public class JsonPropertyWithAnotherNameDTO public class JsonPropertyWithAnotherNameObject
{ {
public string AnotherName { get; set; } public string AnotherName { get; set; }
} }

View File

@ -1,19 +0,0 @@
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Microsoft.AspNetCore.JsonPatch
{
public class JsonPropertyWithInheritanceDTO : JsonPropertyWithInheritanceBaseDTO
{
public override string Name { get; set; }
}
public abstract class JsonPropertyWithInheritanceBaseDTO
{
[JsonProperty("AnotherName")]
public abstract string Name { get; set; }
}
}

View File

@ -0,0 +1,15 @@
using Newtonsoft.Json;
namespace Microsoft.AspNetCore.JsonPatch
{
public class JsonPropertyWithInheritanceObject : JsonPropertyWithInheritanceBaseObject
{
public override string Name { get; set; }
}
public abstract class JsonPropertyWithInheritanceBaseObject
{
[JsonProperty("AnotherName")]
public abstract string Name { get; set; }
}
}

View File

@ -18,10 +18,9 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal
var resolver = new Mock<IContractResolver>(MockBehavior.Strict); var resolver = new Mock<IContractResolver>(MockBehavior.Strict);
var targetObject = new[] { 20, 30 }; var targetObject = new[] { 20, 30 };
var listAdapter = new ListAdapter(); var listAdapter = new ListAdapter();
string message = null;
// Act // Act
var addStatus = listAdapter.TryAdd(targetObject, "0", resolver.Object, "40", out message); var addStatus = listAdapter.TryAdd(targetObject, "0", resolver.Object, "40", out var message);
// Assert // Assert
Assert.False(addStatus); Assert.False(addStatus);
@ -41,10 +40,9 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal
targetObject.Add(20); targetObject.Add(20);
targetObject.Add(30); targetObject.Add(30);
var listAdapter = new ListAdapter(); var listAdapter = new ListAdapter();
string message = null;
// Act // Act
var addStatus = listAdapter.TryAdd(targetObject, "-", resolver.Object, "40", out message); var addStatus = listAdapter.TryAdd(targetObject, "-", resolver.Object, "40", out var message);
// Assert // Assert
Assert.False(addStatus); Assert.False(addStatus);
@ -62,11 +60,10 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal
var resolver = new Mock<IContractResolver>(MockBehavior.Strict); var resolver = new Mock<IContractResolver>(MockBehavior.Strict);
var targetObject = new List<string>() { "James", "Mike" }; var targetObject = new List<string>() { "James", "Mike" };
var listAdapter = new ListAdapter(); var listAdapter = new ListAdapter();
string message = null;
var position = targetObject.Count.ToString(); var position = targetObject.Count.ToString();
// Act // Act
var addStatus = listAdapter.TryAdd(targetObject, position, resolver.Object, "Rob", out message); var addStatus = listAdapter.TryAdd(targetObject, position, resolver.Object, "Rob", out var message);
// Assert // Assert
Assert.Null(message); Assert.Null(message);
@ -85,10 +82,9 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal
var resolver = new Mock<IContractResolver>(MockBehavior.Strict); var resolver = new Mock<IContractResolver>(MockBehavior.Strict);
var targetObject = new List<string>() { "James", "Mike" }; var targetObject = new List<string>() { "James", "Mike" };
var listAdapter = new ListAdapter(); var listAdapter = new ListAdapter();
string message = null;
// Act // Act
var addStatus = listAdapter.TryAdd(targetObject, position, resolver.Object, "40", out message); var addStatus = listAdapter.TryAdd(targetObject, position, resolver.Object, "40", out var message);
// Assert // Assert
Assert.False(addStatus); Assert.False(addStatus);
@ -106,10 +102,9 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal
var resolver = new Mock<IContractResolver>(MockBehavior.Strict); var resolver = new Mock<IContractResolver>(MockBehavior.Strict);
var targetObject = new List<string>() { "James", "Mike" }; var targetObject = new List<string>() { "James", "Mike" };
var listAdapter = new ListAdapter(); var listAdapter = new ListAdapter();
string message = null;
// Act // Act
var addStatus = listAdapter.TryAdd(targetObject, position, resolver.Object, "40", out message); var addStatus = listAdapter.TryAdd(targetObject, position, resolver.Object, "40", out var message);
// Assert // Assert
Assert.False(addStatus); Assert.False(addStatus);
@ -143,10 +138,9 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal
// Arrange // Arrange
var resolver = new Mock<IContractResolver>(MockBehavior.Strict); var resolver = new Mock<IContractResolver>(MockBehavior.Strict);
var listAdapter = new ListAdapter(); var listAdapter = new ListAdapter();
string message = null;
// Act // Act
var addStatus = listAdapter.TryAdd(targetObject, "-", resolver.Object, "20", out message); var addStatus = listAdapter.TryAdd(targetObject, "-", resolver.Object, "20", out var message);
// Assert // Assert
Assert.True(addStatus); Assert.True(addStatus);
@ -162,10 +156,9 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal
var resolver = new Mock<IContractResolver>(MockBehavior.Strict); var resolver = new Mock<IContractResolver>(MockBehavior.Strict);
var listAdapter = new ListAdapter(); var listAdapter = new ListAdapter();
var targetObject = new List<string>() { "James", "Mike" }; var targetObject = new List<string>() { "James", "Mike" };
string message = null;
// Act // Act
var addStatus = listAdapter.TryAdd(targetObject, "-", resolver.Object, value: null, errorMessage: out message); var addStatus = listAdapter.TryAdd(targetObject, "-", resolver.Object, value: null, errorMessage: out var message);
// Assert // Assert
Assert.True(addStatus); Assert.True(addStatus);
@ -178,21 +171,20 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal
public void Add_CompatibleTypeWorks() public void Add_CompatibleTypeWorks()
{ {
// Arrange // Arrange
var sDto = new SimpleDTO(); var sDto = new SimpleObject();
var iDto = new InheritedDTO(); var iDto = new InheritedObject();
var resolver = new Mock<IContractResolver>(MockBehavior.Strict); var resolver = new Mock<IContractResolver>(MockBehavior.Strict);
var targetObject = new List<SimpleDTO>() { sDto }; var targetObject = new List<SimpleObject>() { sDto };
var listAdapter = new ListAdapter(); var listAdapter = new ListAdapter();
string message = null;
// Act // Act
var addStatus = listAdapter.TryAdd(targetObject, "-", resolver.Object, iDto, out message); var addStatus = listAdapter.TryAdd(targetObject, "-", resolver.Object, iDto, out var message);
// Assert // Assert
Assert.True(addStatus); Assert.True(addStatus);
Assert.True(string.IsNullOrEmpty(message), "Expected no error message"); Assert.True(string.IsNullOrEmpty(message), "Expected no error message");
Assert.Equal(2, targetObject.Count); Assert.Equal(2, targetObject.Count);
Assert.Equal(new List<SimpleDTO>() { sDto, iDto }, targetObject); Assert.Equal(new List<SimpleObject>() { sDto, iDto }, targetObject);
} }
[Fact] [Fact]
@ -202,10 +194,9 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal
var resolver = new Mock<IContractResolver>(MockBehavior.Strict); var resolver = new Mock<IContractResolver>(MockBehavior.Strict);
var targetObject = new List<int>() { 10, 20 }; var targetObject = new List<int>() { 10, 20 };
var listAdapter = new ListAdapter(); var listAdapter = new ListAdapter();
string message = null;
// Act // Act
var addStatus = listAdapter.TryAdd(targetObject, "-", resolver.Object, "James", out message); var addStatus = listAdapter.TryAdd(targetObject, "-", resolver.Object, "James", out var message);
// Assert // Assert
Assert.False(addStatus); Assert.False(addStatus);
@ -253,10 +244,9 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal
// Arrange // Arrange
var resolver = new Mock<IContractResolver>(MockBehavior.Strict); var resolver = new Mock<IContractResolver>(MockBehavior.Strict);
var listAdapter = new ListAdapter(); var listAdapter = new ListAdapter();
string message = null;
// Act // Act
var addStatus = listAdapter.TryAdd(targetObject, position, resolver.Object, value, out message); var addStatus = listAdapter.TryAdd(targetObject, position, resolver.Object, value, out var message);
// Assert // Assert
Assert.True(addStatus); Assert.True(addStatus);
@ -267,34 +257,34 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal
public static TheoryData<IList, object, string, IList> AddingKeepsObjectReferenceData { public static TheoryData<IList, object, string, IList> AddingKeepsObjectReferenceData {
get { get {
var sDto1 = new SimpleDTO(); var sDto1 = new SimpleObject();
var sDto2 = new SimpleDTO(); var sDto2 = new SimpleObject();
var sDto3 = new SimpleDTO(); var sDto3 = new SimpleObject();
return new TheoryData<IList, object, string, IList>() return new TheoryData<IList, object, string, IList>()
{ {
{ {
new List<SimpleDTO>() { }, new List<SimpleObject>() { },
sDto1, sDto1,
"-", "-",
new List<SimpleDTO>() { sDto1 } new List<SimpleObject>() { sDto1 }
}, },
{ {
new List<SimpleDTO>() { sDto1, sDto2 }, new List<SimpleObject>() { sDto1, sDto2 },
sDto3, sDto3,
"-", "-",
new List<SimpleDTO>() { sDto1, sDto2, sDto3 } new List<SimpleObject>() { sDto1, sDto2, sDto3 }
}, },
{ {
new List<SimpleDTO>() { sDto1, sDto2 }, new List<SimpleObject>() { sDto1, sDto2 },
sDto3, sDto3,
"0", "0",
new List<SimpleDTO>() { sDto3, sDto1, sDto2 } new List<SimpleObject>() { sDto3, sDto1, sDto2 }
}, },
{ {
new List<SimpleDTO>() { sDto1, sDto2 }, new List<SimpleObject>() { sDto1, sDto2 },
sDto3, sDto3,
"1", "1",
new List<SimpleDTO>() { sDto1, sDto3, sDto2 } new List<SimpleObject>() { sDto1, sDto3, sDto2 }
} }
}; };
} }
@ -307,10 +297,9 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal
// Arrange // Arrange
var resolver = new Mock<IContractResolver>(MockBehavior.Strict); var resolver = new Mock<IContractResolver>(MockBehavior.Strict);
var listAdapter = new ListAdapter(); var listAdapter = new ListAdapter();
string message = null;
// Act // Act
var addStatus = listAdapter.TryAdd(targetObject, position, resolver.Object, value, out message); var addStatus = listAdapter.TryAdd(targetObject, position, resolver.Object, value, out var message);
// Assert // Assert
Assert.True(addStatus); Assert.True(addStatus);
@ -329,11 +318,9 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal
var resolver = new Mock<IContractResolver>(MockBehavior.Strict); var resolver = new Mock<IContractResolver>(MockBehavior.Strict);
var targetObject = new List<int>(input); var targetObject = new List<int>(input);
var listAdapter = new ListAdapter(); var listAdapter = new ListAdapter();
string message = null;
object value = null;
// Act // Act
var getStatus = listAdapter.TryGet(targetObject, position, resolver.Object, out value, out message); var getStatus = listAdapter.TryGet(targetObject, position, resolver.Object, out var value, out var message);
// Assert // Assert
Assert.False(getStatus); Assert.False(getStatus);
@ -352,11 +339,9 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal
var resolver = new Mock<IContractResolver>(MockBehavior.Strict); var resolver = new Mock<IContractResolver>(MockBehavior.Strict);
var targetObject = new List<int>(input); var targetObject = new List<int>(input);
var listAdapter = new ListAdapter(); var listAdapter = new ListAdapter();
string message = null;
object value = null;
// Act // Act
var getStatus = listAdapter.TryGet(targetObject, position, resolver.Object, out value, out message); var getStatus = listAdapter.TryGet(targetObject, position, resolver.Object, out var value, out var message);
// Assert // Assert
Assert.True(getStatus); Assert.True(getStatus);
@ -374,10 +359,9 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal
var resolver = new Mock<IContractResolver>(MockBehavior.Strict); var resolver = new Mock<IContractResolver>(MockBehavior.Strict);
var targetObject = new List<int>(input); var targetObject = new List<int>(input);
var listAdapter = new ListAdapter(); var listAdapter = new ListAdapter();
string message = null;
// Act // Act
var removeStatus = listAdapter.TryRemove(targetObject, position, resolver.Object, out message); var removeStatus = listAdapter.TryRemove(targetObject, position, resolver.Object, out var message);
// Assert // Assert
Assert.False(removeStatus); Assert.False(removeStatus);
@ -396,10 +380,9 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal
var resolver = new Mock<IContractResolver>(MockBehavior.Strict); var resolver = new Mock<IContractResolver>(MockBehavior.Strict);
var targetObject = new List<int>(input); var targetObject = new List<int>(input);
var listAdapter = new ListAdapter(); var listAdapter = new ListAdapter();
string message = null;
// Act // Act
var removeStatus = listAdapter.TryRemove(targetObject, position, resolver.Object, out message); var removeStatus = listAdapter.TryRemove(targetObject, position, resolver.Object, out var message);
// Assert // Assert
Assert.True(removeStatus); Assert.True(removeStatus);
@ -413,10 +396,9 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal
var resolver = new Mock<IContractResolver>(MockBehavior.Strict); var resolver = new Mock<IContractResolver>(MockBehavior.Strict);
var targetObject = new List<int>() { 10, 20 }; var targetObject = new List<int>() { 10, 20 };
var listAdapter = new ListAdapter(); var listAdapter = new ListAdapter();
string message = null;
// Act // Act
var replaceStatus = listAdapter.TryReplace(targetObject, "-", resolver.Object, "James", out message); var replaceStatus = listAdapter.TryReplace(targetObject, "-", resolver.Object, "James", out var message);
// Assert // Assert
Assert.False(replaceStatus); Assert.False(replaceStatus);
@ -432,10 +414,9 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal
var resolver = new Mock<IContractResolver>(MockBehavior.Strict); var resolver = new Mock<IContractResolver>(MockBehavior.Strict);
var targetObject = new List<int>() { 10, 20 }; var targetObject = new List<int>() { 10, 20 };
var listAdapter = new ListAdapter(); var listAdapter = new ListAdapter();
string message = null;
// Act // Act
var replaceStatus = listAdapter.TryReplace(targetObject, "-", resolver.Object, "30", out message); var replaceStatus = listAdapter.TryReplace(targetObject, "-", resolver.Object, "30", out var message);
// Assert // Assert
Assert.True(replaceStatus); Assert.True(replaceStatus);
@ -469,10 +450,9 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal
var resolver = new Mock<IContractResolver>(MockBehavior.Strict); var resolver = new Mock<IContractResolver>(MockBehavior.Strict);
var targetObject = new List<int>() { 10, 20 }; var targetObject = new List<int>() { 10, 20 };
var listAdapter = new ListAdapter(); var listAdapter = new ListAdapter();
string message = null;
// Act // Act
var replaceStatus = listAdapter.TryReplace(targetObject, position, resolver.Object, "30", out message); var replaceStatus = listAdapter.TryReplace(targetObject, position, resolver.Object, "30", out var message);
// Assert // Assert
Assert.True(replaceStatus); Assert.True(replaceStatus);

View File

@ -3,7 +3,7 @@
namespace Microsoft.AspNetCore.JsonPatch namespace Microsoft.AspNetCore.JsonPatch
{ {
public class NestedDTO public class NestedObject
{ {
public string StringProperty { get; set; } public string StringProperty { get; set; }
} }

File diff suppressed because it is too large Load Diff

View File

@ -46,11 +46,9 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal
{ {
// Arrange // Arrange
var visitor = new ObjectVisitor(new ParsedPath(path), new DefaultContractResolver()); var visitor = new ObjectVisitor(new ParsedPath(path), new DefaultContractResolver());
IAdapter adapter = null;
string message = null;
// Act // Act
var visitStatus = visitor.TryVisit(ref targetObject, out adapter, out message); var visitStatus = visitor.TryVisit(ref targetObject, out var adapter, out var message);
// Assert // Assert
Assert.True(visitStatus); Assert.True(visitStatus);
@ -81,11 +79,9 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal
{ {
// Arrange // Arrange
var visitor = new ObjectVisitor(new ParsedPath(path), new DefaultContractResolver()); var visitor = new ObjectVisitor(new ParsedPath(path), new DefaultContractResolver());
IAdapter adapter = null;
string message = null;
// Act // Act
var visitStatus = visitor.TryVisit(ref targetObject, out adapter, out message); var visitStatus = visitor.TryVisit(ref targetObject, out var adapter, out var message);
// Assert // Assert
Assert.True(visitStatus); Assert.True(visitStatus);
@ -112,11 +108,9 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal
{ {
// Arrange // Arrange
var visitor = new ObjectVisitor(new ParsedPath(path), new DefaultContractResolver()); var visitor = new ObjectVisitor(new ParsedPath(path), new DefaultContractResolver());
IAdapter adapter = null;
string message = null;
// Act // Act
var visitStatus = visitor.TryVisit(ref targetObject, out adapter, out message); var visitStatus = visitor.TryVisit(ref targetObject, out var adapter, out var message);
// Assert // Assert
Assert.True(visitStatus); Assert.True(visitStatus);
@ -146,11 +140,9 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal
{ {
// Arrange // Arrange
var visitor = new ObjectVisitor(new ParsedPath(path), new DefaultContractResolver()); var visitor = new ObjectVisitor(new ParsedPath(path), new DefaultContractResolver());
IAdapter adapter = null;
string message = null;
// Act // Act
var visitStatus = visitor.TryVisit(ref targetObject, out adapter, out message); var visitStatus = visitor.TryVisit(ref targetObject, out var adapter, out var message);
// Assert // Assert
Assert.True(visitStatus); Assert.True(visitStatus);
@ -168,11 +160,9 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal
var visitor = new ObjectVisitor(new ParsedPath($"/Customers/{position}/States/-"), new DefaultContractResolver()); var visitor = new ObjectVisitor(new ParsedPath($"/Customers/{position}/States/-"), new DefaultContractResolver());
var automobileDepartment = new Class1Nested(); var automobileDepartment = new Class1Nested();
object targetObject = automobileDepartment; object targetObject = automobileDepartment;
IAdapter adapter = null;
string message = null;
// Act // Act
var visitStatus = visitor.TryVisit(ref targetObject, out adapter, out message); var visitStatus = visitor.TryVisit(ref targetObject, out var adapter, out var message);
// Assert // Assert
Assert.False(visitStatus); Assert.False(visitStatus);
@ -190,11 +180,9 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal
var visitor = new ObjectVisitor(new ParsedPath($"/Customers/{position}/States/-"), new DefaultContractResolver()); var visitor = new ObjectVisitor(new ParsedPath($"/Customers/{position}/States/-"), new DefaultContractResolver());
var automobileDepartment = new Class1Nested(); var automobileDepartment = new Class1Nested();
object targetObject = automobileDepartment; object targetObject = automobileDepartment;
IAdapter adapter = null;
string message = null;
// Act // Act
var visitStatus = visitor.TryVisit(ref targetObject, out adapter, out message); var visitStatus = visitor.TryVisit(ref targetObject, out var adapter, out var message);
// Assert // Assert
Assert.False(visitStatus); Assert.False(visitStatus);
@ -211,16 +199,30 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal
var visitor = new ObjectVisitor(new ParsedPath($"/NonExisting"), new DefaultContractResolver()); var visitor = new ObjectVisitor(new ParsedPath($"/NonExisting"), new DefaultContractResolver());
var model = new Class1(); var model = new Class1();
object targetObject = model; object targetObject = model;
IAdapter adapter = null;
string message = null;
// Act // Act
var visitStatus = visitor.TryVisit(ref targetObject, out adapter, out message); var visitStatus = visitor.TryVisit(ref targetObject, out var adapter, out var message);
// Assert // Assert
Assert.True(visitStatus); Assert.True(visitStatus);
Assert.True(string.IsNullOrEmpty(message), "Expected no error message"); Assert.True(string.IsNullOrEmpty(message), "Expected no error message");
Assert.IsType<PocoAdapter>(adapter); Assert.IsType<PocoAdapter>(adapter);
} }
[Fact]
public void Visit_NullTarget_ReturnsNullAdapter()
{
// Arrange
var visitor = new ObjectVisitor(new ParsedPath("test"), new DefaultContractResolver());
// Act
object target = null;
var visitStatus = visitor.TryVisit(ref target, out var adapter, out var message);
// Assert
Assert.False(visitStatus);
Assert.Null(adapter);
Assert.Null(message);
}
} }
} }

View File

@ -1,30 +0,0 @@
// 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;
namespace Microsoft.AspNetCore.JsonPatch
{
public class SimpleDTOWithNestedDTO
{
public int IntegerValue { get; set; }
public NestedDTO NestedDTO { get; set; }
public SimpleDTO SimpleDTO { get; set; }
public InheritedDTO InheritedDTO { get; set; }
public List<SimpleDTO> SimpleDTOList { get; set; }
public IList<SimpleDTO> SimpleDTOIList { get; set; }
public SimpleDTOWithNestedDTO()
{
this.NestedDTO = new NestedDTO();
this.SimpleDTO = new SimpleDTO();
this.InheritedDTO = new InheritedDTO();
this.SimpleDTOList = new List<SimpleDTO>();
}
}
}

View File

@ -1,15 +0,0 @@
// 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.AspNetCore.JsonPatch
{
public class SimpleDTOWithNestedDTOWithNullCheck
{
public SimpleDTOWithNullCheck SimpleDTOWithNullCheck { get; set; }
public SimpleDTOWithNestedDTOWithNullCheck()
{
SimpleDTOWithNullCheck = new SimpleDTOWithNullCheck();
}
}
}

View File

@ -6,7 +6,7 @@ using System.Collections.Generic;
namespace Microsoft.AspNetCore.JsonPatch namespace Microsoft.AspNetCore.JsonPatch
{ {
public class SimpleDTO public class SimpleObject
{ {
public List<int> IntegerList { get; set; } public List<int> IntegerList { get; set; }
public IList<int> IntegerIList { get; set; } public IList<int> IntegerIList { get; set; }

View File

@ -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.
using System.Collections.Generic;
namespace Microsoft.AspNetCore.JsonPatch
{
public class SimpleObjectWithNestedObject
{
public int IntegerValue { get; set; }
public NestedObject NestedObject { get; set; }
public SimpleObject SimpleObject { get; set; }
public InheritedObject InheritedObject { get; set; }
public List<SimpleObject> SimpleObjectList { get; set; }
public IList<SimpleObject> SimpleObjectIList { get; set; }
public SimpleObjectWithNestedObject()
{
NestedObject = new NestedObject();
SimpleObject = new SimpleObject();
InheritedObject = new InheritedObject();
SimpleObjectList = new List<SimpleObject>();
}
}
}

View File

@ -0,0 +1,15 @@
// 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.AspNetCore.JsonPatch
{
public class SimpleObjectWithNestedObjectWithNullCheck
{
public SimpleObjectWithNullCheck SimpleObjectWithNullCheck { get; set; }
public SimpleObjectWithNestedObjectWithNullCheck()
{
SimpleObjectWithNullCheck = new SimpleObjectWithNullCheck();
}
}
}

View File

@ -5,7 +5,7 @@ using System;
namespace Microsoft.AspNetCore.JsonPatch namespace Microsoft.AspNetCore.JsonPatch
{ {
public class SimpleDTOWithNullCheck public class SimpleObjectWithNullCheck
{ {
private string stringProperty; private string stringProperty;