From 4d92d76b64e3229ea61679945eb8a8bdf4537226 Mon Sep 17 00:00:00 2001 From: DHumphreys Date: Fri, 11 May 2018 15:08:09 -0400 Subject: [PATCH] Initial commit providing the AdapterFactory directly to the ObjectAdapter to all for customization of the Adapter selection and the ability to override the built in adapters to leverage their ability as much as possible. --- .../Adapters/AdapterFactory.cs | 39 ++++++++++ .../Adapters/IAdapterFactory.cs | 22 ++++++ .../Adapters/ObjectAdapter.cs | 36 +++++++-- .../Internal/DictionaryAdapterOfTU.cs | 16 ++-- .../Internal/DynamicObjectAdapter.cs | 18 ++--- .../Internal/ListAdapter.cs | 24 +++--- .../Internal/ObjectVisitor.cs | 39 +++++----- .../Internal/PocoAdapter.cs | 16 ++-- .../JsonPatchDocument.cs | 19 ++++- .../JsonPatchDocumentOfT.cs | 19 ++++- .../Adapters/AdapterFactoryTests.cs | 73 +++++++++++++++++++ .../Adapters/TestDynamicObject.cs | 10 +++ 12 files changed, 263 insertions(+), 68 deletions(-) create mode 100644 src/Microsoft.AspNetCore.JsonPatch/Adapters/AdapterFactory.cs create mode 100644 src/Microsoft.AspNetCore.JsonPatch/Adapters/IAdapterFactory.cs create mode 100644 test/Microsoft.AspNetCore.JsonPatch.Test/Adapters/AdapterFactoryTests.cs create mode 100644 test/Microsoft.AspNetCore.JsonPatch.Test/Adapters/TestDynamicObject.cs diff --git a/src/Microsoft.AspNetCore.JsonPatch/Adapters/AdapterFactory.cs b/src/Microsoft.AspNetCore.JsonPatch/Adapters/AdapterFactory.cs new file mode 100644 index 0000000000..c963fcffdd --- /dev/null +++ b/src/Microsoft.AspNetCore.JsonPatch/Adapters/AdapterFactory.cs @@ -0,0 +1,39 @@ +using Microsoft.AspNetCore.JsonPatch.Internal; +using Newtonsoft.Json.Serialization; +using System; +using System.Collections; +using System.Collections.Generic; +using System.Text; + +namespace Microsoft.AspNetCore.JsonPatch.Adapters +{ + /// + /// The default AdapterFactory to be used for resolving . + /// + public class AdapterFactory : IAdapterFactory + { + /// + public virtual IAdapter Create(object target, IContractResolver contractResolver) + { + var jsonContract = contractResolver.ResolveContract(target.GetType()); + + if (target is IList) + { + return new ListAdapter(); + } + else if (jsonContract is JsonDictionaryContract jsonDictionaryContract) + { + var type = typeof(DictionaryAdapter<,>).MakeGenericType(jsonDictionaryContract.DictionaryKeyType, jsonDictionaryContract.DictionaryValueType); + return (IAdapter)Activator.CreateInstance(type); + } + else if (jsonContract is JsonDynamicContract) + { + return new DynamicObjectAdapter(); + } + else + { + return new PocoAdapter(); + } + } + } +} diff --git a/src/Microsoft.AspNetCore.JsonPatch/Adapters/IAdapterFactory.cs b/src/Microsoft.AspNetCore.JsonPatch/Adapters/IAdapterFactory.cs new file mode 100644 index 0000000000..43ca1e65b6 --- /dev/null +++ b/src/Microsoft.AspNetCore.JsonPatch/Adapters/IAdapterFactory.cs @@ -0,0 +1,22 @@ +using Microsoft.AspNetCore.JsonPatch.Internal; +using Newtonsoft.Json.Serialization; +using System; +using System.Collections.Generic; +using System.Text; + +namespace Microsoft.AspNetCore.JsonPatch.Adapters +{ + /// + /// Defines the operations used for loading an based on the current object and ContractResolver. + /// + public interface IAdapterFactory + { + /// + /// Creates an for the current object + /// + /// The target object + /// The current contract resolver + /// The needed + IAdapter Create(object target, IContractResolver contractResolver); + } +} diff --git a/src/Microsoft.AspNetCore.JsonPatch/Adapters/ObjectAdapter.cs b/src/Microsoft.AspNetCore.JsonPatch/Adapters/ObjectAdapter.cs index 73095b52c2..48d7e69b0f 100644 --- a/src/Microsoft.AspNetCore.JsonPatch/Adapters/ObjectAdapter.cs +++ b/src/Microsoft.AspNetCore.JsonPatch/Adapters/ObjectAdapter.cs @@ -18,17 +18,37 @@ namespace Microsoft.AspNetCore.JsonPatch.Adapters /// The for logging . public ObjectAdapter( IContractResolver contractResolver, - Action logErrorAction) + Action logErrorAction): + this(contractResolver, logErrorAction, new AdapterFactory()) { - ContractResolver = contractResolver ?? throw new ArgumentNullException(nameof(contractResolver)); - LogErrorAction = logErrorAction; } + /// + /// Initializes a new instance of . + /// + /// The . + /// The for logging . + /// The to use when creating adaptors. + public ObjectAdapter( + IContractResolver contractResolver, + Action logErrorAction, + IAdapterFactory adapterFactory) + { + ContractResolver = contractResolver ?? throw new ArgumentNullException(nameof(contractResolver)); + LogErrorAction = logErrorAction; + AdapterFactory = adapterFactory ?? throw new ArgumentNullException(nameof(adapterFactory)); + } + /// /// Gets or sets the . /// public IContractResolver ContractResolver { get; } + /// + /// Gets or sets the + /// + public IAdapterFactory AdapterFactory { get; set; } + /// /// Action for logging . /// @@ -75,7 +95,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Adapters } var parsedPath = new ParsedPath(path); - var visitor = new ObjectVisitor(parsedPath, ContractResolver); + var visitor = new ObjectVisitor(parsedPath, ContractResolver, AdapterFactory); var target = objectToApplyTo; if (!visitor.TryVisit(ref target, out var adapter, out var errorMessage)) @@ -144,7 +164,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Adapters private void Remove(string path, object objectToApplyTo, Operation operationToReport) { var parsedPath = new ParsedPath(path); - var visitor = new ObjectVisitor(parsedPath, ContractResolver); + var visitor = new ObjectVisitor(parsedPath, ContractResolver, AdapterFactory); var target = objectToApplyTo; if (!visitor.TryVisit(ref target, out var adapter, out var errorMessage)) @@ -175,7 +195,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Adapters } var parsedPath = new ParsedPath(operation.path); - var visitor = new ObjectVisitor(parsedPath, ContractResolver); + var visitor = new ObjectVisitor(parsedPath, ContractResolver, AdapterFactory); var target = objectToApplyTo; if (!visitor.TryVisit(ref target, out var adapter, out var errorMessage)) @@ -239,7 +259,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Adapters } var parsedPath = new ParsedPath(operation.path); - var visitor = new ObjectVisitor(parsedPath, ContractResolver); + var visitor = new ObjectVisitor(parsedPath, ContractResolver, AdapterFactory); var target = objectToApplyTo; if (!visitor.TryVisit(ref target, out var adapter, out var errorMessage)) @@ -281,7 +301,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Adapters propertyValue = null; var parsedPath = new ParsedPath(fromLocation); - var visitor = new ObjectVisitor(parsedPath, ContractResolver); + var visitor = new ObjectVisitor(parsedPath, ContractResolver, AdapterFactory); var target = objectToGetValueFrom; if (!visitor.TryVisit(ref target, out var adapter, out var errorMessage)) diff --git a/src/Microsoft.AspNetCore.JsonPatch/Internal/DictionaryAdapterOfTU.cs b/src/Microsoft.AspNetCore.JsonPatch/Internal/DictionaryAdapterOfTU.cs index 8a344e24ee..be2bbffd86 100644 --- a/src/Microsoft.AspNetCore.JsonPatch/Internal/DictionaryAdapterOfTU.cs +++ b/src/Microsoft.AspNetCore.JsonPatch/Internal/DictionaryAdapterOfTU.cs @@ -10,7 +10,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal { public class DictionaryAdapter : IAdapter { - public bool TryAdd( + public virtual bool TryAdd( object target, string segment, IContractResolver contractResolver, @@ -37,7 +37,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal return true; } - public bool TryGet( + public virtual bool TryGet( object target, string segment, IContractResolver contractResolver, @@ -66,7 +66,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal return true; } - public bool TryRemove( + public virtual bool TryRemove( object target, string segment, IContractResolver contractResolver, @@ -94,7 +94,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal return true; } - public bool TryReplace( + public virtual bool TryReplace( object target, string segment, IContractResolver contractResolver, @@ -128,7 +128,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal return true; } - public bool TryTest( + public virtual bool TryTest( object target, string segment, IContractResolver contractResolver, @@ -177,7 +177,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal } } - public bool TryTraverse( + public virtual bool TryTraverse( object target, string segment, IContractResolver contractResolver, @@ -208,7 +208,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal } } - private bool TryConvertKey(string key, out TKey convertedKey, out string errorMessage) + protected virtual bool TryConvertKey(string key, out TKey convertedKey, out string errorMessage) { var conversionResult = ConversionResultProvider.ConvertTo(key, typeof(TKey)); if (conversionResult.CanBeConverted) @@ -225,7 +225,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal } } - private bool TryConvertValue(object value, out TValue convertedValue, out string errorMessage) + protected virtual bool TryConvertValue(object value, out TValue convertedValue, out string errorMessage) { var conversionResult = ConversionResultProvider.ConvertTo(value, typeof(TValue)); if (conversionResult.CanBeConverted) diff --git a/src/Microsoft.AspNetCore.JsonPatch/Internal/DynamicObjectAdapter.cs b/src/Microsoft.AspNetCore.JsonPatch/Internal/DynamicObjectAdapter.cs index fb4adeb1f2..dc3c48266f 100644 --- a/src/Microsoft.AspNetCore.JsonPatch/Internal/DynamicObjectAdapter.cs +++ b/src/Microsoft.AspNetCore.JsonPatch/Internal/DynamicObjectAdapter.cs @@ -15,7 +15,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal { public class DynamicObjectAdapter : IAdapter { - public bool TryAdd( + public virtual bool TryAdd( object target, string segment, IContractResolver contractResolver, @@ -31,7 +31,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal return true; } - public bool TryGet( + public virtual bool TryGet( object target, string segment, IContractResolver contractResolver, @@ -48,7 +48,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal return true; } - public bool TryRemove( + public virtual bool TryRemove( object target, string segment, IContractResolver contractResolver, @@ -78,7 +78,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal } - public bool TryReplace( + public virtual bool TryReplace( object target, string segment, IContractResolver contractResolver, @@ -105,7 +105,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal return true; } - public bool TryTest( + public virtual bool TryTest( object target, string segment, IContractResolver contractResolver, @@ -135,7 +135,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal } } - public bool TryTraverse( + public virtual bool TryTraverse( object target, string segment, IContractResolver contractResolver, @@ -155,7 +155,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal } } - private bool TryGetDynamicObjectProperty( + protected virtual bool TryGetDynamicObjectProperty( object target, IContractResolver contractResolver, string segment, @@ -191,7 +191,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal } } - private bool TrySetDynamicObjectProperty( + protected virtual bool TrySetDynamicObjectProperty( object target, IContractResolver contractResolver, string segment, @@ -227,7 +227,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal } } - private bool TryConvertValue(object value, Type propertyType, out object convertedValue) + protected virtual bool TryConvertValue(object value, Type propertyType, out object convertedValue) { var conversionResult = ConversionResultProvider.ConvertTo(value, propertyType); if (!conversionResult.CanBeConverted) diff --git a/src/Microsoft.AspNetCore.JsonPatch/Internal/ListAdapter.cs b/src/Microsoft.AspNetCore.JsonPatch/Internal/ListAdapter.cs index d1348fd5c6..597f7b9f5f 100644 --- a/src/Microsoft.AspNetCore.JsonPatch/Internal/ListAdapter.cs +++ b/src/Microsoft.AspNetCore.JsonPatch/Internal/ListAdapter.cs @@ -13,7 +13,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal { public class ListAdapter : IAdapter { - public bool TryAdd( + public virtual bool TryAdd( object target, string segment, IContractResolver contractResolver, @@ -50,7 +50,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal return true; } - public bool TryGet( + public virtual bool TryGet( object target, string segment, IContractResolver contractResolver, @@ -84,7 +84,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal return true; } - public bool TryRemove( + public virtual bool TryRemove( object target, string segment, IContractResolver contractResolver, @@ -115,7 +115,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal return true; } - public bool TryReplace( + public virtual bool TryReplace( object target, string segment, IContractResolver contractResolver, @@ -152,7 +152,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal return true; } - public bool TryTest( + public virtual bool TryTest( object target, string segment, IContractResolver contractResolver, @@ -189,7 +189,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal } } - public bool TryTraverse( + public virtual bool TryTraverse( object target, string segment, IContractResolver contractResolver, @@ -224,7 +224,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal return true; } - private bool TryConvertValue( + protected virtual bool TryConvertValue( object originalValue, Type listTypeArgument, string segment, @@ -244,7 +244,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal return true; } - private bool TryGetListTypeArgument(IList list, out Type listTypeArgument, out string errorMessage) + protected virtual bool TryGetListTypeArgument(IList list, out Type listTypeArgument, out string errorMessage) { // Arrays are not supported as they have fixed size and operations like Add, Insert do not make sense var listType = list.GetType(); @@ -272,7 +272,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal } } - private bool TryGetPositionInfo( + protected virtual bool TryGetPositionInfo( IList list, string segment, OperationType operationType, @@ -318,7 +318,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal } } - private struct PositionInfo + protected struct PositionInfo { public PositionInfo(PositionType type, int index) { @@ -330,7 +330,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal public int Index { get; } } - private enum PositionType + protected enum PositionType { Index, // valid index EndOfList, // '-' @@ -338,7 +338,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal OutOfBounds } - private enum OperationType + protected enum OperationType { Add, Remove, diff --git a/src/Microsoft.AspNetCore.JsonPatch/Internal/ObjectVisitor.cs b/src/Microsoft.AspNetCore.JsonPatch/Internal/ObjectVisitor.cs index 8994f0aa52..a988afa300 100644 --- a/src/Microsoft.AspNetCore.JsonPatch/Internal/ObjectVisitor.cs +++ b/src/Microsoft.AspNetCore.JsonPatch/Internal/ObjectVisitor.cs @@ -3,19 +3,38 @@ using System; using System.Collections; +using Microsoft.AspNetCore.JsonPatch.Adapters; using Newtonsoft.Json.Serialization; namespace Microsoft.AspNetCore.JsonPatch.Internal { public class ObjectVisitor { + private readonly IAdapterFactory _adapterFactory; private readonly IContractResolver _contractResolver; private readonly ParsedPath _path; + /// + /// Initializes a new instance of . + /// + /// The path of the JsonPatch operation + /// The . public ObjectVisitor(ParsedPath path, IContractResolver contractResolver) + :this(path, contractResolver, new AdapterFactory()) { + } + + /// + /// Initializes a new instance of . + /// + /// The path of the JsonPatch operation + /// The . + /// The to use when creating adaptors. + public ObjectVisitor(ParsedPath path, IContractResolver contractResolver, IAdapterFactory adapterFactory) + { _path = path; _contractResolver = contractResolver ?? throw new ArgumentNullException(nameof(contractResolver)); + _adapterFactory = adapterFactory ?? throw new ArgumentNullException(nameof(adapterFactory)); } public bool TryVisit(ref object target, out IAdapter adapter, out string errorMessage) @@ -48,25 +67,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal private IAdapter SelectAdapter(object targetObject) { - var jsonContract = _contractResolver.ResolveContract(targetObject.GetType()); - - if (targetObject is IList) - { - return new ListAdapter(); - } - else if (jsonContract is JsonDictionaryContract jsonDictionaryContract) - { - var type = typeof(DictionaryAdapter<,>).MakeGenericType(jsonDictionaryContract.DictionaryKeyType, jsonDictionaryContract.DictionaryValueType); - return (IAdapter)Activator.CreateInstance(type); - } - else if (jsonContract is JsonDynamicContract) - { - return new DynamicObjectAdapter(); - } - else - { - return new PocoAdapter(); - } + return _adapterFactory.Create(targetObject, _contractResolver); } } } diff --git a/src/Microsoft.AspNetCore.JsonPatch/Internal/PocoAdapter.cs b/src/Microsoft.AspNetCore.JsonPatch/Internal/PocoAdapter.cs index 0eee0fc889..5ba3e5587b 100644 --- a/src/Microsoft.AspNetCore.JsonPatch/Internal/PocoAdapter.cs +++ b/src/Microsoft.AspNetCore.JsonPatch/Internal/PocoAdapter.cs @@ -12,7 +12,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal { public class PocoAdapter : IAdapter { - public bool TryAdd( + public virtual bool TryAdd( object target, string segment, IContractResolver contractResolver, @@ -43,7 +43,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal return true; } - public bool TryGet( + public virtual bool TryGet( object target, string segment, IContractResolver contractResolver, @@ -69,7 +69,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal return true; } - public bool TryRemove( + public virtual bool TryRemove( object target, string segment, IContractResolver contractResolver, @@ -102,7 +102,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal return true; } - public bool TryReplace( + public virtual bool TryReplace( object target, string segment, IContractResolver @@ -134,7 +134,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal return true; } - public bool TryTest( + public virtual bool TryTest( object target, string segment, IContractResolver @@ -171,7 +171,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal return true; } - public bool TryTraverse( + public virtual bool TryTraverse( object target, string segment, IContractResolver contractResolver, @@ -197,7 +197,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal return false; } - private bool TryGetJsonProperty( + protected virtual bool TryGetJsonProperty( object target, IContractResolver contractResolver, string segment, @@ -220,7 +220,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal return false; } - private bool TryConvertValue(object value, Type propertyType, out object convertedValue) + protected virtual bool TryConvertValue(object value, Type propertyType, out object convertedValue) { var conversionResult = ConversionResultProvider.ConvertTo(value, propertyType); if (!conversionResult.CanBeConverted) diff --git a/src/Microsoft.AspNetCore.JsonPatch/JsonPatchDocument.cs b/src/Microsoft.AspNetCore.JsonPatch/JsonPatchDocument.cs index b6539caae8..1888ea6b4b 100644 --- a/src/Microsoft.AspNetCore.JsonPatch/JsonPatchDocument.cs +++ b/src/Microsoft.AspNetCore.JsonPatch/JsonPatchDocument.cs @@ -174,7 +174,7 @@ namespace Microsoft.AspNetCore.JsonPatch throw new ArgumentNullException(nameof(objectToApplyTo)); } - ApplyTo(objectToApplyTo, new ObjectAdapter(ContractResolver, logErrorAction: null)); + ApplyTo(objectToApplyTo, new ObjectAdapter(ContractResolver, null, new AdapterFactory())); } /// @@ -183,13 +183,28 @@ namespace Microsoft.AspNetCore.JsonPatch /// Object to apply the JsonPatchDocument to /// Action to log errors public void ApplyTo(object objectToApplyTo, Action logErrorAction) + { + ApplyTo(objectToApplyTo, new ObjectAdapter(ContractResolver, logErrorAction, new AdapterFactory()), logErrorAction); + } + + /// + /// Apply this JsonPatchDocument + /// + /// Object to apply the JsonPatchDocument to + /// IObjectAdapter instance to use when applying + /// Action to log errors + public void ApplyTo(object objectToApplyTo, IObjectAdapter adapter, Action logErrorAction) { if (objectToApplyTo == null) { throw new ArgumentNullException(nameof(objectToApplyTo)); } - var adapter = new ObjectAdapter(ContractResolver, logErrorAction); + if (adapter == null) + { + throw new ArgumentNullException(nameof(adapter)); + } + foreach (var op in Operations) { try diff --git a/src/Microsoft.AspNetCore.JsonPatch/JsonPatchDocumentOfT.cs b/src/Microsoft.AspNetCore.JsonPatch/JsonPatchDocumentOfT.cs index 8ae1430185..3db0aac458 100644 --- a/src/Microsoft.AspNetCore.JsonPatch/JsonPatchDocumentOfT.cs +++ b/src/Microsoft.AspNetCore.JsonPatch/JsonPatchDocumentOfT.cs @@ -697,7 +697,7 @@ namespace Microsoft.AspNetCore.JsonPatch throw new ArgumentNullException(nameof(objectToApplyTo)); } - ApplyTo(objectToApplyTo, new ObjectAdapter(ContractResolver, logErrorAction: null)); + ApplyTo(objectToApplyTo, new ObjectAdapter(ContractResolver, null, new AdapterFactory())); } /// @@ -706,13 +706,28 @@ namespace Microsoft.AspNetCore.JsonPatch /// Object to apply the JsonPatchDocument to /// Action to log errors public void ApplyTo(TModel objectToApplyTo, Action logErrorAction) + { + ApplyTo(objectToApplyTo, new ObjectAdapter(ContractResolver, logErrorAction, new AdapterFactory()), logErrorAction); + } + + /// + /// Apply this JsonPatchDocument + /// + /// Object to apply the JsonPatchDocument to + /// IObjectAdapter instance to use when applying + /// Action to log errors + public void ApplyTo(TModel objectToApplyTo, IObjectAdapter adapter, Action logErrorAction) { if (objectToApplyTo == null) { throw new ArgumentNullException(nameof(objectToApplyTo)); } - var adapter = new ObjectAdapter(ContractResolver, logErrorAction); + if (adapter == null) + { + throw new ArgumentNullException(nameof(adapter)); + } + foreach (var op in Operations) { try diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/Adapters/AdapterFactoryTests.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/Adapters/AdapterFactoryTests.cs new file mode 100644 index 0000000000..1e961c29e9 --- /dev/null +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/Adapters/AdapterFactoryTests.cs @@ -0,0 +1,73 @@ +using Microsoft.AspNetCore.JsonPatch.Adapters; +using Microsoft.AspNetCore.JsonPatch.Internal; +using Moq; +using Newtonsoft.Json.Serialization; +using System; +using System.Collections.Generic; +using System.Dynamic; +using System.Text; +using Xunit; + +namespace Microsoft.AspNetCore.JsonPatch.Test.Adapters +{ + public class AdapterFactoryTests + { + [Fact] + public void GetListAdapterForListTargets() + { + // Arrange + AdapterFactory factory = new AdapterFactory(); + + //Act: + IAdapter adapter = factory.Create(new List(), new DefaultContractResolver()); + + // Assert + Assert.Equal(typeof(ListAdapter), adapter.GetType()); + } + + [Fact] + public void GetDictionaryAdapterForDictionaryObjects() + { + // Arrange + AdapterFactory factory = new AdapterFactory(); + + //Act: + IAdapter adapter = factory.Create(new Dictionary(), new DefaultContractResolver()); + + // Assert + Assert.Equal(typeof(DictionaryAdapter), adapter.GetType()); + } + + private class PocoModel + {} + + + [Fact] + public void GetPocoAdapterForGenericObjects() + { + // Arrange + AdapterFactory factory = new AdapterFactory(); + + //Act: + IAdapter adapter = factory.Create(new PocoModel(), new DefaultContractResolver()); + + // Assert + Assert.Equal(typeof(PocoAdapter), adapter.GetType()); + } + + + + [Fact] + public void GetDynamicAdapterForGenericObjects() + { + // Arrange + AdapterFactory factory = new AdapterFactory(); + + //Act: + IAdapter adapter = factory.Create(new TestDynamicObject(), new DefaultContractResolver()); + + // Assert + Assert.Equal(typeof(DynamicObjectAdapter), adapter.GetType()); + } + } +} diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/Adapters/TestDynamicObject.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/Adapters/TestDynamicObject.cs new file mode 100644 index 0000000000..08371f25c6 --- /dev/null +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/Adapters/TestDynamicObject.cs @@ -0,0 +1,10 @@ +using System; +using System.Collections.Generic; +using System.Dynamic; +using System.Text; + +namespace Microsoft.AspNetCore.JsonPatch.Test.Adapters +{ + public class TestDynamicObject : DynamicObject + { } +}