From 408759ec991674051d3a09560aff09ce1ad42a29 Mon Sep 17 00:00:00 2001 From: Eilon Lipton Date: Thu, 17 Sep 2015 09:36:36 -0700 Subject: [PATCH 001/221] Update LICENSE.txt --- LICENSE.txt | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 LICENSE.txt diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100644 index 0000000000..0bdc1962b6 --- /dev/null +++ b/LICENSE.txt @@ -0,0 +1,12 @@ +Copyright (c) .NET Foundation. All rights reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); you may not use +these files except in compliance with the License. You may obtain a copy of the +License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software distributed +under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +CONDITIONS OF ANY KIND, either express or implied. See the License for the +specific language governing permissions and limitations under the License. From b63d1b618710ab5e6064e013c62dc1d51aa5c877 Mon Sep 17 00:00:00 2001 From: Eilon Lipton Date: Thu, 17 Sep 2015 09:36:53 -0700 Subject: [PATCH 002/221] Create CONTRIBUTING.md --- CONTRIBUTING.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 CONTRIBUTING.md diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000000..64ff041d5c --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,4 @@ +Contributing +====== + +Information on contributing to this repo is in the [Contributing Guide](https://github.com/aspnet/Home/blob/dev/CONTRIBUTING.md) in the Home repo. From 98ce82ed72a2c8a02717c615082e3d9a4decef3e Mon Sep 17 00:00:00 2001 From: Eilon Lipton Date: Thu, 17 Sep 2015 09:41:13 -0700 Subject: [PATCH 003/221] Create README.md --- README.md | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000000..c30d38e62f --- /dev/null +++ b/README.md @@ -0,0 +1,9 @@ +JsonPatch +=== +AppVeyor: [![AppVeyor](https://ci.appveyor.com/api/projects/status/51gggjks5k3q6pr5/branch/dev?svg=true)](https://ci.appveyor.com/project/aspnetci/JsonPatch/branch/dev) + +Travis: [![Travis](https://travis-ci.org/aspnet/JsonPatch.svg?branch=dev)](https://travis-ci.org/aspnet/JsonPatch) + +This project is part of ASP.NET 5. You can find samples, documentation and getting started instructions for ASP.NET 5 at the [Home](https://github.com/aspnet/home) repo. + + From d3f2b240d752e7eb90f0510d7e0d60e6f51cf625 Mon Sep 17 00:00:00 2001 From: Ryan Nowak Date: Mon, 21 Sep 2015 10:42:05 -0700 Subject: [PATCH 004/221] Add build-template files --- .gitignore | 36 ++++++++++++++++++++++++++++++++++++ .travis.yml | 13 +++++++++++++ NuGet.config | 7 +++++++ appveyor.yml | 7 +++++++ build.cmd | 39 +++++++++++++++++++++++++++++++++++++++ build.sh | 41 +++++++++++++++++++++++++++++++++++++++++ global.json | 3 +++ makefile.shade | 12 ++++++++++++ 8 files changed, 158 insertions(+) create mode 100644 .gitignore create mode 100644 .travis.yml create mode 100644 NuGet.config create mode 100644 appveyor.yml create mode 100644 build.cmd create mode 100644 build.sh create mode 100644 global.json create mode 100644 makefile.shade diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000000..8a9bbc3a43 --- /dev/null +++ b/.gitignore @@ -0,0 +1,36 @@ +[Oo]bj/ +[Bb]in/ +TestResults/ +.nuget/ +*.sln.ide/ +_ReSharper.*/ +packages/ +artifacts/ +PublishProfiles/ +.vs/ +bower_components/ +node_modules/ +**/wwwroot/lib/ +debugSettings.json +project.lock.json +*.user +*.suo +*.cache +*.docstates +_ReSharper.* +nuget.exe +*net45.csproj +*net451.csproj +*k10.csproj +*.psess +*.vsp +*.pidb +*.userprefs +*DS_Store +*.ncrunchsolution +*.*sdf +*.ipch +.settings +*.sln.ide +node_modules +**/[Cc]ompiler/[Rr]esources/**/*.js diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000000..568e2673e9 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,13 @@ +language: csharp +sudo: false +mono: + - beta +env: + - MONO_THREADS_PER_CPU=2000 MONO_MANAGED_WATCHER=disabled +os: + - linux + - osx +before_script: + - if [ $TRAVIS_OS_NAME == "osx" ] ; then sudo sysctl -w kern.maxfiles=64000 ; sudo sysctl -w kern.maxfilesperproc=64000 ; sudo launchctl limit maxfiles 64000 64000 ; fi ; ulimit -n 64000 +script: + - ./build.sh --quiet verify \ No newline at end of file diff --git a/NuGet.config b/NuGet.config new file mode 100644 index 0000000000..52bf414192 --- /dev/null +++ b/NuGet.config @@ -0,0 +1,7 @@ + + + + + + + diff --git a/appveyor.yml b/appveyor.yml new file mode 100644 index 0000000000..58a3e1bc22 --- /dev/null +++ b/appveyor.yml @@ -0,0 +1,7 @@ +init: + - git config --global core.autocrlf true +build_script: + - build.cmd --quiet --parallel verify +clone_depth: 1 +test: off +deploy: off \ No newline at end of file diff --git a/build.cmd b/build.cmd new file mode 100644 index 0000000000..177997c42e --- /dev/null +++ b/build.cmd @@ -0,0 +1,39 @@ +@echo off +cd %~dp0 + +SETLOCAL +SET NUGET_VERSION=latest +SET CACHED_NUGET=%LocalAppData%\NuGet\nuget.%NUGET_VERSION%.exe +SET BUILDCMD_KOREBUILD_VERSION="" +SET BUILDCMD_DNX_VERSION="" + +IF EXIST %CACHED_NUGET% goto copynuget +echo Downloading latest version of NuGet.exe... +IF NOT EXIST %LocalAppData%\NuGet md %LocalAppData%\NuGet +@powershell -NoProfile -ExecutionPolicy unrestricted -Command "$ProgressPreference = 'SilentlyContinue'; Invoke-WebRequest 'https://dist.nuget.org/win-x86-commandline/%NUGET_VERSION%/nuget.exe' -OutFile '%CACHED_NUGET%'" + +:copynuget +IF EXIST .nuget\nuget.exe goto restore +md .nuget +copy %CACHED_NUGET% .nuget\nuget.exe > nul + +:restore +IF EXIST packages\KoreBuild goto run +IF %BUILDCMD_KOREBUILD_VERSION%=="" ( + .nuget\nuget.exe install KoreBuild -ExcludeVersion -o packages -nocache -pre +) ELSE ( + .nuget\nuget.exe install KoreBuild -version %BUILDCMD_KOREBUILD_VERSION% -ExcludeVersion -o packages -nocache -pre +) +.nuget\nuget.exe install Sake -ExcludeVersion -Out packages + +IF "%SKIP_DNX_INSTALL%"=="1" goto run +IF %BUILDCMD_DNX_VERSION%=="" ( + CALL packages\KoreBuild\build\dnvm upgrade -runtime CLR -arch x86 +) ELSE ( + CALL packages\KoreBuild\build\dnvm install %BUILDCMD_DNX_VERSION% -runtime CLR -arch x86 -a default +) +CALL packages\KoreBuild\build\dnvm install default -runtime CoreCLR -arch x86 + +:run +CALL packages\KoreBuild\build\dnvm use default -runtime CLR -arch x86 +packages\Sake\tools\Sake.exe -I packages\KoreBuild\build -f makefile.shade %* \ No newline at end of file diff --git a/build.sh b/build.sh new file mode 100644 index 0000000000..0c66139817 --- /dev/null +++ b/build.sh @@ -0,0 +1,41 @@ +#!/usr/bin/env bash + +if test `uname` = Darwin; then + cachedir=~/Library/Caches/KBuild +else + if [ -z $XDG_DATA_HOME ]; then + cachedir=$HOME/.local/share + else + cachedir=$XDG_DATA_HOME; + fi +fi +mkdir -p $cachedir +nugetVersion=latest +cachePath=$cachedir/nuget.$nugetVersion.exe + +url=https://dist.nuget.org/win-x86-commandline/$nugetVersion/nuget.exe + +if test ! -f $cachePath; then + wget -O $cachePath $url 2>/dev/null || curl -o $cachePath --location $url /dev/null +fi + +if test ! -e .nuget; then + mkdir .nuget + cp $cachePath .nuget/nuget.exe +fi + +if test ! -d packages/KoreBuild; then + mono .nuget/nuget.exe install KoreBuild -ExcludeVersion -o packages -nocache -pre + mono .nuget/nuget.exe install Sake -ExcludeVersion -Out packages +fi + +if ! type dnvm > /dev/null 2>&1; then + source packages/KoreBuild/build/dnvm.sh +fi + +if ! type dnx > /dev/null 2>&1; then + dnvm upgrade +fi + +mono packages/Sake/tools/Sake.exe -I packages/KoreBuild/build -f makefile.shade "$@" + diff --git a/global.json b/global.json new file mode 100644 index 0000000000..fad3dfeab0 --- /dev/null +++ b/global.json @@ -0,0 +1,3 @@ +{ + "projects": ["src", "test/WebSites", "samples"] +} diff --git a/makefile.shade b/makefile.shade new file mode 100644 index 0000000000..c87524a3ef --- /dev/null +++ b/makefile.shade @@ -0,0 +1,12 @@ + +var VERSION='0.1' +var FULL_VERSION='0.1' +var AUTHORS='Microsoft Open Technologies, Inc.' + +use-standard-lifecycle +k-standard-goals + +#xml-docs-test .clean .build-compile description='Check generated XML documentation files for errors' target='package' + k-xml-docs-test + + From e0ac69c9f79d8486357531f0ea5125bbef3c42fa Mon Sep 17 00:00:00 2001 From: Ryan Nowak Date: Mon, 21 Sep 2015 11:15:18 -0700 Subject: [PATCH 005/221] Add JsonPatch Moved from https://github.com/aspnet/Mvc --- JsonPatch.sln | 36 + NuGet.config | 2 +- .../Adapters/IObjectAdapter.cs | 19 + .../Adapters/ObjectAdapter.cs | 1105 +++++++++ .../Converters/JsonPatchDocumentConverter.cs | 76 + .../TypedJsonPatchDocumentConverter.cs | 65 + .../Exceptions/JsonPatchException.cs | 38 + .../Helpers/ActualPropertyPathResult.cs | 22 + .../Helpers/ConversionResult.cs | 17 + .../ExpandoObjectDictionaryExtensions.cs | 77 + .../Helpers/ExpressionHelpers.cs | 99 + .../Helpers/GetValueResult.cs | 30 + .../Helpers/JsonPatchProperty.cs | 43 + .../Helpers/ObjectTreeAnalyisResult.cs | 210 ++ .../Helpers/PathHelpers.cs | 31 + .../Helpers/RemovedPropertyTypeResult.cs | 38 + .../IJsonPatchDocument.cs | 16 + .../JsonPatchDocument.cs | 222 ++ .../JsonPatchDocumentOfT.cs | 700 ++++++ .../JsonPatchError.cs | 50 + .../Microsoft.AspNet.JsonPatch.xproj | 17 + .../Operations/Operation.cs | 74 + .../Operations/OperationBase.cs | 57 + .../Operations/OperationOfT.cs | 83 + .../Operations/OperationType.cs | 15 + .../Properties/AssemblyInfo.cs | 8 + .../Properties/Resources.Designer.cs | 270 +++ src/Microsoft.AspNet.JsonPatch/Resources.resx | 165 ++ src/Microsoft.AspNet.JsonPatch/project.json | 25 + .../Dynamic/AddOperationTests.cs | 569 +++++ .../Dynamic/AddTypedOperationTests.cs | 121 + .../Dynamic/CopyOperationTests.cs | 245 ++ .../Dynamic/CopyTypedOperationTests.cs | 268 +++ .../Dynamic/MoveOperationTests.cs | 338 +++ .../Dynamic/MoveTypedOperationTests.cs | 138 ++ .../Dynamic/NestedDTO.cs | 11 + .../Dynamic/PatchDocumentTests.cs | 95 + .../Dynamic/RemoveOperationTests.cs | 302 +++ .../Dynamic/RemoveTypedOperationTests.cs | 244 ++ .../Dynamic/ReplaceOperationTests.cs | 242 ++ .../Dynamic/ReplaceTypedOperationTests.cs | 191 ++ .../Dynamic/SimpleDTO.cs | 21 + .../Dynamic/SimpleDTOWithNestedDTO.cs | 22 + .../Microsoft.AspNet.JsonPatch.Test.xproj | 20 + .../NestedDTO.cs | 10 + .../NestedObjectTests.cs | 2041 +++++++++++++++++ .../ObjectAdapterTests.cs | 1737 ++++++++++++++ .../SimpleDTO.cs | 22 + .../SimpleDTOWithNestedDTO.cs | 27 + .../TestErrorLogger.cs | 15 + .../project.json | 18 + 51 files changed, 10306 insertions(+), 1 deletion(-) create mode 100644 JsonPatch.sln create mode 100644 src/Microsoft.AspNet.JsonPatch/Adapters/IObjectAdapter.cs create mode 100644 src/Microsoft.AspNet.JsonPatch/Adapters/ObjectAdapter.cs create mode 100644 src/Microsoft.AspNet.JsonPatch/Converters/JsonPatchDocumentConverter.cs create mode 100644 src/Microsoft.AspNet.JsonPatch/Converters/TypedJsonPatchDocumentConverter.cs create mode 100644 src/Microsoft.AspNet.JsonPatch/Exceptions/JsonPatchException.cs create mode 100644 src/Microsoft.AspNet.JsonPatch/Helpers/ActualPropertyPathResult.cs create mode 100644 src/Microsoft.AspNet.JsonPatch/Helpers/ConversionResult.cs create mode 100644 src/Microsoft.AspNet.JsonPatch/Helpers/ExpandoObjectDictionaryExtensions.cs create mode 100644 src/Microsoft.AspNet.JsonPatch/Helpers/ExpressionHelpers.cs create mode 100644 src/Microsoft.AspNet.JsonPatch/Helpers/GetValueResult.cs create mode 100644 src/Microsoft.AspNet.JsonPatch/Helpers/JsonPatchProperty.cs create mode 100644 src/Microsoft.AspNet.JsonPatch/Helpers/ObjectTreeAnalyisResult.cs create mode 100644 src/Microsoft.AspNet.JsonPatch/Helpers/PathHelpers.cs create mode 100644 src/Microsoft.AspNet.JsonPatch/Helpers/RemovedPropertyTypeResult.cs create mode 100644 src/Microsoft.AspNet.JsonPatch/IJsonPatchDocument.cs create mode 100644 src/Microsoft.AspNet.JsonPatch/JsonPatchDocument.cs create mode 100644 src/Microsoft.AspNet.JsonPatch/JsonPatchDocumentOfT.cs create mode 100644 src/Microsoft.AspNet.JsonPatch/JsonPatchError.cs create mode 100644 src/Microsoft.AspNet.JsonPatch/Microsoft.AspNet.JsonPatch.xproj create mode 100644 src/Microsoft.AspNet.JsonPatch/Operations/Operation.cs create mode 100644 src/Microsoft.AspNet.JsonPatch/Operations/OperationBase.cs create mode 100644 src/Microsoft.AspNet.JsonPatch/Operations/OperationOfT.cs create mode 100644 src/Microsoft.AspNet.JsonPatch/Operations/OperationType.cs create mode 100644 src/Microsoft.AspNet.JsonPatch/Properties/AssemblyInfo.cs create mode 100644 src/Microsoft.AspNet.JsonPatch/Properties/Resources.Designer.cs create mode 100644 src/Microsoft.AspNet.JsonPatch/Resources.resx create mode 100644 src/Microsoft.AspNet.JsonPatch/project.json create mode 100644 test/Microsoft.AspNet.JsonPatch.Test/Dynamic/AddOperationTests.cs create mode 100644 test/Microsoft.AspNet.JsonPatch.Test/Dynamic/AddTypedOperationTests.cs create mode 100644 test/Microsoft.AspNet.JsonPatch.Test/Dynamic/CopyOperationTests.cs create mode 100644 test/Microsoft.AspNet.JsonPatch.Test/Dynamic/CopyTypedOperationTests.cs create mode 100644 test/Microsoft.AspNet.JsonPatch.Test/Dynamic/MoveOperationTests.cs create mode 100644 test/Microsoft.AspNet.JsonPatch.Test/Dynamic/MoveTypedOperationTests.cs create mode 100644 test/Microsoft.AspNet.JsonPatch.Test/Dynamic/NestedDTO.cs create mode 100644 test/Microsoft.AspNet.JsonPatch.Test/Dynamic/PatchDocumentTests.cs create mode 100644 test/Microsoft.AspNet.JsonPatch.Test/Dynamic/RemoveOperationTests.cs create mode 100644 test/Microsoft.AspNet.JsonPatch.Test/Dynamic/RemoveTypedOperationTests.cs create mode 100644 test/Microsoft.AspNet.JsonPatch.Test/Dynamic/ReplaceOperationTests.cs create mode 100644 test/Microsoft.AspNet.JsonPatch.Test/Dynamic/ReplaceTypedOperationTests.cs create mode 100644 test/Microsoft.AspNet.JsonPatch.Test/Dynamic/SimpleDTO.cs create mode 100644 test/Microsoft.AspNet.JsonPatch.Test/Dynamic/SimpleDTOWithNestedDTO.cs create mode 100644 test/Microsoft.AspNet.JsonPatch.Test/Microsoft.AspNet.JsonPatch.Test.xproj create mode 100644 test/Microsoft.AspNet.JsonPatch.Test/NestedDTO.cs create mode 100644 test/Microsoft.AspNet.JsonPatch.Test/NestedObjectTests.cs create mode 100644 test/Microsoft.AspNet.JsonPatch.Test/ObjectAdapterTests.cs create mode 100644 test/Microsoft.AspNet.JsonPatch.Test/SimpleDTO.cs create mode 100644 test/Microsoft.AspNet.JsonPatch.Test/SimpleDTOWithNestedDTO.cs create mode 100644 test/Microsoft.AspNet.JsonPatch.Test/TestErrorLogger.cs create mode 100644 test/Microsoft.AspNet.JsonPatch.Test/project.json diff --git a/JsonPatch.sln b/JsonPatch.sln new file mode 100644 index 0000000000..01e02f3125 --- /dev/null +++ b/JsonPatch.sln @@ -0,0 +1,36 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 14 +VisualStudioVersion = 14.0.23107.0 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{430B59ED-F960-4D3A-8FFE-3370008E168D}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{36CD6341-AB44-44EB-B3AA-BF98C89FECDD}" +EndProject +Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNet.JsonPatch", "src\Microsoft.AspNet.JsonPatch\Microsoft.AspNet.JsonPatch.xproj", "{4D55F4D8-633B-462F-A5B1-FEB84BD2D534}" +EndProject +Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNet.JsonPatch.Test", "test\Microsoft.AspNet.JsonPatch.Test\Microsoft.AspNet.JsonPatch.Test.xproj", "{81C20848-E063-4E12-AC40-0B55A532C16C}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {4D55F4D8-633B-462F-A5B1-FEB84BD2D534}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4D55F4D8-633B-462F-A5B1-FEB84BD2D534}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4D55F4D8-633B-462F-A5B1-FEB84BD2D534}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4D55F4D8-633B-462F-A5B1-FEB84BD2D534}.Release|Any CPU.Build.0 = Release|Any CPU + {81C20848-E063-4E12-AC40-0B55A532C16C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {81C20848-E063-4E12-AC40-0B55A532C16C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {81C20848-E063-4E12-AC40-0B55A532C16C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {81C20848-E063-4E12-AC40-0B55A532C16C}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {4D55F4D8-633B-462F-A5B1-FEB84BD2D534} = {430B59ED-F960-4D3A-8FFE-3370008E168D} + {81C20848-E063-4E12-AC40-0B55A532C16C} = {36CD6341-AB44-44EB-B3AA-BF98C89FECDD} + EndGlobalSection +EndGlobal diff --git a/NuGet.config b/NuGet.config index 52bf414192..5500f6d507 100644 --- a/NuGet.config +++ b/NuGet.config @@ -1,4 +1,4 @@ - + diff --git a/src/Microsoft.AspNet.JsonPatch/Adapters/IObjectAdapter.cs b/src/Microsoft.AspNet.JsonPatch/Adapters/IObjectAdapter.cs new file mode 100644 index 0000000000..724dfe3f79 --- /dev/null +++ b/src/Microsoft.AspNet.JsonPatch/Adapters/IObjectAdapter.cs @@ -0,0 +1,19 @@ +// 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 Microsoft.AspNet.JsonPatch.Operations; + +namespace Microsoft.AspNet.JsonPatch.Adapters +{ + /// + /// Defines the operations that can be performed on a JSON patch document. + /// + public interface IObjectAdapter + { + void Add(Operation operation, object objectToApplyTo); + void Copy(Operation operation, object objectToApplyTo); + void Move(Operation operation, object objectToApplyTo); + void Remove(Operation operation, object objectToApplyTo); + void Replace(Operation operation, object objectToApplyTo); + } +} \ No newline at end of file diff --git a/src/Microsoft.AspNet.JsonPatch/Adapters/ObjectAdapter.cs b/src/Microsoft.AspNet.JsonPatch/Adapters/ObjectAdapter.cs new file mode 100644 index 0000000000..4640e97039 --- /dev/null +++ b/src/Microsoft.AspNet.JsonPatch/Adapters/ObjectAdapter.cs @@ -0,0 +1,1105 @@ +// 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; +using System.Collections.Generic; +using System.Reflection; +using Microsoft.AspNet.JsonPatch.Exceptions; +using Microsoft.AspNet.JsonPatch.Helpers; +using Microsoft.AspNet.JsonPatch.Operations; +using Newtonsoft.Json; +using Newtonsoft.Json.Serialization; + +namespace Microsoft.AspNet.JsonPatch.Adapters +{ + /// + public class ObjectAdapter : IObjectAdapter + { + /// + /// Initializes a new instance of . + /// + /// The . + /// The for logging . + public ObjectAdapter( + IContractResolver contractResolver, + Action logErrorAction) + { + if (contractResolver == null) + { + throw new ArgumentNullException(nameof(contractResolver)); + } + + ContractResolver = contractResolver; + LogErrorAction = logErrorAction; + } + + /// + /// Gets or sets the . + /// + public IContractResolver ContractResolver { get; } + + /// + /// Action for logging . + /// + public Action LogErrorAction { get; } + + /// + /// The "add" operation performs one of the following functions, + /// depending upon what the target location references: + /// + /// o If the target location specifies an array index, a new value is + /// inserted into the array at the specified index. + /// + /// o If the target location specifies an object member that does not + /// already exist, a new member is added to the object. + /// + /// o If the target location specifies an object member that does exist, + /// that member's value is replaced. + /// + /// The operation object MUST contain a "value" member whose content + /// specifies the value to be added. + /// + /// For example: + /// + /// { "op": "add", "path": "/a/b/c", "value": [ "foo", "bar" ] } + /// + /// When the operation is applied, the target location MUST reference one + /// of: + /// + /// o The root of the target document - whereupon the specified value + /// becomes the entire content of the target document. + /// + /// o A member to add to an existing object - whereupon the supplied + /// value is added to that object at the indicated location. If the + /// member already exists, it is replaced by the specified value. + /// + /// o An element to add to an existing array - whereupon the supplied + /// value is added to the array at the indicated location. Any + /// elements at or above the specified index are shifted one position + /// to the right. The specified index MUST NOT be greater than the + /// number of elements in the array. If the "-" character is used to + /// index the end of the array (see [RFC6901]), this has the effect of + /// appending the value to the array. + /// + /// Because this operation is designed to add to existing objects and + /// arrays, its target location will often not exist. Although the + /// pointer's error handling algorithm will thus be invoked, this + /// specification defines the error handling behavior for "add" pointers + /// to ignore that error and add the value as specified. + /// + /// However, the object itself or an array containing it does need to + /// exist, and it remains an error for that not to be the case. For + /// example, an "add" with a target location of "/a/b" starting with this + /// document: + /// + /// { "a": { "foo": 1 } } + /// + /// is not an error, because "a" exists, and "b" will be added to its + /// value. It is an error in this document: + /// + /// { "q": { "bar": 2 } } + /// + /// because "a" does not exist. + /// + /// The add operation. + /// Object to apply the operation to. + public void Add(Operation operation, object objectToApplyTo) + { + if (operation == null) + { + throw new ArgumentNullException(nameof(operation)); + } + + if (objectToApplyTo == null) + { + throw new ArgumentNullException(nameof(objectToApplyTo)); + } + + Add(operation.path, operation.value, objectToApplyTo, operation); + } + + /// + /// Add is used by various operations (eg: add, copy, ...), yet through different operations; + /// This method allows code reuse yet reporting the correct operation on error + /// + private void Add( + string path, + object value, + object objectToApplyTo, + Operation operationToReport) + { + if (path == null) + { + throw new ArgumentNullException(nameof(path)); + } + + if (objectToApplyTo == null) + { + throw new ArgumentNullException(nameof(objectToApplyTo)); + } + + if (operationToReport == null) + { + throw new ArgumentNullException(nameof(operationToReport)); + } + + // first up: if the path ends in a numeric value, we're inserting in a list and + // that value represents the position; if the path ends in "-", we're appending + // to the list. + + // get path result + var pathResult = GetActualPropertyPath( + path, + objectToApplyTo, + operationToReport); + if (pathResult == null) + { + return; + } + + var appendList = pathResult.ExecuteAtEnd; + var positionAsInteger = pathResult.NumericEnd; + var actualPathToProperty = pathResult.PathToProperty; + + var treeAnalysisResult = new ObjectTreeAnalysisResult( + objectToApplyTo, + actualPathToProperty, + ContractResolver); + + if (!treeAnalysisResult.IsValidPathForAdd) + { + LogError(new JsonPatchError( + objectToApplyTo, + operationToReport, + Resources.FormatPropertyCannotBeAdded(path))); + return; + } + + if (treeAnalysisResult.UseDynamicLogic) + { + var container = treeAnalysisResult.Container; + if (container.ContainsCaseInsensitiveKey(treeAnalysisResult.PropertyPathInParent)) + { + // Existing property. + // If it's not an array, we need to check if the value fits the property type + // + // If it's an array, we need to check if the value fits in that array type, + // and add it at the correct position (if allowed). + if (appendList || positionAsInteger > -1) + { + // get the actual type + var propertyValue = container.GetValueForCaseInsensitiveKey(treeAnalysisResult.PropertyPathInParent); + var typeOfPathProperty = propertyValue.GetType(); + + if (!IsNonStringArray(typeOfPathProperty)) + { + LogError(new JsonPatchError( + objectToApplyTo, + operationToReport, + Resources.FormatInvalidIndexForArrayProperty(operationToReport.op, path))); + return; + } + + // now, get the generic type of the enumerable + var genericTypeOfArray = GetIListType(typeOfPathProperty); + var conversionResult = ConvertToActualType(genericTypeOfArray, value); + if (!conversionResult.CanBeConverted) + { + LogError(new JsonPatchError( + objectToApplyTo, + operationToReport, + Resources.FormatInvalidValueForProperty(value, path))); + return; + } + + // get value (it can be cast, we just checked that) + var array = treeAnalysisResult.Container.GetValueForCaseInsensitiveKey( + treeAnalysisResult.PropertyPathInParent) as IList; + + if (appendList) + { + array.Add(conversionResult.ConvertedInstance); + treeAnalysisResult.Container.SetValueForCaseInsensitiveKey( + treeAnalysisResult.PropertyPathInParent, array); + } + else + { + // specified index must not be greater than + // the amount of items in the array + if (positionAsInteger > array.Count) + { + LogError(new JsonPatchError( + objectToApplyTo, + operationToReport, + Resources.FormatInvalidIndexForArrayProperty( + operationToReport.op, + path))); + return; + } + + array.Insert(positionAsInteger, conversionResult.ConvertedInstance); + treeAnalysisResult.Container.SetValueForCaseInsensitiveKey( + treeAnalysisResult.PropertyPathInParent, array); + } + } + else + { + // get the actual type + var typeOfPathProperty = treeAnalysisResult.Container + .GetValueForCaseInsensitiveKey(treeAnalysisResult.PropertyPathInParent).GetType(); + + // can the value be converted to the actual type? + var conversionResult = ConvertToActualType(typeOfPathProperty, value); + if (conversionResult.CanBeConverted) + { + treeAnalysisResult.Container.SetValueForCaseInsensitiveKey( + treeAnalysisResult.PropertyPathInParent, + conversionResult.ConvertedInstance); + } + else + { + LogError(new JsonPatchError( + objectToApplyTo, + operationToReport, + Resources.FormatInvalidValueForProperty(conversionResult.ConvertedInstance, path))); + return; + } + } + } + else + { + // New property - add it. + treeAnalysisResult.Container.Add(treeAnalysisResult.PropertyPathInParent, value); + } + } + else + { + // If it's an array, add to that array. If it's not, we replace. + + // is the path an array (but not a string (= char[]))? In this case, + // the path must end with "/position" or "/-", which we already determined before. + + var patchProperty = treeAnalysisResult.JsonPatchProperty; + + if (appendList || positionAsInteger > -1) + { + if (!IsNonStringArray(patchProperty.Property.PropertyType)) + { + LogError(new JsonPatchError( + objectToApplyTo, + operationToReport, + Resources.FormatInvalidIndexForArrayProperty(operationToReport.op, path))); + return; + } + + // now, get the generic type of the IList<> from Property type. + var genericTypeOfArray = GetIListType(patchProperty.Property.PropertyType); + var conversionResult = ConvertToActualType(genericTypeOfArray, value); + if (!conversionResult.CanBeConverted) + { + LogError(new JsonPatchError( + objectToApplyTo, + operationToReport, + Resources.FormatInvalidValueForProperty(conversionResult.ConvertedInstance, path))); + return; + } + + if (!patchProperty.Property.Readable) + { + LogError(new JsonPatchError( + objectToApplyTo, + operationToReport, + Resources.FormatCannotReadProperty(path))); + return; + } + + var array = (IList)patchProperty.Property.ValueProvider.GetValue(patchProperty.Parent); + if (appendList) + { + array.Add(conversionResult.ConvertedInstance); + } + else if (positionAsInteger <= array.Count) + { + array.Insert(positionAsInteger, conversionResult.ConvertedInstance); + } + else + { + LogError(new JsonPatchError( + objectToApplyTo, + operationToReport, + Resources.FormatInvalidIndexForArrayProperty(operationToReport.op, path))); + return; + } + } + else + { + var conversionResultTuple = ConvertToActualType( + patchProperty.Property.PropertyType, + value); + + if (!conversionResultTuple.CanBeConverted) + { + LogError(new JsonPatchError( + objectToApplyTo, + operationToReport, + Resources.FormatInvalidValueForProperty(value, path))); + return; + } + + if (!patchProperty.Property.Writable) + { + LogError(new JsonPatchError( + objectToApplyTo, + operationToReport, + Resources.FormatCannotUpdateProperty(path))); + return; + } + + patchProperty.Property.ValueProvider.SetValue( + patchProperty.Parent, + conversionResultTuple.ConvertedInstance); + } + } + } + + /// + /// The "move" operation removes the value at a specified location and + /// adds it to the target location. + /// + /// The operation object MUST contain a "from" member, which is a string + /// containing a JSON Pointer value that references the location in the + /// target document to move the value from. + /// + /// The "from" location MUST exist for the operation to be successful. + /// + /// For example: + /// + /// { "op": "move", "from": "/a/b/c", "path": "/a/b/d" } + /// + /// This operation is functionally identical to a "remove" operation on + /// the "from" location, followed immediately by an "add" operation at + /// the target location with the value that was just removed. + /// + /// The "from" location MUST NOT be a proper prefix of the "path" + /// location; i.e., a location cannot be moved into one of its children. + /// + /// The move operation. + /// Object to apply the operation to. + public void Move(Operation operation, object objectToApplyTo) + { + if (operation == null) + { + throw new ArgumentNullException(nameof(operation)); + } + + if (objectToApplyTo == null) + { + throw new ArgumentNullException(nameof(objectToApplyTo)); + } + + var valueAtFromLocationResult = GetValueAtLocation(operation.from, objectToApplyTo, operation); + + if (valueAtFromLocationResult.HasError) + { + // Error has already been logged in GetValueAtLocation. We + // must return, because remove / add should not be allowed to continue + return; + } + + // remove that value + var removeResult = Remove(operation.from, objectToApplyTo, operation); + + if (removeResult.HasError) + { + // Return => error has already been logged in remove method. We must + // return, because add should not be allowed to continue + return; + } + + // add that value to the path location + Add(operation.path, + valueAtFromLocationResult.PropertyValue, + objectToApplyTo, + operation); + } + + /// + /// The "remove" operation removes the value at the target location. + /// + /// The target location MUST exist for the operation to be successful. + /// + /// For example: + /// + /// { "op": "remove", "path": "/a/b/c" } + /// + /// If removing an element from an array, any elements above the + /// specified index are shifted one position to the left. + /// + /// The remove operation. + /// Object to apply the operation to. + public void Remove(Operation operation, object objectToApplyTo) + { + if (operation == null) + { + throw new ArgumentNullException(nameof(operation)); + } + + if (objectToApplyTo == null) + { + throw new ArgumentNullException(nameof(objectToApplyTo)); + } + + Remove(operation.path, objectToApplyTo, operation); + } + + + /// + /// Remove is used by various operations (eg: remove, move, ...), yet through different operations; + /// This method allows code reuse yet reporting the correct operation on error. The return value + /// contains the type of the item that has been removed (and a bool possibly signifying an error) + /// This can be used by other methods, like replace, to ensure that we can pass in the correctly + /// typed value to whatever method follows. + /// + private RemovedPropertyTypeResult Remove(string path, object objectToApplyTo, Operation operationToReport) + { + // get path result + var pathResult = GetActualPropertyPath( + path, + objectToApplyTo, + operationToReport); + + if (pathResult == null) + { + return new RemovedPropertyTypeResult(null, true); + } + + var removeFromList = pathResult.ExecuteAtEnd; + var positionAsInteger = pathResult.NumericEnd; + var actualPathToProperty = pathResult.PathToProperty; + + var treeAnalysisResult = new ObjectTreeAnalysisResult( + objectToApplyTo, + actualPathToProperty, + ContractResolver); + + if (!treeAnalysisResult.IsValidPathForRemove) + { + LogError(new JsonPatchError( + objectToApplyTo, + operationToReport, + Resources.FormatPropertyCannotBeRemoved(path))); + return new RemovedPropertyTypeResult(null, true); + } + + if (treeAnalysisResult.UseDynamicLogic) + { + // if it's not an array, we can remove the property from + // the dictionary. If it's an array, we need to check the position first. + if (removeFromList || positionAsInteger > -1) + { + var propertyValue = treeAnalysisResult.Container + .GetValueForCaseInsensitiveKey(treeAnalysisResult.PropertyPathInParent); + + // we cannot continue when the value is null, because to be able to + // continue we need to be able to check if the array is a non-string array + if (propertyValue == null) + { + LogError(new JsonPatchError( + objectToApplyTo, + operationToReport, + Resources.FormatCannotDeterminePropertyType(path))); + return new RemovedPropertyTypeResult(null, true); + } + + var typeOfPathProperty = propertyValue.GetType(); + + if (!IsNonStringArray(typeOfPathProperty)) + { + LogError(new JsonPatchError( + objectToApplyTo, + operationToReport, + Resources.FormatInvalidIndexForArrayProperty(operationToReport.op, path))); + return new RemovedPropertyTypeResult(null, true); + } + + // now, get the generic type of the enumerable (we'll return this type) + var genericTypeOfArray = GetIListType(typeOfPathProperty); + + // get the array + var array = (IList)treeAnalysisResult.Container.GetValueForCaseInsensitiveKey( + treeAnalysisResult.PropertyPathInParent); + + if (array.Count == 0) + { + // if the array is empty, we should throw an error + LogError(new JsonPatchError( + objectToApplyTo, + operationToReport, + Resources.FormatInvalidIndexForArrayProperty( + operationToReport.op, + path))); + return new RemovedPropertyTypeResult(null, true); + } + + if (removeFromList) + { + array.RemoveAt(array.Count - 1); + treeAnalysisResult.Container.SetValueForCaseInsensitiveKey( + treeAnalysisResult.PropertyPathInParent, array); + + // return the type of the value that has been removed. + return new RemovedPropertyTypeResult(genericTypeOfArray, false); + } + else + { + if (positionAsInteger >= array.Count) + { + LogError(new JsonPatchError( + objectToApplyTo, + operationToReport, + Resources.FormatInvalidIndexForArrayProperty( + operationToReport.op, + path))); + return new RemovedPropertyTypeResult(null, true); + } + + array.RemoveAt(positionAsInteger); + treeAnalysisResult.Container.SetValueForCaseInsensitiveKey( + treeAnalysisResult.PropertyPathInParent, array); + + // return the type of the value that has been removed. + return new RemovedPropertyTypeResult(genericTypeOfArray, false); + } + } + else + { + // get the property + var getResult = treeAnalysisResult.Container.GetValueForCaseInsensitiveKey( + treeAnalysisResult.PropertyPathInParent); + + // remove the property + treeAnalysisResult.Container.RemoveValueForCaseInsensitiveKey( + treeAnalysisResult.PropertyPathInParent); + + // value is not null, we can determine the type + if (getResult != null) + { + var actualType = getResult.GetType(); + return new RemovedPropertyTypeResult(actualType, false); + } + else + { + return new RemovedPropertyTypeResult(null, false); + } + } + } + else + { + // not dynamic + var patchProperty = treeAnalysisResult.JsonPatchProperty; + + if (removeFromList || positionAsInteger > -1) + { + if (!IsNonStringArray(patchProperty.Property.PropertyType)) + { + LogError(new JsonPatchError( + objectToApplyTo, + operationToReport, + Resources.FormatInvalidIndexForArrayProperty(operationToReport.op, path))); + return new RemovedPropertyTypeResult(null, true); + } + + // now, get the generic type of the IList<> from Property type. + var genericTypeOfArray = GetIListType(patchProperty.Property.PropertyType); + + if (!patchProperty.Property.Readable) + { + LogError(new JsonPatchError( + objectToApplyTo, + operationToReport, + Resources.FormatCannotReadProperty(path))); + return new RemovedPropertyTypeResult(null, true); + } + + var array = (IList)patchProperty.Property.ValueProvider + .GetValue(patchProperty.Parent); + + if (array.Count == 0) + { + // if the array is empty, we should throw an error + LogError(new JsonPatchError( + objectToApplyTo, + operationToReport, + Resources.FormatInvalidIndexForArrayProperty( + operationToReport.op, + path))); + return new RemovedPropertyTypeResult(null, true); + } + + if (removeFromList) + { + array.RemoveAt(array.Count - 1); + + // return the type of the value that has been removed + return new RemovedPropertyTypeResult(genericTypeOfArray, false); + } + else + { + if (positionAsInteger >= array.Count) + { + LogError(new JsonPatchError( + objectToApplyTo, + operationToReport, + Resources.FormatInvalidIndexForArrayProperty( + operationToReport.op, + path))); + return new RemovedPropertyTypeResult(null, true); + } + + array.RemoveAt(positionAsInteger); + + // return the type of the value that has been removed + return new RemovedPropertyTypeResult(genericTypeOfArray, false); + } + } + else + { + if (!patchProperty.Property.Writable) + { + LogError(new JsonPatchError( + objectToApplyTo, + operationToReport, + Resources.FormatCannotUpdateProperty(path))); + return new RemovedPropertyTypeResult(null, true); + } + + // 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 (patchProperty.Property.PropertyType.GetTypeInfo().IsValueType + && Nullable.GetUnderlyingType(patchProperty.Property.PropertyType) == null) + { + value = Activator.CreateInstance(patchProperty.Property.PropertyType); + } + + patchProperty.Property.ValueProvider.SetValue(patchProperty.Parent, value); + return new RemovedPropertyTypeResult(patchProperty.Property.PropertyType, false); + } + } + } + + /// + /// The "replace" operation replaces the value at the target location + /// with a new value. The operation object MUST contain a "value" member + /// whose content specifies the replacement value. + /// + /// The target location MUST exist for the operation to be successful. + /// + /// For example: + /// + /// { "op": "replace", "path": "/a/b/c", "value": 42 } + /// + /// This operation is functionally identical to a "remove" operation for + /// a value, followed immediately by an "add" operation at the same + /// location with the replacement value. + /// + /// Note: even though it's the same functionally, we do not call remove + add + /// for performance reasons (multiple checks of same requirements). + /// + /// The replace operation. + /// Object to apply the operation to. + public void Replace(Operation operation, object objectToApplyTo) + { + if (operation == null) + { + throw new ArgumentNullException(nameof(operation)); + } + + if (objectToApplyTo == null) + { + throw new ArgumentNullException(nameof(objectToApplyTo)); + } + + var removeResult = Remove(operation.path, objectToApplyTo, operation); + + if (removeResult.HasError) + { + // return => error has already been logged in remove method + return; + } + + if (!removeResult.HasError && removeResult.ActualType == null) + { + // the remove operation completed succesfully, but we could not determine the type. + LogError(new JsonPatchError( + objectToApplyTo, + operation, + Resources.FormatCannotDeterminePropertyType(operation.from))); + return; + } + + var conversionResult = ConvertToActualType(removeResult.ActualType, operation.value); + + if (!conversionResult.CanBeConverted) + { + // invalid value for path + LogError(new JsonPatchError( + objectToApplyTo, + operation, + Resources.FormatInvalidValueForProperty(operation.value, operation.path))); + return; + } + + Add(operation.path, conversionResult.ConvertedInstance, objectToApplyTo, operation); + } + + /// + /// The "copy" operation copies the value at a specified location to the + /// target location. + /// + /// The operation object MUST contain a "from" member, which is a string + /// containing a JSON Pointer value that references the location in the + /// target document to copy the value from. + /// + /// The "from" location MUST exist for the operation to be successful. + /// + /// For example: + /// + /// { "op": "copy", "from": "/a/b/c", "path": "/a/b/e" } + /// + /// This operation is functionally identical to an "add" operation at the + /// target location using the value specified in the "from" member. + /// + /// Note: even though it's the same functionally, we do not call add with + /// the value specified in from for performance reasons (multiple checks of same requirements). + /// + /// The copy operation. + /// Object to apply the operation to. + public void Copy(Operation operation, object objectToApplyTo) + { + if (operation == null) + { + throw new ArgumentNullException(nameof(operation)); + } + + if (objectToApplyTo == null) + { + throw new ArgumentNullException(nameof(objectToApplyTo)); + } + + // get value at from location and add that value to the path location + var valueAtFromLocationResult = GetValueAtLocation(operation.from, objectToApplyTo, operation); + + if (valueAtFromLocationResult.HasError) + { + // Return, error has already been logged in GetValueAtLocation + return; + } + + Add(operation.path, + valueAtFromLocationResult.PropertyValue, + objectToApplyTo, + operation); + } + + /// + /// Method is used by Copy and Move to avoid duplicate code + /// + /// Location where value should be + /// Object to inspect for the desired value + /// Operation to report in case of an error + /// GetValueResult containing value and a bool signifying a possible error + private GetValueResult GetValueAtLocation( + string location, + object objectToGetValueFrom, + Operation operationToReport) + { + if (location == null) + { + throw new ArgumentNullException(nameof(location)); + } + + if (objectToGetValueFrom == null) + { + throw new ArgumentNullException(nameof(objectToGetValueFrom)); + } + + if (operationToReport == null) + { + throw new ArgumentNullException(nameof(operationToReport)); + } + + // get path result + var pathResult = GetActualPropertyPath( + location, + objectToGetValueFrom, + operationToReport); + + if (pathResult == null) + { + return new GetValueResult(null, true); + } + + var getAtEndOfList = pathResult.ExecuteAtEnd; + var positionAsInteger = pathResult.NumericEnd; + var actualPathToProperty = pathResult.PathToProperty; + + var treeAnalysisResult = new ObjectTreeAnalysisResult( + objectToGetValueFrom, + actualPathToProperty, + ContractResolver); + + if (treeAnalysisResult.UseDynamicLogic) + { + // if it's not an array, we can remove the property from + // the dictionary. If it's an array, we need to check the position first. + if (getAtEndOfList || positionAsInteger > -1) + { + var propertyValue = treeAnalysisResult.Container + .GetValueForCaseInsensitiveKey(treeAnalysisResult.PropertyPathInParent); + + // we cannot continue when the value is null, because to be able to + // continue we need to be able to check if the array is a non-string array + if (propertyValue == null) + { + LogError(new JsonPatchError( + objectToGetValueFrom, + operationToReport, + Resources.FormatCannotDeterminePropertyType(location))); + return new GetValueResult(null, true); + } + + var typeOfPathProperty = propertyValue.GetType(); + + if (!IsNonStringArray(typeOfPathProperty)) + { + LogError(new JsonPatchError( + objectToGetValueFrom, + operationToReport, + Resources.FormatInvalidIndexForArrayProperty(operationToReport.op, location))); + return new GetValueResult(null, true); + } + + // get the array + var array = (IList)treeAnalysisResult.Container.GetValueForCaseInsensitiveKey( + treeAnalysisResult.PropertyPathInParent); + + if (positionAsInteger >= array.Count) + { + LogError(new JsonPatchError( + objectToGetValueFrom, + operationToReport, + Resources.FormatInvalidIndexForArrayProperty( + operationToReport.op, + location))); + return new GetValueResult(null, true); + } + + if (getAtEndOfList) + { + return new GetValueResult(array[array.Count - 1], false); + } + else + { + return new GetValueResult(array[positionAsInteger], false); + } + } + else + { + // get the property + var propertyValueAtLocation = treeAnalysisResult.Container.GetValueForCaseInsensitiveKey( + treeAnalysisResult.PropertyPathInParent); + + return new GetValueResult(propertyValueAtLocation, false); + } + } + else + { + // not dynamic + var patchProperty = treeAnalysisResult.JsonPatchProperty; + + if (getAtEndOfList || positionAsInteger > -1) + { + if (!IsNonStringArray(patchProperty.Property.PropertyType)) + { + LogError(new JsonPatchError( + objectToGetValueFrom, + operationToReport, + Resources.FormatInvalidIndexForArrayProperty(operationToReport.op, location))); + return new GetValueResult(null, true); + } + + if (!patchProperty.Property.Readable) + { + LogError(new JsonPatchError( + objectToGetValueFrom, + operationToReport, + Resources.FormatCannotReadProperty(location))); + return new GetValueResult(null, true); + } + + var array = (IList)patchProperty.Property.ValueProvider + .GetValue(patchProperty.Parent); + + if (positionAsInteger >= array.Count) + { + LogError(new JsonPatchError( + objectToGetValueFrom, + operationToReport, + Resources.FormatInvalidIndexForArrayProperty( + operationToReport.op, + location))); + return new GetValueResult(null, true); + } + + if (getAtEndOfList) + { + return new GetValueResult(array[array.Count - 1], false); + } + else + { + return new GetValueResult(array[positionAsInteger], false); + } + } + else + { + if (!patchProperty.Property.Readable) + { + LogError(new JsonPatchError( + objectToGetValueFrom, + operationToReport, + Resources.FormatCannotReadProperty( + location))); + return new GetValueResult(null, true); + } + + var propertyValueAtLocation = patchProperty.Property.ValueProvider + .GetValue(patchProperty.Parent); + + return new GetValueResult(propertyValueAtLocation, false); + } + } + } + + private bool IsNonStringArray(Type type) + { + if (GetIListType(type) != null) + { + return true; + } + + return (!(type == typeof(string)) && typeof(IList).GetTypeInfo().IsAssignableFrom(type.GetTypeInfo())); + } + + private void LogError(JsonPatchError jsonPatchError) + { + if (LogErrorAction != null) + { + LogErrorAction(jsonPatchError); + } + else + { + throw new JsonPatchException(jsonPatchError); + } + } + + private ConversionResult ConvertToActualType(Type propertyType, object value) + { + try + { + var o = JsonConvert.DeserializeObject(JsonConvert.SerializeObject(value), propertyType); + + return new ConversionResult(true, o); + } + catch (Exception) + { + return new ConversionResult(false, null); + } + } + + private Type GetIListType(Type type) + { + if (IsGenericListType(type)) + { + return type.GetGenericArguments()[0]; + } + + foreach (Type interfaceType in type.GetTypeInfo().ImplementedInterfaces) + { + if (IsGenericListType(interfaceType)) + { + return interfaceType.GetGenericArguments()[0]; + } + } + + return null; + } + + private bool IsGenericListType(Type type) + { + if (type.GetTypeInfo().IsGenericType && + type.GetGenericTypeDefinition() == typeof(IList<>)) + { + return true; + } + + return false; + } + + private ActualPropertyPathResult GetActualPropertyPath( + string propertyPath, + object objectToApplyTo, + Operation operationToReport) + { + if (propertyPath == null) + { + throw new ArgumentNullException(nameof(propertyPath)); + } + + if (objectToApplyTo == null) + { + throw new ArgumentNullException(nameof(objectToApplyTo)); + } + + if (operationToReport == null) + { + throw new ArgumentNullException(nameof(operationToReport)); + } + + if (propertyPath.EndsWith("/-")) + { + return new ActualPropertyPathResult(-1, propertyPath.Substring(0, propertyPath.Length - 2), true); + } + else + { + var possibleIndex = propertyPath.Substring(propertyPath.LastIndexOf("/") + 1); + int castedIndex = -1; + if (int.TryParse(possibleIndex, out castedIndex)) + { + // has numeric end. + if (castedIndex > -1) + { + var pathToProperty = propertyPath.Substring( + 0, + propertyPath.LastIndexOf('/' + castedIndex.ToString())); + + return new ActualPropertyPathResult(castedIndex, pathToProperty, false); + } + else + { + // negative position - invalid path + LogError(new JsonPatchError( + objectToApplyTo, + operationToReport, + Resources.FormatNegativeIndexForArrayProperty(operationToReport.op, propertyPath))); + return null; + } + } + + return new ActualPropertyPathResult(-1, propertyPath, false); + } + } + } +} \ No newline at end of file diff --git a/src/Microsoft.AspNet.JsonPatch/Converters/JsonPatchDocumentConverter.cs b/src/Microsoft.AspNet.JsonPatch/Converters/JsonPatchDocumentConverter.cs new file mode 100644 index 0000000000..4551f64043 --- /dev/null +++ b/src/Microsoft.AspNet.JsonPatch/Converters/JsonPatchDocumentConverter.cs @@ -0,0 +1,76 @@ +// 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 Microsoft.AspNet.JsonPatch.Exceptions; +using Microsoft.AspNet.JsonPatch.Operations; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; +using Newtonsoft.Json.Serialization; + +namespace Microsoft.AspNet.JsonPatch.Converters +{ + public class JsonPatchDocumentConverter : JsonConverter + { + public override bool CanConvert(Type objectType) + { + return true; + } + + public override object ReadJson(JsonReader reader, Type objectType, object existingValue, + JsonSerializer serializer) + { + if (objectType != typeof(JsonPatchDocument)) + { + throw new ArgumentException(Resources.FormatParameterMustMatchType("objectType", "JsonPatchDocument"), "objectType"); + } + + try + { + if (reader.TokenType == JsonToken.Null) + { + return null; + } + + // load jObject + var jObject = JArray.Load(reader); + + // Create target object for Json => list of operations + var targetOperations = new List(); + + // Create a new reader for this jObject, and set all properties + // to match the original reader. + var jObjectReader = jObject.CreateReader(); + jObjectReader.Culture = reader.Culture; + jObjectReader.DateParseHandling = reader.DateParseHandling; + jObjectReader.DateTimeZoneHandling = reader.DateTimeZoneHandling; + jObjectReader.FloatParseHandling = reader.FloatParseHandling; + + // Populate the object properties + serializer.Populate(jObjectReader, targetOperations); + + // container target: the JsonPatchDocument. + var container = new JsonPatchDocument(targetOperations, new DefaultContractResolver()); + + return container; + } + catch (Exception ex) + { + throw new JsonPatchException(Resources.FormatInvalidJsonPatchDocument(objectType.Name), ex); + } + } + + public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) + { + if (value is IJsonPatchDocument) + { + var jsonPatchDoc = (IJsonPatchDocument)value; + var lst = jsonPatchDoc.GetOperations(); + + // write out the operations, no envelope + serializer.Serialize(writer, lst); + } + } + } +} diff --git a/src/Microsoft.AspNet.JsonPatch/Converters/TypedJsonPatchDocumentConverter.cs b/src/Microsoft.AspNet.JsonPatch/Converters/TypedJsonPatchDocumentConverter.cs new file mode 100644 index 0000000000..7b6bb77e17 --- /dev/null +++ b/src/Microsoft.AspNet.JsonPatch/Converters/TypedJsonPatchDocumentConverter.cs @@ -0,0 +1,65 @@ +// 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 Microsoft.AspNet.JsonPatch.Exceptions; +using Microsoft.AspNet.JsonPatch.Operations; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; +using Newtonsoft.Json.Serialization; + +namespace Microsoft.AspNet.JsonPatch.Converters +{ + public class TypedJsonPatchDocumentConverter : JsonPatchDocumentConverter + { + public override object ReadJson( + JsonReader reader, + Type objectType, + object existingValue, + JsonSerializer serializer) + { + try + { + if (reader.TokenType == JsonToken.Null) + { + return null; + } + + var genericType = objectType.GetGenericArguments()[0]; + + // load jObject + var jObject = JArray.Load(reader); + + // Create target object for Json => list of operations, typed to genericType + var genericOperation = typeof(Operation<>); + var concreteOperationType = genericOperation.MakeGenericType(genericType); + + var genericList = typeof(List<>); + var concreteList = genericList.MakeGenericType(concreteOperationType); + + var targetOperations = Activator.CreateInstance(concreteList); + + //Create a new reader for this jObject, and set all properties to match the original reader. + var jObjectReader = jObject.CreateReader(); + jObjectReader.Culture = reader.Culture; + jObjectReader.DateParseHandling = reader.DateParseHandling; + jObjectReader.DateTimeZoneHandling = reader.DateTimeZoneHandling; + jObjectReader.FloatParseHandling = reader.FloatParseHandling; + + // Populate the object properties + serializer.Populate(jObjectReader, targetOperations); + + // container target: the typed JsonPatchDocument. + var container = Activator.CreateInstance(objectType, targetOperations, new DefaultContractResolver()); + + return container; + } + catch (Exception ex) + { + throw new JsonPatchException(Resources.FormatInvalidJsonPatchDocument(objectType.Name), ex); + } + } + } +} \ No newline at end of file diff --git a/src/Microsoft.AspNet.JsonPatch/Exceptions/JsonPatchException.cs b/src/Microsoft.AspNet.JsonPatch/Exceptions/JsonPatchException.cs new file mode 100644 index 0000000000..ac5222a2bb --- /dev/null +++ b/src/Microsoft.AspNet.JsonPatch/Exceptions/JsonPatchException.cs @@ -0,0 +1,38 @@ +// 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 Microsoft.AspNet.JsonPatch.Operations; + +namespace Microsoft.AspNet.JsonPatch.Exceptions +{ + public class JsonPatchException : Exception + { + public Operation FailedOperation { get; private set; } + public object AffectedObject { get; private set; } + + + public JsonPatchException() + { + + } + + public JsonPatchException(JsonPatchError jsonPatchError, Exception innerException) + : base(jsonPatchError.ErrorMessage, innerException) + { + FailedOperation = jsonPatchError.Operation; + AffectedObject = jsonPatchError.AffectedObject; + } + + public JsonPatchException(JsonPatchError jsonPatchError) + : this(jsonPatchError, null) + { + } + + public JsonPatchException(string message, Exception innerException) + : base (message, innerException) + { + + } + } +} \ No newline at end of file diff --git a/src/Microsoft.AspNet.JsonPatch/Helpers/ActualPropertyPathResult.cs b/src/Microsoft.AspNet.JsonPatch/Helpers/ActualPropertyPathResult.cs new file mode 100644 index 0000000000..d22d1bf830 --- /dev/null +++ b/src/Microsoft.AspNet.JsonPatch/Helpers/ActualPropertyPathResult.cs @@ -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. + +namespace Microsoft.AspNet.JsonPatch.Helpers +{ + internal class ActualPropertyPathResult + { + public int NumericEnd { get; private set; } + public string PathToProperty { get; set; } + public bool ExecuteAtEnd { get; set; } + + public ActualPropertyPathResult( + int numericEnd, + string pathToProperty, + bool executeAtEnd) + { + NumericEnd = numericEnd; + PathToProperty = pathToProperty; + ExecuteAtEnd = executeAtEnd; + } + } +} diff --git a/src/Microsoft.AspNet.JsonPatch/Helpers/ConversionResult.cs b/src/Microsoft.AspNet.JsonPatch/Helpers/ConversionResult.cs new file mode 100644 index 0000000000..aba4913f2d --- /dev/null +++ b/src/Microsoft.AspNet.JsonPatch/Helpers/ConversionResult.cs @@ -0,0 +1,17 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +namespace Microsoft.AspNet.JsonPatch.Helpers +{ + internal class ConversionResult + { + public bool CanBeConverted { get; private set; } + public object ConvertedInstance { get; private set; } + + public ConversionResult(bool canBeConverted, object convertedInstance) + { + CanBeConverted = canBeConverted; + ConvertedInstance = convertedInstance; + } + } +} \ No newline at end of file diff --git a/src/Microsoft.AspNet.JsonPatch/Helpers/ExpandoObjectDictionaryExtensions.cs b/src/Microsoft.AspNet.JsonPatch/Helpers/ExpandoObjectDictionaryExtensions.cs new file mode 100644 index 0000000000..a5911dded2 --- /dev/null +++ b/src/Microsoft.AspNet.JsonPatch/Helpers/ExpandoObjectDictionaryExtensions.cs @@ -0,0 +1,77 @@ +// 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; + +namespace Microsoft.AspNet.JsonPatch.Helpers +{ + // Helper methods to allow case-insensitive key search + internal static class ExpandoObjectDictionaryExtensions + { + internal static void SetValueForCaseInsensitiveKey( + this IDictionary propertyDictionary, + string key, + object value) + { + foreach (KeyValuePair kvp in propertyDictionary) + { + if (string.Equals(kvp.Key, key, StringComparison.OrdinalIgnoreCase)) + { + propertyDictionary[kvp.Key] = value; + break; + } + } + } + + internal static void RemoveValueForCaseInsensitiveKey( + this IDictionary propertyDictionary, + string key) + { + string realKey = null; + foreach (KeyValuePair kvp in propertyDictionary) + { + if (string.Equals(kvp.Key, key, StringComparison.OrdinalIgnoreCase)) + { + realKey = kvp.Key; + break; + } + } + + if (realKey != null) + { + propertyDictionary.Remove(realKey); + } + } + + internal static object GetValueForCaseInsensitiveKey( + this IDictionary propertyDictionary, + string key) + { + foreach (KeyValuePair kvp in propertyDictionary) + { + if (string.Equals(kvp.Key, key, StringComparison.OrdinalIgnoreCase)) + { + return kvp.Value; + } + } + + throw new ArgumentException(Resources.FormatDictionaryKeyNotFound(key)); + } + + internal static bool ContainsCaseInsensitiveKey( + this IDictionary propertyDictionary, + string key) + { + foreach (KeyValuePair kvp in propertyDictionary) + { + if (string.Equals(kvp.Key, key, StringComparison.OrdinalIgnoreCase)) + { + return true; + } + } + + return false; + } + } +} diff --git a/src/Microsoft.AspNet.JsonPatch/Helpers/ExpressionHelpers.cs b/src/Microsoft.AspNet.JsonPatch/Helpers/ExpressionHelpers.cs new file mode 100644 index 0000000000..6a0279876c --- /dev/null +++ b/src/Microsoft.AspNet.JsonPatch/Helpers/ExpressionHelpers.cs @@ -0,0 +1,99 @@ +// 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.Globalization; +using System.Linq.Expressions; + +namespace Microsoft.AspNet.JsonPatch.Helpers +{ + internal static class ExpressionHelpers + { + public static string GetPath(Expression> expr) where TModel : class + { + return "/" + GetPath(expr.Body, true); + } + + private static string GetPath(Expression expr, bool firstTime) + { + switch (expr.NodeType) + { + case ExpressionType.ArrayIndex: + var binaryExpression = (BinaryExpression)expr; + + if (ContinueWithSubPath(binaryExpression.Left.NodeType, false)) + { + var leftFromBinaryExpression = GetPath(binaryExpression.Left, false); + return leftFromBinaryExpression + "/" + binaryExpression.Right.ToString(); + } + else + { + return binaryExpression.Right.ToString(); + } + case ExpressionType.Call: + var methodCallExpression = (MethodCallExpression)expr; + + if (ContinueWithSubPath(methodCallExpression.Object.NodeType, false)) + { + var leftFromMemberCallExpression = GetPath(methodCallExpression.Object, false); + return leftFromMemberCallExpression + "/" + + GetIndexerInvocation(methodCallExpression.Arguments[0]); + } + else + { + return GetIndexerInvocation(methodCallExpression.Arguments[0]); + } + case ExpressionType.Convert: + return GetPath(((UnaryExpression)expr).Operand, false); + case ExpressionType.MemberAccess: + var memberExpression = expr as MemberExpression; + + if (ContinueWithSubPath(memberExpression.Expression.NodeType, false)) + { + var left = GetPath(memberExpression.Expression, false); + return left + "/" + memberExpression.Member.Name; + } + else + { + return memberExpression.Member.Name; + } + case ExpressionType.Parameter: + // Fits "x => x" (the whole document which is "" as JSON pointer) + return firstTime ? string.Empty : null; + default: + return string.Empty; + } + } + + private static bool ContinueWithSubPath(ExpressionType expressionType, bool firstTime) + { + if (firstTime) + { + return (expressionType == ExpressionType.ArrayIndex + || expressionType == ExpressionType.Call + || expressionType == ExpressionType.Convert + || expressionType == ExpressionType.MemberAccess + || expressionType == ExpressionType.Parameter); + } + else + { + return (expressionType == ExpressionType.ArrayIndex + || expressionType == ExpressionType.Call + || expressionType == ExpressionType.Convert + || expressionType == ExpressionType.MemberAccess); + } + } + + private static string GetIndexerInvocation(Expression expression) + { + var converted = Expression.Convert(expression, typeof(object)); + var fakeParameter = Expression.Parameter(typeof(object), null); + var lambda = Expression.Lambda>(converted, fakeParameter); + Func func; + + func = lambda.Compile(); + + return Convert.ToString(func(null), CultureInfo.InvariantCulture); + } + } +} \ No newline at end of file diff --git a/src/Microsoft.AspNet.JsonPatch/Helpers/GetValueResult.cs b/src/Microsoft.AspNet.JsonPatch/Helpers/GetValueResult.cs new file mode 100644 index 0000000000..89b7c93520 --- /dev/null +++ b/src/Microsoft.AspNet.JsonPatch/Helpers/GetValueResult.cs @@ -0,0 +1,30 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +namespace Microsoft.AspNet.JsonPatch.Helpers +{ + /// + /// Return value for the helper method used by Copy/Move. Needed to ensure we can make a different + /// decision in the calling method when the value is null because it cannot be fetched (HasError = true) + /// versus when it actually is null (much like why RemovedPropertyTypeResult is used for returning + /// type in the Remove operation). + /// + public class GetValueResult + { + public GetValueResult(object propertyValue, bool hasError) + { + PropertyValue = propertyValue; + HasError = hasError; + } + + /// + /// The value of the property we're trying to get + /// + public object PropertyValue { get; private set; } + + /// + /// HasError: true when an error occurred, the operation didn't complete succesfully + /// + public bool HasError { get; private set; } + } +} diff --git a/src/Microsoft.AspNet.JsonPatch/Helpers/JsonPatchProperty.cs b/src/Microsoft.AspNet.JsonPatch/Helpers/JsonPatchProperty.cs new file mode 100644 index 0000000000..0539d230a3 --- /dev/null +++ b/src/Microsoft.AspNet.JsonPatch/Helpers/JsonPatchProperty.cs @@ -0,0 +1,43 @@ +// 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 Newtonsoft.Json.Serialization; + +namespace Microsoft.AspNet.JsonPatch +{ + /// + /// Metadata for JsonProperty. + /// + public class JsonPatchProperty + { + /// + /// Initializes a new instance. + /// + public JsonPatchProperty(JsonProperty property, object parent) + { + if (property == null) + { + throw new ArgumentNullException(nameof(property)); + } + + if (parent == null) + { + throw new ArgumentNullException(nameof(parent)); + } + + Property = property; + Parent = parent; + } + + /// + /// Gets or sets JsonProperty. + /// + public JsonProperty Property { get; set; } + + /// + /// Gets or sets Parent. + /// + public object Parent { get; set; } + } +} \ No newline at end of file diff --git a/src/Microsoft.AspNet.JsonPatch/Helpers/ObjectTreeAnalyisResult.cs b/src/Microsoft.AspNet.JsonPatch/Helpers/ObjectTreeAnalyisResult.cs new file mode 100644 index 0000000000..91d5ee129d --- /dev/null +++ b/src/Microsoft.AspNet.JsonPatch/Helpers/ObjectTreeAnalyisResult.cs @@ -0,0 +1,210 @@ +// 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; +using System.Collections.Generic; +using System.Linq; +using Newtonsoft.Json.Serialization; + +namespace Microsoft.AspNet.JsonPatch.Helpers +{ + internal class ObjectTreeAnalysisResult + { + // either the property is part of the container dictionary, + // or we have a direct reference to a JsonPatchProperty instance + + public bool UseDynamicLogic { get; private set; } + + public bool IsValidPathForAdd { get; private set; } + + public bool IsValidPathForRemove { get; private set; } + + public IDictionary Container { get; private set; } + + public string PropertyPathInParent { get; private set; } + + public JsonPatchProperty JsonPatchProperty { get; private set; } + + public ObjectTreeAnalysisResult( + object objectToSearch, + string propertyPath, + IContractResolver contractResolver) + { + // construct the analysis result. + + // split the propertypath, and if necessary, remove the first + // empty item (that's the case when it starts with a "/") + var propertyPathTree = propertyPath.Split( + new char[] { '/' }, + StringSplitOptions.RemoveEmptyEntries); + + // we've now got a split up property tree "base/property/otherproperty/..." + int lastPosition = 0; + object targetObject = objectToSearch; + for (int i = 0; i < propertyPathTree.Length; i++) + { + lastPosition = i; + + // if the current target object is an ExpandoObject (IDictionary), + // we cannot use the ContractResolver. + var dictionary = targetObject as IDictionary; + if (dictionary != null) + { + // find the value in the dictionary + if (dictionary.ContainsCaseInsensitiveKey(propertyPathTree[i])) + { + var possibleNewTargetObject = dictionary.GetValueForCaseInsensitiveKey(propertyPathTree[i]); + + // unless we're at the last item, we should set the targetobject + // to the new object. If we're at the last item, we need to stop + if (i != propertyPathTree.Length - 1) + { + targetObject = possibleNewTargetObject; + } + } + else + { + break; + } + } + else + { + // if the current part of the path is numeric, this means we're trying + // to get the propertyInfo of a specific object in an array. To allow + // for this, the previous value (targetObject) must be an IEnumerable, and + // the position must exist. + + int numericValue = -1; + if (int.TryParse(propertyPathTree[i], out numericValue)) + { + var element = GetElementAtFromObject(targetObject, numericValue); + if (element != null) + { + targetObject = element; + } + else + { + break; + } + } + else + { + var jsonContract = (JsonObjectContract)contractResolver.ResolveContract(targetObject.GetType()); + + // does the property exist? + var attemptedProperty = jsonContract + .Properties + .FirstOrDefault(p => string.Equals(p.PropertyName, propertyPathTree[i], StringComparison.OrdinalIgnoreCase)); + + if (attemptedProperty != null) + { + // unless we're at the last item, we should continue searching. + // If we're at the last item, we need to stop + if ((i != propertyPathTree.Length - 1)) + { + targetObject = attemptedProperty.ValueProvider.GetValue(targetObject); + } + } + else + { + // property cannot be found, and we're not working with dynamics. + // Stop, and return invalid path. + break; + } + } + } + } + + if (propertyPathTree.Length - lastPosition != 1) + { + IsValidPathForAdd = false; + IsValidPathForRemove = false; + return; + } + + // two things can happen now. The targetproperty can be an IDictionary - in that + // case, it's valid for add if there's 1 item left in the propertyPathTree. + // + // it can also be a property info. In that case, if there's nothing left in the path + // tree we're at the end, if there's one left we can try and set that. + if (targetObject is IDictionary) + { + UseDynamicLogic = true; + + Container = (IDictionary)targetObject; + IsValidPathForAdd = true; + PropertyPathInParent = propertyPathTree[propertyPathTree.Length - 1]; + + // to be able to remove this property, it must exist + IsValidPathForRemove = Container.ContainsCaseInsensitiveKey(PropertyPathInParent); + } + else if (targetObject is IList) + { + System.Diagnostics.Debugger.Launch(); + UseDynamicLogic = false; + + int index; + if (!Int32.TryParse(propertyPathTree[propertyPathTree.Length - 1], out index)) + { + // We only support indexing into a list + IsValidPathForAdd = false; + IsValidPathForRemove = false; + return; + } + + IsValidPathForAdd = true; + IsValidPathForRemove = ((IList)targetObject).Count > index; + PropertyPathInParent = propertyPathTree[propertyPathTree.Length - 1]; + } + else + { + UseDynamicLogic = false; + + var property = propertyPathTree[propertyPathTree.Length - 1]; + var jsonContract = (JsonObjectContract)contractResolver.ResolveContract(targetObject.GetType()); + var attemptedProperty = jsonContract + .Properties + .FirstOrDefault(p => string.Equals(p.PropertyName, property, StringComparison.OrdinalIgnoreCase)); + + if (attemptedProperty == null) + { + IsValidPathForAdd = false; + IsValidPathForRemove = false; + } + else + { + IsValidPathForAdd = true; + IsValidPathForRemove = true; + JsonPatchProperty = new JsonPatchProperty(attemptedProperty, targetObject); + PropertyPathInParent = property; + } + } + } + + private object GetElementAtFromObject(object targetObject, int numericValue) + { + if (numericValue > -1) + { + // Check if the targetobject is an IEnumerable, + // and if the position is valid. + if (targetObject is IEnumerable) + { + var indexable = ((IEnumerable)targetObject).Cast(); + + if (indexable.Count() >= numericValue) + { + return indexable.ElementAt(numericValue); + } + else { return null; } + } + else { return null; } + } + else + { + return null; + } + } + + } +} diff --git a/src/Microsoft.AspNet.JsonPatch/Helpers/PathHelpers.cs b/src/Microsoft.AspNet.JsonPatch/Helpers/PathHelpers.cs new file mode 100644 index 0000000000..28683e7c98 --- /dev/null +++ b/src/Microsoft.AspNet.JsonPatch/Helpers/PathHelpers.cs @@ -0,0 +1,31 @@ +// 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 Microsoft.AspNet.JsonPatch.Exceptions; + +namespace Microsoft.AspNet.JsonPatch.Helpers +{ + internal static class PathHelpers + { + internal static string NormalizePath(string path) + { + // check for most common path errors on create. This is not + // absolutely necessary, but it allows us to already catch mistakes + // on creation of the patch document rather than on execute. + + if (path.Contains(".") || path.Contains("//") || path.Contains(" ") || path.Contains("\\")) + { + throw new JsonPatchException(Resources.FormatInvalidValueForPath(path), null); + } + + if (!(path.StartsWith("/"))) + { + return "/" + path; + } + else + { + return path; + } + } + } +} diff --git a/src/Microsoft.AspNet.JsonPatch/Helpers/RemovedPropertyTypeResult.cs b/src/Microsoft.AspNet.JsonPatch/Helpers/RemovedPropertyTypeResult.cs new file mode 100644 index 0000000000..9f5b97a868 --- /dev/null +++ b/src/Microsoft.AspNet.JsonPatch/Helpers/RemovedPropertyTypeResult.cs @@ -0,0 +1,38 @@ +// 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; + +namespace Microsoft.AspNet.JsonPatch.Helpers +{ + /// + /// Return value for Remove operation. The combination tells us what to do next (if this operation + /// is called from inside another operation, eg: Replace, Copy. + /// + /// Possible combo: + /// - ActualType contains type: operation succesfully completed, can continue when called from inside + /// another operation + /// - ActualType null and HasError true: operation not completed succesfully, should not be allowed to continue + /// - ActualType null and HasError false: operation completed succesfully, but we should not be allowed to + /// continue when called from inside another method as we could not verify the type of the removed property. + /// This happens when the value of an item in an ExpandoObject dictionary is null. + /// + internal class RemovedPropertyTypeResult + { + /// + /// The type of the removed property (value) + /// + public Type ActualType { get; private set; } + + /// + /// HasError: true when an error occurred, the operation didn't complete succesfully + /// + public bool HasError { get; set; } + + public RemovedPropertyTypeResult(Type actualType, bool hasError) + { + ActualType = actualType; + HasError = hasError; + } + } +} diff --git a/src/Microsoft.AspNet.JsonPatch/IJsonPatchDocument.cs b/src/Microsoft.AspNet.JsonPatch/IJsonPatchDocument.cs new file mode 100644 index 0000000000..18033e82f0 --- /dev/null +++ b/src/Microsoft.AspNet.JsonPatch/IJsonPatchDocument.cs @@ -0,0 +1,16 @@ +// 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 Microsoft.AspNet.JsonPatch.Operations; +using System.Collections.Generic; +using Newtonsoft.Json.Serialization; + +namespace Microsoft.AspNet.JsonPatch +{ + public interface IJsonPatchDocument + { + IContractResolver ContractResolver { get; set; } + + IList GetOperations(); + } +} \ No newline at end of file diff --git a/src/Microsoft.AspNet.JsonPatch/JsonPatchDocument.cs b/src/Microsoft.AspNet.JsonPatch/JsonPatchDocument.cs new file mode 100644 index 0000000000..fc2e73030a --- /dev/null +++ b/src/Microsoft.AspNet.JsonPatch/JsonPatchDocument.cs @@ -0,0 +1,222 @@ +// 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 Microsoft.AspNet.JsonPatch.Adapters; +using Microsoft.AspNet.JsonPatch.Converters; +using Microsoft.AspNet.JsonPatch.Helpers; +using Microsoft.AspNet.JsonPatch.Operations; +using Newtonsoft.Json; +using Newtonsoft.Json.Serialization; + +namespace Microsoft.AspNet.JsonPatch +{ + // Implementation details: the purpose of this type of patch document is to allow creation of such + // documents for cases where there's no class/DTO to work on. Typical use case: backend not built in + // .NET or architecture doesn't contain a shared DTO layer. + [JsonConverter(typeof(JsonPatchDocumentConverter))] + public class JsonPatchDocument : IJsonPatchDocument + { + public List Operations { get; private set; } + + [JsonIgnore] + public IContractResolver ContractResolver { get; set; } + + public JsonPatchDocument() + { + Operations = new List(); + ContractResolver = new DefaultContractResolver(); + } + + public JsonPatchDocument(List operations, IContractResolver contractResolver) + { + if (operations == null) + { + throw new ArgumentNullException(nameof(operations)); + } + + if (contractResolver == null) + { + throw new ArgumentNullException(nameof(contractResolver)); + } + + Operations = operations; + ContractResolver = contractResolver; + } + + /// + /// Add operation. Will result in, for example, + /// { "op": "add", "path": "/a/b/c", "value": [ "foo", "bar" ] } + /// + /// target location + /// value + /// + public JsonPatchDocument Add(string path, object value) + { + if (path == null) + { + throw new ArgumentNullException(nameof(path)); + } + + Operations.Add(new Operation("add", PathHelpers.NormalizePath(path), null, value)); + return this; + } + + /// + /// Remove value at target location. Will result in, for example, + /// { "op": "remove", "path": "/a/b/c" } + /// + /// target location + /// + public JsonPatchDocument Remove(string path) + { + if (path == null) + { + throw new ArgumentNullException(nameof(path)); + } + + Operations.Add(new Operation("remove", PathHelpers.NormalizePath(path), null, null)); + return this; + } + + /// + /// Replace value. Will result in, for example, + /// { "op": "replace", "path": "/a/b/c", "value": 42 } + /// + /// target location + /// value + /// + public JsonPatchDocument Replace(string path, object value) + { + if (path == null) + { + throw new ArgumentNullException(nameof(path)); + } + + Operations.Add(new Operation("replace", PathHelpers.NormalizePath(path), null, value)); + return this; + } + + /// + /// Removes value at specified location and add it to the target location. Will result in, for example: + /// { "op": "move", "from": "/a/b/c", "path": "/a/b/d" } + /// + /// source location + /// target location + /// + public JsonPatchDocument Move(string from, string path) + { + if (from == null) + { + throw new ArgumentNullException(nameof(from)); + } + + if (path == null) + { + throw new ArgumentNullException(nameof(path)); + } + + Operations.Add(new Operation("move", PathHelpers.NormalizePath(path), PathHelpers.NormalizePath(from))); + return this; + } + + /// + /// Copy the value at specified location to the target location. Willr esult in, for example: + /// { "op": "copy", "from": "/a/b/c", "path": "/a/b/e" } + /// + /// source location + /// target location + /// + public JsonPatchDocument Copy(string from, string path) + { + if (from == null) + { + throw new ArgumentNullException(nameof(from)); + } + + if (path == null) + { + throw new ArgumentNullException(nameof(path)); + } + + Operations.Add(new Operation("copy", PathHelpers.NormalizePath(path), PathHelpers.NormalizePath(from))); + return this; + } + + /// + /// Apply this JsonPatchDocument + /// + /// Object to apply the JsonPatchDocument to + public void ApplyTo(object objectToApplyTo) + { + if (objectToApplyTo == null) + { + throw new ArgumentNullException(nameof(objectToApplyTo)); + } + + ApplyTo(objectToApplyTo, new ObjectAdapter(ContractResolver, logErrorAction: null)); + } + + /// + /// Apply this JsonPatchDocument + /// + /// Object to apply the JsonPatchDocument to + /// Action to log errors + public void ApplyTo(object objectToApplyTo, Action logErrorAction) + { + if (objectToApplyTo == null) + { + throw new ArgumentNullException(nameof(objectToApplyTo)); + } + + ApplyTo(objectToApplyTo, new ObjectAdapter(ContractResolver, logErrorAction)); + } + + /// + /// Apply this JsonPatchDocument + /// + /// Object to apply the JsonPatchDocument to + /// IObjectAdapter instance to use when applying + public void ApplyTo(object objectToApplyTo, IObjectAdapter adapter) + { + if (objectToApplyTo == null) + { + throw new ArgumentNullException(nameof(objectToApplyTo)); + } + + if (adapter == null) + { + throw new ArgumentNullException(nameof(adapter)); + } + + // apply each operation in order + foreach (var op in Operations) + { + op.Apply(objectToApplyTo, adapter); + } + } + + IList IJsonPatchDocument.GetOperations() + { + var allOps = new List(); + + if (Operations != null) + { + foreach (var op in Operations) + { + var untypedOp = new Operation(); + + untypedOp.op = op.op; + untypedOp.value = op.value; + untypedOp.path = op.path; + untypedOp.from = op.from; + + allOps.Add(untypedOp); + } + } + + return allOps; + } + } +} diff --git a/src/Microsoft.AspNet.JsonPatch/JsonPatchDocumentOfT.cs b/src/Microsoft.AspNet.JsonPatch/JsonPatchDocumentOfT.cs new file mode 100644 index 0000000000..7b03f1644c --- /dev/null +++ b/src/Microsoft.AspNet.JsonPatch/JsonPatchDocumentOfT.cs @@ -0,0 +1,700 @@ +// 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.Linq.Expressions; +using Microsoft.AspNet.JsonPatch.Adapters; +using Microsoft.AspNet.JsonPatch.Converters; +using Microsoft.AspNet.JsonPatch.Helpers; +using Microsoft.AspNet.JsonPatch.Operations; +using Newtonsoft.Json; +using Newtonsoft.Json.Serialization; + +namespace Microsoft.AspNet.JsonPatch +{ + // Implementation details: the purpose of this type of patch document is to ensure we can do type-checking + // when producing a JsonPatchDocument. However, we cannot send this "typed" over the wire, as that would require + // including type data in the JsonPatchDocument serialized as JSON (to allow for correct deserialization) - that's + // not according to RFC 6902, and would thus break cross-platform compatibility. + [JsonConverter(typeof(TypedJsonPatchDocumentConverter))] + public class JsonPatchDocument : IJsonPatchDocument where TModel : class + { + public List> Operations { get; private set; } + + [JsonIgnore] + public IContractResolver ContractResolver { get; set; } + + public JsonPatchDocument() + { + Operations = new List>(); + ContractResolver = new DefaultContractResolver(); + } + + // Create from list of operations + public JsonPatchDocument(List> operations, IContractResolver contractResolver) + { + if (operations == null) + { + throw new ArgumentNullException(nameof(operations)); + } + + if (contractResolver == null) + { + throw new ArgumentNullException(nameof(contractResolver)); + } + + Operations = operations; + ContractResolver = contractResolver; + } + + /// + /// Add operation. Will result in, for example, + /// { "op": "add", "path": "/a/b/c", "value": [ "foo", "bar" ] } + /// + /// value type + /// target location + /// value + /// + public JsonPatchDocument Add(Expression> path, TProp value) + { + if (path == null) + { + throw new ArgumentNullException(nameof(path)); + } + + Operations.Add(new Operation( + "add", + ExpressionHelpers.GetPath(path).ToLowerInvariant(), + from: null, + value: value)); + + return this; + } + + /// + /// Add value to list at given position + /// + /// value type + /// target location + /// value + /// position + /// + public JsonPatchDocument Add( + Expression>> path, + TProp value, + int position) + { + if (path == null) + { + throw new ArgumentNullException(nameof(path)); + } + + Operations.Add(new Operation( + "add", + ExpressionHelpers.GetPath(path).ToLowerInvariant() + "/" + position, + from: null, + value: value)); + + return this; + } + + /// + /// At value at end of list + /// + /// value type + /// target location + /// value + /// + public JsonPatchDocument Add(Expression>> path, TProp value) + { + if (path == null) + { + throw new ArgumentNullException(nameof(path)); + } + + Operations.Add(new Operation( + "add", + ExpressionHelpers.GetPath(path).ToLowerInvariant() + "/-", + from: null, + value: value)); + + return this; + } + + /// + /// Remove value at target location. Will result in, for example, + /// { "op": "remove", "path": "/a/b/c" } + /// + /// target location + /// + public JsonPatchDocument Remove(Expression> path) + { + if (path == null) + { + throw new ArgumentNullException(nameof(path)); + } + + Operations.Add(new Operation("remove", ExpressionHelpers.GetPath(path).ToLowerInvariant(), from: null)); + + return this; + } + + /// + /// Remove value from list at given position + /// + /// value type + /// target location + /// position + /// + public JsonPatchDocument Remove(Expression>> path, int position) + { + if (path == null) + { + throw new ArgumentNullException(nameof(path)); + } + + Operations.Add(new Operation( + "remove", + ExpressionHelpers.GetPath(path).ToLowerInvariant() + "/" + position, + from: null)); + + return this; + } + + /// + /// Remove value from end of list + /// + /// value type + /// target location + /// + public JsonPatchDocument Remove(Expression>> path) + { + if (path == null) + { + throw new ArgumentNullException(nameof(path)); + } + + Operations.Add(new Operation( + "remove", + ExpressionHelpers.GetPath(path).ToLowerInvariant() + "/-", + from: null)); + + return this; + } + + /// + /// Replace value. Will result in, for example, + /// { "op": "replace", "path": "/a/b/c", "value": 42 } + /// + /// target location + /// value + /// + public JsonPatchDocument Replace(Expression> path, TProp value) + { + if (path == null) + { + throw new ArgumentNullException(nameof(path)); + } + + Operations.Add(new Operation( + "replace", + ExpressionHelpers.GetPath(path).ToLowerInvariant(), + from: null, + value: value)); + + return this; + } + + /// + /// Replace value in a list at given position + /// + /// value type + /// target location + /// value + /// position + /// + public JsonPatchDocument Replace(Expression>> path, + TProp value, int position) + { + if (path == null) + { + throw new ArgumentNullException(nameof(path)); + } + + Operations.Add(new Operation( + "replace", + ExpressionHelpers.GetPath(path).ToLowerInvariant() + "/" + position, + from: null, + value: value)); + + return this; + } + + /// + /// Replace value at end of a list + /// + /// value type + /// target location + /// value + /// + public JsonPatchDocument Replace(Expression>> path, TProp value) + { + if (path == null) + { + throw new ArgumentNullException(nameof(path)); + } + + Operations.Add(new Operation( + "replace", + ExpressionHelpers.GetPath(path).ToLowerInvariant() + "/-", + from: null, + value: value)); + + return this; + } + + /// + /// Removes value at specified location and add it to the target location. Will result in, for example: + /// { "op": "move", "from": "/a/b/c", "path": "/a/b/d" } + /// + /// source location + /// target location + /// + public JsonPatchDocument Move( + Expression> from, + Expression> path) + { + if (from == null) + { + throw new ArgumentNullException(nameof(from)); + } + + if (path == null) + { + throw new ArgumentNullException(nameof(path)); + } + + Operations.Add(new Operation( + "move", + ExpressionHelpers.GetPath(path).ToLowerInvariant(), + ExpressionHelpers.GetPath(from).ToLowerInvariant())); + + return this; + } + + /// + /// Move from a position in a list to a new location + /// + /// + /// source location + /// position + /// target location + /// + public JsonPatchDocument Move( + Expression>> from, + int positionFrom, + Expression> path) + { + if (from == null) + { + throw new ArgumentNullException(nameof(from)); + } + + if (path == null) + { + throw new ArgumentNullException(nameof(path)); + } + + Operations.Add(new Operation( + "move", + ExpressionHelpers.GetPath(path).ToLowerInvariant(), + ExpressionHelpers.GetPath(from).ToLowerInvariant() + "/" + positionFrom)); + + return this; + } + + /// + /// Move from a property to a location in a list + /// + /// + /// source location + /// target location + /// position + /// + public JsonPatchDocument Move( + Expression> from, + Expression>> path, + int positionTo) + { + if (from == null) + { + throw new ArgumentNullException(nameof(from)); + } + + if (path == null) + { + throw new ArgumentNullException(nameof(path)); + } + + Operations.Add(new Operation( + "move", + ExpressionHelpers.GetPath(path).ToLowerInvariant() + "/" + positionTo, + ExpressionHelpers.GetPath(from).ToLowerInvariant())); + + return this; + } + + /// + /// Move from a position in a list to another location in a list + /// + /// + /// source location + /// position (source) + /// target location + /// position (target) + /// + public JsonPatchDocument Move( + Expression>> from, + int positionFrom, + Expression>> path, + int positionTo) + { + if (from == null) + { + throw new ArgumentNullException(nameof(from)); + } + + if (path == null) + { + throw new ArgumentNullException(nameof(path)); + } + + Operations.Add(new Operation( + "move", + ExpressionHelpers.GetPath(path).ToLowerInvariant() + "/" + positionTo, + ExpressionHelpers.GetPath(from).ToLowerInvariant() + "/" + positionFrom)); + + return this; + } + + /// + /// Move from a position in a list to the end of another list + /// + /// + /// source location + /// position + /// target location + /// + public JsonPatchDocument Move( + Expression>> from, + int positionFrom, + Expression>> path) + { + if (from == null) + { + throw new ArgumentNullException(nameof(from)); + } + + if (path == null) + { + throw new ArgumentNullException(nameof(path)); + } + + Operations.Add(new Operation( + "move", + ExpressionHelpers.GetPath(path).ToLowerInvariant() + "/-", + ExpressionHelpers.GetPath(from).ToLowerInvariant() + "/" + positionFrom)); + + return this; + } + + /// + /// Move to the end of a list + /// + /// + /// source location + /// target location + /// + public JsonPatchDocument Move( + Expression> from, + Expression>> path) + { + if (from == null) + { + throw new ArgumentNullException(nameof(from)); + } + + if (path == null) + { + throw new ArgumentNullException(nameof(path)); + } + + Operations.Add(new Operation( + "move", + ExpressionHelpers.GetPath(path).ToLowerInvariant() + "/-", + ExpressionHelpers.GetPath(from).ToLowerInvariant())); + + return this; + } + + /// + /// Copy the value at specified location to the target location. Willr esult in, for example: + /// { "op": "copy", "from": "/a/b/c", "path": "/a/b/e" } + /// + /// source location + /// target location + /// + public JsonPatchDocument Copy( + Expression> from, + Expression> path) + { + if (from == null) + { + throw new ArgumentNullException(nameof(from)); + } + + if (path == null) + { + throw new ArgumentNullException(nameof(path)); + } + + Operations.Add(new Operation( + "copy", + ExpressionHelpers.GetPath(path).ToLowerInvariant() + , ExpressionHelpers.GetPath(from).ToLowerInvariant())); + + return this; + } + + /// + /// Copy from a position in a list to a new location + /// + /// + /// source location + /// position + /// target location + /// + public JsonPatchDocument Copy( + Expression>> from, + int positionFrom, + Expression> path) + { + if (from == null) + { + throw new ArgumentNullException(nameof(from)); + } + + if (path == null) + { + throw new ArgumentNullException(nameof(path)); + } + + Operations.Add(new Operation( + "copy", + ExpressionHelpers.GetPath(path).ToLowerInvariant(), + ExpressionHelpers.GetPath(from).ToLowerInvariant() + "/" + positionFrom)); + + return this; + } + + /// + /// Copy from a property to a location in a list + /// + /// + /// source location + /// target location + /// position + /// + public JsonPatchDocument Copy( + Expression> from, + Expression>> path, + int positionTo) + { + if (from == null) + { + throw new ArgumentNullException(nameof(from)); + } + + if (path == null) + { + throw new ArgumentNullException(nameof(path)); + } + + Operations.Add(new Operation( + "copy", + ExpressionHelpers.GetPath(path).ToLowerInvariant() + "/" + positionTo, + ExpressionHelpers.GetPath(from).ToLowerInvariant())); + + return this; + } + + /// + /// Copy from a position in a list to a new location in a list + /// + /// + /// source location + /// position (source) + /// target location + /// position (target) + /// + public JsonPatchDocument Copy( + Expression>> from, + int positionFrom, + Expression>> path, + int positionTo) + { + if (from == null) + { + throw new ArgumentNullException(nameof(from)); + } + + if (path == null) + { + throw new ArgumentNullException(nameof(path)); + } + + Operations.Add(new Operation( + "copy", + ExpressionHelpers.GetPath(path).ToLowerInvariant() + "/" + positionTo, + ExpressionHelpers.GetPath(from).ToLowerInvariant() + "/" + positionFrom)); + + return this; + } + + /// + /// Copy from a position in a list to the end of another list + /// + /// + /// source location + /// position + /// target location + /// + public JsonPatchDocument Copy( + Expression>> from, + int positionFrom, + Expression>> path) + { + if (from == null) + { + throw new ArgumentNullException(nameof(from)); + } + + if (path == null) + { + throw new ArgumentNullException(nameof(path)); + } + + Operations.Add(new Operation( + "copy", + ExpressionHelpers.GetPath(path).ToLowerInvariant() + "/-", + ExpressionHelpers.GetPath(from).ToLowerInvariant() + "/" + positionFrom)); + + return this; + } + + /// + /// Copy to the end of a list + /// + /// + /// source location + /// target location + /// + public JsonPatchDocument Copy( + Expression> from, + Expression>> path) + { + if (from == null) + { + throw new ArgumentNullException(nameof(from)); + } + + if (path == null) + { + throw new ArgumentNullException(nameof(path)); + } + + Operations.Add(new Operation( + "copy", + ExpressionHelpers.GetPath(path).ToLowerInvariant() + "/-", + ExpressionHelpers.GetPath(from).ToLowerInvariant())); + + return this; + } + + /// + /// Apply this JsonPatchDocument + /// + /// Object to apply the JsonPatchDocument to + public void ApplyTo(TModel objectToApplyTo) + { + if (objectToApplyTo == null) + { + throw new ArgumentNullException(nameof(objectToApplyTo)); + } + + ApplyTo(objectToApplyTo, new ObjectAdapter(ContractResolver, logErrorAction: null)); + } + + /// + /// Apply this JsonPatchDocument + /// + /// Object to apply the JsonPatchDocument to + /// Action to log errors + public void ApplyTo(TModel objectToApplyTo, Action logErrorAction) + { + if (objectToApplyTo == null) + { + throw new ArgumentNullException(nameof(objectToApplyTo)); + } + + ApplyTo(objectToApplyTo, new ObjectAdapter(ContractResolver, logErrorAction)); + } + + /// + /// Apply this JsonPatchDocument + /// + /// Object to apply the JsonPatchDocument to + /// IObjectAdapter instance to use when applying + public void ApplyTo(TModel objectToApplyTo, IObjectAdapter adapter) + { + if (objectToApplyTo == null) + { + throw new ArgumentNullException(nameof(objectToApplyTo)); + } + + if (adapter == null) + { + throw new ArgumentNullException(nameof(adapter)); + } + + // apply each operation in order + foreach (var op in Operations) + { + op.Apply(objectToApplyTo, adapter); + } + } + + IList IJsonPatchDocument.GetOperations() + { + var allOps = new List(); + + if (Operations != null) + { + foreach (var op in Operations) + { + var untypedOp = new Operation(); + + untypedOp.op = op.op; + untypedOp.value = op.value; + untypedOp.path = op.path; + untypedOp.from = op.from; + + allOps.Add(untypedOp); + } + } + + return allOps; + } + } +} \ No newline at end of file diff --git a/src/Microsoft.AspNet.JsonPatch/JsonPatchError.cs b/src/Microsoft.AspNet.JsonPatch/JsonPatchError.cs new file mode 100644 index 0000000000..a140f0d4c1 --- /dev/null +++ b/src/Microsoft.AspNet.JsonPatch/JsonPatchError.cs @@ -0,0 +1,50 @@ +// 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 Microsoft.AspNet.JsonPatch.Operations; + +namespace Microsoft.AspNet.JsonPatch +{ + /// + /// Captures error message and the related entity and the operation that caused it. + /// + public class JsonPatchError + { + /// + /// Initializes a new instance of . + /// + /// The object that is affected by the error. + /// The that caused the error. + /// The error message. + public JsonPatchError( + object affectedObject, + Operation operation, + string errorMessage) + { + if (errorMessage == null) + { + throw new ArgumentNullException(nameof(errorMessage)); + } + + AffectedObject = affectedObject; + Operation = operation; + ErrorMessage = errorMessage; + } + + /// + /// Gets the object that is affected by the error. + /// + public object AffectedObject { get; } + + /// + /// Gets the that caused the error. + /// + public Operation Operation { get; } + + /// + /// Gets the error message. + /// + public string ErrorMessage { get; } + } +} \ No newline at end of file diff --git a/src/Microsoft.AspNet.JsonPatch/Microsoft.AspNet.JsonPatch.xproj b/src/Microsoft.AspNet.JsonPatch/Microsoft.AspNet.JsonPatch.xproj new file mode 100644 index 0000000000..f9fb187ecd --- /dev/null +++ b/src/Microsoft.AspNet.JsonPatch/Microsoft.AspNet.JsonPatch.xproj @@ -0,0 +1,17 @@ + + + + 14.0 + $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) + + + + 4d55f4d8-633b-462f-a5b1-feb84bd2d534 + ..\..\artifacts\obj\$(MSBuildProjectName) + ..\..\artifacts\bin\$(MSBuildProjectName)\ + + + 2.0 + + + \ No newline at end of file diff --git a/src/Microsoft.AspNet.JsonPatch/Operations/Operation.cs b/src/Microsoft.AspNet.JsonPatch/Operations/Operation.cs new file mode 100644 index 0000000000..7f056f41bf --- /dev/null +++ b/src/Microsoft.AspNet.JsonPatch/Operations/Operation.cs @@ -0,0 +1,74 @@ +// 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 Microsoft.AspNet.JsonPatch.Adapters; +using Newtonsoft.Json; + +namespace Microsoft.AspNet.JsonPatch.Operations +{ + public class Operation : OperationBase + { + [JsonProperty("value")] + public object value { get; set; } + + public Operation() + { + + } + + public Operation(string op, string path, string from, object value) + : base(op, path, from) + { + this.value = value; + } + + public Operation(string op, string path, string from) + : base(op, path, from) + { + } + + public void Apply(object objectToApplyTo, IObjectAdapter adapter) + { + if (objectToApplyTo == null) + { + throw new ArgumentNullException(nameof(objectToApplyTo)); + } + + if (adapter == null) + { + throw new ArgumentNullException(nameof(adapter)); + } + + switch (OperationType) + { + case OperationType.Add: + adapter.Add(this, objectToApplyTo); + break; + case OperationType.Remove: + adapter.Remove(this, objectToApplyTo); + break; + case OperationType.Replace: + adapter.Replace(this, objectToApplyTo); + break; + case OperationType.Move: + adapter.Move(this, objectToApplyTo); + break; + case OperationType.Copy: + adapter.Copy(this, objectToApplyTo); + break; + case OperationType.Test: + throw new NotSupportedException(Resources.TestOperationNotSupported); + default: + break; + } + } + + public bool ShouldSerializevalue() + { + return (OperationType == OperationType.Add + || OperationType == OperationType.Replace + || OperationType == OperationType.Test); + } + } +} \ No newline at end of file diff --git a/src/Microsoft.AspNet.JsonPatch/Operations/OperationBase.cs b/src/Microsoft.AspNet.JsonPatch/Operations/OperationBase.cs new file mode 100644 index 0000000000..17455f75e8 --- /dev/null +++ b/src/Microsoft.AspNet.JsonPatch/Operations/OperationBase.cs @@ -0,0 +1,57 @@ +// 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 Newtonsoft.Json; + +namespace Microsoft.AspNet.JsonPatch.Operations +{ + public class OperationBase + { + [JsonIgnore] + public OperationType OperationType + { + get + { + return (OperationType)Enum.Parse(typeof(OperationType), op, true); + } + } + + [JsonProperty("path")] + public string path { get; set; } + + [JsonProperty("op")] + public string op { get; set; } + + [JsonProperty("from")] + public string from { get; set; } + + public OperationBase() + { + + } + + public OperationBase(string op, string path, string from) + { + if (op == null) + { + throw new ArgumentNullException(nameof(op)); + } + + if (path == null) + { + throw new ArgumentNullException(nameof(path)); + } + + this.op = op; + this.path = path; + this.from = from; + } + + public bool ShouldSerializefrom() + { + return (OperationType == OperationType.Move + || OperationType == OperationType.Copy); + } + } +} \ No newline at end of file diff --git a/src/Microsoft.AspNet.JsonPatch/Operations/OperationOfT.cs b/src/Microsoft.AspNet.JsonPatch/Operations/OperationOfT.cs new file mode 100644 index 0000000000..63663f70d9 --- /dev/null +++ b/src/Microsoft.AspNet.JsonPatch/Operations/OperationOfT.cs @@ -0,0 +1,83 @@ +// 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 Microsoft.AspNet.JsonPatch.Adapters; + +namespace Microsoft.AspNet.JsonPatch.Operations +{ + public class Operation : Operation where TModel : class + { + public Operation() + { + + } + + public Operation(string op, string path, string from, object value) + : base(op, path, from) + { + if (op == null) + { + throw new ArgumentNullException(nameof(op)); + } + + if (path == null) + { + throw new ArgumentNullException(nameof(path)); + } + + this.value = value; + } + + public Operation(string op, string path, string from) + : base(op, path, from) + { + if (op == null) + { + throw new ArgumentNullException(nameof(op)); + } + if (path == null) + { + throw new ArgumentNullException(nameof(path)); + } + + } + + public void Apply(TModel objectToApplyTo, IObjectAdapter adapter) + { + if (objectToApplyTo == null) + { + throw new ArgumentNullException(nameof(objectToApplyTo)); + } + + if (adapter == null) + { + throw new ArgumentNullException(nameof(adapter)); + } + + switch (OperationType) + { + case OperationType.Add: + adapter.Add(this, objectToApplyTo); + break; + case OperationType.Remove: + adapter.Remove(this, objectToApplyTo); + break; + case OperationType.Replace: + adapter.Replace(this, objectToApplyTo); + break; + case OperationType.Move: + adapter.Move(this, objectToApplyTo); + break; + case OperationType.Copy: + adapter.Copy(this, objectToApplyTo); + break; + case OperationType.Test: + throw new NotSupportedException(Resources.TestOperationNotSupported); + default: + break; + } + } + + } +} \ No newline at end of file diff --git a/src/Microsoft.AspNet.JsonPatch/Operations/OperationType.cs b/src/Microsoft.AspNet.JsonPatch/Operations/OperationType.cs new file mode 100644 index 0000000000..a4d006bc51 --- /dev/null +++ b/src/Microsoft.AspNet.JsonPatch/Operations/OperationType.cs @@ -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.AspNet.JsonPatch.Operations +{ + public enum OperationType + { + Add, + Remove, + Replace, + Move, + Copy, + Test + } +} \ No newline at end of file diff --git a/src/Microsoft.AspNet.JsonPatch/Properties/AssemblyInfo.cs b/src/Microsoft.AspNet.JsonPatch/Properties/AssemblyInfo.cs new file mode 100644 index 0000000000..b2437d9ad6 --- /dev/null +++ b/src/Microsoft.AspNet.JsonPatch/Properties/AssemblyInfo.cs @@ -0,0 +1,8 @@ +// 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.Reflection; +using System.Resources; + +[assembly: AssemblyMetadata("Serviceable", "True")] +[assembly: NeutralResourcesLanguage("en-us")] \ No newline at end of file diff --git a/src/Microsoft.AspNet.JsonPatch/Properties/Resources.Designer.cs b/src/Microsoft.AspNet.JsonPatch/Properties/Resources.Designer.cs new file mode 100644 index 0000000000..f0ee7f2439 --- /dev/null +++ b/src/Microsoft.AspNet.JsonPatch/Properties/Resources.Designer.cs @@ -0,0 +1,270 @@ +// +namespace Microsoft.AspNet.JsonPatch +{ + using System.Globalization; + using System.Reflection; + using System.Resources; + + internal static class Resources + { + private static readonly ResourceManager _resourceManager + = new ResourceManager("Microsoft.AspNet.JsonPatch.Resources", typeof(Resources).GetTypeInfo().Assembly); + + /// + /// The type of the property at path '{0}' could not be determined. + /// + internal static string CannotDeterminePropertyType + { + get { return GetString("CannotDeterminePropertyType"); } + } + + /// + /// The type of the property at path '{0}' could not be determined. + /// + internal static string FormatCannotDeterminePropertyType(object p0) + { + return string.Format(CultureInfo.CurrentCulture, GetString("CannotDeterminePropertyType"), p0); + } + + /// + /// The property at '{0}' could not be read. + /// + internal static string CannotReadProperty + { + get { return GetString("CannotReadProperty"); } + } + + /// + /// The property at '{0}' could not be read. + /// + internal static string FormatCannotReadProperty(object p0) + { + return string.Format(CultureInfo.CurrentCulture, GetString("CannotReadProperty"), p0); + } + + /// + /// The property at path '{0}' could not be updated. + /// + internal static string CannotUpdateProperty + { + get { return GetString("CannotUpdateProperty"); } + } + + /// + /// The property at path '{0}' could not be updated. + /// + internal static string FormatCannotUpdateProperty(object p0) + { + return string.Format(CultureInfo.CurrentCulture, GetString("CannotUpdateProperty"), p0); + } + + /// + /// The key '{0}' was not found. + /// + internal static string DictionaryKeyNotFound + { + get { return GetString("DictionaryKeyNotFound"); } + } + + /// + /// The key '{0}' was not found. + /// + internal static string FormatDictionaryKeyNotFound(object p0) + { + return string.Format(CultureInfo.CurrentCulture, GetString("DictionaryKeyNotFound"), p0); + } + + /// + /// For operation '{0}' on array property at path '{1}', the index is larger than the array size. + /// + internal static string InvalidIndexForArrayProperty + { + get { return GetString("InvalidIndexForArrayProperty"); } + } + + /// + /// For operation '{0}' on array property at path '{1}', the index is larger than the array size. + /// + internal static string FormatInvalidIndexForArrayProperty(object p0, object p1) + { + return string.Format(CultureInfo.CurrentCulture, GetString("InvalidIndexForArrayProperty"), p0, p1); + } + + /// + /// The type '{0}' was malformed and could not be parsed. + /// + internal static string InvalidJsonPatchDocument + { + get { return GetString("InvalidJsonPatchDocument"); } + } + + /// + /// The type '{0}' was malformed and could not be parsed. + /// + internal static string FormatInvalidJsonPatchDocument(object p0) + { + return string.Format(CultureInfo.CurrentCulture, GetString("InvalidJsonPatchDocument"), p0); + } + + /// + /// For operation '{0}', the provided path is invalid for array property at path '{1}'. + /// + internal static string InvalidPathForArrayProperty + { + get { return GetString("InvalidPathForArrayProperty"); } + } + + /// + /// For operation '{0}', the provided path is invalid for array property at path '{1}'. + /// + internal static string FormatInvalidPathForArrayProperty(object p0, object p1) + { + return string.Format(CultureInfo.CurrentCulture, GetString("InvalidPathForArrayProperty"), p0, p1); + } + + /// + /// The provided string '{0}' is an invalid path. + /// + internal static string InvalidValueForPath + { + get { return GetString("InvalidValueForPath"); } + } + + /// + /// The provided string '{0}' is an invalid path. + /// + internal static string FormatInvalidValueForPath(object p0) + { + return string.Format(CultureInfo.CurrentCulture, GetString("InvalidValueForPath"), p0); + } + + /// + /// The value '{0}' is invalid for property at path '{1}'. + /// + internal static string InvalidValueForProperty + { + get { return GetString("InvalidValueForProperty"); } + } + + /// + /// The value '{0}' is invalid for property at path '{1}'. + /// + internal static string FormatInvalidValueForProperty(object p0, object p1) + { + return string.Format(CultureInfo.CurrentCulture, GetString("InvalidValueForProperty"), p0, p1); + } + + /// + /// For operation '{0}' on array property at path '{1}', the index is negative. + /// + internal static string NegativeIndexForArrayProperty + { + get { return GetString("NegativeIndexForArrayProperty"); } + } + + /// + /// For operation '{0}' on array property at path '{1}', the index is negative. + /// + internal static string FormatNegativeIndexForArrayProperty(object p0, object p1) + { + return string.Format(CultureInfo.CurrentCulture, GetString("NegativeIndexForArrayProperty"), p0, p1); + } + + /// + /// '{0}' must be of type '{1}'. + /// + internal static string ParameterMustMatchType + { + get { return GetString("ParameterMustMatchType"); } + } + + /// + /// '{0}' must be of type '{1}'. + /// + internal static string FormatParameterMustMatchType(object p0, object p1) + { + return string.Format(CultureInfo.CurrentCulture, GetString("ParameterMustMatchType"), p0, p1); + } + + /// + /// The property at path '{0}' could not be added. + /// + internal static string PropertyCannotBeAdded + { + get { return GetString("PropertyCannotBeAdded"); } + } + + /// + /// The property at path '{0}' could not be added. + /// + internal static string FormatPropertyCannotBeAdded(object p0) + { + return string.Format(CultureInfo.CurrentCulture, GetString("PropertyCannotBeAdded"), p0); + } + + /// + /// The property at path '{0}' could not be removed. + /// + internal static string PropertyCannotBeRemoved + { + get { return GetString("PropertyCannotBeRemoved"); } + } + + /// + /// The property at path '{0}' could not be removed. + /// + internal static string FormatPropertyCannotBeRemoved(object p0) + { + return string.Format(CultureInfo.CurrentCulture, GetString("PropertyCannotBeRemoved"), p0); + } + + /// + /// Property does not exist at path '{0}'. + /// + internal static string PropertyDoesNotExist + { + get { return GetString("PropertyDoesNotExist"); } + } + + /// + /// Property does not exist at path '{0}'. + /// + internal static string FormatPropertyDoesNotExist(object p0) + { + return string.Format(CultureInfo.CurrentCulture, GetString("PropertyDoesNotExist"), p0); + } + + /// + /// The test operation is not supported. + /// + internal static string TestOperationNotSupported + { + get { return GetString("TestOperationNotSupported"); } + } + + /// + /// The test operation is not supported. + /// + internal static string FormatTestOperationNotSupported() + { + return GetString("TestOperationNotSupported"); + } + + private static string GetString(string name, params string[] formatterNames) + { + var value = _resourceManager.GetString(name); + + System.Diagnostics.Debug.Assert(value != null); + + if (formatterNames != null) + { + for (var i = 0; i < formatterNames.Length; i++) + { + value = value.Replace("{" + formatterNames[i] + "}", "{" + i + "}"); + } + } + + return value; + } + } +} diff --git a/src/Microsoft.AspNet.JsonPatch/Resources.resx b/src/Microsoft.AspNet.JsonPatch/Resources.resx new file mode 100644 index 0000000000..59ae2b59c3 --- /dev/null +++ b/src/Microsoft.AspNet.JsonPatch/Resources.resx @@ -0,0 +1,165 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + The type of the property at path '{0}' could not be determined. + + + The property at '{0}' could not be read. + + + The property at path '{0}' could not be updated. + + + The key '{0}' was not found. + + + For operation '{0}' on array property at path '{1}', the index is larger than the array size. + + + The type '{0}' was malformed and could not be parsed. + + + For operation '{0}', the provided path is invalid for array property at path '{1}'. + + + The provided string '{0}' is an invalid path. + + + The value '{0}' is invalid for property at path '{1}'. + + + For operation '{0}' on array property at path '{1}', the index is negative. + + + '{0}' must be of type '{1}'. + + + The property at path '{0}' could not be added. + + + The property at path '{0}' could not be removed. + + + Property does not exist at path '{0}'. + + + The test operation is not supported. + + \ No newline at end of file diff --git a/src/Microsoft.AspNet.JsonPatch/project.json b/src/Microsoft.AspNet.JsonPatch/project.json new file mode 100644 index 0000000000..8d67ec1808 --- /dev/null +++ b/src/Microsoft.AspNet.JsonPatch/project.json @@ -0,0 +1,25 @@ +{ + "version": "1.0.0-*", + "repository": { + "type": "git", + "url": "git://github.com/aspnet/mvc" + }, + "dependencies": { + "Newtonsoft.Json": "6.0.6" + }, + "frameworks": { + "dnx451": { }, + "dnxcore50": { + "dependencies": { + "Microsoft.CSharp": "4.0.1-beta-*", + "System.Collections.Concurrent": "4.0.11-beta-*", + "System.ComponentModel.TypeConverter": "4.0.1-beta-*", + "System.Globalization": "4.0.11-beta-*", + "System.Reflection.Extensions": "4.0.1-beta-*", + "System.Resources.ResourceManager": "4.0.1-beta-*", + "System.Runtime.Extensions": "4.0.11-beta-*", + "System.Text.Encoding.Extensions": "4.0.11-beta-*" + } + } + } +} diff --git a/test/Microsoft.AspNet.JsonPatch.Test/Dynamic/AddOperationTests.cs b/test/Microsoft.AspNet.JsonPatch.Test/Dynamic/AddOperationTests.cs new file mode 100644 index 0000000000..3c2523c5fb --- /dev/null +++ b/test/Microsoft.AspNet.JsonPatch.Test/Dynamic/AddOperationTests.cs @@ -0,0 +1,569 @@ +// 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.Dynamic; +using Microsoft.AspNet.JsonPatch.Exceptions; +using Newtonsoft.Json; +using Xunit; + +namespace Microsoft.AspNet.JsonPatch.Test.Dynamic +{ + public class AddOperationTests + { + [Fact] + public void AddNewPropertyShouldFailIfRootIsNotAnExpandoObject() + { + dynamic doc = new + { + Test = 1 + }; + + // create patch + JsonPatchDocument patchDoc = new JsonPatchDocument(); + patchDoc.Add("NewInt", 1); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject(serialized); + + var exception = Assert.Throws(() => + { + deserialized.ApplyTo(doc); + }); + Assert.Equal( + "The property at path '/NewInt' could not be added.", + exception.Message); + } + + [Fact] + public void AddNewProperty() + { + dynamic obj = new ExpandoObject(); + obj.Test = 1; + + // create patch + JsonPatchDocument patchDoc = new JsonPatchDocument(); + patchDoc.Add("NewInt", 1); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject(serialized); + + deserialized.ApplyTo(obj); + + Assert.Equal(1, obj.NewInt); + Assert.Equal(1, obj.Test); + } + + [Fact] + public void AddNewPropertyToNestedAnonymousObjectShouldFail() + { + dynamic doc = new + { + Test = 1, + nested = new { } + }; + + // create patch + JsonPatchDocument patchDoc = new JsonPatchDocument(); + patchDoc.Add("Nested/NewInt", 1); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject(serialized); + + var exception = Assert.Throws(() => + { + deserialized.ApplyTo(doc); + }); + Assert.Equal( + "The property at path '/Nested/NewInt' could not be added.", + exception.Message); + } + + [Fact] + public void AddNewPropertyToTypedObjectShouldFail() + { + dynamic doc = new + { + Test = 1, + nested = new NestedDTO() + }; + + // create patch + JsonPatchDocument patchDoc = new JsonPatchDocument(); + patchDoc.Add("Nested/NewInt", 1); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject(serialized); + + var exception = Assert.Throws(() => + { + deserialized.ApplyTo(doc); + }); + Assert.Equal( + "The property at path '/Nested/NewInt' could not be added.", + exception.Message); + } + + [Fact] + public void AddToExistingPropertyOnNestedObject() + { + dynamic doc = new + { + Test = 1, + nested = new NestedDTO() + }; + + // create patch + JsonPatchDocument patchDoc = new JsonPatchDocument(); + patchDoc.Add("Nested/StringProperty", "A"); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject(serialized); + + deserialized.ApplyTo(doc); + + Assert.Equal("A", doc.nested.StringProperty); + Assert.Equal(1, doc.Test); + } + + [Fact] + public void AddNewPropertyToExpandoOject() + { + dynamic doc = new + { + Test = 1, + nested = new ExpandoObject() + }; + + // create patch + JsonPatchDocument patchDoc = new JsonPatchDocument(); + patchDoc.Add("Nested/NewInt", 1); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject(serialized); + + deserialized.ApplyTo(doc); + + Assert.Equal(1, doc.nested.NewInt); + Assert.Equal(1, doc.Test); + } + + [Fact] + public void AddNewPropertyToExpandoOjectInTypedObject() + { + var doc = new NestedDTO() + { + DynamicProperty = new ExpandoObject() + }; + + // create patch + JsonPatchDocument patchDoc = new JsonPatchDocument(); + patchDoc.Add("DynamicProperty/NewInt", 1); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject(serialized); + + deserialized.ApplyTo(doc); + + Assert.Equal(1, doc.DynamicProperty.NewInt); + } + + [Fact] + public void AddNewPropertyToTypedObjectInExpandoObject() + { + dynamic dynamicProperty = new ExpandoObject(); + dynamicProperty.StringProperty = "A"; + + var doc = new NestedDTO() + { + DynamicProperty = dynamicProperty + }; + + // create patch + JsonPatchDocument patchDoc = new JsonPatchDocument(); + patchDoc.Add("DynamicProperty/StringProperty", "B"); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject(serialized); + + deserialized.ApplyTo(doc); + + Assert.Equal("B", doc.DynamicProperty.StringProperty); + } + + [Fact] + public void AddNewPropertyToAnonymousObjectShouldFail() + { + dynamic doc = new + { + Test = 1 + }; + + dynamic valueToAdd = new { IntValue = 1, StringValue = "test", GuidValue = Guid.NewGuid() }; + + // create patch + JsonPatchDocument patchDoc = new JsonPatchDocument(); + patchDoc.Add("ComplexProperty", valueToAdd); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject(serialized); + + var exception = Assert.Throws(() => + { + deserialized.ApplyTo(doc); + }); + Assert.Equal( + "The property at path '/ComplexProperty' could not be added.", + exception.Message); + } + + [Fact] + public void AddResultsReplaceShouldFailOnAnonymousDueToNoSetter() + { + var doc = new + { + StringProperty = "A" + }; + + // create patch + JsonPatchDocument patchDoc = new JsonPatchDocument(); + patchDoc.Add("StringProperty", "B"); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject(serialized); + + var exception = Assert.Throws(() => + { + deserialized.ApplyTo(doc); + }); + Assert.Equal( + "The property at path '/StringProperty' could not be updated.", + exception.Message); + } + + [Fact] + public void AddResultsShouldReplace() + { + dynamic doc = new ExpandoObject(); + doc.StringProperty = "A"; + + // create patch + JsonPatchDocument patchDoc = new JsonPatchDocument(); + patchDoc.Add("StringProperty", "B"); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject(serialized); + + deserialized.ApplyTo(doc); + + Assert.Equal("B", doc.StringProperty); + } + + [Fact] + public void AddResultsShouldReplaceInNested() + { + dynamic doc = new ExpandoObject(); + doc.InBetweenFirst = new ExpandoObject(); + doc.InBetweenFirst.InBetweenSecond = new ExpandoObject(); + doc.InBetweenFirst.InBetweenSecond.StringProperty = "A"; + + // create patch + JsonPatchDocument patchDoc = new JsonPatchDocument(); + patchDoc.Add("/InBetweenFirst/InBetweenSecond/StringProperty", "B"); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject(serialized); + + deserialized.ApplyTo(doc); + + Assert.Equal("B", doc.InBetweenFirst.InBetweenSecond.StringProperty); + } + + [Fact] + public void AddResultsShouldReplaceInNestedInDynamic() + { + dynamic doc = new ExpandoObject(); + doc.Nested = new NestedDTO(); + doc.Nested.DynamicProperty = new ExpandoObject(); + doc.Nested.DynamicProperty.InBetweenFirst = new ExpandoObject(); + doc.Nested.DynamicProperty.InBetweenFirst.InBetweenSecond = new ExpandoObject(); + doc.Nested.DynamicProperty.InBetweenFirst.InBetweenSecond.StringProperty = "A"; + + // create patch + JsonPatchDocument patchDoc = new JsonPatchDocument(); + patchDoc.Add("/Nested/DynamicProperty/InBetweenFirst/InBetweenSecond/StringProperty", "B"); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject(serialized); + + deserialized.ApplyTo(doc); + + Assert.Equal("B", doc.Nested.DynamicProperty.InBetweenFirst.InBetweenSecond.StringProperty); + } + + [Fact] + public void ShouldNotBeAbleToAddToNonExistingPropertyThatIsNotTheRoot() + { + //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. + + var doc = new NestedDTO() + { + DynamicProperty = new ExpandoObject() + }; + + // create patch + JsonPatchDocument patchDoc = new JsonPatchDocument(); + patchDoc.Add("DynamicProperty/OtherProperty/IntProperty", 1); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject(serialized); + + var exception = Assert.Throws(() => + { + deserialized.ApplyTo(doc); + }); + Assert.Equal( + "The property at path '/DynamicProperty/OtherProperty/IntProperty' could not be added.", + exception.Message); + } + + [Fact] + public void ShouldNotBeAbleToAddToNonExistingPropertyInNestedPropertyThatIsNotTheRoot() + { + //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. + + var doc = new + { + Foo = "bar" + }; + + // create patch + JsonPatchDocument patchDoc = new JsonPatchDocument(); + patchDoc.Add("baz/bat", "qux"); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject(serialized); + + var exception = Assert.Throws(() => + { + deserialized.ApplyTo(doc); + }); + Assert.Equal( + "The property at path '/baz/bat' could not be added.", + exception.Message); + } + + [Fact] + public void ShouldReplacePropertyWithDifferentCase() + { + dynamic doc = new ExpandoObject(); + doc.StringProperty = "A"; + + // create patch + JsonPatchDocument patchDoc = new JsonPatchDocument(); + patchDoc.Add("stringproperty", "B"); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject(serialized); + + deserialized.ApplyTo(doc); + + Assert.Equal("B", doc.StringProperty); + } + + [Fact] + public void AddToList() + { + var doc = new + { + IntegerList = new List() { 1, 2, 3 } + }; + + // create patch + JsonPatchDocument patchDoc = new JsonPatchDocument(); + patchDoc.Add("IntegerList/0", 4); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject(serialized); + + deserialized.ApplyTo(doc); + + Assert.Equal(new List() { 4, 1, 2, 3 }, doc.IntegerList); + } + + [Fact] + public void AddToListNegativePosition() + { + dynamic doc = new ExpandoObject(); + doc.IntegerList = new List() { 1, 2, 3 }; + + // create patch + JsonPatchDocument patchDoc = new JsonPatchDocument(); + patchDoc.Add("IntegerList/-1", 4); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject(serialized); + + var exception = Assert.Throws(() => + { + deserialized.ApplyTo(doc); + }); + Assert.Equal( + "For operation 'add' on array property at path '/IntegerList/-1', the index is negative.", + exception.Message); + } + + [Fact] + public void ShouldAddToListWithDifferentCase() + { + var doc = new + { + IntegerList = new List() { 1, 2, 3 } + }; + + // create patch + JsonPatchDocument patchDoc = new JsonPatchDocument(); + patchDoc.Add("integerlist/0", 4); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject(serialized); + + deserialized.ApplyTo(doc); + + Assert.Equal(new List() { 4, 1, 2, 3 }, doc.IntegerList); + } + + [Fact] + public void AddToListInvalidPositionTooLarge() + { + var doc = new + { + IntegerList = new List() { 1, 2, 3 } + }; + + // create patch + JsonPatchDocument patchDoc = new JsonPatchDocument(); + patchDoc.Add("IntegerList/4", 4); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject(serialized); + + var exception = Assert.Throws(() => + { + deserialized.ApplyTo(doc); + }); + Assert.Equal( + "For operation 'add' on array property at path '/IntegerList/4', the index is larger than the array size.", + exception.Message); + } + + [Fact] + public void AddToListAtEndWithSerialization() + { + var doc = new + { + IntegerList = new List() { 1, 2, 3 } + }; + + // create patch + JsonPatchDocument patchDoc = new JsonPatchDocument(); + patchDoc.Add("IntegerList/3", 4); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject(serialized); + + deserialized.ApplyTo(doc); + + Assert.Equal(new List() { 1, 2, 3, 4 }, doc.IntegerList); + } + + [Fact] + public void AddToListAtBeginning() + { + var doc = new + { + IntegerList = new List() { 1, 2, 3 } + }; + + // create patch + JsonPatchDocument patchDoc = new JsonPatchDocument(); + patchDoc.Add("IntegerList/0", 4); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject(serialized); + + deserialized.ApplyTo(doc); + + Assert.Equal(new List() { 4, 1, 2, 3 }, doc.IntegerList); + } + + [Fact] + public void AddToListInvalidPositionTooSmall() + { + var doc = new + { + IntegerList = new List() { 1, 2, 3 } + }; + + // create patch + JsonPatchDocument patchDoc = new JsonPatchDocument(); + patchDoc.Add("IntegerList/-1", 4); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject(serialized); + + var exception = Assert.Throws(() => + { + deserialized.ApplyTo(doc); + }); + Assert.Equal( + "For operation 'add' on array property at path '/IntegerList/-1', the index is negative.", + exception.Message); + } + + [Fact] + public void AddToListAppend() + { + var doc = new + { + IntegerList = new List() { 1, 2, 3 } + }; + + // create patch + JsonPatchDocument patchDoc = new JsonPatchDocument(); + patchDoc.Add("IntegerList/-", 4); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject(serialized); + + deserialized.ApplyTo(doc); + + Assert.Equal(new List() { 1, 2, 3, 4 }, doc.IntegerList); + } + } +} \ No newline at end of file diff --git a/test/Microsoft.AspNet.JsonPatch.Test/Dynamic/AddTypedOperationTests.cs b/test/Microsoft.AspNet.JsonPatch.Test/Dynamic/AddTypedOperationTests.cs new file mode 100644 index 0000000000..4d2e8c646d --- /dev/null +++ b/test/Microsoft.AspNet.JsonPatch.Test/Dynamic/AddTypedOperationTests.cs @@ -0,0 +1,121 @@ +// 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.AspNet.JsonPatch.Exceptions; +using Newtonsoft.Json; +using Xunit; + +namespace Microsoft.AspNet.JsonPatch.Test.Dynamic +{ + public class AddTypedOperationTests + { + [Fact] + public void AddToListNegativePosition() + { + var doc = new SimpleDTO() + { + IntegerList = new List() { 1, 2, 3 } + }; + + // create patch + JsonPatchDocument patchDoc = new JsonPatchDocument(); + patchDoc.Add("IntegerList/-1", 4); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject(serialized); + + var exception = Assert.Throws(() => + { + deserialized.ApplyTo(doc); + }); + Assert.Equal( + "For operation 'add' on array property at path '/IntegerList/-1', the index is negative.", + exception.Message); + } + + [Fact] + public void AddToListInList() + { + var doc = new SimpleDTOWithNestedDTO() + { + ListOfSimpleDTO = new List() + { + new SimpleDTO() + { + IntegerList = new List() { 1, 2, 3 } + } + } + }; + + // create patch + JsonPatchDocument patchDoc = new JsonPatchDocument(); + patchDoc.Add("ListOfSimpleDTO/0/IntegerList/0", 4); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject(serialized); + + deserialized.ApplyTo(doc); + Assert.Equal(new List() { 4, 1, 2, 3 }, doc.ListOfSimpleDTO[0].IntegerList); + } + + [Fact] + public void AddToListInListInvalidPositionTooSmall() + { + var doc = new SimpleDTOWithNestedDTO() + { + ListOfSimpleDTO = new List() + { + new SimpleDTO() + { + IntegerList = new List() { 1, 2, 3 } + } + } + }; + + // create patch + JsonPatchDocument patchDoc = new JsonPatchDocument(); + patchDoc.Add("ListOfSimpleDTO/-1/IntegerList/0", 4); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject(serialized); + + var exception = Assert.Throws(() => + { + deserialized.ApplyTo(doc); + }); + Assert.Equal( + "The property at path '/ListOfSimpleDTO/-1/IntegerList/0' could not be added.", + exception.Message); + } + + [Fact] + public void AddToListInListInvalidPositionTooLarge() + { + var doc = new SimpleDTOWithNestedDTO() + { + ListOfSimpleDTO = new List() + { + new SimpleDTO() + { + IntegerList = new List() { 1, 2, 3 } + } + } + }; + // create patch + JsonPatchDocument patchDoc = new JsonPatchDocument(); + patchDoc.Add("ListOfSimpleDTO/20/IntegerList/0", 4); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject(serialized); + + var exception = Assert.Throws(() => + { + deserialized.ApplyTo(doc); + }); + Assert.Equal( + "The property at path '/ListOfSimpleDTO/20/IntegerList/0' could not be added.", + exception.Message); + } + } +} diff --git a/test/Microsoft.AspNet.JsonPatch.Test/Dynamic/CopyOperationTests.cs b/test/Microsoft.AspNet.JsonPatch.Test/Dynamic/CopyOperationTests.cs new file mode 100644 index 0000000000..3fa546faac --- /dev/null +++ b/test/Microsoft.AspNet.JsonPatch.Test/Dynamic/CopyOperationTests.cs @@ -0,0 +1,245 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System.Collections.Generic; +using System.Dynamic; +using Newtonsoft.Json; +using Xunit; + +namespace Microsoft.AspNet.JsonPatch.Test.Dynamic +{ + public class CopyOperationTests + { + [Fact] + public void Copy() + { + dynamic doc = new ExpandoObject(); + + doc.StringProperty = "A"; + doc.AnotherStringProperty = "B"; + + JsonPatchDocument patchDoc = new JsonPatchDocument(); + patchDoc.Copy("StringProperty", "AnotherStringProperty"); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject(serialized); + deserialized.ApplyTo(doc); + + Assert.Equal("A", doc.AnotherStringProperty); + } + + [Fact] + public void CopyInList() + { + dynamic doc = new ExpandoObject(); + doc.IntegerList = new List() { 1, 2, 3 }; + + // create patch + JsonPatchDocument patchDoc = new JsonPatchDocument(); + patchDoc.Copy("IntegerList/0", "IntegerList/1"); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject(serialized); + + deserialized.ApplyTo(doc); + + Assert.Equal(new List() { 1, 1, 2, 3 }, doc.IntegerList); + } + + [Fact] + public void CopyFromListToEndOfList() + { + dynamic doc = new ExpandoObject(); + doc.IntegerList = new List() { 1, 2, 3 }; + + // create patch + JsonPatchDocument patchDoc = new JsonPatchDocument(); + patchDoc.Copy("IntegerList/0", "IntegerList/-"); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject(serialized); + deserialized.ApplyTo(doc); + + Assert.Equal(new List() { 1, 2, 3, 1 }, doc.IntegerList); + } + + [Fact] + public void CopyFromListToNonList() + { + dynamic doc = new ExpandoObject(); + doc.IntegerList = new List() { 1, 2, 3 }; + + // create patch + JsonPatchDocument patchDoc = new JsonPatchDocument(); + patchDoc.Copy("IntegerList/0", "IntegerValue"); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject(serialized); + + deserialized.ApplyTo(doc); + + Assert.Equal(1, doc.IntegerValue); + } + + [Fact] + public void CopyFromNonListToList() + { + dynamic doc = new ExpandoObject(); + doc.IntegerValue = 5; + doc.IntegerList = new List() { 1, 2, 3 }; + + // create patch + JsonPatchDocument patchDoc = new JsonPatchDocument(); + patchDoc.Copy("IntegerValue", "IntegerList/0"); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject(serialized); + deserialized.ApplyTo(doc); + + Assert.Equal(new List() { 5, 1, 2, 3 }, doc.IntegerList); + } + + [Fact] + public void CopyToEndOfList() + { + dynamic doc = new ExpandoObject(); + doc.IntegerValue = 5; + doc.IntegerList = new List() { 1, 2, 3 }; + + // create patch + JsonPatchDocument patchDoc = new JsonPatchDocument(); + patchDoc.Copy("IntegerValue", "IntegerList/-"); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject(serialized); + + deserialized.ApplyTo(doc); + + Assert.Equal(new List() { 1, 2, 3, 5 }, doc.IntegerList); + } + + [Fact] + public void NestedCopy() + { + dynamic doc = new ExpandoObject(); + doc.SimpleDTO = new SimpleDTO() + { + StringProperty = "A", + AnotherStringProperty = "B" + }; + + // create patch + JsonPatchDocument patchDoc = new JsonPatchDocument(); + patchDoc.Copy("SimpleDTO/StringProperty", "SimpleDTO/AnotherStringProperty"); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject(serialized); + + deserialized.ApplyTo(doc); + + Assert.Equal("A", doc.SimpleDTO.AnotherStringProperty); + } + + [Fact] + public void NestedCopyInList() + { + dynamic doc = new ExpandoObject(); + doc.SimpleDTO = new SimpleDTO() + { + IntegerList = new List() { 1, 2, 3 } + }; + + // create patch + JsonPatchDocument patchDoc = new JsonPatchDocument(); + patchDoc.Copy("SimpleDTO/IntegerList/0", "SimpleDTO/IntegerList/1"); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject(serialized); + deserialized.ApplyTo(doc); + + Assert.Equal(new List() { 1, 1, 2, 3 }, doc.SimpleDTO.IntegerList); + } + + [Fact] + public void NestedCopyFromListToEndOfList() + { + dynamic doc = new ExpandoObject(); + doc.SimpleDTO = new SimpleDTO() + { + IntegerList = new List() { 1, 2, 3 } + }; + + // create patch + JsonPatchDocument patchDoc = new JsonPatchDocument(); + patchDoc.Copy("SimpleDTO/IntegerList/0", "SimpleDTO/IntegerList/-"); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject(serialized); + + deserialized.ApplyTo(doc); + + Assert.Equal(new List() { 1, 2, 3, 1 }, doc.SimpleDTO.IntegerList); + } + + [Fact] + public void NestedCopyFromListToNonList() + { + dynamic doc = new ExpandoObject(); + doc.SimpleDTO = new SimpleDTO() + { + IntegerList = new List() { 1, 2, 3 } + }; + + // create patch + JsonPatchDocument patchDoc = new JsonPatchDocument(); + patchDoc.Copy("SimpleDTO/IntegerList/0", "SimpleDTO/IntegerValue"); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject(serialized); + deserialized.ApplyTo(doc); + + Assert.Equal(1, doc.SimpleDTO.IntegerValue); + } + + [Fact] + public void NestedCopyFromNonListToList() + { + dynamic doc = new ExpandoObject(); + doc.SimpleDTO = new SimpleDTO() + { + IntegerValue = 5, + IntegerList = new List() { 1, 2, 3 } + }; + + // create patch + JsonPatchDocument patchDoc = new JsonPatchDocument(); + patchDoc.Copy("SimpleDTO/IntegerValue", "SimpleDTO/IntegerList/0"); + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject(serialized); + deserialized.ApplyTo(doc); + + Assert.Equal(new List() { 5, 1, 2, 3 }, doc.SimpleDTO.IntegerList); + } + + [Fact] + public void NestedCopyToEndOfList() + { + dynamic doc = new ExpandoObject(); + doc.SimpleDTO = new SimpleDTO() + { + IntegerValue = 5, + IntegerList = new List() { 1, 2, 3 } + }; + + // create patch + JsonPatchDocument patchDoc = new JsonPatchDocument(); + patchDoc.Copy("SimpleDTO/IntegerValue", "SimpleDTO/IntegerList/-"); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject(serialized); + deserialized.ApplyTo(doc); + + Assert.Equal(new List() { 1, 2, 3, 5 }, doc.SimpleDTO.IntegerList); + } + } +} diff --git a/test/Microsoft.AspNet.JsonPatch.Test/Dynamic/CopyTypedOperationTests.cs b/test/Microsoft.AspNet.JsonPatch.Test/Dynamic/CopyTypedOperationTests.cs new file mode 100644 index 0000000000..5b015416ac --- /dev/null +++ b/test/Microsoft.AspNet.JsonPatch.Test/Dynamic/CopyTypedOperationTests.cs @@ -0,0 +1,268 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System.Collections.Generic; +using Newtonsoft.Json; +using Xunit; + +namespace Microsoft.AspNet.JsonPatch.Test.Dynamic +{ + public class CopyTypedOperationTests + { + [Fact] + public void Copy() + { + var doc = new SimpleDTO() + { + StringProperty = "A", + AnotherStringProperty = "B" + }; + + // create patch + JsonPatchDocument patchDoc = new JsonPatchDocument(); + patchDoc.Copy("StringProperty", "AnotherStringProperty"); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject(serialized); + deserialized.ApplyTo(doc); + + Assert.Equal("A", doc.AnotherStringProperty); + } + + [Fact] + public void CopyInList() + { + var doc = new SimpleDTO() + { + IntegerList = new List() { 1, 2, 3 } + }; + + // create patch + JsonPatchDocument patchDoc = new JsonPatchDocument(); + patchDoc.Copy("IntegerList/0", "IntegerList/1"); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject(serialized); + + deserialized.ApplyTo(doc); + + Assert.Equal(new List() { 1, 1, 2, 3 }, doc.IntegerList); + } + + [Fact] + public void CopyFromListToEndOfList() + { + var doc = new SimpleDTO() + { + IntegerList = new List() { 1, 2, 3 } + }; + + // create patch + JsonPatchDocument patchDoc = new JsonPatchDocument(); + patchDoc.Copy("IntegerList/0", "IntegerList/-"); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject(serialized); + deserialized.ApplyTo(doc); + + Assert.Equal(new List() { 1, 2, 3, 1 }, doc.IntegerList); + } + + [Fact] + public void CopyFromListToNonList() + { + var doc = new SimpleDTO() + { + IntegerList = new List() { 1, 2, 3 } + }; + + // create patch + JsonPatchDocument patchDoc = new JsonPatchDocument(); + patchDoc.Copy("IntegerList/0", "IntegerValue"); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject(serialized); + + deserialized.ApplyTo(doc); + + Assert.Equal(1, doc.IntegerValue); + } + + [Fact] + public void CopyFromNonListToList() + { + var doc = new SimpleDTO() + { + IntegerValue = 5, + IntegerList = new List() { 1, 2, 3 } + }; + + // create patch + JsonPatchDocument patchDoc = new JsonPatchDocument(); + patchDoc.Copy("IntegerValue", "IntegerList/0"); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject(serialized); + deserialized.ApplyTo(doc); + + Assert.Equal(new List() { 5, 1, 2, 3 }, doc.IntegerList); + } + + [Fact] + public void CopyToEndOfList() + { + var doc = new SimpleDTO() + { + IntegerValue = 5, + IntegerList = new List() { 1, 2, 3 } + }; + + // create patch + JsonPatchDocument patchDoc = new JsonPatchDocument(); + patchDoc.Copy("IntegerValue", "IntegerList/-"); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject(serialized); + + deserialized.ApplyTo(doc); + + Assert.Equal(new List() { 1, 2, 3, 5 }, doc.IntegerList); + } + + [Fact] + public void NestedCopy() + { + var doc = new SimpleDTOWithNestedDTO() + { + SimpleDTO = new SimpleDTO() + { + StringProperty = "A", + AnotherStringProperty = "B" + } + }; + + // create patch + JsonPatchDocument patchDoc = new JsonPatchDocument(); + patchDoc.Copy("SimpleDTO/StringProperty", "SimpleDTO/AnotherStringProperty"); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject(serialized); + + deserialized.ApplyTo(doc); + + Assert.Equal("A", doc.SimpleDTO.AnotherStringProperty); + } + + [Fact] + public void NestedCopyInList() + { + var doc = new SimpleDTOWithNestedDTO() + { + SimpleDTO = new SimpleDTO() + { + IntegerList = new List() { 1, 2, 3 } + } + }; + + // create patch + JsonPatchDocument patchDoc = new JsonPatchDocument(); + patchDoc.Copy("SimpleDTO/IntegerList/0", "SimpleDTO/IntegerList/1"); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject(serialized); + deserialized.ApplyTo(doc); + + Assert.Equal(new List() { 1, 1, 2, 3 }, doc.SimpleDTO.IntegerList); + } + + [Fact] + public void NestedCopyFromListToEndOfList() + { + var doc = new SimpleDTOWithNestedDTO() + { + SimpleDTO = new SimpleDTO() + { + IntegerList = new List() { 1, 2, 3 } + } + }; + + // create patch + JsonPatchDocument patchDoc = new JsonPatchDocument(); + patchDoc.Copy("SimpleDTO/IntegerList/0", "SimpleDTO/IntegerList/-"); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject(serialized); + + deserialized.ApplyTo(doc); + + Assert.Equal(new List() { 1, 2, 3, 1 }, doc.SimpleDTO.IntegerList); + } + + [Fact] + public void NestedCopyFromListToNonList() + { + var doc = new SimpleDTOWithNestedDTO() + { + SimpleDTO = new SimpleDTO() + { + IntegerList = new List() { 1, 2, 3 } + } + }; + + // create patch + JsonPatchDocument patchDoc = new JsonPatchDocument(); + patchDoc.Copy("SimpleDTO/IntegerList/0", "SimpleDTO/IntegerValue"); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject(serialized); + deserialized.ApplyTo(doc); + + Assert.Equal(1, doc.SimpleDTO.IntegerValue); + } + + [Fact] + public void NestedCopyFromNonListToList() + { + var doc = new SimpleDTOWithNestedDTO() + { + SimpleDTO = new SimpleDTO() + { + IntegerValue = 5, + IntegerList = new List() { 1, 2, 3 } + } + }; + + // create patch + JsonPatchDocument patchDoc = new JsonPatchDocument(); + patchDoc.Copy("SimpleDTO/IntegerValue", "SimpleDTO/IntegerList/0"); + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject(serialized); + deserialized.ApplyTo(doc); + + Assert.Equal(new List() { 5, 1, 2, 3 }, doc.SimpleDTO.IntegerList); + } + + [Fact] + public void NestedCopyToEndOfList() + { + var doc = new SimpleDTOWithNestedDTO() + { + SimpleDTO = new SimpleDTO() + { + IntegerValue = 5, + IntegerList = new List() { 1, 2, 3 } + } + }; + + // create patch + JsonPatchDocument patchDoc = new JsonPatchDocument(); + patchDoc.Copy("SimpleDTO/IntegerValue", "SimpleDTO/IntegerList/-"); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject(serialized); + deserialized.ApplyTo(doc); + + Assert.Equal(new List() { 1, 2, 3, 5 }, doc.SimpleDTO.IntegerList); + } + } +} diff --git a/test/Microsoft.AspNet.JsonPatch.Test/Dynamic/MoveOperationTests.cs b/test/Microsoft.AspNet.JsonPatch.Test/Dynamic/MoveOperationTests.cs new file mode 100644 index 0000000000..dea2b6ee32 --- /dev/null +++ b/test/Microsoft.AspNet.JsonPatch.Test/Dynamic/MoveOperationTests.cs @@ -0,0 +1,338 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System.Collections.Generic; +using System.Dynamic; +using Newtonsoft.Json; +using Xunit; + +namespace Microsoft.AspNet.JsonPatch.Test.Dynamic +{ + public class MoveOperationTests + { + [Fact] + public void Move() + { + dynamic doc = new ExpandoObject(); + doc.StringProperty = "A"; + doc.AnotherStringProperty = "B"; + + // create patch + JsonPatchDocument patchDoc = new JsonPatchDocument(); + patchDoc.Move("StringProperty", "AnotherStringProperty"); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject(serialized); + + deserialized.ApplyTo(doc); + + Assert.Equal("A", doc.AnotherStringProperty); + + var cont = doc as IDictionary; + object valueFromDictionary; + cont.TryGetValue("StringProperty", out valueFromDictionary); + Assert.Null(valueFromDictionary); + } + + [Fact] + public void MoveToNonExisting() + { + dynamic doc = new ExpandoObject(); + doc.StringProperty = "A"; + + // create patch + JsonPatchDocument patchDoc = new JsonPatchDocument(); + patchDoc.Move("StringProperty", "AnotherStringProperty"); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject(serialized); + + deserialized.ApplyTo(doc); + + Assert.Equal("A", doc.AnotherStringProperty); + + var cont = doc as IDictionary; + object valueFromDictionary; + cont.TryGetValue("StringProperty", out valueFromDictionary); + Assert.Null(valueFromDictionary); + } + + [Fact] + public void MoveDynamicToTyped() + { + dynamic doc = new ExpandoObject(); + doc.StringProperty = "A"; + doc.SimpleDTO = new SimpleDTO() { AnotherStringProperty = "B" }; + + // create patch + JsonPatchDocument patchDoc = new JsonPatchDocument(); + patchDoc.Move("StringProperty", "SimpleDTO/AnotherStringProperty"); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject(serialized); + + deserialized.ApplyTo(doc); + + Assert.Equal("A", doc.SimpleDTO.AnotherStringProperty); + + var cont = doc as IDictionary; + object valueFromDictionary; + cont.TryGetValue("StringProperty", out valueFromDictionary); + Assert.Null(valueFromDictionary); + } + + [Fact] + public void MoveTypedToDynamic() + { + dynamic doc = new ExpandoObject(); + doc.StringProperty = "A"; + doc.SimpleDTO = new SimpleDTO() { AnotherStringProperty = "B" }; + + // create patch + JsonPatchDocument patchDoc = new JsonPatchDocument(); + patchDoc.Move("SimpleDTO/AnotherStringProperty", "StringProperty"); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject(serialized); + + deserialized.ApplyTo(doc); + + Assert.Equal("B", doc.StringProperty); + Assert.Equal(null, doc.SimpleDTO.AnotherStringProperty); + } + + [Fact] + public void NestedMove() + { + dynamic doc = new ExpandoObject(); + doc.Nested = new SimpleDTO() + { + StringProperty = "A", + AnotherStringProperty = "B" + }; + + // create patch + JsonPatchDocument patchDoc = new JsonPatchDocument(); + patchDoc.Move("Nested/StringProperty", "Nested/AnotherStringProperty"); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject(serialized); + + deserialized.ApplyTo(doc); + + Assert.Equal("A", doc.Nested.AnotherStringProperty); + Assert.Equal(null, doc.Nested.StringProperty); + } + + [Fact] + public void MoveInList() + { + dynamic doc = new ExpandoObject(); + doc.IntegerList = new List() { 1, 2, 3 }; + + // create patch + JsonPatchDocument patchDoc = new JsonPatchDocument(); + patchDoc.Move("IntegerList/0", "IntegerList/1"); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject(serialized); + + deserialized.ApplyTo(doc); + + Assert.Equal(new List() { 2, 1, 3 }, doc.IntegerList); + } + + [Fact] + public void NestedMoveInList() + { + dynamic doc = new ExpandoObject(); + doc.Nested = new SimpleDTO() + { + IntegerList = new List() { 1, 2, 3 } + }; + + // create patch + JsonPatchDocument patchDoc = new JsonPatchDocument(); + patchDoc.Move("Nested/IntegerList/0", "Nested/IntegerList/1"); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject(serialized); + + deserialized.ApplyTo(doc); + + Assert.Equal(new List() { 2, 1, 3 }, doc.Nested.IntegerList); + } + + [Fact] + public void MoveFromListToEndOfList() + { + dynamic doc = new ExpandoObject(); + doc.IntegerList = new List() { 1, 2, 3 }; + + // create patch + JsonPatchDocument patchDoc = new JsonPatchDocument(); + patchDoc.Move("IntegerList/0", "IntegerList/-"); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject(serialized); + deserialized.ApplyTo(doc); + + Assert.Equal(new List() { 2, 3, 1 }, doc.IntegerList); + } + + [Fact] + public void NestedMoveFromListToEndOfList() + { + dynamic doc = new ExpandoObject(); + doc.Nested = new SimpleDTO() + { + IntegerList = new List() { 1, 2, 3 } + }; + + // create patch + JsonPatchDocument patchDoc = new JsonPatchDocument(); + patchDoc.Move("Nested/IntegerList/0", "Nested/IntegerList/-"); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject(serialized); + deserialized.ApplyTo(doc); + + Assert.Equal(new List() { 2, 3, 1 }, doc.Nested.IntegerList); + } + + [Fact] + public void MoveFomListToNonList() + { + dynamic doc = new ExpandoObject(); + doc.IntegerList = new List() { 1, 2, 3 }; + + // create patch + JsonPatchDocument patchDoc = new JsonPatchDocument(); + patchDoc.Move("IntegerList/0", "IntegerValue"); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject(serialized); + + deserialized.ApplyTo(doc); + + Assert.Equal(new List() { 2, 3 }, doc.IntegerList); + Assert.Equal(1, doc.IntegerValue); + } + + [Fact] + public void NestedMoveFomListToNonList() + { + dynamic doc = new ExpandoObject(); + doc.Nested = new SimpleDTO() + { + IntegerList = new List() { 1, 2, 3 } + }; + + // create patch + JsonPatchDocument patchDoc = new JsonPatchDocument(); + patchDoc.Move("Nested/IntegerList/0", "Nested/IntegerValue"); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject(serialized); + + deserialized.ApplyTo(doc); + + Assert.Equal(new List() { 2, 3 }, doc.Nested.IntegerList); + Assert.Equal(1, doc.Nested.IntegerValue); + } + + [Fact] + public void MoveFromNonListToList() + { + dynamic doc = new ExpandoObject(); + doc.IntegerValue = 5; + doc.IntegerList = new List() { 1, 2, 3 }; + + // create patch + JsonPatchDocument patchDoc = new JsonPatchDocument(); + patchDoc.Move("IntegerValue", "IntegerList/0"); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject(serialized); + + deserialized.ApplyTo(doc); + + var cont = doc as IDictionary; + object valueFromDictionary; + cont.TryGetValue("IntegerValue", out valueFromDictionary); + Assert.Null(valueFromDictionary); + + Assert.Equal(new List() { 5, 1, 2, 3 }, doc.IntegerList); + } + + [Fact] + public void NestedMoveFromNonListToList() + { + dynamic doc = new ExpandoObject(); + doc.Nested = new SimpleDTO() + { + IntegerValue = 5, + IntegerList = new List() { 1, 2, 3 } + }; + + // create patch + JsonPatchDocument patchDoc = new JsonPatchDocument(); + patchDoc.Move("Nested/IntegerValue", "Nested/IntegerList/0"); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject(serialized); + + deserialized.ApplyTo(doc); + + Assert.Equal(0, doc.Nested.IntegerValue); + Assert.Equal(new List() { 5, 1, 2, 3 }, doc.Nested.IntegerList); + } + + [Fact] + public void MoveToEndOfList() + { + dynamic doc = new ExpandoObject(); + doc.IntegerValue = 5; + doc.IntegerList = new List() { 1, 2, 3 }; + + // create patch + JsonPatchDocument patchDoc = new JsonPatchDocument(); + patchDoc.Move("IntegerValue", "IntegerList/-"); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject(serialized); + + deserialized.ApplyTo(doc); + + var cont = doc as IDictionary; + object valueFromDictionary; + cont.TryGetValue("IntegerValue", out valueFromDictionary); + Assert.Null(valueFromDictionary); + + Assert.Equal(new List() { 1, 2, 3, 5 }, doc.IntegerList); + } + + [Fact] + public void NestedMoveToEndOfList() + { + dynamic doc = new ExpandoObject(); + doc.Nested = new SimpleDTO() + { + IntegerValue = 5, + IntegerList = new List() { 1, 2, 3 } + }; + + // create patch + JsonPatchDocument patchDoc = new JsonPatchDocument(); + patchDoc.Move("Nested/IntegerValue", "Nested/IntegerList/-"); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject(serialized); + + deserialized.ApplyTo(doc); + + Assert.Equal(0, doc.Nested.IntegerValue); + Assert.Equal(new List() { 1, 2, 3, 5 }, doc.Nested.IntegerList); + } + } +} diff --git a/test/Microsoft.AspNet.JsonPatch.Test/Dynamic/MoveTypedOperationTests.cs b/test/Microsoft.AspNet.JsonPatch.Test/Dynamic/MoveTypedOperationTests.cs new file mode 100644 index 0000000000..3d356a3401 --- /dev/null +++ b/test/Microsoft.AspNet.JsonPatch.Test/Dynamic/MoveTypedOperationTests.cs @@ -0,0 +1,138 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System.Collections.Generic; +using Newtonsoft.Json; +using Xunit; + +namespace Microsoft.AspNet.JsonPatch.Test.Dynamic +{ + public class MoveTypedOperationTests + { + [Fact] + public void Move() + { + var doc = new SimpleDTO() + { + StringProperty = "A", + AnotherStringProperty = "B" + }; + + // create patch + JsonPatchDocument patchDoc = new JsonPatchDocument(); + patchDoc.Move("StringProperty", "AnotherStringProperty"); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject(serialized); + + deserialized.ApplyTo(doc); + + Assert.Equal("A", doc.AnotherStringProperty); + Assert.Equal(null, doc.StringProperty); + } + + [Fact] + public void MoveInList() + { + var doc = new SimpleDTO() + { + IntegerList = new List() { 1, 2, 3 } + }; + + // create patch + JsonPatchDocument patchDoc = new JsonPatchDocument(); + patchDoc.Move("IntegerList/0", "IntegerList/1"); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject(serialized); + + deserialized.ApplyTo(doc); + + Assert.Equal(new List() { 2, 1, 3 }, doc.IntegerList); + } + + [Fact] + public void MoveFromListToEndOfList() + { + var doc = new SimpleDTO() + { + IntegerList = new List() { 1, 2, 3 } + }; + + // create patch + JsonPatchDocument patchDoc = new JsonPatchDocument(); + patchDoc.Move("IntegerList/0", "IntegerList/-"); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject(serialized); + deserialized.ApplyTo(doc); + + Assert.Equal(new List() { 2, 3, 1 }, doc.IntegerList); + } + + [Fact] + public void MoveFomListToNonList() + { + var doc = new SimpleDTO() + { + IntegerList = new List() { 1, 2, 3 } + }; + + // create patch + JsonPatchDocument patchDoc = new JsonPatchDocument(); + patchDoc.Move("IntegerList/0", "IntegerValue"); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject(serialized); + + deserialized.ApplyTo(doc); + + Assert.Equal(new List() { 2, 3 }, doc.IntegerList); + Assert.Equal(1, doc.IntegerValue); + } + + [Fact] + public void MoveFromNonListToList() + { + var doc = new SimpleDTO() + { + IntegerValue = 5, + IntegerList = new List() { 1, 2, 3 } + }; + + // create patch + JsonPatchDocument patchDoc = new JsonPatchDocument(); + patchDoc.Move("IntegerValue", "IntegerList/0"); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject(serialized); + + deserialized.ApplyTo(doc); + + Assert.Equal(0, doc.IntegerValue); + Assert.Equal(new List() { 5, 1, 2, 3 }, doc.IntegerList); + } + + [Fact] + public void MoveToEndOfList() + { + var doc = new SimpleDTO() + { + IntegerValue = 5, + IntegerList = new List() { 1, 2, 3 } + }; + + // create patch + JsonPatchDocument patchDoc = new JsonPatchDocument(); + patchDoc.Move("IntegerValue", "IntegerList/-"); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject(serialized); + + deserialized.ApplyTo(doc); + + Assert.Equal(0, doc.IntegerValue); + Assert.Equal(new List() { 1, 2, 3, 5 }, doc.IntegerList); + } + } +} diff --git a/test/Microsoft.AspNet.JsonPatch.Test/Dynamic/NestedDTO.cs b/test/Microsoft.AspNet.JsonPatch.Test/Dynamic/NestedDTO.cs new file mode 100644 index 0000000000..4d30cf60f2 --- /dev/null +++ b/test/Microsoft.AspNet.JsonPatch.Test/Dynamic/NestedDTO.cs @@ -0,0 +1,11 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +namespace Microsoft.AspNet.JsonPatch.Test.Dynamic +{ + public class NestedDTO + { + public string StringProperty { get; set; } + public dynamic DynamicProperty { get; set; } + } +} diff --git a/test/Microsoft.AspNet.JsonPatch.Test/Dynamic/PatchDocumentTests.cs b/test/Microsoft.AspNet.JsonPatch.Test/Dynamic/PatchDocumentTests.cs new file mode 100644 index 0000000000..e15f85da8e --- /dev/null +++ b/test/Microsoft.AspNet.JsonPatch.Test/Dynamic/PatchDocumentTests.cs @@ -0,0 +1,95 @@ +// 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 Microsoft.AspNet.JsonPatch.Exceptions; +using Newtonsoft.Json; +using Xunit; + +namespace Microsoft.AspNet.JsonPatch.Test.Dynamic +{ + public class PatchDocumentTests + { + [Fact] + public void InvalidPathAtBeginningShouldThrowException() + { + JsonPatchDocument patchDoc = new JsonPatchDocument(); + var exception = Assert.Throws(() => + { + patchDoc.Add("//NewInt", 1); + }); + Assert.Equal( + "The provided string '//NewInt' is an invalid path.", + exception.Message); + } + + [Fact] + public void InvalidPathAtEndShouldThrowException() + { + JsonPatchDocument patchDoc = new JsonPatchDocument(); + var exception = Assert.Throws(() => + { + patchDoc.Add("NewInt//", 1); + }); + Assert.Equal( + "The provided string 'NewInt//' is an invalid path.", + exception.Message); + } + + [Fact] + public void InvalidPathWithDotShouldThrowException() + { + JsonPatchDocument patchDoc = new JsonPatchDocument(); + var exception = Assert.Throws(() => + { + patchDoc.Add("NewInt.Test", 1); + }); + Assert.Equal( + "The provided string 'NewInt.Test' is an invalid path.", + exception.Message); + } + + [Fact] + public void NonGenericPatchDocToGenericMustSerialize() + { + var doc = new SimpleDTO() + { + StringProperty = "A", + AnotherStringProperty = "B" + }; + + JsonPatchDocument patchDoc = new JsonPatchDocument(); + patchDoc.Copy("StringProperty", "AnotherStringProperty"); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject>(serialized); + + deserialized.ApplyTo(doc); + + Assert.Equal("A", doc.AnotherStringProperty); + } + + [Fact] + public void GenericPatchDocToNonGenericMustSerialize() + { + var doc = new SimpleDTO() + { + StringProperty = "A", + AnotherStringProperty = "B" + }; + + JsonPatchDocument patchDocTyped = new JsonPatchDocument(); + patchDocTyped.Copy(o => o.StringProperty, o => o.AnotherStringProperty); + + JsonPatchDocument patchDocUntyped = new JsonPatchDocument(); + patchDocUntyped.Copy("StringProperty", "AnotherStringProperty"); + + var serializedTyped = JsonConvert.SerializeObject(patchDocTyped); + var serializedUntyped = JsonConvert.SerializeObject(patchDocUntyped); + var deserialized = JsonConvert.DeserializeObject(serializedTyped); + + deserialized.ApplyTo(doc); + + Assert.Equal("A", doc.AnotherStringProperty); + } + } +} \ No newline at end of file diff --git a/test/Microsoft.AspNet.JsonPatch.Test/Dynamic/RemoveOperationTests.cs b/test/Microsoft.AspNet.JsonPatch.Test/Dynamic/RemoveOperationTests.cs new file mode 100644 index 0000000000..9ef28ad7cc --- /dev/null +++ b/test/Microsoft.AspNet.JsonPatch.Test/Dynamic/RemoveOperationTests.cs @@ -0,0 +1,302 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System.Collections.Generic; +using System.Dynamic; +using Microsoft.AspNet.JsonPatch.Exceptions; +using Newtonsoft.Json; +using Xunit; + +namespace Microsoft.AspNet.JsonPatch.Test.Dynamic +{ + public class RemoveOperationTests + { + [Fact] + public void RemovePropertyShouldFailIfRootIsAnonymous() + { + dynamic doc = new + { + Test = 1 + }; + + // create patch + JsonPatchDocument patchDoc = new JsonPatchDocument(); + patchDoc.Remove("Test"); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject(serialized); + + var exception = Assert.Throws(() => + { + deserialized.ApplyTo(doc); + }); + Assert.Equal( + "The property at path '/Test' could not be updated.", + exception.Message); + } + + [Fact] + public void RemovePropertyShouldFailIfItDoesntExist() + { + dynamic doc = new ExpandoObject(); + doc.Test = 1; + + // create patch + JsonPatchDocument patchDoc = new JsonPatchDocument(); + patchDoc.Remove("NonExisting"); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject(serialized); + + var exception = Assert.Throws(() => + { + deserialized.ApplyTo(doc); + }); + Assert.Equal( + "The property at path '/NonExisting' could not be removed.", + exception.Message); + } + + [Fact] + public void RemovePropertyFromExpandoObject() + { + dynamic obj = new ExpandoObject(); + obj.Test = 1; + + // create patch + JsonPatchDocument patchDoc = new JsonPatchDocument(); + patchDoc.Remove("Test"); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject(serialized); + + deserialized.ApplyTo(obj); + + var cont = obj as IDictionary; + object valueFromDictionary; + + cont.TryGetValue("Test", out valueFromDictionary); + Assert.Null(valueFromDictionary); + } + + [Fact] + public void RemovePropertyFromExpandoObjectMixedCase() + { + dynamic obj = new ExpandoObject(); + obj.Test = 1; + + // create patch + JsonPatchDocument patchDoc = new JsonPatchDocument(); + patchDoc.Remove("test"); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject(serialized); + + deserialized.ApplyTo(obj); + + var cont = obj as IDictionary; + object valueFromDictionary; + + cont.TryGetValue("Test", out valueFromDictionary); + Assert.Null(valueFromDictionary); + } + + [Fact] + public void RemoveNestedPropertyFromExpandoObject() + { + dynamic obj = new ExpandoObject(); + obj.Test = new ExpandoObject(); + obj.Test.AnotherTest = "A"; + + // create patch + JsonPatchDocument patchDoc = new JsonPatchDocument(); + patchDoc.Remove("Test"); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject(serialized); + + deserialized.ApplyTo(obj); + + var cont = obj as IDictionary; + object valueFromDictionary; + + cont.TryGetValue("Test", out valueFromDictionary); + Assert.Null(valueFromDictionary); + } + + [Fact] + public void RemoveNestedPropertyFromExpandoObjectMixedCase() + { + dynamic obj = new ExpandoObject(); + obj.Test = new ExpandoObject(); + obj.Test.AnotherTest = "A"; + + // create patch + JsonPatchDocument patchDoc = new JsonPatchDocument(); + patchDoc.Remove("test"); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject(serialized); + + deserialized.ApplyTo(obj); + var cont = obj as IDictionary; + + object valueFromDictionary; + cont.TryGetValue("Test", out valueFromDictionary); + Assert.Null(valueFromDictionary); + } + + [Fact] + public void NestedRemove() + { + dynamic doc = new ExpandoObject(); + doc.SimpleDTO = new SimpleDTO() + { + StringProperty = "A" + }; + + // create patch + JsonPatchDocument patchDoc = new JsonPatchDocument(); + patchDoc.Remove("SimpleDTO/StringProperty"); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject(serialized); + + deserialized.ApplyTo(doc); + Assert.Equal(null, doc.SimpleDTO.StringProperty); + } + + [Fact] + public void NestedRemoveMixedCase() + { + dynamic doc = new ExpandoObject(); + doc.SimpleDTO = new SimpleDTO() + { + StringProperty = "A" + }; + + // create patch + JsonPatchDocument patchDoc = new JsonPatchDocument(); + patchDoc.Remove("Simpledto/stringProperty"); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject(serialized); + + deserialized.ApplyTo(doc); + + Assert.Equal(null, doc.SimpleDTO.StringProperty); + } + + [Fact] + public void NestedRemoveFromList() + { + dynamic doc = new ExpandoObject(); + doc.SimpleDTO = new SimpleDTO() + { + IntegerList = new List() { 1, 2, 3 } + }; + + // create patch + JsonPatchDocument patchDoc = new JsonPatchDocument(); + patchDoc.Remove("SimpleDTO/IntegerList/2"); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject(serialized); + + deserialized.ApplyTo(doc); + + Assert.Equal(new List() { 1, 2 }, doc.SimpleDTO.IntegerList); + } + + [Fact] + public void NestedRemoveFromListMixedCase() + { + dynamic doc = new ExpandoObject(); + doc.SimpleDTO = new SimpleDTO() + { + IntegerList = new List() { 1, 2, 3 } + }; + + // create patch + JsonPatchDocument patchDoc = new JsonPatchDocument(); + patchDoc.Remove("SimpleDTO/Integerlist/2"); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject(serialized); + + deserialized.ApplyTo(doc); + + Assert.Equal(new List() { 1, 2 }, doc.SimpleDTO.IntegerList); + } + + [Fact] + public void NestedRemoveFromListInvalidPositionTooLarge() + { + dynamic doc = new ExpandoObject(); + doc.SimpleDTO = new SimpleDTO() + { + IntegerList = new List() { 1, 2, 3 } + }; + + // create patch + JsonPatchDocument patchDoc = new JsonPatchDocument(); + patchDoc.Remove("SimpleDTO/IntegerList/3"); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject(serialized); + + var exception = Assert.Throws(() => + { + deserialized.ApplyTo(doc); + }); + Assert.Equal( + "For operation 'remove' on array property at path '/SimpleDTO/IntegerList/3', the index is larger than the array size.", + exception.Message); + } + + [Fact] + public void NestedRemoveFromListInvalidPositionTooSmall() + { + dynamic doc = new ExpandoObject(); + doc.SimpleDTO = new SimpleDTO() + { + IntegerList = new List() { 1, 2, 3 } + }; + + // create patch + JsonPatchDocument patchDoc = new JsonPatchDocument(); + patchDoc.Remove("SimpleDTO/IntegerList/-1"); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject(serialized); + + var exception = Assert.Throws(() => + { + deserialized.ApplyTo(doc); + }); + Assert.Equal( + "For operation 'remove' on array property at path '/SimpleDTO/IntegerList/-1', the index is negative.", + exception.Message); + } + + [Fact] + public void NestedRemoveFromEndOfList() + { + dynamic doc = new ExpandoObject(); + doc.SimpleDTO = new SimpleDTO() + { + IntegerList = new List() { 1, 2, 3 } + }; + + // create patch + JsonPatchDocument patchDoc = new JsonPatchDocument(); + patchDoc.Remove("SimpleDTO/IntegerList/-"); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject(serialized); + + deserialized.ApplyTo(doc); + Assert.Equal(new List() { 1, 2 }, doc.SimpleDTO.IntegerList); + } + } +} \ No newline at end of file diff --git a/test/Microsoft.AspNet.JsonPatch.Test/Dynamic/RemoveTypedOperationTests.cs b/test/Microsoft.AspNet.JsonPatch.Test/Dynamic/RemoveTypedOperationTests.cs new file mode 100644 index 0000000000..db5d6502d1 --- /dev/null +++ b/test/Microsoft.AspNet.JsonPatch.Test/Dynamic/RemoveTypedOperationTests.cs @@ -0,0 +1,244 @@ +// 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.AspNet.JsonPatch.Exceptions; +using Newtonsoft.Json; +using Xunit; + +namespace Microsoft.AspNet.JsonPatch.Test.Dynamic +{ + public class RemoveTypedOperationTests + { + [Fact] + public void Remove() + { + var doc = new SimpleDTO() + { + StringProperty = "A" + }; + + // create patch + JsonPatchDocument patchDoc = new JsonPatchDocument(); + patchDoc.Remove("StringProperty"); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject(serialized); + + deserialized.ApplyTo(doc); + + Assert.Equal(null, doc.StringProperty); + } + + [Fact] + public void RemoveFromList() + { + var doc = new SimpleDTO() + { + IntegerList = new List() { 1, 2, 3 } + }; + + // create patch + JsonPatchDocument patchDoc = new JsonPatchDocument(); + patchDoc.Remove("IntegerList/2"); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject(serialized); + + deserialized.ApplyTo(doc); + + Assert.Equal(new List() { 1, 2 }, doc.IntegerList); + } + + [Fact] + public void RemoveFromListInvalidPositionTooLarge() + { + var doc = new SimpleDTO() + { + IntegerList = new List() { 1, 2, 3 } + }; + + // create patch + JsonPatchDocument patchDoc = new JsonPatchDocument(); + patchDoc.Remove("IntegerList/3"); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject(serialized); + + var exception = Assert.Throws(() => + { + deserialized.ApplyTo(doc); + }); + Assert.Equal( + "For operation 'remove' on array property at path '/IntegerList/3', the index is larger than the array size.", + exception.Message); + } + + [Fact] + public void RemoveFromListInvalidPositionTooSmall() + { + var doc = new SimpleDTO() + { + IntegerList = new List() { 1, 2, 3 } + }; + + // create patch + JsonPatchDocument patchDoc = new JsonPatchDocument(); + patchDoc.Remove("IntegerList/-1"); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject(serialized); + + var exception = Assert.Throws(() => + { + deserialized.ApplyTo(doc); + }); + Assert.Equal( + "For operation 'remove' on array property at path '/IntegerList/-1', the index is negative.", + exception.Message); + } + + [Fact] + public void RemoveFromEndOfList() + { + var doc = new SimpleDTO() + { + IntegerList = new List() { 1, 2, 3 } + }; + + // create patch + JsonPatchDocument patchDoc = new JsonPatchDocument(); + patchDoc.Remove("IntegerList/-"); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject(serialized); + + deserialized.ApplyTo(doc); + + Assert.Equal(new List() { 1, 2 }, doc.IntegerList); + } + + [Fact] + public void NestedRemove() + { + var doc = new SimpleDTOWithNestedDTO() + { + SimpleDTO = new SimpleDTO() + { + StringProperty = "A" + } + }; + + // create patch + JsonPatchDocument patchDoc = new JsonPatchDocument(); + patchDoc.Remove("SimpleDTO/StringProperty"); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject(serialized); + + deserialized.ApplyTo(doc); + + Assert.Equal(null, doc.SimpleDTO.StringProperty); + } + + [Fact] + public void NestedRemoveFromList() + { + var doc = new SimpleDTOWithNestedDTO() + { + SimpleDTO = new SimpleDTO() + { + IntegerList = new List() { 1, 2, 3 } + } + }; + + // create patch + JsonPatchDocument patchDoc = new JsonPatchDocument(); + patchDoc.Remove("SimpleDTO/IntegerList/2"); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject(serialized); + + deserialized.ApplyTo(doc); + + Assert.Equal(new List() { 1, 2 }, doc.SimpleDTO.IntegerList); + } + + [Fact] + public void NestedRemoveFromListInvalidPositionTooLarge() + { + var doc = new SimpleDTOWithNestedDTO() + { + SimpleDTO = new SimpleDTO() + { + IntegerList = new List() { 1, 2, 3 } + } + }; + + // create patch + JsonPatchDocument patchDoc = new JsonPatchDocument(); + patchDoc.Remove("SimpleDTO/IntegerList/3"); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject(serialized); + + var exception = Assert.Throws(() => + { + deserialized.ApplyTo(doc); + }); + Assert.Equal( + "For operation 'remove' on array property at path '/SimpleDTO/IntegerList/3', the index is larger than the array size.", + exception.Message); + } + + [Fact] + public void NestedRemoveFromListInvalidPositionTooSmall() + { + var doc = new SimpleDTOWithNestedDTO() + { + SimpleDTO = new SimpleDTO() + { + IntegerList = new List() { 1, 2, 3 } + } + }; + + // create patch + JsonPatchDocument patchDoc = new JsonPatchDocument(); + patchDoc.Remove("SimpleDTO/IntegerList/-1"); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject(serialized); + + var exception = Assert.Throws(() => + { + deserialized.ApplyTo(doc); + }); + Assert.Equal( + "For operation 'remove' on array property at path '/SimpleDTO/IntegerList/-1', the index is negative.", + exception.Message); + } + + [Fact] + public void NestedRemoveFromEndOfList() + { + var doc = new SimpleDTOWithNestedDTO() + { + SimpleDTO = new SimpleDTO() + { + IntegerList = new List() { 1, 2, 3 } + } + }; + + // create patch + JsonPatchDocument patchDoc = new JsonPatchDocument(); + patchDoc.Remove("SimpleDTO/IntegerList/-"); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject(serialized); + + deserialized.ApplyTo(doc); + + Assert.Equal(new List() { 1, 2 }, doc.SimpleDTO.IntegerList); + } + } +} \ No newline at end of file diff --git a/test/Microsoft.AspNet.JsonPatch.Test/Dynamic/ReplaceOperationTests.cs b/test/Microsoft.AspNet.JsonPatch.Test/Dynamic/ReplaceOperationTests.cs new file mode 100644 index 0000000000..c7573c0286 --- /dev/null +++ b/test/Microsoft.AspNet.JsonPatch.Test/Dynamic/ReplaceOperationTests.cs @@ -0,0 +1,242 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Dynamic; +using Newtonsoft.Json; +using Xunit; + +namespace Microsoft.AspNet.JsonPatch.Test.Dynamic +{ + public class ReplaceOperationTests + { + [Fact] + public void ReplaceGuidTest() + { + dynamic doc = new SimpleDTO() + { + GuidValue = Guid.NewGuid() + }; + + var newGuid = Guid.NewGuid(); + // create patch + JsonPatchDocument patchDoc = new JsonPatchDocument(); + patchDoc.Replace("GuidValue", newGuid); + + // serialize & deserialize + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserizalized = JsonConvert.DeserializeObject(serialized); + + deserizalized.ApplyTo(doc); + + Assert.Equal(newGuid, doc.GuidValue); + } + + [Fact] + public void ReplaceGuidTestExpandoObject() + { + dynamic doc = new ExpandoObject(); + doc.GuidValue = Guid.NewGuid(); + + var newGuid = Guid.NewGuid(); + // create patch + JsonPatchDocument patchDoc = new JsonPatchDocument(); + patchDoc.Replace("GuidValue", newGuid); + + // serialize & deserialize + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserizalized = JsonConvert.DeserializeObject(serialized); + + deserizalized.ApplyTo(doc); + + Assert.Equal(newGuid, doc.GuidValue); + } + + [Fact] + public void ReplaceGuidTestExpandoObjectInAnonymous() + { + dynamic nestedObject = new ExpandoObject(); + nestedObject.GuidValue = Guid.NewGuid(); + + dynamic doc = new + { + NestedObject = nestedObject + }; + + var newGuid = Guid.NewGuid(); + // create patch + JsonPatchDocument patchDoc = new JsonPatchDocument(); + patchDoc.Replace("nestedobject/GuidValue", newGuid); + + // serialize & deserialize + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserizalized = JsonConvert.DeserializeObject(serialized); + + deserizalized.ApplyTo(doc); + + Assert.Equal(newGuid, doc.NestedObject.GuidValue); + } + + [Fact] + public void ReplaceNestedObjectTest() + { + dynamic doc = new ExpandoObject(); + doc.SimpleDTO = new SimpleDTO() + { + IntegerValue = 5, + IntegerList = new List() { 1, 2, 3 } + }; + + var newDTO = new SimpleDTO() + { + DoubleValue = 1 + }; + + // create patch + JsonPatchDocument patchDoc = new JsonPatchDocument(); + patchDoc.Replace("SimpleDTO", newDTO); + + // serialize & deserialize + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject(serialized); + + deserialized.ApplyTo(doc); + + Assert.Equal(1, doc.SimpleDTO.DoubleValue); + Assert.Equal(0, doc.SimpleDTO.IntegerValue); + Assert.Equal(null, doc.SimpleDTO.IntegerList); + } + + [Fact] + public void ReplaceInList() + { + dynamic doc = new ExpandoObject(); + doc.IntegerList = new List() { 1, 2, 3 }; + + // create patch + JsonPatchDocument patchDoc = new JsonPatchDocument(); + patchDoc.Replace("IntegerList/0", 5); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject(serialized); + + deserialized.ApplyTo(doc); + + Assert.Equal(new List() { 5, 2, 3 }, doc.IntegerList); + } + + [Fact] + public void ReplaceFullList() + { + dynamic doc = new ExpandoObject(); + doc.IntegerList = new List() { 1, 2, 3 }; + + // create patch + JsonPatchDocument patchDoc = new JsonPatchDocument(); + patchDoc.Replace("IntegerList", new List() { 4, 5, 6 }); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject(serialized); + + deserialized.ApplyTo(doc); + + Assert.Equal(new List() { 4, 5, 6 }, doc.IntegerList); + } + + [Fact] + public void ReplaceInListInList() + { + dynamic doc = new ExpandoObject(); + doc.SimpleDTOList = new List() { + new SimpleDTO() { + IntegerList = new List(){1,2,3} + }}; + + // create patch + JsonPatchDocument patchDoc = new JsonPatchDocument(); + patchDoc.Replace("SimpleDTOList/0/IntegerList/0", 4); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject(serialized); + + deserialized.ApplyTo(doc); + + Assert.Equal(4, doc.SimpleDTOList[0].IntegerList[0]); + } + + [Fact] + public void ReplaceInListInListAtEnd() + { + dynamic doc = new ExpandoObject(); + doc.SimpleDTOList = new List() { + new SimpleDTO() { + IntegerList = new List(){1,2,3} + }}; + + // create patch + JsonPatchDocument patchDoc = new JsonPatchDocument(); + patchDoc.Replace("SimpleDTOList/0/IntegerList/-", 4); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject(serialized); + + deserialized.ApplyTo(doc); + + Assert.Equal(4, doc.SimpleDTOList[0].IntegerList[2]); + } + + [Fact] + public void ReplaceFullListFromEnumerable() + { + dynamic doc = new ExpandoObject(); + doc.IntegerList = new List() { 1, 2, 3 }; + + // create patch + JsonPatchDocument patchDoc = new JsonPatchDocument(); + patchDoc.Replace("IntegerList", new List() { 4, 5, 6 }); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject(serialized); + + deserialized.ApplyTo(doc); + Assert.Equal(new List() { 4, 5, 6 }, doc.IntegerList); + } + + [Fact] + public void ReplaceFullListWithCollection() + { + dynamic doc = new ExpandoObject(); + doc.IntegerList = new List() { 1, 2, 3 }; + + // create patch + JsonPatchDocument patchDoc = new JsonPatchDocument(); + patchDoc.Replace("IntegerList", new Collection() { 4, 5, 6 }); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject(serialized); + + deserialized.ApplyTo(doc); + + Assert.Equal(new List() { 4, 5, 6 }, doc.IntegerList); + } + + [Fact] + public void ReplaceAtEndOfList() + { + dynamic doc = new ExpandoObject(); + doc.IntegerList = new List() { 1, 2, 3 }; + + // create patch + JsonPatchDocument patchDoc = new JsonPatchDocument(); + patchDoc.Replace("IntegerList/-", 5); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject(serialized); + deserialized.ApplyTo(doc); + + Assert.Equal(new List() { 1, 2, 5 }, doc.IntegerList); + } + } +} diff --git a/test/Microsoft.AspNet.JsonPatch.Test/Dynamic/ReplaceTypedOperationTests.cs b/test/Microsoft.AspNet.JsonPatch.Test/Dynamic/ReplaceTypedOperationTests.cs new file mode 100644 index 0000000000..ccdd86f1a7 --- /dev/null +++ b/test/Microsoft.AspNet.JsonPatch.Test/Dynamic/ReplaceTypedOperationTests.cs @@ -0,0 +1,191 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Linq; +using Newtonsoft.Json; +using Xunit; + +namespace Microsoft.AspNet.JsonPatch.Test.Dynamic +{ + public class ReplaceTypedOperationTests + { + [Fact] + public void ReplaceGuidTest() + { + var doc = new SimpleDTO() + { + GuidValue = Guid.NewGuid() + }; + + var newGuid = Guid.NewGuid(); + // create patch + JsonPatchDocument patchDoc = new JsonPatchDocument(); + patchDoc.Replace("GuidValue", newGuid); + + // serialize & deserialize + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserizalized = JsonConvert.DeserializeObject(serialized); + + deserizalized.ApplyTo(doc); + + Assert.Equal(newGuid, doc.GuidValue); + } + + [Fact] + public void SerializeAndReplaceNestedObjectTest() + { + var doc = new SimpleDTOWithNestedDTO() + { + SimpleDTO = new SimpleDTO() + { + IntegerValue = 5, + IntegerList = new List() { 1, 2, 3 } + } + }; + + var newDTO = new SimpleDTO() + { + DoubleValue = 1 + }; + + // create patch + JsonPatchDocument patchDoc = new JsonPatchDocument(); + patchDoc.Replace("SimpleDTO", newDTO); + + // serialize & deserialize + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject(serialized); + + deserialized.ApplyTo(doc); + + Assert.Equal(1, doc.SimpleDTO.DoubleValue); + Assert.Equal(0, doc.SimpleDTO.IntegerValue); + Assert.Equal(null, doc.SimpleDTO.IntegerList); + } + + [Fact] + public void ReplaceInList() + { + var doc = new SimpleDTO() + { + IntegerList = new List() { 1, 2, 3 } + }; + + // create patch + JsonPatchDocument patchDoc = new JsonPatchDocument(); + patchDoc.Replace("IntegerList/0", 5); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject(serialized); + + deserialized.ApplyTo(doc); + + Assert.Equal(new List() { 5, 2, 3 }, doc.IntegerList); + } + + [Fact] + public void ReplaceFullList() + { + var doc = new SimpleDTO() + { + IntegerList = new List() { 1, 2, 3 } + }; + + // create patch + JsonPatchDocument patchDoc = new JsonPatchDocument(); + patchDoc.Replace("IntegerList", new List() { 4, 5, 6 }); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject(serialized); + + deserialized.ApplyTo(doc); + + Assert.Equal(new List() { 4, 5, 6 }, doc.IntegerList); + } + + [Fact] + public void ReplaceInListInList() + { + var doc = new SimpleDTO() + { + SimpleDTOList = new List() { + new SimpleDTO() { + IntegerList = new List(){1,2,3} + }} + }; + + // create patch + JsonPatchDocument patchDoc = new JsonPatchDocument(); + patchDoc.Replace("SimpleDTOList/0/IntegerList/0", 4); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject(serialized); + + deserialized.ApplyTo(doc); + + Assert.Equal(4, doc.SimpleDTOList.First().IntegerList.First()); + } + + [Fact] + public void ReplaceFullListFromEnumerable() + { + var doc = new SimpleDTO() + { + IntegerList = new List() { 1, 2, 3 } + }; + + // create patch + JsonPatchDocument patchDoc = new JsonPatchDocument(); + patchDoc.Replace("IntegerList", new List() { 4, 5, 6 }); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject(serialized); + + deserialized.ApplyTo(doc); + + Assert.Equal(new List() { 4, 5, 6 }, doc.IntegerList); + } + + [Fact] + public void ReplaceFullListWithCollection() + { + var doc = new SimpleDTO() + { + IntegerList = new List() { 1, 2, 3 } + }; + + // create patch + JsonPatchDocument patchDoc = new JsonPatchDocument(); + patchDoc.Replace("IntegerList", new Collection() { 4, 5, 6 }); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject(serialized); + + deserialized.ApplyTo(doc); + + Assert.Equal(new List() { 4, 5, 6 }, doc.IntegerList); + } + + [Fact] + public void ReplaceAtEndOfList() + { + var doc = new SimpleDTO() + { + IntegerList = new List() { 1, 2, 3 } + }; + + // create patch + JsonPatchDocument patchDoc = new JsonPatchDocument(); + patchDoc.Replace("IntegerList/-", 5); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject(serialized); + deserialized.ApplyTo(doc); + + Assert.Equal(new List() { 1, 2, 5 }, doc.IntegerList); + } + } +} diff --git a/test/Microsoft.AspNet.JsonPatch.Test/Dynamic/SimpleDTO.cs b/test/Microsoft.AspNet.JsonPatch.Test/Dynamic/SimpleDTO.cs new file mode 100644 index 0000000000..a6938dd992 --- /dev/null +++ b/test/Microsoft.AspNet.JsonPatch.Test/Dynamic/SimpleDTO.cs @@ -0,0 +1,21 @@ +// 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; + +namespace Microsoft.AspNet.JsonPatch.Test.Dynamic +{ + public class SimpleDTO + { + public List SimpleDTOList { get; set; } + public List IntegerList { get; set; } + public int IntegerValue { get; set; } + public string StringProperty { get; set; } + public string AnotherStringProperty { get; set; } + public decimal DecimalValue { get; set; } + public double DoubleValue { get; set; } + public float FloatValue { get; set; } + public Guid GuidValue { get; set; } + } +} diff --git a/test/Microsoft.AspNet.JsonPatch.Test/Dynamic/SimpleDTOWithNestedDTO.cs b/test/Microsoft.AspNet.JsonPatch.Test/Dynamic/SimpleDTOWithNestedDTO.cs new file mode 100644 index 0000000000..2147fcceb1 --- /dev/null +++ b/test/Microsoft.AspNet.JsonPatch.Test/Dynamic/SimpleDTOWithNestedDTO.cs @@ -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.AspNet.JsonPatch.Test.Dynamic +{ + public class SimpleDTOWithNestedDTO + { + public int IntegerValue { get; set; } + public NestedDTO NestedDTO { get; set; } + public SimpleDTO SimpleDTO { get; set; } + public List ListOfSimpleDTO { get; set; } + + public SimpleDTOWithNestedDTO() + { + NestedDTO = new NestedDTO(); + SimpleDTO = new SimpleDTO(); + ListOfSimpleDTO = new List(); + } + } +} diff --git a/test/Microsoft.AspNet.JsonPatch.Test/Microsoft.AspNet.JsonPatch.Test.xproj b/test/Microsoft.AspNet.JsonPatch.Test/Microsoft.AspNet.JsonPatch.Test.xproj new file mode 100644 index 0000000000..74e0fef687 --- /dev/null +++ b/test/Microsoft.AspNet.JsonPatch.Test/Microsoft.AspNet.JsonPatch.Test.xproj @@ -0,0 +1,20 @@ + + + + 14.0 + $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) + + + + 81c20848-e063-4e12-ac40-0b55a532c16c + ..\..\artifacts\obj\$(MSBuildProjectName) + ..\..\artifacts\bin\$(MSBuildProjectName)\ + + + 2.0 + + + + + + \ No newline at end of file diff --git a/test/Microsoft.AspNet.JsonPatch.Test/NestedDTO.cs b/test/Microsoft.AspNet.JsonPatch.Test/NestedDTO.cs new file mode 100644 index 0000000000..6dd5ce8852 --- /dev/null +++ b/test/Microsoft.AspNet.JsonPatch.Test/NestedDTO.cs @@ -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.AspNet.JsonPatch.Test +{ + public class NestedDTO + { + public string StringProperty { get; set; } + } +} \ No newline at end of file diff --git a/test/Microsoft.AspNet.JsonPatch.Test/NestedObjectTests.cs b/test/Microsoft.AspNet.JsonPatch.Test/NestedObjectTests.cs new file mode 100644 index 0000000000..33649b7788 --- /dev/null +++ b/test/Microsoft.AspNet.JsonPatch.Test/NestedObjectTests.cs @@ -0,0 +1,2041 @@ +// 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 Microsoft.AspNet.JsonPatch.Exceptions; +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using Xunit; + +namespace Microsoft.AspNet.JsonPatch.Test +{ + public class NestedObjectTests + { + [Fact] + public void ReplacePropertyInNestedObject() + { + // Arrange + var doc = new SimpleDTOWithNestedDTO() + { + IntegerValue = 1 + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Replace(o => o.NestedDTO.StringProperty, "B"); + + // Act + patchDoc.ApplyTo(doc); + + // Assert + Assert.Equal("B", doc.NestedDTO.StringProperty); + } + + [Fact] + public void ReplacePropertyInNestedObjectWithSerialization() + { + // Arrange + var doc = new SimpleDTOWithNestedDTO() + { + IntegerValue = 1 + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Replace(o => o.NestedDTO.StringProperty, "B"); + + // serialize & deserialize + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject>(serialized); + + // Act + deserialized.ApplyTo(doc); + + // Assert + Assert.Equal("B", doc.NestedDTO.StringProperty); + } + + [Fact] + public void ReplaceNestedObject() + { + // Arrange + var doc = new SimpleDTOWithNestedDTO() + { + IntegerValue = 1 + }; + + var newNested = new NestedDTO() { StringProperty = "B" }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Replace(o => o.NestedDTO, newNested); + + // Act + patchDoc.ApplyTo(doc); + + // Assert + Assert.Equal("B", doc.NestedDTO.StringProperty); + } + + [Fact] + public void ReplaceNestedObjectWithSerialization() + { + // Arrange + var doc = new SimpleDTOWithNestedDTO() + { + IntegerValue = 1 + }; + + var newNested = new NestedDTO() { StringProperty = "B" }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Replace(o => o.NestedDTO, newNested); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject>(serialized); + + // Act + deserialized.ApplyTo(doc); + + // Assert + Assert.Equal("B", doc.NestedDTO.StringProperty); + } + + [Fact] + public void AddResultsInReplace() + { + // Arrange + var doc = new SimpleDTOWithNestedDTO() + { + SimpleDTO = new SimpleDTO() + { + StringProperty = "A" + } + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Add(o => o.SimpleDTO.StringProperty, "B"); + + // Act + patchDoc.ApplyTo(doc); + + // Assert + Assert.Equal("B", doc.SimpleDTO.StringProperty); + } + + [Fact] + public void AddResultsInReplaceWithSerialization() + { + // Arrange + var doc = new SimpleDTOWithNestedDTO() + { + SimpleDTO = new SimpleDTO() + { + StringProperty = "A" + } + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Add(o => o.SimpleDTO.StringProperty, "B"); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject>(serialized); + + // Act + deserialized.ApplyTo(doc); + + // Assert + Assert.Equal("B", doc.SimpleDTO.StringProperty); + } + + [Fact] + public void AddToList() + { + // Arrange + var doc = new SimpleDTOWithNestedDTO() + { + SimpleDTO = new SimpleDTO() + { + IntegerList = new List() { 1, 2, 3 } + } + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Add(o => o.SimpleDTO.IntegerList, 4, 0); + + // Act + patchDoc.ApplyTo(doc); + + // Assert + Assert.Equal(new List() { 4, 1, 2, 3 }, doc.SimpleDTO.IntegerList); + } + + [Fact] + public void AddToListWithSerialization() + { + // Arrange + var doc = new SimpleDTOWithNestedDTO() + { + SimpleDTO = new SimpleDTO() + { + IntegerList = new List() { 1, 2, 3 } + } + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Add(o => o.SimpleDTO.IntegerList, 4, 0); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject>(serialized); + + // Act + deserialized.ApplyTo(doc); + + // Assert + Assert.Equal(new List() { 4, 1, 2, 3 }, doc.SimpleDTO.IntegerList); + } + + [Fact] + public void AddToIntegerIList() + { + // Arrange + var doc = new SimpleDTOWithNestedDTO() + { + SimpleDTO = new SimpleDTO() + { + IntegerIList = new List() { 1, 2, 3 } + } + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Add(o => (List)o.SimpleDTO.IntegerIList, 4, 0); + + // Act + patchDoc.ApplyTo(doc); + + // Assert + Assert.Equal(new List() { 4, 1, 2, 3 }, doc.SimpleDTO.IntegerIList); + } + + [Fact] + public void AddToIntegerIListWithSerialization() + { + // Arrange + var doc = new SimpleDTOWithNestedDTO() + { + SimpleDTO = new SimpleDTO() + { + IntegerIList = new List() { 1, 2, 3 } + } + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Add(o => (List)o.SimpleDTO.IntegerIList, 4, 0); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject>(serialized); + + // Act + deserialized.ApplyTo(doc); + + // Assert + Assert.Equal(new List() { 4, 1, 2, 3 }, doc.SimpleDTO.IntegerIList); + } + + [Fact] + public void AddToNestedIntegerIList() + { + // Arrange + var doc = new SimpleDTOWithNestedDTO() + { + SimpleDTOIList = new List + { + new SimpleDTO + { + IntegerIList = new List() { 1, 2, 3 } + } + } + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Add(o => (List)o.SimpleDTOIList[0].IntegerIList, 4, 0); + + // Act + patchDoc.ApplyTo(doc); + + // Assert + Assert.Equal(new List() { 4, 1, 2, 3 }, doc.SimpleDTOIList[0].IntegerIList); + } + + [Fact] + public void AddToNestedIntegerIListWithSerialization() + { + // Arrange + var doc = new SimpleDTOWithNestedDTO() + { + SimpleDTOIList = new List + { + new SimpleDTO + { + IntegerIList = new List() { 1, 2, 3 } + } + } + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Add(o => (List)o.SimpleDTOIList[0].IntegerIList, 4, 0); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject>(serialized); + + // Act + deserialized.ApplyTo(doc); + + // Assert + Assert.Equal(new List() { 4, 1, 2, 3 }, doc.SimpleDTOIList[0].IntegerIList); + } + + [Fact] + public void AddToComplextTypeListSpecifyIndex() + { + // Arrange + var doc = new SimpleDTOWithNestedDTO() + { + SimpleDTOList = new List() + { + new SimpleDTO + { + StringProperty = "String1" + }, + new SimpleDTO + { + StringProperty = "String2" + } + } + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Add(o => o.SimpleDTOList[0].StringProperty, "ChangedString1"); + + // Act + patchDoc.ApplyTo(doc); + + // Assert + Assert.Equal("ChangedString1", doc.SimpleDTOList[0].StringProperty); + } + + [Fact] + public void AddToComplextTypeListSpecifyIndexWithSerialization() + { + // Arrange + var doc = new SimpleDTOWithNestedDTO() + { + SimpleDTOList = new List() + { + new SimpleDTO + { + StringProperty = "String1" + }, + new SimpleDTO + { + StringProperty = "String2" + } + } + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Add(o => o.SimpleDTOList[0].StringProperty, "ChangedString1"); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject>(serialized); + + // Act + deserialized.ApplyTo(doc); + + // Assert + Assert.Equal("ChangedString1", doc.SimpleDTOList[0].StringProperty); + } + + [Fact] + public void AddToListInvalidPositionTooLarge() + { + // Arrange + var doc = new SimpleDTOWithNestedDTO() + { + SimpleDTO = new SimpleDTO() + { + IntegerList = new List() { 1, 2, 3 } + } + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Add(o => o.SimpleDTO.IntegerList, 4, 4); + + // Act & Assert + var exception = Assert.Throws(() => { patchDoc.ApplyTo(doc); }); + Assert.Equal( + "For operation 'add' on array property at path '/simpledto/integerlist/4', the index is " + + "larger than the array size.", + exception.Message); + + } + + [Fact] + public void AddToListInvalidPositionTooLargeWithSerialization() + { + // Arrange + var doc = new SimpleDTOWithNestedDTO() + { + SimpleDTO = new SimpleDTO() + { + IntegerList = new List() { 1, 2, 3 } + } + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Add(o => o.SimpleDTO.IntegerList, 4, 4); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject>(serialized); + + // Act & Assert + var exception = Assert.Throws(() => + { + deserialized.ApplyTo(doc); + }); + Assert.Equal( + "For operation 'add' on array property at path '/simpledto/integerlist/4', the index is " + + "larger than the array size.", + exception.Message); + } + + [Fact] + public void AddToListInvalidPositionTooLarge_LogsError() + { + // Arrange + var doc = new SimpleDTOWithNestedDTO() + { + SimpleDTO = new SimpleDTO() + { + IntegerList = new List() { 1, 2, 3 } + } + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Add(o => o.SimpleDTO.IntegerList, 4, 4); + + var logger = new TestErrorLogger(); + + patchDoc.ApplyTo(doc, logger.LogErrorMessage); + + + //Assert + Assert.Equal( + "For operation 'add' on array property at path '/simpledto/integerlist/4', the index is larger than " + + "the array size.", + logger.ErrorMessage); + + } + + [Fact] + public void AddToListInvalidPositionTooSmall() + { + // Arrange + var doc = new SimpleDTOWithNestedDTO() + { + SimpleDTO = new SimpleDTO() + { + IntegerList = new List() { 1, 2, 3 } + } + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Add(o => o.SimpleDTO.IntegerList, 4, -1); + + // Act & Assert + var exception = Assert.Throws(() => { patchDoc.ApplyTo(doc); }); + Assert.Equal( + "For operation 'add' on array property at path '/simpledto/integerlist/-1', the index is negative.", + exception.Message); + } + + [Fact] + public void AddToListInvalidPositionTooSmallWithSerialization() + { + // Arrange + var doc = new SimpleDTOWithNestedDTO() + { + SimpleDTO = new SimpleDTO() + { + IntegerList = new List() { 1, 2, 3 } + } + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Add(o => o.SimpleDTO.IntegerList, 4, -1); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject>(serialized); + + // Act & Assert + var exception = Assert.Throws(() => + { + deserialized.ApplyTo(doc); + }); + Assert.Equal( + "For operation 'add' on array property at path '/simpledto/integerlist/-1', the index is negative.", + exception.Message); + } + + [Fact] + public void AddToListInvalidPositionTooSmall_LogsError() + { + // Arrange + var doc = new SimpleDTOWithNestedDTO() + { + SimpleDTO = new SimpleDTO() + { + IntegerList = new List() { 1, 2, 3 } + } + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Add(o => o.SimpleDTO.IntegerList, 4, -1); + + var logger = new TestErrorLogger(); + + + patchDoc.ApplyTo(doc, logger.LogErrorMessage); + + + //Assert + Assert.Equal( + "For operation 'add' on array property at path '/simpledto/integerlist/-1', the index is negative.", + logger.ErrorMessage); + } + + [Fact] + public void AddToListAppend() + { + // Arrange + var doc = new SimpleDTOWithNestedDTO() + { + SimpleDTO = new SimpleDTO() + { + IntegerList = new List() { 1, 2, 3 } + } + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Add(o => o.SimpleDTO.IntegerList, 4); + + // Act + patchDoc.ApplyTo(doc); + + // Assert + Assert.Equal(new List() { 1, 2, 3, 4 }, doc.SimpleDTO.IntegerList); + } + + [Fact] + public void AddToListAppendWithSerialization() + { + // Arrange + var doc = new SimpleDTOWithNestedDTO() + { + SimpleDTO = new SimpleDTO() + { + IntegerList = new List() { 1, 2, 3 } + } + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Add(o => o.SimpleDTO.IntegerList, 4); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject>(serialized); + + // Act + deserialized.ApplyTo(doc); + + // Assert + Assert.Equal(new List() { 1, 2, 3, 4 }, doc.SimpleDTO.IntegerList); + } + + [Fact] + public void Remove() + { + // Arrange + var doc = new SimpleDTOWithNestedDTO() + { + SimpleDTO = new SimpleDTO() + { + StringProperty = "A" + } + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Remove(o => o.SimpleDTO.StringProperty); + + // Act + patchDoc.ApplyTo(doc); + + // Assert + Assert.Equal(null, doc.SimpleDTO.StringProperty); + } + + [Fact] + public void RemoveWithSerialization() + { + // Arrange + var doc = new SimpleDTOWithNestedDTO() + { + SimpleDTO = new SimpleDTO() + { + StringProperty = "A" + } + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Remove(o => o.SimpleDTO.StringProperty); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject>(serialized); + + // Act + deserialized.ApplyTo(doc); + + // Assert + Assert.Equal(null, doc.SimpleDTO.StringProperty); + } + + [Fact] + public void RemoveFromList() + { + // Arrange + var doc = new SimpleDTOWithNestedDTO() + { + SimpleDTO = new SimpleDTO() + { + IntegerList = new List() { 1, 2, 3 } + } + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Remove(o => o.SimpleDTO.IntegerList, 2); + + // Act + patchDoc.ApplyTo(doc); + + // Assert + Assert.Equal(new List() { 1, 2 }, doc.SimpleDTO.IntegerList); + } + + [Fact] + public void RemoveFromListWithSerialization() + { + // Arrange + var doc = new SimpleDTOWithNestedDTO() + { + SimpleDTO = new SimpleDTO() + { + IntegerList = new List() { 1, 2, 3 } + } + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Remove(o => o.SimpleDTO.IntegerList, 2); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject>(serialized); + + // Act + deserialized.ApplyTo(doc); + + // Assert + Assert.Equal(new List() { 1, 2 }, doc.SimpleDTO.IntegerList); + } + + [Fact] + public void RemoveFromListInvalidPositionTooLarge() + { + // Arrange + var doc = new SimpleDTOWithNestedDTO() + { + SimpleDTO = new SimpleDTO() + { + IntegerList = new List() { 1, 2, 3 } + } + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Remove(o => o.SimpleDTO.IntegerList, 3); + + // Act & Assert + var exception = Assert.Throws(() => { patchDoc.ApplyTo(doc); }); + Assert.Equal( + "For operation 'remove' on array property at path '/simpledto/integerlist/3', the index is " + + "larger than the array size.", + exception.Message); + } + + [Fact] + public void RemoveFromListInvalidPositionTooLargeWithSerialization() + { + // Arrange + var doc = new SimpleDTOWithNestedDTO() + { + SimpleDTO = new SimpleDTO() + { + IntegerList = new List() { 1, 2, 3 } + } + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Remove(o => o.SimpleDTO.IntegerList, 3); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject>(serialized); + + // Act & Assert + var exception = Assert.Throws(() => + { + deserialized.ApplyTo(doc); + }); + Assert.Equal( + "For operation 'remove' on array property at path '/simpledto/integerlist/3', the index is " + + "larger than the array size.", + exception.Message); + } + + [Fact] + public void RemoveFromListInvalidPositionTooLarge_LogsError() + { + // Arrange + var doc = new SimpleDTOWithNestedDTO() + { + SimpleDTO = new SimpleDTO() + { + IntegerList = new List() { 1, 2, 3 } + } + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Remove(o => o.SimpleDTO.IntegerList, 3); + + var logger = new TestErrorLogger(); + + patchDoc.ApplyTo(doc, logger.LogErrorMessage); + + // Assert + Assert.Equal( + "For operation 'remove' on array property at path '/simpledto/integerlist/3', the index is " + + "larger than the array size.", + logger.ErrorMessage); + } + + [Fact] + public void RemoveFromListInvalidPositionTooSmall() + { + // Arrange + var doc = new SimpleDTOWithNestedDTO() + { + SimpleDTO = new SimpleDTO() + { + IntegerList = new List() { 1, 2, 3 } + } + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Remove(o => o.SimpleDTO.IntegerList, -1); + + // Act & Assert + var exception = Assert.Throws(() => { patchDoc.ApplyTo(doc); }); + Assert.Equal("For operation 'remove' on array property at path '/simpledto/integerlist/-1', the index is negative.", exception.Message); + } + + [Fact] + public void RemoveFromListInvalidPositionTooSmallWithSerialization() + { + // Arrange + var doc = new SimpleDTOWithNestedDTO() + { + SimpleDTO = new SimpleDTO() + { + IntegerList = new List() { 1, 2, 3 } + } + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Remove(o => o.SimpleDTO.IntegerList, -1); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject>(serialized); + + // Act & Assert + var exception = Assert.Throws(() => + { + deserialized.ApplyTo(doc); + }); + Assert.Equal("For operation 'remove' on array property at path '/simpledto/integerlist/-1', the index is negative.", exception.Message); + } + + [Fact] + public void RemoveFromListInvalidPositionTooSmall_LogsError() + { + // Arrange + var doc = new SimpleDTOWithNestedDTO() + { + SimpleDTO = new SimpleDTO() + { + IntegerList = new List() { 1, 2, 3 } + } + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Remove(o => o.SimpleDTO.IntegerList, -1); + + var logger = new TestErrorLogger(); + + + patchDoc.ApplyTo(doc, logger.LogErrorMessage); + + // Assert + Assert.Equal("For operation 'remove' on array property at path '/simpledto/integerlist/-1', the index is negative.", logger.ErrorMessage); + } + + [Fact] + public void RemoveFromEndOfList() + { + // Arrange + var doc = new SimpleDTOWithNestedDTO() + { + SimpleDTO = new SimpleDTO() + { + IntegerList = new List() { 1, 2, 3 } + } + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Remove(o => o.SimpleDTO.IntegerList); + + // Act + patchDoc.ApplyTo(doc); + + // Assert + Assert.Equal(new List() { 1, 2 }, doc.SimpleDTO.IntegerList); + } + + [Fact] + public void RemoveFromEndOfListWithSerialization() + { + // Arrange + var doc = new SimpleDTOWithNestedDTO() + { + SimpleDTO = new SimpleDTO() + { + IntegerList = new List() { 1, 2, 3 } + } + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Remove(o => o.SimpleDTO.IntegerList); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject>(serialized); + + // Act + deserialized.ApplyTo(doc); + + // Assert + Assert.Equal(new List() { 1, 2 }, doc.SimpleDTO.IntegerList); + } + + [Fact] + public void Replace() + { + // Arrange + var doc = new SimpleDTOWithNestedDTO() + { + SimpleDTO = new SimpleDTO() + { + StringProperty = "A", + DecimalValue = 10 + } + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Replace(o => o.SimpleDTO.StringProperty, "B"); + patchDoc.Replace(o => o.SimpleDTO.DecimalValue, 12); + + // Act + patchDoc.ApplyTo(doc); + + // Assert + Assert.Equal("B", doc.SimpleDTO.StringProperty); + Assert.Equal(12, doc.SimpleDTO.DecimalValue); + } + + [Fact] + public void ReplaceWithSerialization() + { + // Arrange + var doc = new SimpleDTOWithNestedDTO() + { + SimpleDTO = new SimpleDTO() + { + StringProperty = "A", + DecimalValue = 10 + } + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Replace(o => o.SimpleDTO.StringProperty, "B"); + patchDoc.Replace(o => o.SimpleDTO.DecimalValue, 12); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject>(serialized); + + // Act + deserialized.ApplyTo(doc); + + // Assert + Assert.Equal("B", doc.SimpleDTO.StringProperty); + Assert.Equal(12, doc.SimpleDTO.DecimalValue); + } + + [Fact] + public void SerializationTests() + { + // Arrange + var doc = new SimpleDTOWithNestedDTO() + { + SimpleDTO = new SimpleDTO() + { + StringProperty = "A", + DecimalValue = 10, + DoubleValue = 10, + FloatValue = 10, + IntegerValue = 10 + } + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Replace(o => o.SimpleDTO.StringProperty, "B"); + patchDoc.Replace(o => o.SimpleDTO.DecimalValue, 12); + patchDoc.Replace(o => o.SimpleDTO.DoubleValue, 12); + patchDoc.Replace(o => o.SimpleDTO.FloatValue, 12); + patchDoc.Replace(o => o.SimpleDTO.IntegerValue, 12); + + // serialize & deserialize + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserizalized = JsonConvert.DeserializeObject>(serialized); + + // Act + deserizalized.ApplyTo(doc); + + // Assert + Assert.Equal("B", doc.SimpleDTO.StringProperty); + Assert.Equal(12, doc.SimpleDTO.DecimalValue); + Assert.Equal(12, doc.SimpleDTO.DoubleValue); + Assert.Equal(12, doc.SimpleDTO.FloatValue); + Assert.Equal(12, doc.SimpleDTO.IntegerValue); + } + + [Fact] + public void ReplaceInList() + { + // Arrange + var doc = new SimpleDTOWithNestedDTO() + { + SimpleDTO = new SimpleDTO() + { + IntegerList = new List() { 1, 2, 3 } + } + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Replace(o => o.SimpleDTO.IntegerList, 5, 0); + + // Act + patchDoc.ApplyTo(doc); + + // Assert + Assert.Equal(new List() { 5, 2, 3 }, doc.SimpleDTO.IntegerList); + } + + [Fact] + public void ReplaceInListWithSerialization() + { + // Arrange + var doc = new SimpleDTOWithNestedDTO() + { + SimpleDTO = new SimpleDTO() + { + IntegerList = new List() { 1, 2, 3 } + } + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Replace(o => o.SimpleDTO.IntegerList, 5, 0); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject>(serialized); + + // Act + deserialized.ApplyTo(doc); + + // Assert + Assert.Equal(new List() { 5, 2, 3 }, doc.SimpleDTO.IntegerList); + } + + [Fact] + public void ReplaceFullList() + { + // Arrange + var doc = new SimpleDTOWithNestedDTO() + { + SimpleDTO = new SimpleDTO() + { + IntegerList = new List() { 1, 2, 3 } + } + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Replace>(o => o.SimpleDTO.IntegerList, new List() { 4, 5, 6 }); + + // Act + patchDoc.ApplyTo(doc); + + // Arrange + Assert.Equal(new List() { 4, 5, 6 }, doc.SimpleDTO.IntegerList); + } + + [Fact] + public void ReplaceFullListWithSerialiation() + { + // Arrange + var doc = new SimpleDTOWithNestedDTO() + { + SimpleDTO = new SimpleDTO() + { + IntegerList = new List() { 1, 2, 3 } + } + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Replace>(o => o.SimpleDTO.IntegerList, new List() { 4, 5, 6 }); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject>(serialized); + + // Act + deserialized.ApplyTo(doc); + + // Assert + Assert.Equal(new List() { 4, 5, 6 }, doc.SimpleDTO.IntegerList); + } + + [Fact] + public void ReplaceFullListFromEnumerable() + { + // Arrange + var doc = new SimpleDTOWithNestedDTO() + { + SimpleDTO = new SimpleDTO() + { + IntegerList = new List() { 1, 2, 3 } + } + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Replace>(o => o.SimpleDTO.IntegerList, new List() { 4, 5, 6 }); + + // Act + patchDoc.ApplyTo(doc); + + // Assert + Assert.Equal(new List() { 4, 5, 6 }, doc.SimpleDTO.IntegerList); + } + + [Fact] + public void ReplaceFullListFromEnumerableWithSerialization() + { + // Arrange + var doc = new SimpleDTOWithNestedDTO() + { + SimpleDTO = new SimpleDTO() + { + IntegerList = new List() { 1, 2, 3 } + } + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Replace>(o => o.SimpleDTO.IntegerList, new List() { 4, 5, 6 }); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject>(serialized); + + // Act + deserialized.ApplyTo(doc); + + // Assert + Assert.Equal(new List() { 4, 5, 6 }, doc.SimpleDTO.IntegerList); + } + + [Fact] + public void ReplaceFullListWithCollection() + { + // Arrange + var doc = new SimpleDTOWithNestedDTO() + { + SimpleDTO = new SimpleDTO() + { + IntegerList = new List() { 1, 2, 3 } + } + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Replace>(o => o.SimpleDTO.IntegerList, new Collection() { 4, 5, 6 }); + + // Act + patchDoc.ApplyTo(doc); + + // Assert + Assert.Equal(new List() { 4, 5, 6 }, doc.SimpleDTO.IntegerList); + } + + [Fact] + public void ReplaceFullListWithCollectionWithSerialization() + { + // Arrange + var doc = new SimpleDTOWithNestedDTO() + { + SimpleDTO = new SimpleDTO() + { + IntegerList = new List() { 1, 2, 3 } + } + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Replace>(o => o.SimpleDTO.IntegerList, new Collection() { 4, 5, 6 }); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject>(serialized); + + // Act + deserialized.ApplyTo(doc); + + // Assert + Assert.Equal(new List() { 4, 5, 6 }, doc.SimpleDTO.IntegerList); + } + + [Fact] + public void ReplaceAtEndOfList() + { + // Arrange + var doc = new SimpleDTOWithNestedDTO() + { + SimpleDTO = new SimpleDTO() + { + IntegerList = new List() { 1, 2, 3 } + } + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Replace(o => o.SimpleDTO.IntegerList, 5); + + // Act + patchDoc.ApplyTo(doc); + + // Assert + Assert.Equal(new List() { 1, 2, 5 }, doc.SimpleDTO.IntegerList); + } + + [Fact] + public void ReplaceAtEndOfListWithSerialization() + { + // Arrange + var doc = new SimpleDTOWithNestedDTO() + { + SimpleDTO = new SimpleDTO() + { + IntegerList = new List() { 1, 2, 3 } + } + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Replace(o => o.SimpleDTO.IntegerList, 5); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject>(serialized); + + // Act + deserialized.ApplyTo(doc); + + // Assert + Assert.Equal(new List() { 1, 2, 5 }, doc.SimpleDTO.IntegerList); + } + + [Fact] + public void ReplaceInListInvalidInvalidPositionTooLarge() + { + // Arrange + var doc = new SimpleDTOWithNestedDTO() + { + SimpleDTO = new SimpleDTO() + { + IntegerList = new List() { 1, 2, 3 } + } + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Replace(o => o.SimpleDTO.IntegerList, 5, 3); + + // Act & Assert + var exception = Assert.Throws(() => { patchDoc.ApplyTo(doc); }); + Assert.Equal( + "For operation 'replace' on array property at path '/simpledto/integerlist/3', the index is " + + "larger than the array size.", + exception.Message); + } + + [Fact] + public void ReplaceInListInvalidInvalidPositionTooLargeWithSerialization() + { + // Arrange + var doc = new SimpleDTOWithNestedDTO() + { + SimpleDTO = new SimpleDTO() + { + IntegerList = new List() { 1, 2, 3 } + } + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Replace(o => o.SimpleDTO.IntegerList, 5, 3); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject>(serialized); + + // Act & Assert + var exception = Assert.Throws(() => + { + deserialized.ApplyTo(doc); + }); + Assert.Equal( + "For operation 'replace' on array property at path '/simpledto/integerlist/3', the index is " + + "larger than the array size.", + exception.Message); + } + + [Fact] + public void ReplaceInListInvalid_PositionTooLarge_LogsError() + { + // Arrange + var doc = new SimpleDTOWithNestedDTO() + { + SimpleDTO = new SimpleDTO() + { + IntegerList = new List() { 1, 2, 3 } + } + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Replace(o => o.SimpleDTO.IntegerList, 5, 3); + + var logger = new TestErrorLogger(); + + + patchDoc.ApplyTo(doc, logger.LogErrorMessage); + + + // Assert + Assert.Equal( + "For operation 'replace' on array property at path '/simpledto/integerlist/3', the index is " + + "larger than the array size.", + logger.ErrorMessage); + } + + [Fact] + public void ReplaceInListInvalidPositionTooSmall() + { + // Arrange + var doc = new SimpleDTOWithNestedDTO() + { + SimpleDTO = new SimpleDTO() + { + IntegerList = new List() { 1, 2, 3 } + } + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Replace(o => o.SimpleDTO.IntegerList, 5, -1); + + // Act & Assert + var exception = Assert.Throws(() => { patchDoc.ApplyTo(doc); }); + Assert.Equal("For operation 'replace' on array property at path '/simpledto/integerlist/-1', the index is negative.", + exception.Message); + } + + [Fact] + public void ReplaceInListInvalidPositionTooSmallWithSerialization() + { + // Arrange + var doc = new SimpleDTOWithNestedDTO() + { + SimpleDTO = new SimpleDTO() + { + IntegerList = new List() { 1, 2, 3 } + } + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Replace(o => o.SimpleDTO.IntegerList, 5, -1); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject>(serialized); + + // Act & Assert + var exception = Assert.Throws(() => { deserialized.ApplyTo(doc); }); + Assert.Equal( + "For operation 'replace' on array property at path '/simpledto/integerlist/-1', the index is negative.", + exception.Message); + } + + [Fact] + public void ReplaceInListInvalidPositionTooSmall_LogsError() + { + // Arrange + var doc = new SimpleDTOWithNestedDTO() + { + SimpleDTO = new SimpleDTO() + { + IntegerList = new List() { 1, 2, 3 } + } + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Replace(o => o.SimpleDTO.IntegerList, 5, -1); + + var logger = new TestErrorLogger(); + + + patchDoc.ApplyTo(doc, logger.LogErrorMessage); + + + // Assert + Assert.Equal( + "For operation 'replace' on array property at path '/simpledto/integerlist/-1', the index is negative.", + logger.ErrorMessage); + } + + [Fact] + public void Copy() + { + // Arrange + var doc = new SimpleDTOWithNestedDTO() + { + SimpleDTO = new SimpleDTO() + { + StringProperty = "A", + AnotherStringProperty = "B" + } + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Copy(o => o.SimpleDTO.StringProperty, o => o.SimpleDTO.AnotherStringProperty); + + // Act + patchDoc.ApplyTo(doc); + + // Assert + Assert.Equal("A", doc.SimpleDTO.AnotherStringProperty); + } + + [Fact] + public void CopyWithSerialization() + { + // Arrange + var doc = new SimpleDTOWithNestedDTO() + { + SimpleDTO = new SimpleDTO() + { + StringProperty = "A", + AnotherStringProperty = "B" + } + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Copy(o => o.SimpleDTO.StringProperty, o => o.SimpleDTO.AnotherStringProperty); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject>(serialized); + + // Act + deserialized.ApplyTo(doc); + + // Assert + Assert.Equal("A", doc.SimpleDTO.AnotherStringProperty); + } + + [Fact] + public void CopyInList() + { + // Arrange + var doc = new SimpleDTOWithNestedDTO() + { + SimpleDTO = new SimpleDTO() + { + IntegerList = new List() { 1, 2, 3 } + } + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Copy(o => o.SimpleDTO.IntegerList, 0, o => o.SimpleDTO.IntegerList, 1); + + // Act + patchDoc.ApplyTo(doc); + + // Assert + Assert.Equal(new List() { 1, 1, 2, 3 }, doc.SimpleDTO.IntegerList); + } + + [Fact] + public void CopyInListWithSerialization() + { + // Arrange + var doc = new SimpleDTOWithNestedDTO() + { + SimpleDTO = new SimpleDTO() + { + IntegerList = new List() { 1, 2, 3 } + } + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Copy(o => o.SimpleDTO.IntegerList, 0, o => o.SimpleDTO.IntegerList, 1); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject>(serialized); + + // Act + deserialized.ApplyTo(doc); + + // Assert + Assert.Equal(new List() { 1, 1, 2, 3 }, doc.SimpleDTO.IntegerList); + } + + [Fact] + public void CopyFromListToEndOfList() + { + // Arrange + var doc = new SimpleDTOWithNestedDTO() + { + SimpleDTO = new SimpleDTO() + { + IntegerList = new List() { 1, 2, 3 } + } + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Copy(o => o.SimpleDTO.IntegerList, 0, o => o.SimpleDTO.IntegerList); + + // Act + patchDoc.ApplyTo(doc); + + // Assert + Assert.Equal(new List() { 1, 2, 3, 1 }, doc.SimpleDTO.IntegerList); + } + + [Fact] + public void CopyFromListToEndOfListWithSerialization() + { + // Arrange + var doc = new SimpleDTOWithNestedDTO() + { + SimpleDTO = new SimpleDTO() + { + IntegerList = new List() { 1, 2, 3 } + } + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Copy(o => o.SimpleDTO.IntegerList, 0, o => o.SimpleDTO.IntegerList); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject>(serialized); + + // Act + deserialized.ApplyTo(doc); + + // Assert + Assert.Equal(new List() { 1, 2, 3, 1 }, doc.SimpleDTO.IntegerList); + } + + [Fact] + public void CopyFromListToNonList() + { + // Arrange + var doc = new SimpleDTOWithNestedDTO() + { + SimpleDTO = new SimpleDTO() + { + IntegerList = new List() { 1, 2, 3 } + } + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Copy(o => o.SimpleDTO.IntegerList, 0, o => o.SimpleDTO.IntegerValue); + + // Act + patchDoc.ApplyTo(doc); + + // Assert + Assert.Equal(1, doc.SimpleDTO.IntegerValue); + } + + [Fact] + public void CopyFromListToNonListWithSerialization() + { + // Arrange + var doc = new SimpleDTOWithNestedDTO() + { + SimpleDTO = new SimpleDTO() + { + IntegerList = new List() { 1, 2, 3 } + } + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Copy(o => o.SimpleDTO.IntegerList, 0, o => o.SimpleDTO.IntegerValue); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject>(serialized); + + // Act + deserialized.ApplyTo(doc); + + // Assert + Assert.Equal(1, doc.SimpleDTO.IntegerValue); + } + + [Fact] + public void CopyFromNonListToList() + { + // Arrange + var doc = new SimpleDTOWithNestedDTO() + { + SimpleDTO = new SimpleDTO() + { + IntegerValue = 5, + IntegerList = new List() { 1, 2, 3 } + } + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Copy(o => o.SimpleDTO.IntegerValue, o => o.SimpleDTO.IntegerList, 0); + + // Act + patchDoc.ApplyTo(doc); + + // Assert + Assert.Equal(new List() { 5, 1, 2, 3 }, doc.SimpleDTO.IntegerList); + } + + [Fact] + public void CopyFromNonListToListWithSerialization() + { + // Arrange + var doc = new SimpleDTOWithNestedDTO() + { + SimpleDTO = new SimpleDTO() + { + IntegerValue = 5, + IntegerList = new List() { 1, 2, 3 } + } + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Copy(o => o.SimpleDTO.IntegerValue, o => o.SimpleDTO.IntegerList, 0); + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject>(serialized); + + // Act + deserialized.ApplyTo(doc); + + // Assert + Assert.Equal(new List() { 5, 1, 2, 3 }, doc.SimpleDTO.IntegerList); + } + + [Fact] + public void CopyToEndOfList() + { + // Arrange + var doc = new SimpleDTOWithNestedDTO() + { + SimpleDTO = new SimpleDTO() + { + IntegerValue = 5, + IntegerList = new List() { 1, 2, 3 } + } + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Copy(o => o.SimpleDTO.IntegerValue, o => o.SimpleDTO.IntegerList); + + // Act + patchDoc.ApplyTo(doc); + + // Assert + Assert.Equal(new List() { 1, 2, 3, 5 }, doc.SimpleDTO.IntegerList); + } + + [Fact] + public void CopyToEndOfListWithSerialization() + { + // Arrange + var doc = new SimpleDTOWithNestedDTO() + { + SimpleDTO = new SimpleDTO() + { + IntegerValue = 5, + IntegerList = new List() { 1, 2, 3 } + } + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Copy(o => o.SimpleDTO.IntegerValue, o => o.SimpleDTO.IntegerList); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject>(serialized); + + // Act + deserialized.ApplyTo(doc); + + // Assert + Assert.Equal(new List() { 1, 2, 3, 5 }, doc.SimpleDTO.IntegerList); + } + + [Fact] + public void Move() + { + // Arrange + var doc = new SimpleDTOWithNestedDTO() + { + SimpleDTO = new SimpleDTO() + { + StringProperty = "A", + AnotherStringProperty = "B" + } + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Move(o => o.SimpleDTO.StringProperty, o => o.SimpleDTO.AnotherStringProperty); + + // Act + patchDoc.ApplyTo(doc); + + // Assert + Assert.Equal("A", doc.SimpleDTO.AnotherStringProperty); + Assert.Equal(null, doc.SimpleDTO.StringProperty); + } + + [Fact] + public void MoveWithSerialization() + { + // Arrange + var doc = new SimpleDTOWithNestedDTO() + { + SimpleDTO = new SimpleDTO() + { + StringProperty = "A", + AnotherStringProperty = "B" + } + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Move(o => o.SimpleDTO.StringProperty, o => o.SimpleDTO.AnotherStringProperty); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject>(serialized); + + // Act + deserialized.ApplyTo(doc); + + // Assert + Assert.Equal("A", doc.SimpleDTO.AnotherStringProperty); + Assert.Equal(null, doc.SimpleDTO.StringProperty); + } + + [Fact] + public void MoveInList() + { + // Arrange + var doc = new SimpleDTOWithNestedDTO() + { + SimpleDTO = new SimpleDTO() + { + IntegerList = new List() { 1, 2, 3 } + } + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Move(o => o.SimpleDTO.IntegerList, 0, o => o.SimpleDTO.IntegerList, 1); + + // Act + patchDoc.ApplyTo(doc); + + // Assert + Assert.Equal(new List() { 2, 1, 3 }, doc.SimpleDTO.IntegerList); + } + + [Fact] + public void MoveInListWithSerialization() + { + // Arrange + var doc = new SimpleDTOWithNestedDTO() + { + SimpleDTO = new SimpleDTO() + { + IntegerList = new List() { 1, 2, 3 } + } + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Move(o => o.SimpleDTO.IntegerList, 0, o => o.SimpleDTO.IntegerList, 1); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject>(serialized); + + // Act + deserialized.ApplyTo(doc); + + // Assert + Assert.Equal(new List() { 2, 1, 3 }, doc.SimpleDTO.IntegerList); + } + + [Fact] + public void MoveFromListToEndOfList() + { + // Arrange + var doc = new SimpleDTOWithNestedDTO() + { + SimpleDTO = new SimpleDTO() + { + IntegerList = new List() { 1, 2, 3 } + } + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Move(o => o.SimpleDTO.IntegerList, 0, o => o.SimpleDTO.IntegerList); + + // Act + patchDoc.ApplyTo(doc); + + // Assert + Assert.Equal(new List() { 2, 3, 1 }, doc.SimpleDTO.IntegerList); + } + + [Fact] + public void MoveFromListToEndOfListWithSerialization() + { + // Arrange + var doc = new SimpleDTOWithNestedDTO() + { + SimpleDTO = new SimpleDTO() + { + IntegerList = new List() { 1, 2, 3 } + } + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Move(o => o.SimpleDTO.IntegerList, 0, o => o.SimpleDTO.IntegerList); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject>(serialized); + + // Act + deserialized.ApplyTo(doc); + + // Assert + Assert.Equal(new List() { 2, 3, 1 }, doc.SimpleDTO.IntegerList); + } + + [Fact] + public void MoveFomListToNonList() + { + // Arrange + var doc = new SimpleDTOWithNestedDTO() + { + SimpleDTO = new SimpleDTO() + { + IntegerList = new List() { 1, 2, 3 } + } + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Move(o => o.SimpleDTO.IntegerList, 0, o => o.SimpleDTO.IntegerValue); + + // Act + patchDoc.ApplyTo(doc); + + // Assert + Assert.Equal(new List() { 2, 3 }, doc.SimpleDTO.IntegerList); + Assert.Equal(1, doc.SimpleDTO.IntegerValue); + } + + [Fact] + public void MoveFomListToNonListWithSerialization() + { + // Arrange + var doc = new SimpleDTOWithNestedDTO() + { + SimpleDTO = new SimpleDTO() + { + IntegerList = new List() { 1, 2, 3 } + } + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Move(o => o.SimpleDTO.IntegerList, 0, o => o.SimpleDTO.IntegerValue); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject>(serialized); + + // Act + deserialized.ApplyTo(doc); + + // Assert + Assert.Equal(new List() { 2, 3 }, doc.SimpleDTO.IntegerList); + Assert.Equal(1, doc.SimpleDTO.IntegerValue); + } + + [Fact] + public void MoveFomListToNonListBetweenHierarchy() + { + // Arrange + var doc = new SimpleDTOWithNestedDTO() + { + SimpleDTO = new SimpleDTO() + { + IntegerList = new List() { 1, 2, 3 } + } + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Move(o => o.SimpleDTO.IntegerList, 0, o => o.IntegerValue); + + // Act + patchDoc.ApplyTo(doc); + + // Assert + Assert.Equal(new List() { 2, 3 }, doc.SimpleDTO.IntegerList); + Assert.Equal(1, doc.IntegerValue); + } + + [Fact] + public void MoveFomListToNonListBetweenHierarchyWithSerialization() + { + // Arrange + var doc = new SimpleDTOWithNestedDTO() + { + SimpleDTO = new SimpleDTO() + { + IntegerList = new List() { 1, 2, 3 } + } + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Move(o => o.SimpleDTO.IntegerList, 0, o => o.IntegerValue); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject>(serialized); + + // Act + deserialized.ApplyTo(doc); + + // Assert + Assert.Equal(new List() { 2, 3 }, doc.SimpleDTO.IntegerList); + Assert.Equal(1, doc.IntegerValue); + } + + [Fact] + public void MoveFromNonListToList() + { + // Arrange + var doc = new SimpleDTOWithNestedDTO() + { + SimpleDTO = new SimpleDTO() + { + IntegerValue = 5, + IntegerList = new List() { 1, 2, 3 } + } + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Move(o => o.SimpleDTO.IntegerValue, o => o.SimpleDTO.IntegerList, 0); + + // Act + patchDoc.ApplyTo(doc); + + // Assert + Assert.Equal(0, doc.IntegerValue); + Assert.Equal(new List() { 5, 1, 2, 3 }, doc.SimpleDTO.IntegerList); + } + + [Fact] + public void MoveFromNonListToListWithSerialization() + { + // Arrange + var doc = new SimpleDTOWithNestedDTO() + { + SimpleDTO = new SimpleDTO() + { + IntegerValue = 5, + IntegerList = new List() { 1, 2, 3 } + } + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Move(o => o.SimpleDTO.IntegerValue, o => o.SimpleDTO.IntegerList, 0); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject>(serialized); + + // Act + deserialized.ApplyTo(doc); + + // Assert + Assert.Equal(0, doc.IntegerValue); + Assert.Equal(new List() { 5, 1, 2, 3 }, doc.SimpleDTO.IntegerList); + } + + [Fact] + public void MoveToEndOfList() + { + // Arrange + var doc = new SimpleDTOWithNestedDTO() + { + SimpleDTO = new SimpleDTO() + { + IntegerValue = 5, + IntegerList = new List() { 1, 2, 3 } + } + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Move(o => o.SimpleDTO.IntegerValue, o => o.SimpleDTO.IntegerList); + + // Act + patchDoc.ApplyTo(doc); + + // Assert + Assert.Equal(0, doc.IntegerValue); + Assert.Equal(new List() { 1, 2, 3, 5 }, doc.SimpleDTO.IntegerList); + } + + [Fact] + public void MoveToEndOfListWithSerialization() + { + // Arrange + var doc = new SimpleDTOWithNestedDTO() + { + SimpleDTO = new SimpleDTO() + { + IntegerValue = 5, + IntegerList = new List() { 1, 2, 3 } + } + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Move(o => o.SimpleDTO.IntegerValue, o => o.SimpleDTO.IntegerList); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject>(serialized); + + // Act + deserialized.ApplyTo(doc); + + // Assert + Assert.Equal(0, doc.IntegerValue); + Assert.Equal(new List() { 1, 2, 3, 5 }, doc.SimpleDTO.IntegerList); + } + } +} \ No newline at end of file diff --git a/test/Microsoft.AspNet.JsonPatch.Test/ObjectAdapterTests.cs b/test/Microsoft.AspNet.JsonPatch.Test/ObjectAdapterTests.cs new file mode 100644 index 0000000000..0cc97e32c4 --- /dev/null +++ b/test/Microsoft.AspNet.JsonPatch.Test/ObjectAdapterTests.cs @@ -0,0 +1,1737 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using Microsoft.AspNet.JsonPatch.Exceptions; +using Newtonsoft.Json; +using Xunit; + +namespace Microsoft.AspNet.JsonPatch.Test +{ + public class ObjectAdapterTests + { + [Fact] + public void AddResultsShouldReplace() + { + // Arrange + var doc = new SimpleDTO() + { + StringProperty = "A" + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Add(o => o.StringProperty, "B"); + + // Act + patchDoc.ApplyTo(doc); + + // Assert + Assert.Equal("B", doc.StringProperty); + } + + [Fact] + public void AddResultsShouldReplaceWithSerialization() + { + // Arrange + var doc = new SimpleDTO() + { + StringProperty = "A" + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Add(o => o.StringProperty, "B"); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject>(serialized); + + // Act + deserialized.ApplyTo(doc); + + // Assert + Assert.Equal("B", doc.StringProperty); + } + + [Fact] + public void AddToList() + { + // Arrange + var doc = new SimpleDTO() + { + IntegerList = new List() { 1, 2, 3 } + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Add(o => o.IntegerList, 4, 0); + + // Act + patchDoc.ApplyTo(doc); + + // Assert + Assert.Equal(new List() { 4, 1, 2, 3 }, doc.IntegerList); + } + + [Fact] + public void AddToListWithSerialization() + { + // Arrange + var doc = new SimpleDTO() + { + IntegerList = new List() { 1, 2, 3 } + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Add(o => o.IntegerList, 4, 0); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject>(serialized); + + // Act + deserialized.ApplyTo(doc); + + // Assert + Assert.Equal(new List() { 4, 1, 2, 3 }, doc.IntegerList); + } + + [Fact] + public void AddToIntegerIList() + { + // Arrange + var doc = new SimpleDTO() + { + IntegerIList = new List() { 1, 2, 3 } + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Add(o => o.IntegerIList, 4, 0); + + // Act + patchDoc.ApplyTo(doc); + + // Assert + Assert.Equal(new List() { 4, 1, 2, 3 }, doc.IntegerIList); + } + + [Fact] + public void AddToIntegerIListWithSerialization() + { + // Arrange + var doc = new SimpleDTO() + { + IntegerIList = new List() { 1, 2, 3 } + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Add(o => o.IntegerIList, 4, 0); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject>(serialized); + + // Act + deserialized.ApplyTo(doc); + + // Assert + Assert.Equal(new List() { 4, 1, 2, 3 }, doc.IntegerIList); + } + + [Fact] + public void AddToListInvalidPositionTooLarge() + { + // Arrange + var doc = new SimpleDTO() + { + IntegerList = new List() { 1, 2, 3 } + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Add(o => o.IntegerList, 4, 4); + + // Act & Assert + var exception = Assert.Throws(() => { patchDoc.ApplyTo(doc); }); + Assert.Equal( + "For operation 'add' on array property at path '/integerlist/4', the index is " + + "larger than the array size.", + exception.Message); + } + + [Fact] + public void AddToListInvalidPositionTooLargeWithSerialization() + { + // Arrange + var doc = new SimpleDTO() + { + IntegerList = new List() { 1, 2, 3 } + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Add(o => o.IntegerList, 4, 4); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject>(serialized); + + // Act & Assert + var exception = Assert.Throws(() => { deserialized.ApplyTo(doc); }); + Assert.Equal( + "For operation 'add' on array property at path '/integerlist/4', the index is " + + "larger than the array size.", + exception.Message); + } + + [Fact] + public void AddToListInvalidPositionTooLarge_LogsError() + { + // Arrange + var doc = new SimpleDTO() + { + IntegerList = new List() { 1, 2, 3 } + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Add(o => o.IntegerList, 4, 4); + + var logger = new TestErrorLogger(); + + patchDoc.ApplyTo(doc, logger.LogErrorMessage); + + + // Assert + Assert.Equal( + "For operation 'add' on array property at path '/integerlist/4', the index is " + + "larger than the array size.", + logger.ErrorMessage); + } + + [Fact] + public void AddToListAtEnd() + { + // Arrange + var doc = new SimpleDTO() + { + IntegerList = new List() { 1, 2, 3 } + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Add(o => o.IntegerList, 4, 3); + + // Act + patchDoc.ApplyTo(doc); + + // Assert + Assert.Equal(new List() { 1, 2, 3, 4 }, doc.IntegerList); + } + + [Fact] + public void AddToListAtEndWithSerialization() + { + // Arrange + var doc = new SimpleDTO() + { + IntegerList = new List() { 1, 2, 3 } + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Add(o => o.IntegerList, 4, 3); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject>(serialized); + + // Act + deserialized.ApplyTo(doc); + + // Assert + Assert.Equal(new List() { 1, 2, 3, 4 }, doc.IntegerList); + } + + [Fact] + public void AddToListAtBeginning() + { + // Arrange + var doc = new SimpleDTO() + { + IntegerList = new List() { 1, 2, 3 } + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Add(o => o.IntegerList, 4, 0); + + // Act + patchDoc.ApplyTo(doc); + + // Assert + Assert.Equal(new List() { 4, 1, 2, 3 }, doc.IntegerList); + } + + [Fact] + public void AddToListAtBeginningWithSerialization() + { + // Arrange + var doc = new SimpleDTO() + { + IntegerList = new List() { 1, 2, 3 } + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Add(o => o.IntegerList, 4, 0); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject>(serialized); + + // Act + deserialized.ApplyTo(doc); + + // Assert + Assert.Equal(new List() { 4, 1, 2, 3 }, doc.IntegerList); + } + + [Fact] + public void AddToListInvalidPositionTooSmall() + { + // Arrange + var doc = new SimpleDTO() + { + IntegerList = new List() { 1, 2, 3 } + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Add(o => o.IntegerList, 4, -1); + + // Act & Assert + var exception = Assert.Throws(() => { patchDoc.ApplyTo(doc); }); + Assert.Equal( + "For operation 'add' on array property at path '/integerlist/-1', the index is negative.", + exception.Message); + } + + [Fact] + public void AddToListInvalidPositionTooSmallWithSerialization() + { + // Arrange + var doc = new SimpleDTO() + { + IntegerList = new List() { 1, 2, 3 } + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Add(o => o.IntegerList, 4, -1); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject>(serialized); + + // Act & Assert + var exception = Assert.Throws(() => { deserialized.ApplyTo(doc); }); + Assert.Equal( + "For operation 'add' on array property at path '/integerlist/-1', the index is negative.", + exception.Message); + } + + [Fact] + public void AddToListInvalidPositionTooSmall_LogsError() + { + // Arrange + var doc = new SimpleDTO() + { + IntegerList = new List() { 1, 2, 3 } + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Add(o => o.IntegerList, 4, -1); + + var logger = new TestErrorLogger(); + + patchDoc.ApplyTo(doc, logger.LogErrorMessage); + + // Assert + Assert.Equal( + "For operation 'add' on array property at path '/integerlist/-1', the index is negative.", + logger.ErrorMessage); + } + + [Fact] + public void AddToListAppend() + { + // Arrange + var doc = new SimpleDTO() + { + IntegerList = new List() { 1, 2, 3 } + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Add(o => o.IntegerList, 4); + + // Act + patchDoc.ApplyTo(doc); + + // Assert + Assert.Equal(new List() { 1, 2, 3, 4 }, doc.IntegerList); + } + + [Fact] + public void AddToListAppendWithSerialization() + { + // Arrange + var doc = new SimpleDTO() + { + IntegerList = new List() { 1, 2, 3 } + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Add(o => o.IntegerList, 4); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject>(serialized); + + // Act + deserialized.ApplyTo(doc); + + // Assert + Assert.Equal(new List() { 1, 2, 3, 4 }, doc.IntegerList); + } + + [Fact] + public void Remove() + { + // Arrange + var doc = new SimpleDTO() + { + StringProperty = "A" + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Remove(o => o.StringProperty); + + // Act + patchDoc.ApplyTo(doc); + + // Assert + Assert.Equal(null, doc.StringProperty); + } + + [Fact] + public void RemoveWithSerialization() + { + // Arrange + var doc = new SimpleDTO() + { + StringProperty = "A" + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Remove(o => o.StringProperty); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject>(serialized); + + // Act + deserialized.ApplyTo(doc); + + // Assert + Assert.Equal(null, doc.StringProperty); + } + + [Fact] + public void RemoveFromList() + { + // Arrange + var doc = new SimpleDTO() + { + IntegerList = new List() { 1, 2, 3 } + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Remove(o => o.IntegerList, 2); + + // Act + patchDoc.ApplyTo(doc); + + // Assert + Assert.Equal(new List() { 1, 2 }, doc.IntegerList); + } + + [Fact] + public void RemoveFromListWithSerialization() + { + // Arrange + var doc = new SimpleDTO() + { + IntegerList = new List() { 1, 2, 3 } + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Remove(o => o.IntegerList, 2); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject>(serialized); + + // Act + deserialized.ApplyTo(doc); + + // Assert + Assert.Equal(new List() { 1, 2 }, doc.IntegerList); + } + + [Fact] + public void RemoveFromListInvalidPositionTooLarge() + { + // Arrange + var doc = new SimpleDTO() + { + IntegerList = new List() { 1, 2, 3 } + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Remove(o => o.IntegerList, 3); + + // Act & Assert + var exception = Assert.Throws(() => { patchDoc.ApplyTo(doc); }); + Assert.Equal( + "For operation 'remove' on array property at path '/integerlist/3', the index is " + + "larger than the array size.", + exception.Message); + } + + [Fact] + public void RemoveFromListInvalidPositionTooLargeWithSerialization() + { + // Arrange + var doc = new SimpleDTO() + { + IntegerList = new List() { 1, 2, 3 } + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Remove(o => o.IntegerList, 3); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject>(serialized); + + // Act & Assert + var exception = Assert.Throws(() => { deserialized.ApplyTo(doc); }); + Assert.Equal( + "For operation 'remove' on array property at path '/integerlist/3', the index is " + + "larger than the array size.", + exception.Message); + } + + [Fact] + public void RemoveFromListInvalidPositionTooLarge_LogsError() + { + // Arrange + var doc = new SimpleDTO() + { + IntegerList = new List() { 1, 2, 3 } + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Remove(o => o.IntegerList, 3); + + var logger = new TestErrorLogger(); + + patchDoc.ApplyTo(doc, logger.LogErrorMessage); + + + // Assert + Assert.Equal( + "For operation 'remove' on array property at path '/integerlist/3', the index is " + + "larger than the array size.", + logger.ErrorMessage); + } + + [Fact] + public void RemoveFromListInvalidPositionTooSmall() + { + // Arrange + var doc = new SimpleDTO() + { + IntegerList = new List() { 1, 2, 3 } + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Remove(o => o.IntegerList, -1); + + // Act & Assert + var exception = Assert.Throws(() => { patchDoc.ApplyTo(doc); }); + Assert.Equal("For operation 'remove' on array property at path '/integerlist/-1', the index is negative.", exception.Message); + } + + [Fact] + public void RemoveFromListInvalidPositionTooSmallWithSerialization() + { + // Arrange + var doc = new SimpleDTO() + { + IntegerList = new List() { 1, 2, 3 } + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Remove(o => o.IntegerList, -1); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject>(serialized); + + // Act & Assert + var exception = Assert.Throws(() => { deserialized.ApplyTo(doc); }); + Assert.Equal("For operation 'remove' on array property at path '/integerlist/-1', the index is negative.", exception.Message); + } + + [Fact] + public void RemoveFromListInvalidPositionTooSmall_LogsError() + { + // Arrange + var doc = new SimpleDTO() + { + IntegerList = new List() { 1, 2, 3 } + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Remove(o => o.IntegerList, -1); + + var logger = new TestErrorLogger(); + + + patchDoc.ApplyTo(doc, logger.LogErrorMessage); + + + // Assert + Assert.Equal("For operation 'remove' on array property at path '/integerlist/-1', the index is negative.", logger.ErrorMessage); + } + + [Fact] + public void RemoveFromEndOfList() + { + // Arrange + var doc = new SimpleDTO() + { + IntegerList = new List() { 1, 2, 3 } + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Remove(o => o.IntegerList); + + // Act + patchDoc.ApplyTo(doc); + + // Assert + Assert.Equal(new List() { 1, 2 }, doc.IntegerList); + } + + [Fact] + public void RemoveFromEndOfListWithSerialization() + { + // Arrange + var doc = new SimpleDTO() + { + IntegerList = new List() { 1, 2, 3 } + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Remove(o => o.IntegerList); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject>(serialized); + + // Act + deserialized.ApplyTo(doc); + + // Assert + Assert.Equal(new List() { 1, 2 }, doc.IntegerList); + } + + [Fact] + public void Replace() + { + // Arrange + var doc = new SimpleDTO() + { + StringProperty = "A", + DecimalValue = 10 + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Replace(o => o.StringProperty, "B"); + + patchDoc.Replace(o => o.DecimalValue, 12); + + // Act + patchDoc.ApplyTo(doc); + + // Assert + Assert.Equal("B", doc.StringProperty); + Assert.Equal(12, doc.DecimalValue); + } + + [Fact] + public void ReplaceWithSerialization() + { + // Arrange + var doc = new SimpleDTO() + { + StringProperty = "A", + DecimalValue = 10 + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Replace(o => o.StringProperty, "B"); + + patchDoc.Replace(o => o.DecimalValue, 12); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject>(serialized); + + // Act + deserialized.ApplyTo(doc); + + // Assert + Assert.Equal("B", doc.StringProperty); + Assert.Equal(12, doc.DecimalValue); + } + + [Fact] + public void SerializationMustNotIncudeEnvelope() + { + // Arrange + var doc = new SimpleDTO() + { + StringProperty = "A", + DecimalValue = 10, + DoubleValue = 10, + FloatValue = 10, + IntegerValue = 10 + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Replace(o => o.StringProperty, "B"); + patchDoc.Replace(o => o.DecimalValue, 12); + patchDoc.Replace(o => o.DoubleValue, 12); + patchDoc.Replace(o => o.FloatValue, 12); + patchDoc.Replace(o => o.IntegerValue, 12); + + // Act + var serialized = JsonConvert.SerializeObject(patchDoc); + + // Assert + Assert.Equal(false, serialized.Contains("operations")); + Assert.Equal(false, serialized.Contains("Operations")); + } + + [Fact] + public void DeserializationMustWorkWithoutEnvelope() + { + // Arrange + var doc = new SimpleDTO() + { + StringProperty = "A", + DecimalValue = 10, + DoubleValue = 10, + FloatValue = 10, + IntegerValue = 10 + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Replace(o => o.StringProperty, "B"); + patchDoc.Replace(o => o.DecimalValue, 12); + patchDoc.Replace(o => o.DoubleValue, 12); + patchDoc.Replace(o => o.FloatValue, 12); + patchDoc.Replace(o => o.IntegerValue, 12); + + // default: no envelope + var serialized = JsonConvert.SerializeObject(patchDoc); + + // Act + var deserialized = JsonConvert.DeserializeObject>(serialized); + + // Assert + Assert.IsType>(deserialized); + } + + [Fact] + public void DeserializationMustFailWithEnvelope() + { + // Arrange + string serialized = "{\"Operations\": [{ \"op\": \"replace\", \"path\": \"/title\", \"value\": \"New Title\"}]}"; + + // Act & Assert + var exception = Assert.Throws(() => + { + var deserialized + = JsonConvert.DeserializeObject>(serialized); + }); + + Assert.Equal("The type 'JsonPatchDocument`1' was malformed and could not be parsed.", exception.Message); + } + + [Fact] + public void SerializationTests() + { + // Arrange + var doc = new SimpleDTO() + { + StringProperty = "A", + DecimalValue = 10, + DoubleValue = 10, + FloatValue = 10, + IntegerValue = 10 + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Replace(o => o.StringProperty, "B"); + patchDoc.Replace(o => o.DecimalValue, 12); + patchDoc.Replace(o => o.DoubleValue, 12); + patchDoc.Replace(o => o.FloatValue, 12); + patchDoc.Replace(o => o.IntegerValue, 12); + + // serialize & deserialize + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserizalized = JsonConvert.DeserializeObject>(serialized); + + // Act + deserizalized.ApplyTo(doc); + + // Assert + Assert.Equal("B", doc.StringProperty); + Assert.Equal(12, doc.DecimalValue); + Assert.Equal(12, doc.DoubleValue); + Assert.Equal(12, doc.FloatValue); + Assert.Equal(12, doc.IntegerValue); + } + + [Fact] + public void SerializeAndReplaceGuidTest() + { + // Arrange + var doc = new SimpleDTO() + { + GuidValue = Guid.NewGuid() + }; + + var newGuid = Guid.NewGuid(); + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Replace(o => o.GuidValue, newGuid); + + // serialize & deserialize + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserizalized = JsonConvert.DeserializeObject>(serialized); + + // Act + deserizalized.ApplyTo(doc); + + // Assert + Assert.Equal(newGuid, doc.GuidValue); + } + + [Fact] + public void SerializeAndReplaceNestedObjectTest() + { + // Arrange + var doc = new SimpleDTOWithNestedDTO() + { + SimpleDTO = new SimpleDTO() + { + IntegerValue = 5, + IntegerList = new List() { 1, 2, 3 } + } + }; + + var newDTO = new SimpleDTO() + { + DoubleValue = 1 + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Replace(o => o.SimpleDTO, newDTO); + + // serialize & deserialize + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject>(serialized); + + // Act + deserialized.ApplyTo(doc); + + // Assert + Assert.Equal(1, doc.SimpleDTO.DoubleValue); + Assert.Equal(0, doc.SimpleDTO.IntegerValue); + Assert.Equal(null, doc.SimpleDTO.IntegerList); + } + + [Fact] + public void ReplaceInList() + { + // Arrange + var doc = new SimpleDTO() + { + IntegerList = new List() { 1, 2, 3 } + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Replace(o => o.IntegerList, 5, 0); + + // Act + patchDoc.ApplyTo(doc); + + // Assert + Assert.Equal(new List() { 5, 2, 3 }, doc.IntegerList); + } + + [Fact] + public void ReplaceInListWithSerialization() + { + // Arrange + var doc = new SimpleDTO() + { + IntegerList = new List() { 1, 2, 3 } + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Replace(o => o.IntegerList, 5, 0); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject>(serialized); + + // Act + deserialized.ApplyTo(doc); + + // Assert + Assert.Equal(new List() { 5, 2, 3 }, doc.IntegerList); + } + + [Fact] + public void ReplaceFullList() + { + // Arrange + var doc = new SimpleDTO() + { + IntegerList = new List() { 1, 2, 3 } + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Replace>(o => o.IntegerList, new List() { 4, 5, 6 }); + + // Act + patchDoc.ApplyTo(doc); + + // Assert + Assert.Equal(new List() { 4, 5, 6 }, doc.IntegerList); + } + + [Fact] + public void ReplaceFullListWithSerialization() + { + // Arrange + var doc = new SimpleDTO() + { + IntegerList = new List() { 1, 2, 3 } + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Replace>(o => o.IntegerList, new List() { 4, 5, 6 }); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject>(serialized); + + // Act + deserialized.ApplyTo(doc); + + // Assert + Assert.Equal(new List() { 4, 5, 6 }, doc.IntegerList); + } + + [Fact] + public void ReplaceFullListFromEnumerable() + { + // Arrange + var doc = new SimpleDTO() + { + IntegerList = new List() { 1, 2, 3 } + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Replace>(o => o.IntegerList, new List() { 4, 5, 6 }); + + // Act + patchDoc.ApplyTo(doc); + + // Assert + Assert.Equal(new List() { 4, 5, 6 }, doc.IntegerList); + } + + [Fact] + public void ReplaceFullListFromEnumerableWithSerialization() + { + // Arrange + var doc = new SimpleDTO() + { + IntegerList = new List() { 1, 2, 3 } + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Replace>(o => o.IntegerList, new List() { 4, 5, 6 }); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject>(serialized); + + // Act + deserialized.ApplyTo(doc); + + // Assert + Assert.Equal(new List() { 4, 5, 6 }, doc.IntegerList); + } + + [Fact] + public void ReplaceFullListWithCollection() + { + // Arrange + var doc = new SimpleDTO() + { + IntegerList = new List() { 1, 2, 3 } + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Replace>(o => o.IntegerList, new Collection() { 4, 5, 6 }); + + // Act + patchDoc.ApplyTo(doc); + + // Assert + Assert.Equal(new List() { 4, 5, 6 }, doc.IntegerList); + } + + [Fact] + public void ReplaceFullListWithCollectionWithSerialization() + { + // Arrange + var doc = new SimpleDTO() + { + IntegerList = new List() { 1, 2, 3 } + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Replace>(o => o.IntegerList, new Collection() { 4, 5, 6 }); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject>(serialized); + + // Act + deserialized.ApplyTo(doc); + + // Assert + Assert.Equal(new List() { 4, 5, 6 }, doc.IntegerList); + } + + [Fact] + public void ReplaceAtEndOfList() + { + // Arrange + var doc = new SimpleDTO() + { + IntegerList = new List() { 1, 2, 3 } + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Replace(o => o.IntegerList, 5); + + // Act + patchDoc.ApplyTo(doc); + + // Assert + Assert.Equal(new List() { 1, 2, 5 }, doc.IntegerList); + } + + [Fact] + public void ReplaceAtEndOfListWithSerialization() + { + // Arrange + var doc = new SimpleDTO() + { + IntegerList = new List() { 1, 2, 3 } + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Replace(o => o.IntegerList, 5); + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject>(serialized); + + // Act + deserialized.ApplyTo(doc); + + // Assert + Assert.Equal(new List() { 1, 2, 5 }, doc.IntegerList); + } + + [Fact] + public void ReplaceInListInvalidInvalidPositionTooLarge() + { + // Arrange + var doc = new SimpleDTO() + { + IntegerList = new List() { 1, 2, 3 } + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Replace(o => o.IntegerList, 5, 3); + + // Act & Assert + var exception = Assert.Throws(() => + { + patchDoc.ApplyTo(doc); + }); + Assert.Equal( + "For operation 'replace' on array property at path '/integerlist/3', the index is " + + "larger than the array size.", + exception.Message); + } + + [Fact] + public void ReplaceInListInvalidInvalidPositionTooLargeWithSerialization() + { + // Arrange + var doc = new SimpleDTO() + { + IntegerList = new List() { 1, 2, 3 } + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Replace(o => o.IntegerList, 5, 3); + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject>(serialized); + + // Act & Assert + var exception = Assert.Throws(() => + { + deserialized.ApplyTo(doc); + }); + Assert.Equal( + "For operation 'replace' on array property at path '/integerlist/3', the index is " + + "larger than the array size.", + exception.Message); + } + + [Fact] + public void ReplaceInListInvalidPositionTooSmall() + { + // Arrange + var doc = new SimpleDTO() + { + IntegerList = new List() { 1, 2, 3 } + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Replace(o => o.IntegerList, 5, -1); + + // Act & Assert + var exception = Assert.Throws(() => + { + patchDoc.ApplyTo(doc); + }); + Assert.Equal("For operation 'replace' on array property at path '/integerlist/-1', the index is negative.", exception.Message); + } + + [Fact] + public void ReplaceInListInvalidPositionTooSmallWithSerialization() + { + // Arrange + var doc = new SimpleDTO() + { + IntegerList = new List() { 1, 2, 3 } + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Replace(o => o.IntegerList, 5, -1); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject>(serialized); + + // Act & Assert + var exception = Assert.Throws(() => + { + deserialized.ApplyTo(doc); + }); + Assert.Equal("For operation 'replace' on array property at path '/integerlist/-1', the index is negative.", exception.Message); + } + + [Fact] + public void Copy() + { + // Arrange + var doc = new SimpleDTO() + { + StringProperty = "A", + AnotherStringProperty = "B" + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Copy(o => o.StringProperty, o => o.AnotherStringProperty); + + // Act + patchDoc.ApplyTo(doc); + + // Assert + Assert.Equal("A", doc.AnotherStringProperty); + } + + [Fact] + public void CopyWithSerialization() + { + // Arrange + var doc = new SimpleDTO() + { + StringProperty = "A", + AnotherStringProperty = "B" + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Copy(o => o.StringProperty, o => o.AnotherStringProperty); + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject>(serialized); + + // Act + deserialized.ApplyTo(doc); + + // Assert + Assert.Equal("A", doc.AnotherStringProperty); + } + + [Fact] + public void CopyInList() + { + // Arrange + var doc = new SimpleDTO() + { + IntegerList = new List() { 1, 2, 3 } + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Copy(o => o.IntegerList, 0, o => o.IntegerList, 1); + + // Act + patchDoc.ApplyTo(doc); + + // Assert + Assert.Equal(new List() { 1, 1, 2, 3 }, doc.IntegerList); + } + + [Fact] + public void CopyInListWithSerialization() + { + // Arrange + var doc = new SimpleDTO() + { + IntegerList = new List() { 1, 2, 3 } + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Copy(o => o.IntegerList, 0, o => o.IntegerList, 1); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject>(serialized); + + // Act + deserialized.ApplyTo(doc); + + // Assert + Assert.Equal(new List() { 1, 1, 2, 3 }, doc.IntegerList); + } + + [Fact] + public void CopyFromListToEndOfList() + { + // Arrange + var doc = new SimpleDTO() + { + IntegerList = new List() { 1, 2, 3 } + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Copy(o => o.IntegerList, 0, o => o.IntegerList); + + // Act + patchDoc.ApplyTo(doc); + + // Assert + Assert.Equal(new List() { 1, 2, 3, 1 }, doc.IntegerList); + } + + [Fact] + public void CopyFromListToEndOfListWithSerialization() + { + // Arrange + var doc = new SimpleDTO() + { + IntegerList = new List() { 1, 2, 3 } + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Copy(o => o.IntegerList, 0, o => o.IntegerList); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject>(serialized); + + // Act + deserialized.ApplyTo(doc); + + // Assert + Assert.Equal(new List() { 1, 2, 3, 1 }, doc.IntegerList); + } + + [Fact] + public void CopyFromListToNonList() + { + // Arrange + var doc = new SimpleDTO() + { + IntegerList = new List() { 1, 2, 3 } + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Copy(o => o.IntegerList, 0, o => o.IntegerValue); + + // Act + patchDoc.ApplyTo(doc); + + // Assert + Assert.Equal(1, doc.IntegerValue); + } + + [Fact] + public void CopyFromListToNonListWithSerialization() + { + // Arrange + var doc = new SimpleDTO() + { + IntegerList = new List() { 1, 2, 3 } + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Copy(o => o.IntegerList, 0, o => o.IntegerValue); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject>(serialized); + + // Act + deserialized.ApplyTo(doc); + + // Assert + Assert.Equal(1, doc.IntegerValue); + } + + [Fact] + public void CopyFromNonListToList() + { + // Arrange + var doc = new SimpleDTO() + { + IntegerValue = 5, + IntegerList = new List() { 1, 2, 3 } + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Copy(o => o.IntegerValue, o => o.IntegerList, 0); + + // Act + patchDoc.ApplyTo(doc); + + // Assert + Assert.Equal(new List() { 5, 1, 2, 3 }, doc.IntegerList); + } + + [Fact] + public void CopyFromNonListToListWithSerialization() + { + // Arrange + var doc = new SimpleDTO() + { + IntegerValue = 5, + IntegerList = new List() { 1, 2, 3 } + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Copy(o => o.IntegerValue, o => o.IntegerList, 0); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject>(serialized); + + // Act + deserialized.ApplyTo(doc); + + // Assert + Assert.Equal(new List() { 5, 1, 2, 3 }, doc.IntegerList); + } + + [Fact] + public void CopyToEndOfList() + { + // Arrange + var doc = new SimpleDTO() + { + IntegerValue = 5, + IntegerList = new List() { 1, 2, 3 } + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Copy(o => o.IntegerValue, o => o.IntegerList); + + // Act + patchDoc.ApplyTo(doc); + + // Assert + Assert.Equal(new List() { 1, 2, 3, 5 }, doc.IntegerList); + } + + [Fact] + public void CopyToEndOfListWithSerialization() + { + // Arrange + var doc = new SimpleDTO() + { + IntegerValue = 5, + IntegerList = new List() { 1, 2, 3 } + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Copy(o => o.IntegerValue, o => o.IntegerList); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject>(serialized); + + // Act + deserialized.ApplyTo(doc); + + // Assert + Assert.Equal(new List() { 1, 2, 3, 5 }, doc.IntegerList); + } + + [Fact] + public void Move() + { + // Arrange + var doc = new SimpleDTO() + { + StringProperty = "A", + AnotherStringProperty = "B" + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Move(o => o.StringProperty, o => o.AnotherStringProperty); + + // Act + patchDoc.ApplyTo(doc); + + // Assert + Assert.Equal("A", doc.AnotherStringProperty); + Assert.Equal(null, doc.StringProperty); + } + + [Fact] + public void MoveWithSerialization() + { + // Arrange + var doc = new SimpleDTO() + { + StringProperty = "A", + AnotherStringProperty = "B" + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Move(o => o.StringProperty, o => o.AnotherStringProperty); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject>(serialized); + + // Act + deserialized.ApplyTo(doc); + + // Assert + Assert.Equal("A", doc.AnotherStringProperty); + Assert.Equal(null, doc.StringProperty); + } + + [Fact] + public void MoveInList() + { + // Arrange + var doc = new SimpleDTO() + { + IntegerList = new List() { 1, 2, 3 } + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Move(o => o.IntegerList, 0, o => o.IntegerList, 1); + + // Act + patchDoc.ApplyTo(doc); + + // Assert + Assert.Equal(new List() { 2, 1, 3 }, doc.IntegerList); + } + + [Fact] + public void MoveInListWithSerialization() + { + // Arrange + var doc = new SimpleDTO() + { + IntegerList = new List() { 1, 2, 3 } + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Move(o => o.IntegerList, 0, o => o.IntegerList, 1); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject>(serialized); + + // Act + deserialized.ApplyTo(doc); + + // Assert + Assert.Equal(new List() { 2, 1, 3 }, doc.IntegerList); + } + + [Fact] + public void MoveFromListToEndOfList() + { + // Arrange + var doc = new SimpleDTO() + { + IntegerList = new List() { 1, 2, 3 } + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Move(o => o.IntegerList, 0, o => o.IntegerList); + + // Act + patchDoc.ApplyTo(doc); + + // Assert + Assert.Equal(new List() { 2, 3, 1 }, doc.IntegerList); + } + + [Fact] + public void MoveFromListToEndOfListWithSerialization() + { + // Arrange + var doc = new SimpleDTO() + { + IntegerList = new List() { 1, 2, 3 } + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Move(o => o.IntegerList, 0, o => o.IntegerList); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject>(serialized); + + // Act + deserialized.ApplyTo(doc); + + // Assert + Assert.Equal(new List() { 2, 3, 1 }, doc.IntegerList); + } + + [Fact] + public void MoveFomListToNonList() + { + // Arrange + var doc = new SimpleDTO() + { + IntegerList = new List() { 1, 2, 3 } + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Move(o => o.IntegerList, 0, o => o.IntegerValue); + + // Act + patchDoc.ApplyTo(doc); + + // Assert + Assert.Equal(new List() { 2, 3 }, doc.IntegerList); + Assert.Equal(1, doc.IntegerValue); + } + + [Fact] + public void MoveFomListToNonListWithSerialization() + { + // Arrange + var doc = new SimpleDTO() + { + IntegerList = new List() { 1, 2, 3 } + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Move(o => o.IntegerList, 0, o => o.IntegerValue); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject>(serialized); + + // Act + deserialized.ApplyTo(doc); + + // Assert + Assert.Equal(new List() { 2, 3 }, doc.IntegerList); + Assert.Equal(1, doc.IntegerValue); + } + + [Fact] + public void MoveFromNonListToList() + { + // Arrange + var doc = new SimpleDTO() + { + IntegerValue = 5, + IntegerList = new List() { 1, 2, 3 } + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Move(o => o.IntegerValue, o => o.IntegerList, 0); + + // Act + patchDoc.ApplyTo(doc); + + // Assert + Assert.Equal(0, doc.IntegerValue); + Assert.Equal(new List() { 5, 1, 2, 3 }, doc.IntegerList); + } + + [Fact] + public void MoveFromNonListToListWithSerialization() + { + // Arrange + var doc = new SimpleDTO() + { + IntegerValue = 5, + IntegerList = new List() { 1, 2, 3 } + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Move(o => o.IntegerValue, o => o.IntegerList, 0); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject>(serialized); + + // Act + deserialized.ApplyTo(doc); + + // Assert + Assert.Equal(0, doc.IntegerValue); + Assert.Equal(new List() { 5, 1, 2, 3 }, doc.IntegerList); + } + + [Fact] + public void MoveToEndOfList() + { + // Arrange + var doc = new SimpleDTO() + { + IntegerValue = 5, + IntegerList = new List() { 1, 2, 3 } + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Move(o => o.IntegerValue, o => o.IntegerList); + + // Act + patchDoc.ApplyTo(doc); + + // Assert + Assert.Equal(0, doc.IntegerValue); + Assert.Equal(new List() { 1, 2, 3, 5 }, doc.IntegerList); + } + + [Fact] + public void MoveToEndOfListWithSerialization() + { + // Arrange + var doc = new SimpleDTO() + { + IntegerValue = 5, + IntegerList = new List() { 1, 2, 3 } + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Move(o => o.IntegerValue, o => o.IntegerList); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject>(serialized); + + // Act + deserialized.ApplyTo(doc); + + // Assert + Assert.Equal(0, doc.IntegerValue); + Assert.Equal(new List() { 1, 2, 3, 5 }, doc.IntegerList); + } + } +} \ No newline at end of file diff --git a/test/Microsoft.AspNet.JsonPatch.Test/SimpleDTO.cs b/test/Microsoft.AspNet.JsonPatch.Test/SimpleDTO.cs new file mode 100644 index 0000000000..0c29a86e83 --- /dev/null +++ b/test/Microsoft.AspNet.JsonPatch.Test/SimpleDTO.cs @@ -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; +using System.Collections; +using System.Collections.Generic; + +namespace Microsoft.AspNet.JsonPatch.Test +{ + public class SimpleDTO + { + public List IntegerList { get; set; } + public IList IntegerIList { get; set; } + public int IntegerValue { get; set; } + public string StringProperty { get; set; } + public string AnotherStringProperty { get; set; } + public decimal DecimalValue { get; set; } + public double DoubleValue { get; set; } + public float FloatValue { get; set; } + public Guid GuidValue { get; set; } + } +} \ No newline at end of file diff --git a/test/Microsoft.AspNet.JsonPatch.Test/SimpleDTOWithNestedDTO.cs b/test/Microsoft.AspNet.JsonPatch.Test/SimpleDTOWithNestedDTO.cs new file mode 100644 index 0000000000..81aa38e682 --- /dev/null +++ b/test/Microsoft.AspNet.JsonPatch.Test/SimpleDTOWithNestedDTO.cs @@ -0,0 +1,27 @@ +// 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.AspNet.JsonPatch.Test +{ + public class SimpleDTOWithNestedDTO + { + public int IntegerValue { get; set; } + + public NestedDTO NestedDTO { get; set; } + + public SimpleDTO SimpleDTO { get; set; } + + public List SimpleDTOList { get; set; } + + public IList SimpleDTOIList { get; set; } + + public SimpleDTOWithNestedDTO() + { + this.NestedDTO = new NestedDTO(); + this.SimpleDTO = new SimpleDTO(); + this.SimpleDTOList = new List(); + } + } +} \ No newline at end of file diff --git a/test/Microsoft.AspNet.JsonPatch.Test/TestErrorLogger.cs b/test/Microsoft.AspNet.JsonPatch.Test/TestErrorLogger.cs new file mode 100644 index 0000000000..c254eab3e3 --- /dev/null +++ b/test/Microsoft.AspNet.JsonPatch.Test/TestErrorLogger.cs @@ -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.AspNet.JsonPatch.Test +{ + public class TestErrorLogger where T: class + { + public string ErrorMessage { get; set; } + + public void LogErrorMessage(JsonPatchError patchError) + { + ErrorMessage = patchError.ErrorMessage; + } + } +} diff --git a/test/Microsoft.AspNet.JsonPatch.Test/project.json b/test/Microsoft.AspNet.JsonPatch.Test/project.json new file mode 100644 index 0000000000..629b7a1be3 --- /dev/null +++ b/test/Microsoft.AspNet.JsonPatch.Test/project.json @@ -0,0 +1,18 @@ +{ + "compilationOptions": { + "warningsAsErrors": true + }, + "dependencies": { + "Microsoft.AspNet.JsonPatch": "1.0.0-*", + "Microsoft.AspNet.Testing": "1.0.0-*", + "Moq": "4.2.1312.1622", + "Newtonsoft.Json": "6.0.6", + "xunit.runner.aspnet": "2.0.0-aspnet-*" + }, + "commands": { + "test": "xunit.runner.aspnet" + }, + "frameworks": { + "dnx451": { } + } +} \ No newline at end of file From ae0baac22742650e734a41a26e67f864be859b55 Mon Sep 17 00:00:00 2001 From: Ryan Nowak Date: Mon, 21 Sep 2015 11:47:54 -0700 Subject: [PATCH 006/221] simplify .travis.yml --- .travis.yml | 9 --------- 1 file changed, 9 deletions(-) diff --git a/.travis.yml b/.travis.yml index 568e2673e9..947bf868ee 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,13 +1,4 @@ language: csharp sudo: false -mono: - - beta -env: - - MONO_THREADS_PER_CPU=2000 MONO_MANAGED_WATCHER=disabled -os: - - linux - - osx -before_script: - - if [ $TRAVIS_OS_NAME == "osx" ] ; then sudo sysctl -w kern.maxfiles=64000 ; sudo sysctl -w kern.maxfilesperproc=64000 ; sudo launchctl limit maxfiles 64000 64000 ; fi ; ulimit -n 64000 script: - ./build.sh --quiet verify \ No newline at end of file From 22f22c04076c598735469306b291075b7ebfde62 Mon Sep 17 00:00:00 2001 From: Ryan Nowak Date: Mon, 21 Sep 2015 12:48:21 -0700 Subject: [PATCH 007/221] chmod+x on build.sh --- build.sh | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 build.sh diff --git a/build.sh b/build.sh old mode 100644 new mode 100755 From 7b697e8ec9aa2a7278d834189dc1cfc324eac8f0 Mon Sep 17 00:00:00 2001 From: Ajay Bhargav Baaskaran Date: Tue, 22 Sep 2015 16:06:18 -0700 Subject: [PATCH 008/221] Enabling NuGetPackageVerifier --- NuGetPackageVerifier.json | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 NuGetPackageVerifier.json diff --git a/NuGetPackageVerifier.json b/NuGetPackageVerifier.json new file mode 100644 index 0000000000..a45e74c44d --- /dev/null +++ b/NuGetPackageVerifier.json @@ -0,0 +1,25 @@ +{ + "adx": { // Packages written by the ADX team and that ship on NuGet.org + "rules": [ + "AssemblyHasDocumentFileRule", + "AssemblyHasVersionAttributesRule", + "AssemblyHasServicingAttributeRule", + "AssemblyHasNeutralResourcesLanguageAttributeRule", + "SatellitePackageRule", + "StrictSemanticVersionValidationRule" + ], + "packages": { + "Microsoft.AspNet.JsonPatch": { } + } + }, + "Default": { // Rules to run for packages not listed in any other set. + "rules": [ + "AssemblyHasDocumentFileRule", + "AssemblyHasVersionAttributesRule", + "AssemblyHasServicingAttributeRule", + "AssemblyHasNeutralResourcesLanguageAttributeRule", + "SatellitePackageRule", + "StrictSemanticVersionValidationRule" + ] + } +} \ No newline at end of file From bed133858e92099df6dcb269761d6ceb000c40cf Mon Sep 17 00:00:00 2001 From: Pranav K Date: Tue, 29 Sep 2015 12:39:30 -0700 Subject: [PATCH 009/221] Updating to release NuGet.config --- NuGet.config | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NuGet.config b/NuGet.config index 5500f6d507..20950d3df6 100644 --- a/NuGet.config +++ b/NuGet.config @@ -1,7 +1,7 @@  - + From 182b7d588c94085f663788a659eb65fd2506e8d0 Mon Sep 17 00:00:00 2001 From: "N. Taylor Mullen" Date: Thu, 1 Oct 2015 12:13:37 -0700 Subject: [PATCH 010/221] Update 'build.cmd' alias parameter to use full name. --- build.cmd | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.cmd b/build.cmd index 177997c42e..30b3dbba60 100644 --- a/build.cmd +++ b/build.cmd @@ -30,10 +30,10 @@ IF "%SKIP_DNX_INSTALL%"=="1" goto run IF %BUILDCMD_DNX_VERSION%=="" ( CALL packages\KoreBuild\build\dnvm upgrade -runtime CLR -arch x86 ) ELSE ( - CALL packages\KoreBuild\build\dnvm install %BUILDCMD_DNX_VERSION% -runtime CLR -arch x86 -a default + CALL packages\KoreBuild\build\dnvm install %BUILDCMD_DNX_VERSION% -runtime CLR -arch x86 -alias default ) CALL packages\KoreBuild\build\dnvm install default -runtime CoreCLR -arch x86 :run CALL packages\KoreBuild\build\dnvm use default -runtime CLR -arch x86 -packages\Sake\tools\Sake.exe -I packages\KoreBuild\build -f makefile.shade %* \ No newline at end of file +packages\Sake\tools\Sake.exe -I packages\KoreBuild\build -f makefile.shade %* From 21a1c2063c7474cd67c9cae5a2969f18df49a499 Mon Sep 17 00:00:00 2001 From: Doug Bunting Date: Thu, 8 Oct 2015 19:00:51 -0700 Subject: [PATCH 011/221] React to aspnet/Universe#290 fix --- build.cmd | 23 ++++++++++++----------- build.sh | 12 +++++++----- 2 files changed, 19 insertions(+), 16 deletions(-) diff --git a/build.cmd b/build.cmd index 30b3dbba60..84dc87e480 100644 --- a/build.cmd +++ b/build.cmd @@ -18,22 +18,23 @@ md .nuget copy %CACHED_NUGET% .nuget\nuget.exe > nul :restore -IF EXIST packages\KoreBuild goto run +IF EXIST packages\Sake goto getdnx IF %BUILDCMD_KOREBUILD_VERSION%=="" ( - .nuget\nuget.exe install KoreBuild -ExcludeVersion -o packages -nocache -pre + .nuget\nuget.exe install KoreBuild -ExcludeVersion -o packages -nocache -pre ) ELSE ( - .nuget\nuget.exe install KoreBuild -version %BUILDCMD_KOREBUILD_VERSION% -ExcludeVersion -o packages -nocache -pre + .nuget\nuget.exe install KoreBuild -version %BUILDCMD_KOREBUILD_VERSION% -ExcludeVersion -o packages -nocache -pre ) -.nuget\nuget.exe install Sake -ExcludeVersion -Out packages +.nuget\NuGet.exe install Sake -ExcludeVersion -Source https://www.nuget.org/api/v2/ -Out packages -IF "%SKIP_DNX_INSTALL%"=="1" goto run -IF %BUILDCMD_DNX_VERSION%=="" ( - CALL packages\KoreBuild\build\dnvm upgrade -runtime CLR -arch x86 +:getdnx +IF "%SKIP_DNX_INSTALL%"=="" ( + IF "%BUILDCMD_DNX_VERSION%"=="" ( + BUILDCMD_DNX_VERSION=latest + ) + CALL packages\KoreBuild\build\dnvm install %BUILDCMD_DNX_VERSION% -runtime CoreCLR -arch x86 -alias default + CALL packages\KoreBuild\build\dnvm install default -runtime CLR -arch x86 -alias default ) ELSE ( - CALL packages\KoreBuild\build\dnvm install %BUILDCMD_DNX_VERSION% -runtime CLR -arch x86 -alias default + CALL packages\KoreBuild\build\dnvm use default -runtime CLR -arch x86 ) -CALL packages\KoreBuild\build\dnvm install default -runtime CoreCLR -arch x86 -:run -CALL packages\KoreBuild\build\dnvm use default -runtime CLR -arch x86 packages\Sake\tools\Sake.exe -I packages\KoreBuild\build -f makefile.shade %* diff --git a/build.sh b/build.sh index 0c66139817..da4e3fcd1c 100755 --- a/build.sh +++ b/build.sh @@ -24,18 +24,20 @@ if test ! -e .nuget; then cp $cachePath .nuget/nuget.exe fi -if test ! -d packages/KoreBuild; then +if test ! -d packages/Sake; then mono .nuget/nuget.exe install KoreBuild -ExcludeVersion -o packages -nocache -pre - mono .nuget/nuget.exe install Sake -ExcludeVersion -Out packages + mono .nuget/nuget.exe install Sake -ExcludeVersion -Source https://www.nuget.org/api/v2/ -Out packages fi if ! type dnvm > /dev/null 2>&1; then source packages/KoreBuild/build/dnvm.sh fi -if ! type dnx > /dev/null 2>&1; then - dnvm upgrade +if ! type dnx > /dev/null 2>&1 || [ -z "$SKIP_DNX_INSTALL" ]; then + dnvm install latest -runtime coreclr -alias default + dnvm install default -runtime mono -alias default +else + dnvm use default -runtime mono fi mono packages/Sake/tools/Sake.exe -I packages/KoreBuild/build -f makefile.shade "$@" - From 62ca4d6a8cbc1951dbda0f585fa0ec6282fb6eb3 Mon Sep 17 00:00:00 2001 From: Doug Bunting Date: Mon, 12 Oct 2015 12:56:34 -0700 Subject: [PATCH 012/221] Fix local build break --- build.cmd | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/build.cmd b/build.cmd index 84dc87e480..553e3929a0 100644 --- a/build.cmd +++ b/build.cmd @@ -4,8 +4,8 @@ cd %~dp0 SETLOCAL SET NUGET_VERSION=latest SET CACHED_NUGET=%LocalAppData%\NuGet\nuget.%NUGET_VERSION%.exe -SET BUILDCMD_KOREBUILD_VERSION="" -SET BUILDCMD_DNX_VERSION="" +SET BUILDCMD_KOREBUILD_VERSION= +SET BUILDCMD_DNX_VERSION= IF EXIST %CACHED_NUGET% goto copynuget echo Downloading latest version of NuGet.exe... @@ -19,7 +19,7 @@ copy %CACHED_NUGET% .nuget\nuget.exe > nul :restore IF EXIST packages\Sake goto getdnx -IF %BUILDCMD_KOREBUILD_VERSION%=="" ( +IF "%BUILDCMD_KOREBUILD_VERSION%"=="" ( .nuget\nuget.exe install KoreBuild -ExcludeVersion -o packages -nocache -pre ) ELSE ( .nuget\nuget.exe install KoreBuild -version %BUILDCMD_KOREBUILD_VERSION% -ExcludeVersion -o packages -nocache -pre @@ -27,10 +27,10 @@ IF %BUILDCMD_KOREBUILD_VERSION%=="" ( .nuget\NuGet.exe install Sake -ExcludeVersion -Source https://www.nuget.org/api/v2/ -Out packages :getdnx +IF "%BUILDCMD_DNX_VERSION%"=="" ( + SET BUILDCMD_DNX_VERSION=latest +) IF "%SKIP_DNX_INSTALL%"=="" ( - IF "%BUILDCMD_DNX_VERSION%"=="" ( - BUILDCMD_DNX_VERSION=latest - ) CALL packages\KoreBuild\build\dnvm install %BUILDCMD_DNX_VERSION% -runtime CoreCLR -arch x86 -alias default CALL packages\KoreBuild\build\dnvm install default -runtime CLR -arch x86 -alias default ) ELSE ( From 127fc1388537e7c9d2f211942511f40d106de716 Mon Sep 17 00:00:00 2001 From: Pranav K Date: Wed, 21 Oct 2015 21:24:19 -0700 Subject: [PATCH 013/221] Switching to using generations TFM --- src/Microsoft.AspNet.JsonPatch/project.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Microsoft.AspNet.JsonPatch/project.json b/src/Microsoft.AspNet.JsonPatch/project.json index 8d67ec1808..c08afdec7e 100644 --- a/src/Microsoft.AspNet.JsonPatch/project.json +++ b/src/Microsoft.AspNet.JsonPatch/project.json @@ -8,8 +8,8 @@ "Newtonsoft.Json": "6.0.6" }, "frameworks": { - "dnx451": { }, - "dnxcore50": { + "net451": {}, + "dotnet5.4": { "dependencies": { "Microsoft.CSharp": "4.0.1-beta-*", "System.Collections.Concurrent": "4.0.11-beta-*", @@ -22,4 +22,4 @@ } } } -} +} \ No newline at end of file From 76346e48a6e2ce577847be0401ac073c7ceda1ee Mon Sep 17 00:00:00 2001 From: Pranav K Date: Wed, 28 Oct 2015 12:43:05 -0700 Subject: [PATCH 014/221] Updating to release NuGet.config. --- NuGet.config | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/NuGet.config b/NuGet.config index 5500f6d507..71b9724a09 100644 --- a/NuGet.config +++ b/NuGet.config @@ -1,7 +1,7 @@ - + - + From 8a0696602401328e3493ac1ebea67061ce1a692b Mon Sep 17 00:00:00 2001 From: Cesar Blum Silveira Date: Fri, 30 Oct 2015 12:19:00 -0700 Subject: [PATCH 015/221] Strong name Microsoft.AspNet.JsonPatch. --- src/Microsoft.AspNet.JsonPatch/project.json | 4 ++++ tools/Key.snk | Bin 0 -> 596 bytes 2 files changed, 4 insertions(+) create mode 100644 tools/Key.snk diff --git a/src/Microsoft.AspNet.JsonPatch/project.json b/src/Microsoft.AspNet.JsonPatch/project.json index c08afdec7e..d9b41653fb 100644 --- a/src/Microsoft.AspNet.JsonPatch/project.json +++ b/src/Microsoft.AspNet.JsonPatch/project.json @@ -1,5 +1,9 @@ { "version": "1.0.0-*", + "compilationOptions": { + "warningsAsErrors": true, + "keyFile": "../../tools/Key.snk" + }, "repository": { "type": "git", "url": "git://github.com/aspnet/mvc" diff --git a/tools/Key.snk b/tools/Key.snk new file mode 100644 index 0000000000000000000000000000000000000000..e10e4889c125d3120cd9e81582243d70f7cbb806 GIT binary patch literal 596 zcmV-a0;~N80ssI2Bme+XQ$aES1ONa50098=Iw=HCsnz~#iVhm& zj%TU(_THUee?3yHBjk$37ysB?i5#7WD$={H zV4B!OxRPrb|8)HPg~A}8P>^=#y<)56#=E&NzcjOtPK~<4n6GHt=K$ro*T(lhby_@U zEk(hLzk1H)0yXj{A_5>fk-TgNoP|q6(tP2xo8zt8i%212CWM#AeCd?`hS|4~L({h~Moo(~vy&3Z z1uI}`fd^*>o=rwbAGymj6RM^pZm(*Kfhs+Y1#`-2JPWZMK8@;ZWCk2+9bX4YP);~fj-BU*R zQPvWv$89!{Rl9wM+zR>_TSkn^voYxA?2G iKnV#iZ6Ah`K>b=@=IjYJXrxL124zR(38)nxe+&q_$QXwJ literal 0 HcmV?d00001 From f5477d1748905aab3792efa1c4462d5cca6accb8 Mon Sep 17 00:00:00 2001 From: "N. Taylor Mullen" Date: Thu, 12 Nov 2015 12:23:18 -0800 Subject: [PATCH 016/221] Remove System beta tag in project.json for coreclr packages. --- src/Microsoft.AspNet.JsonPatch/project.json | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/Microsoft.AspNet.JsonPatch/project.json b/src/Microsoft.AspNet.JsonPatch/project.json index d9b41653fb..4bbe747d4b 100644 --- a/src/Microsoft.AspNet.JsonPatch/project.json +++ b/src/Microsoft.AspNet.JsonPatch/project.json @@ -15,15 +15,15 @@ "net451": {}, "dotnet5.4": { "dependencies": { - "Microsoft.CSharp": "4.0.1-beta-*", - "System.Collections.Concurrent": "4.0.11-beta-*", - "System.ComponentModel.TypeConverter": "4.0.1-beta-*", - "System.Globalization": "4.0.11-beta-*", - "System.Reflection.Extensions": "4.0.1-beta-*", - "System.Resources.ResourceManager": "4.0.1-beta-*", - "System.Runtime.Extensions": "4.0.11-beta-*", - "System.Text.Encoding.Extensions": "4.0.11-beta-*" + "Microsoft.CSharp": "4.0.1-*", + "System.Collections.Concurrent": "4.0.11-*", + "System.ComponentModel.TypeConverter": "4.0.1-*", + "System.Globalization": "4.0.11-*", + "System.Reflection.Extensions": "4.0.1-*", + "System.Resources.ResourceManager": "4.0.1-*", + "System.Runtime.Extensions": "4.0.11-*", + "System.Text.Encoding.Extensions": "4.0.11-*" } } } -} \ No newline at end of file +} From 02e99e341e91bf72bd7ac210a7c581ef6889c4d2 Mon Sep 17 00:00:00 2001 From: Doug Bunting Date: Tue, 17 Nov 2015 11:03:11 -0800 Subject: [PATCH 017/221] Explicitly choose Mono 4.0.5 - avoids future problems related to aspnet/External#48 - e.g. when Travis updates default Mono version in `csharp` bundle --- .travis.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.travis.yml b/.travis.yml index 947bf868ee..dc44c0f660 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,4 +1,6 @@ language: csharp sudo: false +mono: + - 4.0.5 script: - ./build.sh --quiet verify \ No newline at end of file From b09bdc08f48cbddff43a7ad6045a69b4c8258c11 Mon Sep 17 00:00:00 2001 From: Doug Bunting Date: Tue, 17 Nov 2015 14:01:02 -0800 Subject: [PATCH 018/221] Move Travis to supported Linux distribution - use Ubuntu 14.04 (Trusty) - Travis support for Trusty is in Beta and currently requires `sudo` - run `dnu restore` with DNX Core since aspnet/External#49 is not fixed in Mono versions we can use - add required dependencies for DNX Core to `.travis.yml` - addresses part of aspnet/Universe#290 --- .travis.yml | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index dc44c0f660..2fc624899f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,18 @@ language: csharp -sudo: false +sudo: required +dist: trusty +addons: + apt: + packages: + - gettext + - libcurl4-openssl-dev + - libicu-dev + - libssl-dev + - libunwind8 + - zlib1g +env: + - KOREBUILD_DNU_RESTORE_CORECLR=true mono: - 4.0.5 script: - - ./build.sh --quiet verify \ No newline at end of file + - ./build.sh --quiet verify From 60f5fd591ef301428347de955c02ee06286732db Mon Sep 17 00:00:00 2001 From: Pranav K Date: Mon, 23 Nov 2015 16:40:15 -0800 Subject: [PATCH 019/221] Updating tests to run on dnxcore50 --- .../Dynamic/AddOperationTests.cs | 36 +++++++-------- .../Dynamic/AddTypedOperationTests.cs | 6 +-- .../Dynamic/PatchDocumentTests.cs | 12 ++--- .../Dynamic/RemoveOperationTests.cs | 46 +++++++++---------- .../Dynamic/RemoveTypedOperationTests.cs | 8 ++-- .../Dynamic/SimpleDTOWithNestedDTO.cs | 2 +- .../NestedObjectTests.cs | 29 ++++++------ .../ObjectAdapterTests.cs | 8 ++-- .../SimpleDTO.cs | 1 - .../TestErrorLogger.cs | 2 +- .../project.json | 36 +++++++++------ 11 files changed, 96 insertions(+), 90 deletions(-) diff --git a/test/Microsoft.AspNet.JsonPatch.Test/Dynamic/AddOperationTests.cs b/test/Microsoft.AspNet.JsonPatch.Test/Dynamic/AddOperationTests.cs index 3c2523c5fb..f5a3c384ef 100644 --- a/test/Microsoft.AspNet.JsonPatch.Test/Dynamic/AddOperationTests.cs +++ b/test/Microsoft.AspNet.JsonPatch.Test/Dynamic/AddOperationTests.cs @@ -18,7 +18,7 @@ namespace Microsoft.AspNet.JsonPatch.Test.Dynamic dynamic doc = new { Test = 1 - }; + }; // create patch JsonPatchDocument patchDoc = new JsonPatchDocument(); @@ -33,14 +33,14 @@ namespace Microsoft.AspNet.JsonPatch.Test.Dynamic }); Assert.Equal( "The property at path '/NewInt' could not be added.", - exception.Message); + exception.Message); } [Fact] public void AddNewProperty() { dynamic obj = new ExpandoObject(); - obj.Test = 1; + obj.Test = 1; // create patch JsonPatchDocument patchDoc = new JsonPatchDocument(); @@ -48,7 +48,7 @@ namespace Microsoft.AspNet.JsonPatch.Test.Dynamic var serialized = JsonConvert.SerializeObject(patchDoc); var deserialized = JsonConvert.DeserializeObject(serialized); - + deserialized.ApplyTo(obj); Assert.Equal(1, obj.NewInt); @@ -104,7 +104,7 @@ namespace Microsoft.AspNet.JsonPatch.Test.Dynamic "The property at path '/Nested/NewInt' could not be added.", exception.Message); } - + [Fact] public void AddToExistingPropertyOnNestedObject() { @@ -120,7 +120,7 @@ namespace Microsoft.AspNet.JsonPatch.Test.Dynamic var serialized = JsonConvert.SerializeObject(patchDoc); var deserialized = JsonConvert.DeserializeObject(serialized); - + deserialized.ApplyTo(doc); Assert.Equal("A", doc.nested.StringProperty); @@ -142,13 +142,13 @@ namespace Microsoft.AspNet.JsonPatch.Test.Dynamic var serialized = JsonConvert.SerializeObject(patchDoc); var deserialized = JsonConvert.DeserializeObject(serialized); - + deserialized.ApplyTo(doc); Assert.Equal(1, doc.nested.NewInt); Assert.Equal(1, doc.Test); } - + [Fact] public void AddNewPropertyToExpandoOjectInTypedObject() { @@ -156,7 +156,7 @@ namespace Microsoft.AspNet.JsonPatch.Test.Dynamic { DynamicProperty = new ExpandoObject() }; - + // create patch JsonPatchDocument patchDoc = new JsonPatchDocument(); patchDoc.Add("DynamicProperty/NewInt", 1); @@ -168,9 +168,9 @@ namespace Microsoft.AspNet.JsonPatch.Test.Dynamic Assert.Equal(1, doc.DynamicProperty.NewInt); } - + [Fact] - public void AddNewPropertyToTypedObjectInExpandoObject() + public void AddNewPropertyToTypedObjectInExpandoObject() { dynamic dynamicProperty = new ExpandoObject(); dynamicProperty.StringProperty = "A"; @@ -246,7 +246,7 @@ namespace Microsoft.AspNet.JsonPatch.Test.Dynamic public void AddResultsShouldReplace() { dynamic doc = new ExpandoObject(); - doc.StringProperty = "A"; + doc.StringProperty = "A"; // create patch JsonPatchDocument patchDoc = new JsonPatchDocument(); @@ -289,11 +289,11 @@ namespace Microsoft.AspNet.JsonPatch.Test.Dynamic doc.Nested.DynamicProperty.InBetweenFirst = new ExpandoObject(); doc.Nested.DynamicProperty.InBetweenFirst.InBetweenSecond = new ExpandoObject(); doc.Nested.DynamicProperty.InBetweenFirst.InBetweenSecond.StringProperty = "A"; - + // create patch JsonPatchDocument patchDoc = new JsonPatchDocument(); patchDoc.Add("/Nested/DynamicProperty/InBetweenFirst/InBetweenSecond/StringProperty", "B"); - + var serialized = JsonConvert.SerializeObject(patchDoc); var deserialized = JsonConvert.DeserializeObject(serialized); @@ -301,7 +301,7 @@ namespace Microsoft.AspNet.JsonPatch.Test.Dynamic Assert.Equal("B", doc.Nested.DynamicProperty.InBetweenFirst.InBetweenSecond.StringProperty); } - + [Fact] public void ShouldNotBeAbleToAddToNonExistingPropertyThatIsNotTheRoot() { @@ -387,7 +387,7 @@ namespace Microsoft.AspNet.JsonPatch.Test.Dynamic // create patch JsonPatchDocument patchDoc = new JsonPatchDocument(); patchDoc.Add("stringproperty", "B"); - + var serialized = JsonConvert.SerializeObject(patchDoc); var deserialized = JsonConvert.DeserializeObject(serialized); @@ -415,7 +415,7 @@ namespace Microsoft.AspNet.JsonPatch.Test.Dynamic Assert.Equal(new List() { 4, 1, 2, 3 }, doc.IntegerList); } - + [Fact] public void AddToListNegativePosition() { @@ -452,7 +452,7 @@ namespace Microsoft.AspNet.JsonPatch.Test.Dynamic var serialized = JsonConvert.SerializeObject(patchDoc); var deserialized = JsonConvert.DeserializeObject(serialized); - + deserialized.ApplyTo(doc); Assert.Equal(new List() { 4, 1, 2, 3 }, doc.IntegerList); diff --git a/test/Microsoft.AspNet.JsonPatch.Test/Dynamic/AddTypedOperationTests.cs b/test/Microsoft.AspNet.JsonPatch.Test/Dynamic/AddTypedOperationTests.cs index 4d2e8c646d..7913541514 100644 --- a/test/Microsoft.AspNet.JsonPatch.Test/Dynamic/AddTypedOperationTests.cs +++ b/test/Microsoft.AspNet.JsonPatch.Test/Dynamic/AddTypedOperationTests.cs @@ -21,7 +21,7 @@ namespace Microsoft.AspNet.JsonPatch.Test.Dynamic // create patch JsonPatchDocument patchDoc = new JsonPatchDocument(); patchDoc.Add("IntegerList/-1", 4); - + var serialized = JsonConvert.SerializeObject(patchDoc); var deserialized = JsonConvert.DeserializeObject(serialized); @@ -101,11 +101,11 @@ namespace Microsoft.AspNet.JsonPatch.Test.Dynamic IntegerList = new List() { 1, 2, 3 } } } - }; + }; // create patch JsonPatchDocument patchDoc = new JsonPatchDocument(); patchDoc.Add("ListOfSimpleDTO/20/IntegerList/0", 4); - + var serialized = JsonConvert.SerializeObject(patchDoc); var deserialized = JsonConvert.DeserializeObject(serialized); diff --git a/test/Microsoft.AspNet.JsonPatch.Test/Dynamic/PatchDocumentTests.cs b/test/Microsoft.AspNet.JsonPatch.Test/Dynamic/PatchDocumentTests.cs index e15f85da8e..8b14c3448b 100644 --- a/test/Microsoft.AspNet.JsonPatch.Test/Dynamic/PatchDocumentTests.cs +++ b/test/Microsoft.AspNet.JsonPatch.Test/Dynamic/PatchDocumentTests.cs @@ -8,7 +8,7 @@ using Xunit; namespace Microsoft.AspNet.JsonPatch.Test.Dynamic { public class PatchDocumentTests - { + { [Fact] public void InvalidPathAtBeginningShouldThrowException() { @@ -20,11 +20,11 @@ namespace Microsoft.AspNet.JsonPatch.Test.Dynamic Assert.Equal( "The provided string '//NewInt' is an invalid path.", exception.Message); - } + } [Fact] public void InvalidPathAtEndShouldThrowException() - { + { JsonPatchDocument patchDoc = new JsonPatchDocument(); var exception = Assert.Throws(() => { @@ -33,11 +33,11 @@ namespace Microsoft.AspNet.JsonPatch.Test.Dynamic Assert.Equal( "The provided string 'NewInt//' is an invalid path.", exception.Message); - } + } [Fact] public void InvalidPathWithDotShouldThrowException() - { + { JsonPatchDocument patchDoc = new JsonPatchDocument(); var exception = Assert.Throws(() => { @@ -56,7 +56,7 @@ namespace Microsoft.AspNet.JsonPatch.Test.Dynamic StringProperty = "A", AnotherStringProperty = "B" }; - + JsonPatchDocument patchDoc = new JsonPatchDocument(); patchDoc.Copy("StringProperty", "AnotherStringProperty"); diff --git a/test/Microsoft.AspNet.JsonPatch.Test/Dynamic/RemoveOperationTests.cs b/test/Microsoft.AspNet.JsonPatch.Test/Dynamic/RemoveOperationTests.cs index 9ef28ad7cc..9ecb520b38 100644 --- a/test/Microsoft.AspNet.JsonPatch.Test/Dynamic/RemoveOperationTests.cs +++ b/test/Microsoft.AspNet.JsonPatch.Test/Dynamic/RemoveOperationTests.cs @@ -39,7 +39,7 @@ namespace Microsoft.AspNet.JsonPatch.Test.Dynamic public void RemovePropertyShouldFailIfItDoesntExist() { dynamic doc = new ExpandoObject(); - doc.Test = 1; + doc.Test = 1; // create patch JsonPatchDocument patchDoc = new JsonPatchDocument(); @@ -61,7 +61,7 @@ namespace Microsoft.AspNet.JsonPatch.Test.Dynamic public void RemovePropertyFromExpandoObject() { dynamic obj = new ExpandoObject(); - obj.Test = 1; + obj.Test = 1; // create patch JsonPatchDocument patchDoc = new JsonPatchDocument(); @@ -69,13 +69,13 @@ namespace Microsoft.AspNet.JsonPatch.Test.Dynamic var serialized = JsonConvert.SerializeObject(patchDoc); var deserialized = JsonConvert.DeserializeObject(serialized); - + deserialized.ApplyTo(obj); var cont = obj as IDictionary; object valueFromDictionary; - cont.TryGetValue("Test", out valueFromDictionary); + cont.TryGetValue("Test", out valueFromDictionary); Assert.Null(valueFromDictionary); } @@ -91,7 +91,7 @@ namespace Microsoft.AspNet.JsonPatch.Test.Dynamic var serialized = JsonConvert.SerializeObject(patchDoc); var deserialized = JsonConvert.DeserializeObject(serialized); - + deserialized.ApplyTo(obj); var cont = obj as IDictionary; @@ -137,7 +137,7 @@ namespace Microsoft.AspNet.JsonPatch.Test.Dynamic var serialized = JsonConvert.SerializeObject(patchDoc); var deserialized = JsonConvert.DeserializeObject(serialized); - + deserialized.ApplyTo(obj); var cont = obj as IDictionary; @@ -151,9 +151,9 @@ namespace Microsoft.AspNet.JsonPatch.Test.Dynamic { dynamic doc = new ExpandoObject(); doc.SimpleDTO = new SimpleDTO() - { - StringProperty = "A" - }; + { + StringProperty = "A" + }; // create patch JsonPatchDocument patchDoc = new JsonPatchDocument(); @@ -192,10 +192,10 @@ namespace Microsoft.AspNet.JsonPatch.Test.Dynamic { dynamic doc = new ExpandoObject(); doc.SimpleDTO = new SimpleDTO() - { - IntegerList = new List() { 1, 2, 3 } - }; - + { + IntegerList = new List() { 1, 2, 3 } + }; + // create patch JsonPatchDocument patchDoc = new JsonPatchDocument(); patchDoc.Remove("SimpleDTO/IntegerList/2"); @@ -216,7 +216,7 @@ namespace Microsoft.AspNet.JsonPatch.Test.Dynamic { IntegerList = new List() { 1, 2, 3 } }; - + // create patch JsonPatchDocument patchDoc = new JsonPatchDocument(); patchDoc.Remove("SimpleDTO/Integerlist/2"); @@ -234,9 +234,9 @@ namespace Microsoft.AspNet.JsonPatch.Test.Dynamic { dynamic doc = new ExpandoObject(); doc.SimpleDTO = new SimpleDTO() - { - IntegerList = new List() { 1, 2, 3 } - }; + { + IntegerList = new List() { 1, 2, 3 } + }; // create patch JsonPatchDocument patchDoc = new JsonPatchDocument(); @@ -259,9 +259,9 @@ namespace Microsoft.AspNet.JsonPatch.Test.Dynamic { dynamic doc = new ExpandoObject(); doc.SimpleDTO = new SimpleDTO() - { - IntegerList = new List() { 1, 2, 3 } - }; + { + IntegerList = new List() { 1, 2, 3 } + }; // create patch JsonPatchDocument patchDoc = new JsonPatchDocument(); @@ -284,9 +284,9 @@ namespace Microsoft.AspNet.JsonPatch.Test.Dynamic { dynamic doc = new ExpandoObject(); doc.SimpleDTO = new SimpleDTO() - { - IntegerList = new List() { 1, 2, 3 } - }; + { + IntegerList = new List() { 1, 2, 3 } + }; // create patch JsonPatchDocument patchDoc = new JsonPatchDocument(); diff --git a/test/Microsoft.AspNet.JsonPatch.Test/Dynamic/RemoveTypedOperationTests.cs b/test/Microsoft.AspNet.JsonPatch.Test/Dynamic/RemoveTypedOperationTests.cs index db5d6502d1..802fb27e40 100644 --- a/test/Microsoft.AspNet.JsonPatch.Test/Dynamic/RemoveTypedOperationTests.cs +++ b/test/Microsoft.AspNet.JsonPatch.Test/Dynamic/RemoveTypedOperationTests.cs @@ -73,7 +73,7 @@ namespace Microsoft.AspNet.JsonPatch.Test.Dynamic "For operation 'remove' on array property at path '/IntegerList/3', the index is larger than the array size.", exception.Message); } - + [Fact] public void RemoveFromListInvalidPositionTooSmall() { @@ -135,7 +135,7 @@ namespace Microsoft.AspNet.JsonPatch.Test.Dynamic var serialized = JsonConvert.SerializeObject(patchDoc); var deserialized = JsonConvert.DeserializeObject(serialized); - + deserialized.ApplyTo(doc); Assert.Equal(null, doc.SimpleDTO.StringProperty); @@ -190,7 +190,7 @@ namespace Microsoft.AspNet.JsonPatch.Test.Dynamic "For operation 'remove' on array property at path '/SimpleDTO/IntegerList/3', the index is larger than the array size.", exception.Message); } - + [Fact] public void NestedRemoveFromListInvalidPositionTooSmall() { @@ -216,7 +216,7 @@ namespace Microsoft.AspNet.JsonPatch.Test.Dynamic Assert.Equal( "For operation 'remove' on array property at path '/SimpleDTO/IntegerList/-1', the index is negative.", exception.Message); - } + } [Fact] public void NestedRemoveFromEndOfList() diff --git a/test/Microsoft.AspNet.JsonPatch.Test/Dynamic/SimpleDTOWithNestedDTO.cs b/test/Microsoft.AspNet.JsonPatch.Test/Dynamic/SimpleDTOWithNestedDTO.cs index 2147fcceb1..03c74f8a1b 100644 --- a/test/Microsoft.AspNet.JsonPatch.Test/Dynamic/SimpleDTOWithNestedDTO.cs +++ b/test/Microsoft.AspNet.JsonPatch.Test/Dynamic/SimpleDTOWithNestedDTO.cs @@ -11,7 +11,7 @@ namespace Microsoft.AspNet.JsonPatch.Test.Dynamic public NestedDTO NestedDTO { get; set; } public SimpleDTO SimpleDTO { get; set; } public List ListOfSimpleDTO { get; set; } - + public SimpleDTOWithNestedDTO() { NestedDTO = new NestedDTO(); diff --git a/test/Microsoft.AspNet.JsonPatch.Test/NestedObjectTests.cs b/test/Microsoft.AspNet.JsonPatch.Test/NestedObjectTests.cs index 33649b7788..e736373ed8 100644 --- a/test/Microsoft.AspNet.JsonPatch.Test/NestedObjectTests.cs +++ b/test/Microsoft.AspNet.JsonPatch.Test/NestedObjectTests.cs @@ -1,11 +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. -using Microsoft.AspNet.JsonPatch.Exceptions; -using Newtonsoft.Json; -using System; using System.Collections.Generic; using System.Collections.ObjectModel; +using Microsoft.AspNet.JsonPatch.Exceptions; +using Newtonsoft.Json; using Xunit; namespace Microsoft.AspNet.JsonPatch.Test @@ -388,7 +387,7 @@ namespace Microsoft.AspNet.JsonPatch.Test var exception = Assert.Throws(() => { patchDoc.ApplyTo(doc); }); Assert.Equal( "For operation 'add' on array property at path '/simpledto/integerlist/4', the index is " + - "larger than the array size.", + "larger than the array size.", exception.Message); } @@ -442,7 +441,7 @@ namespace Microsoft.AspNet.JsonPatch.Test var logger = new TestErrorLogger(); patchDoc.ApplyTo(doc, logger.LogErrorMessage); - + //Assert Assert.Equal( @@ -524,8 +523,8 @@ namespace Microsoft.AspNet.JsonPatch.Test patchDoc.ApplyTo(doc, logger.LogErrorMessage); - - + + //Assert Assert.Equal( "For operation 'add' on array property at path '/simpledto/integerlist/-1', the index is negative.", @@ -750,9 +749,9 @@ namespace Microsoft.AspNet.JsonPatch.Test patchDoc.Remove(o => o.SimpleDTO.IntegerList, 3); var logger = new TestErrorLogger(); - + patchDoc.ApplyTo(doc, logger.LogErrorMessage); - + // Assert Assert.Equal( "For operation 'remove' on array property at path '/simpledto/integerlist/3', the index is " + @@ -828,7 +827,7 @@ namespace Microsoft.AspNet.JsonPatch.Test patchDoc.ApplyTo(doc, logger.LogErrorMessage); - + // Assert Assert.Equal("For operation 'remove' on array property at path '/simpledto/integerlist/-1', the index is negative.", logger.ErrorMessage); } @@ -1293,9 +1292,9 @@ namespace Microsoft.AspNet.JsonPatch.Test var logger = new TestErrorLogger(); - + patchDoc.ApplyTo(doc, logger.LogErrorMessage); - + // Assert Assert.Equal( @@ -1319,7 +1318,7 @@ namespace Microsoft.AspNet.JsonPatch.Test // create patch var patchDoc = new JsonPatchDocument(); patchDoc.Replace(o => o.SimpleDTO.IntegerList, 5, -1); - + // Act & Assert var exception = Assert.Throws(() => { patchDoc.ApplyTo(doc); }); Assert.Equal("For operation 'replace' on array property at path '/simpledto/integerlist/-1', the index is negative.", @@ -1371,8 +1370,8 @@ namespace Microsoft.AspNet.JsonPatch.Test var logger = new TestErrorLogger(); - patchDoc.ApplyTo(doc, logger.LogErrorMessage); - + patchDoc.ApplyTo(doc, logger.LogErrorMessage); + // Assert Assert.Equal( diff --git a/test/Microsoft.AspNet.JsonPatch.Test/ObjectAdapterTests.cs b/test/Microsoft.AspNet.JsonPatch.Test/ObjectAdapterTests.cs index 0cc97e32c4..85d9404e6d 100644 --- a/test/Microsoft.AspNet.JsonPatch.Test/ObjectAdapterTests.cs +++ b/test/Microsoft.AspNet.JsonPatch.Test/ObjectAdapterTests.cs @@ -202,7 +202,7 @@ namespace Microsoft.AspNet.JsonPatch.Test var logger = new TestErrorLogger(); patchDoc.ApplyTo(doc, logger.LogErrorMessage); - + // Assert Assert.Equal( @@ -356,7 +356,7 @@ namespace Microsoft.AspNet.JsonPatch.Test var logger = new TestErrorLogger(); patchDoc.ApplyTo(doc, logger.LogErrorMessage); - + // Assert Assert.Equal( "For operation 'add' on array property at path '/integerlist/-1', the index is negative.", @@ -553,7 +553,7 @@ namespace Microsoft.AspNet.JsonPatch.Test var logger = new TestErrorLogger(); patchDoc.ApplyTo(doc, logger.LogErrorMessage); - + // Assert Assert.Equal( @@ -618,7 +618,7 @@ namespace Microsoft.AspNet.JsonPatch.Test patchDoc.ApplyTo(doc, logger.LogErrorMessage); - + // Assert Assert.Equal("For operation 'remove' on array property at path '/integerlist/-1', the index is negative.", logger.ErrorMessage); diff --git a/test/Microsoft.AspNet.JsonPatch.Test/SimpleDTO.cs b/test/Microsoft.AspNet.JsonPatch.Test/SimpleDTO.cs index 0c29a86e83..b1177bc5ce 100644 --- a/test/Microsoft.AspNet.JsonPatch.Test/SimpleDTO.cs +++ b/test/Microsoft.AspNet.JsonPatch.Test/SimpleDTO.cs @@ -2,7 +2,6 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; -using System.Collections; using System.Collections.Generic; namespace Microsoft.AspNet.JsonPatch.Test diff --git a/test/Microsoft.AspNet.JsonPatch.Test/TestErrorLogger.cs b/test/Microsoft.AspNet.JsonPatch.Test/TestErrorLogger.cs index c254eab3e3..525321cfb3 100644 --- a/test/Microsoft.AspNet.JsonPatch.Test/TestErrorLogger.cs +++ b/test/Microsoft.AspNet.JsonPatch.Test/TestErrorLogger.cs @@ -3,7 +3,7 @@ namespace Microsoft.AspNet.JsonPatch.Test { - public class TestErrorLogger where T: class + public class TestErrorLogger where T : class { public string ErrorMessage { get; set; } diff --git a/test/Microsoft.AspNet.JsonPatch.Test/project.json b/test/Microsoft.AspNet.JsonPatch.Test/project.json index 629b7a1be3..8b97af645a 100644 --- a/test/Microsoft.AspNet.JsonPatch.Test/project.json +++ b/test/Microsoft.AspNet.JsonPatch.Test/project.json @@ -1,18 +1,26 @@ { - "compilationOptions": { - "warningsAsErrors": true + "compilationOptions": { + "warningsAsErrors": true + }, + "dependencies": { + "Microsoft.AspNet.JsonPatch": "1.0.0-*", + "Microsoft.AspNet.Testing": "1.0.0-*", + "Newtonsoft.Json": "6.0.6", + "xunit.runner.aspnet": "2.0.0-aspnet-*" + }, + "commands": { + "test": "xunit.runner.aspnet" + }, + "frameworks": { + "dnx451": { + "dependencies": { + "Moq": "4.2.1312.1622" + } }, - "dependencies": { - "Microsoft.AspNet.JsonPatch": "1.0.0-*", - "Microsoft.AspNet.Testing": "1.0.0-*", - "Moq": "4.2.1312.1622", - "Newtonsoft.Json": "6.0.6", - "xunit.runner.aspnet": "2.0.0-aspnet-*" - }, - "commands": { - "test": "xunit.runner.aspnet" - }, - "frameworks": { - "dnx451": { } + "dnxcore50": { + "dependencies": { + "moq.netcore": "4.4.0-beta8" + } } + } } \ No newline at end of file From a2e4c4e13362a54a2b1610b9b878cf60d691bc73 Mon Sep 17 00:00:00 2001 From: Pranav K Date: Tue, 1 Dec 2015 11:01:13 -0800 Subject: [PATCH 020/221] Enabling tests on CoreCLR --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 2fc624899f..c0befaffcf 100644 --- a/.travis.yml +++ b/.travis.yml @@ -11,7 +11,7 @@ addons: - libunwind8 - zlib1g env: - - KOREBUILD_DNU_RESTORE_CORECLR=true + - KOREBUILD_DNU_RESTORE_CORECLR=true KOREBUILD_TEST_DNXCORE=true mono: - 4.0.5 script: From 4cd2730a39da3f41682243e9d0404cfec90e010c Mon Sep 17 00:00:00 2001 From: Pranav K Date: Fri, 11 Dec 2015 12:22:52 -0800 Subject: [PATCH 021/221] Updating to release NuGet.config. --- NuGet.config | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/NuGet.config b/NuGet.config index 5500f6d507..71b9724a09 100644 --- a/NuGet.config +++ b/NuGet.config @@ -1,7 +1,7 @@ - + - + From 1dba1cc6613faec1fe14a06aa445def8a0611e0b Mon Sep 17 00:00:00 2001 From: Pranav K Date: Wed, 13 Jan 2016 18:25:44 -0800 Subject: [PATCH 022/221] Bumping Json.Net version to 8.0.1 --- src/Microsoft.AspNet.JsonPatch/project.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Microsoft.AspNet.JsonPatch/project.json b/src/Microsoft.AspNet.JsonPatch/project.json index 4bbe747d4b..d026fc5266 100644 --- a/src/Microsoft.AspNet.JsonPatch/project.json +++ b/src/Microsoft.AspNet.JsonPatch/project.json @@ -9,7 +9,7 @@ "url": "git://github.com/aspnet/mvc" }, "dependencies": { - "Newtonsoft.Json": "6.0.6" + "Newtonsoft.Json": "8.0.1" }, "frameworks": { "net451": {}, From 9ad62d796332572a5ddc4601b87687b08488c474 Mon Sep 17 00:00:00 2001 From: Pranav K Date: Fri, 15 Jan 2016 15:36:29 -0800 Subject: [PATCH 023/221] Updating to Newtonsoft.Json 8.0.2 --- src/Microsoft.AspNet.JsonPatch/project.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Microsoft.AspNet.JsonPatch/project.json b/src/Microsoft.AspNet.JsonPatch/project.json index d026fc5266..0b9789d9c2 100644 --- a/src/Microsoft.AspNet.JsonPatch/project.json +++ b/src/Microsoft.AspNet.JsonPatch/project.json @@ -9,7 +9,7 @@ "url": "git://github.com/aspnet/mvc" }, "dependencies": { - "Newtonsoft.Json": "8.0.1" + "Newtonsoft.Json": "8.0.2" }, "frameworks": { "net451": {}, From 40bbad426246962a4715747b641bf24996d204fa Mon Sep 17 00:00:00 2001 From: Pranav K Date: Wed, 20 Jan 2016 20:59:53 -0800 Subject: [PATCH 024/221] Reacting to CoreCLR package version change --- src/Microsoft.AspNet.JsonPatch/project.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Microsoft.AspNet.JsonPatch/project.json b/src/Microsoft.AspNet.JsonPatch/project.json index 0b9789d9c2..4d1206eefb 100644 --- a/src/Microsoft.AspNet.JsonPatch/project.json +++ b/src/Microsoft.AspNet.JsonPatch/project.json @@ -21,7 +21,7 @@ "System.Globalization": "4.0.11-*", "System.Reflection.Extensions": "4.0.1-*", "System.Resources.ResourceManager": "4.0.1-*", - "System.Runtime.Extensions": "4.0.11-*", + "System.Runtime.Extensions": "4.1.0-*", "System.Text.Encoding.Extensions": "4.0.11-*" } } From 582e222c2bf4567d28cb224b78284439a6a34651 Mon Sep 17 00:00:00 2001 From: "N. Taylor Mullen" Date: Fri, 22 Jan 2016 12:20:54 -0800 Subject: [PATCH 025/221] Rename AspNet 5 folders and files. See https://github.com/aspnet/Announcements/issues/144 for more information. --- .../Adapters/IObjectAdapter.cs | 0 .../Adapters/ObjectAdapter.cs | 0 .../Converters/JsonPatchDocumentConverter.cs | 0 .../Converters/TypedJsonPatchDocumentConverter.cs | 0 .../Exceptions/JsonPatchException.cs | 0 .../Helpers/ActualPropertyPathResult.cs | 0 .../Helpers/ConversionResult.cs | 0 .../Helpers/ExpandoObjectDictionaryExtensions.cs | 0 .../Helpers/ExpressionHelpers.cs | 0 .../Helpers/GetValueResult.cs | 0 .../Helpers/JsonPatchProperty.cs | 0 .../Helpers/ObjectTreeAnalyisResult.cs | 0 .../Helpers/PathHelpers.cs | 0 .../Helpers/RemovedPropertyTypeResult.cs | 0 .../IJsonPatchDocument.cs | 0 .../JsonPatchDocument.cs | 0 .../JsonPatchDocumentOfT.cs | 0 .../JsonPatchError.cs | 0 .../Microsoft.AspNetCore.JsonPatch.xproj} | 0 .../Operations/Operation.cs | 0 .../Operations/OperationBase.cs | 0 .../Operations/OperationOfT.cs | 0 .../Operations/OperationType.cs | 0 .../Properties/AssemblyInfo.cs | 0 .../Properties/Resources.Designer.cs | 0 .../Resources.resx | 0 .../project.json | 0 .../Dynamic/AddOperationTests.cs | 0 .../Dynamic/AddTypedOperationTests.cs | 0 .../Dynamic/CopyOperationTests.cs | 0 .../Dynamic/CopyTypedOperationTests.cs | 0 .../Dynamic/MoveOperationTests.cs | 0 .../Dynamic/MoveTypedOperationTests.cs | 0 .../Dynamic/NestedDTO.cs | 0 .../Dynamic/PatchDocumentTests.cs | 0 .../Dynamic/RemoveOperationTests.cs | 0 .../Dynamic/RemoveTypedOperationTests.cs | 0 .../Dynamic/ReplaceOperationTests.cs | 0 .../Dynamic/ReplaceTypedOperationTests.cs | 0 .../Dynamic/SimpleDTO.cs | 0 .../Dynamic/SimpleDTOWithNestedDTO.cs | 0 .../Microsoft.AspNetCore.JsonPatch.Test.xproj} | 0 .../NestedDTO.cs | 0 .../NestedObjectTests.cs | 0 .../ObjectAdapterTests.cs | 0 .../SimpleDTO.cs | 0 .../SimpleDTOWithNestedDTO.cs | 0 .../TestErrorLogger.cs | 0 .../project.json | 0 49 files changed, 0 insertions(+), 0 deletions(-) rename src/{Microsoft.AspNet.JsonPatch => Microsoft.AspNetCore.JsonPatch}/Adapters/IObjectAdapter.cs (100%) rename src/{Microsoft.AspNet.JsonPatch => Microsoft.AspNetCore.JsonPatch}/Adapters/ObjectAdapter.cs (100%) rename src/{Microsoft.AspNet.JsonPatch => Microsoft.AspNetCore.JsonPatch}/Converters/JsonPatchDocumentConverter.cs (100%) rename src/{Microsoft.AspNet.JsonPatch => Microsoft.AspNetCore.JsonPatch}/Converters/TypedJsonPatchDocumentConverter.cs (100%) rename src/{Microsoft.AspNet.JsonPatch => Microsoft.AspNetCore.JsonPatch}/Exceptions/JsonPatchException.cs (100%) rename src/{Microsoft.AspNet.JsonPatch => Microsoft.AspNetCore.JsonPatch}/Helpers/ActualPropertyPathResult.cs (100%) rename src/{Microsoft.AspNet.JsonPatch => Microsoft.AspNetCore.JsonPatch}/Helpers/ConversionResult.cs (100%) rename src/{Microsoft.AspNet.JsonPatch => Microsoft.AspNetCore.JsonPatch}/Helpers/ExpandoObjectDictionaryExtensions.cs (100%) rename src/{Microsoft.AspNet.JsonPatch => Microsoft.AspNetCore.JsonPatch}/Helpers/ExpressionHelpers.cs (100%) rename src/{Microsoft.AspNet.JsonPatch => Microsoft.AspNetCore.JsonPatch}/Helpers/GetValueResult.cs (100%) rename src/{Microsoft.AspNet.JsonPatch => Microsoft.AspNetCore.JsonPatch}/Helpers/JsonPatchProperty.cs (100%) rename src/{Microsoft.AspNet.JsonPatch => Microsoft.AspNetCore.JsonPatch}/Helpers/ObjectTreeAnalyisResult.cs (100%) rename src/{Microsoft.AspNet.JsonPatch => Microsoft.AspNetCore.JsonPatch}/Helpers/PathHelpers.cs (100%) rename src/{Microsoft.AspNet.JsonPatch => Microsoft.AspNetCore.JsonPatch}/Helpers/RemovedPropertyTypeResult.cs (100%) rename src/{Microsoft.AspNet.JsonPatch => Microsoft.AspNetCore.JsonPatch}/IJsonPatchDocument.cs (100%) rename src/{Microsoft.AspNet.JsonPatch => Microsoft.AspNetCore.JsonPatch}/JsonPatchDocument.cs (100%) rename src/{Microsoft.AspNet.JsonPatch => Microsoft.AspNetCore.JsonPatch}/JsonPatchDocumentOfT.cs (100%) rename src/{Microsoft.AspNet.JsonPatch => Microsoft.AspNetCore.JsonPatch}/JsonPatchError.cs (100%) rename src/{Microsoft.AspNet.JsonPatch/Microsoft.AspNet.JsonPatch.xproj => Microsoft.AspNetCore.JsonPatch/Microsoft.AspNetCore.JsonPatch.xproj} (100%) rename src/{Microsoft.AspNet.JsonPatch => Microsoft.AspNetCore.JsonPatch}/Operations/Operation.cs (100%) rename src/{Microsoft.AspNet.JsonPatch => Microsoft.AspNetCore.JsonPatch}/Operations/OperationBase.cs (100%) rename src/{Microsoft.AspNet.JsonPatch => Microsoft.AspNetCore.JsonPatch}/Operations/OperationOfT.cs (100%) rename src/{Microsoft.AspNet.JsonPatch => Microsoft.AspNetCore.JsonPatch}/Operations/OperationType.cs (100%) rename src/{Microsoft.AspNet.JsonPatch => Microsoft.AspNetCore.JsonPatch}/Properties/AssemblyInfo.cs (100%) rename src/{Microsoft.AspNet.JsonPatch => Microsoft.AspNetCore.JsonPatch}/Properties/Resources.Designer.cs (100%) rename src/{Microsoft.AspNet.JsonPatch => Microsoft.AspNetCore.JsonPatch}/Resources.resx (100%) rename src/{Microsoft.AspNet.JsonPatch => Microsoft.AspNetCore.JsonPatch}/project.json (100%) rename test/{Microsoft.AspNet.JsonPatch.Test => Microsoft.AspNetCore.JsonPatch.Test}/Dynamic/AddOperationTests.cs (100%) rename test/{Microsoft.AspNet.JsonPatch.Test => Microsoft.AspNetCore.JsonPatch.Test}/Dynamic/AddTypedOperationTests.cs (100%) rename test/{Microsoft.AspNet.JsonPatch.Test => Microsoft.AspNetCore.JsonPatch.Test}/Dynamic/CopyOperationTests.cs (100%) rename test/{Microsoft.AspNet.JsonPatch.Test => Microsoft.AspNetCore.JsonPatch.Test}/Dynamic/CopyTypedOperationTests.cs (100%) rename test/{Microsoft.AspNet.JsonPatch.Test => Microsoft.AspNetCore.JsonPatch.Test}/Dynamic/MoveOperationTests.cs (100%) rename test/{Microsoft.AspNet.JsonPatch.Test => Microsoft.AspNetCore.JsonPatch.Test}/Dynamic/MoveTypedOperationTests.cs (100%) rename test/{Microsoft.AspNet.JsonPatch.Test => Microsoft.AspNetCore.JsonPatch.Test}/Dynamic/NestedDTO.cs (100%) rename test/{Microsoft.AspNet.JsonPatch.Test => Microsoft.AspNetCore.JsonPatch.Test}/Dynamic/PatchDocumentTests.cs (100%) rename test/{Microsoft.AspNet.JsonPatch.Test => Microsoft.AspNetCore.JsonPatch.Test}/Dynamic/RemoveOperationTests.cs (100%) rename test/{Microsoft.AspNet.JsonPatch.Test => Microsoft.AspNetCore.JsonPatch.Test}/Dynamic/RemoveTypedOperationTests.cs (100%) rename test/{Microsoft.AspNet.JsonPatch.Test => Microsoft.AspNetCore.JsonPatch.Test}/Dynamic/ReplaceOperationTests.cs (100%) rename test/{Microsoft.AspNet.JsonPatch.Test => Microsoft.AspNetCore.JsonPatch.Test}/Dynamic/ReplaceTypedOperationTests.cs (100%) rename test/{Microsoft.AspNet.JsonPatch.Test => Microsoft.AspNetCore.JsonPatch.Test}/Dynamic/SimpleDTO.cs (100%) rename test/{Microsoft.AspNet.JsonPatch.Test => Microsoft.AspNetCore.JsonPatch.Test}/Dynamic/SimpleDTOWithNestedDTO.cs (100%) rename test/{Microsoft.AspNet.JsonPatch.Test/Microsoft.AspNet.JsonPatch.Test.xproj => Microsoft.AspNetCore.JsonPatch.Test/Microsoft.AspNetCore.JsonPatch.Test.xproj} (100%) rename test/{Microsoft.AspNet.JsonPatch.Test => Microsoft.AspNetCore.JsonPatch.Test}/NestedDTO.cs (100%) rename test/{Microsoft.AspNet.JsonPatch.Test => Microsoft.AspNetCore.JsonPatch.Test}/NestedObjectTests.cs (100%) rename test/{Microsoft.AspNet.JsonPatch.Test => Microsoft.AspNetCore.JsonPatch.Test}/ObjectAdapterTests.cs (100%) rename test/{Microsoft.AspNet.JsonPatch.Test => Microsoft.AspNetCore.JsonPatch.Test}/SimpleDTO.cs (100%) rename test/{Microsoft.AspNet.JsonPatch.Test => Microsoft.AspNetCore.JsonPatch.Test}/SimpleDTOWithNestedDTO.cs (100%) rename test/{Microsoft.AspNet.JsonPatch.Test => Microsoft.AspNetCore.JsonPatch.Test}/TestErrorLogger.cs (100%) rename test/{Microsoft.AspNet.JsonPatch.Test => Microsoft.AspNetCore.JsonPatch.Test}/project.json (100%) diff --git a/src/Microsoft.AspNet.JsonPatch/Adapters/IObjectAdapter.cs b/src/Microsoft.AspNetCore.JsonPatch/Adapters/IObjectAdapter.cs similarity index 100% rename from src/Microsoft.AspNet.JsonPatch/Adapters/IObjectAdapter.cs rename to src/Microsoft.AspNetCore.JsonPatch/Adapters/IObjectAdapter.cs diff --git a/src/Microsoft.AspNet.JsonPatch/Adapters/ObjectAdapter.cs b/src/Microsoft.AspNetCore.JsonPatch/Adapters/ObjectAdapter.cs similarity index 100% rename from src/Microsoft.AspNet.JsonPatch/Adapters/ObjectAdapter.cs rename to src/Microsoft.AspNetCore.JsonPatch/Adapters/ObjectAdapter.cs diff --git a/src/Microsoft.AspNet.JsonPatch/Converters/JsonPatchDocumentConverter.cs b/src/Microsoft.AspNetCore.JsonPatch/Converters/JsonPatchDocumentConverter.cs similarity index 100% rename from src/Microsoft.AspNet.JsonPatch/Converters/JsonPatchDocumentConverter.cs rename to src/Microsoft.AspNetCore.JsonPatch/Converters/JsonPatchDocumentConverter.cs diff --git a/src/Microsoft.AspNet.JsonPatch/Converters/TypedJsonPatchDocumentConverter.cs b/src/Microsoft.AspNetCore.JsonPatch/Converters/TypedJsonPatchDocumentConverter.cs similarity index 100% rename from src/Microsoft.AspNet.JsonPatch/Converters/TypedJsonPatchDocumentConverter.cs rename to src/Microsoft.AspNetCore.JsonPatch/Converters/TypedJsonPatchDocumentConverter.cs diff --git a/src/Microsoft.AspNet.JsonPatch/Exceptions/JsonPatchException.cs b/src/Microsoft.AspNetCore.JsonPatch/Exceptions/JsonPatchException.cs similarity index 100% rename from src/Microsoft.AspNet.JsonPatch/Exceptions/JsonPatchException.cs rename to src/Microsoft.AspNetCore.JsonPatch/Exceptions/JsonPatchException.cs diff --git a/src/Microsoft.AspNet.JsonPatch/Helpers/ActualPropertyPathResult.cs b/src/Microsoft.AspNetCore.JsonPatch/Helpers/ActualPropertyPathResult.cs similarity index 100% rename from src/Microsoft.AspNet.JsonPatch/Helpers/ActualPropertyPathResult.cs rename to src/Microsoft.AspNetCore.JsonPatch/Helpers/ActualPropertyPathResult.cs diff --git a/src/Microsoft.AspNet.JsonPatch/Helpers/ConversionResult.cs b/src/Microsoft.AspNetCore.JsonPatch/Helpers/ConversionResult.cs similarity index 100% rename from src/Microsoft.AspNet.JsonPatch/Helpers/ConversionResult.cs rename to src/Microsoft.AspNetCore.JsonPatch/Helpers/ConversionResult.cs diff --git a/src/Microsoft.AspNet.JsonPatch/Helpers/ExpandoObjectDictionaryExtensions.cs b/src/Microsoft.AspNetCore.JsonPatch/Helpers/ExpandoObjectDictionaryExtensions.cs similarity index 100% rename from src/Microsoft.AspNet.JsonPatch/Helpers/ExpandoObjectDictionaryExtensions.cs rename to src/Microsoft.AspNetCore.JsonPatch/Helpers/ExpandoObjectDictionaryExtensions.cs diff --git a/src/Microsoft.AspNet.JsonPatch/Helpers/ExpressionHelpers.cs b/src/Microsoft.AspNetCore.JsonPatch/Helpers/ExpressionHelpers.cs similarity index 100% rename from src/Microsoft.AspNet.JsonPatch/Helpers/ExpressionHelpers.cs rename to src/Microsoft.AspNetCore.JsonPatch/Helpers/ExpressionHelpers.cs diff --git a/src/Microsoft.AspNet.JsonPatch/Helpers/GetValueResult.cs b/src/Microsoft.AspNetCore.JsonPatch/Helpers/GetValueResult.cs similarity index 100% rename from src/Microsoft.AspNet.JsonPatch/Helpers/GetValueResult.cs rename to src/Microsoft.AspNetCore.JsonPatch/Helpers/GetValueResult.cs diff --git a/src/Microsoft.AspNet.JsonPatch/Helpers/JsonPatchProperty.cs b/src/Microsoft.AspNetCore.JsonPatch/Helpers/JsonPatchProperty.cs similarity index 100% rename from src/Microsoft.AspNet.JsonPatch/Helpers/JsonPatchProperty.cs rename to src/Microsoft.AspNetCore.JsonPatch/Helpers/JsonPatchProperty.cs diff --git a/src/Microsoft.AspNet.JsonPatch/Helpers/ObjectTreeAnalyisResult.cs b/src/Microsoft.AspNetCore.JsonPatch/Helpers/ObjectTreeAnalyisResult.cs similarity index 100% rename from src/Microsoft.AspNet.JsonPatch/Helpers/ObjectTreeAnalyisResult.cs rename to src/Microsoft.AspNetCore.JsonPatch/Helpers/ObjectTreeAnalyisResult.cs diff --git a/src/Microsoft.AspNet.JsonPatch/Helpers/PathHelpers.cs b/src/Microsoft.AspNetCore.JsonPatch/Helpers/PathHelpers.cs similarity index 100% rename from src/Microsoft.AspNet.JsonPatch/Helpers/PathHelpers.cs rename to src/Microsoft.AspNetCore.JsonPatch/Helpers/PathHelpers.cs diff --git a/src/Microsoft.AspNet.JsonPatch/Helpers/RemovedPropertyTypeResult.cs b/src/Microsoft.AspNetCore.JsonPatch/Helpers/RemovedPropertyTypeResult.cs similarity index 100% rename from src/Microsoft.AspNet.JsonPatch/Helpers/RemovedPropertyTypeResult.cs rename to src/Microsoft.AspNetCore.JsonPatch/Helpers/RemovedPropertyTypeResult.cs diff --git a/src/Microsoft.AspNet.JsonPatch/IJsonPatchDocument.cs b/src/Microsoft.AspNetCore.JsonPatch/IJsonPatchDocument.cs similarity index 100% rename from src/Microsoft.AspNet.JsonPatch/IJsonPatchDocument.cs rename to src/Microsoft.AspNetCore.JsonPatch/IJsonPatchDocument.cs diff --git a/src/Microsoft.AspNet.JsonPatch/JsonPatchDocument.cs b/src/Microsoft.AspNetCore.JsonPatch/JsonPatchDocument.cs similarity index 100% rename from src/Microsoft.AspNet.JsonPatch/JsonPatchDocument.cs rename to src/Microsoft.AspNetCore.JsonPatch/JsonPatchDocument.cs diff --git a/src/Microsoft.AspNet.JsonPatch/JsonPatchDocumentOfT.cs b/src/Microsoft.AspNetCore.JsonPatch/JsonPatchDocumentOfT.cs similarity index 100% rename from src/Microsoft.AspNet.JsonPatch/JsonPatchDocumentOfT.cs rename to src/Microsoft.AspNetCore.JsonPatch/JsonPatchDocumentOfT.cs diff --git a/src/Microsoft.AspNet.JsonPatch/JsonPatchError.cs b/src/Microsoft.AspNetCore.JsonPatch/JsonPatchError.cs similarity index 100% rename from src/Microsoft.AspNet.JsonPatch/JsonPatchError.cs rename to src/Microsoft.AspNetCore.JsonPatch/JsonPatchError.cs diff --git a/src/Microsoft.AspNet.JsonPatch/Microsoft.AspNet.JsonPatch.xproj b/src/Microsoft.AspNetCore.JsonPatch/Microsoft.AspNetCore.JsonPatch.xproj similarity index 100% rename from src/Microsoft.AspNet.JsonPatch/Microsoft.AspNet.JsonPatch.xproj rename to src/Microsoft.AspNetCore.JsonPatch/Microsoft.AspNetCore.JsonPatch.xproj diff --git a/src/Microsoft.AspNet.JsonPatch/Operations/Operation.cs b/src/Microsoft.AspNetCore.JsonPatch/Operations/Operation.cs similarity index 100% rename from src/Microsoft.AspNet.JsonPatch/Operations/Operation.cs rename to src/Microsoft.AspNetCore.JsonPatch/Operations/Operation.cs diff --git a/src/Microsoft.AspNet.JsonPatch/Operations/OperationBase.cs b/src/Microsoft.AspNetCore.JsonPatch/Operations/OperationBase.cs similarity index 100% rename from src/Microsoft.AspNet.JsonPatch/Operations/OperationBase.cs rename to src/Microsoft.AspNetCore.JsonPatch/Operations/OperationBase.cs diff --git a/src/Microsoft.AspNet.JsonPatch/Operations/OperationOfT.cs b/src/Microsoft.AspNetCore.JsonPatch/Operations/OperationOfT.cs similarity index 100% rename from src/Microsoft.AspNet.JsonPatch/Operations/OperationOfT.cs rename to src/Microsoft.AspNetCore.JsonPatch/Operations/OperationOfT.cs diff --git a/src/Microsoft.AspNet.JsonPatch/Operations/OperationType.cs b/src/Microsoft.AspNetCore.JsonPatch/Operations/OperationType.cs similarity index 100% rename from src/Microsoft.AspNet.JsonPatch/Operations/OperationType.cs rename to src/Microsoft.AspNetCore.JsonPatch/Operations/OperationType.cs diff --git a/src/Microsoft.AspNet.JsonPatch/Properties/AssemblyInfo.cs b/src/Microsoft.AspNetCore.JsonPatch/Properties/AssemblyInfo.cs similarity index 100% rename from src/Microsoft.AspNet.JsonPatch/Properties/AssemblyInfo.cs rename to src/Microsoft.AspNetCore.JsonPatch/Properties/AssemblyInfo.cs diff --git a/src/Microsoft.AspNet.JsonPatch/Properties/Resources.Designer.cs b/src/Microsoft.AspNetCore.JsonPatch/Properties/Resources.Designer.cs similarity index 100% rename from src/Microsoft.AspNet.JsonPatch/Properties/Resources.Designer.cs rename to src/Microsoft.AspNetCore.JsonPatch/Properties/Resources.Designer.cs diff --git a/src/Microsoft.AspNet.JsonPatch/Resources.resx b/src/Microsoft.AspNetCore.JsonPatch/Resources.resx similarity index 100% rename from src/Microsoft.AspNet.JsonPatch/Resources.resx rename to src/Microsoft.AspNetCore.JsonPatch/Resources.resx diff --git a/src/Microsoft.AspNet.JsonPatch/project.json b/src/Microsoft.AspNetCore.JsonPatch/project.json similarity index 100% rename from src/Microsoft.AspNet.JsonPatch/project.json rename to src/Microsoft.AspNetCore.JsonPatch/project.json diff --git a/test/Microsoft.AspNet.JsonPatch.Test/Dynamic/AddOperationTests.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/AddOperationTests.cs similarity index 100% rename from test/Microsoft.AspNet.JsonPatch.Test/Dynamic/AddOperationTests.cs rename to test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/AddOperationTests.cs diff --git a/test/Microsoft.AspNet.JsonPatch.Test/Dynamic/AddTypedOperationTests.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/AddTypedOperationTests.cs similarity index 100% rename from test/Microsoft.AspNet.JsonPatch.Test/Dynamic/AddTypedOperationTests.cs rename to test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/AddTypedOperationTests.cs diff --git a/test/Microsoft.AspNet.JsonPatch.Test/Dynamic/CopyOperationTests.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/CopyOperationTests.cs similarity index 100% rename from test/Microsoft.AspNet.JsonPatch.Test/Dynamic/CopyOperationTests.cs rename to test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/CopyOperationTests.cs diff --git a/test/Microsoft.AspNet.JsonPatch.Test/Dynamic/CopyTypedOperationTests.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/CopyTypedOperationTests.cs similarity index 100% rename from test/Microsoft.AspNet.JsonPatch.Test/Dynamic/CopyTypedOperationTests.cs rename to test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/CopyTypedOperationTests.cs diff --git a/test/Microsoft.AspNet.JsonPatch.Test/Dynamic/MoveOperationTests.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/MoveOperationTests.cs similarity index 100% rename from test/Microsoft.AspNet.JsonPatch.Test/Dynamic/MoveOperationTests.cs rename to test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/MoveOperationTests.cs diff --git a/test/Microsoft.AspNet.JsonPatch.Test/Dynamic/MoveTypedOperationTests.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/MoveTypedOperationTests.cs similarity index 100% rename from test/Microsoft.AspNet.JsonPatch.Test/Dynamic/MoveTypedOperationTests.cs rename to test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/MoveTypedOperationTests.cs diff --git a/test/Microsoft.AspNet.JsonPatch.Test/Dynamic/NestedDTO.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/NestedDTO.cs similarity index 100% rename from test/Microsoft.AspNet.JsonPatch.Test/Dynamic/NestedDTO.cs rename to test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/NestedDTO.cs diff --git a/test/Microsoft.AspNet.JsonPatch.Test/Dynamic/PatchDocumentTests.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/PatchDocumentTests.cs similarity index 100% rename from test/Microsoft.AspNet.JsonPatch.Test/Dynamic/PatchDocumentTests.cs rename to test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/PatchDocumentTests.cs diff --git a/test/Microsoft.AspNet.JsonPatch.Test/Dynamic/RemoveOperationTests.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/RemoveOperationTests.cs similarity index 100% rename from test/Microsoft.AspNet.JsonPatch.Test/Dynamic/RemoveOperationTests.cs rename to test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/RemoveOperationTests.cs diff --git a/test/Microsoft.AspNet.JsonPatch.Test/Dynamic/RemoveTypedOperationTests.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/RemoveTypedOperationTests.cs similarity index 100% rename from test/Microsoft.AspNet.JsonPatch.Test/Dynamic/RemoveTypedOperationTests.cs rename to test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/RemoveTypedOperationTests.cs diff --git a/test/Microsoft.AspNet.JsonPatch.Test/Dynamic/ReplaceOperationTests.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/ReplaceOperationTests.cs similarity index 100% rename from test/Microsoft.AspNet.JsonPatch.Test/Dynamic/ReplaceOperationTests.cs rename to test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/ReplaceOperationTests.cs diff --git a/test/Microsoft.AspNet.JsonPatch.Test/Dynamic/ReplaceTypedOperationTests.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/ReplaceTypedOperationTests.cs similarity index 100% rename from test/Microsoft.AspNet.JsonPatch.Test/Dynamic/ReplaceTypedOperationTests.cs rename to test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/ReplaceTypedOperationTests.cs diff --git a/test/Microsoft.AspNet.JsonPatch.Test/Dynamic/SimpleDTO.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/SimpleDTO.cs similarity index 100% rename from test/Microsoft.AspNet.JsonPatch.Test/Dynamic/SimpleDTO.cs rename to test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/SimpleDTO.cs diff --git a/test/Microsoft.AspNet.JsonPatch.Test/Dynamic/SimpleDTOWithNestedDTO.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/SimpleDTOWithNestedDTO.cs similarity index 100% rename from test/Microsoft.AspNet.JsonPatch.Test/Dynamic/SimpleDTOWithNestedDTO.cs rename to test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/SimpleDTOWithNestedDTO.cs diff --git a/test/Microsoft.AspNet.JsonPatch.Test/Microsoft.AspNet.JsonPatch.Test.xproj b/test/Microsoft.AspNetCore.JsonPatch.Test/Microsoft.AspNetCore.JsonPatch.Test.xproj similarity index 100% rename from test/Microsoft.AspNet.JsonPatch.Test/Microsoft.AspNet.JsonPatch.Test.xproj rename to test/Microsoft.AspNetCore.JsonPatch.Test/Microsoft.AspNetCore.JsonPatch.Test.xproj diff --git a/test/Microsoft.AspNet.JsonPatch.Test/NestedDTO.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/NestedDTO.cs similarity index 100% rename from test/Microsoft.AspNet.JsonPatch.Test/NestedDTO.cs rename to test/Microsoft.AspNetCore.JsonPatch.Test/NestedDTO.cs diff --git a/test/Microsoft.AspNet.JsonPatch.Test/NestedObjectTests.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/NestedObjectTests.cs similarity index 100% rename from test/Microsoft.AspNet.JsonPatch.Test/NestedObjectTests.cs rename to test/Microsoft.AspNetCore.JsonPatch.Test/NestedObjectTests.cs diff --git a/test/Microsoft.AspNet.JsonPatch.Test/ObjectAdapterTests.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/ObjectAdapterTests.cs similarity index 100% rename from test/Microsoft.AspNet.JsonPatch.Test/ObjectAdapterTests.cs rename to test/Microsoft.AspNetCore.JsonPatch.Test/ObjectAdapterTests.cs diff --git a/test/Microsoft.AspNet.JsonPatch.Test/SimpleDTO.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/SimpleDTO.cs similarity index 100% rename from test/Microsoft.AspNet.JsonPatch.Test/SimpleDTO.cs rename to test/Microsoft.AspNetCore.JsonPatch.Test/SimpleDTO.cs diff --git a/test/Microsoft.AspNet.JsonPatch.Test/SimpleDTOWithNestedDTO.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/SimpleDTOWithNestedDTO.cs similarity index 100% rename from test/Microsoft.AspNet.JsonPatch.Test/SimpleDTOWithNestedDTO.cs rename to test/Microsoft.AspNetCore.JsonPatch.Test/SimpleDTOWithNestedDTO.cs diff --git a/test/Microsoft.AspNet.JsonPatch.Test/TestErrorLogger.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/TestErrorLogger.cs similarity index 100% rename from test/Microsoft.AspNet.JsonPatch.Test/TestErrorLogger.cs rename to test/Microsoft.AspNetCore.JsonPatch.Test/TestErrorLogger.cs diff --git a/test/Microsoft.AspNet.JsonPatch.Test/project.json b/test/Microsoft.AspNetCore.JsonPatch.Test/project.json similarity index 100% rename from test/Microsoft.AspNet.JsonPatch.Test/project.json rename to test/Microsoft.AspNetCore.JsonPatch.Test/project.json From e2801d6c2065acfcb4b997901f13b474a3acbe57 Mon Sep 17 00:00:00 2001 From: "N. Taylor Mullen" Date: Fri, 22 Jan 2016 12:20:58 -0800 Subject: [PATCH 026/221] Rename AspNet 5 file contents. See https://github.com/aspnet/Announcements/issues/144 for more information. --- JsonPatch.sln | 6 +++--- NuGetPackageVerifier.json | 2 +- .../Adapters/IObjectAdapter.cs | 4 ++-- .../Adapters/ObjectAdapter.cs | 8 ++++---- .../Converters/JsonPatchDocumentConverter.cs | 8 ++++---- .../Converters/TypedJsonPatchDocumentConverter.cs | 6 +++--- .../Exceptions/JsonPatchException.cs | 4 ++-- .../Helpers/ActualPropertyPathResult.cs | 4 ++-- .../Helpers/ConversionResult.cs | 2 +- .../Helpers/ExpandoObjectDictionaryExtensions.cs | 4 ++-- .../Helpers/ExpressionHelpers.cs | 2 +- .../Helpers/GetValueResult.cs | 4 ++-- .../Helpers/JsonPatchProperty.cs | 2 +- .../Helpers/ObjectTreeAnalyisResult.cs | 4 ++-- .../Helpers/PathHelpers.cs | 6 +++--- .../Helpers/RemovedPropertyTypeResult.cs | 4 ++-- .../IJsonPatchDocument.cs | 4 ++-- .../JsonPatchDocument.cs | 10 +++++----- .../JsonPatchDocumentOfT.cs | 10 +++++----- src/Microsoft.AspNetCore.JsonPatch/JsonPatchError.cs | 4 ++-- .../Operations/Operation.cs | 4 ++-- .../Operations/OperationBase.cs | 2 +- .../Operations/OperationOfT.cs | 4 ++-- .../Operations/OperationType.cs | 2 +- .../Properties/Resources.Designer.cs | 4 ++-- .../Dynamic/AddOperationTests.cs | 6 +++--- .../Dynamic/AddTypedOperationTests.cs | 6 +++--- .../Dynamic/CopyOperationTests.cs | 4 ++-- .../Dynamic/CopyTypedOperationTests.cs | 4 ++-- .../Dynamic/MoveOperationTests.cs | 4 ++-- .../Dynamic/MoveTypedOperationTests.cs | 4 ++-- .../Dynamic/NestedDTO.cs | 4 ++-- .../Dynamic/PatchDocumentTests.cs | 6 +++--- .../Dynamic/RemoveOperationTests.cs | 6 +++--- .../Dynamic/RemoveTypedOperationTests.cs | 6 +++--- .../Dynamic/ReplaceOperationTests.cs | 4 ++-- .../Dynamic/ReplaceTypedOperationTests.cs | 4 ++-- .../Dynamic/SimpleDTO.cs | 4 ++-- .../Dynamic/SimpleDTOWithNestedDTO.cs | 4 ++-- test/Microsoft.AspNetCore.JsonPatch.Test/NestedDTO.cs | 2 +- .../NestedObjectTests.cs | 4 ++-- .../ObjectAdapterTests.cs | 4 ++-- test/Microsoft.AspNetCore.JsonPatch.Test/SimpleDTO.cs | 2 +- .../SimpleDTOWithNestedDTO.cs | 2 +- .../TestErrorLogger.cs | 2 +- test/Microsoft.AspNetCore.JsonPatch.Test/project.json | 4 ++-- 46 files changed, 100 insertions(+), 100 deletions(-) diff --git a/JsonPatch.sln b/JsonPatch.sln index 01e02f3125..7149fc4551 100644 --- a/JsonPatch.sln +++ b/JsonPatch.sln @@ -1,4 +1,4 @@ - + Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 14 VisualStudioVersion = 14.0.23107.0 @@ -7,9 +7,9 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{430B59ED-F96 EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{36CD6341-AB44-44EB-B3AA-BF98C89FECDD}" EndProject -Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNet.JsonPatch", "src\Microsoft.AspNet.JsonPatch\Microsoft.AspNet.JsonPatch.xproj", "{4D55F4D8-633B-462F-A5B1-FEB84BD2D534}" +Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNetCore.JsonPatch", "src\Microsoft.AspNetCore.JsonPatch\Microsoft.AspNetCore.JsonPatch.xproj", "{4D55F4D8-633B-462F-A5B1-FEB84BD2D534}" EndProject -Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNet.JsonPatch.Test", "test\Microsoft.AspNet.JsonPatch.Test\Microsoft.AspNet.JsonPatch.Test.xproj", "{81C20848-E063-4E12-AC40-0B55A532C16C}" +Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNetCore.JsonPatch.Test", "test\Microsoft.AspNetCore.JsonPatch.Test\Microsoft.AspNetCore.JsonPatch.Test.xproj", "{81C20848-E063-4E12-AC40-0B55A532C16C}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution diff --git a/NuGetPackageVerifier.json b/NuGetPackageVerifier.json index a45e74c44d..e95640a3d3 100644 --- a/NuGetPackageVerifier.json +++ b/NuGetPackageVerifier.json @@ -9,7 +9,7 @@ "StrictSemanticVersionValidationRule" ], "packages": { - "Microsoft.AspNet.JsonPatch": { } + "Microsoft.AspNetCore.JsonPatch": { } } }, "Default": { // Rules to run for packages not listed in any other set. diff --git a/src/Microsoft.AspNetCore.JsonPatch/Adapters/IObjectAdapter.cs b/src/Microsoft.AspNetCore.JsonPatch/Adapters/IObjectAdapter.cs index 724dfe3f79..f699755ed4 100644 --- a/src/Microsoft.AspNetCore.JsonPatch/Adapters/IObjectAdapter.cs +++ b/src/Microsoft.AspNetCore.JsonPatch/Adapters/IObjectAdapter.cs @@ -1,9 +1,9 @@ // 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 Microsoft.AspNet.JsonPatch.Operations; +using Microsoft.AspNetCore.JsonPatch.Operations; -namespace Microsoft.AspNet.JsonPatch.Adapters +namespace Microsoft.AspNetCore.JsonPatch.Adapters { /// /// Defines the operations that can be performed on a JSON patch document. diff --git a/src/Microsoft.AspNetCore.JsonPatch/Adapters/ObjectAdapter.cs b/src/Microsoft.AspNetCore.JsonPatch/Adapters/ObjectAdapter.cs index 4640e97039..aeae454fa9 100644 --- a/src/Microsoft.AspNetCore.JsonPatch/Adapters/ObjectAdapter.cs +++ b/src/Microsoft.AspNetCore.JsonPatch/Adapters/ObjectAdapter.cs @@ -5,13 +5,13 @@ using System; using System.Collections; using System.Collections.Generic; using System.Reflection; -using Microsoft.AspNet.JsonPatch.Exceptions; -using Microsoft.AspNet.JsonPatch.Helpers; -using Microsoft.AspNet.JsonPatch.Operations; +using Microsoft.AspNetCore.JsonPatch.Exceptions; +using Microsoft.AspNetCore.JsonPatch.Helpers; +using Microsoft.AspNetCore.JsonPatch.Operations; using Newtonsoft.Json; using Newtonsoft.Json.Serialization; -namespace Microsoft.AspNet.JsonPatch.Adapters +namespace Microsoft.AspNetCore.JsonPatch.Adapters { /// public class ObjectAdapter : IObjectAdapter diff --git a/src/Microsoft.AspNetCore.JsonPatch/Converters/JsonPatchDocumentConverter.cs b/src/Microsoft.AspNetCore.JsonPatch/Converters/JsonPatchDocumentConverter.cs index 4551f64043..e93e84e12a 100644 --- a/src/Microsoft.AspNetCore.JsonPatch/Converters/JsonPatchDocumentConverter.cs +++ b/src/Microsoft.AspNetCore.JsonPatch/Converters/JsonPatchDocumentConverter.cs @@ -1,15 +1,15 @@ -// 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. using System; using System.Collections.Generic; -using Microsoft.AspNet.JsonPatch.Exceptions; -using Microsoft.AspNet.JsonPatch.Operations; +using Microsoft.AspNetCore.JsonPatch.Exceptions; +using Microsoft.AspNetCore.JsonPatch.Operations; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using Newtonsoft.Json.Serialization; -namespace Microsoft.AspNet.JsonPatch.Converters +namespace Microsoft.AspNetCore.JsonPatch.Converters { public class JsonPatchDocumentConverter : JsonConverter { diff --git a/src/Microsoft.AspNetCore.JsonPatch/Converters/TypedJsonPatchDocumentConverter.cs b/src/Microsoft.AspNetCore.JsonPatch/Converters/TypedJsonPatchDocumentConverter.cs index 7b6bb77e17..a150bd0478 100644 --- a/src/Microsoft.AspNetCore.JsonPatch/Converters/TypedJsonPatchDocumentConverter.cs +++ b/src/Microsoft.AspNetCore.JsonPatch/Converters/TypedJsonPatchDocumentConverter.cs @@ -4,13 +4,13 @@ using System; using System.Collections.Generic; using System.Reflection; -using Microsoft.AspNet.JsonPatch.Exceptions; -using Microsoft.AspNet.JsonPatch.Operations; +using Microsoft.AspNetCore.JsonPatch.Exceptions; +using Microsoft.AspNetCore.JsonPatch.Operations; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using Newtonsoft.Json.Serialization; -namespace Microsoft.AspNet.JsonPatch.Converters +namespace Microsoft.AspNetCore.JsonPatch.Converters { public class TypedJsonPatchDocumentConverter : JsonPatchDocumentConverter { diff --git a/src/Microsoft.AspNetCore.JsonPatch/Exceptions/JsonPatchException.cs b/src/Microsoft.AspNetCore.JsonPatch/Exceptions/JsonPatchException.cs index ac5222a2bb..90e080575a 100644 --- a/src/Microsoft.AspNetCore.JsonPatch/Exceptions/JsonPatchException.cs +++ b/src/Microsoft.AspNetCore.JsonPatch/Exceptions/JsonPatchException.cs @@ -2,9 +2,9 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; -using Microsoft.AspNet.JsonPatch.Operations; +using Microsoft.AspNetCore.JsonPatch.Operations; -namespace Microsoft.AspNet.JsonPatch.Exceptions +namespace Microsoft.AspNetCore.JsonPatch.Exceptions { public class JsonPatchException : Exception { diff --git a/src/Microsoft.AspNetCore.JsonPatch/Helpers/ActualPropertyPathResult.cs b/src/Microsoft.AspNetCore.JsonPatch/Helpers/ActualPropertyPathResult.cs index d22d1bf830..1967bf6d90 100644 --- a/src/Microsoft.AspNetCore.JsonPatch/Helpers/ActualPropertyPathResult.cs +++ b/src/Microsoft.AspNetCore.JsonPatch/Helpers/ActualPropertyPathResult.cs @@ -1,7 +1,7 @@ -// 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. -namespace Microsoft.AspNet.JsonPatch.Helpers +namespace Microsoft.AspNetCore.JsonPatch.Helpers { internal class ActualPropertyPathResult { diff --git a/src/Microsoft.AspNetCore.JsonPatch/Helpers/ConversionResult.cs b/src/Microsoft.AspNetCore.JsonPatch/Helpers/ConversionResult.cs index aba4913f2d..00a7513d44 100644 --- a/src/Microsoft.AspNetCore.JsonPatch/Helpers/ConversionResult.cs +++ b/src/Microsoft.AspNetCore.JsonPatch/Helpers/ConversionResult.cs @@ -1,7 +1,7 @@ // Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -namespace Microsoft.AspNet.JsonPatch.Helpers +namespace Microsoft.AspNetCore.JsonPatch.Helpers { internal class ConversionResult { diff --git a/src/Microsoft.AspNetCore.JsonPatch/Helpers/ExpandoObjectDictionaryExtensions.cs b/src/Microsoft.AspNetCore.JsonPatch/Helpers/ExpandoObjectDictionaryExtensions.cs index a5911dded2..aa9fa2158b 100644 --- a/src/Microsoft.AspNetCore.JsonPatch/Helpers/ExpandoObjectDictionaryExtensions.cs +++ b/src/Microsoft.AspNetCore.JsonPatch/Helpers/ExpandoObjectDictionaryExtensions.cs @@ -1,10 +1,10 @@ -// 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. using System; using System.Collections.Generic; -namespace Microsoft.AspNet.JsonPatch.Helpers +namespace Microsoft.AspNetCore.JsonPatch.Helpers { // Helper methods to allow case-insensitive key search internal static class ExpandoObjectDictionaryExtensions diff --git a/src/Microsoft.AspNetCore.JsonPatch/Helpers/ExpressionHelpers.cs b/src/Microsoft.AspNetCore.JsonPatch/Helpers/ExpressionHelpers.cs index 6a0279876c..92880eb0e1 100644 --- a/src/Microsoft.AspNetCore.JsonPatch/Helpers/ExpressionHelpers.cs +++ b/src/Microsoft.AspNetCore.JsonPatch/Helpers/ExpressionHelpers.cs @@ -5,7 +5,7 @@ using System; using System.Globalization; using System.Linq.Expressions; -namespace Microsoft.AspNet.JsonPatch.Helpers +namespace Microsoft.AspNetCore.JsonPatch.Helpers { internal static class ExpressionHelpers { diff --git a/src/Microsoft.AspNetCore.JsonPatch/Helpers/GetValueResult.cs b/src/Microsoft.AspNetCore.JsonPatch/Helpers/GetValueResult.cs index 89b7c93520..e2e739a027 100644 --- a/src/Microsoft.AspNetCore.JsonPatch/Helpers/GetValueResult.cs +++ b/src/Microsoft.AspNetCore.JsonPatch/Helpers/GetValueResult.cs @@ -1,7 +1,7 @@ -// 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. -namespace Microsoft.AspNet.JsonPatch.Helpers +namespace Microsoft.AspNetCore.JsonPatch.Helpers { /// /// Return value for the helper method used by Copy/Move. Needed to ensure we can make a different diff --git a/src/Microsoft.AspNetCore.JsonPatch/Helpers/JsonPatchProperty.cs b/src/Microsoft.AspNetCore.JsonPatch/Helpers/JsonPatchProperty.cs index 0539d230a3..041b0104ac 100644 --- a/src/Microsoft.AspNetCore.JsonPatch/Helpers/JsonPatchProperty.cs +++ b/src/Microsoft.AspNetCore.JsonPatch/Helpers/JsonPatchProperty.cs @@ -4,7 +4,7 @@ using System; using Newtonsoft.Json.Serialization; -namespace Microsoft.AspNet.JsonPatch +namespace Microsoft.AspNetCore.JsonPatch { /// /// Metadata for JsonProperty. diff --git a/src/Microsoft.AspNetCore.JsonPatch/Helpers/ObjectTreeAnalyisResult.cs b/src/Microsoft.AspNetCore.JsonPatch/Helpers/ObjectTreeAnalyisResult.cs index 91d5ee129d..4d083bd073 100644 --- a/src/Microsoft.AspNetCore.JsonPatch/Helpers/ObjectTreeAnalyisResult.cs +++ b/src/Microsoft.AspNetCore.JsonPatch/Helpers/ObjectTreeAnalyisResult.cs @@ -1,4 +1,4 @@ -// 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. using System; @@ -7,7 +7,7 @@ using System.Collections.Generic; using System.Linq; using Newtonsoft.Json.Serialization; -namespace Microsoft.AspNet.JsonPatch.Helpers +namespace Microsoft.AspNetCore.JsonPatch.Helpers { internal class ObjectTreeAnalysisResult { diff --git a/src/Microsoft.AspNetCore.JsonPatch/Helpers/PathHelpers.cs b/src/Microsoft.AspNetCore.JsonPatch/Helpers/PathHelpers.cs index 28683e7c98..99bb2f1536 100644 --- a/src/Microsoft.AspNetCore.JsonPatch/Helpers/PathHelpers.cs +++ b/src/Microsoft.AspNetCore.JsonPatch/Helpers/PathHelpers.cs @@ -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. -using Microsoft.AspNet.JsonPatch.Exceptions; +using Microsoft.AspNetCore.JsonPatch.Exceptions; -namespace Microsoft.AspNet.JsonPatch.Helpers +namespace Microsoft.AspNetCore.JsonPatch.Helpers { internal static class PathHelpers { diff --git a/src/Microsoft.AspNetCore.JsonPatch/Helpers/RemovedPropertyTypeResult.cs b/src/Microsoft.AspNetCore.JsonPatch/Helpers/RemovedPropertyTypeResult.cs index 9f5b97a868..c548f55c6e 100644 --- a/src/Microsoft.AspNetCore.JsonPatch/Helpers/RemovedPropertyTypeResult.cs +++ b/src/Microsoft.AspNetCore.JsonPatch/Helpers/RemovedPropertyTypeResult.cs @@ -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. using System; -namespace Microsoft.AspNet.JsonPatch.Helpers +namespace Microsoft.AspNetCore.JsonPatch.Helpers { /// /// Return value for Remove operation. The combination tells us what to do next (if this operation diff --git a/src/Microsoft.AspNetCore.JsonPatch/IJsonPatchDocument.cs b/src/Microsoft.AspNetCore.JsonPatch/IJsonPatchDocument.cs index 18033e82f0..fc5f5bd4d1 100644 --- a/src/Microsoft.AspNetCore.JsonPatch/IJsonPatchDocument.cs +++ b/src/Microsoft.AspNetCore.JsonPatch/IJsonPatchDocument.cs @@ -1,11 +1,11 @@ // 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 Microsoft.AspNet.JsonPatch.Operations; +using Microsoft.AspNetCore.JsonPatch.Operations; using System.Collections.Generic; using Newtonsoft.Json.Serialization; -namespace Microsoft.AspNet.JsonPatch +namespace Microsoft.AspNetCore.JsonPatch { public interface IJsonPatchDocument { diff --git a/src/Microsoft.AspNetCore.JsonPatch/JsonPatchDocument.cs b/src/Microsoft.AspNetCore.JsonPatch/JsonPatchDocument.cs index fc2e73030a..c9c34459a9 100644 --- a/src/Microsoft.AspNetCore.JsonPatch/JsonPatchDocument.cs +++ b/src/Microsoft.AspNetCore.JsonPatch/JsonPatchDocument.cs @@ -3,14 +3,14 @@ using System; using System.Collections.Generic; -using Microsoft.AspNet.JsonPatch.Adapters; -using Microsoft.AspNet.JsonPatch.Converters; -using Microsoft.AspNet.JsonPatch.Helpers; -using Microsoft.AspNet.JsonPatch.Operations; +using Microsoft.AspNetCore.JsonPatch.Adapters; +using Microsoft.AspNetCore.JsonPatch.Converters; +using Microsoft.AspNetCore.JsonPatch.Helpers; +using Microsoft.AspNetCore.JsonPatch.Operations; using Newtonsoft.Json; using Newtonsoft.Json.Serialization; -namespace Microsoft.AspNet.JsonPatch +namespace Microsoft.AspNetCore.JsonPatch { // Implementation details: the purpose of this type of patch document is to allow creation of such // documents for cases where there's no class/DTO to work on. Typical use case: backend not built in diff --git a/src/Microsoft.AspNetCore.JsonPatch/JsonPatchDocumentOfT.cs b/src/Microsoft.AspNetCore.JsonPatch/JsonPatchDocumentOfT.cs index 7b03f1644c..530b414060 100644 --- a/src/Microsoft.AspNetCore.JsonPatch/JsonPatchDocumentOfT.cs +++ b/src/Microsoft.AspNetCore.JsonPatch/JsonPatchDocumentOfT.cs @@ -4,14 +4,14 @@ using System; using System.Collections.Generic; using System.Linq.Expressions; -using Microsoft.AspNet.JsonPatch.Adapters; -using Microsoft.AspNet.JsonPatch.Converters; -using Microsoft.AspNet.JsonPatch.Helpers; -using Microsoft.AspNet.JsonPatch.Operations; +using Microsoft.AspNetCore.JsonPatch.Adapters; +using Microsoft.AspNetCore.JsonPatch.Converters; +using Microsoft.AspNetCore.JsonPatch.Helpers; +using Microsoft.AspNetCore.JsonPatch.Operations; using Newtonsoft.Json; using Newtonsoft.Json.Serialization; -namespace Microsoft.AspNet.JsonPatch +namespace Microsoft.AspNetCore.JsonPatch { // Implementation details: the purpose of this type of patch document is to ensure we can do type-checking // when producing a JsonPatchDocument. However, we cannot send this "typed" over the wire, as that would require diff --git a/src/Microsoft.AspNetCore.JsonPatch/JsonPatchError.cs b/src/Microsoft.AspNetCore.JsonPatch/JsonPatchError.cs index a140f0d4c1..a49af7a4e2 100644 --- a/src/Microsoft.AspNetCore.JsonPatch/JsonPatchError.cs +++ b/src/Microsoft.AspNetCore.JsonPatch/JsonPatchError.cs @@ -2,9 +2,9 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; -using Microsoft.AspNet.JsonPatch.Operations; +using Microsoft.AspNetCore.JsonPatch.Operations; -namespace Microsoft.AspNet.JsonPatch +namespace Microsoft.AspNetCore.JsonPatch { /// /// Captures error message and the related entity and the operation that caused it. diff --git a/src/Microsoft.AspNetCore.JsonPatch/Operations/Operation.cs b/src/Microsoft.AspNetCore.JsonPatch/Operations/Operation.cs index 7f056f41bf..ea81b0c668 100644 --- a/src/Microsoft.AspNetCore.JsonPatch/Operations/Operation.cs +++ b/src/Microsoft.AspNetCore.JsonPatch/Operations/Operation.cs @@ -2,10 +2,10 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; -using Microsoft.AspNet.JsonPatch.Adapters; +using Microsoft.AspNetCore.JsonPatch.Adapters; using Newtonsoft.Json; -namespace Microsoft.AspNet.JsonPatch.Operations +namespace Microsoft.AspNetCore.JsonPatch.Operations { public class Operation : OperationBase { diff --git a/src/Microsoft.AspNetCore.JsonPatch/Operations/OperationBase.cs b/src/Microsoft.AspNetCore.JsonPatch/Operations/OperationBase.cs index 17455f75e8..5f421f41c7 100644 --- a/src/Microsoft.AspNetCore.JsonPatch/Operations/OperationBase.cs +++ b/src/Microsoft.AspNetCore.JsonPatch/Operations/OperationBase.cs @@ -4,7 +4,7 @@ using System; using Newtonsoft.Json; -namespace Microsoft.AspNet.JsonPatch.Operations +namespace Microsoft.AspNetCore.JsonPatch.Operations { public class OperationBase { diff --git a/src/Microsoft.AspNetCore.JsonPatch/Operations/OperationOfT.cs b/src/Microsoft.AspNetCore.JsonPatch/Operations/OperationOfT.cs index 63663f70d9..c41454b7ef 100644 --- a/src/Microsoft.AspNetCore.JsonPatch/Operations/OperationOfT.cs +++ b/src/Microsoft.AspNetCore.JsonPatch/Operations/OperationOfT.cs @@ -2,9 +2,9 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; -using Microsoft.AspNet.JsonPatch.Adapters; +using Microsoft.AspNetCore.JsonPatch.Adapters; -namespace Microsoft.AspNet.JsonPatch.Operations +namespace Microsoft.AspNetCore.JsonPatch.Operations { public class Operation : Operation where TModel : class { diff --git a/src/Microsoft.AspNetCore.JsonPatch/Operations/OperationType.cs b/src/Microsoft.AspNetCore.JsonPatch/Operations/OperationType.cs index a4d006bc51..846b07019f 100644 --- a/src/Microsoft.AspNetCore.JsonPatch/Operations/OperationType.cs +++ b/src/Microsoft.AspNetCore.JsonPatch/Operations/OperationType.cs @@ -1,7 +1,7 @@ // Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -namespace Microsoft.AspNet.JsonPatch.Operations +namespace Microsoft.AspNetCore.JsonPatch.Operations { public enum OperationType { diff --git a/src/Microsoft.AspNetCore.JsonPatch/Properties/Resources.Designer.cs b/src/Microsoft.AspNetCore.JsonPatch/Properties/Resources.Designer.cs index f0ee7f2439..70f76f1fa3 100644 --- a/src/Microsoft.AspNetCore.JsonPatch/Properties/Resources.Designer.cs +++ b/src/Microsoft.AspNetCore.JsonPatch/Properties/Resources.Designer.cs @@ -1,5 +1,5 @@ // -namespace Microsoft.AspNet.JsonPatch +namespace Microsoft.AspNetCore.JsonPatch { using System.Globalization; using System.Reflection; @@ -8,7 +8,7 @@ namespace Microsoft.AspNet.JsonPatch internal static class Resources { private static readonly ResourceManager _resourceManager - = new ResourceManager("Microsoft.AspNet.JsonPatch.Resources", typeof(Resources).GetTypeInfo().Assembly); + = new ResourceManager("Microsoft.AspNetCore.JsonPatch.Resources", typeof(Resources).GetTypeInfo().Assembly); /// /// The type of the property at path '{0}' could not be determined. diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/AddOperationTests.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/AddOperationTests.cs index f5a3c384ef..cb5f090d0f 100644 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/AddOperationTests.cs +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/AddOperationTests.cs @@ -1,14 +1,14 @@ -// 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. using System; using System.Collections.Generic; using System.Dynamic; -using Microsoft.AspNet.JsonPatch.Exceptions; +using Microsoft.AspNetCore.JsonPatch.Exceptions; using Newtonsoft.Json; using Xunit; -namespace Microsoft.AspNet.JsonPatch.Test.Dynamic +namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic { public class AddOperationTests { diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/AddTypedOperationTests.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/AddTypedOperationTests.cs index 7913541514..098e97d850 100644 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/AddTypedOperationTests.cs +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/AddTypedOperationTests.cs @@ -1,12 +1,12 @@ -// 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. using System.Collections.Generic; -using Microsoft.AspNet.JsonPatch.Exceptions; +using Microsoft.AspNetCore.JsonPatch.Exceptions; using Newtonsoft.Json; using Xunit; -namespace Microsoft.AspNet.JsonPatch.Test.Dynamic +namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic { public class AddTypedOperationTests { diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/CopyOperationTests.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/CopyOperationTests.cs index 3fa546faac..87f221bc15 100644 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/CopyOperationTests.cs +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/CopyOperationTests.cs @@ -1,4 +1,4 @@ -// 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. using System.Collections.Generic; @@ -6,7 +6,7 @@ using System.Dynamic; using Newtonsoft.Json; using Xunit; -namespace Microsoft.AspNet.JsonPatch.Test.Dynamic +namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic { public class CopyOperationTests { diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/CopyTypedOperationTests.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/CopyTypedOperationTests.cs index 5b015416ac..3a51556013 100644 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/CopyTypedOperationTests.cs +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/CopyTypedOperationTests.cs @@ -1,11 +1,11 @@ -// 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. using System.Collections.Generic; using Newtonsoft.Json; using Xunit; -namespace Microsoft.AspNet.JsonPatch.Test.Dynamic +namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic { public class CopyTypedOperationTests { diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/MoveOperationTests.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/MoveOperationTests.cs index dea2b6ee32..ed367848b7 100644 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/MoveOperationTests.cs +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/MoveOperationTests.cs @@ -1,4 +1,4 @@ -// 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. using System.Collections.Generic; @@ -6,7 +6,7 @@ using System.Dynamic; using Newtonsoft.Json; using Xunit; -namespace Microsoft.AspNet.JsonPatch.Test.Dynamic +namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic { public class MoveOperationTests { diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/MoveTypedOperationTests.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/MoveTypedOperationTests.cs index 3d356a3401..cd4124d564 100644 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/MoveTypedOperationTests.cs +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/MoveTypedOperationTests.cs @@ -1,11 +1,11 @@ -// 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. using System.Collections.Generic; using Newtonsoft.Json; using Xunit; -namespace Microsoft.AspNet.JsonPatch.Test.Dynamic +namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic { public class MoveTypedOperationTests { diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/NestedDTO.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/NestedDTO.cs index 4d30cf60f2..f94ad05d97 100644 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/NestedDTO.cs +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/NestedDTO.cs @@ -1,7 +1,7 @@ -// 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. -namespace Microsoft.AspNet.JsonPatch.Test.Dynamic +namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic { public class NestedDTO { diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/PatchDocumentTests.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/PatchDocumentTests.cs index 8b14c3448b..e7e6f665a5 100644 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/PatchDocumentTests.cs +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/PatchDocumentTests.cs @@ -1,11 +1,11 @@ -// 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. -using Microsoft.AspNet.JsonPatch.Exceptions; +using Microsoft.AspNetCore.JsonPatch.Exceptions; using Newtonsoft.Json; using Xunit; -namespace Microsoft.AspNet.JsonPatch.Test.Dynamic +namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic { public class PatchDocumentTests { diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/RemoveOperationTests.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/RemoveOperationTests.cs index 9ecb520b38..b436bb4d23 100644 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/RemoveOperationTests.cs +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/RemoveOperationTests.cs @@ -1,13 +1,13 @@ -// 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. using System.Collections.Generic; using System.Dynamic; -using Microsoft.AspNet.JsonPatch.Exceptions; +using Microsoft.AspNetCore.JsonPatch.Exceptions; using Newtonsoft.Json; using Xunit; -namespace Microsoft.AspNet.JsonPatch.Test.Dynamic +namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic { public class RemoveOperationTests { diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/RemoveTypedOperationTests.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/RemoveTypedOperationTests.cs index 802fb27e40..d716dafe9a 100644 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/RemoveTypedOperationTests.cs +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/RemoveTypedOperationTests.cs @@ -1,12 +1,12 @@ -// 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. using System.Collections.Generic; -using Microsoft.AspNet.JsonPatch.Exceptions; +using Microsoft.AspNetCore.JsonPatch.Exceptions; using Newtonsoft.Json; using Xunit; -namespace Microsoft.AspNet.JsonPatch.Test.Dynamic +namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic { public class RemoveTypedOperationTests { diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/ReplaceOperationTests.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/ReplaceOperationTests.cs index c7573c0286..8dff9b6a98 100644 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/ReplaceOperationTests.cs +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/ReplaceOperationTests.cs @@ -1,4 +1,4 @@ -// 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. using System; @@ -8,7 +8,7 @@ using System.Dynamic; using Newtonsoft.Json; using Xunit; -namespace Microsoft.AspNet.JsonPatch.Test.Dynamic +namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic { public class ReplaceOperationTests { diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/ReplaceTypedOperationTests.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/ReplaceTypedOperationTests.cs index ccdd86f1a7..589e86e03a 100644 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/ReplaceTypedOperationTests.cs +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/ReplaceTypedOperationTests.cs @@ -1,4 +1,4 @@ -// 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. using System; @@ -8,7 +8,7 @@ using System.Linq; using Newtonsoft.Json; using Xunit; -namespace Microsoft.AspNet.JsonPatch.Test.Dynamic +namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic { public class ReplaceTypedOperationTests { diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/SimpleDTO.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/SimpleDTO.cs index a6938dd992..d4bf19f75a 100644 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/SimpleDTO.cs +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/SimpleDTO.cs @@ -1,10 +1,10 @@ -// 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. using System; using System.Collections.Generic; -namespace Microsoft.AspNet.JsonPatch.Test.Dynamic +namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic { public class SimpleDTO { diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/SimpleDTOWithNestedDTO.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/SimpleDTOWithNestedDTO.cs index 03c74f8a1b..f8af4bb390 100644 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/SimpleDTOWithNestedDTO.cs +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/SimpleDTOWithNestedDTO.cs @@ -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. using System.Collections.Generic; -namespace Microsoft.AspNet.JsonPatch.Test.Dynamic +namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic { public class SimpleDTOWithNestedDTO { diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/NestedDTO.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/NestedDTO.cs index 6dd5ce8852..aa767557c3 100644 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/NestedDTO.cs +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/NestedDTO.cs @@ -1,7 +1,7 @@ // Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -namespace Microsoft.AspNet.JsonPatch.Test +namespace Microsoft.AspNetCore.JsonPatch.Test { public class NestedDTO { diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/NestedObjectTests.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/NestedObjectTests.cs index e736373ed8..6215da6bcd 100644 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/NestedObjectTests.cs +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/NestedObjectTests.cs @@ -3,11 +3,11 @@ using System.Collections.Generic; using System.Collections.ObjectModel; -using Microsoft.AspNet.JsonPatch.Exceptions; +using Microsoft.AspNetCore.JsonPatch.Exceptions; using Newtonsoft.Json; using Xunit; -namespace Microsoft.AspNet.JsonPatch.Test +namespace Microsoft.AspNetCore.JsonPatch.Test { public class NestedObjectTests { diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/ObjectAdapterTests.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/ObjectAdapterTests.cs index 85d9404e6d..98a72e1bf8 100644 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/ObjectAdapterTests.cs +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/ObjectAdapterTests.cs @@ -4,11 +4,11 @@ using System; using System.Collections.Generic; using System.Collections.ObjectModel; -using Microsoft.AspNet.JsonPatch.Exceptions; +using Microsoft.AspNetCore.JsonPatch.Exceptions; using Newtonsoft.Json; using Xunit; -namespace Microsoft.AspNet.JsonPatch.Test +namespace Microsoft.AspNetCore.JsonPatch.Test { public class ObjectAdapterTests { diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/SimpleDTO.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/SimpleDTO.cs index b1177bc5ce..1206cd108f 100644 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/SimpleDTO.cs +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/SimpleDTO.cs @@ -4,7 +4,7 @@ using System; using System.Collections.Generic; -namespace Microsoft.AspNet.JsonPatch.Test +namespace Microsoft.AspNetCore.JsonPatch.Test { public class SimpleDTO { diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/SimpleDTOWithNestedDTO.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/SimpleDTOWithNestedDTO.cs index 81aa38e682..dbded242ee 100644 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/SimpleDTOWithNestedDTO.cs +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/SimpleDTOWithNestedDTO.cs @@ -3,7 +3,7 @@ using System.Collections.Generic; -namespace Microsoft.AspNet.JsonPatch.Test +namespace Microsoft.AspNetCore.JsonPatch.Test { public class SimpleDTOWithNestedDTO { diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/TestErrorLogger.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/TestErrorLogger.cs index 525321cfb3..6db8a42684 100644 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/TestErrorLogger.cs +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/TestErrorLogger.cs @@ -1,7 +1,7 @@ // Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -namespace Microsoft.AspNet.JsonPatch.Test +namespace Microsoft.AspNetCore.JsonPatch.Test { public class TestErrorLogger where T : class { diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/project.json b/test/Microsoft.AspNetCore.JsonPatch.Test/project.json index 8b97af645a..7699879f8f 100644 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/project.json +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/project.json @@ -3,8 +3,8 @@ "warningsAsErrors": true }, "dependencies": { - "Microsoft.AspNet.JsonPatch": "1.0.0-*", - "Microsoft.AspNet.Testing": "1.0.0-*", + "Microsoft.AspNetCore.JsonPatch": "1.0.0-*", + "Microsoft.AspNetCore.Testing": "1.0.0-*", "Newtonsoft.Json": "6.0.6", "xunit.runner.aspnet": "2.0.0-aspnet-*" }, From 8d19947ada81d6458e6ddf0a48f2cbb12492c9a1 Mon Sep 17 00:00:00 2001 From: Pranav K Date: Thu, 28 Jan 2016 11:03:22 -0800 Subject: [PATCH 027/221] Updating to dotnet-cli build Fixes #9 --- .gitattributes | 52 ++++++++++++++ .gitignore | 15 ++-- .travis.yml | 8 ++- appveyor.yml | 2 +- build.cmd | 68 +++++++++---------- build.sh | 42 ++++++------ .../project.json | 10 +-- 7 files changed, 125 insertions(+), 72 deletions(-) create mode 100644 .gitattributes diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000000..d4ee1cb7f3 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,52 @@ +*.doc diff=astextplain +*.DOC diff=astextplain +*.docx diff=astextplain +*.DOCX diff=astextplain +*.dot diff=astextplain +*.DOT diff=astextplain +*.pdf diff=astextplain +*.PDF diff=astextplain +*.rtf diff=astextplain +*.RTF diff=astextplain + +*.jpg binary +*.png binary +*.gif binary + +*.cs text=auto diff=csharp +*.vb text=auto +*.resx text=auto +*.c text=auto +*.cpp text=auto +*.cxx text=auto +*.h text=auto +*.hxx text=auto +*.py text=auto +*.rb text=auto +*.java text=auto +*.html text=auto +*.htm text=auto +*.css text=auto +*.scss text=auto +*.sass text=auto +*.less text=auto +*.js text=auto +*.lisp text=auto +*.clj text=auto +*.sql text=auto +*.php text=auto +*.lua text=auto +*.m text=auto +*.asm text=auto +*.erl text=auto +*.fs text=auto +*.fsx text=auto +*.hs text=auto + +*.csproj text=auto +*.vbproj text=auto +*.fsproj text=auto +*.dbproj text=auto +*.sln text=auto eol=crlf + +*.sh eol=lf diff --git a/.gitignore b/.gitignore index 8a9bbc3a43..2e4b2d6b5d 100644 --- a/.gitignore +++ b/.gitignore @@ -2,23 +2,21 @@ [Bb]in/ TestResults/ .nuget/ +.build/ +.testPublish/ *.sln.ide/ _ReSharper.*/ packages/ artifacts/ +.build/ PublishProfiles/ -.vs/ -bower_components/ -node_modules/ -**/wwwroot/lib/ -debugSettings.json -project.lock.json *.user *.suo *.cache *.docstates _ReSharper.* nuget.exe +project.lock.json *net45.csproj *net451.csproj *k10.csproj @@ -30,7 +28,4 @@ nuget.exe *.ncrunchsolution *.*sdf *.ipch -.settings -*.sln.ide -node_modules -**/[Cc]ompiler/[Rr]esources/**/*.js +.build/ \ No newline at end of file diff --git a/.travis.yml b/.travis.yml index c0befaffcf..e8f77f0f14 100644 --- a/.travis.yml +++ b/.travis.yml @@ -10,9 +10,11 @@ addons: - libssl-dev - libunwind8 - zlib1g -env: - - KOREBUILD_DNU_RESTORE_CORECLR=true KOREBUILD_TEST_DNXCORE=true mono: - 4.0.5 +os: + - linux + - osx +osx_image: xcode7.1 script: - - ./build.sh --quiet verify + - ./build.sh --quiet verify \ No newline at end of file diff --git a/appveyor.yml b/appveyor.yml index 58a3e1bc22..636a7618d3 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,7 +1,7 @@ init: - git config --global core.autocrlf true build_script: - - build.cmd --quiet --parallel verify + - build.cmd --quiet verify clone_depth: 1 test: off deploy: off \ No newline at end of file diff --git a/build.cmd b/build.cmd index 553e3929a0..65fb3e3353 100644 --- a/build.cmd +++ b/build.cmd @@ -1,40 +1,40 @@ -@echo off -cd %~dp0 - +@ECHO off SETLOCAL + +SET REPO_FOLDER=%~dp0 +CD "%REPO_FOLDER%" + +SET BUILD_FOLDER=.build +SET KOREBUILD_FOLDER=%BUILD_FOLDER%\KoreBuild-dotnet +SET KOREBUILD_VERSION= + +SET NUGET_PATH=%BUILD_FOLDER%\NuGet.exe SET NUGET_VERSION=latest SET CACHED_NUGET=%LocalAppData%\NuGet\nuget.%NUGET_VERSION%.exe -SET BUILDCMD_KOREBUILD_VERSION= -SET BUILDCMD_DNX_VERSION= -IF EXIST %CACHED_NUGET% goto copynuget -echo Downloading latest version of NuGet.exe... -IF NOT EXIST %LocalAppData%\NuGet md %LocalAppData%\NuGet -@powershell -NoProfile -ExecutionPolicy unrestricted -Command "$ProgressPreference = 'SilentlyContinue'; Invoke-WebRequest 'https://dist.nuget.org/win-x86-commandline/%NUGET_VERSION%/nuget.exe' -OutFile '%CACHED_NUGET%'" - -:copynuget -IF EXIST .nuget\nuget.exe goto restore -md .nuget -copy %CACHED_NUGET% .nuget\nuget.exe > nul - -:restore -IF EXIST packages\Sake goto getdnx -IF "%BUILDCMD_KOREBUILD_VERSION%"=="" ( - .nuget\nuget.exe install KoreBuild -ExcludeVersion -o packages -nocache -pre -) ELSE ( - .nuget\nuget.exe install KoreBuild -version %BUILDCMD_KOREBUILD_VERSION% -ExcludeVersion -o packages -nocache -pre -) -.nuget\NuGet.exe install Sake -ExcludeVersion -Source https://www.nuget.org/api/v2/ -Out packages - -:getdnx -IF "%BUILDCMD_DNX_VERSION%"=="" ( - SET BUILDCMD_DNX_VERSION=latest -) -IF "%SKIP_DNX_INSTALL%"=="" ( - CALL packages\KoreBuild\build\dnvm install %BUILDCMD_DNX_VERSION% -runtime CoreCLR -arch x86 -alias default - CALL packages\KoreBuild\build\dnvm install default -runtime CLR -arch x86 -alias default -) ELSE ( - CALL packages\KoreBuild\build\dnvm use default -runtime CLR -arch x86 +IF NOT EXIST %BUILD_FOLDER% ( + md %BUILD_FOLDER% ) -packages\Sake\tools\Sake.exe -I packages\KoreBuild\build -f makefile.shade %* +IF NOT EXIST %NUGET_PATH% ( + IF NOT EXIST %CACHED_NUGET% ( + echo Downloading latest version of NuGet.exe... + IF NOT EXIST %LocalAppData%\NuGet ( + md %LocalAppData%\NuGet + ) + @powershell -NoProfile -ExecutionPolicy unrestricted -Command "$ProgressPreference = 'SilentlyContinue'; Invoke-WebRequest 'https://dist.nuget.org/win-x86-commandline/%NUGET_VERSION%/nuget.exe' -OutFile '%CACHED_NUGET%'" + ) + + copy %CACHED_NUGET% %NUGET_PATH% > nul +) + +IF NOT EXIST %KOREBUILD_FOLDER% ( + SET KOREBUILD_DOWNLOAD_ARGS= + IF NOT "%KOREBUILD_VERSION%"=="" ( + SET KOREBUILD_DOWNLOAD_ARGS=-version %KOREBUILD_VERSION% + ) + + %BUILD_FOLDER%\nuget.exe install KoreBuild-dotnet -ExcludeVersion -o %BUILD_FOLDER% -nocache -pre %KOREBUILD_DOWNLOAD_ARGS% +) + +"%KOREBUILD_FOLDER%\build\KoreBuild.cmd" %* diff --git a/build.sh b/build.sh index da4e3fcd1c..263fb667a8 100755 --- a/build.sh +++ b/build.sh @@ -1,5 +1,10 @@ #!/usr/bin/env bash +buildFolder=.build +koreBuildFolder=$buildFolder/KoreBuild-dotnet + +nugetPath=$buildFolder/nuget.exe + if test `uname` = Darwin; then cachedir=~/Library/Caches/KBuild else @@ -11,33 +16,30 @@ else fi mkdir -p $cachedir nugetVersion=latest -cachePath=$cachedir/nuget.$nugetVersion.exe +cacheNuget=$cachedir/nuget.$nugetVersion.exe -url=https://dist.nuget.org/win-x86-commandline/$nugetVersion/nuget.exe +nugetUrl=https://dist.nuget.org/win-x86-commandline/$nugetVersion/nuget.exe -if test ! -f $cachePath; then - wget -O $cachePath $url 2>/dev/null || curl -o $cachePath --location $url /dev/null +if test ! -d $buildFolder; then + mkdir $buildFolder fi -if test ! -e .nuget; then - mkdir .nuget - cp $cachePath .nuget/nuget.exe +if test ! -f $nugetPath; then + if test ! -f $cacheNuget; then + wget -O $cacheNuget $nugetUrl 2>/dev/null || curl -o $cacheNuget --location $nugetUrl /dev/null + fi + + cp $cacheNuget $nugetPath fi -if test ! -d packages/Sake; then - mono .nuget/nuget.exe install KoreBuild -ExcludeVersion -o packages -nocache -pre - mono .nuget/nuget.exe install Sake -ExcludeVersion -Source https://www.nuget.org/api/v2/ -Out packages +if test ! -d $koreBuildFolder; then + mono $nugetPath install KoreBuild-dotnet -ExcludeVersion -o $buildFolder -nocache -pre + chmod +x $koreBuildFolder/build/KoreBuild.sh fi -if ! type dnvm > /dev/null 2>&1; then - source packages/KoreBuild/build/dnvm.sh +makeFile=makefile.shade +if [ ! -e $makeFile ]; then + makeFile=$koreBuildFolder/build/makefile.shade fi -if ! type dnx > /dev/null 2>&1 || [ -z "$SKIP_DNX_INSTALL" ]; then - dnvm install latest -runtime coreclr -alias default - dnvm install default -runtime mono -alias default -else - dnvm use default -runtime mono -fi - -mono packages/Sake/tools/Sake.exe -I packages/KoreBuild/build -f makefile.shade "$@" +./$koreBuildFolder/build/KoreBuild.sh -n $nugetPath -m $makeFile "$@" diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/project.json b/test/Microsoft.AspNetCore.JsonPatch.Test/project.json index 7699879f8f..963a3eff63 100644 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/project.json +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/project.json @@ -5,21 +5,23 @@ "dependencies": { "Microsoft.AspNetCore.JsonPatch": "1.0.0-*", "Microsoft.AspNetCore.Testing": "1.0.0-*", - "Newtonsoft.Json": "6.0.6", - "xunit.runner.aspnet": "2.0.0-aspnet-*" + "xunit": "2.1.0" }, "commands": { "test": "xunit.runner.aspnet" }, + "testRunner": "xunit", "frameworks": { "dnx451": { "dependencies": { - "Moq": "4.2.1312.1622" + "Moq": "4.2.1312.1622", + "xunit.runner.console": "2.1.0" } }, "dnxcore50": { "dependencies": { - "moq.netcore": "4.4.0-beta8" + "moq.netcore": "4.4.0-beta8", + "xunit.runner.aspnet": "2.0.0-aspnet-*" } } } From 690c42c199e20ed8f7388a497e8672477a4b8594 Mon Sep 17 00:00:00 2001 From: Pranav K Date: Thu, 28 Jan 2016 11:12:36 -0800 Subject: [PATCH 028/221] Add dependency on System.Runtime.Serialization.Primitives to make up for JSON.NET not including it Fixes https://github.com/aspnet/Mvc/issues/3946 --- src/Microsoft.AspNetCore.JsonPatch/project.json | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Microsoft.AspNetCore.JsonPatch/project.json b/src/Microsoft.AspNetCore.JsonPatch/project.json index 4d1206eefb..e654aecf23 100644 --- a/src/Microsoft.AspNetCore.JsonPatch/project.json +++ b/src/Microsoft.AspNetCore.JsonPatch/project.json @@ -22,6 +22,7 @@ "System.Reflection.Extensions": "4.0.1-*", "System.Resources.ResourceManager": "4.0.1-*", "System.Runtime.Extensions": "4.1.0-*", + "System.Runtime.Serialization.Primitives": "4.1.0-*", "System.Text.Encoding.Extensions": "4.0.11-*" } } From 20ed43fd686f86c9be96d7f456864cdc6fa80762 Mon Sep 17 00:00:00 2001 From: John Luo Date: Mon, 1 Feb 2016 14:48:27 -0800 Subject: [PATCH 029/221] Updating to new CLI --- src/Microsoft.AspNetCore.JsonPatch/project.json | 7 +++++-- test/Microsoft.AspNetCore.JsonPatch.Test/project.json | 6 ++++-- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/Microsoft.AspNetCore.JsonPatch/project.json b/src/Microsoft.AspNetCore.JsonPatch/project.json index e654aecf23..2a3d61af5e 100644 --- a/src/Microsoft.AspNetCore.JsonPatch/project.json +++ b/src/Microsoft.AspNetCore.JsonPatch/project.json @@ -9,7 +9,8 @@ "url": "git://github.com/aspnet/mvc" }, "dependencies": { - "Newtonsoft.Json": "8.0.2" + "Newtonsoft.Json": "8.0.2", + "Microsoft.NETCore.Platforms": "1.0.1-*" }, "frameworks": { "net451": {}, @@ -21,10 +22,12 @@ "System.Globalization": "4.0.11-*", "System.Reflection.Extensions": "4.0.1-*", "System.Resources.ResourceManager": "4.0.1-*", + "System.Runtime": "4.0.21-*", "System.Runtime.Extensions": "4.1.0-*", "System.Runtime.Serialization.Primitives": "4.1.0-*", "System.Text.Encoding.Extensions": "4.0.11-*" - } + }, + "imports": "portable-net451+win8" } } } diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/project.json b/test/Microsoft.AspNetCore.JsonPatch.Test/project.json index 963a3eff63..ff30cfb346 100644 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/project.json +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/project.json @@ -5,7 +5,8 @@ "dependencies": { "Microsoft.AspNetCore.JsonPatch": "1.0.0-*", "Microsoft.AspNetCore.Testing": "1.0.0-*", - "xunit": "2.1.0" + "xunit": "2.1.0", + "Microsoft.NETCore.Platforms": "1.0.1-*" }, "commands": { "test": "xunit.runner.aspnet" @@ -22,7 +23,8 @@ "dependencies": { "moq.netcore": "4.4.0-beta8", "xunit.runner.aspnet": "2.0.0-aspnet-*" - } + }, + "imports": "portable-net451+win8" } } } \ No newline at end of file From 82e17ce2b69a6bfdcdb631a93b6066a6c74ad47c Mon Sep 17 00:00:00 2001 From: John Luo Date: Mon, 1 Feb 2016 17:58:41 -0800 Subject: [PATCH 030/221] Removing redundant dependencies --- src/Microsoft.AspNetCore.JsonPatch/project.json | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Microsoft.AspNetCore.JsonPatch/project.json b/src/Microsoft.AspNetCore.JsonPatch/project.json index 2a3d61af5e..072386b843 100644 --- a/src/Microsoft.AspNetCore.JsonPatch/project.json +++ b/src/Microsoft.AspNetCore.JsonPatch/project.json @@ -9,8 +9,7 @@ "url": "git://github.com/aspnet/mvc" }, "dependencies": { - "Newtonsoft.Json": "8.0.2", - "Microsoft.NETCore.Platforms": "1.0.1-*" + "Newtonsoft.Json": "8.0.2" }, "frameworks": { "net451": {}, From e0fbc6e2c218849a04e16e1792ae472d31952f4c Mon Sep 17 00:00:00 2001 From: "N. Taylor Mullen" Date: Fri, 5 Feb 2016 17:22:05 -0800 Subject: [PATCH 031/221] Update project.json to remove redundant System.Runtime dependency. - This package is pulled in transitively. --- src/Microsoft.AspNetCore.JsonPatch/project.json | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Microsoft.AspNetCore.JsonPatch/project.json b/src/Microsoft.AspNetCore.JsonPatch/project.json index 072386b843..bae136cbbc 100644 --- a/src/Microsoft.AspNetCore.JsonPatch/project.json +++ b/src/Microsoft.AspNetCore.JsonPatch/project.json @@ -21,7 +21,6 @@ "System.Globalization": "4.0.11-*", "System.Reflection.Extensions": "4.0.1-*", "System.Resources.ResourceManager": "4.0.1-*", - "System.Runtime": "4.0.21-*", "System.Runtime.Extensions": "4.1.0-*", "System.Runtime.Serialization.Primitives": "4.1.0-*", "System.Text.Encoding.Extensions": "4.0.11-*" From 76c20aa01032064f8c7a4e6baa92007b1302bf0a Mon Sep 17 00:00:00 2001 From: Pranav K Date: Mon, 8 Feb 2016 09:33:46 -0800 Subject: [PATCH 032/221] Reacting to CoreCLR package version changes --- src/Microsoft.AspNetCore.JsonPatch/project.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Microsoft.AspNetCore.JsonPatch/project.json b/src/Microsoft.AspNetCore.JsonPatch/project.json index bae136cbbc..ec303724f5 100644 --- a/src/Microsoft.AspNetCore.JsonPatch/project.json +++ b/src/Microsoft.AspNetCore.JsonPatch/project.json @@ -16,7 +16,7 @@ "dotnet5.4": { "dependencies": { "Microsoft.CSharp": "4.0.1-*", - "System.Collections.Concurrent": "4.0.11-*", + "System.Collections.Concurrent": "4.0.12-*", "System.ComponentModel.TypeConverter": "4.0.1-*", "System.Globalization": "4.0.11-*", "System.Reflection.Extensions": "4.0.1-*", From de419e26ce4eadcd0073ae4d74d66d11f2885a25 Mon Sep 17 00:00:00 2001 From: Kiran Challa Date: Tue, 9 Feb 2016 22:27:25 -0800 Subject: [PATCH 033/221] Enable tests to run using dotnet xunit runner --- .../project.json | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/project.json b/test/Microsoft.AspNetCore.JsonPatch.Test/project.json index ff30cfb346..07a2b3511c 100644 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/project.json +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/project.json @@ -8,23 +8,20 @@ "xunit": "2.1.0", "Microsoft.NETCore.Platforms": "1.0.1-*" }, - "commands": { - "test": "xunit.runner.aspnet" - }, "testRunner": "xunit", "frameworks": { + "dnxcore50": { + "dependencies": { + "moq.netcore": "4.4.0-beta8", + "dotnet-test-xunit": "1.0.0-dev-*" + }, + "imports": "portable-net451+win8" + }, "dnx451": { "dependencies": { "Moq": "4.2.1312.1622", "xunit.runner.console": "2.1.0" } - }, - "dnxcore50": { - "dependencies": { - "moq.netcore": "4.4.0-beta8", - "xunit.runner.aspnet": "2.0.0-aspnet-*" - }, - "imports": "portable-net451+win8" } } } \ No newline at end of file From 2bbb7a69e9ba3b98c53d2a8c70b38b43599a7309 Mon Sep 17 00:00:00 2001 From: Brennan Date: Thu, 11 Feb 2016 09:45:54 -0800 Subject: [PATCH 034/221] Update dependencies --- test/Microsoft.AspNetCore.JsonPatch.Test/project.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/project.json b/test/Microsoft.AspNetCore.JsonPatch.Test/project.json index 07a2b3511c..cb87b096e9 100644 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/project.json +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/project.json @@ -18,6 +18,10 @@ "imports": "portable-net451+win8" }, "dnx451": { + "frameworkAssemblies": { + "System.Runtime": "", + "System.Threading.Tasks": "" + }, "dependencies": { "Moq": "4.2.1312.1622", "xunit.runner.console": "2.1.0" From 4e5e6b3891bd9e6ff22e2cd5a0e435cfad961c57 Mon Sep 17 00:00:00 2001 From: John Luo Date: Thu, 18 Feb 2016 14:46:26 -0800 Subject: [PATCH 035/221] Updating test TFMs for custom test discovery --- test/Microsoft.AspNetCore.JsonPatch.Test/project.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/project.json b/test/Microsoft.AspNetCore.JsonPatch.Test/project.json index cb87b096e9..cd04e92bb2 100644 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/project.json +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/project.json @@ -17,7 +17,7 @@ }, "imports": "portable-net451+win8" }, - "dnx451": { + "net451": { "frameworkAssemblies": { "System.Runtime": "", "System.Threading.Tasks": "" From 42d913b3ba8a7e82867f1cd4749277338071bca7 Mon Sep 17 00:00:00 2001 From: Ajay Bhargav Baaskaran Date: Thu, 18 Feb 2016 16:20:51 -0800 Subject: [PATCH 036/221] Enabled xml doc generation --- NuGetPackageVerifier.json | 14 ++------------ src/Microsoft.AspNetCore.JsonPatch/project.json | 4 +++- 2 files changed, 5 insertions(+), 13 deletions(-) diff --git a/NuGetPackageVerifier.json b/NuGetPackageVerifier.json index e95640a3d3..f68002830f 100644 --- a/NuGetPackageVerifier.json +++ b/NuGetPackageVerifier.json @@ -1,12 +1,7 @@ { "adx": { // Packages written by the ADX team and that ship on NuGet.org "rules": [ - "AssemblyHasDocumentFileRule", - "AssemblyHasVersionAttributesRule", - "AssemblyHasServicingAttributeRule", - "AssemblyHasNeutralResourcesLanguageAttributeRule", - "SatellitePackageRule", - "StrictSemanticVersionValidationRule" + "AdxVerificationCompositeRule" ], "packages": { "Microsoft.AspNetCore.JsonPatch": { } @@ -14,12 +9,7 @@ }, "Default": { // Rules to run for packages not listed in any other set. "rules": [ - "AssemblyHasDocumentFileRule", - "AssemblyHasVersionAttributesRule", - "AssemblyHasServicingAttributeRule", - "AssemblyHasNeutralResourcesLanguageAttributeRule", - "SatellitePackageRule", - "StrictSemanticVersionValidationRule" + "DefaultCompositeRule" ] } } \ No newline at end of file diff --git a/src/Microsoft.AspNetCore.JsonPatch/project.json b/src/Microsoft.AspNetCore.JsonPatch/project.json index ec303724f5..91adf85b87 100644 --- a/src/Microsoft.AspNetCore.JsonPatch/project.json +++ b/src/Microsoft.AspNetCore.JsonPatch/project.json @@ -2,7 +2,9 @@ "version": "1.0.0-*", "compilationOptions": { "warningsAsErrors": true, - "keyFile": "../../tools/Key.snk" + "keyFile": "../../tools/Key.snk", + "nowarn": [ "CS1591" ], + "xmlDoc": true }, "repository": { "type": "git", From 34c0c208518badb6658806ebbb5f9c13895c186b Mon Sep 17 00:00:00 2001 From: Doug Bunting Date: Wed, 24 Feb 2016 12:47:22 -0800 Subject: [PATCH 037/221] Update `build.cmd` to match latest template - aspnet/Universe#347 - `%KOREBUILD_VERSION%` doesn't work without this fix --- build.cmd | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/build.cmd b/build.cmd index 65fb3e3353..95b049cf63 100644 --- a/build.cmd +++ b/build.cmd @@ -28,12 +28,11 @@ IF NOT EXIST %NUGET_PATH% ( copy %CACHED_NUGET% %NUGET_PATH% > nul ) +SET KOREBUILD_DOWNLOAD_ARGS= +IF NOT "%KOREBUILD_VERSION%"=="" ( + SET KOREBUILD_DOWNLOAD_ARGS=-version %KOREBUILD_VERSION% +) IF NOT EXIST %KOREBUILD_FOLDER% ( - SET KOREBUILD_DOWNLOAD_ARGS= - IF NOT "%KOREBUILD_VERSION%"=="" ( - SET KOREBUILD_DOWNLOAD_ARGS=-version %KOREBUILD_VERSION% - ) - %BUILD_FOLDER%\nuget.exe install KoreBuild-dotnet -ExcludeVersion -o %BUILD_FOLDER% -nocache -pre %KOREBUILD_DOWNLOAD_ARGS% ) From c6e3cf30d3ab9ba2e1793fcdc42652823ed0614a Mon Sep 17 00:00:00 2001 From: Victor Hurdugaci Date: Sat, 27 Feb 2016 12:51:10 -0800 Subject: [PATCH 038/221] Update the build scripts --- build.cmd | 41 ++----------------------------------- build.ps1 | 36 +++++++++++++++++++++++++++++++++ build.sh | 60 +++++++++++++++++++++++-------------------------------- 3 files changed, 63 insertions(+), 74 deletions(-) create mode 100644 build.ps1 diff --git a/build.cmd b/build.cmd index 95b049cf63..2fa024b15e 100644 --- a/build.cmd +++ b/build.cmd @@ -1,39 +1,2 @@ -@ECHO off -SETLOCAL - -SET REPO_FOLDER=%~dp0 -CD "%REPO_FOLDER%" - -SET BUILD_FOLDER=.build -SET KOREBUILD_FOLDER=%BUILD_FOLDER%\KoreBuild-dotnet -SET KOREBUILD_VERSION= - -SET NUGET_PATH=%BUILD_FOLDER%\NuGet.exe -SET NUGET_VERSION=latest -SET CACHED_NUGET=%LocalAppData%\NuGet\nuget.%NUGET_VERSION%.exe - -IF NOT EXIST %BUILD_FOLDER% ( - md %BUILD_FOLDER% -) - -IF NOT EXIST %NUGET_PATH% ( - IF NOT EXIST %CACHED_NUGET% ( - echo Downloading latest version of NuGet.exe... - IF NOT EXIST %LocalAppData%\NuGet ( - md %LocalAppData%\NuGet - ) - @powershell -NoProfile -ExecutionPolicy unrestricted -Command "$ProgressPreference = 'SilentlyContinue'; Invoke-WebRequest 'https://dist.nuget.org/win-x86-commandline/%NUGET_VERSION%/nuget.exe' -OutFile '%CACHED_NUGET%'" - ) - - copy %CACHED_NUGET% %NUGET_PATH% > nul -) - -SET KOREBUILD_DOWNLOAD_ARGS= -IF NOT "%KOREBUILD_VERSION%"=="" ( - SET KOREBUILD_DOWNLOAD_ARGS=-version %KOREBUILD_VERSION% -) -IF NOT EXIST %KOREBUILD_FOLDER% ( - %BUILD_FOLDER%\nuget.exe install KoreBuild-dotnet -ExcludeVersion -o %BUILD_FOLDER% -nocache -pre %KOREBUILD_DOWNLOAD_ARGS% -) - -"%KOREBUILD_FOLDER%\build\KoreBuild.cmd" %* +@ECHO OFF +PowerShell -NoProfile -NoLogo -ExecutionPolicy unrestricted -Command "[System.Threading.Thread]::CurrentThread.CurrentCulture = ''; [System.Threading.Thread]::CurrentThread.CurrentUICulture = '';& '%~dp0build.ps1' %*" \ No newline at end of file diff --git a/build.ps1 b/build.ps1 new file mode 100644 index 0000000000..4fd24a30d5 --- /dev/null +++ b/build.ps1 @@ -0,0 +1,36 @@ +cd $PSScriptRoot + +$repoFolder = $PSScriptRoot +$env:REPO_FOLDER = $repoFolder + +$koreBuildZip="https://github.com/aspnet/KoreBuild/archive/dev.zip" +if ($env:KOREBUILD_ZIP) +{ + $koreBuildZip=$env:KOREBUILD_ZIP +} + +$buildFolder = ".build" +$buildFile="$buildFolder\KoreBuild.ps1" + +if (!(Test-Path $buildFolder)) { + Write-Host "Downloading KoreBuild from $koreBuildZip" + + $tempFolder=$env:TEMP + "\KoreBuild-" + [guid]::NewGuid() + New-Item -Path "$tempFolder" -Type directory | Out-Null + + $localZipFile="$tempFolder\korebuild.zip" + + Invoke-WebRequest $koreBuildZip -OutFile $localZipFile + Add-Type -AssemblyName System.IO.Compression.FileSystem + [System.IO.Compression.ZipFile]::ExtractToDirectory($localZipFile, $tempFolder) + + New-Item -Path "$buildFolder" -Type directory | Out-Null + copy-item "$tempFolder\**\build\*" $buildFolder -Recurse + + # Cleanup + if (Test-Path $tempFolder) { + Remove-Item -Recurse -Force $tempFolder + } +} + +&"$buildFile" $args \ No newline at end of file diff --git a/build.sh b/build.sh index 263fb667a8..79638d06b6 100755 --- a/build.sh +++ b/build.sh @@ -1,45 +1,35 @@ #!/usr/bin/env bash +repoFolder="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +cd $repoFolder -buildFolder=.build -koreBuildFolder=$buildFolder/KoreBuild-dotnet - -nugetPath=$buildFolder/nuget.exe - -if test `uname` = Darwin; then - cachedir=~/Library/Caches/KBuild -else - if [ -z $XDG_DATA_HOME ]; then - cachedir=$HOME/.local/share - else - cachedir=$XDG_DATA_HOME; - fi +koreBuildZip="https://github.com/aspnet/KoreBuild/archive/dev.zip" +if [ ! -z $KOREBUILD_ZIP ]; then + koreBuildZip=$KOREBUILD_ZIP fi -mkdir -p $cachedir -nugetVersion=latest -cacheNuget=$cachedir/nuget.$nugetVersion.exe -nugetUrl=https://dist.nuget.org/win-x86-commandline/$nugetVersion/nuget.exe +buildFolder=".build" +buildFile="$buildFolder/KoreBuild.sh" if test ! -d $buildFolder; then + echo "Downloading KoreBuild from $koreBuildZip" + + tempFolder="/tmp/KoreBuild-$(uuidgen)" + mkdir $tempFolder + + localZipFile="$tempFolder/korebuild.zip" + + wget -O $localZipFile $koreBuildZip 2>/dev/null || curl -o $localZipFile --location $koreBuildZip /dev/null + unzip -q -d $tempFolder $localZipFile + mkdir $buildFolder -fi - -if test ! -f $nugetPath; then - if test ! -f $cacheNuget; then - wget -O $cacheNuget $nugetUrl 2>/dev/null || curl -o $cacheNuget --location $nugetUrl /dev/null + cp -r $tempFolder/**/build/** $buildFolder + + chmod +x $buildFile + + # Cleanup + if test ! -d $tempFolder; then + rm -rf $tempFolder fi - - cp $cacheNuget $nugetPath fi -if test ! -d $koreBuildFolder; then - mono $nugetPath install KoreBuild-dotnet -ExcludeVersion -o $buildFolder -nocache -pre - chmod +x $koreBuildFolder/build/KoreBuild.sh -fi - -makeFile=makefile.shade -if [ ! -e $makeFile ]; then - makeFile=$koreBuildFolder/build/makefile.shade -fi - -./$koreBuildFolder/build/KoreBuild.sh -n $nugetPath -m $makeFile "$@" +$buildFile -r $repoFolder "$@" From 39af4735ac70102f05fe8b4a895d3fed8f7c6934 Mon Sep 17 00:00:00 2001 From: Victor Hurdugaci Date: Sun, 28 Feb 2016 10:12:13 -0800 Subject: [PATCH 039/221] Return the error code from build.cmd --- build.cmd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.cmd b/build.cmd index 2fa024b15e..7d4894cb4a 100644 --- a/build.cmd +++ b/build.cmd @@ -1,2 +1,2 @@ @ECHO OFF -PowerShell -NoProfile -NoLogo -ExecutionPolicy unrestricted -Command "[System.Threading.Thread]::CurrentThread.CurrentCulture = ''; [System.Threading.Thread]::CurrentThread.CurrentUICulture = '';& '%~dp0build.ps1' %*" \ No newline at end of file +PowerShell -NoProfile -NoLogo -ExecutionPolicy unrestricted -Command "[System.Threading.Thread]::CurrentThread.CurrentCulture = ''; [System.Threading.Thread]::CurrentThread.CurrentUICulture = '';& '%~dp0build.ps1' %*; exit $LASTEXITCODE" \ No newline at end of file From 8c293934e874addfcdcfc3859592dc1ac3de210d Mon Sep 17 00:00:00 2001 From: "N. Taylor Mullen" Date: Tue, 1 Mar 2016 13:32:25 -0800 Subject: [PATCH 040/221] Transition to netstandard. - dotnet5.X => netstandard1.y (where y = x-1). - DNXCore50 => netstandardapp1.5. - Applied the same changes to ifdefs. --- src/Microsoft.AspNetCore.JsonPatch/project.json | 13 +++++++++---- .../project.json | 7 +++++-- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/src/Microsoft.AspNetCore.JsonPatch/project.json b/src/Microsoft.AspNetCore.JsonPatch/project.json index 91adf85b87..6e66884725 100644 --- a/src/Microsoft.AspNetCore.JsonPatch/project.json +++ b/src/Microsoft.AspNetCore.JsonPatch/project.json @@ -3,7 +3,9 @@ "compilationOptions": { "warningsAsErrors": true, "keyFile": "../../tools/Key.snk", - "nowarn": [ "CS1591" ], + "nowarn": [ + "CS1591" + ], "xmlDoc": true }, "repository": { @@ -15,7 +17,7 @@ }, "frameworks": { "net451": {}, - "dotnet5.4": { + "netstandard1.3": { "dependencies": { "Microsoft.CSharp": "4.0.1-*", "System.Collections.Concurrent": "4.0.12-*", @@ -27,7 +29,10 @@ "System.Runtime.Serialization.Primitives": "4.1.0-*", "System.Text.Encoding.Extensions": "4.0.11-*" }, - "imports": "portable-net451+win8" + "imports": [ + "dotnet5.4", + "portable-net451+win8" + ] } } -} +} \ No newline at end of file diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/project.json b/test/Microsoft.AspNetCore.JsonPatch.Test/project.json index cd04e92bb2..6bfaeafb67 100644 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/project.json +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/project.json @@ -10,12 +10,15 @@ }, "testRunner": "xunit", "frameworks": { - "dnxcore50": { + "netstandardapp1.5": { "dependencies": { "moq.netcore": "4.4.0-beta8", "dotnet-test-xunit": "1.0.0-dev-*" }, - "imports": "portable-net451+win8" + "imports": [ + "dnxcore50", + "portable-net451+win8" + ] }, "net451": { "frameworkAssemblies": { From 404a3144cf8c2cb609f79c51d94c3053491db04c Mon Sep 17 00:00:00 2001 From: Doug Bunting Date: Wed, 2 Mar 2016 18:55:57 -0800 Subject: [PATCH 041/221] Remove project name from output path - aspnet/Coherence-Signed#187 - remove `` settings but maintain other unique aspects e.g. `` - in a few cases, standardize on VS version `14.0` and not something more specific --- .../Microsoft.AspNetCore.JsonPatch.xproj | 2 +- .../Microsoft.AspNetCore.JsonPatch.Test.xproj | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Microsoft.AspNetCore.JsonPatch/Microsoft.AspNetCore.JsonPatch.xproj b/src/Microsoft.AspNetCore.JsonPatch/Microsoft.AspNetCore.JsonPatch.xproj index f9fb187ecd..d11d600744 100644 --- a/src/Microsoft.AspNetCore.JsonPatch/Microsoft.AspNetCore.JsonPatch.xproj +++ b/src/Microsoft.AspNetCore.JsonPatch/Microsoft.AspNetCore.JsonPatch.xproj @@ -8,7 +8,7 @@ 4d55f4d8-633b-462f-a5b1-feb84bd2d534 ..\..\artifacts\obj\$(MSBuildProjectName) - ..\..\artifacts\bin\$(MSBuildProjectName)\ + ..\..\artifacts\bin\ 2.0 diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/Microsoft.AspNetCore.JsonPatch.Test.xproj b/test/Microsoft.AspNetCore.JsonPatch.Test/Microsoft.AspNetCore.JsonPatch.Test.xproj index 74e0fef687..0b71c5d301 100644 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/Microsoft.AspNetCore.JsonPatch.Test.xproj +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/Microsoft.AspNetCore.JsonPatch.Test.xproj @@ -8,7 +8,7 @@ 81c20848-e063-4e12-ac40-0b55a532c16c ..\..\artifacts\obj\$(MSBuildProjectName) - ..\..\artifacts\bin\$(MSBuildProjectName)\ + ..\..\artifacts\bin\ 2.0 From e95ed5d204956a60a1b8ebe992aa25d4b862181b Mon Sep 17 00:00:00 2001 From: Ajay Bhargav Baaskaran Date: Thu, 3 Mar 2016 17:31:17 -0800 Subject: [PATCH 042/221] Added Company, Copyright and Product attributes to AssemblyInfo --- .../Properties/AssemblyInfo.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/Microsoft.AspNetCore.JsonPatch/Properties/AssemblyInfo.cs b/src/Microsoft.AspNetCore.JsonPatch/Properties/AssemblyInfo.cs index b2437d9ad6..76feceeff0 100644 --- a/src/Microsoft.AspNetCore.JsonPatch/Properties/AssemblyInfo.cs +++ b/src/Microsoft.AspNetCore.JsonPatch/Properties/AssemblyInfo.cs @@ -5,4 +5,7 @@ using System.Reflection; using System.Resources; [assembly: AssemblyMetadata("Serviceable", "True")] -[assembly: NeutralResourcesLanguage("en-us")] \ No newline at end of file +[assembly: NeutralResourcesLanguage("en-us")] +[assembly: AssemblyCompany("Microsoft Corporation.")] +[assembly: AssemblyCopyright("© Microsoft Corporation. All rights reserved.")] +[assembly: AssemblyProduct("Microsoft ASP.NET Core")] From 5b5655f62808723e2be37b442277b393a813bf48 Mon Sep 17 00:00:00 2001 From: Victor Hurdugaci Date: Mon, 7 Mar 2016 20:54:58 -0800 Subject: [PATCH 043/221] Update the build scripts to the latest version --- build.ps1 | 33 ++++++++++++++++++++++++++++++++- build.sh | 15 +++++++++++++-- 2 files changed, 45 insertions(+), 3 deletions(-) diff --git a/build.ps1 b/build.ps1 index 4fd24a30d5..8f2f99691a 100644 --- a/build.ps1 +++ b/build.ps1 @@ -1,3 +1,33 @@ +$ErrorActionPreference = "Stop" + +function DownloadWithRetry([string] $url, [string] $downloadLocation, [int] $retries) +{ + while($true) + { + try + { + Invoke-WebRequest $url -OutFile $downloadLocation + break + } + catch + { + $exceptionMessage = $_.Exception.Message + Write-Host "Failed to download '$url': $exceptionMessage" + if ($retries -gt 0) { + $retries-- + Write-Host "Waiting 10 seconds before retrying. Retries left: $retries" + Start-Sleep -Seconds 10 + + } + else + { + $exception = $_.Exception + throw $exception + } + } + } +} + cd $PSScriptRoot $repoFolder = $PSScriptRoot @@ -20,7 +50,8 @@ if (!(Test-Path $buildFolder)) { $localZipFile="$tempFolder\korebuild.zip" - Invoke-WebRequest $koreBuildZip -OutFile $localZipFile + DownloadWithRetry -url $koreBuildZip -downloadLocation $localZipFile -retries 6 + Add-Type -AssemblyName System.IO.Compression.FileSystem [System.IO.Compression.ZipFile]::ExtractToDirectory($localZipFile, $tempFolder) diff --git a/build.sh b/build.sh index 79638d06b6..f4208100eb 100755 --- a/build.sh +++ b/build.sh @@ -18,7 +18,18 @@ if test ! -d $buildFolder; then localZipFile="$tempFolder/korebuild.zip" - wget -O $localZipFile $koreBuildZip 2>/dev/null || curl -o $localZipFile --location $koreBuildZip /dev/null + retries=6 + until (wget -O $localZipFile $koreBuildZip 2>/dev/null || curl -o $localZipFile --location $koreBuildZip 2>/dev/null) + do + echo "Failed to download '$koreBuildZip'" + if [ "$retries" -le 0 ]; then + exit 1 + fi + retries=$((retries - 1)) + echo "Waiting 10 seconds before retrying. Retries left: $retries" + sleep 10s + done + unzip -q -d $tempFolder $localZipFile mkdir $buildFolder @@ -32,4 +43,4 @@ if test ! -d $buildFolder; then fi fi -$buildFile -r $repoFolder "$@" +$buildFile -r $repoFolder "$@" \ No newline at end of file From b7993bd562df1dca3c3f9d5d672f90911c880cf6 Mon Sep 17 00:00:00 2001 From: Nate McMaster Date: Wed, 9 Mar 2016 16:35:07 -0800 Subject: [PATCH 044/221] Limit the branches that build on our public CI. [ci skip] --- .travis.yml | 6 ++++++ appveyor.yml | 6 ++++++ 2 files changed, 12 insertions(+) diff --git a/.travis.yml b/.travis.yml index e8f77f0f14..e63d71127a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -16,5 +16,11 @@ os: - linux - osx osx_image: xcode7.1 +branches: + only: + - master + - release + - dev + - /^(.*\\/)?ci-.*$/ script: - ./build.sh --quiet verify \ No newline at end of file diff --git a/appveyor.yml b/appveyor.yml index 636a7618d3..15ffe737a5 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,5 +1,11 @@ init: - git config --global core.autocrlf true +branches: + only: + - master + - release + - dev + - /^(.*\\/)?ci-.*$/ build_script: - build.cmd --quiet verify clone_depth: 1 From 104163e275cce1f95b5b77a6bd6c38abe64061fa Mon Sep 17 00:00:00 2001 From: Nate McMaster Date: Wed, 9 Mar 2016 17:44:47 -0800 Subject: [PATCH 045/221] Fix backslashes in yml config. [ci skip] --- .travis.yml | 2 +- appveyor.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index e63d71127a..304e307169 100644 --- a/.travis.yml +++ b/.travis.yml @@ -21,6 +21,6 @@ branches: - master - release - dev - - /^(.*\\/)?ci-.*$/ + - /^(.*\/)?ci-.*$/ script: - ./build.sh --quiet verify \ No newline at end of file diff --git a/appveyor.yml b/appveyor.yml index 15ffe737a5..be95b88d6f 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -5,7 +5,7 @@ branches: - master - release - dev - - /^(.*\\/)?ci-.*$/ + - /^(.*\/)?ci-.*$/ build_script: - build.cmd --quiet verify clone_depth: 1 From b734291b1395d8134b911141c01d8c6aee9ea86e Mon Sep 17 00:00:00 2001 From: Pranav K Date: Thu, 10 Mar 2016 21:46:51 -0800 Subject: [PATCH 046/221] Target minimal TFMs --- .../Adapters/ObjectAdapter.cs | 4 ++-- .../Converters/TypedJsonPatchDocumentConverter.cs | 2 +- .../Helpers/ObjectTreeAnalyisResult.cs | 1 - src/Microsoft.AspNetCore.JsonPatch/project.json | 7 ++++--- test/Microsoft.AspNetCore.JsonPatch.Test/project.json | 5 +++-- 5 files changed, 10 insertions(+), 9 deletions(-) diff --git a/src/Microsoft.AspNetCore.JsonPatch/Adapters/ObjectAdapter.cs b/src/Microsoft.AspNetCore.JsonPatch/Adapters/ObjectAdapter.cs index aeae454fa9..b70ff697c3 100644 --- a/src/Microsoft.AspNetCore.JsonPatch/Adapters/ObjectAdapter.cs +++ b/src/Microsoft.AspNetCore.JsonPatch/Adapters/ObjectAdapter.cs @@ -1023,14 +1023,14 @@ namespace Microsoft.AspNetCore.JsonPatch.Adapters { if (IsGenericListType(type)) { - return type.GetGenericArguments()[0]; + return type.GetTypeInfo().GenericTypeArguments[0]; } foreach (Type interfaceType in type.GetTypeInfo().ImplementedInterfaces) { if (IsGenericListType(interfaceType)) { - return interfaceType.GetGenericArguments()[0]; + return interfaceType.GetTypeInfo().GenericTypeArguments[0]; } } diff --git a/src/Microsoft.AspNetCore.JsonPatch/Converters/TypedJsonPatchDocumentConverter.cs b/src/Microsoft.AspNetCore.JsonPatch/Converters/TypedJsonPatchDocumentConverter.cs index a150bd0478..292a3be556 100644 --- a/src/Microsoft.AspNetCore.JsonPatch/Converters/TypedJsonPatchDocumentConverter.cs +++ b/src/Microsoft.AspNetCore.JsonPatch/Converters/TypedJsonPatchDocumentConverter.cs @@ -27,7 +27,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Converters return null; } - var genericType = objectType.GetGenericArguments()[0]; + var genericType = objectType.GetTypeInfo().GenericTypeArguments[0]; // load jObject var jObject = JArray.Load(reader); diff --git a/src/Microsoft.AspNetCore.JsonPatch/Helpers/ObjectTreeAnalyisResult.cs b/src/Microsoft.AspNetCore.JsonPatch/Helpers/ObjectTreeAnalyisResult.cs index 4d083bd073..782859ad5f 100644 --- a/src/Microsoft.AspNetCore.JsonPatch/Helpers/ObjectTreeAnalyisResult.cs +++ b/src/Microsoft.AspNetCore.JsonPatch/Helpers/ObjectTreeAnalyisResult.cs @@ -141,7 +141,6 @@ namespace Microsoft.AspNetCore.JsonPatch.Helpers } else if (targetObject is IList) { - System.Diagnostics.Debugger.Launch(); UseDynamicLogic = false; int index; diff --git a/src/Microsoft.AspNetCore.JsonPatch/project.json b/src/Microsoft.AspNetCore.JsonPatch/project.json index 6e66884725..abfc19cba3 100644 --- a/src/Microsoft.AspNetCore.JsonPatch/project.json +++ b/src/Microsoft.AspNetCore.JsonPatch/project.json @@ -16,13 +16,14 @@ "Newtonsoft.Json": "8.0.2" }, "frameworks": { - "net451": {}, - "netstandard1.3": { + "netstandard1.1": { "dependencies": { "Microsoft.CSharp": "4.0.1-*", "System.Collections.Concurrent": "4.0.12-*", "System.ComponentModel.TypeConverter": "4.0.1-*", + "System.Diagnostics.Debug": "4.0.11-*", "System.Globalization": "4.0.11-*", + "System.Linq": "4.1.0-*", "System.Reflection.Extensions": "4.0.1-*", "System.Resources.ResourceManager": "4.0.1-*", "System.Runtime.Extensions": "4.1.0-*", @@ -30,7 +31,7 @@ "System.Text.Encoding.Extensions": "4.0.11-*" }, "imports": [ - "dotnet5.4", + "dotnet5.2", "portable-net451+win8" ] } diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/project.json b/test/Microsoft.AspNetCore.JsonPatch.Test/project.json index 6bfaeafb67..c8772f21fb 100644 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/project.json +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/project.json @@ -22,11 +22,12 @@ }, "net451": { "frameworkAssemblies": { - "System.Runtime": "", - "System.Threading.Tasks": "" + "System.Linq.Expressions": {"type": "build"}, + "System.Threading.Tasks": { "type": "build" } }, "dependencies": { "Moq": "4.2.1312.1622", + "System.Runtime": "4.1.0-*", "xunit.runner.console": "2.1.0" } } From bfe81edbdc29c88a9814fbb939ea465293f960e3 Mon Sep 17 00:00:00 2001 From: Ajay Bhargav Baaskaran Date: Mon, 14 Mar 2016 14:42:18 -0700 Subject: [PATCH 047/221] Updated Json.Net version --- src/Microsoft.AspNetCore.JsonPatch/project.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Microsoft.AspNetCore.JsonPatch/project.json b/src/Microsoft.AspNetCore.JsonPatch/project.json index abfc19cba3..f4cc9ede98 100644 --- a/src/Microsoft.AspNetCore.JsonPatch/project.json +++ b/src/Microsoft.AspNetCore.JsonPatch/project.json @@ -13,7 +13,7 @@ "url": "git://github.com/aspnet/mvc" }, "dependencies": { - "Newtonsoft.Json": "8.0.2" + "Newtonsoft.Json": "8.0.3" }, "frameworks": { "netstandard1.1": { From 10c33445dcc7b0f2d45df8fdc803751d762c7e2e Mon Sep 17 00:00:00 2001 From: Cesar Blum Silveira Date: Mon, 14 Mar 2016 21:37:36 -0700 Subject: [PATCH 048/221] ASP.NET 5 -> ASP.NET Core --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index c30d38e62f..6c27b76d9d 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,6 @@ AppVeyor: [![AppVeyor](https://ci.appveyor.com/api/projects/status/51gggjks5k3q6 Travis: [![Travis](https://travis-ci.org/aspnet/JsonPatch.svg?branch=dev)](https://travis-ci.org/aspnet/JsonPatch) -This project is part of ASP.NET 5. You can find samples, documentation and getting started instructions for ASP.NET 5 at the [Home](https://github.com/aspnet/home) repo. +This project is part of ASP.NET Core. You can find samples, documentation and getting started instructions for ASP.NET Core at the [Home](https://github.com/aspnet/home) repo. From 4e396b8443bfc0c73651d25e17791fd0296097c9 Mon Sep 17 00:00:00 2001 From: Victor Hurdugaci Date: Thu, 17 Mar 2016 14:27:21 -0700 Subject: [PATCH 049/221] Remove the makefile --- makefile.shade | 12 ------------ 1 file changed, 12 deletions(-) delete mode 100644 makefile.shade diff --git a/makefile.shade b/makefile.shade deleted file mode 100644 index c87524a3ef..0000000000 --- a/makefile.shade +++ /dev/null @@ -1,12 +0,0 @@ - -var VERSION='0.1' -var FULL_VERSION='0.1' -var AUTHORS='Microsoft Open Technologies, Inc.' - -use-standard-lifecycle -k-standard-goals - -#xml-docs-test .clean .build-compile description='Check generated XML documentation files for errors' target='package' - k-xml-docs-test - - From 8965b63ec107fff486b46a03b4de4274be2f83dc Mon Sep 17 00:00:00 2001 From: David Fowler Date: Fri, 25 Mar 2016 02:02:41 -0700 Subject: [PATCH 050/221] Fixed build --- test/Microsoft.AspNetCore.JsonPatch.Test/project.json | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/project.json b/test/Microsoft.AspNetCore.JsonPatch.Test/project.json index c8772f21fb..72fdfa43b4 100644 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/project.json +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/project.json @@ -5,15 +5,16 @@ "dependencies": { "Microsoft.AspNetCore.JsonPatch": "1.0.0-*", "Microsoft.AspNetCore.Testing": "1.0.0-*", - "xunit": "2.1.0", - "Microsoft.NETCore.Platforms": "1.0.1-*" + "xunit": "2.1.0" }, "testRunner": "xunit", "frameworks": { "netstandardapp1.5": { "dependencies": { "moq.netcore": "4.4.0-beta8", - "dotnet-test-xunit": "1.0.0-dev-*" + "dotnet-test-xunit": "1.0.0-dev-*", + "NETStandard.Library": "1.5.0-*", + "System.Diagnostics.Process": "4.1.0-*" }, "imports": [ "dnxcore50", From 98e2d5d4c729770e5e8e146602ab2b6c5bdc439a Mon Sep 17 00:00:00 2001 From: Pranav K Date: Thu, 24 Mar 2016 12:59:08 -0700 Subject: [PATCH 051/221] Fix dotnet restore warning --- test/Microsoft.AspNetCore.JsonPatch.Test/project.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/project.json b/test/Microsoft.AspNetCore.JsonPatch.Test/project.json index 72fdfa43b4..4dcf2002cf 100644 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/project.json +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/project.json @@ -23,12 +23,12 @@ }, "net451": { "frameworkAssemblies": { - "System.Linq.Expressions": {"type": "build"}, + "System.Linq.Expressions": { "type": "build" }, + "System.Runtime": { "type": "build" }, "System.Threading.Tasks": { "type": "build" } }, "dependencies": { "Moq": "4.2.1312.1622", - "System.Runtime": "4.1.0-*", "xunit.runner.console": "2.1.0" } } From 7eb34ad25775f0c5d0c4f1055954d2429ad7ef57 Mon Sep 17 00:00:00 2001 From: David Fowler Date: Thu, 31 Mar 2016 12:08:59 -0700 Subject: [PATCH 052/221] Update project.json Fixed System.Runtime.Serialization.Primitives version --- src/Microsoft.AspNetCore.JsonPatch/project.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Microsoft.AspNetCore.JsonPatch/project.json b/src/Microsoft.AspNetCore.JsonPatch/project.json index f4cc9ede98..9749ef91a1 100644 --- a/src/Microsoft.AspNetCore.JsonPatch/project.json +++ b/src/Microsoft.AspNetCore.JsonPatch/project.json @@ -27,7 +27,7 @@ "System.Reflection.Extensions": "4.0.1-*", "System.Resources.ResourceManager": "4.0.1-*", "System.Runtime.Extensions": "4.1.0-*", - "System.Runtime.Serialization.Primitives": "4.1.0-*", + "System.Runtime.Serialization.Primitives": "4.1.1-*", "System.Text.Encoding.Extensions": "4.0.11-*" }, "imports": [ @@ -36,4 +36,4 @@ ] } } -} \ No newline at end of file +} From 1de783c26bf158d0005a1328c265961f5efcdeb9 Mon Sep 17 00:00:00 2001 From: Pranav K Date: Wed, 6 Apr 2016 09:45:27 -0700 Subject: [PATCH 053/221] Updating to release. --- NuGet.config | 4 ++-- build.ps1 | 2 +- build.sh | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/NuGet.config b/NuGet.config index 5500f6d507..71b9724a09 100644 --- a/NuGet.config +++ b/NuGet.config @@ -1,7 +1,7 @@ - + - + diff --git a/build.ps1 b/build.ps1 index 8f2f99691a..cf8bff13bb 100644 --- a/build.ps1 +++ b/build.ps1 @@ -33,7 +33,7 @@ cd $PSScriptRoot $repoFolder = $PSScriptRoot $env:REPO_FOLDER = $repoFolder -$koreBuildZip="https://github.com/aspnet/KoreBuild/archive/dev.zip" +$koreBuildZip="https://github.com/aspnet/KoreBuild/archive/release.zip" if ($env:KOREBUILD_ZIP) { $koreBuildZip=$env:KOREBUILD_ZIP diff --git a/build.sh b/build.sh index f4208100eb..f88fe4052e 100755 --- a/build.sh +++ b/build.sh @@ -2,7 +2,7 @@ repoFolder="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" cd $repoFolder -koreBuildZip="https://github.com/aspnet/KoreBuild/archive/dev.zip" +koreBuildZip="https://github.com/aspnet/KoreBuild/archive/release.zip" if [ ! -z $KOREBUILD_ZIP ]; then koreBuildZip=$KOREBUILD_ZIP fi From aeb3939ac8418b072db5a8472f876315b5e975c9 Mon Sep 17 00:00:00 2001 From: Pranav K Date: Thu, 7 Apr 2016 15:17:00 -0700 Subject: [PATCH 054/221] Removing imports from src projects --- src/Microsoft.AspNetCore.JsonPatch/project.json | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Microsoft.AspNetCore.JsonPatch/project.json b/src/Microsoft.AspNetCore.JsonPatch/project.json index 9749ef91a1..1d736bfde3 100644 --- a/src/Microsoft.AspNetCore.JsonPatch/project.json +++ b/src/Microsoft.AspNetCore.JsonPatch/project.json @@ -31,9 +31,8 @@ "System.Text.Encoding.Extensions": "4.0.11-*" }, "imports": [ - "dotnet5.2", "portable-net451+win8" ] } } -} +} \ No newline at end of file From 78d3428eb7494f7f8e53fc15b5ca8e84a892ed55 Mon Sep 17 00:00:00 2001 From: Eilon Lipton Date: Tue, 12 Apr 2016 19:06:55 -0700 Subject: [PATCH 055/221] Fix package metadata --- src/Microsoft.AspNetCore.JsonPatch/project.json | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/Microsoft.AspNetCore.JsonPatch/project.json b/src/Microsoft.AspNetCore.JsonPatch/project.json index 1d736bfde3..0eeb88f010 100644 --- a/src/Microsoft.AspNetCore.JsonPatch/project.json +++ b/src/Microsoft.AspNetCore.JsonPatch/project.json @@ -1,5 +1,11 @@ { "version": "1.0.0-*", + "description": "ASP.NET Core support for JSON PATCH.", + "tags": [ + "aspnetcore", + "json", + "jsonpatch" + ], "compilationOptions": { "warningsAsErrors": true, "keyFile": "../../tools/Key.snk", @@ -10,7 +16,7 @@ }, "repository": { "type": "git", - "url": "git://github.com/aspnet/mvc" + "url": "git://github.com/aspnet/jsonpatch" }, "dependencies": { "Newtonsoft.Json": "8.0.3" From 9337f3e48e1d609b3d88e129a5676ec3185b2cb2 Mon Sep 17 00:00:00 2001 From: Pavel Krymets Date: Mon, 18 Apr 2016 16:28:14 -0700 Subject: [PATCH 056/221] Migrate tests, tools and samples to portable --- .../project.json | 23 ++++++++++++++----- 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/project.json b/test/Microsoft.AspNetCore.JsonPatch.Test/project.json index 4dcf2002cf..9455e29da1 100644 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/project.json +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/project.json @@ -3,18 +3,23 @@ "warningsAsErrors": true }, "dependencies": { + "Microsoft.NETCore.Platforms": "1.0.1-*", "Microsoft.AspNetCore.JsonPatch": "1.0.0-*", "Microsoft.AspNetCore.Testing": "1.0.0-*", "xunit": "2.1.0" }, "testRunner": "xunit", "frameworks": { - "netstandardapp1.5": { + "netcoreapp1.0": { "dependencies": { + "Microsoft.NETCore.App": { + "version": "1.0.0-*", + "type": "platform" + }, "moq.netcore": "4.4.0-beta8", "dotnet-test-xunit": "1.0.0-dev-*", - "NETStandard.Library": "1.5.0-*", - "System.Diagnostics.Process": "4.1.0-*" + "System.Diagnostics.Process": "4.1.0-*", + "System.Diagnostics.TraceSource": "4.0.0-*" }, "imports": [ "dnxcore50", @@ -23,9 +28,15 @@ }, "net451": { "frameworkAssemblies": { - "System.Linq.Expressions": { "type": "build" }, - "System.Runtime": { "type": "build" }, - "System.Threading.Tasks": { "type": "build" } + "System.Linq.Expressions": { + "type": "build" + }, + "System.Runtime": { + "type": "build" + }, + "System.Threading.Tasks": { + "type": "build" + } }, "dependencies": { "Moq": "4.2.1312.1622", From 088d8b291ac4beaddebd6ec0a97747ef3dc7ba12 Mon Sep 17 00:00:00 2001 From: Pranav K Date: Tue, 19 Apr 2016 14:54:04 -0700 Subject: [PATCH 057/221] Use latest build of dotnet-test-xunit --- test/Microsoft.AspNetCore.JsonPatch.Test/project.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/project.json b/test/Microsoft.AspNetCore.JsonPatch.Test/project.json index 9455e29da1..8dfb164801 100644 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/project.json +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/project.json @@ -17,7 +17,7 @@ "type": "platform" }, "moq.netcore": "4.4.0-beta8", - "dotnet-test-xunit": "1.0.0-dev-*", + "dotnet-test-xunit": "1.0.0-*", "System.Diagnostics.Process": "4.1.0-*", "System.Diagnostics.TraceSource": "4.0.0-*" }, From 2cd905dd44caff74332a8dc85b7fbcd253f79387 Mon Sep 17 00:00:00 2001 From: Pranav K Date: Mon, 2 May 2016 11:27:18 -0700 Subject: [PATCH 058/221] Fix build warnings --- .../project.json | 20 ++++++++++--------- .../project.json | 4 ++-- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/src/Microsoft.AspNetCore.JsonPatch/project.json b/src/Microsoft.AspNetCore.JsonPatch/project.json index 0eeb88f010..1860893f6b 100644 --- a/src/Microsoft.AspNetCore.JsonPatch/project.json +++ b/src/Microsoft.AspNetCore.JsonPatch/project.json @@ -1,12 +1,7 @@ { "version": "1.0.0-*", "description": "ASP.NET Core support for JSON PATCH.", - "tags": [ - "aspnetcore", - "json", - "jsonpatch" - ], - "compilationOptions": { + "buildOptions": { "warningsAsErrors": true, "keyFile": "../../tools/Key.snk", "nowarn": [ @@ -14,9 +9,16 @@ ], "xmlDoc": true }, - "repository": { - "type": "git", - "url": "git://github.com/aspnet/jsonpatch" + "packOptions": { + "repository": { + "type": "git", + "url": "git://github.com/aspnet/jsonpatch" + }, + "tags": [ + "aspnetcore", + "json", + "jsonpatch" + ] }, "dependencies": { "Newtonsoft.Json": "8.0.3" diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/project.json b/test/Microsoft.AspNetCore.JsonPatch.Test/project.json index 8dfb164801..dac020cb6c 100644 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/project.json +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/project.json @@ -1,8 +1,9 @@ { - "compilationOptions": { + "buildOptions": { "warningsAsErrors": true }, "dependencies": { + "dotnet-test-xunit": "1.0.0-*", "Microsoft.NETCore.Platforms": "1.0.1-*", "Microsoft.AspNetCore.JsonPatch": "1.0.0-*", "Microsoft.AspNetCore.Testing": "1.0.0-*", @@ -17,7 +18,6 @@ "type": "platform" }, "moq.netcore": "4.4.0-beta8", - "dotnet-test-xunit": "1.0.0-*", "System.Diagnostics.Process": "4.1.0-*", "System.Diagnostics.TraceSource": "4.0.0-*" }, From ca1e53bb34ace9802dd20df8e555d1ce4b1a29d7 Mon Sep 17 00:00:00 2001 From: Ryan Brandenburg Date: Tue, 17 May 2016 12:28:18 -0700 Subject: [PATCH 059/221] Update minor version of TypeConverter (#22) --- src/Microsoft.AspNetCore.JsonPatch/project.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Microsoft.AspNetCore.JsonPatch/project.json b/src/Microsoft.AspNetCore.JsonPatch/project.json index 1860893f6b..d01e21cbb9 100644 --- a/src/Microsoft.AspNetCore.JsonPatch/project.json +++ b/src/Microsoft.AspNetCore.JsonPatch/project.json @@ -28,7 +28,7 @@ "dependencies": { "Microsoft.CSharp": "4.0.1-*", "System.Collections.Concurrent": "4.0.12-*", - "System.ComponentModel.TypeConverter": "4.0.1-*", + "System.ComponentModel.TypeConverter": "4.1.0-*", "System.Diagnostics.Debug": "4.0.11-*", "System.Globalization": "4.0.11-*", "System.Linq": "4.1.0-*", From 47ee8e0cfaa002cce1c57d3f22b40eed9ffd5cb7 Mon Sep 17 00:00:00 2001 From: Pranav K Date: Wed, 18 May 2016 09:44:47 -0700 Subject: [PATCH 060/221] Revert "Update minor version of TypeConverter (#22)" This reverts commit ca1e53bb34ace9802dd20df8e555d1ce4b1a29d7. --- src/Microsoft.AspNetCore.JsonPatch/project.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Microsoft.AspNetCore.JsonPatch/project.json b/src/Microsoft.AspNetCore.JsonPatch/project.json index d01e21cbb9..1860893f6b 100644 --- a/src/Microsoft.AspNetCore.JsonPatch/project.json +++ b/src/Microsoft.AspNetCore.JsonPatch/project.json @@ -28,7 +28,7 @@ "dependencies": { "Microsoft.CSharp": "4.0.1-*", "System.Collections.Concurrent": "4.0.12-*", - "System.ComponentModel.TypeConverter": "4.1.0-*", + "System.ComponentModel.TypeConverter": "4.0.1-*", "System.Diagnostics.Debug": "4.0.11-*", "System.Globalization": "4.0.11-*", "System.Linq": "4.1.0-*", From a2e3bdf408938bd670ab988c0aad6a08565915d4 Mon Sep 17 00:00:00 2001 From: John Luo Date: Thu, 26 May 2016 18:29:26 -0700 Subject: [PATCH 061/221] React to updated CoreCLR packages https://github.com/aspnet/Coherence/issues/97 --- src/Microsoft.AspNetCore.JsonPatch/project.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Microsoft.AspNetCore.JsonPatch/project.json b/src/Microsoft.AspNetCore.JsonPatch/project.json index 1860893f6b..d01e21cbb9 100644 --- a/src/Microsoft.AspNetCore.JsonPatch/project.json +++ b/src/Microsoft.AspNetCore.JsonPatch/project.json @@ -28,7 +28,7 @@ "dependencies": { "Microsoft.CSharp": "4.0.1-*", "System.Collections.Concurrent": "4.0.12-*", - "System.ComponentModel.TypeConverter": "4.0.1-*", + "System.ComponentModel.TypeConverter": "4.1.0-*", "System.Diagnostics.Debug": "4.0.11-*", "System.Globalization": "4.0.11-*", "System.Linq": "4.1.0-*", From 8bd631170328b5bfcbf7b8503487a05ba0b886b7 Mon Sep 17 00:00:00 2001 From: Cesar Blum Silveira Date: Fri, 27 May 2016 11:32:14 -0700 Subject: [PATCH 062/221] Fix OSX build on Travis. --- .travis.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.travis.yml b/.travis.yml index 304e307169..bb366b178f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -22,5 +22,7 @@ branches: - release - dev - /^(.*\/)?ci-.*$/ +before_install: + - if test "$TRAVIS_OS_NAME" == "osx"; then brew update; brew install openssl; brew link --force openssl; fi script: - ./build.sh --quiet verify \ No newline at end of file From 0f1836c6dd418bbab40520c25ab6a27002691d1b Mon Sep 17 00:00:00 2001 From: jacalvar Date: Fri, 3 Jun 2016 13:08:19 -0700 Subject: [PATCH 063/221] Update Json.NET to 9.0.1-beta1 --- src/Microsoft.AspNetCore.JsonPatch/project.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Microsoft.AspNetCore.JsonPatch/project.json b/src/Microsoft.AspNetCore.JsonPatch/project.json index d01e21cbb9..78a4fe8fb2 100644 --- a/src/Microsoft.AspNetCore.JsonPatch/project.json +++ b/src/Microsoft.AspNetCore.JsonPatch/project.json @@ -21,7 +21,7 @@ ] }, "dependencies": { - "Newtonsoft.Json": "8.0.3" + "Newtonsoft.Json": "9.0.1-beta1" }, "frameworks": { "netstandard1.1": { From 4d77dce803855d31c6405bdc81403fbf8ada6e3e Mon Sep 17 00:00:00 2001 From: jacalvar Date: Tue, 7 Jun 2016 22:08:02 -0700 Subject: [PATCH 064/221] Remove unncessary imports --- src/Microsoft.AspNetCore.JsonPatch/project.json | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/Microsoft.AspNetCore.JsonPatch/project.json b/src/Microsoft.AspNetCore.JsonPatch/project.json index 78a4fe8fb2..6395f3ecf1 100644 --- a/src/Microsoft.AspNetCore.JsonPatch/project.json +++ b/src/Microsoft.AspNetCore.JsonPatch/project.json @@ -37,10 +37,7 @@ "System.Runtime.Extensions": "4.1.0-*", "System.Runtime.Serialization.Primitives": "4.1.1-*", "System.Text.Encoding.Extensions": "4.0.11-*" - }, - "imports": [ - "portable-net451+win8" - ] + } } } } \ No newline at end of file From af8e9fb4434c0f24f35ea4a15d82b0995d8569c5 Mon Sep 17 00:00:00 2001 From: "N. Taylor Mullen" Date: Mon, 13 Jun 2016 15:27:34 -0700 Subject: [PATCH 065/221] Remove direct Microsoft.NETCore.Platforms dependency. - Microsoft.NETCore.App now pulls this package in. aspnet/Coherence-Signed#344 --- test/Microsoft.AspNetCore.JsonPatch.Test/project.json | 1 - 1 file changed, 1 deletion(-) diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/project.json b/test/Microsoft.AspNetCore.JsonPatch.Test/project.json index dac020cb6c..dc9abdb71c 100644 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/project.json +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/project.json @@ -4,7 +4,6 @@ }, "dependencies": { "dotnet-test-xunit": "1.0.0-*", - "Microsoft.NETCore.Platforms": "1.0.1-*", "Microsoft.AspNetCore.JsonPatch": "1.0.0-*", "Microsoft.AspNetCore.Testing": "1.0.0-*", "xunit": "2.1.0" From 288810c95ce6f6d2589f4cbbd016e12d48a8e4c3 Mon Sep 17 00:00:00 2001 From: Pranav K Date: Tue, 14 Jun 2016 16:21:56 -0700 Subject: [PATCH 066/221] Updating to release. --- NuGet.config | 4 ++-- build.ps1 | 2 +- build.sh | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/NuGet.config b/NuGet.config index 5500f6d507..71b9724a09 100644 --- a/NuGet.config +++ b/NuGet.config @@ -1,7 +1,7 @@ - + - + diff --git a/build.ps1 b/build.ps1 index 8f2f99691a..cf8bff13bb 100644 --- a/build.ps1 +++ b/build.ps1 @@ -33,7 +33,7 @@ cd $PSScriptRoot $repoFolder = $PSScriptRoot $env:REPO_FOLDER = $repoFolder -$koreBuildZip="https://github.com/aspnet/KoreBuild/archive/dev.zip" +$koreBuildZip="https://github.com/aspnet/KoreBuild/archive/release.zip" if ($env:KOREBUILD_ZIP) { $koreBuildZip=$env:KOREBUILD_ZIP diff --git a/build.sh b/build.sh index f4208100eb..f88fe4052e 100755 --- a/build.sh +++ b/build.sh @@ -2,7 +2,7 @@ repoFolder="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" cd $repoFolder -koreBuildZip="https://github.com/aspnet/KoreBuild/archive/dev.zip" +koreBuildZip="https://github.com/aspnet/KoreBuild/archive/release.zip" if [ ! -z $KOREBUILD_ZIP ]; then koreBuildZip=$KOREBUILD_ZIP fi From d7d8af57f6a890360d77e65a68fc54b7cd45d0f6 Mon Sep 17 00:00:00 2001 From: jacalvar Date: Mon, 13 Jun 2016 14:24:30 -0700 Subject: [PATCH 067/221] Update Json.NET to 9.0.1 --- src/Microsoft.AspNetCore.JsonPatch/project.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Microsoft.AspNetCore.JsonPatch/project.json b/src/Microsoft.AspNetCore.JsonPatch/project.json index 6395f3ecf1..ac582cbac3 100644 --- a/src/Microsoft.AspNetCore.JsonPatch/project.json +++ b/src/Microsoft.AspNetCore.JsonPatch/project.json @@ -21,7 +21,7 @@ ] }, "dependencies": { - "Newtonsoft.Json": "9.0.1-beta1" + "Newtonsoft.Json": "9.0.1" }, "frameworks": { "netstandard1.1": { From 36e5c0e6fae4d9f547904509b5044678ad559430 Mon Sep 17 00:00:00 2001 From: Pranav K Date: Thu, 16 Jun 2016 10:18:06 -0700 Subject: [PATCH 068/221] Updating to dev versions --- src/Microsoft.AspNetCore.JsonPatch/project.json | 2 +- test/Microsoft.AspNetCore.JsonPatch.Test/project.json | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Microsoft.AspNetCore.JsonPatch/project.json b/src/Microsoft.AspNetCore.JsonPatch/project.json index ac582cbac3..44daeef0e9 100644 --- a/src/Microsoft.AspNetCore.JsonPatch/project.json +++ b/src/Microsoft.AspNetCore.JsonPatch/project.json @@ -1,5 +1,5 @@ { - "version": "1.0.0-*", + "version": "1.1.0-*", "description": "ASP.NET Core support for JSON PATCH.", "buildOptions": { "warningsAsErrors": true, diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/project.json b/test/Microsoft.AspNetCore.JsonPatch.Test/project.json index dc9abdb71c..4bd3e6450b 100644 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/project.json +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/project.json @@ -4,8 +4,8 @@ }, "dependencies": { "dotnet-test-xunit": "1.0.0-*", - "Microsoft.AspNetCore.JsonPatch": "1.0.0-*", - "Microsoft.AspNetCore.Testing": "1.0.0-*", + "Microsoft.AspNetCore.JsonPatch": "1.1.0-*", + "Microsoft.AspNetCore.Testing": "1.1.0-*", "xunit": "2.1.0" }, "testRunner": "xunit", From 24439bc400ab5c67e9480dfc56ed9d8f361a5f4c Mon Sep 17 00:00:00 2001 From: Pranav K Date: Thu, 30 Jun 2016 15:36:11 -0700 Subject: [PATCH 069/221] Updating to RTM builds of xunit and Moq --- .gitignore | 13 ++++++++--- .../project.json | 22 ++++--------------- 2 files changed, 14 insertions(+), 21 deletions(-) diff --git a/.gitignore b/.gitignore index 2e4b2d6b5d..06cfaa0cbe 100644 --- a/.gitignore +++ b/.gitignore @@ -8,15 +8,18 @@ TestResults/ _ReSharper.*/ packages/ artifacts/ -.build/ PublishProfiles/ +.vs/ +bower_components/ +node_modules/ +debugSettings.json +project.lock.json *.user *.suo *.cache *.docstates _ReSharper.* nuget.exe -project.lock.json *net45.csproj *net451.csproj *k10.csproj @@ -28,4 +31,8 @@ project.lock.json *.ncrunchsolution *.*sdf *.ipch -.build/ \ No newline at end of file +.settings +*.sln.ide +node_modules +*launchSettings.json +*.orig \ No newline at end of file diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/project.json b/test/Microsoft.AspNetCore.JsonPatch.Test/project.json index 4bd3e6450b..d6f8f5cbc6 100644 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/project.json +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/project.json @@ -3,10 +3,11 @@ "warningsAsErrors": true }, "dependencies": { - "dotnet-test-xunit": "1.0.0-*", + "dotnet-test-xunit": "2.2.0-*", "Microsoft.AspNetCore.JsonPatch": "1.1.0-*", "Microsoft.AspNetCore.Testing": "1.1.0-*", - "xunit": "2.1.0" + "Moq": "4.6.25-*", + "xunit": "2.2.0-*" }, "testRunner": "xunit", "frameworks": { @@ -16,30 +17,15 @@ "version": "1.0.0-*", "type": "platform" }, - "moq.netcore": "4.4.0-beta8", - "System.Diagnostics.Process": "4.1.0-*", "System.Diagnostics.TraceSource": "4.0.0-*" }, - "imports": [ - "dnxcore50", - "portable-net451+win8" - ] + "imports": "dotnet5.4" }, "net451": { "frameworkAssemblies": { "System.Linq.Expressions": { "type": "build" - }, - "System.Runtime": { - "type": "build" - }, - "System.Threading.Tasks": { - "type": "build" } - }, - "dependencies": { - "Moq": "4.2.1312.1622", - "xunit.runner.console": "2.1.0" } } } From 6b08efb12271fd6c81ab60e1c509032cf5ed5e39 Mon Sep 17 00:00:00 2001 From: Doug Bunting Date: Thu, 7 Jul 2016 12:06:18 -0700 Subject: [PATCH 070/221] One build to rule them all - well, at least VS and command-line builds will share output - part of aspnet/Coherence-Signed#277 --- .../Microsoft.AspNetCore.JsonPatch.xproj | 4 ++-- .../Microsoft.AspNetCore.JsonPatch.Test.xproj | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Microsoft.AspNetCore.JsonPatch/Microsoft.AspNetCore.JsonPatch.xproj b/src/Microsoft.AspNetCore.JsonPatch/Microsoft.AspNetCore.JsonPatch.xproj index d11d600744..0ebf789691 100644 --- a/src/Microsoft.AspNetCore.JsonPatch/Microsoft.AspNetCore.JsonPatch.xproj +++ b/src/Microsoft.AspNetCore.JsonPatch/Microsoft.AspNetCore.JsonPatch.xproj @@ -7,8 +7,8 @@ 4d55f4d8-633b-462f-a5b1-feb84bd2d534 - ..\..\artifacts\obj\$(MSBuildProjectName) - ..\..\artifacts\bin\ + .\obj + .\bin\ 2.0 diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/Microsoft.AspNetCore.JsonPatch.Test.xproj b/test/Microsoft.AspNetCore.JsonPatch.Test/Microsoft.AspNetCore.JsonPatch.Test.xproj index 0b71c5d301..c8942c121e 100644 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/Microsoft.AspNetCore.JsonPatch.Test.xproj +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/Microsoft.AspNetCore.JsonPatch.Test.xproj @@ -7,8 +7,8 @@ 81c20848-e063-4e12-ac40-0b55a532c16c - ..\..\artifacts\obj\$(MSBuildProjectName) - ..\..\artifacts\bin\ + .\obj + .\bin\ 2.0 From c7035517724bc5b0fbdc8cd1b67656f90a953f0a Mon Sep 17 00:00:00 2001 From: BrennanConroy Date: Tue, 2 Aug 2016 13:14:37 -0700 Subject: [PATCH 071/221] Update .travis.yml --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index bb366b178f..631adcf570 100644 --- a/.travis.yml +++ b/.travis.yml @@ -23,6 +23,6 @@ branches: - dev - /^(.*\/)?ci-.*$/ before_install: - - if test "$TRAVIS_OS_NAME" == "osx"; then brew update; brew install openssl; brew link --force openssl; fi + - if test "$TRAVIS_OS_NAME" == "osx"; then brew update; brew install openssl; ln -s /usr/local/opt/openssl/lib/libcrypto.1.0.0.dylib /usr/local/lib/; ln -s /usr/local/opt/openssl/lib/libssl.1.0.0.dylib /usr/local/lib/; fi script: - - ./build.sh --quiet verify \ No newline at end of file + - ./build.sh --quiet verify From e991ebaa4fd6b0011d7492f0e30520f657d02119 Mon Sep 17 00:00:00 2001 From: Pranav K Date: Mon, 8 Aug 2016 14:29:46 -0700 Subject: [PATCH 072/221] Updating to Moq \ Castle.Core that does not require imports --- test/Microsoft.AspNetCore.JsonPatch.Test/project.json | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/project.json b/test/Microsoft.AspNetCore.JsonPatch.Test/project.json index d6f8f5cbc6..acc8390c6d 100644 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/project.json +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/project.json @@ -6,7 +6,7 @@ "dotnet-test-xunit": "2.2.0-*", "Microsoft.AspNetCore.JsonPatch": "1.1.0-*", "Microsoft.AspNetCore.Testing": "1.1.0-*", - "Moq": "4.6.25-*", + "Moq": "4.6.36-*", "xunit": "2.2.0-*" }, "testRunner": "xunit", @@ -18,8 +18,7 @@ "type": "platform" }, "System.Diagnostics.TraceSource": "4.0.0-*" - }, - "imports": "dotnet5.4" + } }, "net451": { "frameworkAssemblies": { From 2e53d0e55be8fde8f7bf112dd2d814eea8f490a8 Mon Sep 17 00:00:00 2001 From: Pranav K Date: Tue, 9 Aug 2016 15:04:20 -0700 Subject: [PATCH 073/221] Switching to dotnet.myget.org feed --- NuGet.config | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NuGet.config b/NuGet.config index 5500f6d507..0fd623ffdd 100644 --- a/NuGet.config +++ b/NuGet.config @@ -1,7 +1,7 @@  - + From e72d4b4876ca0599aa1afc685e8d50b50ed6d71b Mon Sep 17 00:00:00 2001 From: Doug Bunting Date: Sun, 4 Sep 2016 15:46:35 -0700 Subject: [PATCH 074/221] Increase .travis.yml consistency between repos - aspnet/Universe#349 - minimize `dotnet` setup time; no need for caching --- .travis.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.travis.yml b/.travis.yml index 631adcf570..d7636fa329 100644 --- a/.travis.yml +++ b/.travis.yml @@ -10,6 +10,10 @@ addons: - libssl-dev - libunwind8 - zlib1g +env: + global: + - DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true + - DOTNET_CLI_TELEMETRY_OPTOUT: 1 mono: - 4.0.5 os: From c88aa0042a8ae3457bb6731fcbbc6721d4b8c335 Mon Sep 17 00:00:00 2001 From: Kevin Dockx Date: Wed, 28 Sep 2016 18:37:21 +0200 Subject: [PATCH 075/221] Fix for issue #29 (Honor JsonProperty when serializing a JsonPatchDocument) (#35) * Fix for issue #29 (Honor JsonProperty when serializing a JsonPatchDocument) --- .../Helpers/ExpressionHelpers.cs | 26 ++- ...nPatchDocumentJsonPropertyAttributeTest.cs | 148 ++++++++++++++++++ .../JsonPropertyDTO.cs | 13 ++ .../JsonPropertyWithAnotherNameDTO.cs | 10 ++ .../JsonPropertyWithInheritanceDTO.cs | 19 +++ 5 files changed, 214 insertions(+), 2 deletions(-) create mode 100644 test/Microsoft.AspNetCore.JsonPatch.Test/JsonPatchDocumentJsonPropertyAttributeTest.cs create mode 100644 test/Microsoft.AspNetCore.JsonPatch.Test/JsonPropertyDTO.cs create mode 100644 test/Microsoft.AspNetCore.JsonPatch.Test/JsonPropertyWithAnotherNameDTO.cs create mode 100644 test/Microsoft.AspNetCore.JsonPatch.Test/JsonPropertyWithInheritanceDTO.cs diff --git a/src/Microsoft.AspNetCore.JsonPatch/Helpers/ExpressionHelpers.cs b/src/Microsoft.AspNetCore.JsonPatch/Helpers/ExpressionHelpers.cs index 92880eb0e1..d9b516cc0e 100644 --- a/src/Microsoft.AspNetCore.JsonPatch/Helpers/ExpressionHelpers.cs +++ b/src/Microsoft.AspNetCore.JsonPatch/Helpers/ExpressionHelpers.cs @@ -1,9 +1,12 @@ // 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 Newtonsoft.Json; using System; using System.Globalization; +using System.Linq; using System.Linq.Expressions; +using System.Reflection; namespace Microsoft.AspNetCore.JsonPatch.Helpers { @@ -51,11 +54,13 @@ namespace Microsoft.AspNetCore.JsonPatch.Helpers if (ContinueWithSubPath(memberExpression.Expression.NodeType, false)) { var left = GetPath(memberExpression.Expression, false); - return left + "/" + memberExpression.Member.Name; + // Get property name, respecting JsonProperty attribute + return left + "/" + GetPropertyNameFromMemberExpression(memberExpression); } else { - return memberExpression.Member.Name; + // Get property name, respecting JsonProperty attribute + return GetPropertyNameFromMemberExpression(memberExpression); } case ExpressionType.Parameter: // Fits "x => x" (the whole document which is "" as JSON pointer) @@ -65,6 +70,23 @@ namespace Microsoft.AspNetCore.JsonPatch.Helpers } } + private static string GetPropertyNameFromMemberExpression(MemberExpression memberExpression) + { + // if there's a JsonProperty attribute, we must return the PropertyName + // from the attribute rather than the member name + var jsonPropertyAttribute = + memberExpression.Member.GetCustomAttribute( + typeof(JsonPropertyAttribute), true); + + if (jsonPropertyAttribute == null) + { + return memberExpression.Member.Name; + } + // get value + var castedAttribute = (JsonPropertyAttribute)jsonPropertyAttribute; + return castedAttribute.PropertyName; + } + private static bool ContinueWithSubPath(ExpressionType expressionType, bool firstTime) { if (firstTime) diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/JsonPatchDocumentJsonPropertyAttributeTest.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/JsonPatchDocumentJsonPropertyAttributeTest.cs new file mode 100644 index 0000000000..ef7d53c21a --- /dev/null +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/JsonPatchDocumentJsonPropertyAttributeTest.cs @@ -0,0 +1,148 @@ +// 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 Newtonsoft.Json; +using System.Linq; +using Xunit; + +namespace Microsoft.AspNetCore.JsonPatch +{ + public class JsonPatchDocumentJsonPropertyAttributeTest + { + [Fact] + public void Add_WithExpression_RespectsJsonPropertyName_ForModelProperty() + { + var patchDoc = new JsonPatchDocument(); + patchDoc.Add(p => p.Name, "John"); + + var serialized = JsonConvert.SerializeObject(patchDoc); + // serialized value should have "AnotherName" as path + // deserialize to a JsonPatchDocument to check + var deserialized = + JsonConvert.DeserializeObject>(serialized); + + // get path + var pathToCheck = deserialized.Operations.First().path; + Assert.Equal(pathToCheck, "/anothername"); + } + + [Fact] + public void Add_WithExpression_RespectsJsonPropertyName_WhenApplyingToDifferentlyTypedClassWithPropertyMatchingJsonPropertyName() + { + var patchDocToSerialize = new JsonPatchDocument(); + patchDocToSerialize.Add(p => p.Name, "John"); + + // the patchdoc will deserialize to "anothername". We should thus be able to apply + // it to a class that HAS that other property name. + var doc = new JsonPropertyWithAnotherNameDTO() + { + AnotherName = "InitialValue" + }; + + var serialized = JsonConvert.SerializeObject(patchDocToSerialize); + var deserialized = + JsonConvert.DeserializeObject> + (serialized); + + deserialized.ApplyTo(doc); + + Assert.Equal(doc.AnotherName, "John"); + } + + [Fact] + public void Add_WithExpression_RespectsJsonPropertyName_WhenApplyingToSameTypedClassWithMatchingJsonPropertyName() + { + var patchDocToSerialize = new JsonPatchDocument(); + patchDocToSerialize.Add(p => p.Name, "John"); + + // the patchdoc will deserialize to "anothername". As JsonPropertyDTO has + // a JsonProperty signifying that "Name" should be deseriallized from "AnotherName", + // we should be able to apply the patchDoc. + + var doc = new JsonPropertyDTO() + { + Name = "InitialValue" + }; + + var serialized = JsonConvert.SerializeObject(patchDocToSerialize); + var deserialized = + JsonConvert.DeserializeObject> + (serialized); + + deserialized.ApplyTo(doc); + + Assert.Equal(doc.Name, "John"); + } + + [Fact] + public void Add_OnApplyFromJson_RespectsJsonPropertyNameOnJsonDocument() + { + var doc = new JsonPropertyDTO() + { + Name = "InitialValue" + }; + + // serialization should serialize to "AnotherName" + var serialized = "[{\"value\":\"Kevin\",\"path\":\"/AnotherName\",\"op\":\"add\"}]"; + var deserialized = + JsonConvert.DeserializeObject>(serialized); + + deserialized.ApplyTo(doc); + + Assert.Equal("Kevin", doc.Name); + } + + [Fact] + public void Remove_OnApplyFromJson_RespectsJsonPropertyNameOnJsonDocument() + { + var doc = new JsonPropertyDTO() + { + Name = "InitialValue" + }; + + // serialization should serialize to "AnotherName" + var serialized = "[{\"path\":\"/AnotherName\",\"op\":\"remove\"}]"; + var deserialized = + JsonConvert.DeserializeObject>(serialized); + + deserialized.ApplyTo(doc); + + Assert.Equal(null, doc.Name); + } + + [Fact] + public void Add_OnApplyFromJson_RespectsInheritedJsonPropertyNameOnJsonDocument() + { + var doc = new JsonPropertyWithInheritanceDTO() + { + Name = "InitialName" + }; + + // serialization should serialize to "AnotherName" + var serialized = "[{\"value\":\"Kevin\",\"path\":\"/AnotherName\",\"op\":\"add\"}]"; + var deserialized = + JsonConvert.DeserializeObject>(serialized); + + deserialized.ApplyTo(doc); + + Assert.Equal("Kevin", doc.Name); + } + + [Fact] + public void Add_WithExpression_RespectsJsonPropertyName_ForInheritedModelProperty() + { + var patchDoc = new JsonPatchDocument(); + patchDoc.Add(p => p.Name, "John"); + + var serialized = JsonConvert.SerializeObject(patchDoc); + // serialized value should have "AnotherName" as path + // deserialize to a JsonPatchDocument to check + var deserialized = + JsonConvert.DeserializeObject>(serialized); + + // get path + var pathToCheck = deserialized.Operations.First().path; + Assert.Equal(pathToCheck, "/anothername"); + } + } +} diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/JsonPropertyDTO.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/JsonPropertyDTO.cs new file mode 100644 index 0000000000..c926d9f5fd --- /dev/null +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/JsonPropertyDTO.cs @@ -0,0 +1,13 @@ +// 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 Newtonsoft.Json; + +namespace Microsoft.AspNetCore.JsonPatch +{ + public class JsonPropertyDTO + { + [JsonProperty("AnotherName")] + public string Name { get; set; } + } +} diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/JsonPropertyWithAnotherNameDTO.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/JsonPropertyWithAnotherNameDTO.cs new file mode 100644 index 0000000000..9b61e09005 --- /dev/null +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/JsonPropertyWithAnotherNameDTO.cs @@ -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 +{ + public class JsonPropertyWithAnotherNameDTO + { + public string AnotherName { get; set; } + } +} diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/JsonPropertyWithInheritanceDTO.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/JsonPropertyWithInheritanceDTO.cs new file mode 100644 index 0000000000..fa69425ea9 --- /dev/null +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/JsonPropertyWithInheritanceDTO.cs @@ -0,0 +1,19 @@ +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; } + } +} From 9e8aee24788a48b0d3277a85cebb3a228be8f9dd Mon Sep 17 00:00:00 2001 From: Pranav K Date: Wed, 28 Sep 2016 11:51:01 -0700 Subject: [PATCH 076/221] Updating partner package versions --- src/Microsoft.AspNetCore.JsonPatch/project.json | 15 ++++----------- .../project.json | 4 ++-- 2 files changed, 6 insertions(+), 13 deletions(-) diff --git a/src/Microsoft.AspNetCore.JsonPatch/project.json b/src/Microsoft.AspNetCore.JsonPatch/project.json index 44daeef0e9..5180ee7e23 100644 --- a/src/Microsoft.AspNetCore.JsonPatch/project.json +++ b/src/Microsoft.AspNetCore.JsonPatch/project.json @@ -21,22 +21,15 @@ ] }, "dependencies": { + "NETStandard.Library": "1.6.1-*", "Newtonsoft.Json": "9.0.1" }, "frameworks": { "netstandard1.1": { "dependencies": { - "Microsoft.CSharp": "4.0.1-*", - "System.Collections.Concurrent": "4.0.12-*", - "System.ComponentModel.TypeConverter": "4.1.0-*", - "System.Diagnostics.Debug": "4.0.11-*", - "System.Globalization": "4.0.11-*", - "System.Linq": "4.1.0-*", - "System.Reflection.Extensions": "4.0.1-*", - "System.Resources.ResourceManager": "4.0.1-*", - "System.Runtime.Extensions": "4.1.0-*", - "System.Runtime.Serialization.Primitives": "4.1.1-*", - "System.Text.Encoding.Extensions": "4.0.11-*" + "Microsoft.CSharp": "4.3.0-*", + "System.ComponentModel.TypeConverter": "4.3.0-*", + "System.Runtime.Serialization.Primitives": "4.3.0-*" } } } diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/project.json b/test/Microsoft.AspNetCore.JsonPatch.Test/project.json index acc8390c6d..9da14bf59e 100644 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/project.json +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/project.json @@ -14,10 +14,10 @@ "netcoreapp1.0": { "dependencies": { "Microsoft.NETCore.App": { - "version": "1.0.0-*", + "version": "1.1.0-*", "type": "platform" }, - "System.Diagnostics.TraceSource": "4.0.0-*" + "System.Diagnostics.TraceSource": "4.3.0-*" } }, "net451": { From 393c25988ae2a57b6be4235ee4848212c3dcd861 Mon Sep 17 00:00:00 2001 From: Kiran Challa Date: Wed, 21 Sep 2016 22:56:55 -0700 Subject: [PATCH 077/221] [Fixes #33] Dictionary operations fail due to contract issues --- .../Adapters/ObjectAdapter.cs | 853 ++---------------- .../Helpers/ActualPropertyPathResult.cs | 22 - .../ExpandoObjectDictionaryExtensions.cs | 77 -- .../Helpers/ObjectTreeAnalyisResult.cs | 209 ----- .../Helpers/RemovedPropertyTypeResult.cs | 38 - .../{Helpers => Internal}/ConversionResult.cs | 10 +- .../Internal/ConversionResultProvider.cs | 24 + .../Internal/DictionaryAdapter.cs | 111 +++ .../Internal/ExpandoObjectAdapter.cs | 143 +++ .../ExpandoObjectDictionaryExtensions.cs | 26 + .../ExpressionHelpers.cs | 11 +- .../Internal/IAdapter.cs | 44 + .../Internal/ListAdapter.cs | 299 ++++++ .../Internal/ObjectVisitor.cs | 76 ++ .../Internal/ParsedPath.cs | 40 + .../{Helpers => Internal}/PathHelpers.cs | 2 +- .../Internal/PocoAdapter.cs | 205 +++++ .../JsonPatchDocument.cs | 10 +- .../JsonPatchDocumentOfT.cs | 10 +- .../Properties/Resources.Designer.cs | 132 +-- .../Resources.resx | 34 +- .../project.json | 12 +- .../DictionaryAdapterTest.cs | 176 ++++ .../Dynamic/AddOperationTests.cs | 43 +- .../Dynamic/AddTypedOperationTests.cs | 6 +- .../Dynamic/RemoveOperationTests.cs | 10 +- .../Dynamic/RemoveTypedOperationTests.cs | 10 +- .../Dynamic/ReplaceOperationTests.cs | 10 +- .../ListAdapterTest.cs | 302 +++++++ .../NestedDTO.cs | 2 +- .../NestedObjectTests.cs | 54 +- .../ObjectAdapterTests.cs | 667 ++++++++++++-- .../ObjectVisitorTest.cs | 230 +++++ .../ObjectVisitorTest.cs~RF1ad82e13.TMP | 119 +++ .../ObjectVisitorTest.cs~RF1ae034c3.TMP | 131 +++ .../SimpleDTO.cs | 2 +- .../SimpleDTOWithNestedDTO.cs | 2 +- .../TestErrorLogger.cs | 2 +- 38 files changed, 2796 insertions(+), 1358 deletions(-) delete mode 100644 src/Microsoft.AspNetCore.JsonPatch/Helpers/ActualPropertyPathResult.cs delete mode 100644 src/Microsoft.AspNetCore.JsonPatch/Helpers/ExpandoObjectDictionaryExtensions.cs delete mode 100644 src/Microsoft.AspNetCore.JsonPatch/Helpers/ObjectTreeAnalyisResult.cs delete mode 100644 src/Microsoft.AspNetCore.JsonPatch/Helpers/RemovedPropertyTypeResult.cs rename src/Microsoft.AspNetCore.JsonPatch/{Helpers => Internal}/ConversionResult.cs (64%) create mode 100644 src/Microsoft.AspNetCore.JsonPatch/Internal/ConversionResultProvider.cs create mode 100644 src/Microsoft.AspNetCore.JsonPatch/Internal/DictionaryAdapter.cs create mode 100644 src/Microsoft.AspNetCore.JsonPatch/Internal/ExpandoObjectAdapter.cs create mode 100644 src/Microsoft.AspNetCore.JsonPatch/Internal/ExpandoObjectDictionaryExtensions.cs rename src/Microsoft.AspNetCore.JsonPatch/{Helpers => Internal}/ExpressionHelpers.cs (95%) create mode 100644 src/Microsoft.AspNetCore.JsonPatch/Internal/IAdapter.cs create mode 100644 src/Microsoft.AspNetCore.JsonPatch/Internal/ListAdapter.cs create mode 100644 src/Microsoft.AspNetCore.JsonPatch/Internal/ObjectVisitor.cs create mode 100644 src/Microsoft.AspNetCore.JsonPatch/Internal/ParsedPath.cs rename src/Microsoft.AspNetCore.JsonPatch/{Helpers => Internal}/PathHelpers.cs (95%) create mode 100644 src/Microsoft.AspNetCore.JsonPatch/Internal/PocoAdapter.cs create mode 100644 test/Microsoft.AspNetCore.JsonPatch.Test/DictionaryAdapterTest.cs create mode 100644 test/Microsoft.AspNetCore.JsonPatch.Test/ListAdapterTest.cs create mode 100644 test/Microsoft.AspNetCore.JsonPatch.Test/ObjectVisitorTest.cs create mode 100644 test/Microsoft.AspNetCore.JsonPatch.Test/ObjectVisitorTest.cs~RF1ad82e13.TMP create mode 100644 test/Microsoft.AspNetCore.JsonPatch.Test/ObjectVisitorTest.cs~RF1ae034c3.TMP diff --git a/src/Microsoft.AspNetCore.JsonPatch/Adapters/ObjectAdapter.cs b/src/Microsoft.AspNetCore.JsonPatch/Adapters/ObjectAdapter.cs index b70ff697c3..ee01fbeba7 100644 --- a/src/Microsoft.AspNetCore.JsonPatch/Adapters/ObjectAdapter.cs +++ b/src/Microsoft.AspNetCore.JsonPatch/Adapters/ObjectAdapter.cs @@ -1,14 +1,11 @@ -// 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. using System; -using System.Collections; -using System.Collections.Generic; -using System.Reflection; using Microsoft.AspNetCore.JsonPatch.Exceptions; using Microsoft.AspNetCore.JsonPatch.Helpers; +using Microsoft.AspNetCore.JsonPatch.Internal; using Microsoft.AspNetCore.JsonPatch.Operations; -using Newtonsoft.Json; using Newtonsoft.Json.Serialization; namespace Microsoft.AspNetCore.JsonPatch.Adapters @@ -127,7 +124,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Adapters string path, object value, object objectToApplyTo, - Operation operationToReport) + Operation operation) { if (path == null) { @@ -139,228 +136,30 @@ namespace Microsoft.AspNetCore.JsonPatch.Adapters throw new ArgumentNullException(nameof(objectToApplyTo)); } - if (operationToReport == null) + if (operation == null) { - throw new ArgumentNullException(nameof(operationToReport)); + throw new ArgumentNullException(nameof(operation)); } - // first up: if the path ends in a numeric value, we're inserting in a list and - // that value represents the position; if the path ends in "-", we're appending - // to the list. + var parsedPath = new ParsedPath(path); + var visitor = new ObjectVisitor(parsedPath, ContractResolver); - // get path result - var pathResult = GetActualPropertyPath( - path, - objectToApplyTo, - operationToReport); - if (pathResult == null) + IAdapter adapter; + var target = objectToApplyTo; + string errorMessage; + if (!visitor.TryVisit(ref target, out adapter, out errorMessage)) { + var error = CreatePathNotFoundError(objectToApplyTo, path, operation, errorMessage); + ReportError(error); return; } - var appendList = pathResult.ExecuteAtEnd; - var positionAsInteger = pathResult.NumericEnd; - var actualPathToProperty = pathResult.PathToProperty; - - var treeAnalysisResult = new ObjectTreeAnalysisResult( - objectToApplyTo, - actualPathToProperty, - ContractResolver); - - if (!treeAnalysisResult.IsValidPathForAdd) + if (!adapter.TryAdd(target, parsedPath.LastSegment, ContractResolver, value, out errorMessage)) { - LogError(new JsonPatchError( - objectToApplyTo, - operationToReport, - Resources.FormatPropertyCannotBeAdded(path))); + var error = CreateOperationFailedError(objectToApplyTo, path, operation, errorMessage); + ReportError(error); return; } - - if (treeAnalysisResult.UseDynamicLogic) - { - var container = treeAnalysisResult.Container; - if (container.ContainsCaseInsensitiveKey(treeAnalysisResult.PropertyPathInParent)) - { - // Existing property. - // If it's not an array, we need to check if the value fits the property type - // - // If it's an array, we need to check if the value fits in that array type, - // and add it at the correct position (if allowed). - if (appendList || positionAsInteger > -1) - { - // get the actual type - var propertyValue = container.GetValueForCaseInsensitiveKey(treeAnalysisResult.PropertyPathInParent); - var typeOfPathProperty = propertyValue.GetType(); - - if (!IsNonStringArray(typeOfPathProperty)) - { - LogError(new JsonPatchError( - objectToApplyTo, - operationToReport, - Resources.FormatInvalidIndexForArrayProperty(operationToReport.op, path))); - return; - } - - // now, get the generic type of the enumerable - var genericTypeOfArray = GetIListType(typeOfPathProperty); - var conversionResult = ConvertToActualType(genericTypeOfArray, value); - if (!conversionResult.CanBeConverted) - { - LogError(new JsonPatchError( - objectToApplyTo, - operationToReport, - Resources.FormatInvalidValueForProperty(value, path))); - return; - } - - // get value (it can be cast, we just checked that) - var array = treeAnalysisResult.Container.GetValueForCaseInsensitiveKey( - treeAnalysisResult.PropertyPathInParent) as IList; - - if (appendList) - { - array.Add(conversionResult.ConvertedInstance); - treeAnalysisResult.Container.SetValueForCaseInsensitiveKey( - treeAnalysisResult.PropertyPathInParent, array); - } - else - { - // specified index must not be greater than - // the amount of items in the array - if (positionAsInteger > array.Count) - { - LogError(new JsonPatchError( - objectToApplyTo, - operationToReport, - Resources.FormatInvalidIndexForArrayProperty( - operationToReport.op, - path))); - return; - } - - array.Insert(positionAsInteger, conversionResult.ConvertedInstance); - treeAnalysisResult.Container.SetValueForCaseInsensitiveKey( - treeAnalysisResult.PropertyPathInParent, array); - } - } - else - { - // get the actual type - var typeOfPathProperty = treeAnalysisResult.Container - .GetValueForCaseInsensitiveKey(treeAnalysisResult.PropertyPathInParent).GetType(); - - // can the value be converted to the actual type? - var conversionResult = ConvertToActualType(typeOfPathProperty, value); - if (conversionResult.CanBeConverted) - { - treeAnalysisResult.Container.SetValueForCaseInsensitiveKey( - treeAnalysisResult.PropertyPathInParent, - conversionResult.ConvertedInstance); - } - else - { - LogError(new JsonPatchError( - objectToApplyTo, - operationToReport, - Resources.FormatInvalidValueForProperty(conversionResult.ConvertedInstance, path))); - return; - } - } - } - else - { - // New property - add it. - treeAnalysisResult.Container.Add(treeAnalysisResult.PropertyPathInParent, value); - } - } - else - { - // If it's an array, add to that array. If it's not, we replace. - - // is the path an array (but not a string (= char[]))? In this case, - // the path must end with "/position" or "/-", which we already determined before. - - var patchProperty = treeAnalysisResult.JsonPatchProperty; - - if (appendList || positionAsInteger > -1) - { - if (!IsNonStringArray(patchProperty.Property.PropertyType)) - { - LogError(new JsonPatchError( - objectToApplyTo, - operationToReport, - Resources.FormatInvalidIndexForArrayProperty(operationToReport.op, path))); - return; - } - - // now, get the generic type of the IList<> from Property type. - var genericTypeOfArray = GetIListType(patchProperty.Property.PropertyType); - var conversionResult = ConvertToActualType(genericTypeOfArray, value); - if (!conversionResult.CanBeConverted) - { - LogError(new JsonPatchError( - objectToApplyTo, - operationToReport, - Resources.FormatInvalidValueForProperty(conversionResult.ConvertedInstance, path))); - return; - } - - if (!patchProperty.Property.Readable) - { - LogError(new JsonPatchError( - objectToApplyTo, - operationToReport, - Resources.FormatCannotReadProperty(path))); - return; - } - - var array = (IList)patchProperty.Property.ValueProvider.GetValue(patchProperty.Parent); - if (appendList) - { - array.Add(conversionResult.ConvertedInstance); - } - else if (positionAsInteger <= array.Count) - { - array.Insert(positionAsInteger, conversionResult.ConvertedInstance); - } - else - { - LogError(new JsonPatchError( - objectToApplyTo, - operationToReport, - Resources.FormatInvalidIndexForArrayProperty(operationToReport.op, path))); - return; - } - } - else - { - var conversionResultTuple = ConvertToActualType( - patchProperty.Property.PropertyType, - value); - - if (!conversionResultTuple.CanBeConverted) - { - LogError(new JsonPatchError( - objectToApplyTo, - operationToReport, - Resources.FormatInvalidValueForProperty(value, path))); - return; - } - - if (!patchProperty.Property.Writable) - { - LogError(new JsonPatchError( - objectToApplyTo, - operationToReport, - Resources.FormatCannotUpdateProperty(path))); - return; - } - - patchProperty.Property.ValueProvider.SetValue( - patchProperty.Parent, - conversionResultTuple.ConvertedInstance); - } - } } /// @@ -398,30 +197,19 @@ namespace Microsoft.AspNetCore.JsonPatch.Adapters throw new ArgumentNullException(nameof(objectToApplyTo)); } - var valueAtFromLocationResult = GetValueAtLocation(operation.from, objectToApplyTo, operation); - - if (valueAtFromLocationResult.HasError) + object propertyValue; + // Get value at 'from' location and add that value to the 'path' location + if (TryGetValue(operation.from, objectToApplyTo, operation, out propertyValue)) { - // Error has already been logged in GetValueAtLocation. We - // must return, because remove / add should not be allowed to continue - return; + // remove that value + Remove(operation.from, objectToApplyTo, operation); + + // add that value to the path location + Add(operation.path, + propertyValue, + objectToApplyTo, + operation); } - - // remove that value - var removeResult = Remove(operation.from, objectToApplyTo, operation); - - if (removeResult.HasError) - { - // Return => error has already been logged in remove method. We must - // return, because add should not be allowed to continue - return; - } - - // add that value to the path location - Add(operation.path, - valueAtFromLocationResult.PropertyValue, - objectToApplyTo, - operation); } /// @@ -453,240 +241,33 @@ namespace Microsoft.AspNetCore.JsonPatch.Adapters Remove(operation.path, objectToApplyTo, operation); } - /// /// Remove is used by various operations (eg: remove, move, ...), yet through different operations; /// This method allows code reuse yet reporting the correct operation on error. The return value /// contains the type of the item that has been removed (and a bool possibly signifying an error) - /// This can be used by other methods, like replace, to ensure that we can pass in the correctly + /// This can be used by other methods, like replace, to ensure that we can pass in the correctly /// typed value to whatever method follows. /// - private RemovedPropertyTypeResult Remove(string path, object objectToApplyTo, Operation operationToReport) + private void Remove(string path, object objectToApplyTo, Operation operationToReport) { - // get path result - var pathResult = GetActualPropertyPath( - path, - objectToApplyTo, - operationToReport); + var parsedPath = new ParsedPath(path); + var visitor = new ObjectVisitor(parsedPath, ContractResolver); - if (pathResult == null) + IAdapter adapter; + var target = objectToApplyTo; + string errorMessage; + if (!visitor.TryVisit(ref target, out adapter, out errorMessage)) { - return new RemovedPropertyTypeResult(null, true); + var error = CreatePathNotFoundError(objectToApplyTo, path, operationToReport, errorMessage); + ReportError(error); + return; } - var removeFromList = pathResult.ExecuteAtEnd; - var positionAsInteger = pathResult.NumericEnd; - var actualPathToProperty = pathResult.PathToProperty; - - var treeAnalysisResult = new ObjectTreeAnalysisResult( - objectToApplyTo, - actualPathToProperty, - ContractResolver); - - if (!treeAnalysisResult.IsValidPathForRemove) + if (!adapter.TryRemove(target, parsedPath.LastSegment, ContractResolver, out errorMessage)) { - LogError(new JsonPatchError( - objectToApplyTo, - operationToReport, - Resources.FormatPropertyCannotBeRemoved(path))); - return new RemovedPropertyTypeResult(null, true); - } - - if (treeAnalysisResult.UseDynamicLogic) - { - // if it's not an array, we can remove the property from - // the dictionary. If it's an array, we need to check the position first. - if (removeFromList || positionAsInteger > -1) - { - var propertyValue = treeAnalysisResult.Container - .GetValueForCaseInsensitiveKey(treeAnalysisResult.PropertyPathInParent); - - // we cannot continue when the value is null, because to be able to - // continue we need to be able to check if the array is a non-string array - if (propertyValue == null) - { - LogError(new JsonPatchError( - objectToApplyTo, - operationToReport, - Resources.FormatCannotDeterminePropertyType(path))); - return new RemovedPropertyTypeResult(null, true); - } - - var typeOfPathProperty = propertyValue.GetType(); - - if (!IsNonStringArray(typeOfPathProperty)) - { - LogError(new JsonPatchError( - objectToApplyTo, - operationToReport, - Resources.FormatInvalidIndexForArrayProperty(operationToReport.op, path))); - return new RemovedPropertyTypeResult(null, true); - } - - // now, get the generic type of the enumerable (we'll return this type) - var genericTypeOfArray = GetIListType(typeOfPathProperty); - - // get the array - var array = (IList)treeAnalysisResult.Container.GetValueForCaseInsensitiveKey( - treeAnalysisResult.PropertyPathInParent); - - if (array.Count == 0) - { - // if the array is empty, we should throw an error - LogError(new JsonPatchError( - objectToApplyTo, - operationToReport, - Resources.FormatInvalidIndexForArrayProperty( - operationToReport.op, - path))); - return new RemovedPropertyTypeResult(null, true); - } - - if (removeFromList) - { - array.RemoveAt(array.Count - 1); - treeAnalysisResult.Container.SetValueForCaseInsensitiveKey( - treeAnalysisResult.PropertyPathInParent, array); - - // return the type of the value that has been removed. - return new RemovedPropertyTypeResult(genericTypeOfArray, false); - } - else - { - if (positionAsInteger >= array.Count) - { - LogError(new JsonPatchError( - objectToApplyTo, - operationToReport, - Resources.FormatInvalidIndexForArrayProperty( - operationToReport.op, - path))); - return new RemovedPropertyTypeResult(null, true); - } - - array.RemoveAt(positionAsInteger); - treeAnalysisResult.Container.SetValueForCaseInsensitiveKey( - treeAnalysisResult.PropertyPathInParent, array); - - // return the type of the value that has been removed. - return new RemovedPropertyTypeResult(genericTypeOfArray, false); - } - } - else - { - // get the property - var getResult = treeAnalysisResult.Container.GetValueForCaseInsensitiveKey( - treeAnalysisResult.PropertyPathInParent); - - // remove the property - treeAnalysisResult.Container.RemoveValueForCaseInsensitiveKey( - treeAnalysisResult.PropertyPathInParent); - - // value is not null, we can determine the type - if (getResult != null) - { - var actualType = getResult.GetType(); - return new RemovedPropertyTypeResult(actualType, false); - } - else - { - return new RemovedPropertyTypeResult(null, false); - } - } - } - else - { - // not dynamic - var patchProperty = treeAnalysisResult.JsonPatchProperty; - - if (removeFromList || positionAsInteger > -1) - { - if (!IsNonStringArray(patchProperty.Property.PropertyType)) - { - LogError(new JsonPatchError( - objectToApplyTo, - operationToReport, - Resources.FormatInvalidIndexForArrayProperty(operationToReport.op, path))); - return new RemovedPropertyTypeResult(null, true); - } - - // now, get the generic type of the IList<> from Property type. - var genericTypeOfArray = GetIListType(patchProperty.Property.PropertyType); - - if (!patchProperty.Property.Readable) - { - LogError(new JsonPatchError( - objectToApplyTo, - operationToReport, - Resources.FormatCannotReadProperty(path))); - return new RemovedPropertyTypeResult(null, true); - } - - var array = (IList)patchProperty.Property.ValueProvider - .GetValue(patchProperty.Parent); - - if (array.Count == 0) - { - // if the array is empty, we should throw an error - LogError(new JsonPatchError( - objectToApplyTo, - operationToReport, - Resources.FormatInvalidIndexForArrayProperty( - operationToReport.op, - path))); - return new RemovedPropertyTypeResult(null, true); - } - - if (removeFromList) - { - array.RemoveAt(array.Count - 1); - - // return the type of the value that has been removed - return new RemovedPropertyTypeResult(genericTypeOfArray, false); - } - else - { - if (positionAsInteger >= array.Count) - { - LogError(new JsonPatchError( - objectToApplyTo, - operationToReport, - Resources.FormatInvalidIndexForArrayProperty( - operationToReport.op, - path))); - return new RemovedPropertyTypeResult(null, true); - } - - array.RemoveAt(positionAsInteger); - - // return the type of the value that has been removed - return new RemovedPropertyTypeResult(genericTypeOfArray, false); - } - } - else - { - if (!patchProperty.Property.Writable) - { - LogError(new JsonPatchError( - objectToApplyTo, - operationToReport, - Resources.FormatCannotUpdateProperty(path))); - return new RemovedPropertyTypeResult(null, true); - } - - // 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 (patchProperty.Property.PropertyType.GetTypeInfo().IsValueType - && Nullable.GetUnderlyingType(patchProperty.Property.PropertyType) == null) - { - value = Activator.CreateInstance(patchProperty.Property.PropertyType); - } - - patchProperty.Property.ValueProvider.SetValue(patchProperty.Parent, value); - return new RemovedPropertyTypeResult(patchProperty.Property.PropertyType, false); - } + var error = CreateOperationFailedError(objectToApplyTo, path, operationToReport, errorMessage); + ReportError(error); + return; } } @@ -722,37 +303,25 @@ namespace Microsoft.AspNetCore.JsonPatch.Adapters throw new ArgumentNullException(nameof(objectToApplyTo)); } - var removeResult = Remove(operation.path, objectToApplyTo, operation); + var parsedPath = new ParsedPath(operation.path); + var visitor = new ObjectVisitor(parsedPath, ContractResolver); - if (removeResult.HasError) + IAdapter adapter; + var target = objectToApplyTo; + string errorMessage; + if (!visitor.TryVisit(ref target, out adapter, out errorMessage)) { - // return => error has already been logged in remove method + var error = CreatePathNotFoundError(objectToApplyTo, operation.path, operation, errorMessage); + ReportError(error); return; } - if (!removeResult.HasError && removeResult.ActualType == null) + if (!adapter.TryReplace(target, parsedPath.LastSegment, ContractResolver, operation.value, out errorMessage)) { - // the remove operation completed succesfully, but we could not determine the type. - LogError(new JsonPatchError( - objectToApplyTo, - operation, - Resources.FormatCannotDeterminePropertyType(operation.from))); + var error = CreateOperationFailedError(objectToApplyTo, operation.path, operation, errorMessage); + ReportError(error); return; } - - var conversionResult = ConvertToActualType(removeResult.ActualType, operation.value); - - if (!conversionResult.CanBeConverted) - { - // invalid value for path - LogError(new JsonPatchError( - objectToApplyTo, - operation, - Resources.FormatInvalidValueForProperty(operation.value, operation.path))); - return; - } - - Add(operation.path, conversionResult.ConvertedInstance, objectToApplyTo, operation); } /// @@ -789,36 +358,26 @@ namespace Microsoft.AspNetCore.JsonPatch.Adapters throw new ArgumentNullException(nameof(objectToApplyTo)); } - // get value at from location and add that value to the path location - var valueAtFromLocationResult = GetValueAtLocation(operation.from, objectToApplyTo, operation); - - if (valueAtFromLocationResult.HasError) + object propertyValue; + // Get value at 'from' location and add that value to the 'path' location + if (TryGetValue(operation.from, objectToApplyTo, operation, out propertyValue)) { - // Return, error has already been logged in GetValueAtLocation - return; + Add(operation.path, + propertyValue, + objectToApplyTo, + operation); } - - Add(operation.path, - valueAtFromLocationResult.PropertyValue, - objectToApplyTo, - operation); } - /// - /// Method is used by Copy and Move to avoid duplicate code - /// - /// Location where value should be - /// Object to inspect for the desired value - /// Operation to report in case of an error - /// GetValueResult containing value and a bool signifying a possible error - private GetValueResult GetValueAtLocation( - string location, + private bool TryGetValue( + string fromLocation, object objectToGetValueFrom, - Operation operationToReport) + Operation operation, + out object propertyValue) { - if (location == null) + if (fromLocation == null) { - throw new ArgumentNullException(nameof(location)); + throw new ArgumentNullException(nameof(fromLocation)); } if (objectToGetValueFrom == null) @@ -826,280 +385,62 @@ namespace Microsoft.AspNetCore.JsonPatch.Adapters throw new ArgumentNullException(nameof(objectToGetValueFrom)); } - if (operationToReport == null) + if (operation == null) { - throw new ArgumentNullException(nameof(operationToReport)); + throw new ArgumentNullException(nameof(operation)); } - // get path result - var pathResult = GetActualPropertyPath( - location, - objectToGetValueFrom, - operationToReport); + propertyValue = null; - if (pathResult == null) + var parsedPath = new ParsedPath(fromLocation); + var visitor = new ObjectVisitor(parsedPath, ContractResolver); + + IAdapter adapter; + var target = objectToGetValueFrom; + string errorMessage; + if (!visitor.TryVisit(ref target, out adapter, out errorMessage)) { - return new GetValueResult(null, true); + var error = CreatePathNotFoundError(objectToGetValueFrom, fromLocation, operation, errorMessage); + ReportError(error); + return false; } - var getAtEndOfList = pathResult.ExecuteAtEnd; - var positionAsInteger = pathResult.NumericEnd; - var actualPathToProperty = pathResult.PathToProperty; - - var treeAnalysisResult = new ObjectTreeAnalysisResult( - objectToGetValueFrom, - actualPathToProperty, - ContractResolver); - - if (treeAnalysisResult.UseDynamicLogic) + if (!adapter.TryGet(target, parsedPath.LastSegment, ContractResolver, out propertyValue, out errorMessage)) { - // if it's not an array, we can remove the property from - // the dictionary. If it's an array, we need to check the position first. - if (getAtEndOfList || positionAsInteger > -1) - { - var propertyValue = treeAnalysisResult.Container - .GetValueForCaseInsensitiveKey(treeAnalysisResult.PropertyPathInParent); - - // we cannot continue when the value is null, because to be able to - // continue we need to be able to check if the array is a non-string array - if (propertyValue == null) - { - LogError(new JsonPatchError( - objectToGetValueFrom, - operationToReport, - Resources.FormatCannotDeterminePropertyType(location))); - return new GetValueResult(null, true); - } - - var typeOfPathProperty = propertyValue.GetType(); - - if (!IsNonStringArray(typeOfPathProperty)) - { - LogError(new JsonPatchError( - objectToGetValueFrom, - operationToReport, - Resources.FormatInvalidIndexForArrayProperty(operationToReport.op, location))); - return new GetValueResult(null, true); - } - - // get the array - var array = (IList)treeAnalysisResult.Container.GetValueForCaseInsensitiveKey( - treeAnalysisResult.PropertyPathInParent); - - if (positionAsInteger >= array.Count) - { - LogError(new JsonPatchError( - objectToGetValueFrom, - operationToReport, - Resources.FormatInvalidIndexForArrayProperty( - operationToReport.op, - location))); - return new GetValueResult(null, true); - } - - if (getAtEndOfList) - { - return new GetValueResult(array[array.Count - 1], false); - } - else - { - return new GetValueResult(array[positionAsInteger], false); - } - } - else - { - // get the property - var propertyValueAtLocation = treeAnalysisResult.Container.GetValueForCaseInsensitiveKey( - treeAnalysisResult.PropertyPathInParent); - - return new GetValueResult(propertyValueAtLocation, false); - } + var error = CreateOperationFailedError(objectToGetValueFrom, fromLocation, operation, errorMessage); + ReportError(error); + return false; } - else - { - // not dynamic - var patchProperty = treeAnalysisResult.JsonPatchProperty; - if (getAtEndOfList || positionAsInteger > -1) - { - if (!IsNonStringArray(patchProperty.Property.PropertyType)) - { - LogError(new JsonPatchError( - objectToGetValueFrom, - operationToReport, - Resources.FormatInvalidIndexForArrayProperty(operationToReport.op, location))); - return new GetValueResult(null, true); - } - - if (!patchProperty.Property.Readable) - { - LogError(new JsonPatchError( - objectToGetValueFrom, - operationToReport, - Resources.FormatCannotReadProperty(location))); - return new GetValueResult(null, true); - } - - var array = (IList)patchProperty.Property.ValueProvider - .GetValue(patchProperty.Parent); - - if (positionAsInteger >= array.Count) - { - LogError(new JsonPatchError( - objectToGetValueFrom, - operationToReport, - Resources.FormatInvalidIndexForArrayProperty( - operationToReport.op, - location))); - return new GetValueResult(null, true); - } - - if (getAtEndOfList) - { - return new GetValueResult(array[array.Count - 1], false); - } - else - { - return new GetValueResult(array[positionAsInteger], false); - } - } - else - { - if (!patchProperty.Property.Readable) - { - LogError(new JsonPatchError( - objectToGetValueFrom, - operationToReport, - Resources.FormatCannotReadProperty( - location))); - return new GetValueResult(null, true); - } - - var propertyValueAtLocation = patchProperty.Property.ValueProvider - .GetValue(patchProperty.Parent); - - return new GetValueResult(propertyValueAtLocation, false); - } - } + return true; } - private bool IsNonStringArray(Type type) - { - if (GetIListType(type) != null) - { - return true; - } - - return (!(type == typeof(string)) && typeof(IList).GetTypeInfo().IsAssignableFrom(type.GetTypeInfo())); - } - - private void LogError(JsonPatchError jsonPatchError) + private void ReportError(JsonPatchError error) { if (LogErrorAction != null) { - LogErrorAction(jsonPatchError); + LogErrorAction(error); } else { - throw new JsonPatchException(jsonPatchError); + throw new JsonPatchException(error); } } - private ConversionResult ConvertToActualType(Type propertyType, object value) + private JsonPatchError CreateOperationFailedError(object target, string path, Operation operation, string errorMessage) { - try - { - var o = JsonConvert.DeserializeObject(JsonConvert.SerializeObject(value), propertyType); - - return new ConversionResult(true, o); - } - catch (Exception) - { - return new ConversionResult(false, null); - } + return new JsonPatchError( + target, + operation, + errorMessage ?? Resources.FormatCannotPerformOperation(operation.op, path)); } - private Type GetIListType(Type type) + private JsonPatchError CreatePathNotFoundError(object target, string path, Operation operation, string errorMessage) { - if (IsGenericListType(type)) - { - return type.GetTypeInfo().GenericTypeArguments[0]; - } - - foreach (Type interfaceType in type.GetTypeInfo().ImplementedInterfaces) - { - if (IsGenericListType(interfaceType)) - { - return interfaceType.GetTypeInfo().GenericTypeArguments[0]; - } - } - - return null; - } - - private bool IsGenericListType(Type type) - { - if (type.GetTypeInfo().IsGenericType && - type.GetGenericTypeDefinition() == typeof(IList<>)) - { - return true; - } - - return false; - } - - private ActualPropertyPathResult GetActualPropertyPath( - string propertyPath, - object objectToApplyTo, - Operation operationToReport) - { - if (propertyPath == null) - { - throw new ArgumentNullException(nameof(propertyPath)); - } - - if (objectToApplyTo == null) - { - throw new ArgumentNullException(nameof(objectToApplyTo)); - } - - if (operationToReport == null) - { - throw new ArgumentNullException(nameof(operationToReport)); - } - - if (propertyPath.EndsWith("/-")) - { - return new ActualPropertyPathResult(-1, propertyPath.Substring(0, propertyPath.Length - 2), true); - } - else - { - var possibleIndex = propertyPath.Substring(propertyPath.LastIndexOf("/") + 1); - int castedIndex = -1; - if (int.TryParse(possibleIndex, out castedIndex)) - { - // has numeric end. - if (castedIndex > -1) - { - var pathToProperty = propertyPath.Substring( - 0, - propertyPath.LastIndexOf('/' + castedIndex.ToString())); - - return new ActualPropertyPathResult(castedIndex, pathToProperty, false); - } - else - { - // negative position - invalid path - LogError(new JsonPatchError( - objectToApplyTo, - operationToReport, - Resources.FormatNegativeIndexForArrayProperty(operationToReport.op, propertyPath))); - return null; - } - } - - return new ActualPropertyPathResult(-1, propertyPath, false); - } + return new JsonPatchError( + target, + operation, + errorMessage ?? Resources.FormatTargetLocationNotFound(operation.op, path)); } } } \ No newline at end of file diff --git a/src/Microsoft.AspNetCore.JsonPatch/Helpers/ActualPropertyPathResult.cs b/src/Microsoft.AspNetCore.JsonPatch/Helpers/ActualPropertyPathResult.cs deleted file mode 100644 index 1967bf6d90..0000000000 --- a/src/Microsoft.AspNetCore.JsonPatch/Helpers/ActualPropertyPathResult.cs +++ /dev/null @@ -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. - -namespace Microsoft.AspNetCore.JsonPatch.Helpers -{ - internal class ActualPropertyPathResult - { - public int NumericEnd { get; private set; } - public string PathToProperty { get; set; } - public bool ExecuteAtEnd { get; set; } - - public ActualPropertyPathResult( - int numericEnd, - string pathToProperty, - bool executeAtEnd) - { - NumericEnd = numericEnd; - PathToProperty = pathToProperty; - ExecuteAtEnd = executeAtEnd; - } - } -} diff --git a/src/Microsoft.AspNetCore.JsonPatch/Helpers/ExpandoObjectDictionaryExtensions.cs b/src/Microsoft.AspNetCore.JsonPatch/Helpers/ExpandoObjectDictionaryExtensions.cs deleted file mode 100644 index aa9fa2158b..0000000000 --- a/src/Microsoft.AspNetCore.JsonPatch/Helpers/ExpandoObjectDictionaryExtensions.cs +++ /dev/null @@ -1,77 +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; -using System.Collections.Generic; - -namespace Microsoft.AspNetCore.JsonPatch.Helpers -{ - // Helper methods to allow case-insensitive key search - internal static class ExpandoObjectDictionaryExtensions - { - internal static void SetValueForCaseInsensitiveKey( - this IDictionary propertyDictionary, - string key, - object value) - { - foreach (KeyValuePair kvp in propertyDictionary) - { - if (string.Equals(kvp.Key, key, StringComparison.OrdinalIgnoreCase)) - { - propertyDictionary[kvp.Key] = value; - break; - } - } - } - - internal static void RemoveValueForCaseInsensitiveKey( - this IDictionary propertyDictionary, - string key) - { - string realKey = null; - foreach (KeyValuePair kvp in propertyDictionary) - { - if (string.Equals(kvp.Key, key, StringComparison.OrdinalIgnoreCase)) - { - realKey = kvp.Key; - break; - } - } - - if (realKey != null) - { - propertyDictionary.Remove(realKey); - } - } - - internal static object GetValueForCaseInsensitiveKey( - this IDictionary propertyDictionary, - string key) - { - foreach (KeyValuePair kvp in propertyDictionary) - { - if (string.Equals(kvp.Key, key, StringComparison.OrdinalIgnoreCase)) - { - return kvp.Value; - } - } - - throw new ArgumentException(Resources.FormatDictionaryKeyNotFound(key)); - } - - internal static bool ContainsCaseInsensitiveKey( - this IDictionary propertyDictionary, - string key) - { - foreach (KeyValuePair kvp in propertyDictionary) - { - if (string.Equals(kvp.Key, key, StringComparison.OrdinalIgnoreCase)) - { - return true; - } - } - - return false; - } - } -} diff --git a/src/Microsoft.AspNetCore.JsonPatch/Helpers/ObjectTreeAnalyisResult.cs b/src/Microsoft.AspNetCore.JsonPatch/Helpers/ObjectTreeAnalyisResult.cs deleted file mode 100644 index 782859ad5f..0000000000 --- a/src/Microsoft.AspNetCore.JsonPatch/Helpers/ObjectTreeAnalyisResult.cs +++ /dev/null @@ -1,209 +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; -using System.Collections; -using System.Collections.Generic; -using System.Linq; -using Newtonsoft.Json.Serialization; - -namespace Microsoft.AspNetCore.JsonPatch.Helpers -{ - internal class ObjectTreeAnalysisResult - { - // either the property is part of the container dictionary, - // or we have a direct reference to a JsonPatchProperty instance - - public bool UseDynamicLogic { get; private set; } - - public bool IsValidPathForAdd { get; private set; } - - public bool IsValidPathForRemove { get; private set; } - - public IDictionary Container { get; private set; } - - public string PropertyPathInParent { get; private set; } - - public JsonPatchProperty JsonPatchProperty { get; private set; } - - public ObjectTreeAnalysisResult( - object objectToSearch, - string propertyPath, - IContractResolver contractResolver) - { - // construct the analysis result. - - // split the propertypath, and if necessary, remove the first - // empty item (that's the case when it starts with a "/") - var propertyPathTree = propertyPath.Split( - new char[] { '/' }, - StringSplitOptions.RemoveEmptyEntries); - - // we've now got a split up property tree "base/property/otherproperty/..." - int lastPosition = 0; - object targetObject = objectToSearch; - for (int i = 0; i < propertyPathTree.Length; i++) - { - lastPosition = i; - - // if the current target object is an ExpandoObject (IDictionary), - // we cannot use the ContractResolver. - var dictionary = targetObject as IDictionary; - if (dictionary != null) - { - // find the value in the dictionary - if (dictionary.ContainsCaseInsensitiveKey(propertyPathTree[i])) - { - var possibleNewTargetObject = dictionary.GetValueForCaseInsensitiveKey(propertyPathTree[i]); - - // unless we're at the last item, we should set the targetobject - // to the new object. If we're at the last item, we need to stop - if (i != propertyPathTree.Length - 1) - { - targetObject = possibleNewTargetObject; - } - } - else - { - break; - } - } - else - { - // if the current part of the path is numeric, this means we're trying - // to get the propertyInfo of a specific object in an array. To allow - // for this, the previous value (targetObject) must be an IEnumerable, and - // the position must exist. - - int numericValue = -1; - if (int.TryParse(propertyPathTree[i], out numericValue)) - { - var element = GetElementAtFromObject(targetObject, numericValue); - if (element != null) - { - targetObject = element; - } - else - { - break; - } - } - else - { - var jsonContract = (JsonObjectContract)contractResolver.ResolveContract(targetObject.GetType()); - - // does the property exist? - var attemptedProperty = jsonContract - .Properties - .FirstOrDefault(p => string.Equals(p.PropertyName, propertyPathTree[i], StringComparison.OrdinalIgnoreCase)); - - if (attemptedProperty != null) - { - // unless we're at the last item, we should continue searching. - // If we're at the last item, we need to stop - if ((i != propertyPathTree.Length - 1)) - { - targetObject = attemptedProperty.ValueProvider.GetValue(targetObject); - } - } - else - { - // property cannot be found, and we're not working with dynamics. - // Stop, and return invalid path. - break; - } - } - } - } - - if (propertyPathTree.Length - lastPosition != 1) - { - IsValidPathForAdd = false; - IsValidPathForRemove = false; - return; - } - - // two things can happen now. The targetproperty can be an IDictionary - in that - // case, it's valid for add if there's 1 item left in the propertyPathTree. - // - // it can also be a property info. In that case, if there's nothing left in the path - // tree we're at the end, if there's one left we can try and set that. - if (targetObject is IDictionary) - { - UseDynamicLogic = true; - - Container = (IDictionary)targetObject; - IsValidPathForAdd = true; - PropertyPathInParent = propertyPathTree[propertyPathTree.Length - 1]; - - // to be able to remove this property, it must exist - IsValidPathForRemove = Container.ContainsCaseInsensitiveKey(PropertyPathInParent); - } - else if (targetObject is IList) - { - UseDynamicLogic = false; - - int index; - if (!Int32.TryParse(propertyPathTree[propertyPathTree.Length - 1], out index)) - { - // We only support indexing into a list - IsValidPathForAdd = false; - IsValidPathForRemove = false; - return; - } - - IsValidPathForAdd = true; - IsValidPathForRemove = ((IList)targetObject).Count > index; - PropertyPathInParent = propertyPathTree[propertyPathTree.Length - 1]; - } - else - { - UseDynamicLogic = false; - - var property = propertyPathTree[propertyPathTree.Length - 1]; - var jsonContract = (JsonObjectContract)contractResolver.ResolveContract(targetObject.GetType()); - var attemptedProperty = jsonContract - .Properties - .FirstOrDefault(p => string.Equals(p.PropertyName, property, StringComparison.OrdinalIgnoreCase)); - - if (attemptedProperty == null) - { - IsValidPathForAdd = false; - IsValidPathForRemove = false; - } - else - { - IsValidPathForAdd = true; - IsValidPathForRemove = true; - JsonPatchProperty = new JsonPatchProperty(attemptedProperty, targetObject); - PropertyPathInParent = property; - } - } - } - - private object GetElementAtFromObject(object targetObject, int numericValue) - { - if (numericValue > -1) - { - // Check if the targetobject is an IEnumerable, - // and if the position is valid. - if (targetObject is IEnumerable) - { - var indexable = ((IEnumerable)targetObject).Cast(); - - if (indexable.Count() >= numericValue) - { - return indexable.ElementAt(numericValue); - } - else { return null; } - } - else { return null; } - } - else - { - return null; - } - } - - } -} diff --git a/src/Microsoft.AspNetCore.JsonPatch/Helpers/RemovedPropertyTypeResult.cs b/src/Microsoft.AspNetCore.JsonPatch/Helpers/RemovedPropertyTypeResult.cs deleted file mode 100644 index c548f55c6e..0000000000 --- a/src/Microsoft.AspNetCore.JsonPatch/Helpers/RemovedPropertyTypeResult.cs +++ /dev/null @@ -1,38 +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; - -namespace Microsoft.AspNetCore.JsonPatch.Helpers -{ - /// - /// Return value for Remove operation. The combination tells us what to do next (if this operation - /// is called from inside another operation, eg: Replace, Copy. - /// - /// Possible combo: - /// - ActualType contains type: operation succesfully completed, can continue when called from inside - /// another operation - /// - ActualType null and HasError true: operation not completed succesfully, should not be allowed to continue - /// - ActualType null and HasError false: operation completed succesfully, but we should not be allowed to - /// continue when called from inside another method as we could not verify the type of the removed property. - /// This happens when the value of an item in an ExpandoObject dictionary is null. - /// - internal class RemovedPropertyTypeResult - { - /// - /// The type of the removed property (value) - /// - public Type ActualType { get; private set; } - - /// - /// HasError: true when an error occurred, the operation didn't complete succesfully - /// - public bool HasError { get; set; } - - public RemovedPropertyTypeResult(Type actualType, bool hasError) - { - ActualType = actualType; - HasError = hasError; - } - } -} diff --git a/src/Microsoft.AspNetCore.JsonPatch/Helpers/ConversionResult.cs b/src/Microsoft.AspNetCore.JsonPatch/Internal/ConversionResult.cs similarity index 64% rename from src/Microsoft.AspNetCore.JsonPatch/Helpers/ConversionResult.cs rename to src/Microsoft.AspNetCore.JsonPatch/Internal/ConversionResult.cs index 00a7513d44..77181eb18d 100644 --- a/src/Microsoft.AspNetCore.JsonPatch/Helpers/ConversionResult.cs +++ b/src/Microsoft.AspNetCore.JsonPatch/Internal/ConversionResult.cs @@ -1,17 +1,17 @@ // 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.Helpers +namespace Microsoft.AspNetCore.JsonPatch.Internal { - internal class ConversionResult + public class ConversionResult { - public bool CanBeConverted { get; private set; } - public object ConvertedInstance { get; private set; } - public ConversionResult(bool canBeConverted, object convertedInstance) { CanBeConverted = canBeConverted; ConvertedInstance = convertedInstance; } + + public bool CanBeConverted { get; } + public object ConvertedInstance { get; } } } \ No newline at end of file diff --git a/src/Microsoft.AspNetCore.JsonPatch/Internal/ConversionResultProvider.cs b/src/Microsoft.AspNetCore.JsonPatch/Internal/ConversionResultProvider.cs new file mode 100644 index 0000000000..bdf4122394 --- /dev/null +++ b/src/Microsoft.AspNetCore.JsonPatch/Internal/ConversionResultProvider.cs @@ -0,0 +1,24 @@ +// 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 Newtonsoft.Json; + +namespace Microsoft.AspNetCore.JsonPatch.Internal +{ + public static class ConversionResultProvider + { + public static ConversionResult ConvertTo(object value, Type typeToConvertTo) + { + try + { + var deserialized = JsonConvert.DeserializeObject(JsonConvert.SerializeObject(value), typeToConvertTo); + return new ConversionResult(true, deserialized); + } + catch + { + return new ConversionResult(canBeConverted: false, convertedInstance: null); + } + } + } +} diff --git a/src/Microsoft.AspNetCore.JsonPatch/Internal/DictionaryAdapter.cs b/src/Microsoft.AspNetCore.JsonPatch/Internal/DictionaryAdapter.cs new file mode 100644 index 0000000000..4c7651e475 --- /dev/null +++ b/src/Microsoft.AspNetCore.JsonPatch/Internal/DictionaryAdapter.cs @@ -0,0 +1,111 @@ +// 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; +using Newtonsoft.Json.Serialization; + +namespace Microsoft.AspNetCore.JsonPatch.Internal +{ + public class DictionaryAdapter : IAdapter + { + public bool TryAdd( + object target, + string segment, + IContractResolver contractResolver, + object value, + out string errorMessage) + { + var dictionary = (IDictionary)target; + + // As per JsonPatch spec, if a key already exists, adding should replace the existing value + dictionary[segment] = value; + + errorMessage = null; + return true; + } + + public bool TryGet( + object target, + string segment, + IContractResolver contractResolver, + out object value, + out string errorMessage) + { + var dictionary = (IDictionary)target; + + value = dictionary[segment]; + errorMessage = null; + return true; + } + + public bool TryRemove( + object target, + string segment, + IContractResolver contractResolver, + out string errorMessage) + { + var dictionary = (IDictionary)target; + + // As per JsonPatch spec, the target location must exist for remove to be successful + if (!dictionary.Contains(segment)) + { + errorMessage = Resources.FormatTargetLocationAtPathSegmentNotFound(segment); + return false; + } + + dictionary.Remove(segment); + errorMessage = null; + return true; + } + + public bool TryReplace( + object target, + string segment, + IContractResolver contractResolver, + object value, + out string errorMessage) + { + var dictionary = (IDictionary)target; + + // As per JsonPatch spec, the target location must exist for remove to be successful + if (!dictionary.Contains(segment)) + { + errorMessage = Resources.FormatTargetLocationAtPathSegmentNotFound(segment); + return false; + } + + dictionary[segment] = value; + errorMessage = null; + return true; + } + + public bool TryTraverse( + object target, + string segment, + IContractResolver contractResolver, + out object nextTarget, + out string errorMessage) + { + var dictionary = target as IDictionary; + if (dictionary == null) + { + nextTarget = null; + errorMessage = null; + return false; + } + + if (dictionary.Contains(segment)) + { + nextTarget = dictionary[segment]; + errorMessage = null; + return true; + } + else + { + nextTarget = null; + errorMessage = null; + return false; + } + } + } +} diff --git a/src/Microsoft.AspNetCore.JsonPatch/Internal/ExpandoObjectAdapter.cs b/src/Microsoft.AspNetCore.JsonPatch/Internal/ExpandoObjectAdapter.cs new file mode 100644 index 0000000000..681b5309e6 --- /dev/null +++ b/src/Microsoft.AspNetCore.JsonPatch/Internal/ExpandoObjectAdapter.cs @@ -0,0 +1,143 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System.Collections.Generic; +using System.Dynamic; +using Newtonsoft.Json.Serialization; + +namespace Microsoft.AspNetCore.JsonPatch.Internal +{ + public class ExpandoObjectAdapter : IAdapter + { + public bool TryAdd( + object target, + string segment, + IContractResolver contractResolver, + object value, + out string errorMessage) + { + var dictionary = (IDictionary)target; + + var key = dictionary.GetKeyUsingCaseInsensitiveSearch(segment); + + // As per JsonPatch spec, if a key already exists, adding should replace the existing value + dictionary[key] = ConvertValue(dictionary, key, value); + + errorMessage = null; + return true; + } + + public bool TryGet( + object target, + string segment, + IContractResolver contractResolver, + out object value, + out string errorMessage) + { + var dictionary = (IDictionary)target; + + var key = dictionary.GetKeyUsingCaseInsensitiveSearch(segment); + value = dictionary[key]; + + errorMessage = null; + return true; + } + + public bool TryRemove( + object target, + string segment, + IContractResolver contractResolver, + out string errorMessage) + { + var dictionary = (IDictionary)target; + + var key = dictionary.GetKeyUsingCaseInsensitiveSearch(segment); + + // As per JsonPatch spec, the target location must exist for remove to be successful + if (!dictionary.ContainsKey(key)) + { + errorMessage = Resources.FormatTargetLocationAtPathSegmentNotFound(segment); + return false; + } + + dictionary.Remove(key); + + errorMessage = null; + return true; + } + + public bool TryReplace( + object target, + string segment, + IContractResolver contractResolver, + object value, + out string errorMessage) + { + var dictionary = (IDictionary)target; + + var key = dictionary.GetKeyUsingCaseInsensitiveSearch(segment); + + // As per JsonPatch spec, the target location must exist for remove to be successful + if (!dictionary.ContainsKey(key)) + { + errorMessage = Resources.FormatTargetLocationAtPathSegmentNotFound(segment); + return false; + } + + dictionary[key] = ConvertValue(dictionary, key, value); + + errorMessage = null; + return true; + } + + public bool TryTraverse( + object target, + string segment, + IContractResolver contractResolver, + out object nextTarget, + out string errorMessage) + { + var expandoObject = target as ExpandoObject; + if (expandoObject == null) + { + errorMessage = null; + nextTarget = null; + return false; + } + + var dictionary = (IDictionary)expandoObject; + + var key = dictionary.GetKeyUsingCaseInsensitiveSearch(segment); + + if (dictionary.ContainsKey(key)) + { + nextTarget = dictionary[key]; + errorMessage = null; + return true; + } + else + { + nextTarget = null; + errorMessage = null; + return false; + } + } + + private object ConvertValue(IDictionary dictionary, string key, object newValue) + { + object existingValue = null; + if (dictionary.TryGetValue(key, out existingValue)) + { + if (existingValue != null) + { + var conversionResult = ConversionResultProvider.ConvertTo(newValue, existingValue.GetType()); + if (conversionResult.CanBeConverted) + { + return conversionResult.ConvertedInstance; + } + } + } + return newValue; + } + } +} diff --git a/src/Microsoft.AspNetCore.JsonPatch/Internal/ExpandoObjectDictionaryExtensions.cs b/src/Microsoft.AspNetCore.JsonPatch/Internal/ExpandoObjectDictionaryExtensions.cs new file mode 100644 index 0000000000..8bb60dd2a7 --- /dev/null +++ b/src/Microsoft.AspNetCore.JsonPatch/Internal/ExpandoObjectDictionaryExtensions.cs @@ -0,0 +1,26 @@ +// 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; + +namespace Microsoft.AspNetCore.JsonPatch.Internal +{ + // Helper methods to allow case-insensitive key search + public static class ExpandoObjectDictionaryExtensions + { + internal static string GetKeyUsingCaseInsensitiveSearch( + this IDictionary propertyDictionary, + string key) + { + foreach (var keyInDictionary in propertyDictionary.Keys) + { + if (string.Equals(key, keyInDictionary, StringComparison.OrdinalIgnoreCase)) + { + return keyInDictionary; + } + } + return key; + } + } +} \ No newline at end of file diff --git a/src/Microsoft.AspNetCore.JsonPatch/Helpers/ExpressionHelpers.cs b/src/Microsoft.AspNetCore.JsonPatch/Internal/ExpressionHelpers.cs similarity index 95% rename from src/Microsoft.AspNetCore.JsonPatch/Helpers/ExpressionHelpers.cs rename to src/Microsoft.AspNetCore.JsonPatch/Internal/ExpressionHelpers.cs index d9b516cc0e..c978330e5c 100644 --- a/src/Microsoft.AspNetCore.JsonPatch/Helpers/ExpressionHelpers.cs +++ b/src/Microsoft.AspNetCore.JsonPatch/Internal/ExpressionHelpers.cs @@ -1,16 +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. -using Newtonsoft.Json; using System; using System.Globalization; -using System.Linq; using System.Linq.Expressions; using System.Reflection; +using Newtonsoft.Json; -namespace Microsoft.AspNetCore.JsonPatch.Helpers +namespace Microsoft.AspNetCore.JsonPatch.Internal { - internal static class ExpressionHelpers + public static class ExpressionHelpers { public static string GetPath(Expression> expr) where TModel : class { @@ -59,7 +58,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Helpers } else { - // Get property name, respecting JsonProperty attribute + // Get property name, respecting JsonProperty attribute return GetPropertyNameFromMemberExpression(memberExpression); } case ExpressionType.Parameter: @@ -73,7 +72,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Helpers private static string GetPropertyNameFromMemberExpression(MemberExpression memberExpression) { // if there's a JsonProperty attribute, we must return the PropertyName - // from the attribute rather than the member name + // from the attribute rather than the member name var jsonPropertyAttribute = memberExpression.Member.GetCustomAttribute( typeof(JsonPropertyAttribute), true); diff --git a/src/Microsoft.AspNetCore.JsonPatch/Internal/IAdapter.cs b/src/Microsoft.AspNetCore.JsonPatch/Internal/IAdapter.cs new file mode 100644 index 0000000000..1866b42ed4 --- /dev/null +++ b/src/Microsoft.AspNetCore.JsonPatch/Internal/IAdapter.cs @@ -0,0 +1,44 @@ +// 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 Newtonsoft.Json.Serialization; + +namespace Microsoft.AspNetCore.JsonPatch.Internal +{ + public interface IAdapter + { + bool TryTraverse( + object target, + string segment, + IContractResolver contractResolver, + out object nextTarget, + out string errorMessage); + + bool TryAdd( + object target, + string segment, + IContractResolver contractResolver, + object value, + out string errorMessage); + + bool TryRemove( + object target, + string segment, + IContractResolver contractResolver, + out string errorMessage); + + bool TryGet( + object target, + string segment, + IContractResolver contractResolver, + out object value, + out string errorMessage); + + bool TryReplace( + object target, + string segment, + IContractResolver contractResolver, + object value, + out string errorMessage); + } +} diff --git a/src/Microsoft.AspNetCore.JsonPatch/Internal/ListAdapter.cs b/src/Microsoft.AspNetCore.JsonPatch/Internal/ListAdapter.cs new file mode 100644 index 0000000000..c3da14fe5a --- /dev/null +++ b/src/Microsoft.AspNetCore.JsonPatch/Internal/ListAdapter.cs @@ -0,0 +1,299 @@ +// 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; +using System.Collections.Generic; +using Microsoft.Extensions.Internal; +using Newtonsoft.Json.Serialization; + +namespace Microsoft.AspNetCore.JsonPatch.Internal +{ + public class ListAdapter : IAdapter + { + public bool TryAdd( + object target, + string segment, + IContractResolver contractResolver, + object value, + out string errorMessage) + { + var list = (IList)target; + + Type typeArgument = null; + if (!TryGetListTypeArgument(list, out typeArgument, out errorMessage)) + { + return false; + } + + PositionInfo positionInfo; + if (!TryGetPositionInfo(list, segment, out positionInfo, out errorMessage)) + { + return false; + } + + object convertedValue = null; + if (!TryConvertValue(value, typeArgument, segment, out convertedValue, out errorMessage)) + { + return false; + } + + if (positionInfo.Type == PositionType.EndOfList) + { + list.Add(convertedValue); + } + else + { + list.Insert(positionInfo.Index, convertedValue); + } + + errorMessage = null; + return true; + } + + public bool TryGet( + object target, + string segment, + IContractResolver contractResolver, + out object value, + out string errorMessage) + { + var list = (IList)target; + + Type typeArgument = null; + if (!TryGetListTypeArgument(list, out typeArgument, out errorMessage)) + { + value = null; + return false; + } + + PositionInfo positionInfo; + if (!TryGetPositionInfo(list, segment, out positionInfo, out errorMessage)) + { + value = null; + return false; + } + + if (positionInfo.Type == PositionType.EndOfList) + { + value = list[list.Count - 1]; + } + else + { + value = list[positionInfo.Index]; + } + + errorMessage = null; + return true; + } + + public bool TryRemove( + object target, + string segment, + IContractResolver contractResolver, + out string errorMessage) + { + var list = (IList)target; + + Type typeArgument = null; + if (!TryGetListTypeArgument(list, out typeArgument, out errorMessage)) + { + return false; + } + + PositionInfo positionInfo; + if (!TryGetPositionInfo(list, segment, out positionInfo, out errorMessage)) + { + return false; + } + + if (positionInfo.Type == PositionType.EndOfList) + { + list.RemoveAt(list.Count - 1); + } + else + { + list.RemoveAt(positionInfo.Index); + } + + errorMessage = null; + return true; + } + + public bool TryReplace( + object target, + string segment, + IContractResolver contractResolver, + object value, + out string errorMessage) + { + var list = (IList)target; + + Type typeArgument = null; + if (!TryGetListTypeArgument(list, out typeArgument, out errorMessage)) + { + return false; + } + + PositionInfo positionInfo; + if (!TryGetPositionInfo(list, segment, out positionInfo, out errorMessage)) + { + return false; + } + + object convertedValue = null; + if (!TryConvertValue(value, typeArgument, segment, out convertedValue, out errorMessage)) + { + return false; + } + + if (positionInfo.Type == PositionType.EndOfList) + { + list[list.Count - 1] = convertedValue; + } + else + { + list[positionInfo.Index] = convertedValue; + } + + errorMessage = null; + return true; + } + + public bool TryTraverse( + object target, + string segment, + IContractResolver contractResolver, + out object value, + out string errorMessage) + { + var list = target as IList; + if (list == null) + { + value = null; + errorMessage = null; + return false; + } + + int index = -1; + if (!int.TryParse(segment, out index)) + { + value = null; + errorMessage = Resources.FormatInvalidIndexValue(segment); + return false; + } + + if (index < 0 || index >= list.Count) + { + value = null; + errorMessage = Resources.FormatIndexOutOfBounds(segment); + return false; + } + + value = list[index]; + errorMessage = null; + return true; + } + + private bool TryConvertValue( + object originalValue, + Type listTypeArgument, + string segment, + out object convertedValue, + out string errorMessage) + { + var conversionResult = ConversionResultProvider.ConvertTo(originalValue, listTypeArgument); + if (!conversionResult.CanBeConverted) + { + convertedValue = null; + errorMessage = Resources.FormatInvalidValueForProperty(originalValue); + return false; + } + + convertedValue = conversionResult.ConvertedInstance; + errorMessage = null; + return true; + } + + private 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(); + if (listType.IsArray) + { + errorMessage = Resources.FormatPatchNotSupportedForArrays(listType.FullName); + listTypeArgument = null; + return false; + } + else + { + var genericList = ClosedGenericMatcher.ExtractGenericInterface(listType, typeof(IList<>)); + if (genericList == null) + { + errorMessage = Resources.FormatPatchNotSupportedForNonGenericLists(listType.FullName); + listTypeArgument = null; + return false; + } + else + { + listTypeArgument = genericList.GenericTypeArguments[0]; + errorMessage = null; + return true; + } + } + } + + private bool TryGetPositionInfo(IList list, string segment, out PositionInfo positionInfo, out string errorMessage) + { + if (segment == "-") + { + positionInfo = new PositionInfo(PositionType.EndOfList, -1); + errorMessage = null; + return true; + } + + int position = -1; + if (int.TryParse(segment, out position)) + { + if (position >= 0 && position < list.Count) + { + positionInfo = new PositionInfo(PositionType.Index, position); + errorMessage = null; + return true; + } + else + { + positionInfo = default(PositionInfo); + errorMessage = Resources.FormatIndexOutOfBounds(segment); + return false; + } + } + else + { + positionInfo = default(PositionInfo); + errorMessage = Resources.FormatInvalidIndexValue(segment); + return false; + } + } + + private struct PositionInfo + { + public PositionInfo(PositionType type, int index) + { + Type = type; + Index = index; + } + + public PositionType Type { get; } + public int Index { get; } + } + + private enum PositionType + { + Index, // valid index + EndOfList, // '-' + Invalid, // Ex: not an integer + OutOfBounds + } + } +} diff --git a/src/Microsoft.AspNetCore.JsonPatch/Internal/ObjectVisitor.cs b/src/Microsoft.AspNetCore.JsonPatch/Internal/ObjectVisitor.cs new file mode 100644 index 0000000000..b604f65a17 --- /dev/null +++ b/src/Microsoft.AspNetCore.JsonPatch/Internal/ObjectVisitor.cs @@ -0,0 +1,76 @@ +// 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; +using System.Dynamic; +using Newtonsoft.Json.Serialization; + +namespace Microsoft.AspNetCore.JsonPatch.Internal +{ + public class ObjectVisitor + { + private readonly IContractResolver _contractResolver; + private readonly ParsedPath _path; + + public ObjectVisitor(ParsedPath path, IContractResolver contractResolver) + { + if (contractResolver == null) + { + throw new ArgumentNullException(nameof(contractResolver)); + } + + _path = path; + _contractResolver = contractResolver; + } + + public bool TryVisit(ref object target, out IAdapter adapter, out string errorMessage) + { + if (target == null) + { + adapter = null; + errorMessage = null; + return false; + } + + adapter = SelectAdapater(target); + + // Traverse until the penultimate segment to get the target object and adapter + for (var i = 0; i < _path.Segments.Count - 1; i++) + { + object next; + if (!adapter.TryTraverse(target, _path.Segments[i], _contractResolver, out next, out errorMessage)) + { + adapter = null; + return false; + } + + target = next; + adapter = SelectAdapater(target); + } + + errorMessage = null; + return true; + } + + private IAdapter SelectAdapater(object targetObject) + { + if (targetObject is ExpandoObject) + { + return new ExpandoObjectAdapter(); + } + else if (targetObject is IDictionary) + { + return new DictionaryAdapter(); + } + else if (targetObject is IList) + { + return new ListAdapter(); + } + else + { + return new PocoAdapter(); + } + } + } +} diff --git a/src/Microsoft.AspNetCore.JsonPatch/Internal/ParsedPath.cs b/src/Microsoft.AspNetCore.JsonPatch/Internal/ParsedPath.cs new file mode 100644 index 0000000000..fe786b86c1 --- /dev/null +++ b/src/Microsoft.AspNetCore.JsonPatch/Internal/ParsedPath.cs @@ -0,0 +1,40 @@ +// 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; + +namespace Microsoft.AspNetCore.JsonPatch.Internal +{ + public struct ParsedPath + { + private static readonly string[] Empty = null; + + private readonly string[] _segments; + + public ParsedPath(string path) + { + if (path == null) + { + throw new ArgumentNullException(nameof(path)); + } + + _segments = path.Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries); + } + + public string LastSegment + { + get + { + if (_segments == null || _segments.Length == 0) + { + return null; + } + + return _segments[_segments.Length - 1]; + } + } + + public IReadOnlyList Segments => _segments ?? Empty; + } +} diff --git a/src/Microsoft.AspNetCore.JsonPatch/Helpers/PathHelpers.cs b/src/Microsoft.AspNetCore.JsonPatch/Internal/PathHelpers.cs similarity index 95% rename from src/Microsoft.AspNetCore.JsonPatch/Helpers/PathHelpers.cs rename to src/Microsoft.AspNetCore.JsonPatch/Internal/PathHelpers.cs index 99bb2f1536..7ef8fe7baf 100644 --- a/src/Microsoft.AspNetCore.JsonPatch/Helpers/PathHelpers.cs +++ b/src/Microsoft.AspNetCore.JsonPatch/Internal/PathHelpers.cs @@ -3,7 +3,7 @@ using Microsoft.AspNetCore.JsonPatch.Exceptions; -namespace Microsoft.AspNetCore.JsonPatch.Helpers +namespace Microsoft.AspNetCore.JsonPatch.Internal { internal static class PathHelpers { diff --git a/src/Microsoft.AspNetCore.JsonPatch/Internal/PocoAdapter.cs b/src/Microsoft.AspNetCore.JsonPatch/Internal/PocoAdapter.cs new file mode 100644 index 0000000000..0755e132e1 --- /dev/null +++ b/src/Microsoft.AspNetCore.JsonPatch/Internal/PocoAdapter.cs @@ -0,0 +1,205 @@ +// 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.Linq; +using System.Reflection; +using Newtonsoft.Json.Serialization; + +namespace Microsoft.AspNetCore.JsonPatch.Internal +{ + public class PocoAdapter : IAdapter + { + public bool TryAdd( + object target, + string segment, + IContractResolver contractResolver, + object value, + out string errorMessage) + { + JsonProperty jsonProperty = null; + if (!TryGetJsonProperty(target, contractResolver, segment, out jsonProperty)) + { + errorMessage = Resources.FormatTargetLocationAtPathSegmentNotFound(segment); + return false; + } + + if (!jsonProperty.Writable) + { + errorMessage = Resources.FormatCannotUpdateProperty(segment); + return false; + } + + object convertedValue = null; + if (!TryConvertValue(value, jsonProperty.PropertyType, out convertedValue)) + { + errorMessage = Resources.FormatInvalidValueForProperty(value); + return false; + } + + jsonProperty.ValueProvider.SetValue(target, convertedValue); + + errorMessage = null; + return true; + } + + public bool TryGet( + object target, + string segment, + IContractResolver contractResolver, + out object value, + out string errorMessage) + { + JsonProperty jsonProperty = null; + if (!TryGetJsonProperty(target, contractResolver, segment, out jsonProperty)) + { + errorMessage = Resources.FormatTargetLocationAtPathSegmentNotFound(segment); + value = null; + return false; + } + + if (!jsonProperty.Readable) + { + errorMessage = Resources.FormatCannotReadProperty(segment); + value = null; + return false; + } + + value = jsonProperty.ValueProvider.GetValue(target); + errorMessage = null; + return true; + } + + public bool TryRemove( + object target, + string segment, + IContractResolver contractResolver, + out string errorMessage) + { + JsonProperty jsonProperty = null; + if (!TryGetJsonProperty(target, contractResolver, segment, out jsonProperty)) + { + errorMessage = Resources.FormatTargetLocationAtPathSegmentNotFound(segment); + return false; + } + + if (!jsonProperty.Writable) + { + errorMessage = Resources.FormatCannotUpdateProperty(segment); + 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 (jsonProperty.PropertyType.GetTypeInfo().IsValueType + && Nullable.GetUnderlyingType(jsonProperty.PropertyType) == null) + { + value = Activator.CreateInstance(jsonProperty.PropertyType); + } + + jsonProperty.ValueProvider.SetValue(target, value); + + errorMessage = null; + return true; + } + + public bool TryReplace( + object target, + string segment, + IContractResolver + contractResolver, + object value, + out string errorMessage) + { + JsonProperty jsonProperty = null; + if (!TryGetJsonProperty(target, contractResolver, segment, out jsonProperty)) + { + errorMessage = Resources.FormatTargetLocationAtPathSegmentNotFound(segment); + return false; + } + + if (!jsonProperty.Writable) + { + errorMessage = Resources.FormatCannotUpdateProperty(segment); + return false; + } + + object convertedValue = null; + if (!TryConvertValue(value, jsonProperty.PropertyType, out convertedValue)) + { + errorMessage = Resources.FormatInvalidValueForProperty(value); + return false; + } + + jsonProperty.ValueProvider.SetValue(target, convertedValue); + + errorMessage = null; + return true; + } + + public bool TryTraverse( + object target, + string segment, + IContractResolver contractResolver, + out object value, + out string errorMessage) + { + if (target == null) + { + value = null; + errorMessage = null; + return false; + } + + JsonProperty jsonProperty = null; + if (TryGetJsonProperty(target, contractResolver, segment, out jsonProperty)) + { + value = jsonProperty.ValueProvider.GetValue(target); + errorMessage = null; + return true; + } + + value = null; + errorMessage = Resources.FormatTargetLocationAtPathSegmentNotFound(segment); + return false; + } + + private bool TryGetJsonProperty( + object target, + IContractResolver contractResolver, + string segment, + out JsonProperty jsonProperty) + { + var jsonObjectContract = contractResolver.ResolveContract(target.GetType()) as JsonObjectContract; + if (jsonObjectContract != null) + { + var pocoProperty = jsonObjectContract + .Properties + .FirstOrDefault(p => string.Equals(p.PropertyName, segment, StringComparison.OrdinalIgnoreCase)); + + if (pocoProperty != null) + { + jsonProperty = pocoProperty; + return true; + } + } + + jsonProperty = null; + 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; + } + } +} diff --git a/src/Microsoft.AspNetCore.JsonPatch/JsonPatchDocument.cs b/src/Microsoft.AspNetCore.JsonPatch/JsonPatchDocument.cs index c9c34459a9..72e93e0302 100644 --- a/src/Microsoft.AspNetCore.JsonPatch/JsonPatchDocument.cs +++ b/src/Microsoft.AspNetCore.JsonPatch/JsonPatchDocument.cs @@ -5,7 +5,7 @@ using System; using System.Collections.Generic; using Microsoft.AspNetCore.JsonPatch.Adapters; using Microsoft.AspNetCore.JsonPatch.Converters; -using Microsoft.AspNetCore.JsonPatch.Helpers; +using Microsoft.AspNetCore.JsonPatch.Internal; using Microsoft.AspNetCore.JsonPatch.Operations; using Newtonsoft.Json; using Newtonsoft.Json.Serialization; @@ -13,7 +13,7 @@ using Newtonsoft.Json.Serialization; namespace Microsoft.AspNetCore.JsonPatch { // Implementation details: the purpose of this type of patch document is to allow creation of such - // documents for cases where there's no class/DTO to work on. Typical use case: backend not built in + // documents for cases where there's no class/DTO to work on. Typical use case: backend not built in // .NET or architecture doesn't contain a shared DTO layer. [JsonConverter(typeof(JsonPatchDocumentConverter))] public class JsonPatchDocument : IJsonPatchDocument @@ -145,7 +145,7 @@ namespace Microsoft.AspNetCore.JsonPatch } /// - /// Apply this JsonPatchDocument + /// Apply this JsonPatchDocument /// /// Object to apply the JsonPatchDocument to public void ApplyTo(object objectToApplyTo) @@ -159,7 +159,7 @@ namespace Microsoft.AspNetCore.JsonPatch } /// - /// Apply this JsonPatchDocument + /// Apply this JsonPatchDocument /// /// Object to apply the JsonPatchDocument to /// Action to log errors @@ -174,7 +174,7 @@ namespace Microsoft.AspNetCore.JsonPatch } /// - /// Apply this JsonPatchDocument + /// Apply this JsonPatchDocument /// /// Object to apply the JsonPatchDocument to /// IObjectAdapter instance to use when applying diff --git a/src/Microsoft.AspNetCore.JsonPatch/JsonPatchDocumentOfT.cs b/src/Microsoft.AspNetCore.JsonPatch/JsonPatchDocumentOfT.cs index 530b414060..afb5eb3ff1 100644 --- a/src/Microsoft.AspNetCore.JsonPatch/JsonPatchDocumentOfT.cs +++ b/src/Microsoft.AspNetCore.JsonPatch/JsonPatchDocumentOfT.cs @@ -6,7 +6,7 @@ using System.Collections.Generic; using System.Linq.Expressions; using Microsoft.AspNetCore.JsonPatch.Adapters; using Microsoft.AspNetCore.JsonPatch.Converters; -using Microsoft.AspNetCore.JsonPatch.Helpers; +using Microsoft.AspNetCore.JsonPatch.Internal; using Microsoft.AspNetCore.JsonPatch.Operations; using Newtonsoft.Json; using Newtonsoft.Json.Serialization; @@ -502,7 +502,7 @@ namespace Microsoft.AspNetCore.JsonPatch /// Copy from a property to a location in a list /// /// - /// source location + /// source location /// target location /// position /// @@ -623,7 +623,7 @@ namespace Microsoft.AspNetCore.JsonPatch } /// - /// Apply this JsonPatchDocument + /// Apply this JsonPatchDocument /// /// Object to apply the JsonPatchDocument to public void ApplyTo(TModel objectToApplyTo) @@ -637,7 +637,7 @@ namespace Microsoft.AspNetCore.JsonPatch } /// - /// Apply this JsonPatchDocument + /// Apply this JsonPatchDocument /// /// Object to apply the JsonPatchDocument to /// Action to log errors @@ -652,7 +652,7 @@ namespace Microsoft.AspNetCore.JsonPatch } /// - /// Apply this JsonPatchDocument + /// Apply this JsonPatchDocument /// /// Object to apply the JsonPatchDocument to /// IObjectAdapter instance to use when applying diff --git a/src/Microsoft.AspNetCore.JsonPatch/Properties/Resources.Designer.cs b/src/Microsoft.AspNetCore.JsonPatch/Properties/Resources.Designer.cs index 70f76f1fa3..9e00cc2f00 100644 --- a/src/Microsoft.AspNetCore.JsonPatch/Properties/Resources.Designer.cs +++ b/src/Microsoft.AspNetCore.JsonPatch/Properties/Resources.Designer.cs @@ -26,6 +26,22 @@ namespace Microsoft.AspNetCore.JsonPatch return string.Format(CultureInfo.CurrentCulture, GetString("CannotDeterminePropertyType"), p0); } + /// + /// The '{0}' operation at path '{1}' could not be performed. + /// + internal static string CannotPerformOperation + { + get { return GetString("CannotPerformOperation"); } + } + + /// + /// The '{0}' operation at path '{1}' could not be performed. + /// + internal static string FormatCannotPerformOperation(object p0, object p1) + { + return string.Format(CultureInfo.CurrentCulture, GetString("CannotPerformOperation"), p0, p1); + } + /// /// The property at '{0}' could not be read. /// @@ -59,35 +75,35 @@ namespace Microsoft.AspNetCore.JsonPatch } /// - /// The key '{0}' was not found. + /// The index value provided by path segment '{0}' is out of bounds of the array size. /// - internal static string DictionaryKeyNotFound + internal static string IndexOutOfBounds { - get { return GetString("DictionaryKeyNotFound"); } + get { return GetString("IndexOutOfBounds"); } } /// - /// The key '{0}' was not found. + /// The index value provided by path segment '{0}' is out of bounds of the array size. /// - internal static string FormatDictionaryKeyNotFound(object p0) + internal static string FormatIndexOutOfBounds(object p0) { - return string.Format(CultureInfo.CurrentCulture, GetString("DictionaryKeyNotFound"), p0); + return string.Format(CultureInfo.CurrentCulture, GetString("IndexOutOfBounds"), p0); } /// - /// For operation '{0}' on array property at path '{1}', the index is larger than the array size. + /// The path segment '{0}' is invalid for an array index. /// - internal static string InvalidIndexForArrayProperty + internal static string InvalidIndexValue { - get { return GetString("InvalidIndexForArrayProperty"); } + get { return GetString("InvalidIndexValue"); } } /// - /// For operation '{0}' on array property at path '{1}', the index is larger than the array size. + /// The path segment '{0}' is invalid for an array index. /// - internal static string FormatInvalidIndexForArrayProperty(object p0, object p1) + internal static string FormatInvalidIndexValue(object p0) { - return string.Format(CultureInfo.CurrentCulture, GetString("InvalidIndexForArrayProperty"), p0, p1); + return string.Format(CultureInfo.CurrentCulture, GetString("InvalidIndexValue"), p0); } /// @@ -106,22 +122,6 @@ namespace Microsoft.AspNetCore.JsonPatch return string.Format(CultureInfo.CurrentCulture, GetString("InvalidJsonPatchDocument"), p0); } - /// - /// For operation '{0}', the provided path is invalid for array property at path '{1}'. - /// - internal static string InvalidPathForArrayProperty - { - get { return GetString("InvalidPathForArrayProperty"); } - } - - /// - /// For operation '{0}', the provided path is invalid for array property at path '{1}'. - /// - internal static string FormatInvalidPathForArrayProperty(object p0, object p1) - { - return string.Format(CultureInfo.CurrentCulture, GetString("InvalidPathForArrayProperty"), p0, p1); - } - /// /// The provided string '{0}' is an invalid path. /// @@ -139,7 +139,7 @@ namespace Microsoft.AspNetCore.JsonPatch } /// - /// The value '{0}' is invalid for property at path '{1}'. + /// The value '{0}' is invalid for target location. /// internal static string InvalidValueForProperty { @@ -147,27 +147,11 @@ namespace Microsoft.AspNetCore.JsonPatch } /// - /// The value '{0}' is invalid for property at path '{1}'. + /// The value '{0}' is invalid for target location. /// - internal static string FormatInvalidValueForProperty(object p0, object p1) + internal static string FormatInvalidValueForProperty(object p0) { - return string.Format(CultureInfo.CurrentCulture, GetString("InvalidValueForProperty"), p0, p1); - } - - /// - /// For operation '{0}' on array property at path '{1}', the index is negative. - /// - internal static string NegativeIndexForArrayProperty - { - get { return GetString("NegativeIndexForArrayProperty"); } - } - - /// - /// For operation '{0}' on array property at path '{1}', the index is negative. - /// - internal static string FormatNegativeIndexForArrayProperty(object p0, object p1) - { - return string.Format(CultureInfo.CurrentCulture, GetString("NegativeIndexForArrayProperty"), p0, p1); + return string.Format(CultureInfo.CurrentCulture, GetString("InvalidValueForProperty"), p0); } /// @@ -187,51 +171,67 @@ namespace Microsoft.AspNetCore.JsonPatch } /// - /// The property at path '{0}' could not be added. + /// The type '{0}' which is an array is not supported for json patch operations as it has a fixed size. /// - internal static string PropertyCannotBeAdded + internal static string PatchNotSupportedForArrays { - get { return GetString("PropertyCannotBeAdded"); } + get { return GetString("PatchNotSupportedForArrays"); } } /// - /// The property at path '{0}' could not be added. + /// The type '{0}' which is an array is not supported for json patch operations as it has a fixed size. /// - internal static string FormatPropertyCannotBeAdded(object p0) + internal static string FormatPatchNotSupportedForArrays(object p0) { - return string.Format(CultureInfo.CurrentCulture, GetString("PropertyCannotBeAdded"), p0); + return string.Format(CultureInfo.CurrentCulture, GetString("PatchNotSupportedForArrays"), p0); } /// - /// The property at path '{0}' could not be removed. + /// The type '{0}' which is a non generic list is not supported for json patch operations. Only generic list types are supported. /// - internal static string PropertyCannotBeRemoved + internal static string PatchNotSupportedForNonGenericLists { - get { return GetString("PropertyCannotBeRemoved"); } + get { return GetString("PatchNotSupportedForNonGenericLists"); } } /// - /// The property at path '{0}' could not be removed. + /// The type '{0}' which is a non generic list is not supported for json patch operations. Only generic list types are supported. /// - internal static string FormatPropertyCannotBeRemoved(object p0) + internal static string FormatPatchNotSupportedForNonGenericLists(object p0) { - return string.Format(CultureInfo.CurrentCulture, GetString("PropertyCannotBeRemoved"), p0); + return string.Format(CultureInfo.CurrentCulture, GetString("PatchNotSupportedForNonGenericLists"), p0); } /// - /// Property does not exist at path '{0}'. + /// The target location specified by path segment '{0}' was not found. /// - internal static string PropertyDoesNotExist + internal static string TargetLocationAtPathSegmentNotFound { - get { return GetString("PropertyDoesNotExist"); } + get { return GetString("TargetLocationAtPathSegmentNotFound"); } } /// - /// Property does not exist at path '{0}'. + /// The target location specified by path segment '{0}' was not found. /// - internal static string FormatPropertyDoesNotExist(object p0) + internal static string FormatTargetLocationAtPathSegmentNotFound(object p0) { - return string.Format(CultureInfo.CurrentCulture, GetString("PropertyDoesNotExist"), p0); + return string.Format(CultureInfo.CurrentCulture, GetString("TargetLocationAtPathSegmentNotFound"), p0); + } + + /// + /// For operation '{0}', the target location specified by path '{1}' was not found. + /// + internal static string TargetLocationNotFound + { + get { return GetString("TargetLocationNotFound"); } + } + + /// + /// For operation '{0}', the target location specified by path '{1}' was not found. + /// + internal static string FormatTargetLocationNotFound(object p0, object p1) + { + return string.Format(CultureInfo.CurrentCulture, GetString("TargetLocationNotFound"), p0, p1); } /// diff --git a/src/Microsoft.AspNetCore.JsonPatch/Resources.resx b/src/Microsoft.AspNetCore.JsonPatch/Resources.resx index 59ae2b59c3..a7b50520ac 100644 --- a/src/Microsoft.AspNetCore.JsonPatch/Resources.resx +++ b/src/Microsoft.AspNetCore.JsonPatch/Resources.resx @@ -120,44 +120,44 @@ The type of the property at path '{0}' could not be determined. + + The '{0}' operation at path '{1}' could not be performed. + The property at '{0}' could not be read. The property at path '{0}' could not be updated. - - The key '{0}' was not found. + + The index value provided by path segment '{0}' is out of bounds of the array size. - - For operation '{0}' on array property at path '{1}', the index is larger than the array size. + + The path segment '{0}' is invalid for an array index. The type '{0}' was malformed and could not be parsed. - - For operation '{0}', the provided path is invalid for array property at path '{1}'. - The provided string '{0}' is an invalid path. - The value '{0}' is invalid for property at path '{1}'. - - - For operation '{0}' on array property at path '{1}', the index is negative. + The value '{0}' is invalid for target location. '{0}' must be of type '{1}'. - - The property at path '{0}' could not be added. + + The type '{0}' which is an array is not supported for json patch operations as it has a fixed size. - - The property at path '{0}' could not be removed. + + The type '{0}' which is a non generic list is not supported for json patch operations. Only generic list types are supported. - - Property does not exist at path '{0}'. + + The target location specified by path segment '{0}' was not found. + + + For operation '{0}', the target location specified by path '{1}' was not found. The test operation is not supported. diff --git a/src/Microsoft.AspNetCore.JsonPatch/project.json b/src/Microsoft.AspNetCore.JsonPatch/project.json index 5180ee7e23..c9beba3639 100644 --- a/src/Microsoft.AspNetCore.JsonPatch/project.json +++ b/src/Microsoft.AspNetCore.JsonPatch/project.json @@ -22,14 +22,18 @@ }, "dependencies": { "NETStandard.Library": "1.6.1-*", - "Newtonsoft.Json": "9.0.1" + "Newtonsoft.Json": "9.0.1", + "Microsoft.Extensions.ClosedGenericMatcher.Sources": { + "type": "build", + "version": "1.1.0-*" + } }, "frameworks": { - "netstandard1.1": { + "net451": {}, + "netstandard1.3": { "dependencies": { "Microsoft.CSharp": "4.3.0-*", - "System.ComponentModel.TypeConverter": "4.3.0-*", - "System.Runtime.Serialization.Primitives": "4.3.0-*" + "System.Reflection.TypeExtensions": "4.1.0-*" } } } diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/DictionaryAdapterTest.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/DictionaryAdapterTest.cs new file mode 100644 index 0000000000..6a88bd6cc7 --- /dev/null +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/DictionaryAdapterTest.cs @@ -0,0 +1,176 @@ +// 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 Moq; +using Newtonsoft.Json.Serialization; +using Xunit; + +namespace Microsoft.AspNetCore.JsonPatch.Internal +{ + public class DictionaryAdapterTest + { + [Fact] + public void Add_KeyWhichAlreadyExists_ReplacesExistingValue() + { + // Arrange + var nameKey = "Name"; + var dictionary = new Dictionary(StringComparer.Ordinal); + dictionary[nameKey] = "Mike"; + var dictionaryAdapter = new DictionaryAdapter(); + var resolver = new Mock(MockBehavior.Strict); + string message = null; + + // Act + var addStatus = dictionaryAdapter.TryAdd(dictionary, nameKey, resolver.Object, "James", out message); + + // Assert + Assert.True(addStatus); + Assert.True(string.IsNullOrEmpty(message), "Expected no error message"); + Assert.Equal(1, dictionary.Count); + Assert.Equal("James", dictionary[nameKey]); + } + + [Fact] + public void Get_UsingCaseSensitiveKey_FailureScenario() + { + // Arrange + var dictionaryAdapter = new DictionaryAdapter(); + var resolver = new Mock(MockBehavior.Strict); + string message = null; + var nameKey = "Name"; + var dictionary = new Dictionary(StringComparer.Ordinal); + + // Act + var addStatus = dictionaryAdapter.TryAdd(dictionary, nameKey, resolver.Object, "James", out message); + + // Assert + Assert.True(addStatus); + Assert.True(string.IsNullOrEmpty(message), "Expected no error message"); + Assert.Equal(1, dictionary.Count); + Assert.Equal("James", dictionary[nameKey]); + + // Act + object outValue = null; + addStatus = dictionaryAdapter.TryGet(dictionary, nameKey.ToUpper(), resolver.Object, out outValue, out message); + + // Assert + Assert.True(addStatus); + Assert.True(string.IsNullOrEmpty(message), "Expected no error message"); + Assert.Null(outValue); + } + + [Fact] + public void Get_UsingCaseSensitiveKey_SuccessScenario() + { + // Arrange + var dictionaryAdapter = new DictionaryAdapter(); + var resolver = new Mock(MockBehavior.Strict); + string message = null; + var nameKey = "Name"; + var dictionary = new Dictionary(StringComparer.Ordinal); + + // Act + var addStatus = dictionaryAdapter.TryAdd(dictionary, nameKey, resolver.Object, "James", out message); + + // Assert + Assert.True(addStatus); + Assert.True(string.IsNullOrEmpty(message), "Expected no error message"); + Assert.Equal(1, dictionary.Count); + Assert.Equal("James", dictionary[nameKey]); + + // Act + object outValue = null; + addStatus = dictionaryAdapter.TryGet(dictionary, nameKey, resolver.Object, out outValue, out message); + + // Assert + Assert.True(addStatus); + Assert.True(string.IsNullOrEmpty(message), "Expected no error message"); + Assert.Equal("James", outValue?.ToString()); + } + + [Fact] + public void ReplacingExistingItem() + { + // Arrange + var nameKey = "Name"; + var dictionary = new Dictionary(StringComparer.Ordinal); + dictionary.Add(nameKey, "Mike"); + var dictionaryAdapter = new DictionaryAdapter(); + var resolver = new Mock(MockBehavior.Strict); + string message = null; + + // Act + var replaceStatus = dictionaryAdapter.TryReplace(dictionary, nameKey, resolver.Object, "James", out message); + + // Assert + Assert.True(replaceStatus); + Assert.True(string.IsNullOrEmpty(message), "Expected no error message"); + Assert.Equal(1, dictionary.Count); + Assert.Equal("James", dictionary[nameKey]); + } + + [Fact] + public void Replace_NonExistingKey_Fails() + { + // Arrange + var nameKey = "Name"; + var dictionary = new Dictionary(StringComparer.Ordinal); + var dictionaryAdapter = new DictionaryAdapter(); + var resolver = new Mock(MockBehavior.Strict); + string message = null; + + // Act + var replaceStatus = dictionaryAdapter.TryReplace(dictionary, nameKey, resolver.Object, "Mike", out message); + + // Assert + Assert.False(replaceStatus); + Assert.Equal( + string.Format("The target location specified by path segment '{0}' was not found.", nameKey), + message); + Assert.Equal(0, dictionary.Count); + } + + [Fact] + public void Remove_NonExistingKey_Fails() + { + // Arrange + var nameKey = "Name"; + var dictionary = new Dictionary(StringComparer.Ordinal); + var dictionaryAdapter = new DictionaryAdapter(); + var resolver = new Mock(MockBehavior.Strict); + string message = null; + + // Act + var removeStatus = dictionaryAdapter.TryRemove(dictionary, nameKey, resolver.Object, out message); + + // Assert + Assert.False(removeStatus); + Assert.Equal( + string.Format("The target location specified by path segment '{0}' was not found.", nameKey), + message); + Assert.Equal(0, dictionary.Count); + } + + [Fact] + public void Remove_RemovesFromDictionary() + { + // Arrange + var nameKey = "Name"; + var dictionary = new Dictionary(StringComparer.Ordinal); + dictionary[nameKey] = "James"; + var dictionaryAdapter = new DictionaryAdapter(); + var resolver = new Mock(MockBehavior.Strict); + string message = null; + + // Act + var removeStatus = dictionaryAdapter.TryRemove(dictionary, nameKey, resolver.Object, out message); + + //Assert + Assert.True(removeStatus); + Assert.True(string.IsNullOrEmpty(message), "Expected no error message"); + Assert.Equal(0, dictionary.Count); + } + } +} diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/AddOperationTests.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/AddOperationTests.cs index cb5f090d0f..cbd44a7ef9 100644 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/AddOperationTests.cs +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/AddOperationTests.cs @@ -32,7 +32,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic deserialized.ApplyTo(doc); }); Assert.Equal( - "The property at path '/NewInt' could not be added.", + string.Format("The target location specified by path segment '{0}' was not found.", "NewInt"), exception.Message); } @@ -76,7 +76,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic deserialized.ApplyTo(doc); }); Assert.Equal( - "The property at path '/Nested/NewInt' could not be added.", + string.Format("The target location specified by path segment '{0}' was not found.", "NewInt"), exception.Message); } @@ -101,7 +101,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic deserialized.ApplyTo(doc); }); Assert.Equal( - "The property at path '/Nested/NewInt' could not be added.", + string.Format("The target location specified by path segment '{0}' was not found.", "NewInt"), exception.Message); } @@ -214,7 +214,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic deserialized.ApplyTo(doc); }); Assert.Equal( - "The property at path '/ComplexProperty' could not be added.", + string.Format("The target location specified by path segment '{0}' was not found.", "ComplexProperty"), exception.Message); } @@ -238,7 +238,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic deserialized.ApplyTo(doc); }); Assert.Equal( - "The property at path '/StringProperty' could not be updated.", + string.Format("The property at path '{0}' could not be updated.", "StringProperty"), exception.Message); } @@ -336,7 +336,10 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic deserialized.ApplyTo(doc); }); Assert.Equal( - "The property at path '/DynamicProperty/OtherProperty/IntProperty' could not be added.", + string.Format( + "For operation '{0}', the target location specified by path '{1}' was not found.", + "add", + "/DynamicProperty/OtherProperty/IntProperty"), exception.Message); } @@ -374,7 +377,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic deserialized.ApplyTo(doc); }); Assert.Equal( - "The property at path '/baz/bat' could not be added.", + string.Format("The target location specified by path segment '{0}' was not found.", "baz"), exception.Message); } @@ -434,7 +437,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic deserialized.ApplyTo(doc); }); Assert.Equal( - "For operation 'add' on array property at path '/IntegerList/-1', the index is negative.", + string.Format("The index value provided by path segment '{0}' is out of bounds of the array size.", "-1"), exception.Message); } @@ -478,30 +481,10 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic deserialized.ApplyTo(doc); }); Assert.Equal( - "For operation 'add' on array property at path '/IntegerList/4', the index is larger than the array size.", + string.Format("The index value provided by path segment '{0}' is out of bounds of the array size.", "4"), exception.Message); } - [Fact] - public void AddToListAtEndWithSerialization() - { - var doc = new - { - IntegerList = new List() { 1, 2, 3 } - }; - - // create patch - JsonPatchDocument patchDoc = new JsonPatchDocument(); - patchDoc.Add("IntegerList/3", 4); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject(serialized); - - deserialized.ApplyTo(doc); - - Assert.Equal(new List() { 1, 2, 3, 4 }, doc.IntegerList); - } - [Fact] public void AddToListAtBeginning() { @@ -542,7 +525,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic deserialized.ApplyTo(doc); }); Assert.Equal( - "For operation 'add' on array property at path '/IntegerList/-1', the index is negative.", + string.Format("The index value provided by path segment '{0}' is out of bounds of the array size.", "-1"), exception.Message); } diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/AddTypedOperationTests.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/AddTypedOperationTests.cs index 098e97d850..f28d877ea4 100644 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/AddTypedOperationTests.cs +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/AddTypedOperationTests.cs @@ -30,7 +30,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic deserialized.ApplyTo(doc); }); Assert.Equal( - "For operation 'add' on array property at path '/IntegerList/-1', the index is negative.", + string.Format("The index value provided by path segment '{0}' is out of bounds of the array size.", "-1"), exception.Message); } @@ -85,7 +85,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic deserialized.ApplyTo(doc); }); Assert.Equal( - "The property at path '/ListOfSimpleDTO/-1/IntegerList/0' could not be added.", + string.Format("The index value provided by path segment '{0}' is out of bounds of the array size.", "-1"), exception.Message); } @@ -114,7 +114,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic deserialized.ApplyTo(doc); }); Assert.Equal( - "The property at path '/ListOfSimpleDTO/20/IntegerList/0' could not be added.", + string.Format("The index value provided by path segment '{0}' is out of bounds of the array size.", "20"), exception.Message); } } diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/RemoveOperationTests.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/RemoveOperationTests.cs index b436bb4d23..6e903bf2ec 100644 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/RemoveOperationTests.cs +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/RemoveOperationTests.cs @@ -31,7 +31,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic deserialized.ApplyTo(doc); }); Assert.Equal( - "The property at path '/Test' could not be updated.", + string.Format("The property at path '{0}' could not be updated.", "Test"), exception.Message); } @@ -53,7 +53,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic deserialized.ApplyTo(doc); }); Assert.Equal( - "The property at path '/NonExisting' could not be removed.", + string.Format("The target location specified by path segment '{0}' was not found.", "NonExisting"), exception.Message); } @@ -250,7 +250,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic deserialized.ApplyTo(doc); }); Assert.Equal( - "For operation 'remove' on array property at path '/SimpleDTO/IntegerList/3', the index is larger than the array size.", + string.Format("The index value provided by path segment '{0}' is out of bounds of the array size.", "3"), exception.Message); } @@ -275,8 +275,8 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic deserialized.ApplyTo(doc); }); Assert.Equal( - "For operation 'remove' on array property at path '/SimpleDTO/IntegerList/-1', the index is negative.", - exception.Message); + string.Format("The index value provided by path segment '{0}' is out of bounds of the array size.", "-1"), + exception.Message); } [Fact] diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/RemoveTypedOperationTests.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/RemoveTypedOperationTests.cs index d716dafe9a..126706eef2 100644 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/RemoveTypedOperationTests.cs +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/RemoveTypedOperationTests.cs @@ -70,7 +70,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic deserialized.ApplyTo(doc); }); Assert.Equal( - "For operation 'remove' on array property at path '/IntegerList/3', the index is larger than the array size.", + string.Format("The index value provided by path segment '{0}' is out of bounds of the array size.", "3"), exception.Message); } @@ -94,7 +94,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic deserialized.ApplyTo(doc); }); Assert.Equal( - "For operation 'remove' on array property at path '/IntegerList/-1', the index is negative.", + string.Format("The index value provided by path segment '{0}' is out of bounds of the array size.", "-1"), exception.Message); } @@ -187,8 +187,8 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic deserialized.ApplyTo(doc); }); Assert.Equal( - "For operation 'remove' on array property at path '/SimpleDTO/IntegerList/3', the index is larger than the array size.", - exception.Message); + string.Format("The index value provided by path segment '{0}' is out of bounds of the array size.", "3"), + exception.Message); } [Fact] @@ -214,7 +214,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic deserialized.ApplyTo(doc); }); Assert.Equal( - "For operation 'remove' on array property at path '/SimpleDTO/IntegerList/-1', the index is negative.", + string.Format("The index value provided by path segment '{0}' is out of bounds of the array size.", "-1"), exception.Message); } diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/ReplaceOperationTests.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/ReplaceOperationTests.cs index 8dff9b6a98..b8e7196068 100644 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/ReplaceOperationTests.cs +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/ReplaceOperationTests.cs @@ -6,6 +6,7 @@ using System.Collections.Generic; using System.Collections.ObjectModel; using System.Dynamic; using Newtonsoft.Json; +using Newtonsoft.Json.Linq; using Xunit; namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic @@ -25,7 +26,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic JsonPatchDocument patchDoc = new JsonPatchDocument(); patchDoc.Replace("GuidValue", newGuid); - // serialize & deserialize + // serialize & deserialize var serialized = JsonConvert.SerializeObject(patchDoc); var deserizalized = JsonConvert.DeserializeObject(serialized); @@ -45,7 +46,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic JsonPatchDocument patchDoc = new JsonPatchDocument(); patchDoc.Replace("GuidValue", newGuid); - // serialize & deserialize + // serialize & deserialize var serialized = JsonConvert.SerializeObject(patchDoc); var deserizalized = JsonConvert.DeserializeObject(serialized); @@ -70,7 +71,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic JsonPatchDocument patchDoc = new JsonPatchDocument(); patchDoc.Replace("nestedobject/GuidValue", newGuid); - // serialize & deserialize + // serialize & deserialize var serialized = JsonConvert.SerializeObject(patchDoc); var deserizalized = JsonConvert.DeserializeObject(serialized); @@ -98,7 +99,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic JsonPatchDocument patchDoc = new JsonPatchDocument(); patchDoc.Replace("SimpleDTO", newDTO); - // serialize & deserialize + // serialize & deserialize var serialized = JsonConvert.SerializeObject(patchDoc); var deserialized = JsonConvert.DeserializeObject(serialized); @@ -201,6 +202,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic var deserialized = JsonConvert.DeserializeObject(serialized); deserialized.ApplyTo(doc); + Assert.Equal(new List() { 4, 5, 6 }, doc.IntegerList); } diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/ListAdapterTest.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/ListAdapterTest.cs new file mode 100644 index 0000000000..ee331a2b30 --- /dev/null +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/ListAdapterTest.cs @@ -0,0 +1,302 @@ +// 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; +using System.Collections.Generic; +using Moq; +using Newtonsoft.Json.Serialization; +using Xunit; + +namespace Microsoft.AspNetCore.JsonPatch.Internal +{ + public class ListAdapterTest + { + [Fact] + public void Patch_OnArrayObject_Fails() + { + // Arrange + var resolver = new Mock(MockBehavior.Strict); + var targetObject = new[] { 20, 30 }; + var listAdapter = new ListAdapter(); + string message = null; + + // Act + var addStatus = listAdapter.TryAdd(targetObject, "0", resolver.Object, "40", out message); + + // Assert + Assert.False(addStatus); + Assert.Equal( + string.Format( + "The type '{0}' which is an array is not supported for json patch operations as it has a fixed size.", + targetObject.GetType().FullName), + message); + } + + [Fact] + public void Patch_OnNonGenericListObject_Fails() + { + // Arrange + var resolver = new Mock(MockBehavior.Strict); + var targetObject = new ArrayList(); + targetObject.Add(20); + targetObject.Add(30); + var listAdapter = new ListAdapter(); + string message = null; + + // Act + var addStatus = listAdapter.TryAdd(targetObject, "-", resolver.Object, "40", out message); + + // Assert + Assert.False(addStatus); + Assert.Equal( + string.Format( + "The type '{0}' which is a non generic list is not supported for json patch operations. Only generic list types are supported.", + targetObject.GetType().FullName), + message); + } + + [Theory] + [InlineData("-1")] + [InlineData("-2")] + [InlineData("2")] + [InlineData("3")] + public void Patch_WithOutOfBoundsIndex_Fails(string position) + { + // Arrange + var resolver = new Mock(MockBehavior.Strict); + var targetObject = new List() { "James", "Mike" }; + var listAdapter = new ListAdapter(); + string message = null; + + // Act + var addStatus = listAdapter.TryAdd(targetObject, position, resolver.Object, "40", out message); + + // Assert + Assert.False(addStatus); + Assert.Equal( + string.Format("The index value provided by path segment '{0}' is out of bounds of the array size.", position), + message); + } + + [Theory] + [InlineData("_")] + [InlineData("blah")] + public void Patch_WithInvalidPositionFormat_Fails(string position) + { + // Arrange + var resolver = new Mock(MockBehavior.Strict); + var targetObject = new List() { "James", "Mike" }; + var listAdapter = new ListAdapter(); + string message = null; + + // Act + var addStatus = listAdapter.TryAdd(targetObject, position, resolver.Object, "40", out message); + + // Assert + Assert.False(addStatus); + Assert.Equal( + string.Format("The path segment '{0}' is invalid for an array index.", position), + message); + } + + public static TheoryData, List> AppendAtEndOfListData + { + get + { + return new TheoryData, List>() + { + { + new List() { }, + new List() { 20 } + }, + { + new List() { 5, 10 }, + new List() { 5, 10, 20 } + } + }; + } + } + + [Theory] + [MemberData(nameof(AppendAtEndOfListData))] + public void Add_Appends_AtTheEnd(List targetObject, List expected) + { + // Arrange + var resolver = new Mock(MockBehavior.Strict); + var listAdapter = new ListAdapter(); + string message = null; + + // Act + var addStatus = listAdapter.TryAdd(targetObject, "-", resolver.Object, "20", out message); + + // Assert + Assert.True(addStatus); + Assert.True(string.IsNullOrEmpty(message), "Expected no error message"); + Assert.Equal(expected.Count, targetObject.Count); + Assert.Equal(expected, targetObject); + } + + [Fact] + public void Add_NullObject_ToReferenceTypeListWorks() + { + // Arrange + var resolver = new Mock(MockBehavior.Strict); + var listAdapter = new ListAdapter(); + var targetObject = new List() { "James", "Mike" }; + string message = null; + + // Act + var addStatus = listAdapter.TryAdd(targetObject, "-", resolver.Object, value: null, errorMessage: out message); + + // Assert + Assert.True(addStatus); + Assert.True(string.IsNullOrEmpty(message), "Expected no error message"); + Assert.Equal(3, targetObject.Count); + Assert.Equal(new List() { "James", "Mike", null }, targetObject); + } + + [Fact] + public void Add_NonCompatibleType_Fails() + { + // Arrange + var resolver = new Mock(MockBehavior.Strict); + var targetObject = (new List() { 10, 20 }).AsReadOnly(); + var listAdapter = new ListAdapter(); + string message = null; + + // Act + var addStatus = listAdapter.TryAdd(targetObject, "-", resolver.Object, "James", out message); + + // Assert + Assert.False(addStatus); + Assert.Equal(string.Format("The value '{0}' is invalid for target location.", "James"), message); + } + + public static TheoryData AddingDifferentComplexTypeWorksData + { + get + { + return new TheoryData() + { + { + new List() { }, + "a", + "-", + new List() { "a" } + }, + { + new List() { "a", "b" }, + "c", + "-", + new List() { "a", "b", "c" } + }, + { + new List() { "a", "b" }, + "c", + "0", + new List() { "c", "a", "b" } + }, + { + new List() { "a", "b" }, + "c", + "1", + new List() { "a", "c", "b" } + } + }; + } + } + + [Theory] + [MemberData(nameof(AddingDifferentComplexTypeWorksData))] + public void Add_DifferentComplexTypeWorks(IList targetObject, object value, string position, IList expected) + { + // Arrange + var resolver = new Mock(MockBehavior.Strict); + var listAdapter = new ListAdapter(); + string message = null; + + // Act + var addStatus = listAdapter.TryAdd(targetObject, position, resolver.Object, value, out message); + + // Assert + Assert.True(addStatus); + Assert.True(string.IsNullOrEmpty(message), "Expected no error message"); + Assert.Equal(expected.Count, targetObject.Count); + Assert.Equal(expected, targetObject); + } + + [Fact] + public void Replace_NonCompatibleType_Fails() + { + // Arrange + var resolver = new Mock(MockBehavior.Strict); + var targetObject = (new List() { 10, 20 }).AsReadOnly(); + var listAdapter = new ListAdapter(); + string message = null; + + // Act + var replaceStatus = listAdapter.TryReplace(targetObject, "-", resolver.Object, "James", out message); + + // Assert + Assert.False(replaceStatus); + Assert.Equal( + string.Format("The value '{0}' is invalid for target location.", "James"), + message); + } + + [Fact] + public void Replace_ReplacesValue_AtTheEnd() + { + // Arrange + var resolver = new Mock(MockBehavior.Strict); + var targetObject = new List() { 10, 20 }; + var listAdapter = new ListAdapter(); + string message = null; + + // Act + var replaceStatus = listAdapter.TryReplace(targetObject, "-", resolver.Object, "30", out message); + + // Assert + Assert.True(replaceStatus); + Assert.True(string.IsNullOrEmpty(message), "Expected no error message"); + Assert.Equal(new List() { 10, 30 }, targetObject); + } + + public static TheoryData> ReplacesValuesAtPositionData + { + get + { + return new TheoryData>() + { + { + "0", + new List() { 30, 20 } + }, + { + "1", + new List() { 10, 30 } + } + }; + } + } + + [Theory] + [MemberData(nameof(ReplacesValuesAtPositionData))] + public void Replace_ReplacesValue_AtGivenPosition(string position, List expected) + { + // Arrange + var resolver = new Mock(MockBehavior.Strict); + var targetObject = new List() { 10, 20 }; + var listAdapter = new ListAdapter(); + string message = null; + + // Act + var replaceStatus = listAdapter.TryReplace(targetObject, position, resolver.Object, "30", out message); + + // Assert + Assert.True(replaceStatus); + Assert.True(string.IsNullOrEmpty(message), "Expected no error message"); + Assert.Equal(expected, targetObject); + } + } +} diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/NestedDTO.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/NestedDTO.cs index aa767557c3..90be5152cb 100644 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/NestedDTO.cs +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/NestedDTO.cs @@ -1,7 +1,7 @@ // 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.Test +namespace Microsoft.AspNetCore.JsonPatch { public class NestedDTO { diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/NestedObjectTests.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/NestedObjectTests.cs index 6215da6bcd..345ffe2201 100644 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/NestedObjectTests.cs +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/NestedObjectTests.cs @@ -7,7 +7,7 @@ using Microsoft.AspNetCore.JsonPatch.Exceptions; using Newtonsoft.Json; using Xunit; -namespace Microsoft.AspNetCore.JsonPatch.Test +namespace Microsoft.AspNetCore.JsonPatch { public class NestedObjectTests { @@ -386,8 +386,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test // Act & Assert var exception = Assert.Throws(() => { patchDoc.ApplyTo(doc); }); Assert.Equal( - "For operation 'add' on array property at path '/simpledto/integerlist/4', the index is " + - "larger than the array size.", + string.Format("The index value provided by path segment '{0}' is out of bounds of the array size.", "4"), exception.Message); } @@ -417,8 +416,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test deserialized.ApplyTo(doc); }); Assert.Equal( - "For operation 'add' on array property at path '/simpledto/integerlist/4', the index is " + - "larger than the array size.", + string.Format("The index value provided by path segment '{0}' is out of bounds of the array size.", "4"), exception.Message); } @@ -445,8 +443,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test //Assert Assert.Equal( - "For operation 'add' on array property at path '/simpledto/integerlist/4', the index is larger than " + - "the array size.", + string.Format("The index value provided by path segment '{0}' is out of bounds of the array size.", "4"), logger.ErrorMessage); } @@ -470,7 +467,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test // Act & Assert var exception = Assert.Throws(() => { patchDoc.ApplyTo(doc); }); Assert.Equal( - "For operation 'add' on array property at path '/simpledto/integerlist/-1', the index is negative.", + string.Format("The index value provided by path segment '{0}' is out of bounds of the array size.", "-1"), exception.Message); } @@ -499,7 +496,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test deserialized.ApplyTo(doc); }); Assert.Equal( - "For operation 'add' on array property at path '/simpledto/integerlist/-1', the index is negative.", + string.Format("The index value provided by path segment '{0}' is out of bounds of the array size.", "-1"), exception.Message); } @@ -527,7 +524,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test //Assert Assert.Equal( - "For operation 'add' on array property at path '/simpledto/integerlist/-1', the index is negative.", + string.Format("The index value provided by path segment '{0}' is out of bounds of the array size.", "-1"), logger.ErrorMessage); } @@ -697,8 +694,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test // Act & Assert var exception = Assert.Throws(() => { patchDoc.ApplyTo(doc); }); Assert.Equal( - "For operation 'remove' on array property at path '/simpledto/integerlist/3', the index is " + - "larger than the array size.", + string.Format("The index value provided by path segment '{0}' is out of bounds of the array size.", "3"), exception.Message); } @@ -727,8 +723,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test deserialized.ApplyTo(doc); }); Assert.Equal( - "For operation 'remove' on array property at path '/simpledto/integerlist/3', the index is " + - "larger than the array size.", + string.Format("The index value provided by path segment '{0}' is out of bounds of the array size.", "3"), exception.Message); } @@ -754,8 +749,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test // Assert Assert.Equal( - "For operation 'remove' on array property at path '/simpledto/integerlist/3', the index is " + - "larger than the array size.", + string.Format("The index value provided by path segment '{0}' is out of bounds of the array size.", "3"), logger.ErrorMessage); } @@ -777,7 +771,9 @@ namespace Microsoft.AspNetCore.JsonPatch.Test // Act & Assert var exception = Assert.Throws(() => { patchDoc.ApplyTo(doc); }); - Assert.Equal("For operation 'remove' on array property at path '/simpledto/integerlist/-1', the index is negative.", exception.Message); + Assert.Equal( + string.Format("The index value provided by path segment '{0}' is out of bounds of the array size.", "-1"), + exception.Message); } [Fact] @@ -804,7 +800,9 @@ namespace Microsoft.AspNetCore.JsonPatch.Test { deserialized.ApplyTo(doc); }); - Assert.Equal("For operation 'remove' on array property at path '/simpledto/integerlist/-1', the index is negative.", exception.Message); + Assert.Equal( + string.Format("The index value provided by path segment '{0}' is out of bounds of the array size.", "-1"), + exception.Message); } [Fact] @@ -829,7 +827,9 @@ namespace Microsoft.AspNetCore.JsonPatch.Test patchDoc.ApplyTo(doc, logger.LogErrorMessage); // Assert - Assert.Equal("For operation 'remove' on array property at path '/simpledto/integerlist/-1', the index is negative.", logger.ErrorMessage); + Assert.Equal( + string.Format("The index value provided by path segment '{0}' is out of bounds of the array size.", "-1"), + logger.ErrorMessage); } [Fact] @@ -1239,8 +1239,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test // Act & Assert var exception = Assert.Throws(() => { patchDoc.ApplyTo(doc); }); Assert.Equal( - "For operation 'replace' on array property at path '/simpledto/integerlist/3', the index is " + - "larger than the array size.", + string.Format("The index value provided by path segment '{0}' is out of bounds of the array size.", "3"), exception.Message); } @@ -1269,8 +1268,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test deserialized.ApplyTo(doc); }); Assert.Equal( - "For operation 'replace' on array property at path '/simpledto/integerlist/3', the index is " + - "larger than the array size.", + string.Format("The index value provided by path segment '{0}' is out of bounds of the array size.", "3"), exception.Message); } @@ -1298,8 +1296,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test // Assert Assert.Equal( - "For operation 'replace' on array property at path '/simpledto/integerlist/3', the index is " + - "larger than the array size.", + string.Format("The index value provided by path segment '{0}' is out of bounds of the array size.", "3"), logger.ErrorMessage); } @@ -1321,7 +1318,8 @@ namespace Microsoft.AspNetCore.JsonPatch.Test // Act & Assert var exception = Assert.Throws(() => { patchDoc.ApplyTo(doc); }); - Assert.Equal("For operation 'replace' on array property at path '/simpledto/integerlist/-1', the index is negative.", + Assert.Equal( + string.Format("The index value provided by path segment '{0}' is out of bounds of the array size.", "-1"), exception.Message); } @@ -1347,7 +1345,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test // Act & Assert var exception = Assert.Throws(() => { deserialized.ApplyTo(doc); }); Assert.Equal( - "For operation 'replace' on array property at path '/simpledto/integerlist/-1', the index is negative.", + string.Format("The index value provided by path segment '{0}' is out of bounds of the array size.", "-1"), exception.Message); } @@ -1375,7 +1373,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test // Assert Assert.Equal( - "For operation 'replace' on array property at path '/simpledto/integerlist/-1', the index is negative.", + string.Format("The index value provided by path segment '{0}' is out of bounds of the array size.", "-1"), logger.ErrorMessage); } diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/ObjectAdapterTests.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/ObjectAdapterTests.cs index 98a72e1bf8..88693fdbd5 100644 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/ObjectAdapterTests.cs +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/ObjectAdapterTests.cs @@ -8,7 +8,7 @@ using Microsoft.AspNetCore.JsonPatch.Exceptions; using Newtonsoft.Json; using Xunit; -namespace Microsoft.AspNetCore.JsonPatch.Test +namespace Microsoft.AspNetCore.JsonPatch.Adapters { public class ObjectAdapterTests { @@ -157,8 +157,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test // Act & Assert var exception = Assert.Throws(() => { patchDoc.ApplyTo(doc); }); Assert.Equal( - "For operation 'add' on array property at path '/integerlist/4', the index is " + - "larger than the array size.", + string.Format("The index value provided by path segment '{0}' is out of bounds of the array size.", "4"), exception.Message); } @@ -181,8 +180,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test // Act & Assert var exception = Assert.Throws(() => { deserialized.ApplyTo(doc); }); Assert.Equal( - "For operation 'add' on array property at path '/integerlist/4', the index is " + - "larger than the array size.", + string.Format("The index value provided by path segment '{0}' is out of bounds of the array size.", "4"), exception.Message); } @@ -206,54 +204,10 @@ namespace Microsoft.AspNetCore.JsonPatch.Test // Assert Assert.Equal( - "For operation 'add' on array property at path '/integerlist/4', the index is " + - "larger than the array size.", + string.Format("The index value provided by path segment '{0}' is out of bounds of the array size.", "4"), logger.ErrorMessage); } - [Fact] - public void AddToListAtEnd() - { - // Arrange - var doc = new SimpleDTO() - { - IntegerList = new List() { 1, 2, 3 } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Add(o => o.IntegerList, 4, 3); - - // Act - patchDoc.ApplyTo(doc); - - // Assert - Assert.Equal(new List() { 1, 2, 3, 4 }, doc.IntegerList); - } - - [Fact] - public void AddToListAtEndWithSerialization() - { - // Arrange - var doc = new SimpleDTO() - { - IntegerList = new List() { 1, 2, 3 } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Add(o => o.IntegerList, 4, 3); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject>(serialized); - - // Act - deserialized.ApplyTo(doc); - - // Assert - Assert.Equal(new List() { 1, 2, 3, 4 }, doc.IntegerList); - } - [Fact] public void AddToListAtBeginning() { @@ -313,7 +267,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test // Act & Assert var exception = Assert.Throws(() => { patchDoc.ApplyTo(doc); }); Assert.Equal( - "For operation 'add' on array property at path '/integerlist/-1', the index is negative.", + string.Format("The index value provided by path segment '{0}' is out of bounds of the array size.", "-1"), exception.Message); } @@ -336,7 +290,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test // Act & Assert var exception = Assert.Throws(() => { deserialized.ApplyTo(doc); }); Assert.Equal( - "For operation 'add' on array property at path '/integerlist/-1', the index is negative.", + string.Format("The index value provided by path segment '{0}' is out of bounds of the array size.", "-1"), exception.Message); } @@ -359,7 +313,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test // Assert Assert.Equal( - "For operation 'add' on array property at path '/integerlist/-1', the index is negative.", + string.Format("The index value provided by path segment '{0}' is out of bounds of the array size.", "-1"), logger.ErrorMessage); } @@ -508,8 +462,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test // Act & Assert var exception = Assert.Throws(() => { patchDoc.ApplyTo(doc); }); Assert.Equal( - "For operation 'remove' on array property at path '/integerlist/3', the index is " + - "larger than the array size.", + string.Format("The index value provided by path segment '{0}' is out of bounds of the array size.", "3"), exception.Message); } @@ -532,8 +485,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test // Act & Assert var exception = Assert.Throws(() => { deserialized.ApplyTo(doc); }); Assert.Equal( - "For operation 'remove' on array property at path '/integerlist/3', the index is " + - "larger than the array size.", + string.Format("The index value provided by path segment '{0}' is out of bounds of the array size.", "3"), exception.Message); } @@ -557,8 +509,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test // Assert Assert.Equal( - "For operation 'remove' on array property at path '/integerlist/3', the index is " + - "larger than the array size.", + string.Format("The index value provided by path segment '{0}' is out of bounds of the array size.", "3"), logger.ErrorMessage); } @@ -577,7 +528,9 @@ namespace Microsoft.AspNetCore.JsonPatch.Test // Act & Assert var exception = Assert.Throws(() => { patchDoc.ApplyTo(doc); }); - Assert.Equal("For operation 'remove' on array property at path '/integerlist/-1', the index is negative.", exception.Message); + Assert.Equal( + string.Format("The index value provided by path segment '{0}' is out of bounds of the array size.", "-1"), + exception.Message); } [Fact] @@ -598,7 +551,9 @@ namespace Microsoft.AspNetCore.JsonPatch.Test // Act & Assert var exception = Assert.Throws(() => { deserialized.ApplyTo(doc); }); - Assert.Equal("For operation 'remove' on array property at path '/integerlist/-1', the index is negative.", exception.Message); + Assert.Equal( + string.Format("The index value provided by path segment '{0}' is out of bounds of the array size.", "-1"), + exception.Message); } [Fact] @@ -621,7 +576,9 @@ namespace Microsoft.AspNetCore.JsonPatch.Test // Assert - Assert.Equal("For operation 'remove' on array property at path '/integerlist/-1', the index is negative.", logger.ErrorMessage); + Assert.Equal( + string.Format("The index value provided by path segment '{0}' is out of bounds of the array size.", "-1"), + logger.ErrorMessage); } [Fact] @@ -1123,8 +1080,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test patchDoc.ApplyTo(doc); }); Assert.Equal( - "For operation 'replace' on array property at path '/integerlist/3', the index is " + - "larger than the array size.", + string.Format("The index value provided by path segment '{0}' is out of bounds of the array size.", "3"), exception.Message); } @@ -1149,8 +1105,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test deserialized.ApplyTo(doc); }); Assert.Equal( - "For operation 'replace' on array property at path '/integerlist/3', the index is " + - "larger than the array size.", + string.Format("The index value provided by path segment '{0}' is out of bounds of the array size.", "3"), exception.Message); } @@ -1172,7 +1127,9 @@ namespace Microsoft.AspNetCore.JsonPatch.Test { patchDoc.ApplyTo(doc); }); - Assert.Equal("For operation 'replace' on array property at path '/integerlist/-1', the index is negative.", exception.Message); + Assert.Equal( + string.Format("The index value provided by path segment '{0}' is out of bounds of the array size.", "-1"), + exception.Message); } [Fact] @@ -1196,7 +1153,9 @@ namespace Microsoft.AspNetCore.JsonPatch.Test { deserialized.ApplyTo(doc); }); - Assert.Equal("For operation 'replace' on array property at path '/integerlist/-1', the index is negative.", exception.Message); + Assert.Equal( + string.Format("The index value provided by path segment '{0}' is out of bounds of the array size.", "-1"), + exception.Message); } [Fact] @@ -1733,5 +1692,577 @@ namespace Microsoft.AspNetCore.JsonPatch.Test Assert.Equal(0, doc.IntegerValue); Assert.Equal(new List() { 1, 2, 3, 5 }, doc.IntegerList); } + + private class Class6 + { + public IDictionary DictionaryOfStringToInteger { get; } = new Dictionary(); + } + + [Fact] + public void Add_WhenDictionary_ValueIsNonObject_Succeeds() + { + // Arrange + var model = new Class6(); + model.DictionaryOfStringToInteger["one"] = 1; + model.DictionaryOfStringToInteger["two"] = 2; + var patchDocument = new JsonPatchDocument(); + patchDocument.Add("/DictionaryOfStringToInteger/three", 3); + + // Act + patchDocument.ApplyTo(model); + + // Assert + Assert.Equal(3, model.DictionaryOfStringToInteger.Count); + Assert.Equal(1, model.DictionaryOfStringToInteger["one"]); + Assert.Equal(2, model.DictionaryOfStringToInteger["two"]); + Assert.Equal(3, model.DictionaryOfStringToInteger["three"]); + } + + [Fact] + public void Remove_WhenDictionary_ValueIsNonObject_Succeeds() + { + // Arrange + var model = new Class6(); + model.DictionaryOfStringToInteger["one"] = 1; + model.DictionaryOfStringToInteger["two"] = 2; + var patchDocument = new JsonPatchDocument(); + patchDocument.Remove("/DictionaryOfStringToInteger/two"); + + // Act + patchDocument.ApplyTo(model); + + // Assert + Assert.Equal(1, model.DictionaryOfStringToInteger.Count); + Assert.Equal(1, model.DictionaryOfStringToInteger["one"]); + } + + [Fact] + public void Replace_WhenDictionary_ValueIsNonObject_Succeeds() + { + // Arrange + var model = new Class6(); + model.DictionaryOfStringToInteger["one"] = 1; + model.DictionaryOfStringToInteger["two"] = 2; + var patchDocument = new JsonPatchDocument(); + patchDocument.Replace("/DictionaryOfStringToInteger/two", 20); + + // Act + patchDocument.ApplyTo(model); + + // Assert + Assert.Equal(2, model.DictionaryOfStringToInteger.Count); + Assert.Equal(1, model.DictionaryOfStringToInteger["one"]); + Assert.Equal(20, model.DictionaryOfStringToInteger["two"]); + } + + private class Customer + { + public string Name { get; set; } + public Address Address { get; set; } + } + + private class Address + { + public string City { get; set; } + } + + private class Class8 + { + public IDictionary DictionaryOfStringToCustomer { get; } = new Dictionary(); + } + + [Fact] + public void Replace_WhenDictionary_ValueAPocoType_Succeeds() + { + // Arrange + var key1 = "key1"; + var value1 = new Customer() { Name = "Jamesss" }; + var key2 = "key2"; + var value2 = new Customer() { Name = "Mike" }; + var model = new Class8(); + model.DictionaryOfStringToCustomer[key1] = value1; + model.DictionaryOfStringToCustomer[key2] = value2; + var patchDocument = new JsonPatchDocument(); + patchDocument.Replace($"/DictionaryOfStringToCustomer/{key1}/Name", "James"); + + // Act + patchDocument.ApplyTo(model); + + // Assert + Assert.Equal(2, model.DictionaryOfStringToCustomer.Count); + var actualValue1 = model.DictionaryOfStringToCustomer[key1]; + Assert.NotNull(actualValue1); + Assert.Equal("James", actualValue1.Name); + } + + [Fact] + public void Replace_WhenDictionary_ValueAPocoType_Succeeds_WithSerialization() + { + // Arrange + var key1 = "key1"; + var value1 = new Customer() { Name = "Jamesss" }; + var key2 = "key2"; + var value2 = new Customer() { Name = "Mike" }; + var model = new Class8(); + model.DictionaryOfStringToCustomer[key1] = value1; + model.DictionaryOfStringToCustomer[key2] = value2; + var patchDocument = new JsonPatchDocument(); + patchDocument.Replace($"/DictionaryOfStringToCustomer/{key1}/Name", "James"); + var serialized = JsonConvert.SerializeObject(patchDocument); + var deserialized = JsonConvert.DeserializeObject>(serialized); + + // Act + patchDocument.ApplyTo(model); + + // Assert + Assert.Equal(2, model.DictionaryOfStringToCustomer.Count); + var actualValue1 = model.DictionaryOfStringToCustomer[key1]; + Assert.NotNull(actualValue1); + Assert.Equal("James", actualValue1.Name); + } + + [Fact] + public void Replace_DeepNested_DictionaryValue_Succeeds() + { + // Arrange + var key1 = "key1"; + var value1 = new Customer() { Name = "Jamesss" }; + var key2 = "key2"; + var value2 = new Customer() { Name = "Mike" }; + var model = new Class8(); + model.DictionaryOfStringToCustomer[key1] = value1; + model.DictionaryOfStringToCustomer[key2] = value2; + var patchDocument = new JsonPatchDocument(); + patchDocument.Replace($"/DictionaryOfStringToCustomer/{key1}/Name", "James"); + + // Act + patchDocument.ApplyTo(model); + + // Assert + Assert.Equal(2, model.DictionaryOfStringToCustomer.Count); + var actualValue1 = model.DictionaryOfStringToCustomer[key1]; + Assert.NotNull(actualValue1); + Assert.Equal("James", actualValue1.Name); + } + + [Fact] + public void Replace_DeepNested_DictionaryValue_Succeeds_WithSerialization() + { + // Arrange + var key1 = "key1"; + var value1 = new Customer() { Name = "James", Address = new Address { City = "Redmond" } }; + var key2 = "key2"; + var value2 = new Customer() { Name = "Mike", Address = new Address { City = "Seattle" } }; + var model = new Class8(); + model.DictionaryOfStringToCustomer[key1] = value1; + model.DictionaryOfStringToCustomer[key2] = value2; + var patchDocument = new JsonPatchDocument(); + patchDocument.Replace($"/DictionaryOfStringToCustomer/{key1}/Address/City", "Bellevue"); + var serialized = JsonConvert.SerializeObject(patchDocument); + var deserialized = JsonConvert.DeserializeObject>(serialized); + + // Act + patchDocument.ApplyTo(model); + + // Assert + Assert.Equal(2, model.DictionaryOfStringToCustomer.Count); + var actualValue1 = model.DictionaryOfStringToCustomer[key1]; + Assert.NotNull(actualValue1); + Assert.Equal("James", actualValue1.Name); + var address = actualValue1.Address; + Assert.NotNull(address); + Assert.Equal("Bellevue", address.City); + } + + class Class9 + { + public List StringList { get; set; } = new List(); + } + + [Fact] + public void AddToNonIntegerListAtEnd() + { + // Arrange + var model = new Class9() + { + StringList = new List() + }; + model.StringList.Add("string1"); + model.StringList.Add("string2"); + var patchDoc = new JsonPatchDocument(); + patchDoc.Add("/StringList/0", "string3"); + + // Act + patchDoc.ApplyTo(model); + + // Assert + Assert.Equal(new List() { "string3", "string1", "string2" }, model.StringList); + } + + [Fact] + public void AddMember_OnPOCO_WithNullPropertyValue_ShouldAddPropertyValue() + { + // Arrange + var doc = new SimpleDTO() + { + StringProperty = null + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Add(o => o.StringProperty, "B"); + + // Act + patchDoc.ApplyTo(doc); + + // Assert + Assert.Equal("B", doc.StringProperty); + } + + private class Class1 + { + public IDictionary USStates { get; set; } = new Dictionary(); + } + + [Fact] + public void AddMember_OnDictionaryProperty_ShouldAddKeyValueMember() + { + // Arrange + var expected = "Washington"; + var model = new Class1(); + var patchDoc = new JsonPatchDocument(); + patchDoc.Add("/USStates/WA", expected); + + // Act + patchDoc.ApplyTo(model); + + // Assert + Assert.Equal(1, model.USStates.Count); + Assert.Equal(expected, model.USStates["WA"]); + } + + [Fact] + public void AddMember_OnDictionaryProperty_ShouldAddKeyValueMember_WithSerialization() + { + // Arrange + var expected = "Washington"; + var model = new Class1(); + var patchDoc = new JsonPatchDocument(); + patchDoc.Add("/USStates/WA", expected); + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject>(serialized); + + // Act + deserialized.ApplyTo(model); + + // Assert + Assert.Equal(1, model.USStates.Count); + Assert.Equal(expected, model.USStates["WA"]); + } + + private class Class2 + { + public Class1 Class1Property { get; set; } = new Class1(); + } + + [Fact] + public void AddMember_OnDictionaryPropertyDeeplyNested_ShouldAddKeyValueMember() + { + // Arrange + var expected = "Washington"; + var model = new Class2(); + var patchDoc = new JsonPatchDocument(); + patchDoc.Add("/Class1Property/USStates/WA", expected); + + // Act + patchDoc.ApplyTo(model); + + // Assert + Assert.Equal(1, model.Class1Property.USStates.Count); + Assert.Equal(expected, model.Class1Property.USStates["WA"]); + } + + [Fact] + public void AddMember_OnDictionaryPropertyDeeplyNested_ShouldAddKeyValueMember_WithSerialization() + { + // Arrange + var expected = "Washington"; + var model = new Class2(); + var patchDoc = new JsonPatchDocument(); + patchDoc.Add("/Class1Property/USStates/WA", expected); + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject>(serialized); + + // Act + deserialized.ApplyTo(model); + + // Assert + Assert.Equal(1, model.Class1Property.USStates.Count); + Assert.Equal(expected, model.Class1Property.USStates["WA"]); + } + + [Fact] + public void AddMember_OnDictionaryObjectDirectly_ShouldAddKeyValueMember() + { + // Arrange + var expected = "Washington"; + var model = new Dictionary(); + var patchDoc = new JsonPatchDocument(); + patchDoc.Add("/WA", expected); + + // Act + patchDoc.ApplyTo(model); + + // Assert + Assert.Equal(1, model.Count); + Assert.Equal(expected, model["WA"]); + } + + [Fact] + public void AddMember_OnDictionaryObjectDirectly_ShouldAddKeyValueMember_WithSerialization() + { + // Arrange + var expected = "Washington"; + var model = new Dictionary(); + var patchDoc = new JsonPatchDocument(); + patchDoc.Add("/WA", expected); + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject>>(serialized); + + // Act + deserialized.ApplyTo(model); + + // Assert + Assert.Equal(1, model.Count); + Assert.Equal(expected, model["WA"]); + } + + [Fact] + public void AddElement_ToListDirectly_ShouldAppendValue() + { + // Arrange + var model = new List() { 1, 2, 3 }; + var patchDoc = new JsonPatchDocument(); + patchDoc.Add("/-", value: 4); + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject>>(serialized); + + // Act + deserialized.ApplyTo(model); + + // Assert + Assert.Equal(new List() { 1, 2, 3, 4 }, model); + } + + [Fact] + public void AddElement_ToListDirectly_ShouldAppendValue_WithSerialization() + { + // Arrange + var model = new List() { 1, 2, 3 }; + var patchDoc = new JsonPatchDocument(); + patchDoc.Add("/-", value: 4); + + // Act + patchDoc.ApplyTo(model); + + // Assert + Assert.Equal(new List() { 1, 2, 3, 4 }, model); + } + + [Fact] + public void AddElement_ToListDirectly_ShouldAddValue_AtSuppliedPosition() + { + // Arrange + var model = new List() { 1, 2, 3 }; + var patchDoc = new JsonPatchDocument(); + patchDoc.Add("/0", value: 4); + + // Act + patchDoc.ApplyTo(model); + + // Assert + Assert.Equal(new List() { 4, 1, 2, 3 }, model); + } + + [Fact] + public void AddElement_ToListDirectly_ShouldAddValue_AtSuppliedPosition_WithSerialization() + { + // Arrange + var model = new List() { 1, 2, 3 }; + var patchDoc = new JsonPatchDocument(); + patchDoc.Add("/0", value: 4); + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject>>(serialized); + + // Act + deserialized.ApplyTo(model); + + // Assert + Assert.Equal(new List() { 4, 1, 2, 3 }, model); + } + + class ListOnDictionary + { + public IDictionary> NamesAndBadgeIds { get; set; } = new Dictionary>(); + } + + [Fact] + public void AddElement_ToList_OnDictionary_ShouldAddValue_AtSuppliedPosition() + { + // Arrange + var model = new ListOnDictionary(); + model.NamesAndBadgeIds["James"] = new List(); + var patchDoc = new JsonPatchDocument(); + patchDoc.Add("/NamesAndBadgeIds/James/-", 200); + + // Act + patchDoc.ApplyTo(model); + + // Assert + var list = model.NamesAndBadgeIds["James"]; + Assert.NotNull(list); + Assert.Equal(new List() { 200 }, list); + } + + [Fact] + public void AddElement_ToList_OnPOCO_ShouldAddValue_AtSuppliedPosition() + { + // Arrange + var doc = new SimpleDTO() + { + IntegerIList = new List() { 1, 2, 3 } + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Add(o => o.IntegerIList, 4, 0); + + // Act + patchDoc.ApplyTo(doc); + + // Assert + Assert.Equal(new List() { 4, 1, 2, 3 }, doc.IntegerIList); + } + + class Class3 + { + public SimpleDTO SimpleDTOProperty { get; set; } = new SimpleDTO(); + } + + [Fact] + public void AddElement_ToDeeplyNestedListProperty_OnPOCO_ShouldAddValue_AtSuppliedPosition() + { + // Arrange + var model = new Class3() + { + SimpleDTOProperty = new SimpleDTO() + { + IntegerIList = new List() { 1, 2, 3 } + } + }; + var patchDoc = new JsonPatchDocument(); + patchDoc.Add(o => o.SimpleDTOProperty.IntegerIList, value: 4, position: 0); + + // Act + patchDoc.ApplyTo(model); + + // Assert + Assert.Equal(new List() { 4, 1, 2, 3 }, model.SimpleDTOProperty.IntegerIList); + } + + [Fact] + public void AddElement_ToDeeplyNestedListProperty_OnPOCO_ShouldAddValue_AtSuppliedPosition_WithSerialization() + { + // Arrange + var model = new Class3() + { + SimpleDTOProperty = new SimpleDTO() + { + IntegerIList = new List() { 1, 2, 3 } + } + }; + var patchDoc = new JsonPatchDocument(); + patchDoc.Add(o => o.SimpleDTOProperty.IntegerIList, value: 4, position: 0); + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject>(serialized); + + // Act + deserialized.ApplyTo(model); + + // Assert + Assert.Equal(new List() { 4, 1, 2, 3 }, model.SimpleDTOProperty.IntegerIList); + } + + class Class4 + { + public int IntegerProperty { get; set; } + } + + [Fact] + public void Remove_OnNonReferenceType_POCOProperty_ShouldSetDefaultValue() + { + // Arrange + var model = new Class4() + { + IntegerProperty = 10 + }; + var patchDoc = new JsonPatchDocument(); + patchDoc.Remove(o => o.IntegerProperty); + + // Act + patchDoc.ApplyTo(model); + + // Assert + Assert.Equal(0, model.IntegerProperty); + } + + [Fact] + public void Remove_OnNonReferenceType_POCOProperty_ShouldSetDefaultValue_WithSerialization() + { + // Arrange + var doc = new SimpleDTO() + { + StringProperty = "A" + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Remove(o => o.StringProperty); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject>(serialized); + + // Act + deserialized.ApplyTo(doc); + + // Assert + Assert.Equal(null, doc.StringProperty); + } + + class ClassWithPrivateProperties + { + public string Name { get; set; } + private int Age { get; set; } = 45; + } + + [Fact] + public void Add_OnPrivateProperties_FailesWithException() + { + // Arrange + var doc = new ClassWithPrivateProperties() + { + Name = "James" + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Add("/Age", 30); + + // Act & Assert + var exception = Assert.Throws(() => patchDoc.ApplyTo(doc)); + Assert.Equal( + string.Format("The target location specified by path segment '{0}' was not found.", "Age"), + exception.Message); + } } } \ No newline at end of file diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/ObjectVisitorTest.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/ObjectVisitorTest.cs new file mode 100644 index 0000000000..a03b830e02 --- /dev/null +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/ObjectVisitorTest.cs @@ -0,0 +1,230 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System.Collections.Generic; +using System.Dynamic; +using Newtonsoft.Json.Serialization; +using Xunit; + +namespace Microsoft.AspNetCore.JsonPatch.Internal +{ + public class ObjectVisitorTest + { + private class Class1 + { + public string Name { get; set; } + public IList States { get; set; } = new List(); + public IDictionary Countries = new Dictionary(); + public dynamic Items { get; set; } = new ExpandoObject(); + } + + private class Class1Nested + { + public List Customers { get; set; } = new List(); + } + + public static IEnumerable ReturnsListAdapterData + { + get + { + var model = new Class1(); + yield return new object[] { model, "/States/-", model.States }; + yield return new object[] { model.States, "/-", model.States }; + + var nestedModel = new Class1Nested(); + nestedModel.Customers.Add(new Class1()); + yield return new object[] { nestedModel, "/Customers/0/States/-", nestedModel.Customers[0].States }; + yield return new object[] { nestedModel, "/Customers/0/States/0", nestedModel.Customers[0].States }; + yield return new object[] { nestedModel.Customers, "/0/States/-", nestedModel.Customers[0].States }; + yield return new object[] { nestedModel.Customers[0], "/States/-", nestedModel.Customers[0].States }; + } + } + + [Theory] + [MemberData(nameof(ReturnsListAdapterData))] + public void Visit_ValidPathToArray_ReturnsListAdapter(object targetObject, string path, object expectedTargetObject) + { + // Arrange + var visitor = new ObjectVisitor(new ParsedPath(path), new DefaultContractResolver()); + IAdapter adapter = null; + string message = null; + + // Act + var visitStatus = visitor.TryVisit(ref targetObject, out adapter, out message); + + // Assert + Assert.True(visitStatus); + Assert.True(string.IsNullOrEmpty(message), "Expected no error message"); + Assert.Same(expectedTargetObject, targetObject); + Assert.IsType(adapter); + } + + public static IEnumerable ReturnsDictionaryAdapterData + { + get + { + var model = new Class1(); + yield return new object[] { model, "/Countries/USA", model.Countries }; + yield return new object[] { model.Countries, "/USA", model.Countries }; + + var nestedModel = new Class1Nested(); + nestedModel.Customers.Add(new Class1()); + yield return new object[] { nestedModel, "/Customers/0/Countries/USA", nestedModel.Customers[0].Countries }; + yield return new object[] { nestedModel.Customers, "/0/Countries/USA", nestedModel.Customers[0].Countries }; + yield return new object[] { nestedModel.Customers[0], "/Countries/USA", nestedModel.Customers[0].Countries }; + } + } + + [Theory] + [MemberData(nameof(ReturnsDictionaryAdapterData))] + public void Visit_ValidPathToDictionary_ReturnsDictionaryAdapter(object targetObject, string path, object expectedTargetObject) + { + // Arrange + var visitor = new ObjectVisitor(new ParsedPath(path), new DefaultContractResolver()); + IAdapter adapter = null; + string message = null; + + // Act + var visitStatus = visitor.TryVisit(ref targetObject, out adapter, out message); + + // Assert + Assert.True(visitStatus); + Assert.True(string.IsNullOrEmpty(message), "Expected no error message"); + Assert.Same(expectedTargetObject, targetObject); + Assert.IsType(adapter); + } + + public static IEnumerable ReturnsExpandoAdapterData + { + get + { + var model = new Class1(); + yield return new object[] { model, "/Items/Name", model.Items }; + yield return new object[] { model.Items, "/Name", model.Items }; + + var nestedModel = new Class1Nested(); + nestedModel.Customers.Add(new Class1()); + yield return new object[] { nestedModel, "/Customers/0/Items/Name", nestedModel.Customers[0].Items }; + yield return new object[] { nestedModel.Customers, "/0/Items/Name", nestedModel.Customers[0].Items }; + yield return new object[] { nestedModel.Customers[0], "/Items/Name", nestedModel.Customers[0].Items }; + } + } + + [Theory] + [MemberData(nameof(ReturnsExpandoAdapterData))] + public void Visit_ValidPathToExpandoObject_ReturnsExpandoAdapter(object targetObject, string path, object expectedTargetObject) + { + // Arrange + var visitor = new ObjectVisitor(new ParsedPath(path), new DefaultContractResolver()); + IAdapter adapter = null; + string message = null; + + // Act + var visitStatus = visitor.TryVisit(ref targetObject, out adapter, out message); + + // Assert + Assert.True(visitStatus); + Assert.True(string.IsNullOrEmpty(message), "Expected no error message"); + Assert.Same(expectedTargetObject, targetObject); + Assert.IsType(adapter); + } + + public static IEnumerable ReturnsPocoAdapterData + { + get + { + var model = new Class1(); + yield return new object[] { model, "/Name", model }; + + var nestedModel = new Class1Nested(); + nestedModel.Customers.Add(new Class1()); + yield return new object[] { nestedModel, "/Customers/0/Name", nestedModel.Customers[0] }; + yield return new object[] { nestedModel.Customers, "/0/Name", nestedModel.Customers[0] }; + yield return new object[] { nestedModel.Customers[0], "/Name", nestedModel.Customers[0] }; + } + } + + [Theory] + [MemberData(nameof(ReturnsPocoAdapterData))] + public void Visit_ValidPath_ReturnsExpandoAdapter(object targetObject, string path, object expectedTargetObject) + { + // Arrange + var visitor = new ObjectVisitor(new ParsedPath(path), new DefaultContractResolver()); + IAdapter adapter = null; + string message = null; + + // Act + var visitStatus = visitor.TryVisit(ref targetObject, out adapter, out message); + + // Assert + Assert.True(visitStatus); + Assert.True(string.IsNullOrEmpty(message), "Expected no error message"); + Assert.Same(expectedTargetObject, targetObject); + Assert.IsType(adapter); + } + + [Theory] + [InlineData("0")] + [InlineData("-1")] + public void Visit_InvalidIndexToArray_Fails(string position) + { + // Arrange + var visitor = new ObjectVisitor(new ParsedPath($"/Customers/{position}/States/-"), new DefaultContractResolver()); + var automobileDepartment = new Class1Nested(); + object targetObject = automobileDepartment; + IAdapter adapter = null; + string message = null; + + // Act + var visitStatus = visitor.TryVisit(ref targetObject, out adapter, out message); + + // Assert + Assert.False(visitStatus); + Assert.Equal( + string.Format("The index value provided by path segment '{0}' is out of bounds of the array size.", position), + message); + } + + [Theory] + [InlineData("-")] + [InlineData("foo")] + public void Visit_InvalidIndexFormatToArray_Fails(string position) + { + // Arrange + var visitor = new ObjectVisitor(new ParsedPath($"/Customers/{position}/States/-"), new DefaultContractResolver()); + var automobileDepartment = new Class1Nested(); + object targetObject = automobileDepartment; + IAdapter adapter = null; + string message = null; + + // Act + var visitStatus = visitor.TryVisit(ref targetObject, out adapter, out message); + + // Assert + Assert.False(visitStatus); + Assert.Equal(string.Format( + "The path segment '{0}' is invalid for an array index.", position), + message); + } + + // The adapter takes care of the responsibility of validating the final segment + [Fact] + public void Visit_DoesNotValidate_FinalPathSegment() + { + // Arrange + var visitor = new ObjectVisitor(new ParsedPath($"/NonExisting"), new DefaultContractResolver()); + var model = new Class1(); + object targetObject = model; + IAdapter adapter = null; + string message = null; + + // Act + var visitStatus = visitor.TryVisit(ref targetObject, out adapter, out message); + + // Assert + Assert.True(visitStatus); + Assert.True(string.IsNullOrEmpty(message), "Expected no error message"); + Assert.IsType(adapter); + } + } +} diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/ObjectVisitorTest.cs~RF1ad82e13.TMP b/test/Microsoft.AspNetCore.JsonPatch.Test/ObjectVisitorTest.cs~RF1ad82e13.TMP new file mode 100644 index 0000000000..694c33c633 --- /dev/null +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/ObjectVisitorTest.cs~RF1ad82e13.TMP @@ -0,0 +1,119 @@ +using System.Collections.Generic; +using Newtonsoft.Json.Serialization; +using Xunit; + +namespace Microsoft.AspNetCore.JsonPatch.Internal +{ + public class ObjectVisitorTest + { + private class Class1 + { + public IList States { get; set; } = new List(); + public IDictionary Countries = new Dictionary(); + } + + [Fact] + public void Visit_ValidPathToArray_ReturnsListAdapter() + { + // Arrange + var visitor = new ObjectVisitor(new ParsedPath("/States/-"), new DefaultContractResolver()); + var model = new Class1(); + object targetObject = model; + IAdapter adapter = null; + string message = null; + + // Act + var visitStatus = visitor.TryVisit(ref targetObject, out adapter, out message); + + // Assert + Assert.True(visitStatus); + Assert.True(string.IsNullOrEmpty(message), "Expected no error message"); + Assert.Same(model.States, targetObject); + Assert.IsType(adapter); + } + + [Fact] + public void Visit_ValidPathToDictionary_ReturnsDictionaryAdapter() + { + // Arrange + var visitor = new ObjectVisitor(new ParsedPath("/Countries/USA"), new DefaultContractResolver()); + var model = new Class1(); + object targetObject = model; + IAdapter adapter = null; + string message = null; + + // Act + var visitStatus = visitor.TryVisit(ref targetObject, out adapter, out message); + + // Assert + Assert.True(visitStatus); + Assert.True(string.IsNullOrEmpty(message), "Expected no error message"); + Assert.Same(model.Countries, targetObject); + Assert.IsType(adapter); + } + + private class AutomobileDepartment + { + public List Customers { get; set; } = new List(); + } + + [Fact] + public void Visit_ValidPathToArray_ReturnsListAdapter_ForDeepNestedPath() + { + // Arrange + var visitor = new ObjectVisitor(new ParsedPath("/Customers/0/States/-"), new DefaultContractResolver()); + var customer = new Class1(); + var automobileDepartment = new AutomobileDepartment(); + automobileDepartment.Customers.Add(customer); + object targetObject = automobileDepartment; + IAdapter adapter = null; + string message = null; + + // Act + var visitStatus = visitor.TryVisit(ref targetObject, out adapter, out message); + + // Assert + Assert.True(visitStatus); + Assert.True(string.IsNullOrEmpty(message), "Expected no error message"); + Assert.Same(customer.States, targetObject); + Assert.IsType(adapter); + } + + [Fact] + public void Visit_InvalidPathToArray_Fails() + { + // Arrange + var invalidIndex = 2; + var visitor = new ObjectVisitor(new ParsedPath($"/Customers/{invalidIndex}/States/-"), new DefaultContractResolver()); + var automobileDepartment = new AutomobileDepartment(); + object targetObject = automobileDepartment; + IAdapter adapter = null; + string message = null; + + // Act + var visitStatus = visitor.TryVisit(ref targetObject, out adapter, out message); + + // Assert + Assert.False(visitStatus); + Assert.Equal(string.Format(ErrorMessageFormats.IndexOutOfBounds, invalidIndex), message); + } + + [Fact] + public void Visit_DoesNotValidate_FinalPathSegment() + { + // Arrange + var visitor = new ObjectVisitor(new ParsedPath($"/NonExisting"), new DefaultContractResolver()); + var model = new Class1(); + object targetObject = model; + IAdapter adapter = null; + string message = null; + + // Act + var visitStatus = visitor.TryVisit(ref targetObject, out adapter, out message); + + // Assert + Assert.False(visitStatus); + Assert.Equal(string.Format(ErrorMessageFormats.TargetLocationAtPathSegmentNotFound, "NonExisting"), message); + } + } +} diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/ObjectVisitorTest.cs~RF1ae034c3.TMP b/test/Microsoft.AspNetCore.JsonPatch.Test/ObjectVisitorTest.cs~RF1ae034c3.TMP new file mode 100644 index 0000000000..88139198ac --- /dev/null +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/ObjectVisitorTest.cs~RF1ae034c3.TMP @@ -0,0 +1,131 @@ +using System.Collections.Generic; +using Newtonsoft.Json.Serialization; +using Xunit; + +namespace Microsoft.AspNetCore.JsonPatch.Internal +{ + public class ObjectVisitorTest + { + private class Class1 + { + public IList States { get; set; } = new List(); + public IDictionary Countries = new Dictionary(); + } + + public static IEnumerable ReturnsListAdapterData + { + get + { + var model = new Class1(); + yield return new object[] { model, "/States/-", model.States }; + + yield return new object[] { model.States, "/-", model.States }; + } + } + + [Theory] + [MemberData(nameof(ReturnsListAdapterData))] + public void Visit_ValidPathToArray_ReturnsListAdapter(object targetObject, string path, object expectedTargetObject) + { + // Arrange + var visitor = new ObjectVisitor(new ParsedPath(path), new DefaultContractResolver()); + IAdapter adapter = null; + string message = null; + + // Act + var visitStatus = visitor.TryVisit(ref targetObject, out adapter, out message); + + // Assert + Assert.True(visitStatus); + Assert.True(string.IsNullOrEmpty(message), "Expected no error message"); + Assert.Same(expectedTargetObject, targetObject); + Assert.IsType(adapter); + } + + [Fact] + public void Visit_ValidPathToDictionary_ReturnsDictionaryAdapter() + { + // Arrange + var visitor = new ObjectVisitor(new ParsedPath("/Countries/USA"), new DefaultContractResolver()); + var model = new Class1(); + object targetObject = model; + IAdapter adapter = null; + string message = null; + + // Act + var visitStatus = visitor.TryVisit(ref targetObject, out adapter, out message); + + // Assert + Assert.True(visitStatus); + Assert.True(string.IsNullOrEmpty(message), "Expected no error message"); + Assert.Same(model.Countries, targetObject); + Assert.IsType(adapter); + } + + private class AutomobileDepartment + { + public List Customers { get; set; } = new List(); + } + + [Fact] + public void Visit_ValidPathToArray_ReturnsListAdapter_ForDeepNestedPath() + { + // Arrange + var visitor = new ObjectVisitor(new ParsedPath("/Customers/0/States/-"), new DefaultContractResolver()); + var customer = new Class1(); + var automobileDepartment = new AutomobileDepartment(); + automobileDepartment.Customers.Add(customer); + object targetObject = automobileDepartment; + IAdapter adapter = null; + string message = null; + + // Act + var visitStatus = visitor.TryVisit(ref targetObject, out adapter, out message); + + // Assert + Assert.True(visitStatus); + Assert.True(string.IsNullOrEmpty(message), "Expected no error message"); + Assert.Same(customer.States, targetObject); + Assert.IsType(adapter); + } + + [Fact] + public void Visit_InvalidPathToArray_Fails() + { + // Arrange + var invalidIndex = 2; + var visitor = new ObjectVisitor(new ParsedPath($"/Customers/{invalidIndex}/States/-"), new DefaultContractResolver()); + var automobileDepartment = new AutomobileDepartment(); + object targetObject = automobileDepartment; + IAdapter adapter = null; + string message = null; + + // Act + var visitStatus = visitor.TryVisit(ref targetObject, out adapter, out message); + + // Assert + Assert.False(visitStatus); + Assert.Equal(string.Format(ErrorMessageFormats.IndexOutOfBounds, invalidIndex), message); + } + + // The adapter takes care of the responsibility of validating the final segment + [Fact] + public void Visit_DoesNotValidate_FinalPathSegment() + { + // Arrange + var visitor = new ObjectVisitor(new ParsedPath($"/NonExisting"), new DefaultContractResolver()); + var model = new Class1(); + object targetObject = model; + IAdapter adapter = null; + string message = null; + + // Act + var visitStatus = visitor.TryVisit(ref targetObject, out adapter, out message); + + // Assert + Assert.True(visitStatus); + Assert.True(string.IsNullOrEmpty(message), "Expected no error message"); + Assert.IsType(adapter); + } + } +} diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/SimpleDTO.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/SimpleDTO.cs index 1206cd108f..6dc1f173de 100644 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/SimpleDTO.cs +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/SimpleDTO.cs @@ -4,7 +4,7 @@ using System; using System.Collections.Generic; -namespace Microsoft.AspNetCore.JsonPatch.Test +namespace Microsoft.AspNetCore.JsonPatch { public class SimpleDTO { diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/SimpleDTOWithNestedDTO.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/SimpleDTOWithNestedDTO.cs index dbded242ee..879d820277 100644 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/SimpleDTOWithNestedDTO.cs +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/SimpleDTOWithNestedDTO.cs @@ -3,7 +3,7 @@ using System.Collections.Generic; -namespace Microsoft.AspNetCore.JsonPatch.Test +namespace Microsoft.AspNetCore.JsonPatch { public class SimpleDTOWithNestedDTO { diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/TestErrorLogger.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/TestErrorLogger.cs index 6db8a42684..2cd6a4453e 100644 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/TestErrorLogger.cs +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/TestErrorLogger.cs @@ -1,7 +1,7 @@ // 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.Test +namespace Microsoft.AspNetCore.JsonPatch { public class TestErrorLogger where T : class { From 3b7f9b4043c978e1ce1d1d9d974be36f05b8e985 Mon Sep 17 00:00:00 2001 From: Kiran Challa Date: Fri, 7 Oct 2016 11:28:07 -0700 Subject: [PATCH 078/221] Fixed version of System.Reflection.TypeExtensions package --- src/Microsoft.AspNetCore.JsonPatch/project.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Microsoft.AspNetCore.JsonPatch/project.json b/src/Microsoft.AspNetCore.JsonPatch/project.json index c9beba3639..5b998272ff 100644 --- a/src/Microsoft.AspNetCore.JsonPatch/project.json +++ b/src/Microsoft.AspNetCore.JsonPatch/project.json @@ -33,7 +33,7 @@ "netstandard1.3": { "dependencies": { "Microsoft.CSharp": "4.3.0-*", - "System.Reflection.TypeExtensions": "4.1.0-*" + "System.Reflection.TypeExtensions": "4.3.0-*" } } } From ddcee4774dc3d316498c8a177d9b765eabe8bc33 Mon Sep 17 00:00:00 2001 From: Pranav K Date: Wed, 12 Oct 2016 13:45:39 -0700 Subject: [PATCH 079/221] Updating to netcoreapp1.1 --- test/Microsoft.AspNetCore.JsonPatch.Test/project.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/project.json b/test/Microsoft.AspNetCore.JsonPatch.Test/project.json index 9da14bf59e..9e95ee86e0 100644 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/project.json +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/project.json @@ -11,7 +11,7 @@ }, "testRunner": "xunit", "frameworks": { - "netcoreapp1.0": { + "netcoreapp1.1": { "dependencies": { "Microsoft.NETCore.App": { "version": "1.1.0-*", From 681812d0f40cb9c4281215413e8b3c0feca30509 Mon Sep 17 00:00:00 2001 From: Pranav K Date: Wed, 12 Oct 2016 16:08:53 -0700 Subject: [PATCH 080/221] Revert "Updating to netcoreapp1.1" This reverts commit ddcee4774dc3d316498c8a177d9b765eabe8bc33. --- test/Microsoft.AspNetCore.JsonPatch.Test/project.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/project.json b/test/Microsoft.AspNetCore.JsonPatch.Test/project.json index 9e95ee86e0..9da14bf59e 100644 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/project.json +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/project.json @@ -11,7 +11,7 @@ }, "testRunner": "xunit", "frameworks": { - "netcoreapp1.1": { + "netcoreapp1.0": { "dependencies": { "Microsoft.NETCore.App": { "version": "1.1.0-*", From 17a4e83babc7e4a6882d1e80b68a5e4fb4a1e5f1 Mon Sep 17 00:00:00 2001 From: Pranav K Date: Thu, 13 Oct 2016 11:19:06 -0700 Subject: [PATCH 081/221] Updating to netcoreapp1.1 --- test/Microsoft.AspNetCore.JsonPatch.Test/project.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/project.json b/test/Microsoft.AspNetCore.JsonPatch.Test/project.json index 9da14bf59e..9e95ee86e0 100644 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/project.json +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/project.json @@ -11,7 +11,7 @@ }, "testRunner": "xunit", "frameworks": { - "netcoreapp1.0": { + "netcoreapp1.1": { "dependencies": { "Microsoft.NETCore.App": { "version": "1.1.0-*", From ad17eb8b562c4e0971bd1faa2bb95c1392ebca8d Mon Sep 17 00:00:00 2001 From: Pranav K Date: Mon, 17 Oct 2016 09:49:16 -0700 Subject: [PATCH 082/221] Branching for 1.1.0-preview1 --- NuGet.config | 4 ++-- build.ps1 | 2 +- build.sh | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/NuGet.config b/NuGet.config index 0fd623ffdd..ad973186eb 100644 --- a/NuGet.config +++ b/NuGet.config @@ -1,7 +1,7 @@ - + - + diff --git a/build.ps1 b/build.ps1 index 8f2f99691a..787f63ac02 100644 --- a/build.ps1 +++ b/build.ps1 @@ -33,7 +33,7 @@ cd $PSScriptRoot $repoFolder = $PSScriptRoot $env:REPO_FOLDER = $repoFolder -$koreBuildZip="https://github.com/aspnet/KoreBuild/archive/dev.zip" +$koreBuildZip="https://github.com/aspnet/KoreBuild/archive/rel/1.1.0-preview1.zip" if ($env:KOREBUILD_ZIP) { $koreBuildZip=$env:KOREBUILD_ZIP diff --git a/build.sh b/build.sh index f4208100eb..355c682856 100755 --- a/build.sh +++ b/build.sh @@ -2,7 +2,7 @@ repoFolder="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" cd $repoFolder -koreBuildZip="https://github.com/aspnet/KoreBuild/archive/dev.zip" +koreBuildZip="https://github.com/aspnet/KoreBuild/archive/rel/1.1.0-preview1.zip" if [ ! -z $KOREBUILD_ZIP ]; then koreBuildZip=$KOREBUILD_ZIP fi From 81931e75d48370cf9163254523b1f6c4bcc92acb Mon Sep 17 00:00:00 2001 From: Kiran Challa Date: Mon, 31 Oct 2016 15:06:25 -0700 Subject: [PATCH 083/221] Handle exceptions for invalid operation types Related to https://github.com/aspnet/Mvc/issues/5463 --- .../Adapters/ObjectAdapter.cs | 26 +++--- .../Internal/ErrorReporter.cs | 16 ++++ .../JsonPatchDocument.cs | 18 +++- .../JsonPatchDocumentOfT.cs | 18 +++- .../Operations/OperationBase.cs | 10 +- .../Operations/OperationOfT.cs | 3 +- .../Properties/Resources.Designer.cs | 16 ++++ .../Resources.resx | 3 + .../JsonPatchDocumentTest.cs | 91 +++++++++++++++++++ 9 files changed, 182 insertions(+), 19 deletions(-) create mode 100644 src/Microsoft.AspNetCore.JsonPatch/Internal/ErrorReporter.cs create mode 100644 test/Microsoft.AspNetCore.JsonPatch.Test/JsonPatchDocumentTest.cs diff --git a/src/Microsoft.AspNetCore.JsonPatch/Adapters/ObjectAdapter.cs b/src/Microsoft.AspNetCore.JsonPatch/Adapters/ObjectAdapter.cs index ee01fbeba7..0ac2ebbe56 100644 --- a/src/Microsoft.AspNetCore.JsonPatch/Adapters/ObjectAdapter.cs +++ b/src/Microsoft.AspNetCore.JsonPatch/Adapters/ObjectAdapter.cs @@ -150,14 +150,14 @@ namespace Microsoft.AspNetCore.JsonPatch.Adapters if (!visitor.TryVisit(ref target, out adapter, out errorMessage)) { var error = CreatePathNotFoundError(objectToApplyTo, path, operation, errorMessage); - ReportError(error); + ErrorReporter(error); return; } if (!adapter.TryAdd(target, parsedPath.LastSegment, ContractResolver, value, out errorMessage)) { var error = CreateOperationFailedError(objectToApplyTo, path, operation, errorMessage); - ReportError(error); + ErrorReporter(error); return; } } @@ -259,14 +259,14 @@ namespace Microsoft.AspNetCore.JsonPatch.Adapters if (!visitor.TryVisit(ref target, out adapter, out errorMessage)) { var error = CreatePathNotFoundError(objectToApplyTo, path, operationToReport, errorMessage); - ReportError(error); + ErrorReporter(error); return; } if (!adapter.TryRemove(target, parsedPath.LastSegment, ContractResolver, out errorMessage)) { var error = CreateOperationFailedError(objectToApplyTo, path, operationToReport, errorMessage); - ReportError(error); + ErrorReporter(error); return; } } @@ -312,14 +312,14 @@ namespace Microsoft.AspNetCore.JsonPatch.Adapters if (!visitor.TryVisit(ref target, out adapter, out errorMessage)) { var error = CreatePathNotFoundError(objectToApplyTo, operation.path, operation, errorMessage); - ReportError(error); + ErrorReporter(error); return; } if (!adapter.TryReplace(target, parsedPath.LastSegment, ContractResolver, operation.value, out errorMessage)) { var error = CreateOperationFailedError(objectToApplyTo, operation.path, operation, errorMessage); - ReportError(error); + ErrorReporter(error); return; } } @@ -401,29 +401,25 @@ namespace Microsoft.AspNetCore.JsonPatch.Adapters if (!visitor.TryVisit(ref target, out adapter, out errorMessage)) { var error = CreatePathNotFoundError(objectToGetValueFrom, fromLocation, operation, errorMessage); - ReportError(error); + ErrorReporter(error); return false; } if (!adapter.TryGet(target, parsedPath.LastSegment, ContractResolver, out propertyValue, out errorMessage)) { var error = CreateOperationFailedError(objectToGetValueFrom, fromLocation, operation, errorMessage); - ReportError(error); + ErrorReporter(error); return false; } return true; } - private void ReportError(JsonPatchError error) + private Action ErrorReporter { - if (LogErrorAction != null) + get { - LogErrorAction(error); - } - else - { - throw new JsonPatchException(error); + return LogErrorAction ?? Internal.ErrorReporter.Default; } } diff --git a/src/Microsoft.AspNetCore.JsonPatch/Internal/ErrorReporter.cs b/src/Microsoft.AspNetCore.JsonPatch/Internal/ErrorReporter.cs new file mode 100644 index 0000000000..76b55a6144 --- /dev/null +++ b/src/Microsoft.AspNetCore.JsonPatch/Internal/ErrorReporter.cs @@ -0,0 +1,16 @@ +// 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 Microsoft.AspNetCore.JsonPatch.Exceptions; + +namespace Microsoft.AspNetCore.JsonPatch.Internal +{ + internal static class ErrorReporter + { + public static readonly Action Default = (error) => + { + throw new JsonPatchException(error); + }; + } +} diff --git a/src/Microsoft.AspNetCore.JsonPatch/JsonPatchDocument.cs b/src/Microsoft.AspNetCore.JsonPatch/JsonPatchDocument.cs index 72e93e0302..875134ed9d 100644 --- a/src/Microsoft.AspNetCore.JsonPatch/JsonPatchDocument.cs +++ b/src/Microsoft.AspNetCore.JsonPatch/JsonPatchDocument.cs @@ -5,6 +5,7 @@ using System; using System.Collections.Generic; using Microsoft.AspNetCore.JsonPatch.Adapters; using Microsoft.AspNetCore.JsonPatch.Converters; +using Microsoft.AspNetCore.JsonPatch.Exceptions; using Microsoft.AspNetCore.JsonPatch.Internal; using Microsoft.AspNetCore.JsonPatch.Operations; using Newtonsoft.Json; @@ -170,7 +171,22 @@ namespace Microsoft.AspNetCore.JsonPatch throw new ArgumentNullException(nameof(objectToApplyTo)); } - ApplyTo(objectToApplyTo, new ObjectAdapter(ContractResolver, logErrorAction)); + var adapter = new ObjectAdapter(ContractResolver, logErrorAction); + foreach (var op in Operations) + { + try + { + op.Apply(objectToApplyTo, adapter); + } + catch (JsonPatchException jsonPatchException) + { + var errorReporter = logErrorAction ?? ErrorReporter.Default; + errorReporter(new JsonPatchError(objectToApplyTo, op, jsonPatchException.Message)); + + // As per JSON Patch spec if an operation results in error, further operations should not be executed. + break; + } + } } /// diff --git a/src/Microsoft.AspNetCore.JsonPatch/JsonPatchDocumentOfT.cs b/src/Microsoft.AspNetCore.JsonPatch/JsonPatchDocumentOfT.cs index afb5eb3ff1..fc660b2b45 100644 --- a/src/Microsoft.AspNetCore.JsonPatch/JsonPatchDocumentOfT.cs +++ b/src/Microsoft.AspNetCore.JsonPatch/JsonPatchDocumentOfT.cs @@ -6,6 +6,7 @@ using System.Collections.Generic; using System.Linq.Expressions; using Microsoft.AspNetCore.JsonPatch.Adapters; using Microsoft.AspNetCore.JsonPatch.Converters; +using Microsoft.AspNetCore.JsonPatch.Exceptions; using Microsoft.AspNetCore.JsonPatch.Internal; using Microsoft.AspNetCore.JsonPatch.Operations; using Newtonsoft.Json; @@ -648,7 +649,22 @@ namespace Microsoft.AspNetCore.JsonPatch throw new ArgumentNullException(nameof(objectToApplyTo)); } - ApplyTo(objectToApplyTo, new ObjectAdapter(ContractResolver, logErrorAction)); + var adapter = new ObjectAdapter(ContractResolver, logErrorAction); + foreach (var op in Operations) + { + try + { + op.Apply(objectToApplyTo, adapter); + } + catch (JsonPatchException jsonPatchException) + { + var errorReporter = logErrorAction ?? ErrorReporter.Default; + errorReporter(new JsonPatchError(objectToApplyTo, op, jsonPatchException.Message)); + + // As per JSON Patch spec if an operation results in error, further operations should not be executed. + break; + } + } } /// diff --git a/src/Microsoft.AspNetCore.JsonPatch/Operations/OperationBase.cs b/src/Microsoft.AspNetCore.JsonPatch/Operations/OperationBase.cs index 5f421f41c7..eb35fa7e9d 100644 --- a/src/Microsoft.AspNetCore.JsonPatch/Operations/OperationBase.cs +++ b/src/Microsoft.AspNetCore.JsonPatch/Operations/OperationBase.cs @@ -2,6 +2,7 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; +using Microsoft.AspNetCore.JsonPatch.Exceptions; using Newtonsoft.Json; namespace Microsoft.AspNetCore.JsonPatch.Operations @@ -13,7 +14,14 @@ namespace Microsoft.AspNetCore.JsonPatch.Operations { get { - return (OperationType)Enum.Parse(typeof(OperationType), op, true); + OperationType result; + if (!Enum.TryParse(op, ignoreCase: true, result: out result)) + { + throw new JsonPatchException( + Resources.FormatInvalidJsonPatchOperation(op), + innerException: null); + } + return result; } } diff --git a/src/Microsoft.AspNetCore.JsonPatch/Operations/OperationOfT.cs b/src/Microsoft.AspNetCore.JsonPatch/Operations/OperationOfT.cs index c41454b7ef..5af4f5d3f9 100644 --- a/src/Microsoft.AspNetCore.JsonPatch/Operations/OperationOfT.cs +++ b/src/Microsoft.AspNetCore.JsonPatch/Operations/OperationOfT.cs @@ -3,6 +3,7 @@ using System; using Microsoft.AspNetCore.JsonPatch.Adapters; +using Microsoft.AspNetCore.JsonPatch.Exceptions; namespace Microsoft.AspNetCore.JsonPatch.Operations { @@ -73,7 +74,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Operations adapter.Copy(this, objectToApplyTo); break; case OperationType.Test: - throw new NotSupportedException(Resources.TestOperationNotSupported); + throw new JsonPatchException(new JsonPatchError(objectToApplyTo, this, Resources.TestOperationNotSupported)); default: break; } diff --git a/src/Microsoft.AspNetCore.JsonPatch/Properties/Resources.Designer.cs b/src/Microsoft.AspNetCore.JsonPatch/Properties/Resources.Designer.cs index 9e00cc2f00..ed567cf003 100644 --- a/src/Microsoft.AspNetCore.JsonPatch/Properties/Resources.Designer.cs +++ b/src/Microsoft.AspNetCore.JsonPatch/Properties/Resources.Designer.cs @@ -122,6 +122,22 @@ namespace Microsoft.AspNetCore.JsonPatch return string.Format(CultureInfo.CurrentCulture, GetString("InvalidJsonPatchDocument"), p0); } + /// + /// Invalid JsonPatch operation '{0}'. + /// + internal static string InvalidJsonPatchOperation + { + get { return GetString("InvalidJsonPatchOperation"); } + } + + /// + /// Invalid JsonPatch operation '{0}'. + /// + internal static string FormatInvalidJsonPatchOperation(object p0) + { + return string.Format(CultureInfo.CurrentCulture, GetString("InvalidJsonPatchOperation"), p0); + } + /// /// The provided string '{0}' is an invalid path. /// diff --git a/src/Microsoft.AspNetCore.JsonPatch/Resources.resx b/src/Microsoft.AspNetCore.JsonPatch/Resources.resx index a7b50520ac..7381ad02fc 100644 --- a/src/Microsoft.AspNetCore.JsonPatch/Resources.resx +++ b/src/Microsoft.AspNetCore.JsonPatch/Resources.resx @@ -138,6 +138,9 @@ The type '{0}' was malformed and could not be parsed. + + Invalid JsonPatch operation '{0}'. + The provided string '{0}' is an invalid path. diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/JsonPatchDocumentTest.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/JsonPatchDocumentTest.cs new file mode 100644 index 0000000000..723ef15b64 --- /dev/null +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/JsonPatchDocumentTest.cs @@ -0,0 +1,91 @@ +// 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 Microsoft.AspNetCore.JsonPatch.Exceptions; +using Newtonsoft.Json; +using Xunit; + +namespace Microsoft.AspNetCore.JsonPatch.Test +{ + public class JsonPatchDocumentTest + { + [Fact] + public void TestOperation_ThrowsException_CallsIntoLogErrorAction() + { + // Arrange + var serialized = "[{\"value\":\"John\",\"path\":\"/Name\",\"op\":\"test\"}]"; + var jsonPatchDocument = JsonConvert.DeserializeObject>(serialized); + var model = new Customer(); + var expectedErrorMessage = "The test operation is not supported."; + string actualErrorMessage = null; + + // Act + jsonPatchDocument.ApplyTo(model, (jsonPatchError) => + { + actualErrorMessage = jsonPatchError.ErrorMessage; + }); + + // Assert + Assert.Equal(expectedErrorMessage, actualErrorMessage); + } + + [Fact] + public void TestOperation_NoLogErrorAction_ThrowsJsonPatchException() + { + // Arrange + var serialized = "[{\"value\":\"John\",\"path\":\"/Name\",\"op\":\"test\"}]"; + var jsonPatchDocument = JsonConvert.DeserializeObject>(serialized); + var model = new Customer(); + var expectedErrorMessage = "The test operation is not supported."; + + // Act + var jsonPatchException = Assert.Throws(() => jsonPatchDocument.ApplyTo(model)); + + // Assert + Assert.Equal(expectedErrorMessage, jsonPatchException.Message); + } + + [Fact] + public void InvalidOperation_ThrowsException_CallsIntoLogErrorAction() + { + // Arrange + var operationName = "foo"; + var serialized = "[{\"value\":\"John\",\"path\":\"/Name\",\"op\":\"" + operationName + "\"}]"; + var jsonPatchDocument = JsonConvert.DeserializeObject>(serialized); + var model = new Customer(); + var expectedErrorMessage = $"Invalid JsonPatch operation '{operationName}'."; + string actualErrorMessage = null; + + // Act + jsonPatchDocument.ApplyTo(model, (jsonPatchError) => + { + actualErrorMessage = jsonPatchError.ErrorMessage; + }); + + // Assert + Assert.Equal(expectedErrorMessage, actualErrorMessage); + } + + [Fact] + public void InvalidOperation_NoLogErrorAction_ThrowsJsonPatchException() + { + // Arrange + var operationName = "foo"; + var serialized = "[{\"value\":\"John\",\"path\":\"/Name\",\"op\":\"" + operationName + "\"}]"; + var jsonPatchDocument = JsonConvert.DeserializeObject>(serialized); + var model = new Customer(); + var expectedErrorMessage = $"Invalid JsonPatch operation '{operationName}'."; + + // Act + var jsonPatchException = Assert.Throws(() => jsonPatchDocument.ApplyTo(model)); + + // Assert + Assert.Equal(expectedErrorMessage, jsonPatchException.Message); + } + + private class Customer + { + public string Name { get; set; } + } + } +} From 373097e0dd772d947603c2e1a316fe323f50a288 Mon Sep 17 00:00:00 2001 From: jacalvar Date: Fri, 4 Nov 2016 17:05:29 -0700 Subject: [PATCH 084/221] Created public API baselines --- .../baseline.netcore.json | 1840 +++++++++++++++++ 1 file changed, 1840 insertions(+) create mode 100644 src/Microsoft.AspNetCore.JsonPatch/baseline.netcore.json diff --git a/src/Microsoft.AspNetCore.JsonPatch/baseline.netcore.json b/src/Microsoft.AspNetCore.JsonPatch/baseline.netcore.json new file mode 100644 index 0000000000..c84771a03c --- /dev/null +++ b/src/Microsoft.AspNetCore.JsonPatch/baseline.netcore.json @@ -0,0 +1,1840 @@ +{ + "AssemblyIdentity": "Microsoft.AspNetCore.JsonPatch, Version=1.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60", + "Types": [ + { + "Name": "Microsoft.AspNetCore.JsonPatch.IJsonPatchDocument", + "Visibility": "Public", + "Kind": "Interface", + "Abstract": true, + "ImplementedInterfaces": [], + "Members": [ + { + "Kind": "Method", + "Name": "get_ContractResolver", + "Parameters": [], + "ReturnType": "Newtonsoft.Json.Serialization.IContractResolver", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "set_ContractResolver", + "Parameters": [ + { + "Name": "value", + "Type": "Newtonsoft.Json.Serialization.IContractResolver" + } + ], + "ReturnType": "System.Void", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "GetOperations", + "Parameters": [], + "ReturnType": "System.Collections.Generic.IList", + "GenericParameter": [] + } + ], + "GenericParameters": [] + }, + { + "Name": "Microsoft.AspNetCore.JsonPatch.JsonPatchDocument", + "Visibility": "Public", + "Kind": "Class", + "ImplementedInterfaces": [ + "Microsoft.AspNetCore.JsonPatch.IJsonPatchDocument" + ], + "Members": [ + { + "Kind": "Method", + "Name": "get_Operations", + "Parameters": [], + "ReturnType": "System.Collections.Generic.List", + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "get_ContractResolver", + "Parameters": [], + "ReturnType": "Newtonsoft.Json.Serialization.IContractResolver", + "Sealed": true, + "Virtual": true, + "ImplementedInterface": "Microsoft.AspNetCore.JsonPatch.IJsonPatchDocument", + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "set_ContractResolver", + "Parameters": [ + { + "Name": "value", + "Type": "Newtonsoft.Json.Serialization.IContractResolver" + } + ], + "ReturnType": "System.Void", + "Sealed": true, + "Virtual": true, + "ImplementedInterface": "Microsoft.AspNetCore.JsonPatch.IJsonPatchDocument", + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "Add", + "Parameters": [ + { + "Name": "path", + "Type": "System.String" + }, + { + "Name": "value", + "Type": "System.Object" + } + ], + "ReturnType": "Microsoft.AspNetCore.JsonPatch.JsonPatchDocument", + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "Remove", + "Parameters": [ + { + "Name": "path", + "Type": "System.String" + } + ], + "ReturnType": "Microsoft.AspNetCore.JsonPatch.JsonPatchDocument", + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "Replace", + "Parameters": [ + { + "Name": "path", + "Type": "System.String" + }, + { + "Name": "value", + "Type": "System.Object" + } + ], + "ReturnType": "Microsoft.AspNetCore.JsonPatch.JsonPatchDocument", + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "Move", + "Parameters": [ + { + "Name": "from", + "Type": "System.String" + }, + { + "Name": "path", + "Type": "System.String" + } + ], + "ReturnType": "Microsoft.AspNetCore.JsonPatch.JsonPatchDocument", + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "Copy", + "Parameters": [ + { + "Name": "from", + "Type": "System.String" + }, + { + "Name": "path", + "Type": "System.String" + } + ], + "ReturnType": "Microsoft.AspNetCore.JsonPatch.JsonPatchDocument", + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "ApplyTo", + "Parameters": [ + { + "Name": "objectToApplyTo", + "Type": "System.Object" + } + ], + "ReturnType": "System.Void", + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "ApplyTo", + "Parameters": [ + { + "Name": "objectToApplyTo", + "Type": "System.Object" + }, + { + "Name": "logErrorAction", + "Type": "System.Action" + } + ], + "ReturnType": "System.Void", + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "ApplyTo", + "Parameters": [ + { + "Name": "objectToApplyTo", + "Type": "System.Object" + }, + { + "Name": "adapter", + "Type": "Microsoft.AspNetCore.JsonPatch.Adapters.IObjectAdapter" + } + ], + "ReturnType": "System.Void", + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Constructor", + "Name": ".ctor", + "Parameters": [], + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Constructor", + "Name": ".ctor", + "Parameters": [ + { + "Name": "operations", + "Type": "System.Collections.Generic.List" + }, + { + "Name": "contractResolver", + "Type": "Newtonsoft.Json.Serialization.IContractResolver" + } + ], + "Visibility": "Public", + "GenericParameter": [] + } + ], + "GenericParameters": [] + }, + { + "Name": "Microsoft.AspNetCore.JsonPatch.JsonPatchDocument", + "Visibility": "Public", + "Kind": "Class", + "ImplementedInterfaces": [ + "Microsoft.AspNetCore.JsonPatch.IJsonPatchDocument" + ], + "Members": [ + { + "Kind": "Method", + "Name": "get_Operations", + "Parameters": [], + "ReturnType": "System.Collections.Generic.List>", + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "get_ContractResolver", + "Parameters": [], + "ReturnType": "Newtonsoft.Json.Serialization.IContractResolver", + "Sealed": true, + "Virtual": true, + "ImplementedInterface": "Microsoft.AspNetCore.JsonPatch.IJsonPatchDocument", + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "set_ContractResolver", + "Parameters": [ + { + "Name": "value", + "Type": "Newtonsoft.Json.Serialization.IContractResolver" + } + ], + "ReturnType": "System.Void", + "Sealed": true, + "Virtual": true, + "ImplementedInterface": "Microsoft.AspNetCore.JsonPatch.IJsonPatchDocument", + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "Add", + "Parameters": [ + { + "Name": "path", + "Type": "System.Linq.Expressions.Expression>" + }, + { + "Name": "value", + "Type": "T0" + } + ], + "ReturnType": "Microsoft.AspNetCore.JsonPatch.JsonPatchDocument", + "Visibility": "Public", + "GenericParameter": [ + { + "ParameterName": "TProp", + "ParameterPosition": 0, + "BaseTypeOrInterfaces": [] + } + ] + }, + { + "Kind": "Method", + "Name": "Add", + "Parameters": [ + { + "Name": "path", + "Type": "System.Linq.Expressions.Expression>>" + }, + { + "Name": "value", + "Type": "T0" + }, + { + "Name": "position", + "Type": "System.Int32" + } + ], + "ReturnType": "Microsoft.AspNetCore.JsonPatch.JsonPatchDocument", + "Visibility": "Public", + "GenericParameter": [ + { + "ParameterName": "TProp", + "ParameterPosition": 0, + "BaseTypeOrInterfaces": [] + } + ] + }, + { + "Kind": "Method", + "Name": "Add", + "Parameters": [ + { + "Name": "path", + "Type": "System.Linq.Expressions.Expression>>" + }, + { + "Name": "value", + "Type": "T0" + } + ], + "ReturnType": "Microsoft.AspNetCore.JsonPatch.JsonPatchDocument", + "Visibility": "Public", + "GenericParameter": [ + { + "ParameterName": "TProp", + "ParameterPosition": 0, + "BaseTypeOrInterfaces": [] + } + ] + }, + { + "Kind": "Method", + "Name": "Remove", + "Parameters": [ + { + "Name": "path", + "Type": "System.Linq.Expressions.Expression>" + } + ], + "ReturnType": "Microsoft.AspNetCore.JsonPatch.JsonPatchDocument", + "Visibility": "Public", + "GenericParameter": [ + { + "ParameterName": "TProp", + "ParameterPosition": 0, + "BaseTypeOrInterfaces": [] + } + ] + }, + { + "Kind": "Method", + "Name": "Remove", + "Parameters": [ + { + "Name": "path", + "Type": "System.Linq.Expressions.Expression>>" + }, + { + "Name": "position", + "Type": "System.Int32" + } + ], + "ReturnType": "Microsoft.AspNetCore.JsonPatch.JsonPatchDocument", + "Visibility": "Public", + "GenericParameter": [ + { + "ParameterName": "TProp", + "ParameterPosition": 0, + "BaseTypeOrInterfaces": [] + } + ] + }, + { + "Kind": "Method", + "Name": "Remove", + "Parameters": [ + { + "Name": "path", + "Type": "System.Linq.Expressions.Expression>>" + } + ], + "ReturnType": "Microsoft.AspNetCore.JsonPatch.JsonPatchDocument", + "Visibility": "Public", + "GenericParameter": [ + { + "ParameterName": "TProp", + "ParameterPosition": 0, + "BaseTypeOrInterfaces": [] + } + ] + }, + { + "Kind": "Method", + "Name": "Replace", + "Parameters": [ + { + "Name": "path", + "Type": "System.Linq.Expressions.Expression>" + }, + { + "Name": "value", + "Type": "T0" + } + ], + "ReturnType": "Microsoft.AspNetCore.JsonPatch.JsonPatchDocument", + "Visibility": "Public", + "GenericParameter": [ + { + "ParameterName": "TProp", + "ParameterPosition": 0, + "BaseTypeOrInterfaces": [] + } + ] + }, + { + "Kind": "Method", + "Name": "Replace", + "Parameters": [ + { + "Name": "path", + "Type": "System.Linq.Expressions.Expression>>" + }, + { + "Name": "value", + "Type": "T0" + }, + { + "Name": "position", + "Type": "System.Int32" + } + ], + "ReturnType": "Microsoft.AspNetCore.JsonPatch.JsonPatchDocument", + "Visibility": "Public", + "GenericParameter": [ + { + "ParameterName": "TProp", + "ParameterPosition": 0, + "BaseTypeOrInterfaces": [] + } + ] + }, + { + "Kind": "Method", + "Name": "Replace", + "Parameters": [ + { + "Name": "path", + "Type": "System.Linq.Expressions.Expression>>" + }, + { + "Name": "value", + "Type": "T0" + } + ], + "ReturnType": "Microsoft.AspNetCore.JsonPatch.JsonPatchDocument", + "Visibility": "Public", + "GenericParameter": [ + { + "ParameterName": "TProp", + "ParameterPosition": 0, + "BaseTypeOrInterfaces": [] + } + ] + }, + { + "Kind": "Method", + "Name": "Move", + "Parameters": [ + { + "Name": "from", + "Type": "System.Linq.Expressions.Expression>" + }, + { + "Name": "path", + "Type": "System.Linq.Expressions.Expression>" + } + ], + "ReturnType": "Microsoft.AspNetCore.JsonPatch.JsonPatchDocument", + "Visibility": "Public", + "GenericParameter": [ + { + "ParameterName": "TProp", + "ParameterPosition": 0, + "BaseTypeOrInterfaces": [] + } + ] + }, + { + "Kind": "Method", + "Name": "Move", + "Parameters": [ + { + "Name": "from", + "Type": "System.Linq.Expressions.Expression>>" + }, + { + "Name": "positionFrom", + "Type": "System.Int32" + }, + { + "Name": "path", + "Type": "System.Linq.Expressions.Expression>" + } + ], + "ReturnType": "Microsoft.AspNetCore.JsonPatch.JsonPatchDocument", + "Visibility": "Public", + "GenericParameter": [ + { + "ParameterName": "TProp", + "ParameterPosition": 0, + "BaseTypeOrInterfaces": [] + } + ] + }, + { + "Kind": "Method", + "Name": "Move", + "Parameters": [ + { + "Name": "from", + "Type": "System.Linq.Expressions.Expression>" + }, + { + "Name": "path", + "Type": "System.Linq.Expressions.Expression>>" + }, + { + "Name": "positionTo", + "Type": "System.Int32" + } + ], + "ReturnType": "Microsoft.AspNetCore.JsonPatch.JsonPatchDocument", + "Visibility": "Public", + "GenericParameter": [ + { + "ParameterName": "TProp", + "ParameterPosition": 0, + "BaseTypeOrInterfaces": [] + } + ] + }, + { + "Kind": "Method", + "Name": "Move", + "Parameters": [ + { + "Name": "from", + "Type": "System.Linq.Expressions.Expression>>" + }, + { + "Name": "positionFrom", + "Type": "System.Int32" + }, + { + "Name": "path", + "Type": "System.Linq.Expressions.Expression>>" + }, + { + "Name": "positionTo", + "Type": "System.Int32" + } + ], + "ReturnType": "Microsoft.AspNetCore.JsonPatch.JsonPatchDocument", + "Visibility": "Public", + "GenericParameter": [ + { + "ParameterName": "TProp", + "ParameterPosition": 0, + "BaseTypeOrInterfaces": [] + } + ] + }, + { + "Kind": "Method", + "Name": "Move", + "Parameters": [ + { + "Name": "from", + "Type": "System.Linq.Expressions.Expression>>" + }, + { + "Name": "positionFrom", + "Type": "System.Int32" + }, + { + "Name": "path", + "Type": "System.Linq.Expressions.Expression>>" + } + ], + "ReturnType": "Microsoft.AspNetCore.JsonPatch.JsonPatchDocument", + "Visibility": "Public", + "GenericParameter": [ + { + "ParameterName": "TProp", + "ParameterPosition": 0, + "BaseTypeOrInterfaces": [] + } + ] + }, + { + "Kind": "Method", + "Name": "Move", + "Parameters": [ + { + "Name": "from", + "Type": "System.Linq.Expressions.Expression>" + }, + { + "Name": "path", + "Type": "System.Linq.Expressions.Expression>>" + } + ], + "ReturnType": "Microsoft.AspNetCore.JsonPatch.JsonPatchDocument", + "Visibility": "Public", + "GenericParameter": [ + { + "ParameterName": "TProp", + "ParameterPosition": 0, + "BaseTypeOrInterfaces": [] + } + ] + }, + { + "Kind": "Method", + "Name": "Copy", + "Parameters": [ + { + "Name": "from", + "Type": "System.Linq.Expressions.Expression>" + }, + { + "Name": "path", + "Type": "System.Linq.Expressions.Expression>" + } + ], + "ReturnType": "Microsoft.AspNetCore.JsonPatch.JsonPatchDocument", + "Visibility": "Public", + "GenericParameter": [ + { + "ParameterName": "TProp", + "ParameterPosition": 0, + "BaseTypeOrInterfaces": [] + } + ] + }, + { + "Kind": "Method", + "Name": "Copy", + "Parameters": [ + { + "Name": "from", + "Type": "System.Linq.Expressions.Expression>>" + }, + { + "Name": "positionFrom", + "Type": "System.Int32" + }, + { + "Name": "path", + "Type": "System.Linq.Expressions.Expression>" + } + ], + "ReturnType": "Microsoft.AspNetCore.JsonPatch.JsonPatchDocument", + "Visibility": "Public", + "GenericParameter": [ + { + "ParameterName": "TProp", + "ParameterPosition": 0, + "BaseTypeOrInterfaces": [] + } + ] + }, + { + "Kind": "Method", + "Name": "Copy", + "Parameters": [ + { + "Name": "from", + "Type": "System.Linq.Expressions.Expression>" + }, + { + "Name": "path", + "Type": "System.Linq.Expressions.Expression>>" + }, + { + "Name": "positionTo", + "Type": "System.Int32" + } + ], + "ReturnType": "Microsoft.AspNetCore.JsonPatch.JsonPatchDocument", + "Visibility": "Public", + "GenericParameter": [ + { + "ParameterName": "TProp", + "ParameterPosition": 0, + "BaseTypeOrInterfaces": [] + } + ] + }, + { + "Kind": "Method", + "Name": "Copy", + "Parameters": [ + { + "Name": "from", + "Type": "System.Linq.Expressions.Expression>>" + }, + { + "Name": "positionFrom", + "Type": "System.Int32" + }, + { + "Name": "path", + "Type": "System.Linq.Expressions.Expression>>" + }, + { + "Name": "positionTo", + "Type": "System.Int32" + } + ], + "ReturnType": "Microsoft.AspNetCore.JsonPatch.JsonPatchDocument", + "Visibility": "Public", + "GenericParameter": [ + { + "ParameterName": "TProp", + "ParameterPosition": 0, + "BaseTypeOrInterfaces": [] + } + ] + }, + { + "Kind": "Method", + "Name": "Copy", + "Parameters": [ + { + "Name": "from", + "Type": "System.Linq.Expressions.Expression>>" + }, + { + "Name": "positionFrom", + "Type": "System.Int32" + }, + { + "Name": "path", + "Type": "System.Linq.Expressions.Expression>>" + } + ], + "ReturnType": "Microsoft.AspNetCore.JsonPatch.JsonPatchDocument", + "Visibility": "Public", + "GenericParameter": [ + { + "ParameterName": "TProp", + "ParameterPosition": 0, + "BaseTypeOrInterfaces": [] + } + ] + }, + { + "Kind": "Method", + "Name": "Copy", + "Parameters": [ + { + "Name": "from", + "Type": "System.Linq.Expressions.Expression>" + }, + { + "Name": "path", + "Type": "System.Linq.Expressions.Expression>>" + } + ], + "ReturnType": "Microsoft.AspNetCore.JsonPatch.JsonPatchDocument", + "Visibility": "Public", + "GenericParameter": [ + { + "ParameterName": "TProp", + "ParameterPosition": 0, + "BaseTypeOrInterfaces": [] + } + ] + }, + { + "Kind": "Method", + "Name": "ApplyTo", + "Parameters": [ + { + "Name": "objectToApplyTo", + "Type": "T0" + } + ], + "ReturnType": "System.Void", + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "ApplyTo", + "Parameters": [ + { + "Name": "objectToApplyTo", + "Type": "T0" + }, + { + "Name": "logErrorAction", + "Type": "System.Action" + } + ], + "ReturnType": "System.Void", + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "ApplyTo", + "Parameters": [ + { + "Name": "objectToApplyTo", + "Type": "T0" + }, + { + "Name": "adapter", + "Type": "Microsoft.AspNetCore.JsonPatch.Adapters.IObjectAdapter" + } + ], + "ReturnType": "System.Void", + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Constructor", + "Name": ".ctor", + "Parameters": [], + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Constructor", + "Name": ".ctor", + "Parameters": [ + { + "Name": "operations", + "Type": "System.Collections.Generic.List>" + }, + { + "Name": "contractResolver", + "Type": "Newtonsoft.Json.Serialization.IContractResolver" + } + ], + "Visibility": "Public", + "GenericParameter": [] + } + ], + "GenericParameters": [ + { + "ParameterName": "TModel", + "ParameterPosition": 0, + "Class": true, + "BaseTypeOrInterfaces": [] + } + ] + }, + { + "Name": "Microsoft.AspNetCore.JsonPatch.JsonPatchError", + "Visibility": "Public", + "Kind": "Class", + "ImplementedInterfaces": [], + "Members": [ + { + "Kind": "Method", + "Name": "get_AffectedObject", + "Parameters": [], + "ReturnType": "System.Object", + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "get_Operation", + "Parameters": [], + "ReturnType": "Microsoft.AspNetCore.JsonPatch.Operations.Operation", + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "get_ErrorMessage", + "Parameters": [], + "ReturnType": "System.String", + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Constructor", + "Name": ".ctor", + "Parameters": [ + { + "Name": "affectedObject", + "Type": "System.Object" + }, + { + "Name": "operation", + "Type": "Microsoft.AspNetCore.JsonPatch.Operations.Operation" + }, + { + "Name": "errorMessage", + "Type": "System.String" + } + ], + "Visibility": "Public", + "GenericParameter": [] + } + ], + "GenericParameters": [] + }, + { + "Name": "Microsoft.AspNetCore.JsonPatch.JsonPatchProperty", + "Visibility": "Public", + "Kind": "Class", + "ImplementedInterfaces": [], + "Members": [ + { + "Kind": "Method", + "Name": "get_Property", + "Parameters": [], + "ReturnType": "Newtonsoft.Json.Serialization.JsonProperty", + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "set_Property", + "Parameters": [ + { + "Name": "value", + "Type": "Newtonsoft.Json.Serialization.JsonProperty" + } + ], + "ReturnType": "System.Void", + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "get_Parent", + "Parameters": [], + "ReturnType": "System.Object", + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "set_Parent", + "Parameters": [ + { + "Name": "value", + "Type": "System.Object" + } + ], + "ReturnType": "System.Void", + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Constructor", + "Name": ".ctor", + "Parameters": [ + { + "Name": "property", + "Type": "Newtonsoft.Json.Serialization.JsonProperty" + }, + { + "Name": "parent", + "Type": "System.Object" + } + ], + "Visibility": "Public", + "GenericParameter": [] + } + ], + "GenericParameters": [] + }, + { + "Name": "Microsoft.AspNetCore.JsonPatch.Operations.Operation", + "Visibility": "Public", + "Kind": "Class", + "BaseType": "Microsoft.AspNetCore.JsonPatch.Operations.OperationBase", + "ImplementedInterfaces": [], + "Members": [ + { + "Kind": "Method", + "Name": "get_value", + "Parameters": [], + "ReturnType": "System.Object", + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "set_value", + "Parameters": [ + { + "Name": "value", + "Type": "System.Object" + } + ], + "ReturnType": "System.Void", + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "Apply", + "Parameters": [ + { + "Name": "objectToApplyTo", + "Type": "System.Object" + }, + { + "Name": "adapter", + "Type": "Microsoft.AspNetCore.JsonPatch.Adapters.IObjectAdapter" + } + ], + "ReturnType": "System.Void", + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "ShouldSerializevalue", + "Parameters": [], + "ReturnType": "System.Boolean", + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Constructor", + "Name": ".ctor", + "Parameters": [], + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Constructor", + "Name": ".ctor", + "Parameters": [ + { + "Name": "op", + "Type": "System.String" + }, + { + "Name": "path", + "Type": "System.String" + }, + { + "Name": "from", + "Type": "System.String" + }, + { + "Name": "value", + "Type": "System.Object" + } + ], + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Constructor", + "Name": ".ctor", + "Parameters": [ + { + "Name": "op", + "Type": "System.String" + }, + { + "Name": "path", + "Type": "System.String" + }, + { + "Name": "from", + "Type": "System.String" + } + ], + "Visibility": "Public", + "GenericParameter": [] + } + ], + "GenericParameters": [] + }, + { + "Name": "Microsoft.AspNetCore.JsonPatch.Operations.OperationBase", + "Visibility": "Public", + "Kind": "Class", + "ImplementedInterfaces": [], + "Members": [ + { + "Kind": "Method", + "Name": "get_OperationType", + "Parameters": [], + "ReturnType": "Microsoft.AspNetCore.JsonPatch.Operations.OperationType", + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "get_path", + "Parameters": [], + "ReturnType": "System.String", + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "set_path", + "Parameters": [ + { + "Name": "value", + "Type": "System.String" + } + ], + "ReturnType": "System.Void", + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "get_op", + "Parameters": [], + "ReturnType": "System.String", + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "set_op", + "Parameters": [ + { + "Name": "value", + "Type": "System.String" + } + ], + "ReturnType": "System.Void", + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "get_from", + "Parameters": [], + "ReturnType": "System.String", + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "set_from", + "Parameters": [ + { + "Name": "value", + "Type": "System.String" + } + ], + "ReturnType": "System.Void", + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "ShouldSerializefrom", + "Parameters": [], + "ReturnType": "System.Boolean", + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Constructor", + "Name": ".ctor", + "Parameters": [], + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Constructor", + "Name": ".ctor", + "Parameters": [ + { + "Name": "op", + "Type": "System.String" + }, + { + "Name": "path", + "Type": "System.String" + }, + { + "Name": "from", + "Type": "System.String" + } + ], + "Visibility": "Public", + "GenericParameter": [] + } + ], + "GenericParameters": [] + }, + { + "Name": "Microsoft.AspNetCore.JsonPatch.Operations.Operation", + "Visibility": "Public", + "Kind": "Class", + "BaseType": "Microsoft.AspNetCore.JsonPatch.Operations.Operation", + "ImplementedInterfaces": [], + "Members": [ + { + "Kind": "Method", + "Name": "Apply", + "Parameters": [ + { + "Name": "objectToApplyTo", + "Type": "T0" + }, + { + "Name": "adapter", + "Type": "Microsoft.AspNetCore.JsonPatch.Adapters.IObjectAdapter" + } + ], + "ReturnType": "System.Void", + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Constructor", + "Name": ".ctor", + "Parameters": [], + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Constructor", + "Name": ".ctor", + "Parameters": [ + { + "Name": "op", + "Type": "System.String" + }, + { + "Name": "path", + "Type": "System.String" + }, + { + "Name": "from", + "Type": "System.String" + }, + { + "Name": "value", + "Type": "System.Object" + } + ], + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Constructor", + "Name": ".ctor", + "Parameters": [ + { + "Name": "op", + "Type": "System.String" + }, + { + "Name": "path", + "Type": "System.String" + }, + { + "Name": "from", + "Type": "System.String" + } + ], + "Visibility": "Public", + "GenericParameter": [] + } + ], + "GenericParameters": [ + { + "ParameterName": "TModel", + "ParameterPosition": 0, + "Class": true, + "BaseTypeOrInterfaces": [] + } + ] + }, + { + "Name": "Microsoft.AspNetCore.JsonPatch.Operations.OperationType", + "Visibility": "Public", + "Kind": "Enumeration", + "Sealed": true, + "ImplementedInterfaces": [], + "Members": [ + { + "Kind": "Field", + "Name": "Add", + "Parameters": [], + "GenericParameter": [], + "Literal": "0" + }, + { + "Kind": "Field", + "Name": "Remove", + "Parameters": [], + "GenericParameter": [], + "Literal": "1" + }, + { + "Kind": "Field", + "Name": "Replace", + "Parameters": [], + "GenericParameter": [], + "Literal": "2" + }, + { + "Kind": "Field", + "Name": "Move", + "Parameters": [], + "GenericParameter": [], + "Literal": "3" + }, + { + "Kind": "Field", + "Name": "Copy", + "Parameters": [], + "GenericParameter": [], + "Literal": "4" + }, + { + "Kind": "Field", + "Name": "Test", + "Parameters": [], + "GenericParameter": [], + "Literal": "5" + } + ], + "GenericParameters": [] + }, + { + "Name": "Microsoft.AspNetCore.JsonPatch.Helpers.GetValueResult", + "Visibility": "Public", + "Kind": "Class", + "ImplementedInterfaces": [], + "Members": [ + { + "Kind": "Method", + "Name": "get_PropertyValue", + "Parameters": [], + "ReturnType": "System.Object", + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "get_HasError", + "Parameters": [], + "ReturnType": "System.Boolean", + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Constructor", + "Name": ".ctor", + "Parameters": [ + { + "Name": "propertyValue", + "Type": "System.Object" + }, + { + "Name": "hasError", + "Type": "System.Boolean" + } + ], + "Visibility": "Public", + "GenericParameter": [] + } + ], + "GenericParameters": [] + }, + { + "Name": "Microsoft.AspNetCore.JsonPatch.Exceptions.JsonPatchException", + "Visibility": "Public", + "Kind": "Class", + "BaseType": "System.Exception", + "ImplementedInterfaces": [], + "Members": [ + { + "Kind": "Method", + "Name": "get_FailedOperation", + "Parameters": [], + "ReturnType": "Microsoft.AspNetCore.JsonPatch.Operations.Operation", + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "get_AffectedObject", + "Parameters": [], + "ReturnType": "System.Object", + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Constructor", + "Name": ".ctor", + "Parameters": [], + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Constructor", + "Name": ".ctor", + "Parameters": [ + { + "Name": "jsonPatchError", + "Type": "Microsoft.AspNetCore.JsonPatch.JsonPatchError" + }, + { + "Name": "innerException", + "Type": "System.Exception" + } + ], + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Constructor", + "Name": ".ctor", + "Parameters": [ + { + "Name": "jsonPatchError", + "Type": "Microsoft.AspNetCore.JsonPatch.JsonPatchError" + } + ], + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Constructor", + "Name": ".ctor", + "Parameters": [ + { + "Name": "message", + "Type": "System.String" + }, + { + "Name": "innerException", + "Type": "System.Exception" + } + ], + "Visibility": "Public", + "GenericParameter": [] + } + ], + "GenericParameters": [] + }, + { + "Name": "Microsoft.AspNetCore.JsonPatch.Converters.JsonPatchDocumentConverter", + "Visibility": "Public", + "Kind": "Class", + "BaseType": "Newtonsoft.Json.JsonConverter", + "ImplementedInterfaces": [], + "Members": [ + { + "Kind": "Method", + "Name": "CanConvert", + "Parameters": [ + { + "Name": "objectType", + "Type": "System.Type" + } + ], + "ReturnType": "System.Boolean", + "Virtual": true, + "Override": true, + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "ReadJson", + "Parameters": [ + { + "Name": "reader", + "Type": "Newtonsoft.Json.JsonReader" + }, + { + "Name": "objectType", + "Type": "System.Type" + }, + { + "Name": "existingValue", + "Type": "System.Object" + }, + { + "Name": "serializer", + "Type": "Newtonsoft.Json.JsonSerializer" + } + ], + "ReturnType": "System.Object", + "Virtual": true, + "Override": true, + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "WriteJson", + "Parameters": [ + { + "Name": "writer", + "Type": "Newtonsoft.Json.JsonWriter" + }, + { + "Name": "value", + "Type": "System.Object" + }, + { + "Name": "serializer", + "Type": "Newtonsoft.Json.JsonSerializer" + } + ], + "ReturnType": "System.Void", + "Virtual": true, + "Override": true, + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Constructor", + "Name": ".ctor", + "Parameters": [], + "Visibility": "Public", + "GenericParameter": [] + } + ], + "GenericParameters": [] + }, + { + "Name": "Microsoft.AspNetCore.JsonPatch.Converters.TypedJsonPatchDocumentConverter", + "Visibility": "Public", + "Kind": "Class", + "BaseType": "Microsoft.AspNetCore.JsonPatch.Converters.JsonPatchDocumentConverter", + "ImplementedInterfaces": [], + "Members": [ + { + "Kind": "Method", + "Name": "ReadJson", + "Parameters": [ + { + "Name": "reader", + "Type": "Newtonsoft.Json.JsonReader" + }, + { + "Name": "objectType", + "Type": "System.Type" + }, + { + "Name": "existingValue", + "Type": "System.Object" + }, + { + "Name": "serializer", + "Type": "Newtonsoft.Json.JsonSerializer" + } + ], + "ReturnType": "System.Object", + "Virtual": true, + "Override": true, + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Constructor", + "Name": ".ctor", + "Parameters": [], + "Visibility": "Public", + "GenericParameter": [] + } + ], + "GenericParameters": [] + }, + { + "Name": "Microsoft.AspNetCore.JsonPatch.Adapters.IObjectAdapter", + "Visibility": "Public", + "Kind": "Interface", + "Abstract": true, + "ImplementedInterfaces": [], + "Members": [ + { + "Kind": "Method", + "Name": "Add", + "Parameters": [ + { + "Name": "operation", + "Type": "Microsoft.AspNetCore.JsonPatch.Operations.Operation" + }, + { + "Name": "objectToApplyTo", + "Type": "System.Object" + } + ], + "ReturnType": "System.Void", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "Copy", + "Parameters": [ + { + "Name": "operation", + "Type": "Microsoft.AspNetCore.JsonPatch.Operations.Operation" + }, + { + "Name": "objectToApplyTo", + "Type": "System.Object" + } + ], + "ReturnType": "System.Void", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "Move", + "Parameters": [ + { + "Name": "operation", + "Type": "Microsoft.AspNetCore.JsonPatch.Operations.Operation" + }, + { + "Name": "objectToApplyTo", + "Type": "System.Object" + } + ], + "ReturnType": "System.Void", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "Remove", + "Parameters": [ + { + "Name": "operation", + "Type": "Microsoft.AspNetCore.JsonPatch.Operations.Operation" + }, + { + "Name": "objectToApplyTo", + "Type": "System.Object" + } + ], + "ReturnType": "System.Void", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "Replace", + "Parameters": [ + { + "Name": "operation", + "Type": "Microsoft.AspNetCore.JsonPatch.Operations.Operation" + }, + { + "Name": "objectToApplyTo", + "Type": "System.Object" + } + ], + "ReturnType": "System.Void", + "GenericParameter": [] + } + ], + "GenericParameters": [] + }, + { + "Name": "Microsoft.AspNetCore.JsonPatch.Adapters.ObjectAdapter", + "Visibility": "Public", + "Kind": "Class", + "ImplementedInterfaces": [ + "Microsoft.AspNetCore.JsonPatch.Adapters.IObjectAdapter" + ], + "Members": [ + { + "Kind": "Method", + "Name": "get_ContractResolver", + "Parameters": [], + "ReturnType": "Newtonsoft.Json.Serialization.IContractResolver", + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "get_LogErrorAction", + "Parameters": [], + "ReturnType": "System.Action", + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "Add", + "Parameters": [ + { + "Name": "operation", + "Type": "Microsoft.AspNetCore.JsonPatch.Operations.Operation" + }, + { + "Name": "objectToApplyTo", + "Type": "System.Object" + } + ], + "ReturnType": "System.Void", + "Sealed": true, + "Virtual": true, + "ImplementedInterface": "Microsoft.AspNetCore.JsonPatch.Adapters.IObjectAdapter", + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "Move", + "Parameters": [ + { + "Name": "operation", + "Type": "Microsoft.AspNetCore.JsonPatch.Operations.Operation" + }, + { + "Name": "objectToApplyTo", + "Type": "System.Object" + } + ], + "ReturnType": "System.Void", + "Sealed": true, + "Virtual": true, + "ImplementedInterface": "Microsoft.AspNetCore.JsonPatch.Adapters.IObjectAdapter", + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "Remove", + "Parameters": [ + { + "Name": "operation", + "Type": "Microsoft.AspNetCore.JsonPatch.Operations.Operation" + }, + { + "Name": "objectToApplyTo", + "Type": "System.Object" + } + ], + "ReturnType": "System.Void", + "Sealed": true, + "Virtual": true, + "ImplementedInterface": "Microsoft.AspNetCore.JsonPatch.Adapters.IObjectAdapter", + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "Replace", + "Parameters": [ + { + "Name": "operation", + "Type": "Microsoft.AspNetCore.JsonPatch.Operations.Operation" + }, + { + "Name": "objectToApplyTo", + "Type": "System.Object" + } + ], + "ReturnType": "System.Void", + "Sealed": true, + "Virtual": true, + "ImplementedInterface": "Microsoft.AspNetCore.JsonPatch.Adapters.IObjectAdapter", + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "Copy", + "Parameters": [ + { + "Name": "operation", + "Type": "Microsoft.AspNetCore.JsonPatch.Operations.Operation" + }, + { + "Name": "objectToApplyTo", + "Type": "System.Object" + } + ], + "ReturnType": "System.Void", + "Sealed": true, + "Virtual": true, + "ImplementedInterface": "Microsoft.AspNetCore.JsonPatch.Adapters.IObjectAdapter", + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Constructor", + "Name": ".ctor", + "Parameters": [ + { + "Name": "contractResolver", + "Type": "Newtonsoft.Json.Serialization.IContractResolver" + }, + { + "Name": "logErrorAction", + "Type": "System.Action" + } + ], + "Visibility": "Public", + "GenericParameter": [] + } + ], + "GenericParameters": [] + } + ] +} \ No newline at end of file From fe2453b93abe4f0bfbfade7abcb737fe10ed4040 Mon Sep 17 00:00:00 2001 From: Cyprien Autexier Date: Sat, 8 Oct 2016 04:43:22 -0700 Subject: [PATCH 085/221] Escaping support for JSON pointers --- .../Internal/ParsedPath.cs | 54 ++++++++++++++++++- ...nPatchDocumentJsonPropertyAttributeTest.cs | 23 ++++++++ .../JsonPropertyComplexNameDTO.cs | 16 ++++++ .../ObjectAdapterTests.cs | 27 ++++++++++ .../ParsedPathTests.cs | 39 ++++++++++++++ 5 files changed, 158 insertions(+), 1 deletion(-) create mode 100644 test/Microsoft.AspNetCore.JsonPatch.Test/JsonPropertyComplexNameDTO.cs create mode 100644 test/Microsoft.AspNetCore.JsonPatch.Test/ParsedPathTests.cs diff --git a/src/Microsoft.AspNetCore.JsonPatch/Internal/ParsedPath.cs b/src/Microsoft.AspNetCore.JsonPatch/Internal/ParsedPath.cs index fe786b86c1..8d0e69aa4d 100644 --- a/src/Microsoft.AspNetCore.JsonPatch/Internal/ParsedPath.cs +++ b/src/Microsoft.AspNetCore.JsonPatch/Internal/ParsedPath.cs @@ -1,8 +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. +using Microsoft.AspNetCore.JsonPatch.Exceptions; using System; using System.Collections.Generic; +using System.Text; namespace Microsoft.AspNetCore.JsonPatch.Internal { @@ -19,7 +21,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal throw new ArgumentNullException(nameof(path)); } - _segments = path.Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries); + _segments = ParsePath(path); } public string LastSegment @@ -36,5 +38,55 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal } public IReadOnlyList Segments => _segments ?? Empty; + + private static string[] ParsePath(string path) + { + var strings = new List(); + var sb = new StringBuilder(path.Length); + + for (var i = 0; i < path.Length; i++) + { + if (path[i] == '/') + { + if (sb.Length > 0) + { + strings.Add(sb.ToString()); + sb.Length = 0; + } + } + else if (path[i] == '~') + { + ++i; + if (i >= path.Length) + { + throw new JsonPatchException(Resources.FormatInvalidValueForPath(path), null); + } + + if (path[i] == '0') + { + sb.Append('~'); + } + else if (path[i] == '1') + { + sb.Append('/'); + } + else + { + throw new JsonPatchException(Resources.FormatInvalidValueForPath(path), null); + } + } + else + { + sb.Append(path[i]); + } + } + + if (sb.Length > 0) + { + strings.Add(sb.ToString()); + } + + return strings.ToArray(); + } } } diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/JsonPatchDocumentJsonPropertyAttributeTest.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/JsonPatchDocumentJsonPropertyAttributeTest.cs index ef7d53c21a..0ec0c18afd 100644 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/JsonPatchDocumentJsonPropertyAttributeTest.cs +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/JsonPatchDocumentJsonPropertyAttributeTest.cs @@ -144,5 +144,28 @@ namespace Microsoft.AspNetCore.JsonPatch var pathToCheck = deserialized.Operations.First().path; Assert.Equal(pathToCheck, "/anothername"); } + + [Fact] + public void Add_OnApplyFromJson_EscapingHandledOnComplexJsonPropertyNameOnJsonDocument() + { + var doc = new JsonPropertyComplexNameDTO() + { + FooSlashBars = "InitialName", + FooSlashTilde = new SimpleDTO + { + StringProperty = "Initial Value" + } + }; + + // 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 deserialized = + JsonConvert.DeserializeObject>(serialized); + + deserialized.ApplyTo(doc); + + Assert.Equal("Kevin", doc.FooSlashBars); + Assert.Equal("Final Value", doc.FooSlashTilde.StringProperty); + } } } diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/JsonPropertyComplexNameDTO.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/JsonPropertyComplexNameDTO.cs new file mode 100644 index 0000000000..7ff66481ad --- /dev/null +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/JsonPropertyComplexNameDTO.cs @@ -0,0 +1,16 @@ +// 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 Newtonsoft.Json; + +namespace Microsoft.AspNetCore.JsonPatch +{ + public class JsonPropertyComplexNameDTO + { + [JsonProperty("foo/bar~")] + public string FooSlashBars { get; set; } + + [JsonProperty("foo/~")] + public SimpleDTO FooSlashTilde { get; set; } + } +} diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/ObjectAdapterTests.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/ObjectAdapterTests.cs index 88693fdbd5..5898311044 100644 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/ObjectAdapterTests.cs +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/ObjectAdapterTests.cs @@ -1821,6 +1821,33 @@ namespace Microsoft.AspNetCore.JsonPatch.Adapters Assert.Equal("James", actualValue1.Name); } + [Fact] + public void Replace_WhenDictionary_ValueAPocoType_WithEscaping_Succeeds() + { + // Arrange + var key1 = "Foo/Name"; + var value1 = new Customer() { Name = "Jamesss" }; + var key2 = "Foo"; + var value2 = new Customer() { Name = "Mike" }; + var model = new Class8(); + model.DictionaryOfStringToCustomer[key1] = value1; + model.DictionaryOfStringToCustomer[key2] = value2; + var patchDocument = new JsonPatchDocument(); + patchDocument.Replace($"/DictionaryOfStringToCustomer/Foo~1Name/Name", "James"); + + // Act + patchDocument.ApplyTo(model); + + // Assert + Assert.Equal(2, model.DictionaryOfStringToCustomer.Count); + var actualValue1 = model.DictionaryOfStringToCustomer[key1]; + var actualValue2 = model.DictionaryOfStringToCustomer[key2]; + Assert.NotNull(actualValue1); + Assert.Equal("James", actualValue1.Name); + Assert.Equal("Mike", actualValue2.Name); + + } + [Fact] public void Replace_DeepNested_DictionaryValue_Succeeds() { diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/ParsedPathTests.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/ParsedPathTests.cs new file mode 100644 index 0000000000..6b7c2e69cb --- /dev/null +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/ParsedPathTests.cs @@ -0,0 +1,39 @@ +// 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 Microsoft.AspNetCore.JsonPatch.Exceptions; +using Microsoft.AspNetCore.JsonPatch.Internal; +using Xunit; + +namespace Microsoft.AspNetCore.JsonPatch.Test +{ + public class ParsedPathTests + { + [Theory] + [InlineData("foo/bar~0baz", new string[] { "foo", "bar~baz" })] + [InlineData("foo/bar~00baz", new string[] { "foo", "bar~0baz" })] + [InlineData("foo/bar~01baz", new string[] { "foo", "bar~1baz" })] + [InlineData("foo/bar~10baz", new string[] { "foo", "bar/0baz" })] + [InlineData("foo/bar~1baz", new string[] { "foo", "bar/baz" })] + [InlineData("foo/bar~0/~0/~1~1/~0~0/baz", new string[] { "foo", "bar~", "~", "//", "~~", "baz" })] + [InlineData("~0~1foo", new string[] { "~/foo" })] + public void ParsingValidPathShouldSucceed(string path, string[] expected) + { + var parsedPath = new ParsedPath(path); + Assert.Equal(expected, parsedPath.Segments); + } + + [Theory] + [InlineData("foo/bar~")] + [InlineData("~")] + [InlineData("~2")] + [InlineData("foo~3bar")] + public void PathWithInvalidEscapeSequenceShouldFail(string path) + { + Assert.Throws(() => + { + var parsedPath = new ParsedPath(path); + }); + } + } +} From fd2aec9d343ac0794f4acb27b2bf26ace3242c50 Mon Sep 17 00:00:00 2001 From: Pranav K Date: Wed, 9 Nov 2016 11:31:27 -0800 Subject: [PATCH 086/221] Branching for 1.1.0 --- NuGet.config | 4 ++-- build.ps1 | 2 +- build.sh | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/NuGet.config b/NuGet.config index 0fd623ffdd..ad973186eb 100644 --- a/NuGet.config +++ b/NuGet.config @@ -1,7 +1,7 @@ - + - + diff --git a/build.ps1 b/build.ps1 index 8f2f99691a..24ca167cf6 100644 --- a/build.ps1 +++ b/build.ps1 @@ -33,7 +33,7 @@ cd $PSScriptRoot $repoFolder = $PSScriptRoot $env:REPO_FOLDER = $repoFolder -$koreBuildZip="https://github.com/aspnet/KoreBuild/archive/dev.zip" +$koreBuildZip="https://github.com/aspnet/KoreBuild/archive/rel/1.1.0.zip" if ($env:KOREBUILD_ZIP) { $koreBuildZip=$env:KOREBUILD_ZIP diff --git a/build.sh b/build.sh index f4208100eb..fea9ac64ad 100755 --- a/build.sh +++ b/build.sh @@ -2,7 +2,7 @@ repoFolder="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" cd $repoFolder -koreBuildZip="https://github.com/aspnet/KoreBuild/archive/dev.zip" +koreBuildZip="https://github.com/aspnet/KoreBuild/archive/rel/1.1.0.zip" if [ ! -z $KOREBUILD_ZIP ]; then koreBuildZip=$KOREBUILD_ZIP fi From 6ee6220e06131584a56d7225e1dcdb5fe4b7a867 Mon Sep 17 00:00:00 2001 From: Pranav K Date: Wed, 9 Nov 2016 14:18:11 -0800 Subject: [PATCH 087/221] Updating versions to 1.2.0-* --- src/Microsoft.AspNetCore.JsonPatch/project.json | 4 ++-- test/Microsoft.AspNetCore.JsonPatch.Test/project.json | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Microsoft.AspNetCore.JsonPatch/project.json b/src/Microsoft.AspNetCore.JsonPatch/project.json index 5b998272ff..a2015980e1 100644 --- a/src/Microsoft.AspNetCore.JsonPatch/project.json +++ b/src/Microsoft.AspNetCore.JsonPatch/project.json @@ -1,5 +1,5 @@ { - "version": "1.1.0-*", + "version": "1.2.0-*", "description": "ASP.NET Core support for JSON PATCH.", "buildOptions": { "warningsAsErrors": true, @@ -25,7 +25,7 @@ "Newtonsoft.Json": "9.0.1", "Microsoft.Extensions.ClosedGenericMatcher.Sources": { "type": "build", - "version": "1.1.0-*" + "version": "1.2.0-*" } }, "frameworks": { diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/project.json b/test/Microsoft.AspNetCore.JsonPatch.Test/project.json index 9e95ee86e0..158192b281 100644 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/project.json +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/project.json @@ -4,8 +4,8 @@ }, "dependencies": { "dotnet-test-xunit": "2.2.0-*", - "Microsoft.AspNetCore.JsonPatch": "1.1.0-*", - "Microsoft.AspNetCore.Testing": "1.1.0-*", + "Microsoft.AspNetCore.JsonPatch": "1.2.0-*", + "Microsoft.AspNetCore.Testing": "1.2.0-*", "Moq": "4.6.36-*", "xunit": "2.2.0-*" }, From 758f35835c1a9257fefa8692431d662ed5d53824 Mon Sep 17 00:00:00 2001 From: Nate McMaster Date: Fri, 18 Nov 2016 10:56:54 -0800 Subject: [PATCH 088/221] Clean tmp folder after unzipping KoreBuild --- build.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sh b/build.sh index f4208100eb..4fd7ede788 100755 --- a/build.sh +++ b/build.sh @@ -38,7 +38,7 @@ if test ! -d $buildFolder; then chmod +x $buildFile # Cleanup - if test ! -d $tempFolder; then + if test -d $tempFolder; then rm -rf $tempFolder fi fi From 4faf89030c47e5ee5c7193a26d810a50862a3cf4 Mon Sep 17 00:00:00 2001 From: Pranav K Date: Fri, 18 Nov 2016 12:12:17 -0800 Subject: [PATCH 089/221] Pinning versions for 1.1.0 release --- NuGet.config | 7 ++++--- src/Microsoft.AspNetCore.JsonPatch/project.json | 14 +++++++------- .../project.json | 8 ++++---- 3 files changed, 15 insertions(+), 14 deletions(-) diff --git a/NuGet.config b/NuGet.config index ad973186eb..feaadcda87 100644 --- a/NuGet.config +++ b/NuGet.config @@ -1,7 +1,8 @@ - + - - + + + diff --git a/src/Microsoft.AspNetCore.JsonPatch/project.json b/src/Microsoft.AspNetCore.JsonPatch/project.json index 5b998272ff..6d2ccde5cc 100644 --- a/src/Microsoft.AspNetCore.JsonPatch/project.json +++ b/src/Microsoft.AspNetCore.JsonPatch/project.json @@ -1,5 +1,5 @@ { - "version": "1.1.0-*", + "version": "1.1.0", "description": "ASP.NET Core support for JSON PATCH.", "buildOptions": { "warningsAsErrors": true, @@ -21,19 +21,19 @@ ] }, "dependencies": { - "NETStandard.Library": "1.6.1-*", - "Newtonsoft.Json": "9.0.1", "Microsoft.Extensions.ClosedGenericMatcher.Sources": { "type": "build", - "version": "1.1.0-*" - } + "version": "1.1.0-rtm-22752" + }, + "NETStandard.Library": "1.6.1", + "Newtonsoft.Json": "9.0.1" }, "frameworks": { "net451": {}, "netstandard1.3": { "dependencies": { - "Microsoft.CSharp": "4.3.0-*", - "System.Reflection.TypeExtensions": "4.3.0-*" + "Microsoft.CSharp": "4.3.0", + "System.Reflection.TypeExtensions": "4.3.0" } } } diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/project.json b/test/Microsoft.AspNetCore.JsonPatch.Test/project.json index 9e95ee86e0..196dbcac08 100644 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/project.json +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/project.json @@ -4,8 +4,8 @@ }, "dependencies": { "dotnet-test-xunit": "2.2.0-*", - "Microsoft.AspNetCore.JsonPatch": "1.1.0-*", - "Microsoft.AspNetCore.Testing": "1.1.0-*", + "Microsoft.AspNetCore.JsonPatch": "1.1.0", + "Microsoft.AspNetCore.Testing": "1.1.0-rtm-22752", "Moq": "4.6.36-*", "xunit": "2.2.0-*" }, @@ -14,10 +14,10 @@ "netcoreapp1.1": { "dependencies": { "Microsoft.NETCore.App": { - "version": "1.1.0-*", + "version": "1.1.0", "type": "platform" }, - "System.Diagnostics.TraceSource": "4.3.0-*" + "System.Diagnostics.TraceSource": "4.3.0" } }, "net451": { From 4dea3e7512a5ebf0d502c4a01ec0a69650af8270 Mon Sep 17 00:00:00 2001 From: "N. Taylor Mullen" Date: Wed, 23 Nov 2016 15:57:04 -0800 Subject: [PATCH 090/221] Pin global.json SDK to 1.0.0-preview2-1-003177. --- global.json | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/global.json b/global.json index fad3dfeab0..e04bdfc390 100644 --- a/global.json +++ b/global.json @@ -1,3 +1,10 @@ { - "projects": ["src", "test/WebSites", "samples"] -} + "projects": [ + "src", + "test/WebSites", + "samples" + ], + "sdk": { + "version": "1.0.0-preview2-1-003177" + } +} \ No newline at end of file From 5d8be62037127a1ac102a63e7a9ac7c21c3d8e88 Mon Sep 17 00:00:00 2001 From: "N. Taylor Mullen" Date: Thu, 8 Dec 2016 10:01:52 -0800 Subject: [PATCH 091/221] Update .travis.yml osx image to xcode7.3. --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index d7636fa329..a0be886892 100644 --- a/.travis.yml +++ b/.travis.yml @@ -19,7 +19,7 @@ mono: os: - linux - osx -osx_image: xcode7.1 +osx_image: xcode7.3 branches: only: - master From 9bf8486fe58017b0a0cb586f8a9ca04e9ada8728 Mon Sep 17 00:00:00 2001 From: Ajay Bhargav Baaskaran Date: Mon, 12 Dec 2016 00:42:23 -0800 Subject: [PATCH 092/221] Removed packages list in NuGetPackageVerifier.json --- NuGetPackageVerifier.json | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/NuGetPackageVerifier.json b/NuGetPackageVerifier.json index f68002830f..b153ab1515 100644 --- a/NuGetPackageVerifier.json +++ b/NuGetPackageVerifier.json @@ -1,13 +1,5 @@ { - "adx": { // Packages written by the ADX team and that ship on NuGet.org - "rules": [ - "AdxVerificationCompositeRule" - ], - "packages": { - "Microsoft.AspNetCore.JsonPatch": { } - } - }, - "Default": { // Rules to run for packages not listed in any other set. + "Default": { "rules": [ "DefaultCompositeRule" ] From c8c2dfaad97d1e21eacb8ba0bbd1b65a9cc6993f Mon Sep 17 00:00:00 2001 From: Pranav K Date: Mon, 5 Dec 2016 09:02:54 -0800 Subject: [PATCH 093/221] Updating to 4.4 CoreFx packages --- global.json | 2 +- src/Microsoft.AspNetCore.JsonPatch/project.json | 6 +++--- test/Microsoft.AspNetCore.JsonPatch.Test/project.json | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/global.json b/global.json index e04bdfc390..a5c02fe221 100644 --- a/global.json +++ b/global.json @@ -5,6 +5,6 @@ "samples" ], "sdk": { - "version": "1.0.0-preview2-1-003177" + "version": "1.0.0-preview2-1-003180" } } \ No newline at end of file diff --git a/src/Microsoft.AspNetCore.JsonPatch/project.json b/src/Microsoft.AspNetCore.JsonPatch/project.json index a2015980e1..7214cde411 100644 --- a/src/Microsoft.AspNetCore.JsonPatch/project.json +++ b/src/Microsoft.AspNetCore.JsonPatch/project.json @@ -21,7 +21,7 @@ ] }, "dependencies": { - "NETStandard.Library": "1.6.1-*", + "NETStandard.Library": "1.6.2-*", "Newtonsoft.Json": "9.0.1", "Microsoft.Extensions.ClosedGenericMatcher.Sources": { "type": "build", @@ -32,8 +32,8 @@ "net451": {}, "netstandard1.3": { "dependencies": { - "Microsoft.CSharp": "4.3.0-*", - "System.Reflection.TypeExtensions": "4.3.0-*" + "Microsoft.CSharp": "4.4.0-*", + "System.Reflection.TypeExtensions": "4.4.0-*" } } } diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/project.json b/test/Microsoft.AspNetCore.JsonPatch.Test/project.json index 158192b281..4790217eba 100644 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/project.json +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/project.json @@ -14,10 +14,10 @@ "netcoreapp1.1": { "dependencies": { "Microsoft.NETCore.App": { - "version": "1.1.0-*", + "version": "1.2.0-*", "type": "platform" }, - "System.Diagnostics.TraceSource": "4.3.0-*" + "System.Diagnostics.TraceSource": "4.4.0-*" } }, "net451": { From 5966024d01278bccb4cf2581fdd93575e87da9d8 Mon Sep 17 00:00:00 2001 From: David Rovani Date: Fri, 23 Dec 2016 09:33:39 -0600 Subject: [PATCH 094/221] Fixed minor spelling error in comments. --- src/Microsoft.AspNetCore.JsonPatch/JsonPatchDocument.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Microsoft.AspNetCore.JsonPatch/JsonPatchDocument.cs b/src/Microsoft.AspNetCore.JsonPatch/JsonPatchDocument.cs index 875134ed9d..4da2bdbe1e 100644 --- a/src/Microsoft.AspNetCore.JsonPatch/JsonPatchDocument.cs +++ b/src/Microsoft.AspNetCore.JsonPatch/JsonPatchDocument.cs @@ -123,7 +123,7 @@ namespace Microsoft.AspNetCore.JsonPatch } /// - /// Copy the value at specified location to the target location. Willr esult in, for example: + /// Copy the value at specified location to the target location. Will result in, for example: /// { "op": "copy", "from": "/a/b/c", "path": "/a/b/e" } /// /// source location From e8452821b9a7689853e36c9a10ad4b8c6281817c Mon Sep 17 00:00:00 2001 From: Kiran Challa Date: Wed, 28 Dec 2016 13:35:15 -0800 Subject: [PATCH 095/221] [Fixes #50] JsonPatchDocument.Replace() yields invalid path when [JsonProperty] is used (1.1.0) --- .../Internal/ExpressionHelpers.cs | 120 ------------- .../JsonPatchDocumentOfT.cs | 170 ++++++++++++++---- ...nPatchDocumentJsonPropertyAttributeTest.cs | 113 +++++++++++- 3 files changed, 245 insertions(+), 158 deletions(-) delete mode 100644 src/Microsoft.AspNetCore.JsonPatch/Internal/ExpressionHelpers.cs diff --git a/src/Microsoft.AspNetCore.JsonPatch/Internal/ExpressionHelpers.cs b/src/Microsoft.AspNetCore.JsonPatch/Internal/ExpressionHelpers.cs deleted file mode 100644 index c978330e5c..0000000000 --- a/src/Microsoft.AspNetCore.JsonPatch/Internal/ExpressionHelpers.cs +++ /dev/null @@ -1,120 +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; -using System.Globalization; -using System.Linq.Expressions; -using System.Reflection; -using Newtonsoft.Json; - -namespace Microsoft.AspNetCore.JsonPatch.Internal -{ - public static class ExpressionHelpers - { - public static string GetPath(Expression> expr) where TModel : class - { - return "/" + GetPath(expr.Body, true); - } - - private static string GetPath(Expression expr, bool firstTime) - { - switch (expr.NodeType) - { - case ExpressionType.ArrayIndex: - var binaryExpression = (BinaryExpression)expr; - - if (ContinueWithSubPath(binaryExpression.Left.NodeType, false)) - { - var leftFromBinaryExpression = GetPath(binaryExpression.Left, false); - return leftFromBinaryExpression + "/" + binaryExpression.Right.ToString(); - } - else - { - return binaryExpression.Right.ToString(); - } - case ExpressionType.Call: - var methodCallExpression = (MethodCallExpression)expr; - - if (ContinueWithSubPath(methodCallExpression.Object.NodeType, false)) - { - var leftFromMemberCallExpression = GetPath(methodCallExpression.Object, false); - return leftFromMemberCallExpression + "/" + - GetIndexerInvocation(methodCallExpression.Arguments[0]); - } - else - { - return GetIndexerInvocation(methodCallExpression.Arguments[0]); - } - case ExpressionType.Convert: - return GetPath(((UnaryExpression)expr).Operand, false); - case ExpressionType.MemberAccess: - var memberExpression = expr as MemberExpression; - - if (ContinueWithSubPath(memberExpression.Expression.NodeType, false)) - { - var left = GetPath(memberExpression.Expression, false); - // Get property name, respecting JsonProperty attribute - return left + "/" + GetPropertyNameFromMemberExpression(memberExpression); - } - else - { - // Get property name, respecting JsonProperty attribute - return GetPropertyNameFromMemberExpression(memberExpression); - } - case ExpressionType.Parameter: - // Fits "x => x" (the whole document which is "" as JSON pointer) - return firstTime ? string.Empty : null; - default: - return string.Empty; - } - } - - private static string GetPropertyNameFromMemberExpression(MemberExpression memberExpression) - { - // if there's a JsonProperty attribute, we must return the PropertyName - // from the attribute rather than the member name - var jsonPropertyAttribute = - memberExpression.Member.GetCustomAttribute( - typeof(JsonPropertyAttribute), true); - - if (jsonPropertyAttribute == null) - { - return memberExpression.Member.Name; - } - // get value - var castedAttribute = (JsonPropertyAttribute)jsonPropertyAttribute; - return castedAttribute.PropertyName; - } - - private static bool ContinueWithSubPath(ExpressionType expressionType, bool firstTime) - { - if (firstTime) - { - return (expressionType == ExpressionType.ArrayIndex - || expressionType == ExpressionType.Call - || expressionType == ExpressionType.Convert - || expressionType == ExpressionType.MemberAccess - || expressionType == ExpressionType.Parameter); - } - else - { - return (expressionType == ExpressionType.ArrayIndex - || expressionType == ExpressionType.Call - || expressionType == ExpressionType.Convert - || expressionType == ExpressionType.MemberAccess); - } - } - - private static string GetIndexerInvocation(Expression expression) - { - var converted = Expression.Convert(expression, typeof(object)); - var fakeParameter = Expression.Parameter(typeof(object), null); - var lambda = Expression.Lambda>(converted, fakeParameter); - Func func; - - func = lambda.Compile(); - - return Convert.ToString(func(null), CultureInfo.InvariantCulture); - } - } -} \ No newline at end of file diff --git a/src/Microsoft.AspNetCore.JsonPatch/JsonPatchDocumentOfT.cs b/src/Microsoft.AspNetCore.JsonPatch/JsonPatchDocumentOfT.cs index fc660b2b45..c81c4e4d6c 100644 --- a/src/Microsoft.AspNetCore.JsonPatch/JsonPatchDocumentOfT.cs +++ b/src/Microsoft.AspNetCore.JsonPatch/JsonPatchDocumentOfT.cs @@ -2,7 +2,9 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; +using System.Linq; using System.Collections.Generic; +using System.Globalization; using System.Linq.Expressions; using Microsoft.AspNetCore.JsonPatch.Adapters; using Microsoft.AspNetCore.JsonPatch.Converters; @@ -66,7 +68,7 @@ namespace Microsoft.AspNetCore.JsonPatch Operations.Add(new Operation( "add", - ExpressionHelpers.GetPath(path).ToLowerInvariant(), + GetPath(path), from: null, value: value)); @@ -93,7 +95,7 @@ namespace Microsoft.AspNetCore.JsonPatch Operations.Add(new Operation( "add", - ExpressionHelpers.GetPath(path).ToLowerInvariant() + "/" + position, + GetPath(path) + "/" + position, from: null, value: value)); @@ -116,7 +118,7 @@ namespace Microsoft.AspNetCore.JsonPatch Operations.Add(new Operation( "add", - ExpressionHelpers.GetPath(path).ToLowerInvariant() + "/-", + GetPath(path) + "/-", from: null, value: value)); @@ -136,7 +138,7 @@ namespace Microsoft.AspNetCore.JsonPatch throw new ArgumentNullException(nameof(path)); } - Operations.Add(new Operation("remove", ExpressionHelpers.GetPath(path).ToLowerInvariant(), from: null)); + Operations.Add(new Operation("remove", GetPath(path), from: null)); return this; } @@ -157,7 +159,7 @@ namespace Microsoft.AspNetCore.JsonPatch Operations.Add(new Operation( "remove", - ExpressionHelpers.GetPath(path).ToLowerInvariant() + "/" + position, + GetPath(path) + "/" + position, from: null)); return this; @@ -178,7 +180,7 @@ namespace Microsoft.AspNetCore.JsonPatch Operations.Add(new Operation( "remove", - ExpressionHelpers.GetPath(path).ToLowerInvariant() + "/-", + GetPath(path) + "/-", from: null)); return this; @@ -200,7 +202,7 @@ namespace Microsoft.AspNetCore.JsonPatch Operations.Add(new Operation( "replace", - ExpressionHelpers.GetPath(path).ToLowerInvariant(), + GetPath(path), from: null, value: value)); @@ -225,7 +227,7 @@ namespace Microsoft.AspNetCore.JsonPatch Operations.Add(new Operation( "replace", - ExpressionHelpers.GetPath(path).ToLowerInvariant() + "/" + position, + GetPath(path) + "/" + position, from: null, value: value)); @@ -248,7 +250,7 @@ namespace Microsoft.AspNetCore.JsonPatch Operations.Add(new Operation( "replace", - ExpressionHelpers.GetPath(path).ToLowerInvariant() + "/-", + GetPath(path) + "/-", from: null, value: value)); @@ -278,8 +280,8 @@ namespace Microsoft.AspNetCore.JsonPatch Operations.Add(new Operation( "move", - ExpressionHelpers.GetPath(path).ToLowerInvariant(), - ExpressionHelpers.GetPath(from).ToLowerInvariant())); + GetPath(path), + GetPath(from))); return this; } @@ -309,8 +311,8 @@ namespace Microsoft.AspNetCore.JsonPatch Operations.Add(new Operation( "move", - ExpressionHelpers.GetPath(path).ToLowerInvariant(), - ExpressionHelpers.GetPath(from).ToLowerInvariant() + "/" + positionFrom)); + GetPath(path), + GetPath(from) + "/" + positionFrom)); return this; } @@ -340,8 +342,8 @@ namespace Microsoft.AspNetCore.JsonPatch Operations.Add(new Operation( "move", - ExpressionHelpers.GetPath(path).ToLowerInvariant() + "/" + positionTo, - ExpressionHelpers.GetPath(from).ToLowerInvariant())); + GetPath(path) + "/" + positionTo, + GetPath(from))); return this; } @@ -373,8 +375,8 @@ namespace Microsoft.AspNetCore.JsonPatch Operations.Add(new Operation( "move", - ExpressionHelpers.GetPath(path).ToLowerInvariant() + "/" + positionTo, - ExpressionHelpers.GetPath(from).ToLowerInvariant() + "/" + positionFrom)); + GetPath(path) + "/" + positionTo, + GetPath(from) + "/" + positionFrom)); return this; } @@ -404,8 +406,8 @@ namespace Microsoft.AspNetCore.JsonPatch Operations.Add(new Operation( "move", - ExpressionHelpers.GetPath(path).ToLowerInvariant() + "/-", - ExpressionHelpers.GetPath(from).ToLowerInvariant() + "/" + positionFrom)); + GetPath(path) + "/-", + GetPath(from) + "/" + positionFrom)); return this; } @@ -433,8 +435,8 @@ namespace Microsoft.AspNetCore.JsonPatch Operations.Add(new Operation( "move", - ExpressionHelpers.GetPath(path).ToLowerInvariant() + "/-", - ExpressionHelpers.GetPath(from).ToLowerInvariant())); + GetPath(path) + "/-", + GetPath(from))); return this; } @@ -462,8 +464,8 @@ namespace Microsoft.AspNetCore.JsonPatch Operations.Add(new Operation( "copy", - ExpressionHelpers.GetPath(path).ToLowerInvariant() - , ExpressionHelpers.GetPath(from).ToLowerInvariant())); + GetPath(path) + , GetPath(from))); return this; } @@ -493,8 +495,8 @@ namespace Microsoft.AspNetCore.JsonPatch Operations.Add(new Operation( "copy", - ExpressionHelpers.GetPath(path).ToLowerInvariant(), - ExpressionHelpers.GetPath(from).ToLowerInvariant() + "/" + positionFrom)); + GetPath(path), + GetPath(from) + "/" + positionFrom)); return this; } @@ -524,8 +526,8 @@ namespace Microsoft.AspNetCore.JsonPatch Operations.Add(new Operation( "copy", - ExpressionHelpers.GetPath(path).ToLowerInvariant() + "/" + positionTo, - ExpressionHelpers.GetPath(from).ToLowerInvariant())); + GetPath(path) + "/" + positionTo, + GetPath(from))); return this; } @@ -557,8 +559,8 @@ namespace Microsoft.AspNetCore.JsonPatch Operations.Add(new Operation( "copy", - ExpressionHelpers.GetPath(path).ToLowerInvariant() + "/" + positionTo, - ExpressionHelpers.GetPath(from).ToLowerInvariant() + "/" + positionFrom)); + GetPath(path) + "/" + positionTo, + GetPath(from) + "/" + positionFrom)); return this; } @@ -588,8 +590,8 @@ namespace Microsoft.AspNetCore.JsonPatch Operations.Add(new Operation( "copy", - ExpressionHelpers.GetPath(path).ToLowerInvariant() + "/-", - ExpressionHelpers.GetPath(from).ToLowerInvariant() + "/" + positionFrom)); + GetPath(path) + "/-", + GetPath(from) + "/" + positionFrom)); return this; } @@ -617,8 +619,8 @@ namespace Microsoft.AspNetCore.JsonPatch Operations.Add(new Operation( "copy", - ExpressionHelpers.GetPath(path).ToLowerInvariant() + "/-", - ExpressionHelpers.GetPath(from).ToLowerInvariant())); + GetPath(path) + "/-", + GetPath(from))); return this; } @@ -712,5 +714,107 @@ namespace Microsoft.AspNetCore.JsonPatch return allOps; } + + private string GetPath(Expression> expr) + { + return "/" + GetPath(expr.Body, true).ToLowerInvariant(); + } + + private string GetPath(Expression expr, bool firstTime) + { + switch (expr.NodeType) + { + case ExpressionType.ArrayIndex: + var binaryExpression = (BinaryExpression)expr; + + if (ContinueWithSubPath(binaryExpression.Left.NodeType, false)) + { + var leftFromBinaryExpression = GetPath(binaryExpression.Left, false); + return leftFromBinaryExpression + "/" + binaryExpression.Right.ToString(); + } + else + { + return binaryExpression.Right.ToString(); + } + case ExpressionType.Call: + var methodCallExpression = (MethodCallExpression)expr; + + if (ContinueWithSubPath(methodCallExpression.Object.NodeType, false)) + { + var leftFromMemberCallExpression = GetPath(methodCallExpression.Object, false); + return leftFromMemberCallExpression + "/" + + GetIndexerInvocation(methodCallExpression.Arguments[0]); + } + else + { + return GetIndexerInvocation(methodCallExpression.Arguments[0]); + } + case ExpressionType.Convert: + return GetPath(((UnaryExpression)expr).Operand, false); + case ExpressionType.MemberAccess: + var memberExpression = expr as MemberExpression; + + if (ContinueWithSubPath(memberExpression.Expression.NodeType, false)) + { + var left = GetPath(memberExpression.Expression, false); + // Get property name, respecting JsonProperty attribute + return left + "/" + GetPropertyNameFromMemberExpression(memberExpression); + } + else + { + // Get property name, respecting JsonProperty attribute + return GetPropertyNameFromMemberExpression(memberExpression); + } + case ExpressionType.Parameter: + // Fits "x => x" (the whole document which is "" as JSON pointer) + return firstTime ? string.Empty : null; + default: + return string.Empty; + } + } + + private string GetPropertyNameFromMemberExpression(MemberExpression memberExpression) + { + var jsonObjectContract = ContractResolver.ResolveContract(memberExpression.Expression.Type) as JsonObjectContract; + if (jsonObjectContract != null) + { + return jsonObjectContract.Properties + .First(jsonProperty => jsonProperty.UnderlyingName == memberExpression.Member.Name) + .PropertyName; + } + + return null; + } + + private static bool ContinueWithSubPath(ExpressionType expressionType, bool firstTime) + { + if (firstTime) + { + return (expressionType == ExpressionType.ArrayIndex + || expressionType == ExpressionType.Call + || expressionType == ExpressionType.Convert + || expressionType == ExpressionType.MemberAccess + || expressionType == ExpressionType.Parameter); + } + else + { + return (expressionType == ExpressionType.ArrayIndex + || expressionType == ExpressionType.Call + || expressionType == ExpressionType.Convert + || expressionType == ExpressionType.MemberAccess); + } + } + + private static string GetIndexerInvocation(Expression expression) + { + var converted = Expression.Convert(expression, typeof(object)); + var fakeParameter = Expression.Parameter(typeof(object), null); + var lambda = Expression.Lambda>(converted, fakeParameter); + Func func; + + func = lambda.Compile(); + + return Convert.ToString(func(null), CultureInfo.InvariantCulture); + } } } \ No newline at end of file diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/JsonPatchDocumentJsonPropertyAttributeTest.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/JsonPatchDocumentJsonPropertyAttributeTest.cs index 0ec0c18afd..182cf1cd6d 100644 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/JsonPatchDocumentJsonPropertyAttributeTest.cs +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/JsonPatchDocumentJsonPropertyAttributeTest.cs @@ -1,8 +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. -using Newtonsoft.Json; using System.Linq; +using System.Reflection; +using Newtonsoft.Json; +using Newtonsoft.Json.Serialization; using Xunit; namespace Microsoft.AspNetCore.JsonPatch @@ -26,13 +28,47 @@ namespace Microsoft.AspNetCore.JsonPatch Assert.Equal(pathToCheck, "/anothername"); } + [Fact] + public void Add_WithExpressionOnStringProperty_FallsbackToPropertyName_WhenJsonPropertyName_IsEmpty() + { + // Arrange + var patchDoc = new JsonPatchDocument(); + patchDoc.Add(m => m.StringProperty, "Test"); + var serialized = JsonConvert.SerializeObject(patchDoc); + + // Act + var deserialized = + JsonConvert.DeserializeObject>(serialized); + + // Assert + var pathToCheck = deserialized.Operations.First().path; + Assert.Equal("/stringproperty", pathToCheck); + } + + [Fact] + public void Add_WithExpressionOnArrayProperty_FallsbackToPropertyName_WhenJsonPropertyName_IsEmpty() + { + // Arrange + var patchDoc = new JsonPatchDocument(); + patchDoc.Add(m => m.ArrayProperty, "James"); + var serialized = JsonConvert.SerializeObject(patchDoc); + + // Act + var deserialized = + JsonConvert.DeserializeObject>(serialized); + + // Assert + var pathToCheck = deserialized.Operations.First().path; + Assert.Equal("/arrayproperty/-", pathToCheck); + } + [Fact] public void Add_WithExpression_RespectsJsonPropertyName_WhenApplyingToDifferentlyTypedClassWithPropertyMatchingJsonPropertyName() { var patchDocToSerialize = new JsonPatchDocument(); 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. var doc = new JsonPropertyWithAnotherNameDTO() { @@ -81,7 +117,7 @@ namespace Microsoft.AspNetCore.JsonPatch { Name = "InitialValue" }; - + // serialization should serialize to "AnotherName" var serialized = "[{\"value\":\"Kevin\",\"path\":\"/AnotherName\",\"op\":\"add\"}]"; var deserialized = @@ -151,9 +187,9 @@ namespace Microsoft.AspNetCore.JsonPatch var doc = new JsonPropertyComplexNameDTO() { FooSlashBars = "InitialName", - FooSlashTilde = new SimpleDTO + FooSlashTilde = new SimpleDTO { - StringProperty = "Initial Value" + StringProperty = "Initial Value" } }; @@ -167,5 +203,72 @@ namespace Microsoft.AspNetCore.JsonPatch Assert.Equal("Kevin", doc.FooSlashBars); Assert.Equal("Final Value", doc.FooSlashTilde.StringProperty); } + + [Fact] + public void Move_WithExpression_FallsbackToPropertyName_WhenJsonPropertyName_IsEmpty() + { + // Arrange + var patchDoc = new JsonPatchDocument(); + patchDoc.Move(m => m.StringProperty, m => m.StringProperty2); + var serialized = JsonConvert.SerializeObject(patchDoc); + + // Act + var deserialized = + JsonConvert.DeserializeObject>(serialized); + + // Assert + var fromPath = deserialized.Operations.First().from; + Assert.Equal("/stringproperty", fromPath); + var toPath = deserialized.Operations.First().path; + Assert.Equal("/stringproperty2", toPath); + } + + [Fact] + public void Add_WithExpression_AndCustomContractResolver_UsesPropertyName_SetByContractResolver() + { + // Arrange + var patchDoc = new JsonPatchDocument(); + patchDoc.ContractResolver = new CustomContractResolver(); + patchDoc.Add(m => m.SSN, "123-45-6789"); + var serialized = JsonConvert.SerializeObject(patchDoc); + + // Act + var deserialized = + JsonConvert.DeserializeObject>(serialized); + + // Assert + var path = deserialized.Operations.First().path; + Assert.Equal("/socialsecuritynumber", path); + } + + private class JsonPropertyWithNoPropertyName + { + [JsonProperty] + public string StringProperty { get; set; } + + [JsonProperty] + public string[] ArrayProperty { get; set; } + + [JsonProperty] + public string StringProperty2 { get; set; } + + [JsonProperty] + public string SSN { get; set; } + } + + private class CustomContractResolver : DefaultContractResolver + { + protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization) + { + var jsonProperty = base.CreateProperty(member, memberSerialization); + + if (jsonProperty.PropertyName == "SSN") + { + jsonProperty.PropertyName = "SocialSecurityNumber"; + } + + return jsonProperty; + } + } } } From 0795ec1d9afdbac6c85990f7beb414bf7241fb3e Mon Sep 17 00:00:00 2001 From: Jass Bagga Date: Thu, 26 Jan 2017 11:28:35 -0800 Subject: [PATCH 096/221] Add tests for Replace operation with null checks for property (#56) See #32 --- .../NestedObjectTests.cs | 23 ++++++++++++++ .../ObjectAdapterTests.cs | 20 +++++++++++++ .../SimpleDTOWithNestedDTOWithNullCheck.cs | 15 ++++++++++ .../SimpleDTOWithNullCheck.cs | 30 +++++++++++++++++++ 4 files changed, 88 insertions(+) create mode 100644 test/Microsoft.AspNetCore.JsonPatch.Test/SimpleDTOWithNestedDTOWithNullCheck.cs create mode 100644 test/Microsoft.AspNetCore.JsonPatch.Test/SimpleDTOWithNullCheck.cs diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/NestedObjectTests.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/NestedObjectTests.cs index 345ffe2201..cc2e990997 100644 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/NestedObjectTests.cs +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/NestedObjectTests.cs @@ -907,6 +907,29 @@ namespace Microsoft.AspNetCore.JsonPatch Assert.Equal(12, doc.SimpleDTO.DecimalValue); } + [Fact] + public void Replace_DTOWithNullCheck() + { + // Arrange + var doc = new SimpleDTOWithNestedDTOWithNullCheck() + { + SimpleDTOWithNullCheck = new SimpleDTOWithNullCheck() + { + StringProperty = "A" + } + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Replace(o => o.SimpleDTOWithNullCheck.StringProperty, "B"); + + // Act + patchDoc.ApplyTo(doc); + + // Assert + Assert.Equal("B", doc.SimpleDTOWithNullCheck.StringProperty); + } + [Fact] public void ReplaceWithSerialization() { diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/ObjectAdapterTests.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/ObjectAdapterTests.cs index 5898311044..d14daadbff 100644 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/ObjectAdapterTests.cs +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/ObjectAdapterTests.cs @@ -648,6 +648,26 @@ namespace Microsoft.AspNetCore.JsonPatch.Adapters Assert.Equal(12, doc.DecimalValue); } + [Fact] + public void Replace_DTOWithNullCheck() + { + // Arrange + var doc = new SimpleDTOWithNullCheck() + { + StringProperty = "A", + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Replace(o => o.StringProperty, "B"); + + // Act + patchDoc.ApplyTo(doc); + + // Assert + Assert.Equal("B", doc.StringProperty); + } + [Fact] public void ReplaceWithSerialization() { diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/SimpleDTOWithNestedDTOWithNullCheck.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/SimpleDTOWithNestedDTOWithNullCheck.cs new file mode 100644 index 0000000000..308f23b470 --- /dev/null +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/SimpleDTOWithNestedDTOWithNullCheck.cs @@ -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 SimpleDTOWithNestedDTOWithNullCheck + { + public SimpleDTOWithNullCheck SimpleDTOWithNullCheck { get; set; } + + public SimpleDTOWithNestedDTOWithNullCheck() + { + SimpleDTOWithNullCheck = new SimpleDTOWithNullCheck(); + } + } +} diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/SimpleDTOWithNullCheck.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/SimpleDTOWithNullCheck.cs new file mode 100644 index 0000000000..d2a5fe51a4 --- /dev/null +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/SimpleDTOWithNullCheck.cs @@ -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; + +namespace Microsoft.AspNetCore.JsonPatch +{ + public class SimpleDTOWithNullCheck + { + private string stringProperty; + + public string StringProperty + { + get + { + return stringProperty; + } + + set + { + if (value == null) + { + throw new ArgumentNullException(); + } + + stringProperty = value; + } + } + } +} From 7a487a880a6525ced73b2e3d658c8e20b6578afb Mon Sep 17 00:00:00 2001 From: Kiran Challa Date: Mon, 23 Jan 2017 12:00:42 -0800 Subject: [PATCH 097/221] [Fixes #48] Regression: List add must support adding items where index is same as count of elements --- .../Internal/ListAdapter.cs | 35 ++++-- .../ListAdapterTest.cs | 110 +++++++++++++++++- 2 files changed, 136 insertions(+), 9 deletions(-) diff --git a/src/Microsoft.AspNetCore.JsonPatch/Internal/ListAdapter.cs b/src/Microsoft.AspNetCore.JsonPatch/Internal/ListAdapter.cs index c3da14fe5a..343712690a 100644 --- a/src/Microsoft.AspNetCore.JsonPatch/Internal/ListAdapter.cs +++ b/src/Microsoft.AspNetCore.JsonPatch/Internal/ListAdapter.cs @@ -27,7 +27,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal } PositionInfo positionInfo; - if (!TryGetPositionInfo(list, segment, out positionInfo, out errorMessage)) + if (!TryGetPositionInfo(list, segment, OperationType.Add, out positionInfo, out errorMessage)) { return false; } @@ -68,7 +68,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal } PositionInfo positionInfo; - if (!TryGetPositionInfo(list, segment, out positionInfo, out errorMessage)) + if (!TryGetPositionInfo(list, segment, OperationType.Get, out positionInfo, out errorMessage)) { value = null; return false; @@ -102,7 +102,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal } PositionInfo positionInfo; - if (!TryGetPositionInfo(list, segment, out positionInfo, out errorMessage)) + if (!TryGetPositionInfo(list, segment, OperationType.Remove, out positionInfo, out errorMessage)) { return false; } @@ -136,7 +136,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal } PositionInfo positionInfo; - if (!TryGetPositionInfo(list, segment, out positionInfo, out errorMessage)) + if (!TryGetPositionInfo(list, segment, OperationType.Replace, out positionInfo, out errorMessage)) { return false; } @@ -243,7 +243,12 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal } } - private bool TryGetPositionInfo(IList list, string segment, out PositionInfo positionInfo, out string errorMessage) + private bool TryGetPositionInfo( + IList list, + string segment, + OperationType operationType, + out PositionInfo positionInfo, + out string errorMessage) { if (segment == "-") { @@ -261,16 +266,24 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal errorMessage = null; return true; } + // As per JSON Patch spec, for Add operation the index value representing the number of elements is valid, + // where as for other operations like Remove, Replace, Move and Copy the target index MUST exist. + else if (position == list.Count && operationType == OperationType.Add) + { + positionInfo = new PositionInfo(PositionType.EndOfList, -1); + errorMessage = null; + return true; + } else { - positionInfo = default(PositionInfo); + positionInfo = new PositionInfo(PositionType.OutOfBounds, position); errorMessage = Resources.FormatIndexOutOfBounds(segment); return false; } } else { - positionInfo = default(PositionInfo); + positionInfo = new PositionInfo(PositionType.Invalid, -1); errorMessage = Resources.FormatInvalidIndexValue(segment); return false; } @@ -295,5 +308,13 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal Invalid, // Ex: not an integer OutOfBounds } + + private enum OperationType + { + Add, + Remove, + Get, + Replace + } } } diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/ListAdapterTest.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/ListAdapterTest.cs index ee331a2b30..799f6e9e89 100644 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/ListAdapterTest.cs +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/ListAdapterTest.cs @@ -55,12 +55,31 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal message); } + [Fact] + public void Add_WithIndexSameAsNumberOfElements_Works() + { + // Arrange + var resolver = new Mock(MockBehavior.Strict); + var targetObject = new List() { "James", "Mike" }; + var listAdapter = new ListAdapter(); + string message = null; + var position = targetObject.Count.ToString(); + + // Act + var addStatus = listAdapter.TryAdd(targetObject, position, resolver.Object, "Rob", out message); + + // Assert + Assert.Null(message); + Assert.True(addStatus); + Assert.Equal(3, targetObject.Count); + Assert.Equal(new List() { "James", "Mike", "Rob" }, targetObject); + } + [Theory] [InlineData("-1")] [InlineData("-2")] - [InlineData("2")] [InlineData("3")] - public void Patch_WithOutOfBoundsIndex_Fails(string position) + public void Add_WithOutOfBoundsIndex_Fails(string position) { // Arrange var resolver = new Mock(MockBehavior.Strict); @@ -225,6 +244,93 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal Assert.Equal(expected, targetObject); } + [Theory] + [InlineData(new int[] { }, "0")] + [InlineData(new[] { 10, 20 }, "-1")] + [InlineData(new[] { 10, 20 }, "2")] + public void Get_IndexOutOfBounds(int[] input, string position) + { + // Arrange + var resolver = new Mock(MockBehavior.Strict); + var targetObject = new List(input); + var listAdapter = new ListAdapter(); + string message = null; + object value = null; + + // Act + var getStatus = listAdapter.TryGet(targetObject, position, resolver.Object, out value, out message); + + // Assert + Assert.False(getStatus); + Assert.Equal( + string.Format("The index value provided by path segment '{0}' is out of bounds of the array size.", position), + message); + } + + [Theory] + [InlineData(new[] { 10, 20 }, "0", 10)] + [InlineData(new[] { 10, 20 }, "1", 20)] + [InlineData(new[] { 10 }, "0", 10)] + public void Get(int[] input, string position, object expected) + { + // Arrange + var resolver = new Mock(MockBehavior.Strict); + var targetObject = new List(input); + var listAdapter = new ListAdapter(); + string message = null; + object value = null; + + // Act + var getStatus = listAdapter.TryGet(targetObject, position, resolver.Object, out value, out message); + + // Assert + Assert.True(getStatus); + Assert.Equal(expected, value); + Assert.Equal(new List(input), targetObject); + } + + [Theory] + [InlineData(new int[] { }, "0")] + [InlineData(new[] { 10, 20 }, "-1")] + [InlineData(new[] { 10, 20 }, "2")] + public void Remove_IndexOutOfBounds(int[] input, string position) + { + // Arrange + var resolver = new Mock(MockBehavior.Strict); + var targetObject = new List(input); + var listAdapter = new ListAdapter(); + string message = null; + + // Act + var removeStatus = listAdapter.TryRemove(targetObject, position, resolver.Object, out message); + + // Assert + Assert.False(removeStatus); + Assert.Equal( + string.Format("The index value provided by path segment '{0}' is out of bounds of the array size.", position), + message); + } + + [Theory] + [InlineData(new[] { 10, 20 }, "0", new[] { 20 })] + [InlineData(new[] { 10, 20 }, "1", new[] { 10 })] + [InlineData(new[] { 10 }, "0", new int[] { })] + public void Remove(int[] input, string position, int[] expected) + { + // Arrange + var resolver = new Mock(MockBehavior.Strict); + var targetObject = new List(input); + var listAdapter = new ListAdapter(); + string message = null; + + // Act + var removeStatus = listAdapter.TryRemove(targetObject, position, resolver.Object, out message); + + // Assert + Assert.True(removeStatus); + Assert.Equal(new List(expected), targetObject); + } + [Fact] public void Replace_NonCompatibleType_Fails() { From 48ab68bd2a47d87b1660bdf264898e4bc32aed24 Mon Sep 17 00:00:00 2001 From: Jass Bagga Date: Mon, 30 Jan 2017 15:58:19 -0800 Subject: [PATCH 098/221] Upgrade to msbuild Addresses #57 --- JsonPatch.sln | 20 ++- NuGet.config | 1 + appveyor.yml | 4 +- build.ps1 | 2 +- build.sh | 2 +- build/Key.snk | Bin 0 -> 596 bytes build/common.props | 25 ++++ global.json | 10 -- .../Microsoft.AspNetCore.JsonPatch.csproj | 22 +++ .../Microsoft.AspNetCore.JsonPatch.xproj | 17 --- .../Properties/AssemblyInfo.cs | 11 -- .../project.json | 40 ------ ...Microsoft.AspNetCore.JsonPatch.Test.csproj | 25 ++++ .../Microsoft.AspNetCore.JsonPatch.Test.xproj | 20 --- .../ObjectVisitorTest.cs~RF1ad82e13.TMP | 119 ---------------- .../ObjectVisitorTest.cs~RF1ae034c3.TMP | 131 ------------------ .../project.json | 31 ----- version.props | 7 + 18 files changed, 101 insertions(+), 386 deletions(-) create mode 100644 build/Key.snk create mode 100644 build/common.props delete mode 100644 global.json create mode 100644 src/Microsoft.AspNetCore.JsonPatch/Microsoft.AspNetCore.JsonPatch.csproj delete mode 100644 src/Microsoft.AspNetCore.JsonPatch/Microsoft.AspNetCore.JsonPatch.xproj delete mode 100644 src/Microsoft.AspNetCore.JsonPatch/Properties/AssemblyInfo.cs delete mode 100644 src/Microsoft.AspNetCore.JsonPatch/project.json create mode 100644 test/Microsoft.AspNetCore.JsonPatch.Test/Microsoft.AspNetCore.JsonPatch.Test.csproj delete mode 100644 test/Microsoft.AspNetCore.JsonPatch.Test/Microsoft.AspNetCore.JsonPatch.Test.xproj delete mode 100644 test/Microsoft.AspNetCore.JsonPatch.Test/ObjectVisitorTest.cs~RF1ad82e13.TMP delete mode 100644 test/Microsoft.AspNetCore.JsonPatch.Test/ObjectVisitorTest.cs~RF1ae034c3.TMP delete mode 100644 test/Microsoft.AspNetCore.JsonPatch.Test/project.json create mode 100644 version.props diff --git a/JsonPatch.sln b/JsonPatch.sln index 7149fc4551..ae03b680d3 100644 --- a/JsonPatch.sln +++ b/JsonPatch.sln @@ -1,15 +1,27 @@ Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 14 -VisualStudioVersion = 14.0.23107.0 +# Visual Studio 15 +VisualStudioVersion = 15.0.26123.0 MinimumVisualStudioVersion = 10.0.40219.1 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{430B59ED-F960-4D3A-8FFE-3370008E168D}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{36CD6341-AB44-44EB-B3AA-BF98C89FECDD}" EndProject -Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNetCore.JsonPatch", "src\Microsoft.AspNetCore.JsonPatch\Microsoft.AspNetCore.JsonPatch.xproj", "{4D55F4D8-633B-462F-A5B1-FEB84BD2D534}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.JsonPatch", "src\Microsoft.AspNetCore.JsonPatch\Microsoft.AspNetCore.JsonPatch.csproj", "{4D55F4D8-633B-462F-A5B1-FEB84BD2D534}" EndProject -Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNetCore.JsonPatch.Test", "test\Microsoft.AspNetCore.JsonPatch.Test\Microsoft.AspNetCore.JsonPatch.Test.xproj", "{81C20848-E063-4E12-AC40-0B55A532C16C}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.JsonPatch.Test", "test\Microsoft.AspNetCore.JsonPatch.Test\Microsoft.AspNetCore.JsonPatch.Test.csproj", "{81C20848-E063-4E12-AC40-0B55A532C16C}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{C430C499-382D-47BD-B351-CF8F89C08CD2}" + ProjectSection(SolutionItems) = preProject + NuGet.config = NuGet.config + EndProjectSection +EndProject + +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "build", "build", "{6DC6B416-C8C4-4BFA-8C1E-A55A6D7EFD08}" + ProjectSection(SolutionItems) = preProject + build\common.props = build\common.props + build\Key.snk = build\Key.snk + EndProjectSection EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution diff --git a/NuGet.config b/NuGet.config index 0fd623ffdd..93f1ac47df 100644 --- a/NuGet.config +++ b/NuGet.config @@ -2,6 +2,7 @@ + diff --git a/appveyor.yml b/appveyor.yml index be95b88d6f..06545db9f6 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -10,4 +10,6 @@ build_script: - build.cmd --quiet verify clone_depth: 1 test: off -deploy: off \ No newline at end of file +deploy: off +# Required for dotnet-test to work +os: Visual Studio 2015 \ No newline at end of file diff --git a/build.ps1 b/build.ps1 index 8f2f99691a..0605b59c01 100644 --- a/build.ps1 +++ b/build.ps1 @@ -33,7 +33,7 @@ cd $PSScriptRoot $repoFolder = $PSScriptRoot $env:REPO_FOLDER = $repoFolder -$koreBuildZip="https://github.com/aspnet/KoreBuild/archive/dev.zip" +$koreBuildZip="https://github.com/aspnet/KoreBuild/archive/feature/msbuild.zip" if ($env:KOREBUILD_ZIP) { $koreBuildZip=$env:KOREBUILD_ZIP diff --git a/build.sh b/build.sh index 4fd7ede788..07997d6c83 100755 --- a/build.sh +++ b/build.sh @@ -2,7 +2,7 @@ repoFolder="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" cd $repoFolder -koreBuildZip="https://github.com/aspnet/KoreBuild/archive/dev.zip" +koreBuildZip="https://github.com/aspnet/KoreBuild/archive/feature/msbuild.zip" if [ ! -z $KOREBUILD_ZIP ]; then koreBuildZip=$KOREBUILD_ZIP fi diff --git a/build/Key.snk b/build/Key.snk new file mode 100644 index 0000000000000000000000000000000000000000..e10e4889c125d3120cd9e81582243d70f7cbb806 GIT binary patch literal 596 zcmV-a0;~N80ssI2Bme+XQ$aES1ONa50098=Iw=HCsnz~#iVhm& zj%TU(_THUee?3yHBjk$37ysB?i5#7WD$={H zV4B!OxRPrb|8)HPg~A}8P>^=#y<)56#=E&NzcjOtPK~<4n6GHt=K$ro*T(lhby_@U zEk(hLzk1H)0yXj{A_5>fk-TgNoP|q6(tP2xo8zt8i%212CWM#AeCd?`hS|4~L({h~Moo(~vy&3Z z1uI}`fd^*>o=rwbAGymj6RM^pZm(*Kfhs+Y1#`-2JPWZMK8@;ZWCk2+9bX4YP);~fj-BU*R zQPvWv$89!{Rl9wM+zR>_TSkn^voYxA?2G iKnV#iZ6Ah`K>b=@=IjYJXrxL124zR(38)nxe+&q_$QXwJ literal 0 HcmV?d00001 diff --git a/build/common.props b/build/common.props new file mode 100644 index 0000000000..813c202b7f --- /dev/null +++ b/build/common.props @@ -0,0 +1,25 @@ + + + + + + Microsoft ASP.NET Core + https://github.com/aspnet/JsonPatch + git + $(MSBuildThisFileDirectory)Key.snk + true + true + 1.2.0-* + 1.6.2-* + $(VersionSuffix)-$(BuildNumber) + + + + + + + + + + + \ No newline at end of file diff --git a/global.json b/global.json deleted file mode 100644 index a5c02fe221..0000000000 --- a/global.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "projects": [ - "src", - "test/WebSites", - "samples" - ], - "sdk": { - "version": "1.0.0-preview2-1-003180" - } -} \ No newline at end of file diff --git a/src/Microsoft.AspNetCore.JsonPatch/Microsoft.AspNetCore.JsonPatch.csproj b/src/Microsoft.AspNetCore.JsonPatch/Microsoft.AspNetCore.JsonPatch.csproj new file mode 100644 index 0000000000..5bf2f0f74e --- /dev/null +++ b/src/Microsoft.AspNetCore.JsonPatch/Microsoft.AspNetCore.JsonPatch.csproj @@ -0,0 +1,22 @@ + + + + + ASP.NET Core support for JSON PATCH. + net451;netstandard1.3 + $(NoWarn);CS1591 + true + aspnetcore;json;jsonpatch + + + + + + + + + + + + + diff --git a/src/Microsoft.AspNetCore.JsonPatch/Microsoft.AspNetCore.JsonPatch.xproj b/src/Microsoft.AspNetCore.JsonPatch/Microsoft.AspNetCore.JsonPatch.xproj deleted file mode 100644 index 0ebf789691..0000000000 --- a/src/Microsoft.AspNetCore.JsonPatch/Microsoft.AspNetCore.JsonPatch.xproj +++ /dev/null @@ -1,17 +0,0 @@ - - - - 14.0 - $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) - - - - 4d55f4d8-633b-462f-a5b1-feb84bd2d534 - .\obj - .\bin\ - - - 2.0 - - - \ No newline at end of file diff --git a/src/Microsoft.AspNetCore.JsonPatch/Properties/AssemblyInfo.cs b/src/Microsoft.AspNetCore.JsonPatch/Properties/AssemblyInfo.cs deleted file mode 100644 index 76feceeff0..0000000000 --- a/src/Microsoft.AspNetCore.JsonPatch/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,11 +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.Reflection; -using System.Resources; - -[assembly: AssemblyMetadata("Serviceable", "True")] -[assembly: NeutralResourcesLanguage("en-us")] -[assembly: AssemblyCompany("Microsoft Corporation.")] -[assembly: AssemblyCopyright("© Microsoft Corporation. All rights reserved.")] -[assembly: AssemblyProduct("Microsoft ASP.NET Core")] diff --git a/src/Microsoft.AspNetCore.JsonPatch/project.json b/src/Microsoft.AspNetCore.JsonPatch/project.json deleted file mode 100644 index 7214cde411..0000000000 --- a/src/Microsoft.AspNetCore.JsonPatch/project.json +++ /dev/null @@ -1,40 +0,0 @@ -{ - "version": "1.2.0-*", - "description": "ASP.NET Core support for JSON PATCH.", - "buildOptions": { - "warningsAsErrors": true, - "keyFile": "../../tools/Key.snk", - "nowarn": [ - "CS1591" - ], - "xmlDoc": true - }, - "packOptions": { - "repository": { - "type": "git", - "url": "git://github.com/aspnet/jsonpatch" - }, - "tags": [ - "aspnetcore", - "json", - "jsonpatch" - ] - }, - "dependencies": { - "NETStandard.Library": "1.6.2-*", - "Newtonsoft.Json": "9.0.1", - "Microsoft.Extensions.ClosedGenericMatcher.Sources": { - "type": "build", - "version": "1.2.0-*" - } - }, - "frameworks": { - "net451": {}, - "netstandard1.3": { - "dependencies": { - "Microsoft.CSharp": "4.4.0-*", - "System.Reflection.TypeExtensions": "4.4.0-*" - } - } - } -} \ No newline at end of file diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/Microsoft.AspNetCore.JsonPatch.Test.csproj b/test/Microsoft.AspNetCore.JsonPatch.Test/Microsoft.AspNetCore.JsonPatch.Test.csproj new file mode 100644 index 0000000000..6715989b4e --- /dev/null +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/Microsoft.AspNetCore.JsonPatch.Test.csproj @@ -0,0 +1,25 @@ + + + + netcoreapp1.1;net451 + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/Microsoft.AspNetCore.JsonPatch.Test.xproj b/test/Microsoft.AspNetCore.JsonPatch.Test/Microsoft.AspNetCore.JsonPatch.Test.xproj deleted file mode 100644 index c8942c121e..0000000000 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/Microsoft.AspNetCore.JsonPatch.Test.xproj +++ /dev/null @@ -1,20 +0,0 @@ - - - - 14.0 - $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) - - - - 81c20848-e063-4e12-ac40-0b55a532c16c - .\obj - .\bin\ - - - 2.0 - - - - - - \ No newline at end of file diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/ObjectVisitorTest.cs~RF1ad82e13.TMP b/test/Microsoft.AspNetCore.JsonPatch.Test/ObjectVisitorTest.cs~RF1ad82e13.TMP deleted file mode 100644 index 694c33c633..0000000000 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/ObjectVisitorTest.cs~RF1ad82e13.TMP +++ /dev/null @@ -1,119 +0,0 @@ -using System.Collections.Generic; -using Newtonsoft.Json.Serialization; -using Xunit; - -namespace Microsoft.AspNetCore.JsonPatch.Internal -{ - public class ObjectVisitorTest - { - private class Class1 - { - public IList States { get; set; } = new List(); - public IDictionary Countries = new Dictionary(); - } - - [Fact] - public void Visit_ValidPathToArray_ReturnsListAdapter() - { - // Arrange - var visitor = new ObjectVisitor(new ParsedPath("/States/-"), new DefaultContractResolver()); - var model = new Class1(); - object targetObject = model; - IAdapter adapter = null; - string message = null; - - // Act - var visitStatus = visitor.TryVisit(ref targetObject, out adapter, out message); - - // Assert - Assert.True(visitStatus); - Assert.True(string.IsNullOrEmpty(message), "Expected no error message"); - Assert.Same(model.States, targetObject); - Assert.IsType(adapter); - } - - [Fact] - public void Visit_ValidPathToDictionary_ReturnsDictionaryAdapter() - { - // Arrange - var visitor = new ObjectVisitor(new ParsedPath("/Countries/USA"), new DefaultContractResolver()); - var model = new Class1(); - object targetObject = model; - IAdapter adapter = null; - string message = null; - - // Act - var visitStatus = visitor.TryVisit(ref targetObject, out adapter, out message); - - // Assert - Assert.True(visitStatus); - Assert.True(string.IsNullOrEmpty(message), "Expected no error message"); - Assert.Same(model.Countries, targetObject); - Assert.IsType(adapter); - } - - private class AutomobileDepartment - { - public List Customers { get; set; } = new List(); - } - - [Fact] - public void Visit_ValidPathToArray_ReturnsListAdapter_ForDeepNestedPath() - { - // Arrange - var visitor = new ObjectVisitor(new ParsedPath("/Customers/0/States/-"), new DefaultContractResolver()); - var customer = new Class1(); - var automobileDepartment = new AutomobileDepartment(); - automobileDepartment.Customers.Add(customer); - object targetObject = automobileDepartment; - IAdapter adapter = null; - string message = null; - - // Act - var visitStatus = visitor.TryVisit(ref targetObject, out adapter, out message); - - // Assert - Assert.True(visitStatus); - Assert.True(string.IsNullOrEmpty(message), "Expected no error message"); - Assert.Same(customer.States, targetObject); - Assert.IsType(adapter); - } - - [Fact] - public void Visit_InvalidPathToArray_Fails() - { - // Arrange - var invalidIndex = 2; - var visitor = new ObjectVisitor(new ParsedPath($"/Customers/{invalidIndex}/States/-"), new DefaultContractResolver()); - var automobileDepartment = new AutomobileDepartment(); - object targetObject = automobileDepartment; - IAdapter adapter = null; - string message = null; - - // Act - var visitStatus = visitor.TryVisit(ref targetObject, out adapter, out message); - - // Assert - Assert.False(visitStatus); - Assert.Equal(string.Format(ErrorMessageFormats.IndexOutOfBounds, invalidIndex), message); - } - - [Fact] - public void Visit_DoesNotValidate_FinalPathSegment() - { - // Arrange - var visitor = new ObjectVisitor(new ParsedPath($"/NonExisting"), new DefaultContractResolver()); - var model = new Class1(); - object targetObject = model; - IAdapter adapter = null; - string message = null; - - // Act - var visitStatus = visitor.TryVisit(ref targetObject, out adapter, out message); - - // Assert - Assert.False(visitStatus); - Assert.Equal(string.Format(ErrorMessageFormats.TargetLocationAtPathSegmentNotFound, "NonExisting"), message); - } - } -} diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/ObjectVisitorTest.cs~RF1ae034c3.TMP b/test/Microsoft.AspNetCore.JsonPatch.Test/ObjectVisitorTest.cs~RF1ae034c3.TMP deleted file mode 100644 index 88139198ac..0000000000 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/ObjectVisitorTest.cs~RF1ae034c3.TMP +++ /dev/null @@ -1,131 +0,0 @@ -using System.Collections.Generic; -using Newtonsoft.Json.Serialization; -using Xunit; - -namespace Microsoft.AspNetCore.JsonPatch.Internal -{ - public class ObjectVisitorTest - { - private class Class1 - { - public IList States { get; set; } = new List(); - public IDictionary Countries = new Dictionary(); - } - - public static IEnumerable ReturnsListAdapterData - { - get - { - var model = new Class1(); - yield return new object[] { model, "/States/-", model.States }; - - yield return new object[] { model.States, "/-", model.States }; - } - } - - [Theory] - [MemberData(nameof(ReturnsListAdapterData))] - public void Visit_ValidPathToArray_ReturnsListAdapter(object targetObject, string path, object expectedTargetObject) - { - // Arrange - var visitor = new ObjectVisitor(new ParsedPath(path), new DefaultContractResolver()); - IAdapter adapter = null; - string message = null; - - // Act - var visitStatus = visitor.TryVisit(ref targetObject, out adapter, out message); - - // Assert - Assert.True(visitStatus); - Assert.True(string.IsNullOrEmpty(message), "Expected no error message"); - Assert.Same(expectedTargetObject, targetObject); - Assert.IsType(adapter); - } - - [Fact] - public void Visit_ValidPathToDictionary_ReturnsDictionaryAdapter() - { - // Arrange - var visitor = new ObjectVisitor(new ParsedPath("/Countries/USA"), new DefaultContractResolver()); - var model = new Class1(); - object targetObject = model; - IAdapter adapter = null; - string message = null; - - // Act - var visitStatus = visitor.TryVisit(ref targetObject, out adapter, out message); - - // Assert - Assert.True(visitStatus); - Assert.True(string.IsNullOrEmpty(message), "Expected no error message"); - Assert.Same(model.Countries, targetObject); - Assert.IsType(adapter); - } - - private class AutomobileDepartment - { - public List Customers { get; set; } = new List(); - } - - [Fact] - public void Visit_ValidPathToArray_ReturnsListAdapter_ForDeepNestedPath() - { - // Arrange - var visitor = new ObjectVisitor(new ParsedPath("/Customers/0/States/-"), new DefaultContractResolver()); - var customer = new Class1(); - var automobileDepartment = new AutomobileDepartment(); - automobileDepartment.Customers.Add(customer); - object targetObject = automobileDepartment; - IAdapter adapter = null; - string message = null; - - // Act - var visitStatus = visitor.TryVisit(ref targetObject, out adapter, out message); - - // Assert - Assert.True(visitStatus); - Assert.True(string.IsNullOrEmpty(message), "Expected no error message"); - Assert.Same(customer.States, targetObject); - Assert.IsType(adapter); - } - - [Fact] - public void Visit_InvalidPathToArray_Fails() - { - // Arrange - var invalidIndex = 2; - var visitor = new ObjectVisitor(new ParsedPath($"/Customers/{invalidIndex}/States/-"), new DefaultContractResolver()); - var automobileDepartment = new AutomobileDepartment(); - object targetObject = automobileDepartment; - IAdapter adapter = null; - string message = null; - - // Act - var visitStatus = visitor.TryVisit(ref targetObject, out adapter, out message); - - // Assert - Assert.False(visitStatus); - Assert.Equal(string.Format(ErrorMessageFormats.IndexOutOfBounds, invalidIndex), message); - } - - // The adapter takes care of the responsibility of validating the final segment - [Fact] - public void Visit_DoesNotValidate_FinalPathSegment() - { - // Arrange - var visitor = new ObjectVisitor(new ParsedPath($"/NonExisting"), new DefaultContractResolver()); - var model = new Class1(); - object targetObject = model; - IAdapter adapter = null; - string message = null; - - // Act - var visitStatus = visitor.TryVisit(ref targetObject, out adapter, out message); - - // Assert - Assert.True(visitStatus); - Assert.True(string.IsNullOrEmpty(message), "Expected no error message"); - Assert.IsType(adapter); - } - } -} diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/project.json b/test/Microsoft.AspNetCore.JsonPatch.Test/project.json deleted file mode 100644 index 4790217eba..0000000000 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/project.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "buildOptions": { - "warningsAsErrors": true - }, - "dependencies": { - "dotnet-test-xunit": "2.2.0-*", - "Microsoft.AspNetCore.JsonPatch": "1.2.0-*", - "Microsoft.AspNetCore.Testing": "1.2.0-*", - "Moq": "4.6.36-*", - "xunit": "2.2.0-*" - }, - "testRunner": "xunit", - "frameworks": { - "netcoreapp1.1": { - "dependencies": { - "Microsoft.NETCore.App": { - "version": "1.2.0-*", - "type": "platform" - }, - "System.Diagnostics.TraceSource": "4.4.0-*" - } - }, - "net451": { - "frameworkAssemblies": { - "System.Linq.Expressions": { - "type": "build" - } - } - } - } -} \ No newline at end of file diff --git a/version.props b/version.props new file mode 100644 index 0000000000..e77c8d9c38 --- /dev/null +++ b/version.props @@ -0,0 +1,7 @@ + + + + 1.2.0 + preview1 + + \ No newline at end of file From 50abb557fc31b6803897cc4b9a8ce03e2e6efbec Mon Sep 17 00:00:00 2001 From: Doug Bunting Date: Mon, 13 Feb 2017 11:13:17 -0800 Subject: [PATCH 099/221] Bump test projects up to .NET 4.5.2 - aspnet/Testing#248 - xUnit no longer supports .NET 4.5.1 - build tests for desktop .NET only on Windows --- .../Microsoft.AspNetCore.JsonPatch.Test.csproj | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/Microsoft.AspNetCore.JsonPatch.Test.csproj b/test/Microsoft.AspNetCore.JsonPatch.Test/Microsoft.AspNetCore.JsonPatch.Test.csproj index 6715989b4e..0825a33ba9 100644 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/Microsoft.AspNetCore.JsonPatch.Test.csproj +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/Microsoft.AspNetCore.JsonPatch.Test.csproj @@ -1,7 +1,8 @@  - netcoreapp1.1;net451 + netcoreapp1.1;net452 + netcoreapp1.1 @@ -14,7 +15,7 @@ - + From 8051f3671b273fd1b8118563b2022e2e2078f4f0 Mon Sep 17 00:00:00 2001 From: Nate McMaster Date: Tue, 14 Feb 2017 16:03:53 -0800 Subject: [PATCH 100/221] Downgrade to stable packages --- build/common.props | 7 +++---- build/dependencies.props | 6 ++++++ .../Microsoft.AspNetCore.JsonPatch.csproj | 6 +++--- .../Microsoft.AspNetCore.JsonPatch.Test.csproj | 6 +----- 4 files changed, 13 insertions(+), 12 deletions(-) create mode 100644 build/dependencies.props diff --git a/build/common.props b/build/common.props index 813c202b7f..17a0ccb4d8 100644 --- a/build/common.props +++ b/build/common.props @@ -1,5 +1,6 @@ - + + @@ -9,8 +10,6 @@ $(MSBuildThisFileDirectory)Key.snk true true - 1.2.0-* - 1.6.2-* $(VersionSuffix)-$(BuildNumber) @@ -22,4 +21,4 @@ - \ No newline at end of file + diff --git a/build/dependencies.props b/build/dependencies.props new file mode 100644 index 0000000000..e704edaec0 --- /dev/null +++ b/build/dependencies.props @@ -0,0 +1,6 @@ + + + 1.6.1 + 4.3.0 + + diff --git a/src/Microsoft.AspNetCore.JsonPatch/Microsoft.AspNetCore.JsonPatch.csproj b/src/Microsoft.AspNetCore.JsonPatch/Microsoft.AspNetCore.JsonPatch.csproj index 5bf2f0f74e..d3d5b01a89 100644 --- a/src/Microsoft.AspNetCore.JsonPatch/Microsoft.AspNetCore.JsonPatch.csproj +++ b/src/Microsoft.AspNetCore.JsonPatch/Microsoft.AspNetCore.JsonPatch.csproj @@ -13,10 +13,10 @@ - + - - + + diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/Microsoft.AspNetCore.JsonPatch.Test.csproj b/test/Microsoft.AspNetCore.JsonPatch.Test/Microsoft.AspNetCore.JsonPatch.Test.csproj index 0825a33ba9..e939e5d62c 100644 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/Microsoft.AspNetCore.JsonPatch.Test.csproj +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/Microsoft.AspNetCore.JsonPatch.Test.csproj @@ -12,15 +12,11 @@ - - - - - \ No newline at end of file + From b312a84ff488d7acd06d8e9510961bce86ffbfee Mon Sep 17 00:00:00 2001 From: Kiran Challa Date: Fri, 24 Feb 2017 15:55:59 -0800 Subject: [PATCH 101/221] Fixed solution file --- JsonPatch.sln | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/JsonPatch.sln b/JsonPatch.sln index ae03b680d3..b75721a487 100644 --- a/JsonPatch.sln +++ b/JsonPatch.sln @@ -1,7 +1,6 @@ - Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 15 -VisualStudioVersion = 15.0.26123.0 +VisualStudioVersion = 15.0.26222.1 MinimumVisualStudioVersion = 10.0.40219.1 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{430B59ED-F960-4D3A-8FFE-3370008E168D}" EndProject @@ -12,16 +11,9 @@ EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.JsonPatch.Test", "test\Microsoft.AspNetCore.JsonPatch.Test\Microsoft.AspNetCore.JsonPatch.Test.csproj", "{81C20848-E063-4E12-AC40-0B55A532C16C}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{C430C499-382D-47BD-B351-CF8F89C08CD2}" - ProjectSection(SolutionItems) = preProject - NuGet.config = NuGet.config - EndProjectSection -EndProject - -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "build", "build", "{6DC6B416-C8C4-4BFA-8C1E-A55A6D7EFD08}" ProjectSection(SolutionItems) = preProject - build\common.props = build\common.props - build\Key.snk = build\Key.snk - EndProjectSection + NuGet.config = NuGet.config + EndProjectSection EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution From 1f74ceca1b670c249f8118415e16afc4ba3f6ef7 Mon Sep 17 00:00:00 2001 From: Nate McMaster Date: Wed, 1 Mar 2017 18:14:13 -0800 Subject: [PATCH 102/221] Change korebuild branch and fix argument forwarding in bootstrapper --- build.ps1 | 16 ++++++++-------- build.sh | 22 +++++++++++----------- 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/build.ps1 b/build.ps1 index 0605b59c01..5bf0e2c113 100644 --- a/build.ps1 +++ b/build.ps1 @@ -1,6 +1,6 @@ $ErrorActionPreference = "Stop" -function DownloadWithRetry([string] $url, [string] $downloadLocation, [int] $retries) +function DownloadWithRetry([string] $url, [string] $downloadLocation, [int] $retries) { while($true) { @@ -19,7 +19,7 @@ function DownloadWithRetry([string] $url, [string] $downloadLocation, [int] $ret Start-Sleep -Seconds 10 } - else + else { $exception = $_.Exception throw $exception @@ -33,7 +33,7 @@ cd $PSScriptRoot $repoFolder = $PSScriptRoot $env:REPO_FOLDER = $repoFolder -$koreBuildZip="https://github.com/aspnet/KoreBuild/archive/feature/msbuild.zip" +$koreBuildZip="https://github.com/aspnet/KoreBuild/archive/dev.zip" if ($env:KOREBUILD_ZIP) { $koreBuildZip=$env:KOREBUILD_ZIP @@ -43,18 +43,18 @@ $buildFolder = ".build" $buildFile="$buildFolder\KoreBuild.ps1" if (!(Test-Path $buildFolder)) { - Write-Host "Downloading KoreBuild from $koreBuildZip" - + Write-Host "Downloading KoreBuild from $koreBuildZip" + $tempFolder=$env:TEMP + "\KoreBuild-" + [guid]::NewGuid() New-Item -Path "$tempFolder" -Type directory | Out-Null $localZipFile="$tempFolder\korebuild.zip" - + DownloadWithRetry -url $koreBuildZip -downloadLocation $localZipFile -retries 6 Add-Type -AssemblyName System.IO.Compression.FileSystem [System.IO.Compression.ZipFile]::ExtractToDirectory($localZipFile, $tempFolder) - + New-Item -Path "$buildFolder" -Type directory | Out-Null copy-item "$tempFolder\**\build\*" $buildFolder -Recurse @@ -64,4 +64,4 @@ if (!(Test-Path $buildFolder)) { } } -&"$buildFile" $args \ No newline at end of file +&"$buildFile" @args diff --git a/build.sh b/build.sh index 07997d6c83..b0bcadb579 100755 --- a/build.sh +++ b/build.sh @@ -2,7 +2,7 @@ repoFolder="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" cd $repoFolder -koreBuildZip="https://github.com/aspnet/KoreBuild/archive/feature/msbuild.zip" +koreBuildZip="https://github.com/aspnet/KoreBuild/archive/dev.zip" if [ ! -z $KOREBUILD_ZIP ]; then koreBuildZip=$KOREBUILD_ZIP fi @@ -12,12 +12,12 @@ buildFile="$buildFolder/KoreBuild.sh" if test ! -d $buildFolder; then echo "Downloading KoreBuild from $koreBuildZip" - - tempFolder="/tmp/KoreBuild-$(uuidgen)" + + tempFolder="/tmp/KoreBuild-$(uuidgen)" mkdir $tempFolder - + localZipFile="$tempFolder/korebuild.zip" - + retries=6 until (wget -O $localZipFile $koreBuildZip 2>/dev/null || curl -o $localZipFile --location $koreBuildZip 2>/dev/null) do @@ -29,18 +29,18 @@ if test ! -d $buildFolder; then echo "Waiting 10 seconds before retrying. Retries left: $retries" sleep 10s done - + unzip -q -d $tempFolder $localZipFile - + mkdir $buildFolder cp -r $tempFolder/**/build/** $buildFolder - + chmod +x $buildFile - + # Cleanup if test -d $tempFolder; then - rm -rf $tempFolder + rm -rf $tempFolder fi fi -$buildFile -r $repoFolder "$@" \ No newline at end of file +$buildFile -r $repoFolder "$@" From dcfbbab005c1fe59e131a0795fff05abf64f76d9 Mon Sep 17 00:00:00 2001 From: Nate McMaster Date: Wed, 1 Mar 2017 18:25:39 -0800 Subject: [PATCH 103/221] Update AppVeyor and Travis settings --- .travis.yml | 2 +- appveyor.yml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index a0be886892..af659e9ae9 100644 --- a/.travis.yml +++ b/.travis.yml @@ -29,4 +29,4 @@ branches: before_install: - if test "$TRAVIS_OS_NAME" == "osx"; then brew update; brew install openssl; ln -s /usr/local/opt/openssl/lib/libcrypto.1.0.0.dylib /usr/local/lib/; ln -s /usr/local/opt/openssl/lib/libssl.1.0.0.dylib /usr/local/lib/; fi script: - - ./build.sh --quiet verify + - ./build.sh diff --git a/appveyor.yml b/appveyor.yml index 06545db9f6..944c23c8ba 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -7,9 +7,9 @@ branches: - dev - /^(.*\/)?ci-.*$/ build_script: - - build.cmd --quiet verify + - ps: .\build.ps1 clone_depth: 1 test: off deploy: off # Required for dotnet-test to work -os: Visual Studio 2015 \ No newline at end of file +os: Visual Studio 2015 From 42d0d40b36df498f6367326810852ac546c81352 Mon Sep 17 00:00:00 2001 From: Thierry Fleury Date: Tue, 7 Feb 2017 14:20:42 -0800 Subject: [PATCH 104/221] [Fixes #61] Move must keep object reference --- .../Adapters/ObjectAdapter.cs | 19 +- .../Internal/ConversionResultProvider.cs | 53 ++++- .../Properties/Resources.Designer.cs | 16 ++ .../Resources.resx | 3 + .../InheritedDTO.cs | 10 + .../ListAdapterTest.cs | 75 +++++++ .../NestedObjectTests.cs | 211 ++++++++++++++++++ .../SimpleDTOWithNestedDTO.cs | 3 + 8 files changed, 385 insertions(+), 5 deletions(-) create mode 100644 test/Microsoft.AspNetCore.JsonPatch.Test/InheritedDTO.cs diff --git a/src/Microsoft.AspNetCore.JsonPatch/Adapters/ObjectAdapter.cs b/src/Microsoft.AspNetCore.JsonPatch/Adapters/ObjectAdapter.cs index 0ac2ebbe56..b1a487f088 100644 --- a/src/Microsoft.AspNetCore.JsonPatch/Adapters/ObjectAdapter.cs +++ b/src/Microsoft.AspNetCore.JsonPatch/Adapters/ObjectAdapter.cs @@ -362,10 +362,21 @@ namespace Microsoft.AspNetCore.JsonPatch.Adapters // Get value at 'from' location and add that value to the 'path' location if (TryGetValue(operation.from, objectToApplyTo, operation, out propertyValue)) { - Add(operation.path, - propertyValue, - objectToApplyTo, - operation); + // Create deep copy + var copyResult = ConversionResultProvider.CopyTo(propertyValue, propertyValue.GetType()); + if (copyResult.CanBeConverted) + { + Add(operation.path, + copyResult.ConvertedInstance, + objectToApplyTo, + operation); + } + else + { + var error = CreateOperationFailedError(objectToApplyTo, operation.path, operation, Resources.FormatCannotCopyProperty(operation.from)); + ErrorReporter(error); + return; + } } } diff --git a/src/Microsoft.AspNetCore.JsonPatch/Internal/ConversionResultProvider.cs b/src/Microsoft.AspNetCore.JsonPatch/Internal/ConversionResultProvider.cs index bdf4122394..71af0d27fc 100644 --- a/src/Microsoft.AspNetCore.JsonPatch/Internal/ConversionResultProvider.cs +++ b/src/Microsoft.AspNetCore.JsonPatch/Internal/ConversionResultProvider.cs @@ -2,6 +2,7 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; +using System.Reflection; using Newtonsoft.Json; namespace Microsoft.AspNetCore.JsonPatch.Internal @@ -10,9 +11,44 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal { public static ConversionResult ConvertTo(object value, Type typeToConvertTo) { + if (value == null) + { + return new ConversionResult(IsNullableType(typeToConvertTo), null); + } + else if (typeToConvertTo.IsAssignableFrom(value.GetType())) + { + // No need to convert + return new ConversionResult(true, value); + } + else + { + try + { + var deserialized = JsonConvert.DeserializeObject(JsonConvert.SerializeObject(value), typeToConvertTo); + return new ConversionResult(true, deserialized); + } + catch + { + return new ConversionResult(canBeConverted: false, convertedInstance: null); + } + } + } + + public static ConversionResult CopyTo(object value, Type typeToConvertTo) + { + var targetType = typeToConvertTo; + if (value == null) + { + return new ConversionResult(IsNullableType(typeToConvertTo), null); + } + else if (typeToConvertTo.IsAssignableFrom(value.GetType())) + { + // Keep original type + targetType = value.GetType(); + } try { - var deserialized = JsonConvert.DeserializeObject(JsonConvert.SerializeObject(value), typeToConvertTo); + var deserialized = JsonConvert.DeserializeObject(JsonConvert.SerializeObject(value), targetType); return new ConversionResult(true, deserialized); } catch @@ -20,5 +56,20 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal return new ConversionResult(canBeConverted: false, convertedInstance: null); } } + + private static bool IsNullableType(Type type) + { + var typeInfo = type.GetTypeInfo(); + if (typeInfo.IsValueType) + { + // value types are only nullable if they are Nullable + return typeInfo.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>); + } + else + { + // reference types are always nullable + return true; + } + } } } diff --git a/src/Microsoft.AspNetCore.JsonPatch/Properties/Resources.Designer.cs b/src/Microsoft.AspNetCore.JsonPatch/Properties/Resources.Designer.cs index ed567cf003..97c98c2b05 100644 --- a/src/Microsoft.AspNetCore.JsonPatch/Properties/Resources.Designer.cs +++ b/src/Microsoft.AspNetCore.JsonPatch/Properties/Resources.Designer.cs @@ -26,6 +26,22 @@ namespace Microsoft.AspNetCore.JsonPatch return string.Format(CultureInfo.CurrentCulture, GetString("CannotDeterminePropertyType"), p0); } + /// + /// The property at '{0}' could not be copied. + /// + internal static string CannotCannotCopyProperty + { + get { return GetString("CannotCannotCopyProperty"); } + } + + /// + /// The property at '{0}' could not be copied. + /// + internal static string FormatCannotCopyProperty(object p0) + { + return string.Format(CultureInfo.CurrentCulture, GetString("CannotCannotCopyProperty"), p0); + } + /// /// The '{0}' operation at path '{1}' could not be performed. /// diff --git a/src/Microsoft.AspNetCore.JsonPatch/Resources.resx b/src/Microsoft.AspNetCore.JsonPatch/Resources.resx index 7381ad02fc..87ed5c0a17 100644 --- a/src/Microsoft.AspNetCore.JsonPatch/Resources.resx +++ b/src/Microsoft.AspNetCore.JsonPatch/Resources.resx @@ -117,6 +117,9 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + The property at '{0}' could not be copied. + The type of the property at path '{0}' could not be determined. diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/InheritedDTO.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/InheritedDTO.cs new file mode 100644 index 0000000000..a784a6304b --- /dev/null +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/InheritedDTO.cs @@ -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 +{ + public class InheritedDTO : SimpleDTO + { + public string AdditionalStringProperty { get; set; } + } +} \ No newline at end of file diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/ListAdapterTest.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/ListAdapterTest.cs index 799f6e9e89..077a179a40 100644 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/ListAdapterTest.cs +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/ListAdapterTest.cs @@ -174,6 +174,27 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal Assert.Equal(new List() { "James", "Mike", null }, targetObject); } + [Fact] + public void Add_CompatibleTypeWorks() + { + // Arrange + var sDto = new SimpleDTO(); + var iDto = new InheritedDTO(); + var resolver = new Mock(MockBehavior.Strict); + var targetObject = (new List() { sDto }); + var listAdapter = new ListAdapter(); + string message = null; + + // Act + var addStatus = listAdapter.TryAdd(targetObject, "-", resolver.Object, iDto, out message); + + // Assert + Assert.True(addStatus); + Assert.True(string.IsNullOrEmpty(message), "Expected no error message"); + Assert.Equal(2, targetObject.Count); + Assert.Equal(new List() { sDto, iDto }, targetObject); + } + [Fact] public void Add_NonCompatibleType_Fails() { @@ -244,6 +265,60 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal Assert.Equal(expected, targetObject); } + public static TheoryData AddingKeepsObjectReferenceData { + get { + var sDto1 = new SimpleDTO(); + var sDto2 = new SimpleDTO(); + var sDto3 = new SimpleDTO(); + return new TheoryData() + { + { + new List() { }, + sDto1, + "-", + new List() { sDto1 } + }, + { + new List() { sDto1, sDto2 }, + sDto3, + "-", + new List() { sDto1, sDto2, sDto3 } + }, + { + new List() { sDto1, sDto2 }, + sDto3, + "0", + new List() { sDto3, sDto1, sDto2 } + }, + { + new List() { sDto1, sDto2 }, + sDto3, + "1", + new List() { sDto1, sDto3, sDto2 } + } + }; + } + } + + [Theory] + [MemberData(nameof(AddingKeepsObjectReferenceData))] + public void Add_KeepsObjectReference(IList targetObject, object value, string position, IList expected) + { + // Arrange + var resolver = new Mock(MockBehavior.Strict); + var listAdapter = new ListAdapter(); + string message = null; + + // Act + var addStatus = listAdapter.TryAdd(targetObject, position, resolver.Object, value, out message); + + // Assert + Assert.True(addStatus); + Assert.True(string.IsNullOrEmpty(message), "Expected no error message"); + Assert.Equal(expected.Count, targetObject.Count); + Assert.Equal(expected, targetObject); + } + [Theory] [InlineData(new int[] { }, "0")] [InlineData(new[] { 10, 20 }, "-1")] diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/NestedObjectTests.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/NestedObjectTests.cs index cc2e990997..ece1a6e3d6 100644 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/NestedObjectTests.cs +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/NestedObjectTests.cs @@ -1699,6 +1699,81 @@ namespace Microsoft.AspNetCore.JsonPatch Assert.Equal(new List() { 1, 2, 3, 5 }, doc.SimpleDTO.IntegerList); } + [Fact] + public void Copy_DeepClonesObject() + { + // Arrange + var doc = new SimpleDTOWithNestedDTO() + { + SimpleDTO = new SimpleDTO() + { + StringProperty = "A", + AnotherStringProperty = "B" + }, + InheritedDTO = new InheritedDTO() + { + StringProperty = "C", + AnotherStringProperty = "D" + } + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Copy(o => o.InheritedDTO, o => o.SimpleDTO); + + // Act + patchDoc.ApplyTo(doc); + + // Assert + Assert.Equal("C", doc.SimpleDTO.StringProperty); + Assert.Equal("D", doc.SimpleDTO.AnotherStringProperty); + Assert.Equal("C", doc.InheritedDTO.StringProperty); + Assert.Equal("D", doc.InheritedDTO.AnotherStringProperty); + Assert.NotSame(doc.SimpleDTO.StringProperty, doc.InheritedDTO.StringProperty); + } + + [Fact] + public void Copy_KeepsObjectType() + { + // Arrange + var doc = new SimpleDTOWithNestedDTO() + { + SimpleDTO = new SimpleDTO(), + InheritedDTO = new InheritedDTO() + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Copy(o => o.InheritedDTO, o => o.SimpleDTO); + + // Act + patchDoc.ApplyTo(doc); + + // Assert + Assert.Equal(typeof(InheritedDTO), doc.SimpleDTO.GetType()); + } + + [Fact] + public void Copy_BreaksObjectReference() + { + // Arrange + var doc = new SimpleDTOWithNestedDTO() + { + SimpleDTO = new SimpleDTO(), + InheritedDTO = new InheritedDTO() + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Copy(o => o.InheritedDTO, o => o.SimpleDTO); + + // Act + patchDoc.ApplyTo(doc); + + // Assert + Assert.NotSame(doc.SimpleDTO, doc.InheritedDTO); + } + [Fact] public void Move() { @@ -1752,6 +1827,77 @@ namespace Microsoft.AspNetCore.JsonPatch Assert.Equal(null, doc.SimpleDTO.StringProperty); } + [Fact] + public void Move_KeepsObjectReference() + { + // Arrange + var sDto = new SimpleDTO() + { + StringProperty = "A", + AnotherStringProperty = "B" + }; + var iDto = new InheritedDTO() + { + StringProperty = "C", + AnotherStringProperty = "D" + }; + var doc = new SimpleDTOWithNestedDTO() + { + SimpleDTO = sDto, + InheritedDTO = iDto + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Move(o => o.InheritedDTO, o => o.SimpleDTO); + + // Act + patchDoc.ApplyTo(doc); + + // Assert + Assert.Equal("C", doc.SimpleDTO.StringProperty); + Assert.Equal("D", doc.SimpleDTO.AnotherStringProperty); + Assert.Same(iDto, doc.SimpleDTO); + Assert.Equal(null, doc.InheritedDTO); + } + + [Fact] + public void Move_KeepsObjectReferenceWithSerialization() + { + // Arrange + var sDto = new SimpleDTO() + { + StringProperty = "A", + AnotherStringProperty = "B" + }; + var iDto = new InheritedDTO() + { + StringProperty = "C", + AnotherStringProperty = "D" + }; + var doc = new SimpleDTOWithNestedDTO() + { + SimpleDTO = sDto, + InheritedDTO = iDto + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Move(o => o.InheritedDTO, o => o.SimpleDTO); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject>(serialized); + + // Act + deserialized.ApplyTo(doc); + + // Assert + Assert.Equal("C", doc.SimpleDTO.StringProperty); + Assert.Equal("D", doc.SimpleDTO.AnotherStringProperty); + Assert.Same(iDto, doc.SimpleDTO); + Assert.Equal(null, doc.InheritedDTO); + } + [Fact] public void MoveInList() { @@ -1801,6 +1947,71 @@ namespace Microsoft.AspNetCore.JsonPatch Assert.Equal(new List() { 2, 1, 3 }, doc.SimpleDTO.IntegerList); } + [Fact] + public void Move_KeepsObjectReferenceInList() + { + // Arrange + var sDto1 = new SimpleDTO() { IntegerValue = 1 }; + var sDto2 = new SimpleDTO() { IntegerValue = 2 }; + var sDto3 = new SimpleDTO() { IntegerValue = 3 }; + var doc = new SimpleDTOWithNestedDTO() + { + SimpleDTOList = new List() { + sDto1, + sDto2, + sDto3 + } + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Move(o => o.SimpleDTOList, 0, o => o.SimpleDTOList, 1); + + // Act + patchDoc.ApplyTo(doc); + + // Assert + Assert.Equal(new List() { sDto2, sDto1, sDto3 }, doc.SimpleDTOList); + Assert.Equal(2, doc.SimpleDTOList[0].IntegerValue); + Assert.Equal(1, doc.SimpleDTOList[1].IntegerValue); + Assert.Same(sDto2, doc.SimpleDTOList[0]); + Assert.Same(sDto1, doc.SimpleDTOList[1]); + } + + [Fact] + public void Move_KeepsObjectReferenceInListWithSerialization() + { + // Arrange + var sDto1 = new SimpleDTO() { IntegerValue = 1 }; + var sDto2 = new SimpleDTO() { IntegerValue = 2 }; + var sDto3 = new SimpleDTO() { IntegerValue = 3 }; + var doc = new SimpleDTOWithNestedDTO() + { + SimpleDTOList = new List() { + sDto1, + sDto2, + sDto3 + } + }; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Move(o => o.SimpleDTOList, 0, o => o.SimpleDTOList, 1); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = JsonConvert.DeserializeObject>(serialized); + + // Act + patchDoc.ApplyTo(doc); + + // Assert + Assert.Equal(new List() { sDto2, sDto1, sDto3 }, doc.SimpleDTOList); + Assert.Equal(2, doc.SimpleDTOList[0].IntegerValue); + Assert.Equal(1, doc.SimpleDTOList[1].IntegerValue); + Assert.Same(sDto2, doc.SimpleDTOList[0]); + Assert.Same(sDto1, doc.SimpleDTOList[1]); + } + [Fact] public void MoveFromListToEndOfList() { diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/SimpleDTOWithNestedDTO.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/SimpleDTOWithNestedDTO.cs index 879d820277..de089eb25f 100644 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/SimpleDTOWithNestedDTO.cs +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/SimpleDTOWithNestedDTO.cs @@ -13,6 +13,8 @@ namespace Microsoft.AspNetCore.JsonPatch public SimpleDTO SimpleDTO { get; set; } + public InheritedDTO InheritedDTO { get; set; } + public List SimpleDTOList { get; set; } public IList SimpleDTOIList { get; set; } @@ -21,6 +23,7 @@ namespace Microsoft.AspNetCore.JsonPatch { this.NestedDTO = new NestedDTO(); this.SimpleDTO = new SimpleDTO(); + this.InheritedDTO = new InheritedDTO(); this.SimpleDTOList = new List(); } } From d3a09ca9e879507fb7b7c5a8825da59b3bfa63ef Mon Sep 17 00:00:00 2001 From: Thierry Fleury Date: Tue, 7 Feb 2017 13:38:10 -0800 Subject: [PATCH 105/221] Correct ListAdapter tests Modifying a ReadOnlyCollection will always fail --- test/Microsoft.AspNetCore.JsonPatch.Test/ListAdapterTest.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/ListAdapterTest.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/ListAdapterTest.cs index 077a179a40..6a087edd8f 100644 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/ListAdapterTest.cs +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/ListAdapterTest.cs @@ -181,7 +181,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal var sDto = new SimpleDTO(); var iDto = new InheritedDTO(); var resolver = new Mock(MockBehavior.Strict); - var targetObject = (new List() { sDto }); + var targetObject = new List() { sDto }; var listAdapter = new ListAdapter(); string message = null; @@ -200,7 +200,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal { // Arrange var resolver = new Mock(MockBehavior.Strict); - var targetObject = (new List() { 10, 20 }).AsReadOnly(); + var targetObject = new List() { 10, 20 }; var listAdapter = new ListAdapter(); string message = null; @@ -411,7 +411,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal { // Arrange var resolver = new Mock(MockBehavior.Strict); - var targetObject = (new List() { 10, 20 }).AsReadOnly(); + var targetObject = new List() { 10, 20 }; var listAdapter = new ListAdapter(); string message = null; From 9c618c8600b1748146f5454cf4e25ad3cbb1980c Mon Sep 17 00:00:00 2001 From: David Fowler Date: Wed, 8 Mar 2017 20:00:41 -0800 Subject: [PATCH 106/221] Update .travis.yml --- .travis.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index af659e9ae9..b8f60ce2e5 100644 --- a/.travis.yml +++ b/.travis.yml @@ -14,8 +14,7 @@ env: global: - DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true - DOTNET_CLI_TELEMETRY_OPTOUT: 1 -mono: - - 4.0.5 +mono: none os: - linux - osx From d01f81eeb84d5edbcf6d52de4863e2eceaf8d8ab Mon Sep 17 00:00:00 2001 From: Nate McMaster Date: Tue, 14 Mar 2017 13:40:42 -0700 Subject: [PATCH 107/221] Update appveyor and travis settings --- .travis.yml | 1 - appveyor.yml | 3 +-- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index b8f60ce2e5..e4c69a2a09 100644 --- a/.travis.yml +++ b/.travis.yml @@ -18,7 +18,6 @@ mono: none os: - linux - osx -osx_image: xcode7.3 branches: only: - master diff --git a/appveyor.yml b/appveyor.yml index 944c23c8ba..1041615c68 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -11,5 +11,4 @@ build_script: clone_depth: 1 test: off deploy: off -# Required for dotnet-test to work -os: Visual Studio 2015 +os: Visual Studio 2017 From 832cbdcee8df72ba74d6892542e16312c5d0ef38 Mon Sep 17 00:00:00 2001 From: Nate McMaster Date: Wed, 15 Mar 2017 15:11:25 -0700 Subject: [PATCH 108/221] Unify dependency versions to one file --- build/common.props | 1 - build/dependencies.props | 7 ++++++- .../Microsoft.AspNetCore.JsonPatch.csproj | 4 ++-- ...Microsoft.AspNetCore.JsonPatch.Test.csproj | 19 +++++++++++++----- tools/Key.snk | Bin 596 -> 0 bytes 5 files changed, 22 insertions(+), 9 deletions(-) delete mode 100644 tools/Key.snk diff --git a/build/common.props b/build/common.props index 17a0ccb4d8..1d3e64007b 100644 --- a/build/common.props +++ b/build/common.props @@ -1,5 +1,4 @@ - diff --git a/build/dependencies.props b/build/dependencies.props index e704edaec0..4fe028e673 100644 --- a/build/dependencies.props +++ b/build/dependencies.props @@ -1,6 +1,11 @@ - 1.6.1 + 1.2.0-* 4.3.0 + 9.0.1 + 4.7.1 + 1.6.1 + 15.0.0 + 2.2.0 diff --git a/src/Microsoft.AspNetCore.JsonPatch/Microsoft.AspNetCore.JsonPatch.csproj b/src/Microsoft.AspNetCore.JsonPatch/Microsoft.AspNetCore.JsonPatch.csproj index d3d5b01a89..f68aae1aaa 100644 --- a/src/Microsoft.AspNetCore.JsonPatch/Microsoft.AspNetCore.JsonPatch.csproj +++ b/src/Microsoft.AspNetCore.JsonPatch/Microsoft.AspNetCore.JsonPatch.csproj @@ -10,8 +10,8 @@ - - + + diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/Microsoft.AspNetCore.JsonPatch.Test.csproj b/test/Microsoft.AspNetCore.JsonPatch.Test/Microsoft.AspNetCore.JsonPatch.Test.csproj index e939e5d62c..6f5575c5ee 100644 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/Microsoft.AspNetCore.JsonPatch.Test.csproj +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/Microsoft.AspNetCore.JsonPatch.Test.csproj @@ -1,22 +1,31 @@  + + netcoreapp1.1;net452 netcoreapp1.1 + - - - - - + + + + + + + + + + + diff --git a/tools/Key.snk b/tools/Key.snk deleted file mode 100644 index e10e4889c125d3120cd9e81582243d70f7cbb806..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 596 zcmV-a0;~N80ssI2Bme+XQ$aES1ONa50098=Iw=HCsnz~#iVhm& zj%TU(_THUee?3yHBjk$37ysB?i5#7WD$={H zV4B!OxRPrb|8)HPg~A}8P>^=#y<)56#=E&NzcjOtPK~<4n6GHt=K$ro*T(lhby_@U zEk(hLzk1H)0yXj{A_5>fk-TgNoP|q6(tP2xo8zt8i%212CWM#AeCd?`hS|4~L({h~Moo(~vy&3Z z1uI}`fd^*>o=rwbAGymj6RM^pZm(*Kfhs+Y1#`-2JPWZMK8@;ZWCk2+9bX4YP);~fj-BU*R zQPvWv$89!{Rl9wM+zR>_TSkn^voYxA?2G iKnV#iZ6Ah`K>b=@=IjYJXrxL124zR(38)nxe+&q_$QXwJ From 616f7dcfe74d809543125558af6dc984dfb1315c Mon Sep 17 00:00:00 2001 From: Nate McMaster Date: Tue, 21 Mar 2017 11:46:29 -0700 Subject: [PATCH 109/221] Update Travis to macOS Sierra [skip appveyor] --- .travis.yml | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/.travis.yml b/.travis.yml index e4c69a2a09..2a46104677 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,15 +1,6 @@ language: csharp -sudo: required +sudo: false dist: trusty -addons: - apt: - packages: - - gettext - - libcurl4-openssl-dev - - libicu-dev - - libssl-dev - - libunwind8 - - zlib1g env: global: - DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true @@ -18,6 +9,7 @@ mono: none os: - linux - osx +osx_image: xcode8.2 branches: only: - master From d2be921ca461505e93a5bae957ea345d1b1b1379 Mon Sep 17 00:00:00 2001 From: Kiran Challa Date: Mon, 13 Mar 2017 17:20:01 -0700 Subject: [PATCH 110/221] Converted test project to run on netcoreapp2.0 --- build/dependencies.props | 1 + .../Microsoft.AspNetCore.JsonPatch.Test.csproj | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/build/dependencies.props b/build/dependencies.props index 4fe028e673..b810d63d6e 100644 --- a/build/dependencies.props +++ b/build/dependencies.props @@ -5,6 +5,7 @@ 9.0.1 4.7.1 1.6.1 + 2.0.0-* 15.0.0 2.2.0 diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/Microsoft.AspNetCore.JsonPatch.Test.csproj b/test/Microsoft.AspNetCore.JsonPatch.Test/Microsoft.AspNetCore.JsonPatch.Test.csproj index 6f5575c5ee..bb67d98fb1 100644 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/Microsoft.AspNetCore.JsonPatch.Test.csproj +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/Microsoft.AspNetCore.JsonPatch.Test.csproj @@ -3,8 +3,8 @@ - netcoreapp1.1;net452 - netcoreapp1.1 + netcoreapp2.0;net452 + netcoreapp2.0 From f66753cc3c0ec85ea806970a50271acba16b982f Mon Sep 17 00:00:00 2001 From: Pranav K Date: Sun, 12 Mar 2017 15:50:01 -0700 Subject: [PATCH 111/221] Remove net451 as a cross-compile target --- .gitignore | 3 ++- .../Microsoft.AspNetCore.JsonPatch.csproj | 7 ++----- .../Microsoft.AspNetCore.JsonPatch.Test.csproj | 2 +- 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/.gitignore b/.gitignore index 06cfaa0cbe..2e8ec28064 100644 --- a/.gitignore +++ b/.gitignore @@ -35,4 +35,5 @@ nuget.exe *.sln.ide node_modules *launchSettings.json -*.orig \ No newline at end of file +*.orig +global.json diff --git a/src/Microsoft.AspNetCore.JsonPatch/Microsoft.AspNetCore.JsonPatch.csproj b/src/Microsoft.AspNetCore.JsonPatch/Microsoft.AspNetCore.JsonPatch.csproj index f68aae1aaa..073f7f170f 100644 --- a/src/Microsoft.AspNetCore.JsonPatch/Microsoft.AspNetCore.JsonPatch.csproj +++ b/src/Microsoft.AspNetCore.JsonPatch/Microsoft.AspNetCore.JsonPatch.csproj @@ -3,7 +3,7 @@ ASP.NET Core support for JSON PATCH. - net451;netstandard1.3 + netstandard1.3 $(NoWarn);CS1591 true aspnetcore;json;jsonpatch @@ -11,11 +11,8 @@ - - - - + diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/Microsoft.AspNetCore.JsonPatch.Test.csproj b/test/Microsoft.AspNetCore.JsonPatch.Test/Microsoft.AspNetCore.JsonPatch.Test.csproj index bb67d98fb1..d8ef8158e3 100644 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/Microsoft.AspNetCore.JsonPatch.Test.csproj +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/Microsoft.AspNetCore.JsonPatch.Test.csproj @@ -3,7 +3,7 @@ - netcoreapp2.0;net452 + netcoreapp2.0;net46 netcoreapp2.0 From ab6e74f4b4eb19c02156ed85934a29000b4d008f Mon Sep 17 00:00:00 2001 From: Kiran Challa Date: Mon, 27 Mar 2017 18:14:22 -0700 Subject: [PATCH 112/221] Upgraded Json.NET version to 10.0.1 --- build/dependencies.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/dependencies.props b/build/dependencies.props index b810d63d6e..8aa0110742 100644 --- a/build/dependencies.props +++ b/build/dependencies.props @@ -2,7 +2,7 @@ 1.2.0-* 4.3.0 - 9.0.1 + 10.0.1 4.7.1 1.6.1 2.0.0-* From 99ff496e7128b3b51968c0971459143df1321205 Mon Sep 17 00:00:00 2001 From: Pranav K Date: Wed, 29 Mar 2017 11:30:34 -0700 Subject: [PATCH 113/221] Updating to 2.0.0 Internal.AspNetCore.Sdk --- build/common.props | 2 +- build/dependencies.props | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/build/common.props b/build/common.props index 1d3e64007b..ffe4d99846 100644 --- a/build/common.props +++ b/build/common.props @@ -13,7 +13,7 @@ - + diff --git a/build/dependencies.props b/build/dependencies.props index 8aa0110742..72d6874ffd 100644 --- a/build/dependencies.props +++ b/build/dependencies.props @@ -2,6 +2,7 @@ 1.2.0-* 4.3.0 + 2.0.0-* 10.0.1 4.7.1 1.6.1 @@ -9,4 +10,4 @@ 15.0.0 2.2.0 - + \ No newline at end of file From 290fd0a28da2b4edebb74709fed71517cfcc6778 Mon Sep 17 00:00:00 2001 From: Pranav K Date: Mon, 3 Apr 2017 21:41:10 -0700 Subject: [PATCH 114/221] Updating versions to 2.0.0-preview1 --- build/dependencies.props | 2 +- version.props | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/build/dependencies.props b/build/dependencies.props index 72d6874ffd..5f6c92189c 100644 --- a/build/dependencies.props +++ b/build/dependencies.props @@ -1,6 +1,6 @@ - 1.2.0-* + 2.0.0-* 4.3.0 2.0.0-* 10.0.1 diff --git a/version.props b/version.props index e77c8d9c38..44cb2290b9 100644 --- a/version.props +++ b/version.props @@ -1,7 +1,7 @@ - 1.2.0 + 2.0.0 preview1 \ No newline at end of file From e61f7a591ce3d5c05ef3246dfd2ea45662dbb277 Mon Sep 17 00:00:00 2001 From: Pranav K Date: Tue, 25 Apr 2017 11:04:08 -0700 Subject: [PATCH 115/221] Use Bundled NETStandard.Library \ NETCoreApp versions instead of explicitly specifying one --- build/common.props | 2 +- build/dependencies.props | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/build/common.props b/build/common.props index ffe4d99846..a2698f3553 100644 --- a/build/common.props +++ b/build/common.props @@ -17,7 +17,7 @@ - + diff --git a/build/dependencies.props b/build/dependencies.props index 5f6c92189c..ac44ce3323 100644 --- a/build/dependencies.props +++ b/build/dependencies.props @@ -5,9 +5,7 @@ 2.0.0-* 10.0.1 4.7.1 - 1.6.1 - 2.0.0-* 15.0.0 2.2.0 - \ No newline at end of file + From c4dbc8d31592bb3ca191e77a6aeecffbbeb964df Mon Sep 17 00:00:00 2001 From: Pranav K Date: Tue, 25 Apr 2017 22:03:21 -0700 Subject: [PATCH 116/221] Branching for 2.0.0-preview1 --- NuGet.config | 4 ++-- build.ps1 | 2 +- build.sh | 2 +- build/dependencies.props | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/NuGet.config b/NuGet.config index 93f1ac47df..fa4304af9c 100644 --- a/NuGet.config +++ b/NuGet.config @@ -1,7 +1,7 @@ - + - + diff --git a/build.ps1 b/build.ps1 index 5bf0e2c113..225b1fe450 100644 --- a/build.ps1 +++ b/build.ps1 @@ -33,7 +33,7 @@ cd $PSScriptRoot $repoFolder = $PSScriptRoot $env:REPO_FOLDER = $repoFolder -$koreBuildZip="https://github.com/aspnet/KoreBuild/archive/dev.zip" +$koreBuildZip="https://github.com/aspnet/KoreBuild/archive/rel/2.0.0-preview1.zip" if ($env:KOREBUILD_ZIP) { $koreBuildZip=$env:KOREBUILD_ZIP diff --git a/build.sh b/build.sh index b0bcadb579..702b25c636 100755 --- a/build.sh +++ b/build.sh @@ -2,7 +2,7 @@ repoFolder="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" cd $repoFolder -koreBuildZip="https://github.com/aspnet/KoreBuild/archive/dev.zip" +koreBuildZip="https://github.com/aspnet/KoreBuild/archive/rel/2.0.0-preview1.zip" if [ ! -z $KOREBUILD_ZIP ]; then koreBuildZip=$KOREBUILD_ZIP fi diff --git a/build/dependencies.props b/build/dependencies.props index ac44ce3323..dddf01f9f0 100644 --- a/build/dependencies.props +++ b/build/dependencies.props @@ -1,6 +1,6 @@ - 2.0.0-* + 2.0.0-preview1-* 4.3.0 2.0.0-* 10.0.1 From d0e7b6b7cdd23c352cb06b721707fb10de605524 Mon Sep 17 00:00:00 2001 From: Pranav K Date: Wed, 26 Apr 2017 07:13:08 -0700 Subject: [PATCH 117/221] Updating package version to preview2 --- version.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.props b/version.props index 44cb2290b9..0b2b8e0010 100644 --- a/version.props +++ b/version.props @@ -2,6 +2,6 @@ 2.0.0 - preview1 + preview2 \ No newline at end of file From 4628a2ff4e3097dd7e3c14e5e0d74d9c3d50371c Mon Sep 17 00:00:00 2001 From: Pranav K Date: Mon, 1 May 2017 12:39:39 -0700 Subject: [PATCH 118/221] Use the bundled NETStandard.Library package in netstandard targeting libraries --- build/dependencies.props | 1 + 1 file changed, 1 insertion(+) diff --git a/build/dependencies.props b/build/dependencies.props index dddf01f9f0..8dce2099b3 100644 --- a/build/dependencies.props +++ b/build/dependencies.props @@ -5,6 +5,7 @@ 2.0.0-* 10.0.1 4.7.1 + $(BundledNETStandardPackageVersion) 15.0.0 2.2.0 From 8a0a8a781ec03d19a030db3b737b0d27c28f2497 Mon Sep 17 00:00:00 2001 From: Pavel Krymets Date: Fri, 5 May 2017 10:23:47 -0700 Subject: [PATCH 119/221] Update InternalAspNetCoreSdkVersion --- build/dependencies.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/dependencies.props b/build/dependencies.props index 8dce2099b3..40945df373 100644 --- a/build/dependencies.props +++ b/build/dependencies.props @@ -2,7 +2,7 @@ 2.0.0-preview1-* 4.3.0 - 2.0.0-* + 2.1.0-* 10.0.1 4.7.1 $(BundledNETStandardPackageVersion) From 378136f794017ed847d4ed0f3273d19bd89eb125 Mon Sep 17 00:00:00 2001 From: Jass Bagga Date: Fri, 5 May 2017 16:12:46 -0700 Subject: [PATCH 120/221] Change TFM to netcoreapp2.0 (#78) --- .../Microsoft.AspNetCore.JsonPatch.csproj | 2 +- .../Microsoft.AspNetCore.JsonPatch.Test.csproj | 8 +------- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/src/Microsoft.AspNetCore.JsonPatch/Microsoft.AspNetCore.JsonPatch.csproj b/src/Microsoft.AspNetCore.JsonPatch/Microsoft.AspNetCore.JsonPatch.csproj index 073f7f170f..f31e8b9f82 100644 --- a/src/Microsoft.AspNetCore.JsonPatch/Microsoft.AspNetCore.JsonPatch.csproj +++ b/src/Microsoft.AspNetCore.JsonPatch/Microsoft.AspNetCore.JsonPatch.csproj @@ -3,7 +3,7 @@ ASP.NET Core support for JSON PATCH. - netstandard1.3 + netcoreapp2.0 $(NoWarn);CS1591 true aspnetcore;json;jsonpatch diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/Microsoft.AspNetCore.JsonPatch.Test.csproj b/test/Microsoft.AspNetCore.JsonPatch.Test/Microsoft.AspNetCore.JsonPatch.Test.csproj index d8ef8158e3..8f007862cd 100644 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/Microsoft.AspNetCore.JsonPatch.Test.csproj +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/Microsoft.AspNetCore.JsonPatch.Test.csproj @@ -3,8 +3,7 @@ - netcoreapp2.0;net46 - netcoreapp2.0 + netcoreapp2.0 @@ -19,11 +18,6 @@ - - - - - From ec0ce4b63855275c18b40ae9d1ff1e085bd9cea0 Mon Sep 17 00:00:00 2001 From: Jass Bagga Date: Fri, 5 May 2017 16:17:15 -0700 Subject: [PATCH 121/221] Change TFM to netcoreapp2.0 (#78) --- .../Microsoft.AspNetCore.JsonPatch.csproj | 2 +- .../Microsoft.AspNetCore.JsonPatch.Test.csproj | 8 +------- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/src/Microsoft.AspNetCore.JsonPatch/Microsoft.AspNetCore.JsonPatch.csproj b/src/Microsoft.AspNetCore.JsonPatch/Microsoft.AspNetCore.JsonPatch.csproj index 073f7f170f..f31e8b9f82 100644 --- a/src/Microsoft.AspNetCore.JsonPatch/Microsoft.AspNetCore.JsonPatch.csproj +++ b/src/Microsoft.AspNetCore.JsonPatch/Microsoft.AspNetCore.JsonPatch.csproj @@ -3,7 +3,7 @@ ASP.NET Core support for JSON PATCH. - netstandard1.3 + netcoreapp2.0 $(NoWarn);CS1591 true aspnetcore;json;jsonpatch diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/Microsoft.AspNetCore.JsonPatch.Test.csproj b/test/Microsoft.AspNetCore.JsonPatch.Test/Microsoft.AspNetCore.JsonPatch.Test.csproj index d8ef8158e3..8f007862cd 100644 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/Microsoft.AspNetCore.JsonPatch.Test.csproj +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/Microsoft.AspNetCore.JsonPatch.Test.csproj @@ -3,8 +3,7 @@ - netcoreapp2.0;net46 - netcoreapp2.0 + netcoreapp2.0 @@ -19,11 +18,6 @@ - - - - - From 7a7dc711643858fb18e69cad296d30233ddcf847 Mon Sep 17 00:00:00 2001 From: Pavel Krymets Date: Wed, 10 May 2017 11:45:31 -0700 Subject: [PATCH 122/221] Remove unnecessary package references (#79) --- build/dependencies.props | 1 - .../Microsoft.AspNetCore.JsonPatch.csproj | 4 +--- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/build/dependencies.props b/build/dependencies.props index ce45e95994..28b5745a79 100644 --- a/build/dependencies.props +++ b/build/dependencies.props @@ -1,7 +1,6 @@ 2.0.0-* - 4.3.0 2.1.0-* 10.0.1 4.7.1 diff --git a/src/Microsoft.AspNetCore.JsonPatch/Microsoft.AspNetCore.JsonPatch.csproj b/src/Microsoft.AspNetCore.JsonPatch/Microsoft.AspNetCore.JsonPatch.csproj index f31e8b9f82..f9c60761bf 100644 --- a/src/Microsoft.AspNetCore.JsonPatch/Microsoft.AspNetCore.JsonPatch.csproj +++ b/src/Microsoft.AspNetCore.JsonPatch/Microsoft.AspNetCore.JsonPatch.csproj @@ -1,4 +1,4 @@ - + @@ -11,9 +11,7 @@ - - From a7524e189d7f0c0099ea9d0b2a53ae440a8df605 Mon Sep 17 00:00:00 2001 From: Nate McMaster Date: Mon, 15 May 2017 16:14:55 -0700 Subject: [PATCH 123/221] Upgrade test framework versions and fix test issues --- build/dependencies.props | 4 ++-- .../Dynamic/MoveOperationTests.cs | 4 ++-- .../Dynamic/MoveTypedOperationTests.cs | 2 +- .../Dynamic/RemoveOperationTests.cs | 6 ++--- .../Dynamic/RemoveTypedOperationTests.cs | 6 ++--- .../Dynamic/ReplaceOperationTests.cs | 2 +- .../Dynamic/ReplaceTypedOperationTests.cs | 6 ++--- ...nPatchDocumentJsonPropertyAttributeTest.cs | 10 ++++----- ...Microsoft.AspNetCore.JsonPatch.Test.csproj | 4 ---- .../NestedObjectTests.cs | 14 ++++++------ .../ObjectAdapterTests.cs | 22 +++++++++---------- 11 files changed, 38 insertions(+), 42 deletions(-) diff --git a/build/dependencies.props b/build/dependencies.props index 28b5745a79..3abab6008e 100644 --- a/build/dependencies.props +++ b/build/dependencies.props @@ -5,7 +5,7 @@ 10.0.1 4.7.1 $(BundledNETStandardPackageVersion) - 15.0.0 - 2.2.0 + 15.3.0-* + 2.3.0-beta2-* diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/MoveOperationTests.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/MoveOperationTests.cs index ed367848b7..5e2f7ae814 100644 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/MoveOperationTests.cs +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/MoveOperationTests.cs @@ -98,7 +98,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic deserialized.ApplyTo(doc); Assert.Equal("B", doc.StringProperty); - Assert.Equal(null, doc.SimpleDTO.AnotherStringProperty); + Assert.Null(doc.SimpleDTO.AnotherStringProperty); } [Fact] @@ -121,7 +121,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic deserialized.ApplyTo(doc); Assert.Equal("A", doc.Nested.AnotherStringProperty); - Assert.Equal(null, doc.Nested.StringProperty); + Assert.Null(doc.Nested.StringProperty); } [Fact] diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/MoveTypedOperationTests.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/MoveTypedOperationTests.cs index cd4124d564..f57ad3d11c 100644 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/MoveTypedOperationTests.cs +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/MoveTypedOperationTests.cs @@ -28,7 +28,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic deserialized.ApplyTo(doc); Assert.Equal("A", doc.AnotherStringProperty); - Assert.Equal(null, doc.StringProperty); + Assert.Null(doc.StringProperty); } [Fact] diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/RemoveOperationTests.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/RemoveOperationTests.cs index 6e903bf2ec..f0164765ee 100644 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/RemoveOperationTests.cs +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/RemoveOperationTests.cs @@ -163,7 +163,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic var deserialized = JsonConvert.DeserializeObject(serialized); deserialized.ApplyTo(doc); - Assert.Equal(null, doc.SimpleDTO.StringProperty); + Assert.Null(doc.SimpleDTO.StringProperty); } [Fact] @@ -184,7 +184,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic deserialized.ApplyTo(doc); - Assert.Equal(null, doc.SimpleDTO.StringProperty); + Assert.Null(doc.SimpleDTO.StringProperty); } [Fact] @@ -299,4 +299,4 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic Assert.Equal(new List() { 1, 2 }, doc.SimpleDTO.IntegerList); } } -} \ No newline at end of file +} diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/RemoveTypedOperationTests.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/RemoveTypedOperationTests.cs index 126706eef2..50ae6e8d5d 100644 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/RemoveTypedOperationTests.cs +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/RemoveTypedOperationTests.cs @@ -27,7 +27,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic deserialized.ApplyTo(doc); - Assert.Equal(null, doc.StringProperty); + Assert.Null(doc.StringProperty); } [Fact] @@ -138,7 +138,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic deserialized.ApplyTo(doc); - Assert.Equal(null, doc.SimpleDTO.StringProperty); + Assert.Null(doc.SimpleDTO.StringProperty); } [Fact] @@ -241,4 +241,4 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic Assert.Equal(new List() { 1, 2 }, doc.SimpleDTO.IntegerList); } } -} \ No newline at end of file +} diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/ReplaceOperationTests.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/ReplaceOperationTests.cs index b8e7196068..c5936ec1b0 100644 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/ReplaceOperationTests.cs +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/ReplaceOperationTests.cs @@ -107,7 +107,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic Assert.Equal(1, doc.SimpleDTO.DoubleValue); Assert.Equal(0, doc.SimpleDTO.IntegerValue); - Assert.Equal(null, doc.SimpleDTO.IntegerList); + Assert.Null(doc.SimpleDTO.IntegerList); } [Fact] diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/ReplaceTypedOperationTests.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/ReplaceTypedOperationTests.cs index 589e86e03a..d0bf23f487 100644 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/ReplaceTypedOperationTests.cs +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/ReplaceTypedOperationTests.cs @@ -25,7 +25,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic JsonPatchDocument patchDoc = new JsonPatchDocument(); patchDoc.Replace("GuidValue", newGuid); - // serialize & deserialize + // serialize & deserialize var serialized = JsonConvert.SerializeObject(patchDoc); var deserizalized = JsonConvert.DeserializeObject(serialized); @@ -55,7 +55,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic JsonPatchDocument patchDoc = new JsonPatchDocument(); patchDoc.Replace("SimpleDTO", newDTO); - // serialize & deserialize + // serialize & deserialize var serialized = JsonConvert.SerializeObject(patchDoc); var deserialized = JsonConvert.DeserializeObject(serialized); @@ -63,7 +63,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic Assert.Equal(1, doc.SimpleDTO.DoubleValue); Assert.Equal(0, doc.SimpleDTO.IntegerValue); - Assert.Equal(null, doc.SimpleDTO.IntegerList); + Assert.Null(doc.SimpleDTO.IntegerList); } [Fact] diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/JsonPatchDocumentJsonPropertyAttributeTest.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/JsonPatchDocumentJsonPropertyAttributeTest.cs index 182cf1cd6d..efc780b388 100644 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/JsonPatchDocumentJsonPropertyAttributeTest.cs +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/JsonPatchDocumentJsonPropertyAttributeTest.cs @@ -25,7 +25,7 @@ namespace Microsoft.AspNetCore.JsonPatch // get path var pathToCheck = deserialized.Operations.First().path; - Assert.Equal(pathToCheck, "/anothername"); + Assert.Equal("/anothername", pathToCheck); } [Fact] @@ -82,7 +82,7 @@ namespace Microsoft.AspNetCore.JsonPatch deserialized.ApplyTo(doc); - Assert.Equal(doc.AnotherName, "John"); + Assert.Equal("John", doc.AnotherName); } [Fact] @@ -107,7 +107,7 @@ namespace Microsoft.AspNetCore.JsonPatch deserialized.ApplyTo(doc); - Assert.Equal(doc.Name, "John"); + Assert.Equal("John", doc.Name); } [Fact] @@ -143,7 +143,7 @@ namespace Microsoft.AspNetCore.JsonPatch deserialized.ApplyTo(doc); - Assert.Equal(null, doc.Name); + Assert.Null(doc.Name); } [Fact] @@ -178,7 +178,7 @@ namespace Microsoft.AspNetCore.JsonPatch // get path var pathToCheck = deserialized.Operations.First().path; - Assert.Equal(pathToCheck, "/anothername"); + Assert.Equal("/anothername", pathToCheck); } [Fact] diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/Microsoft.AspNetCore.JsonPatch.Test.csproj b/test/Microsoft.AspNetCore.JsonPatch.Test/Microsoft.AspNetCore.JsonPatch.Test.csproj index 8f007862cd..29a1f7dbed 100644 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/Microsoft.AspNetCore.JsonPatch.Test.csproj +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/Microsoft.AspNetCore.JsonPatch.Test.csproj @@ -18,8 +18,4 @@ - - - - diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/NestedObjectTests.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/NestedObjectTests.cs index ece1a6e3d6..4aa25a3af1 100644 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/NestedObjectTests.cs +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/NestedObjectTests.cs @@ -597,7 +597,7 @@ namespace Microsoft.AspNetCore.JsonPatch patchDoc.ApplyTo(doc); // Assert - Assert.Equal(null, doc.SimpleDTO.StringProperty); + Assert.Null(doc.SimpleDTO.StringProperty); } [Fact] @@ -623,7 +623,7 @@ namespace Microsoft.AspNetCore.JsonPatch deserialized.ApplyTo(doc); // Assert - Assert.Equal(null, doc.SimpleDTO.StringProperty); + Assert.Null(doc.SimpleDTO.StringProperty); } [Fact] @@ -1796,7 +1796,7 @@ namespace Microsoft.AspNetCore.JsonPatch // Assert Assert.Equal("A", doc.SimpleDTO.AnotherStringProperty); - Assert.Equal(null, doc.SimpleDTO.StringProperty); + Assert.Null(doc.SimpleDTO.StringProperty); } [Fact] @@ -1824,7 +1824,7 @@ namespace Microsoft.AspNetCore.JsonPatch // Assert Assert.Equal("A", doc.SimpleDTO.AnotherStringProperty); - Assert.Equal(null, doc.SimpleDTO.StringProperty); + Assert.Null(doc.SimpleDTO.StringProperty); } [Fact] @@ -1858,7 +1858,7 @@ namespace Microsoft.AspNetCore.JsonPatch Assert.Equal("C", doc.SimpleDTO.StringProperty); Assert.Equal("D", doc.SimpleDTO.AnotherStringProperty); Assert.Same(iDto, doc.SimpleDTO); - Assert.Equal(null, doc.InheritedDTO); + Assert.Null(doc.InheritedDTO); } [Fact] @@ -1895,7 +1895,7 @@ namespace Microsoft.AspNetCore.JsonPatch Assert.Equal("C", doc.SimpleDTO.StringProperty); Assert.Equal("D", doc.SimpleDTO.AnotherStringProperty); Assert.Same(iDto, doc.SimpleDTO); - Assert.Equal(null, doc.InheritedDTO); + Assert.Null(doc.InheritedDTO); } [Fact] @@ -2269,4 +2269,4 @@ namespace Microsoft.AspNetCore.JsonPatch Assert.Equal(new List() { 1, 2, 3, 5 }, doc.SimpleDTO.IntegerList); } } -} \ No newline at end of file +} diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/ObjectAdapterTests.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/ObjectAdapterTests.cs index d14daadbff..56b25d22be 100644 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/ObjectAdapterTests.cs +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/ObjectAdapterTests.cs @@ -377,7 +377,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Adapters patchDoc.ApplyTo(doc); // Assert - Assert.Equal(null, doc.StringProperty); + Assert.Null(doc.StringProperty); } [Fact] @@ -400,7 +400,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Adapters deserialized.ApplyTo(doc); // Assert - Assert.Equal(null, doc.StringProperty); + Assert.Null(doc.StringProperty); } [Fact] @@ -654,7 +654,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Adapters // Arrange var doc = new SimpleDTOWithNullCheck() { - StringProperty = "A", + StringProperty = "A", }; // create patch @@ -720,8 +720,8 @@ namespace Microsoft.AspNetCore.JsonPatch.Adapters var serialized = JsonConvert.SerializeObject(patchDoc); // Assert - Assert.Equal(false, serialized.Contains("operations")); - Assert.Equal(false, serialized.Contains("Operations")); + Assert.False(serialized.Contains("operations")); + Assert.False(serialized.Contains("Operations")); } [Fact] @@ -864,7 +864,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Adapters // Assert Assert.Equal(1, doc.SimpleDTO.DoubleValue); Assert.Equal(0, doc.SimpleDTO.IntegerValue); - Assert.Equal(null, doc.SimpleDTO.IntegerList); + Assert.Null(doc.SimpleDTO.IntegerList); } [Fact] @@ -1460,7 +1460,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Adapters // Assert Assert.Equal("A", doc.AnotherStringProperty); - Assert.Equal(null, doc.StringProperty); + Assert.Null(doc.StringProperty); } [Fact] @@ -1485,7 +1485,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Adapters // Assert Assert.Equal("A", doc.AnotherStringProperty); - Assert.Equal(null, doc.StringProperty); + Assert.Null(doc.StringProperty); } [Fact] @@ -2283,7 +2283,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Adapters deserialized.ApplyTo(doc); // Assert - Assert.Equal(null, doc.StringProperty); + Assert.Null(doc.StringProperty); } class ClassWithPrivateProperties @@ -2308,8 +2308,8 @@ namespace Microsoft.AspNetCore.JsonPatch.Adapters // Act & Assert var exception = Assert.Throws(() => patchDoc.ApplyTo(doc)); Assert.Equal( - string.Format("The target location specified by path segment '{0}' was not found.", "Age"), + string.Format("The target location specified by path segment '{0}' was not found.", "Age"), exception.Message); } } -} \ No newline at end of file +} From e3114dc6a41be48dfeff17306fad428670c0f550 Mon Sep 17 00:00:00 2001 From: Kiran Challa Date: Fri, 19 May 2017 13:44:15 -0700 Subject: [PATCH 124/221] Temporarily change tfm to netstandard1.3 Ideally we want to target netstandard2.0 but this conversion is blocked on the issue: https://github.com/dotnet/sdk/issues/1219 --- build/dependencies.props | 1 + .../Microsoft.AspNetCore.JsonPatch.csproj | 4 +++- .../Microsoft.AspNetCore.JsonPatch.Test.csproj | 3 ++- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/build/dependencies.props b/build/dependencies.props index 3abab6008e..0011678b86 100644 --- a/build/dependencies.props +++ b/build/dependencies.props @@ -1,6 +1,7 @@ 2.0.0-* + 4.3.0 2.1.0-* 10.0.1 4.7.1 diff --git a/src/Microsoft.AspNetCore.JsonPatch/Microsoft.AspNetCore.JsonPatch.csproj b/src/Microsoft.AspNetCore.JsonPatch/Microsoft.AspNetCore.JsonPatch.csproj index f9c60761bf..3e275fe102 100644 --- a/src/Microsoft.AspNetCore.JsonPatch/Microsoft.AspNetCore.JsonPatch.csproj +++ b/src/Microsoft.AspNetCore.JsonPatch/Microsoft.AspNetCore.JsonPatch.csproj @@ -3,13 +3,15 @@ ASP.NET Core support for JSON PATCH. - netcoreapp2.0 + netstandard1.3 $(NoWarn);CS1591 true aspnetcore;json;jsonpatch + + diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/Microsoft.AspNetCore.JsonPatch.Test.csproj b/test/Microsoft.AspNetCore.JsonPatch.Test/Microsoft.AspNetCore.JsonPatch.Test.csproj index 29a1f7dbed..f5b8c8268a 100644 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/Microsoft.AspNetCore.JsonPatch.Test.csproj +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/Microsoft.AspNetCore.JsonPatch.Test.csproj @@ -3,7 +3,8 @@ - netcoreapp2.0 + netcoreapp2.0;net461 + netcoreapp2.0 From 758006d17f7d6accea730627d451a8d0c6b731cf Mon Sep 17 00:00:00 2001 From: Kiran Challa Date: Fri, 26 May 2017 12:41:43 -0700 Subject: [PATCH 125/221] Updated to use the latest shared runtime --- build/dependencies.props | 1 + 1 file changed, 1 insertion(+) diff --git a/build/dependencies.props b/build/dependencies.props index 0011678b86..55f77f78f3 100644 --- a/build/dependencies.props +++ b/build/dependencies.props @@ -6,6 +6,7 @@ 10.0.1 4.7.1 $(BundledNETStandardPackageVersion) + 2.0.0-* 15.3.0-* 2.3.0-beta2-* From 14c35c1faef0d2afe1e5d2a93b888ff66100769d Mon Sep 17 00:00:00 2001 From: Pranav K Date: Wed, 31 May 2017 19:36:49 -0700 Subject: [PATCH 126/221] Branching for rel/2.0.0-preview2 --- NuGet.config | 5 +++-- build/dependencies.props | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/NuGet.config b/NuGet.config index 93f1ac47df..c4bc056c4d 100644 --- a/NuGet.config +++ b/NuGet.config @@ -1,8 +1,9 @@  - + + - + \ No newline at end of file diff --git a/build/dependencies.props b/build/dependencies.props index 55f77f78f3..2b3acda9ac 100644 --- a/build/dependencies.props +++ b/build/dependencies.props @@ -1,6 +1,6 @@ - 2.0.0-* + 2.0.0-preview2-* 4.3.0 2.1.0-* 10.0.1 From b647c68176a5a6e71906c16fc5c5e9f741fb1f87 Mon Sep 17 00:00:00 2001 From: Pranav K Date: Wed, 31 May 2017 19:53:23 -0700 Subject: [PATCH 127/221] Updating build scripts to point to 2.0.0-preview2 KoreBuild --- build.ps1 | 2 +- build.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/build.ps1 b/build.ps1 index 5bf0e2c113..3a2476b2b4 100644 --- a/build.ps1 +++ b/build.ps1 @@ -33,7 +33,7 @@ cd $PSScriptRoot $repoFolder = $PSScriptRoot $env:REPO_FOLDER = $repoFolder -$koreBuildZip="https://github.com/aspnet/KoreBuild/archive/dev.zip" +$koreBuildZip="https://github.com/aspnet/KoreBuild/archive/rel/2.0.0-preview2.zip" if ($env:KOREBUILD_ZIP) { $koreBuildZip=$env:KOREBUILD_ZIP diff --git a/build.sh b/build.sh index b0bcadb579..a40bdb87b1 100755 --- a/build.sh +++ b/build.sh @@ -2,7 +2,7 @@ repoFolder="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" cd $repoFolder -koreBuildZip="https://github.com/aspnet/KoreBuild/archive/dev.zip" +koreBuildZip="https://github.com/aspnet/KoreBuild/archive/rel/2.0.0-preview2.zip" if [ ! -z $KOREBUILD_ZIP ]; then koreBuildZip=$KOREBUILD_ZIP fi From f66166f6bc4165b01ba1d7fb3682ca99feb488a7 Mon Sep 17 00:00:00 2001 From: Pranav K Date: Thu, 1 Jun 2017 10:47:14 -0700 Subject: [PATCH 128/221] Updating versions to preview3 --- NuGet.config | 1 + version.props | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/NuGet.config b/NuGet.config index 93f1ac47df..4e8a1f6de1 100644 --- a/NuGet.config +++ b/NuGet.config @@ -1,6 +1,7 @@  + diff --git a/version.props b/version.props index 0b2b8e0010..90a2f5b5cc 100644 --- a/version.props +++ b/version.props @@ -2,6 +2,6 @@ 2.0.0 - preview2 + preview3 \ No newline at end of file From d9531031a869cab74d412ecfb396ce1b0797c301 Mon Sep 17 00:00:00 2001 From: Kiran Challa Date: Tue, 6 Jun 2017 10:28:19 -0700 Subject: [PATCH 129/221] Updated to netstandard2.0 --- build/dependencies.props | 3 ++- .../Microsoft.AspNetCore.JsonPatch.csproj | 3 +-- .../Microsoft.AspNetCore.JsonPatch.Test.csproj | 4 ++++ 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/build/dependencies.props b/build/dependencies.props index 2b3acda9ac..9a1d9569a2 100644 --- a/build/dependencies.props +++ b/build/dependencies.props @@ -1,10 +1,11 @@ 2.0.0-preview2-* - 4.3.0 + 4.4.0-* 2.1.0-* 10.0.1 4.7.1 + 2.0.0-* $(BundledNETStandardPackageVersion) 2.0.0-* 15.3.0-* diff --git a/src/Microsoft.AspNetCore.JsonPatch/Microsoft.AspNetCore.JsonPatch.csproj b/src/Microsoft.AspNetCore.JsonPatch/Microsoft.AspNetCore.JsonPatch.csproj index 3e275fe102..e9732e8621 100644 --- a/src/Microsoft.AspNetCore.JsonPatch/Microsoft.AspNetCore.JsonPatch.csproj +++ b/src/Microsoft.AspNetCore.JsonPatch/Microsoft.AspNetCore.JsonPatch.csproj @@ -3,7 +3,7 @@ ASP.NET Core support for JSON PATCH. - netstandard1.3 + netstandard2.0 $(NoWarn);CS1591 true aspnetcore;json;jsonpatch @@ -11,7 +11,6 @@ - diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/Microsoft.AspNetCore.JsonPatch.Test.csproj b/test/Microsoft.AspNetCore.JsonPatch.Test/Microsoft.AspNetCore.JsonPatch.Test.csproj index f5b8c8268a..d5bb8d950f 100644 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/Microsoft.AspNetCore.JsonPatch.Test.csproj +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/Microsoft.AspNetCore.JsonPatch.Test.csproj @@ -7,6 +7,10 @@ netcoreapp2.0 + + + + From cfb7ae413f811e54ade3db99fb468b8629676a81 Mon Sep 17 00:00:00 2001 From: Kiran Challa Date: Thu, 15 Jun 2017 05:07:52 -0700 Subject: [PATCH 130/221] Updated NETStandardImplicitPackageVersion to 2.0.0-* from BundledNETStandardPackageVersion --- NuGet.config | 1 + build/common.props | 2 +- build/dependencies.props | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/NuGet.config b/NuGet.config index 4e8a1f6de1..42f3f72326 100644 --- a/NuGet.config +++ b/NuGet.config @@ -3,6 +3,7 @@ + diff --git a/build/common.props b/build/common.props index a2698f3553..9f0faa97ad 100644 --- a/build/common.props +++ b/build/common.props @@ -17,7 +17,7 @@ - + diff --git a/build/dependencies.props b/build/dependencies.props index 5e815355d7..33e05e9df0 100644 --- a/build/dependencies.props +++ b/build/dependencies.props @@ -6,7 +6,7 @@ 10.0.1 4.7.1 2.0.0-* - $(BundledNETStandardPackageVersion) + 2.0.0-* 2.0.0-* 15.3.0-* 2.3.0-beta2-* From a8b6fa757a3ae49bfe02e0c75bb30006eb404d10 Mon Sep 17 00:00:00 2001 From: Pranav K Date: Fri, 16 Jun 2017 08:19:31 -0700 Subject: [PATCH 131/221] Remove dotnet-core feed from NuGet.config --- NuGet.config | 1 - 1 file changed, 1 deletion(-) diff --git a/NuGet.config b/NuGet.config index 42f3f72326..4e8a1f6de1 100644 --- a/NuGet.config +++ b/NuGet.config @@ -3,7 +3,6 @@ - From c816bce13a1f6eb0fc529a56dd1801d3221faafb Mon Sep 17 00:00:00 2001 From: Jass Bagga Date: Wed, 21 Jun 2017 12:35:31 -0700 Subject: [PATCH 132/221] Refactor invalid operation exception handling (#87) Addresses part of #80 --- .../Operations/OperationBase.cs | 31 +++++++++----- .../Operations/OperationOfT.cs | 3 ++ .../Operations/OperationType.cs | 3 +- .../OperationBaseTests.cs | 41 +++++++++++++++++++ 4 files changed, 67 insertions(+), 11 deletions(-) create mode 100644 test/Microsoft.AspNetCore.JsonPatch.Test/OperationBaseTests.cs diff --git a/src/Microsoft.AspNetCore.JsonPatch/Operations/OperationBase.cs b/src/Microsoft.AspNetCore.JsonPatch/Operations/OperationBase.cs index eb35fa7e9d..e629e2308d 100644 --- a/src/Microsoft.AspNetCore.JsonPatch/Operations/OperationBase.cs +++ b/src/Microsoft.AspNetCore.JsonPatch/Operations/OperationBase.cs @@ -2,26 +2,21 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; -using Microsoft.AspNetCore.JsonPatch.Exceptions; using Newtonsoft.Json; namespace Microsoft.AspNetCore.JsonPatch.Operations { public class OperationBase { + private string _op; + private OperationType _operationType; + [JsonIgnore] public OperationType OperationType { get { - OperationType result; - if (!Enum.TryParse(op, ignoreCase: true, result: out result)) - { - throw new JsonPatchException( - Resources.FormatInvalidJsonPatchOperation(op), - innerException: null); - } - return result; + return _operationType; } } @@ -29,7 +24,23 @@ namespace Microsoft.AspNetCore.JsonPatch.Operations public string path { get; set; } [JsonProperty("op")] - public string op { get; set; } + public string op + { + get + { + return _op; + } + set + { + OperationType result; + if (!Enum.TryParse(value, ignoreCase: true, result: out result)) + { + result = OperationType.Invalid; + } + _operationType = result; + _op = value; + } + } [JsonProperty("from")] public string from { get; set; } diff --git a/src/Microsoft.AspNetCore.JsonPatch/Operations/OperationOfT.cs b/src/Microsoft.AspNetCore.JsonPatch/Operations/OperationOfT.cs index 5af4f5d3f9..7189cf8210 100644 --- a/src/Microsoft.AspNetCore.JsonPatch/Operations/OperationOfT.cs +++ b/src/Microsoft.AspNetCore.JsonPatch/Operations/OperationOfT.cs @@ -75,6 +75,9 @@ namespace Microsoft.AspNetCore.JsonPatch.Operations break; case OperationType.Test: throw new JsonPatchException(new JsonPatchError(objectToApplyTo, this, Resources.TestOperationNotSupported)); + case OperationType.Invalid: + throw new JsonPatchException( + Resources.FormatInvalidJsonPatchOperation(op), innerException: null); default: break; } diff --git a/src/Microsoft.AspNetCore.JsonPatch/Operations/OperationType.cs b/src/Microsoft.AspNetCore.JsonPatch/Operations/OperationType.cs index 846b07019f..725646df3a 100644 --- a/src/Microsoft.AspNetCore.JsonPatch/Operations/OperationType.cs +++ b/src/Microsoft.AspNetCore.JsonPatch/Operations/OperationType.cs @@ -10,6 +10,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Operations Replace, Move, Copy, - Test + Test, + Invalid } } \ No newline at end of file diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/OperationBaseTests.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/OperationBaseTests.cs new file mode 100644 index 0000000000..955344404f --- /dev/null +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/OperationBaseTests.cs @@ -0,0 +1,41 @@ +// 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 Xunit; + +namespace Microsoft.AspNetCore.JsonPatch.Operations +{ + public class OperationBaseTests + { + [Theory] + [InlineData("ADd", OperationType.Add)] + [InlineData("Copy", OperationType.Copy)] + [InlineData("mOVE", OperationType.Move)] + [InlineData("REMOVE", OperationType.Remove)] + [InlineData("replace", OperationType.Replace)] + [InlineData("TeSt", OperationType.Test)] + public void SetValidOperationType(string op, OperationType operationType) + { + // Arrange + var operationBase = new OperationBase(); + operationBase.op = op; + + // Act & Assert + Assert.Equal(operationType, operationBase.OperationType); + } + + [Theory] + [InlineData("invalid", OperationType.Invalid)] + [InlineData("coppy", OperationType.Invalid)] + [InlineData("notvalid", OperationType.Invalid)] + public void InvalidOperationType_SetsOperationTypeInvalid(string op, OperationType operationType) + { + // Arrange + var operationBase = new OperationBase(); + operationBase.op = op; + + // Act & Assert + Assert.Equal(operationType, operationBase.OperationType); + } + } +} From 877e458da066c42ab84f067de49e9fbddd849238 Mon Sep 17 00:00:00 2001 From: Nate McMaster Date: Mon, 26 Jun 2017 09:38:31 -0700 Subject: [PATCH 133/221] Adding libunwind8 to .travis.yml [skip appveyor] --- .travis.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.travis.yml b/.travis.yml index 2a46104677..b10be14215 100644 --- a/.travis.yml +++ b/.travis.yml @@ -10,6 +10,10 @@ os: - linux - osx osx_image: xcode8.2 +addons: + apt: + packages: + - libunwind8 branches: only: - master From d7bdf1d4e4f2415c9ea3f50c06679b35522d4bf4 Mon Sep 17 00:00:00 2001 From: Pranav K Date: Thu, 29 Jun 2017 08:18:18 -0700 Subject: [PATCH 134/221] Update dependencies.props * Update Moq to 4.7.49. * Add NETStandardImplicitPackageVersion --- build/dependencies.props | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/build/dependencies.props b/build/dependencies.props index 33e05e9df0..22b77634a0 100644 --- a/build/dependencies.props +++ b/build/dependencies.props @@ -1,10 +1,11 @@ - + 2.0.0-* 4.4.0-* 2.1.0-* 10.0.1 - 4.7.1 + 4.7.49 + 2.0.0-* 2.0.0-* 2.0.0-* 2.0.0-* From fbfdbf4fe905898d18d119b2729bb5f25d8788b8 Mon Sep 17 00:00:00 2001 From: Pranav K Date: Mon, 3 Jul 2017 14:06:32 -0700 Subject: [PATCH 135/221] Update LICENSE.txt text --- LICENSE.txt | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/LICENSE.txt b/LICENSE.txt index 0bdc1962b6..7b2956ecee 100644 --- a/LICENSE.txt +++ b/LICENSE.txt @@ -1,10 +1,12 @@ -Copyright (c) .NET Foundation. All rights reserved. +Copyright (c) .NET Foundation and Contributors + +All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use -these files except in compliance with the License. You may obtain a copy of the +this file except in compliance with the License. You may obtain a copy of the License at -http://www.apache.org/licenses/LICENSE-2.0 + http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR From 4d87a52f6e6b7d360e1fa4fd950a8bc127e59cff Mon Sep 17 00:00:00 2001 From: Nate McMaster Date: Thu, 6 Jul 2017 10:38:05 -0700 Subject: [PATCH 136/221] React to aspnet/BuildTools#293 [ci skip] --- build/dependencies.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/dependencies.props b/build/dependencies.props index 22b77634a0..624ea78685 100644 --- a/build/dependencies.props +++ b/build/dependencies.props @@ -2,7 +2,7 @@ 2.0.0-* 4.4.0-* - 2.1.0-* + 2.0.1-* 10.0.1 4.7.49 2.0.0-* From 2a2326dec94d569e27c839de7a79e3d2a1412714 Mon Sep 17 00:00:00 2001 From: Ryan Brandenburg Date: Thu, 6 Jul 2017 12:16:57 -0700 Subject: [PATCH 137/221] Set "TreatWarningsAsErrors" before NuGet restore * Ensures our build stays clean of NuGet warnings --- build/common.props | 1 + 1 file changed, 1 insertion(+) diff --git a/build/common.props b/build/common.props index 9f0faa97ad..c00767473e 100644 --- a/build/common.props +++ b/build/common.props @@ -10,6 +10,7 @@ true true $(VersionSuffix)-$(BuildNumber) + true From bd90271c85460f93fb3a067cd1c55315fc71618b Mon Sep 17 00:00:00 2001 From: Pranav K Date: Thu, 6 Jul 2017 15:08:27 -0700 Subject: [PATCH 138/221] Update version suffix for 2.0.0 RTM release --- version.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.props b/version.props index 90a2f5b5cc..b94223e008 100644 --- a/version.props +++ b/version.props @@ -2,6 +2,6 @@ 2.0.0 - preview3 + rtm \ No newline at end of file From e4f3b9d624d8cf3fff8edd281defdb610a33b7f2 Mon Sep 17 00:00:00 2001 From: Ryan Brandenburg Date: Thu, 6 Jul 2017 15:28:29 -0700 Subject: [PATCH 139/221] Remove NETSTandard.Library.NETFramework --- .../Microsoft.AspNetCore.JsonPatch.Test.csproj | 4 ---- 1 file changed, 4 deletions(-) diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/Microsoft.AspNetCore.JsonPatch.Test.csproj b/test/Microsoft.AspNetCore.JsonPatch.Test/Microsoft.AspNetCore.JsonPatch.Test.csproj index d5bb8d950f..f5b8c8268a 100644 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/Microsoft.AspNetCore.JsonPatch.Test.csproj +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/Microsoft.AspNetCore.JsonPatch.Test.csproj @@ -7,10 +7,6 @@ netcoreapp2.0 - - - - From 28801a17e7786daabd31cd27665cb988495a772d Mon Sep 17 00:00:00 2001 From: Pranav K Date: Mon, 10 Jul 2017 11:43:45 -0700 Subject: [PATCH 140/221] Branching for 2.0.0 rtm --- NuGet.config | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NuGet.config b/NuGet.config index 4e8a1f6de1..37f0d27ea0 100644 --- a/NuGet.config +++ b/NuGet.config @@ -2,7 +2,7 @@ - + From 1481037d6ec436fd6d290bef5deeb115099d96e1 Mon Sep 17 00:00:00 2001 From: Pranav K Date: Mon, 10 Jul 2017 11:57:58 -0700 Subject: [PATCH 141/221] Updating KoreBuild branch --- build.ps1 | 2 +- build.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/build.ps1 b/build.ps1 index 5bf0e2c113..1785334385 100644 --- a/build.ps1 +++ b/build.ps1 @@ -33,7 +33,7 @@ cd $PSScriptRoot $repoFolder = $PSScriptRoot $env:REPO_FOLDER = $repoFolder -$koreBuildZip="https://github.com/aspnet/KoreBuild/archive/dev.zip" +$koreBuildZip="https://github.com/aspnet/KoreBuild/archive/rel/2.0.0.zip" if ($env:KOREBUILD_ZIP) { $koreBuildZip=$env:KOREBUILD_ZIP diff --git a/build.sh b/build.sh index b0bcadb579..5e27ed8efb 100755 --- a/build.sh +++ b/build.sh @@ -2,7 +2,7 @@ repoFolder="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" cd $repoFolder -koreBuildZip="https://github.com/aspnet/KoreBuild/archive/dev.zip" +koreBuildZip="https://github.com/aspnet/KoreBuild/archive/rel/2.0.0.zip" if [ ! -z $KOREBUILD_ZIP ]; then koreBuildZip=$KOREBUILD_ZIP fi From 8f13caf33f263f76f72d2ab0f356e9c30bc09905 Mon Sep 17 00:00:00 2001 From: Ryan Brandenburg Date: Fri, 7 Jul 2017 14:56:16 -0700 Subject: [PATCH 142/221] Skip first time experience on Appveyor --- appveyor.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/appveyor.yml b/appveyor.yml index 1041615c68..31efd8196f 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,4 +1,4 @@ -init: +init: - git config --global core.autocrlf true branches: only: @@ -9,6 +9,10 @@ branches: build_script: - ps: .\build.ps1 clone_depth: 1 +environment: + global: + DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true + DOTNET_CLI_TELEMETRY_OPTOUT: 1 test: off deploy: off os: Visual Studio 2017 From 465f09b3364a551771b6a3d5a22c344ec650dd0e Mon Sep 17 00:00:00 2001 From: Mike Harder Date: Wed, 19 Jul 2017 09:38:17 -0700 Subject: [PATCH 143/221] Remove duplicate NETStandardImplicitPackageVersion (#95) --- build/dependencies.props | 1 - 1 file changed, 1 deletion(-) diff --git a/build/dependencies.props b/build/dependencies.props index 624ea78685..f04855911e 100644 --- a/build/dependencies.props +++ b/build/dependencies.props @@ -7,7 +7,6 @@ 4.7.49 2.0.0-* 2.0.0-* - 2.0.0-* 2.0.0-* 15.3.0-* 2.3.0-beta2-* From 7f2a1def984a685f1ed39a70cf47c6cc868f0914 Mon Sep 17 00:00:00 2001 From: Ryan Brandenburg Date: Fri, 21 Jul 2017 13:00:17 -0700 Subject: [PATCH 144/221] 2.0.0-rtm to 2.1.0-preview1 --- version.props | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/version.props b/version.props index b94223e008..cb77b43933 100644 --- a/version.props +++ b/version.props @@ -1,7 +1,7 @@ - 2.0.0 - rtm + 2.1.0 + preview1 \ No newline at end of file From db9eee83b78e20d32232e60c382cea006265aa9c Mon Sep 17 00:00:00 2001 From: Ryan Brandenburg Date: Mon, 24 Jul 2017 17:56:54 -0700 Subject: [PATCH 145/221] Set AspNetCoreVersion --- build/dependencies.props | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build/dependencies.props b/build/dependencies.props index f04855911e..0071bd6d24 100644 --- a/build/dependencies.props +++ b/build/dependencies.props @@ -1,6 +1,6 @@ - + - 2.0.0-* + 2.1.0-* 4.4.0-* 2.0.1-* 10.0.1 From eaefe914eace7fa16e8deb497f07d313fbc0b366 Mon Sep 17 00:00:00 2001 From: Pranav K Date: Tue, 25 Jul 2017 15:13:44 -0700 Subject: [PATCH 146/221] Updating to InternalAspNetCoreSdkVersion 2.1.1-* --- build/dependencies.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/dependencies.props b/build/dependencies.props index 0071bd6d24..f2fb071ace 100644 --- a/build/dependencies.props +++ b/build/dependencies.props @@ -2,7 +2,7 @@ 2.1.0-* 4.4.0-* - 2.0.1-* + 2.1.1-* 10.0.1 4.7.49 2.0.0-* From b52b1d700ecd22b3437411e6e29d2cba9cca611f Mon Sep 17 00:00:00 2001 From: Nate McMaster Date: Tue, 25 Jul 2017 16:32:53 -0700 Subject: [PATCH 147/221] Update bootstrappers to use the compiled version of KoreBuild [ci skip] --- .gitignore | 1 + build.cmd | 2 +- build.ps1 | 218 ++++++++++++++++++++++++++++++++----------- build.sh | 224 +++++++++++++++++++++++++++++++++++++-------- build/common.props | 2 +- version.props | 7 -- version.xml | 8 ++ 7 files changed, 362 insertions(+), 100 deletions(-) delete mode 100644 version.props create mode 100644 version.xml diff --git a/.gitignore b/.gitignore index 2e8ec28064..24d990294f 100644 --- a/.gitignore +++ b/.gitignore @@ -37,3 +37,4 @@ node_modules *launchSettings.json *.orig global.json +korebuild-lock.txt diff --git a/build.cmd b/build.cmd index 7d4894cb4a..b6c8d24864 100644 --- a/build.cmd +++ b/build.cmd @@ -1,2 +1,2 @@ @ECHO OFF -PowerShell -NoProfile -NoLogo -ExecutionPolicy unrestricted -Command "[System.Threading.Thread]::CurrentThread.CurrentCulture = ''; [System.Threading.Thread]::CurrentThread.CurrentUICulture = '';& '%~dp0build.ps1' %*; exit $LASTEXITCODE" \ No newline at end of file +PowerShell -NoProfile -NoLogo -ExecutionPolicy unrestricted -Command "[System.Threading.Thread]::CurrentThread.CurrentCulture = ''; [System.Threading.Thread]::CurrentThread.CurrentUICulture = '';& '%~dp0build.ps1' %*; exit $LASTEXITCODE" diff --git a/build.ps1 b/build.ps1 index 5bf0e2c113..d5eb4d5cf2 100644 --- a/build.ps1 +++ b/build.ps1 @@ -1,67 +1,177 @@ -$ErrorActionPreference = "Stop" +#!/usr/bin/env powershell +#requires -version 4 -function DownloadWithRetry([string] $url, [string] $downloadLocation, [int] $retries) -{ - while($true) - { - try - { - Invoke-WebRequest $url -OutFile $downloadLocation - break - } - catch - { - $exceptionMessage = $_.Exception.Message - Write-Host "Failed to download '$url': $exceptionMessage" - if ($retries -gt 0) { - $retries-- - Write-Host "Waiting 10 seconds before retrying. Retries left: $retries" - Start-Sleep -Seconds 10 +<# +.SYNOPSIS +Build this repository +.DESCRIPTION +Downloads korebuild if required. Then builds the repository. + +.PARAMETER Path +The folder to build. Defaults to the folder containing this script. + +.PARAMETER Channel +The channel of KoreBuild to download. Overrides the value from the config file. + +.PARAMETER DotNetHome +The directory where .NET Core tools will be stored. + +.PARAMETER ToolsSource +The base url where build tools can be downloaded. Overrides the value from the config file. + +.PARAMETER Update +Updates KoreBuild to the latest version even if a lock file is present. + +.PARAMETER ConfigFile +The path to the configuration file that stores values. Defaults to version.xml. + +.PARAMETER MSBuildArgs +Arguments to be passed to MSBuild + +.NOTES +This function will create a file $PSScriptRoot/korebuild-lock.txt. This lock file can be committed to source, but does not have to be. +When the lockfile is not present, KoreBuild will create one using latest available version from $Channel. + +The $ConfigFile is expected to be an XML file. It is optional, and the configuration values in it are optional as well. + +.EXAMPLE +Example config file: +```xml + + + + dev + https://aspnetcore.blob.core.windows.net/buildtools + + +``` +#> +[CmdletBinding(PositionalBinding = $false)] +param( + [string]$Path = $PSScriptRoot, + [Alias('c')] + [string]$Channel, + [Alias('d')] + [string]$DotNetHome, + [Alias('s')] + [string]$ToolsSource, + [Alias('u')] + [switch]$Update, + [string]$ConfigFile = (Join-Path $PSScriptRoot 'version.xml'), + [Parameter(ValueFromRemainingArguments = $true)] + [string[]]$MSBuildArgs +) + +Set-StrictMode -Version 2 +$ErrorActionPreference = 'Stop' + +# +# Functions +# + +function Get-KoreBuild { + + $lockFile = Join-Path $Path 'korebuild-lock.txt' + + if (!(Test-Path $lockFile) -or $Update) { + Get-RemoteFile "$ToolsSource/korebuild/channels/$Channel/latest.txt" $lockFile + } + + $version = Get-Content $lockFile | Where-Object { $_ -like 'version:*' } | Select-Object -first 1 + if (!$version) { + Write-Error "Failed to parse version from $lockFile. Expected a line that begins with 'version:'" + } + $version = $version.TrimStart('version:').Trim() + $korebuildPath = Join-Paths $DotNetHome ('buildtools', 'korebuild', $version) + + if (!(Test-Path $korebuildPath)) { + Write-Host -ForegroundColor Magenta "Downloading KoreBuild $version" + New-Item -ItemType Directory -Path $korebuildPath | Out-Null + $remotePath = "$ToolsSource/korebuild/artifacts/$version/korebuild.$version.zip" + + try { + $tmpfile = Join-Path ([IO.Path]::GetTempPath()) "KoreBuild-$([guid]::NewGuid()).zip" + Get-RemoteFile $remotePath $tmpfile + if (Get-Command -Name 'Expand-Archive' -ErrorAction Ignore) { + # Use built-in commands where possible as they are cross-plat compatible + Expand-Archive -Path $tmpfile -DestinationPath $korebuildPath } - else - { - $exception = $_.Exception - throw $exception + else { + # Fallback to old approach for old installations of PowerShell + Add-Type -AssemblyName System.IO.Compression.FileSystem + [System.IO.Compression.ZipFile]::ExtractToDirectory($tmpfile, $korebuildPath) } } + catch { + Remove-Item -Recurse -Force $korebuildPath -ErrorAction Ignore + throw + } + finally { + Remove-Item $tmpfile -ErrorAction Ignore + } } + + return $korebuildPath } -cd $PSScriptRoot - -$repoFolder = $PSScriptRoot -$env:REPO_FOLDER = $repoFolder - -$koreBuildZip="https://github.com/aspnet/KoreBuild/archive/dev.zip" -if ($env:KOREBUILD_ZIP) -{ - $koreBuildZip=$env:KOREBUILD_ZIP +function Join-Paths([string]$path, [string[]]$childPaths) { + $childPaths | ForEach-Object { $path = Join-Path $path $_ } + return $path } -$buildFolder = ".build" -$buildFile="$buildFolder\KoreBuild.ps1" - -if (!(Test-Path $buildFolder)) { - Write-Host "Downloading KoreBuild from $koreBuildZip" - - $tempFolder=$env:TEMP + "\KoreBuild-" + [guid]::NewGuid() - New-Item -Path "$tempFolder" -Type directory | Out-Null - - $localZipFile="$tempFolder\korebuild.zip" - - DownloadWithRetry -url $koreBuildZip -downloadLocation $localZipFile -retries 6 - - Add-Type -AssemblyName System.IO.Compression.FileSystem - [System.IO.Compression.ZipFile]::ExtractToDirectory($localZipFile, $tempFolder) - - New-Item -Path "$buildFolder" -Type directory | Out-Null - copy-item "$tempFolder\**\build\*" $buildFolder -Recurse - - # Cleanup - if (Test-Path $tempFolder) { - Remove-Item -Recurse -Force $tempFolder +function Get-RemoteFile([string]$RemotePath, [string]$LocalPath) { + if ($RemotePath -notlike 'http*') { + Copy-Item $RemotePath $LocalPath + return } + + $retries = 10 + while ($retries -gt 0) { + $retries -= 1 + try { + Invoke-WebRequest -UseBasicParsing -Uri $RemotePath -OutFile $LocalPath + return + } + catch { + Write-Verbose "Request failed. $retries retries remaining" + } + } + + Write-Error "Download failed: '$RemotePath'." } -&"$buildFile" @args +# +# Main +# + +# Load configuration or set defaults + +if (Test-Path $ConfigFile) { + [xml] $config = Get-Content $ConfigFile + if (!($Channel)) { [string] $Channel = Select-Xml -Xml $config -XPath '/Project/PropertyGroup/KoreBuildChannel' } + if (!($ToolsSource)) { [string] $ToolsSource = Select-Xml -Xml $config -XPath '/Project/PropertyGroup/KoreBuildToolsSource' } +} + +if (!$DotNetHome) { + $DotNetHome = if ($env:DOTNET_HOME) { $env:DOTNET_HOME } ` + elseif ($env:USERPROFILE) { Join-Path $env:USERPROFILE '.dotnet'} ` + elseif ($env:HOME) {Join-Path $env:HOME '.dotnet'}` + else { Join-Path $PSScriptRoot '.dotnet'} +} + +if (!$Channel) { $Channel = 'dev' } +if (!$ToolsSource) { $ToolsSource = 'https://aspnetcore.blob.core.windows.net/buildtools' } + +# Execute + +$korebuildPath = Get-KoreBuild +Import-Module -Force -Scope Local (Join-Path $korebuildPath 'KoreBuild.psd1') + +try { + Install-Tools $ToolsSource $DotNetHome + Invoke-RepositoryBuild $Path @MSBuildArgs +} +finally { + Remove-Module 'KoreBuild' -ErrorAction Ignore +} diff --git a/build.sh b/build.sh index b0bcadb579..ab590e62f1 100755 --- a/build.sh +++ b/build.sh @@ -1,46 +1,196 @@ #!/usr/bin/env bash -repoFolder="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" -cd $repoFolder -koreBuildZip="https://github.com/aspnet/KoreBuild/archive/dev.zip" -if [ ! -z $KOREBUILD_ZIP ]; then - koreBuildZip=$KOREBUILD_ZIP -fi +set -euo pipefail -buildFolder=".build" -buildFile="$buildFolder/KoreBuild.sh" +# +# variables +# -if test ! -d $buildFolder; then - echo "Downloading KoreBuild from $koreBuildZip" +RESET="\033[0m" +RED="\033[0;31m" +MAGENTA="\033[0;95m" +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +[ -z "${DOTNET_HOME:-}"] && DOTNET_HOME="$HOME/.dotnet" +config_file="$DIR/version.xml" +verbose=false +update=false +repo_path="$DIR" +channel='' +tools_source='' - tempFolder="/tmp/KoreBuild-$(uuidgen)" - mkdir $tempFolder +# +# Functions +# +__usage() { + echo "Usage: $(basename ${BASH_SOURCE[0]}) [options] [[--] ...]" + echo "" + echo "Arguments:" + echo " ... Arguments passed to MSBuild. Variable number of arguments allowed." + echo "" + echo "Options:" + echo " --verbose Show verbose output." + echo " -c|--channel The channel of KoreBuild to download. Overrides the value from the config file.." + echo " --config-file TThe path to the configuration file that stores values. Defaults to version.xml." + echo " -d|--dotnet-home The directory where .NET Core tools will be stored. Defaults to '\$DOTNET_HOME' or '\$HOME/.dotnet." + echo " --path The directory to build. Defaults to the directory containing the script." + echo " -s|--tools-source The base url where build tools can be downloaded. Overrides the value from the config file." + echo " -u|--update Update to the latest KoreBuild even if the lock file is present." + echo "" + echo "Description:" + echo " This function will create a file \$DIR/korebuild-lock.txt. This lock file can be committed to source, but does not have to be." + echo " When the lockfile is not present, KoreBuild will create one using latest available version from \$channel." - localZipFile="$tempFolder/korebuild.zip" - - retries=6 - until (wget -O $localZipFile $koreBuildZip 2>/dev/null || curl -o $localZipFile --location $koreBuildZip 2>/dev/null) - do - echo "Failed to download '$koreBuildZip'" - if [ "$retries" -le 0 ]; then - exit 1 - fi - retries=$((retries - 1)) - echo "Waiting 10 seconds before retrying. Retries left: $retries" - sleep 10s - done - - unzip -q -d $tempFolder $localZipFile - - mkdir $buildFolder - cp -r $tempFolder/**/build/** $buildFolder - - chmod +x $buildFile - - # Cleanup - if test -d $tempFolder; then - rm -rf $tempFolder + if [[ "${1:-}" != '--no-exit' ]]; then + exit 2 fi +} + +get_korebuild() { + local lock_file="$repo_path/korebuild-lock.txt" + if [ ! -f $lock_file ] || [ "$update" = true ]; then + __get_remote_file "$tools_source/korebuild/channels/$channel/latest.txt" $lock_file + fi + local version="$(grep 'version:*' -m 1 $lock_file)" + if [[ "$version" == '' ]]; then + __error "Failed to parse version from $lock_file. Expected a line that begins with 'version:'" + return 1 + fi + version="$(echo ${version#version:} | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')" + local korebuild_path="$DOTNET_HOME/buildtools/korebuild/$version" + + { + if [ ! -d "$korebuild_path" ]; then + mkdir -p "$korebuild_path" + local remote_path="$tools_source/korebuild/artifacts/$version/korebuild.$version.zip" + tmpfile="$(mktemp)" + echo -e "${MAGENTA}Downloading KoreBuild ${version}${RESET}" + if __get_remote_file $remote_path $tmpfile; then + unzip -q -d "$korebuild_path" $tmpfile + fi + rm $tmpfile || true + fi + + source "$korebuild_path/KoreBuild.sh" + } || { + if [ -d "$korebuild_path" ]; then + echo "Cleaning up after failed installation" + rm -rf "$korebuild_path" || true + fi + return 1 + } +} + +__error() { + echo -e "${RED}$@${RESET}" 1>&2 +} + +__machine_has() { + hash "$1" > /dev/null 2>&1 + return $? +} + +__get_remote_file() { + local remote_path=$1 + local local_path=$2 + + if [[ "$remote_path" != 'http'* ]]; then + cp $remote_path $local_path + return 0 + fi + + failed=false + if __machine_has wget; then + wget --tries 10 --quiet -O $local_path $remote_path || failed=true + fi + + if [ "$failed" = true ] && __machine_has curl; then + failed=false + curl --retry 10 -sSL -f --create-dirs -o $local_path $remote_path || failed=true + fi + + if [ "$failed" = true ]; then + __error "Download failed: $remote_path" 1>&2 + return 1 + fi +} + +__read_dom () { local IFS=\> ; read -d \< ENTITY CONTENT ;} + +# +# main +# + +while [[ $# > 0 ]]; do + case $1 in + -\?|-h|--help) + __usage --no-exit + exit 0 + ;; + -c|--channel|-Channel) + shift + channel=${1:-} + [ -z "$channel" ] && __usage + ;; + --config-file|-ConfigFile) + shift + config_file="${1:-}" + [ -z "$config_file" ] && __usage + ;; + -d|--dotnet-home|-DotNetHome) + shift + DOTNET_HOME=${1:-} + [ -z "$DOTNET_HOME" ] && __usage + ;; + --path|-Path) + shift + repo_path="${1:-}" + [ -z "$repo_path" ] && __usage + ;; + -s|--tools-source|-ToolsSource) + shift + tools_source="${1:-}" + [ -z "$tools_source" ] && __usage + ;; + -u|--update|-Update) + update=true + ;; + --verbose|-Verbose) + verbose=true + ;; + --) + shift + break + ;; + *) + break + ;; + esac + shift +done + +if ! __machine_has unzip; then + __error 'Missing required command: unzip' + exit 1 fi -$buildFile -r $repoFolder "$@" +if ! __machine_has curl && ! __machine_has wget; then + __error 'Missing required command. Either wget or curl is required.' + exit 1 +fi + +if [ -f $config_file ]; then + comment=false + while __read_dom; do + if [ "$comment" = true ]; then [[ $CONTENT == *'-->'* ]] && comment=false ; continue; fi + if [[ $ENTITY == '!--'* ]]; then comment=true; continue; fi + if [ -z "$channel" ] && [[ $ENTITY == "KoreBuildChannel" ]]; then channel=$CONTENT; fi + if [ -z "$tools_source" ] && [[ $ENTITY == "KoreBuildToolsSource" ]]; then tools_source=$CONTENT; fi + done < $config_file +fi + +[ -z "$channel" ] && channel='dev' +[ -z "$tools_source" ] && tools_source='https://aspnetcore.blob.core.windows.net/buildtools' + +get_korebuild +install_tools "$tools_source" "$DOTNET_HOME" +invoke_repository_build "$repo_path" $@ diff --git a/build/common.props b/build/common.props index c00767473e..b749c350f1 100644 --- a/build/common.props +++ b/build/common.props @@ -1,6 +1,6 @@ - + Microsoft ASP.NET Core diff --git a/version.props b/version.props deleted file mode 100644 index cb77b43933..0000000000 --- a/version.props +++ /dev/null @@ -1,7 +0,0 @@ - - - - 2.1.0 - preview1 - - \ No newline at end of file diff --git a/version.xml b/version.xml new file mode 100644 index 0000000000..3c05022b7d --- /dev/null +++ b/version.xml @@ -0,0 +1,8 @@ + + + + dev + 2.1.0 + preview1 + + From 6a20337254dc0fcc5227e2243fdc3f52c88e58da Mon Sep 17 00:00:00 2001 From: Nate McMaster Date: Wed, 26 Jul 2017 10:27:59 -0700 Subject: [PATCH 148/221] Fix syntax warning when running build.sh on older versions of bash [ci skip] --- build.sh | 41 +++++++++++++++++++++-------------------- 1 file changed, 21 insertions(+), 20 deletions(-) diff --git a/build.sh b/build.sh index ab590e62f1..5568c6182a 100755 --- a/build.sh +++ b/build.sh @@ -10,7 +10,7 @@ RESET="\033[0m" RED="\033[0;31m" MAGENTA="\033[0;95m" DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" -[ -z "${DOTNET_HOME:-}"] && DOTNET_HOME="$HOME/.dotnet" +[ -z "${DOTNET_HOME:-}" ] && DOTNET_HOME="$HOME/.dotnet" config_file="$DIR/version.xml" verbose=false update=false @@ -22,7 +22,7 @@ tools_source='' # Functions # __usage() { - echo "Usage: $(basename ${BASH_SOURCE[0]}) [options] [[--] ...]" + echo "Usage: $(basename "${BASH_SOURCE[0]}") [options] [[--] ...]" echo "" echo "Arguments:" echo " ... Arguments passed to MSBuild. Variable number of arguments allowed." @@ -46,16 +46,17 @@ __usage() { } get_korebuild() { + local version local lock_file="$repo_path/korebuild-lock.txt" - if [ ! -f $lock_file ] || [ "$update" = true ]; then - __get_remote_file "$tools_source/korebuild/channels/$channel/latest.txt" $lock_file + if [ ! -f "$lock_file" ] || [ "$update" = true ]; then + __get_remote_file "$tools_source/korebuild/channels/$channel/latest.txt" "$lock_file" fi - local version="$(grep 'version:*' -m 1 $lock_file)" + version="$(grep 'version:*' -m 1 "$lock_file")" if [[ "$version" == '' ]]; then __error "Failed to parse version from $lock_file. Expected a line that begins with 'version:'" return 1 fi - version="$(echo ${version#version:} | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')" + version="$(echo "${version#version:}" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')" local korebuild_path="$DOTNET_HOME/buildtools/korebuild/$version" { @@ -64,10 +65,10 @@ get_korebuild() { local remote_path="$tools_source/korebuild/artifacts/$version/korebuild.$version.zip" tmpfile="$(mktemp)" echo -e "${MAGENTA}Downloading KoreBuild ${version}${RESET}" - if __get_remote_file $remote_path $tmpfile; then - unzip -q -d "$korebuild_path" $tmpfile + if __get_remote_file "$remote_path" "$tmpfile"; then + unzip -q -d "$korebuild_path" "$tmpfile" fi - rm $tmpfile || true + rm "$tmpfile" || true fi source "$korebuild_path/KoreBuild.sh" @@ -81,7 +82,7 @@ get_korebuild() { } __error() { - echo -e "${RED}$@${RESET}" 1>&2 + echo -e "${RED}$*${RESET}" 1>&2 } __machine_has() { @@ -94,18 +95,18 @@ __get_remote_file() { local local_path=$2 if [[ "$remote_path" != 'http'* ]]; then - cp $remote_path $local_path + cp "$remote_path" "$local_path" return 0 fi failed=false if __machine_has wget; then - wget --tries 10 --quiet -O $local_path $remote_path || failed=true + wget --tries 10 --quiet -O "$local_path" "$remote_path" || failed=true fi if [ "$failed" = true ] && __machine_has curl; then failed=false - curl --retry 10 -sSL -f --create-dirs -o $local_path $remote_path || failed=true + curl --retry 10 -sSL -f --create-dirs -o "$local_path" "$remote_path" || failed=true fi if [ "$failed" = true ]; then @@ -114,13 +115,13 @@ __get_remote_file() { fi } -__read_dom () { local IFS=\> ; read -d \< ENTITY CONTENT ;} +__read_dom () { local IFS=\> ; read -r -d \< ENTITY CONTENT ;} # # main # -while [[ $# > 0 ]]; do +while [[ $# -gt 0 ]]; do case $1 in -\?|-h|--help) __usage --no-exit @@ -128,7 +129,7 @@ while [[ $# > 0 ]]; do ;; -c|--channel|-Channel) shift - channel=${1:-} + channel="${1:-}" [ -z "$channel" ] && __usage ;; --config-file|-ConfigFile) @@ -138,7 +139,7 @@ while [[ $# > 0 ]]; do ;; -d|--dotnet-home|-DotNetHome) shift - DOTNET_HOME=${1:-} + DOTNET_HOME="${1:-}" [ -z "$DOTNET_HOME" ] && __usage ;; --path|-Path) @@ -178,14 +179,14 @@ if ! __machine_has curl && ! __machine_has wget; then exit 1 fi -if [ -f $config_file ]; then +if [ -f "$config_file" ]; then comment=false while __read_dom; do if [ "$comment" = true ]; then [[ $CONTENT == *'-->'* ]] && comment=false ; continue; fi if [[ $ENTITY == '!--'* ]]; then comment=true; continue; fi if [ -z "$channel" ] && [[ $ENTITY == "KoreBuildChannel" ]]; then channel=$CONTENT; fi if [ -z "$tools_source" ] && [[ $ENTITY == "KoreBuildToolsSource" ]]; then tools_source=$CONTENT; fi - done < $config_file + done < "$config_file" fi [ -z "$channel" ] && channel='dev' @@ -193,4 +194,4 @@ fi get_korebuild install_tools "$tools_source" "$DOTNET_HOME" -invoke_repository_build "$repo_path" $@ +invoke_repository_build "$repo_path" "$@" From 90d9b8d5131bffe2e16a19aeb964066b59b0aca1 Mon Sep 17 00:00:00 2001 From: John Luo Date: Wed, 2 Aug 2017 12:44:46 -0700 Subject: [PATCH 149/221] Update __get_remote_file logic --- build.sh | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/build.sh b/build.sh index 5568c6182a..8eace4c20d 100755 --- a/build.sh +++ b/build.sh @@ -99,17 +99,16 @@ __get_remote_file() { return 0 fi - failed=false + local succeeded=false if __machine_has wget; then - wget --tries 10 --quiet -O "$local_path" "$remote_path" || failed=true + wget --tries 10 --quiet -O "$local_path" "$remote_path" && succeeded=true fi - if [ "$failed" = true ] && __machine_has curl; then - failed=false - curl --retry 10 -sSL -f --create-dirs -o "$local_path" "$remote_path" || failed=true + if [ "$succeeded" = false ] && __machine_has curl; then + curl --retry 10 -sSL -f --create-dirs -o "$local_path" "$remote_path" && succeeded=true fi - if [ "$failed" = true ]; then + if [ "$succeeded" = false ]; then __error "Download failed: $remote_path" 1>&2 return 1 fi From 13754ed0c7dc7db53fa1ee6d79b714d0882a8ac5 Mon Sep 17 00:00:00 2001 From: John Luo Date: Wed, 2 Aug 2017 14:32:27 -0700 Subject: [PATCH 150/221] Ensure fallback to curl after failed wget --- build.sh | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/build.sh b/build.sh index 8eace4c20d..11cdbe5504 100755 --- a/build.sh +++ b/build.sh @@ -99,16 +99,19 @@ __get_remote_file() { return 0 fi - local succeeded=false + local failed=false if __machine_has wget; then - wget --tries 10 --quiet -O "$local_path" "$remote_path" && succeeded=true + wget --tries 10 --quiet -O "$local_path" "$remote_path" || failed=true + else + failed=true fi - if [ "$succeeded" = false ] && __machine_has curl; then - curl --retry 10 -sSL -f --create-dirs -o "$local_path" "$remote_path" && succeeded=true + if [ "$failed" = true ] && __machine_has curl; then + failed=false + curl --retry 10 -sSL -f --create-dirs -o "$local_path" "$remote_path" || failed=true fi - if [ "$succeeded" = false ]; then + if [ "$failed" = true ]; then __error "Download failed: $remote_path" 1>&2 return 1 fi From a2c0410e39a05bf646d1a042ec2284af37847b1b Mon Sep 17 00:00:00 2001 From: Nate McMaster Date: Thu, 17 Aug 2017 16:15:42 -0700 Subject: [PATCH 151/221] Use PackageLineup to manage package versions --- appveyor.yml => .appveyor.yml | 0 Directory.Build.props | 14 +++++++++++ Directory.Build.targets | 14 +++++++++++ JsonPatch.sln | 25 ++++++++++++++++++- build/common.props | 24 ------------------ build/dependencies.props | 14 ----------- build/repo.props | 6 +++++ src/Directory.Build.props | 7 ++++++ .../Microsoft.AspNetCore.JsonPatch.csproj | 7 +++--- test/Directory.Build.props | 11 ++++++++ .../DictionaryAdapterTest.cs | 14 +++++------ ...Microsoft.AspNetCore.JsonPatch.Test.csproj | 9 ++----- .../ObjectAdapterTests.cs | 8 +++--- 13 files changed, 92 insertions(+), 61 deletions(-) rename appveyor.yml => .appveyor.yml (100%) create mode 100644 Directory.Build.props create mode 100644 Directory.Build.targets delete mode 100644 build/common.props delete mode 100644 build/dependencies.props create mode 100644 build/repo.props create mode 100644 src/Directory.Build.props create mode 100644 test/Directory.Build.props diff --git a/appveyor.yml b/.appveyor.yml similarity index 100% rename from appveyor.yml rename to .appveyor.yml diff --git a/Directory.Build.props b/Directory.Build.props new file mode 100644 index 0000000000..57d9ef7e6a --- /dev/null +++ b/Directory.Build.props @@ -0,0 +1,14 @@ + + + + + Microsoft ASP.NET Core + https://github.com/aspnet/JsonPatch + git + $(MSBuildThisFileDirectory)build\Key.snk + true + true + $(VersionSuffix)-$(BuildNumber) + true + + diff --git a/Directory.Build.targets b/Directory.Build.targets new file mode 100644 index 0000000000..9989b1046b --- /dev/null +++ b/Directory.Build.targets @@ -0,0 +1,14 @@ + + + + <_BootstrapperFile Condition=" $([MSBuild]::IsOSUnixLike()) ">build.sh + <_BootstrapperFile Condition="! $([MSBuild]::IsOSUnixLike()) ">build.cmd + <_BootstrapperError> + Package references have not been pinned. Run './$(_BootstrapperFile) /t:Pin'. + Also, you can run './$(_BootstrapperFile) /t:Restore' which will pin *and* restore packages. '$(_BootstrapperFile)' can be found in '$(MSBuildThisFileDirectory)'. + + + + + + diff --git a/JsonPatch.sln b/JsonPatch.sln index b75721a487..87b48a8ea1 100644 --- a/JsonPatch.sln +++ b/JsonPatch.sln @@ -1,10 +1,16 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 15 -VisualStudioVersion = 15.0.26222.1 +VisualStudioVersion = 15.0.26815.3 MinimumVisualStudioVersion = 10.0.40219.1 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{430B59ED-F960-4D3A-8FFE-3370008E168D}" + ProjectSection(SolutionItems) = preProject + src\Directory.Build.props = src\Directory.Build.props + EndProjectSection EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{36CD6341-AB44-44EB-B3AA-BF98C89FECDD}" + ProjectSection(SolutionItems) = preProject + test\Directory.Build.props = test\Directory.Build.props + EndProjectSection EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.JsonPatch", "src\Microsoft.AspNetCore.JsonPatch\Microsoft.AspNetCore.JsonPatch.csproj", "{4D55F4D8-633B-462F-A5B1-FEB84BD2D534}" EndProject @@ -12,7 +18,21 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.JsonPa EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{C430C499-382D-47BD-B351-CF8F89C08CD2}" ProjectSection(SolutionItems) = preProject + .appveyor.yml = .appveyor.yml + .gitattributes = .gitattributes + .gitignore = .gitignore + .travis.yml = .travis.yml + build.cmd = build.cmd + build.ps1 = build.ps1 + build.sh = build.sh + CONTRIBUTING.md = CONTRIBUTING.md + Directory.Build.props = Directory.Build.props + Directory.Build.targets = Directory.Build.targets + LICENSE.txt = LICENSE.txt NuGet.config = NuGet.config + NuGetPackageVerifier.json = NuGetPackageVerifier.json + README.md = README.md + version.xml = version.xml EndProjectSection EndProject Global @@ -37,4 +57,7 @@ Global {4D55F4D8-633B-462F-A5B1-FEB84BD2D534} = {430B59ED-F960-4D3A-8FFE-3370008E168D} {81C20848-E063-4E12-AC40-0B55A532C16C} = {36CD6341-AB44-44EB-B3AA-BF98C89FECDD} EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {9FFA3EB9-8740-4434-BC8C-F3D595161B59} + EndGlobalSection EndGlobal diff --git a/build/common.props b/build/common.props deleted file mode 100644 index b749c350f1..0000000000 --- a/build/common.props +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - Microsoft ASP.NET Core - https://github.com/aspnet/JsonPatch - git - $(MSBuildThisFileDirectory)Key.snk - true - true - $(VersionSuffix)-$(BuildNumber) - true - - - - - - - - - - - diff --git a/build/dependencies.props b/build/dependencies.props deleted file mode 100644 index f2fb071ace..0000000000 --- a/build/dependencies.props +++ /dev/null @@ -1,14 +0,0 @@ - - - 2.1.0-* - 4.4.0-* - 2.1.1-* - 10.0.1 - 4.7.49 - 2.0.0-* - 2.0.0-* - 2.0.0-* - 15.3.0-* - 2.3.0-beta2-* - - diff --git a/build/repo.props b/build/repo.props new file mode 100644 index 0000000000..c5d91e8a2c --- /dev/null +++ b/build/repo.props @@ -0,0 +1,6 @@ + + + + + + diff --git a/src/Directory.Build.props b/src/Directory.Build.props new file mode 100644 index 0000000000..5236edee58 --- /dev/null +++ b/src/Directory.Build.props @@ -0,0 +1,7 @@ + + + + + + + diff --git a/src/Microsoft.AspNetCore.JsonPatch/Microsoft.AspNetCore.JsonPatch.csproj b/src/Microsoft.AspNetCore.JsonPatch/Microsoft.AspNetCore.JsonPatch.csproj index e9732e8621..a364de22ef 100644 --- a/src/Microsoft.AspNetCore.JsonPatch/Microsoft.AspNetCore.JsonPatch.csproj +++ b/src/Microsoft.AspNetCore.JsonPatch/Microsoft.AspNetCore.JsonPatch.csproj @@ -1,5 +1,4 @@ - ASP.NET Core support for JSON PATCH. @@ -10,9 +9,9 @@ - - - + + + diff --git a/test/Directory.Build.props b/test/Directory.Build.props new file mode 100644 index 0000000000..31ed7dd07c --- /dev/null +++ b/test/Directory.Build.props @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/DictionaryAdapterTest.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/DictionaryAdapterTest.cs index 6a88bd6cc7..bc50b872a2 100644 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/DictionaryAdapterTest.cs +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/DictionaryAdapterTest.cs @@ -28,7 +28,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal // Assert Assert.True(addStatus); Assert.True(string.IsNullOrEmpty(message), "Expected no error message"); - Assert.Equal(1, dictionary.Count); + Assert.Single(dictionary); Assert.Equal("James", dictionary[nameKey]); } @@ -48,7 +48,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal // Assert Assert.True(addStatus); Assert.True(string.IsNullOrEmpty(message), "Expected no error message"); - Assert.Equal(1, dictionary.Count); + Assert.Single(dictionary); Assert.Equal("James", dictionary[nameKey]); // Act @@ -77,7 +77,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal // Assert Assert.True(addStatus); Assert.True(string.IsNullOrEmpty(message), "Expected no error message"); - Assert.Equal(1, dictionary.Count); + Assert.Single(dictionary); Assert.Equal("James", dictionary[nameKey]); // Act @@ -107,7 +107,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal // Assert Assert.True(replaceStatus); Assert.True(string.IsNullOrEmpty(message), "Expected no error message"); - Assert.Equal(1, dictionary.Count); + Assert.Single(dictionary); Assert.Equal("James", dictionary[nameKey]); } @@ -129,7 +129,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal Assert.Equal( string.Format("The target location specified by path segment '{0}' was not found.", nameKey), message); - Assert.Equal(0, dictionary.Count); + Assert.Empty(dictionary); } [Fact] @@ -150,7 +150,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal Assert.Equal( string.Format("The target location specified by path segment '{0}' was not found.", nameKey), message); - Assert.Equal(0, dictionary.Count); + Assert.Empty(dictionary); } [Fact] @@ -170,7 +170,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal //Assert Assert.True(removeStatus); Assert.True(string.IsNullOrEmpty(message), "Expected no error message"); - Assert.Equal(0, dictionary.Count); + Assert.Empty(dictionary); } } } diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/Microsoft.AspNetCore.JsonPatch.Test.csproj b/test/Microsoft.AspNetCore.JsonPatch.Test/Microsoft.AspNetCore.JsonPatch.Test.csproj index f5b8c8268a..2e4f68b538 100644 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/Microsoft.AspNetCore.JsonPatch.Test.csproj +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/Microsoft.AspNetCore.JsonPatch.Test.csproj @@ -1,7 +1,5 @@  - - netcoreapp2.0;net461 netcoreapp2.0 @@ -12,11 +10,8 @@ - - - - - + + diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/ObjectAdapterTests.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/ObjectAdapterTests.cs index 56b25d22be..34a8c97b67 100644 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/ObjectAdapterTests.cs +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/ObjectAdapterTests.cs @@ -720,8 +720,8 @@ namespace Microsoft.AspNetCore.JsonPatch.Adapters var serialized = JsonConvert.SerializeObject(patchDoc); // Assert - Assert.False(serialized.Contains("operations")); - Assert.False(serialized.Contains("Operations")); + Assert.DoesNotContain("operations", serialized); + Assert.DoesNotContain("Operations", serialized); } [Fact] @@ -2061,7 +2061,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Adapters patchDoc.ApplyTo(model); // Assert - Assert.Equal(1, model.Count); + Assert.Single(model); Assert.Equal(expected, model["WA"]); } @@ -2080,7 +2080,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Adapters deserialized.ApplyTo(model); // Assert - Assert.Equal(1, model.Count); + Assert.Single(model); Assert.Equal(expected, model["WA"]); } From 01bf47170fdb848f4ced623b1fad7450c8848d64 Mon Sep 17 00:00:00 2001 From: Nate McMaster Date: Fri, 18 Aug 2017 10:43:19 -0700 Subject: [PATCH 152/221] Revert lineups change until we work out issues with PackageLineup This reverts commit a2c0410e39a05bf646d1a042ec2284af37847b1b. --- Directory.Build.props | 14 ----------- Directory.Build.targets | 14 ----------- JsonPatch.sln | 25 +------------------ .appveyor.yml => appveyor.yml | 0 build/common.props | 24 ++++++++++++++++++ build/dependencies.props | 14 +++++++++++ build/repo.props | 6 ----- src/Directory.Build.props | 7 ------ .../Microsoft.AspNetCore.JsonPatch.csproj | 7 +++--- test/Directory.Build.props | 11 -------- .../DictionaryAdapterTest.cs | 14 +++++------ ...Microsoft.AspNetCore.JsonPatch.Test.csproj | 9 +++++-- .../ObjectAdapterTests.cs | 8 +++--- 13 files changed, 61 insertions(+), 92 deletions(-) delete mode 100644 Directory.Build.props delete mode 100644 Directory.Build.targets rename .appveyor.yml => appveyor.yml (100%) create mode 100644 build/common.props create mode 100644 build/dependencies.props delete mode 100644 build/repo.props delete mode 100644 src/Directory.Build.props delete mode 100644 test/Directory.Build.props diff --git a/Directory.Build.props b/Directory.Build.props deleted file mode 100644 index 57d9ef7e6a..0000000000 --- a/Directory.Build.props +++ /dev/null @@ -1,14 +0,0 @@ - - - - - Microsoft ASP.NET Core - https://github.com/aspnet/JsonPatch - git - $(MSBuildThisFileDirectory)build\Key.snk - true - true - $(VersionSuffix)-$(BuildNumber) - true - - diff --git a/Directory.Build.targets b/Directory.Build.targets deleted file mode 100644 index 9989b1046b..0000000000 --- a/Directory.Build.targets +++ /dev/null @@ -1,14 +0,0 @@ - - - - <_BootstrapperFile Condition=" $([MSBuild]::IsOSUnixLike()) ">build.sh - <_BootstrapperFile Condition="! $([MSBuild]::IsOSUnixLike()) ">build.cmd - <_BootstrapperError> - Package references have not been pinned. Run './$(_BootstrapperFile) /t:Pin'. - Also, you can run './$(_BootstrapperFile) /t:Restore' which will pin *and* restore packages. '$(_BootstrapperFile)' can be found in '$(MSBuildThisFileDirectory)'. - - - - - - diff --git a/JsonPatch.sln b/JsonPatch.sln index 87b48a8ea1..b75721a487 100644 --- a/JsonPatch.sln +++ b/JsonPatch.sln @@ -1,16 +1,10 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 15 -VisualStudioVersion = 15.0.26815.3 +VisualStudioVersion = 15.0.26222.1 MinimumVisualStudioVersion = 10.0.40219.1 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{430B59ED-F960-4D3A-8FFE-3370008E168D}" - ProjectSection(SolutionItems) = preProject - src\Directory.Build.props = src\Directory.Build.props - EndProjectSection EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{36CD6341-AB44-44EB-B3AA-BF98C89FECDD}" - ProjectSection(SolutionItems) = preProject - test\Directory.Build.props = test\Directory.Build.props - EndProjectSection EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.JsonPatch", "src\Microsoft.AspNetCore.JsonPatch\Microsoft.AspNetCore.JsonPatch.csproj", "{4D55F4D8-633B-462F-A5B1-FEB84BD2D534}" EndProject @@ -18,21 +12,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.JsonPa EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{C430C499-382D-47BD-B351-CF8F89C08CD2}" ProjectSection(SolutionItems) = preProject - .appveyor.yml = .appveyor.yml - .gitattributes = .gitattributes - .gitignore = .gitignore - .travis.yml = .travis.yml - build.cmd = build.cmd - build.ps1 = build.ps1 - build.sh = build.sh - CONTRIBUTING.md = CONTRIBUTING.md - Directory.Build.props = Directory.Build.props - Directory.Build.targets = Directory.Build.targets - LICENSE.txt = LICENSE.txt NuGet.config = NuGet.config - NuGetPackageVerifier.json = NuGetPackageVerifier.json - README.md = README.md - version.xml = version.xml EndProjectSection EndProject Global @@ -57,7 +37,4 @@ Global {4D55F4D8-633B-462F-A5B1-FEB84BD2D534} = {430B59ED-F960-4D3A-8FFE-3370008E168D} {81C20848-E063-4E12-AC40-0B55A532C16C} = {36CD6341-AB44-44EB-B3AA-BF98C89FECDD} EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {9FFA3EB9-8740-4434-BC8C-F3D595161B59} - EndGlobalSection EndGlobal diff --git a/.appveyor.yml b/appveyor.yml similarity index 100% rename from .appveyor.yml rename to appveyor.yml diff --git a/build/common.props b/build/common.props new file mode 100644 index 0000000000..b749c350f1 --- /dev/null +++ b/build/common.props @@ -0,0 +1,24 @@ + + + + + + Microsoft ASP.NET Core + https://github.com/aspnet/JsonPatch + git + $(MSBuildThisFileDirectory)Key.snk + true + true + $(VersionSuffix)-$(BuildNumber) + true + + + + + + + + + + + diff --git a/build/dependencies.props b/build/dependencies.props new file mode 100644 index 0000000000..f2fb071ace --- /dev/null +++ b/build/dependencies.props @@ -0,0 +1,14 @@ + + + 2.1.0-* + 4.4.0-* + 2.1.1-* + 10.0.1 + 4.7.49 + 2.0.0-* + 2.0.0-* + 2.0.0-* + 15.3.0-* + 2.3.0-beta2-* + + diff --git a/build/repo.props b/build/repo.props deleted file mode 100644 index c5d91e8a2c..0000000000 --- a/build/repo.props +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/src/Directory.Build.props b/src/Directory.Build.props deleted file mode 100644 index 5236edee58..0000000000 --- a/src/Directory.Build.props +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/src/Microsoft.AspNetCore.JsonPatch/Microsoft.AspNetCore.JsonPatch.csproj b/src/Microsoft.AspNetCore.JsonPatch/Microsoft.AspNetCore.JsonPatch.csproj index a364de22ef..e9732e8621 100644 --- a/src/Microsoft.AspNetCore.JsonPatch/Microsoft.AspNetCore.JsonPatch.csproj +++ b/src/Microsoft.AspNetCore.JsonPatch/Microsoft.AspNetCore.JsonPatch.csproj @@ -1,4 +1,5 @@ + ASP.NET Core support for JSON PATCH. @@ -9,9 +10,9 @@ - - - + + + diff --git a/test/Directory.Build.props b/test/Directory.Build.props deleted file mode 100644 index 31ed7dd07c..0000000000 --- a/test/Directory.Build.props +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/DictionaryAdapterTest.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/DictionaryAdapterTest.cs index bc50b872a2..6a88bd6cc7 100644 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/DictionaryAdapterTest.cs +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/DictionaryAdapterTest.cs @@ -28,7 +28,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal // Assert Assert.True(addStatus); Assert.True(string.IsNullOrEmpty(message), "Expected no error message"); - Assert.Single(dictionary); + Assert.Equal(1, dictionary.Count); Assert.Equal("James", dictionary[nameKey]); } @@ -48,7 +48,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal // Assert Assert.True(addStatus); Assert.True(string.IsNullOrEmpty(message), "Expected no error message"); - Assert.Single(dictionary); + Assert.Equal(1, dictionary.Count); Assert.Equal("James", dictionary[nameKey]); // Act @@ -77,7 +77,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal // Assert Assert.True(addStatus); Assert.True(string.IsNullOrEmpty(message), "Expected no error message"); - Assert.Single(dictionary); + Assert.Equal(1, dictionary.Count); Assert.Equal("James", dictionary[nameKey]); // Act @@ -107,7 +107,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal // Assert Assert.True(replaceStatus); Assert.True(string.IsNullOrEmpty(message), "Expected no error message"); - Assert.Single(dictionary); + Assert.Equal(1, dictionary.Count); Assert.Equal("James", dictionary[nameKey]); } @@ -129,7 +129,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal Assert.Equal( string.Format("The target location specified by path segment '{0}' was not found.", nameKey), message); - Assert.Empty(dictionary); + Assert.Equal(0, dictionary.Count); } [Fact] @@ -150,7 +150,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal Assert.Equal( string.Format("The target location specified by path segment '{0}' was not found.", nameKey), message); - Assert.Empty(dictionary); + Assert.Equal(0, dictionary.Count); } [Fact] @@ -170,7 +170,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal //Assert Assert.True(removeStatus); Assert.True(string.IsNullOrEmpty(message), "Expected no error message"); - Assert.Empty(dictionary); + Assert.Equal(0, dictionary.Count); } } } diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/Microsoft.AspNetCore.JsonPatch.Test.csproj b/test/Microsoft.AspNetCore.JsonPatch.Test/Microsoft.AspNetCore.JsonPatch.Test.csproj index 2e4f68b538..f5b8c8268a 100644 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/Microsoft.AspNetCore.JsonPatch.Test.csproj +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/Microsoft.AspNetCore.JsonPatch.Test.csproj @@ -1,5 +1,7 @@  + + netcoreapp2.0;net461 netcoreapp2.0 @@ -10,8 +12,11 @@ - - + + + + + diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/ObjectAdapterTests.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/ObjectAdapterTests.cs index 34a8c97b67..56b25d22be 100644 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/ObjectAdapterTests.cs +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/ObjectAdapterTests.cs @@ -720,8 +720,8 @@ namespace Microsoft.AspNetCore.JsonPatch.Adapters var serialized = JsonConvert.SerializeObject(patchDoc); // Assert - Assert.DoesNotContain("operations", serialized); - Assert.DoesNotContain("Operations", serialized); + Assert.False(serialized.Contains("operations")); + Assert.False(serialized.Contains("Operations")); } [Fact] @@ -2061,7 +2061,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Adapters patchDoc.ApplyTo(model); // Assert - Assert.Single(model); + Assert.Equal(1, model.Count); Assert.Equal(expected, model["WA"]); } @@ -2080,7 +2080,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Adapters deserialized.ApplyTo(model); // Assert - Assert.Single(model); + Assert.Equal(1, model.Count); Assert.Equal(expected, model["WA"]); } From a993c2a5ff3d4f21a50c3a424cb42201944c4b19 Mon Sep 17 00:00:00 2001 From: Nate McMaster Date: Fri, 18 Aug 2017 16:31:06 -0700 Subject: [PATCH 153/221] Use PackageLineup to manage versions (revert revert) We resolved the issues with PackageLineup and partial graph builds. This reverts commit 01bf47170fdb848f4ced623b1fad7450c8848d64. --- appveyor.yml => .appveyor.yml | 0 Directory.Build.props | 14 +++++++++++ Directory.Build.targets | 14 +++++++++++ JsonPatch.sln | 25 ++++++++++++++++++- build/common.props | 24 ------------------ build/dependencies.props | 14 ----------- build/repo.props | 6 +++++ src/Directory.Build.props | 7 ++++++ .../Microsoft.AspNetCore.JsonPatch.csproj | 7 +++--- test/Directory.Build.props | 11 ++++++++ .../DictionaryAdapterTest.cs | 14 +++++------ ...Microsoft.AspNetCore.JsonPatch.Test.csproj | 9 ++----- .../ObjectAdapterTests.cs | 8 +++--- 13 files changed, 92 insertions(+), 61 deletions(-) rename appveyor.yml => .appveyor.yml (100%) create mode 100644 Directory.Build.props create mode 100644 Directory.Build.targets delete mode 100644 build/common.props delete mode 100644 build/dependencies.props create mode 100644 build/repo.props create mode 100644 src/Directory.Build.props create mode 100644 test/Directory.Build.props diff --git a/appveyor.yml b/.appveyor.yml similarity index 100% rename from appveyor.yml rename to .appveyor.yml diff --git a/Directory.Build.props b/Directory.Build.props new file mode 100644 index 0000000000..57d9ef7e6a --- /dev/null +++ b/Directory.Build.props @@ -0,0 +1,14 @@ + + + + + Microsoft ASP.NET Core + https://github.com/aspnet/JsonPatch + git + $(MSBuildThisFileDirectory)build\Key.snk + true + true + $(VersionSuffix)-$(BuildNumber) + true + + diff --git a/Directory.Build.targets b/Directory.Build.targets new file mode 100644 index 0000000000..9989b1046b --- /dev/null +++ b/Directory.Build.targets @@ -0,0 +1,14 @@ + + + + <_BootstrapperFile Condition=" $([MSBuild]::IsOSUnixLike()) ">build.sh + <_BootstrapperFile Condition="! $([MSBuild]::IsOSUnixLike()) ">build.cmd + <_BootstrapperError> + Package references have not been pinned. Run './$(_BootstrapperFile) /t:Pin'. + Also, you can run './$(_BootstrapperFile) /t:Restore' which will pin *and* restore packages. '$(_BootstrapperFile)' can be found in '$(MSBuildThisFileDirectory)'. + + + + + + diff --git a/JsonPatch.sln b/JsonPatch.sln index b75721a487..87b48a8ea1 100644 --- a/JsonPatch.sln +++ b/JsonPatch.sln @@ -1,10 +1,16 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 15 -VisualStudioVersion = 15.0.26222.1 +VisualStudioVersion = 15.0.26815.3 MinimumVisualStudioVersion = 10.0.40219.1 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{430B59ED-F960-4D3A-8FFE-3370008E168D}" + ProjectSection(SolutionItems) = preProject + src\Directory.Build.props = src\Directory.Build.props + EndProjectSection EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{36CD6341-AB44-44EB-B3AA-BF98C89FECDD}" + ProjectSection(SolutionItems) = preProject + test\Directory.Build.props = test\Directory.Build.props + EndProjectSection EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.JsonPatch", "src\Microsoft.AspNetCore.JsonPatch\Microsoft.AspNetCore.JsonPatch.csproj", "{4D55F4D8-633B-462F-A5B1-FEB84BD2D534}" EndProject @@ -12,7 +18,21 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.JsonPa EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{C430C499-382D-47BD-B351-CF8F89C08CD2}" ProjectSection(SolutionItems) = preProject + .appveyor.yml = .appveyor.yml + .gitattributes = .gitattributes + .gitignore = .gitignore + .travis.yml = .travis.yml + build.cmd = build.cmd + build.ps1 = build.ps1 + build.sh = build.sh + CONTRIBUTING.md = CONTRIBUTING.md + Directory.Build.props = Directory.Build.props + Directory.Build.targets = Directory.Build.targets + LICENSE.txt = LICENSE.txt NuGet.config = NuGet.config + NuGetPackageVerifier.json = NuGetPackageVerifier.json + README.md = README.md + version.xml = version.xml EndProjectSection EndProject Global @@ -37,4 +57,7 @@ Global {4D55F4D8-633B-462F-A5B1-FEB84BD2D534} = {430B59ED-F960-4D3A-8FFE-3370008E168D} {81C20848-E063-4E12-AC40-0B55A532C16C} = {36CD6341-AB44-44EB-B3AA-BF98C89FECDD} EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {9FFA3EB9-8740-4434-BC8C-F3D595161B59} + EndGlobalSection EndGlobal diff --git a/build/common.props b/build/common.props deleted file mode 100644 index b749c350f1..0000000000 --- a/build/common.props +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - Microsoft ASP.NET Core - https://github.com/aspnet/JsonPatch - git - $(MSBuildThisFileDirectory)Key.snk - true - true - $(VersionSuffix)-$(BuildNumber) - true - - - - - - - - - - - diff --git a/build/dependencies.props b/build/dependencies.props deleted file mode 100644 index f2fb071ace..0000000000 --- a/build/dependencies.props +++ /dev/null @@ -1,14 +0,0 @@ - - - 2.1.0-* - 4.4.0-* - 2.1.1-* - 10.0.1 - 4.7.49 - 2.0.0-* - 2.0.0-* - 2.0.0-* - 15.3.0-* - 2.3.0-beta2-* - - diff --git a/build/repo.props b/build/repo.props new file mode 100644 index 0000000000..c5d91e8a2c --- /dev/null +++ b/build/repo.props @@ -0,0 +1,6 @@ + + + + + + diff --git a/src/Directory.Build.props b/src/Directory.Build.props new file mode 100644 index 0000000000..5236edee58 --- /dev/null +++ b/src/Directory.Build.props @@ -0,0 +1,7 @@ + + + + + + + diff --git a/src/Microsoft.AspNetCore.JsonPatch/Microsoft.AspNetCore.JsonPatch.csproj b/src/Microsoft.AspNetCore.JsonPatch/Microsoft.AspNetCore.JsonPatch.csproj index e9732e8621..a364de22ef 100644 --- a/src/Microsoft.AspNetCore.JsonPatch/Microsoft.AspNetCore.JsonPatch.csproj +++ b/src/Microsoft.AspNetCore.JsonPatch/Microsoft.AspNetCore.JsonPatch.csproj @@ -1,5 +1,4 @@ - ASP.NET Core support for JSON PATCH. @@ -10,9 +9,9 @@ - - - + + + diff --git a/test/Directory.Build.props b/test/Directory.Build.props new file mode 100644 index 0000000000..31ed7dd07c --- /dev/null +++ b/test/Directory.Build.props @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/DictionaryAdapterTest.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/DictionaryAdapterTest.cs index 6a88bd6cc7..bc50b872a2 100644 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/DictionaryAdapterTest.cs +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/DictionaryAdapterTest.cs @@ -28,7 +28,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal // Assert Assert.True(addStatus); Assert.True(string.IsNullOrEmpty(message), "Expected no error message"); - Assert.Equal(1, dictionary.Count); + Assert.Single(dictionary); Assert.Equal("James", dictionary[nameKey]); } @@ -48,7 +48,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal // Assert Assert.True(addStatus); Assert.True(string.IsNullOrEmpty(message), "Expected no error message"); - Assert.Equal(1, dictionary.Count); + Assert.Single(dictionary); Assert.Equal("James", dictionary[nameKey]); // Act @@ -77,7 +77,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal // Assert Assert.True(addStatus); Assert.True(string.IsNullOrEmpty(message), "Expected no error message"); - Assert.Equal(1, dictionary.Count); + Assert.Single(dictionary); Assert.Equal("James", dictionary[nameKey]); // Act @@ -107,7 +107,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal // Assert Assert.True(replaceStatus); Assert.True(string.IsNullOrEmpty(message), "Expected no error message"); - Assert.Equal(1, dictionary.Count); + Assert.Single(dictionary); Assert.Equal("James", dictionary[nameKey]); } @@ -129,7 +129,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal Assert.Equal( string.Format("The target location specified by path segment '{0}' was not found.", nameKey), message); - Assert.Equal(0, dictionary.Count); + Assert.Empty(dictionary); } [Fact] @@ -150,7 +150,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal Assert.Equal( string.Format("The target location specified by path segment '{0}' was not found.", nameKey), message); - Assert.Equal(0, dictionary.Count); + Assert.Empty(dictionary); } [Fact] @@ -170,7 +170,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal //Assert Assert.True(removeStatus); Assert.True(string.IsNullOrEmpty(message), "Expected no error message"); - Assert.Equal(0, dictionary.Count); + Assert.Empty(dictionary); } } } diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/Microsoft.AspNetCore.JsonPatch.Test.csproj b/test/Microsoft.AspNetCore.JsonPatch.Test/Microsoft.AspNetCore.JsonPatch.Test.csproj index f5b8c8268a..2e4f68b538 100644 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/Microsoft.AspNetCore.JsonPatch.Test.csproj +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/Microsoft.AspNetCore.JsonPatch.Test.csproj @@ -1,7 +1,5 @@  - - netcoreapp2.0;net461 netcoreapp2.0 @@ -12,11 +10,8 @@ - - - - - + + diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/ObjectAdapterTests.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/ObjectAdapterTests.cs index 56b25d22be..34a8c97b67 100644 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/ObjectAdapterTests.cs +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/ObjectAdapterTests.cs @@ -720,8 +720,8 @@ namespace Microsoft.AspNetCore.JsonPatch.Adapters var serialized = JsonConvert.SerializeObject(patchDoc); // Assert - Assert.False(serialized.Contains("operations")); - Assert.False(serialized.Contains("Operations")); + Assert.DoesNotContain("operations", serialized); + Assert.DoesNotContain("Operations", serialized); } [Fact] @@ -2061,7 +2061,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Adapters patchDoc.ApplyTo(model); // Assert - Assert.Equal(1, model.Count); + Assert.Single(model); Assert.Equal(expected, model["WA"]); } @@ -2080,7 +2080,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Adapters deserialized.ApplyTo(model); // Assert - Assert.Equal(1, model.Count); + Assert.Single(model); Assert.Equal(expected, model["WA"]); } From d4b64af0e60a319d8240837d3174fac9b04e271b Mon Sep 17 00:00:00 2001 From: Jass Bagga Date: Wed, 23 Aug 2017 10:30:11 -0700 Subject: [PATCH 154/221] Use DictionaryKeyResolver for ExpandoObjectAdapter (#100) Addresses #102 --- .../Adapters/ObjectAdapter.cs | 31 +--- .../Internal/ExpandoObjectAdapter.cs | 22 +-- .../ExpandoObjectDictionaryExtensions.cs | 26 --- .../Internal/ListAdapter.cs | 34 ++-- .../Internal/PocoAdapter.cs | 24 +-- .../Dynamic/AddOperationTests.cs | 51 +++--- .../Dynamic/AddTypedOperationTests.cs | 8 +- .../Dynamic/CopyOperationTests.cs | 24 +-- .../Dynamic/CopyTypedOperationTests.cs | 24 +-- .../Dynamic/CustomNamingStrategyTests.cs | 154 ++++++++++++++++++ .../Dynamic/MoveOperationTests.cs | 45 +++-- .../Dynamic/MoveTypedOperationTests.cs | 12 +- .../Dynamic/PatchDocumentTests.cs | 12 +- .../Dynamic/RemoveOperationTests.cs | 80 ++++----- .../Dynamic/RemoveTypedOperationTests.cs | 20 +-- .../ObjectVisitorTest.cs | 4 - 16 files changed, 330 insertions(+), 241 deletions(-) delete mode 100644 src/Microsoft.AspNetCore.JsonPatch/Internal/ExpandoObjectDictionaryExtensions.cs create mode 100644 test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/CustomNamingStrategyTests.cs diff --git a/src/Microsoft.AspNetCore.JsonPatch/Adapters/ObjectAdapter.cs b/src/Microsoft.AspNetCore.JsonPatch/Adapters/ObjectAdapter.cs index b1a487f088..a30343868a 100644 --- a/src/Microsoft.AspNetCore.JsonPatch/Adapters/ObjectAdapter.cs +++ b/src/Microsoft.AspNetCore.JsonPatch/Adapters/ObjectAdapter.cs @@ -2,8 +2,6 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; -using Microsoft.AspNetCore.JsonPatch.Exceptions; -using Microsoft.AspNetCore.JsonPatch.Helpers; using Microsoft.AspNetCore.JsonPatch.Internal; using Microsoft.AspNetCore.JsonPatch.Operations; using Newtonsoft.Json.Serialization; @@ -22,12 +20,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Adapters IContractResolver contractResolver, Action logErrorAction) { - if (contractResolver == null) - { - throw new ArgumentNullException(nameof(contractResolver)); - } - - ContractResolver = contractResolver; + ContractResolver = contractResolver ?? throw new ArgumentNullException(nameof(contractResolver)); LogErrorAction = logErrorAction; } @@ -144,10 +137,8 @@ namespace Microsoft.AspNetCore.JsonPatch.Adapters var parsedPath = new ParsedPath(path); var visitor = new ObjectVisitor(parsedPath, ContractResolver); - IAdapter adapter; var target = objectToApplyTo; - string errorMessage; - if (!visitor.TryVisit(ref target, out adapter, out errorMessage)) + if (!visitor.TryVisit(ref target, out var adapter, out var errorMessage)) { var error = CreatePathNotFoundError(objectToApplyTo, path, operation, errorMessage); ErrorReporter(error); @@ -197,9 +188,8 @@ namespace Microsoft.AspNetCore.JsonPatch.Adapters throw new ArgumentNullException(nameof(objectToApplyTo)); } - object propertyValue; // Get value at 'from' location and add that value to the 'path' location - if (TryGetValue(operation.from, objectToApplyTo, operation, out propertyValue)) + if (TryGetValue(operation.from, objectToApplyTo, operation, out var propertyValue)) { // remove that value Remove(operation.from, objectToApplyTo, operation); @@ -253,10 +243,8 @@ namespace Microsoft.AspNetCore.JsonPatch.Adapters var parsedPath = new ParsedPath(path); var visitor = new ObjectVisitor(parsedPath, ContractResolver); - IAdapter adapter; var target = objectToApplyTo; - string errorMessage; - if (!visitor.TryVisit(ref target, out adapter, out errorMessage)) + if (!visitor.TryVisit(ref target, out var adapter, out var errorMessage)) { var error = CreatePathNotFoundError(objectToApplyTo, path, operationToReport, errorMessage); ErrorReporter(error); @@ -306,10 +294,8 @@ namespace Microsoft.AspNetCore.JsonPatch.Adapters var parsedPath = new ParsedPath(operation.path); var visitor = new ObjectVisitor(parsedPath, ContractResolver); - IAdapter adapter; var target = objectToApplyTo; - string errorMessage; - if (!visitor.TryVisit(ref target, out adapter, out errorMessage)) + if (!visitor.TryVisit(ref target, out var adapter, out var errorMessage)) { var error = CreatePathNotFoundError(objectToApplyTo, operation.path, operation, errorMessage); ErrorReporter(error); @@ -358,9 +344,8 @@ namespace Microsoft.AspNetCore.JsonPatch.Adapters throw new ArgumentNullException(nameof(objectToApplyTo)); } - object propertyValue; // Get value at 'from' location and add that value to the 'path' location - if (TryGetValue(operation.from, objectToApplyTo, operation, out propertyValue)) + if (TryGetValue(operation.from, objectToApplyTo, operation, out var propertyValue)) { // Create deep copy var copyResult = ConversionResultProvider.CopyTo(propertyValue, propertyValue.GetType()); @@ -406,10 +391,8 @@ namespace Microsoft.AspNetCore.JsonPatch.Adapters var parsedPath = new ParsedPath(fromLocation); var visitor = new ObjectVisitor(parsedPath, ContractResolver); - IAdapter adapter; var target = objectToGetValueFrom; - string errorMessage; - if (!visitor.TryVisit(ref target, out adapter, out errorMessage)) + if (!visitor.TryVisit(ref target, out var adapter, out var errorMessage)) { var error = CreatePathNotFoundError(objectToGetValueFrom, fromLocation, operation, errorMessage); ErrorReporter(error); diff --git a/src/Microsoft.AspNetCore.JsonPatch/Internal/ExpandoObjectAdapter.cs b/src/Microsoft.AspNetCore.JsonPatch/Internal/ExpandoObjectAdapter.cs index 681b5309e6..c35d1b702c 100644 --- a/src/Microsoft.AspNetCore.JsonPatch/Internal/ExpandoObjectAdapter.cs +++ b/src/Microsoft.AspNetCore.JsonPatch/Internal/ExpandoObjectAdapter.cs @@ -16,10 +16,10 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal object value, out string errorMessage) { + var contract = (JsonDictionaryContract)contractResolver.ResolveContract(target.GetType()); + var key = contract.DictionaryKeyResolver(segment); var dictionary = (IDictionary)target; - var key = dictionary.GetKeyUsingCaseInsensitiveSearch(segment); - // As per JsonPatch spec, if a key already exists, adding should replace the existing value dictionary[key] = ConvertValue(dictionary, key, value); @@ -34,9 +34,10 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal out object value, out string errorMessage) { + var contract = (JsonDictionaryContract)contractResolver.ResolveContract(target.GetType()); + var key = contract.DictionaryKeyResolver(segment); var dictionary = (IDictionary)target; - var key = dictionary.GetKeyUsingCaseInsensitiveSearch(segment); value = dictionary[key]; errorMessage = null; @@ -49,10 +50,10 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal IContractResolver contractResolver, out string errorMessage) { + var contract = (JsonDictionaryContract)contractResolver.ResolveContract(target.GetType()); + var key = contract.DictionaryKeyResolver(segment); var dictionary = (IDictionary)target; - var key = dictionary.GetKeyUsingCaseInsensitiveSearch(segment); - // As per JsonPatch spec, the target location must exist for remove to be successful if (!dictionary.ContainsKey(key)) { @@ -73,10 +74,10 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal object value, out string errorMessage) { + var contract = (JsonDictionaryContract)contractResolver.ResolveContract(target.GetType()); + var key = contract.DictionaryKeyResolver(segment); var dictionary = (IDictionary)target; - var key = dictionary.GetKeyUsingCaseInsensitiveSearch(segment); - // As per JsonPatch spec, the target location must exist for remove to be successful if (!dictionary.ContainsKey(key)) { @@ -105,10 +106,10 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal return false; } + var contract = (JsonDictionaryContract)contractResolver.ResolveContract(target.GetType()); + var key = contract.DictionaryKeyResolver(segment); var dictionary = (IDictionary)expandoObject; - var key = dictionary.GetKeyUsingCaseInsensitiveSearch(segment); - if (dictionary.ContainsKey(key)) { nextTarget = dictionary[key]; @@ -125,8 +126,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal private object ConvertValue(IDictionary dictionary, string key, object newValue) { - object existingValue = null; - if (dictionary.TryGetValue(key, out existingValue)) + if (dictionary.TryGetValue(key, out var existingValue)) { if (existingValue != null) { diff --git a/src/Microsoft.AspNetCore.JsonPatch/Internal/ExpandoObjectDictionaryExtensions.cs b/src/Microsoft.AspNetCore.JsonPatch/Internal/ExpandoObjectDictionaryExtensions.cs deleted file mode 100644 index 8bb60dd2a7..0000000000 --- a/src/Microsoft.AspNetCore.JsonPatch/Internal/ExpandoObjectDictionaryExtensions.cs +++ /dev/null @@ -1,26 +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; -using System.Collections.Generic; - -namespace Microsoft.AspNetCore.JsonPatch.Internal -{ - // Helper methods to allow case-insensitive key search - public static class ExpandoObjectDictionaryExtensions - { - internal static string GetKeyUsingCaseInsensitiveSearch( - this IDictionary propertyDictionary, - string key) - { - foreach (var keyInDictionary in propertyDictionary.Keys) - { - if (string.Equals(key, keyInDictionary, StringComparison.OrdinalIgnoreCase)) - { - return keyInDictionary; - } - } - return key; - } - } -} \ No newline at end of file diff --git a/src/Microsoft.AspNetCore.JsonPatch/Internal/ListAdapter.cs b/src/Microsoft.AspNetCore.JsonPatch/Internal/ListAdapter.cs index 343712690a..a1c0498e47 100644 --- a/src/Microsoft.AspNetCore.JsonPatch/Internal/ListAdapter.cs +++ b/src/Microsoft.AspNetCore.JsonPatch/Internal/ListAdapter.cs @@ -20,20 +20,17 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal { var list = (IList)target; - Type typeArgument = null; - if (!TryGetListTypeArgument(list, out typeArgument, out errorMessage)) + if (!TryGetListTypeArgument(list, out var typeArgument, out errorMessage)) { return false; } - PositionInfo positionInfo; - if (!TryGetPositionInfo(list, segment, OperationType.Add, out positionInfo, out errorMessage)) + if (!TryGetPositionInfo(list, segment, OperationType.Add, out var positionInfo, out errorMessage)) { return false; } - object convertedValue = null; - if (!TryConvertValue(value, typeArgument, segment, out convertedValue, out errorMessage)) + if (!TryConvertValue(value, typeArgument, segment, out var convertedValue, out errorMessage)) { return false; } @@ -60,15 +57,13 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal { var list = (IList)target; - Type typeArgument = null; - if (!TryGetListTypeArgument(list, out typeArgument, out errorMessage)) + if (!TryGetListTypeArgument(list, out var typeArgument, out errorMessage)) { value = null; return false; } - PositionInfo positionInfo; - if (!TryGetPositionInfo(list, segment, OperationType.Get, out positionInfo, out errorMessage)) + if (!TryGetPositionInfo(list, segment, OperationType.Get, out var positionInfo, out errorMessage)) { value = null; return false; @@ -95,14 +90,12 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal { var list = (IList)target; - Type typeArgument = null; - if (!TryGetListTypeArgument(list, out typeArgument, out errorMessage)) + if (!TryGetListTypeArgument(list, out var typeArgument, out errorMessage)) { return false; } - PositionInfo positionInfo; - if (!TryGetPositionInfo(list, segment, OperationType.Remove, out positionInfo, out errorMessage)) + if (!TryGetPositionInfo(list, segment, OperationType.Remove, out var positionInfo, out errorMessage)) { return false; } @@ -129,20 +122,17 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal { var list = (IList)target; - Type typeArgument = null; - if (!TryGetListTypeArgument(list, out typeArgument, out errorMessage)) + if (!TryGetListTypeArgument(list, out var typeArgument, out errorMessage)) { return false; } - PositionInfo positionInfo; - if (!TryGetPositionInfo(list, segment, OperationType.Replace, out positionInfo, out errorMessage)) + if (!TryGetPositionInfo(list, segment, OperationType.Replace, out var positionInfo, out errorMessage)) { return false; } - object convertedValue = null; - if (!TryConvertValue(value, typeArgument, segment, out convertedValue, out errorMessage)) + if (!TryConvertValue(value, typeArgument, segment, out var convertedValue, out errorMessage)) { return false; } @@ -175,7 +165,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal return false; } - int index = -1; + var index = -1; if (!int.TryParse(segment, out index)) { value = null; @@ -257,7 +247,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal return true; } - int position = -1; + var position = -1; if (int.TryParse(segment, out position)) { if (position >= 0 && position < list.Count) diff --git a/src/Microsoft.AspNetCore.JsonPatch/Internal/PocoAdapter.cs b/src/Microsoft.AspNetCore.JsonPatch/Internal/PocoAdapter.cs index 0755e132e1..eab16a3035 100644 --- a/src/Microsoft.AspNetCore.JsonPatch/Internal/PocoAdapter.cs +++ b/src/Microsoft.AspNetCore.JsonPatch/Internal/PocoAdapter.cs @@ -17,8 +17,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal object value, out string errorMessage) { - JsonProperty jsonProperty = null; - if (!TryGetJsonProperty(target, contractResolver, segment, out jsonProperty)) + if (!TryGetJsonProperty(target, contractResolver, segment, out var jsonProperty)) { errorMessage = Resources.FormatTargetLocationAtPathSegmentNotFound(segment); return false; @@ -30,8 +29,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal return false; } - object convertedValue = null; - if (!TryConvertValue(value, jsonProperty.PropertyType, out convertedValue)) + if (!TryConvertValue(value, jsonProperty.PropertyType, out var convertedValue)) { errorMessage = Resources.FormatInvalidValueForProperty(value); return false; @@ -50,8 +48,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal out object value, out string errorMessage) { - JsonProperty jsonProperty = null; - if (!TryGetJsonProperty(target, contractResolver, segment, out jsonProperty)) + if (!TryGetJsonProperty(target, contractResolver, segment, out var jsonProperty)) { errorMessage = Resources.FormatTargetLocationAtPathSegmentNotFound(segment); value = null; @@ -76,8 +73,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal IContractResolver contractResolver, out string errorMessage) { - JsonProperty jsonProperty = null; - if (!TryGetJsonProperty(target, contractResolver, segment, out jsonProperty)) + if (!TryGetJsonProperty(target, contractResolver, segment, out var jsonProperty)) { errorMessage = Resources.FormatTargetLocationAtPathSegmentNotFound(segment); return false; @@ -112,8 +108,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal object value, out string errorMessage) { - JsonProperty jsonProperty = null; - if (!TryGetJsonProperty(target, contractResolver, segment, out jsonProperty)) + if (!TryGetJsonProperty(target, contractResolver, segment, out var jsonProperty)) { errorMessage = Resources.FormatTargetLocationAtPathSegmentNotFound(segment); return false; @@ -125,8 +120,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal return false; } - object convertedValue = null; - if (!TryConvertValue(value, jsonProperty.PropertyType, out convertedValue)) + if (!TryConvertValue(value, jsonProperty.PropertyType, out var convertedValue)) { errorMessage = Resources.FormatInvalidValueForProperty(value); return false; @@ -152,8 +146,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal return false; } - JsonProperty jsonProperty = null; - if (TryGetJsonProperty(target, contractResolver, segment, out jsonProperty)) + if (TryGetJsonProperty(target, contractResolver, segment, out var jsonProperty)) { value = jsonProperty.ValueProvider.GetValue(target); errorMessage = null; @@ -171,8 +164,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal string segment, out JsonProperty jsonProperty) { - var jsonObjectContract = contractResolver.ResolveContract(target.GetType()) as JsonObjectContract; - if (jsonObjectContract != null) + if (contractResolver.ResolveContract(target.GetType()) is JsonObjectContract jsonObjectContract) { var pocoProperty = jsonObjectContract .Properties diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/AddOperationTests.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/AddOperationTests.cs index cbd44a7ef9..e1cdb21df2 100644 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/AddOperationTests.cs +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/AddOperationTests.cs @@ -21,7 +21,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic }; // create patch - JsonPatchDocument patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Add("NewInt", 1); var serialized = JsonConvert.SerializeObject(patchDoc); @@ -43,7 +43,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic obj.Test = 1; // create patch - JsonPatchDocument patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Add("NewInt", 1); var serialized = JsonConvert.SerializeObject(patchDoc); @@ -65,7 +65,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic }; // create patch - JsonPatchDocument patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Add("Nested/NewInt", 1); var serialized = JsonConvert.SerializeObject(patchDoc); @@ -90,7 +90,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic }; // create patch - JsonPatchDocument patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Add("Nested/NewInt", 1); var serialized = JsonConvert.SerializeObject(patchDoc); @@ -115,7 +115,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic }; // create patch - JsonPatchDocument patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Add("Nested/StringProperty", "A"); var serialized = JsonConvert.SerializeObject(patchDoc); @@ -137,7 +137,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic }; // create patch - JsonPatchDocument patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Add("Nested/NewInt", 1); var serialized = JsonConvert.SerializeObject(patchDoc); @@ -158,7 +158,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic }; // create patch - JsonPatchDocument patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Add("DynamicProperty/NewInt", 1); var serialized = JsonConvert.SerializeObject(patchDoc); @@ -181,7 +181,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic }; // create patch - JsonPatchDocument patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Add("DynamicProperty/StringProperty", "B"); var serialized = JsonConvert.SerializeObject(patchDoc); @@ -203,7 +203,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic dynamic valueToAdd = new { IntValue = 1, StringValue = "test", GuidValue = Guid.NewGuid() }; // create patch - JsonPatchDocument patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Add("ComplexProperty", valueToAdd); var serialized = JsonConvert.SerializeObject(patchDoc); @@ -227,7 +227,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic }; // create patch - JsonPatchDocument patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Add("StringProperty", "B"); var serialized = JsonConvert.SerializeObject(patchDoc); @@ -249,7 +249,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic doc.StringProperty = "A"; // create patch - JsonPatchDocument patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Add("StringProperty", "B"); var serialized = JsonConvert.SerializeObject(patchDoc); @@ -269,7 +269,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic doc.InBetweenFirst.InBetweenSecond.StringProperty = "A"; // create patch - JsonPatchDocument patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Add("/InBetweenFirst/InBetweenSecond/StringProperty", "B"); var serialized = JsonConvert.SerializeObject(patchDoc); @@ -291,7 +291,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic doc.Nested.DynamicProperty.InBetweenFirst.InBetweenSecond.StringProperty = "A"; // create patch - JsonPatchDocument patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Add("/Nested/DynamicProperty/InBetweenFirst/InBetweenSecond/StringProperty", "B"); var serialized = JsonConvert.SerializeObject(patchDoc); @@ -325,7 +325,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic }; // create patch - JsonPatchDocument patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Add("DynamicProperty/OtherProperty/IntProperty", 1); var serialized = JsonConvert.SerializeObject(patchDoc); @@ -366,7 +366,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic }; // create patch - JsonPatchDocument patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Add("baz/bat", "qux"); var serialized = JsonConvert.SerializeObject(patchDoc); @@ -382,13 +382,13 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic } [Fact] - public void ShouldReplacePropertyWithDifferentCase() + public void ShouldNotReplacePropertyWithDifferentCase() { dynamic doc = new ExpandoObject(); doc.StringProperty = "A"; // create patch - JsonPatchDocument patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Add("stringproperty", "B"); var serialized = JsonConvert.SerializeObject(patchDoc); @@ -396,7 +396,8 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic deserialized.ApplyTo(doc); - Assert.Equal("B", doc.StringProperty); + Assert.Equal("A", doc.StringProperty); + Assert.Equal("B", doc.stringproperty); } [Fact] @@ -408,7 +409,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic }; // create patch - JsonPatchDocument patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Add("IntegerList/0", 4); var serialized = JsonConvert.SerializeObject(patchDoc); @@ -426,7 +427,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic doc.IntegerList = new List() { 1, 2, 3 }; // create patch - JsonPatchDocument patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Add("IntegerList/-1", 4); var serialized = JsonConvert.SerializeObject(patchDoc); @@ -450,7 +451,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic }; // create patch - JsonPatchDocument patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Add("integerlist/0", 4); var serialized = JsonConvert.SerializeObject(patchDoc); @@ -470,7 +471,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic }; // create patch - JsonPatchDocument patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Add("IntegerList/4", 4); var serialized = JsonConvert.SerializeObject(patchDoc); @@ -494,7 +495,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic }; // create patch - JsonPatchDocument patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Add("IntegerList/0", 4); var serialized = JsonConvert.SerializeObject(patchDoc); @@ -514,7 +515,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic }; // create patch - JsonPatchDocument patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Add("IntegerList/-1", 4); var serialized = JsonConvert.SerializeObject(patchDoc); @@ -538,7 +539,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic }; // create patch - JsonPatchDocument patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Add("IntegerList/-", 4); var serialized = JsonConvert.SerializeObject(patchDoc); diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/AddTypedOperationTests.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/AddTypedOperationTests.cs index f28d877ea4..bbf5118962 100644 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/AddTypedOperationTests.cs +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/AddTypedOperationTests.cs @@ -19,7 +19,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic }; // create patch - JsonPatchDocument patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Add("IntegerList/-1", 4); var serialized = JsonConvert.SerializeObject(patchDoc); @@ -49,7 +49,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic }; // create patch - JsonPatchDocument patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Add("ListOfSimpleDTO/0/IntegerList/0", 4); var serialized = JsonConvert.SerializeObject(patchDoc); @@ -74,7 +74,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic }; // create patch - JsonPatchDocument patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Add("ListOfSimpleDTO/-1/IntegerList/0", 4); var serialized = JsonConvert.SerializeObject(patchDoc); @@ -103,7 +103,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic } }; // create patch - JsonPatchDocument patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Add("ListOfSimpleDTO/20/IntegerList/0", 4); var serialized = JsonConvert.SerializeObject(patchDoc); diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/CopyOperationTests.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/CopyOperationTests.cs index 87f221bc15..42dd0072c4 100644 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/CopyOperationTests.cs +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/CopyOperationTests.cs @@ -18,7 +18,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic doc.StringProperty = "A"; doc.AnotherStringProperty = "B"; - JsonPatchDocument patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Copy("StringProperty", "AnotherStringProperty"); var serialized = JsonConvert.SerializeObject(patchDoc); @@ -35,7 +35,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic doc.IntegerList = new List() { 1, 2, 3 }; // create patch - JsonPatchDocument patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Copy("IntegerList/0", "IntegerList/1"); var serialized = JsonConvert.SerializeObject(patchDoc); @@ -53,7 +53,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic doc.IntegerList = new List() { 1, 2, 3 }; // create patch - JsonPatchDocument patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Copy("IntegerList/0", "IntegerList/-"); var serialized = JsonConvert.SerializeObject(patchDoc); @@ -70,7 +70,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic doc.IntegerList = new List() { 1, 2, 3 }; // create patch - JsonPatchDocument patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Copy("IntegerList/0", "IntegerValue"); var serialized = JsonConvert.SerializeObject(patchDoc); @@ -89,7 +89,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic doc.IntegerList = new List() { 1, 2, 3 }; // create patch - JsonPatchDocument patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Copy("IntegerValue", "IntegerList/0"); var serialized = JsonConvert.SerializeObject(patchDoc); @@ -107,7 +107,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic doc.IntegerList = new List() { 1, 2, 3 }; // create patch - JsonPatchDocument patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Copy("IntegerValue", "IntegerList/-"); var serialized = JsonConvert.SerializeObject(patchDoc); @@ -129,7 +129,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic }; // create patch - JsonPatchDocument patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Copy("SimpleDTO/StringProperty", "SimpleDTO/AnotherStringProperty"); var serialized = JsonConvert.SerializeObject(patchDoc); @@ -150,7 +150,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic }; // create patch - JsonPatchDocument patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Copy("SimpleDTO/IntegerList/0", "SimpleDTO/IntegerList/1"); var serialized = JsonConvert.SerializeObject(patchDoc); @@ -170,7 +170,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic }; // create patch - JsonPatchDocument patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Copy("SimpleDTO/IntegerList/0", "SimpleDTO/IntegerList/-"); var serialized = JsonConvert.SerializeObject(patchDoc); @@ -191,7 +191,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic }; // create patch - JsonPatchDocument patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Copy("SimpleDTO/IntegerList/0", "SimpleDTO/IntegerValue"); var serialized = JsonConvert.SerializeObject(patchDoc); @@ -212,7 +212,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic }; // create patch - JsonPatchDocument patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Copy("SimpleDTO/IntegerValue", "SimpleDTO/IntegerList/0"); var serialized = JsonConvert.SerializeObject(patchDoc); var deserialized = JsonConvert.DeserializeObject(serialized); @@ -232,7 +232,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic }; // create patch - JsonPatchDocument patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Copy("SimpleDTO/IntegerValue", "SimpleDTO/IntegerList/-"); var serialized = JsonConvert.SerializeObject(patchDoc); diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/CopyTypedOperationTests.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/CopyTypedOperationTests.cs index 3a51556013..0ea602da03 100644 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/CopyTypedOperationTests.cs +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/CopyTypedOperationTests.cs @@ -19,7 +19,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic }; // create patch - JsonPatchDocument patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Copy("StringProperty", "AnotherStringProperty"); var serialized = JsonConvert.SerializeObject(patchDoc); @@ -38,7 +38,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic }; // create patch - JsonPatchDocument patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Copy("IntegerList/0", "IntegerList/1"); var serialized = JsonConvert.SerializeObject(patchDoc); @@ -58,7 +58,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic }; // create patch - JsonPatchDocument patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Copy("IntegerList/0", "IntegerList/-"); var serialized = JsonConvert.SerializeObject(patchDoc); @@ -77,7 +77,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic }; // create patch - JsonPatchDocument patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Copy("IntegerList/0", "IntegerValue"); var serialized = JsonConvert.SerializeObject(patchDoc); @@ -98,7 +98,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic }; // create patch - JsonPatchDocument patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Copy("IntegerValue", "IntegerList/0"); var serialized = JsonConvert.SerializeObject(patchDoc); @@ -118,7 +118,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic }; // create patch - JsonPatchDocument patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Copy("IntegerValue", "IntegerList/-"); var serialized = JsonConvert.SerializeObject(patchDoc); @@ -142,7 +142,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic }; // create patch - JsonPatchDocument patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Copy("SimpleDTO/StringProperty", "SimpleDTO/AnotherStringProperty"); var serialized = JsonConvert.SerializeObject(patchDoc); @@ -165,7 +165,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic }; // create patch - JsonPatchDocument patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Copy("SimpleDTO/IntegerList/0", "SimpleDTO/IntegerList/1"); var serialized = JsonConvert.SerializeObject(patchDoc); @@ -187,7 +187,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic }; // create patch - JsonPatchDocument patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Copy("SimpleDTO/IntegerList/0", "SimpleDTO/IntegerList/-"); var serialized = JsonConvert.SerializeObject(patchDoc); @@ -210,7 +210,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic }; // create patch - JsonPatchDocument patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Copy("SimpleDTO/IntegerList/0", "SimpleDTO/IntegerValue"); var serialized = JsonConvert.SerializeObject(patchDoc); @@ -233,7 +233,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic }; // create patch - JsonPatchDocument patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Copy("SimpleDTO/IntegerValue", "SimpleDTO/IntegerList/0"); var serialized = JsonConvert.SerializeObject(patchDoc); var deserialized = JsonConvert.DeserializeObject(serialized); @@ -255,7 +255,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic }; // create patch - JsonPatchDocument patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Copy("SimpleDTO/IntegerValue", "SimpleDTO/IntegerList/-"); var serialized = JsonConvert.SerializeObject(patchDoc); diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/CustomNamingStrategyTests.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/CustomNamingStrategyTests.cs new file mode 100644 index 0000000000..b829b81902 --- /dev/null +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/CustomNamingStrategyTests.cs @@ -0,0 +1,154 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System.Collections.Generic; +using System.Dynamic; +using Newtonsoft.Json.Serialization; +using Xunit; + +namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic +{ + public class CustomNamingStrategyTests + { + [Fact] + public void AddProperty_ToExpandoObject_WithCustomNamingStrategy() + { + // Arrange + var contractResolver = new DefaultContractResolver + { + NamingStrategy = new TestNamingStrategy() + }; + + dynamic obj = new ExpandoObject(); + obj.Test = 1; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Add("NewInt", 1); + patchDoc.ContractResolver = contractResolver; + + // Act + patchDoc.ApplyTo(obj); + + // Assert + Assert.Equal(1, obj.customNewInt); + Assert.Equal(1, obj.Test); + } + + [Fact] + public void CopyPropertyValue_ForExpandoObject_WithCustomNamingStrategy() + { + // Arrange + var contractResolver = new DefaultContractResolver + { + NamingStrategy = new TestNamingStrategy() + }; + + dynamic obj = new ExpandoObject(); + obj.customStringProperty = "A"; + obj.customAnotherStringProperty = "B"; + + var patchDoc = new JsonPatchDocument(); + patchDoc.Copy("StringProperty", "AnotherStringProperty"); + patchDoc.ContractResolver = contractResolver; + + // Act + patchDoc.ApplyTo(obj); + + // Assert + Assert.Equal("A", obj.customAnotherStringProperty); + } + + [Fact] + public void MovePropertyValue_ForExpandoObject_WithCustomNamingStrategy() + { + // Arrange + var contractResolver = new DefaultContractResolver + { + NamingStrategy = new TestNamingStrategy() + }; + + dynamic obj = new ExpandoObject(); + obj.customStringProperty = "A"; + obj.customAnotherStringProperty = "B"; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Move("StringProperty", "AnotherStringProperty"); + patchDoc.ContractResolver = contractResolver; + + // Act + patchDoc.ApplyTo(obj); + var cont = obj as IDictionary; + cont.TryGetValue("customStringProperty", out var valueFromDictionary); + + // Assert + Assert.Equal("A", obj.customAnotherStringProperty); + Assert.Null(valueFromDictionary); + } + + [Fact] + public void RemoveProperty_FromExpandoObject_WithCustomNamingStrategy() + { + // Arrange + var contractResolver = new DefaultContractResolver + { + NamingStrategy = new TestNamingStrategy() + }; + + dynamic obj = new ExpandoObject(); + obj.customTest = 1; + + // create patch + var patchDoc = new JsonPatchDocument(); + patchDoc.Remove("Test"); + patchDoc.ContractResolver = contractResolver; + + // Act + patchDoc.ApplyTo(obj); + var cont = obj as IDictionary; + cont.TryGetValue("customTest", out var valueFromDictionary); + + // Assert + Assert.Null(valueFromDictionary); + } + + [Fact] + public void ReplacePropertyValue_ForExpandoObject_WithCustomNamingStrategy() + { + // Arrange + var contractResolver = new DefaultContractResolver + { + NamingStrategy = new TestNamingStrategy() + }; + + dynamic obj = new ExpandoObject(); + obj.customTest = 1; + + var patchDoc = new JsonPatchDocument(); + patchDoc.Replace("Test", 2); + patchDoc.ContractResolver = contractResolver; + + // Act + patchDoc.ApplyTo(obj); + + // Assert + Assert.Equal(2, obj.customTest); + } + + private class TestNamingStrategy : NamingStrategy + { + public new bool ProcessDictionaryKeys => true; + + public override string GetDictionaryKey(string key) + { + return "custom" + key; + } + + protected override string ResolvePropertyName(string name) + { + return name; + } + } + } +} diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/MoveOperationTests.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/MoveOperationTests.cs index 5e2f7ae814..0e3ea2cea0 100644 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/MoveOperationTests.cs +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/MoveOperationTests.cs @@ -18,7 +18,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic doc.AnotherStringProperty = "B"; // create patch - JsonPatchDocument patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Move("StringProperty", "AnotherStringProperty"); var serialized = JsonConvert.SerializeObject(patchDoc); @@ -29,8 +29,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic Assert.Equal("A", doc.AnotherStringProperty); var cont = doc as IDictionary; - object valueFromDictionary; - cont.TryGetValue("StringProperty", out valueFromDictionary); + cont.TryGetValue("StringProperty", out var valueFromDictionary); Assert.Null(valueFromDictionary); } @@ -41,7 +40,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic doc.StringProperty = "A"; // create patch - JsonPatchDocument patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Move("StringProperty", "AnotherStringProperty"); var serialized = JsonConvert.SerializeObject(patchDoc); @@ -52,8 +51,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic Assert.Equal("A", doc.AnotherStringProperty); var cont = doc as IDictionary; - object valueFromDictionary; - cont.TryGetValue("StringProperty", out valueFromDictionary); + cont.TryGetValue("StringProperty", out var valueFromDictionary); Assert.Null(valueFromDictionary); } @@ -65,7 +63,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic doc.SimpleDTO = new SimpleDTO() { AnotherStringProperty = "B" }; // create patch - JsonPatchDocument patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Move("StringProperty", "SimpleDTO/AnotherStringProperty"); var serialized = JsonConvert.SerializeObject(patchDoc); @@ -76,8 +74,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic Assert.Equal("A", doc.SimpleDTO.AnotherStringProperty); var cont = doc as IDictionary; - object valueFromDictionary; - cont.TryGetValue("StringProperty", out valueFromDictionary); + cont.TryGetValue("StringProperty", out var valueFromDictionary); Assert.Null(valueFromDictionary); } @@ -89,7 +86,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic doc.SimpleDTO = new SimpleDTO() { AnotherStringProperty = "B" }; // create patch - JsonPatchDocument patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Move("SimpleDTO/AnotherStringProperty", "StringProperty"); var serialized = JsonConvert.SerializeObject(patchDoc); @@ -112,7 +109,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic }; // create patch - JsonPatchDocument patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Move("Nested/StringProperty", "Nested/AnotherStringProperty"); var serialized = JsonConvert.SerializeObject(patchDoc); @@ -131,7 +128,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic doc.IntegerList = new List() { 1, 2, 3 }; // create patch - JsonPatchDocument patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Move("IntegerList/0", "IntegerList/1"); var serialized = JsonConvert.SerializeObject(patchDoc); @@ -152,7 +149,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic }; // create patch - JsonPatchDocument patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Move("Nested/IntegerList/0", "Nested/IntegerList/1"); var serialized = JsonConvert.SerializeObject(patchDoc); @@ -170,7 +167,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic doc.IntegerList = new List() { 1, 2, 3 }; // create patch - JsonPatchDocument patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Move("IntegerList/0", "IntegerList/-"); var serialized = JsonConvert.SerializeObject(patchDoc); @@ -190,7 +187,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic }; // create patch - JsonPatchDocument patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Move("Nested/IntegerList/0", "Nested/IntegerList/-"); var serialized = JsonConvert.SerializeObject(patchDoc); @@ -207,7 +204,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic doc.IntegerList = new List() { 1, 2, 3 }; // create patch - JsonPatchDocument patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Move("IntegerList/0", "IntegerValue"); var serialized = JsonConvert.SerializeObject(patchDoc); @@ -229,7 +226,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic }; // create patch - JsonPatchDocument patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Move("Nested/IntegerList/0", "Nested/IntegerValue"); var serialized = JsonConvert.SerializeObject(patchDoc); @@ -249,7 +246,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic doc.IntegerList = new List() { 1, 2, 3 }; // create patch - JsonPatchDocument patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Move("IntegerValue", "IntegerList/0"); var serialized = JsonConvert.SerializeObject(patchDoc); @@ -258,8 +255,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic deserialized.ApplyTo(doc); var cont = doc as IDictionary; - object valueFromDictionary; - cont.TryGetValue("IntegerValue", out valueFromDictionary); + cont.TryGetValue("IntegerValue", out var valueFromDictionary); Assert.Null(valueFromDictionary); Assert.Equal(new List() { 5, 1, 2, 3 }, doc.IntegerList); @@ -276,7 +272,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic }; // create patch - JsonPatchDocument patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Move("Nested/IntegerValue", "Nested/IntegerList/0"); var serialized = JsonConvert.SerializeObject(patchDoc); @@ -296,7 +292,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic doc.IntegerList = new List() { 1, 2, 3 }; // create patch - JsonPatchDocument patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Move("IntegerValue", "IntegerList/-"); var serialized = JsonConvert.SerializeObject(patchDoc); @@ -305,8 +301,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic deserialized.ApplyTo(doc); var cont = doc as IDictionary; - object valueFromDictionary; - cont.TryGetValue("IntegerValue", out valueFromDictionary); + cont.TryGetValue("IntegerValue", out var valueFromDictionary); Assert.Null(valueFromDictionary); Assert.Equal(new List() { 1, 2, 3, 5 }, doc.IntegerList); @@ -323,7 +318,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic }; // create patch - JsonPatchDocument patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Move("Nested/IntegerValue", "Nested/IntegerList/-"); var serialized = JsonConvert.SerializeObject(patchDoc); diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/MoveTypedOperationTests.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/MoveTypedOperationTests.cs index f57ad3d11c..bfd79a0ea2 100644 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/MoveTypedOperationTests.cs +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/MoveTypedOperationTests.cs @@ -19,7 +19,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic }; // create patch - JsonPatchDocument patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Move("StringProperty", "AnotherStringProperty"); var serialized = JsonConvert.SerializeObject(patchDoc); @@ -40,7 +40,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic }; // create patch - JsonPatchDocument patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Move("IntegerList/0", "IntegerList/1"); var serialized = JsonConvert.SerializeObject(patchDoc); @@ -60,7 +60,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic }; // create patch - JsonPatchDocument patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Move("IntegerList/0", "IntegerList/-"); var serialized = JsonConvert.SerializeObject(patchDoc); @@ -79,7 +79,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic }; // create patch - JsonPatchDocument patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Move("IntegerList/0", "IntegerValue"); var serialized = JsonConvert.SerializeObject(patchDoc); @@ -101,7 +101,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic }; // create patch - JsonPatchDocument patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Move("IntegerValue", "IntegerList/0"); var serialized = JsonConvert.SerializeObject(patchDoc); @@ -123,7 +123,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic }; // create patch - JsonPatchDocument patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Move("IntegerValue", "IntegerList/-"); var serialized = JsonConvert.SerializeObject(patchDoc); diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/PatchDocumentTests.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/PatchDocumentTests.cs index e7e6f665a5..e86dc8acbd 100644 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/PatchDocumentTests.cs +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/PatchDocumentTests.cs @@ -12,7 +12,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic [Fact] public void InvalidPathAtBeginningShouldThrowException() { - JsonPatchDocument patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); var exception = Assert.Throws(() => { patchDoc.Add("//NewInt", 1); @@ -25,7 +25,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic [Fact] public void InvalidPathAtEndShouldThrowException() { - JsonPatchDocument patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); var exception = Assert.Throws(() => { patchDoc.Add("NewInt//", 1); @@ -38,7 +38,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic [Fact] public void InvalidPathWithDotShouldThrowException() { - JsonPatchDocument patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); var exception = Assert.Throws(() => { patchDoc.Add("NewInt.Test", 1); @@ -57,7 +57,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic AnotherStringProperty = "B" }; - JsonPatchDocument patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Copy("StringProperty", "AnotherStringProperty"); var serialized = JsonConvert.SerializeObject(patchDoc); @@ -77,10 +77,10 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic AnotherStringProperty = "B" }; - JsonPatchDocument patchDocTyped = new JsonPatchDocument(); + var patchDocTyped = new JsonPatchDocument(); patchDocTyped.Copy(o => o.StringProperty, o => o.AnotherStringProperty); - JsonPatchDocument patchDocUntyped = new JsonPatchDocument(); + var patchDocUntyped = new JsonPatchDocument(); patchDocUntyped.Copy("StringProperty", "AnotherStringProperty"); var serializedTyped = JsonConvert.SerializeObject(patchDocTyped); diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/RemoveOperationTests.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/RemoveOperationTests.cs index f0164765ee..c8985e3a86 100644 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/RemoveOperationTests.cs +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/RemoveOperationTests.cs @@ -20,7 +20,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic }; // create patch - JsonPatchDocument patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Remove("Test"); var serialized = JsonConvert.SerializeObject(patchDoc); @@ -42,7 +42,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic doc.Test = 1; // create patch - JsonPatchDocument patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Remove("NonExisting"); var serialized = JsonConvert.SerializeObject(patchDoc); @@ -64,7 +64,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic obj.Test = 1; // create patch - JsonPatchDocument patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Remove("Test"); var serialized = JsonConvert.SerializeObject(patchDoc); @@ -73,32 +73,31 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic deserialized.ApplyTo(obj); var cont = obj as IDictionary; - object valueFromDictionary; - - cont.TryGetValue("Test", out valueFromDictionary); + cont.TryGetValue("Test", out var valueFromDictionary); Assert.Null(valueFromDictionary); } [Fact] - public void RemovePropertyFromExpandoObjectMixedCase() + public void RemoveProperty_FromExpandoObject_MixedCase_ThrowsPathNotFoundException() { dynamic obj = new ExpandoObject(); obj.Test = 1; // create patch - JsonPatchDocument patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Remove("test"); var serialized = JsonConvert.SerializeObject(patchDoc); var deserialized = JsonConvert.DeserializeObject(serialized); - deserialized.ApplyTo(obj); - - var cont = obj as IDictionary; - object valueFromDictionary; - - cont.TryGetValue("Test", out valueFromDictionary); - Assert.Null(valueFromDictionary); + var exception = Assert.Throws(() => + { + deserialized.ApplyTo(obj); + }); + Assert.Equal( + string.Format("The target location specified by path segment '{0}' was not found.", + "test"), + exception.Message); } [Fact] @@ -109,7 +108,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic obj.Test.AnotherTest = "A"; // create patch - JsonPatchDocument patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Remove("Test"); var serialized = JsonConvert.SerializeObject(patchDoc); @@ -118,32 +117,31 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic deserialized.ApplyTo(obj); var cont = obj as IDictionary; - object valueFromDictionary; - - cont.TryGetValue("Test", out valueFromDictionary); + cont.TryGetValue("Test", out var valueFromDictionary); Assert.Null(valueFromDictionary); } [Fact] - public void RemoveNestedPropertyFromExpandoObjectMixedCase() + public void RemoveNestedProperty_FromExpandoObject_MixedCase_ThrowsPathNotFoundException() { dynamic obj = new ExpandoObject(); obj.Test = new ExpandoObject(); obj.Test.AnotherTest = "A"; // create patch - JsonPatchDocument patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Remove("test"); var serialized = JsonConvert.SerializeObject(patchDoc); var deserialized = JsonConvert.DeserializeObject(serialized); - deserialized.ApplyTo(obj); - var cont = obj as IDictionary; - - object valueFromDictionary; - cont.TryGetValue("Test", out valueFromDictionary); - Assert.Null(valueFromDictionary); + var exception = Assert.Throws(() => + { + deserialized.ApplyTo(obj); + }); + Assert.Equal( + string.Format("The target location specified by path segment '{0}' was not found.", "test"), + exception.Message); } [Fact] @@ -156,7 +154,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic }; // create patch - JsonPatchDocument patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Remove("SimpleDTO/StringProperty"); var serialized = JsonConvert.SerializeObject(patchDoc); @@ -167,7 +165,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic } [Fact] - public void NestedRemoveMixedCase() + public void NestedRemove_MixedCase_ThrowsPathNotFoundException() { dynamic doc = new ExpandoObject(); doc.SimpleDTO = new SimpleDTO() @@ -176,15 +174,21 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic }; // create patch - JsonPatchDocument patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Remove("Simpledto/stringProperty"); var serialized = JsonConvert.SerializeObject(patchDoc); var deserialized = JsonConvert.DeserializeObject(serialized); - deserialized.ApplyTo(doc); - - Assert.Null(doc.SimpleDTO.StringProperty); + var exception = Assert.Throws(() => + { + deserialized.ApplyTo(doc); + }); + Assert.Equal( + string.Format("For operation '{0}', the target location specified by path '{1}' was not found.", + "remove", + "/Simpledto/stringProperty"), + exception.Message); } [Fact] @@ -197,7 +201,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic }; // create patch - JsonPatchDocument patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Remove("SimpleDTO/IntegerList/2"); var serialized = JsonConvert.SerializeObject(patchDoc); @@ -218,7 +222,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic }; // create patch - JsonPatchDocument patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Remove("SimpleDTO/Integerlist/2"); var serialized = JsonConvert.SerializeObject(patchDoc); @@ -239,7 +243,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic }; // create patch - JsonPatchDocument patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Remove("SimpleDTO/IntegerList/3"); var serialized = JsonConvert.SerializeObject(patchDoc); @@ -264,7 +268,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic }; // create patch - JsonPatchDocument patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Remove("SimpleDTO/IntegerList/-1"); var serialized = JsonConvert.SerializeObject(patchDoc); @@ -289,7 +293,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic }; // create patch - JsonPatchDocument patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Remove("SimpleDTO/IntegerList/-"); var serialized = JsonConvert.SerializeObject(patchDoc); diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/RemoveTypedOperationTests.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/RemoveTypedOperationTests.cs index 50ae6e8d5d..f65b2e6342 100644 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/RemoveTypedOperationTests.cs +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/RemoveTypedOperationTests.cs @@ -19,7 +19,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic }; // create patch - JsonPatchDocument patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Remove("StringProperty"); var serialized = JsonConvert.SerializeObject(patchDoc); @@ -39,7 +39,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic }; // create patch - JsonPatchDocument patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Remove("IntegerList/2"); var serialized = JsonConvert.SerializeObject(patchDoc); @@ -59,7 +59,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic }; // create patch - JsonPatchDocument patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Remove("IntegerList/3"); var serialized = JsonConvert.SerializeObject(patchDoc); @@ -83,7 +83,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic }; // create patch - JsonPatchDocument patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Remove("IntegerList/-1"); var serialized = JsonConvert.SerializeObject(patchDoc); @@ -107,7 +107,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic }; // create patch - JsonPatchDocument patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Remove("IntegerList/-"); var serialized = JsonConvert.SerializeObject(patchDoc); @@ -130,7 +130,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic }; // create patch - JsonPatchDocument patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Remove("SimpleDTO/StringProperty"); var serialized = JsonConvert.SerializeObject(patchDoc); @@ -153,7 +153,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic }; // create patch - JsonPatchDocument patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Remove("SimpleDTO/IntegerList/2"); var serialized = JsonConvert.SerializeObject(patchDoc); @@ -176,7 +176,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic }; // create patch - JsonPatchDocument patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Remove("SimpleDTO/IntegerList/3"); var serialized = JsonConvert.SerializeObject(patchDoc); @@ -203,7 +203,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic }; // create patch - JsonPatchDocument patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Remove("SimpleDTO/IntegerList/-1"); var serialized = JsonConvert.SerializeObject(patchDoc); @@ -230,7 +230,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic }; // create patch - JsonPatchDocument patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Remove("SimpleDTO/IntegerList/-"); var serialized = JsonConvert.SerializeObject(patchDoc); diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/ObjectVisitorTest.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/ObjectVisitorTest.cs index a03b830e02..391b5ebe2c 100644 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/ObjectVisitorTest.cs +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/ObjectVisitorTest.cs @@ -98,10 +98,6 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal { get { - var model = new Class1(); - yield return new object[] { model, "/Items/Name", model.Items }; - yield return new object[] { model.Items, "/Name", model.Items }; - var nestedModel = new Class1Nested(); nestedModel.Customers.Add(new Class1()); yield return new object[] { nestedModel, "/Customers/0/Items/Name", nestedModel.Customers[0].Items }; From 3d6a8615de85a8d25f78db2abe2cc511be46592c Mon Sep 17 00:00:00 2001 From: Jass Bagga Date: Thu, 24 Aug 2017 15:11:01 -0700 Subject: [PATCH 155/221] Support DynamicObject types (#99) Addresses #38 --- .../Internal/DynamicObjectAdapter.cs | 211 ++++ .../Internal/ObjectVisitor.cs | 14 +- .../Properties/Resources.Designer.cs | 124 +- .../DictionaryAdapterTest.cs | 27 +- .../Dynamic/AddOperationTests.cs | 14 +- .../Dynamic/AddTypedOperationTests.cs | 30 +- .../Dynamic/CopyOperationTests.cs | 38 +- .../Dynamic/CopyTypedOperationTests.cs | 62 +- .../Dynamic/InheritedObject.cs | 10 + .../Dynamic/MoveOperationTests.cs | 24 +- .../Dynamic/MoveTypedOperationTests.cs | 14 +- .../Dynamic/{NestedDTO.cs => NestedObject.cs} | 4 +- .../Dynamic/PatchDocumentTests.cs | 12 +- .../Dynamic/RemoveOperationTests.cs | 43 +- .../Dynamic/RemoveTypedOperationTests.cs | 48 +- .../Dynamic/ReplaceOperationTests.cs | 38 +- .../Dynamic/ReplaceTypedOperationTests.cs | 54 +- .../Dynamic/SimpleDTOWithNestedDTO.cs | 22 - .../Dynamic/{SimpleDTO.cs => SimpleObject.cs} | 6 +- .../Dynamic/SimpleObjectWithNestedObject.cs | 22 + .../DynamicObjectAdapterTest.cs | 231 ++++ .../DynamicTestObject.cs | 87 ++ .../{InheritedDTO.cs => InheritedObject.cs} | 2 +- .../DynamicObjectIntegrationTests.cs | 263 +++++ ...nPatchDocumentJsonPropertyAttributeTest.cs | 38 +- ...TO.cs => JsonPropertyComplexNameObject.cs} | 4 +- ...onPropertyDTO.cs => JsonPropertyObject.cs} | 2 +- ...s => JsonPropertyWithAnotherNameObject.cs} | 2 +- .../JsonPropertyWithInheritanceDTO.cs | 19 - .../JsonPropertyWithInheritanceObject.cs | 15 + .../ListAdapterTest.cs | 86 +- .../{NestedDTO.cs => NestedObject.cs} | 2 +- .../NestedObjectTests.cs | 1030 ++++++++--------- .../ObjectAdapterTests.cs | 422 +++---- .../ObjectVisitorTest.cs | 44 +- .../SimpleDTOWithNestedDTO.cs | 30 - .../SimpleDTOWithNestedDTOWithNullCheck.cs | 15 - .../{SimpleDTO.cs => SimpleObject.cs} | 2 +- .../SimpleObjectWithNestedObject.cs | 30 + ...mpleObjectWithNestedObjectWithNullCheck.cs | 15 + ...lCheck.cs => SimpleObjectWithNullCheck.cs} | 2 +- 41 files changed, 1950 insertions(+), 1208 deletions(-) create mode 100644 src/Microsoft.AspNetCore.JsonPatch/Internal/DynamicObjectAdapter.cs create mode 100644 test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/InheritedObject.cs rename test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/{NestedDTO.cs => NestedObject.cs} (78%) delete mode 100644 test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/SimpleDTOWithNestedDTO.cs rename test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/{SimpleDTO.cs => SimpleObject.cs} (81%) create mode 100644 test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/SimpleObjectWithNestedObject.cs create mode 100644 test/Microsoft.AspNetCore.JsonPatch.Test/DynamicObjectAdapterTest.cs create mode 100644 test/Microsoft.AspNetCore.JsonPatch.Test/DynamicTestObject.cs rename test/Microsoft.AspNetCore.JsonPatch.Test/{InheritedDTO.cs => InheritedObject.cs} (85%) create mode 100644 test/Microsoft.AspNetCore.JsonPatch.Test/IntegrationTests/DynamicObjectIntegrationTests.cs rename test/Microsoft.AspNetCore.JsonPatch.Test/{JsonPropertyComplexNameDTO.cs => JsonPropertyComplexNameObject.cs} (78%) rename test/Microsoft.AspNetCore.JsonPatch.Test/{JsonPropertyDTO.cs => JsonPropertyObject.cs} (90%) rename test/Microsoft.AspNetCore.JsonPatch.Test/{JsonPropertyWithAnotherNameDTO.cs => JsonPropertyWithAnotherNameObject.cs} (84%) delete mode 100644 test/Microsoft.AspNetCore.JsonPatch.Test/JsonPropertyWithInheritanceDTO.cs create mode 100644 test/Microsoft.AspNetCore.JsonPatch.Test/JsonPropertyWithInheritanceObject.cs rename test/Microsoft.AspNetCore.JsonPatch.Test/{NestedDTO.cs => NestedObject.cs} (89%) delete mode 100644 test/Microsoft.AspNetCore.JsonPatch.Test/SimpleDTOWithNestedDTO.cs delete mode 100644 test/Microsoft.AspNetCore.JsonPatch.Test/SimpleDTOWithNestedDTOWithNullCheck.cs rename test/Microsoft.AspNetCore.JsonPatch.Test/{SimpleDTO.cs => SimpleObject.cs} (95%) create mode 100644 test/Microsoft.AspNetCore.JsonPatch.Test/SimpleObjectWithNestedObject.cs create mode 100644 test/Microsoft.AspNetCore.JsonPatch.Test/SimpleObjectWithNestedObjectWithNullCheck.cs rename test/Microsoft.AspNetCore.JsonPatch.Test/{SimpleDTOWithNullCheck.cs => SimpleObjectWithNullCheck.cs} (93%) diff --git a/src/Microsoft.AspNetCore.JsonPatch/Internal/DynamicObjectAdapter.cs b/src/Microsoft.AspNetCore.JsonPatch/Internal/DynamicObjectAdapter.cs new file mode 100644 index 0000000000..433326ce53 --- /dev/null +++ b/src/Microsoft.AspNetCore.JsonPatch/Internal/DynamicObjectAdapter.cs @@ -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.Create(CSharpArgumentInfoFlags.None, null) + }); + + var callsite = CallSite>.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.Create(CSharpArgumentInfoFlags.None, null), + CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null) + }); + + var callsite = CallSite>.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; + } + } +} diff --git a/src/Microsoft.AspNetCore.JsonPatch/Internal/ObjectVisitor.cs b/src/Microsoft.AspNetCore.JsonPatch/Internal/ObjectVisitor.cs index b604f65a17..bbf6db4ff6 100644 --- a/src/Microsoft.AspNetCore.JsonPatch/Internal/ObjectVisitor.cs +++ b/src/Microsoft.AspNetCore.JsonPatch/Internal/ObjectVisitor.cs @@ -15,13 +15,8 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal public ObjectVisitor(ParsedPath path, IContractResolver contractResolver) { - if (contractResolver == null) - { - throw new ArgumentNullException(nameof(contractResolver)); - } - _path = path; - _contractResolver = contractResolver; + _contractResolver = contractResolver ?? throw new ArgumentNullException(nameof(contractResolver)); } 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 for (var i = 0; i < _path.Segments.Count - 1; i++) { - object next; - if (!adapter.TryTraverse(target, _path.Segments[i], _contractResolver, out next, out errorMessage)) + if (!adapter.TryTraverse(target, _path.Segments[i], _contractResolver, out var next, out errorMessage)) { adapter = null; return false; @@ -59,6 +53,10 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal { return new ExpandoObjectAdapter(); } + else if (targetObject is IDynamicMetaObjectProvider) + { + return new DynamicObjectAdapter(); + } else if (targetObject is IDictionary) { return new DictionaryAdapter(); diff --git a/src/Microsoft.AspNetCore.JsonPatch/Properties/Resources.Designer.cs b/src/Microsoft.AspNetCore.JsonPatch/Properties/Resources.Designer.cs index 97c98c2b05..cd99292061 100644 --- a/src/Microsoft.AspNetCore.JsonPatch/Properties/Resources.Designer.cs +++ b/src/Microsoft.AspNetCore.JsonPatch/Properties/Resources.Designer.cs @@ -10,277 +10,243 @@ namespace Microsoft.AspNetCore.JsonPatch private static readonly ResourceManager _resourceManager = new ResourceManager("Microsoft.AspNetCore.JsonPatch.Resources", typeof(Resources).GetTypeInfo().Assembly); - /// - /// The type of the property at path '{0}' could not be determined. - /// - internal static string CannotDeterminePropertyType - { - get { return GetString("CannotDeterminePropertyType"); } - } - - /// - /// The type of the property at path '{0}' could not be determined. - /// - internal static string FormatCannotDeterminePropertyType(object p0) - { - return string.Format(CultureInfo.CurrentCulture, GetString("CannotDeterminePropertyType"), p0); - } - /// /// The property at '{0}' could not be copied. /// - internal static string CannotCannotCopyProperty + internal static string CannotCopyProperty { - get { return GetString("CannotCannotCopyProperty"); } + get => GetString("CannotCopyProperty"); } /// /// The property at '{0}' could not be copied. /// internal static string FormatCannotCopyProperty(object p0) + => string.Format(CultureInfo.CurrentCulture, GetString("CannotCopyProperty"), p0); + + /// + /// The type of the property at path '{0}' could not be determined. + /// + internal static string CannotDeterminePropertyType { - return string.Format(CultureInfo.CurrentCulture, GetString("CannotCannotCopyProperty"), p0); + get => GetString("CannotDeterminePropertyType"); } + /// + /// The type of the property at path '{0}' could not be determined. + /// + internal static string FormatCannotDeterminePropertyType(object p0) + => string.Format(CultureInfo.CurrentCulture, GetString("CannotDeterminePropertyType"), p0); + /// /// The '{0}' operation at path '{1}' could not be performed. /// internal static string CannotPerformOperation { - get { return GetString("CannotPerformOperation"); } + get => GetString("CannotPerformOperation"); } /// /// The '{0}' operation at path '{1}' could not be performed. /// internal static string FormatCannotPerformOperation(object p0, object p1) - { - return string.Format(CultureInfo.CurrentCulture, GetString("CannotPerformOperation"), p0, p1); - } + => string.Format(CultureInfo.CurrentCulture, GetString("CannotPerformOperation"), p0, p1); /// /// The property at '{0}' could not be read. /// internal static string CannotReadProperty { - get { return GetString("CannotReadProperty"); } + get => GetString("CannotReadProperty"); } /// /// The property at '{0}' could not be read. /// internal static string FormatCannotReadProperty(object p0) - { - return string.Format(CultureInfo.CurrentCulture, GetString("CannotReadProperty"), p0); - } + => string.Format(CultureInfo.CurrentCulture, GetString("CannotReadProperty"), p0); /// /// The property at path '{0}' could not be updated. /// internal static string CannotUpdateProperty { - get { return GetString("CannotUpdateProperty"); } + get => GetString("CannotUpdateProperty"); } /// /// The property at path '{0}' could not be updated. /// internal static string FormatCannotUpdateProperty(object p0) - { - return string.Format(CultureInfo.CurrentCulture, GetString("CannotUpdateProperty"), p0); - } + => string.Format(CultureInfo.CurrentCulture, GetString("CannotUpdateProperty"), p0); /// /// The index value provided by path segment '{0}' is out of bounds of the array size. /// internal static string IndexOutOfBounds { - get { return GetString("IndexOutOfBounds"); } + get => GetString("IndexOutOfBounds"); } /// /// The index value provided by path segment '{0}' is out of bounds of the array size. /// internal static string FormatIndexOutOfBounds(object p0) - { - return string.Format(CultureInfo.CurrentCulture, GetString("IndexOutOfBounds"), p0); - } + => string.Format(CultureInfo.CurrentCulture, GetString("IndexOutOfBounds"), p0); /// /// The path segment '{0}' is invalid for an array index. /// internal static string InvalidIndexValue { - get { return GetString("InvalidIndexValue"); } + get => GetString("InvalidIndexValue"); } /// /// The path segment '{0}' is invalid for an array index. /// internal static string FormatInvalidIndexValue(object p0) - { - return string.Format(CultureInfo.CurrentCulture, GetString("InvalidIndexValue"), p0); - } + => string.Format(CultureInfo.CurrentCulture, GetString("InvalidIndexValue"), p0); /// /// The type '{0}' was malformed and could not be parsed. /// internal static string InvalidJsonPatchDocument { - get { return GetString("InvalidJsonPatchDocument"); } + get => GetString("InvalidJsonPatchDocument"); } /// /// The type '{0}' was malformed and could not be parsed. /// internal static string FormatInvalidJsonPatchDocument(object p0) - { - return string.Format(CultureInfo.CurrentCulture, GetString("InvalidJsonPatchDocument"), p0); - } + => string.Format(CultureInfo.CurrentCulture, GetString("InvalidJsonPatchDocument"), p0); /// /// Invalid JsonPatch operation '{0}'. /// internal static string InvalidJsonPatchOperation { - get { return GetString("InvalidJsonPatchOperation"); } + get => GetString("InvalidJsonPatchOperation"); } /// /// Invalid JsonPatch operation '{0}'. /// internal static string FormatInvalidJsonPatchOperation(object p0) - { - return string.Format(CultureInfo.CurrentCulture, GetString("InvalidJsonPatchOperation"), p0); - } + => string.Format(CultureInfo.CurrentCulture, GetString("InvalidJsonPatchOperation"), p0); /// /// The provided string '{0}' is an invalid path. /// internal static string InvalidValueForPath { - get { return GetString("InvalidValueForPath"); } + get => GetString("InvalidValueForPath"); } /// /// The provided string '{0}' is an invalid path. /// internal static string FormatInvalidValueForPath(object p0) - { - return string.Format(CultureInfo.CurrentCulture, GetString("InvalidValueForPath"), p0); - } + => string.Format(CultureInfo.CurrentCulture, GetString("InvalidValueForPath"), p0); /// /// The value '{0}' is invalid for target location. /// internal static string InvalidValueForProperty { - get { return GetString("InvalidValueForProperty"); } + get => GetString("InvalidValueForProperty"); } /// /// The value '{0}' is invalid for target location. /// internal static string FormatInvalidValueForProperty(object p0) - { - return string.Format(CultureInfo.CurrentCulture, GetString("InvalidValueForProperty"), p0); - } + => string.Format(CultureInfo.CurrentCulture, GetString("InvalidValueForProperty"), p0); /// /// '{0}' must be of type '{1}'. /// internal static string ParameterMustMatchType { - get { return GetString("ParameterMustMatchType"); } + get => GetString("ParameterMustMatchType"); } /// /// '{0}' must be of type '{1}'. /// internal static string FormatParameterMustMatchType(object p0, object p1) - { - return string.Format(CultureInfo.CurrentCulture, GetString("ParameterMustMatchType"), p0, p1); - } + => string.Format(CultureInfo.CurrentCulture, GetString("ParameterMustMatchType"), p0, p1); /// /// The type '{0}' which is an array is not supported for json patch operations as it has a fixed size. /// internal static string PatchNotSupportedForArrays { - get { return GetString("PatchNotSupportedForArrays"); } + get => GetString("PatchNotSupportedForArrays"); } /// /// The type '{0}' which is an array is not supported for json patch operations as it has a fixed size. /// internal static string FormatPatchNotSupportedForArrays(object p0) - { - return string.Format(CultureInfo.CurrentCulture, GetString("PatchNotSupportedForArrays"), p0); - } + => string.Format(CultureInfo.CurrentCulture, GetString("PatchNotSupportedForArrays"), p0); /// /// The type '{0}' which is a non generic list is not supported for json patch operations. Only generic list types are supported. /// internal static string PatchNotSupportedForNonGenericLists { - get { return GetString("PatchNotSupportedForNonGenericLists"); } + get => GetString("PatchNotSupportedForNonGenericLists"); } /// /// The type '{0}' which is a non generic list is not supported for json patch operations. Only generic list types are supported. /// internal static string FormatPatchNotSupportedForNonGenericLists(object p0) - { - return string.Format(CultureInfo.CurrentCulture, GetString("PatchNotSupportedForNonGenericLists"), p0); - } + => string.Format(CultureInfo.CurrentCulture, GetString("PatchNotSupportedForNonGenericLists"), p0); /// /// The target location specified by path segment '{0}' was not found. /// internal static string TargetLocationAtPathSegmentNotFound { - get { return GetString("TargetLocationAtPathSegmentNotFound"); } + get => GetString("TargetLocationAtPathSegmentNotFound"); } /// /// The target location specified by path segment '{0}' was not found. /// internal static string FormatTargetLocationAtPathSegmentNotFound(object p0) - { - return string.Format(CultureInfo.CurrentCulture, GetString("TargetLocationAtPathSegmentNotFound"), p0); - } + => string.Format(CultureInfo.CurrentCulture, GetString("TargetLocationAtPathSegmentNotFound"), p0); /// /// For operation '{0}', the target location specified by path '{1}' was not found. /// internal static string TargetLocationNotFound { - get { return GetString("TargetLocationNotFound"); } + get => GetString("TargetLocationNotFound"); } /// /// For operation '{0}', the target location specified by path '{1}' was not found. /// internal static string FormatTargetLocationNotFound(object p0, object p1) - { - return string.Format(CultureInfo.CurrentCulture, GetString("TargetLocationNotFound"), p0, p1); - } + => string.Format(CultureInfo.CurrentCulture, GetString("TargetLocationNotFound"), p0, p1); /// /// The test operation is not supported. /// internal static string TestOperationNotSupported { - get { return GetString("TestOperationNotSupported"); } + get => GetString("TestOperationNotSupported"); } /// /// The test operation is not supported. /// internal static string FormatTestOperationNotSupported() - { - return GetString("TestOperationNotSupported"); - } + => GetString("TestOperationNotSupported"); private static string GetString(string name, params string[] formatterNames) { diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/DictionaryAdapterTest.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/DictionaryAdapterTest.cs index bc50b872a2..084aa57379 100644 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/DictionaryAdapterTest.cs +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/DictionaryAdapterTest.cs @@ -20,10 +20,9 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal dictionary[nameKey] = "Mike"; var dictionaryAdapter = new DictionaryAdapter(); var resolver = new Mock(MockBehavior.Strict); - string message = null; // 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.True(addStatus); @@ -38,12 +37,11 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal // Arrange var dictionaryAdapter = new DictionaryAdapter(); var resolver = new Mock(MockBehavior.Strict); - string message = null; var nameKey = "Name"; var dictionary = new Dictionary(StringComparer.Ordinal); // 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.True(addStatus); @@ -52,8 +50,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal Assert.Equal("James", dictionary[nameKey]); // Act - object outValue = null; - addStatus = dictionaryAdapter.TryGet(dictionary, nameKey.ToUpper(), resolver.Object, out outValue, out message); + addStatus = dictionaryAdapter.TryGet(dictionary, nameKey.ToUpper(), resolver.Object, out var outValue, out message); // Assert Assert.True(addStatus); @@ -67,12 +64,11 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal // Arrange var dictionaryAdapter = new DictionaryAdapter(); var resolver = new Mock(MockBehavior.Strict); - string message = null; var nameKey = "Name"; var dictionary = new Dictionary(StringComparer.Ordinal); // 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.True(addStatus); @@ -81,8 +77,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal Assert.Equal("James", dictionary[nameKey]); // Act - object outValue = null; - addStatus = dictionaryAdapter.TryGet(dictionary, nameKey, resolver.Object, out outValue, out message); + addStatus = dictionaryAdapter.TryGet(dictionary, nameKey, resolver.Object, out var outValue, out message); // Assert Assert.True(addStatus); @@ -99,10 +94,9 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal dictionary.Add(nameKey, "Mike"); var dictionaryAdapter = new DictionaryAdapter(); var resolver = new Mock(MockBehavior.Strict); - string message = null; // 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.True(replaceStatus); @@ -119,10 +113,9 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal var dictionary = new Dictionary(StringComparer.Ordinal); var dictionaryAdapter = new DictionaryAdapter(); var resolver = new Mock(MockBehavior.Strict); - string message = null; // 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.False(replaceStatus); @@ -140,10 +133,9 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal var dictionary = new Dictionary(StringComparer.Ordinal); var dictionaryAdapter = new DictionaryAdapter(); var resolver = new Mock(MockBehavior.Strict); - string message = null; // Act - var removeStatus = dictionaryAdapter.TryRemove(dictionary, nameKey, resolver.Object, out message); + var removeStatus = dictionaryAdapter.TryRemove(dictionary, nameKey, resolver.Object, out var message); // Assert Assert.False(removeStatus); @@ -162,10 +154,9 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal dictionary[nameKey] = "James"; var dictionaryAdapter = new DictionaryAdapter(); var resolver = new Mock(MockBehavior.Strict); - string message = null; // Act - var removeStatus = dictionaryAdapter.TryRemove(dictionary, nameKey, resolver.Object, out message); + var removeStatus = dictionaryAdapter.TryRemove(dictionary, nameKey, resolver.Object, out var message); //Assert Assert.True(removeStatus); diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/AddOperationTests.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/AddOperationTests.cs index e1cdb21df2..493444066b 100644 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/AddOperationTests.cs +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/AddOperationTests.cs @@ -8,7 +8,7 @@ using Microsoft.AspNetCore.JsonPatch.Exceptions; using Newtonsoft.Json; using Xunit; -namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic +namespace Microsoft.AspNetCore.JsonPatch.Internal { public class AddOperationTests { @@ -86,7 +86,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic dynamic doc = new { Test = 1, - nested = new NestedDTO() + nested = new NestedObject() }; // create patch @@ -111,7 +111,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic dynamic doc = new { Test = 1, - nested = new NestedDTO() + nested = new NestedObject() }; // create patch @@ -152,7 +152,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic [Fact] public void AddNewPropertyToExpandoOjectInTypedObject() { - var doc = new NestedDTO() + var doc = new NestedObject() { DynamicProperty = new ExpandoObject() }; @@ -175,7 +175,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic dynamic dynamicProperty = new ExpandoObject(); dynamicProperty.StringProperty = "A"; - var doc = new NestedDTO() + var doc = new NestedObject() { DynamicProperty = dynamicProperty }; @@ -284,7 +284,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic public void AddResultsShouldReplaceInNestedInDynamic() { dynamic doc = new ExpandoObject(); - doc.Nested = new NestedDTO(); + doc.Nested = new NestedObject(); doc.Nested.DynamicProperty = new ExpandoObject(); doc.Nested.DynamicProperty.InBetweenFirst = 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 // member of an existing array. - var doc = new NestedDTO() + var doc = new NestedObject() { DynamicProperty = new ExpandoObject() }; diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/AddTypedOperationTests.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/AddTypedOperationTests.cs index bbf5118962..b2eb4d3a3c 100644 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/AddTypedOperationTests.cs +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/AddTypedOperationTests.cs @@ -6,14 +6,14 @@ using Microsoft.AspNetCore.JsonPatch.Exceptions; using Newtonsoft.Json; using Xunit; -namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic +namespace Microsoft.AspNetCore.JsonPatch.Internal { public class AddTypedOperationTests { [Fact] public void AddToListNegativePosition() { - var doc = new SimpleDTO() + var doc = new SimpleObject() { IntegerList = new List() { 1, 2, 3 } }; @@ -37,11 +37,11 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic [Fact] public void AddToListInList() { - var doc = new SimpleDTOWithNestedDTO() + var doc = new SimpleObjectWithNestedObject() { - ListOfSimpleDTO = new List() + ListOfSimpleObject = new List() { - new SimpleDTO() + new SimpleObject() { IntegerList = new List() { 1, 2, 3 } } @@ -50,23 +50,23 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic // create patch var patchDoc = new JsonPatchDocument(); - patchDoc.Add("ListOfSimpleDTO/0/IntegerList/0", 4); + patchDoc.Add("ListOfSimpleObject/0/IntegerList/0", 4); var serialized = JsonConvert.SerializeObject(patchDoc); var deserialized = JsonConvert.DeserializeObject(serialized); deserialized.ApplyTo(doc); - Assert.Equal(new List() { 4, 1, 2, 3 }, doc.ListOfSimpleDTO[0].IntegerList); + Assert.Equal(new List() { 4, 1, 2, 3 }, doc.ListOfSimpleObject[0].IntegerList); } [Fact] public void AddToListInListInvalidPositionTooSmall() { - var doc = new SimpleDTOWithNestedDTO() + var doc = new SimpleObjectWithNestedObject() { - ListOfSimpleDTO = new List() + ListOfSimpleObject = new List() { - new SimpleDTO() + new SimpleObject() { IntegerList = new List() { 1, 2, 3 } } @@ -75,7 +75,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic // create patch var patchDoc = new JsonPatchDocument(); - patchDoc.Add("ListOfSimpleDTO/-1/IntegerList/0", 4); + patchDoc.Add("ListOfSimpleObject/-1/IntegerList/0", 4); var serialized = JsonConvert.SerializeObject(patchDoc); var deserialized = JsonConvert.DeserializeObject(serialized); @@ -92,11 +92,11 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic [Fact] public void AddToListInListInvalidPositionTooLarge() { - var doc = new SimpleDTOWithNestedDTO() + var doc = new SimpleObjectWithNestedObject() { - ListOfSimpleDTO = new List() + ListOfSimpleObject = new List() { - new SimpleDTO() + new SimpleObject() { IntegerList = new List() { 1, 2, 3 } } @@ -104,7 +104,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic }; // create patch var patchDoc = new JsonPatchDocument(); - patchDoc.Add("ListOfSimpleDTO/20/IntegerList/0", 4); + patchDoc.Add("ListOfSimpleObject/20/IntegerList/0", 4); var serialized = JsonConvert.SerializeObject(patchDoc); var deserialized = JsonConvert.DeserializeObject(serialized); diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/CopyOperationTests.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/CopyOperationTests.cs index 42dd0072c4..b2faff25a0 100644 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/CopyOperationTests.cs +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/CopyOperationTests.cs @@ -6,7 +6,7 @@ using System.Dynamic; using Newtonsoft.Json; using Xunit; -namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic +namespace Microsoft.AspNetCore.JsonPatch.Internal { public class CopyOperationTests { @@ -122,7 +122,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic public void NestedCopy() { dynamic doc = new ExpandoObject(); - doc.SimpleDTO = new SimpleDTO() + doc.SimpleObject = new SimpleObject() { StringProperty = "A", AnotherStringProperty = "B" @@ -130,82 +130,82 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic // create patch var patchDoc = new JsonPatchDocument(); - patchDoc.Copy("SimpleDTO/StringProperty", "SimpleDTO/AnotherStringProperty"); + patchDoc.Copy("SimpleObject/StringProperty", "SimpleObject/AnotherStringProperty"); var serialized = JsonConvert.SerializeObject(patchDoc); var deserialized = JsonConvert.DeserializeObject(serialized); deserialized.ApplyTo(doc); - Assert.Equal("A", doc.SimpleDTO.AnotherStringProperty); + Assert.Equal("A", doc.SimpleObject.AnotherStringProperty); } [Fact] public void NestedCopyInList() { dynamic doc = new ExpandoObject(); - doc.SimpleDTO = new SimpleDTO() + doc.SimpleObject = new SimpleObject() { IntegerList = new List() { 1, 2, 3 } }; // create patch 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 deserialized = JsonConvert.DeserializeObject(serialized); deserialized.ApplyTo(doc); - Assert.Equal(new List() { 1, 1, 2, 3 }, doc.SimpleDTO.IntegerList); + Assert.Equal(new List() { 1, 1, 2, 3 }, doc.SimpleObject.IntegerList); } [Fact] public void NestedCopyFromListToEndOfList() { dynamic doc = new ExpandoObject(); - doc.SimpleDTO = new SimpleDTO() + doc.SimpleObject = new SimpleObject() { IntegerList = new List() { 1, 2, 3 } }; // create patch var patchDoc = new JsonPatchDocument(); - patchDoc.Copy("SimpleDTO/IntegerList/0", "SimpleDTO/IntegerList/-"); + patchDoc.Copy("SimpleObject/IntegerList/0", "SimpleObject/IntegerList/-"); var serialized = JsonConvert.SerializeObject(patchDoc); var deserialized = JsonConvert.DeserializeObject(serialized); deserialized.ApplyTo(doc); - Assert.Equal(new List() { 1, 2, 3, 1 }, doc.SimpleDTO.IntegerList); + Assert.Equal(new List() { 1, 2, 3, 1 }, doc.SimpleObject.IntegerList); } [Fact] public void NestedCopyFromListToNonList() { dynamic doc = new ExpandoObject(); - doc.SimpleDTO = new SimpleDTO() + doc.SimpleObject = new SimpleObject() { IntegerList = new List() { 1, 2, 3 } }; // create patch var patchDoc = new JsonPatchDocument(); - patchDoc.Copy("SimpleDTO/IntegerList/0", "SimpleDTO/IntegerValue"); + patchDoc.Copy("SimpleObject/IntegerList/0", "SimpleObject/IntegerValue"); var serialized = JsonConvert.SerializeObject(patchDoc); var deserialized = JsonConvert.DeserializeObject(serialized); deserialized.ApplyTo(doc); - Assert.Equal(1, doc.SimpleDTO.IntegerValue); + Assert.Equal(1, doc.SimpleObject.IntegerValue); } [Fact] public void NestedCopyFromNonListToList() { dynamic doc = new ExpandoObject(); - doc.SimpleDTO = new SimpleDTO() + doc.SimpleObject = new SimpleObject() { IntegerValue = 5, IntegerList = new List() { 1, 2, 3 } @@ -213,19 +213,19 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic // create patch var patchDoc = new JsonPatchDocument(); - patchDoc.Copy("SimpleDTO/IntegerValue", "SimpleDTO/IntegerList/0"); + patchDoc.Copy("SimpleObject/IntegerValue", "SimpleObject/IntegerList/0"); var serialized = JsonConvert.SerializeObject(patchDoc); var deserialized = JsonConvert.DeserializeObject(serialized); deserialized.ApplyTo(doc); - Assert.Equal(new List() { 5, 1, 2, 3 }, doc.SimpleDTO.IntegerList); + Assert.Equal(new List() { 5, 1, 2, 3 }, doc.SimpleObject.IntegerList); } [Fact] public void NestedCopyToEndOfList() { dynamic doc = new ExpandoObject(); - doc.SimpleDTO = new SimpleDTO() + doc.SimpleObject = new SimpleObject() { IntegerValue = 5, IntegerList = new List() { 1, 2, 3 } @@ -233,13 +233,13 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic // create patch var patchDoc = new JsonPatchDocument(); - patchDoc.Copy("SimpleDTO/IntegerValue", "SimpleDTO/IntegerList/-"); + patchDoc.Copy("SimpleObject/IntegerValue", "SimpleObject/IntegerList/-"); var serialized = JsonConvert.SerializeObject(patchDoc); var deserialized = JsonConvert.DeserializeObject(serialized); deserialized.ApplyTo(doc); - Assert.Equal(new List() { 1, 2, 3, 5 }, doc.SimpleDTO.IntegerList); + Assert.Equal(new List() { 1, 2, 3, 5 }, doc.SimpleObject.IntegerList); } } } diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/CopyTypedOperationTests.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/CopyTypedOperationTests.cs index 0ea602da03..d0b0847c71 100644 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/CopyTypedOperationTests.cs +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/CopyTypedOperationTests.cs @@ -5,14 +5,14 @@ using System.Collections.Generic; using Newtonsoft.Json; using Xunit; -namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic +namespace Microsoft.AspNetCore.JsonPatch.Internal { public class CopyTypedOperationTests { [Fact] public void Copy() { - var doc = new SimpleDTO() + var doc = new SimpleObject() { StringProperty = "A", AnotherStringProperty = "B" @@ -32,7 +32,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic [Fact] public void CopyInList() { - var doc = new SimpleDTO() + var doc = new SimpleObject() { IntegerList = new List() { 1, 2, 3 } }; @@ -52,7 +52,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic [Fact] public void CopyFromListToEndOfList() { - var doc = new SimpleDTO() + var doc = new SimpleObject() { IntegerList = new List() { 1, 2, 3 } }; @@ -71,7 +71,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic [Fact] public void CopyFromListToNonList() { - var doc = new SimpleDTO() + var doc = new SimpleObject() { IntegerList = new List() { 1, 2, 3 } }; @@ -91,7 +91,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic [Fact] public void CopyFromNonListToList() { - var doc = new SimpleDTO() + var doc = new SimpleObject() { IntegerValue = 5, IntegerList = new List() { 1, 2, 3 } @@ -111,7 +111,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic [Fact] public void CopyToEndOfList() { - var doc = new SimpleDTO() + var doc = new SimpleObject() { IntegerValue = 5, IntegerList = new List() { 1, 2, 3 } @@ -132,9 +132,9 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic [Fact] public void NestedCopy() { - var doc = new SimpleDTOWithNestedDTO() + var doc = new SimpleObjectWithNestedObject() { - SimpleDTO = new SimpleDTO() + SimpleObject = new SimpleObject() { StringProperty = "A", AnotherStringProperty = "B" @@ -143,22 +143,22 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic // create patch var patchDoc = new JsonPatchDocument(); - patchDoc.Copy("SimpleDTO/StringProperty", "SimpleDTO/AnotherStringProperty"); + patchDoc.Copy("SimpleObject/StringProperty", "SimpleObject/AnotherStringProperty"); var serialized = JsonConvert.SerializeObject(patchDoc); var deserialized = JsonConvert.DeserializeObject(serialized); deserialized.ApplyTo(doc); - Assert.Equal("A", doc.SimpleDTO.AnotherStringProperty); + Assert.Equal("A", doc.SimpleObject.AnotherStringProperty); } [Fact] public void NestedCopyInList() { - var doc = new SimpleDTOWithNestedDTO() + var doc = new SimpleObjectWithNestedObject() { - SimpleDTO = new SimpleDTO() + SimpleObject = new SimpleObject() { IntegerList = new List() { 1, 2, 3 } } @@ -166,21 +166,21 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic // create patch 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 deserialized = JsonConvert.DeserializeObject(serialized); deserialized.ApplyTo(doc); - Assert.Equal(new List() { 1, 1, 2, 3 }, doc.SimpleDTO.IntegerList); + Assert.Equal(new List() { 1, 1, 2, 3 }, doc.SimpleObject.IntegerList); } [Fact] public void NestedCopyFromListToEndOfList() { - var doc = new SimpleDTOWithNestedDTO() + var doc = new SimpleObjectWithNestedObject() { - SimpleDTO = new SimpleDTO() + SimpleObject = new SimpleObject() { IntegerList = new List() { 1, 2, 3 } } @@ -188,22 +188,22 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic // create patch var patchDoc = new JsonPatchDocument(); - patchDoc.Copy("SimpleDTO/IntegerList/0", "SimpleDTO/IntegerList/-"); + patchDoc.Copy("SimpleObject/IntegerList/0", "SimpleObject/IntegerList/-"); var serialized = JsonConvert.SerializeObject(patchDoc); var deserialized = JsonConvert.DeserializeObject(serialized); deserialized.ApplyTo(doc); - Assert.Equal(new List() { 1, 2, 3, 1 }, doc.SimpleDTO.IntegerList); + Assert.Equal(new List() { 1, 2, 3, 1 }, doc.SimpleObject.IntegerList); } [Fact] public void NestedCopyFromListToNonList() { - var doc = new SimpleDTOWithNestedDTO() + var doc = new SimpleObjectWithNestedObject() { - SimpleDTO = new SimpleDTO() + SimpleObject = new SimpleObject() { IntegerList = new List() { 1, 2, 3 } } @@ -211,21 +211,21 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic // create patch var patchDoc = new JsonPatchDocument(); - patchDoc.Copy("SimpleDTO/IntegerList/0", "SimpleDTO/IntegerValue"); + patchDoc.Copy("SimpleObject/IntegerList/0", "SimpleObject/IntegerValue"); var serialized = JsonConvert.SerializeObject(patchDoc); var deserialized = JsonConvert.DeserializeObject(serialized); deserialized.ApplyTo(doc); - Assert.Equal(1, doc.SimpleDTO.IntegerValue); + Assert.Equal(1, doc.SimpleObject.IntegerValue); } [Fact] public void NestedCopyFromNonListToList() { - var doc = new SimpleDTOWithNestedDTO() + var doc = new SimpleObjectWithNestedObject() { - SimpleDTO = new SimpleDTO() + SimpleObject = new SimpleObject() { IntegerValue = 5, IntegerList = new List() { 1, 2, 3 } @@ -234,20 +234,20 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic // create patch var patchDoc = new JsonPatchDocument(); - patchDoc.Copy("SimpleDTO/IntegerValue", "SimpleDTO/IntegerList/0"); + patchDoc.Copy("SimpleObject/IntegerValue", "SimpleObject/IntegerList/0"); var serialized = JsonConvert.SerializeObject(patchDoc); var deserialized = JsonConvert.DeserializeObject(serialized); deserialized.ApplyTo(doc); - Assert.Equal(new List() { 5, 1, 2, 3 }, doc.SimpleDTO.IntegerList); + Assert.Equal(new List() { 5, 1, 2, 3 }, doc.SimpleObject.IntegerList); } [Fact] public void NestedCopyToEndOfList() { - var doc = new SimpleDTOWithNestedDTO() + var doc = new SimpleObjectWithNestedObject() { - SimpleDTO = new SimpleDTO() + SimpleObject = new SimpleObject() { IntegerValue = 5, IntegerList = new List() { 1, 2, 3 } @@ -256,13 +256,13 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic // create patch var patchDoc = new JsonPatchDocument(); - patchDoc.Copy("SimpleDTO/IntegerValue", "SimpleDTO/IntegerList/-"); + patchDoc.Copy("SimpleObject/IntegerValue", "SimpleObject/IntegerList/-"); var serialized = JsonConvert.SerializeObject(patchDoc); var deserialized = JsonConvert.DeserializeObject(serialized); deserialized.ApplyTo(doc); - Assert.Equal(new List() { 1, 2, 3, 5 }, doc.SimpleDTO.IntegerList); + Assert.Equal(new List() { 1, 2, 3, 5 }, doc.SimpleObject.IntegerList); } } } diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/InheritedObject.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/InheritedObject.cs new file mode 100644 index 0000000000..29424d591e --- /dev/null +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/InheritedObject.cs @@ -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; } + } +} \ No newline at end of file diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/MoveOperationTests.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/MoveOperationTests.cs index 0e3ea2cea0..31f58c4b82 100644 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/MoveOperationTests.cs +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/MoveOperationTests.cs @@ -6,7 +6,7 @@ using System.Dynamic; using Newtonsoft.Json; using Xunit; -namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic +namespace Microsoft.AspNetCore.JsonPatch.Internal { public class MoveOperationTests { @@ -29,7 +29,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic Assert.Equal("A", doc.AnotherStringProperty); var cont = doc as IDictionary; - cont.TryGetValue("StringProperty", out var valueFromDictionary); + cont.TryGetValue("StringProperty", out object valueFromDictionary); Assert.Null(valueFromDictionary); } @@ -60,7 +60,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic { dynamic doc = new ExpandoObject(); doc.StringProperty = "A"; - doc.SimpleDTO = new SimpleDTO() { AnotherStringProperty = "B" }; + doc.SimpleDTO = new SimpleObject() { AnotherStringProperty = "B" }; // create patch var patchDoc = new JsonPatchDocument(); @@ -74,7 +74,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic Assert.Equal("A", doc.SimpleDTO.AnotherStringProperty); var cont = doc as IDictionary; - cont.TryGetValue("StringProperty", out var valueFromDictionary); + cont.TryGetValue("StringProperty", out object valueFromDictionary); Assert.Null(valueFromDictionary); } @@ -83,7 +83,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic { dynamic doc = new ExpandoObject(); doc.StringProperty = "A"; - doc.SimpleDTO = new SimpleDTO() { AnotherStringProperty = "B" }; + doc.SimpleDTO = new SimpleObject() { AnotherStringProperty = "B" }; // create patch var patchDoc = new JsonPatchDocument(); @@ -102,7 +102,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic public void NestedMove() { dynamic doc = new ExpandoObject(); - doc.Nested = new SimpleDTO() + doc.Nested = new SimpleObject() { StringProperty = "A", AnotherStringProperty = "B" @@ -143,7 +143,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic public void NestedMoveInList() { dynamic doc = new ExpandoObject(); - doc.Nested = new SimpleDTO() + doc.Nested = new SimpleObject() { IntegerList = new List() { 1, 2, 3 } }; @@ -181,7 +181,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic public void NestedMoveFromListToEndOfList() { dynamic doc = new ExpandoObject(); - doc.Nested = new SimpleDTO() + doc.Nested = new SimpleObject() { IntegerList = new List() { 1, 2, 3 } }; @@ -220,7 +220,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic public void NestedMoveFomListToNonList() { dynamic doc = new ExpandoObject(); - doc.Nested = new SimpleDTO() + doc.Nested = new SimpleObject() { IntegerList = new List() { 1, 2, 3 } }; @@ -255,7 +255,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic deserialized.ApplyTo(doc); var cont = doc as IDictionary; - cont.TryGetValue("IntegerValue", out var valueFromDictionary); + cont.TryGetValue("IntegerValue", out object valueFromDictionary); Assert.Null(valueFromDictionary); Assert.Equal(new List() { 5, 1, 2, 3 }, doc.IntegerList); @@ -265,7 +265,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic public void NestedMoveFromNonListToList() { dynamic doc = new ExpandoObject(); - doc.Nested = new SimpleDTO() + doc.Nested = new SimpleObject() { IntegerValue = 5, IntegerList = new List() { 1, 2, 3 } @@ -311,7 +311,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic public void NestedMoveToEndOfList() { dynamic doc = new ExpandoObject(); - doc.Nested = new SimpleDTO() + doc.Nested = new SimpleObject() { IntegerValue = 5, IntegerList = new List() { 1, 2, 3 } diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/MoveTypedOperationTests.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/MoveTypedOperationTests.cs index bfd79a0ea2..4638718a59 100644 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/MoveTypedOperationTests.cs +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/MoveTypedOperationTests.cs @@ -5,14 +5,14 @@ using System.Collections.Generic; using Newtonsoft.Json; using Xunit; -namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic +namespace Microsoft.AspNetCore.JsonPatch.Internal { public class MoveTypedOperationTests { [Fact] public void Move() { - var doc = new SimpleDTO() + var doc = new SimpleObject() { StringProperty = "A", AnotherStringProperty = "B" @@ -34,7 +34,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic [Fact] public void MoveInList() { - var doc = new SimpleDTO() + var doc = new SimpleObject() { IntegerList = new List() { 1, 2, 3 } }; @@ -54,7 +54,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic [Fact] public void MoveFromListToEndOfList() { - var doc = new SimpleDTO() + var doc = new SimpleObject() { IntegerList = new List() { 1, 2, 3 } }; @@ -73,7 +73,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic [Fact] public void MoveFomListToNonList() { - var doc = new SimpleDTO() + var doc = new SimpleObject() { IntegerList = new List() { 1, 2, 3 } }; @@ -94,7 +94,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic [Fact] public void MoveFromNonListToList() { - var doc = new SimpleDTO() + var doc = new SimpleObject() { IntegerValue = 5, IntegerList = new List() { 1, 2, 3 } @@ -116,7 +116,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic [Fact] public void MoveToEndOfList() { - var doc = new SimpleDTO() + var doc = new SimpleObject() { IntegerValue = 5, IntegerList = new List() { 1, 2, 3 } diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/NestedDTO.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/NestedObject.cs similarity index 78% rename from test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/NestedDTO.cs rename to test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/NestedObject.cs index f94ad05d97..050ad3a3b4 100644 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/NestedDTO.cs +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/NestedObject.cs @@ -1,9 +1,9 @@ // 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.Test.Dynamic +namespace Microsoft.AspNetCore.JsonPatch.Internal { - public class NestedDTO + public class NestedObject { public string StringProperty { get; set; } public dynamic DynamicProperty { get; set; } diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/PatchDocumentTests.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/PatchDocumentTests.cs index e86dc8acbd..403238bf99 100644 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/PatchDocumentTests.cs +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/PatchDocumentTests.cs @@ -5,7 +5,7 @@ using Microsoft.AspNetCore.JsonPatch.Exceptions; using Newtonsoft.Json; using Xunit; -namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic +namespace Microsoft.AspNetCore.JsonPatch.Internal { public class PatchDocumentTests { @@ -51,7 +51,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic [Fact] public void NonGenericPatchDocToGenericMustSerialize() { - var doc = new SimpleDTO() + var doc = new SimpleObject() { StringProperty = "A", AnotherStringProperty = "B" @@ -61,7 +61,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic patchDoc.Copy("StringProperty", "AnotherStringProperty"); var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject>(serialized); + var deserialized = JsonConvert.DeserializeObject>(serialized); deserialized.ApplyTo(doc); @@ -71,14 +71,14 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic [Fact] public void GenericPatchDocToNonGenericMustSerialize() { - var doc = new SimpleDTO() + var doc = new SimpleObject() { StringProperty = "A", AnotherStringProperty = "B" }; - var patchDocTyped = new JsonPatchDocument(); - patchDocTyped.Copy(o => o.StringProperty, o => o.AnotherStringProperty); + var patchDocTyped = new JsonPatchDocument(); + patchDocTyped.Copy(o => o.StringProperty, o => o.AnotherStringProperty); var patchDocUntyped = new JsonPatchDocument(); patchDocUntyped.Copy("StringProperty", "AnotherStringProperty"); diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/RemoveOperationTests.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/RemoveOperationTests.cs index c8985e3a86..22707add87 100644 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/RemoveOperationTests.cs +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/RemoveOperationTests.cs @@ -7,7 +7,7 @@ using Microsoft.AspNetCore.JsonPatch.Exceptions; using Newtonsoft.Json; using Xunit; -namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic +namespace Microsoft.AspNetCore.JsonPatch.Internal { public class RemoveOperationTests { @@ -73,7 +73,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic deserialized.ApplyTo(obj); var cont = obj as IDictionary; - cont.TryGetValue("Test", out var valueFromDictionary); + cont.TryGetValue("Test", out object valueFromDictionary); Assert.Null(valueFromDictionary); } @@ -94,9 +94,11 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic { deserialized.ApplyTo(obj); }); + 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); } @@ -117,7 +119,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic deserialized.ApplyTo(obj); var cont = obj as IDictionary; - cont.TryGetValue("Test", out var valueFromDictionary); + cont.TryGetValue("Test", out object valueFromDictionary); Assert.Null(valueFromDictionary); } @@ -139,8 +141,11 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic { deserialized.ApplyTo(obj); }); + 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); } @@ -148,7 +153,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic public void NestedRemove() { dynamic doc = new ExpandoObject(); - doc.SimpleDTO = new SimpleDTO() + doc.SimpleDTO = new SimpleObject() { StringProperty = "A" }; @@ -168,14 +173,14 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic public void NestedRemove_MixedCase_ThrowsPathNotFoundException() { dynamic doc = new ExpandoObject(); - doc.SimpleDTO = new SimpleDTO() + doc.SimpleObject = new SimpleObject() { StringProperty = "A" }; // create patch var patchDoc = new JsonPatchDocument(); - patchDoc.Remove("Simpledto/stringProperty"); + patchDoc.Remove("Simpleobject/stringProperty"); var serialized = JsonConvert.SerializeObject(patchDoc); var deserialized = JsonConvert.DeserializeObject(serialized); @@ -184,10 +189,12 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic { deserialized.ApplyTo(doc); }); + Assert.Equal( - string.Format("For operation '{0}', the target location specified by path '{1}' was not found.", - "remove", - "/Simpledto/stringProperty"), + string.Format( + "For operation '{0}', the target location specified by path '{1}' was not found.", + "remove", + "/Simpleobject/stringProperty"), exception.Message); } @@ -195,7 +202,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic public void NestedRemoveFromList() { dynamic doc = new ExpandoObject(); - doc.SimpleDTO = new SimpleDTO() + doc.SimpleDTO = new SimpleObject() { IntegerList = new List() { 1, 2, 3 } }; @@ -213,10 +220,10 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic } [Fact] - public void NestedRemoveFromListMixedCase() + public void NestedRemoveFromList_MixedCase() { dynamic doc = new ExpandoObject(); - doc.SimpleDTO = new SimpleDTO() + doc.SimpleDTO = new SimpleObject() { IntegerList = new List() { 1, 2, 3 } }; @@ -237,7 +244,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic public void NestedRemoveFromListInvalidPositionTooLarge() { dynamic doc = new ExpandoObject(); - doc.SimpleDTO = new SimpleDTO() + doc.SimpleDTO = new SimpleObject() { IntegerList = new List() { 1, 2, 3 } }; @@ -262,7 +269,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic public void NestedRemoveFromListInvalidPositionTooSmall() { dynamic doc = new ExpandoObject(); - doc.SimpleDTO = new SimpleDTO() + doc.SimpleDTO = new SimpleObject() { IntegerList = new List() { 1, 2, 3 } }; @@ -287,7 +294,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic public void NestedRemoveFromEndOfList() { dynamic doc = new ExpandoObject(); - doc.SimpleDTO = new SimpleDTO() + doc.SimpleDTO = new SimpleObject() { IntegerList = new List() { 1, 2, 3 } }; diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/RemoveTypedOperationTests.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/RemoveTypedOperationTests.cs index f65b2e6342..000b049b1b 100644 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/RemoveTypedOperationTests.cs +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/RemoveTypedOperationTests.cs @@ -6,14 +6,14 @@ using Microsoft.AspNetCore.JsonPatch.Exceptions; using Newtonsoft.Json; using Xunit; -namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic +namespace Microsoft.AspNetCore.JsonPatch.Internal { public class RemoveTypedOperationTests { [Fact] public void Remove() { - var doc = new SimpleDTO() + var doc = new SimpleObject() { StringProperty = "A" }; @@ -33,7 +33,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic [Fact] public void RemoveFromList() { - var doc = new SimpleDTO() + var doc = new SimpleObject() { IntegerList = new List() { 1, 2, 3 } }; @@ -53,7 +53,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic [Fact] public void RemoveFromListInvalidPositionTooLarge() { - var doc = new SimpleDTO() + var doc = new SimpleObject() { IntegerList = new List() { 1, 2, 3 } }; @@ -77,7 +77,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic [Fact] public void RemoveFromListInvalidPositionTooSmall() { - var doc = new SimpleDTO() + var doc = new SimpleObject() { IntegerList = new List() { 1, 2, 3 } }; @@ -101,7 +101,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic [Fact] public void RemoveFromEndOfList() { - var doc = new SimpleDTO() + var doc = new SimpleObject() { IntegerList = new List() { 1, 2, 3 } }; @@ -121,9 +121,9 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic [Fact] public void NestedRemove() { - var doc = new SimpleDTOWithNestedDTO() + var doc = new SimpleObjectWithNestedObject() { - SimpleDTO = new SimpleDTO() + SimpleObject = new SimpleObject() { StringProperty = "A" } @@ -131,22 +131,22 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic // create patch var patchDoc = new JsonPatchDocument(); - patchDoc.Remove("SimpleDTO/StringProperty"); + patchDoc.Remove("SimpleObject/StringProperty"); var serialized = JsonConvert.SerializeObject(patchDoc); var deserialized = JsonConvert.DeserializeObject(serialized); deserialized.ApplyTo(doc); - Assert.Null(doc.SimpleDTO.StringProperty); + Assert.Null(doc.SimpleObject.StringProperty); } [Fact] public void NestedRemoveFromList() { - var doc = new SimpleDTOWithNestedDTO() + var doc = new SimpleObjectWithNestedObject() { - SimpleDTO = new SimpleDTO() + SimpleObject = new SimpleObject() { IntegerList = new List() { 1, 2, 3 } } @@ -154,22 +154,22 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic // create patch var patchDoc = new JsonPatchDocument(); - patchDoc.Remove("SimpleDTO/IntegerList/2"); + patchDoc.Remove("SimpleObject/IntegerList/2"); var serialized = JsonConvert.SerializeObject(patchDoc); var deserialized = JsonConvert.DeserializeObject(serialized); deserialized.ApplyTo(doc); - Assert.Equal(new List() { 1, 2 }, doc.SimpleDTO.IntegerList); + Assert.Equal(new List() { 1, 2 }, doc.SimpleObject.IntegerList); } [Fact] public void NestedRemoveFromListInvalidPositionTooLarge() { - var doc = new SimpleDTOWithNestedDTO() + var doc = new SimpleObjectWithNestedObject() { - SimpleDTO = new SimpleDTO() + SimpleObject = new SimpleObject() { IntegerList = new List() { 1, 2, 3 } } @@ -177,7 +177,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic // create patch var patchDoc = new JsonPatchDocument(); - patchDoc.Remove("SimpleDTO/IntegerList/3"); + patchDoc.Remove("SimpleObject/IntegerList/3"); var serialized = JsonConvert.SerializeObject(patchDoc); var deserialized = JsonConvert.DeserializeObject(serialized); @@ -194,9 +194,9 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic [Fact] public void NestedRemoveFromListInvalidPositionTooSmall() { - var doc = new SimpleDTOWithNestedDTO() + var doc = new SimpleObjectWithNestedObject() { - SimpleDTO = new SimpleDTO() + SimpleObject = new SimpleObject() { IntegerList = new List() { 1, 2, 3 } } @@ -204,7 +204,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic // create patch var patchDoc = new JsonPatchDocument(); - patchDoc.Remove("SimpleDTO/IntegerList/-1"); + patchDoc.Remove("SimpleObject/IntegerList/-1"); var serialized = JsonConvert.SerializeObject(patchDoc); var deserialized = JsonConvert.DeserializeObject(serialized); @@ -221,9 +221,9 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic [Fact] public void NestedRemoveFromEndOfList() { - var doc = new SimpleDTOWithNestedDTO() + var doc = new SimpleObjectWithNestedObject() { - SimpleDTO = new SimpleDTO() + SimpleObject = new SimpleObject() { IntegerList = new List() { 1, 2, 3 } } @@ -231,14 +231,14 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic // create patch var patchDoc = new JsonPatchDocument(); - patchDoc.Remove("SimpleDTO/IntegerList/-"); + patchDoc.Remove("SimpleObject/IntegerList/-"); var serialized = JsonConvert.SerializeObject(patchDoc); var deserialized = JsonConvert.DeserializeObject(serialized); deserialized.ApplyTo(doc); - Assert.Equal(new List() { 1, 2 }, doc.SimpleDTO.IntegerList); + Assert.Equal(new List() { 1, 2 }, doc.SimpleObject.IntegerList); } } } diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/ReplaceOperationTests.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/ReplaceOperationTests.cs index c5936ec1b0..88d1662e1d 100644 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/ReplaceOperationTests.cs +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/ReplaceOperationTests.cs @@ -9,21 +9,21 @@ using Newtonsoft.Json; using Newtonsoft.Json.Linq; using Xunit; -namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic +namespace Microsoft.AspNetCore.JsonPatch.Internal { public class ReplaceOperationTests { [Fact] public void ReplaceGuidTest() { - dynamic doc = new SimpleDTO() + dynamic doc = new SimpleObject() { GuidValue = Guid.NewGuid() }; var newGuid = Guid.NewGuid(); // create patch - JsonPatchDocument patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Replace("GuidValue", newGuid); // serialize & deserialize @@ -43,7 +43,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic var newGuid = Guid.NewGuid(); // create patch - JsonPatchDocument patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Replace("GuidValue", newGuid); // serialize & deserialize @@ -68,7 +68,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic var newGuid = Guid.NewGuid(); // create patch - JsonPatchDocument patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Replace("nestedobject/GuidValue", newGuid); // serialize & deserialize @@ -84,19 +84,19 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic public void ReplaceNestedObjectTest() { dynamic doc = new ExpandoObject(); - doc.SimpleDTO = new SimpleDTO() + doc.SimpleDTO = new SimpleObject() { IntegerValue = 5, IntegerList = new List() { 1, 2, 3 } }; - var newDTO = new SimpleDTO() + var newDTO = new SimpleObject() { DoubleValue = 1 }; // create patch - JsonPatchDocument patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Replace("SimpleDTO", newDTO); // serialize & deserialize @@ -117,7 +117,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic doc.IntegerList = new List() { 1, 2, 3 }; // create patch - JsonPatchDocument patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Replace("IntegerList/0", 5); var serialized = JsonConvert.SerializeObject(patchDoc); @@ -135,7 +135,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic doc.IntegerList = new List() { 1, 2, 3 }; // create patch - JsonPatchDocument patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Replace("IntegerList", new List() { 4, 5, 6 }); var serialized = JsonConvert.SerializeObject(patchDoc); @@ -150,13 +150,13 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic public void ReplaceInListInList() { dynamic doc = new ExpandoObject(); - doc.SimpleDTOList = new List() { - new SimpleDTO() { + doc.SimpleDTOList = new List() { + new SimpleObject() { IntegerList = new List(){1,2,3} }}; // create patch - JsonPatchDocument patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Replace("SimpleDTOList/0/IntegerList/0", 4); var serialized = JsonConvert.SerializeObject(patchDoc); @@ -171,13 +171,13 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic public void ReplaceInListInListAtEnd() { dynamic doc = new ExpandoObject(); - doc.SimpleDTOList = new List() { - new SimpleDTO() { + doc.SimpleDTOList = new List() { + new SimpleObject() { IntegerList = new List(){1,2,3} }}; // create patch - JsonPatchDocument patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Replace("SimpleDTOList/0/IntegerList/-", 4); var serialized = JsonConvert.SerializeObject(patchDoc); @@ -195,7 +195,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic doc.IntegerList = new List() { 1, 2, 3 }; // create patch - JsonPatchDocument patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Replace("IntegerList", new List() { 4, 5, 6 }); var serialized = JsonConvert.SerializeObject(patchDoc); @@ -213,7 +213,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic doc.IntegerList = new List() { 1, 2, 3 }; // create patch - JsonPatchDocument patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Replace("IntegerList", new Collection() { 4, 5, 6 }); var serialized = JsonConvert.SerializeObject(patchDoc); @@ -231,7 +231,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic doc.IntegerList = new List() { 1, 2, 3 }; // create patch - JsonPatchDocument patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Replace("IntegerList/-", 5); var serialized = JsonConvert.SerializeObject(patchDoc); diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/ReplaceTypedOperationTests.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/ReplaceTypedOperationTests.cs index d0bf23f487..94131ff3b5 100644 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/ReplaceTypedOperationTests.cs +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/ReplaceTypedOperationTests.cs @@ -8,21 +8,21 @@ using System.Linq; using Newtonsoft.Json; using Xunit; -namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic +namespace Microsoft.AspNetCore.JsonPatch.Internal { public class ReplaceTypedOperationTests { [Fact] public void ReplaceGuidTest() { - var doc = new SimpleDTO() + var doc = new SimpleObject() { GuidValue = Guid.NewGuid() }; var newGuid = Guid.NewGuid(); // create patch - JsonPatchDocument patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Replace("GuidValue", newGuid); // serialize & deserialize @@ -37,23 +37,23 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic [Fact] public void SerializeAndReplaceNestedObjectTest() { - var doc = new SimpleDTOWithNestedDTO() + var doc = new SimpleObjectWithNestedObject() { - SimpleDTO = new SimpleDTO() + SimpleObject = new SimpleObject() { IntegerValue = 5, IntegerList = new List() { 1, 2, 3 } } }; - var newDTO = new SimpleDTO() + var newDTO = new SimpleObject() { DoubleValue = 1 }; // create patch - JsonPatchDocument patchDoc = new JsonPatchDocument(); - patchDoc.Replace("SimpleDTO", newDTO); + var patchDoc = new JsonPatchDocument(); + patchDoc.Replace("SimpleObject", newDTO); // serialize & deserialize var serialized = JsonConvert.SerializeObject(patchDoc); @@ -61,21 +61,21 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic deserialized.ApplyTo(doc); - Assert.Equal(1, doc.SimpleDTO.DoubleValue); - Assert.Equal(0, doc.SimpleDTO.IntegerValue); - Assert.Null(doc.SimpleDTO.IntegerList); + Assert.Equal(1, doc.SimpleObject.DoubleValue); + Assert.Equal(0, doc.SimpleObject.IntegerValue); + Assert.Null(doc.SimpleObject.IntegerList); } [Fact] public void ReplaceInList() { - var doc = new SimpleDTO() + var doc = new SimpleObject() { IntegerList = new List() { 1, 2, 3 } }; // create patch - JsonPatchDocument patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Replace("IntegerList/0", 5); var serialized = JsonConvert.SerializeObject(patchDoc); @@ -89,13 +89,13 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic [Fact] public void ReplaceFullList() { - var doc = new SimpleDTO() + var doc = new SimpleObject() { IntegerList = new List() { 1, 2, 3 } }; // create patch - JsonPatchDocument patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Replace("IntegerList", new List() { 4, 5, 6 }); var serialized = JsonConvert.SerializeObject(patchDoc); @@ -109,36 +109,36 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic [Fact] public void ReplaceInListInList() { - var doc = new SimpleDTO() + var doc = new SimpleObject() { - SimpleDTOList = new List() { - new SimpleDTO() { + SimpleObjectList = new List() { + new SimpleObject() { IntegerList = new List(){1,2,3} }} }; // create patch - JsonPatchDocument patchDoc = new JsonPatchDocument(); - patchDoc.Replace("SimpleDTOList/0/IntegerList/0", 4); + var patchDoc = new JsonPatchDocument(); + patchDoc.Replace("SimpleObjectList/0/IntegerList/0", 4); var serialized = JsonConvert.SerializeObject(patchDoc); var deserialized = JsonConvert.DeserializeObject(serialized); deserialized.ApplyTo(doc); - Assert.Equal(4, doc.SimpleDTOList.First().IntegerList.First()); + Assert.Equal(4, doc.SimpleObjectList.First().IntegerList.First()); } [Fact] public void ReplaceFullListFromEnumerable() { - var doc = new SimpleDTO() + var doc = new SimpleObject() { IntegerList = new List() { 1, 2, 3 } }; // create patch - JsonPatchDocument patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Replace("IntegerList", new List() { 4, 5, 6 }); var serialized = JsonConvert.SerializeObject(patchDoc); @@ -152,13 +152,13 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic [Fact] public void ReplaceFullListWithCollection() { - var doc = new SimpleDTO() + var doc = new SimpleObject() { IntegerList = new List() { 1, 2, 3 } }; // create patch - JsonPatchDocument patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Replace("IntegerList", new Collection() { 4, 5, 6 }); var serialized = JsonConvert.SerializeObject(patchDoc); @@ -172,13 +172,13 @@ namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic [Fact] public void ReplaceAtEndOfList() { - var doc = new SimpleDTO() + var doc = new SimpleObject() { IntegerList = new List() { 1, 2, 3 } }; // create patch - JsonPatchDocument patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Replace("IntegerList/-", 5); var serialized = JsonConvert.SerializeObject(patchDoc); diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/SimpleDTOWithNestedDTO.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/SimpleDTOWithNestedDTO.cs deleted file mode 100644 index f8af4bb390..0000000000 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/SimpleDTOWithNestedDTO.cs +++ /dev/null @@ -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 ListOfSimpleDTO { get; set; } - - public SimpleDTOWithNestedDTO() - { - NestedDTO = new NestedDTO(); - SimpleDTO = new SimpleDTO(); - ListOfSimpleDTO = new List(); - } - } -} diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/SimpleDTO.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/SimpleObject.cs similarity index 81% rename from test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/SimpleDTO.cs rename to test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/SimpleObject.cs index d4bf19f75a..01a890d7be 100644 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/SimpleDTO.cs +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/SimpleObject.cs @@ -4,11 +4,11 @@ using System; using System.Collections.Generic; -namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic +namespace Microsoft.AspNetCore.JsonPatch.Internal { - public class SimpleDTO + public class SimpleObject { - public List SimpleDTOList { get; set; } + public List SimpleObjectList { get; set; } public List IntegerList { get; set; } public int IntegerValue { get; set; } public string StringProperty { get; set; } diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/SimpleObjectWithNestedObject.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/SimpleObjectWithNestedObject.cs new file mode 100644 index 0000000000..aa766b8438 --- /dev/null +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/SimpleObjectWithNestedObject.cs @@ -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 ListOfSimpleObject { get; set; } + + public SimpleObjectWithNestedObject() + { + NestedObject = new NestedObject(); + SimpleObject = new SimpleObject(); + ListOfSimpleObject = new List(); + } + } +} diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/DynamicObjectAdapterTest.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/DynamicObjectAdapterTest.cs new file mode 100644 index 0000000000..18bb7a775c --- /dev/null +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/DynamicObjectAdapterTest.cs @@ -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() { 1, 2, 3 }; + var value = new List() { "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); + } + } +} diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/DynamicTestObject.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/DynamicTestObject.cs new file mode 100644 index 0000000000..4268d5526c --- /dev/null +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/DynamicTestObject.cs @@ -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 _dictionary = new Dictionary(); + + public object this[string key] { get => ((IDictionary)_dictionary)[key]; set => ((IDictionary)_dictionary)[key] = value; } + + public ICollection Keys => ((IDictionary)_dictionary).Keys; + + public ICollection Values => ((IDictionary)_dictionary).Values; + + public int Count => ((IDictionary)_dictionary).Count; + + public bool IsReadOnly => ((IDictionary)_dictionary).IsReadOnly; + + public void Add(string key, object value) + { + ((IDictionary)_dictionary).Add(key, value); + } + + public void Add(KeyValuePair item) + { + ((IDictionary)_dictionary).Add(item); + } + + public void Clear() + { + ((IDictionary)_dictionary).Clear(); + } + + public bool Contains(KeyValuePair item) + { + return ((IDictionary)_dictionary).Contains(item); + } + + public bool ContainsKey(string key) + { + return ((IDictionary)_dictionary).ContainsKey(key); + } + + public void CopyTo(KeyValuePair[] array, int arrayIndex) + { + ((IDictionary)_dictionary).CopyTo(array, arrayIndex); + } + + public IEnumerator> GetEnumerator() + { + return ((IDictionary)_dictionary).GetEnumerator(); + } + + public bool Remove(string key) + { + return ((IDictionary)_dictionary).Remove(key); + } + + public bool Remove(KeyValuePair item) + { + return ((IDictionary)_dictionary).Remove(item); + } + + public bool TryGetValue(string key, out object value) + { + return ((IDictionary)_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; + } + } +} diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/InheritedDTO.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/InheritedObject.cs similarity index 85% rename from test/Microsoft.AspNetCore.JsonPatch.Test/InheritedDTO.cs rename to test/Microsoft.AspNetCore.JsonPatch.Test/InheritedObject.cs index a784a6304b..37b8a10dc9 100644 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/InheritedDTO.cs +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/InheritedObject.cs @@ -3,7 +3,7 @@ namespace Microsoft.AspNetCore.JsonPatch { - public class InheritedDTO : SimpleDTO + public class InheritedObject : SimpleObject { public string AdditionalStringProperty { get; set; } } diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/IntegrationTests/DynamicObjectIntegrationTests.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/IntegrationTests/DynamicObjectIntegrationTests.cs new file mode 100644 index 0000000000..4b5fc96e24 --- /dev/null +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/IntegrationTests/DynamicObjectIntegrationTests.cs @@ -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(() => + { + 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() { 1, 2, 3 } + }; + + var patchDoc = new JsonPatchDocument(); + patchDoc.Move("Nested/IntegerList/0", "Nested/IntegerValue"); + + // Act + patchDoc.ApplyTo(dynamicTestObject); + + // Assert + Assert.Equal(new List() { 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(() => + { + 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() { 1, 2, 3 } + }; + + var patchDoc = new JsonPatchDocument(); + patchDoc.Remove("SimpleObject/IntegerList/2"); + + // Act + patchDoc.ApplyTo(dynamicTestObject); + + // Assert + Assert.Equal(new List() { 1, 2 }, dynamicTestObject.SimpleObject.IntegerList); + } + + [Fact] + public void ReplaceNestedTypedObject_InDynamicObject() + { + // Arrange + dynamic dynamicTestObject = new DynamicTestObject(); + dynamicTestObject.SimpleObject = new SimpleObject() + { + IntegerValue = 5, + IntegerList = new List() { 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() { 1, 2, 3 }; + + var patchDoc = new JsonPatchDocument(); + patchDoc.Replace("IntegerList", new List() { 4, 5, 6 }); + + // Act + patchDoc.ApplyTo(dynamicTestObject); + + // Assert + Assert.Equal(new List() { 4, 5, 6 }, dynamicTestObject.IntegerList); + } + } +} diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/JsonPatchDocumentJsonPropertyAttributeTest.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/JsonPatchDocumentJsonPropertyAttributeTest.cs index efc780b388..3948b79484 100644 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/JsonPatchDocumentJsonPropertyAttributeTest.cs +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/JsonPatchDocumentJsonPropertyAttributeTest.cs @@ -14,14 +14,14 @@ namespace Microsoft.AspNetCore.JsonPatch [Fact] public void Add_WithExpression_RespectsJsonPropertyName_ForModelProperty() { - var patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Add(p => p.Name, "John"); var serialized = JsonConvert.SerializeObject(patchDoc); // serialized value should have "AnotherName" as path // deserialize to a JsonPatchDocument to check var deserialized = - JsonConvert.DeserializeObject>(serialized); + JsonConvert.DeserializeObject>(serialized); // get path var pathToCheck = deserialized.Operations.First().path; @@ -65,19 +65,19 @@ namespace Microsoft.AspNetCore.JsonPatch [Fact] public void Add_WithExpression_RespectsJsonPropertyName_WhenApplyingToDifferentlyTypedClassWithPropertyMatchingJsonPropertyName() { - var patchDocToSerialize = new JsonPatchDocument(); + var patchDocToSerialize = new JsonPatchDocument(); patchDocToSerialize.Add(p => p.Name, "John"); // the patchdoc will deserialize to "anothername". We should thus be able to apply // it to a class that HAS that other property name. - var doc = new JsonPropertyWithAnotherNameDTO() + var doc = new JsonPropertyWithAnotherNameObject() { AnotherName = "InitialValue" }; var serialized = JsonConvert.SerializeObject(patchDocToSerialize); var deserialized = - JsonConvert.DeserializeObject> + JsonConvert.DeserializeObject> (serialized); deserialized.ApplyTo(doc); @@ -88,21 +88,21 @@ namespace Microsoft.AspNetCore.JsonPatch [Fact] public void Add_WithExpression_RespectsJsonPropertyName_WhenApplyingToSameTypedClassWithMatchingJsonPropertyName() { - var patchDocToSerialize = new JsonPatchDocument(); + var patchDocToSerialize = new JsonPatchDocument(); patchDocToSerialize.Add(p => p.Name, "John"); // the patchdoc will deserialize to "anothername". As JsonPropertyDTO has // a JsonProperty signifying that "Name" should be deseriallized from "AnotherName", // we should be able to apply the patchDoc. - var doc = new JsonPropertyDTO() + var doc = new JsonPropertyObject() { Name = "InitialValue" }; var serialized = JsonConvert.SerializeObject(patchDocToSerialize); var deserialized = - JsonConvert.DeserializeObject> + JsonConvert.DeserializeObject> (serialized); deserialized.ApplyTo(doc); @@ -113,7 +113,7 @@ namespace Microsoft.AspNetCore.JsonPatch [Fact] public void Add_OnApplyFromJson_RespectsJsonPropertyNameOnJsonDocument() { - var doc = new JsonPropertyDTO() + var doc = new JsonPropertyObject() { Name = "InitialValue" }; @@ -121,7 +121,7 @@ namespace Microsoft.AspNetCore.JsonPatch // serialization should serialize to "AnotherName" var serialized = "[{\"value\":\"Kevin\",\"path\":\"/AnotherName\",\"op\":\"add\"}]"; var deserialized = - JsonConvert.DeserializeObject>(serialized); + JsonConvert.DeserializeObject>(serialized); deserialized.ApplyTo(doc); @@ -131,7 +131,7 @@ namespace Microsoft.AspNetCore.JsonPatch [Fact] public void Remove_OnApplyFromJson_RespectsJsonPropertyNameOnJsonDocument() { - var doc = new JsonPropertyDTO() + var doc = new JsonPropertyObject() { Name = "InitialValue" }; @@ -139,7 +139,7 @@ namespace Microsoft.AspNetCore.JsonPatch // serialization should serialize to "AnotherName" var serialized = "[{\"path\":\"/AnotherName\",\"op\":\"remove\"}]"; var deserialized = - JsonConvert.DeserializeObject>(serialized); + JsonConvert.DeserializeObject>(serialized); deserialized.ApplyTo(doc); @@ -149,7 +149,7 @@ namespace Microsoft.AspNetCore.JsonPatch [Fact] public void Add_OnApplyFromJson_RespectsInheritedJsonPropertyNameOnJsonDocument() { - var doc = new JsonPropertyWithInheritanceDTO() + var doc = new JsonPropertyWithInheritanceObject() { Name = "InitialName" }; @@ -157,7 +157,7 @@ namespace Microsoft.AspNetCore.JsonPatch // serialization should serialize to "AnotherName" var serialized = "[{\"value\":\"Kevin\",\"path\":\"/AnotherName\",\"op\":\"add\"}]"; var deserialized = - JsonConvert.DeserializeObject>(serialized); + JsonConvert.DeserializeObject>(serialized); deserialized.ApplyTo(doc); @@ -167,14 +167,14 @@ namespace Microsoft.AspNetCore.JsonPatch [Fact] public void Add_WithExpression_RespectsJsonPropertyName_ForInheritedModelProperty() { - var patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Add(p => p.Name, "John"); var serialized = JsonConvert.SerializeObject(patchDoc); // serialized value should have "AnotherName" as path // deserialize to a JsonPatchDocument to check var deserialized = - JsonConvert.DeserializeObject>(serialized); + JsonConvert.DeserializeObject>(serialized); // get path var pathToCheck = deserialized.Operations.First().path; @@ -184,10 +184,10 @@ namespace Microsoft.AspNetCore.JsonPatch [Fact] public void Add_OnApplyFromJson_EscapingHandledOnComplexJsonPropertyNameOnJsonDocument() { - var doc = new JsonPropertyComplexNameDTO() + var doc = new JsonPropertyComplexNameObject() { FooSlashBars = "InitialName", - FooSlashTilde = new SimpleDTO + FooSlashTilde = new SimpleObject { StringProperty = "Initial Value" } @@ -196,7 +196,7 @@ namespace Microsoft.AspNetCore.JsonPatch // 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 deserialized = - JsonConvert.DeserializeObject>(serialized); + JsonConvert.DeserializeObject>(serialized); deserialized.ApplyTo(doc); diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/JsonPropertyComplexNameDTO.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/JsonPropertyComplexNameObject.cs similarity index 78% rename from test/Microsoft.AspNetCore.JsonPatch.Test/JsonPropertyComplexNameDTO.cs rename to test/Microsoft.AspNetCore.JsonPatch.Test/JsonPropertyComplexNameObject.cs index 7ff66481ad..a39aa8e30c 100644 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/JsonPropertyComplexNameDTO.cs +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/JsonPropertyComplexNameObject.cs @@ -5,12 +5,12 @@ using Newtonsoft.Json; namespace Microsoft.AspNetCore.JsonPatch { - public class JsonPropertyComplexNameDTO + public class JsonPropertyComplexNameObject { [JsonProperty("foo/bar~")] public string FooSlashBars { get; set; } [JsonProperty("foo/~")] - public SimpleDTO FooSlashTilde { get; set; } + public SimpleObject FooSlashTilde { get; set; } } } diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/JsonPropertyDTO.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/JsonPropertyObject.cs similarity index 90% rename from test/Microsoft.AspNetCore.JsonPatch.Test/JsonPropertyDTO.cs rename to test/Microsoft.AspNetCore.JsonPatch.Test/JsonPropertyObject.cs index c926d9f5fd..245ae6bb65 100644 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/JsonPropertyDTO.cs +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/JsonPropertyObject.cs @@ -5,7 +5,7 @@ using Newtonsoft.Json; namespace Microsoft.AspNetCore.JsonPatch { - public class JsonPropertyDTO + public class JsonPropertyObject { [JsonProperty("AnotherName")] public string Name { get; set; } diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/JsonPropertyWithAnotherNameDTO.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/JsonPropertyWithAnotherNameObject.cs similarity index 84% rename from test/Microsoft.AspNetCore.JsonPatch.Test/JsonPropertyWithAnotherNameDTO.cs rename to test/Microsoft.AspNetCore.JsonPatch.Test/JsonPropertyWithAnotherNameObject.cs index 9b61e09005..4581a4826d 100644 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/JsonPropertyWithAnotherNameDTO.cs +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/JsonPropertyWithAnotherNameObject.cs @@ -3,7 +3,7 @@ namespace Microsoft.AspNetCore.JsonPatch { - public class JsonPropertyWithAnotherNameDTO + public class JsonPropertyWithAnotherNameObject { public string AnotherName { get; set; } } diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/JsonPropertyWithInheritanceDTO.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/JsonPropertyWithInheritanceDTO.cs deleted file mode 100644 index fa69425ea9..0000000000 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/JsonPropertyWithInheritanceDTO.cs +++ /dev/null @@ -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; } - } -} diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/JsonPropertyWithInheritanceObject.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/JsonPropertyWithInheritanceObject.cs new file mode 100644 index 0000000000..935ef275ad --- /dev/null +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/JsonPropertyWithInheritanceObject.cs @@ -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; } + } +} diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/ListAdapterTest.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/ListAdapterTest.cs index 6a087edd8f..3c692ea150 100644 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/ListAdapterTest.cs +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/ListAdapterTest.cs @@ -18,10 +18,9 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal var resolver = new Mock(MockBehavior.Strict); var targetObject = new[] { 20, 30 }; var listAdapter = new ListAdapter(); - string message = null; // 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.False(addStatus); @@ -41,10 +40,9 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal targetObject.Add(20); targetObject.Add(30); var listAdapter = new ListAdapter(); - string message = null; // Act - var addStatus = listAdapter.TryAdd(targetObject, "-", resolver.Object, "40", out message); + var addStatus = listAdapter.TryAdd(targetObject, "-", resolver.Object, "40", out var message); // Assert Assert.False(addStatus); @@ -62,11 +60,10 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal var resolver = new Mock(MockBehavior.Strict); var targetObject = new List() { "James", "Mike" }; var listAdapter = new ListAdapter(); - string message = null; var position = targetObject.Count.ToString(); // 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.Null(message); @@ -85,10 +82,9 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal var resolver = new Mock(MockBehavior.Strict); var targetObject = new List() { "James", "Mike" }; var listAdapter = new ListAdapter(); - string message = null; // 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.False(addStatus); @@ -106,10 +102,9 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal var resolver = new Mock(MockBehavior.Strict); var targetObject = new List() { "James", "Mike" }; var listAdapter = new ListAdapter(); - string message = null; // 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.False(addStatus); @@ -143,10 +138,9 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal // Arrange var resolver = new Mock(MockBehavior.Strict); var listAdapter = new ListAdapter(); - string message = null; // Act - var addStatus = listAdapter.TryAdd(targetObject, "-", resolver.Object, "20", out message); + var addStatus = listAdapter.TryAdd(targetObject, "-", resolver.Object, "20", out var message); // Assert Assert.True(addStatus); @@ -162,10 +156,9 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal var resolver = new Mock(MockBehavior.Strict); var listAdapter = new ListAdapter(); var targetObject = new List() { "James", "Mike" }; - string message = null; // 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.True(addStatus); @@ -178,21 +171,20 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal public void Add_CompatibleTypeWorks() { // Arrange - var sDto = new SimpleDTO(); - var iDto = new InheritedDTO(); + var sDto = new SimpleObject(); + var iDto = new InheritedObject(); var resolver = new Mock(MockBehavior.Strict); - var targetObject = new List() { sDto }; + var targetObject = new List() { sDto }; var listAdapter = new ListAdapter(); - string message = null; // Act - var addStatus = listAdapter.TryAdd(targetObject, "-", resolver.Object, iDto, out message); + var addStatus = listAdapter.TryAdd(targetObject, "-", resolver.Object, iDto, out var message); // Assert Assert.True(addStatus); Assert.True(string.IsNullOrEmpty(message), "Expected no error message"); Assert.Equal(2, targetObject.Count); - Assert.Equal(new List() { sDto, iDto }, targetObject); + Assert.Equal(new List() { sDto, iDto }, targetObject); } [Fact] @@ -202,10 +194,9 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal var resolver = new Mock(MockBehavior.Strict); var targetObject = new List() { 10, 20 }; var listAdapter = new ListAdapter(); - string message = null; // Act - var addStatus = listAdapter.TryAdd(targetObject, "-", resolver.Object, "James", out message); + var addStatus = listAdapter.TryAdd(targetObject, "-", resolver.Object, "James", out var message); // Assert Assert.False(addStatus); @@ -253,10 +244,9 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal // Arrange var resolver = new Mock(MockBehavior.Strict); var listAdapter = new ListAdapter(); - string message = null; // 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.True(addStatus); @@ -267,34 +257,34 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal public static TheoryData AddingKeepsObjectReferenceData { get { - var sDto1 = new SimpleDTO(); - var sDto2 = new SimpleDTO(); - var sDto3 = new SimpleDTO(); + var sDto1 = new SimpleObject(); + var sDto2 = new SimpleObject(); + var sDto3 = new SimpleObject(); return new TheoryData() { { - new List() { }, + new List() { }, sDto1, "-", - new List() { sDto1 } + new List() { sDto1 } }, { - new List() { sDto1, sDto2 }, + new List() { sDto1, sDto2 }, sDto3, "-", - new List() { sDto1, sDto2, sDto3 } + new List() { sDto1, sDto2, sDto3 } }, { - new List() { sDto1, sDto2 }, + new List() { sDto1, sDto2 }, sDto3, "0", - new List() { sDto3, sDto1, sDto2 } + new List() { sDto3, sDto1, sDto2 } }, { - new List() { sDto1, sDto2 }, + new List() { sDto1, sDto2 }, sDto3, "1", - new List() { sDto1, sDto3, sDto2 } + new List() { sDto1, sDto3, sDto2 } } }; } @@ -307,10 +297,9 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal // Arrange var resolver = new Mock(MockBehavior.Strict); var listAdapter = new ListAdapter(); - string message = null; // 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.True(addStatus); @@ -329,11 +318,9 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal var resolver = new Mock(MockBehavior.Strict); var targetObject = new List(input); var listAdapter = new ListAdapter(); - string message = null; - object value = null; // 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.False(getStatus); @@ -352,11 +339,9 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal var resolver = new Mock(MockBehavior.Strict); var targetObject = new List(input); var listAdapter = new ListAdapter(); - string message = null; - object value = null; // 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.True(getStatus); @@ -374,10 +359,9 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal var resolver = new Mock(MockBehavior.Strict); var targetObject = new List(input); var listAdapter = new ListAdapter(); - string message = null; // Act - var removeStatus = listAdapter.TryRemove(targetObject, position, resolver.Object, out message); + var removeStatus = listAdapter.TryRemove(targetObject, position, resolver.Object, out var message); // Assert Assert.False(removeStatus); @@ -396,10 +380,9 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal var resolver = new Mock(MockBehavior.Strict); var targetObject = new List(input); var listAdapter = new ListAdapter(); - string message = null; // Act - var removeStatus = listAdapter.TryRemove(targetObject, position, resolver.Object, out message); + var removeStatus = listAdapter.TryRemove(targetObject, position, resolver.Object, out var message); // Assert Assert.True(removeStatus); @@ -413,10 +396,9 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal var resolver = new Mock(MockBehavior.Strict); var targetObject = new List() { 10, 20 }; var listAdapter = new ListAdapter(); - string message = null; // Act - var replaceStatus = listAdapter.TryReplace(targetObject, "-", resolver.Object, "James", out message); + var replaceStatus = listAdapter.TryReplace(targetObject, "-", resolver.Object, "James", out var message); // Assert Assert.False(replaceStatus); @@ -432,10 +414,9 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal var resolver = new Mock(MockBehavior.Strict); var targetObject = new List() { 10, 20 }; var listAdapter = new ListAdapter(); - string message = null; // Act - var replaceStatus = listAdapter.TryReplace(targetObject, "-", resolver.Object, "30", out message); + var replaceStatus = listAdapter.TryReplace(targetObject, "-", resolver.Object, "30", out var message); // Assert Assert.True(replaceStatus); @@ -469,10 +450,9 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal var resolver = new Mock(MockBehavior.Strict); var targetObject = new List() { 10, 20 }; var listAdapter = new ListAdapter(); - string message = null; // 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.True(replaceStatus); diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/NestedDTO.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/NestedObject.cs similarity index 89% rename from test/Microsoft.AspNetCore.JsonPatch.Test/NestedDTO.cs rename to test/Microsoft.AspNetCore.JsonPatch.Test/NestedObject.cs index 90be5152cb..8f0927297e 100644 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/NestedDTO.cs +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/NestedObject.cs @@ -3,7 +3,7 @@ namespace Microsoft.AspNetCore.JsonPatch { - public class NestedDTO + public class NestedObject { public string StringProperty { get; set; } } diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/NestedObjectTests.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/NestedObjectTests.cs index 4aa25a3af1..a0b5bd7e3f 100644 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/NestedObjectTests.cs +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/NestedObjectTests.cs @@ -15,249 +15,249 @@ namespace Microsoft.AspNetCore.JsonPatch public void ReplacePropertyInNestedObject() { // Arrange - var doc = new SimpleDTOWithNestedDTO() + var doc = new SimpleObjectWithNestedObject() { IntegerValue = 1 }; // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Replace(o => o.NestedDTO.StringProperty, "B"); + var patchDoc = new JsonPatchDocument(); + patchDoc.Replace(o => o.NestedObject.StringProperty, "B"); // Act patchDoc.ApplyTo(doc); // Assert - Assert.Equal("B", doc.NestedDTO.StringProperty); + Assert.Equal("B", doc.NestedObject.StringProperty); } [Fact] public void ReplacePropertyInNestedObjectWithSerialization() { // Arrange - var doc = new SimpleDTOWithNestedDTO() + var doc = new SimpleObjectWithNestedObject() { IntegerValue = 1 }; // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Replace(o => o.NestedDTO.StringProperty, "B"); + var patchDoc = new JsonPatchDocument(); + patchDoc.Replace(o => o.NestedObject.StringProperty, "B"); // serialize & deserialize var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject>(serialized); + var deserialized = JsonConvert.DeserializeObject>(serialized); // Act deserialized.ApplyTo(doc); // Assert - Assert.Equal("B", doc.NestedDTO.StringProperty); + Assert.Equal("B", doc.NestedObject.StringProperty); } [Fact] public void ReplaceNestedObject() { // Arrange - var doc = new SimpleDTOWithNestedDTO() + var doc = new SimpleObjectWithNestedObject() { IntegerValue = 1 }; - var newNested = new NestedDTO() { StringProperty = "B" }; + var newNested = new NestedObject() { StringProperty = "B" }; // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Replace(o => o.NestedDTO, newNested); + var patchDoc = new JsonPatchDocument(); + patchDoc.Replace(o => o.NestedObject, newNested); // Act patchDoc.ApplyTo(doc); // Assert - Assert.Equal("B", doc.NestedDTO.StringProperty); + Assert.Equal("B", doc.NestedObject.StringProperty); } [Fact] public void ReplaceNestedObjectWithSerialization() { // Arrange - var doc = new SimpleDTOWithNestedDTO() + var doc = new SimpleObjectWithNestedObject() { IntegerValue = 1 }; - var newNested = new NestedDTO() { StringProperty = "B" }; + var newNested = new NestedObject() { StringProperty = "B" }; // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Replace(o => o.NestedDTO, newNested); + var patchDoc = new JsonPatchDocument(); + patchDoc.Replace(o => o.NestedObject, newNested); var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject>(serialized); + var deserialized = JsonConvert.DeserializeObject>(serialized); // Act deserialized.ApplyTo(doc); // Assert - Assert.Equal("B", doc.NestedDTO.StringProperty); + Assert.Equal("B", doc.NestedObject.StringProperty); } [Fact] public void AddResultsInReplace() { // Arrange - var doc = new SimpleDTOWithNestedDTO() + var doc = new SimpleObjectWithNestedObject() { - SimpleDTO = new SimpleDTO() + SimpleObject = new SimpleObject() { StringProperty = "A" } }; // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Add(o => o.SimpleDTO.StringProperty, "B"); + var patchDoc = new JsonPatchDocument(); + patchDoc.Add(o => o.SimpleObject.StringProperty, "B"); // Act patchDoc.ApplyTo(doc); // Assert - Assert.Equal("B", doc.SimpleDTO.StringProperty); + Assert.Equal("B", doc.SimpleObject.StringProperty); } [Fact] public void AddResultsInReplaceWithSerialization() { // Arrange - var doc = new SimpleDTOWithNestedDTO() + var doc = new SimpleObjectWithNestedObject() { - SimpleDTO = new SimpleDTO() + SimpleObject = new SimpleObject() { StringProperty = "A" } }; // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Add(o => o.SimpleDTO.StringProperty, "B"); + var patchDoc = new JsonPatchDocument(); + patchDoc.Add(o => o.SimpleObject.StringProperty, "B"); var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject>(serialized); + var deserialized = JsonConvert.DeserializeObject>(serialized); // Act deserialized.ApplyTo(doc); // Assert - Assert.Equal("B", doc.SimpleDTO.StringProperty); + Assert.Equal("B", doc.SimpleObject.StringProperty); } [Fact] public void AddToList() { // Arrange - var doc = new SimpleDTOWithNestedDTO() + var doc = new SimpleObjectWithNestedObject() { - SimpleDTO = new SimpleDTO() + SimpleObject = new SimpleObject() { IntegerList = new List() { 1, 2, 3 } } }; // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Add(o => o.SimpleDTO.IntegerList, 4, 0); + var patchDoc = new JsonPatchDocument(); + patchDoc.Add(o => o.SimpleObject.IntegerList, 4, 0); // Act patchDoc.ApplyTo(doc); // Assert - Assert.Equal(new List() { 4, 1, 2, 3 }, doc.SimpleDTO.IntegerList); + Assert.Equal(new List() { 4, 1, 2, 3 }, doc.SimpleObject.IntegerList); } [Fact] public void AddToListWithSerialization() { // Arrange - var doc = new SimpleDTOWithNestedDTO() + var doc = new SimpleObjectWithNestedObject() { - SimpleDTO = new SimpleDTO() + SimpleObject = new SimpleObject() { IntegerList = new List() { 1, 2, 3 } } }; // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Add(o => o.SimpleDTO.IntegerList, 4, 0); + var patchDoc = new JsonPatchDocument(); + patchDoc.Add(o => o.SimpleObject.IntegerList, 4, 0); var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject>(serialized); + var deserialized = JsonConvert.DeserializeObject>(serialized); // Act deserialized.ApplyTo(doc); // Assert - Assert.Equal(new List() { 4, 1, 2, 3 }, doc.SimpleDTO.IntegerList); + Assert.Equal(new List() { 4, 1, 2, 3 }, doc.SimpleObject.IntegerList); } [Fact] public void AddToIntegerIList() { // Arrange - var doc = new SimpleDTOWithNestedDTO() + var doc = new SimpleObjectWithNestedObject() { - SimpleDTO = new SimpleDTO() + SimpleObject = new SimpleObject() { IntegerIList = new List() { 1, 2, 3 } } }; // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Add(o => (List)o.SimpleDTO.IntegerIList, 4, 0); + var patchDoc = new JsonPatchDocument(); + patchDoc.Add(o => (List)o.SimpleObject.IntegerIList, 4, 0); // Act patchDoc.ApplyTo(doc); // Assert - Assert.Equal(new List() { 4, 1, 2, 3 }, doc.SimpleDTO.IntegerIList); + Assert.Equal(new List() { 4, 1, 2, 3 }, doc.SimpleObject.IntegerIList); } [Fact] public void AddToIntegerIListWithSerialization() { // Arrange - var doc = new SimpleDTOWithNestedDTO() + var doc = new SimpleObjectWithNestedObject() { - SimpleDTO = new SimpleDTO() + SimpleObject = new SimpleObject() { IntegerIList = new List() { 1, 2, 3 } } }; // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Add(o => (List)o.SimpleDTO.IntegerIList, 4, 0); + var patchDoc = new JsonPatchDocument(); + patchDoc.Add(o => (List)o.SimpleObject.IntegerIList, 4, 0); var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject>(serialized); + var deserialized = JsonConvert.DeserializeObject>(serialized); // Act deserialized.ApplyTo(doc); // Assert - Assert.Equal(new List() { 4, 1, 2, 3 }, doc.SimpleDTO.IntegerIList); + Assert.Equal(new List() { 4, 1, 2, 3 }, doc.SimpleObject.IntegerIList); } [Fact] public void AddToNestedIntegerIList() { // Arrange - var doc = new SimpleDTOWithNestedDTO() + var doc = new SimpleObjectWithNestedObject() { - SimpleDTOIList = new List + SimpleObjectIList = new List { - new SimpleDTO + new SimpleObject { IntegerIList = new List() { 1, 2, 3 } } @@ -265,25 +265,25 @@ namespace Microsoft.AspNetCore.JsonPatch }; // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Add(o => (List)o.SimpleDTOIList[0].IntegerIList, 4, 0); + var patchDoc = new JsonPatchDocument(); + patchDoc.Add(o => (List)o.SimpleObjectIList[0].IntegerIList, 4, 0); // Act patchDoc.ApplyTo(doc); // Assert - Assert.Equal(new List() { 4, 1, 2, 3 }, doc.SimpleDTOIList[0].IntegerIList); + Assert.Equal(new List() { 4, 1, 2, 3 }, doc.SimpleObjectIList[0].IntegerIList); } [Fact] public void AddToNestedIntegerIListWithSerialization() { // Arrange - var doc = new SimpleDTOWithNestedDTO() + var doc = new SimpleObjectWithNestedObject() { - SimpleDTOIList = new List + SimpleObjectIList = new List { - new SimpleDTO + new SimpleObject { IntegerIList = new List() { 1, 2, 3 } } @@ -291,32 +291,32 @@ namespace Microsoft.AspNetCore.JsonPatch }; // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Add(o => (List)o.SimpleDTOIList[0].IntegerIList, 4, 0); + var patchDoc = new JsonPatchDocument(); + patchDoc.Add(o => (List)o.SimpleObjectIList[0].IntegerIList, 4, 0); var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject>(serialized); + var deserialized = JsonConvert.DeserializeObject>(serialized); // Act deserialized.ApplyTo(doc); // Assert - Assert.Equal(new List() { 4, 1, 2, 3 }, doc.SimpleDTOIList[0].IntegerIList); + Assert.Equal(new List() { 4, 1, 2, 3 }, doc.SimpleObjectIList[0].IntegerIList); } [Fact] public void AddToComplextTypeListSpecifyIndex() { // Arrange - var doc = new SimpleDTOWithNestedDTO() + var doc = new SimpleObjectWithNestedObject() { - SimpleDTOList = new List() + SimpleObjectList = new List() { - new SimpleDTO + new SimpleObject { StringProperty = "String1" }, - new SimpleDTO + new SimpleObject { StringProperty = "String2" } @@ -324,29 +324,29 @@ namespace Microsoft.AspNetCore.JsonPatch }; // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Add(o => o.SimpleDTOList[0].StringProperty, "ChangedString1"); + var patchDoc = new JsonPatchDocument(); + patchDoc.Add(o => o.SimpleObjectList[0].StringProperty, "ChangedString1"); // Act patchDoc.ApplyTo(doc); // Assert - Assert.Equal("ChangedString1", doc.SimpleDTOList[0].StringProperty); + Assert.Equal("ChangedString1", doc.SimpleObjectList[0].StringProperty); } [Fact] public void AddToComplextTypeListSpecifyIndexWithSerialization() { // Arrange - var doc = new SimpleDTOWithNestedDTO() + var doc = new SimpleObjectWithNestedObject() { - SimpleDTOList = new List() + SimpleObjectList = new List() { - new SimpleDTO + new SimpleObject { StringProperty = "String1" }, - new SimpleDTO + new SimpleObject { StringProperty = "String2" } @@ -354,34 +354,34 @@ namespace Microsoft.AspNetCore.JsonPatch }; // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Add(o => o.SimpleDTOList[0].StringProperty, "ChangedString1"); + var patchDoc = new JsonPatchDocument(); + patchDoc.Add(o => o.SimpleObjectList[0].StringProperty, "ChangedString1"); var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject>(serialized); + var deserialized = JsonConvert.DeserializeObject>(serialized); // Act deserialized.ApplyTo(doc); // Assert - Assert.Equal("ChangedString1", doc.SimpleDTOList[0].StringProperty); + Assert.Equal("ChangedString1", doc.SimpleObjectList[0].StringProperty); } [Fact] public void AddToListInvalidPositionTooLarge() { // Arrange - var doc = new SimpleDTOWithNestedDTO() + var doc = new SimpleObjectWithNestedObject() { - SimpleDTO = new SimpleDTO() + SimpleObject = new SimpleObject() { IntegerList = new List() { 1, 2, 3 } } }; // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Add(o => o.SimpleDTO.IntegerList, 4, 4); + var patchDoc = new JsonPatchDocument(); + patchDoc.Add(o => o.SimpleObject.IntegerList, 4, 4); // Act & Assert var exception = Assert.Throws(() => { patchDoc.ApplyTo(doc); }); @@ -395,20 +395,20 @@ namespace Microsoft.AspNetCore.JsonPatch public void AddToListInvalidPositionTooLargeWithSerialization() { // Arrange - var doc = new SimpleDTOWithNestedDTO() + var doc = new SimpleObjectWithNestedObject() { - SimpleDTO = new SimpleDTO() + SimpleObject = new SimpleObject() { IntegerList = new List() { 1, 2, 3 } } }; // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Add(o => o.SimpleDTO.IntegerList, 4, 4); + var patchDoc = new JsonPatchDocument(); + patchDoc.Add(o => o.SimpleObject.IntegerList, 4, 4); var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject>(serialized); + var deserialized = JsonConvert.DeserializeObject>(serialized); // Act & Assert var exception = Assert.Throws(() => @@ -424,19 +424,19 @@ namespace Microsoft.AspNetCore.JsonPatch public void AddToListInvalidPositionTooLarge_LogsError() { // Arrange - var doc = new SimpleDTOWithNestedDTO() + var doc = new SimpleObjectWithNestedObject() { - SimpleDTO = new SimpleDTO() + SimpleObject = new SimpleObject() { IntegerList = new List() { 1, 2, 3 } } }; // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Add(o => o.SimpleDTO.IntegerList, 4, 4); + var patchDoc = new JsonPatchDocument(); + patchDoc.Add(o => o.SimpleObject.IntegerList, 4, 4); - var logger = new TestErrorLogger(); + var logger = new TestErrorLogger(); patchDoc.ApplyTo(doc, logger.LogErrorMessage); @@ -452,17 +452,17 @@ namespace Microsoft.AspNetCore.JsonPatch public void AddToListInvalidPositionTooSmall() { // Arrange - var doc = new SimpleDTOWithNestedDTO() + var doc = new SimpleObjectWithNestedObject() { - SimpleDTO = new SimpleDTO() + SimpleObject = new SimpleObject() { IntegerList = new List() { 1, 2, 3 } } }; // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Add(o => o.SimpleDTO.IntegerList, 4, -1); + var patchDoc = new JsonPatchDocument(); + patchDoc.Add(o => o.SimpleObject.IntegerList, 4, -1); // Act & Assert var exception = Assert.Throws(() => { patchDoc.ApplyTo(doc); }); @@ -475,20 +475,20 @@ namespace Microsoft.AspNetCore.JsonPatch public void AddToListInvalidPositionTooSmallWithSerialization() { // Arrange - var doc = new SimpleDTOWithNestedDTO() + var doc = new SimpleObjectWithNestedObject() { - SimpleDTO = new SimpleDTO() + SimpleObject = new SimpleObject() { IntegerList = new List() { 1, 2, 3 } } }; // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Add(o => o.SimpleDTO.IntegerList, 4, -1); + var patchDoc = new JsonPatchDocument(); + patchDoc.Add(o => o.SimpleObject.IntegerList, 4, -1); var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject>(serialized); + var deserialized = JsonConvert.DeserializeObject>(serialized); // Act & Assert var exception = Assert.Throws(() => @@ -504,19 +504,19 @@ namespace Microsoft.AspNetCore.JsonPatch public void AddToListInvalidPositionTooSmall_LogsError() { // Arrange - var doc = new SimpleDTOWithNestedDTO() + var doc = new SimpleObjectWithNestedObject() { - SimpleDTO = new SimpleDTO() + SimpleObject = new SimpleObject() { IntegerList = new List() { 1, 2, 3 } } }; // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Add(o => o.SimpleDTO.IntegerList, 4, -1); + var patchDoc = new JsonPatchDocument(); + patchDoc.Add(o => o.SimpleObject.IntegerList, 4, -1); - var logger = new TestErrorLogger(); + var logger = new TestErrorLogger(); patchDoc.ApplyTo(doc, logger.LogErrorMessage); @@ -532,164 +532,164 @@ namespace Microsoft.AspNetCore.JsonPatch public void AddToListAppend() { // Arrange - var doc = new SimpleDTOWithNestedDTO() + var doc = new SimpleObjectWithNestedObject() { - SimpleDTO = new SimpleDTO() + SimpleObject = new SimpleObject() { IntegerList = new List() { 1, 2, 3 } } }; // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Add(o => o.SimpleDTO.IntegerList, 4); + var patchDoc = new JsonPatchDocument(); + patchDoc.Add(o => o.SimpleObject.IntegerList, 4); // Act patchDoc.ApplyTo(doc); // Assert - Assert.Equal(new List() { 1, 2, 3, 4 }, doc.SimpleDTO.IntegerList); + Assert.Equal(new List() { 1, 2, 3, 4 }, doc.SimpleObject.IntegerList); } [Fact] public void AddToListAppendWithSerialization() { // Arrange - var doc = new SimpleDTOWithNestedDTO() + var doc = new SimpleObjectWithNestedObject() { - SimpleDTO = new SimpleDTO() + SimpleObject = new SimpleObject() { IntegerList = new List() { 1, 2, 3 } } }; // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Add(o => o.SimpleDTO.IntegerList, 4); + var patchDoc = new JsonPatchDocument(); + patchDoc.Add(o => o.SimpleObject.IntegerList, 4); var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject>(serialized); + var deserialized = JsonConvert.DeserializeObject>(serialized); // Act deserialized.ApplyTo(doc); // Assert - Assert.Equal(new List() { 1, 2, 3, 4 }, doc.SimpleDTO.IntegerList); + Assert.Equal(new List() { 1, 2, 3, 4 }, doc.SimpleObject.IntegerList); } [Fact] public void Remove() { // Arrange - var doc = new SimpleDTOWithNestedDTO() + var doc = new SimpleObjectWithNestedObject() { - SimpleDTO = new SimpleDTO() + SimpleObject = new SimpleObject() { StringProperty = "A" } }; // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Remove(o => o.SimpleDTO.StringProperty); + var patchDoc = new JsonPatchDocument(); + patchDoc.Remove(o => o.SimpleObject.StringProperty); // Act patchDoc.ApplyTo(doc); // Assert - Assert.Null(doc.SimpleDTO.StringProperty); + Assert.Null(doc.SimpleObject.StringProperty); } [Fact] public void RemoveWithSerialization() { // Arrange - var doc = new SimpleDTOWithNestedDTO() + var doc = new SimpleObjectWithNestedObject() { - SimpleDTO = new SimpleDTO() + SimpleObject = new SimpleObject() { StringProperty = "A" } }; // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Remove(o => o.SimpleDTO.StringProperty); + var patchDoc = new JsonPatchDocument(); + patchDoc.Remove(o => o.SimpleObject.StringProperty); var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject>(serialized); + var deserialized = JsonConvert.DeserializeObject>(serialized); // Act deserialized.ApplyTo(doc); // Assert - Assert.Null(doc.SimpleDTO.StringProperty); + Assert.Null(doc.SimpleObject.StringProperty); } [Fact] public void RemoveFromList() { // Arrange - var doc = new SimpleDTOWithNestedDTO() + var doc = new SimpleObjectWithNestedObject() { - SimpleDTO = new SimpleDTO() + SimpleObject = new SimpleObject() { IntegerList = new List() { 1, 2, 3 } } }; // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Remove(o => o.SimpleDTO.IntegerList, 2); + var patchDoc = new JsonPatchDocument(); + patchDoc.Remove(o => o.SimpleObject.IntegerList, 2); // Act patchDoc.ApplyTo(doc); // Assert - Assert.Equal(new List() { 1, 2 }, doc.SimpleDTO.IntegerList); + Assert.Equal(new List() { 1, 2 }, doc.SimpleObject.IntegerList); } [Fact] public void RemoveFromListWithSerialization() { // Arrange - var doc = new SimpleDTOWithNestedDTO() + var doc = new SimpleObjectWithNestedObject() { - SimpleDTO = new SimpleDTO() + SimpleObject = new SimpleObject() { IntegerList = new List() { 1, 2, 3 } } }; // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Remove(o => o.SimpleDTO.IntegerList, 2); + var patchDoc = new JsonPatchDocument(); + patchDoc.Remove(o => o.SimpleObject.IntegerList, 2); var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject>(serialized); + var deserialized = JsonConvert.DeserializeObject>(serialized); // Act deserialized.ApplyTo(doc); // Assert - Assert.Equal(new List() { 1, 2 }, doc.SimpleDTO.IntegerList); + Assert.Equal(new List() { 1, 2 }, doc.SimpleObject.IntegerList); } [Fact] public void RemoveFromListInvalidPositionTooLarge() { // Arrange - var doc = new SimpleDTOWithNestedDTO() + var doc = new SimpleObjectWithNestedObject() { - SimpleDTO = new SimpleDTO() + SimpleObject = new SimpleObject() { IntegerList = new List() { 1, 2, 3 } } }; // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Remove(o => o.SimpleDTO.IntegerList, 3); + var patchDoc = new JsonPatchDocument(); + patchDoc.Remove(o => o.SimpleObject.IntegerList, 3); // Act & Assert var exception = Assert.Throws(() => { patchDoc.ApplyTo(doc); }); @@ -702,20 +702,20 @@ namespace Microsoft.AspNetCore.JsonPatch public void RemoveFromListInvalidPositionTooLargeWithSerialization() { // Arrange - var doc = new SimpleDTOWithNestedDTO() + var doc = new SimpleObjectWithNestedObject() { - SimpleDTO = new SimpleDTO() + SimpleObject = new SimpleObject() { IntegerList = new List() { 1, 2, 3 } } }; // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Remove(o => o.SimpleDTO.IntegerList, 3); + var patchDoc = new JsonPatchDocument(); + patchDoc.Remove(o => o.SimpleObject.IntegerList, 3); var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject>(serialized); + var deserialized = JsonConvert.DeserializeObject>(serialized); // Act & Assert var exception = Assert.Throws(() => @@ -731,19 +731,19 @@ namespace Microsoft.AspNetCore.JsonPatch public void RemoveFromListInvalidPositionTooLarge_LogsError() { // Arrange - var doc = new SimpleDTOWithNestedDTO() + var doc = new SimpleObjectWithNestedObject() { - SimpleDTO = new SimpleDTO() + SimpleObject = new SimpleObject() { IntegerList = new List() { 1, 2, 3 } } }; // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Remove(o => o.SimpleDTO.IntegerList, 3); + var patchDoc = new JsonPatchDocument(); + patchDoc.Remove(o => o.SimpleObject.IntegerList, 3); - var logger = new TestErrorLogger(); + var logger = new TestErrorLogger(); patchDoc.ApplyTo(doc, logger.LogErrorMessage); @@ -757,17 +757,17 @@ namespace Microsoft.AspNetCore.JsonPatch public void RemoveFromListInvalidPositionTooSmall() { // Arrange - var doc = new SimpleDTOWithNestedDTO() + var doc = new SimpleObjectWithNestedObject() { - SimpleDTO = new SimpleDTO() + SimpleObject = new SimpleObject() { IntegerList = new List() { 1, 2, 3 } } }; // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Remove(o => o.SimpleDTO.IntegerList, -1); + var patchDoc = new JsonPatchDocument(); + patchDoc.Remove(o => o.SimpleObject.IntegerList, -1); // Act & Assert var exception = Assert.Throws(() => { patchDoc.ApplyTo(doc); }); @@ -780,20 +780,20 @@ namespace Microsoft.AspNetCore.JsonPatch public void RemoveFromListInvalidPositionTooSmallWithSerialization() { // Arrange - var doc = new SimpleDTOWithNestedDTO() + var doc = new SimpleObjectWithNestedObject() { - SimpleDTO = new SimpleDTO() + SimpleObject = new SimpleObject() { IntegerList = new List() { 1, 2, 3 } } }; // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Remove(o => o.SimpleDTO.IntegerList, -1); + var patchDoc = new JsonPatchDocument(); + patchDoc.Remove(o => o.SimpleObject.IntegerList, -1); var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject>(serialized); + var deserialized = JsonConvert.DeserializeObject>(serialized); // Act & Assert var exception = Assert.Throws(() => @@ -809,19 +809,19 @@ namespace Microsoft.AspNetCore.JsonPatch public void RemoveFromListInvalidPositionTooSmall_LogsError() { // Arrange - var doc = new SimpleDTOWithNestedDTO() + var doc = new SimpleObjectWithNestedObject() { - SimpleDTO = new SimpleDTO() + SimpleObject = new SimpleObject() { IntegerList = new List() { 1, 2, 3 } } }; // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Remove(o => o.SimpleDTO.IntegerList, -1); + var patchDoc = new JsonPatchDocument(); + patchDoc.Remove(o => o.SimpleObject.IntegerList, -1); - var logger = new TestErrorLogger(); + var logger = new TestErrorLogger(); patchDoc.ApplyTo(doc, logger.LogErrorMessage); @@ -836,58 +836,58 @@ namespace Microsoft.AspNetCore.JsonPatch public void RemoveFromEndOfList() { // Arrange - var doc = new SimpleDTOWithNestedDTO() + var doc = new SimpleObjectWithNestedObject() { - SimpleDTO = new SimpleDTO() + SimpleObject = new SimpleObject() { IntegerList = new List() { 1, 2, 3 } } }; // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Remove(o => o.SimpleDTO.IntegerList); + var patchDoc = new JsonPatchDocument(); + patchDoc.Remove(o => o.SimpleObject.IntegerList); // Act patchDoc.ApplyTo(doc); // Assert - Assert.Equal(new List() { 1, 2 }, doc.SimpleDTO.IntegerList); + Assert.Equal(new List() { 1, 2 }, doc.SimpleObject.IntegerList); } [Fact] public void RemoveFromEndOfListWithSerialization() { // Arrange - var doc = new SimpleDTOWithNestedDTO() + var doc = new SimpleObjectWithNestedObject() { - SimpleDTO = new SimpleDTO() + SimpleObject = new SimpleObject() { IntegerList = new List() { 1, 2, 3 } } }; // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Remove(o => o.SimpleDTO.IntegerList); + var patchDoc = new JsonPatchDocument(); + patchDoc.Remove(o => o.SimpleObject.IntegerList); var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject>(serialized); + var deserialized = JsonConvert.DeserializeObject>(serialized); // Act deserialized.ApplyTo(doc); // Assert - Assert.Equal(new List() { 1, 2 }, doc.SimpleDTO.IntegerList); + Assert.Equal(new List() { 1, 2 }, doc.SimpleObject.IntegerList); } [Fact] public void Replace() { // Arrange - var doc = new SimpleDTOWithNestedDTO() + var doc = new SimpleObjectWithNestedObject() { - SimpleDTO = new SimpleDTO() + SimpleObject = new SimpleObject() { StringProperty = "A", DecimalValue = 10 @@ -895,48 +895,48 @@ namespace Microsoft.AspNetCore.JsonPatch }; // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Replace(o => o.SimpleDTO.StringProperty, "B"); - patchDoc.Replace(o => o.SimpleDTO.DecimalValue, 12); + var patchDoc = new JsonPatchDocument(); + patchDoc.Replace(o => o.SimpleObject.StringProperty, "B"); + patchDoc.Replace(o => o.SimpleObject.DecimalValue, 12); // Act patchDoc.ApplyTo(doc); // Assert - Assert.Equal("B", doc.SimpleDTO.StringProperty); - Assert.Equal(12, doc.SimpleDTO.DecimalValue); + Assert.Equal("B", doc.SimpleObject.StringProperty); + Assert.Equal(12, doc.SimpleObject.DecimalValue); } [Fact] public void Replace_DTOWithNullCheck() { // Arrange - var doc = new SimpleDTOWithNestedDTOWithNullCheck() + var doc = new SimpleObjectWithNestedObjectWithNullCheck() { - SimpleDTOWithNullCheck = new SimpleDTOWithNullCheck() + SimpleObjectWithNullCheck = new SimpleObjectWithNullCheck() { StringProperty = "A" } }; // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Replace(o => o.SimpleDTOWithNullCheck.StringProperty, "B"); + var patchDoc = new JsonPatchDocument(); + patchDoc.Replace(o => o.SimpleObjectWithNullCheck.StringProperty, "B"); // Act patchDoc.ApplyTo(doc); // Assert - Assert.Equal("B", doc.SimpleDTOWithNullCheck.StringProperty); + Assert.Equal("B", doc.SimpleObjectWithNullCheck.StringProperty); } [Fact] public void ReplaceWithSerialization() { // Arrange - var doc = new SimpleDTOWithNestedDTO() + var doc = new SimpleObjectWithNestedObject() { - SimpleDTO = new SimpleDTO() + SimpleObject = new SimpleObject() { StringProperty = "A", DecimalValue = 10 @@ -944,28 +944,28 @@ namespace Microsoft.AspNetCore.JsonPatch }; // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Replace(o => o.SimpleDTO.StringProperty, "B"); - patchDoc.Replace(o => o.SimpleDTO.DecimalValue, 12); + var patchDoc = new JsonPatchDocument(); + patchDoc.Replace(o => o.SimpleObject.StringProperty, "B"); + patchDoc.Replace(o => o.SimpleObject.DecimalValue, 12); var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject>(serialized); + var deserialized = JsonConvert.DeserializeObject>(serialized); // Act deserialized.ApplyTo(doc); // Assert - Assert.Equal("B", doc.SimpleDTO.StringProperty); - Assert.Equal(12, doc.SimpleDTO.DecimalValue); + Assert.Equal("B", doc.SimpleObject.StringProperty); + Assert.Equal(12, doc.SimpleObject.DecimalValue); } [Fact] public void SerializationTests() { // Arrange - var doc = new SimpleDTOWithNestedDTO() + var doc = new SimpleObjectWithNestedObject() { - SimpleDTO = new SimpleDTO() + SimpleObject = new SimpleObject() { StringProperty = "A", DecimalValue = 10, @@ -976,288 +976,288 @@ namespace Microsoft.AspNetCore.JsonPatch }; // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Replace(o => o.SimpleDTO.StringProperty, "B"); - patchDoc.Replace(o => o.SimpleDTO.DecimalValue, 12); - patchDoc.Replace(o => o.SimpleDTO.DoubleValue, 12); - patchDoc.Replace(o => o.SimpleDTO.FloatValue, 12); - patchDoc.Replace(o => o.SimpleDTO.IntegerValue, 12); + var patchDoc = new JsonPatchDocument(); + patchDoc.Replace(o => o.SimpleObject.StringProperty, "B"); + patchDoc.Replace(o => o.SimpleObject.DecimalValue, 12); + patchDoc.Replace(o => o.SimpleObject.DoubleValue, 12); + patchDoc.Replace(o => o.SimpleObject.FloatValue, 12); + patchDoc.Replace(o => o.SimpleObject.IntegerValue, 12); // serialize & deserialize var serialized = JsonConvert.SerializeObject(patchDoc); - var deserizalized = JsonConvert.DeserializeObject>(serialized); + var deserizalized = JsonConvert.DeserializeObject>(serialized); // Act deserizalized.ApplyTo(doc); // Assert - Assert.Equal("B", doc.SimpleDTO.StringProperty); - Assert.Equal(12, doc.SimpleDTO.DecimalValue); - Assert.Equal(12, doc.SimpleDTO.DoubleValue); - Assert.Equal(12, doc.SimpleDTO.FloatValue); - Assert.Equal(12, doc.SimpleDTO.IntegerValue); + Assert.Equal("B", doc.SimpleObject.StringProperty); + Assert.Equal(12, doc.SimpleObject.DecimalValue); + Assert.Equal(12, doc.SimpleObject.DoubleValue); + Assert.Equal(12, doc.SimpleObject.FloatValue); + Assert.Equal(12, doc.SimpleObject.IntegerValue); } [Fact] public void ReplaceInList() { // Arrange - var doc = new SimpleDTOWithNestedDTO() + var doc = new SimpleObjectWithNestedObject() { - SimpleDTO = new SimpleDTO() + SimpleObject = new SimpleObject() { IntegerList = new List() { 1, 2, 3 } } }; // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Replace(o => o.SimpleDTO.IntegerList, 5, 0); + var patchDoc = new JsonPatchDocument(); + patchDoc.Replace(o => o.SimpleObject.IntegerList, 5, 0); // Act patchDoc.ApplyTo(doc); // Assert - Assert.Equal(new List() { 5, 2, 3 }, doc.SimpleDTO.IntegerList); + Assert.Equal(new List() { 5, 2, 3 }, doc.SimpleObject.IntegerList); } [Fact] public void ReplaceInListWithSerialization() { // Arrange - var doc = new SimpleDTOWithNestedDTO() + var doc = new SimpleObjectWithNestedObject() { - SimpleDTO = new SimpleDTO() + SimpleObject = new SimpleObject() { IntegerList = new List() { 1, 2, 3 } } }; // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Replace(o => o.SimpleDTO.IntegerList, 5, 0); + var patchDoc = new JsonPatchDocument(); + patchDoc.Replace(o => o.SimpleObject.IntegerList, 5, 0); var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject>(serialized); + var deserialized = JsonConvert.DeserializeObject>(serialized); // Act deserialized.ApplyTo(doc); // Assert - Assert.Equal(new List() { 5, 2, 3 }, doc.SimpleDTO.IntegerList); + Assert.Equal(new List() { 5, 2, 3 }, doc.SimpleObject.IntegerList); } [Fact] public void ReplaceFullList() { // Arrange - var doc = new SimpleDTOWithNestedDTO() + var doc = new SimpleObjectWithNestedObject() { - SimpleDTO = new SimpleDTO() + SimpleObject = new SimpleObject() { IntegerList = new List() { 1, 2, 3 } } }; // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Replace>(o => o.SimpleDTO.IntegerList, new List() { 4, 5, 6 }); + var patchDoc = new JsonPatchDocument(); + patchDoc.Replace(o => o.SimpleObject.IntegerList, new List() { 4, 5, 6 }); // Act patchDoc.ApplyTo(doc); // Arrange - Assert.Equal(new List() { 4, 5, 6 }, doc.SimpleDTO.IntegerList); + Assert.Equal(new List() { 4, 5, 6 }, doc.SimpleObject.IntegerList); } [Fact] public void ReplaceFullListWithSerialiation() { // Arrange - var doc = new SimpleDTOWithNestedDTO() + var doc = new SimpleObjectWithNestedObject() { - SimpleDTO = new SimpleDTO() + SimpleObject = new SimpleObject() { IntegerList = new List() { 1, 2, 3 } } }; // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Replace>(o => o.SimpleDTO.IntegerList, new List() { 4, 5, 6 }); + var patchDoc = new JsonPatchDocument(); + patchDoc.Replace(o => o.SimpleObject.IntegerList, new List() { 4, 5, 6 }); var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject>(serialized); + var deserialized = JsonConvert.DeserializeObject>(serialized); // Act deserialized.ApplyTo(doc); // Assert - Assert.Equal(new List() { 4, 5, 6 }, doc.SimpleDTO.IntegerList); + Assert.Equal(new List() { 4, 5, 6 }, doc.SimpleObject.IntegerList); } [Fact] public void ReplaceFullListFromEnumerable() { // Arrange - var doc = new SimpleDTOWithNestedDTO() + var doc = new SimpleObjectWithNestedObject() { - SimpleDTO = new SimpleDTO() + SimpleObject = new SimpleObject() { IntegerList = new List() { 1, 2, 3 } } }; // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Replace>(o => o.SimpleDTO.IntegerList, new List() { 4, 5, 6 }); + var patchDoc = new JsonPatchDocument(); + patchDoc.Replace>(o => o.SimpleObject.IntegerList, new List() { 4, 5, 6 }); // Act patchDoc.ApplyTo(doc); // Assert - Assert.Equal(new List() { 4, 5, 6 }, doc.SimpleDTO.IntegerList); + Assert.Equal(new List() { 4, 5, 6 }, doc.SimpleObject.IntegerList); } [Fact] public void ReplaceFullListFromEnumerableWithSerialization() { // Arrange - var doc = new SimpleDTOWithNestedDTO() + var doc = new SimpleObjectWithNestedObject() { - SimpleDTO = new SimpleDTO() + SimpleObject = new SimpleObject() { IntegerList = new List() { 1, 2, 3 } } }; // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Replace>(o => o.SimpleDTO.IntegerList, new List() { 4, 5, 6 }); + var patchDoc = new JsonPatchDocument(); + patchDoc.Replace>(o => o.SimpleObject.IntegerList, new List() { 4, 5, 6 }); var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject>(serialized); + var deserialized = JsonConvert.DeserializeObject>(serialized); // Act deserialized.ApplyTo(doc); // Assert - Assert.Equal(new List() { 4, 5, 6 }, doc.SimpleDTO.IntegerList); + Assert.Equal(new List() { 4, 5, 6 }, doc.SimpleObject.IntegerList); } [Fact] public void ReplaceFullListWithCollection() { // Arrange - var doc = new SimpleDTOWithNestedDTO() + var doc = new SimpleObjectWithNestedObject() { - SimpleDTO = new SimpleDTO() + SimpleObject = new SimpleObject() { IntegerList = new List() { 1, 2, 3 } } }; // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Replace>(o => o.SimpleDTO.IntegerList, new Collection() { 4, 5, 6 }); + var patchDoc = new JsonPatchDocument(); + patchDoc.Replace>(o => o.SimpleObject.IntegerList, new Collection() { 4, 5, 6 }); // Act patchDoc.ApplyTo(doc); // Assert - Assert.Equal(new List() { 4, 5, 6 }, doc.SimpleDTO.IntegerList); + Assert.Equal(new List() { 4, 5, 6 }, doc.SimpleObject.IntegerList); } [Fact] public void ReplaceFullListWithCollectionWithSerialization() { // Arrange - var doc = new SimpleDTOWithNestedDTO() + var doc = new SimpleObjectWithNestedObject() { - SimpleDTO = new SimpleDTO() + SimpleObject = new SimpleObject() { IntegerList = new List() { 1, 2, 3 } } }; // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Replace>(o => o.SimpleDTO.IntegerList, new Collection() { 4, 5, 6 }); + var patchDoc = new JsonPatchDocument(); + patchDoc.Replace>(o => o.SimpleObject.IntegerList, new Collection() { 4, 5, 6 }); var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject>(serialized); + var deserialized = JsonConvert.DeserializeObject>(serialized); // Act deserialized.ApplyTo(doc); // Assert - Assert.Equal(new List() { 4, 5, 6 }, doc.SimpleDTO.IntegerList); + Assert.Equal(new List() { 4, 5, 6 }, doc.SimpleObject.IntegerList); } [Fact] public void ReplaceAtEndOfList() { // Arrange - var doc = new SimpleDTOWithNestedDTO() + var doc = new SimpleObjectWithNestedObject() { - SimpleDTO = new SimpleDTO() + SimpleObject = new SimpleObject() { IntegerList = new List() { 1, 2, 3 } } }; // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Replace(o => o.SimpleDTO.IntegerList, 5); + var patchDoc = new JsonPatchDocument(); + patchDoc.Replace(o => o.SimpleObject.IntegerList, 5); // Act patchDoc.ApplyTo(doc); // Assert - Assert.Equal(new List() { 1, 2, 5 }, doc.SimpleDTO.IntegerList); + Assert.Equal(new List() { 1, 2, 5 }, doc.SimpleObject.IntegerList); } [Fact] public void ReplaceAtEndOfListWithSerialization() { // Arrange - var doc = new SimpleDTOWithNestedDTO() + var doc = new SimpleObjectWithNestedObject() { - SimpleDTO = new SimpleDTO() + SimpleObject = new SimpleObject() { IntegerList = new List() { 1, 2, 3 } } }; // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Replace(o => o.SimpleDTO.IntegerList, 5); + var patchDoc = new JsonPatchDocument(); + patchDoc.Replace(o => o.SimpleObject.IntegerList, 5); var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject>(serialized); + var deserialized = JsonConvert.DeserializeObject>(serialized); // Act deserialized.ApplyTo(doc); // Assert - Assert.Equal(new List() { 1, 2, 5 }, doc.SimpleDTO.IntegerList); + Assert.Equal(new List() { 1, 2, 5 }, doc.SimpleObject.IntegerList); } [Fact] public void ReplaceInListInvalidInvalidPositionTooLarge() { // Arrange - var doc = new SimpleDTOWithNestedDTO() + var doc = new SimpleObjectWithNestedObject() { - SimpleDTO = new SimpleDTO() + SimpleObject = new SimpleObject() { IntegerList = new List() { 1, 2, 3 } } }; // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Replace(o => o.SimpleDTO.IntegerList, 5, 3); + var patchDoc = new JsonPatchDocument(); + patchDoc.Replace(o => o.SimpleObject.IntegerList, 5, 3); // Act & Assert var exception = Assert.Throws(() => { patchDoc.ApplyTo(doc); }); @@ -1270,20 +1270,20 @@ namespace Microsoft.AspNetCore.JsonPatch public void ReplaceInListInvalidInvalidPositionTooLargeWithSerialization() { // Arrange - var doc = new SimpleDTOWithNestedDTO() + var doc = new SimpleObjectWithNestedObject() { - SimpleDTO = new SimpleDTO() + SimpleObject = new SimpleObject() { IntegerList = new List() { 1, 2, 3 } } }; // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Replace(o => o.SimpleDTO.IntegerList, 5, 3); + var patchDoc = new JsonPatchDocument(); + patchDoc.Replace(o => o.SimpleObject.IntegerList, 5, 3); var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject>(serialized); + var deserialized = JsonConvert.DeserializeObject>(serialized); // Act & Assert var exception = Assert.Throws(() => @@ -1299,19 +1299,19 @@ namespace Microsoft.AspNetCore.JsonPatch public void ReplaceInListInvalid_PositionTooLarge_LogsError() { // Arrange - var doc = new SimpleDTOWithNestedDTO() + var doc = new SimpleObjectWithNestedObject() { - SimpleDTO = new SimpleDTO() + SimpleObject = new SimpleObject() { IntegerList = new List() { 1, 2, 3 } } }; // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Replace(o => o.SimpleDTO.IntegerList, 5, 3); + var patchDoc = new JsonPatchDocument(); + patchDoc.Replace(o => o.SimpleObject.IntegerList, 5, 3); - var logger = new TestErrorLogger(); + var logger = new TestErrorLogger(); patchDoc.ApplyTo(doc, logger.LogErrorMessage); @@ -1327,17 +1327,17 @@ namespace Microsoft.AspNetCore.JsonPatch public void ReplaceInListInvalidPositionTooSmall() { // Arrange - var doc = new SimpleDTOWithNestedDTO() + var doc = new SimpleObjectWithNestedObject() { - SimpleDTO = new SimpleDTO() + SimpleObject = new SimpleObject() { IntegerList = new List() { 1, 2, 3 } } }; // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Replace(o => o.SimpleDTO.IntegerList, 5, -1); + var patchDoc = new JsonPatchDocument(); + patchDoc.Replace(o => o.SimpleObject.IntegerList, 5, -1); // Act & Assert var exception = Assert.Throws(() => { patchDoc.ApplyTo(doc); }); @@ -1350,20 +1350,20 @@ namespace Microsoft.AspNetCore.JsonPatch public void ReplaceInListInvalidPositionTooSmallWithSerialization() { // Arrange - var doc = new SimpleDTOWithNestedDTO() + var doc = new SimpleObjectWithNestedObject() { - SimpleDTO = new SimpleDTO() + SimpleObject = new SimpleObject() { IntegerList = new List() { 1, 2, 3 } } }; // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Replace(o => o.SimpleDTO.IntegerList, 5, -1); + var patchDoc = new JsonPatchDocument(); + patchDoc.Replace(o => o.SimpleObject.IntegerList, 5, -1); var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject>(serialized); + var deserialized = JsonConvert.DeserializeObject>(serialized); // Act & Assert var exception = Assert.Throws(() => { deserialized.ApplyTo(doc); }); @@ -1376,19 +1376,19 @@ namespace Microsoft.AspNetCore.JsonPatch public void ReplaceInListInvalidPositionTooSmall_LogsError() { // Arrange - var doc = new SimpleDTOWithNestedDTO() + var doc = new SimpleObjectWithNestedObject() { - SimpleDTO = new SimpleDTO() + SimpleObject = new SimpleObject() { IntegerList = new List() { 1, 2, 3 } } }; // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Replace(o => o.SimpleDTO.IntegerList, 5, -1); + var patchDoc = new JsonPatchDocument(); + patchDoc.Replace(o => o.SimpleObject.IntegerList, 5, -1); - var logger = new TestErrorLogger(); + var logger = new TestErrorLogger(); patchDoc.ApplyTo(doc, logger.LogErrorMessage); @@ -1404,9 +1404,9 @@ namespace Microsoft.AspNetCore.JsonPatch public void Copy() { // Arrange - var doc = new SimpleDTOWithNestedDTO() + var doc = new SimpleObjectWithNestedObject() { - SimpleDTO = new SimpleDTO() + SimpleObject = new SimpleObject() { StringProperty = "A", AnotherStringProperty = "B" @@ -1414,23 +1414,23 @@ namespace Microsoft.AspNetCore.JsonPatch }; // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Copy(o => o.SimpleDTO.StringProperty, o => o.SimpleDTO.AnotherStringProperty); + var patchDoc = new JsonPatchDocument(); + patchDoc.Copy(o => o.SimpleObject.StringProperty, o => o.SimpleObject.AnotherStringProperty); // Act patchDoc.ApplyTo(doc); // Assert - Assert.Equal("A", doc.SimpleDTO.AnotherStringProperty); + Assert.Equal("A", doc.SimpleObject.AnotherStringProperty); } [Fact] public void CopyWithSerialization() { // Arrange - var doc = new SimpleDTOWithNestedDTO() + var doc = new SimpleObjectWithNestedObject() { - SimpleDTO = new SimpleDTO() + SimpleObject = new SimpleObject() { StringProperty = "A", AnotherStringProperty = "B" @@ -1438,173 +1438,173 @@ namespace Microsoft.AspNetCore.JsonPatch }; // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Copy(o => o.SimpleDTO.StringProperty, o => o.SimpleDTO.AnotherStringProperty); + var patchDoc = new JsonPatchDocument(); + patchDoc.Copy(o => o.SimpleObject.StringProperty, o => o.SimpleObject.AnotherStringProperty); var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject>(serialized); + var deserialized = JsonConvert.DeserializeObject>(serialized); // Act deserialized.ApplyTo(doc); // Assert - Assert.Equal("A", doc.SimpleDTO.AnotherStringProperty); + Assert.Equal("A", doc.SimpleObject.AnotherStringProperty); } [Fact] public void CopyInList() { // Arrange - var doc = new SimpleDTOWithNestedDTO() + var doc = new SimpleObjectWithNestedObject() { - SimpleDTO = new SimpleDTO() + SimpleObject = new SimpleObject() { IntegerList = new List() { 1, 2, 3 } } }; // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Copy(o => o.SimpleDTO.IntegerList, 0, o => o.SimpleDTO.IntegerList, 1); + var patchDoc = new JsonPatchDocument(); + patchDoc.Copy(o => o.SimpleObject.IntegerList, 0, o => o.SimpleObject.IntegerList, 1); // Act patchDoc.ApplyTo(doc); // Assert - Assert.Equal(new List() { 1, 1, 2, 3 }, doc.SimpleDTO.IntegerList); + Assert.Equal(new List() { 1, 1, 2, 3 }, doc.SimpleObject.IntegerList); } [Fact] public void CopyInListWithSerialization() { // Arrange - var doc = new SimpleDTOWithNestedDTO() + var doc = new SimpleObjectWithNestedObject() { - SimpleDTO = new SimpleDTO() + SimpleObject = new SimpleObject() { IntegerList = new List() { 1, 2, 3 } } }; // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Copy(o => o.SimpleDTO.IntegerList, 0, o => o.SimpleDTO.IntegerList, 1); + var patchDoc = new JsonPatchDocument(); + patchDoc.Copy(o => o.SimpleObject.IntegerList, 0, o => o.SimpleObject.IntegerList, 1); var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject>(serialized); + var deserialized = JsonConvert.DeserializeObject>(serialized); // Act deserialized.ApplyTo(doc); // Assert - Assert.Equal(new List() { 1, 1, 2, 3 }, doc.SimpleDTO.IntegerList); + Assert.Equal(new List() { 1, 1, 2, 3 }, doc.SimpleObject.IntegerList); } [Fact] public void CopyFromListToEndOfList() { // Arrange - var doc = new SimpleDTOWithNestedDTO() + var doc = new SimpleObjectWithNestedObject() { - SimpleDTO = new SimpleDTO() + SimpleObject = new SimpleObject() { IntegerList = new List() { 1, 2, 3 } } }; // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Copy(o => o.SimpleDTO.IntegerList, 0, o => o.SimpleDTO.IntegerList); + var patchDoc = new JsonPatchDocument(); + patchDoc.Copy(o => o.SimpleObject.IntegerList, 0, o => o.SimpleObject.IntegerList); // Act patchDoc.ApplyTo(doc); // Assert - Assert.Equal(new List() { 1, 2, 3, 1 }, doc.SimpleDTO.IntegerList); + Assert.Equal(new List() { 1, 2, 3, 1 }, doc.SimpleObject.IntegerList); } [Fact] public void CopyFromListToEndOfListWithSerialization() { // Arrange - var doc = new SimpleDTOWithNestedDTO() + var doc = new SimpleObjectWithNestedObject() { - SimpleDTO = new SimpleDTO() + SimpleObject = new SimpleObject() { IntegerList = new List() { 1, 2, 3 } } }; // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Copy(o => o.SimpleDTO.IntegerList, 0, o => o.SimpleDTO.IntegerList); + var patchDoc = new JsonPatchDocument(); + patchDoc.Copy(o => o.SimpleObject.IntegerList, 0, o => o.SimpleObject.IntegerList); var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject>(serialized); + var deserialized = JsonConvert.DeserializeObject>(serialized); // Act deserialized.ApplyTo(doc); // Assert - Assert.Equal(new List() { 1, 2, 3, 1 }, doc.SimpleDTO.IntegerList); + Assert.Equal(new List() { 1, 2, 3, 1 }, doc.SimpleObject.IntegerList); } [Fact] public void CopyFromListToNonList() { // Arrange - var doc = new SimpleDTOWithNestedDTO() + var doc = new SimpleObjectWithNestedObject() { - SimpleDTO = new SimpleDTO() + SimpleObject = new SimpleObject() { IntegerList = new List() { 1, 2, 3 } } }; // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Copy(o => o.SimpleDTO.IntegerList, 0, o => o.SimpleDTO.IntegerValue); + var patchDoc = new JsonPatchDocument(); + patchDoc.Copy(o => o.SimpleObject.IntegerList, 0, o => o.SimpleObject.IntegerValue); // Act patchDoc.ApplyTo(doc); // Assert - Assert.Equal(1, doc.SimpleDTO.IntegerValue); + Assert.Equal(1, doc.SimpleObject.IntegerValue); } [Fact] public void CopyFromListToNonListWithSerialization() { // Arrange - var doc = new SimpleDTOWithNestedDTO() + var doc = new SimpleObjectWithNestedObject() { - SimpleDTO = new SimpleDTO() + SimpleObject = new SimpleObject() { IntegerList = new List() { 1, 2, 3 } } }; // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Copy(o => o.SimpleDTO.IntegerList, 0, o => o.SimpleDTO.IntegerValue); + var patchDoc = new JsonPatchDocument(); + patchDoc.Copy(o => o.SimpleObject.IntegerList, 0, o => o.SimpleObject.IntegerValue); var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject>(serialized); + var deserialized = JsonConvert.DeserializeObject>(serialized); // Act deserialized.ApplyTo(doc); // Assert - Assert.Equal(1, doc.SimpleDTO.IntegerValue); + Assert.Equal(1, doc.SimpleObject.IntegerValue); } [Fact] public void CopyFromNonListToList() { // Arrange - var doc = new SimpleDTOWithNestedDTO() + var doc = new SimpleObjectWithNestedObject() { - SimpleDTO = new SimpleDTO() + SimpleObject = new SimpleObject() { IntegerValue = 5, IntegerList = new List() { 1, 2, 3 } @@ -1612,23 +1612,23 @@ namespace Microsoft.AspNetCore.JsonPatch }; // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Copy(o => o.SimpleDTO.IntegerValue, o => o.SimpleDTO.IntegerList, 0); + var patchDoc = new JsonPatchDocument(); + patchDoc.Copy(o => o.SimpleObject.IntegerValue, o => o.SimpleObject.IntegerList, 0); // Act patchDoc.ApplyTo(doc); // Assert - Assert.Equal(new List() { 5, 1, 2, 3 }, doc.SimpleDTO.IntegerList); + Assert.Equal(new List() { 5, 1, 2, 3 }, doc.SimpleObject.IntegerList); } [Fact] public void CopyFromNonListToListWithSerialization() { // Arrange - var doc = new SimpleDTOWithNestedDTO() + var doc = new SimpleObjectWithNestedObject() { - SimpleDTO = new SimpleDTO() + SimpleObject = new SimpleObject() { IntegerValue = 5, IntegerList = new List() { 1, 2, 3 } @@ -1636,25 +1636,25 @@ namespace Microsoft.AspNetCore.JsonPatch }; // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Copy(o => o.SimpleDTO.IntegerValue, o => o.SimpleDTO.IntegerList, 0); + var patchDoc = new JsonPatchDocument(); + patchDoc.Copy(o => o.SimpleObject.IntegerValue, o => o.SimpleObject.IntegerList, 0); var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject>(serialized); + var deserialized = JsonConvert.DeserializeObject>(serialized); // Act deserialized.ApplyTo(doc); // Assert - Assert.Equal(new List() { 5, 1, 2, 3 }, doc.SimpleDTO.IntegerList); + Assert.Equal(new List() { 5, 1, 2, 3 }, doc.SimpleObject.IntegerList); } [Fact] public void CopyToEndOfList() { // Arrange - var doc = new SimpleDTOWithNestedDTO() + var doc = new SimpleObjectWithNestedObject() { - SimpleDTO = new SimpleDTO() + SimpleObject = new SimpleObject() { IntegerValue = 5, IntegerList = new List() { 1, 2, 3 } @@ -1662,23 +1662,23 @@ namespace Microsoft.AspNetCore.JsonPatch }; // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Copy(o => o.SimpleDTO.IntegerValue, o => o.SimpleDTO.IntegerList); + var patchDoc = new JsonPatchDocument(); + patchDoc.Copy(o => o.SimpleObject.IntegerValue, o => o.SimpleObject.IntegerList); // Act patchDoc.ApplyTo(doc); // Assert - Assert.Equal(new List() { 1, 2, 3, 5 }, doc.SimpleDTO.IntegerList); + Assert.Equal(new List() { 1, 2, 3, 5 }, doc.SimpleObject.IntegerList); } [Fact] public void CopyToEndOfListWithSerialization() { // Arrange - var doc = new SimpleDTOWithNestedDTO() + var doc = new SimpleObjectWithNestedObject() { - SimpleDTO = new SimpleDTO() + SimpleObject = new SimpleObject() { IntegerValue = 5, IntegerList = new List() { 1, 2, 3 } @@ -1686,31 +1686,31 @@ namespace Microsoft.AspNetCore.JsonPatch }; // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Copy(o => o.SimpleDTO.IntegerValue, o => o.SimpleDTO.IntegerList); + var patchDoc = new JsonPatchDocument(); + patchDoc.Copy(o => o.SimpleObject.IntegerValue, o => o.SimpleObject.IntegerList); var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject>(serialized); + var deserialized = JsonConvert.DeserializeObject>(serialized); // Act deserialized.ApplyTo(doc); // Assert - Assert.Equal(new List() { 1, 2, 3, 5 }, doc.SimpleDTO.IntegerList); + Assert.Equal(new List() { 1, 2, 3, 5 }, doc.SimpleObject.IntegerList); } [Fact] public void Copy_DeepClonesObject() { // Arrange - var doc = new SimpleDTOWithNestedDTO() + var doc = new SimpleObjectWithNestedObject() { - SimpleDTO = new SimpleDTO() + SimpleObject = new SimpleObject() { StringProperty = "A", AnotherStringProperty = "B" }, - InheritedDTO = new InheritedDTO() + InheritedObject = new InheritedObject() { StringProperty = "C", AnotherStringProperty = "D" @@ -1718,69 +1718,69 @@ namespace Microsoft.AspNetCore.JsonPatch }; // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Copy(o => o.InheritedDTO, o => o.SimpleDTO); + var patchDoc = new JsonPatchDocument(); + patchDoc.Copy(o => o.InheritedObject, o => o.SimpleObject); // Act patchDoc.ApplyTo(doc); // Assert - Assert.Equal("C", doc.SimpleDTO.StringProperty); - Assert.Equal("D", doc.SimpleDTO.AnotherStringProperty); - Assert.Equal("C", doc.InheritedDTO.StringProperty); - Assert.Equal("D", doc.InheritedDTO.AnotherStringProperty); - Assert.NotSame(doc.SimpleDTO.StringProperty, doc.InheritedDTO.StringProperty); + Assert.Equal("C", doc.SimpleObject.StringProperty); + Assert.Equal("D", doc.SimpleObject.AnotherStringProperty); + Assert.Equal("C", doc.InheritedObject.StringProperty); + Assert.Equal("D", doc.InheritedObject.AnotherStringProperty); + Assert.NotSame(doc.SimpleObject.StringProperty, doc.InheritedObject.StringProperty); } [Fact] public void Copy_KeepsObjectType() { // Arrange - var doc = new SimpleDTOWithNestedDTO() + var doc = new SimpleObjectWithNestedObject() { - SimpleDTO = new SimpleDTO(), - InheritedDTO = new InheritedDTO() + SimpleObject = new SimpleObject(), + InheritedObject = new InheritedObject() }; // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Copy(o => o.InheritedDTO, o => o.SimpleDTO); + var patchDoc = new JsonPatchDocument(); + patchDoc.Copy(o => o.InheritedObject, o => o.SimpleObject); // Act patchDoc.ApplyTo(doc); // Assert - Assert.Equal(typeof(InheritedDTO), doc.SimpleDTO.GetType()); + Assert.Equal(typeof(InheritedObject), doc.SimpleObject.GetType()); } [Fact] public void Copy_BreaksObjectReference() { // Arrange - var doc = new SimpleDTOWithNestedDTO() + var doc = new SimpleObjectWithNestedObject() { - SimpleDTO = new SimpleDTO(), - InheritedDTO = new InheritedDTO() + SimpleObject = new SimpleObject(), + InheritedObject = new InheritedObject() }; // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Copy(o => o.InheritedDTO, o => o.SimpleDTO); + var patchDoc = new JsonPatchDocument(); + patchDoc.Copy(o => o.InheritedObject, o => o.SimpleObject); // Act patchDoc.ApplyTo(doc); // Assert - Assert.NotSame(doc.SimpleDTO, doc.InheritedDTO); + Assert.NotSame(doc.SimpleObject, doc.InheritedObject); } [Fact] public void Move() { // Arrange - var doc = new SimpleDTOWithNestedDTO() + var doc = new SimpleObjectWithNestedObject() { - SimpleDTO = new SimpleDTO() + SimpleObject = new SimpleObject() { StringProperty = "A", AnotherStringProperty = "B" @@ -1788,24 +1788,24 @@ namespace Microsoft.AspNetCore.JsonPatch }; // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Move(o => o.SimpleDTO.StringProperty, o => o.SimpleDTO.AnotherStringProperty); + var patchDoc = new JsonPatchDocument(); + patchDoc.Move(o => o.SimpleObject.StringProperty, o => o.SimpleObject.AnotherStringProperty); // Act patchDoc.ApplyTo(doc); // Assert - Assert.Equal("A", doc.SimpleDTO.AnotherStringProperty); - Assert.Null(doc.SimpleDTO.StringProperty); + Assert.Equal("A", doc.SimpleObject.AnotherStringProperty); + Assert.Null(doc.SimpleObject.StringProperty); } [Fact] public void MoveWithSerialization() { // Arrange - var doc = new SimpleDTOWithNestedDTO() + var doc = new SimpleObjectWithNestedObject() { - SimpleDTO = new SimpleDTO() + SimpleObject = new SimpleObject() { StringProperty = "A", AnotherStringProperty = "B" @@ -1813,150 +1813,150 @@ namespace Microsoft.AspNetCore.JsonPatch }; // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Move(o => o.SimpleDTO.StringProperty, o => o.SimpleDTO.AnotherStringProperty); + var patchDoc = new JsonPatchDocument(); + patchDoc.Move(o => o.SimpleObject.StringProperty, o => o.SimpleObject.AnotherStringProperty); var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject>(serialized); + var deserialized = JsonConvert.DeserializeObject>(serialized); // Act deserialized.ApplyTo(doc); // Assert - Assert.Equal("A", doc.SimpleDTO.AnotherStringProperty); - Assert.Null(doc.SimpleDTO.StringProperty); + Assert.Equal("A", doc.SimpleObject.AnotherStringProperty); + Assert.Null(doc.SimpleObject.StringProperty); } [Fact] public void Move_KeepsObjectReference() { // Arrange - var sDto = new SimpleDTO() + var sDto = new SimpleObject() { StringProperty = "A", AnotherStringProperty = "B" }; - var iDto = new InheritedDTO() + var iDto = new InheritedObject() { StringProperty = "C", AnotherStringProperty = "D" }; - var doc = new SimpleDTOWithNestedDTO() + var doc = new SimpleObjectWithNestedObject() { - SimpleDTO = sDto, - InheritedDTO = iDto + SimpleObject = sDto, + InheritedObject = iDto }; // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Move(o => o.InheritedDTO, o => o.SimpleDTO); + var patchDoc = new JsonPatchDocument(); + patchDoc.Move(o => o.InheritedObject, o => o.SimpleObject); // Act patchDoc.ApplyTo(doc); // Assert - Assert.Equal("C", doc.SimpleDTO.StringProperty); - Assert.Equal("D", doc.SimpleDTO.AnotherStringProperty); - Assert.Same(iDto, doc.SimpleDTO); - Assert.Null(doc.InheritedDTO); + Assert.Equal("C", doc.SimpleObject.StringProperty); + Assert.Equal("D", doc.SimpleObject.AnotherStringProperty); + Assert.Same(iDto, doc.SimpleObject); + Assert.Null(doc.InheritedObject); } [Fact] public void Move_KeepsObjectReferenceWithSerialization() { // Arrange - var sDto = new SimpleDTO() + var sDto = new SimpleObject() { StringProperty = "A", AnotherStringProperty = "B" }; - var iDto = new InheritedDTO() + var iDto = new InheritedObject() { StringProperty = "C", AnotherStringProperty = "D" }; - var doc = new SimpleDTOWithNestedDTO() + var doc = new SimpleObjectWithNestedObject() { - SimpleDTO = sDto, - InheritedDTO = iDto + SimpleObject = sDto, + InheritedObject = iDto }; // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Move(o => o.InheritedDTO, o => o.SimpleDTO); + var patchDoc = new JsonPatchDocument(); + patchDoc.Move(o => o.InheritedObject, o => o.SimpleObject); var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject>(serialized); + var deserialized = JsonConvert.DeserializeObject>(serialized); // Act deserialized.ApplyTo(doc); // Assert - Assert.Equal("C", doc.SimpleDTO.StringProperty); - Assert.Equal("D", doc.SimpleDTO.AnotherStringProperty); - Assert.Same(iDto, doc.SimpleDTO); - Assert.Null(doc.InheritedDTO); + Assert.Equal("C", doc.SimpleObject.StringProperty); + Assert.Equal("D", doc.SimpleObject.AnotherStringProperty); + Assert.Same(iDto, doc.SimpleObject); + Assert.Null(doc.InheritedObject); } [Fact] public void MoveInList() { // Arrange - var doc = new SimpleDTOWithNestedDTO() + var doc = new SimpleObjectWithNestedObject() { - SimpleDTO = new SimpleDTO() + SimpleObject = new SimpleObject() { IntegerList = new List() { 1, 2, 3 } } }; // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Move(o => o.SimpleDTO.IntegerList, 0, o => o.SimpleDTO.IntegerList, 1); + var patchDoc = new JsonPatchDocument(); + patchDoc.Move(o => o.SimpleObject.IntegerList, 0, o => o.SimpleObject.IntegerList, 1); // Act patchDoc.ApplyTo(doc); // Assert - Assert.Equal(new List() { 2, 1, 3 }, doc.SimpleDTO.IntegerList); + Assert.Equal(new List() { 2, 1, 3 }, doc.SimpleObject.IntegerList); } [Fact] public void MoveInListWithSerialization() { // Arrange - var doc = new SimpleDTOWithNestedDTO() + var doc = new SimpleObjectWithNestedObject() { - SimpleDTO = new SimpleDTO() + SimpleObject = new SimpleObject() { IntegerList = new List() { 1, 2, 3 } } }; // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Move(o => o.SimpleDTO.IntegerList, 0, o => o.SimpleDTO.IntegerList, 1); + var patchDoc = new JsonPatchDocument(); + patchDoc.Move(o => o.SimpleObject.IntegerList, 0, o => o.SimpleObject.IntegerList, 1); var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject>(serialized); + var deserialized = JsonConvert.DeserializeObject>(serialized); // Act deserialized.ApplyTo(doc); // Assert - Assert.Equal(new List() { 2, 1, 3 }, doc.SimpleDTO.IntegerList); + Assert.Equal(new List() { 2, 1, 3 }, doc.SimpleObject.IntegerList); } [Fact] public void Move_KeepsObjectReferenceInList() { // Arrange - var sDto1 = new SimpleDTO() { IntegerValue = 1 }; - var sDto2 = new SimpleDTO() { IntegerValue = 2 }; - var sDto3 = new SimpleDTO() { IntegerValue = 3 }; - var doc = new SimpleDTOWithNestedDTO() + var sDto1 = new SimpleObject() { IntegerValue = 1 }; + var sDto2 = new SimpleObject() { IntegerValue = 2 }; + var sDto3 = new SimpleObject() { IntegerValue = 3 }; + var doc = new SimpleObjectWithNestedObject() { - SimpleDTOList = new List() { + SimpleObjectList = new List() { sDto1, sDto2, sDto3 @@ -1964,30 +1964,30 @@ namespace Microsoft.AspNetCore.JsonPatch }; // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Move(o => o.SimpleDTOList, 0, o => o.SimpleDTOList, 1); + var patchDoc = new JsonPatchDocument(); + patchDoc.Move(o => o.SimpleObjectList, 0, o => o.SimpleObjectList, 1); // Act patchDoc.ApplyTo(doc); // Assert - Assert.Equal(new List() { sDto2, sDto1, sDto3 }, doc.SimpleDTOList); - Assert.Equal(2, doc.SimpleDTOList[0].IntegerValue); - Assert.Equal(1, doc.SimpleDTOList[1].IntegerValue); - Assert.Same(sDto2, doc.SimpleDTOList[0]); - Assert.Same(sDto1, doc.SimpleDTOList[1]); + Assert.Equal(new List() { sDto2, sDto1, sDto3 }, doc.SimpleObjectList); + Assert.Equal(2, doc.SimpleObjectList[0].IntegerValue); + Assert.Equal(1, doc.SimpleObjectList[1].IntegerValue); + Assert.Same(sDto2, doc.SimpleObjectList[0]); + Assert.Same(sDto1, doc.SimpleObjectList[1]); } [Fact] public void Move_KeepsObjectReferenceInListWithSerialization() { // Arrange - var sDto1 = new SimpleDTO() { IntegerValue = 1 }; - var sDto2 = new SimpleDTO() { IntegerValue = 2 }; - var sDto3 = new SimpleDTO() { IntegerValue = 3 }; - var doc = new SimpleDTOWithNestedDTO() + var sDto1 = new SimpleObject() { IntegerValue = 1 }; + var sDto2 = new SimpleObject() { IntegerValue = 2 }; + var sDto3 = new SimpleObject() { IntegerValue = 3 }; + var doc = new SimpleObjectWithNestedObject() { - SimpleDTOList = new List() { + SimpleObjectList = new List() { sDto1, sDto2, sDto3 @@ -1995,144 +1995,144 @@ namespace Microsoft.AspNetCore.JsonPatch }; // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Move(o => o.SimpleDTOList, 0, o => o.SimpleDTOList, 1); + var patchDoc = new JsonPatchDocument(); + patchDoc.Move(o => o.SimpleObjectList, 0, o => o.SimpleObjectList, 1); var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject>(serialized); + var deserialized = JsonConvert.DeserializeObject>(serialized); // Act patchDoc.ApplyTo(doc); // Assert - Assert.Equal(new List() { sDto2, sDto1, sDto3 }, doc.SimpleDTOList); - Assert.Equal(2, doc.SimpleDTOList[0].IntegerValue); - Assert.Equal(1, doc.SimpleDTOList[1].IntegerValue); - Assert.Same(sDto2, doc.SimpleDTOList[0]); - Assert.Same(sDto1, doc.SimpleDTOList[1]); + Assert.Equal(new List() { sDto2, sDto1, sDto3 }, doc.SimpleObjectList); + Assert.Equal(2, doc.SimpleObjectList[0].IntegerValue); + Assert.Equal(1, doc.SimpleObjectList[1].IntegerValue); + Assert.Same(sDto2, doc.SimpleObjectList[0]); + Assert.Same(sDto1, doc.SimpleObjectList[1]); } [Fact] public void MoveFromListToEndOfList() { // Arrange - var doc = new SimpleDTOWithNestedDTO() + var doc = new SimpleObjectWithNestedObject() { - SimpleDTO = new SimpleDTO() + SimpleObject = new SimpleObject() { IntegerList = new List() { 1, 2, 3 } } }; // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Move(o => o.SimpleDTO.IntegerList, 0, o => o.SimpleDTO.IntegerList); + var patchDoc = new JsonPatchDocument(); + patchDoc.Move(o => o.SimpleObject.IntegerList, 0, o => o.SimpleObject.IntegerList); // Act patchDoc.ApplyTo(doc); // Assert - Assert.Equal(new List() { 2, 3, 1 }, doc.SimpleDTO.IntegerList); + Assert.Equal(new List() { 2, 3, 1 }, doc.SimpleObject.IntegerList); } [Fact] public void MoveFromListToEndOfListWithSerialization() { // Arrange - var doc = new SimpleDTOWithNestedDTO() + var doc = new SimpleObjectWithNestedObject() { - SimpleDTO = new SimpleDTO() + SimpleObject = new SimpleObject() { IntegerList = new List() { 1, 2, 3 } } }; // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Move(o => o.SimpleDTO.IntegerList, 0, o => o.SimpleDTO.IntegerList); + var patchDoc = new JsonPatchDocument(); + patchDoc.Move(o => o.SimpleObject.IntegerList, 0, o => o.SimpleObject.IntegerList); var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject>(serialized); + var deserialized = JsonConvert.DeserializeObject>(serialized); // Act deserialized.ApplyTo(doc); // Assert - Assert.Equal(new List() { 2, 3, 1 }, doc.SimpleDTO.IntegerList); + Assert.Equal(new List() { 2, 3, 1 }, doc.SimpleObject.IntegerList); } [Fact] public void MoveFomListToNonList() { // Arrange - var doc = new SimpleDTOWithNestedDTO() + var doc = new SimpleObjectWithNestedObject() { - SimpleDTO = new SimpleDTO() + SimpleObject = new SimpleObject() { IntegerList = new List() { 1, 2, 3 } } }; // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Move(o => o.SimpleDTO.IntegerList, 0, o => o.SimpleDTO.IntegerValue); + var patchDoc = new JsonPatchDocument(); + patchDoc.Move(o => o.SimpleObject.IntegerList, 0, o => o.SimpleObject.IntegerValue); // Act patchDoc.ApplyTo(doc); // Assert - Assert.Equal(new List() { 2, 3 }, doc.SimpleDTO.IntegerList); - Assert.Equal(1, doc.SimpleDTO.IntegerValue); + Assert.Equal(new List() { 2, 3 }, doc.SimpleObject.IntegerList); + Assert.Equal(1, doc.SimpleObject.IntegerValue); } [Fact] public void MoveFomListToNonListWithSerialization() { // Arrange - var doc = new SimpleDTOWithNestedDTO() + var doc = new SimpleObjectWithNestedObject() { - SimpleDTO = new SimpleDTO() + SimpleObject = new SimpleObject() { IntegerList = new List() { 1, 2, 3 } } }; // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Move(o => o.SimpleDTO.IntegerList, 0, o => o.SimpleDTO.IntegerValue); + var patchDoc = new JsonPatchDocument(); + patchDoc.Move(o => o.SimpleObject.IntegerList, 0, o => o.SimpleObject.IntegerValue); var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject>(serialized); + var deserialized = JsonConvert.DeserializeObject>(serialized); // Act deserialized.ApplyTo(doc); // Assert - Assert.Equal(new List() { 2, 3 }, doc.SimpleDTO.IntegerList); - Assert.Equal(1, doc.SimpleDTO.IntegerValue); + Assert.Equal(new List() { 2, 3 }, doc.SimpleObject.IntegerList); + Assert.Equal(1, doc.SimpleObject.IntegerValue); } [Fact] public void MoveFomListToNonListBetweenHierarchy() { // Arrange - var doc = new SimpleDTOWithNestedDTO() + var doc = new SimpleObjectWithNestedObject() { - SimpleDTO = new SimpleDTO() + SimpleObject = new SimpleObject() { IntegerList = new List() { 1, 2, 3 } } }; // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Move(o => o.SimpleDTO.IntegerList, 0, o => o.IntegerValue); + var patchDoc = new JsonPatchDocument(); + patchDoc.Move(o => o.SimpleObject.IntegerList, 0, o => o.IntegerValue); // Act patchDoc.ApplyTo(doc); // Assert - Assert.Equal(new List() { 2, 3 }, doc.SimpleDTO.IntegerList); + Assert.Equal(new List() { 2, 3 }, doc.SimpleObject.IntegerList); Assert.Equal(1, doc.IntegerValue); } @@ -2140,26 +2140,26 @@ namespace Microsoft.AspNetCore.JsonPatch public void MoveFomListToNonListBetweenHierarchyWithSerialization() { // Arrange - var doc = new SimpleDTOWithNestedDTO() + var doc = new SimpleObjectWithNestedObject() { - SimpleDTO = new SimpleDTO() + SimpleObject = new SimpleObject() { IntegerList = new List() { 1, 2, 3 } } }; // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Move(o => o.SimpleDTO.IntegerList, 0, o => o.IntegerValue); + var patchDoc = new JsonPatchDocument(); + patchDoc.Move(o => o.SimpleObject.IntegerList, 0, o => o.IntegerValue); var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject>(serialized); + var deserialized = JsonConvert.DeserializeObject>(serialized); // Act deserialized.ApplyTo(doc); // Assert - Assert.Equal(new List() { 2, 3 }, doc.SimpleDTO.IntegerList); + Assert.Equal(new List() { 2, 3 }, doc.SimpleObject.IntegerList); Assert.Equal(1, doc.IntegerValue); } @@ -2167,9 +2167,9 @@ namespace Microsoft.AspNetCore.JsonPatch public void MoveFromNonListToList() { // Arrange - var doc = new SimpleDTOWithNestedDTO() + var doc = new SimpleObjectWithNestedObject() { - SimpleDTO = new SimpleDTO() + SimpleObject = new SimpleObject() { IntegerValue = 5, IntegerList = new List() { 1, 2, 3 } @@ -2177,24 +2177,24 @@ namespace Microsoft.AspNetCore.JsonPatch }; // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Move(o => o.SimpleDTO.IntegerValue, o => o.SimpleDTO.IntegerList, 0); + var patchDoc = new JsonPatchDocument(); + patchDoc.Move(o => o.SimpleObject.IntegerValue, o => o.SimpleObject.IntegerList, 0); // Act patchDoc.ApplyTo(doc); // Assert Assert.Equal(0, doc.IntegerValue); - Assert.Equal(new List() { 5, 1, 2, 3 }, doc.SimpleDTO.IntegerList); + Assert.Equal(new List() { 5, 1, 2, 3 }, doc.SimpleObject.IntegerList); } [Fact] public void MoveFromNonListToListWithSerialization() { // Arrange - var doc = new SimpleDTOWithNestedDTO() + var doc = new SimpleObjectWithNestedObject() { - SimpleDTO = new SimpleDTO() + SimpleObject = new SimpleObject() { IntegerValue = 5, IntegerList = new List() { 1, 2, 3 } @@ -2202,27 +2202,27 @@ namespace Microsoft.AspNetCore.JsonPatch }; // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Move(o => o.SimpleDTO.IntegerValue, o => o.SimpleDTO.IntegerList, 0); + var patchDoc = new JsonPatchDocument(); + patchDoc.Move(o => o.SimpleObject.IntegerValue, o => o.SimpleObject.IntegerList, 0); var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject>(serialized); + var deserialized = JsonConvert.DeserializeObject>(serialized); // Act deserialized.ApplyTo(doc); // Assert Assert.Equal(0, doc.IntegerValue); - Assert.Equal(new List() { 5, 1, 2, 3 }, doc.SimpleDTO.IntegerList); + Assert.Equal(new List() { 5, 1, 2, 3 }, doc.SimpleObject.IntegerList); } [Fact] public void MoveToEndOfList() { // Arrange - var doc = new SimpleDTOWithNestedDTO() + var doc = new SimpleObjectWithNestedObject() { - SimpleDTO = new SimpleDTO() + SimpleObject = new SimpleObject() { IntegerValue = 5, IntegerList = new List() { 1, 2, 3 } @@ -2230,24 +2230,24 @@ namespace Microsoft.AspNetCore.JsonPatch }; // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Move(o => o.SimpleDTO.IntegerValue, o => o.SimpleDTO.IntegerList); + var patchDoc = new JsonPatchDocument(); + patchDoc.Move(o => o.SimpleObject.IntegerValue, o => o.SimpleObject.IntegerList); // Act patchDoc.ApplyTo(doc); // Assert Assert.Equal(0, doc.IntegerValue); - Assert.Equal(new List() { 1, 2, 3, 5 }, doc.SimpleDTO.IntegerList); + Assert.Equal(new List() { 1, 2, 3, 5 }, doc.SimpleObject.IntegerList); } [Fact] public void MoveToEndOfListWithSerialization() { // Arrange - var doc = new SimpleDTOWithNestedDTO() + var doc = new SimpleObjectWithNestedObject() { - SimpleDTO = new SimpleDTO() + SimpleObject = new SimpleObject() { IntegerValue = 5, IntegerList = new List() { 1, 2, 3 } @@ -2255,18 +2255,18 @@ namespace Microsoft.AspNetCore.JsonPatch }; // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Move(o => o.SimpleDTO.IntegerValue, o => o.SimpleDTO.IntegerList); + var patchDoc = new JsonPatchDocument(); + patchDoc.Move(o => o.SimpleObject.IntegerValue, o => o.SimpleObject.IntegerList); var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject>(serialized); + var deserialized = JsonConvert.DeserializeObject>(serialized); // Act deserialized.ApplyTo(doc); // Assert Assert.Equal(0, doc.IntegerValue); - Assert.Equal(new List() { 1, 2, 3, 5 }, doc.SimpleDTO.IntegerList); + Assert.Equal(new List() { 1, 2, 3, 5 }, doc.SimpleObject.IntegerList); } } } diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/ObjectAdapterTests.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/ObjectAdapterTests.cs index 34a8c97b67..d35f8eb4e9 100644 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/ObjectAdapterTests.cs +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/ObjectAdapterTests.cs @@ -16,13 +16,13 @@ namespace Microsoft.AspNetCore.JsonPatch.Adapters public void AddResultsShouldReplace() { // Arrange - var doc = new SimpleDTO() + var doc = new SimpleObject() { StringProperty = "A" }; // create patch - var patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Add(o => o.StringProperty, "B"); // Act @@ -36,17 +36,17 @@ namespace Microsoft.AspNetCore.JsonPatch.Adapters public void AddResultsShouldReplaceWithSerialization() { // Arrange - var doc = new SimpleDTO() + var doc = new SimpleObject() { StringProperty = "A" }; // create patch - var patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Add(o => o.StringProperty, "B"); var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject>(serialized); + var deserialized = JsonConvert.DeserializeObject>(serialized); // Act deserialized.ApplyTo(doc); @@ -59,13 +59,13 @@ namespace Microsoft.AspNetCore.JsonPatch.Adapters public void AddToList() { // Arrange - var doc = new SimpleDTO() + var doc = new SimpleObject() { IntegerList = new List() { 1, 2, 3 } }; // create patch - var patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Add(o => o.IntegerList, 4, 0); // Act @@ -79,17 +79,17 @@ namespace Microsoft.AspNetCore.JsonPatch.Adapters public void AddToListWithSerialization() { // Arrange - var doc = new SimpleDTO() + var doc = new SimpleObject() { IntegerList = new List() { 1, 2, 3 } }; // create patch - var patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Add(o => o.IntegerList, 4, 0); var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject>(serialized); + var deserialized = JsonConvert.DeserializeObject>(serialized); // Act deserialized.ApplyTo(doc); @@ -102,13 +102,13 @@ namespace Microsoft.AspNetCore.JsonPatch.Adapters public void AddToIntegerIList() { // Arrange - var doc = new SimpleDTO() + var doc = new SimpleObject() { IntegerIList = new List() { 1, 2, 3 } }; // create patch - var patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Add(o => o.IntegerIList, 4, 0); // Act @@ -122,17 +122,17 @@ namespace Microsoft.AspNetCore.JsonPatch.Adapters public void AddToIntegerIListWithSerialization() { // Arrange - var doc = new SimpleDTO() + var doc = new SimpleObject() { IntegerIList = new List() { 1, 2, 3 } }; // create patch - var patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Add(o => o.IntegerIList, 4, 0); var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject>(serialized); + var deserialized = JsonConvert.DeserializeObject>(serialized); // Act deserialized.ApplyTo(doc); @@ -145,13 +145,13 @@ namespace Microsoft.AspNetCore.JsonPatch.Adapters public void AddToListInvalidPositionTooLarge() { // Arrange - var doc = new SimpleDTO() + var doc = new SimpleObject() { IntegerList = new List() { 1, 2, 3 } }; // create patch - var patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Add(o => o.IntegerList, 4, 4); // Act & Assert @@ -165,17 +165,17 @@ namespace Microsoft.AspNetCore.JsonPatch.Adapters public void AddToListInvalidPositionTooLargeWithSerialization() { // Arrange - var doc = new SimpleDTO() + var doc = new SimpleObject() { IntegerList = new List() { 1, 2, 3 } }; // create patch - var patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Add(o => o.IntegerList, 4, 4); var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject>(serialized); + var deserialized = JsonConvert.DeserializeObject>(serialized); // Act & Assert var exception = Assert.Throws(() => { deserialized.ApplyTo(doc); }); @@ -188,16 +188,16 @@ namespace Microsoft.AspNetCore.JsonPatch.Adapters public void AddToListInvalidPositionTooLarge_LogsError() { // Arrange - var doc = new SimpleDTO() + var doc = new SimpleObject() { IntegerList = new List() { 1, 2, 3 } }; // create patch - var patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Add(o => o.IntegerList, 4, 4); - var logger = new TestErrorLogger(); + var logger = new TestErrorLogger(); patchDoc.ApplyTo(doc, logger.LogErrorMessage); @@ -212,13 +212,13 @@ namespace Microsoft.AspNetCore.JsonPatch.Adapters public void AddToListAtBeginning() { // Arrange - var doc = new SimpleDTO() + var doc = new SimpleObject() { IntegerList = new List() { 1, 2, 3 } }; // create patch - var patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Add(o => o.IntegerList, 4, 0); // Act @@ -232,17 +232,17 @@ namespace Microsoft.AspNetCore.JsonPatch.Adapters public void AddToListAtBeginningWithSerialization() { // Arrange - var doc = new SimpleDTO() + var doc = new SimpleObject() { IntegerList = new List() { 1, 2, 3 } }; // create patch - var patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Add(o => o.IntegerList, 4, 0); var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject>(serialized); + var deserialized = JsonConvert.DeserializeObject>(serialized); // Act deserialized.ApplyTo(doc); @@ -255,13 +255,13 @@ namespace Microsoft.AspNetCore.JsonPatch.Adapters public void AddToListInvalidPositionTooSmall() { // Arrange - var doc = new SimpleDTO() + var doc = new SimpleObject() { IntegerList = new List() { 1, 2, 3 } }; // create patch - var patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Add(o => o.IntegerList, 4, -1); // Act & Assert @@ -275,17 +275,17 @@ namespace Microsoft.AspNetCore.JsonPatch.Adapters public void AddToListInvalidPositionTooSmallWithSerialization() { // Arrange - var doc = new SimpleDTO() + var doc = new SimpleObject() { IntegerList = new List() { 1, 2, 3 } }; // create patch - var patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Add(o => o.IntegerList, 4, -1); var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject>(serialized); + var deserialized = JsonConvert.DeserializeObject>(serialized); // Act & Assert var exception = Assert.Throws(() => { deserialized.ApplyTo(doc); }); @@ -298,16 +298,16 @@ namespace Microsoft.AspNetCore.JsonPatch.Adapters public void AddToListInvalidPositionTooSmall_LogsError() { // Arrange - var doc = new SimpleDTO() + var doc = new SimpleObject() { IntegerList = new List() { 1, 2, 3 } }; // create patch - var patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Add(o => o.IntegerList, 4, -1); - var logger = new TestErrorLogger(); + var logger = new TestErrorLogger(); patchDoc.ApplyTo(doc, logger.LogErrorMessage); @@ -321,13 +321,13 @@ namespace Microsoft.AspNetCore.JsonPatch.Adapters public void AddToListAppend() { // Arrange - var doc = new SimpleDTO() + var doc = new SimpleObject() { IntegerList = new List() { 1, 2, 3 } }; // create patch - var patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Add(o => o.IntegerList, 4); // Act @@ -341,17 +341,17 @@ namespace Microsoft.AspNetCore.JsonPatch.Adapters public void AddToListAppendWithSerialization() { // Arrange - var doc = new SimpleDTO() + var doc = new SimpleObject() { IntegerList = new List() { 1, 2, 3 } }; // create patch - var patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Add(o => o.IntegerList, 4); var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject>(serialized); + var deserialized = JsonConvert.DeserializeObject>(serialized); // Act deserialized.ApplyTo(doc); @@ -364,13 +364,13 @@ namespace Microsoft.AspNetCore.JsonPatch.Adapters public void Remove() { // Arrange - var doc = new SimpleDTO() + var doc = new SimpleObject() { StringProperty = "A" }; // create patch - var patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Remove(o => o.StringProperty); // Act @@ -384,17 +384,17 @@ namespace Microsoft.AspNetCore.JsonPatch.Adapters public void RemoveWithSerialization() { // Arrange - var doc = new SimpleDTO() + var doc = new SimpleObject() { StringProperty = "A" }; // create patch - var patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Remove(o => o.StringProperty); var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject>(serialized); + var deserialized = JsonConvert.DeserializeObject>(serialized); // Act deserialized.ApplyTo(doc); @@ -407,13 +407,13 @@ namespace Microsoft.AspNetCore.JsonPatch.Adapters public void RemoveFromList() { // Arrange - var doc = new SimpleDTO() + var doc = new SimpleObject() { IntegerList = new List() { 1, 2, 3 } }; // create patch - var patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Remove(o => o.IntegerList, 2); // Act @@ -427,17 +427,17 @@ namespace Microsoft.AspNetCore.JsonPatch.Adapters public void RemoveFromListWithSerialization() { // Arrange - var doc = new SimpleDTO() + var doc = new SimpleObject() { IntegerList = new List() { 1, 2, 3 } }; // create patch - var patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Remove(o => o.IntegerList, 2); var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject>(serialized); + var deserialized = JsonConvert.DeserializeObject>(serialized); // Act deserialized.ApplyTo(doc); @@ -450,13 +450,13 @@ namespace Microsoft.AspNetCore.JsonPatch.Adapters public void RemoveFromListInvalidPositionTooLarge() { // Arrange - var doc = new SimpleDTO() + var doc = new SimpleObject() { IntegerList = new List() { 1, 2, 3 } }; // create patch - var patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Remove(o => o.IntegerList, 3); // Act & Assert @@ -470,17 +470,17 @@ namespace Microsoft.AspNetCore.JsonPatch.Adapters public void RemoveFromListInvalidPositionTooLargeWithSerialization() { // Arrange - var doc = new SimpleDTO() + var doc = new SimpleObject() { IntegerList = new List() { 1, 2, 3 } }; // create patch - var patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Remove(o => o.IntegerList, 3); var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject>(serialized); + var deserialized = JsonConvert.DeserializeObject>(serialized); // Act & Assert var exception = Assert.Throws(() => { deserialized.ApplyTo(doc); }); @@ -493,16 +493,16 @@ namespace Microsoft.AspNetCore.JsonPatch.Adapters public void RemoveFromListInvalidPositionTooLarge_LogsError() { // Arrange - var doc = new SimpleDTO() + var doc = new SimpleObject() { IntegerList = new List() { 1, 2, 3 } }; // create patch - var patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Remove(o => o.IntegerList, 3); - var logger = new TestErrorLogger(); + var logger = new TestErrorLogger(); patchDoc.ApplyTo(doc, logger.LogErrorMessage); @@ -517,13 +517,13 @@ namespace Microsoft.AspNetCore.JsonPatch.Adapters public void RemoveFromListInvalidPositionTooSmall() { // Arrange - var doc = new SimpleDTO() + var doc = new SimpleObject() { IntegerList = new List() { 1, 2, 3 } }; // create patch - var patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Remove(o => o.IntegerList, -1); // Act & Assert @@ -537,17 +537,17 @@ namespace Microsoft.AspNetCore.JsonPatch.Adapters public void RemoveFromListInvalidPositionTooSmallWithSerialization() { // Arrange - var doc = new SimpleDTO() + var doc = new SimpleObject() { IntegerList = new List() { 1, 2, 3 } }; // create patch - var patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Remove(o => o.IntegerList, -1); var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject>(serialized); + var deserialized = JsonConvert.DeserializeObject>(serialized); // Act & Assert var exception = Assert.Throws(() => { deserialized.ApplyTo(doc); }); @@ -560,16 +560,16 @@ namespace Microsoft.AspNetCore.JsonPatch.Adapters public void RemoveFromListInvalidPositionTooSmall_LogsError() { // Arrange - var doc = new SimpleDTO() + var doc = new SimpleObject() { IntegerList = new List() { 1, 2, 3 } }; // create patch - var patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Remove(o => o.IntegerList, -1); - var logger = new TestErrorLogger(); + var logger = new TestErrorLogger(); patchDoc.ApplyTo(doc, logger.LogErrorMessage); @@ -585,13 +585,13 @@ namespace Microsoft.AspNetCore.JsonPatch.Adapters public void RemoveFromEndOfList() { // Arrange - var doc = new SimpleDTO() + var doc = new SimpleObject() { IntegerList = new List() { 1, 2, 3 } }; // create patch - var patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Remove(o => o.IntegerList); // Act @@ -605,17 +605,17 @@ namespace Microsoft.AspNetCore.JsonPatch.Adapters public void RemoveFromEndOfListWithSerialization() { // Arrange - var doc = new SimpleDTO() + var doc = new SimpleObject() { IntegerList = new List() { 1, 2, 3 } }; // create patch - var patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Remove(o => o.IntegerList); var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject>(serialized); + var deserialized = JsonConvert.DeserializeObject>(serialized); // Act deserialized.ApplyTo(doc); @@ -628,14 +628,14 @@ namespace Microsoft.AspNetCore.JsonPatch.Adapters public void Replace() { // Arrange - var doc = new SimpleDTO() + var doc = new SimpleObject() { StringProperty = "A", DecimalValue = 10 }; // create patch - var patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Replace(o => o.StringProperty, "B"); patchDoc.Replace(o => o.DecimalValue, 12); @@ -652,13 +652,13 @@ namespace Microsoft.AspNetCore.JsonPatch.Adapters public void Replace_DTOWithNullCheck() { // Arrange - var doc = new SimpleDTOWithNullCheck() + var doc = new SimpleObjectWithNullCheck() { StringProperty = "A", }; // create patch - var patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Replace(o => o.StringProperty, "B"); // Act @@ -672,20 +672,20 @@ namespace Microsoft.AspNetCore.JsonPatch.Adapters public void ReplaceWithSerialization() { // Arrange - var doc = new SimpleDTO() + var doc = new SimpleObject() { StringProperty = "A", DecimalValue = 10 }; // create patch - var patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Replace(o => o.StringProperty, "B"); patchDoc.Replace(o => o.DecimalValue, 12); var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject>(serialized); + var deserialized = JsonConvert.DeserializeObject>(serialized); // Act deserialized.ApplyTo(doc); @@ -699,7 +699,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Adapters public void SerializationMustNotIncudeEnvelope() { // Arrange - var doc = new SimpleDTO() + var doc = new SimpleObject() { StringProperty = "A", DecimalValue = 10, @@ -709,7 +709,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Adapters }; // create patch - var patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Replace(o => o.StringProperty, "B"); patchDoc.Replace(o => o.DecimalValue, 12); patchDoc.Replace(o => o.DoubleValue, 12); @@ -728,7 +728,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Adapters public void DeserializationMustWorkWithoutEnvelope() { // Arrange - var doc = new SimpleDTO() + var doc = new SimpleObject() { StringProperty = "A", DecimalValue = 10, @@ -738,7 +738,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Adapters }; // create patch - var patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Replace(o => o.StringProperty, "B"); patchDoc.Replace(o => o.DecimalValue, 12); patchDoc.Replace(o => o.DoubleValue, 12); @@ -749,23 +749,23 @@ namespace Microsoft.AspNetCore.JsonPatch.Adapters var serialized = JsonConvert.SerializeObject(patchDoc); // Act - var deserialized = JsonConvert.DeserializeObject>(serialized); + var deserialized = JsonConvert.DeserializeObject>(serialized); // Assert - Assert.IsType>(deserialized); + Assert.IsType>(deserialized); } [Fact] public void DeserializationMustFailWithEnvelope() { // Arrange - string serialized = "{\"Operations\": [{ \"op\": \"replace\", \"path\": \"/title\", \"value\": \"New Title\"}]}"; + var serialized = "{\"Operations\": [{ \"op\": \"replace\", \"path\": \"/title\", \"value\": \"New Title\"}]}"; // Act & Assert var exception = Assert.Throws(() => { var deserialized - = JsonConvert.DeserializeObject>(serialized); + = JsonConvert.DeserializeObject>(serialized); }); Assert.Equal("The type 'JsonPatchDocument`1' was malformed and could not be parsed.", exception.Message); @@ -775,7 +775,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Adapters public void SerializationTests() { // Arrange - var doc = new SimpleDTO() + var doc = new SimpleObject() { StringProperty = "A", DecimalValue = 10, @@ -785,7 +785,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Adapters }; // create patch - var patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Replace(o => o.StringProperty, "B"); patchDoc.Replace(o => o.DecimalValue, 12); patchDoc.Replace(o => o.DoubleValue, 12); @@ -794,7 +794,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Adapters // serialize & deserialize var serialized = JsonConvert.SerializeObject(patchDoc); - var deserizalized = JsonConvert.DeserializeObject>(serialized); + var deserizalized = JsonConvert.DeserializeObject>(serialized); // Act deserizalized.ApplyTo(doc); @@ -811,19 +811,19 @@ namespace Microsoft.AspNetCore.JsonPatch.Adapters public void SerializeAndReplaceGuidTest() { // Arrange - var doc = new SimpleDTO() + var doc = new SimpleObject() { GuidValue = Guid.NewGuid() }; var newGuid = Guid.NewGuid(); // create patch - var patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Replace(o => o.GuidValue, newGuid); // serialize & deserialize var serialized = JsonConvert.SerializeObject(patchDoc); - var deserizalized = JsonConvert.DeserializeObject>(serialized); + var deserizalized = JsonConvert.DeserializeObject>(serialized); // Act deserizalized.ApplyTo(doc); @@ -836,48 +836,48 @@ namespace Microsoft.AspNetCore.JsonPatch.Adapters public void SerializeAndReplaceNestedObjectTest() { // Arrange - var doc = new SimpleDTOWithNestedDTO() + var doc = new SimpleObjectWithNestedObject() { - SimpleDTO = new SimpleDTO() + SimpleObject = new SimpleObject() { IntegerValue = 5, IntegerList = new List() { 1, 2, 3 } } }; - var newDTO = new SimpleDTO() + var newDTO = new SimpleObject() { DoubleValue = 1 }; // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Replace(o => o.SimpleDTO, newDTO); + var patchDoc = new JsonPatchDocument(); + patchDoc.Replace(o => o.SimpleObject, newDTO); // serialize & deserialize var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject>(serialized); + var deserialized = JsonConvert.DeserializeObject>(serialized); // Act deserialized.ApplyTo(doc); // Assert - Assert.Equal(1, doc.SimpleDTO.DoubleValue); - Assert.Equal(0, doc.SimpleDTO.IntegerValue); - Assert.Null(doc.SimpleDTO.IntegerList); + Assert.Equal(1, doc.SimpleObject.DoubleValue); + Assert.Equal(0, doc.SimpleObject.IntegerValue); + Assert.Null(doc.SimpleObject.IntegerList); } [Fact] public void ReplaceInList() { // Arrange - var doc = new SimpleDTO() + var doc = new SimpleObject() { IntegerList = new List() { 1, 2, 3 } }; // create patch - var patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Replace(o => o.IntegerList, 5, 0); // Act @@ -891,17 +891,17 @@ namespace Microsoft.AspNetCore.JsonPatch.Adapters public void ReplaceInListWithSerialization() { // Arrange - var doc = new SimpleDTO() + var doc = new SimpleObject() { IntegerList = new List() { 1, 2, 3 } }; // create patch - var patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Replace(o => o.IntegerList, 5, 0); var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject>(serialized); + var deserialized = JsonConvert.DeserializeObject>(serialized); // Act deserialized.ApplyTo(doc); @@ -914,13 +914,13 @@ namespace Microsoft.AspNetCore.JsonPatch.Adapters public void ReplaceFullList() { // Arrange - var doc = new SimpleDTO() + var doc = new SimpleObject() { IntegerList = new List() { 1, 2, 3 } }; // create patch - var patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Replace>(o => o.IntegerList, new List() { 4, 5, 6 }); // Act @@ -934,17 +934,17 @@ namespace Microsoft.AspNetCore.JsonPatch.Adapters public void ReplaceFullListWithSerialization() { // Arrange - var doc = new SimpleDTO() + var doc = new SimpleObject() { IntegerList = new List() { 1, 2, 3 } }; // create patch - var patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Replace>(o => o.IntegerList, new List() { 4, 5, 6 }); var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject>(serialized); + var deserialized = JsonConvert.DeserializeObject>(serialized); // Act deserialized.ApplyTo(doc); @@ -957,13 +957,13 @@ namespace Microsoft.AspNetCore.JsonPatch.Adapters public void ReplaceFullListFromEnumerable() { // Arrange - var doc = new SimpleDTO() + var doc = new SimpleObject() { IntegerList = new List() { 1, 2, 3 } }; // create patch - var patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Replace>(o => o.IntegerList, new List() { 4, 5, 6 }); // Act @@ -977,17 +977,17 @@ namespace Microsoft.AspNetCore.JsonPatch.Adapters public void ReplaceFullListFromEnumerableWithSerialization() { // Arrange - var doc = new SimpleDTO() + var doc = new SimpleObject() { IntegerList = new List() { 1, 2, 3 } }; // create patch - var patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Replace>(o => o.IntegerList, new List() { 4, 5, 6 }); var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject>(serialized); + var deserialized = JsonConvert.DeserializeObject>(serialized); // Act deserialized.ApplyTo(doc); @@ -1000,13 +1000,13 @@ namespace Microsoft.AspNetCore.JsonPatch.Adapters public void ReplaceFullListWithCollection() { // Arrange - var doc = new SimpleDTO() + var doc = new SimpleObject() { IntegerList = new List() { 1, 2, 3 } }; // create patch - var patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Replace>(o => o.IntegerList, new Collection() { 4, 5, 6 }); // Act @@ -1020,17 +1020,17 @@ namespace Microsoft.AspNetCore.JsonPatch.Adapters public void ReplaceFullListWithCollectionWithSerialization() { // Arrange - var doc = new SimpleDTO() + var doc = new SimpleObject() { IntegerList = new List() { 1, 2, 3 } }; // create patch - var patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Replace>(o => o.IntegerList, new Collection() { 4, 5, 6 }); var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject>(serialized); + var deserialized = JsonConvert.DeserializeObject>(serialized); // Act deserialized.ApplyTo(doc); @@ -1043,13 +1043,13 @@ namespace Microsoft.AspNetCore.JsonPatch.Adapters public void ReplaceAtEndOfList() { // Arrange - var doc = new SimpleDTO() + var doc = new SimpleObject() { IntegerList = new List() { 1, 2, 3 } }; // create patch - var patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Replace(o => o.IntegerList, 5); // Act @@ -1063,16 +1063,16 @@ namespace Microsoft.AspNetCore.JsonPatch.Adapters public void ReplaceAtEndOfListWithSerialization() { // Arrange - var doc = new SimpleDTO() + var doc = new SimpleObject() { IntegerList = new List() { 1, 2, 3 } }; // create patch - var patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Replace(o => o.IntegerList, 5); var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject>(serialized); + var deserialized = JsonConvert.DeserializeObject>(serialized); // Act deserialized.ApplyTo(doc); @@ -1085,13 +1085,13 @@ namespace Microsoft.AspNetCore.JsonPatch.Adapters public void ReplaceInListInvalidInvalidPositionTooLarge() { // Arrange - var doc = new SimpleDTO() + var doc = new SimpleObject() { IntegerList = new List() { 1, 2, 3 } }; // create patch - var patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Replace(o => o.IntegerList, 5, 3); // Act & Assert @@ -1108,16 +1108,16 @@ namespace Microsoft.AspNetCore.JsonPatch.Adapters public void ReplaceInListInvalidInvalidPositionTooLargeWithSerialization() { // Arrange - var doc = new SimpleDTO() + var doc = new SimpleObject() { IntegerList = new List() { 1, 2, 3 } }; // create patch - var patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Replace(o => o.IntegerList, 5, 3); var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject>(serialized); + var deserialized = JsonConvert.DeserializeObject>(serialized); // Act & Assert var exception = Assert.Throws(() => @@ -1133,13 +1133,13 @@ namespace Microsoft.AspNetCore.JsonPatch.Adapters public void ReplaceInListInvalidPositionTooSmall() { // Arrange - var doc = new SimpleDTO() + var doc = new SimpleObject() { IntegerList = new List() { 1, 2, 3 } }; // create patch - var patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Replace(o => o.IntegerList, 5, -1); // Act & Assert @@ -1156,17 +1156,17 @@ namespace Microsoft.AspNetCore.JsonPatch.Adapters public void ReplaceInListInvalidPositionTooSmallWithSerialization() { // Arrange - var doc = new SimpleDTO() + var doc = new SimpleObject() { IntegerList = new List() { 1, 2, 3 } }; // create patch - var patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Replace(o => o.IntegerList, 5, -1); var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject>(serialized); + var deserialized = JsonConvert.DeserializeObject>(serialized); // Act & Assert var exception = Assert.Throws(() => @@ -1182,14 +1182,14 @@ namespace Microsoft.AspNetCore.JsonPatch.Adapters public void Copy() { // Arrange - var doc = new SimpleDTO() + var doc = new SimpleObject() { StringProperty = "A", AnotherStringProperty = "B" }; // create patch - var patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Copy(o => o.StringProperty, o => o.AnotherStringProperty); // Act @@ -1203,17 +1203,17 @@ namespace Microsoft.AspNetCore.JsonPatch.Adapters public void CopyWithSerialization() { // Arrange - var doc = new SimpleDTO() + var doc = new SimpleObject() { StringProperty = "A", AnotherStringProperty = "B" }; // create patch - var patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Copy(o => o.StringProperty, o => o.AnotherStringProperty); var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject>(serialized); + var deserialized = JsonConvert.DeserializeObject>(serialized); // Act deserialized.ApplyTo(doc); @@ -1226,13 +1226,13 @@ namespace Microsoft.AspNetCore.JsonPatch.Adapters public void CopyInList() { // Arrange - var doc = new SimpleDTO() + var doc = new SimpleObject() { IntegerList = new List() { 1, 2, 3 } }; // create patch - var patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Copy(o => o.IntegerList, 0, o => o.IntegerList, 1); // Act @@ -1246,17 +1246,17 @@ namespace Microsoft.AspNetCore.JsonPatch.Adapters public void CopyInListWithSerialization() { // Arrange - var doc = new SimpleDTO() + var doc = new SimpleObject() { IntegerList = new List() { 1, 2, 3 } }; // create patch - var patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Copy(o => o.IntegerList, 0, o => o.IntegerList, 1); var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject>(serialized); + var deserialized = JsonConvert.DeserializeObject>(serialized); // Act deserialized.ApplyTo(doc); @@ -1269,13 +1269,13 @@ namespace Microsoft.AspNetCore.JsonPatch.Adapters public void CopyFromListToEndOfList() { // Arrange - var doc = new SimpleDTO() + var doc = new SimpleObject() { IntegerList = new List() { 1, 2, 3 } }; // create patch - var patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Copy(o => o.IntegerList, 0, o => o.IntegerList); // Act @@ -1289,17 +1289,17 @@ namespace Microsoft.AspNetCore.JsonPatch.Adapters public void CopyFromListToEndOfListWithSerialization() { // Arrange - var doc = new SimpleDTO() + var doc = new SimpleObject() { IntegerList = new List() { 1, 2, 3 } }; // create patch - var patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Copy(o => o.IntegerList, 0, o => o.IntegerList); var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject>(serialized); + var deserialized = JsonConvert.DeserializeObject>(serialized); // Act deserialized.ApplyTo(doc); @@ -1312,13 +1312,13 @@ namespace Microsoft.AspNetCore.JsonPatch.Adapters public void CopyFromListToNonList() { // Arrange - var doc = new SimpleDTO() + var doc = new SimpleObject() { IntegerList = new List() { 1, 2, 3 } }; // create patch - var patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Copy(o => o.IntegerList, 0, o => o.IntegerValue); // Act @@ -1332,17 +1332,17 @@ namespace Microsoft.AspNetCore.JsonPatch.Adapters public void CopyFromListToNonListWithSerialization() { // Arrange - var doc = new SimpleDTO() + var doc = new SimpleObject() { IntegerList = new List() { 1, 2, 3 } }; // create patch - var patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Copy(o => o.IntegerList, 0, o => o.IntegerValue); var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject>(serialized); + var deserialized = JsonConvert.DeserializeObject>(serialized); // Act deserialized.ApplyTo(doc); @@ -1355,14 +1355,14 @@ namespace Microsoft.AspNetCore.JsonPatch.Adapters public void CopyFromNonListToList() { // Arrange - var doc = new SimpleDTO() + var doc = new SimpleObject() { IntegerValue = 5, IntegerList = new List() { 1, 2, 3 } }; // create patch - var patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Copy(o => o.IntegerValue, o => o.IntegerList, 0); // Act @@ -1376,18 +1376,18 @@ namespace Microsoft.AspNetCore.JsonPatch.Adapters public void CopyFromNonListToListWithSerialization() { // Arrange - var doc = new SimpleDTO() + var doc = new SimpleObject() { IntegerValue = 5, IntegerList = new List() { 1, 2, 3 } }; // create patch - var patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Copy(o => o.IntegerValue, o => o.IntegerList, 0); var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject>(serialized); + var deserialized = JsonConvert.DeserializeObject>(serialized); // Act deserialized.ApplyTo(doc); @@ -1400,14 +1400,14 @@ namespace Microsoft.AspNetCore.JsonPatch.Adapters public void CopyToEndOfList() { // Arrange - var doc = new SimpleDTO() + var doc = new SimpleObject() { IntegerValue = 5, IntegerList = new List() { 1, 2, 3 } }; // create patch - var patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Copy(o => o.IntegerValue, o => o.IntegerList); // Act @@ -1421,18 +1421,18 @@ namespace Microsoft.AspNetCore.JsonPatch.Adapters public void CopyToEndOfListWithSerialization() { // Arrange - var doc = new SimpleDTO() + var doc = new SimpleObject() { IntegerValue = 5, IntegerList = new List() { 1, 2, 3 } }; // create patch - var patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Copy(o => o.IntegerValue, o => o.IntegerList); var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject>(serialized); + var deserialized = JsonConvert.DeserializeObject>(serialized); // Act deserialized.ApplyTo(doc); @@ -1445,14 +1445,14 @@ namespace Microsoft.AspNetCore.JsonPatch.Adapters public void Move() { // Arrange - var doc = new SimpleDTO() + var doc = new SimpleObject() { StringProperty = "A", AnotherStringProperty = "B" }; // create patch - var patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Move(o => o.StringProperty, o => o.AnotherStringProperty); // Act @@ -1467,18 +1467,18 @@ namespace Microsoft.AspNetCore.JsonPatch.Adapters public void MoveWithSerialization() { // Arrange - var doc = new SimpleDTO() + var doc = new SimpleObject() { StringProperty = "A", AnotherStringProperty = "B" }; // create patch - var patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Move(o => o.StringProperty, o => o.AnotherStringProperty); var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject>(serialized); + var deserialized = JsonConvert.DeserializeObject>(serialized); // Act deserialized.ApplyTo(doc); @@ -1492,13 +1492,13 @@ namespace Microsoft.AspNetCore.JsonPatch.Adapters public void MoveInList() { // Arrange - var doc = new SimpleDTO() + var doc = new SimpleObject() { IntegerList = new List() { 1, 2, 3 } }; // create patch - var patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Move(o => o.IntegerList, 0, o => o.IntegerList, 1); // Act @@ -1512,17 +1512,17 @@ namespace Microsoft.AspNetCore.JsonPatch.Adapters public void MoveInListWithSerialization() { // Arrange - var doc = new SimpleDTO() + var doc = new SimpleObject() { IntegerList = new List() { 1, 2, 3 } }; // create patch - var patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Move(o => o.IntegerList, 0, o => o.IntegerList, 1); var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject>(serialized); + var deserialized = JsonConvert.DeserializeObject>(serialized); // Act deserialized.ApplyTo(doc); @@ -1535,13 +1535,13 @@ namespace Microsoft.AspNetCore.JsonPatch.Adapters public void MoveFromListToEndOfList() { // Arrange - var doc = new SimpleDTO() + var doc = new SimpleObject() { IntegerList = new List() { 1, 2, 3 } }; // create patch - var patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Move(o => o.IntegerList, 0, o => o.IntegerList); // Act @@ -1555,17 +1555,17 @@ namespace Microsoft.AspNetCore.JsonPatch.Adapters public void MoveFromListToEndOfListWithSerialization() { // Arrange - var doc = new SimpleDTO() + var doc = new SimpleObject() { IntegerList = new List() { 1, 2, 3 } }; // create patch - var patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Move(o => o.IntegerList, 0, o => o.IntegerList); var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject>(serialized); + var deserialized = JsonConvert.DeserializeObject>(serialized); // Act deserialized.ApplyTo(doc); @@ -1578,13 +1578,13 @@ namespace Microsoft.AspNetCore.JsonPatch.Adapters public void MoveFomListToNonList() { // Arrange - var doc = new SimpleDTO() + var doc = new SimpleObject() { IntegerList = new List() { 1, 2, 3 } }; // create patch - var patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Move(o => o.IntegerList, 0, o => o.IntegerValue); // Act @@ -1599,17 +1599,17 @@ namespace Microsoft.AspNetCore.JsonPatch.Adapters public void MoveFomListToNonListWithSerialization() { // Arrange - var doc = new SimpleDTO() + var doc = new SimpleObject() { IntegerList = new List() { 1, 2, 3 } }; // create patch - var patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Move(o => o.IntegerList, 0, o => o.IntegerValue); var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject>(serialized); + var deserialized = JsonConvert.DeserializeObject>(serialized); // Act deserialized.ApplyTo(doc); @@ -1623,14 +1623,14 @@ namespace Microsoft.AspNetCore.JsonPatch.Adapters public void MoveFromNonListToList() { // Arrange - var doc = new SimpleDTO() + var doc = new SimpleObject() { IntegerValue = 5, IntegerList = new List() { 1, 2, 3 } }; // create patch - var patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Move(o => o.IntegerValue, o => o.IntegerList, 0); // Act @@ -1645,18 +1645,18 @@ namespace Microsoft.AspNetCore.JsonPatch.Adapters public void MoveFromNonListToListWithSerialization() { // Arrange - var doc = new SimpleDTO() + var doc = new SimpleObject() { IntegerValue = 5, IntegerList = new List() { 1, 2, 3 } }; // create patch - var patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Move(o => o.IntegerValue, o => o.IntegerList, 0); var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject>(serialized); + var deserialized = JsonConvert.DeserializeObject>(serialized); // Act deserialized.ApplyTo(doc); @@ -1670,14 +1670,14 @@ namespace Microsoft.AspNetCore.JsonPatch.Adapters public void MoveToEndOfList() { // Arrange - var doc = new SimpleDTO() + var doc = new SimpleObject() { IntegerValue = 5, IntegerList = new List() { 1, 2, 3 } }; // create patch - var patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Move(o => o.IntegerValue, o => o.IntegerList); // Act @@ -1692,18 +1692,18 @@ namespace Microsoft.AspNetCore.JsonPatch.Adapters public void MoveToEndOfListWithSerialization() { // Arrange - var doc = new SimpleDTO() + var doc = new SimpleObject() { IntegerValue = 5, IntegerList = new List() { 1, 2, 3 } }; // create patch - var patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Move(o => o.IntegerValue, o => o.IntegerList); var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject>(serialized); + var deserialized = JsonConvert.DeserializeObject>(serialized); // Act deserialized.ApplyTo(doc); @@ -1950,13 +1950,13 @@ namespace Microsoft.AspNetCore.JsonPatch.Adapters public void AddMember_OnPOCO_WithNullPropertyValue_ShouldAddPropertyValue() { // Arrange - var doc = new SimpleDTO() + var doc = new SimpleObject() { StringProperty = null }; // create patch - var patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Add(o => o.StringProperty, "B"); // Act @@ -2175,13 +2175,13 @@ namespace Microsoft.AspNetCore.JsonPatch.Adapters public void AddElement_ToList_OnPOCO_ShouldAddValue_AtSuppliedPosition() { // Arrange - var doc = new SimpleDTO() + var doc = new SimpleObject() { IntegerIList = new List() { 1, 2, 3 } }; // create patch - var patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Add(o => o.IntegerIList, 4, 0); // Act @@ -2193,7 +2193,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Adapters class Class3 { - public SimpleDTO SimpleDTOProperty { get; set; } = new SimpleDTO(); + public SimpleObject SimpleObjectProperty { get; set; } = new SimpleObject(); } [Fact] @@ -2202,19 +2202,19 @@ namespace Microsoft.AspNetCore.JsonPatch.Adapters // Arrange var model = new Class3() { - SimpleDTOProperty = new SimpleDTO() + SimpleObjectProperty = new SimpleObject() { IntegerIList = new List() { 1, 2, 3 } } }; var patchDoc = new JsonPatchDocument(); - patchDoc.Add(o => o.SimpleDTOProperty.IntegerIList, value: 4, position: 0); + patchDoc.Add(o => o.SimpleObjectProperty.IntegerIList, value: 4, position: 0); // Act patchDoc.ApplyTo(model); // Assert - Assert.Equal(new List() { 4, 1, 2, 3 }, model.SimpleDTOProperty.IntegerIList); + Assert.Equal(new List() { 4, 1, 2, 3 }, model.SimpleObjectProperty.IntegerIList); } [Fact] @@ -2223,13 +2223,13 @@ namespace Microsoft.AspNetCore.JsonPatch.Adapters // Arrange var model = new Class3() { - SimpleDTOProperty = new SimpleDTO() + SimpleObjectProperty = new SimpleObject() { IntegerIList = new List() { 1, 2, 3 } } }; var patchDoc = new JsonPatchDocument(); - patchDoc.Add(o => o.SimpleDTOProperty.IntegerIList, value: 4, position: 0); + patchDoc.Add(o => o.SimpleObjectProperty.IntegerIList, value: 4, position: 0); var serialized = JsonConvert.SerializeObject(patchDoc); var deserialized = JsonConvert.DeserializeObject>(serialized); @@ -2237,7 +2237,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Adapters deserialized.ApplyTo(model); // Assert - Assert.Equal(new List() { 4, 1, 2, 3 }, model.SimpleDTOProperty.IntegerIList); + Assert.Equal(new List() { 4, 1, 2, 3 }, model.SimpleObjectProperty.IntegerIList); } class Class4 @@ -2267,17 +2267,17 @@ namespace Microsoft.AspNetCore.JsonPatch.Adapters public void Remove_OnNonReferenceType_POCOProperty_ShouldSetDefaultValue_WithSerialization() { // Arrange - var doc = new SimpleDTO() + var doc = new SimpleObject() { StringProperty = "A" }; // create patch - var patchDoc = new JsonPatchDocument(); + var patchDoc = new JsonPatchDocument(); patchDoc.Remove(o => o.StringProperty); var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject>(serialized); + var deserialized = JsonConvert.DeserializeObject>(serialized); // Act deserialized.ApplyTo(doc); diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/ObjectVisitorTest.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/ObjectVisitorTest.cs index 391b5ebe2c..5eddac8685 100644 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/ObjectVisitorTest.cs +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/ObjectVisitorTest.cs @@ -46,11 +46,9 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal { // Arrange var visitor = new ObjectVisitor(new ParsedPath(path), new DefaultContractResolver()); - IAdapter adapter = null; - string message = null; // 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.True(visitStatus); @@ -81,11 +79,9 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal { // Arrange var visitor = new ObjectVisitor(new ParsedPath(path), new DefaultContractResolver()); - IAdapter adapter = null; - string message = null; // 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.True(visitStatus); @@ -112,11 +108,9 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal { // Arrange var visitor = new ObjectVisitor(new ParsedPath(path), new DefaultContractResolver()); - IAdapter adapter = null; - string message = null; // 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.True(visitStatus); @@ -146,11 +140,9 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal { // Arrange var visitor = new ObjectVisitor(new ParsedPath(path), new DefaultContractResolver()); - IAdapter adapter = null; - string message = null; // 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.True(visitStatus); @@ -168,11 +160,9 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal var visitor = new ObjectVisitor(new ParsedPath($"/Customers/{position}/States/-"), new DefaultContractResolver()); var automobileDepartment = new Class1Nested(); object targetObject = automobileDepartment; - IAdapter adapter = null; - string message = null; // 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.False(visitStatus); @@ -190,11 +180,9 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal var visitor = new ObjectVisitor(new ParsedPath($"/Customers/{position}/States/-"), new DefaultContractResolver()); var automobileDepartment = new Class1Nested(); object targetObject = automobileDepartment; - IAdapter adapter = null; - string message = null; // 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.False(visitStatus); @@ -211,16 +199,30 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal var visitor = new ObjectVisitor(new ParsedPath($"/NonExisting"), new DefaultContractResolver()); var model = new Class1(); object targetObject = model; - IAdapter adapter = null; - string message = null; // 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.True(visitStatus); Assert.True(string.IsNullOrEmpty(message), "Expected no error message"); Assert.IsType(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); + } } } diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/SimpleDTOWithNestedDTO.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/SimpleDTOWithNestedDTO.cs deleted file mode 100644 index de089eb25f..0000000000 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/SimpleDTOWithNestedDTO.cs +++ /dev/null @@ -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 SimpleDTOList { get; set; } - - public IList SimpleDTOIList { get; set; } - - public SimpleDTOWithNestedDTO() - { - this.NestedDTO = new NestedDTO(); - this.SimpleDTO = new SimpleDTO(); - this.InheritedDTO = new InheritedDTO(); - this.SimpleDTOList = new List(); - } - } -} \ No newline at end of file diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/SimpleDTOWithNestedDTOWithNullCheck.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/SimpleDTOWithNestedDTOWithNullCheck.cs deleted file mode 100644 index 308f23b470..0000000000 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/SimpleDTOWithNestedDTOWithNullCheck.cs +++ /dev/null @@ -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(); - } - } -} diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/SimpleDTO.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/SimpleObject.cs similarity index 95% rename from test/Microsoft.AspNetCore.JsonPatch.Test/SimpleDTO.cs rename to test/Microsoft.AspNetCore.JsonPatch.Test/SimpleObject.cs index 6dc1f173de..28a9570c2b 100644 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/SimpleDTO.cs +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/SimpleObject.cs @@ -6,7 +6,7 @@ using System.Collections.Generic; namespace Microsoft.AspNetCore.JsonPatch { - public class SimpleDTO + public class SimpleObject { public List IntegerList { get; set; } public IList IntegerIList { get; set; } diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/SimpleObjectWithNestedObject.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/SimpleObjectWithNestedObject.cs new file mode 100644 index 0000000000..4d7c0e2bd8 --- /dev/null +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/SimpleObjectWithNestedObject.cs @@ -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 SimpleObjectList { get; set; } + + public IList SimpleObjectIList { get; set; } + + public SimpleObjectWithNestedObject() + { + NestedObject = new NestedObject(); + SimpleObject = new SimpleObject(); + InheritedObject = new InheritedObject(); + SimpleObjectList = new List(); + } + } +} \ No newline at end of file diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/SimpleObjectWithNestedObjectWithNullCheck.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/SimpleObjectWithNestedObjectWithNullCheck.cs new file mode 100644 index 0000000000..f2423700d8 --- /dev/null +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/SimpleObjectWithNestedObjectWithNullCheck.cs @@ -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(); + } + } +} diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/SimpleDTOWithNullCheck.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/SimpleObjectWithNullCheck.cs similarity index 93% rename from test/Microsoft.AspNetCore.JsonPatch.Test/SimpleDTOWithNullCheck.cs rename to test/Microsoft.AspNetCore.JsonPatch.Test/SimpleObjectWithNullCheck.cs index d2a5fe51a4..83338c5a23 100644 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/SimpleDTOWithNullCheck.cs +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/SimpleObjectWithNullCheck.cs @@ -5,7 +5,7 @@ using System; namespace Microsoft.AspNetCore.JsonPatch { - public class SimpleDTOWithNullCheck + public class SimpleObjectWithNullCheck { private string stringProperty; From 0f51c56c3fa120edeeaec51629117338c6265fd3 Mon Sep 17 00:00:00 2001 From: Jass Bagga Date: Tue, 5 Sep 2017 16:07:25 -0700 Subject: [PATCH 156/221] Combine ExpandoObjectAdapter and DictionaryAdapter (#106) Use JsonDictionaryContract in the DictionaryAdapter and combine with ExpandoObjectAdapter --- .../Internal/DictionaryAdapter.cs | 111 ------------ ...ectAdapter.cs => DictionaryAdapterOfTU.cs} | 115 ++++++++---- .../Internal/ObjectVisitor.cs | 27 +-- .../JsonPatchDocumentOfT.cs | 14 +- .../Properties/Resources.Designer.cs | 14 ++ .../Resources.resx | 3 + .../DictionaryAdapterTest.cs | 171 +++++++++++++++--- .../Dynamic/ReplaceOperationTests.cs | 60 ++---- .../ObjectVisitorTest.cs | 8 +- 9 files changed, 273 insertions(+), 250 deletions(-) delete mode 100644 src/Microsoft.AspNetCore.JsonPatch/Internal/DictionaryAdapter.cs rename src/Microsoft.AspNetCore.JsonPatch/Internal/{ExpandoObjectAdapter.cs => DictionaryAdapterOfTU.cs} (52%) diff --git a/src/Microsoft.AspNetCore.JsonPatch/Internal/DictionaryAdapter.cs b/src/Microsoft.AspNetCore.JsonPatch/Internal/DictionaryAdapter.cs deleted file mode 100644 index 4c7651e475..0000000000 --- a/src/Microsoft.AspNetCore.JsonPatch/Internal/DictionaryAdapter.cs +++ /dev/null @@ -1,111 +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; -using Newtonsoft.Json.Serialization; - -namespace Microsoft.AspNetCore.JsonPatch.Internal -{ - public class DictionaryAdapter : IAdapter - { - public bool TryAdd( - object target, - string segment, - IContractResolver contractResolver, - object value, - out string errorMessage) - { - var dictionary = (IDictionary)target; - - // As per JsonPatch spec, if a key already exists, adding should replace the existing value - dictionary[segment] = value; - - errorMessage = null; - return true; - } - - public bool TryGet( - object target, - string segment, - IContractResolver contractResolver, - out object value, - out string errorMessage) - { - var dictionary = (IDictionary)target; - - value = dictionary[segment]; - errorMessage = null; - return true; - } - - public bool TryRemove( - object target, - string segment, - IContractResolver contractResolver, - out string errorMessage) - { - var dictionary = (IDictionary)target; - - // As per JsonPatch spec, the target location must exist for remove to be successful - if (!dictionary.Contains(segment)) - { - errorMessage = Resources.FormatTargetLocationAtPathSegmentNotFound(segment); - return false; - } - - dictionary.Remove(segment); - errorMessage = null; - return true; - } - - public bool TryReplace( - object target, - string segment, - IContractResolver contractResolver, - object value, - out string errorMessage) - { - var dictionary = (IDictionary)target; - - // As per JsonPatch spec, the target location must exist for remove to be successful - if (!dictionary.Contains(segment)) - { - errorMessage = Resources.FormatTargetLocationAtPathSegmentNotFound(segment); - return false; - } - - dictionary[segment] = value; - errorMessage = null; - return true; - } - - public bool TryTraverse( - object target, - string segment, - IContractResolver contractResolver, - out object nextTarget, - out string errorMessage) - { - var dictionary = target as IDictionary; - if (dictionary == null) - { - nextTarget = null; - errorMessage = null; - return false; - } - - if (dictionary.Contains(segment)) - { - nextTarget = dictionary[segment]; - errorMessage = null; - return true; - } - else - { - nextTarget = null; - errorMessage = null; - return false; - } - } - } -} diff --git a/src/Microsoft.AspNetCore.JsonPatch/Internal/ExpandoObjectAdapter.cs b/src/Microsoft.AspNetCore.JsonPatch/Internal/DictionaryAdapterOfTU.cs similarity index 52% rename from src/Microsoft.AspNetCore.JsonPatch/Internal/ExpandoObjectAdapter.cs rename to src/Microsoft.AspNetCore.JsonPatch/Internal/DictionaryAdapterOfTU.cs index c35d1b702c..67fd33e231 100644 --- a/src/Microsoft.AspNetCore.JsonPatch/Internal/ExpandoObjectAdapter.cs +++ b/src/Microsoft.AspNetCore.JsonPatch/Internal/DictionaryAdapterOfTU.cs @@ -2,12 +2,11 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System.Collections.Generic; -using System.Dynamic; using Newtonsoft.Json.Serialization; namespace Microsoft.AspNetCore.JsonPatch.Internal { - public class ExpandoObjectAdapter : IAdapter + public class DictionaryAdapter : IAdapter { public bool TryAdd( object target, @@ -18,11 +17,20 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal { var contract = (JsonDictionaryContract)contractResolver.ResolveContract(target.GetType()); var key = contract.DictionaryKeyResolver(segment); - var dictionary = (IDictionary)target; + var dictionary = (IDictionary)target; // As per JsonPatch spec, if a key already exists, adding should replace the existing value - dictionary[key] = ConvertValue(dictionary, key, value); + if (!TryConvertKey(key, out var convertedKey, out errorMessage)) + { + return false; + } + if (!TryConvertValue(value, out var convertedValue, out errorMessage)) + { + return false; + } + + dictionary[convertedKey] = convertedValue; errorMessage = null; return true; } @@ -36,10 +44,22 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal { var contract = (JsonDictionaryContract)contractResolver.ResolveContract(target.GetType()); var key = contract.DictionaryKeyResolver(segment); - var dictionary = (IDictionary)target; + var dictionary = (IDictionary)target; - value = dictionary[key]; + if (!TryConvertKey(key, out var convertedKey, out errorMessage)) + { + value = null; + return false; + } + if (!dictionary.ContainsKey(convertedKey)) + { + value = null; + errorMessage = Resources.FormatTargetLocationAtPathSegmentNotFound(segment); + return false; + } + + value = dictionary[convertedKey]; errorMessage = null; return true; } @@ -52,16 +72,21 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal { var contract = (JsonDictionaryContract)contractResolver.ResolveContract(target.GetType()); var key = contract.DictionaryKeyResolver(segment); - var dictionary = (IDictionary)target; + var dictionary = (IDictionary)target; + + if (!TryConvertKey(key, out var convertedKey, out errorMessage)) + { + return false; + } // As per JsonPatch spec, the target location must exist for remove to be successful - if (!dictionary.ContainsKey(key)) + if (!dictionary.ContainsKey(convertedKey)) { errorMessage = Resources.FormatTargetLocationAtPathSegmentNotFound(segment); return false; } - dictionary.Remove(key); + dictionary.Remove(convertedKey); errorMessage = null; return true; @@ -76,16 +101,26 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal { var contract = (JsonDictionaryContract)contractResolver.ResolveContract(target.GetType()); var key = contract.DictionaryKeyResolver(segment); - var dictionary = (IDictionary)target; + var dictionary = (IDictionary)target; + + if (!TryConvertKey(key, out var convertedKey, out errorMessage)) + { + return false; + } // As per JsonPatch spec, the target location must exist for remove to be successful - if (!dictionary.ContainsKey(key)) + if (!dictionary.ContainsKey(convertedKey)) { errorMessage = Resources.FormatTargetLocationAtPathSegmentNotFound(segment); return false; } - dictionary[key] = ConvertValue(dictionary, key, value); + if (!TryConvertValue(value, out var convertedValue, out errorMessage)) + { + return false; + } + + dictionary[convertedKey] = convertedValue; errorMessage = null; return true; @@ -98,21 +133,19 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal out object nextTarget, out string errorMessage) { - var expandoObject = target as ExpandoObject; - if (expandoObject == null) + var contract = (JsonDictionaryContract)contractResolver.ResolveContract(target.GetType()); + var key = contract.DictionaryKeyResolver(segment); + var dictionary = (IDictionary)target; + + if (!TryConvertKey(key, out var convertedKey, out errorMessage)) { - errorMessage = null; nextTarget = null; return false; } - var contract = (JsonDictionaryContract)contractResolver.ResolveContract(target.GetType()); - var key = contract.DictionaryKeyResolver(segment); - var dictionary = (IDictionary)expandoObject; - - if (dictionary.ContainsKey(key)) + if (dictionary.ContainsKey(convertedKey)) { - nextTarget = dictionary[key]; + nextTarget = dictionary[convertedKey]; errorMessage = null; return true; } @@ -124,20 +157,38 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal } } - private object ConvertValue(IDictionary dictionary, string key, object newValue) + private bool TryConvertKey(string key, out TKey convertedKey, out string errorMessage) { - if (dictionary.TryGetValue(key, out var existingValue)) + var conversionResult = ConversionResultProvider.ConvertTo(key, typeof(TKey)); + if (conversionResult.CanBeConverted) { - if (existingValue != null) - { - var conversionResult = ConversionResultProvider.ConvertTo(newValue, existingValue.GetType()); - if (conversionResult.CanBeConverted) - { - return conversionResult.ConvertedInstance; - } - } + errorMessage = null; + convertedKey = (TKey)conversionResult.ConvertedInstance; + return true; + } + else + { + errorMessage = Resources.FormatInvalidPathSegment(key); + convertedKey = default(TKey); + return false; + } + } + + private bool TryConvertValue(object value, out TValue convertedValue, out string errorMessage) + { + var conversionResult = ConversionResultProvider.ConvertTo(value, typeof(TValue)); + if (conversionResult.CanBeConverted) + { + errorMessage = null; + convertedValue = (TValue)conversionResult.ConvertedInstance; + return true; + } + else + { + errorMessage = Resources.FormatInvalidValueForProperty(value); + convertedValue = default(TValue); + return false; } - return newValue; } } } diff --git a/src/Microsoft.AspNetCore.JsonPatch/Internal/ObjectVisitor.cs b/src/Microsoft.AspNetCore.JsonPatch/Internal/ObjectVisitor.cs index bbf6db4ff6..97f108c0a0 100644 --- a/src/Microsoft.AspNetCore.JsonPatch/Internal/ObjectVisitor.cs +++ b/src/Microsoft.AspNetCore.JsonPatch/Internal/ObjectVisitor.cs @@ -3,7 +3,9 @@ using System; using System.Collections; +using System.Collections.Generic; using System.Dynamic; +using Microsoft.AspNetCore.JsonPatch.Adapters; using Newtonsoft.Json.Serialization; namespace Microsoft.AspNetCore.JsonPatch.Internal @@ -49,22 +51,21 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal private IAdapter SelectAdapater(object targetObject) { - if (targetObject is ExpandoObject) - { - return new ExpandoObjectAdapter(); - } - else if (targetObject is IDynamicMetaObjectProvider) - { - return new DynamicObjectAdapter(); - } - else if (targetObject is IDictionary) - { - return new DictionaryAdapter(); - } - else if (targetObject is IList) + 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(); diff --git a/src/Microsoft.AspNetCore.JsonPatch/JsonPatchDocumentOfT.cs b/src/Microsoft.AspNetCore.JsonPatch/JsonPatchDocumentOfT.cs index c81c4e4d6c..d669970407 100644 --- a/src/Microsoft.AspNetCore.JsonPatch/JsonPatchDocumentOfT.cs +++ b/src/Microsoft.AspNetCore.JsonPatch/JsonPatchDocumentOfT.cs @@ -37,18 +37,8 @@ namespace Microsoft.AspNetCore.JsonPatch // Create from list of operations public JsonPatchDocument(List> operations, IContractResolver contractResolver) { - if (operations == null) - { - throw new ArgumentNullException(nameof(operations)); - } - - if (contractResolver == null) - { - throw new ArgumentNullException(nameof(contractResolver)); - } - - Operations = operations; - ContractResolver = contractResolver; + Operations = operations ?? throw new ArgumentNullException(nameof(operations)); + ContractResolver = contractResolver ?? throw new ArgumentNullException(nameof(contractResolver)); } /// diff --git a/src/Microsoft.AspNetCore.JsonPatch/Properties/Resources.Designer.cs b/src/Microsoft.AspNetCore.JsonPatch/Properties/Resources.Designer.cs index cd99292061..896a3d2ad4 100644 --- a/src/Microsoft.AspNetCore.JsonPatch/Properties/Resources.Designer.cs +++ b/src/Microsoft.AspNetCore.JsonPatch/Properties/Resources.Designer.cs @@ -206,6 +206,20 @@ namespace Microsoft.AspNetCore.JsonPatch internal static string FormatPatchNotSupportedForNonGenericLists(object p0) => string.Format(CultureInfo.CurrentCulture, GetString("PatchNotSupportedForNonGenericLists"), p0); + /// + /// The provided path segment '{0}' cannot be converted to the target type. + /// + internal static string InvalidPathSegment + { + get => GetString("InvalidPathSegment"); + } + + /// + /// The provided path segment '{0}' cannot be converted to the target type. + /// + internal static string FormatInvalidPathSegment(object p0) + => string.Format(CultureInfo.CurrentCulture, GetString("InvalidPathSegment"), p0); + /// /// The target location specified by path segment '{0}' was not found. /// diff --git a/src/Microsoft.AspNetCore.JsonPatch/Resources.resx b/src/Microsoft.AspNetCore.JsonPatch/Resources.resx index 87ed5c0a17..0b67084233 100644 --- a/src/Microsoft.AspNetCore.JsonPatch/Resources.resx +++ b/src/Microsoft.AspNetCore.JsonPatch/Resources.resx @@ -144,6 +144,9 @@ Invalid JsonPatch operation '{0}'. + + The provided path segment '{0}' cannot be converted to the target type. + The provided string '{0}' is an invalid path. diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/DictionaryAdapterTest.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/DictionaryAdapterTest.cs index 084aa57379..cfb99d61ce 100644 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/DictionaryAdapterTest.cs +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/DictionaryAdapterTest.cs @@ -3,7 +3,6 @@ using System; using System.Collections.Generic; -using Moq; using Newtonsoft.Json.Serialization; using Xunit; @@ -15,33 +14,83 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal public void Add_KeyWhichAlreadyExists_ReplacesExistingValue() { // Arrange - var nameKey = "Name"; - var dictionary = new Dictionary(StringComparer.Ordinal); - dictionary[nameKey] = "Mike"; - var dictionaryAdapter = new DictionaryAdapter(); - var resolver = new Mock(MockBehavior.Strict); + var key = "Status"; + var dictionary = new Dictionary(StringComparer.Ordinal); + dictionary[key] = 404; + var dictionaryAdapter = new DictionaryAdapter(); + var resolver = new DefaultContractResolver(); // Act - var addStatus = dictionaryAdapter.TryAdd(dictionary, nameKey, resolver.Object, "James", out var message); + var addStatus = dictionaryAdapter.TryAdd(dictionary, key, resolver, 200, out var message); // Assert Assert.True(addStatus); Assert.True(string.IsNullOrEmpty(message), "Expected no error message"); Assert.Single(dictionary); - Assert.Equal("James", dictionary[nameKey]); + Assert.Equal(200, dictionary[key]); + } + + [Fact] + public void Add_IntKeyWhichAlreadyExists_ReplacesExistingValue() + { + // Arrange + var intKey = 1; + var dictionary = new Dictionary(); + dictionary[intKey] = "Mike"; + var dictionaryAdapter = new DictionaryAdapter(); + var resolver = new DefaultContractResolver(); + + // Act + var addStatus = dictionaryAdapter.TryAdd(dictionary, intKey.ToString(), resolver, "James", out var message); + + // Assert + Assert.True(addStatus); + Assert.True(string.IsNullOrEmpty(message), "Expected no error message"); + Assert.Single(dictionary); + Assert.Equal("James", dictionary[intKey]); + } + + [Fact] + public void GetInvalidKey_ThrowsInvalidPathSegmentException() + { + // Arrange + var dictionaryAdapter = new DictionaryAdapter(); + var resolver = new DefaultContractResolver(); + var key = 1; + var dictionary = new Dictionary(); + + // Act + var addStatus = dictionaryAdapter.TryAdd(dictionary, key.ToString(), resolver, "James", out var message); + + // Assert + Assert.True(addStatus); + Assert.True(string.IsNullOrEmpty(message), "Expected no error message"); + Assert.Single(dictionary); + Assert.Equal("James", dictionary[key]); + + // Act + var guidKey = new Guid(); + var getStatus = dictionaryAdapter.TryGet(dictionary, guidKey.ToString(), resolver, out var outValue, out message); + + // Assert + Assert.False(getStatus); + Assert.Equal( + string.Format("The provided path segment '{0}' cannot be converted to the target type.", guidKey.ToString()), + message); + Assert.Null(outValue); } [Fact] public void Get_UsingCaseSensitiveKey_FailureScenario() { // Arrange - var dictionaryAdapter = new DictionaryAdapter(); - var resolver = new Mock(MockBehavior.Strict); + var dictionaryAdapter = new DictionaryAdapter(); + var resolver = new DefaultContractResolver(); var nameKey = "Name"; var dictionary = new Dictionary(StringComparer.Ordinal); // Act - var addStatus = dictionaryAdapter.TryAdd(dictionary, nameKey, resolver.Object, "James", out var message); + var addStatus = dictionaryAdapter.TryAdd(dictionary, nameKey, resolver, "James", out var message); // Assert Assert.True(addStatus); @@ -50,11 +99,13 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal Assert.Equal("James", dictionary[nameKey]); // Act - addStatus = dictionaryAdapter.TryGet(dictionary, nameKey.ToUpper(), resolver.Object, out var outValue, out message); + var getStatus = dictionaryAdapter.TryGet(dictionary, nameKey.ToUpper(), resolver, out var outValue, out message); // Assert - Assert.True(addStatus); - Assert.True(string.IsNullOrEmpty(message), "Expected no error message"); + Assert.False(getStatus); + Assert.Equal( + string.Format("The target location specified by path segment '{0}' was not found.", nameKey.ToUpper()), + message); Assert.Null(outValue); } @@ -62,13 +113,13 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal public void Get_UsingCaseSensitiveKey_SuccessScenario() { // Arrange - var dictionaryAdapter = new DictionaryAdapter(); - var resolver = new Mock(MockBehavior.Strict); + var dictionaryAdapter = new DictionaryAdapter(); + var resolver = new DefaultContractResolver(); var nameKey = "Name"; var dictionary = new Dictionary(StringComparer.Ordinal); // Act - var addStatus = dictionaryAdapter.TryAdd(dictionary, nameKey, resolver.Object, "James", out var message); + var addStatus = dictionaryAdapter.TryAdd(dictionary, nameKey, resolver, "James", out var message); // Assert Assert.True(addStatus); @@ -77,7 +128,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal Assert.Equal("James", dictionary[nameKey]); // Act - addStatus = dictionaryAdapter.TryGet(dictionary, nameKey, resolver.Object, out var outValue, out message); + addStatus = dictionaryAdapter.TryGet(dictionary, nameKey, resolver, out var outValue, out message); // Assert Assert.True(addStatus); @@ -92,11 +143,11 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal var nameKey = "Name"; var dictionary = new Dictionary(StringComparer.Ordinal); dictionary.Add(nameKey, "Mike"); - var dictionaryAdapter = new DictionaryAdapter(); - var resolver = new Mock(MockBehavior.Strict); + var dictionaryAdapter = new DictionaryAdapter(); + var resolver = new DefaultContractResolver(); // Act - var replaceStatus = dictionaryAdapter.TryReplace(dictionary, nameKey, resolver.Object, "James", out var message); + var replaceStatus = dictionaryAdapter.TryReplace(dictionary, nameKey, resolver, "James", out var message); // Assert Assert.True(replaceStatus); @@ -105,17 +156,58 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal Assert.Equal("James", dictionary[nameKey]); } + [Fact] + public void ReplacingExistingItem_WithGuidKey() + { + // Arrange + var guidKey = new Guid(); + var dictionary = new Dictionary(); + dictionary.Add(guidKey, "Mike"); + var dictionaryAdapter = new DictionaryAdapter(); + var resolver = new DefaultContractResolver(); + + // Act + var replaceStatus = dictionaryAdapter.TryReplace(dictionary, guidKey.ToString(), resolver, "James", out var message); + + // Assert + Assert.True(replaceStatus); + Assert.True(string.IsNullOrEmpty(message), "Expected no error message"); + Assert.Single(dictionary); + Assert.Equal("James", dictionary[guidKey]); + } + + [Fact] + public void ReplacingWithInvalidValue_ThrowsInvalidValueForPropertyException() + { + // Arrange + var guidKey = new Guid(); + var dictionary = new Dictionary(); + dictionary.Add(guidKey, 5); + var dictionaryAdapter = new DictionaryAdapter(); + var resolver = new DefaultContractResolver(); + + // Act + var replaceStatus = dictionaryAdapter.TryReplace(dictionary, guidKey.ToString(), resolver, "test", out var message); + + // Assert + Assert.False(replaceStatus); + Assert.Equal( + string.Format("The value '{0}' is invalid for target location.", "test"), + message); + Assert.Equal(5, dictionary[guidKey]); + } + [Fact] public void Replace_NonExistingKey_Fails() { // Arrange var nameKey = "Name"; var dictionary = new Dictionary(StringComparer.Ordinal); - var dictionaryAdapter = new DictionaryAdapter(); - var resolver = new Mock(MockBehavior.Strict); + var dictionaryAdapter = new DictionaryAdapter(); + var resolver = new DefaultContractResolver(); // Act - var replaceStatus = dictionaryAdapter.TryReplace(dictionary, nameKey, resolver.Object, "Mike", out var message); + var replaceStatus = dictionaryAdapter.TryReplace(dictionary, nameKey, resolver, "Mike", out var message); // Assert Assert.False(replaceStatus); @@ -131,11 +223,11 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal // Arrange var nameKey = "Name"; var dictionary = new Dictionary(StringComparer.Ordinal); - var dictionaryAdapter = new DictionaryAdapter(); - var resolver = new Mock(MockBehavior.Strict); + var dictionaryAdapter = new DictionaryAdapter(); + var resolver = new DefaultContractResolver(); // Act - var removeStatus = dictionaryAdapter.TryRemove(dictionary, nameKey, resolver.Object, out var message); + var removeStatus = dictionaryAdapter.TryRemove(dictionary, nameKey, resolver, out var message); // Assert Assert.False(removeStatus); @@ -152,11 +244,30 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal var nameKey = "Name"; var dictionary = new Dictionary(StringComparer.Ordinal); dictionary[nameKey] = "James"; - var dictionaryAdapter = new DictionaryAdapter(); - var resolver = new Mock(MockBehavior.Strict); + var dictionaryAdapter = new DictionaryAdapter(); + var resolver = new DefaultContractResolver(); // Act - var removeStatus = dictionaryAdapter.TryRemove(dictionary, nameKey, resolver.Object, out var message); + var removeStatus = dictionaryAdapter.TryRemove(dictionary, nameKey, resolver, out var message); + + //Assert + Assert.True(removeStatus); + Assert.True(string.IsNullOrEmpty(message), "Expected no error message"); + Assert.Empty(dictionary); + } + + [Fact] + public void Remove_RemovesFromDictionary_WithUriKey() + { + // Arrange + var uriKey = new Uri("http://www.test.com/name"); + var dictionary = new Dictionary(); + dictionary[uriKey] = "James"; + var dictionaryAdapter = new DictionaryAdapter(); + var resolver = new DefaultContractResolver(); + + // Act + var removeStatus = dictionaryAdapter.TryRemove(dictionary, uriKey.ToString(), resolver, out var message); //Assert Assert.True(removeStatus); diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/ReplaceOperationTests.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/ReplaceOperationTests.cs index 88d1662e1d..5d1fa77d85 100644 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/ReplaceOperationTests.cs +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/ReplaceOperationTests.cs @@ -5,8 +5,6 @@ using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Dynamic; -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; using Xunit; namespace Microsoft.AspNetCore.JsonPatch.Internal @@ -26,11 +24,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal var patchDoc = new JsonPatchDocument(); patchDoc.Replace("GuidValue", newGuid); - // serialize & deserialize - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserizalized = JsonConvert.DeserializeObject(serialized); - - deserizalized.ApplyTo(doc); + patchDoc.ApplyTo(doc); Assert.Equal(newGuid, doc.GuidValue); } @@ -46,11 +40,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal var patchDoc = new JsonPatchDocument(); patchDoc.Replace("GuidValue", newGuid); - // serialize & deserialize - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserizalized = JsonConvert.DeserializeObject(serialized); - - deserizalized.ApplyTo(doc); + patchDoc.ApplyTo(doc); Assert.Equal(newGuid, doc.GuidValue); } @@ -71,11 +61,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal var patchDoc = new JsonPatchDocument(); patchDoc.Replace("nestedobject/GuidValue", newGuid); - // serialize & deserialize - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserizalized = JsonConvert.DeserializeObject(serialized); - - deserizalized.ApplyTo(doc); + patchDoc.ApplyTo(doc); Assert.Equal(newGuid, doc.NestedObject.GuidValue); } @@ -99,11 +85,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal var patchDoc = new JsonPatchDocument(); patchDoc.Replace("SimpleDTO", newDTO); - // serialize & deserialize - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject(serialized); - - deserialized.ApplyTo(doc); + patchDoc.ApplyTo(doc); Assert.Equal(1, doc.SimpleDTO.DoubleValue); Assert.Equal(0, doc.SimpleDTO.IntegerValue); @@ -120,10 +102,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal var patchDoc = new JsonPatchDocument(); patchDoc.Replace("IntegerList/0", 5); - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject(serialized); - - deserialized.ApplyTo(doc); + patchDoc.ApplyTo(doc); Assert.Equal(new List() { 5, 2, 3 }, doc.IntegerList); } @@ -138,10 +117,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal var patchDoc = new JsonPatchDocument(); patchDoc.Replace("IntegerList", new List() { 4, 5, 6 }); - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject(serialized); - - deserialized.ApplyTo(doc); + patchDoc.ApplyTo(doc); Assert.Equal(new List() { 4, 5, 6 }, doc.IntegerList); } @@ -159,10 +135,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal var patchDoc = new JsonPatchDocument(); patchDoc.Replace("SimpleDTOList/0/IntegerList/0", 4); - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject(serialized); - - deserialized.ApplyTo(doc); + patchDoc.ApplyTo(doc); Assert.Equal(4, doc.SimpleDTOList[0].IntegerList[0]); } @@ -180,10 +153,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal var patchDoc = new JsonPatchDocument(); patchDoc.Replace("SimpleDTOList/0/IntegerList/-", 4); - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject(serialized); - - deserialized.ApplyTo(doc); + patchDoc.ApplyTo(doc); Assert.Equal(4, doc.SimpleDTOList[0].IntegerList[2]); } @@ -198,10 +168,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal var patchDoc = new JsonPatchDocument(); patchDoc.Replace("IntegerList", new List() { 4, 5, 6 }); - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject(serialized); - - deserialized.ApplyTo(doc); + patchDoc.ApplyTo(doc); Assert.Equal(new List() { 4, 5, 6 }, doc.IntegerList); } @@ -216,10 +183,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal var patchDoc = new JsonPatchDocument(); patchDoc.Replace("IntegerList", new Collection() { 4, 5, 6 }); - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject(serialized); - - deserialized.ApplyTo(doc); + patchDoc.ApplyTo(doc); Assert.Equal(new List() { 4, 5, 6 }, doc.IntegerList); } @@ -234,9 +198,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal var patchDoc = new JsonPatchDocument(); patchDoc.Replace("IntegerList/-", 5); - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject(serialized); - deserialized.ApplyTo(doc); + patchDoc.ApplyTo(doc); Assert.Equal(new List() { 1, 2, 5 }, doc.IntegerList); } diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/ObjectVisitorTest.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/ObjectVisitorTest.cs index 5eddac8685..3384986c28 100644 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/ObjectVisitorTest.cs +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/ObjectVisitorTest.cs @@ -1,6 +1,7 @@ // 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.Dynamic; using Newtonsoft.Json.Serialization; @@ -87,7 +88,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal Assert.True(visitStatus); Assert.True(string.IsNullOrEmpty(message), "Expected no error message"); Assert.Same(expectedTargetObject, targetObject); - Assert.IsType(adapter); + Assert.Equal(typeof(DictionaryAdapter), adapter.GetType()); } public static IEnumerable ReturnsExpandoAdapterData @@ -107,7 +108,8 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal public void Visit_ValidPathToExpandoObject_ReturnsExpandoAdapter(object targetObject, string path, object expectedTargetObject) { // Arrange - var visitor = new ObjectVisitor(new ParsedPath(path), new DefaultContractResolver()); + var contractResolver = new DefaultContractResolver(); + var visitor = new ObjectVisitor(new ParsedPath(path), contractResolver); // Act var visitStatus = visitor.TryVisit(ref targetObject, out var adapter, out var message); @@ -116,7 +118,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal Assert.True(visitStatus); Assert.True(string.IsNullOrEmpty(message), "Expected no error message"); Assert.Same(expectedTargetObject, targetObject); - Assert.IsType(adapter); + Assert.Same(typeof(DictionaryAdapter), adapter.GetType()); } public static IEnumerable ReturnsPocoAdapterData From bf5c043de39d1f415baedc38f559db23ebc4d2e2 Mon Sep 17 00:00:00 2001 From: Jass Bagga Date: Mon, 11 Sep 2017 09:54:29 -0700 Subject: [PATCH 157/221] Refactor GetPath in JsonPatchDocumentOfT (#107) Addresses #98 --- .../JsonPatchDocumentOfT.cs | 167 ++++++++---------- .../Properties/AssemblyInfo.cs | 7 + .../Properties/Resources.Designer.cs | 42 +++-- .../Resources.resx | 3 + .../JsonPatchDocumentGetPathTest.cs | 124 +++++++++++++ ...nPatchDocumentJsonPropertyAttributeTest.cs | 31 ++++ ...Microsoft.AspNetCore.JsonPatch.Test.csproj | 4 + 7 files changed, 274 insertions(+), 104 deletions(-) create mode 100644 src/Microsoft.AspNetCore.JsonPatch/Properties/AssemblyInfo.cs create mode 100644 test/Microsoft.AspNetCore.JsonPatch.Test/JsonPatchDocumentGetPathTest.cs diff --git a/src/Microsoft.AspNetCore.JsonPatch/JsonPatchDocumentOfT.cs b/src/Microsoft.AspNetCore.JsonPatch/JsonPatchDocumentOfT.cs index d669970407..33e1e5033f 100644 --- a/src/Microsoft.AspNetCore.JsonPatch/JsonPatchDocumentOfT.cs +++ b/src/Microsoft.AspNetCore.JsonPatch/JsonPatchDocumentOfT.cs @@ -58,7 +58,7 @@ namespace Microsoft.AspNetCore.JsonPatch Operations.Add(new Operation( "add", - GetPath(path), + GetPath(path, null), from: null, value: value)); @@ -85,7 +85,7 @@ namespace Microsoft.AspNetCore.JsonPatch Operations.Add(new Operation( "add", - GetPath(path) + "/" + position, + GetPath(path, position.ToString()), from: null, value: value)); @@ -93,7 +93,7 @@ namespace Microsoft.AspNetCore.JsonPatch } /// - /// At value at end of list + /// Add value to the end of the list /// /// value type /// target location @@ -108,7 +108,7 @@ namespace Microsoft.AspNetCore.JsonPatch Operations.Add(new Operation( "add", - GetPath(path) + "/-", + GetPath(path, "-"), from: null, value: value)); @@ -128,7 +128,7 @@ namespace Microsoft.AspNetCore.JsonPatch throw new ArgumentNullException(nameof(path)); } - Operations.Add(new Operation("remove", GetPath(path), from: null)); + Operations.Add(new Operation("remove", GetPath(path, null), from: null)); return this; } @@ -149,7 +149,7 @@ namespace Microsoft.AspNetCore.JsonPatch Operations.Add(new Operation( "remove", - GetPath(path) + "/" + position, + GetPath(path, position.ToString()), from: null)); return this; @@ -170,7 +170,7 @@ namespace Microsoft.AspNetCore.JsonPatch Operations.Add(new Operation( "remove", - GetPath(path) + "/-", + GetPath(path, "-"), from: null)); return this; @@ -192,7 +192,7 @@ namespace Microsoft.AspNetCore.JsonPatch Operations.Add(new Operation( "replace", - GetPath(path), + GetPath(path, null), from: null, value: value)); @@ -217,7 +217,7 @@ namespace Microsoft.AspNetCore.JsonPatch Operations.Add(new Operation( "replace", - GetPath(path) + "/" + position, + GetPath(path, position.ToString()), from: null, value: value)); @@ -240,7 +240,7 @@ namespace Microsoft.AspNetCore.JsonPatch Operations.Add(new Operation( "replace", - GetPath(path) + "/-", + GetPath(path, "-"), from: null, value: value)); @@ -270,8 +270,8 @@ namespace Microsoft.AspNetCore.JsonPatch Operations.Add(new Operation( "move", - GetPath(path), - GetPath(from))); + GetPath(path, null), + GetPath(from, null))); return this; } @@ -301,8 +301,8 @@ namespace Microsoft.AspNetCore.JsonPatch Operations.Add(new Operation( "move", - GetPath(path), - GetPath(from) + "/" + positionFrom)); + GetPath(path, null), + GetPath(from, positionFrom.ToString()))); return this; } @@ -332,8 +332,8 @@ namespace Microsoft.AspNetCore.JsonPatch Operations.Add(new Operation( "move", - GetPath(path) + "/" + positionTo, - GetPath(from))); + GetPath(path, positionTo.ToString()), + GetPath(from, null))); return this; } @@ -365,8 +365,8 @@ namespace Microsoft.AspNetCore.JsonPatch Operations.Add(new Operation( "move", - GetPath(path) + "/" + positionTo, - GetPath(from) + "/" + positionFrom)); + GetPath(path, positionTo.ToString()), + GetPath(from, positionFrom.ToString()))); return this; } @@ -396,8 +396,8 @@ namespace Microsoft.AspNetCore.JsonPatch Operations.Add(new Operation( "move", - GetPath(path) + "/-", - GetPath(from) + "/" + positionFrom)); + GetPath(path, "-"), + GetPath(from, positionFrom.ToString()))); return this; } @@ -425,8 +425,8 @@ namespace Microsoft.AspNetCore.JsonPatch Operations.Add(new Operation( "move", - GetPath(path) + "/-", - GetPath(from))); + GetPath(path, "-"), + GetPath(from, null))); return this; } @@ -454,8 +454,8 @@ namespace Microsoft.AspNetCore.JsonPatch Operations.Add(new Operation( "copy", - GetPath(path) - , GetPath(from))); + GetPath(path, null), + GetPath(from, null))); return this; } @@ -485,8 +485,8 @@ namespace Microsoft.AspNetCore.JsonPatch Operations.Add(new Operation( "copy", - GetPath(path), - GetPath(from) + "/" + positionFrom)); + GetPath(path, null), + GetPath(from, positionFrom.ToString()))); return this; } @@ -516,8 +516,8 @@ namespace Microsoft.AspNetCore.JsonPatch Operations.Add(new Operation( "copy", - GetPath(path) + "/" + positionTo, - GetPath(from))); + GetPath(path, positionTo.ToString()), + GetPath(from, null))); return this; } @@ -549,8 +549,8 @@ namespace Microsoft.AspNetCore.JsonPatch Operations.Add(new Operation( "copy", - GetPath(path) + "/" + positionTo, - GetPath(from) + "/" + positionFrom)); + GetPath(path, positionTo.ToString()), + GetPath(from, positionFrom.ToString()))); return this; } @@ -580,8 +580,8 @@ namespace Microsoft.AspNetCore.JsonPatch Operations.Add(new Operation( "copy", - GetPath(path) + "/-", - GetPath(from) + "/" + positionFrom)); + GetPath(path, "-"), + GetPath(from, positionFrom.ToString()))); return this; } @@ -609,8 +609,8 @@ namespace Microsoft.AspNetCore.JsonPatch Operations.Add(new Operation( "copy", - GetPath(path) + "/-", - GetPath(from))); + GetPath(path, "-"), + GetPath(from, null))); return this; } @@ -705,61 +705,57 @@ namespace Microsoft.AspNetCore.JsonPatch return allOps; } - private string GetPath(Expression> expr) + // Internal for testing + internal string GetPath(Expression> expr, string position) { - return "/" + GetPath(expr.Body, true).ToLowerInvariant(); + var segments = GetPathSegments(expr.Body); + var path = String.Join("/", segments); + if (position != null) + { + path += "/" + position; + if (segments.Count == 0) + { + return path.ToLowerInvariant(); + } + } + + return "/" + path.ToLowerInvariant(); } - private string GetPath(Expression expr, bool firstTime) + private List GetPathSegments(Expression expr) { + var listOfSegments = new List(); switch (expr.NodeType) { case ExpressionType.ArrayIndex: var binaryExpression = (BinaryExpression)expr; + listOfSegments.AddRange(GetPathSegments(binaryExpression.Left)); + listOfSegments.Add(binaryExpression.Right.ToString()); + return listOfSegments; - if (ContinueWithSubPath(binaryExpression.Left.NodeType, false)) - { - var leftFromBinaryExpression = GetPath(binaryExpression.Left, false); - return leftFromBinaryExpression + "/" + binaryExpression.Right.ToString(); - } - else - { - return binaryExpression.Right.ToString(); - } case ExpressionType.Call: var methodCallExpression = (MethodCallExpression)expr; + listOfSegments.AddRange(GetPathSegments(methodCallExpression.Object)); + listOfSegments.Add(EvaluateExpression(methodCallExpression.Arguments[0])); + return listOfSegments; - if (ContinueWithSubPath(methodCallExpression.Object.NodeType, false)) - { - var leftFromMemberCallExpression = GetPath(methodCallExpression.Object, false); - return leftFromMemberCallExpression + "/" + - GetIndexerInvocation(methodCallExpression.Arguments[0]); - } - else - { - return GetIndexerInvocation(methodCallExpression.Arguments[0]); - } case ExpressionType.Convert: - return GetPath(((UnaryExpression)expr).Operand, false); + listOfSegments.AddRange(GetPathSegments(((UnaryExpression)expr).Operand)); + return listOfSegments; + case ExpressionType.MemberAccess: var memberExpression = expr as MemberExpression; + listOfSegments.AddRange(GetPathSegments(memberExpression.Expression)); + // Get property name, respecting JsonProperty attribute + listOfSegments.Add(GetPropertyNameFromMemberExpression(memberExpression)); + return listOfSegments; - if (ContinueWithSubPath(memberExpression.Expression.NodeType, false)) - { - var left = GetPath(memberExpression.Expression, false); - // Get property name, respecting JsonProperty attribute - return left + "/" + GetPropertyNameFromMemberExpression(memberExpression); - } - else - { - // Get property name, respecting JsonProperty attribute - return GetPropertyNameFromMemberExpression(memberExpression); - } case ExpressionType.Parameter: // Fits "x => x" (the whole document which is "" as JSON pointer) - return firstTime ? string.Empty : null; + return listOfSegments; + default: - return string.Empty; + throw new InvalidOperationException(Resources.FormatExpressionTypeNotSupported(expr)); } } @@ -776,33 +772,24 @@ namespace Microsoft.AspNetCore.JsonPatch return null; } - private static bool ContinueWithSubPath(ExpressionType expressionType, bool firstTime) + private static bool ContinueWithSubPath(ExpressionType expressionType) { - if (firstTime) - { - return (expressionType == ExpressionType.ArrayIndex - || expressionType == ExpressionType.Call - || expressionType == ExpressionType.Convert - || expressionType == ExpressionType.MemberAccess - || expressionType == ExpressionType.Parameter); - } - else - { - return (expressionType == ExpressionType.ArrayIndex - || expressionType == ExpressionType.Call - || expressionType == ExpressionType.Convert - || expressionType == ExpressionType.MemberAccess); - } + return (expressionType == ExpressionType.ArrayIndex + || expressionType == ExpressionType.Call + || expressionType == ExpressionType.Convert + || expressionType == ExpressionType.MemberAccess); + } - private static string GetIndexerInvocation(Expression expression) + // Evaluates the value of the key or index which may be an int or a string, + // or some other expression type. + // The expression is converted to a delegate and the result of executing the delegate is returned as a string. + private static string EvaluateExpression(Expression expression) { var converted = Expression.Convert(expression, typeof(object)); var fakeParameter = Expression.Parameter(typeof(object), null); var lambda = Expression.Lambda>(converted, fakeParameter); - Func func; - - func = lambda.Compile(); + var func = lambda.Compile(); return Convert.ToString(func(null), CultureInfo.InvariantCulture); } diff --git a/src/Microsoft.AspNetCore.JsonPatch/Properties/AssemblyInfo.cs b/src/Microsoft.AspNetCore.JsonPatch/Properties/AssemblyInfo.cs new file mode 100644 index 0000000000..08e6f5e01c --- /dev/null +++ b/src/Microsoft.AspNetCore.JsonPatch/Properties/AssemblyInfo.cs @@ -0,0 +1,7 @@ + +// 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.Runtime.CompilerServices; + +[assembly: InternalsVisibleTo("Microsoft.AspNetCore.JsonPatch.Test, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")] diff --git a/src/Microsoft.AspNetCore.JsonPatch/Properties/Resources.Designer.cs b/src/Microsoft.AspNetCore.JsonPatch/Properties/Resources.Designer.cs index 896a3d2ad4..432fab2cbf 100644 --- a/src/Microsoft.AspNetCore.JsonPatch/Properties/Resources.Designer.cs +++ b/src/Microsoft.AspNetCore.JsonPatch/Properties/Resources.Designer.cs @@ -80,6 +80,20 @@ namespace Microsoft.AspNetCore.JsonPatch internal static string FormatCannotUpdateProperty(object p0) => string.Format(CultureInfo.CurrentCulture, GetString("CannotUpdateProperty"), p0); + /// + /// The expression '{0}' is not supported. + /// + internal static string ExpressionTypeNotSupported + { + get => GetString("ExpressionTypeNotSupported"); + } + + /// + /// The expression '{0}' is not supported. + /// + internal static string FormatExpressionTypeNotSupported(object p0) + => string.Format(CultureInfo.CurrentCulture, GetString("ExpressionTypeNotSupported"), p0); + /// /// The index value provided by path segment '{0}' is out of bounds of the array size. /// @@ -136,6 +150,20 @@ namespace Microsoft.AspNetCore.JsonPatch internal static string FormatInvalidJsonPatchOperation(object p0) => string.Format(CultureInfo.CurrentCulture, GetString("InvalidJsonPatchOperation"), p0); + /// + /// The provided path segment '{0}' cannot be converted to the target type. + /// + internal static string InvalidPathSegment + { + get => GetString("InvalidPathSegment"); + } + + /// + /// The provided path segment '{0}' cannot be converted to the target type. + /// + internal static string FormatInvalidPathSegment(object p0) + => string.Format(CultureInfo.CurrentCulture, GetString("InvalidPathSegment"), p0); + /// /// The provided string '{0}' is an invalid path. /// @@ -206,20 +234,6 @@ namespace Microsoft.AspNetCore.JsonPatch internal static string FormatPatchNotSupportedForNonGenericLists(object p0) => string.Format(CultureInfo.CurrentCulture, GetString("PatchNotSupportedForNonGenericLists"), p0); - /// - /// The provided path segment '{0}' cannot be converted to the target type. - /// - internal static string InvalidPathSegment - { - get => GetString("InvalidPathSegment"); - } - - /// - /// The provided path segment '{0}' cannot be converted to the target type. - /// - internal static string FormatInvalidPathSegment(object p0) - => string.Format(CultureInfo.CurrentCulture, GetString("InvalidPathSegment"), p0); - /// /// The target location specified by path segment '{0}' was not found. /// diff --git a/src/Microsoft.AspNetCore.JsonPatch/Resources.resx b/src/Microsoft.AspNetCore.JsonPatch/Resources.resx index 0b67084233..bf07e4a31e 100644 --- a/src/Microsoft.AspNetCore.JsonPatch/Resources.resx +++ b/src/Microsoft.AspNetCore.JsonPatch/Resources.resx @@ -132,6 +132,9 @@ The property at path '{0}' could not be updated. + + The expression '{0}' is not supported. Supported expressions include member access and indexer expressions. + The index value provided by path segment '{0}' is out of bounds of the array size. diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/JsonPatchDocumentGetPathTest.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/JsonPatchDocumentGetPathTest.cs new file mode 100644 index 0000000000..dcde4b442d --- /dev/null +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/JsonPatchDocumentGetPathTest.cs @@ -0,0 +1,124 @@ +// 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 Xunit; + +namespace Microsoft.AspNetCore.JsonPatch +{ + public class JsonPatchDocumentGetPathTest + { + [Fact] + public void ExpressionType_MemberAccess() + { + // Arrange + var patchDocument = new JsonPatchDocument(); + + // Act + var path = patchDocument.GetPath(p => p.SimpleObject.IntegerList, "-"); + + // Assert + Assert.Equal("/simpleobject/integerlist/-", path); + } + + [Fact] + public void ExpressionType_ArrayIndex() + { + // Arrange + var patchDocument = new JsonPatchDocument(); + + // Act + var path = patchDocument.GetPath(p => p[3], null); + + // Assert + Assert.Equal("/3", path); + } + + [Fact] + public void ExpressionType_Call() + { + // Arrange + var patchDocument = new JsonPatchDocument>(); + + // Act + var path = patchDocument.GetPath(p => p["key"], "3"); + + // Assert + Assert.Equal("/key/3", path); + } + + [Fact] + public void ExpressionType_Parameter_NullPosition() + { + // Arrange + var patchDocument = new JsonPatchDocument(); + + // Act + var path = patchDocument.GetPath(p => p, null); + + // Assert + Assert.Equal("/", path); + } + + [Fact] + public void ExpressionType_Parameter_WithPosition() + { + // Arrange + var patchDocument = new JsonPatchDocument(); + + // Act + var path = patchDocument.GetPath(p => p, "-"); + + // Assert + Assert.Equal("/-", path); + } + + [Fact] + public void ExpressionType_Convert() + { + // Arrange + var patchDocument = new JsonPatchDocument(); + + // Act + var path = patchDocument.GetPath(p => (BaseClass)p.DerivedObject, null); + + // Assert + Assert.Equal("/derivedobject", path); + } + + [Fact] + public void ExpressionType_NotSupported() + { + // Arrange + var patchDocument = new JsonPatchDocument(); + + // Act + var exception = Assert.Throws(() => + { + patchDocument.GetPath(p => p.IntegerValue >= 4, null); + }); + + // Assert + Assert.Equal( + string.Format("The expression '(p.IntegerValue >= 4)' is not supported. Supported expressions include member access and indexer expressions."), + exception.Message); + } + } + + internal class DerivedClass : BaseClass + { + public DerivedClass() + { + } + } + + internal class NestedObjectWithDerivedClass + { + public DerivedClass DerivedObject { get; set; } + } + + internal class BaseClass + { + } +} diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/JsonPatchDocumentJsonPropertyAttributeTest.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/JsonPatchDocumentJsonPropertyAttributeTest.cs index 3948b79484..50ab6a9f5b 100644 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/JsonPatchDocumentJsonPropertyAttributeTest.cs +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/JsonPatchDocumentJsonPropertyAttributeTest.cs @@ -1,6 +1,7 @@ // 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.Linq; using System.Reflection; using Newtonsoft.Json; @@ -11,6 +12,36 @@ namespace Microsoft.AspNetCore.JsonPatch { public class JsonPatchDocumentJsonPropertyAttributeTest { + [Fact] + public void Add_ToRoot_OfListOfObjects_AtEndOfList() + { + var patchDoc = new JsonPatchDocument>(); + patchDoc.Add(p => p, new JsonPropertyObject()); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = + JsonConvert.DeserializeObject>(serialized); + + // get path + var pathToCheck = deserialized.Operations.First().path; + Assert.Equal("/-", pathToCheck); + } + + [Fact] + public void Add_ToRoot_OfListOfObjects_AtGivenPosition() + { + var patchDoc = new JsonPatchDocument>(); + patchDoc.Add(p => p[3], new JsonPropertyObject()); + + var serialized = JsonConvert.SerializeObject(patchDoc); + var deserialized = + JsonConvert.DeserializeObject>(serialized); + + // get path + var pathToCheck = deserialized.Operations.First().path; + Assert.Equal("/3", pathToCheck); + } + [Fact] public void Add_WithExpression_RespectsJsonPropertyName_ForModelProperty() { diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/Microsoft.AspNetCore.JsonPatch.Test.csproj b/test/Microsoft.AspNetCore.JsonPatch.Test/Microsoft.AspNetCore.JsonPatch.Test.csproj index 2e4f68b538..6d7b403a79 100644 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/Microsoft.AspNetCore.JsonPatch.Test.csproj +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/Microsoft.AspNetCore.JsonPatch.Test.csproj @@ -14,4 +14,8 @@ + + + + From 34f59ad305166e1efe64d17f96c5e5e30d728628 Mon Sep 17 00:00:00 2001 From: Justin Kotalik Date: Thu, 21 Sep 2017 17:49:32 -0700 Subject: [PATCH 158/221] Increase Minimum Version of Visual Studio to 15.3.0 --- JsonPatch.sln | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/JsonPatch.sln b/JsonPatch.sln index 87b48a8ea1..f0b6a578f1 100644 --- a/JsonPatch.sln +++ b/JsonPatch.sln @@ -1,7 +1,7 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 15 VisualStudioVersion = 15.0.26815.3 -MinimumVisualStudioVersion = 10.0.40219.1 +MinimumVisualStudioVersion = 15.0.26730.03 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{430B59ED-F960-4D3A-8FFE-3370008E168D}" ProjectSection(SolutionItems) = preProject src\Directory.Build.props = src\Directory.Build.props From e4a412e1644dfea026b20c8625a6f5a636ee1134 Mon Sep 17 00:00:00 2001 From: Ryan Brandenburg Date: Wed, 20 Sep 2017 13:21:17 -0700 Subject: [PATCH 159/221] Update bootstrappers --- .appveyor.yml | 4 +- build.cmd | 2 +- build.sh | 197 +------------------------------------- run.cmd | 2 + build.ps1 => run.ps1 | 56 +++++++---- run.sh | 223 +++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 266 insertions(+), 218 deletions(-) create mode 100644 run.cmd rename build.ps1 => run.ps1 (73%) create mode 100755 run.sh diff --git a/.appveyor.yml b/.appveyor.yml index 31efd8196f..46038786c9 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -1,4 +1,4 @@ -init: +init: - git config --global core.autocrlf true branches: only: @@ -7,7 +7,7 @@ branches: - dev - /^(.*\/)?ci-.*$/ build_script: - - ps: .\build.ps1 + - ps: .\run.ps1 default-build clone_depth: 1 environment: global: diff --git a/build.cmd b/build.cmd index b6c8d24864..c0050bda12 100644 --- a/build.cmd +++ b/build.cmd @@ -1,2 +1,2 @@ @ECHO OFF -PowerShell -NoProfile -NoLogo -ExecutionPolicy unrestricted -Command "[System.Threading.Thread]::CurrentThread.CurrentCulture = ''; [System.Threading.Thread]::CurrentThread.CurrentUICulture = '';& '%~dp0build.ps1' %*; exit $LASTEXITCODE" +PowerShell -NoProfile -NoLogo -ExecutionPolicy unrestricted -Command "[System.Threading.Thread]::CurrentThread.CurrentCulture = ''; [System.Threading.Thread]::CurrentThread.CurrentUICulture = '';& '%~dp0run.ps1' default-build %*; exit $LASTEXITCODE" diff --git a/build.sh b/build.sh index 11cdbe5504..98a4b22765 100755 --- a/build.sh +++ b/build.sh @@ -1,199 +1,8 @@ #!/usr/bin/env bash set -euo pipefail - -# -# variables -# - -RESET="\033[0m" -RED="\033[0;31m" -MAGENTA="\033[0;95m" DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" -[ -z "${DOTNET_HOME:-}" ] && DOTNET_HOME="$HOME/.dotnet" -config_file="$DIR/version.xml" -verbose=false -update=false -repo_path="$DIR" -channel='' -tools_source='' -# -# Functions -# -__usage() { - echo "Usage: $(basename "${BASH_SOURCE[0]}") [options] [[--] ...]" - echo "" - echo "Arguments:" - echo " ... Arguments passed to MSBuild. Variable number of arguments allowed." - echo "" - echo "Options:" - echo " --verbose Show verbose output." - echo " -c|--channel The channel of KoreBuild to download. Overrides the value from the config file.." - echo " --config-file TThe path to the configuration file that stores values. Defaults to version.xml." - echo " -d|--dotnet-home The directory where .NET Core tools will be stored. Defaults to '\$DOTNET_HOME' or '\$HOME/.dotnet." - echo " --path The directory to build. Defaults to the directory containing the script." - echo " -s|--tools-source The base url where build tools can be downloaded. Overrides the value from the config file." - echo " -u|--update Update to the latest KoreBuild even if the lock file is present." - echo "" - echo "Description:" - echo " This function will create a file \$DIR/korebuild-lock.txt. This lock file can be committed to source, but does not have to be." - echo " When the lockfile is not present, KoreBuild will create one using latest available version from \$channel." - - if [[ "${1:-}" != '--no-exit' ]]; then - exit 2 - fi -} - -get_korebuild() { - local version - local lock_file="$repo_path/korebuild-lock.txt" - if [ ! -f "$lock_file" ] || [ "$update" = true ]; then - __get_remote_file "$tools_source/korebuild/channels/$channel/latest.txt" "$lock_file" - fi - version="$(grep 'version:*' -m 1 "$lock_file")" - if [[ "$version" == '' ]]; then - __error "Failed to parse version from $lock_file. Expected a line that begins with 'version:'" - return 1 - fi - version="$(echo "${version#version:}" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')" - local korebuild_path="$DOTNET_HOME/buildtools/korebuild/$version" - - { - if [ ! -d "$korebuild_path" ]; then - mkdir -p "$korebuild_path" - local remote_path="$tools_source/korebuild/artifacts/$version/korebuild.$version.zip" - tmpfile="$(mktemp)" - echo -e "${MAGENTA}Downloading KoreBuild ${version}${RESET}" - if __get_remote_file "$remote_path" "$tmpfile"; then - unzip -q -d "$korebuild_path" "$tmpfile" - fi - rm "$tmpfile" || true - fi - - source "$korebuild_path/KoreBuild.sh" - } || { - if [ -d "$korebuild_path" ]; then - echo "Cleaning up after failed installation" - rm -rf "$korebuild_path" || true - fi - return 1 - } -} - -__error() { - echo -e "${RED}$*${RESET}" 1>&2 -} - -__machine_has() { - hash "$1" > /dev/null 2>&1 - return $? -} - -__get_remote_file() { - local remote_path=$1 - local local_path=$2 - - if [[ "$remote_path" != 'http'* ]]; then - cp "$remote_path" "$local_path" - return 0 - fi - - local failed=false - if __machine_has wget; then - wget --tries 10 --quiet -O "$local_path" "$remote_path" || failed=true - else - failed=true - fi - - if [ "$failed" = true ] && __machine_has curl; then - failed=false - curl --retry 10 -sSL -f --create-dirs -o "$local_path" "$remote_path" || failed=true - fi - - if [ "$failed" = true ]; then - __error "Download failed: $remote_path" 1>&2 - return 1 - fi -} - -__read_dom () { local IFS=\> ; read -r -d \< ENTITY CONTENT ;} - -# -# main -# - -while [[ $# -gt 0 ]]; do - case $1 in - -\?|-h|--help) - __usage --no-exit - exit 0 - ;; - -c|--channel|-Channel) - shift - channel="${1:-}" - [ -z "$channel" ] && __usage - ;; - --config-file|-ConfigFile) - shift - config_file="${1:-}" - [ -z "$config_file" ] && __usage - ;; - -d|--dotnet-home|-DotNetHome) - shift - DOTNET_HOME="${1:-}" - [ -z "$DOTNET_HOME" ] && __usage - ;; - --path|-Path) - shift - repo_path="${1:-}" - [ -z "$repo_path" ] && __usage - ;; - -s|--tools-source|-ToolsSource) - shift - tools_source="${1:-}" - [ -z "$tools_source" ] && __usage - ;; - -u|--update|-Update) - update=true - ;; - --verbose|-Verbose) - verbose=true - ;; - --) - shift - break - ;; - *) - break - ;; - esac - shift -done - -if ! __machine_has unzip; then - __error 'Missing required command: unzip' - exit 1 -fi - -if ! __machine_has curl && ! __machine_has wget; then - __error 'Missing required command. Either wget or curl is required.' - exit 1 -fi - -if [ -f "$config_file" ]; then - comment=false - while __read_dom; do - if [ "$comment" = true ]; then [[ $CONTENT == *'-->'* ]] && comment=false ; continue; fi - if [[ $ENTITY == '!--'* ]]; then comment=true; continue; fi - if [ -z "$channel" ] && [[ $ENTITY == "KoreBuildChannel" ]]; then channel=$CONTENT; fi - if [ -z "$tools_source" ] && [[ $ENTITY == "KoreBuildToolsSource" ]]; then tools_source=$CONTENT; fi - done < "$config_file" -fi - -[ -z "$channel" ] && channel='dev' -[ -z "$tools_source" ] && tools_source='https://aspnetcore.blob.core.windows.net/buildtools' - -get_korebuild -install_tools "$tools_source" "$DOTNET_HOME" -invoke_repository_build "$repo_path" "$@" +# Call "sync" between "chmod" and execution to prevent "text file busy" error in Docker (aufs) +chmod +x "$DIR/run.sh"; sync +"$DIR/run.sh" default-build "$@" diff --git a/run.cmd b/run.cmd new file mode 100644 index 0000000000..d52d5c7e68 --- /dev/null +++ b/run.cmd @@ -0,0 +1,2 @@ +@ECHO OFF +PowerShell -NoProfile -NoLogo -ExecutionPolicy unrestricted -Command "[System.Threading.Thread]::CurrentThread.CurrentCulture = ''; [System.Threading.Thread]::CurrentThread.CurrentUICulture = '';& '%~dp0run.ps1' %*; exit $LASTEXITCODE" diff --git a/build.ps1 b/run.ps1 similarity index 73% rename from build.ps1 rename to run.ps1 index d5eb4d5cf2..49c2899856 100644 --- a/build.ps1 +++ b/run.ps1 @@ -3,10 +3,13 @@ <# .SYNOPSIS -Build this repository +Executes KoreBuild commands. .DESCRIPTION -Downloads korebuild if required. Then builds the repository. +Downloads korebuild if required. Then executes the KoreBuild command. To see available commands, execute with `-Command help`. + +.PARAMETER Command +The KoreBuild command to run. .PARAMETER Path The folder to build. Defaults to the folder containing this script. @@ -24,31 +27,32 @@ The base url where build tools can be downloaded. Overrides the value from the c Updates KoreBuild to the latest version even if a lock file is present. .PARAMETER ConfigFile -The path to the configuration file that stores values. Defaults to version.xml. +The path to the configuration file that stores values. Defaults to korebuild.json. -.PARAMETER MSBuildArgs -Arguments to be passed to MSBuild +.PARAMETER Arguments +Arguments to be passed to the command .NOTES This function will create a file $PSScriptRoot/korebuild-lock.txt. This lock file can be committed to source, but does not have to be. When the lockfile is not present, KoreBuild will create one using latest available version from $Channel. -The $ConfigFile is expected to be an XML file. It is optional, and the configuration values in it are optional as well. +The $ConfigFile is expected to be an JSON file. It is optional, and the configuration values in it are optional as well. Any options set +in the file are overridden by command line parameters. .EXAMPLE Example config file: -```xml - - - - dev - https://aspnetcore.blob.core.windows.net/buildtools - - +```json +{ + "$schema": "https://raw.githubusercontent.com/aspnet/BuildTools/dev/tools/korebuild.schema.json", + "channel": "dev", + "toolsSource": "https://aspnetcore.blob.core.windows.net/buildtools" +} ``` #> [CmdletBinding(PositionalBinding = $false)] param( + [Parameter(Mandatory=$true, Position = 0)] + [string]$Command, [string]$Path = $PSScriptRoot, [Alias('c')] [string]$Channel, @@ -58,9 +62,9 @@ param( [string]$ToolsSource, [Alias('u')] [switch]$Update, - [string]$ConfigFile = (Join-Path $PSScriptRoot 'version.xml'), + [string]$ConfigFile, [Parameter(ValueFromRemainingArguments = $true)] - [string[]]$MSBuildArgs + [string[]]$Arguments ) Set-StrictMode -Version 2 @@ -147,10 +151,20 @@ function Get-RemoteFile([string]$RemotePath, [string]$LocalPath) { # Load configuration or set defaults +$Path = Resolve-Path $Path +if (!$ConfigFile) { $ConfigFile = Join-Path $Path 'korebuild.json' } + if (Test-Path $ConfigFile) { - [xml] $config = Get-Content $ConfigFile - if (!($Channel)) { [string] $Channel = Select-Xml -Xml $config -XPath '/Project/PropertyGroup/KoreBuildChannel' } - if (!($ToolsSource)) { [string] $ToolsSource = Select-Xml -Xml $config -XPath '/Project/PropertyGroup/KoreBuildToolsSource' } + try { + $config = Get-Content -Raw -Encoding UTF8 -Path $ConfigFile | ConvertFrom-Json + if ($config) { + if (!($Channel) -and (Get-Member -Name 'channel' -InputObject $config)) { [string] $Channel = $config.channel } + if (!($ToolsSource) -and (Get-Member -Name 'toolsSource' -InputObject $config)) { [string] $ToolsSource = $config.toolsSource} + } + } catch { + Write-Warning "$ConfigFile could not be read. Its settings will be ignored." + Write-Warning $Error[0] + } } if (!$DotNetHome) { @@ -169,8 +183,8 @@ $korebuildPath = Get-KoreBuild Import-Module -Force -Scope Local (Join-Path $korebuildPath 'KoreBuild.psd1') try { - Install-Tools $ToolsSource $DotNetHome - Invoke-RepositoryBuild $Path @MSBuildArgs + Set-KoreBuildSettings -ToolsSource $ToolsSource -DotNetHome $DotNetHome -RepoPath $Path -ConfigFile $ConfigFile + Invoke-KoreBuildCommand $Command @Arguments } finally { Remove-Module 'KoreBuild' -ErrorAction Ignore diff --git a/run.sh b/run.sh new file mode 100755 index 0000000000..c278423acc --- /dev/null +++ b/run.sh @@ -0,0 +1,223 @@ +#!/usr/bin/env bash + +set -euo pipefail + +# +# variables +# + +RESET="\033[0m" +RED="\033[0;31m" +YELLOW="\033[0;33m" +MAGENTA="\033[0;95m" +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +[ -z "${DOTNET_HOME:-}" ] && DOTNET_HOME="$HOME/.dotnet" +verbose=false +update=false +repo_path="$DIR" +channel='' +tools_source='' + +# +# Functions +# +__usage() { + echo "Usage: $(basename "${BASH_SOURCE[0]}") command [options] [[--] ...]" + echo "" + echo "Arguments:" + echo " command The command to be run." + echo " ... Arguments passed to the command. Variable number of arguments allowed." + echo "" + echo "Options:" + echo " --verbose Show verbose output." + echo " -c|--channel The channel of KoreBuild to download. Overrides the value from the config file.." + echo " --config-file The path to the configuration file that stores values. Defaults to korebuild.json." + echo " -d|--dotnet-home The directory where .NET Core tools will be stored. Defaults to '\$DOTNET_HOME' or '\$HOME/.dotnet." + echo " --path The directory to build. Defaults to the directory containing the script." + echo " -s|--tools-source|-ToolsSource The base url where build tools can be downloaded. Overrides the value from the config file." + echo " -u|--update Update to the latest KoreBuild even if the lock file is present." + echo "" + echo "Description:" + echo " This function will create a file \$DIR/korebuild-lock.txt. This lock file can be committed to source, but does not have to be." + echo " When the lockfile is not present, KoreBuild will create one using latest available version from \$channel." + + if [[ "${1:-}" != '--no-exit' ]]; then + exit 2 + fi +} + +get_korebuild() { + local version + local lock_file="$repo_path/korebuild-lock.txt" + if [ ! -f "$lock_file" ] || [ "$update" = true ]; then + __get_remote_file "$tools_source/korebuild/channels/$channel/latest.txt" "$lock_file" + fi + version="$(grep 'version:*' -m 1 "$lock_file")" + if [[ "$version" == '' ]]; then + __error "Failed to parse version from $lock_file. Expected a line that begins with 'version:'" + return 1 + fi + version="$(echo "${version#version:}" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')" + local korebuild_path="$DOTNET_HOME/buildtools/korebuild/$version" + + { + if [ ! -d "$korebuild_path" ]; then + mkdir -p "$korebuild_path" + local remote_path="$tools_source/korebuild/artifacts/$version/korebuild.$version.zip" + tmpfile="$(mktemp)" + echo -e "${MAGENTA}Downloading KoreBuild ${version}${RESET}" + if __get_remote_file "$remote_path" "$tmpfile"; then + unzip -q -d "$korebuild_path" "$tmpfile" + fi + rm "$tmpfile" || true + fi + + source "$korebuild_path/KoreBuild.sh" + } || { + if [ -d "$korebuild_path" ]; then + echo "Cleaning up after failed installation" + rm -rf "$korebuild_path" || true + fi + return 1 + } +} + +__error() { + echo -e "${RED}error: $*${RESET}" 1>&2 +} + +__warn() { + echo -e "${YELLOW}warning: $*${RESET}" +} + +__machine_has() { + hash "$1" > /dev/null 2>&1 + return $? +} + +__get_remote_file() { + local remote_path=$1 + local local_path=$2 + + if [[ "$remote_path" != 'http'* ]]; then + cp "$remote_path" "$local_path" + return 0 + fi + + local failed=false + if __machine_has wget; then + wget --tries 10 --quiet -O "$local_path" "$remote_path" || failed=true + else + failed=true + fi + + if [ "$failed" = true ] && __machine_has curl; then + failed=false + curl --retry 10 -sSL -f --create-dirs -o "$local_path" "$remote_path" || failed=true + fi + + if [ "$failed" = true ]; then + __error "Download failed: $remote_path" 1>&2 + return 1 + fi +} + +# +# main +# + +command="${1:-}" +shift + +while [[ $# -gt 0 ]]; do + case $1 in + -\?|-h|--help) + __usage --no-exit + exit 0 + ;; + -c|--channel|-Channel) + shift + channel="${1:-}" + [ -z "$channel" ] && __usage + ;; + --config-file|-ConfigFile) + shift + config_file="${1:-}" + [ -z "$config_file" ] && __usage + if [ ! -f "$config_file" ]; then + __error "Invalid value for --config-file. $config_file does not exist." + exit 1 + fi + ;; + -d|--dotnet-home|-DotNetHome) + shift + DOTNET_HOME="${1:-}" + [ -z "$DOTNET_HOME" ] && __usage + ;; + --path|-Path) + shift + repo_path="${1:-}" + [ -z "$repo_path" ] && __usage + ;; + -s|--tools-source|-ToolsSource) + shift + tools_source="${1:-}" + [ -z "$tools_source" ] && __usage + ;; + -u|--update|-Update) + update=true + ;; + --verbose|-Verbose) + verbose=true + ;; + --) + shift + break + ;; + *) + break + ;; + esac + shift +done + +if ! __machine_has unzip; then + __error 'Missing required command: unzip' + exit 1 +fi + +if ! __machine_has curl && ! __machine_has wget; then + __error 'Missing required command. Either wget or curl is required.' + exit 1 +fi + +[ -z "${config_file:-}" ] && config_file="$repo_path/korebuild.json" +if [ -f "$config_file" ]; then + if __machine_has jq ; then + if jq '.' "$config_file" >/dev/null ; then + config_channel="$(jq -r 'select(.channel!=null) | .channel' "$config_file")" + config_tools_source="$(jq -r 'select(.toolsSource!=null) | .toolsSource' "$config_file")" + else + __warn "$config_file is invalid JSON. Its settings will be ignored." + fi + elif __machine_has python ; then + if python -c "import json,codecs;obj=json.load(codecs.open('$config_file', 'r', 'utf-8-sig'))" >/dev/null ; then + config_channel="$(python -c "import json,codecs;obj=json.load(codecs.open('$config_file', 'r', 'utf-8-sig'));print(obj['channel'] if 'channel' in obj else '')")" + config_tools_source="$(python -c "import json,codecs;obj=json.load(codecs.open('$config_file', 'r', 'utf-8-sig'));print(obj['toolsSource'] if 'toolsSource' in obj else '')")" + else + __warn "$config_file is invalid JSON. Its settings will be ignored." + fi + else + __warn 'Missing required command: jq or pyton. Could not parse the JSON file. Its settings will be ignored.' + fi + + [ ! -z "${config_channel:-}" ] && channel="$config_channel" + [ ! -z "${config_tools_source:-}" ] && tools_source="$config_tools_source" +fi + +[ -z "$channel" ] && channel='dev' +[ -z "$tools_source" ] && tools_source='https://aspnetcore.blob.core.windows.net/buildtools' + +get_korebuild +set_korebuildsettings "$tools_source" "$DOTNET_HOME" "$repo_path" "$config_file" +invoke_korebuild_command "$command" "$@" From f1efb29b18d1dece867300f2d6f2115e9fd0e248 Mon Sep 17 00:00:00 2001 From: Jass Bagga Date: Wed, 11 Oct 2017 14:09:35 -0700 Subject: [PATCH 160/221] Use ContractResolver instead of forcing to lower case (#112) Addresses #90 --- .../JsonPatchDocumentOfT.cs | 17 +++++++++-------- .../JsonPatchDocumentGetPathTest.cs | 4 ++-- ...sonPatchDocumentJsonPropertyAttributeTest.cs | 14 +++++++------- 3 files changed, 18 insertions(+), 17 deletions(-) diff --git a/src/Microsoft.AspNetCore.JsonPatch/JsonPatchDocumentOfT.cs b/src/Microsoft.AspNetCore.JsonPatch/JsonPatchDocumentOfT.cs index 33e1e5033f..5b9df2b52b 100644 --- a/src/Microsoft.AspNetCore.JsonPatch/JsonPatchDocumentOfT.cs +++ b/src/Microsoft.AspNetCore.JsonPatch/JsonPatchDocumentOfT.cs @@ -691,12 +691,13 @@ namespace Microsoft.AspNetCore.JsonPatch { foreach (var op in Operations) { - var untypedOp = new Operation(); - - untypedOp.op = op.op; - untypedOp.value = op.value; - untypedOp.path = op.path; - untypedOp.from = op.from; + var untypedOp = new Operation + { + op = op.op, + value = op.value, + path = op.path, + from = op.from + }; allOps.Add(untypedOp); } @@ -715,11 +716,11 @@ namespace Microsoft.AspNetCore.JsonPatch path += "/" + position; if (segments.Count == 0) { - return path.ToLowerInvariant(); + return path; } } - return "/" + path.ToLowerInvariant(); + return "/" + path; } private List GetPathSegments(Expression expr) diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/JsonPatchDocumentGetPathTest.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/JsonPatchDocumentGetPathTest.cs index dcde4b442d..7d3331231c 100644 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/JsonPatchDocumentGetPathTest.cs +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/JsonPatchDocumentGetPathTest.cs @@ -19,7 +19,7 @@ namespace Microsoft.AspNetCore.JsonPatch var path = patchDocument.GetPath(p => p.SimpleObject.IntegerList, "-"); // Assert - Assert.Equal("/simpleobject/integerlist/-", path); + Assert.Equal("/SimpleObject/IntegerList/-", path); } [Fact] @@ -84,7 +84,7 @@ namespace Microsoft.AspNetCore.JsonPatch var path = patchDocument.GetPath(p => (BaseClass)p.DerivedObject, null); // Assert - Assert.Equal("/derivedobject", path); + Assert.Equal("/DerivedObject", path); } [Fact] diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/JsonPatchDocumentJsonPropertyAttributeTest.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/JsonPatchDocumentJsonPropertyAttributeTest.cs index 50ab6a9f5b..882e09ffe7 100644 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/JsonPatchDocumentJsonPropertyAttributeTest.cs +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/JsonPatchDocumentJsonPropertyAttributeTest.cs @@ -56,7 +56,7 @@ namespace Microsoft.AspNetCore.JsonPatch // get path var pathToCheck = deserialized.Operations.First().path; - Assert.Equal("/anothername", pathToCheck); + Assert.Equal("/AnotherName", pathToCheck); } [Fact] @@ -73,7 +73,7 @@ namespace Microsoft.AspNetCore.JsonPatch // Assert var pathToCheck = deserialized.Operations.First().path; - Assert.Equal("/stringproperty", pathToCheck); + Assert.Equal("/StringProperty", pathToCheck); } [Fact] @@ -90,7 +90,7 @@ namespace Microsoft.AspNetCore.JsonPatch // Assert var pathToCheck = deserialized.Operations.First().path; - Assert.Equal("/arrayproperty/-", pathToCheck); + Assert.Equal("/ArrayProperty/-", pathToCheck); } [Fact] @@ -209,7 +209,7 @@ namespace Microsoft.AspNetCore.JsonPatch // get path var pathToCheck = deserialized.Operations.First().path; - Assert.Equal("/anothername", pathToCheck); + Assert.Equal("/AnotherName", pathToCheck); } [Fact] @@ -249,9 +249,9 @@ namespace Microsoft.AspNetCore.JsonPatch // Assert var fromPath = deserialized.Operations.First().from; - Assert.Equal("/stringproperty", fromPath); + Assert.Equal("/StringProperty", fromPath); var toPath = deserialized.Operations.First().path; - Assert.Equal("/stringproperty2", toPath); + Assert.Equal("/StringProperty2", toPath); } [Fact] @@ -269,7 +269,7 @@ namespace Microsoft.AspNetCore.JsonPatch // Assert var path = deserialized.Operations.First().path; - Assert.Equal("/socialsecuritynumber", path); + Assert.Equal("/SocialSecurityNumber", path); } private class JsonPropertyWithNoPropertyName From e245de21fcc6bda605991f5b9963f1a6b9bb6125 Mon Sep 17 00:00:00 2001 From: Ryan Brandenburg Date: Mon, 16 Oct 2017 12:50:35 -0700 Subject: [PATCH 161/221] Add RepositoryRoot --- Directory.Build.props | 1 + 1 file changed, 1 insertion(+) diff --git a/Directory.Build.props b/Directory.Build.props index 57d9ef7e6a..fb7dfae923 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -5,6 +5,7 @@ Microsoft ASP.NET Core https://github.com/aspnet/JsonPatch git + $(MSBuildThisFileDirectory) $(MSBuildThisFileDirectory)build\Key.snk true true From 8eefe0fdc22793f6573f82c9856abcbe36a7bb80 Mon Sep 17 00:00:00 2001 From: Jass Bagga Date: Thu, 19 Oct 2017 10:46:08 -0700 Subject: [PATCH 162/221] Add Test Operation (#114) Addresses #1 --- .../Adapters/IObjectAdapter.cs | 95 ++++++- .../Adapters/IObjectAdapterWithTest.cs | 32 +++ .../Adapters/ObjectAdapter.cs | 172 +++---------- .../Internal/DictionaryAdapterOfTU.cs | 51 ++++ .../Internal/DynamicObjectAdapter.cs | 32 +++ .../Internal/IAdapter.cs | 7 + .../Internal/ListAdapter.cs | 39 +++ .../Internal/ObjectVisitor.cs | 9 +- .../Internal/PocoAdapter.cs | 39 +++ .../JsonPatchDocument.cs | 18 ++ .../JsonPatchDocumentOfT.cs | 71 ++++++ .../Operations/Operation.cs | 10 +- .../Operations/OperationOfT.cs | 11 +- .../Properties/Resources.Designer.cs | 46 +++- .../Resources.resx | 9 + .../{ => Adapters}/DictionaryAdapterTest.cs | 37 +++ .../DynamicObjectAdapterTest.cs | 37 +++ .../{ => Adapters}/ListAdapterTest.cs | 50 ++++ .../Adapters/PocoAdapterTest.cs | 241 ++++++++++++++++++ ...tegrationTests.cs => DynamicObjectTest.cs} | 42 ++- .../JsonPatchDocumentTest.cs | 36 --- 21 files changed, 895 insertions(+), 189 deletions(-) create mode 100644 src/Microsoft.AspNetCore.JsonPatch/Adapters/IObjectAdapterWithTest.cs rename test/Microsoft.AspNetCore.JsonPatch.Test/{ => Adapters}/DictionaryAdapterTest.cs (88%) rename test/Microsoft.AspNetCore.JsonPatch.Test/{ => Adapters}/DynamicObjectAdapterTest.cs (85%) rename test/Microsoft.AspNetCore.JsonPatch.Test/{ => Adapters}/ListAdapterTest.cs (89%) create mode 100644 test/Microsoft.AspNetCore.JsonPatch.Test/Adapters/PocoAdapterTest.cs rename test/Microsoft.AspNetCore.JsonPatch.Test/IntegrationTests/{DynamicObjectIntegrationTests.cs => DynamicObjectTest.cs} (86%) diff --git a/src/Microsoft.AspNetCore.JsonPatch/Adapters/IObjectAdapter.cs b/src/Microsoft.AspNetCore.JsonPatch/Adapters/IObjectAdapter.cs index f699755ed4..e5206bfa0d 100644 --- a/src/Microsoft.AspNetCore.JsonPatch/Adapters/IObjectAdapter.cs +++ b/src/Microsoft.AspNetCore.JsonPatch/Adapters/IObjectAdapter.cs @@ -8,12 +8,105 @@ namespace Microsoft.AspNetCore.JsonPatch.Adapters /// /// Defines the operations that can be performed on a JSON patch document. /// - public interface IObjectAdapter + public interface IObjectAdapter { + /// + /// Using the "add" operation a new value is inserted into the root of the target + /// document, into the target array at the specified valid index, or to a target object at + /// the specified location. + /// + /// When adding to arrays, the specified index MUST NOT be greater than the number of elements in the array. + /// To append the value to the array, the index of "-" character is used (see [RFC6901]). + /// + /// When adding to an object, if an object member does not already exist, a new member is added to the object at the + /// specified location or if an object member does exist, that member's value is replaced. + /// + /// The operation object MUST contain a "value" member whose content + /// specifies the value to be added. + /// + /// For example: + /// + /// { "op": "add", "path": "/a/b/c", "value": [ "foo", "bar" ] } + /// + /// See RFC 6902 https://tools.ietf.org/html/rfc6902#page-4 + /// + /// The add operation. + /// Object to apply the operation to. void Add(Operation operation, object objectToApplyTo); + + /// + /// Using the "copy" operation, a value is copied from a specified location to the + /// target location. + /// + /// The operation object MUST contain a "from" member, which references the location in the + /// target document to copy the value from. + /// + /// The "from" location MUST exist for the operation to be successful. + /// + /// For example: + /// + /// { "op": "copy", "from": "/a/b/c", "path": "/a/b/e" } + /// + /// See RFC 6902 https://tools.ietf.org/html/rfc6902#page-7 + /// + /// The copy operation. + /// Object to apply the operation to. void Copy(Operation operation, object objectToApplyTo); + + /// + /// Using the "move" operation the value at a specified location is removed and + /// added to the target location. + /// + /// The operation object MUST contain a "from" member, which references the location in the + /// target document to move the value from. + /// + /// The "from" location MUST exist for the operation to be successful. + /// + /// For example: + /// + /// { "op": "move", "from": "/a/b/c", "path": "/a/b/d" } + /// + /// A location cannot be moved into one of its children. + /// + /// See RFC 6902 https://tools.ietf.org/html/rfc6902#page-6 + /// + /// The move operation. + /// Object to apply the operation to. void Move(Operation operation, object objectToApplyTo); + + /// + /// Using the "remove" operation the value at the target location is removed. + /// + /// The target location MUST exist for the operation to be successful. + /// + /// For example: + /// + /// { "op": "remove", "path": "/a/b/c" } + /// + /// If removing an element from an array, any elements above the + /// specified index are shifted one position to the left. + /// + /// See RFC 6902 https://tools.ietf.org/html/rfc6902#page-6 + /// + /// The remove operation. + /// Object to apply the operation to. void Remove(Operation operation, object objectToApplyTo); + + /// + /// Using the "replace" operation he value at the target location is replaced + /// with a new value. The operation object MUST contain a "value" member + /// which specifies the replacement value. + /// + /// The target location MUST exist for the operation to be successful. + /// + /// For example: + /// + /// { "op": "replace", "path": "/a/b/c", "value": 42 } + /// + /// See RFC 6902 https://tools.ietf.org/html/rfc6902#page-6 + /// + /// The replace operation. + /// Object to apply the operation to. void Replace(Operation operation, object objectToApplyTo); } } \ No newline at end of file diff --git a/src/Microsoft.AspNetCore.JsonPatch/Adapters/IObjectAdapterWithTest.cs b/src/Microsoft.AspNetCore.JsonPatch/Adapters/IObjectAdapterWithTest.cs new file mode 100644 index 0000000000..e1b4ce7950 --- /dev/null +++ b/src/Microsoft.AspNetCore.JsonPatch/Adapters/IObjectAdapterWithTest.cs @@ -0,0 +1,32 @@ +// 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 Microsoft.AspNetCore.JsonPatch.Operations; + +namespace Microsoft.AspNetCore.JsonPatch.Adapters +{ + /// + /// Defines the operations that can be performed on a JSON patch document, including "test". + /// + public interface IObjectAdapterWithTest : IObjectAdapter + { + /// + /// Using the "test" operation a value at the target location is compared for + /// equality to a specified value. + /// + /// The operation object MUST contain a "value" member that specifies + /// value to be compared to the target location's value. + /// + /// The target location MUST be equal to the "value" value for the + /// operation to be considered successful. + /// + /// For example: + /// { "op": "test", "path": "/a/b/c", "value": "foo" } + /// + /// See RFC 6902 https://tools.ietf.org/html/rfc6902#page-7 + /// + /// The test operation. + /// Object to apply the operation to. + void Test(Operation operation, object objectToApplyTo); + } +} diff --git a/src/Microsoft.AspNetCore.JsonPatch/Adapters/ObjectAdapter.cs b/src/Microsoft.AspNetCore.JsonPatch/Adapters/ObjectAdapter.cs index a30343868a..73095b52c2 100644 --- a/src/Microsoft.AspNetCore.JsonPatch/Adapters/ObjectAdapter.cs +++ b/src/Microsoft.AspNetCore.JsonPatch/Adapters/ObjectAdapter.cs @@ -9,7 +9,7 @@ using Newtonsoft.Json.Serialization; namespace Microsoft.AspNetCore.JsonPatch.Adapters { /// - public class ObjectAdapter : IObjectAdapter + public class ObjectAdapter : IObjectAdapterWithTest { /// /// Initializes a new instance of . @@ -34,66 +34,6 @@ namespace Microsoft.AspNetCore.JsonPatch.Adapters /// public Action LogErrorAction { get; } - /// - /// The "add" operation performs one of the following functions, - /// depending upon what the target location references: - /// - /// o If the target location specifies an array index, a new value is - /// inserted into the array at the specified index. - /// - /// o If the target location specifies an object member that does not - /// already exist, a new member is added to the object. - /// - /// o If the target location specifies an object member that does exist, - /// that member's value is replaced. - /// - /// The operation object MUST contain a "value" member whose content - /// specifies the value to be added. - /// - /// For example: - /// - /// { "op": "add", "path": "/a/b/c", "value": [ "foo", "bar" ] } - /// - /// When the operation is applied, the target location MUST reference one - /// of: - /// - /// o The root of the target document - whereupon the specified value - /// becomes the entire content of the target document. - /// - /// o A member to add to an existing object - whereupon the supplied - /// value is added to that object at the indicated location. If the - /// member already exists, it is replaced by the specified value. - /// - /// o An element to add to an existing array - whereupon the supplied - /// value is added to the array at the indicated location. Any - /// elements at or above the specified index are shifted one position - /// to the right. The specified index MUST NOT be greater than the - /// number of elements in the array. If the "-" character is used to - /// index the end of the array (see [RFC6901]), this has the effect of - /// appending the value to the array. - /// - /// Because this operation is designed to add to existing objects and - /// arrays, its target location will often not exist. Although the - /// pointer's error handling algorithm will thus be invoked, this - /// specification defines the error handling behavior for "add" pointers - /// to ignore that error and add the value as specified. - /// - /// However, the object itself or an array containing it does need to - /// exist, and it remains an error for that not to be the case. For - /// example, an "add" with a target location of "/a/b" starting with this - /// document: - /// - /// { "a": { "foo": 1 } } - /// - /// is not an error, because "a" exists, and "b" will be added to its - /// value. It is an error in this document: - /// - /// { "q": { "bar": 2 } } - /// - /// because "a" does not exist. - /// - /// The add operation. - /// Object to apply the operation to. public void Add(Operation operation, object objectToApplyTo) { if (operation == null) @@ -153,29 +93,6 @@ namespace Microsoft.AspNetCore.JsonPatch.Adapters } } - /// - /// The "move" operation removes the value at a specified location and - /// adds it to the target location. - /// - /// The operation object MUST contain a "from" member, which is a string - /// containing a JSON Pointer value that references the location in the - /// target document to move the value from. - /// - /// The "from" location MUST exist for the operation to be successful. - /// - /// For example: - /// - /// { "op": "move", "from": "/a/b/c", "path": "/a/b/d" } - /// - /// This operation is functionally identical to a "remove" operation on - /// the "from" location, followed immediately by an "add" operation at - /// the target location with the value that was just removed. - /// - /// The "from" location MUST NOT be a proper prefix of the "path" - /// location; i.e., a location cannot be moved into one of its children. - /// - /// The move operation. - /// Object to apply the operation to. public void Move(Operation operation, object objectToApplyTo) { if (operation == null) @@ -202,20 +119,6 @@ namespace Microsoft.AspNetCore.JsonPatch.Adapters } } - /// - /// The "remove" operation removes the value at the target location. - /// - /// The target location MUST exist for the operation to be successful. - /// - /// For example: - /// - /// { "op": "remove", "path": "/a/b/c" } - /// - /// If removing an element from an array, any elements above the - /// specified index are shifted one position to the left. - /// - /// The remove operation. - /// Object to apply the operation to. public void Remove(Operation operation, object objectToApplyTo) { if (operation == null) @@ -259,26 +162,6 @@ namespace Microsoft.AspNetCore.JsonPatch.Adapters } } - /// - /// The "replace" operation replaces the value at the target location - /// with a new value. The operation object MUST contain a "value" member - /// whose content specifies the replacement value. - /// - /// The target location MUST exist for the operation to be successful. - /// - /// For example: - /// - /// { "op": "replace", "path": "/a/b/c", "value": 42 } - /// - /// This operation is functionally identical to a "remove" operation for - /// a value, followed immediately by an "add" operation at the same - /// location with the replacement value. - /// - /// Note: even though it's the same functionally, we do not call remove + add - /// for performance reasons (multiple checks of same requirements). - /// - /// The replace operation. - /// Object to apply the operation to. public void Replace(Operation operation, object objectToApplyTo) { if (operation == null) @@ -310,28 +193,6 @@ namespace Microsoft.AspNetCore.JsonPatch.Adapters } } - /// - /// The "copy" operation copies the value at a specified location to the - /// target location. - /// - /// The operation object MUST contain a "from" member, which is a string - /// containing a JSON Pointer value that references the location in the - /// target document to copy the value from. - /// - /// The "from" location MUST exist for the operation to be successful. - /// - /// For example: - /// - /// { "op": "copy", "from": "/a/b/c", "path": "/a/b/e" } - /// - /// This operation is functionally identical to an "add" operation at the - /// target location using the value specified in the "from" member. - /// - /// Note: even though it's the same functionally, we do not call add with - /// the value specified in from for performance reasons (multiple checks of same requirements). - /// - /// The copy operation. - /// Object to apply the operation to. public void Copy(Operation operation, object objectToApplyTo) { if (operation == null) @@ -365,6 +226,37 @@ namespace Microsoft.AspNetCore.JsonPatch.Adapters } } + public void Test(Operation operation, object objectToApplyTo) + { + if (operation == null) + { + throw new ArgumentNullException(nameof(operation)); + } + + if (objectToApplyTo == null) + { + throw new ArgumentNullException(nameof(objectToApplyTo)); + } + + var parsedPath = new ParsedPath(operation.path); + var visitor = new ObjectVisitor(parsedPath, ContractResolver); + + var target = objectToApplyTo; + if (!visitor.TryVisit(ref target, out var adapter, out var errorMessage)) + { + var error = CreatePathNotFoundError(objectToApplyTo, operation.path, operation, errorMessage); + ErrorReporter(error); + return; + } + + if (!adapter.TryTest(target, parsedPath.LastSegment, ContractResolver, operation.value, out errorMessage)) + { + var error = CreateOperationFailedError(objectToApplyTo, operation.path, operation, errorMessage); + ErrorReporter(error); + return; + } + } + private bool TryGetValue( string fromLocation, object objectToGetValueFrom, diff --git a/src/Microsoft.AspNetCore.JsonPatch/Internal/DictionaryAdapterOfTU.cs b/src/Microsoft.AspNetCore.JsonPatch/Internal/DictionaryAdapterOfTU.cs index 67fd33e231..8a344e24ee 100644 --- a/src/Microsoft.AspNetCore.JsonPatch/Internal/DictionaryAdapterOfTU.cs +++ b/src/Microsoft.AspNetCore.JsonPatch/Internal/DictionaryAdapterOfTU.cs @@ -2,6 +2,8 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; using Newtonsoft.Json.Serialization; namespace Microsoft.AspNetCore.JsonPatch.Internal @@ -126,6 +128,55 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal return true; } + public bool TryTest( + object target, + string segment, + IContractResolver contractResolver, + object value, + out string errorMessage) + { + var contract = (JsonDictionaryContract)contractResolver.ResolveContract(target.GetType()); + var key = contract.DictionaryKeyResolver(segment); + var dictionary = (IDictionary)target; + + if (!TryConvertKey(key, out var convertedKey, out errorMessage)) + { + return false; + } + + // As per JsonPatch spec, the target location must exist for test to be successful + if (!dictionary.ContainsKey(convertedKey)) + { + errorMessage = Resources.FormatTargetLocationAtPathSegmentNotFound(segment); + return false; + } + + if (!TryConvertValue(value, out var convertedValue, out errorMessage)) + { + return false; + } + + var currentValue = dictionary[convertedKey]; + + // The target segment does not have an assigned value to compare the test value with + if (currentValue == null || string.IsNullOrEmpty(currentValue.ToString())) + { + errorMessage = Resources.FormatValueForTargetSegmentCannotBeNullOrEmpty(segment); + return false; + } + + if (!JToken.DeepEquals(JsonConvert.SerializeObject(currentValue), JsonConvert.SerializeObject(convertedValue))) + { + errorMessage = Resources.FormatValueNotEqualToTestValue(currentValue, value, segment); + return false; + } + else + { + errorMessage = null; + return true; + } + } + public bool TryTraverse( object target, string segment, diff --git a/src/Microsoft.AspNetCore.JsonPatch/Internal/DynamicObjectAdapter.cs b/src/Microsoft.AspNetCore.JsonPatch/Internal/DynamicObjectAdapter.cs index 433326ce53..fb4adeb1f2 100644 --- a/src/Microsoft.AspNetCore.JsonPatch/Internal/DynamicObjectAdapter.cs +++ b/src/Microsoft.AspNetCore.JsonPatch/Internal/DynamicObjectAdapter.cs @@ -6,6 +6,8 @@ using System.Collections.Generic; using System.Reflection; using System.Runtime.CompilerServices; using Microsoft.CSharp.RuntimeBinder; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; using Newtonsoft.Json.Serialization; using CSharpBinder = Microsoft.CSharp.RuntimeBinder; @@ -103,6 +105,36 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal return true; } + public bool TryTest( + 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 (!JToken.DeepEquals(JsonConvert.SerializeObject(property), JsonConvert.SerializeObject(convertedValue))) + { + errorMessage = Resources.FormatValueNotEqualToTestValue(property, value, segment); + return false; + } + else + { + errorMessage = null; + return true; + } + } + public bool TryTraverse( object target, string segment, diff --git a/src/Microsoft.AspNetCore.JsonPatch/Internal/IAdapter.cs b/src/Microsoft.AspNetCore.JsonPatch/Internal/IAdapter.cs index 1866b42ed4..ec28131f7d 100644 --- a/src/Microsoft.AspNetCore.JsonPatch/Internal/IAdapter.cs +++ b/src/Microsoft.AspNetCore.JsonPatch/Internal/IAdapter.cs @@ -40,5 +40,12 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal IContractResolver contractResolver, object value, out string errorMessage); + + bool TryTest( + object target, + string segment, + IContractResolver contractResolver, + object value, + out string errorMessage); } } diff --git a/src/Microsoft.AspNetCore.JsonPatch/Internal/ListAdapter.cs b/src/Microsoft.AspNetCore.JsonPatch/Internal/ListAdapter.cs index a1c0498e47..d1348fd5c6 100644 --- a/src/Microsoft.AspNetCore.JsonPatch/Internal/ListAdapter.cs +++ b/src/Microsoft.AspNetCore.JsonPatch/Internal/ListAdapter.cs @@ -5,6 +5,8 @@ using System; using System.Collections; using System.Collections.Generic; using Microsoft.Extensions.Internal; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; using Newtonsoft.Json.Serialization; namespace Microsoft.AspNetCore.JsonPatch.Internal @@ -150,6 +152,43 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal return true; } + public bool TryTest( + object target, + string segment, + IContractResolver contractResolver, + object value, + out string errorMessage) + { + var list = (IList)target; + + if (!TryGetListTypeArgument(list, out var typeArgument, out errorMessage)) + { + return false; + } + + if (!TryGetPositionInfo(list, segment, OperationType.Replace, out var positionInfo, out errorMessage)) + { + return false; + } + + if (!TryConvertValue(value, typeArgument, segment, out var convertedValue, out errorMessage)) + { + return false; + } + + var currentValue = list[positionInfo.Index]; + if (!JToken.DeepEquals(JsonConvert.SerializeObject(currentValue), JsonConvert.SerializeObject(convertedValue))) + { + errorMessage = Resources.FormatValueAtListPositionNotEqualToTestValue(currentValue, value, positionInfo.Index); + return false; + } + else + { + errorMessage = null; + return true; + } + } + public bool TryTraverse( object target, string segment, diff --git a/src/Microsoft.AspNetCore.JsonPatch/Internal/ObjectVisitor.cs b/src/Microsoft.AspNetCore.JsonPatch/Internal/ObjectVisitor.cs index 97f108c0a0..8994f0aa52 100644 --- a/src/Microsoft.AspNetCore.JsonPatch/Internal/ObjectVisitor.cs +++ b/src/Microsoft.AspNetCore.JsonPatch/Internal/ObjectVisitor.cs @@ -3,9 +3,6 @@ using System; using System.Collections; -using System.Collections.Generic; -using System.Dynamic; -using Microsoft.AspNetCore.JsonPatch.Adapters; using Newtonsoft.Json.Serialization; namespace Microsoft.AspNetCore.JsonPatch.Internal @@ -30,7 +27,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal return false; } - adapter = SelectAdapater(target); + adapter = SelectAdapter(target); // Traverse until the penultimate segment to get the target object and adapter for (var i = 0; i < _path.Segments.Count - 1; i++) @@ -42,14 +39,14 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal } target = next; - adapter = SelectAdapater(target); + adapter = SelectAdapter(target); } errorMessage = null; return true; } - private IAdapter SelectAdapater(object targetObject) + private IAdapter SelectAdapter(object targetObject) { var jsonContract = _contractResolver.ResolveContract(targetObject.GetType()); diff --git a/src/Microsoft.AspNetCore.JsonPatch/Internal/PocoAdapter.cs b/src/Microsoft.AspNetCore.JsonPatch/Internal/PocoAdapter.cs index eab16a3035..0eee0fc889 100644 --- a/src/Microsoft.AspNetCore.JsonPatch/Internal/PocoAdapter.cs +++ b/src/Microsoft.AspNetCore.JsonPatch/Internal/PocoAdapter.cs @@ -4,6 +4,8 @@ using System; using System.Linq; using System.Reflection; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; using Newtonsoft.Json.Serialization; namespace Microsoft.AspNetCore.JsonPatch.Internal @@ -132,6 +134,43 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal return true; } + public bool TryTest( + object target, + string segment, + IContractResolver + contractResolver, + object value, + out string errorMessage) + { + if (!TryGetJsonProperty(target, contractResolver, segment, out var jsonProperty)) + { + errorMessage = Resources.FormatTargetLocationAtPathSegmentNotFound(segment); + return false; + } + + if (!jsonProperty.Readable) + { + errorMessage = Resources.FormatCannotReadProperty(segment); + return false; + } + + if (!TryConvertValue(value, jsonProperty.PropertyType, out var convertedValue)) + { + errorMessage = Resources.FormatInvalidValueForProperty(value); + return false; + } + + var currentValue = jsonProperty.ValueProvider.GetValue(target); + if (!JToken.DeepEquals(JsonConvert.SerializeObject(currentValue), JsonConvert.SerializeObject(convertedValue))) + { + errorMessage = Resources.FormatValueNotEqualToTestValue(currentValue, value, segment); + return false; + } + + errorMessage = null; + return true; + } + public bool TryTraverse( object target, string segment, diff --git a/src/Microsoft.AspNetCore.JsonPatch/JsonPatchDocument.cs b/src/Microsoft.AspNetCore.JsonPatch/JsonPatchDocument.cs index 4da2bdbe1e..4420e576bf 100644 --- a/src/Microsoft.AspNetCore.JsonPatch/JsonPatchDocument.cs +++ b/src/Microsoft.AspNetCore.JsonPatch/JsonPatchDocument.cs @@ -99,6 +99,24 @@ namespace Microsoft.AspNetCore.JsonPatch return this; } + /// + /// Test value. Will result in, for example, + /// { "op": "test", "path": "/a/b/c", "value": 42 } + /// + /// target location + /// value + /// + public JsonPatchDocument Test(string path, object value) + { + if (path == null) + { + throw new ArgumentNullException(nameof(path)); + } + + Operations.Add(new Operation("test", PathHelpers.NormalizePath(path), null, value)); + return this; + } + /// /// Removes value at specified location and add it to the target location. Will result in, for example: /// { "op": "move", "from": "/a/b/c", "path": "/a/b/d" } diff --git a/src/Microsoft.AspNetCore.JsonPatch/JsonPatchDocumentOfT.cs b/src/Microsoft.AspNetCore.JsonPatch/JsonPatchDocumentOfT.cs index 5b9df2b52b..8ae1430185 100644 --- a/src/Microsoft.AspNetCore.JsonPatch/JsonPatchDocumentOfT.cs +++ b/src/Microsoft.AspNetCore.JsonPatch/JsonPatchDocumentOfT.cs @@ -247,6 +247,77 @@ namespace Microsoft.AspNetCore.JsonPatch return this; } + /// + /// Test value. Will result in, for example, + /// { "op": "test", "path": "/a/b/c", "value": 42 } + /// + /// target location + /// value + /// + public JsonPatchDocument Test(Expression> path, TProp value) + { + if (path == null) + { + throw new ArgumentNullException(nameof(path)); + } + + Operations.Add(new Operation( + "test", + GetPath(path, null), + from: null, + value: value)); + + return this; + } + + /// + /// Test value in a list at given position + /// + /// value type + /// target location + /// value + /// position + /// + public JsonPatchDocument Test(Expression>> path, + TProp value, int position) + { + if (path == null) + { + throw new ArgumentNullException(nameof(path)); + } + + Operations.Add(new Operation( + "test", + GetPath(path, position.ToString()), + from: null, + value: value)); + + return this; + } + + /// + /// Test value at end of a list + /// + /// value type + /// target location + /// value + /// + public JsonPatchDocument Test(Expression>> path, TProp value) + { + if (path == null) + { + throw new ArgumentNullException(nameof(path)); + } + + Operations.Add(new Operation( + "test", + GetPath(path, "-"), + from: null, + value: value)); + + return this; + } + /// /// Removes value at specified location and add it to the target location. Will result in, for example: /// { "op": "move", "from": "/a/b/c", "path": "/a/b/d" } diff --git a/src/Microsoft.AspNetCore.JsonPatch/Operations/Operation.cs b/src/Microsoft.AspNetCore.JsonPatch/Operations/Operation.cs index ea81b0c668..690ade4776 100644 --- a/src/Microsoft.AspNetCore.JsonPatch/Operations/Operation.cs +++ b/src/Microsoft.AspNetCore.JsonPatch/Operations/Operation.cs @@ -58,7 +58,15 @@ namespace Microsoft.AspNetCore.JsonPatch.Operations adapter.Copy(this, objectToApplyTo); break; case OperationType.Test: - throw new NotSupportedException(Resources.TestOperationNotSupported); + if (adapter is IObjectAdapterWithTest adapterWithTest) + { + adapterWithTest.Test(this, objectToApplyTo); + break; + } + else + { + throw new NotSupportedException(Resources.TestOperationNotSupported); + } default: break; } diff --git a/src/Microsoft.AspNetCore.JsonPatch/Operations/OperationOfT.cs b/src/Microsoft.AspNetCore.JsonPatch/Operations/OperationOfT.cs index 7189cf8210..bd13528775 100644 --- a/src/Microsoft.AspNetCore.JsonPatch/Operations/OperationOfT.cs +++ b/src/Microsoft.AspNetCore.JsonPatch/Operations/OperationOfT.cs @@ -74,7 +74,15 @@ namespace Microsoft.AspNetCore.JsonPatch.Operations adapter.Copy(this, objectToApplyTo); break; case OperationType.Test: - throw new JsonPatchException(new JsonPatchError(objectToApplyTo, this, Resources.TestOperationNotSupported)); + if (adapter is IObjectAdapterWithTest adapterWithTest) + { + adapterWithTest.Test(this, objectToApplyTo); + break; + } + else + { + throw new JsonPatchException(new JsonPatchError(objectToApplyTo, this, Resources.TestOperationNotSupported)); + } case OperationType.Invalid: throw new JsonPatchException( Resources.FormatInvalidJsonPatchOperation(op), innerException: null); @@ -82,6 +90,5 @@ namespace Microsoft.AspNetCore.JsonPatch.Operations break; } } - } } \ No newline at end of file diff --git a/src/Microsoft.AspNetCore.JsonPatch/Properties/Resources.Designer.cs b/src/Microsoft.AspNetCore.JsonPatch/Properties/Resources.Designer.cs index 432fab2cbf..cfb8e087d0 100644 --- a/src/Microsoft.AspNetCore.JsonPatch/Properties/Resources.Designer.cs +++ b/src/Microsoft.AspNetCore.JsonPatch/Properties/Resources.Designer.cs @@ -81,7 +81,7 @@ namespace Microsoft.AspNetCore.JsonPatch => string.Format(CultureInfo.CurrentCulture, GetString("CannotUpdateProperty"), p0); /// - /// The expression '{0}' is not supported. + /// The expression '{0}' is not supported. Supported expressions include member access and indexer expressions. /// internal static string ExpressionTypeNotSupported { @@ -89,7 +89,7 @@ namespace Microsoft.AspNetCore.JsonPatch } /// - /// The expression '{0}' is not supported. + /// The expression '{0}' is not supported. Supported expressions include member access and indexer expressions. /// internal static string FormatExpressionTypeNotSupported(object p0) => string.Format(CultureInfo.CurrentCulture, GetString("ExpressionTypeNotSupported"), p0); @@ -276,6 +276,48 @@ namespace Microsoft.AspNetCore.JsonPatch internal static string FormatTestOperationNotSupported() => GetString("TestOperationNotSupported"); + /// + /// The current value '{0}' at position '{2}' is not equal to the test value '{1}'. + /// + internal static string ValueAtListPositionNotEqualToTestValue + { + get => GetString("ValueAtListPositionNotEqualToTestValue"); + } + + /// + /// The current value '{0}' at position '{2}' is not equal to the test value '{1}'. + /// + internal static string FormatValueAtListPositionNotEqualToTestValue(object p0, object p1, object p2) + => string.Format(CultureInfo.CurrentCulture, GetString("ValueAtListPositionNotEqualToTestValue"), p0, p1, p2); + + /// + /// The value at '{0}' cannot be null or empty to perform the test operation. + /// + internal static string ValueForTargetSegmentCannotBeNullOrEmpty + { + get => GetString("ValueForTargetSegmentCannotBeNullOrEmpty"); + } + + /// + /// The value at '{0}' cannot be null or empty to perform the test operation. + /// + internal static string FormatValueForTargetSegmentCannotBeNullOrEmpty(object p0) + => string.Format(CultureInfo.CurrentCulture, GetString("ValueForTargetSegmentCannotBeNullOrEmpty"), p0); + + /// + /// The current value '{0}' at path '{2}' is not equal to the test value '{1}'. + /// + internal static string ValueNotEqualToTestValue + { + get => GetString("ValueNotEqualToTestValue"); + } + + /// + /// The current value '{0}' at path '{2}' is not equal to the test value '{1}'. + /// + internal static string FormatValueNotEqualToTestValue(object p0, object p1, object p2) + => string.Format(CultureInfo.CurrentCulture, GetString("ValueNotEqualToTestValue"), p0, p1, p2); + private static string GetString(string name, params string[] formatterNames) { var value = _resourceManager.GetString(name); diff --git a/src/Microsoft.AspNetCore.JsonPatch/Resources.resx b/src/Microsoft.AspNetCore.JsonPatch/Resources.resx index bf07e4a31e..3763e4a841 100644 --- a/src/Microsoft.AspNetCore.JsonPatch/Resources.resx +++ b/src/Microsoft.AspNetCore.JsonPatch/Resources.resx @@ -174,4 +174,13 @@ The test operation is not supported. + + The current value '{0}' at position '{2}' is not equal to the test value '{1}'. + + + The value at '{0}' cannot be null or empty to perform the test operation. + + + The current value '{0}' at path '{2}' is not equal to the test value '{1}'. + \ No newline at end of file diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/DictionaryAdapterTest.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/Adapters/DictionaryAdapterTest.cs similarity index 88% rename from test/Microsoft.AspNetCore.JsonPatch.Test/DictionaryAdapterTest.cs rename to test/Microsoft.AspNetCore.JsonPatch.Test/Adapters/DictionaryAdapterTest.cs index cfb99d61ce..d1d2216c2c 100644 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/DictionaryAdapterTest.cs +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/Adapters/DictionaryAdapterTest.cs @@ -274,5 +274,42 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal Assert.True(string.IsNullOrEmpty(message), "Expected no error message"); Assert.Empty(dictionary); } + + [Fact] + public void Test_DoesNotThrowException_IfTestIsSuccessful() + { + // Arrange + var key = "Name"; + var dictionary = new Dictionary(); + dictionary[key] = "James"; + var dictionaryAdapter = new DictionaryAdapter(); + var resolver = new DefaultContractResolver(); + + // Act + var testStatus = dictionaryAdapter.TryTest(dictionary, key, resolver, "James", out var message); + + //Assert + Assert.True(testStatus); + Assert.True(string.IsNullOrEmpty(message), "Expected no error message"); + } + + [Fact] + public void Test_ThrowsJsonPatchException_IfTestFails() + { + // Arrange + var key = "Name"; + var dictionary = new Dictionary(); + dictionary[key] = "James"; + var dictionaryAdapter = new DictionaryAdapter(); + var resolver = new DefaultContractResolver(); + var expectedErrorMessage = "The current value 'James' at path 'Name' is not equal to the test value 'John'."; + + // Act + var testStatus = dictionaryAdapter.TryTest(dictionary, key, resolver, "John", out var errorMessage); + + //Assert + Assert.False(testStatus); + Assert.Equal(expectedErrorMessage, errorMessage); + } } } diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/DynamicObjectAdapterTest.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/Adapters/DynamicObjectAdapterTest.cs similarity index 85% rename from test/Microsoft.AspNetCore.JsonPatch.Test/DynamicObjectAdapterTest.cs rename to test/Microsoft.AspNetCore.JsonPatch.Test/Adapters/DynamicObjectAdapterTest.cs index 18bb7a775c..9ed9a51ed0 100644 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/DynamicObjectAdapterTest.cs +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/Adapters/DynamicObjectAdapterTest.cs @@ -227,5 +227,42 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal Assert.False(removeStatus); Assert.Equal($"The target location specified by path segment '{segment}' was not found.", removeErrorMessage); } + + [Fact] + public void TryTest_DoesNotThrowException_IfTestSuccessful() + { + var adapter = new DynamicObjectAdapter(); + dynamic target = new DynamicTestObject(); + target.NewProperty = "Joana"; + var segment = "NewProperty"; + var resolver = new DefaultContractResolver(); + + // Act + var testStatus = adapter.TryTest(target, segment, resolver, "Joana", out string errorMessage); + + // Assert + Assert.Equal("Joana", target.NewProperty); + Assert.True(testStatus); + Assert.True(string.IsNullOrEmpty(errorMessage), "Expected no error message"); + } + + [Fact] + public void TryTest_ThrowsJsonPatchException_IfTestFails() + { + // Arrange + var adapter = new DynamicObjectAdapter(); + dynamic target = new DynamicTestObject(); + target.NewProperty = "Joana"; + var segment = "NewProperty"; + var resolver = new DefaultContractResolver(); + var expectedErrorMessage = $"The current value 'Joana' at path '{segment}' is not equal to the test value 'John'."; + + // Act + var testStatus = adapter.TryTest(target, segment, resolver, "John", out string errorMessage); + + // Assert + Assert.False(testStatus); + Assert.Equal(expectedErrorMessage, errorMessage); + } } } diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/ListAdapterTest.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/Adapters/ListAdapterTest.cs similarity index 89% rename from test/Microsoft.AspNetCore.JsonPatch.Test/ListAdapterTest.cs rename to test/Microsoft.AspNetCore.JsonPatch.Test/Adapters/ListAdapterTest.cs index 3c692ea150..25d8ae387b 100644 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/ListAdapterTest.cs +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/Adapters/ListAdapterTest.cs @@ -459,5 +459,55 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal Assert.True(string.IsNullOrEmpty(message), "Expected no error message"); Assert.Equal(expected, targetObject); } + + [Fact] + public void Test_DoesNotThrowException_IfTestIsSuccessful() + { + // Arrange + var resolver = new Mock(MockBehavior.Strict); + var targetObject = new List() { 10, 20 }; + var listAdapter = new ListAdapter(); + + // Act + var testStatus = listAdapter.TryTest(targetObject, "0", resolver.Object, "10", out var message); + + //Assert + Assert.True(testStatus); + Assert.True(string.IsNullOrEmpty(message), "Expected no error message"); + } + + [Fact] + public void Test_ThrowsJsonPatchException_IfTestFails() + { + // Arrange + var resolver = new Mock(MockBehavior.Strict); + var targetObject = new List() { 10, 20 }; + var listAdapter = new ListAdapter(); + var expectedErrorMessage = "The current value '20' at position '1' is not equal to the test value '10'."; + + // Act + var testStatus = listAdapter.TryTest(targetObject, "1", resolver.Object, "10", out var errorMessage); + + //Assert + Assert.False(testStatus); + Assert.Equal(expectedErrorMessage, errorMessage); + } + + [Fact] + public void Test_ThrowsJsonPatchException_IfListPositionOutOfBounds() + { + // Arrange + var resolver = new Mock(MockBehavior.Strict); + var targetObject = new List() { 10, 20 }; + var listAdapter = new ListAdapter(); + var expectedErrorMessage = "The index value provided by path segment '2' is out of bounds of the array size."; + + // Act + var testStatus = listAdapter.TryTest(targetObject, "2", resolver.Object, "10", out var errorMessage); + + //Assert + Assert.False(testStatus); + Assert.Equal(expectedErrorMessage, errorMessage); + } } } diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/Adapters/PocoAdapterTest.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/Adapters/PocoAdapterTest.cs new file mode 100644 index 0000000000..9a31ea11a8 --- /dev/null +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/Adapters/PocoAdapterTest.cs @@ -0,0 +1,241 @@ +// 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 Newtonsoft.Json.Serialization; +using Xunit; + +namespace Microsoft.AspNetCore.JsonPatch.Internal +{ + public class PocoAdapterTest + { + [Fact] + public void TryAdd_ReplacesExistingProperty() + { + // Arrange + var adapter = new PocoAdapter(); + var contractResolver = new DefaultContractResolver(); + var model = new Customer + { + Name = "Joana" + }; + + // Act + var addStatus = adapter.TryAdd(model, "Name", contractResolver, "John", out var errorMessage); + + // Assert + Assert.Equal("John", model.Name); + Assert.True(addStatus); + Assert.True(string.IsNullOrEmpty(errorMessage), "Expected no error message"); + } + + [Fact] + public void TryAdd_ThrowsJsonPatchException_IfPropertyDoesNotExist() + { + // Arrange + var adapter = new PocoAdapter(); + var contractResolver = new DefaultContractResolver(); + var model = new Customer + { + Name = "Joana" + }; + var expectedErrorMessage = "The target location specified by path segment 'LastName' was not found."; + + // Act + var addStatus = adapter.TryAdd(model, "LastName", contractResolver, "Smith", out var errorMessage); + + // Assert + Assert.False(addStatus); + Assert.Equal(expectedErrorMessage, errorMessage); + } + + [Fact] + public void TryGet_ExistingProperty() + { + // Arrange + var adapter = new PocoAdapter(); + var contractResolver = new DefaultContractResolver(); + var model = new Customer + { + Name = "Joana" + }; + + // Act + var getStatus = adapter.TryGet(model, "Name", contractResolver, out var value, out var errorMessage); + + // Assert + Assert.Equal("Joana", value); + Assert.True(getStatus); + Assert.True(string.IsNullOrEmpty(errorMessage), "Expected no error message"); + } + + [Fact] + public void TryGet_ThrowsJsonPatchException_IfPropertyDoesNotExist() + { + // Arrange + var adapter = new PocoAdapter(); + var contractResolver = new DefaultContractResolver(); + var model = new Customer + { + Name = "Joana" + }; + var expectedErrorMessage = "The target location specified by path segment 'LastName' was not found."; + + // Act + var getStatus = adapter.TryGet(model, "LastName", contractResolver, out var value, out var errorMessage); + + // Assert + Assert.Null(value); + Assert.False(getStatus); + Assert.Equal(expectedErrorMessage, errorMessage); + } + + [Fact] + public void TryRemove_SetsPropertyToNull() + { + // Arrange + var adapter = new PocoAdapter(); + var contractResolver = new DefaultContractResolver(); + var model = new Customer + { + Name = "Joana" + }; + + // Act + var removeStatus = adapter.TryRemove(model, "Name", contractResolver, out var errorMessage); + + // Assert + Assert.Null(model.Name); + Assert.True(removeStatus); + Assert.True(string.IsNullOrEmpty(errorMessage), "Expected no error message"); + } + + [Fact] + public void TryRemove_ThrowsJsonPatchException_IfPropertyDoesNotExist() + { + // Arrange + var adapter = new PocoAdapter(); + var contractResolver = new DefaultContractResolver(); + var model = new Customer + { + Name = "Joana" + }; + var expectedErrorMessage = "The target location specified by path segment 'LastName' was not found."; + + // Act + var removeStatus = adapter.TryRemove(model, "LastName", contractResolver, out var errorMessage); + + // Assert + Assert.False(removeStatus); + Assert.Equal(expectedErrorMessage, errorMessage); + } + + [Fact] + public void TryReplace_OverwritesExistingValue() + { + // Arrange + var adapter = new PocoAdapter(); + var contractResolver = new DefaultContractResolver(); + var model = new Customer + { + Name = "Joana" + }; + + // Act + var replaceStatus = adapter.TryReplace(model, "Name", contractResolver, "John", out var errorMessage); + + // Assert + Assert.Equal("John", model.Name); + Assert.True(replaceStatus); + Assert.True(string.IsNullOrEmpty(errorMessage), "Expected no error message"); + } + + [Fact] + public void TryReplace_ThrowsJsonPatchException_IfNewValueIsInvalidType() + { + // Arrange + var adapter = new PocoAdapter(); + var contractResolver = new DefaultContractResolver(); + var model = new Customer + { + Age = 25 + }; + + var expectedErrorMessage = "The value 'TwentySix' is invalid for target location."; + + // Act + var replaceStatus = adapter.TryReplace(model, "Age", contractResolver, "TwentySix", out var errorMessage); + + // Assert + Assert.Equal(25, model.Age); + Assert.False(replaceStatus); + Assert.Equal(expectedErrorMessage, errorMessage); + } + + [Fact] + public void TryReplace_ThrowsJsonPatchException_IfPropertyDoesNotExist() + { + // Arrange + var adapter = new PocoAdapter(); + var contractResolver = new DefaultContractResolver(); + var model = new Customer + { + Name = "Joana" + }; + var expectedErrorMessage = "The target location specified by path segment 'LastName' was not found."; + + // Act + var replaceStatus = adapter.TryReplace(model, "LastName", contractResolver, "Smith", out var errorMessage); + + // Assert + Assert.Equal("Joana", model.Name); + Assert.False(replaceStatus); + Assert.Equal(expectedErrorMessage, errorMessage); + } + + [Fact] + public void TryTest_DoesNotThrowException_IfTestSuccessful() + { + var adapter = new PocoAdapter(); + var contractResolver = new DefaultContractResolver(); + var model = new Customer + { + Name = "Joana" + }; + + // Act + var testStatus = adapter.TryTest(model, "Name", contractResolver, "Joana", out var errorMessage); + + // Assert + Assert.Equal("Joana", model.Name); + Assert.True(testStatus); + Assert.True(string.IsNullOrEmpty(errorMessage), "Expected no error message"); + } + + [Fact] + public void TryTest_ThrowsJsonPatchException_IfTestFails() + { + // Arrange + var adapter = new PocoAdapter(); + var contractResolver = new DefaultContractResolver(); + var model = new Customer + { + Name = "Joana" + }; + var expectedErrorMessage = "The current value 'Joana' at path 'Name' is not equal to the test value 'John'."; + + // Act + var testStatus = adapter.TryTest(model, "Name", contractResolver, "John", out var errorMessage); + + // Assert + Assert.False(testStatus); + Assert.Equal(expectedErrorMessage, errorMessage); + } + + private class Customer + { + public string Name { get; set; } + + public int Age { get; set; } + } + } +} diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/IntegrationTests/DynamicObjectIntegrationTests.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/IntegrationTests/DynamicObjectTest.cs similarity index 86% rename from test/Microsoft.AspNetCore.JsonPatch.Test/IntegrationTests/DynamicObjectIntegrationTests.cs rename to test/Microsoft.AspNetCore.JsonPatch.Test/IntegrationTests/DynamicObjectTest.cs index 4b5fc96e24..be7738419f 100644 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/IntegrationTests/DynamicObjectIntegrationTests.cs +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/IntegrationTests/DynamicObjectTest.cs @@ -7,7 +7,7 @@ using Xunit; namespace Microsoft.AspNetCore.JsonPatch.Internal { - public class DynamicObjectIntegrationTests + public class DynamicObjectTest { [Fact] public void AddResults_ShouldReplaceExistingPropertyValue_InNestedDynamicObject() @@ -259,5 +259,45 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal // Assert Assert.Equal(new List() { 4, 5, 6 }, dynamicTestObject.IntegerList); } + + [Fact] + public void TestPropertyValue_FromListToNonList_InNestedTypedObject_InDynamicObject() + { + // Arrange + dynamic dynamicTestObject = new DynamicTestObject(); + dynamicTestObject.Nested = new SimpleObject() + { + IntegerList = new List() { 1, 2, 3 } + }; + + var patchDoc = new JsonPatchDocument(); + patchDoc.Test("Nested/IntegerList/1", 2); + + // Act & Assert + patchDoc.ApplyTo(dynamicTestObject); + } + + [Fact] + public void TestPropertyValue_FromListToNonList_InNestedTypedObject_InDynamicObject_ThrowsJsonPatchException_IfTestFails() + { + // Arrange + dynamic dynamicTestObject = new DynamicTestObject(); + dynamicTestObject.Nested = new SimpleObject() + { + IntegerList = new List() { 1, 2, 3 } + }; + + var patchDoc = new JsonPatchDocument(); + patchDoc.Test("Nested/IntegerList/0", 2); + + // Act + var exception = Assert.Throws(() => + { + patchDoc.ApplyTo(dynamicTestObject); + }); + + // Assert + Assert.Equal("The current value '1' at position '0' is not equal to the test value '2'.", exception.Message); + } } } diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/JsonPatchDocumentTest.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/JsonPatchDocumentTest.cs index 723ef15b64..d754e8da5b 100644 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/JsonPatchDocumentTest.cs +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/JsonPatchDocumentTest.cs @@ -9,42 +9,6 @@ namespace Microsoft.AspNetCore.JsonPatch.Test { public class JsonPatchDocumentTest { - [Fact] - public void TestOperation_ThrowsException_CallsIntoLogErrorAction() - { - // Arrange - var serialized = "[{\"value\":\"John\",\"path\":\"/Name\",\"op\":\"test\"}]"; - var jsonPatchDocument = JsonConvert.DeserializeObject>(serialized); - var model = new Customer(); - var expectedErrorMessage = "The test operation is not supported."; - string actualErrorMessage = null; - - // Act - jsonPatchDocument.ApplyTo(model, (jsonPatchError) => - { - actualErrorMessage = jsonPatchError.ErrorMessage; - }); - - // Assert - Assert.Equal(expectedErrorMessage, actualErrorMessage); - } - - [Fact] - public void TestOperation_NoLogErrorAction_ThrowsJsonPatchException() - { - // Arrange - var serialized = "[{\"value\":\"John\",\"path\":\"/Name\",\"op\":\"test\"}]"; - var jsonPatchDocument = JsonConvert.DeserializeObject>(serialized); - var model = new Customer(); - var expectedErrorMessage = "The test operation is not supported."; - - // Act - var jsonPatchException = Assert.Throws(() => jsonPatchDocument.ApplyTo(model)); - - // Assert - Assert.Equal(expectedErrorMessage, jsonPatchException.Message); - } - [Fact] public void InvalidOperation_ThrowsException_CallsIntoLogErrorAction() { From e46ba481c8b281b04fbb682ca4db92bee6799d24 Mon Sep 17 00:00:00 2001 From: Jass Bagga Date: Thu, 19 Oct 2017 13:32:04 -0700 Subject: [PATCH 163/221] Throw JsonSerializationException from converters (#116) --- .../Converters/JsonPatchDocumentConverter.cs | 2 +- .../TypedJsonPatchDocumentConverter.cs | 3 +-- .../Properties/Resources.Designer.cs | 8 +++---- .../Resources.resx | 2 +- .../ObjectAdapterTests.cs | 24 +++++++++++++++---- 5 files changed, 27 insertions(+), 12 deletions(-) diff --git a/src/Microsoft.AspNetCore.JsonPatch/Converters/JsonPatchDocumentConverter.cs b/src/Microsoft.AspNetCore.JsonPatch/Converters/JsonPatchDocumentConverter.cs index e93e84e12a..aed9c48474 100644 --- a/src/Microsoft.AspNetCore.JsonPatch/Converters/JsonPatchDocumentConverter.cs +++ b/src/Microsoft.AspNetCore.JsonPatch/Converters/JsonPatchDocumentConverter.cs @@ -57,7 +57,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Converters } catch (Exception ex) { - throw new JsonPatchException(Resources.FormatInvalidJsonPatchDocument(objectType.Name), ex); + throw new JsonSerializationException(Resources.InvalidJsonPatchDocument, ex); } } diff --git a/src/Microsoft.AspNetCore.JsonPatch/Converters/TypedJsonPatchDocumentConverter.cs b/src/Microsoft.AspNetCore.JsonPatch/Converters/TypedJsonPatchDocumentConverter.cs index 292a3be556..fd779ba4ee 100644 --- a/src/Microsoft.AspNetCore.JsonPatch/Converters/TypedJsonPatchDocumentConverter.cs +++ b/src/Microsoft.AspNetCore.JsonPatch/Converters/TypedJsonPatchDocumentConverter.cs @@ -4,7 +4,6 @@ using System; using System.Collections.Generic; using System.Reflection; -using Microsoft.AspNetCore.JsonPatch.Exceptions; using Microsoft.AspNetCore.JsonPatch.Operations; using Newtonsoft.Json; using Newtonsoft.Json.Linq; @@ -58,7 +57,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Converters } catch (Exception ex) { - throw new JsonPatchException(Resources.FormatInvalidJsonPatchDocument(objectType.Name), ex); + throw new JsonSerializationException(Resources.InvalidJsonPatchDocument, ex); } } } diff --git a/src/Microsoft.AspNetCore.JsonPatch/Properties/Resources.Designer.cs b/src/Microsoft.AspNetCore.JsonPatch/Properties/Resources.Designer.cs index cfb8e087d0..c314465238 100644 --- a/src/Microsoft.AspNetCore.JsonPatch/Properties/Resources.Designer.cs +++ b/src/Microsoft.AspNetCore.JsonPatch/Properties/Resources.Designer.cs @@ -123,7 +123,7 @@ namespace Microsoft.AspNetCore.JsonPatch => string.Format(CultureInfo.CurrentCulture, GetString("InvalidIndexValue"), p0); /// - /// The type '{0}' was malformed and could not be parsed. + /// The JSON patch document was malformed and could not be parsed. /// internal static string InvalidJsonPatchDocument { @@ -131,10 +131,10 @@ namespace Microsoft.AspNetCore.JsonPatch } /// - /// The type '{0}' was malformed and could not be parsed. + /// The JSON patch document was malformed and could not be parsed. /// - internal static string FormatInvalidJsonPatchDocument(object p0) - => string.Format(CultureInfo.CurrentCulture, GetString("InvalidJsonPatchDocument"), p0); + internal static string FormatInvalidJsonPatchDocument() + => GetString("InvalidJsonPatchDocument"); /// /// Invalid JsonPatch operation '{0}'. diff --git a/src/Microsoft.AspNetCore.JsonPatch/Resources.resx b/src/Microsoft.AspNetCore.JsonPatch/Resources.resx index 3763e4a841..87cc399c62 100644 --- a/src/Microsoft.AspNetCore.JsonPatch/Resources.resx +++ b/src/Microsoft.AspNetCore.JsonPatch/Resources.resx @@ -142,7 +142,7 @@ The path segment '{0}' is invalid for an array index. - The type '{0}' was malformed and could not be parsed. + The JSON patch document was malformed and could not be parsed. Invalid JsonPatch operation '{0}'. diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/ObjectAdapterTests.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/ObjectAdapterTests.cs index d35f8eb4e9..c1d005e897 100644 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/ObjectAdapterTests.cs +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/ObjectAdapterTests.cs @@ -725,7 +725,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Adapters } [Fact] - public void DeserializationMustWorkWithoutEnvelope() + public void Deserialization_Successful_ForValidJsonPatchDocument() { // Arrange var doc = new SimpleObject() @@ -756,19 +756,35 @@ namespace Microsoft.AspNetCore.JsonPatch.Adapters } [Fact] - public void DeserializationMustFailWithEnvelope() + public void Deserialization_Fails_ForInvalidJsonPatchDocument() { // Arrange var serialized = "{\"Operations\": [{ \"op\": \"replace\", \"path\": \"/title\", \"value\": \"New Title\"}]}"; // Act & Assert - var exception = Assert.Throws(() => + var exception = Assert.Throws(() => + { + var deserialized + = JsonConvert.DeserializeObject(serialized); + }); + + Assert.Equal("The JSON patch document was malformed and could not be parsed.", exception.Message); + } + + [Fact] + public void Deserialization_Fails_ForInvalidTypedJsonPatchDocument() + { + // Arrange + var serialized = "{\"Operations\": [{ \"op\": \"replace\", \"path\": \"/title\", \"value\": \"New Title\"}]}"; + + // Act & Assert + var exception = Assert.Throws(() => { var deserialized = JsonConvert.DeserializeObject>(serialized); }); - Assert.Equal("The type 'JsonPatchDocument`1' was malformed and could not be parsed.", exception.Message); + Assert.Equal("The JSON patch document was malformed and could not be parsed.", exception.Message); } [Fact] From e453fafad52649daff689c24fa2374a143f43654 Mon Sep 17 00:00:00 2001 From: Jass Bagga Date: Thu, 26 Oct 2017 12:51:06 -0700 Subject: [PATCH 164/221] Reorganize tests (#117) Addresses #105 --- .../CustomNamingStrategyTests.cs | 153 ++ .../Dynamic/AddOperationTests.cs | 553 ---- .../Dynamic/AddTypedOperationTests.cs | 121 - .../Dynamic/CopyOperationTests.cs | 245 -- .../Dynamic/CopyTypedOperationTests.cs | 268 -- .../Dynamic/CustomNamingStrategyTests.cs | 154 -- .../Dynamic/InheritedObject.cs | 10 - .../Dynamic/MoveOperationTests.cs | 333 --- .../Dynamic/MoveTypedOperationTests.cs | 138 - .../Dynamic/PatchDocumentTests.cs | 95 - .../Dynamic/RemoveOperationTests.cs | 313 --- .../Dynamic/RemoveTypedOperationTests.cs | 244 -- .../Dynamic/ReplaceOperationTests.cs | 206 -- .../Dynamic/ReplaceTypedOperationTests.cs | 191 -- .../Dynamic/SimpleObject.cs | 21 - .../Dynamic/SimpleObjectWithNestedObject.cs | 22 - .../AnonymousObjectIntegrationTest.cs | 190 ++ .../DictionaryIntegrationTest.cs | 319 +++ ...est.cs => DynamicObjectIntegrationTest.cs} | 141 +- .../ExpandoObjectIntegrationTest.cs | 327 +++ .../IntegrationTests/ListIntegrationTest.cs | 366 +++ .../NestedObjectIntegrationTest.cs | 342 +++ .../SimpleObjectIntegrationTest.cs | 128 + .../DictionaryAdapterTest.cs | 34 +- .../DynamicObjectAdapterTest.cs | 12 +- .../{Adapters => Internal}/ListAdapterTest.cs | 40 +- .../{ => Internal}/ObjectVisitorTest.cs | 10 +- .../{ => Internal}/ParsedPathTests.cs | 7 +- .../{Adapters => Internal}/PocoAdapterTest.cs | 0 .../JsonPatchDocumentGetPathTest.cs | 4 +- ...nPatchDocumentJsonPropertyAttributeTest.cs | 271 +- .../JsonPatchDocumentTest.cs | 171 +- .../JsonPropertyComplexNameObject.cs | 16 - .../JsonPropertyObject.cs | 13 - .../JsonPropertyWithAnotherNameObject.cs | 10 - .../JsonPropertyWithInheritanceObject.cs | 15 - .../NestedObject.cs | 10 - .../NestedObjectTests.cs | 2272 ---------------- .../ObjectAdapterTests.cs | 2331 ----------------- ...mpleObjectWithNestedObjectWithNullCheck.cs | 15 - .../SimpleObjectWithNullCheck.cs | 30 - .../TestObjectModels/Customer.cs | 17 + .../DynamicTestObject.cs | 2 +- .../{ => TestObjectModels}/InheritedObject.cs | 0 .../NestedObject.cs | 4 +- .../{ => TestObjectModels}/SimpleObject.cs | 2 + .../SimpleObjectWithNestedObject.cs | 0 47 files changed, 2091 insertions(+), 8075 deletions(-) create mode 100644 test/Microsoft.AspNetCore.JsonPatch.Test/CustomNamingStrategyTests.cs delete mode 100644 test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/AddOperationTests.cs delete mode 100644 test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/AddTypedOperationTests.cs delete mode 100644 test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/CopyOperationTests.cs delete mode 100644 test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/CopyTypedOperationTests.cs delete mode 100644 test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/CustomNamingStrategyTests.cs delete mode 100644 test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/InheritedObject.cs delete mode 100644 test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/MoveOperationTests.cs delete mode 100644 test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/MoveTypedOperationTests.cs delete mode 100644 test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/PatchDocumentTests.cs delete mode 100644 test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/RemoveOperationTests.cs delete mode 100644 test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/RemoveTypedOperationTests.cs delete mode 100644 test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/ReplaceOperationTests.cs delete mode 100644 test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/ReplaceTypedOperationTests.cs delete mode 100644 test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/SimpleObject.cs delete mode 100644 test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/SimpleObjectWithNestedObject.cs create mode 100644 test/Microsoft.AspNetCore.JsonPatch.Test/IntegrationTests/AnonymousObjectIntegrationTest.cs create mode 100644 test/Microsoft.AspNetCore.JsonPatch.Test/IntegrationTests/DictionaryIntegrationTest.cs rename test/Microsoft.AspNetCore.JsonPatch.Test/IntegrationTests/{DynamicObjectTest.cs => DynamicObjectIntegrationTest.cs} (58%) create mode 100644 test/Microsoft.AspNetCore.JsonPatch.Test/IntegrationTests/ExpandoObjectIntegrationTest.cs create mode 100644 test/Microsoft.AspNetCore.JsonPatch.Test/IntegrationTests/ListIntegrationTest.cs create mode 100644 test/Microsoft.AspNetCore.JsonPatch.Test/IntegrationTests/NestedObjectIntegrationTest.cs create mode 100644 test/Microsoft.AspNetCore.JsonPatch.Test/IntegrationTests/SimpleObjectIntegrationTest.cs rename test/Microsoft.AspNetCore.JsonPatch.Test/{Adapters => Internal}/DictionaryAdapterTest.cs (91%) rename test/Microsoft.AspNetCore.JsonPatch.Test/{Adapters => Internal}/DynamicObjectAdapterTest.cs (97%) rename test/Microsoft.AspNetCore.JsonPatch.Test/{Adapters => Internal}/ListAdapterTest.cs (91%) rename test/Microsoft.AspNetCore.JsonPatch.Test/{ => Internal}/ObjectVisitorTest.cs (95%) rename test/Microsoft.AspNetCore.JsonPatch.Test/{ => Internal}/ParsedPathTests.cs (91%) rename test/Microsoft.AspNetCore.JsonPatch.Test/{Adapters => Internal}/PocoAdapterTest.cs (100%) delete mode 100644 test/Microsoft.AspNetCore.JsonPatch.Test/JsonPropertyComplexNameObject.cs delete mode 100644 test/Microsoft.AspNetCore.JsonPatch.Test/JsonPropertyObject.cs delete mode 100644 test/Microsoft.AspNetCore.JsonPatch.Test/JsonPropertyWithAnotherNameObject.cs delete mode 100644 test/Microsoft.AspNetCore.JsonPatch.Test/JsonPropertyWithInheritanceObject.cs delete mode 100644 test/Microsoft.AspNetCore.JsonPatch.Test/NestedObject.cs delete mode 100644 test/Microsoft.AspNetCore.JsonPatch.Test/NestedObjectTests.cs delete mode 100644 test/Microsoft.AspNetCore.JsonPatch.Test/ObjectAdapterTests.cs delete mode 100644 test/Microsoft.AspNetCore.JsonPatch.Test/SimpleObjectWithNestedObjectWithNullCheck.cs delete mode 100644 test/Microsoft.AspNetCore.JsonPatch.Test/SimpleObjectWithNullCheck.cs create mode 100644 test/Microsoft.AspNetCore.JsonPatch.Test/TestObjectModels/Customer.cs rename test/Microsoft.AspNetCore.JsonPatch.Test/{ => TestObjectModels}/DynamicTestObject.cs (98%) rename test/Microsoft.AspNetCore.JsonPatch.Test/{ => TestObjectModels}/InheritedObject.cs (100%) rename test/Microsoft.AspNetCore.JsonPatch.Test/{Dynamic => TestObjectModels}/NestedObject.cs (85%) rename test/Microsoft.AspNetCore.JsonPatch.Test/{ => TestObjectModels}/SimpleObject.cs (86%) rename test/Microsoft.AspNetCore.JsonPatch.Test/{ => TestObjectModels}/SimpleObjectWithNestedObject.cs (100%) diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/CustomNamingStrategyTests.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/CustomNamingStrategyTests.cs new file mode 100644 index 0000000000..ebc45874d9 --- /dev/null +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/CustomNamingStrategyTests.cs @@ -0,0 +1,153 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System.Collections.Generic; +using System.Dynamic; +using Newtonsoft.Json.Serialization; +using Xunit; + +namespace Microsoft.AspNetCore.JsonPatch +{ + public class CustomNamingStrategyTests + { + [Fact] + public void AddProperty_ToDynamicTestObject_WithCustomNamingStrategy() + { + // Arrange + var contractResolver = new DefaultContractResolver + { + NamingStrategy = new TestNamingStrategy() + }; + + dynamic targetObject = new DynamicTestObject(); + targetObject.Test = 1; + + var patchDocument = new JsonPatchDocument(); + patchDocument.Add("NewInt", 1); + patchDocument.ContractResolver = contractResolver; + + // Act + patchDocument.ApplyTo(targetObject); + + // Assert + Assert.Equal(1, targetObject.customNewInt); + Assert.Equal(1, targetObject.Test); + } + + [Fact] + public void CopyPropertyValue_ToDynamicTestObject_WithCustomNamingStrategy() + { + // Arrange + var contractResolver = new DefaultContractResolver + { + NamingStrategy = new TestNamingStrategy() + }; + + dynamic targetObject = new DynamicTestObject(); + targetObject.customStringProperty = "A"; + targetObject.customAnotherStringProperty = "B"; + + var patchDocument = new JsonPatchDocument(); + patchDocument.Copy("StringProperty", "AnotherStringProperty"); + patchDocument.ContractResolver = contractResolver; + + // Act + patchDocument.ApplyTo(targetObject); + + // Assert + Assert.Equal("A", targetObject.customAnotherStringProperty); + } + + [Fact] + public void MovePropertyValue_ForExpandoObject_WithCustomNamingStrategy() + { + // Arrange + var contractResolver = new DefaultContractResolver + { + NamingStrategy = new TestNamingStrategy() + }; + + dynamic targetObject = new ExpandoObject(); + targetObject.customStringProperty = "A"; + targetObject.customAnotherStringProperty = "B"; + + var patchDocument = new JsonPatchDocument(); + patchDocument.Move("StringProperty", "AnotherStringProperty"); + patchDocument.ContractResolver = contractResolver; + + // Act + patchDocument.ApplyTo(targetObject); + var cont = targetObject as IDictionary; + cont.TryGetValue("customStringProperty", out var valueFromDictionary); + + // Assert + Assert.Equal("A", targetObject.customAnotherStringProperty); + Assert.Null(valueFromDictionary); + } + + [Fact] + public void RemoveProperty_FromDictionaryObject_WithCustomNamingStrategy() + { + // Arrange + var contractResolver = new DefaultContractResolver + { + NamingStrategy = new TestNamingStrategy() + }; + + var targetObject = new Dictionary() + { + { "customTest", 1}, + }; + + var patchDocument = new JsonPatchDocument(); + patchDocument.Remove("Test"); + patchDocument.ContractResolver = contractResolver; + + // Act + patchDocument.ApplyTo(targetObject); + var cont = targetObject as IDictionary; + cont.TryGetValue("customTest", out var valueFromDictionary); + + // Assert + Assert.Equal(0, valueFromDictionary); + } + + [Fact] + public void ReplacePropertyValue_ForExpandoObject_WithCustomNamingStrategy() + { + // Arrange + var contractResolver = new DefaultContractResolver + { + NamingStrategy = new TestNamingStrategy() + }; + + dynamic targetObject = new ExpandoObject(); + targetObject.customTest = 1; + + var patchDocument = new JsonPatchDocument(); + patchDocument.Replace("Test", 2); + patchDocument.ContractResolver = contractResolver; + + // Act + patchDocument.ApplyTo(targetObject); + + // Assert + Assert.Equal(2, targetObject.customTest); + } + + private class TestNamingStrategy : NamingStrategy + { + public new bool ProcessDictionaryKeys => true; + + public override string GetDictionaryKey(string key) + { + return "custom" + key; + } + + protected override string ResolvePropertyName(string name) + { + return name; + } + } + } +} diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/AddOperationTests.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/AddOperationTests.cs deleted file mode 100644 index 493444066b..0000000000 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/AddOperationTests.cs +++ /dev/null @@ -1,553 +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; -using System.Collections.Generic; -using System.Dynamic; -using Microsoft.AspNetCore.JsonPatch.Exceptions; -using Newtonsoft.Json; -using Xunit; - -namespace Microsoft.AspNetCore.JsonPatch.Internal -{ - public class AddOperationTests - { - [Fact] - public void AddNewPropertyShouldFailIfRootIsNotAnExpandoObject() - { - dynamic doc = new - { - Test = 1 - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Add("NewInt", 1); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject(serialized); - - var exception = Assert.Throws(() => - { - deserialized.ApplyTo(doc); - }); - Assert.Equal( - string.Format("The target location specified by path segment '{0}' was not found.", "NewInt"), - exception.Message); - } - - [Fact] - public void AddNewProperty() - { - dynamic obj = new ExpandoObject(); - obj.Test = 1; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Add("NewInt", 1); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject(serialized); - - deserialized.ApplyTo(obj); - - Assert.Equal(1, obj.NewInt); - Assert.Equal(1, obj.Test); - } - - [Fact] - public void AddNewPropertyToNestedAnonymousObjectShouldFail() - { - dynamic doc = new - { - Test = 1, - nested = new { } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Add("Nested/NewInt", 1); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject(serialized); - - var exception = Assert.Throws(() => - { - deserialized.ApplyTo(doc); - }); - Assert.Equal( - string.Format("The target location specified by path segment '{0}' was not found.", "NewInt"), - exception.Message); - } - - [Fact] - public void AddNewPropertyToTypedObjectShouldFail() - { - dynamic doc = new - { - Test = 1, - nested = new NestedObject() - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Add("Nested/NewInt", 1); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject(serialized); - - var exception = Assert.Throws(() => - { - deserialized.ApplyTo(doc); - }); - Assert.Equal( - string.Format("The target location specified by path segment '{0}' was not found.", "NewInt"), - exception.Message); - } - - [Fact] - public void AddToExistingPropertyOnNestedObject() - { - dynamic doc = new - { - Test = 1, - nested = new NestedObject() - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Add("Nested/StringProperty", "A"); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject(serialized); - - deserialized.ApplyTo(doc); - - Assert.Equal("A", doc.nested.StringProperty); - Assert.Equal(1, doc.Test); - } - - [Fact] - public void AddNewPropertyToExpandoOject() - { - dynamic doc = new - { - Test = 1, - nested = new ExpandoObject() - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Add("Nested/NewInt", 1); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject(serialized); - - deserialized.ApplyTo(doc); - - Assert.Equal(1, doc.nested.NewInt); - Assert.Equal(1, doc.Test); - } - - [Fact] - public void AddNewPropertyToExpandoOjectInTypedObject() - { - var doc = new NestedObject() - { - DynamicProperty = new ExpandoObject() - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Add("DynamicProperty/NewInt", 1); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject(serialized); - - deserialized.ApplyTo(doc); - - Assert.Equal(1, doc.DynamicProperty.NewInt); - } - - [Fact] - public void AddNewPropertyToTypedObjectInExpandoObject() - { - dynamic dynamicProperty = new ExpandoObject(); - dynamicProperty.StringProperty = "A"; - - var doc = new NestedObject() - { - DynamicProperty = dynamicProperty - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Add("DynamicProperty/StringProperty", "B"); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject(serialized); - - deserialized.ApplyTo(doc); - - Assert.Equal("B", doc.DynamicProperty.StringProperty); - } - - [Fact] - public void AddNewPropertyToAnonymousObjectShouldFail() - { - dynamic doc = new - { - Test = 1 - }; - - dynamic valueToAdd = new { IntValue = 1, StringValue = "test", GuidValue = Guid.NewGuid() }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Add("ComplexProperty", valueToAdd); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject(serialized); - - var exception = Assert.Throws(() => - { - deserialized.ApplyTo(doc); - }); - Assert.Equal( - string.Format("The target location specified by path segment '{0}' was not found.", "ComplexProperty"), - exception.Message); - } - - [Fact] - public void AddResultsReplaceShouldFailOnAnonymousDueToNoSetter() - { - var doc = new - { - StringProperty = "A" - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Add("StringProperty", "B"); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject(serialized); - - var exception = Assert.Throws(() => - { - deserialized.ApplyTo(doc); - }); - Assert.Equal( - string.Format("The property at path '{0}' could not be updated.", "StringProperty"), - exception.Message); - } - - [Fact] - public void AddResultsShouldReplace() - { - dynamic doc = new ExpandoObject(); - doc.StringProperty = "A"; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Add("StringProperty", "B"); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject(serialized); - - deserialized.ApplyTo(doc); - - Assert.Equal("B", doc.StringProperty); - } - - [Fact] - public void AddResultsShouldReplaceInNested() - { - dynamic doc = new ExpandoObject(); - doc.InBetweenFirst = new ExpandoObject(); - doc.InBetweenFirst.InBetweenSecond = new ExpandoObject(); - doc.InBetweenFirst.InBetweenSecond.StringProperty = "A"; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Add("/InBetweenFirst/InBetweenSecond/StringProperty", "B"); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject(serialized); - - deserialized.ApplyTo(doc); - - Assert.Equal("B", doc.InBetweenFirst.InBetweenSecond.StringProperty); - } - - [Fact] - public void AddResultsShouldReplaceInNestedInDynamic() - { - dynamic doc = new ExpandoObject(); - doc.Nested = new NestedObject(); - doc.Nested.DynamicProperty = new ExpandoObject(); - doc.Nested.DynamicProperty.InBetweenFirst = new ExpandoObject(); - doc.Nested.DynamicProperty.InBetweenFirst.InBetweenSecond = new ExpandoObject(); - doc.Nested.DynamicProperty.InBetweenFirst.InBetweenSecond.StringProperty = "A"; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Add("/Nested/DynamicProperty/InBetweenFirst/InBetweenSecond/StringProperty", "B"); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject(serialized); - - deserialized.ApplyTo(doc); - - Assert.Equal("B", doc.Nested.DynamicProperty.InBetweenFirst.InBetweenSecond.StringProperty); - } - - [Fact] - public void ShouldNotBeAbleToAddToNonExistingPropertyThatIsNotTheRoot() - { - //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. - - var doc = new NestedObject() - { - DynamicProperty = new ExpandoObject() - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Add("DynamicProperty/OtherProperty/IntProperty", 1); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject(serialized); - - var exception = Assert.Throws(() => - { - deserialized.ApplyTo(doc); - }); - Assert.Equal( - string.Format( - "For operation '{0}', the target location specified by path '{1}' was not found.", - "add", - "/DynamicProperty/OtherProperty/IntProperty"), - exception.Message); - } - - [Fact] - public void ShouldNotBeAbleToAddToNonExistingPropertyInNestedPropertyThatIsNotTheRoot() - { - //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. - - var doc = new - { - Foo = "bar" - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Add("baz/bat", "qux"); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject(serialized); - - var exception = Assert.Throws(() => - { - deserialized.ApplyTo(doc); - }); - Assert.Equal( - string.Format("The target location specified by path segment '{0}' was not found.", "baz"), - exception.Message); - } - - [Fact] - public void ShouldNotReplacePropertyWithDifferentCase() - { - dynamic doc = new ExpandoObject(); - doc.StringProperty = "A"; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Add("stringproperty", "B"); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject(serialized); - - deserialized.ApplyTo(doc); - - Assert.Equal("A", doc.StringProperty); - Assert.Equal("B", doc.stringproperty); - } - - [Fact] - public void AddToList() - { - var doc = new - { - IntegerList = new List() { 1, 2, 3 } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Add("IntegerList/0", 4); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject(serialized); - - deserialized.ApplyTo(doc); - - Assert.Equal(new List() { 4, 1, 2, 3 }, doc.IntegerList); - } - - [Fact] - public void AddToListNegativePosition() - { - dynamic doc = new ExpandoObject(); - doc.IntegerList = new List() { 1, 2, 3 }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Add("IntegerList/-1", 4); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject(serialized); - - var exception = Assert.Throws(() => - { - deserialized.ApplyTo(doc); - }); - Assert.Equal( - string.Format("The index value provided by path segment '{0}' is out of bounds of the array size.", "-1"), - exception.Message); - } - - [Fact] - public void ShouldAddToListWithDifferentCase() - { - var doc = new - { - IntegerList = new List() { 1, 2, 3 } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Add("integerlist/0", 4); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject(serialized); - - deserialized.ApplyTo(doc); - - Assert.Equal(new List() { 4, 1, 2, 3 }, doc.IntegerList); - } - - [Fact] - public void AddToListInvalidPositionTooLarge() - { - var doc = new - { - IntegerList = new List() { 1, 2, 3 } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Add("IntegerList/4", 4); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject(serialized); - - var exception = Assert.Throws(() => - { - deserialized.ApplyTo(doc); - }); - Assert.Equal( - string.Format("The index value provided by path segment '{0}' is out of bounds of the array size.", "4"), - exception.Message); - } - - [Fact] - public void AddToListAtBeginning() - { - var doc = new - { - IntegerList = new List() { 1, 2, 3 } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Add("IntegerList/0", 4); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject(serialized); - - deserialized.ApplyTo(doc); - - Assert.Equal(new List() { 4, 1, 2, 3 }, doc.IntegerList); - } - - [Fact] - public void AddToListInvalidPositionTooSmall() - { - var doc = new - { - IntegerList = new List() { 1, 2, 3 } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Add("IntegerList/-1", 4); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject(serialized); - - var exception = Assert.Throws(() => - { - deserialized.ApplyTo(doc); - }); - Assert.Equal( - string.Format("The index value provided by path segment '{0}' is out of bounds of the array size.", "-1"), - exception.Message); - } - - [Fact] - public void AddToListAppend() - { - var doc = new - { - IntegerList = new List() { 1, 2, 3 } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Add("IntegerList/-", 4); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject(serialized); - - deserialized.ApplyTo(doc); - - Assert.Equal(new List() { 1, 2, 3, 4 }, doc.IntegerList); - } - } -} \ No newline at end of file diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/AddTypedOperationTests.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/AddTypedOperationTests.cs deleted file mode 100644 index b2eb4d3a3c..0000000000 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/AddTypedOperationTests.cs +++ /dev/null @@ -1,121 +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; -using Microsoft.AspNetCore.JsonPatch.Exceptions; -using Newtonsoft.Json; -using Xunit; - -namespace Microsoft.AspNetCore.JsonPatch.Internal -{ - public class AddTypedOperationTests - { - [Fact] - public void AddToListNegativePosition() - { - var doc = new SimpleObject() - { - IntegerList = new List() { 1, 2, 3 } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Add("IntegerList/-1", 4); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject(serialized); - - var exception = Assert.Throws(() => - { - deserialized.ApplyTo(doc); - }); - Assert.Equal( - string.Format("The index value provided by path segment '{0}' is out of bounds of the array size.", "-1"), - exception.Message); - } - - [Fact] - public void AddToListInList() - { - var doc = new SimpleObjectWithNestedObject() - { - ListOfSimpleObject = new List() - { - new SimpleObject() - { - IntegerList = new List() { 1, 2, 3 } - } - } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Add("ListOfSimpleObject/0/IntegerList/0", 4); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject(serialized); - - deserialized.ApplyTo(doc); - Assert.Equal(new List() { 4, 1, 2, 3 }, doc.ListOfSimpleObject[0].IntegerList); - } - - [Fact] - public void AddToListInListInvalidPositionTooSmall() - { - var doc = new SimpleObjectWithNestedObject() - { - ListOfSimpleObject = new List() - { - new SimpleObject() - { - IntegerList = new List() { 1, 2, 3 } - } - } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Add("ListOfSimpleObject/-1/IntegerList/0", 4); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject(serialized); - - var exception = Assert.Throws(() => - { - deserialized.ApplyTo(doc); - }); - Assert.Equal( - string.Format("The index value provided by path segment '{0}' is out of bounds of the array size.", "-1"), - exception.Message); - } - - [Fact] - public void AddToListInListInvalidPositionTooLarge() - { - var doc = new SimpleObjectWithNestedObject() - { - ListOfSimpleObject = new List() - { - new SimpleObject() - { - IntegerList = new List() { 1, 2, 3 } - } - } - }; - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Add("ListOfSimpleObject/20/IntegerList/0", 4); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject(serialized); - - var exception = Assert.Throws(() => - { - deserialized.ApplyTo(doc); - }); - Assert.Equal( - string.Format("The index value provided by path segment '{0}' is out of bounds of the array size.", "20"), - exception.Message); - } - } -} diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/CopyOperationTests.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/CopyOperationTests.cs deleted file mode 100644 index b2faff25a0..0000000000 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/CopyOperationTests.cs +++ /dev/null @@ -1,245 +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; -using System.Dynamic; -using Newtonsoft.Json; -using Xunit; - -namespace Microsoft.AspNetCore.JsonPatch.Internal -{ - public class CopyOperationTests - { - [Fact] - public void Copy() - { - dynamic doc = new ExpandoObject(); - - doc.StringProperty = "A"; - doc.AnotherStringProperty = "B"; - - var patchDoc = new JsonPatchDocument(); - patchDoc.Copy("StringProperty", "AnotherStringProperty"); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject(serialized); - deserialized.ApplyTo(doc); - - Assert.Equal("A", doc.AnotherStringProperty); - } - - [Fact] - public void CopyInList() - { - dynamic doc = new ExpandoObject(); - doc.IntegerList = new List() { 1, 2, 3 }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Copy("IntegerList/0", "IntegerList/1"); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject(serialized); - - deserialized.ApplyTo(doc); - - Assert.Equal(new List() { 1, 1, 2, 3 }, doc.IntegerList); - } - - [Fact] - public void CopyFromListToEndOfList() - { - dynamic doc = new ExpandoObject(); - doc.IntegerList = new List() { 1, 2, 3 }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Copy("IntegerList/0", "IntegerList/-"); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject(serialized); - deserialized.ApplyTo(doc); - - Assert.Equal(new List() { 1, 2, 3, 1 }, doc.IntegerList); - } - - [Fact] - public void CopyFromListToNonList() - { - dynamic doc = new ExpandoObject(); - doc.IntegerList = new List() { 1, 2, 3 }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Copy("IntegerList/0", "IntegerValue"); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject(serialized); - - deserialized.ApplyTo(doc); - - Assert.Equal(1, doc.IntegerValue); - } - - [Fact] - public void CopyFromNonListToList() - { - dynamic doc = new ExpandoObject(); - doc.IntegerValue = 5; - doc.IntegerList = new List() { 1, 2, 3 }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Copy("IntegerValue", "IntegerList/0"); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject(serialized); - deserialized.ApplyTo(doc); - - Assert.Equal(new List() { 5, 1, 2, 3 }, doc.IntegerList); - } - - [Fact] - public void CopyToEndOfList() - { - dynamic doc = new ExpandoObject(); - doc.IntegerValue = 5; - doc.IntegerList = new List() { 1, 2, 3 }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Copy("IntegerValue", "IntegerList/-"); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject(serialized); - - deserialized.ApplyTo(doc); - - Assert.Equal(new List() { 1, 2, 3, 5 }, doc.IntegerList); - } - - [Fact] - public void NestedCopy() - { - dynamic doc = new ExpandoObject(); - doc.SimpleObject = new SimpleObject() - { - StringProperty = "A", - AnotherStringProperty = "B" - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Copy("SimpleObject/StringProperty", "SimpleObject/AnotherStringProperty"); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject(serialized); - - deserialized.ApplyTo(doc); - - Assert.Equal("A", doc.SimpleObject.AnotherStringProperty); - } - - [Fact] - public void NestedCopyInList() - { - dynamic doc = new ExpandoObject(); - doc.SimpleObject = new SimpleObject() - { - IntegerList = new List() { 1, 2, 3 } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Copy("SimpleObject/IntegerList/0", "SimpleObject/IntegerList/1"); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject(serialized); - deserialized.ApplyTo(doc); - - Assert.Equal(new List() { 1, 1, 2, 3 }, doc.SimpleObject.IntegerList); - } - - [Fact] - public void NestedCopyFromListToEndOfList() - { - dynamic doc = new ExpandoObject(); - doc.SimpleObject = new SimpleObject() - { - IntegerList = new List() { 1, 2, 3 } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Copy("SimpleObject/IntegerList/0", "SimpleObject/IntegerList/-"); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject(serialized); - - deserialized.ApplyTo(doc); - - Assert.Equal(new List() { 1, 2, 3, 1 }, doc.SimpleObject.IntegerList); - } - - [Fact] - public void NestedCopyFromListToNonList() - { - dynamic doc = new ExpandoObject(); - doc.SimpleObject = new SimpleObject() - { - IntegerList = new List() { 1, 2, 3 } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Copy("SimpleObject/IntegerList/0", "SimpleObject/IntegerValue"); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject(serialized); - deserialized.ApplyTo(doc); - - Assert.Equal(1, doc.SimpleObject.IntegerValue); - } - - [Fact] - public void NestedCopyFromNonListToList() - { - dynamic doc = new ExpandoObject(); - doc.SimpleObject = new SimpleObject() - { - IntegerValue = 5, - IntegerList = new List() { 1, 2, 3 } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Copy("SimpleObject/IntegerValue", "SimpleObject/IntegerList/0"); - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject(serialized); - deserialized.ApplyTo(doc); - - Assert.Equal(new List() { 5, 1, 2, 3 }, doc.SimpleObject.IntegerList); - } - - [Fact] - public void NestedCopyToEndOfList() - { - dynamic doc = new ExpandoObject(); - doc.SimpleObject = new SimpleObject() - { - IntegerValue = 5, - IntegerList = new List() { 1, 2, 3 } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Copy("SimpleObject/IntegerValue", "SimpleObject/IntegerList/-"); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject(serialized); - deserialized.ApplyTo(doc); - - Assert.Equal(new List() { 1, 2, 3, 5 }, doc.SimpleObject.IntegerList); - } - } -} diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/CopyTypedOperationTests.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/CopyTypedOperationTests.cs deleted file mode 100644 index d0b0847c71..0000000000 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/CopyTypedOperationTests.cs +++ /dev/null @@ -1,268 +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; -using Newtonsoft.Json; -using Xunit; - -namespace Microsoft.AspNetCore.JsonPatch.Internal -{ - public class CopyTypedOperationTests - { - [Fact] - public void Copy() - { - var doc = new SimpleObject() - { - StringProperty = "A", - AnotherStringProperty = "B" - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Copy("StringProperty", "AnotherStringProperty"); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject(serialized); - deserialized.ApplyTo(doc); - - Assert.Equal("A", doc.AnotherStringProperty); - } - - [Fact] - public void CopyInList() - { - var doc = new SimpleObject() - { - IntegerList = new List() { 1, 2, 3 } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Copy("IntegerList/0", "IntegerList/1"); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject(serialized); - - deserialized.ApplyTo(doc); - - Assert.Equal(new List() { 1, 1, 2, 3 }, doc.IntegerList); - } - - [Fact] - public void CopyFromListToEndOfList() - { - var doc = new SimpleObject() - { - IntegerList = new List() { 1, 2, 3 } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Copy("IntegerList/0", "IntegerList/-"); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject(serialized); - deserialized.ApplyTo(doc); - - Assert.Equal(new List() { 1, 2, 3, 1 }, doc.IntegerList); - } - - [Fact] - public void CopyFromListToNonList() - { - var doc = new SimpleObject() - { - IntegerList = new List() { 1, 2, 3 } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Copy("IntegerList/0", "IntegerValue"); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject(serialized); - - deserialized.ApplyTo(doc); - - Assert.Equal(1, doc.IntegerValue); - } - - [Fact] - public void CopyFromNonListToList() - { - var doc = new SimpleObject() - { - IntegerValue = 5, - IntegerList = new List() { 1, 2, 3 } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Copy("IntegerValue", "IntegerList/0"); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject(serialized); - deserialized.ApplyTo(doc); - - Assert.Equal(new List() { 5, 1, 2, 3 }, doc.IntegerList); - } - - [Fact] - public void CopyToEndOfList() - { - var doc = new SimpleObject() - { - IntegerValue = 5, - IntegerList = new List() { 1, 2, 3 } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Copy("IntegerValue", "IntegerList/-"); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject(serialized); - - deserialized.ApplyTo(doc); - - Assert.Equal(new List() { 1, 2, 3, 5 }, doc.IntegerList); - } - - [Fact] - public void NestedCopy() - { - var doc = new SimpleObjectWithNestedObject() - { - SimpleObject = new SimpleObject() - { - StringProperty = "A", - AnotherStringProperty = "B" - } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Copy("SimpleObject/StringProperty", "SimpleObject/AnotherStringProperty"); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject(serialized); - - deserialized.ApplyTo(doc); - - Assert.Equal("A", doc.SimpleObject.AnotherStringProperty); - } - - [Fact] - public void NestedCopyInList() - { - var doc = new SimpleObjectWithNestedObject() - { - SimpleObject = new SimpleObject() - { - IntegerList = new List() { 1, 2, 3 } - } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Copy("SimpleObject/IntegerList/0", "SimpleObject/IntegerList/1"); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject(serialized); - deserialized.ApplyTo(doc); - - Assert.Equal(new List() { 1, 1, 2, 3 }, doc.SimpleObject.IntegerList); - } - - [Fact] - public void NestedCopyFromListToEndOfList() - { - var doc = new SimpleObjectWithNestedObject() - { - SimpleObject = new SimpleObject() - { - IntegerList = new List() { 1, 2, 3 } - } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Copy("SimpleObject/IntegerList/0", "SimpleObject/IntegerList/-"); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject(serialized); - - deserialized.ApplyTo(doc); - - Assert.Equal(new List() { 1, 2, 3, 1 }, doc.SimpleObject.IntegerList); - } - - [Fact] - public void NestedCopyFromListToNonList() - { - var doc = new SimpleObjectWithNestedObject() - { - SimpleObject = new SimpleObject() - { - IntegerList = new List() { 1, 2, 3 } - } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Copy("SimpleObject/IntegerList/0", "SimpleObject/IntegerValue"); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject(serialized); - deserialized.ApplyTo(doc); - - Assert.Equal(1, doc.SimpleObject.IntegerValue); - } - - [Fact] - public void NestedCopyFromNonListToList() - { - var doc = new SimpleObjectWithNestedObject() - { - SimpleObject = new SimpleObject() - { - IntegerValue = 5, - IntegerList = new List() { 1, 2, 3 } - } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Copy("SimpleObject/IntegerValue", "SimpleObject/IntegerList/0"); - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject(serialized); - deserialized.ApplyTo(doc); - - Assert.Equal(new List() { 5, 1, 2, 3 }, doc.SimpleObject.IntegerList); - } - - [Fact] - public void NestedCopyToEndOfList() - { - var doc = new SimpleObjectWithNestedObject() - { - SimpleObject = new SimpleObject() - { - IntegerValue = 5, - IntegerList = new List() { 1, 2, 3 } - } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Copy("SimpleObject/IntegerValue", "SimpleObject/IntegerList/-"); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject(serialized); - deserialized.ApplyTo(doc); - - Assert.Equal(new List() { 1, 2, 3, 5 }, doc.SimpleObject.IntegerList); - } - } -} diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/CustomNamingStrategyTests.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/CustomNamingStrategyTests.cs deleted file mode 100644 index b829b81902..0000000000 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/CustomNamingStrategyTests.cs +++ /dev/null @@ -1,154 +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; -using System.Dynamic; -using Newtonsoft.Json.Serialization; -using Xunit; - -namespace Microsoft.AspNetCore.JsonPatch.Test.Dynamic -{ - public class CustomNamingStrategyTests - { - [Fact] - public void AddProperty_ToExpandoObject_WithCustomNamingStrategy() - { - // Arrange - var contractResolver = new DefaultContractResolver - { - NamingStrategy = new TestNamingStrategy() - }; - - dynamic obj = new ExpandoObject(); - obj.Test = 1; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Add("NewInt", 1); - patchDoc.ContractResolver = contractResolver; - - // Act - patchDoc.ApplyTo(obj); - - // Assert - Assert.Equal(1, obj.customNewInt); - Assert.Equal(1, obj.Test); - } - - [Fact] - public void CopyPropertyValue_ForExpandoObject_WithCustomNamingStrategy() - { - // Arrange - var contractResolver = new DefaultContractResolver - { - NamingStrategy = new TestNamingStrategy() - }; - - dynamic obj = new ExpandoObject(); - obj.customStringProperty = "A"; - obj.customAnotherStringProperty = "B"; - - var patchDoc = new JsonPatchDocument(); - patchDoc.Copy("StringProperty", "AnotherStringProperty"); - patchDoc.ContractResolver = contractResolver; - - // Act - patchDoc.ApplyTo(obj); - - // Assert - Assert.Equal("A", obj.customAnotherStringProperty); - } - - [Fact] - public void MovePropertyValue_ForExpandoObject_WithCustomNamingStrategy() - { - // Arrange - var contractResolver = new DefaultContractResolver - { - NamingStrategy = new TestNamingStrategy() - }; - - dynamic obj = new ExpandoObject(); - obj.customStringProperty = "A"; - obj.customAnotherStringProperty = "B"; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Move("StringProperty", "AnotherStringProperty"); - patchDoc.ContractResolver = contractResolver; - - // Act - patchDoc.ApplyTo(obj); - var cont = obj as IDictionary; - cont.TryGetValue("customStringProperty", out var valueFromDictionary); - - // Assert - Assert.Equal("A", obj.customAnotherStringProperty); - Assert.Null(valueFromDictionary); - } - - [Fact] - public void RemoveProperty_FromExpandoObject_WithCustomNamingStrategy() - { - // Arrange - var contractResolver = new DefaultContractResolver - { - NamingStrategy = new TestNamingStrategy() - }; - - dynamic obj = new ExpandoObject(); - obj.customTest = 1; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Remove("Test"); - patchDoc.ContractResolver = contractResolver; - - // Act - patchDoc.ApplyTo(obj); - var cont = obj as IDictionary; - cont.TryGetValue("customTest", out var valueFromDictionary); - - // Assert - Assert.Null(valueFromDictionary); - } - - [Fact] - public void ReplacePropertyValue_ForExpandoObject_WithCustomNamingStrategy() - { - // Arrange - var contractResolver = new DefaultContractResolver - { - NamingStrategy = new TestNamingStrategy() - }; - - dynamic obj = new ExpandoObject(); - obj.customTest = 1; - - var patchDoc = new JsonPatchDocument(); - patchDoc.Replace("Test", 2); - patchDoc.ContractResolver = contractResolver; - - // Act - patchDoc.ApplyTo(obj); - - // Assert - Assert.Equal(2, obj.customTest); - } - - private class TestNamingStrategy : NamingStrategy - { - public new bool ProcessDictionaryKeys => true; - - public override string GetDictionaryKey(string key) - { - return "custom" + key; - } - - protected override string ResolvePropertyName(string name) - { - return name; - } - } - } -} diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/InheritedObject.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/InheritedObject.cs deleted file mode 100644 index 29424d591e..0000000000 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/InheritedObject.cs +++ /dev/null @@ -1,10 +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.Internal -{ - public class InheritedObject : SimpleObject - { - public string AdditionalStringProperty { get; set; } - } -} \ No newline at end of file diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/MoveOperationTests.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/MoveOperationTests.cs deleted file mode 100644 index 31f58c4b82..0000000000 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/MoveOperationTests.cs +++ /dev/null @@ -1,333 +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; -using System.Dynamic; -using Newtonsoft.Json; -using Xunit; - -namespace Microsoft.AspNetCore.JsonPatch.Internal -{ - public class MoveOperationTests - { - [Fact] - public void Move() - { - dynamic doc = new ExpandoObject(); - doc.StringProperty = "A"; - doc.AnotherStringProperty = "B"; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Move("StringProperty", "AnotherStringProperty"); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject(serialized); - - deserialized.ApplyTo(doc); - - Assert.Equal("A", doc.AnotherStringProperty); - - var cont = doc as IDictionary; - cont.TryGetValue("StringProperty", out object valueFromDictionary); - Assert.Null(valueFromDictionary); - } - - [Fact] - public void MoveToNonExisting() - { - dynamic doc = new ExpandoObject(); - doc.StringProperty = "A"; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Move("StringProperty", "AnotherStringProperty"); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject(serialized); - - deserialized.ApplyTo(doc); - - Assert.Equal("A", doc.AnotherStringProperty); - - var cont = doc as IDictionary; - cont.TryGetValue("StringProperty", out var valueFromDictionary); - Assert.Null(valueFromDictionary); - } - - [Fact] - public void MoveDynamicToTyped() - { - dynamic doc = new ExpandoObject(); - doc.StringProperty = "A"; - doc.SimpleDTO = new SimpleObject() { AnotherStringProperty = "B" }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Move("StringProperty", "SimpleDTO/AnotherStringProperty"); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject(serialized); - - deserialized.ApplyTo(doc); - - Assert.Equal("A", doc.SimpleDTO.AnotherStringProperty); - - var cont = doc as IDictionary; - cont.TryGetValue("StringProperty", out object valueFromDictionary); - Assert.Null(valueFromDictionary); - } - - [Fact] - public void MoveTypedToDynamic() - { - dynamic doc = new ExpandoObject(); - doc.StringProperty = "A"; - doc.SimpleDTO = new SimpleObject() { AnotherStringProperty = "B" }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Move("SimpleDTO/AnotherStringProperty", "StringProperty"); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject(serialized); - - deserialized.ApplyTo(doc); - - Assert.Equal("B", doc.StringProperty); - Assert.Null(doc.SimpleDTO.AnotherStringProperty); - } - - [Fact] - public void NestedMove() - { - dynamic doc = new ExpandoObject(); - doc.Nested = new SimpleObject() - { - StringProperty = "A", - AnotherStringProperty = "B" - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Move("Nested/StringProperty", "Nested/AnotherStringProperty"); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject(serialized); - - deserialized.ApplyTo(doc); - - Assert.Equal("A", doc.Nested.AnotherStringProperty); - Assert.Null(doc.Nested.StringProperty); - } - - [Fact] - public void MoveInList() - { - dynamic doc = new ExpandoObject(); - doc.IntegerList = new List() { 1, 2, 3 }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Move("IntegerList/0", "IntegerList/1"); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject(serialized); - - deserialized.ApplyTo(doc); - - Assert.Equal(new List() { 2, 1, 3 }, doc.IntegerList); - } - - [Fact] - public void NestedMoveInList() - { - dynamic doc = new ExpandoObject(); - doc.Nested = new SimpleObject() - { - IntegerList = new List() { 1, 2, 3 } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Move("Nested/IntegerList/0", "Nested/IntegerList/1"); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject(serialized); - - deserialized.ApplyTo(doc); - - Assert.Equal(new List() { 2, 1, 3 }, doc.Nested.IntegerList); - } - - [Fact] - public void MoveFromListToEndOfList() - { - dynamic doc = new ExpandoObject(); - doc.IntegerList = new List() { 1, 2, 3 }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Move("IntegerList/0", "IntegerList/-"); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject(serialized); - deserialized.ApplyTo(doc); - - Assert.Equal(new List() { 2, 3, 1 }, doc.IntegerList); - } - - [Fact] - public void NestedMoveFromListToEndOfList() - { - dynamic doc = new ExpandoObject(); - doc.Nested = new SimpleObject() - { - IntegerList = new List() { 1, 2, 3 } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Move("Nested/IntegerList/0", "Nested/IntegerList/-"); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject(serialized); - deserialized.ApplyTo(doc); - - Assert.Equal(new List() { 2, 3, 1 }, doc.Nested.IntegerList); - } - - [Fact] - public void MoveFomListToNonList() - { - dynamic doc = new ExpandoObject(); - doc.IntegerList = new List() { 1, 2, 3 }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Move("IntegerList/0", "IntegerValue"); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject(serialized); - - deserialized.ApplyTo(doc); - - Assert.Equal(new List() { 2, 3 }, doc.IntegerList); - Assert.Equal(1, doc.IntegerValue); - } - - [Fact] - public void NestedMoveFomListToNonList() - { - dynamic doc = new ExpandoObject(); - doc.Nested = new SimpleObject() - { - IntegerList = new List() { 1, 2, 3 } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Move("Nested/IntegerList/0", "Nested/IntegerValue"); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject(serialized); - - deserialized.ApplyTo(doc); - - Assert.Equal(new List() { 2, 3 }, doc.Nested.IntegerList); - Assert.Equal(1, doc.Nested.IntegerValue); - } - - [Fact] - public void MoveFromNonListToList() - { - dynamic doc = new ExpandoObject(); - doc.IntegerValue = 5; - doc.IntegerList = new List() { 1, 2, 3 }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Move("IntegerValue", "IntegerList/0"); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject(serialized); - - deserialized.ApplyTo(doc); - - var cont = doc as IDictionary; - cont.TryGetValue("IntegerValue", out object valueFromDictionary); - Assert.Null(valueFromDictionary); - - Assert.Equal(new List() { 5, 1, 2, 3 }, doc.IntegerList); - } - - [Fact] - public void NestedMoveFromNonListToList() - { - dynamic doc = new ExpandoObject(); - doc.Nested = new SimpleObject() - { - IntegerValue = 5, - IntegerList = new List() { 1, 2, 3 } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Move("Nested/IntegerValue", "Nested/IntegerList/0"); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject(serialized); - - deserialized.ApplyTo(doc); - - Assert.Equal(0, doc.Nested.IntegerValue); - Assert.Equal(new List() { 5, 1, 2, 3 }, doc.Nested.IntegerList); - } - - [Fact] - public void MoveToEndOfList() - { - dynamic doc = new ExpandoObject(); - doc.IntegerValue = 5; - doc.IntegerList = new List() { 1, 2, 3 }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Move("IntegerValue", "IntegerList/-"); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject(serialized); - - deserialized.ApplyTo(doc); - - var cont = doc as IDictionary; - cont.TryGetValue("IntegerValue", out var valueFromDictionary); - Assert.Null(valueFromDictionary); - - Assert.Equal(new List() { 1, 2, 3, 5 }, doc.IntegerList); - } - - [Fact] - public void NestedMoveToEndOfList() - { - dynamic doc = new ExpandoObject(); - doc.Nested = new SimpleObject() - { - IntegerValue = 5, - IntegerList = new List() { 1, 2, 3 } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Move("Nested/IntegerValue", "Nested/IntegerList/-"); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject(serialized); - - deserialized.ApplyTo(doc); - - Assert.Equal(0, doc.Nested.IntegerValue); - Assert.Equal(new List() { 1, 2, 3, 5 }, doc.Nested.IntegerList); - } - } -} diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/MoveTypedOperationTests.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/MoveTypedOperationTests.cs deleted file mode 100644 index 4638718a59..0000000000 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/MoveTypedOperationTests.cs +++ /dev/null @@ -1,138 +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; -using Newtonsoft.Json; -using Xunit; - -namespace Microsoft.AspNetCore.JsonPatch.Internal -{ - public class MoveTypedOperationTests - { - [Fact] - public void Move() - { - var doc = new SimpleObject() - { - StringProperty = "A", - AnotherStringProperty = "B" - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Move("StringProperty", "AnotherStringProperty"); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject(serialized); - - deserialized.ApplyTo(doc); - - Assert.Equal("A", doc.AnotherStringProperty); - Assert.Null(doc.StringProperty); - } - - [Fact] - public void MoveInList() - { - var doc = new SimpleObject() - { - IntegerList = new List() { 1, 2, 3 } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Move("IntegerList/0", "IntegerList/1"); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject(serialized); - - deserialized.ApplyTo(doc); - - Assert.Equal(new List() { 2, 1, 3 }, doc.IntegerList); - } - - [Fact] - public void MoveFromListToEndOfList() - { - var doc = new SimpleObject() - { - IntegerList = new List() { 1, 2, 3 } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Move("IntegerList/0", "IntegerList/-"); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject(serialized); - deserialized.ApplyTo(doc); - - Assert.Equal(new List() { 2, 3, 1 }, doc.IntegerList); - } - - [Fact] - public void MoveFomListToNonList() - { - var doc = new SimpleObject() - { - IntegerList = new List() { 1, 2, 3 } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Move("IntegerList/0", "IntegerValue"); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject(serialized); - - deserialized.ApplyTo(doc); - - Assert.Equal(new List() { 2, 3 }, doc.IntegerList); - Assert.Equal(1, doc.IntegerValue); - } - - [Fact] - public void MoveFromNonListToList() - { - var doc = new SimpleObject() - { - IntegerValue = 5, - IntegerList = new List() { 1, 2, 3 } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Move("IntegerValue", "IntegerList/0"); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject(serialized); - - deserialized.ApplyTo(doc); - - Assert.Equal(0, doc.IntegerValue); - Assert.Equal(new List() { 5, 1, 2, 3 }, doc.IntegerList); - } - - [Fact] - public void MoveToEndOfList() - { - var doc = new SimpleObject() - { - IntegerValue = 5, - IntegerList = new List() { 1, 2, 3 } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Move("IntegerValue", "IntegerList/-"); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject(serialized); - - deserialized.ApplyTo(doc); - - Assert.Equal(0, doc.IntegerValue); - Assert.Equal(new List() { 1, 2, 3, 5 }, doc.IntegerList); - } - } -} diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/PatchDocumentTests.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/PatchDocumentTests.cs deleted file mode 100644 index 403238bf99..0000000000 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/PatchDocumentTests.cs +++ /dev/null @@ -1,95 +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 Microsoft.AspNetCore.JsonPatch.Exceptions; -using Newtonsoft.Json; -using Xunit; - -namespace Microsoft.AspNetCore.JsonPatch.Internal -{ - public class PatchDocumentTests - { - [Fact] - public void InvalidPathAtBeginningShouldThrowException() - { - var patchDoc = new JsonPatchDocument(); - var exception = Assert.Throws(() => - { - patchDoc.Add("//NewInt", 1); - }); - Assert.Equal( - "The provided string '//NewInt' is an invalid path.", - exception.Message); - } - - [Fact] - public void InvalidPathAtEndShouldThrowException() - { - var patchDoc = new JsonPatchDocument(); - var exception = Assert.Throws(() => - { - patchDoc.Add("NewInt//", 1); - }); - Assert.Equal( - "The provided string 'NewInt//' is an invalid path.", - exception.Message); - } - - [Fact] - public void InvalidPathWithDotShouldThrowException() - { - var patchDoc = new JsonPatchDocument(); - var exception = Assert.Throws(() => - { - patchDoc.Add("NewInt.Test", 1); - }); - Assert.Equal( - "The provided string 'NewInt.Test' is an invalid path.", - exception.Message); - } - - [Fact] - public void NonGenericPatchDocToGenericMustSerialize() - { - var doc = new SimpleObject() - { - StringProperty = "A", - AnotherStringProperty = "B" - }; - - var patchDoc = new JsonPatchDocument(); - patchDoc.Copy("StringProperty", "AnotherStringProperty"); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject>(serialized); - - deserialized.ApplyTo(doc); - - Assert.Equal("A", doc.AnotherStringProperty); - } - - [Fact] - public void GenericPatchDocToNonGenericMustSerialize() - { - var doc = new SimpleObject() - { - StringProperty = "A", - AnotherStringProperty = "B" - }; - - var patchDocTyped = new JsonPatchDocument(); - patchDocTyped.Copy(o => o.StringProperty, o => o.AnotherStringProperty); - - var patchDocUntyped = new JsonPatchDocument(); - patchDocUntyped.Copy("StringProperty", "AnotherStringProperty"); - - var serializedTyped = JsonConvert.SerializeObject(patchDocTyped); - var serializedUntyped = JsonConvert.SerializeObject(patchDocUntyped); - var deserialized = JsonConvert.DeserializeObject(serializedTyped); - - deserialized.ApplyTo(doc); - - Assert.Equal("A", doc.AnotherStringProperty); - } - } -} \ No newline at end of file diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/RemoveOperationTests.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/RemoveOperationTests.cs deleted file mode 100644 index 22707add87..0000000000 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/RemoveOperationTests.cs +++ /dev/null @@ -1,313 +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; -using System.Dynamic; -using Microsoft.AspNetCore.JsonPatch.Exceptions; -using Newtonsoft.Json; -using Xunit; - -namespace Microsoft.AspNetCore.JsonPatch.Internal -{ - public class RemoveOperationTests - { - [Fact] - public void RemovePropertyShouldFailIfRootIsAnonymous() - { - dynamic doc = new - { - Test = 1 - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Remove("Test"); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject(serialized); - - var exception = Assert.Throws(() => - { - deserialized.ApplyTo(doc); - }); - Assert.Equal( - string.Format("The property at path '{0}' could not be updated.", "Test"), - exception.Message); - } - - [Fact] - public void RemovePropertyShouldFailIfItDoesntExist() - { - dynamic doc = new ExpandoObject(); - doc.Test = 1; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Remove("NonExisting"); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject(serialized); - - var exception = Assert.Throws(() => - { - deserialized.ApplyTo(doc); - }); - Assert.Equal( - string.Format("The target location specified by path segment '{0}' was not found.", "NonExisting"), - exception.Message); - } - - [Fact] - public void RemovePropertyFromExpandoObject() - { - dynamic obj = new ExpandoObject(); - obj.Test = 1; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Remove("Test"); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject(serialized); - - deserialized.ApplyTo(obj); - - var cont = obj as IDictionary; - cont.TryGetValue("Test", out object valueFromDictionary); - Assert.Null(valueFromDictionary); - } - - [Fact] - public void RemoveProperty_FromExpandoObject_MixedCase_ThrowsPathNotFoundException() - { - dynamic obj = new ExpandoObject(); - obj.Test = 1; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Remove("test"); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject(serialized); - - var exception = Assert.Throws(() => - { - deserialized.ApplyTo(obj); - }); - - Assert.Equal( - string.Format( - "The target location specified by path segment '{0}' was not found.", - "test"), - exception.Message); - } - - [Fact] - public void RemoveNestedPropertyFromExpandoObject() - { - dynamic obj = new ExpandoObject(); - obj.Test = new ExpandoObject(); - obj.Test.AnotherTest = "A"; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Remove("Test"); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject(serialized); - - deserialized.ApplyTo(obj); - - var cont = obj as IDictionary; - cont.TryGetValue("Test", out object valueFromDictionary); - Assert.Null(valueFromDictionary); - } - - [Fact] - public void RemoveNestedProperty_FromExpandoObject_MixedCase_ThrowsPathNotFoundException() - { - dynamic obj = new ExpandoObject(); - obj.Test = new ExpandoObject(); - obj.Test.AnotherTest = "A"; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Remove("test"); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject(serialized); - - var exception = Assert.Throws(() => - { - deserialized.ApplyTo(obj); - }); - - Assert.Equal( - string.Format( - "The target location specified by path segment '{0}' was not found.", - "test"), - exception.Message); - } - - [Fact] - public void NestedRemove() - { - dynamic doc = new ExpandoObject(); - doc.SimpleDTO = new SimpleObject() - { - StringProperty = "A" - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Remove("SimpleDTO/StringProperty"); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject(serialized); - - deserialized.ApplyTo(doc); - Assert.Null(doc.SimpleDTO.StringProperty); - } - - [Fact] - public void NestedRemove_MixedCase_ThrowsPathNotFoundException() - { - dynamic doc = new ExpandoObject(); - doc.SimpleObject = new SimpleObject() - { - StringProperty = "A" - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Remove("Simpleobject/stringProperty"); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject(serialized); - - var exception = Assert.Throws(() => - { - deserialized.ApplyTo(doc); - }); - - Assert.Equal( - string.Format( - "For operation '{0}', the target location specified by path '{1}' was not found.", - "remove", - "/Simpleobject/stringProperty"), - exception.Message); - } - - [Fact] - public void NestedRemoveFromList() - { - dynamic doc = new ExpandoObject(); - doc.SimpleDTO = new SimpleObject() - { - IntegerList = new List() { 1, 2, 3 } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Remove("SimpleDTO/IntegerList/2"); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject(serialized); - - deserialized.ApplyTo(doc); - - Assert.Equal(new List() { 1, 2 }, doc.SimpleDTO.IntegerList); - } - - [Fact] - public void NestedRemoveFromList_MixedCase() - { - dynamic doc = new ExpandoObject(); - doc.SimpleDTO = new SimpleObject() - { - IntegerList = new List() { 1, 2, 3 } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Remove("SimpleDTO/Integerlist/2"); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject(serialized); - - deserialized.ApplyTo(doc); - - Assert.Equal(new List() { 1, 2 }, doc.SimpleDTO.IntegerList); - } - - [Fact] - public void NestedRemoveFromListInvalidPositionTooLarge() - { - dynamic doc = new ExpandoObject(); - doc.SimpleDTO = new SimpleObject() - { - IntegerList = new List() { 1, 2, 3 } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Remove("SimpleDTO/IntegerList/3"); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject(serialized); - - var exception = Assert.Throws(() => - { - deserialized.ApplyTo(doc); - }); - Assert.Equal( - string.Format("The index value provided by path segment '{0}' is out of bounds of the array size.", "3"), - exception.Message); - } - - [Fact] - public void NestedRemoveFromListInvalidPositionTooSmall() - { - dynamic doc = new ExpandoObject(); - doc.SimpleDTO = new SimpleObject() - { - IntegerList = new List() { 1, 2, 3 } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Remove("SimpleDTO/IntegerList/-1"); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject(serialized); - - var exception = Assert.Throws(() => - { - deserialized.ApplyTo(doc); - }); - Assert.Equal( - string.Format("The index value provided by path segment '{0}' is out of bounds of the array size.", "-1"), - exception.Message); - } - - [Fact] - public void NestedRemoveFromEndOfList() - { - dynamic doc = new ExpandoObject(); - doc.SimpleDTO = new SimpleObject() - { - IntegerList = new List() { 1, 2, 3 } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Remove("SimpleDTO/IntegerList/-"); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject(serialized); - - deserialized.ApplyTo(doc); - Assert.Equal(new List() { 1, 2 }, doc.SimpleDTO.IntegerList); - } - } -} diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/RemoveTypedOperationTests.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/RemoveTypedOperationTests.cs deleted file mode 100644 index 000b049b1b..0000000000 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/RemoveTypedOperationTests.cs +++ /dev/null @@ -1,244 +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; -using Microsoft.AspNetCore.JsonPatch.Exceptions; -using Newtonsoft.Json; -using Xunit; - -namespace Microsoft.AspNetCore.JsonPatch.Internal -{ - public class RemoveTypedOperationTests - { - [Fact] - public void Remove() - { - var doc = new SimpleObject() - { - StringProperty = "A" - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Remove("StringProperty"); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject(serialized); - - deserialized.ApplyTo(doc); - - Assert.Null(doc.StringProperty); - } - - [Fact] - public void RemoveFromList() - { - var doc = new SimpleObject() - { - IntegerList = new List() { 1, 2, 3 } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Remove("IntegerList/2"); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject(serialized); - - deserialized.ApplyTo(doc); - - Assert.Equal(new List() { 1, 2 }, doc.IntegerList); - } - - [Fact] - public void RemoveFromListInvalidPositionTooLarge() - { - var doc = new SimpleObject() - { - IntegerList = new List() { 1, 2, 3 } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Remove("IntegerList/3"); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject(serialized); - - var exception = Assert.Throws(() => - { - deserialized.ApplyTo(doc); - }); - Assert.Equal( - string.Format("The index value provided by path segment '{0}' is out of bounds of the array size.", "3"), - exception.Message); - } - - [Fact] - public void RemoveFromListInvalidPositionTooSmall() - { - var doc = new SimpleObject() - { - IntegerList = new List() { 1, 2, 3 } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Remove("IntegerList/-1"); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject(serialized); - - var exception = Assert.Throws(() => - { - deserialized.ApplyTo(doc); - }); - Assert.Equal( - string.Format("The index value provided by path segment '{0}' is out of bounds of the array size.", "-1"), - exception.Message); - } - - [Fact] - public void RemoveFromEndOfList() - { - var doc = new SimpleObject() - { - IntegerList = new List() { 1, 2, 3 } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Remove("IntegerList/-"); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject(serialized); - - deserialized.ApplyTo(doc); - - Assert.Equal(new List() { 1, 2 }, doc.IntegerList); - } - - [Fact] - public void NestedRemove() - { - var doc = new SimpleObjectWithNestedObject() - { - SimpleObject = new SimpleObject() - { - StringProperty = "A" - } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Remove("SimpleObject/StringProperty"); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject(serialized); - - deserialized.ApplyTo(doc); - - Assert.Null(doc.SimpleObject.StringProperty); - } - - [Fact] - public void NestedRemoveFromList() - { - var doc = new SimpleObjectWithNestedObject() - { - SimpleObject = new SimpleObject() - { - IntegerList = new List() { 1, 2, 3 } - } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Remove("SimpleObject/IntegerList/2"); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject(serialized); - - deserialized.ApplyTo(doc); - - Assert.Equal(new List() { 1, 2 }, doc.SimpleObject.IntegerList); - } - - [Fact] - public void NestedRemoveFromListInvalidPositionTooLarge() - { - var doc = new SimpleObjectWithNestedObject() - { - SimpleObject = new SimpleObject() - { - IntegerList = new List() { 1, 2, 3 } - } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Remove("SimpleObject/IntegerList/3"); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject(serialized); - - var exception = Assert.Throws(() => - { - deserialized.ApplyTo(doc); - }); - Assert.Equal( - string.Format("The index value provided by path segment '{0}' is out of bounds of the array size.", "3"), - exception.Message); - } - - [Fact] - public void NestedRemoveFromListInvalidPositionTooSmall() - { - var doc = new SimpleObjectWithNestedObject() - { - SimpleObject = new SimpleObject() - { - IntegerList = new List() { 1, 2, 3 } - } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Remove("SimpleObject/IntegerList/-1"); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject(serialized); - - var exception = Assert.Throws(() => - { - deserialized.ApplyTo(doc); - }); - Assert.Equal( - string.Format("The index value provided by path segment '{0}' is out of bounds of the array size.", "-1"), - exception.Message); - } - - [Fact] - public void NestedRemoveFromEndOfList() - { - var doc = new SimpleObjectWithNestedObject() - { - SimpleObject = new SimpleObject() - { - IntegerList = new List() { 1, 2, 3 } - } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Remove("SimpleObject/IntegerList/-"); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject(serialized); - - deserialized.ApplyTo(doc); - - Assert.Equal(new List() { 1, 2 }, doc.SimpleObject.IntegerList); - } - } -} diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/ReplaceOperationTests.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/ReplaceOperationTests.cs deleted file mode 100644 index 5d1fa77d85..0000000000 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/ReplaceOperationTests.cs +++ /dev/null @@ -1,206 +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; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.Dynamic; -using Xunit; - -namespace Microsoft.AspNetCore.JsonPatch.Internal -{ - public class ReplaceOperationTests - { - [Fact] - public void ReplaceGuidTest() - { - dynamic doc = new SimpleObject() - { - GuidValue = Guid.NewGuid() - }; - - var newGuid = Guid.NewGuid(); - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Replace("GuidValue", newGuid); - - patchDoc.ApplyTo(doc); - - Assert.Equal(newGuid, doc.GuidValue); - } - - [Fact] - public void ReplaceGuidTestExpandoObject() - { - dynamic doc = new ExpandoObject(); - doc.GuidValue = Guid.NewGuid(); - - var newGuid = Guid.NewGuid(); - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Replace("GuidValue", newGuid); - - patchDoc.ApplyTo(doc); - - Assert.Equal(newGuid, doc.GuidValue); - } - - [Fact] - public void ReplaceGuidTestExpandoObjectInAnonymous() - { - dynamic nestedObject = new ExpandoObject(); - nestedObject.GuidValue = Guid.NewGuid(); - - dynamic doc = new - { - NestedObject = nestedObject - }; - - var newGuid = Guid.NewGuid(); - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Replace("nestedobject/GuidValue", newGuid); - - patchDoc.ApplyTo(doc); - - Assert.Equal(newGuid, doc.NestedObject.GuidValue); - } - - [Fact] - public void ReplaceNestedObjectTest() - { - dynamic doc = new ExpandoObject(); - doc.SimpleDTO = new SimpleObject() - { - IntegerValue = 5, - IntegerList = new List() { 1, 2, 3 } - }; - - var newDTO = new SimpleObject() - { - DoubleValue = 1 - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Replace("SimpleDTO", newDTO); - - patchDoc.ApplyTo(doc); - - Assert.Equal(1, doc.SimpleDTO.DoubleValue); - Assert.Equal(0, doc.SimpleDTO.IntegerValue); - Assert.Null(doc.SimpleDTO.IntegerList); - } - - [Fact] - public void ReplaceInList() - { - dynamic doc = new ExpandoObject(); - doc.IntegerList = new List() { 1, 2, 3 }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Replace("IntegerList/0", 5); - - patchDoc.ApplyTo(doc); - - Assert.Equal(new List() { 5, 2, 3 }, doc.IntegerList); - } - - [Fact] - public void ReplaceFullList() - { - dynamic doc = new ExpandoObject(); - doc.IntegerList = new List() { 1, 2, 3 }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Replace("IntegerList", new List() { 4, 5, 6 }); - - patchDoc.ApplyTo(doc); - - Assert.Equal(new List() { 4, 5, 6 }, doc.IntegerList); - } - - [Fact] - public void ReplaceInListInList() - { - dynamic doc = new ExpandoObject(); - doc.SimpleDTOList = new List() { - new SimpleObject() { - IntegerList = new List(){1,2,3} - }}; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Replace("SimpleDTOList/0/IntegerList/0", 4); - - patchDoc.ApplyTo(doc); - - Assert.Equal(4, doc.SimpleDTOList[0].IntegerList[0]); - } - - [Fact] - public void ReplaceInListInListAtEnd() - { - dynamic doc = new ExpandoObject(); - doc.SimpleDTOList = new List() { - new SimpleObject() { - IntegerList = new List(){1,2,3} - }}; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Replace("SimpleDTOList/0/IntegerList/-", 4); - - patchDoc.ApplyTo(doc); - - Assert.Equal(4, doc.SimpleDTOList[0].IntegerList[2]); - } - - [Fact] - public void ReplaceFullListFromEnumerable() - { - dynamic doc = new ExpandoObject(); - doc.IntegerList = new List() { 1, 2, 3 }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Replace("IntegerList", new List() { 4, 5, 6 }); - - patchDoc.ApplyTo(doc); - - Assert.Equal(new List() { 4, 5, 6 }, doc.IntegerList); - } - - [Fact] - public void ReplaceFullListWithCollection() - { - dynamic doc = new ExpandoObject(); - doc.IntegerList = new List() { 1, 2, 3 }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Replace("IntegerList", new Collection() { 4, 5, 6 }); - - patchDoc.ApplyTo(doc); - - Assert.Equal(new List() { 4, 5, 6 }, doc.IntegerList); - } - - [Fact] - public void ReplaceAtEndOfList() - { - dynamic doc = new ExpandoObject(); - doc.IntegerList = new List() { 1, 2, 3 }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Replace("IntegerList/-", 5); - - patchDoc.ApplyTo(doc); - - Assert.Equal(new List() { 1, 2, 5 }, doc.IntegerList); - } - } -} diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/ReplaceTypedOperationTests.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/ReplaceTypedOperationTests.cs deleted file mode 100644 index 94131ff3b5..0000000000 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/ReplaceTypedOperationTests.cs +++ /dev/null @@ -1,191 +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; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.Linq; -using Newtonsoft.Json; -using Xunit; - -namespace Microsoft.AspNetCore.JsonPatch.Internal -{ - public class ReplaceTypedOperationTests - { - [Fact] - public void ReplaceGuidTest() - { - var doc = new SimpleObject() - { - GuidValue = Guid.NewGuid() - }; - - var newGuid = Guid.NewGuid(); - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Replace("GuidValue", newGuid); - - // serialize & deserialize - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserizalized = JsonConvert.DeserializeObject(serialized); - - deserizalized.ApplyTo(doc); - - Assert.Equal(newGuid, doc.GuidValue); - } - - [Fact] - public void SerializeAndReplaceNestedObjectTest() - { - var doc = new SimpleObjectWithNestedObject() - { - SimpleObject = new SimpleObject() - { - IntegerValue = 5, - IntegerList = new List() { 1, 2, 3 } - } - }; - - var newDTO = new SimpleObject() - { - DoubleValue = 1 - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Replace("SimpleObject", newDTO); - - // serialize & deserialize - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject(serialized); - - deserialized.ApplyTo(doc); - - Assert.Equal(1, doc.SimpleObject.DoubleValue); - Assert.Equal(0, doc.SimpleObject.IntegerValue); - Assert.Null(doc.SimpleObject.IntegerList); - } - - [Fact] - public void ReplaceInList() - { - var doc = new SimpleObject() - { - IntegerList = new List() { 1, 2, 3 } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Replace("IntegerList/0", 5); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject(serialized); - - deserialized.ApplyTo(doc); - - Assert.Equal(new List() { 5, 2, 3 }, doc.IntegerList); - } - - [Fact] - public void ReplaceFullList() - { - var doc = new SimpleObject() - { - IntegerList = new List() { 1, 2, 3 } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Replace("IntegerList", new List() { 4, 5, 6 }); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject(serialized); - - deserialized.ApplyTo(doc); - - Assert.Equal(new List() { 4, 5, 6 }, doc.IntegerList); - } - - [Fact] - public void ReplaceInListInList() - { - var doc = new SimpleObject() - { - SimpleObjectList = new List() { - new SimpleObject() { - IntegerList = new List(){1,2,3} - }} - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Replace("SimpleObjectList/0/IntegerList/0", 4); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject(serialized); - - deserialized.ApplyTo(doc); - - Assert.Equal(4, doc.SimpleObjectList.First().IntegerList.First()); - } - - [Fact] - public void ReplaceFullListFromEnumerable() - { - var doc = new SimpleObject() - { - IntegerList = new List() { 1, 2, 3 } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Replace("IntegerList", new List() { 4, 5, 6 }); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject(serialized); - - deserialized.ApplyTo(doc); - - Assert.Equal(new List() { 4, 5, 6 }, doc.IntegerList); - } - - [Fact] - public void ReplaceFullListWithCollection() - { - var doc = new SimpleObject() - { - IntegerList = new List() { 1, 2, 3 } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Replace("IntegerList", new Collection() { 4, 5, 6 }); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject(serialized); - - deserialized.ApplyTo(doc); - - Assert.Equal(new List() { 4, 5, 6 }, doc.IntegerList); - } - - [Fact] - public void ReplaceAtEndOfList() - { - var doc = new SimpleObject() - { - IntegerList = new List() { 1, 2, 3 } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Replace("IntegerList/-", 5); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject(serialized); - deserialized.ApplyTo(doc); - - Assert.Equal(new List() { 1, 2, 5 }, doc.IntegerList); - } - } -} diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/SimpleObject.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/SimpleObject.cs deleted file mode 100644 index 01a890d7be..0000000000 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/SimpleObject.cs +++ /dev/null @@ -1,21 +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; -using System.Collections.Generic; - -namespace Microsoft.AspNetCore.JsonPatch.Internal -{ - public class SimpleObject - { - public List SimpleObjectList { get; set; } - public List IntegerList { get; set; } - public int IntegerValue { get; set; } - public string StringProperty { get; set; } - public string AnotherStringProperty { get; set; } - public decimal DecimalValue { get; set; } - public double DoubleValue { get; set; } - public float FloatValue { get; set; } - public Guid GuidValue { get; set; } - } -} diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/SimpleObjectWithNestedObject.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/SimpleObjectWithNestedObject.cs deleted file mode 100644 index aa766b8438..0000000000 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/SimpleObjectWithNestedObject.cs +++ /dev/null @@ -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.Internal -{ - public class SimpleObjectWithNestedObject - { - public int IntegerValue { get; set; } - public NestedObject NestedObject { get; set; } - public SimpleObject SimpleObject { get; set; } - public List ListOfSimpleObject { get; set; } - - public SimpleObjectWithNestedObject() - { - NestedObject = new NestedObject(); - SimpleObject = new SimpleObject(); - ListOfSimpleObject = new List(); - } - } -} diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/IntegrationTests/AnonymousObjectIntegrationTest.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/IntegrationTests/AnonymousObjectIntegrationTest.cs new file mode 100644 index 0000000000..4f290aae2f --- /dev/null +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/IntegrationTests/AnonymousObjectIntegrationTest.cs @@ -0,0 +1,190 @@ +// 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 Microsoft.AspNetCore.JsonPatch.Exceptions; +using Xunit; + +namespace Microsoft.AspNetCore.JsonPatch.IntegrationTests +{ + public class AnonymousObjectIntegrationTest + { + [Fact] + public void AddNewProperty_ShouldFail() + { + // Arrange + var targetObject = new { }; + + var patchDocument = new JsonPatchDocument(); + patchDocument.Add("NewProperty", 4); + + // Act + var exception = Assert.Throws(() => + { + patchDocument.ApplyTo(targetObject); + }); + + // Assert + Assert.Equal("The target location specified by path segment 'NewProperty' was not found.", + exception.Message); + } + + [Fact] + public void AddNewProperty_ToNestedAnonymousObject_ShouldFail() + { + // Arrange + dynamic targetObject = new + { + Test = 1, + nested = new { } + }; + + var patchDocument = new JsonPatchDocument(); + patchDocument.Add("Nested/NewInt", 1); + + // Act + var exception = Assert.Throws(() => + { + patchDocument.ApplyTo(targetObject); + }); + + // Assert + Assert.Equal("The target location specified by path segment 'NewInt' was not found.", + exception.Message); + } + + [Fact] + public void AddDoesNotReplace() + { + // Arrange + var targetObject = new + { + StringProperty = "A" + }; + + var patchDocument = new JsonPatchDocument(); + patchDocument.Add("StringProperty", "B"); + + // Act + var exception = Assert.Throws(() => + { + patchDocument.ApplyTo(targetObject); + }); + + // Assert + Assert.Equal("The property at path 'StringProperty' could not be updated.", + exception.Message); + } + + [Fact] + public void RemoveProperty_ShouldFail() + { + // Arrange + dynamic targetObject = new + { + Test = 1 + }; + + var patchDocument = new JsonPatchDocument(); + patchDocument.Remove("Test"); + + // Act + var exception = Assert.Throws(() => + { + patchDocument.ApplyTo(targetObject); + }); + + // Assert + Assert.Equal("The property at path 'Test' could not be updated.", + exception.Message); + } + + [Fact] + public void ReplaceProperty_ShouldFail() + { + // Arrange + var targetObject = new + { + StringProperty = "A", + AnotherStringProperty = "B" + }; + + var patchDocument = new JsonPatchDocument(); + patchDocument.Replace("StringProperty", "AnotherStringProperty"); + + // Act + var exception = Assert.Throws(() => + { + patchDocument.ApplyTo(targetObject); + }); + + // Assert + Assert.Equal("The property at path 'StringProperty' could not be updated.", + exception.Message); + } + + [Fact] + public void MoveProperty_ShouldFail() + { + // Arrange + var targetObject = new + { + StringProperty = "A", + AnotherStringProperty = "B" + }; + + var patchDocument = new JsonPatchDocument(); + patchDocument.Move("StringProperty", "AnotherStringProperty"); + + // Act + var exception = Assert.Throws(() => + { + patchDocument.ApplyTo(targetObject); + }); + + // Assert + Assert.Equal("The property at path 'StringProperty' could not be updated.", + exception.Message); + } + + [Fact] + public void TestStringProperty_IsSucessful() + { + // Arrange + var targetObject = new + { + StringProperty = "A", + AnotherStringProperty = "B" + }; + + var patchDocument = new JsonPatchDocument(); + patchDocument.Test("StringProperty", "A"); + + // Act & Assert + patchDocument.ApplyTo(targetObject); + } + + [Fact] + public void TestStringProperty_Fails() + { + // Arrange + var targetObject = new + { + StringProperty = "A", + AnotherStringProperty = "B" + }; + + var patchDocument = new JsonPatchDocument(); + patchDocument.Test("StringProperty", "B"); + + // Act + var exception = Assert.Throws(() => + { + patchDocument.ApplyTo(targetObject); + }); + + // Assert + Assert.Equal("The current value 'A' at path 'StringProperty' is not equal to the test value 'B'.", + exception.Message); + } + } +} diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/IntegrationTests/DictionaryIntegrationTest.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/IntegrationTests/DictionaryIntegrationTest.cs new file mode 100644 index 0000000000..da990e3e8c --- /dev/null +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/IntegrationTests/DictionaryIntegrationTest.cs @@ -0,0 +1,319 @@ +// 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.IntegrationTests +{ + public class DictionaryTest + { + [Fact] + public void TestIntegerValue_IsSuccessful() + { + // Arrange + var model = new IntDictionary(); + model.DictionaryOfStringToInteger["one"] = 1; + model.DictionaryOfStringToInteger["two"] = 2; + var patchDocument = new JsonPatchDocument(); + patchDocument.Test("/DictionaryOfStringToInteger/two", 2); + + // Act & Assert + patchDocument.ApplyTo(model); + } + + [Fact] + public void AddIntegerValue_Succeeds() + { + // Arrange + var model = new IntDictionary(); + model.DictionaryOfStringToInteger["one"] = 1; + model.DictionaryOfStringToInteger["two"] = 2; + var patchDocument = new JsonPatchDocument(); + patchDocument.Add("/DictionaryOfStringToInteger/three", 3); + + // Act + patchDocument.ApplyTo(model); + + // Assert + Assert.Equal(3, model.DictionaryOfStringToInteger.Count); + Assert.Equal(1, model.DictionaryOfStringToInteger["one"]); + Assert.Equal(2, model.DictionaryOfStringToInteger["two"]); + Assert.Equal(3, model.DictionaryOfStringToInteger["three"]); + } + + [Fact] + public void RemoveIntegerValue_Succeeds() + { + // Arrange + var model = new IntDictionary(); + model.DictionaryOfStringToInteger["one"] = 1; + model.DictionaryOfStringToInteger["two"] = 2; + var patchDocument = new JsonPatchDocument(); + patchDocument.Remove("/DictionaryOfStringToInteger/two"); + + // Act + patchDocument.ApplyTo(model); + + // Assert + Assert.Equal(1, model.DictionaryOfStringToInteger.Count); + Assert.Equal(1, model.DictionaryOfStringToInteger["one"]); + } + + [Fact] + public void MoveIntegerValue_Succeeds() + { + // Arrange + var model = new IntDictionary(); + model.DictionaryOfStringToInteger["one"] = 1; + model.DictionaryOfStringToInteger["two"] = 2; + var patchDocument = new JsonPatchDocument(); + patchDocument.Move("/DictionaryOfStringToInteger/one", "/DictionaryOfStringToInteger/two"); + + // Act + patchDocument.ApplyTo(model); + + // Assert + Assert.Equal(1, model.DictionaryOfStringToInteger.Count); + Assert.Equal(1, model.DictionaryOfStringToInteger["two"]); + } + + [Fact] + public void ReplaceIntegerValue_Succeeds() + { + // Arrange + var model = new IntDictionary(); + model.DictionaryOfStringToInteger["one"] = 1; + model.DictionaryOfStringToInteger["two"] = 2; + var patchDocument = new JsonPatchDocument(); + patchDocument.Replace("/DictionaryOfStringToInteger/two", 20); + + // Act + patchDocument.ApplyTo(model); + + // Assert + Assert.Equal(2, model.DictionaryOfStringToInteger.Count); + Assert.Equal(1, model.DictionaryOfStringToInteger["one"]); + Assert.Equal(20, model.DictionaryOfStringToInteger["two"]); + } + + [Fact] + public void CopyIntegerValue_Succeeds() + { + // Arrange + var model = new IntDictionary(); + model.DictionaryOfStringToInteger["one"] = 1; + model.DictionaryOfStringToInteger["two"] = 2; + var patchDocument = new JsonPatchDocument(); + patchDocument.Copy("/DictionaryOfStringToInteger/one", "/DictionaryOfStringToInteger/two"); + + // Act + patchDocument.ApplyTo(model); + + // Assert + Assert.Equal(2, model.DictionaryOfStringToInteger.Count); + Assert.Equal(1, model.DictionaryOfStringToInteger["one"]); + Assert.Equal(1, model.DictionaryOfStringToInteger["two"]); + } + + private class Customer + { + public string Name { get; set; } + public Address Address { get; set; } + } + + private class Address + { + public string City { get; set; } + } + + private class IntDictionary + { + public IDictionary DictionaryOfStringToInteger { get; } = new Dictionary(); + } + + private class CustomerDictionary + { + public IDictionary DictionaryOfStringToCustomer { get; } = new Dictionary(); + } + + [Fact] + public void TestPocoObject_Succeeds() + { + // Arrange + var key1 = 100; + var value1 = new Customer() { Name = "James" }; + var model = new CustomerDictionary(); + model.DictionaryOfStringToCustomer[key1] = value1; + var patchDocument = new JsonPatchDocument(); + patchDocument.Test($"/DictionaryOfStringToCustomer/{key1}/Name", "James"); + + // Act & Assert + patchDocument.ApplyTo(model); + } + + [Fact] + public void TestPocoObject_FailsWhenTestValueIsNotEqualToObjectValue() + { + // Arrange + var key1 = 100; + var value1 = new Customer() { Name = "James" }; + var model = new CustomerDictionary(); + model.DictionaryOfStringToCustomer[key1] = value1; + var patchDocument = new JsonPatchDocument(); + patchDocument.Test($"/DictionaryOfStringToCustomer/{key1}/Name", "Mike"); + + // Act + var exception = Assert.Throws(() => + { + patchDocument.ApplyTo(model); + }); + + // Assert + Assert.Equal("The current value 'James' at path 'Name' is not equal to the test value 'Mike'.", exception.Message); + } + + [Fact] + public void AddReplacesPocoObject_Succeeds() + { + // Arrange + var key1 = 100; + var value1 = new Customer() { Name = "Jamesss" }; + var key2 = 200; + var value2 = new Customer() { Name = "Mike" }; + var model = new CustomerDictionary(); + model.DictionaryOfStringToCustomer[key1] = value1; + model.DictionaryOfStringToCustomer[key2] = value2; + var patchDocument = new JsonPatchDocument(); + patchDocument.Add($"/DictionaryOfStringToCustomer/{key1}/Name", "James"); + + // Act + patchDocument.ApplyTo(model); + + // Assert + Assert.Equal(2, model.DictionaryOfStringToCustomer.Count); + var actualValue1 = model.DictionaryOfStringToCustomer[key1]; + Assert.NotNull(actualValue1); + Assert.Equal("James", actualValue1.Name); + } + + [Fact] + public void RemovePocoObject_Succeeds() + { + // Arrange + var key1 = 100; + var value1 = new Customer() { Name = "Jamesss" }; + var key2 = 200; + var value2 = new Customer() { Name = "Mike" }; + var model = new CustomerDictionary(); + model.DictionaryOfStringToCustomer[key1] = value1; + model.DictionaryOfStringToCustomer[key2] = value2; + var patchDocument = new JsonPatchDocument(); + patchDocument.Remove($"/DictionaryOfStringToCustomer/{key1}/Name"); + + // Act + patchDocument.ApplyTo(model); + + // Assert + var actualValue1 = model.DictionaryOfStringToCustomer[key1]; + Assert.Null(actualValue1.Name); + } + + [Fact] + public void MovePocoObject_Succeeds() + { + // Arrange + var key1 = 100; + var value1 = new Customer() { Name = "James" }; + var key2 = 200; + var value2 = new Customer() { Name = "Mike" }; + var model = new CustomerDictionary(); + model.DictionaryOfStringToCustomer[key1] = value1; + model.DictionaryOfStringToCustomer[key2] = value2; + var patchDocument = new JsonPatchDocument(); + patchDocument.Move($"/DictionaryOfStringToCustomer/{key1}/Name", $"/DictionaryOfStringToCustomer/{key2}/Name"); + + // Act + patchDocument.ApplyTo(model); + + // Assert + var actualValue2 = model.DictionaryOfStringToCustomer[key2]; + Assert.NotNull(actualValue2); + Assert.Equal("James", actualValue2.Name); + } + + [Fact] + public void CopyPocoObject_Succeeds() + { + // Arrange + var key1 = 100; + var value1 = new Customer() { Name = "James" }; + var key2 = 200; + var value2 = new Customer() { Name = "Mike" }; + var model = new CustomerDictionary(); + model.DictionaryOfStringToCustomer[key1] = value1; + model.DictionaryOfStringToCustomer[key2] = value2; + var patchDocument = new JsonPatchDocument(); + patchDocument.Copy($"/DictionaryOfStringToCustomer/{key1}/Name", $"/DictionaryOfStringToCustomer/{key2}/Name"); + + // Act + patchDocument.ApplyTo(model); + + // Assert + Assert.Equal(2, model.DictionaryOfStringToCustomer.Count); + var actualValue2 = model.DictionaryOfStringToCustomer[key2]; + Assert.NotNull(actualValue2); + Assert.Equal("James", actualValue2.Name); + } + + [Fact] + public void ReplacePocoObject_Succeeds() + { + // Arrange + var key1 = 100; + var value1 = new Customer() { Name = "Jamesss" }; + var key2 = 200; + var value2 = new Customer() { Name = "Mike" }; + var model = new CustomerDictionary(); + model.DictionaryOfStringToCustomer[key1] = value1; + model.DictionaryOfStringToCustomer[key2] = value2; + var patchDocument = new JsonPatchDocument(); + patchDocument.Replace($"/DictionaryOfStringToCustomer/{key1}/Name", "James"); + + // Act + patchDocument.ApplyTo(model); + + // Assert + Assert.Equal(2, model.DictionaryOfStringToCustomer.Count); + var actualValue1 = model.DictionaryOfStringToCustomer[key1]; + Assert.NotNull(actualValue1); + Assert.Equal("James", actualValue1.Name); + } + + [Fact] + public void ReplacePocoObject_WithEscaping_Succeeds() + { + // Arrange + var key1 = "Foo/Name"; + var value1 = 100; + var key2 = "Foo"; + var value2 = 200; + var model = new IntDictionary(); + model.DictionaryOfStringToInteger[key1] = value1; + model.DictionaryOfStringToInteger[key2] = value2; + var patchDocument = new JsonPatchDocument(); + patchDocument.Replace($"/DictionaryOfStringToInteger/Foo~1Name", 300); + + // Act + patchDocument.ApplyTo(model); + + // Assert + Assert.Equal(2, model.DictionaryOfStringToInteger.Count); + var actualValue1 = model.DictionaryOfStringToInteger[key1]; + var actualValue2 = model.DictionaryOfStringToInteger[key2]; + Assert.Equal(300, actualValue1); + Assert.Equal(200, actualValue2); + } + } +} diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/IntegrationTests/DynamicObjectTest.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/IntegrationTests/DynamicObjectIntegrationTest.cs similarity index 58% rename from test/Microsoft.AspNetCore.JsonPatch.Test/IntegrationTests/DynamicObjectTest.cs rename to test/Microsoft.AspNetCore.JsonPatch.Test/IntegrationTests/DynamicObjectIntegrationTest.cs index be7738419f..ec15951a85 100644 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/IntegrationTests/DynamicObjectTest.cs +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/IntegrationTests/DynamicObjectIntegrationTest.cs @@ -5,9 +5,9 @@ using System.Collections.Generic; using Microsoft.AspNetCore.JsonPatch.Exceptions; using Xunit; -namespace Microsoft.AspNetCore.JsonPatch.Internal +namespace Microsoft.AspNetCore.JsonPatch.IntegrationTests { - public class DynamicObjectTest + public class DynamicObjectIntegrationTest { [Fact] public void AddResults_ShouldReplaceExistingPropertyValue_InNestedDynamicObject() @@ -20,11 +20,11 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal 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"); + var patchDocument = new JsonPatchDocument(); + patchDocument.Add("/Nested/DynamicProperty/InBetweenFirst/InBetweenSecond/StringProperty", "B"); // Act - patchDoc.ApplyTo(dynamicTestObject); + patchDocument.ApplyTo(dynamicTestObject); // Assert Assert.Equal("B", dynamicTestObject.Nested.DynamicProperty.InBetweenFirst.InBetweenSecond.StringProperty); @@ -53,21 +53,17 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal DynamicProperty = new DynamicTestObject() }; - var patchDoc = new JsonPatchDocument(); - patchDoc.Add("DynamicProperty/OtherProperty/IntProperty", 1); + var patchDocument = new JsonPatchDocument(); + patchDocument.Add("DynamicProperty/OtherProperty/IntProperty", 1); // Act var exception = Assert.Throws(() => { - patchDoc.ApplyTo(nestedObject); + patchDocument.ApplyTo(nestedObject); }); // Assert - Assert.Equal( - string.Format( - "The target location specified by path segment '{0}' was not found.", - "OtherProperty"), - exception.Message); + Assert.Equal("The target location specified by path segment 'OtherProperty' was not found.", exception.Message); } [Fact] @@ -79,11 +75,11 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal dynamicTestObject.NestedDynamicObject.StringProperty = "A"; dynamicTestObject.NestedDynamicObject.AnotherStringProperty = "B"; - var patchDoc = new JsonPatchDocument(); - patchDoc.Copy("NestedDynamicObject/StringProperty", "NestedDynamicObject/AnotherStringProperty"); + var patchDocument = new JsonPatchDocument(); + patchDocument.Copy("NestedDynamicObject/StringProperty", "NestedDynamicObject/AnotherStringProperty"); // Act - patchDoc.ApplyTo(dynamicTestObject); + patchDocument.ApplyTo(dynamicTestObject); // Assert Assert.Equal("A", dynamicTestObject.NestedDynamicObject.AnotherStringProperty); @@ -97,11 +93,11 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal dynamic dynamicTestObject = new DynamicTestObject(); dynamicTestObject.StringProperty = "A"; - var patchDoc = new JsonPatchDocument(); - patchDoc.Move("StringProperty", "AnotherStringProperty"); + var patchDocument = new JsonPatchDocument(); + patchDocument.Move("StringProperty", "AnotherStringProperty"); // Act - patchDoc.ApplyTo(dynamicTestObject); + patchDocument.ApplyTo(dynamicTestObject); dynamicTestObject.TryGetValue("StringProperty", out object valueFromDictionary); // Assert @@ -117,11 +113,11 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal dynamicTestObject.StringProperty = "A"; dynamicTestObject.SimpleObject = new SimpleObject() { AnotherStringProperty = "B" }; - var patchDoc = new JsonPatchDocument(); - patchDoc.Move("StringProperty", "SimpleObject/AnotherStringProperty"); + var patchDocument = new JsonPatchDocument(); + patchDocument.Move("StringProperty", "SimpleObject/AnotherStringProperty"); // Act - patchDoc.ApplyTo(dynamicTestObject); + patchDocument.ApplyTo(dynamicTestObject); dynamicTestObject.TryGetValue("StringProperty", out object valueFromDictionary); // Assert @@ -129,27 +125,6 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal Assert.Null(valueFromDictionary); } - [Fact] - public void MovePropertyValue_FromListToNonList_InNestedTypedObject_InDynamicObject() - { - // Arrange - dynamic dynamicTestObject = new DynamicTestObject(); - dynamicTestObject.Nested = new SimpleObject() - { - IntegerList = new List() { 1, 2, 3 } - }; - - var patchDoc = new JsonPatchDocument(); - patchDoc.Move("Nested/IntegerList/0", "Nested/IntegerValue"); - - // Act - patchDoc.ApplyTo(dynamicTestObject); - - // Assert - Assert.Equal(new List() { 2, 3 }, dynamicTestObject.Nested.IntegerList); - Assert.Equal(1, dynamicTestObject.Nested.IntegerValue); - } - [Fact] public void RemoveNestedProperty_FromDynamicObject() { @@ -158,11 +133,11 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal dynamicTestObject.Test = new DynamicTestObject(); dynamicTestObject.Test.AnotherTest = "A"; - var patchDoc = new JsonPatchDocument(); - patchDoc.Remove("Test"); + var patchDocument = new JsonPatchDocument(); + patchDocument.Remove("Test"); // Act - patchDoc.ApplyTo(dynamicTestObject); + patchDocument.ApplyTo(dynamicTestObject); dynamicTestObject.TryGetValue("Test", out object valueFromDictionary); // Assert @@ -179,41 +154,19 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal StringProperty = "A" }; - var patchDoc = new JsonPatchDocument(); - patchDoc.Remove("Simpleobject/stringProperty"); + var patchDocument = new JsonPatchDocument(); + patchDocument.Remove("Simpleobject/stringProperty"); // Act var exception = Assert.Throws(() => { - patchDoc.ApplyTo(dynamicTestObject); + patchDocument.ApplyTo(dynamicTestObject); }); // Assert - Assert.Equal( - string.Format("The target location specified by path segment '{0}' was not found.", - "Simpleobject"), - exception.Message); + Assert.Equal("The target location specified by path segment 'Simpleobject' was not found.", exception.Message); } - [Fact] - public void RemoveFromList_NestedInDynamicObject() - { - // Arrange - dynamic dynamicTestObject = new DynamicTestObject(); - dynamicTestObject.SimpleObject = new SimpleObject() - { - IntegerList = new List() { 1, 2, 3 } - }; - - var patchDoc = new JsonPatchDocument(); - patchDoc.Remove("SimpleObject/IntegerList/2"); - - // Act - patchDoc.ApplyTo(dynamicTestObject); - - // Assert - Assert.Equal(new List() { 1, 2 }, dynamicTestObject.SimpleObject.IntegerList); - } [Fact] public void ReplaceNestedTypedObject_InDynamicObject() @@ -231,11 +184,11 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal DoubleValue = 1 }; - var patchDoc = new JsonPatchDocument(); - patchDoc.Replace("SimpleObject", newObject); + var patchDocument = new JsonPatchDocument(); + patchDocument.Replace("SimpleObject", newObject); // Act - patchDoc.ApplyTo(dynamicTestObject); + patchDocument.ApplyTo(dynamicTestObject); // Assert Assert.Equal(1, dynamicTestObject.SimpleObject.DoubleValue); @@ -244,41 +197,21 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal } [Fact] - public void ReplaceFullList_InDynamicObject() + public void TestStringPropertyValue_IsSuccessful() { // Arrange dynamic dynamicTestObject = new DynamicTestObject(); - dynamicTestObject.IntegerList = new List() { 1, 2, 3 }; + dynamicTestObject.Property = "A"; - var patchDoc = new JsonPatchDocument(); - patchDoc.Replace("IntegerList", new List() { 4, 5, 6 }); - - // Act - patchDoc.ApplyTo(dynamicTestObject); - - // Assert - Assert.Equal(new List() { 4, 5, 6 }, dynamicTestObject.IntegerList); - } - - [Fact] - public void TestPropertyValue_FromListToNonList_InNestedTypedObject_InDynamicObject() - { - // Arrange - dynamic dynamicTestObject = new DynamicTestObject(); - dynamicTestObject.Nested = new SimpleObject() - { - IntegerList = new List() { 1, 2, 3 } - }; - - var patchDoc = new JsonPatchDocument(); - patchDoc.Test("Nested/IntegerList/1", 2); + var patchDocument = new JsonPatchDocument(); + patchDocument.Test("Property", "A"); // Act & Assert - patchDoc.ApplyTo(dynamicTestObject); + patchDocument.ApplyTo(dynamicTestObject); } [Fact] - public void TestPropertyValue_FromListToNonList_InNestedTypedObject_InDynamicObject_ThrowsJsonPatchException_IfTestFails() + public void TestIntegerPropertyValue_ThrowsJsonPatchException_IfTestFails() { // Arrange dynamic dynamicTestObject = new DynamicTestObject(); @@ -287,13 +220,13 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal IntegerList = new List() { 1, 2, 3 } }; - var patchDoc = new JsonPatchDocument(); - patchDoc.Test("Nested/IntegerList/0", 2); + var patchDocument = new JsonPatchDocument(); + patchDocument.Test("Nested/IntegerList/0", 2); // Act var exception = Assert.Throws(() => { - patchDoc.ApplyTo(dynamicTestObject); + patchDocument.ApplyTo(dynamicTestObject); }); // Assert diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/IntegrationTests/ExpandoObjectIntegrationTest.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/IntegrationTests/ExpandoObjectIntegrationTest.cs new file mode 100644 index 0000000000..b1b58556f0 --- /dev/null +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/IntegrationTests/ExpandoObjectIntegrationTest.cs @@ -0,0 +1,327 @@ +// 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.Dynamic; +using Microsoft.AspNetCore.JsonPatch.Exceptions; +using Xunit; + +namespace Microsoft.AspNetCore.JsonPatch.IntegrationTests +{ + public class ExpandoObjectIntegrationTest + { + [Fact] + public void AddNewIntProperty() + { + // Arrange + dynamic targetObject = new ExpandoObject(); + targetObject.Test = 1; + + var patchDocument = new JsonPatchDocument(); + patchDocument.Add("NewInt", 1); + + // Act + patchDocument.ApplyTo(targetObject); + + // Assert + Assert.Equal(1, targetObject.NewInt); + Assert.Equal(1, targetObject.Test); + } + + [Fact] + public void AddNewProperty_ToTypedObject_InExpandoObject() + { + // Arrange + dynamic dynamicProperty = new ExpandoObject(); + dynamicProperty.StringProperty = "A"; + + var targetObject = new NestedObject() + { + DynamicProperty = dynamicProperty + }; + + var patchDocument = new JsonPatchDocument(); + patchDocument.Add("DynamicProperty/StringProperty", "B"); + + // Act + patchDocument.ApplyTo(targetObject); + + // Assert + Assert.Equal("B", targetObject.DynamicProperty.StringProperty); + } + + [Fact] + public void AddReplaces_ExistingProperty() + { + // Arrange + dynamic targetObject = new ExpandoObject(); + targetObject.StringProperty = "A"; + + var patchDocument = new JsonPatchDocument(); + patchDocument.Add("StringProperty", "B"); + + // Act + patchDocument.ApplyTo(targetObject); + + // Assert + Assert.Equal("B", targetObject.StringProperty); + } + + [Fact] + public void AddReplaces_ExistingProperty_InNestedExpandoObject() + { + // Arrange + dynamic targetObject = new ExpandoObject(); + targetObject.InBetweenFirst = new ExpandoObject(); + targetObject.InBetweenFirst.InBetweenSecond = new ExpandoObject(); + targetObject.InBetweenFirst.InBetweenSecond.StringProperty = "A"; + + var patchDocument = new JsonPatchDocument(); + patchDocument.Add("/InBetweenFirst/InBetweenSecond/StringProperty", "B"); + + // Act + patchDocument.ApplyTo(targetObject); + + // Assert + Assert.Equal("B", targetObject.InBetweenFirst.InBetweenSecond.StringProperty); + } + + [Fact] + public void ShouldNotReplaceProperty_WithDifferentCase() + { + // Arrange + dynamic targetObject = new ExpandoObject(); + targetObject.StringProperty = "A"; + + var patchDocument = new JsonPatchDocument(); + patchDocument.Add("stringproperty", "B"); + + // Act + patchDocument.ApplyTo(targetObject); + + // Assert + Assert.Equal("A", targetObject.StringProperty); + Assert.Equal("B", targetObject.stringproperty); + } + + [Fact] + public void TestIntegerProperty_IsSucessful() + { + // Arrange + dynamic targetObject = new ExpandoObject(); + targetObject.Test = 1; + + var patchDocument = new JsonPatchDocument(); + patchDocument.Test("Test", 1); + + // Act & Assert + patchDocument.ApplyTo(targetObject); + } + + [Fact] + public void TestStringProperty_ThrowsJsonPatchException_IfTestFails() + { + // Arrange + dynamic targetObject = new ExpandoObject(); + targetObject.Test = "Value"; + + var patchDocument = new JsonPatchDocument(); + patchDocument.Test("Test", "TestValue"); + + // Act + var exception = Assert.Throws(() => + { + patchDocument.ApplyTo(targetObject); + }); + + // Assert + Assert.Equal("The current value 'Value' at path 'Test' is not equal to the test value 'TestValue'.", + exception.Message); + } + + [Fact] + public void CopyStringProperty_ToAnotherStringProperty() + { + // Arrange + dynamic targetObject = new ExpandoObject(); + + targetObject.StringProperty = "A"; + targetObject.AnotherStringProperty = "B"; + + var patchDocument = new JsonPatchDocument(); + patchDocument.Copy("StringProperty", "AnotherStringProperty"); + + // Act + patchDocument.ApplyTo(targetObject); + + // Assert + Assert.Equal("A", targetObject.AnotherStringProperty); + } + + [Fact] + public void MoveIntegerValue_ToAnotherIntegerProperty() + { + // Arrange + dynamic targetObject = new ExpandoObject(); + targetObject.IntegerValue = 100; + targetObject.AnotherIntegerValue = 200; + + var patchDocument = new JsonPatchDocument(); + patchDocument.Move("IntegerValue", "AnotherIntegerValue"); + + // Act + patchDocument.ApplyTo(targetObject); + + Assert.Equal(100, targetObject.AnotherIntegerValue); + + var cont = targetObject as IDictionary; + cont.TryGetValue("IntegerValue", out object valueFromDictionary); + + // Assert + Assert.Null(valueFromDictionary); + } + + [Fact] + public void Move_ToNonExistingProperty() + { + // Arrange + dynamic targetObject = new ExpandoObject(); + targetObject.StringProperty = "A"; + + var patchDocument = new JsonPatchDocument(); + patchDocument.Move("StringProperty", "AnotherStringProperty"); + + // Act + patchDocument.ApplyTo(targetObject); + + Assert.Equal("A", targetObject.AnotherStringProperty); + + var cont = targetObject as IDictionary; + cont.TryGetValue("StringProperty", out var valueFromDictionary); + + // Assert + Assert.Null(valueFromDictionary); + } + + [Fact] + public void RemoveProperty_ShouldFail_IfItDoesntExist() + { + // Arrange + dynamic targetObject = new ExpandoObject(); + targetObject.Test = 1; + + var patchDocument = new JsonPatchDocument(); + patchDocument.Remove("NonExisting"); + + // Act + var exception = Assert.Throws(() => + { + patchDocument.ApplyTo(targetObject); + }); + + // Assert + Assert.Equal("The target location specified by path segment 'NonExisting' was not found.", exception.Message); + } + + [Fact] + public void RemoveStringProperty() + { + // Arrange + dynamic targetObject = new ExpandoObject(); + targetObject.Test = 1; + + var patchDocument = new JsonPatchDocument(); + patchDocument.Remove("Test"); + + // Act + patchDocument.ApplyTo(targetObject); + + var cont = targetObject as IDictionary; + cont.TryGetValue("Test", out object valueFromDictionary); + + // Assert + Assert.Null(valueFromDictionary); + } + + [Fact] + public void RemoveProperty_MixedCase_ThrowsPathNotFoundException() + { + // Arrange + dynamic targetObject = new ExpandoObject(); + targetObject.Test = 1; + + var patchDocument = new JsonPatchDocument(); + patchDocument.Remove("test"); + + // Act + var exception = Assert.Throws(() => + { + patchDocument.ApplyTo(targetObject); + }); + + // Assert + Assert.Equal("The target location specified by path segment 'test' was not found.", exception.Message); + } + + [Fact] + public void RemoveNestedProperty() + { + // Arrange + dynamic targetObject = new ExpandoObject(); + targetObject.Test = new ExpandoObject(); + targetObject.Test.AnotherTest = "A"; + + var patchDocument = new JsonPatchDocument(); + patchDocument.Remove("Test"); + + // Act + patchDocument.ApplyTo(targetObject); + + var cont = targetObject as IDictionary; + cont.TryGetValue("Test", out object valueFromDictionary); + + // Assert + Assert.Null(valueFromDictionary); + } + + [Fact] + public void RemoveNestedProperty_MixedCase_ThrowsPathNotFoundException() + { + // Arrange + dynamic targetObject = new ExpandoObject(); + targetObject.Test = new ExpandoObject(); + targetObject.Test.AnotherTest = "A"; + + var patchDocument = new JsonPatchDocument(); + patchDocument.Remove("test"); + + // Act + var exception = Assert.Throws(() => + { + patchDocument.ApplyTo(targetObject); + }); + + // Assert + Assert.Equal("The target location specified by path segment 'test' was not found.", exception.Message); + } + + [Fact] + public void ReplaceGuid() + { + // Arrange + dynamic targetObject = new ExpandoObject(); + targetObject.GuidValue = Guid.NewGuid(); + + var newGuid = Guid.NewGuid(); + var patchDocument = new JsonPatchDocument(); + patchDocument.Replace("GuidValue", newGuid); + + // Act + patchDocument.ApplyTo(targetObject); + + // Assert + Assert.Equal(newGuid, targetObject.GuidValue); + } + } +} \ No newline at end of file diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/IntegrationTests/ListIntegrationTest.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/IntegrationTests/ListIntegrationTest.cs new file mode 100644 index 0000000000..5e261ea08b --- /dev/null +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/IntegrationTests/ListIntegrationTest.cs @@ -0,0 +1,366 @@ +// 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.Collections.ObjectModel; +using Microsoft.AspNetCore.JsonPatch.Exceptions; +using Xunit; + +namespace Microsoft.AspNetCore.JsonPatch.IntegrationTests +{ + public class ListIntegrationTest + { + [Fact] + public void TestInList_IsSuccessful() + { + // Arrange + var targetObject = new SimpleObjectWithNestedObject() + { + SimpleObject = new SimpleObject() + { + IntegerList = new List() { 1, 2, 3 } + } + }; + + var patchDocument = new JsonPatchDocument(); + patchDocument.Test(o => o.SimpleObject.IntegerList, 3, 2); + + // Act & Assert + patchDocument.ApplyTo(targetObject); + } + + [Fact] + public void TestInList_InvalidPosition() + { + // Arrange + var targetObject = new SimpleObjectWithNestedObject() + { + SimpleObject = new SimpleObject() + { + IntegerList = new List() { 1, 2, 3 } + } + }; + + var patchDocument = new JsonPatchDocument(); + patchDocument.Test(o => o.SimpleObject.IntegerList, 4, -1); + + // Act & Assert + var exception = Assert.Throws(() => { patchDocument.ApplyTo(targetObject); }); + Assert.Equal("The index value provided by path segment '-1' is out of bounds of the array size.", + exception.Message); + } + + [Fact] + public void AddToIntegerIList() + { + // Arrange + var targetObject = new SimpleObjectWithNestedObject() + { + SimpleObject = new SimpleObject() + { + IntegerIList = new List() { 1, 2, 3 } + } + }; + + var patchDocument = new JsonPatchDocument(); + patchDocument.Add(o => (List)o.SimpleObject.IntegerIList, 4, 0); + + // Act + patchDocument.ApplyTo(targetObject); + + // Assert + Assert.Equal(new List() { 4, 1, 2, 3 }, targetObject.SimpleObject.IntegerIList); + } + + [Fact] + public void AddToComplextTypeList_SpecifyIndex() + { + // Arrange + var targetObject = new SimpleObjectWithNestedObject() + { + SimpleObjectList = new List() + { + new SimpleObject + { + StringProperty = "String1" + }, + new SimpleObject + { + StringProperty = "String2" + } + } + }; + + var patchDocument = new JsonPatchDocument(); + patchDocument.Add(o => o.SimpleObjectList[0].StringProperty, "ChangedString1"); + + // Act + patchDocument.ApplyTo(targetObject); + + // Assert + Assert.Equal("ChangedString1", targetObject.SimpleObjectList[0].StringProperty); + } + + [Fact] + public void AddToListAppend() + { + // Arrange + var targetObject = new SimpleObjectWithNestedObject() + { + SimpleObject = new SimpleObject() + { + IntegerList = new List() { 1, 2, 3 } + } + }; + + var patchDocument = new JsonPatchDocument(); + patchDocument.Add(o => o.SimpleObject.IntegerList, 4); + + // Act + patchDocument.ApplyTo(targetObject); + + // Assert + Assert.Equal(new List() { 1, 2, 3, 4 }, targetObject.SimpleObject.IntegerList); + } + + [Fact] + public void RemoveFromList() + { + // Arrange + var targetObject = new SimpleObject() + { + IntegerList = new List() { 1, 2, 3 } + }; + + var patchDocument = new JsonPatchDocument(); + patchDocument.Remove("IntegerList/2"); + + // Act + patchDocument.ApplyTo(targetObject); + + // Assert + Assert.Equal(new List() { 1, 2 }, targetObject.IntegerList); + } + + [Theory] + [InlineData("3")] + [InlineData("-1")] + public void RemoveFromList_InvalidPosition(string position) + { + // Arrange + var targetObject = new SimpleObject() + { + IntegerList = new List() { 1, 2, 3 } + }; + + var patchDocument = new JsonPatchDocument(); + patchDocument.Remove("IntegerList/" + position); + + // Act + var exception = Assert.Throws(() => + { + patchDocument.ApplyTo(targetObject); + }); + + // Assert + Assert.Equal($"The index value provided by path segment '{position}' is out of bounds of the array size.", exception.Message); + } + + [Fact] + public void Remove_FromEndOfList() + { + // Arrange + var targetObject = new SimpleObjectWithNestedObject() + { + SimpleObject = new SimpleObject() + { + IntegerList = new List() { 1, 2, 3 } + } + }; + + var patchDocument = new JsonPatchDocument(); + patchDocument.Remove(o => o.SimpleObject.IntegerList); + + // Act + patchDocument.ApplyTo(targetObject); + + // Assert + Assert.Equal(new List() { 1, 2 }, targetObject.SimpleObject.IntegerList); + } + + [Fact] + public void ReplaceFullList_WithCollection() + { + // Arrange + var targetObject = new SimpleObject() + { + IntegerList = new List() { 1, 2, 3 } + }; + + var patchDocument = new JsonPatchDocument(); + patchDocument.Replace("IntegerList", new Collection() { 4, 5, 6 }); + + // Act + patchDocument.ApplyTo(targetObject); + + // Assert + Assert.Equal(new List() { 4, 5, 6 }, targetObject.IntegerList); + } + + [Fact] + public void Replace_AtEndOfList() + { + // Arrange + var targetObject = new SimpleObjectWithNestedObject() + { + SimpleObject = new SimpleObject() + { + IntegerList = new List() { 1, 2, 3 } + } + }; + + var patchDocument = new JsonPatchDocument(); + patchDocument.Replace(o => o.SimpleObject.IntegerList, 5); + + // Act + patchDocument.ApplyTo(targetObject); + + // Assert + Assert.Equal(new List() { 1, 2, 5 }, targetObject.SimpleObject.IntegerList); + } + + [Fact] + public void Replace_InList_InvalidPosition() + { + // Arrange + var targetObject = new SimpleObjectWithNestedObject() + { + SimpleObject = new SimpleObject() + { + IntegerList = new List() { 1, 2, 3 } + } + }; + + var patchDocument = new JsonPatchDocument(); + patchDocument.Replace(o => o.SimpleObject.IntegerList, 5, -1); + + // Act + var exception = Assert.Throws(() => { patchDocument.ApplyTo(targetObject); }); + + // Assert + Assert.Equal("The index value provided by path segment '-1' is out of bounds of the array size.", exception.Message); + } + + [Fact] + public void CopyFromListToEndOfList() + { + // Arrange + var targetObject = new SimpleObject() + { + IntegerList = new List() { 1, 2, 3 } + }; + + var patchDocument = new JsonPatchDocument(); + patchDocument.Copy("IntegerList/0", "IntegerList/-"); + + // Act + patchDocument.ApplyTo(targetObject); + + // Assert + Assert.Equal(new List() { 1, 2, 3, 1 }, targetObject.IntegerList); + } + + [Fact] + public void CopyFromListToNonList() + { + // Arrange + var targetObject = new SimpleObject() + { + IntegerList = new List() { 1, 2, 3 } + }; + + var patchDocument = new JsonPatchDocument(); + patchDocument.Copy("IntegerList/0", "IntegerValue"); + + // Act + patchDocument.ApplyTo(targetObject); + + // Assert + Assert.Equal(1, targetObject.IntegerValue); + } + + [Fact] + public void MoveToEndOfList() + { + // Arrange + var targetObject = new SimpleObject() + { + IntegerValue = 5, + IntegerList = new List() { 1, 2, 3 } + }; + + var patchDocument = new JsonPatchDocument(); + patchDocument.Move("IntegerValue", "IntegerList/-"); + + // Act + patchDocument.ApplyTo(targetObject); + + // Assert + Assert.Equal(0, targetObject.IntegerValue); + Assert.Equal(new List() { 1, 2, 3, 5 }, targetObject.IntegerList); + } + + [Fact] + public void Move_KeepsObjectReferenceInList() + { + // Arrange + var simpleObject1 = new SimpleObject() { IntegerValue = 1 }; + var simpleObject2 = new SimpleObject() { IntegerValue = 2 }; + var simpleObject3 = new SimpleObject() { IntegerValue = 3 }; + var targetObject = new SimpleObjectWithNestedObject() + { + SimpleObjectList = new List() { + simpleObject1, + simpleObject2, + simpleObject3 + } + }; + + var patchDocument = new JsonPatchDocument(); + patchDocument.Move(o => o.SimpleObjectList, 0, o => o.SimpleObjectList, 1); + + // Act + patchDocument.ApplyTo(targetObject); + + // Assert + Assert.Equal(new List() { simpleObject2, simpleObject1, simpleObject3 }, targetObject.SimpleObjectList); + Assert.Equal(2, targetObject.SimpleObjectList[0].IntegerValue); + Assert.Equal(1, targetObject.SimpleObjectList[1].IntegerValue); + Assert.Same(simpleObject2, targetObject.SimpleObjectList[0]); + Assert.Same(simpleObject1, targetObject.SimpleObjectList[1]); + } + + [Fact] + public void MoveFromList_ToNonList_BetweenHierarchy() + { + // Arrange + var targetObject = new SimpleObjectWithNestedObject() + { + SimpleObject = new SimpleObject() + { + IntegerList = new List() { 1, 2, 3 } + } + }; + + var patchDocument = new JsonPatchDocument(); + patchDocument.Move(o => o.SimpleObject.IntegerList, 0, o => o.IntegerValue); + + // Act + patchDocument.ApplyTo(targetObject); + + // Assert + Assert.Equal(new List() { 2, 3 }, targetObject.SimpleObject.IntegerList); + Assert.Equal(1, targetObject.IntegerValue); + } + } +} diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/IntegrationTests/NestedObjectIntegrationTest.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/IntegrationTests/NestedObjectIntegrationTest.cs new file mode 100644 index 0000000000..92c0e7fb2d --- /dev/null +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/IntegrationTests/NestedObjectIntegrationTest.cs @@ -0,0 +1,342 @@ +// 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.Dynamic; +using Newtonsoft.Json; +using Xunit; + +namespace Microsoft.AspNetCore.JsonPatch.IntegrationTests +{ + public class NestedObjectIntegrationTest + { + [Fact] + public void Replace_DTOWithNullCheck() + { + // Arrange + var targetObject = new SimpleObjectWithNestedObjectWithNullCheck() + { + SimpleObjectWithNullCheck = new SimpleObjectWithNullCheck() + { + StringProperty = "A" + } + }; + + var patchDocument = new JsonPatchDocument(); + patchDocument.Replace(o => o.SimpleObjectWithNullCheck.StringProperty, "B"); + + // Act + patchDocument.ApplyTo(targetObject); + + // Assert + Assert.Equal("B", targetObject.SimpleObjectWithNullCheck.StringProperty); + } + + [Fact] + public void ReplaceNestedObject_WithSerialization() + { + // Arrange + var targetObject = new SimpleObjectWithNestedObject() + { + IntegerValue = 1 + }; + + var newNested = new NestedObject() { StringProperty = "B" }; + var patchDocument = new JsonPatchDocument(); + patchDocument.Replace(o => o.NestedObject, newNested); + + var serialized = JsonConvert.SerializeObject(patchDocument); + var deserialized = JsonConvert.DeserializeObject>(serialized); + + // Act + deserialized.ApplyTo(targetObject); + + // Assert + Assert.Equal("B", targetObject.NestedObject.StringProperty); + } + + [Fact] + public void TestStringProperty_InNestedObject() + { + // Arrange + var targetObject = new SimpleObjectWithNestedObject() + { + NestedObject = new NestedObject() { StringProperty = "A"} + }; + + var patchDocument = new JsonPatchDocument(); + patchDocument.Test(o => o.StringProperty, "A"); + + // Act + patchDocument.ApplyTo(targetObject.NestedObject); + + // Assert + Assert.Equal("A", targetObject.NestedObject.StringProperty); + } + + [Fact] + public void TestNestedObject() + { + // Arrange + var targetObject = new SimpleObjectWithNestedObject() + { + NestedObject = new NestedObject() { StringProperty = "B"} + }; + + var testNested = new NestedObject() { StringProperty = "B" }; + var patchDocument = new JsonPatchDocument(); + patchDocument.Test(o => o.NestedObject, testNested); + + // Act + patchDocument.ApplyTo(targetObject); + + // Assert + Assert.Equal("B", targetObject.NestedObject.StringProperty); + } + + [Fact] + public void AddReplaces_ExistingStringProperty() + { + // Arrange + var targetObject = new SimpleObjectWithNestedObject() + { + SimpleObject = new SimpleObject() + { + StringProperty = "A" + } + }; + + var patchDocument = new JsonPatchDocument(); + patchDocument.Add(o => o.SimpleObject.StringProperty, "B"); + + // Act + patchDocument.ApplyTo(targetObject); + + // Assert + Assert.Equal("B", targetObject.SimpleObject.StringProperty); + } + + [Fact] + public void AddNewProperty_ToExpandoOject_InTypedObject() + { + var targetObject = new NestedObject() + { + DynamicProperty = new ExpandoObject() + }; + + var patchDocument = new JsonPatchDocument(); + patchDocument.Add("DynamicProperty/NewInt", 1); + + patchDocument.ApplyTo(targetObject); + + Assert.Equal(1, targetObject.DynamicProperty.NewInt); + } + + [Fact] + public void RemoveStringProperty() + { + // Arrange + var targetObject = new SimpleObjectWithNestedObject() + { + SimpleObject = new SimpleObject() + { + StringProperty = "A" + } + }; + + var patchDocument = new JsonPatchDocument(); + patchDocument.Remove(o => o.SimpleObject.StringProperty); + + // Act + patchDocument.ApplyTo(targetObject); + + // Assert + Assert.Null(targetObject.SimpleObject.StringProperty); + } + + [Fact] + public void CopyStringProperty_ToAnotherStringProperty() + { + // Arrange + var targetObject = new SimpleObjectWithNestedObject() + { + SimpleObject = new SimpleObject() + { + StringProperty = "A", + AnotherStringProperty = "B" + } + }; + + var patchDocument = new JsonPatchDocument(); + patchDocument.Copy(o => o.SimpleObject.StringProperty, o => o.SimpleObject.AnotherStringProperty); + + // Act + patchDocument.ApplyTo(targetObject); + + // Assert + Assert.Equal("A", targetObject.SimpleObject.AnotherStringProperty); + } + + [Fact] + public void Copy_DeepClonesObject() + { + // Arrange + var targetObject = new SimpleObjectWithNestedObject() + { + SimpleObject = new SimpleObject() + { + StringProperty = "A", + AnotherStringProperty = "B" + }, + InheritedObject = new InheritedObject() + { + StringProperty = "C", + AnotherStringProperty = "D" + } + }; + + var patchDocument = new JsonPatchDocument(); + patchDocument.Copy(o => o.InheritedObject, o => o.SimpleObject); + + // Act + patchDocument.ApplyTo(targetObject); + + // Assert + Assert.Equal("C", targetObject.SimpleObject.StringProperty); + Assert.Equal("D", targetObject.SimpleObject.AnotherStringProperty); + Assert.Equal("C", targetObject.InheritedObject.StringProperty); + Assert.Equal("D", targetObject.InheritedObject.AnotherStringProperty); + Assert.NotSame(targetObject.SimpleObject.StringProperty, targetObject.InheritedObject.StringProperty); + } + + [Fact] + public void Copy_KeepsObjectType() + { + // Arrange + var targetObject = new SimpleObjectWithNestedObject() + { + SimpleObject = new SimpleObject(), + InheritedObject = new InheritedObject() + }; + + var patchDocument = new JsonPatchDocument(); + patchDocument.Copy(o => o.InheritedObject, o => o.SimpleObject); + + // Act + patchDocument.ApplyTo(targetObject); + + // Assert + Assert.Equal(typeof(InheritedObject), targetObject.SimpleObject.GetType()); + } + + [Fact] + public void Copy_BreaksObjectReference() + { + // Arrange + var targetObject = new SimpleObjectWithNestedObject() + { + SimpleObject = new SimpleObject(), + InheritedObject = new InheritedObject() + }; + + var patchDocument = new JsonPatchDocument(); + patchDocument.Copy(o => o.InheritedObject, o => o.SimpleObject); + + // Act + patchDocument.ApplyTo(targetObject); + + // Assert + Assert.NotSame(targetObject.SimpleObject, targetObject.InheritedObject); + } + + [Fact] + public void MoveIntegerValue_ToAnotherIntegerProperty() + { + // Arrange + var targetObject = new SimpleObjectWithNestedObject() + { + SimpleObject = new SimpleObject() + { + IntegerValue = 2, + AnotherIntegerValue = 3 + } + }; + + var patchDocument = new JsonPatchDocument(); + patchDocument.Move(o => o.SimpleObject.IntegerValue, o => o.SimpleObject.AnotherIntegerValue); + + // Act + patchDocument.ApplyTo(targetObject); + + // Assert + Assert.Equal(2, targetObject.SimpleObject.AnotherIntegerValue); + Assert.Equal(0, targetObject.SimpleObject.IntegerValue); + } + + [Fact] + public void Move_KeepsObjectReference() + { + // Arrange + var sDto = new SimpleObject() + { + StringProperty = "A", + AnotherStringProperty = "B" + }; + var iDto = new InheritedObject() + { + StringProperty = "C", + AnotherStringProperty = "D" + }; + var targetObject = new SimpleObjectWithNestedObject() + { + SimpleObject = sDto, + InheritedObject = iDto + }; + + var patchDocument = new JsonPatchDocument(); + patchDocument.Move(o => o.InheritedObject, o => o.SimpleObject); + + // Act + patchDocument.ApplyTo(targetObject); + + // Assert + Assert.Equal("C", targetObject.SimpleObject.StringProperty); + Assert.Equal("D", targetObject.SimpleObject.AnotherStringProperty); + Assert.Same(iDto, targetObject.SimpleObject); + Assert.Null(targetObject.InheritedObject); + } + + private class SimpleObjectWithNullCheck + { + private string stringProperty; + + public string StringProperty + { + get + { + return stringProperty; + } + + set + { + if (value == null) + { + throw new ArgumentNullException(); + } + + stringProperty = value; + } + } + } + + private class SimpleObjectWithNestedObjectWithNullCheck + { + public SimpleObjectWithNullCheck SimpleObjectWithNullCheck { get; set; } + + public SimpleObjectWithNestedObjectWithNullCheck() + { + SimpleObjectWithNullCheck = new SimpleObjectWithNullCheck(); + } + } + } +} diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/IntegrationTests/SimpleObjectIntegrationTest.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/IntegrationTests/SimpleObjectIntegrationTest.cs new file mode 100644 index 0000000000..669c6d7af4 --- /dev/null +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/IntegrationTests/SimpleObjectIntegrationTest.cs @@ -0,0 +1,128 @@ +// 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 Xunit; + +namespace Microsoft.AspNetCore.JsonPatch.IntegrationTests +{ + public class SimpleObjectIntegrationTest + { + [Fact] + public void TestDoubleValueProperty() + { + // Arrange + var targetObject = new SimpleObject() + { + DoubleValue = 9.8 + }; + + var patchDocument = new JsonPatchDocument(); + patchDocument.Test("DoubleValue", 9.8); + + // Act & Assert + patchDocument.ApplyTo(targetObject); + } + + [Fact] + public void CopyStringProperty_ToAnotherStringProperty() + { + // Arrange + var targetObject = new SimpleObject() + { + StringProperty = "A", + AnotherStringProperty = "B" + }; + + var patchDocument = new JsonPatchDocument(); + patchDocument.Copy("StringProperty", "AnotherStringProperty"); + + // Act + patchDocument.ApplyTo(targetObject); + + // Assert + Assert.Equal("A", targetObject.AnotherStringProperty); + } + + [Fact] + public void MoveIntegerProperty_ToAnotherIntegerProperty() + { + // Arrange + var targetObject = new SimpleObject() + { + IntegerValue = 2, + AnotherIntegerValue = 3 + }; + + var patchDocument = new JsonPatchDocument(); + patchDocument.Move("IntegerValue", "AnotherIntegerValue"); + + // Act + patchDocument.ApplyTo(targetObject); + + // Assert + Assert.Equal(2, targetObject.AnotherIntegerValue); + Assert.Equal(0, targetObject.IntegerValue); + } + + [Fact] + public void RemoveDecimalPropertyValue() + { + // Arrange + var targetObject = new SimpleObject() + { + DecimalValue = 9.8M + }; + + var patchDocument = new JsonPatchDocument(); + patchDocument.Remove("DecimalValue"); + + // Act + patchDocument.ApplyTo(targetObject); + + // Assert + Assert.Equal(0, targetObject.DecimalValue); + } + + [Fact] + public void ReplaceGuid() + { + // Arrange + var targetObject = new SimpleObject() + { + GuidValue = Guid.NewGuid() + }; + + var newGuid = Guid.NewGuid(); + var patchDocument = new JsonPatchDocument(); + patchDocument.Replace("GuidValue", newGuid); + + // Act + patchDocument.ApplyTo(targetObject); + + // Assert + Assert.Equal(newGuid, targetObject.GuidValue); + } + + [Fact] + public void AddReplacesGuid() + { + // Arrange + var targetObject = new SimpleObject() + { + GuidValue = Guid.NewGuid() + }; + + var newGuid = Guid.NewGuid(); + var patchDocument = new JsonPatchDocument(); + patchDocument.Add("GuidValue", newGuid); + + // Act + patchDocument.ApplyTo(targetObject); + + // Assert + Assert.Equal(newGuid, targetObject.GuidValue); + } + + } +} diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/Adapters/DictionaryAdapterTest.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/Internal/DictionaryAdapterTest.cs similarity index 91% rename from test/Microsoft.AspNetCore.JsonPatch.Test/Adapters/DictionaryAdapterTest.cs rename to test/Microsoft.AspNetCore.JsonPatch.Test/Internal/DictionaryAdapterTest.cs index d1d2216c2c..a0dcd82ab0 100644 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/Adapters/DictionaryAdapterTest.cs +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/Internal/DictionaryAdapterTest.cs @@ -74,9 +74,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal // Assert Assert.False(getStatus); - Assert.Equal( - string.Format("The provided path segment '{0}' cannot be converted to the target type.", guidKey.ToString()), - message); + Assert.Equal($"The provided path segment '{guidKey.ToString()}' cannot be converted to the target type.", message); Assert.Null(outValue); } @@ -103,9 +101,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal // Assert Assert.False(getStatus); - Assert.Equal( - string.Format("The target location specified by path segment '{0}' was not found.", nameKey.ToUpper()), - message); + Assert.Equal("The target location specified by path segment 'NAME' was not found.", message); Assert.Null(outValue); } @@ -191,9 +187,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal // Assert Assert.False(replaceStatus); - Assert.Equal( - string.Format("The value '{0}' is invalid for target location.", "test"), - message); + Assert.Equal("The value 'test' is invalid for target location.", message); Assert.Equal(5, dictionary[guidKey]); } @@ -211,9 +205,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal // Assert Assert.False(replaceStatus); - Assert.Equal( - string.Format("The target location specified by path segment '{0}' was not found.", nameKey), - message); + Assert.Equal("The target location specified by path segment 'Name' was not found.", message); Assert.Empty(dictionary); } @@ -231,9 +223,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal // Assert Assert.False(removeStatus); - Assert.Equal( - string.Format("The target location specified by path segment '{0}' was not found.", nameKey), - message); + Assert.Equal("The target location specified by path segment 'Name' was not found.", message); Assert.Empty(dictionary); } @@ -280,13 +270,19 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal { // Arrange var key = "Name"; - var dictionary = new Dictionary(); - dictionary[key] = "James"; - var dictionaryAdapter = new DictionaryAdapter(); + var dictionary = new Dictionary>(); + var value = new List() + { + "James", + 2, + new Customer("James", 25) + }; + dictionary[key] = value; + var dictionaryAdapter = new DictionaryAdapter>(); var resolver = new DefaultContractResolver(); // Act - var testStatus = dictionaryAdapter.TryTest(dictionary, key, resolver, "James", out var message); + var testStatus = dictionaryAdapter.TryTest(dictionary, key, resolver, value, out var message); //Assert Assert.True(testStatus); diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/Adapters/DynamicObjectAdapterTest.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/Internal/DynamicObjectAdapterTest.cs similarity index 97% rename from test/Microsoft.AspNetCore.JsonPatch.Test/Adapters/DynamicObjectAdapterTest.cs rename to test/Microsoft.AspNetCore.JsonPatch.Test/Internal/DynamicObjectAdapterTest.cs index 9ed9a51ed0..96b1aee935 100644 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/Adapters/DynamicObjectAdapterTest.cs +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/Internal/DynamicObjectAdapterTest.cs @@ -233,15 +233,21 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal { var adapter = new DynamicObjectAdapter(); dynamic target = new DynamicTestObject(); - target.NewProperty = "Joana"; + var value = new List() + { + "Joana", + 2, + new Customer("Joana", 25) + }; + target.NewProperty = value; var segment = "NewProperty"; var resolver = new DefaultContractResolver(); // Act - var testStatus = adapter.TryTest(target, segment, resolver, "Joana", out string errorMessage); + var testStatus = adapter.TryTest(target, segment, resolver, value, out string errorMessage); // Assert - Assert.Equal("Joana", target.NewProperty); + Assert.Equal(value, target.NewProperty); Assert.True(testStatus); Assert.True(string.IsNullOrEmpty(errorMessage), "Expected no error message"); } diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/Adapters/ListAdapterTest.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/Internal/ListAdapterTest.cs similarity index 91% rename from test/Microsoft.AspNetCore.JsonPatch.Test/Adapters/ListAdapterTest.cs rename to test/Microsoft.AspNetCore.JsonPatch.Test/Internal/ListAdapterTest.cs index 25d8ae387b..f31e57541b 100644 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/Adapters/ListAdapterTest.cs +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/Internal/ListAdapterTest.cs @@ -24,11 +24,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal // Assert Assert.False(addStatus); - Assert.Equal( - string.Format( - "The type '{0}' which is an array is not supported for json patch operations as it has a fixed size.", - targetObject.GetType().FullName), - message); + Assert.Equal($"The type '{targetObject.GetType().FullName}' which is an array is not supported for json patch operations as it has a fixed size.", message); } [Fact] @@ -46,11 +42,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal // Assert Assert.False(addStatus); - Assert.Equal( - string.Format( - "The type '{0}' which is a non generic list is not supported for json patch operations. Only generic list types are supported.", - targetObject.GetType().FullName), - message); + Assert.Equal($"The type '{targetObject.GetType().FullName}' which is a non generic list is not supported for json patch operations. Only generic list types are supported.", message); } [Fact] @@ -88,9 +80,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal // Assert Assert.False(addStatus); - Assert.Equal( - string.Format("The index value provided by path segment '{0}' is out of bounds of the array size.", position), - message); + Assert.Equal($"The index value provided by path segment '{position}' is out of bounds of the array size.", message); } [Theory] @@ -108,9 +98,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal // Assert Assert.False(addStatus); - Assert.Equal( - string.Format("The path segment '{0}' is invalid for an array index.", position), - message); + Assert.Equal($"The path segment '{position}' is invalid for an array index.", message); } public static TheoryData, List> AppendAtEndOfListData @@ -200,7 +188,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal // Assert Assert.False(addStatus); - Assert.Equal(string.Format("The value '{0}' is invalid for target location.", "James"), message); + Assert.Equal("The value 'James' is invalid for target location.", message); } public static TheoryData AddingDifferentComplexTypeWorksData @@ -255,8 +243,10 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal Assert.Equal(expected, targetObject); } - public static TheoryData AddingKeepsObjectReferenceData { - get { + public static TheoryData AddingKeepsObjectReferenceData + { + get + { var sDto1 = new SimpleObject(); var sDto2 = new SimpleObject(); var sDto3 = new SimpleObject(); @@ -324,9 +314,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal // Assert Assert.False(getStatus); - Assert.Equal( - string.Format("The index value provided by path segment '{0}' is out of bounds of the array size.", position), - message); + Assert.Equal($"The index value provided by path segment '{position}' is out of bounds of the array size.", message); } [Theory] @@ -365,9 +353,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal // Assert Assert.False(removeStatus); - Assert.Equal( - string.Format("The index value provided by path segment '{0}' is out of bounds of the array size.", position), - message); + Assert.Equal($"The index value provided by path segment '{position}' is out of bounds of the array size.", message); } [Theory] @@ -402,9 +388,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal // Assert Assert.False(replaceStatus); - Assert.Equal( - string.Format("The value '{0}' is invalid for target location.", "James"), - message); + Assert.Equal("The value 'James' is invalid for target location.", message); } [Fact] diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/ObjectVisitorTest.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/Internal/ObjectVisitorTest.cs similarity index 95% rename from test/Microsoft.AspNetCore.JsonPatch.Test/ObjectVisitorTest.cs rename to test/Microsoft.AspNetCore.JsonPatch.Test/Internal/ObjectVisitorTest.cs index 3384986c28..cb299cf0dc 100644 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/ObjectVisitorTest.cs +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/Internal/ObjectVisitorTest.cs @@ -1,7 +1,6 @@ // 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.Dynamic; using Newtonsoft.Json.Serialization; @@ -168,9 +167,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal // Assert Assert.False(visitStatus); - Assert.Equal( - string.Format("The index value provided by path segment '{0}' is out of bounds of the array size.", position), - message); + Assert.Equal($"The index value provided by path segment '{position}' is out of bounds of the array size.", message); } [Theory] @@ -188,12 +185,9 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal // Assert Assert.False(visitStatus); - Assert.Equal(string.Format( - "The path segment '{0}' is invalid for an array index.", position), - message); + Assert.Equal($"The path segment '{position}' is invalid for an array index.", message); } - // The adapter takes care of the responsibility of validating the final segment [Fact] public void Visit_DoesNotValidate_FinalPathSegment() { diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/ParsedPathTests.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/Internal/ParsedPathTests.cs similarity index 91% rename from test/Microsoft.AspNetCore.JsonPatch.Test/ParsedPathTests.cs rename to test/Microsoft.AspNetCore.JsonPatch.Test/Internal/ParsedPathTests.cs index 6b7c2e69cb..c23abcdb5e 100644 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/ParsedPathTests.cs +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/Internal/ParsedPathTests.cs @@ -2,10 +2,9 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using Microsoft.AspNetCore.JsonPatch.Exceptions; -using Microsoft.AspNetCore.JsonPatch.Internal; using Xunit; -namespace Microsoft.AspNetCore.JsonPatch.Test +namespace Microsoft.AspNetCore.JsonPatch.Internal { public class ParsedPathTests { @@ -19,7 +18,10 @@ namespace Microsoft.AspNetCore.JsonPatch.Test [InlineData("~0~1foo", new string[] { "~/foo" })] public void ParsingValidPathShouldSucceed(string path, string[] expected) { + // Arrange & Act var parsedPath = new ParsedPath(path); + + // Assert Assert.Equal(expected, parsedPath.Segments); } @@ -30,6 +32,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Test [InlineData("foo~3bar")] public void PathWithInvalidEscapeSequenceShouldFail(string path) { + // Arrange, Act & Assert Assert.Throws(() => { var parsedPath = new ParsedPath(path); diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/Adapters/PocoAdapterTest.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/Internal/PocoAdapterTest.cs similarity index 100% rename from test/Microsoft.AspNetCore.JsonPatch.Test/Adapters/PocoAdapterTest.cs rename to test/Microsoft.AspNetCore.JsonPatch.Test/Internal/PocoAdapterTest.cs diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/JsonPatchDocumentGetPathTest.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/JsonPatchDocumentGetPathTest.cs index 7d3331231c..266202c7a5 100644 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/JsonPatchDocumentGetPathTest.cs +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/JsonPatchDocumentGetPathTest.cs @@ -100,9 +100,7 @@ namespace Microsoft.AspNetCore.JsonPatch }); // Assert - Assert.Equal( - string.Format("The expression '(p.IntegerValue >= 4)' is not supported. Supported expressions include member access and indexer expressions."), - exception.Message); + Assert.Equal("The expression '(p.IntegerValue >= 4)' is not supported. Supported expressions include member access and indexer expressions.", exception.Message); } } diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/JsonPatchDocumentJsonPropertyAttributeTest.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/JsonPatchDocumentJsonPropertyAttributeTest.cs index 882e09ffe7..f5d6377989 100644 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/JsonPatchDocumentJsonPropertyAttributeTest.cs +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/JsonPatchDocumentJsonPropertyAttributeTest.cs @@ -1,9 +1,7 @@ // 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.Linq; -using System.Reflection; using Newtonsoft.Json; using Newtonsoft.Json.Serialization; using Xunit; @@ -13,263 +11,39 @@ namespace Microsoft.AspNetCore.JsonPatch public class JsonPatchDocumentJsonPropertyAttributeTest { [Fact] - public void Add_ToRoot_OfListOfObjects_AtEndOfList() + public void Add_RespectsJsonPropertyAttribute() { - var patchDoc = new JsonPatchDocument>(); - patchDoc.Add(p => p, new JsonPropertyObject()); + // Arrange + var patchDocument = new JsonPatchDocument(); - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = - JsonConvert.DeserializeObject>(serialized); + // Act + patchDocument.Add(p => p.Name, "John"); - // get path - var pathToCheck = deserialized.Operations.First().path; - Assert.Equal("/-", pathToCheck); - } - - [Fact] - public void Add_ToRoot_OfListOfObjects_AtGivenPosition() - { - var patchDoc = new JsonPatchDocument>(); - patchDoc.Add(p => p[3], new JsonPropertyObject()); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = - JsonConvert.DeserializeObject>(serialized); - - // get path - var pathToCheck = deserialized.Operations.First().path; - Assert.Equal("/3", pathToCheck); - } - - [Fact] - public void Add_WithExpression_RespectsJsonPropertyName_ForModelProperty() - { - var patchDoc = new JsonPatchDocument(); - patchDoc.Add(p => p.Name, "John"); - - var serialized = JsonConvert.SerializeObject(patchDoc); - // serialized value should have "AnotherName" as path - // deserialize to a JsonPatchDocument to check - var deserialized = - JsonConvert.DeserializeObject>(serialized); - - // get path - var pathToCheck = deserialized.Operations.First().path; + // Assert + var pathToCheck = patchDocument.Operations.First().path; Assert.Equal("/AnotherName", pathToCheck); } [Fact] - public void Add_WithExpressionOnStringProperty_FallsbackToPropertyName_WhenJsonPropertyName_IsEmpty() + public void Move_FallsbackToPropertyName_WhenJsonPropertyAttributeName_IsEmpty() { // Arrange - var patchDoc = new JsonPatchDocument(); - patchDoc.Add(m => m.StringProperty, "Test"); - var serialized = JsonConvert.SerializeObject(patchDoc); + var patchDocument = new JsonPatchDocument(); // Act - var deserialized = - JsonConvert.DeserializeObject>(serialized); + patchDocument.Move(m => m.StringProperty, m => m.StringProperty2); // Assert - var pathToCheck = deserialized.Operations.First().path; - Assert.Equal("/StringProperty", pathToCheck); - } - - [Fact] - public void Add_WithExpressionOnArrayProperty_FallsbackToPropertyName_WhenJsonPropertyName_IsEmpty() - { - // Arrange - var patchDoc = new JsonPatchDocument(); - patchDoc.Add(m => m.ArrayProperty, "James"); - var serialized = JsonConvert.SerializeObject(patchDoc); - - // Act - var deserialized = - JsonConvert.DeserializeObject>(serialized); - - // Assert - var pathToCheck = deserialized.Operations.First().path; - Assert.Equal("/ArrayProperty/-", pathToCheck); - } - - [Fact] - public void Add_WithExpression_RespectsJsonPropertyName_WhenApplyingToDifferentlyTypedClassWithPropertyMatchingJsonPropertyName() - { - var patchDocToSerialize = new JsonPatchDocument(); - patchDocToSerialize.Add(p => p.Name, "John"); - - // the patchdoc will deserialize to "anothername". We should thus be able to apply - // it to a class that HAS that other property name. - var doc = new JsonPropertyWithAnotherNameObject() - { - AnotherName = "InitialValue" - }; - - var serialized = JsonConvert.SerializeObject(patchDocToSerialize); - var deserialized = - JsonConvert.DeserializeObject> - (serialized); - - deserialized.ApplyTo(doc); - - Assert.Equal("John", doc.AnotherName); - } - - [Fact] - public void Add_WithExpression_RespectsJsonPropertyName_WhenApplyingToSameTypedClassWithMatchingJsonPropertyName() - { - var patchDocToSerialize = new JsonPatchDocument(); - patchDocToSerialize.Add(p => p.Name, "John"); - - // the patchdoc will deserialize to "anothername". As JsonPropertyDTO has - // a JsonProperty signifying that "Name" should be deseriallized from "AnotherName", - // we should be able to apply the patchDoc. - - var doc = new JsonPropertyObject() - { - Name = "InitialValue" - }; - - var serialized = JsonConvert.SerializeObject(patchDocToSerialize); - var deserialized = - JsonConvert.DeserializeObject> - (serialized); - - deserialized.ApplyTo(doc); - - Assert.Equal("John", doc.Name); - } - - [Fact] - public void Add_OnApplyFromJson_RespectsJsonPropertyNameOnJsonDocument() - { - var doc = new JsonPropertyObject() - { - Name = "InitialValue" - }; - - // serialization should serialize to "AnotherName" - var serialized = "[{\"value\":\"Kevin\",\"path\":\"/AnotherName\",\"op\":\"add\"}]"; - var deserialized = - JsonConvert.DeserializeObject>(serialized); - - deserialized.ApplyTo(doc); - - Assert.Equal("Kevin", doc.Name); - } - - [Fact] - public void Remove_OnApplyFromJson_RespectsJsonPropertyNameOnJsonDocument() - { - var doc = new JsonPropertyObject() - { - Name = "InitialValue" - }; - - // serialization should serialize to "AnotherName" - var serialized = "[{\"path\":\"/AnotherName\",\"op\":\"remove\"}]"; - var deserialized = - JsonConvert.DeserializeObject>(serialized); - - deserialized.ApplyTo(doc); - - Assert.Null(doc.Name); - } - - [Fact] - public void Add_OnApplyFromJson_RespectsInheritedJsonPropertyNameOnJsonDocument() - { - var doc = new JsonPropertyWithInheritanceObject() - { - Name = "InitialName" - }; - - // serialization should serialize to "AnotherName" - var serialized = "[{\"value\":\"Kevin\",\"path\":\"/AnotherName\",\"op\":\"add\"}]"; - var deserialized = - JsonConvert.DeserializeObject>(serialized); - - deserialized.ApplyTo(doc); - - Assert.Equal("Kevin", doc.Name); - } - - [Fact] - public void Add_WithExpression_RespectsJsonPropertyName_ForInheritedModelProperty() - { - var patchDoc = new JsonPatchDocument(); - patchDoc.Add(p => p.Name, "John"); - - var serialized = JsonConvert.SerializeObject(patchDoc); - // serialized value should have "AnotherName" as path - // deserialize to a JsonPatchDocument to check - var deserialized = - JsonConvert.DeserializeObject>(serialized); - - // get path - var pathToCheck = deserialized.Operations.First().path; - Assert.Equal("/AnotherName", pathToCheck); - } - - [Fact] - public void Add_OnApplyFromJson_EscapingHandledOnComplexJsonPropertyNameOnJsonDocument() - { - var doc = new JsonPropertyComplexNameObject() - { - FooSlashBars = "InitialName", - FooSlashTilde = new SimpleObject - { - StringProperty = "Initial Value" - } - }; - - // 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 deserialized = - JsonConvert.DeserializeObject>(serialized); - - deserialized.ApplyTo(doc); - - Assert.Equal("Kevin", doc.FooSlashBars); - Assert.Equal("Final Value", doc.FooSlashTilde.StringProperty); - } - - [Fact] - public void Move_WithExpression_FallsbackToPropertyName_WhenJsonPropertyName_IsEmpty() - { - // Arrange - var patchDoc = new JsonPatchDocument(); - patchDoc.Move(m => m.StringProperty, m => m.StringProperty2); - var serialized = JsonConvert.SerializeObject(patchDoc); - - // Act - var deserialized = - JsonConvert.DeserializeObject>(serialized); - - // Assert - var fromPath = deserialized.Operations.First().from; + var fromPath = patchDocument.Operations.First().from; Assert.Equal("/StringProperty", fromPath); - var toPath = deserialized.Operations.First().path; + var toPath = patchDocument.Operations.First().path; Assert.Equal("/StringProperty2", toPath); } - [Fact] - public void Add_WithExpression_AndCustomContractResolver_UsesPropertyName_SetByContractResolver() + private class JsonPropertyObject { - // Arrange - var patchDoc = new JsonPatchDocument(); - patchDoc.ContractResolver = new CustomContractResolver(); - patchDoc.Add(m => m.SSN, "123-45-6789"); - var serialized = JsonConvert.SerializeObject(patchDoc); - - // Act - var deserialized = - JsonConvert.DeserializeObject>(serialized); - - // Assert - var path = deserialized.Operations.First().path; - Assert.Equal("/SocialSecurityNumber", path); + [JsonProperty("AnotherName")] + public string Name { get; set; } } private class JsonPropertyWithNoPropertyName @@ -286,20 +60,5 @@ namespace Microsoft.AspNetCore.JsonPatch [JsonProperty] public string SSN { get; set; } } - - private class CustomContractResolver : DefaultContractResolver - { - protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization) - { - var jsonProperty = base.CreateProperty(member, memberSerialization); - - if (jsonProperty.PropertyName == "SSN") - { - jsonProperty.PropertyName = "SocialSecurityNumber"; - } - - return jsonProperty; - } - } } } diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/JsonPatchDocumentTest.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/JsonPatchDocumentTest.cs index d754e8da5b..6b44b6696c 100644 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/JsonPatchDocumentTest.cs +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/JsonPatchDocumentTest.cs @@ -1,55 +1,180 @@ -// 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. using Microsoft.AspNetCore.JsonPatch.Exceptions; using Newtonsoft.Json; using Xunit; -namespace Microsoft.AspNetCore.JsonPatch.Test +namespace Microsoft.AspNetCore.JsonPatch { public class JsonPatchDocumentTest { [Fact] - public void InvalidOperation_ThrowsException_CallsIntoLogErrorAction() + public void InvalidPathAtBeginningShouldThrowException() { // Arrange - var operationName = "foo"; - var serialized = "[{\"value\":\"John\",\"path\":\"/Name\",\"op\":\"" + operationName + "\"}]"; - var jsonPatchDocument = JsonConvert.DeserializeObject>(serialized); - var model = new Customer(); - var expectedErrorMessage = $"Invalid JsonPatch operation '{operationName}'."; - string actualErrorMessage = null; + var patchDocument = new JsonPatchDocument(); // Act - jsonPatchDocument.ApplyTo(model, (jsonPatchError) => + var exception = Assert.Throws(() => { - actualErrorMessage = jsonPatchError.ErrorMessage; + patchDocument.Add("//NewInt", 1); }); // Assert - Assert.Equal(expectedErrorMessage, actualErrorMessage); + Assert.Equal( + "The provided string '//NewInt' is an invalid path.", + exception.Message); } [Fact] - public void InvalidOperation_NoLogErrorAction_ThrowsJsonPatchException() + public void InvalidPathAtEndShouldThrowException() { // Arrange - var operationName = "foo"; - var serialized = "[{\"value\":\"John\",\"path\":\"/Name\",\"op\":\"" + operationName + "\"}]"; - var jsonPatchDocument = JsonConvert.DeserializeObject>(serialized); - var model = new Customer(); - var expectedErrorMessage = $"Invalid JsonPatch operation '{operationName}'."; + var patchDocument = new JsonPatchDocument(); // Act - var jsonPatchException = Assert.Throws(() => jsonPatchDocument.ApplyTo(model)); + var exception = Assert.Throws(() => + { + patchDocument.Add("NewInt//", 1); + }); // Assert - Assert.Equal(expectedErrorMessage, jsonPatchException.Message); + Assert.Equal( + "The provided string 'NewInt//' is an invalid path.", + exception.Message); } - private class Customer + [Fact] + public void InvalidPathWithDotShouldThrowException() { - public string Name { get; set; } + // Arrange + var patchDocument = new JsonPatchDocument(); + + // Act + var exception = Assert.Throws(() => + { + patchDocument.Add("NewInt.Test", 1); + }); + + // Assert + Assert.Equal( + "The provided string 'NewInt.Test' is an invalid path.", + exception.Message); + } + + [Fact] + public void NonGenericPatchDocToGenericMustSerialize() + { + // Arrange + var targetObject = new SimpleObject() + { + StringProperty = "A", + AnotherStringProperty = "B" + }; + + var patchDocument = new JsonPatchDocument(); + patchDocument.Copy("StringProperty", "AnotherStringProperty"); + + var serialized = JsonConvert.SerializeObject(patchDocument); + var deserialized = JsonConvert.DeserializeObject>(serialized); + + // Act + deserialized.ApplyTo(targetObject); + + // Assert + Assert.Equal("A", targetObject.AnotherStringProperty); + } + + [Fact] + public void GenericPatchDocToNonGenericMustSerialize() + { + // Arrange + var targetObject = new SimpleObject() + { + StringProperty = "A", + AnotherStringProperty = "B" + }; + + var patchDocTyped = new JsonPatchDocument(); + patchDocTyped.Copy(o => o.StringProperty, o => o.AnotherStringProperty); + + var patchDocUntyped = new JsonPatchDocument(); + patchDocUntyped.Copy("StringProperty", "AnotherStringProperty"); + + var serializedTyped = JsonConvert.SerializeObject(patchDocTyped); + var serializedUntyped = JsonConvert.SerializeObject(patchDocUntyped); + var deserialized = JsonConvert.DeserializeObject(serializedTyped); + + // Act + deserialized.ApplyTo(targetObject); + + // Assert + Assert.Equal("A", targetObject.AnotherStringProperty); + } + + [Fact] + public void Deserialization_Successful_ForValidJsonPatchDocument() + { + // Arrange + var doc = new SimpleObject() + { + StringProperty = "A", + DecimalValue = 10, + DoubleValue = 10, + FloatValue = 10, + IntegerValue = 10 + }; + + var patchDocument = new JsonPatchDocument(); + patchDocument.Replace(o => o.StringProperty, "B"); + patchDocument.Replace(o => o.DecimalValue, 12); + patchDocument.Replace(o => o.DoubleValue, 12); + patchDocument.Replace(o => o.FloatValue, 12); + patchDocument.Replace(o => o.IntegerValue, 12); + + // default: no envelope + var serialized = JsonConvert.SerializeObject(patchDocument); + + // Act + var deserialized = JsonConvert.DeserializeObject>(serialized); + + // Assert + Assert.IsType>(deserialized); + } + + [Fact] + public void Deserialization_Fails_ForInvalidJsonPatchDocument() + { + // Arrange + var serialized = "{\"Operations\": [{ \"op\": \"replace\", \"path\": \"/title\", \"value\": \"New Title\"}]}"; + + // Act + var exception = Assert.Throws(() => + { + var deserialized + = JsonConvert.DeserializeObject(serialized); + }); + + // Assert + Assert.Equal("The JSON patch document was malformed and could not be parsed.", exception.Message); + } + + [Fact] + public void Deserialization_Fails_ForInvalidTypedJsonPatchDocument() + { + // Arrange + var serialized = "{\"Operations\": [{ \"op\": \"replace\", \"path\": \"/title\", \"value\": \"New Title\"}]}"; + + // Act + var exception = Assert.Throws(() => + { + var deserialized + = JsonConvert.DeserializeObject>(serialized); + }); + + // Assert + Assert.Equal("The JSON patch document was malformed and could not be parsed.", exception.Message); } } -} +} \ No newline at end of file diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/JsonPropertyComplexNameObject.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/JsonPropertyComplexNameObject.cs deleted file mode 100644 index a39aa8e30c..0000000000 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/JsonPropertyComplexNameObject.cs +++ /dev/null @@ -1,16 +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 Newtonsoft.Json; - -namespace Microsoft.AspNetCore.JsonPatch -{ - public class JsonPropertyComplexNameObject - { - [JsonProperty("foo/bar~")] - public string FooSlashBars { get; set; } - - [JsonProperty("foo/~")] - public SimpleObject FooSlashTilde { get; set; } - } -} diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/JsonPropertyObject.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/JsonPropertyObject.cs deleted file mode 100644 index 245ae6bb65..0000000000 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/JsonPropertyObject.cs +++ /dev/null @@ -1,13 +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 Newtonsoft.Json; - -namespace Microsoft.AspNetCore.JsonPatch -{ - public class JsonPropertyObject - { - [JsonProperty("AnotherName")] - public string Name { get; set; } - } -} diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/JsonPropertyWithAnotherNameObject.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/JsonPropertyWithAnotherNameObject.cs deleted file mode 100644 index 4581a4826d..0000000000 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/JsonPropertyWithAnotherNameObject.cs +++ /dev/null @@ -1,10 +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 JsonPropertyWithAnotherNameObject - { - public string AnotherName { get; set; } - } -} diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/JsonPropertyWithInheritanceObject.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/JsonPropertyWithInheritanceObject.cs deleted file mode 100644 index 935ef275ad..0000000000 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/JsonPropertyWithInheritanceObject.cs +++ /dev/null @@ -1,15 +0,0 @@ -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; } - } -} diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/NestedObject.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/NestedObject.cs deleted file mode 100644 index 8f0927297e..0000000000 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/NestedObject.cs +++ /dev/null @@ -1,10 +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 NestedObject - { - public string StringProperty { get; set; } - } -} \ No newline at end of file diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/NestedObjectTests.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/NestedObjectTests.cs deleted file mode 100644 index a0b5bd7e3f..0000000000 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/NestedObjectTests.cs +++ /dev/null @@ -1,2272 +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; -using System.Collections.ObjectModel; -using Microsoft.AspNetCore.JsonPatch.Exceptions; -using Newtonsoft.Json; -using Xunit; - -namespace Microsoft.AspNetCore.JsonPatch -{ - public class NestedObjectTests - { - [Fact] - public void ReplacePropertyInNestedObject() - { - // Arrange - var doc = new SimpleObjectWithNestedObject() - { - IntegerValue = 1 - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Replace(o => o.NestedObject.StringProperty, "B"); - - // Act - patchDoc.ApplyTo(doc); - - // Assert - Assert.Equal("B", doc.NestedObject.StringProperty); - } - - [Fact] - public void ReplacePropertyInNestedObjectWithSerialization() - { - // Arrange - var doc = new SimpleObjectWithNestedObject() - { - IntegerValue = 1 - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Replace(o => o.NestedObject.StringProperty, "B"); - - // serialize & deserialize - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject>(serialized); - - // Act - deserialized.ApplyTo(doc); - - // Assert - Assert.Equal("B", doc.NestedObject.StringProperty); - } - - [Fact] - public void ReplaceNestedObject() - { - // Arrange - var doc = new SimpleObjectWithNestedObject() - { - IntegerValue = 1 - }; - - var newNested = new NestedObject() { StringProperty = "B" }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Replace(o => o.NestedObject, newNested); - - // Act - patchDoc.ApplyTo(doc); - - // Assert - Assert.Equal("B", doc.NestedObject.StringProperty); - } - - [Fact] - public void ReplaceNestedObjectWithSerialization() - { - // Arrange - var doc = new SimpleObjectWithNestedObject() - { - IntegerValue = 1 - }; - - var newNested = new NestedObject() { StringProperty = "B" }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Replace(o => o.NestedObject, newNested); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject>(serialized); - - // Act - deserialized.ApplyTo(doc); - - // Assert - Assert.Equal("B", doc.NestedObject.StringProperty); - } - - [Fact] - public void AddResultsInReplace() - { - // Arrange - var doc = new SimpleObjectWithNestedObject() - { - SimpleObject = new SimpleObject() - { - StringProperty = "A" - } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Add(o => o.SimpleObject.StringProperty, "B"); - - // Act - patchDoc.ApplyTo(doc); - - // Assert - Assert.Equal("B", doc.SimpleObject.StringProperty); - } - - [Fact] - public void AddResultsInReplaceWithSerialization() - { - // Arrange - var doc = new SimpleObjectWithNestedObject() - { - SimpleObject = new SimpleObject() - { - StringProperty = "A" - } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Add(o => o.SimpleObject.StringProperty, "B"); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject>(serialized); - - // Act - deserialized.ApplyTo(doc); - - // Assert - Assert.Equal("B", doc.SimpleObject.StringProperty); - } - - [Fact] - public void AddToList() - { - // Arrange - var doc = new SimpleObjectWithNestedObject() - { - SimpleObject = new SimpleObject() - { - IntegerList = new List() { 1, 2, 3 } - } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Add(o => o.SimpleObject.IntegerList, 4, 0); - - // Act - patchDoc.ApplyTo(doc); - - // Assert - Assert.Equal(new List() { 4, 1, 2, 3 }, doc.SimpleObject.IntegerList); - } - - [Fact] - public void AddToListWithSerialization() - { - // Arrange - var doc = new SimpleObjectWithNestedObject() - { - SimpleObject = new SimpleObject() - { - IntegerList = new List() { 1, 2, 3 } - } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Add(o => o.SimpleObject.IntegerList, 4, 0); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject>(serialized); - - // Act - deserialized.ApplyTo(doc); - - // Assert - Assert.Equal(new List() { 4, 1, 2, 3 }, doc.SimpleObject.IntegerList); - } - - [Fact] - public void AddToIntegerIList() - { - // Arrange - var doc = new SimpleObjectWithNestedObject() - { - SimpleObject = new SimpleObject() - { - IntegerIList = new List() { 1, 2, 3 } - } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Add(o => (List)o.SimpleObject.IntegerIList, 4, 0); - - // Act - patchDoc.ApplyTo(doc); - - // Assert - Assert.Equal(new List() { 4, 1, 2, 3 }, doc.SimpleObject.IntegerIList); - } - - [Fact] - public void AddToIntegerIListWithSerialization() - { - // Arrange - var doc = new SimpleObjectWithNestedObject() - { - SimpleObject = new SimpleObject() - { - IntegerIList = new List() { 1, 2, 3 } - } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Add(o => (List)o.SimpleObject.IntegerIList, 4, 0); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject>(serialized); - - // Act - deserialized.ApplyTo(doc); - - // Assert - Assert.Equal(new List() { 4, 1, 2, 3 }, doc.SimpleObject.IntegerIList); - } - - [Fact] - public void AddToNestedIntegerIList() - { - // Arrange - var doc = new SimpleObjectWithNestedObject() - { - SimpleObjectIList = new List - { - new SimpleObject - { - IntegerIList = new List() { 1, 2, 3 } - } - } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Add(o => (List)o.SimpleObjectIList[0].IntegerIList, 4, 0); - - // Act - patchDoc.ApplyTo(doc); - - // Assert - Assert.Equal(new List() { 4, 1, 2, 3 }, doc.SimpleObjectIList[0].IntegerIList); - } - - [Fact] - public void AddToNestedIntegerIListWithSerialization() - { - // Arrange - var doc = new SimpleObjectWithNestedObject() - { - SimpleObjectIList = new List - { - new SimpleObject - { - IntegerIList = new List() { 1, 2, 3 } - } - } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Add(o => (List)o.SimpleObjectIList[0].IntegerIList, 4, 0); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject>(serialized); - - // Act - deserialized.ApplyTo(doc); - - // Assert - Assert.Equal(new List() { 4, 1, 2, 3 }, doc.SimpleObjectIList[0].IntegerIList); - } - - [Fact] - public void AddToComplextTypeListSpecifyIndex() - { - // Arrange - var doc = new SimpleObjectWithNestedObject() - { - SimpleObjectList = new List() - { - new SimpleObject - { - StringProperty = "String1" - }, - new SimpleObject - { - StringProperty = "String2" - } - } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Add(o => o.SimpleObjectList[0].StringProperty, "ChangedString1"); - - // Act - patchDoc.ApplyTo(doc); - - // Assert - Assert.Equal("ChangedString1", doc.SimpleObjectList[0].StringProperty); - } - - [Fact] - public void AddToComplextTypeListSpecifyIndexWithSerialization() - { - // Arrange - var doc = new SimpleObjectWithNestedObject() - { - SimpleObjectList = new List() - { - new SimpleObject - { - StringProperty = "String1" - }, - new SimpleObject - { - StringProperty = "String2" - } - } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Add(o => o.SimpleObjectList[0].StringProperty, "ChangedString1"); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject>(serialized); - - // Act - deserialized.ApplyTo(doc); - - // Assert - Assert.Equal("ChangedString1", doc.SimpleObjectList[0].StringProperty); - } - - [Fact] - public void AddToListInvalidPositionTooLarge() - { - // Arrange - var doc = new SimpleObjectWithNestedObject() - { - SimpleObject = new SimpleObject() - { - IntegerList = new List() { 1, 2, 3 } - } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Add(o => o.SimpleObject.IntegerList, 4, 4); - - // Act & Assert - var exception = Assert.Throws(() => { patchDoc.ApplyTo(doc); }); - Assert.Equal( - string.Format("The index value provided by path segment '{0}' is out of bounds of the array size.", "4"), - exception.Message); - - } - - [Fact] - public void AddToListInvalidPositionTooLargeWithSerialization() - { - // Arrange - var doc = new SimpleObjectWithNestedObject() - { - SimpleObject = new SimpleObject() - { - IntegerList = new List() { 1, 2, 3 } - } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Add(o => o.SimpleObject.IntegerList, 4, 4); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject>(serialized); - - // Act & Assert - var exception = Assert.Throws(() => - { - deserialized.ApplyTo(doc); - }); - Assert.Equal( - string.Format("The index value provided by path segment '{0}' is out of bounds of the array size.", "4"), - exception.Message); - } - - [Fact] - public void AddToListInvalidPositionTooLarge_LogsError() - { - // Arrange - var doc = new SimpleObjectWithNestedObject() - { - SimpleObject = new SimpleObject() - { - IntegerList = new List() { 1, 2, 3 } - } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Add(o => o.SimpleObject.IntegerList, 4, 4); - - var logger = new TestErrorLogger(); - - patchDoc.ApplyTo(doc, logger.LogErrorMessage); - - - //Assert - Assert.Equal( - string.Format("The index value provided by path segment '{0}' is out of bounds of the array size.", "4"), - logger.ErrorMessage); - - } - - [Fact] - public void AddToListInvalidPositionTooSmall() - { - // Arrange - var doc = new SimpleObjectWithNestedObject() - { - SimpleObject = new SimpleObject() - { - IntegerList = new List() { 1, 2, 3 } - } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Add(o => o.SimpleObject.IntegerList, 4, -1); - - // Act & Assert - var exception = Assert.Throws(() => { patchDoc.ApplyTo(doc); }); - Assert.Equal( - string.Format("The index value provided by path segment '{0}' is out of bounds of the array size.", "-1"), - exception.Message); - } - - [Fact] - public void AddToListInvalidPositionTooSmallWithSerialization() - { - // Arrange - var doc = new SimpleObjectWithNestedObject() - { - SimpleObject = new SimpleObject() - { - IntegerList = new List() { 1, 2, 3 } - } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Add(o => o.SimpleObject.IntegerList, 4, -1); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject>(serialized); - - // Act & Assert - var exception = Assert.Throws(() => - { - deserialized.ApplyTo(doc); - }); - Assert.Equal( - string.Format("The index value provided by path segment '{0}' is out of bounds of the array size.", "-1"), - exception.Message); - } - - [Fact] - public void AddToListInvalidPositionTooSmall_LogsError() - { - // Arrange - var doc = new SimpleObjectWithNestedObject() - { - SimpleObject = new SimpleObject() - { - IntegerList = new List() { 1, 2, 3 } - } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Add(o => o.SimpleObject.IntegerList, 4, -1); - - var logger = new TestErrorLogger(); - - - patchDoc.ApplyTo(doc, logger.LogErrorMessage); - - - //Assert - Assert.Equal( - string.Format("The index value provided by path segment '{0}' is out of bounds of the array size.", "-1"), - logger.ErrorMessage); - } - - [Fact] - public void AddToListAppend() - { - // Arrange - var doc = new SimpleObjectWithNestedObject() - { - SimpleObject = new SimpleObject() - { - IntegerList = new List() { 1, 2, 3 } - } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Add(o => o.SimpleObject.IntegerList, 4); - - // Act - patchDoc.ApplyTo(doc); - - // Assert - Assert.Equal(new List() { 1, 2, 3, 4 }, doc.SimpleObject.IntegerList); - } - - [Fact] - public void AddToListAppendWithSerialization() - { - // Arrange - var doc = new SimpleObjectWithNestedObject() - { - SimpleObject = new SimpleObject() - { - IntegerList = new List() { 1, 2, 3 } - } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Add(o => o.SimpleObject.IntegerList, 4); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject>(serialized); - - // Act - deserialized.ApplyTo(doc); - - // Assert - Assert.Equal(new List() { 1, 2, 3, 4 }, doc.SimpleObject.IntegerList); - } - - [Fact] - public void Remove() - { - // Arrange - var doc = new SimpleObjectWithNestedObject() - { - SimpleObject = new SimpleObject() - { - StringProperty = "A" - } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Remove(o => o.SimpleObject.StringProperty); - - // Act - patchDoc.ApplyTo(doc); - - // Assert - Assert.Null(doc.SimpleObject.StringProperty); - } - - [Fact] - public void RemoveWithSerialization() - { - // Arrange - var doc = new SimpleObjectWithNestedObject() - { - SimpleObject = new SimpleObject() - { - StringProperty = "A" - } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Remove(o => o.SimpleObject.StringProperty); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject>(serialized); - - // Act - deserialized.ApplyTo(doc); - - // Assert - Assert.Null(doc.SimpleObject.StringProperty); - } - - [Fact] - public void RemoveFromList() - { - // Arrange - var doc = new SimpleObjectWithNestedObject() - { - SimpleObject = new SimpleObject() - { - IntegerList = new List() { 1, 2, 3 } - } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Remove(o => o.SimpleObject.IntegerList, 2); - - // Act - patchDoc.ApplyTo(doc); - - // Assert - Assert.Equal(new List() { 1, 2 }, doc.SimpleObject.IntegerList); - } - - [Fact] - public void RemoveFromListWithSerialization() - { - // Arrange - var doc = new SimpleObjectWithNestedObject() - { - SimpleObject = new SimpleObject() - { - IntegerList = new List() { 1, 2, 3 } - } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Remove(o => o.SimpleObject.IntegerList, 2); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject>(serialized); - - // Act - deserialized.ApplyTo(doc); - - // Assert - Assert.Equal(new List() { 1, 2 }, doc.SimpleObject.IntegerList); - } - - [Fact] - public void RemoveFromListInvalidPositionTooLarge() - { - // Arrange - var doc = new SimpleObjectWithNestedObject() - { - SimpleObject = new SimpleObject() - { - IntegerList = new List() { 1, 2, 3 } - } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Remove(o => o.SimpleObject.IntegerList, 3); - - // Act & Assert - var exception = Assert.Throws(() => { patchDoc.ApplyTo(doc); }); - Assert.Equal( - string.Format("The index value provided by path segment '{0}' is out of bounds of the array size.", "3"), - exception.Message); - } - - [Fact] - public void RemoveFromListInvalidPositionTooLargeWithSerialization() - { - // Arrange - var doc = new SimpleObjectWithNestedObject() - { - SimpleObject = new SimpleObject() - { - IntegerList = new List() { 1, 2, 3 } - } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Remove(o => o.SimpleObject.IntegerList, 3); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject>(serialized); - - // Act & Assert - var exception = Assert.Throws(() => - { - deserialized.ApplyTo(doc); - }); - Assert.Equal( - string.Format("The index value provided by path segment '{0}' is out of bounds of the array size.", "3"), - exception.Message); - } - - [Fact] - public void RemoveFromListInvalidPositionTooLarge_LogsError() - { - // Arrange - var doc = new SimpleObjectWithNestedObject() - { - SimpleObject = new SimpleObject() - { - IntegerList = new List() { 1, 2, 3 } - } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Remove(o => o.SimpleObject.IntegerList, 3); - - var logger = new TestErrorLogger(); - - patchDoc.ApplyTo(doc, logger.LogErrorMessage); - - // Assert - Assert.Equal( - string.Format("The index value provided by path segment '{0}' is out of bounds of the array size.", "3"), - logger.ErrorMessage); - } - - [Fact] - public void RemoveFromListInvalidPositionTooSmall() - { - // Arrange - var doc = new SimpleObjectWithNestedObject() - { - SimpleObject = new SimpleObject() - { - IntegerList = new List() { 1, 2, 3 } - } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Remove(o => o.SimpleObject.IntegerList, -1); - - // Act & Assert - var exception = Assert.Throws(() => { patchDoc.ApplyTo(doc); }); - Assert.Equal( - string.Format("The index value provided by path segment '{0}' is out of bounds of the array size.", "-1"), - exception.Message); - } - - [Fact] - public void RemoveFromListInvalidPositionTooSmallWithSerialization() - { - // Arrange - var doc = new SimpleObjectWithNestedObject() - { - SimpleObject = new SimpleObject() - { - IntegerList = new List() { 1, 2, 3 } - } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Remove(o => o.SimpleObject.IntegerList, -1); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject>(serialized); - - // Act & Assert - var exception = Assert.Throws(() => - { - deserialized.ApplyTo(doc); - }); - Assert.Equal( - string.Format("The index value provided by path segment '{0}' is out of bounds of the array size.", "-1"), - exception.Message); - } - - [Fact] - public void RemoveFromListInvalidPositionTooSmall_LogsError() - { - // Arrange - var doc = new SimpleObjectWithNestedObject() - { - SimpleObject = new SimpleObject() - { - IntegerList = new List() { 1, 2, 3 } - } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Remove(o => o.SimpleObject.IntegerList, -1); - - var logger = new TestErrorLogger(); - - - patchDoc.ApplyTo(doc, logger.LogErrorMessage); - - // Assert - Assert.Equal( - string.Format("The index value provided by path segment '{0}' is out of bounds of the array size.", "-1"), - logger.ErrorMessage); - } - - [Fact] - public void RemoveFromEndOfList() - { - // Arrange - var doc = new SimpleObjectWithNestedObject() - { - SimpleObject = new SimpleObject() - { - IntegerList = new List() { 1, 2, 3 } - } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Remove(o => o.SimpleObject.IntegerList); - - // Act - patchDoc.ApplyTo(doc); - - // Assert - Assert.Equal(new List() { 1, 2 }, doc.SimpleObject.IntegerList); - } - - [Fact] - public void RemoveFromEndOfListWithSerialization() - { - // Arrange - var doc = new SimpleObjectWithNestedObject() - { - SimpleObject = new SimpleObject() - { - IntegerList = new List() { 1, 2, 3 } - } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Remove(o => o.SimpleObject.IntegerList); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject>(serialized); - - // Act - deserialized.ApplyTo(doc); - - // Assert - Assert.Equal(new List() { 1, 2 }, doc.SimpleObject.IntegerList); - } - - [Fact] - public void Replace() - { - // Arrange - var doc = new SimpleObjectWithNestedObject() - { - SimpleObject = new SimpleObject() - { - StringProperty = "A", - DecimalValue = 10 - } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Replace(o => o.SimpleObject.StringProperty, "B"); - patchDoc.Replace(o => o.SimpleObject.DecimalValue, 12); - - // Act - patchDoc.ApplyTo(doc); - - // Assert - Assert.Equal("B", doc.SimpleObject.StringProperty); - Assert.Equal(12, doc.SimpleObject.DecimalValue); - } - - [Fact] - public void Replace_DTOWithNullCheck() - { - // Arrange - var doc = new SimpleObjectWithNestedObjectWithNullCheck() - { - SimpleObjectWithNullCheck = new SimpleObjectWithNullCheck() - { - StringProperty = "A" - } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Replace(o => o.SimpleObjectWithNullCheck.StringProperty, "B"); - - // Act - patchDoc.ApplyTo(doc); - - // Assert - Assert.Equal("B", doc.SimpleObjectWithNullCheck.StringProperty); - } - - [Fact] - public void ReplaceWithSerialization() - { - // Arrange - var doc = new SimpleObjectWithNestedObject() - { - SimpleObject = new SimpleObject() - { - StringProperty = "A", - DecimalValue = 10 - } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Replace(o => o.SimpleObject.StringProperty, "B"); - patchDoc.Replace(o => o.SimpleObject.DecimalValue, 12); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject>(serialized); - - // Act - deserialized.ApplyTo(doc); - - // Assert - Assert.Equal("B", doc.SimpleObject.StringProperty); - Assert.Equal(12, doc.SimpleObject.DecimalValue); - } - - [Fact] - public void SerializationTests() - { - // Arrange - var doc = new SimpleObjectWithNestedObject() - { - SimpleObject = new SimpleObject() - { - StringProperty = "A", - DecimalValue = 10, - DoubleValue = 10, - FloatValue = 10, - IntegerValue = 10 - } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Replace(o => o.SimpleObject.StringProperty, "B"); - patchDoc.Replace(o => o.SimpleObject.DecimalValue, 12); - patchDoc.Replace(o => o.SimpleObject.DoubleValue, 12); - patchDoc.Replace(o => o.SimpleObject.FloatValue, 12); - patchDoc.Replace(o => o.SimpleObject.IntegerValue, 12); - - // serialize & deserialize - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserizalized = JsonConvert.DeserializeObject>(serialized); - - // Act - deserizalized.ApplyTo(doc); - - // Assert - Assert.Equal("B", doc.SimpleObject.StringProperty); - Assert.Equal(12, doc.SimpleObject.DecimalValue); - Assert.Equal(12, doc.SimpleObject.DoubleValue); - Assert.Equal(12, doc.SimpleObject.FloatValue); - Assert.Equal(12, doc.SimpleObject.IntegerValue); - } - - [Fact] - public void ReplaceInList() - { - // Arrange - var doc = new SimpleObjectWithNestedObject() - { - SimpleObject = new SimpleObject() - { - IntegerList = new List() { 1, 2, 3 } - } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Replace(o => o.SimpleObject.IntegerList, 5, 0); - - // Act - patchDoc.ApplyTo(doc); - - // Assert - Assert.Equal(new List() { 5, 2, 3 }, doc.SimpleObject.IntegerList); - } - - [Fact] - public void ReplaceInListWithSerialization() - { - // Arrange - var doc = new SimpleObjectWithNestedObject() - { - SimpleObject = new SimpleObject() - { - IntegerList = new List() { 1, 2, 3 } - } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Replace(o => o.SimpleObject.IntegerList, 5, 0); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject>(serialized); - - // Act - deserialized.ApplyTo(doc); - - // Assert - Assert.Equal(new List() { 5, 2, 3 }, doc.SimpleObject.IntegerList); - } - - [Fact] - public void ReplaceFullList() - { - // Arrange - var doc = new SimpleObjectWithNestedObject() - { - SimpleObject = new SimpleObject() - { - IntegerList = new List() { 1, 2, 3 } - } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Replace(o => o.SimpleObject.IntegerList, new List() { 4, 5, 6 }); - - // Act - patchDoc.ApplyTo(doc); - - // Arrange - Assert.Equal(new List() { 4, 5, 6 }, doc.SimpleObject.IntegerList); - } - - [Fact] - public void ReplaceFullListWithSerialiation() - { - // Arrange - var doc = new SimpleObjectWithNestedObject() - { - SimpleObject = new SimpleObject() - { - IntegerList = new List() { 1, 2, 3 } - } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Replace(o => o.SimpleObject.IntegerList, new List() { 4, 5, 6 }); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject>(serialized); - - // Act - deserialized.ApplyTo(doc); - - // Assert - Assert.Equal(new List() { 4, 5, 6 }, doc.SimpleObject.IntegerList); - } - - [Fact] - public void ReplaceFullListFromEnumerable() - { - // Arrange - var doc = new SimpleObjectWithNestedObject() - { - SimpleObject = new SimpleObject() - { - IntegerList = new List() { 1, 2, 3 } - } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Replace>(o => o.SimpleObject.IntegerList, new List() { 4, 5, 6 }); - - // Act - patchDoc.ApplyTo(doc); - - // Assert - Assert.Equal(new List() { 4, 5, 6 }, doc.SimpleObject.IntegerList); - } - - [Fact] - public void ReplaceFullListFromEnumerableWithSerialization() - { - // Arrange - var doc = new SimpleObjectWithNestedObject() - { - SimpleObject = new SimpleObject() - { - IntegerList = new List() { 1, 2, 3 } - } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Replace>(o => o.SimpleObject.IntegerList, new List() { 4, 5, 6 }); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject>(serialized); - - // Act - deserialized.ApplyTo(doc); - - // Assert - Assert.Equal(new List() { 4, 5, 6 }, doc.SimpleObject.IntegerList); - } - - [Fact] - public void ReplaceFullListWithCollection() - { - // Arrange - var doc = new SimpleObjectWithNestedObject() - { - SimpleObject = new SimpleObject() - { - IntegerList = new List() { 1, 2, 3 } - } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Replace>(o => o.SimpleObject.IntegerList, new Collection() { 4, 5, 6 }); - - // Act - patchDoc.ApplyTo(doc); - - // Assert - Assert.Equal(new List() { 4, 5, 6 }, doc.SimpleObject.IntegerList); - } - - [Fact] - public void ReplaceFullListWithCollectionWithSerialization() - { - // Arrange - var doc = new SimpleObjectWithNestedObject() - { - SimpleObject = new SimpleObject() - { - IntegerList = new List() { 1, 2, 3 } - } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Replace>(o => o.SimpleObject.IntegerList, new Collection() { 4, 5, 6 }); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject>(serialized); - - // Act - deserialized.ApplyTo(doc); - - // Assert - Assert.Equal(new List() { 4, 5, 6 }, doc.SimpleObject.IntegerList); - } - - [Fact] - public void ReplaceAtEndOfList() - { - // Arrange - var doc = new SimpleObjectWithNestedObject() - { - SimpleObject = new SimpleObject() - { - IntegerList = new List() { 1, 2, 3 } - } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Replace(o => o.SimpleObject.IntegerList, 5); - - // Act - patchDoc.ApplyTo(doc); - - // Assert - Assert.Equal(new List() { 1, 2, 5 }, doc.SimpleObject.IntegerList); - } - - [Fact] - public void ReplaceAtEndOfListWithSerialization() - { - // Arrange - var doc = new SimpleObjectWithNestedObject() - { - SimpleObject = new SimpleObject() - { - IntegerList = new List() { 1, 2, 3 } - } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Replace(o => o.SimpleObject.IntegerList, 5); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject>(serialized); - - // Act - deserialized.ApplyTo(doc); - - // Assert - Assert.Equal(new List() { 1, 2, 5 }, doc.SimpleObject.IntegerList); - } - - [Fact] - public void ReplaceInListInvalidInvalidPositionTooLarge() - { - // Arrange - var doc = new SimpleObjectWithNestedObject() - { - SimpleObject = new SimpleObject() - { - IntegerList = new List() { 1, 2, 3 } - } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Replace(o => o.SimpleObject.IntegerList, 5, 3); - - // Act & Assert - var exception = Assert.Throws(() => { patchDoc.ApplyTo(doc); }); - Assert.Equal( - string.Format("The index value provided by path segment '{0}' is out of bounds of the array size.", "3"), - exception.Message); - } - - [Fact] - public void ReplaceInListInvalidInvalidPositionTooLargeWithSerialization() - { - // Arrange - var doc = new SimpleObjectWithNestedObject() - { - SimpleObject = new SimpleObject() - { - IntegerList = new List() { 1, 2, 3 } - } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Replace(o => o.SimpleObject.IntegerList, 5, 3); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject>(serialized); - - // Act & Assert - var exception = Assert.Throws(() => - { - deserialized.ApplyTo(doc); - }); - Assert.Equal( - string.Format("The index value provided by path segment '{0}' is out of bounds of the array size.", "3"), - exception.Message); - } - - [Fact] - public void ReplaceInListInvalid_PositionTooLarge_LogsError() - { - // Arrange - var doc = new SimpleObjectWithNestedObject() - { - SimpleObject = new SimpleObject() - { - IntegerList = new List() { 1, 2, 3 } - } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Replace(o => o.SimpleObject.IntegerList, 5, 3); - - var logger = new TestErrorLogger(); - - - patchDoc.ApplyTo(doc, logger.LogErrorMessage); - - - // Assert - Assert.Equal( - string.Format("The index value provided by path segment '{0}' is out of bounds of the array size.", "3"), - logger.ErrorMessage); - } - - [Fact] - public void ReplaceInListInvalidPositionTooSmall() - { - // Arrange - var doc = new SimpleObjectWithNestedObject() - { - SimpleObject = new SimpleObject() - { - IntegerList = new List() { 1, 2, 3 } - } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Replace(o => o.SimpleObject.IntegerList, 5, -1); - - // Act & Assert - var exception = Assert.Throws(() => { patchDoc.ApplyTo(doc); }); - Assert.Equal( - string.Format("The index value provided by path segment '{0}' is out of bounds of the array size.", "-1"), - exception.Message); - } - - [Fact] - public void ReplaceInListInvalidPositionTooSmallWithSerialization() - { - // Arrange - var doc = new SimpleObjectWithNestedObject() - { - SimpleObject = new SimpleObject() - { - IntegerList = new List() { 1, 2, 3 } - } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Replace(o => o.SimpleObject.IntegerList, 5, -1); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject>(serialized); - - // Act & Assert - var exception = Assert.Throws(() => { deserialized.ApplyTo(doc); }); - Assert.Equal( - string.Format("The index value provided by path segment '{0}' is out of bounds of the array size.", "-1"), - exception.Message); - } - - [Fact] - public void ReplaceInListInvalidPositionTooSmall_LogsError() - { - // Arrange - var doc = new SimpleObjectWithNestedObject() - { - SimpleObject = new SimpleObject() - { - IntegerList = new List() { 1, 2, 3 } - } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Replace(o => o.SimpleObject.IntegerList, 5, -1); - - var logger = new TestErrorLogger(); - - - patchDoc.ApplyTo(doc, logger.LogErrorMessage); - - - // Assert - Assert.Equal( - string.Format("The index value provided by path segment '{0}' is out of bounds of the array size.", "-1"), - logger.ErrorMessage); - } - - [Fact] - public void Copy() - { - // Arrange - var doc = new SimpleObjectWithNestedObject() - { - SimpleObject = new SimpleObject() - { - StringProperty = "A", - AnotherStringProperty = "B" - } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Copy(o => o.SimpleObject.StringProperty, o => o.SimpleObject.AnotherStringProperty); - - // Act - patchDoc.ApplyTo(doc); - - // Assert - Assert.Equal("A", doc.SimpleObject.AnotherStringProperty); - } - - [Fact] - public void CopyWithSerialization() - { - // Arrange - var doc = new SimpleObjectWithNestedObject() - { - SimpleObject = new SimpleObject() - { - StringProperty = "A", - AnotherStringProperty = "B" - } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Copy(o => o.SimpleObject.StringProperty, o => o.SimpleObject.AnotherStringProperty); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject>(serialized); - - // Act - deserialized.ApplyTo(doc); - - // Assert - Assert.Equal("A", doc.SimpleObject.AnotherStringProperty); - } - - [Fact] - public void CopyInList() - { - // Arrange - var doc = new SimpleObjectWithNestedObject() - { - SimpleObject = new SimpleObject() - { - IntegerList = new List() { 1, 2, 3 } - } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Copy(o => o.SimpleObject.IntegerList, 0, o => o.SimpleObject.IntegerList, 1); - - // Act - patchDoc.ApplyTo(doc); - - // Assert - Assert.Equal(new List() { 1, 1, 2, 3 }, doc.SimpleObject.IntegerList); - } - - [Fact] - public void CopyInListWithSerialization() - { - // Arrange - var doc = new SimpleObjectWithNestedObject() - { - SimpleObject = new SimpleObject() - { - IntegerList = new List() { 1, 2, 3 } - } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Copy(o => o.SimpleObject.IntegerList, 0, o => o.SimpleObject.IntegerList, 1); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject>(serialized); - - // Act - deserialized.ApplyTo(doc); - - // Assert - Assert.Equal(new List() { 1, 1, 2, 3 }, doc.SimpleObject.IntegerList); - } - - [Fact] - public void CopyFromListToEndOfList() - { - // Arrange - var doc = new SimpleObjectWithNestedObject() - { - SimpleObject = new SimpleObject() - { - IntegerList = new List() { 1, 2, 3 } - } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Copy(o => o.SimpleObject.IntegerList, 0, o => o.SimpleObject.IntegerList); - - // Act - patchDoc.ApplyTo(doc); - - // Assert - Assert.Equal(new List() { 1, 2, 3, 1 }, doc.SimpleObject.IntegerList); - } - - [Fact] - public void CopyFromListToEndOfListWithSerialization() - { - // Arrange - var doc = new SimpleObjectWithNestedObject() - { - SimpleObject = new SimpleObject() - { - IntegerList = new List() { 1, 2, 3 } - } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Copy(o => o.SimpleObject.IntegerList, 0, o => o.SimpleObject.IntegerList); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject>(serialized); - - // Act - deserialized.ApplyTo(doc); - - // Assert - Assert.Equal(new List() { 1, 2, 3, 1 }, doc.SimpleObject.IntegerList); - } - - [Fact] - public void CopyFromListToNonList() - { - // Arrange - var doc = new SimpleObjectWithNestedObject() - { - SimpleObject = new SimpleObject() - { - IntegerList = new List() { 1, 2, 3 } - } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Copy(o => o.SimpleObject.IntegerList, 0, o => o.SimpleObject.IntegerValue); - - // Act - patchDoc.ApplyTo(doc); - - // Assert - Assert.Equal(1, doc.SimpleObject.IntegerValue); - } - - [Fact] - public void CopyFromListToNonListWithSerialization() - { - // Arrange - var doc = new SimpleObjectWithNestedObject() - { - SimpleObject = new SimpleObject() - { - IntegerList = new List() { 1, 2, 3 } - } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Copy(o => o.SimpleObject.IntegerList, 0, o => o.SimpleObject.IntegerValue); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject>(serialized); - - // Act - deserialized.ApplyTo(doc); - - // Assert - Assert.Equal(1, doc.SimpleObject.IntegerValue); - } - - [Fact] - public void CopyFromNonListToList() - { - // Arrange - var doc = new SimpleObjectWithNestedObject() - { - SimpleObject = new SimpleObject() - { - IntegerValue = 5, - IntegerList = new List() { 1, 2, 3 } - } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Copy(o => o.SimpleObject.IntegerValue, o => o.SimpleObject.IntegerList, 0); - - // Act - patchDoc.ApplyTo(doc); - - // Assert - Assert.Equal(new List() { 5, 1, 2, 3 }, doc.SimpleObject.IntegerList); - } - - [Fact] - public void CopyFromNonListToListWithSerialization() - { - // Arrange - var doc = new SimpleObjectWithNestedObject() - { - SimpleObject = new SimpleObject() - { - IntegerValue = 5, - IntegerList = new List() { 1, 2, 3 } - } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Copy(o => o.SimpleObject.IntegerValue, o => o.SimpleObject.IntegerList, 0); - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject>(serialized); - - // Act - deserialized.ApplyTo(doc); - - // Assert - Assert.Equal(new List() { 5, 1, 2, 3 }, doc.SimpleObject.IntegerList); - } - - [Fact] - public void CopyToEndOfList() - { - // Arrange - var doc = new SimpleObjectWithNestedObject() - { - SimpleObject = new SimpleObject() - { - IntegerValue = 5, - IntegerList = new List() { 1, 2, 3 } - } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Copy(o => o.SimpleObject.IntegerValue, o => o.SimpleObject.IntegerList); - - // Act - patchDoc.ApplyTo(doc); - - // Assert - Assert.Equal(new List() { 1, 2, 3, 5 }, doc.SimpleObject.IntegerList); - } - - [Fact] - public void CopyToEndOfListWithSerialization() - { - // Arrange - var doc = new SimpleObjectWithNestedObject() - { - SimpleObject = new SimpleObject() - { - IntegerValue = 5, - IntegerList = new List() { 1, 2, 3 } - } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Copy(o => o.SimpleObject.IntegerValue, o => o.SimpleObject.IntegerList); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject>(serialized); - - // Act - deserialized.ApplyTo(doc); - - // Assert - Assert.Equal(new List() { 1, 2, 3, 5 }, doc.SimpleObject.IntegerList); - } - - [Fact] - public void Copy_DeepClonesObject() - { - // Arrange - var doc = new SimpleObjectWithNestedObject() - { - SimpleObject = new SimpleObject() - { - StringProperty = "A", - AnotherStringProperty = "B" - }, - InheritedObject = new InheritedObject() - { - StringProperty = "C", - AnotherStringProperty = "D" - } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Copy(o => o.InheritedObject, o => o.SimpleObject); - - // Act - patchDoc.ApplyTo(doc); - - // Assert - Assert.Equal("C", doc.SimpleObject.StringProperty); - Assert.Equal("D", doc.SimpleObject.AnotherStringProperty); - Assert.Equal("C", doc.InheritedObject.StringProperty); - Assert.Equal("D", doc.InheritedObject.AnotherStringProperty); - Assert.NotSame(doc.SimpleObject.StringProperty, doc.InheritedObject.StringProperty); - } - - [Fact] - public void Copy_KeepsObjectType() - { - // Arrange - var doc = new SimpleObjectWithNestedObject() - { - SimpleObject = new SimpleObject(), - InheritedObject = new InheritedObject() - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Copy(o => o.InheritedObject, o => o.SimpleObject); - - // Act - patchDoc.ApplyTo(doc); - - // Assert - Assert.Equal(typeof(InheritedObject), doc.SimpleObject.GetType()); - } - - [Fact] - public void Copy_BreaksObjectReference() - { - // Arrange - var doc = new SimpleObjectWithNestedObject() - { - SimpleObject = new SimpleObject(), - InheritedObject = new InheritedObject() - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Copy(o => o.InheritedObject, o => o.SimpleObject); - - // Act - patchDoc.ApplyTo(doc); - - // Assert - Assert.NotSame(doc.SimpleObject, doc.InheritedObject); - } - - [Fact] - public void Move() - { - // Arrange - var doc = new SimpleObjectWithNestedObject() - { - SimpleObject = new SimpleObject() - { - StringProperty = "A", - AnotherStringProperty = "B" - } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Move(o => o.SimpleObject.StringProperty, o => o.SimpleObject.AnotherStringProperty); - - // Act - patchDoc.ApplyTo(doc); - - // Assert - Assert.Equal("A", doc.SimpleObject.AnotherStringProperty); - Assert.Null(doc.SimpleObject.StringProperty); - } - - [Fact] - public void MoveWithSerialization() - { - // Arrange - var doc = new SimpleObjectWithNestedObject() - { - SimpleObject = new SimpleObject() - { - StringProperty = "A", - AnotherStringProperty = "B" - } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Move(o => o.SimpleObject.StringProperty, o => o.SimpleObject.AnotherStringProperty); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject>(serialized); - - // Act - deserialized.ApplyTo(doc); - - // Assert - Assert.Equal("A", doc.SimpleObject.AnotherStringProperty); - Assert.Null(doc.SimpleObject.StringProperty); - } - - [Fact] - public void Move_KeepsObjectReference() - { - // Arrange - var sDto = new SimpleObject() - { - StringProperty = "A", - AnotherStringProperty = "B" - }; - var iDto = new InheritedObject() - { - StringProperty = "C", - AnotherStringProperty = "D" - }; - var doc = new SimpleObjectWithNestedObject() - { - SimpleObject = sDto, - InheritedObject = iDto - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Move(o => o.InheritedObject, o => o.SimpleObject); - - // Act - patchDoc.ApplyTo(doc); - - // Assert - Assert.Equal("C", doc.SimpleObject.StringProperty); - Assert.Equal("D", doc.SimpleObject.AnotherStringProperty); - Assert.Same(iDto, doc.SimpleObject); - Assert.Null(doc.InheritedObject); - } - - [Fact] - public void Move_KeepsObjectReferenceWithSerialization() - { - // Arrange - var sDto = new SimpleObject() - { - StringProperty = "A", - AnotherStringProperty = "B" - }; - var iDto = new InheritedObject() - { - StringProperty = "C", - AnotherStringProperty = "D" - }; - var doc = new SimpleObjectWithNestedObject() - { - SimpleObject = sDto, - InheritedObject = iDto - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Move(o => o.InheritedObject, o => o.SimpleObject); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject>(serialized); - - // Act - deserialized.ApplyTo(doc); - - // Assert - Assert.Equal("C", doc.SimpleObject.StringProperty); - Assert.Equal("D", doc.SimpleObject.AnotherStringProperty); - Assert.Same(iDto, doc.SimpleObject); - Assert.Null(doc.InheritedObject); - } - - [Fact] - public void MoveInList() - { - // Arrange - var doc = new SimpleObjectWithNestedObject() - { - SimpleObject = new SimpleObject() - { - IntegerList = new List() { 1, 2, 3 } - } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Move(o => o.SimpleObject.IntegerList, 0, o => o.SimpleObject.IntegerList, 1); - - // Act - patchDoc.ApplyTo(doc); - - // Assert - Assert.Equal(new List() { 2, 1, 3 }, doc.SimpleObject.IntegerList); - } - - [Fact] - public void MoveInListWithSerialization() - { - // Arrange - var doc = new SimpleObjectWithNestedObject() - { - SimpleObject = new SimpleObject() - { - IntegerList = new List() { 1, 2, 3 } - } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Move(o => o.SimpleObject.IntegerList, 0, o => o.SimpleObject.IntegerList, 1); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject>(serialized); - - // Act - deserialized.ApplyTo(doc); - - // Assert - Assert.Equal(new List() { 2, 1, 3 }, doc.SimpleObject.IntegerList); - } - - [Fact] - public void Move_KeepsObjectReferenceInList() - { - // Arrange - var sDto1 = new SimpleObject() { IntegerValue = 1 }; - var sDto2 = new SimpleObject() { IntegerValue = 2 }; - var sDto3 = new SimpleObject() { IntegerValue = 3 }; - var doc = new SimpleObjectWithNestedObject() - { - SimpleObjectList = new List() { - sDto1, - sDto2, - sDto3 - } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Move(o => o.SimpleObjectList, 0, o => o.SimpleObjectList, 1); - - // Act - patchDoc.ApplyTo(doc); - - // Assert - Assert.Equal(new List() { sDto2, sDto1, sDto3 }, doc.SimpleObjectList); - Assert.Equal(2, doc.SimpleObjectList[0].IntegerValue); - Assert.Equal(1, doc.SimpleObjectList[1].IntegerValue); - Assert.Same(sDto2, doc.SimpleObjectList[0]); - Assert.Same(sDto1, doc.SimpleObjectList[1]); - } - - [Fact] - public void Move_KeepsObjectReferenceInListWithSerialization() - { - // Arrange - var sDto1 = new SimpleObject() { IntegerValue = 1 }; - var sDto2 = new SimpleObject() { IntegerValue = 2 }; - var sDto3 = new SimpleObject() { IntegerValue = 3 }; - var doc = new SimpleObjectWithNestedObject() - { - SimpleObjectList = new List() { - sDto1, - sDto2, - sDto3 - } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Move(o => o.SimpleObjectList, 0, o => o.SimpleObjectList, 1); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject>(serialized); - - // Act - patchDoc.ApplyTo(doc); - - // Assert - Assert.Equal(new List() { sDto2, sDto1, sDto3 }, doc.SimpleObjectList); - Assert.Equal(2, doc.SimpleObjectList[0].IntegerValue); - Assert.Equal(1, doc.SimpleObjectList[1].IntegerValue); - Assert.Same(sDto2, doc.SimpleObjectList[0]); - Assert.Same(sDto1, doc.SimpleObjectList[1]); - } - - [Fact] - public void MoveFromListToEndOfList() - { - // Arrange - var doc = new SimpleObjectWithNestedObject() - { - SimpleObject = new SimpleObject() - { - IntegerList = new List() { 1, 2, 3 } - } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Move(o => o.SimpleObject.IntegerList, 0, o => o.SimpleObject.IntegerList); - - // Act - patchDoc.ApplyTo(doc); - - // Assert - Assert.Equal(new List() { 2, 3, 1 }, doc.SimpleObject.IntegerList); - } - - [Fact] - public void MoveFromListToEndOfListWithSerialization() - { - // Arrange - var doc = new SimpleObjectWithNestedObject() - { - SimpleObject = new SimpleObject() - { - IntegerList = new List() { 1, 2, 3 } - } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Move(o => o.SimpleObject.IntegerList, 0, o => o.SimpleObject.IntegerList); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject>(serialized); - - // Act - deserialized.ApplyTo(doc); - - // Assert - Assert.Equal(new List() { 2, 3, 1 }, doc.SimpleObject.IntegerList); - } - - [Fact] - public void MoveFomListToNonList() - { - // Arrange - var doc = new SimpleObjectWithNestedObject() - { - SimpleObject = new SimpleObject() - { - IntegerList = new List() { 1, 2, 3 } - } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Move(o => o.SimpleObject.IntegerList, 0, o => o.SimpleObject.IntegerValue); - - // Act - patchDoc.ApplyTo(doc); - - // Assert - Assert.Equal(new List() { 2, 3 }, doc.SimpleObject.IntegerList); - Assert.Equal(1, doc.SimpleObject.IntegerValue); - } - - [Fact] - public void MoveFomListToNonListWithSerialization() - { - // Arrange - var doc = new SimpleObjectWithNestedObject() - { - SimpleObject = new SimpleObject() - { - IntegerList = new List() { 1, 2, 3 } - } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Move(o => o.SimpleObject.IntegerList, 0, o => o.SimpleObject.IntegerValue); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject>(serialized); - - // Act - deserialized.ApplyTo(doc); - - // Assert - Assert.Equal(new List() { 2, 3 }, doc.SimpleObject.IntegerList); - Assert.Equal(1, doc.SimpleObject.IntegerValue); - } - - [Fact] - public void MoveFomListToNonListBetweenHierarchy() - { - // Arrange - var doc = new SimpleObjectWithNestedObject() - { - SimpleObject = new SimpleObject() - { - IntegerList = new List() { 1, 2, 3 } - } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Move(o => o.SimpleObject.IntegerList, 0, o => o.IntegerValue); - - // Act - patchDoc.ApplyTo(doc); - - // Assert - Assert.Equal(new List() { 2, 3 }, doc.SimpleObject.IntegerList); - Assert.Equal(1, doc.IntegerValue); - } - - [Fact] - public void MoveFomListToNonListBetweenHierarchyWithSerialization() - { - // Arrange - var doc = new SimpleObjectWithNestedObject() - { - SimpleObject = new SimpleObject() - { - IntegerList = new List() { 1, 2, 3 } - } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Move(o => o.SimpleObject.IntegerList, 0, o => o.IntegerValue); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject>(serialized); - - // Act - deserialized.ApplyTo(doc); - - // Assert - Assert.Equal(new List() { 2, 3 }, doc.SimpleObject.IntegerList); - Assert.Equal(1, doc.IntegerValue); - } - - [Fact] - public void MoveFromNonListToList() - { - // Arrange - var doc = new SimpleObjectWithNestedObject() - { - SimpleObject = new SimpleObject() - { - IntegerValue = 5, - IntegerList = new List() { 1, 2, 3 } - } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Move(o => o.SimpleObject.IntegerValue, o => o.SimpleObject.IntegerList, 0); - - // Act - patchDoc.ApplyTo(doc); - - // Assert - Assert.Equal(0, doc.IntegerValue); - Assert.Equal(new List() { 5, 1, 2, 3 }, doc.SimpleObject.IntegerList); - } - - [Fact] - public void MoveFromNonListToListWithSerialization() - { - // Arrange - var doc = new SimpleObjectWithNestedObject() - { - SimpleObject = new SimpleObject() - { - IntegerValue = 5, - IntegerList = new List() { 1, 2, 3 } - } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Move(o => o.SimpleObject.IntegerValue, o => o.SimpleObject.IntegerList, 0); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject>(serialized); - - // Act - deserialized.ApplyTo(doc); - - // Assert - Assert.Equal(0, doc.IntegerValue); - Assert.Equal(new List() { 5, 1, 2, 3 }, doc.SimpleObject.IntegerList); - } - - [Fact] - public void MoveToEndOfList() - { - // Arrange - var doc = new SimpleObjectWithNestedObject() - { - SimpleObject = new SimpleObject() - { - IntegerValue = 5, - IntegerList = new List() { 1, 2, 3 } - } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Move(o => o.SimpleObject.IntegerValue, o => o.SimpleObject.IntegerList); - - // Act - patchDoc.ApplyTo(doc); - - // Assert - Assert.Equal(0, doc.IntegerValue); - Assert.Equal(new List() { 1, 2, 3, 5 }, doc.SimpleObject.IntegerList); - } - - [Fact] - public void MoveToEndOfListWithSerialization() - { - // Arrange - var doc = new SimpleObjectWithNestedObject() - { - SimpleObject = new SimpleObject() - { - IntegerValue = 5, - IntegerList = new List() { 1, 2, 3 } - } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Move(o => o.SimpleObject.IntegerValue, o => o.SimpleObject.IntegerList); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject>(serialized); - - // Act - deserialized.ApplyTo(doc); - - // Assert - Assert.Equal(0, doc.IntegerValue); - Assert.Equal(new List() { 1, 2, 3, 5 }, doc.SimpleObject.IntegerList); - } - } -} diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/ObjectAdapterTests.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/ObjectAdapterTests.cs deleted file mode 100644 index c1d005e897..0000000000 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/ObjectAdapterTests.cs +++ /dev/null @@ -1,2331 +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; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using Microsoft.AspNetCore.JsonPatch.Exceptions; -using Newtonsoft.Json; -using Xunit; - -namespace Microsoft.AspNetCore.JsonPatch.Adapters -{ - public class ObjectAdapterTests - { - [Fact] - public void AddResultsShouldReplace() - { - // Arrange - var doc = new SimpleObject() - { - StringProperty = "A" - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Add(o => o.StringProperty, "B"); - - // Act - patchDoc.ApplyTo(doc); - - // Assert - Assert.Equal("B", doc.StringProperty); - } - - [Fact] - public void AddResultsShouldReplaceWithSerialization() - { - // Arrange - var doc = new SimpleObject() - { - StringProperty = "A" - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Add(o => o.StringProperty, "B"); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject>(serialized); - - // Act - deserialized.ApplyTo(doc); - - // Assert - Assert.Equal("B", doc.StringProperty); - } - - [Fact] - public void AddToList() - { - // Arrange - var doc = new SimpleObject() - { - IntegerList = new List() { 1, 2, 3 } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Add(o => o.IntegerList, 4, 0); - - // Act - patchDoc.ApplyTo(doc); - - // Assert - Assert.Equal(new List() { 4, 1, 2, 3 }, doc.IntegerList); - } - - [Fact] - public void AddToListWithSerialization() - { - // Arrange - var doc = new SimpleObject() - { - IntegerList = new List() { 1, 2, 3 } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Add(o => o.IntegerList, 4, 0); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject>(serialized); - - // Act - deserialized.ApplyTo(doc); - - // Assert - Assert.Equal(new List() { 4, 1, 2, 3 }, doc.IntegerList); - } - - [Fact] - public void AddToIntegerIList() - { - // Arrange - var doc = new SimpleObject() - { - IntegerIList = new List() { 1, 2, 3 } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Add(o => o.IntegerIList, 4, 0); - - // Act - patchDoc.ApplyTo(doc); - - // Assert - Assert.Equal(new List() { 4, 1, 2, 3 }, doc.IntegerIList); - } - - [Fact] - public void AddToIntegerIListWithSerialization() - { - // Arrange - var doc = new SimpleObject() - { - IntegerIList = new List() { 1, 2, 3 } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Add(o => o.IntegerIList, 4, 0); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject>(serialized); - - // Act - deserialized.ApplyTo(doc); - - // Assert - Assert.Equal(new List() { 4, 1, 2, 3 }, doc.IntegerIList); - } - - [Fact] - public void AddToListInvalidPositionTooLarge() - { - // Arrange - var doc = new SimpleObject() - { - IntegerList = new List() { 1, 2, 3 } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Add(o => o.IntegerList, 4, 4); - - // Act & Assert - var exception = Assert.Throws(() => { patchDoc.ApplyTo(doc); }); - Assert.Equal( - string.Format("The index value provided by path segment '{0}' is out of bounds of the array size.", "4"), - exception.Message); - } - - [Fact] - public void AddToListInvalidPositionTooLargeWithSerialization() - { - // Arrange - var doc = new SimpleObject() - { - IntegerList = new List() { 1, 2, 3 } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Add(o => o.IntegerList, 4, 4); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject>(serialized); - - // Act & Assert - var exception = Assert.Throws(() => { deserialized.ApplyTo(doc); }); - Assert.Equal( - string.Format("The index value provided by path segment '{0}' is out of bounds of the array size.", "4"), - exception.Message); - } - - [Fact] - public void AddToListInvalidPositionTooLarge_LogsError() - { - // Arrange - var doc = new SimpleObject() - { - IntegerList = new List() { 1, 2, 3 } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Add(o => o.IntegerList, 4, 4); - - var logger = new TestErrorLogger(); - - patchDoc.ApplyTo(doc, logger.LogErrorMessage); - - - // Assert - Assert.Equal( - string.Format("The index value provided by path segment '{0}' is out of bounds of the array size.", "4"), - logger.ErrorMessage); - } - - [Fact] - public void AddToListAtBeginning() - { - // Arrange - var doc = new SimpleObject() - { - IntegerList = new List() { 1, 2, 3 } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Add(o => o.IntegerList, 4, 0); - - // Act - patchDoc.ApplyTo(doc); - - // Assert - Assert.Equal(new List() { 4, 1, 2, 3 }, doc.IntegerList); - } - - [Fact] - public void AddToListAtBeginningWithSerialization() - { - // Arrange - var doc = new SimpleObject() - { - IntegerList = new List() { 1, 2, 3 } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Add(o => o.IntegerList, 4, 0); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject>(serialized); - - // Act - deserialized.ApplyTo(doc); - - // Assert - Assert.Equal(new List() { 4, 1, 2, 3 }, doc.IntegerList); - } - - [Fact] - public void AddToListInvalidPositionTooSmall() - { - // Arrange - var doc = new SimpleObject() - { - IntegerList = new List() { 1, 2, 3 } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Add(o => o.IntegerList, 4, -1); - - // Act & Assert - var exception = Assert.Throws(() => { patchDoc.ApplyTo(doc); }); - Assert.Equal( - string.Format("The index value provided by path segment '{0}' is out of bounds of the array size.", "-1"), - exception.Message); - } - - [Fact] - public void AddToListInvalidPositionTooSmallWithSerialization() - { - // Arrange - var doc = new SimpleObject() - { - IntegerList = new List() { 1, 2, 3 } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Add(o => o.IntegerList, 4, -1); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject>(serialized); - - // Act & Assert - var exception = Assert.Throws(() => { deserialized.ApplyTo(doc); }); - Assert.Equal( - string.Format("The index value provided by path segment '{0}' is out of bounds of the array size.", "-1"), - exception.Message); - } - - [Fact] - public void AddToListInvalidPositionTooSmall_LogsError() - { - // Arrange - var doc = new SimpleObject() - { - IntegerList = new List() { 1, 2, 3 } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Add(o => o.IntegerList, 4, -1); - - var logger = new TestErrorLogger(); - - patchDoc.ApplyTo(doc, logger.LogErrorMessage); - - // Assert - Assert.Equal( - string.Format("The index value provided by path segment '{0}' is out of bounds of the array size.", "-1"), - logger.ErrorMessage); - } - - [Fact] - public void AddToListAppend() - { - // Arrange - var doc = new SimpleObject() - { - IntegerList = new List() { 1, 2, 3 } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Add(o => o.IntegerList, 4); - - // Act - patchDoc.ApplyTo(doc); - - // Assert - Assert.Equal(new List() { 1, 2, 3, 4 }, doc.IntegerList); - } - - [Fact] - public void AddToListAppendWithSerialization() - { - // Arrange - var doc = new SimpleObject() - { - IntegerList = new List() { 1, 2, 3 } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Add(o => o.IntegerList, 4); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject>(serialized); - - // Act - deserialized.ApplyTo(doc); - - // Assert - Assert.Equal(new List() { 1, 2, 3, 4 }, doc.IntegerList); - } - - [Fact] - public void Remove() - { - // Arrange - var doc = new SimpleObject() - { - StringProperty = "A" - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Remove(o => o.StringProperty); - - // Act - patchDoc.ApplyTo(doc); - - // Assert - Assert.Null(doc.StringProperty); - } - - [Fact] - public void RemoveWithSerialization() - { - // Arrange - var doc = new SimpleObject() - { - StringProperty = "A" - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Remove(o => o.StringProperty); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject>(serialized); - - // Act - deserialized.ApplyTo(doc); - - // Assert - Assert.Null(doc.StringProperty); - } - - [Fact] - public void RemoveFromList() - { - // Arrange - var doc = new SimpleObject() - { - IntegerList = new List() { 1, 2, 3 } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Remove(o => o.IntegerList, 2); - - // Act - patchDoc.ApplyTo(doc); - - // Assert - Assert.Equal(new List() { 1, 2 }, doc.IntegerList); - } - - [Fact] - public void RemoveFromListWithSerialization() - { - // Arrange - var doc = new SimpleObject() - { - IntegerList = new List() { 1, 2, 3 } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Remove(o => o.IntegerList, 2); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject>(serialized); - - // Act - deserialized.ApplyTo(doc); - - // Assert - Assert.Equal(new List() { 1, 2 }, doc.IntegerList); - } - - [Fact] - public void RemoveFromListInvalidPositionTooLarge() - { - // Arrange - var doc = new SimpleObject() - { - IntegerList = new List() { 1, 2, 3 } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Remove(o => o.IntegerList, 3); - - // Act & Assert - var exception = Assert.Throws(() => { patchDoc.ApplyTo(doc); }); - Assert.Equal( - string.Format("The index value provided by path segment '{0}' is out of bounds of the array size.", "3"), - exception.Message); - } - - [Fact] - public void RemoveFromListInvalidPositionTooLargeWithSerialization() - { - // Arrange - var doc = new SimpleObject() - { - IntegerList = new List() { 1, 2, 3 } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Remove(o => o.IntegerList, 3); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject>(serialized); - - // Act & Assert - var exception = Assert.Throws(() => { deserialized.ApplyTo(doc); }); - Assert.Equal( - string.Format("The index value provided by path segment '{0}' is out of bounds of the array size.", "3"), - exception.Message); - } - - [Fact] - public void RemoveFromListInvalidPositionTooLarge_LogsError() - { - // Arrange - var doc = new SimpleObject() - { - IntegerList = new List() { 1, 2, 3 } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Remove(o => o.IntegerList, 3); - - var logger = new TestErrorLogger(); - - patchDoc.ApplyTo(doc, logger.LogErrorMessage); - - - // Assert - Assert.Equal( - string.Format("The index value provided by path segment '{0}' is out of bounds of the array size.", "3"), - logger.ErrorMessage); - } - - [Fact] - public void RemoveFromListInvalidPositionTooSmall() - { - // Arrange - var doc = new SimpleObject() - { - IntegerList = new List() { 1, 2, 3 } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Remove(o => o.IntegerList, -1); - - // Act & Assert - var exception = Assert.Throws(() => { patchDoc.ApplyTo(doc); }); - Assert.Equal( - string.Format("The index value provided by path segment '{0}' is out of bounds of the array size.", "-1"), - exception.Message); - } - - [Fact] - public void RemoveFromListInvalidPositionTooSmallWithSerialization() - { - // Arrange - var doc = new SimpleObject() - { - IntegerList = new List() { 1, 2, 3 } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Remove(o => o.IntegerList, -1); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject>(serialized); - - // Act & Assert - var exception = Assert.Throws(() => { deserialized.ApplyTo(doc); }); - Assert.Equal( - string.Format("The index value provided by path segment '{0}' is out of bounds of the array size.", "-1"), - exception.Message); - } - - [Fact] - public void RemoveFromListInvalidPositionTooSmall_LogsError() - { - // Arrange - var doc = new SimpleObject() - { - IntegerList = new List() { 1, 2, 3 } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Remove(o => o.IntegerList, -1); - - var logger = new TestErrorLogger(); - - - patchDoc.ApplyTo(doc, logger.LogErrorMessage); - - - // Assert - Assert.Equal( - string.Format("The index value provided by path segment '{0}' is out of bounds of the array size.", "-1"), - logger.ErrorMessage); - } - - [Fact] - public void RemoveFromEndOfList() - { - // Arrange - var doc = new SimpleObject() - { - IntegerList = new List() { 1, 2, 3 } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Remove(o => o.IntegerList); - - // Act - patchDoc.ApplyTo(doc); - - // Assert - Assert.Equal(new List() { 1, 2 }, doc.IntegerList); - } - - [Fact] - public void RemoveFromEndOfListWithSerialization() - { - // Arrange - var doc = new SimpleObject() - { - IntegerList = new List() { 1, 2, 3 } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Remove(o => o.IntegerList); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject>(serialized); - - // Act - deserialized.ApplyTo(doc); - - // Assert - Assert.Equal(new List() { 1, 2 }, doc.IntegerList); - } - - [Fact] - public void Replace() - { - // Arrange - var doc = new SimpleObject() - { - StringProperty = "A", - DecimalValue = 10 - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Replace(o => o.StringProperty, "B"); - - patchDoc.Replace(o => o.DecimalValue, 12); - - // Act - patchDoc.ApplyTo(doc); - - // Assert - Assert.Equal("B", doc.StringProperty); - Assert.Equal(12, doc.DecimalValue); - } - - [Fact] - public void Replace_DTOWithNullCheck() - { - // Arrange - var doc = new SimpleObjectWithNullCheck() - { - StringProperty = "A", - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Replace(o => o.StringProperty, "B"); - - // Act - patchDoc.ApplyTo(doc); - - // Assert - Assert.Equal("B", doc.StringProperty); - } - - [Fact] - public void ReplaceWithSerialization() - { - // Arrange - var doc = new SimpleObject() - { - StringProperty = "A", - DecimalValue = 10 - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Replace(o => o.StringProperty, "B"); - - patchDoc.Replace(o => o.DecimalValue, 12); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject>(serialized); - - // Act - deserialized.ApplyTo(doc); - - // Assert - Assert.Equal("B", doc.StringProperty); - Assert.Equal(12, doc.DecimalValue); - } - - [Fact] - public void SerializationMustNotIncudeEnvelope() - { - // Arrange - var doc = new SimpleObject() - { - StringProperty = "A", - DecimalValue = 10, - DoubleValue = 10, - FloatValue = 10, - IntegerValue = 10 - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Replace(o => o.StringProperty, "B"); - patchDoc.Replace(o => o.DecimalValue, 12); - patchDoc.Replace(o => o.DoubleValue, 12); - patchDoc.Replace(o => o.FloatValue, 12); - patchDoc.Replace(o => o.IntegerValue, 12); - - // Act - var serialized = JsonConvert.SerializeObject(patchDoc); - - // Assert - Assert.DoesNotContain("operations", serialized); - Assert.DoesNotContain("Operations", serialized); - } - - [Fact] - public void Deserialization_Successful_ForValidJsonPatchDocument() - { - // Arrange - var doc = new SimpleObject() - { - StringProperty = "A", - DecimalValue = 10, - DoubleValue = 10, - FloatValue = 10, - IntegerValue = 10 - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Replace(o => o.StringProperty, "B"); - patchDoc.Replace(o => o.DecimalValue, 12); - patchDoc.Replace(o => o.DoubleValue, 12); - patchDoc.Replace(o => o.FloatValue, 12); - patchDoc.Replace(o => o.IntegerValue, 12); - - // default: no envelope - var serialized = JsonConvert.SerializeObject(patchDoc); - - // Act - var deserialized = JsonConvert.DeserializeObject>(serialized); - - // Assert - Assert.IsType>(deserialized); - } - - [Fact] - public void Deserialization_Fails_ForInvalidJsonPatchDocument() - { - // Arrange - var serialized = "{\"Operations\": [{ \"op\": \"replace\", \"path\": \"/title\", \"value\": \"New Title\"}]}"; - - // Act & Assert - var exception = Assert.Throws(() => - { - var deserialized - = JsonConvert.DeserializeObject(serialized); - }); - - Assert.Equal("The JSON patch document was malformed and could not be parsed.", exception.Message); - } - - [Fact] - public void Deserialization_Fails_ForInvalidTypedJsonPatchDocument() - { - // Arrange - var serialized = "{\"Operations\": [{ \"op\": \"replace\", \"path\": \"/title\", \"value\": \"New Title\"}]}"; - - // Act & Assert - var exception = Assert.Throws(() => - { - var deserialized - = JsonConvert.DeserializeObject>(serialized); - }); - - Assert.Equal("The JSON patch document was malformed and could not be parsed.", exception.Message); - } - - [Fact] - public void SerializationTests() - { - // Arrange - var doc = new SimpleObject() - { - StringProperty = "A", - DecimalValue = 10, - DoubleValue = 10, - FloatValue = 10, - IntegerValue = 10 - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Replace(o => o.StringProperty, "B"); - patchDoc.Replace(o => o.DecimalValue, 12); - patchDoc.Replace(o => o.DoubleValue, 12); - patchDoc.Replace(o => o.FloatValue, 12); - patchDoc.Replace(o => o.IntegerValue, 12); - - // serialize & deserialize - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserizalized = JsonConvert.DeserializeObject>(serialized); - - // Act - deserizalized.ApplyTo(doc); - - // Assert - Assert.Equal("B", doc.StringProperty); - Assert.Equal(12, doc.DecimalValue); - Assert.Equal(12, doc.DoubleValue); - Assert.Equal(12, doc.FloatValue); - Assert.Equal(12, doc.IntegerValue); - } - - [Fact] - public void SerializeAndReplaceGuidTest() - { - // Arrange - var doc = new SimpleObject() - { - GuidValue = Guid.NewGuid() - }; - - var newGuid = Guid.NewGuid(); - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Replace(o => o.GuidValue, newGuid); - - // serialize & deserialize - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserizalized = JsonConvert.DeserializeObject>(serialized); - - // Act - deserizalized.ApplyTo(doc); - - // Assert - Assert.Equal(newGuid, doc.GuidValue); - } - - [Fact] - public void SerializeAndReplaceNestedObjectTest() - { - // Arrange - var doc = new SimpleObjectWithNestedObject() - { - SimpleObject = new SimpleObject() - { - IntegerValue = 5, - IntegerList = new List() { 1, 2, 3 } - } - }; - - var newDTO = new SimpleObject() - { - DoubleValue = 1 - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Replace(o => o.SimpleObject, newDTO); - - // serialize & deserialize - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject>(serialized); - - // Act - deserialized.ApplyTo(doc); - - // Assert - Assert.Equal(1, doc.SimpleObject.DoubleValue); - Assert.Equal(0, doc.SimpleObject.IntegerValue); - Assert.Null(doc.SimpleObject.IntegerList); - } - - [Fact] - public void ReplaceInList() - { - // Arrange - var doc = new SimpleObject() - { - IntegerList = new List() { 1, 2, 3 } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Replace(o => o.IntegerList, 5, 0); - - // Act - patchDoc.ApplyTo(doc); - - // Assert - Assert.Equal(new List() { 5, 2, 3 }, doc.IntegerList); - } - - [Fact] - public void ReplaceInListWithSerialization() - { - // Arrange - var doc = new SimpleObject() - { - IntegerList = new List() { 1, 2, 3 } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Replace(o => o.IntegerList, 5, 0); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject>(serialized); - - // Act - deserialized.ApplyTo(doc); - - // Assert - Assert.Equal(new List() { 5, 2, 3 }, doc.IntegerList); - } - - [Fact] - public void ReplaceFullList() - { - // Arrange - var doc = new SimpleObject() - { - IntegerList = new List() { 1, 2, 3 } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Replace>(o => o.IntegerList, new List() { 4, 5, 6 }); - - // Act - patchDoc.ApplyTo(doc); - - // Assert - Assert.Equal(new List() { 4, 5, 6 }, doc.IntegerList); - } - - [Fact] - public void ReplaceFullListWithSerialization() - { - // Arrange - var doc = new SimpleObject() - { - IntegerList = new List() { 1, 2, 3 } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Replace>(o => o.IntegerList, new List() { 4, 5, 6 }); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject>(serialized); - - // Act - deserialized.ApplyTo(doc); - - // Assert - Assert.Equal(new List() { 4, 5, 6 }, doc.IntegerList); - } - - [Fact] - public void ReplaceFullListFromEnumerable() - { - // Arrange - var doc = new SimpleObject() - { - IntegerList = new List() { 1, 2, 3 } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Replace>(o => o.IntegerList, new List() { 4, 5, 6 }); - - // Act - patchDoc.ApplyTo(doc); - - // Assert - Assert.Equal(new List() { 4, 5, 6 }, doc.IntegerList); - } - - [Fact] - public void ReplaceFullListFromEnumerableWithSerialization() - { - // Arrange - var doc = new SimpleObject() - { - IntegerList = new List() { 1, 2, 3 } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Replace>(o => o.IntegerList, new List() { 4, 5, 6 }); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject>(serialized); - - // Act - deserialized.ApplyTo(doc); - - // Assert - Assert.Equal(new List() { 4, 5, 6 }, doc.IntegerList); - } - - [Fact] - public void ReplaceFullListWithCollection() - { - // Arrange - var doc = new SimpleObject() - { - IntegerList = new List() { 1, 2, 3 } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Replace>(o => o.IntegerList, new Collection() { 4, 5, 6 }); - - // Act - patchDoc.ApplyTo(doc); - - // Assert - Assert.Equal(new List() { 4, 5, 6 }, doc.IntegerList); - } - - [Fact] - public void ReplaceFullListWithCollectionWithSerialization() - { - // Arrange - var doc = new SimpleObject() - { - IntegerList = new List() { 1, 2, 3 } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Replace>(o => o.IntegerList, new Collection() { 4, 5, 6 }); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject>(serialized); - - // Act - deserialized.ApplyTo(doc); - - // Assert - Assert.Equal(new List() { 4, 5, 6 }, doc.IntegerList); - } - - [Fact] - public void ReplaceAtEndOfList() - { - // Arrange - var doc = new SimpleObject() - { - IntegerList = new List() { 1, 2, 3 } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Replace(o => o.IntegerList, 5); - - // Act - patchDoc.ApplyTo(doc); - - // Assert - Assert.Equal(new List() { 1, 2, 5 }, doc.IntegerList); - } - - [Fact] - public void ReplaceAtEndOfListWithSerialization() - { - // Arrange - var doc = new SimpleObject() - { - IntegerList = new List() { 1, 2, 3 } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Replace(o => o.IntegerList, 5); - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject>(serialized); - - // Act - deserialized.ApplyTo(doc); - - // Assert - Assert.Equal(new List() { 1, 2, 5 }, doc.IntegerList); - } - - [Fact] - public void ReplaceInListInvalidInvalidPositionTooLarge() - { - // Arrange - var doc = new SimpleObject() - { - IntegerList = new List() { 1, 2, 3 } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Replace(o => o.IntegerList, 5, 3); - - // Act & Assert - var exception = Assert.Throws(() => - { - patchDoc.ApplyTo(doc); - }); - Assert.Equal( - string.Format("The index value provided by path segment '{0}' is out of bounds of the array size.", "3"), - exception.Message); - } - - [Fact] - public void ReplaceInListInvalidInvalidPositionTooLargeWithSerialization() - { - // Arrange - var doc = new SimpleObject() - { - IntegerList = new List() { 1, 2, 3 } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Replace(o => o.IntegerList, 5, 3); - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject>(serialized); - - // Act & Assert - var exception = Assert.Throws(() => - { - deserialized.ApplyTo(doc); - }); - Assert.Equal( - string.Format("The index value provided by path segment '{0}' is out of bounds of the array size.", "3"), - exception.Message); - } - - [Fact] - public void ReplaceInListInvalidPositionTooSmall() - { - // Arrange - var doc = new SimpleObject() - { - IntegerList = new List() { 1, 2, 3 } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Replace(o => o.IntegerList, 5, -1); - - // Act & Assert - var exception = Assert.Throws(() => - { - patchDoc.ApplyTo(doc); - }); - Assert.Equal( - string.Format("The index value provided by path segment '{0}' is out of bounds of the array size.", "-1"), - exception.Message); - } - - [Fact] - public void ReplaceInListInvalidPositionTooSmallWithSerialization() - { - // Arrange - var doc = new SimpleObject() - { - IntegerList = new List() { 1, 2, 3 } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Replace(o => o.IntegerList, 5, -1); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject>(serialized); - - // Act & Assert - var exception = Assert.Throws(() => - { - deserialized.ApplyTo(doc); - }); - Assert.Equal( - string.Format("The index value provided by path segment '{0}' is out of bounds of the array size.", "-1"), - exception.Message); - } - - [Fact] - public void Copy() - { - // Arrange - var doc = new SimpleObject() - { - StringProperty = "A", - AnotherStringProperty = "B" - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Copy(o => o.StringProperty, o => o.AnotherStringProperty); - - // Act - patchDoc.ApplyTo(doc); - - // Assert - Assert.Equal("A", doc.AnotherStringProperty); - } - - [Fact] - public void CopyWithSerialization() - { - // Arrange - var doc = new SimpleObject() - { - StringProperty = "A", - AnotherStringProperty = "B" - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Copy(o => o.StringProperty, o => o.AnotherStringProperty); - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject>(serialized); - - // Act - deserialized.ApplyTo(doc); - - // Assert - Assert.Equal("A", doc.AnotherStringProperty); - } - - [Fact] - public void CopyInList() - { - // Arrange - var doc = new SimpleObject() - { - IntegerList = new List() { 1, 2, 3 } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Copy(o => o.IntegerList, 0, o => o.IntegerList, 1); - - // Act - patchDoc.ApplyTo(doc); - - // Assert - Assert.Equal(new List() { 1, 1, 2, 3 }, doc.IntegerList); - } - - [Fact] - public void CopyInListWithSerialization() - { - // Arrange - var doc = new SimpleObject() - { - IntegerList = new List() { 1, 2, 3 } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Copy(o => o.IntegerList, 0, o => o.IntegerList, 1); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject>(serialized); - - // Act - deserialized.ApplyTo(doc); - - // Assert - Assert.Equal(new List() { 1, 1, 2, 3 }, doc.IntegerList); - } - - [Fact] - public void CopyFromListToEndOfList() - { - // Arrange - var doc = new SimpleObject() - { - IntegerList = new List() { 1, 2, 3 } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Copy(o => o.IntegerList, 0, o => o.IntegerList); - - // Act - patchDoc.ApplyTo(doc); - - // Assert - Assert.Equal(new List() { 1, 2, 3, 1 }, doc.IntegerList); - } - - [Fact] - public void CopyFromListToEndOfListWithSerialization() - { - // Arrange - var doc = new SimpleObject() - { - IntegerList = new List() { 1, 2, 3 } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Copy(o => o.IntegerList, 0, o => o.IntegerList); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject>(serialized); - - // Act - deserialized.ApplyTo(doc); - - // Assert - Assert.Equal(new List() { 1, 2, 3, 1 }, doc.IntegerList); - } - - [Fact] - public void CopyFromListToNonList() - { - // Arrange - var doc = new SimpleObject() - { - IntegerList = new List() { 1, 2, 3 } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Copy(o => o.IntegerList, 0, o => o.IntegerValue); - - // Act - patchDoc.ApplyTo(doc); - - // Assert - Assert.Equal(1, doc.IntegerValue); - } - - [Fact] - public void CopyFromListToNonListWithSerialization() - { - // Arrange - var doc = new SimpleObject() - { - IntegerList = new List() { 1, 2, 3 } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Copy(o => o.IntegerList, 0, o => o.IntegerValue); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject>(serialized); - - // Act - deserialized.ApplyTo(doc); - - // Assert - Assert.Equal(1, doc.IntegerValue); - } - - [Fact] - public void CopyFromNonListToList() - { - // Arrange - var doc = new SimpleObject() - { - IntegerValue = 5, - IntegerList = new List() { 1, 2, 3 } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Copy(o => o.IntegerValue, o => o.IntegerList, 0); - - // Act - patchDoc.ApplyTo(doc); - - // Assert - Assert.Equal(new List() { 5, 1, 2, 3 }, doc.IntegerList); - } - - [Fact] - public void CopyFromNonListToListWithSerialization() - { - // Arrange - var doc = new SimpleObject() - { - IntegerValue = 5, - IntegerList = new List() { 1, 2, 3 } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Copy(o => o.IntegerValue, o => o.IntegerList, 0); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject>(serialized); - - // Act - deserialized.ApplyTo(doc); - - // Assert - Assert.Equal(new List() { 5, 1, 2, 3 }, doc.IntegerList); - } - - [Fact] - public void CopyToEndOfList() - { - // Arrange - var doc = new SimpleObject() - { - IntegerValue = 5, - IntegerList = new List() { 1, 2, 3 } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Copy(o => o.IntegerValue, o => o.IntegerList); - - // Act - patchDoc.ApplyTo(doc); - - // Assert - Assert.Equal(new List() { 1, 2, 3, 5 }, doc.IntegerList); - } - - [Fact] - public void CopyToEndOfListWithSerialization() - { - // Arrange - var doc = new SimpleObject() - { - IntegerValue = 5, - IntegerList = new List() { 1, 2, 3 } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Copy(o => o.IntegerValue, o => o.IntegerList); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject>(serialized); - - // Act - deserialized.ApplyTo(doc); - - // Assert - Assert.Equal(new List() { 1, 2, 3, 5 }, doc.IntegerList); - } - - [Fact] - public void Move() - { - // Arrange - var doc = new SimpleObject() - { - StringProperty = "A", - AnotherStringProperty = "B" - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Move(o => o.StringProperty, o => o.AnotherStringProperty); - - // Act - patchDoc.ApplyTo(doc); - - // Assert - Assert.Equal("A", doc.AnotherStringProperty); - Assert.Null(doc.StringProperty); - } - - [Fact] - public void MoveWithSerialization() - { - // Arrange - var doc = new SimpleObject() - { - StringProperty = "A", - AnotherStringProperty = "B" - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Move(o => o.StringProperty, o => o.AnotherStringProperty); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject>(serialized); - - // Act - deserialized.ApplyTo(doc); - - // Assert - Assert.Equal("A", doc.AnotherStringProperty); - Assert.Null(doc.StringProperty); - } - - [Fact] - public void MoveInList() - { - // Arrange - var doc = new SimpleObject() - { - IntegerList = new List() { 1, 2, 3 } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Move(o => o.IntegerList, 0, o => o.IntegerList, 1); - - // Act - patchDoc.ApplyTo(doc); - - // Assert - Assert.Equal(new List() { 2, 1, 3 }, doc.IntegerList); - } - - [Fact] - public void MoveInListWithSerialization() - { - // Arrange - var doc = new SimpleObject() - { - IntegerList = new List() { 1, 2, 3 } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Move(o => o.IntegerList, 0, o => o.IntegerList, 1); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject>(serialized); - - // Act - deserialized.ApplyTo(doc); - - // Assert - Assert.Equal(new List() { 2, 1, 3 }, doc.IntegerList); - } - - [Fact] - public void MoveFromListToEndOfList() - { - // Arrange - var doc = new SimpleObject() - { - IntegerList = new List() { 1, 2, 3 } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Move(o => o.IntegerList, 0, o => o.IntegerList); - - // Act - patchDoc.ApplyTo(doc); - - // Assert - Assert.Equal(new List() { 2, 3, 1 }, doc.IntegerList); - } - - [Fact] - public void MoveFromListToEndOfListWithSerialization() - { - // Arrange - var doc = new SimpleObject() - { - IntegerList = new List() { 1, 2, 3 } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Move(o => o.IntegerList, 0, o => o.IntegerList); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject>(serialized); - - // Act - deserialized.ApplyTo(doc); - - // Assert - Assert.Equal(new List() { 2, 3, 1 }, doc.IntegerList); - } - - [Fact] - public void MoveFomListToNonList() - { - // Arrange - var doc = new SimpleObject() - { - IntegerList = new List() { 1, 2, 3 } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Move(o => o.IntegerList, 0, o => o.IntegerValue); - - // Act - patchDoc.ApplyTo(doc); - - // Assert - Assert.Equal(new List() { 2, 3 }, doc.IntegerList); - Assert.Equal(1, doc.IntegerValue); - } - - [Fact] - public void MoveFomListToNonListWithSerialization() - { - // Arrange - var doc = new SimpleObject() - { - IntegerList = new List() { 1, 2, 3 } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Move(o => o.IntegerList, 0, o => o.IntegerValue); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject>(serialized); - - // Act - deserialized.ApplyTo(doc); - - // Assert - Assert.Equal(new List() { 2, 3 }, doc.IntegerList); - Assert.Equal(1, doc.IntegerValue); - } - - [Fact] - public void MoveFromNonListToList() - { - // Arrange - var doc = new SimpleObject() - { - IntegerValue = 5, - IntegerList = new List() { 1, 2, 3 } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Move(o => o.IntegerValue, o => o.IntegerList, 0); - - // Act - patchDoc.ApplyTo(doc); - - // Assert - Assert.Equal(0, doc.IntegerValue); - Assert.Equal(new List() { 5, 1, 2, 3 }, doc.IntegerList); - } - - [Fact] - public void MoveFromNonListToListWithSerialization() - { - // Arrange - var doc = new SimpleObject() - { - IntegerValue = 5, - IntegerList = new List() { 1, 2, 3 } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Move(o => o.IntegerValue, o => o.IntegerList, 0); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject>(serialized); - - // Act - deserialized.ApplyTo(doc); - - // Assert - Assert.Equal(0, doc.IntegerValue); - Assert.Equal(new List() { 5, 1, 2, 3 }, doc.IntegerList); - } - - [Fact] - public void MoveToEndOfList() - { - // Arrange - var doc = new SimpleObject() - { - IntegerValue = 5, - IntegerList = new List() { 1, 2, 3 } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Move(o => o.IntegerValue, o => o.IntegerList); - - // Act - patchDoc.ApplyTo(doc); - - // Assert - Assert.Equal(0, doc.IntegerValue); - Assert.Equal(new List() { 1, 2, 3, 5 }, doc.IntegerList); - } - - [Fact] - public void MoveToEndOfListWithSerialization() - { - // Arrange - var doc = new SimpleObject() - { - IntegerValue = 5, - IntegerList = new List() { 1, 2, 3 } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Move(o => o.IntegerValue, o => o.IntegerList); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject>(serialized); - - // Act - deserialized.ApplyTo(doc); - - // Assert - Assert.Equal(0, doc.IntegerValue); - Assert.Equal(new List() { 1, 2, 3, 5 }, doc.IntegerList); - } - - private class Class6 - { - public IDictionary DictionaryOfStringToInteger { get; } = new Dictionary(); - } - - [Fact] - public void Add_WhenDictionary_ValueIsNonObject_Succeeds() - { - // Arrange - var model = new Class6(); - model.DictionaryOfStringToInteger["one"] = 1; - model.DictionaryOfStringToInteger["two"] = 2; - var patchDocument = new JsonPatchDocument(); - patchDocument.Add("/DictionaryOfStringToInteger/three", 3); - - // Act - patchDocument.ApplyTo(model); - - // Assert - Assert.Equal(3, model.DictionaryOfStringToInteger.Count); - Assert.Equal(1, model.DictionaryOfStringToInteger["one"]); - Assert.Equal(2, model.DictionaryOfStringToInteger["two"]); - Assert.Equal(3, model.DictionaryOfStringToInteger["three"]); - } - - [Fact] - public void Remove_WhenDictionary_ValueIsNonObject_Succeeds() - { - // Arrange - var model = new Class6(); - model.DictionaryOfStringToInteger["one"] = 1; - model.DictionaryOfStringToInteger["two"] = 2; - var patchDocument = new JsonPatchDocument(); - patchDocument.Remove("/DictionaryOfStringToInteger/two"); - - // Act - patchDocument.ApplyTo(model); - - // Assert - Assert.Equal(1, model.DictionaryOfStringToInteger.Count); - Assert.Equal(1, model.DictionaryOfStringToInteger["one"]); - } - - [Fact] - public void Replace_WhenDictionary_ValueIsNonObject_Succeeds() - { - // Arrange - var model = new Class6(); - model.DictionaryOfStringToInteger["one"] = 1; - model.DictionaryOfStringToInteger["two"] = 2; - var patchDocument = new JsonPatchDocument(); - patchDocument.Replace("/DictionaryOfStringToInteger/two", 20); - - // Act - patchDocument.ApplyTo(model); - - // Assert - Assert.Equal(2, model.DictionaryOfStringToInteger.Count); - Assert.Equal(1, model.DictionaryOfStringToInteger["one"]); - Assert.Equal(20, model.DictionaryOfStringToInteger["two"]); - } - - private class Customer - { - public string Name { get; set; } - public Address Address { get; set; } - } - - private class Address - { - public string City { get; set; } - } - - private class Class8 - { - public IDictionary DictionaryOfStringToCustomer { get; } = new Dictionary(); - } - - [Fact] - public void Replace_WhenDictionary_ValueAPocoType_Succeeds() - { - // Arrange - var key1 = "key1"; - var value1 = new Customer() { Name = "Jamesss" }; - var key2 = "key2"; - var value2 = new Customer() { Name = "Mike" }; - var model = new Class8(); - model.DictionaryOfStringToCustomer[key1] = value1; - model.DictionaryOfStringToCustomer[key2] = value2; - var patchDocument = new JsonPatchDocument(); - patchDocument.Replace($"/DictionaryOfStringToCustomer/{key1}/Name", "James"); - - // Act - patchDocument.ApplyTo(model); - - // Assert - Assert.Equal(2, model.DictionaryOfStringToCustomer.Count); - var actualValue1 = model.DictionaryOfStringToCustomer[key1]; - Assert.NotNull(actualValue1); - Assert.Equal("James", actualValue1.Name); - } - - [Fact] - public void Replace_WhenDictionary_ValueAPocoType_Succeeds_WithSerialization() - { - // Arrange - var key1 = "key1"; - var value1 = new Customer() { Name = "Jamesss" }; - var key2 = "key2"; - var value2 = new Customer() { Name = "Mike" }; - var model = new Class8(); - model.DictionaryOfStringToCustomer[key1] = value1; - model.DictionaryOfStringToCustomer[key2] = value2; - var patchDocument = new JsonPatchDocument(); - patchDocument.Replace($"/DictionaryOfStringToCustomer/{key1}/Name", "James"); - var serialized = JsonConvert.SerializeObject(patchDocument); - var deserialized = JsonConvert.DeserializeObject>(serialized); - - // Act - patchDocument.ApplyTo(model); - - // Assert - Assert.Equal(2, model.DictionaryOfStringToCustomer.Count); - var actualValue1 = model.DictionaryOfStringToCustomer[key1]; - Assert.NotNull(actualValue1); - Assert.Equal("James", actualValue1.Name); - } - - [Fact] - public void Replace_WhenDictionary_ValueAPocoType_WithEscaping_Succeeds() - { - // Arrange - var key1 = "Foo/Name"; - var value1 = new Customer() { Name = "Jamesss" }; - var key2 = "Foo"; - var value2 = new Customer() { Name = "Mike" }; - var model = new Class8(); - model.DictionaryOfStringToCustomer[key1] = value1; - model.DictionaryOfStringToCustomer[key2] = value2; - var patchDocument = new JsonPatchDocument(); - patchDocument.Replace($"/DictionaryOfStringToCustomer/Foo~1Name/Name", "James"); - - // Act - patchDocument.ApplyTo(model); - - // Assert - Assert.Equal(2, model.DictionaryOfStringToCustomer.Count); - var actualValue1 = model.DictionaryOfStringToCustomer[key1]; - var actualValue2 = model.DictionaryOfStringToCustomer[key2]; - Assert.NotNull(actualValue1); - Assert.Equal("James", actualValue1.Name); - Assert.Equal("Mike", actualValue2.Name); - - } - - [Fact] - public void Replace_DeepNested_DictionaryValue_Succeeds() - { - // Arrange - var key1 = "key1"; - var value1 = new Customer() { Name = "Jamesss" }; - var key2 = "key2"; - var value2 = new Customer() { Name = "Mike" }; - var model = new Class8(); - model.DictionaryOfStringToCustomer[key1] = value1; - model.DictionaryOfStringToCustomer[key2] = value2; - var patchDocument = new JsonPatchDocument(); - patchDocument.Replace($"/DictionaryOfStringToCustomer/{key1}/Name", "James"); - - // Act - patchDocument.ApplyTo(model); - - // Assert - Assert.Equal(2, model.DictionaryOfStringToCustomer.Count); - var actualValue1 = model.DictionaryOfStringToCustomer[key1]; - Assert.NotNull(actualValue1); - Assert.Equal("James", actualValue1.Name); - } - - [Fact] - public void Replace_DeepNested_DictionaryValue_Succeeds_WithSerialization() - { - // Arrange - var key1 = "key1"; - var value1 = new Customer() { Name = "James", Address = new Address { City = "Redmond" } }; - var key2 = "key2"; - var value2 = new Customer() { Name = "Mike", Address = new Address { City = "Seattle" } }; - var model = new Class8(); - model.DictionaryOfStringToCustomer[key1] = value1; - model.DictionaryOfStringToCustomer[key2] = value2; - var patchDocument = new JsonPatchDocument(); - patchDocument.Replace($"/DictionaryOfStringToCustomer/{key1}/Address/City", "Bellevue"); - var serialized = JsonConvert.SerializeObject(patchDocument); - var deserialized = JsonConvert.DeserializeObject>(serialized); - - // Act - patchDocument.ApplyTo(model); - - // Assert - Assert.Equal(2, model.DictionaryOfStringToCustomer.Count); - var actualValue1 = model.DictionaryOfStringToCustomer[key1]; - Assert.NotNull(actualValue1); - Assert.Equal("James", actualValue1.Name); - var address = actualValue1.Address; - Assert.NotNull(address); - Assert.Equal("Bellevue", address.City); - } - - class Class9 - { - public List StringList { get; set; } = new List(); - } - - [Fact] - public void AddToNonIntegerListAtEnd() - { - // Arrange - var model = new Class9() - { - StringList = new List() - }; - model.StringList.Add("string1"); - model.StringList.Add("string2"); - var patchDoc = new JsonPatchDocument(); - patchDoc.Add("/StringList/0", "string3"); - - // Act - patchDoc.ApplyTo(model); - - // Assert - Assert.Equal(new List() { "string3", "string1", "string2" }, model.StringList); - } - - [Fact] - public void AddMember_OnPOCO_WithNullPropertyValue_ShouldAddPropertyValue() - { - // Arrange - var doc = new SimpleObject() - { - StringProperty = null - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Add(o => o.StringProperty, "B"); - - // Act - patchDoc.ApplyTo(doc); - - // Assert - Assert.Equal("B", doc.StringProperty); - } - - private class Class1 - { - public IDictionary USStates { get; set; } = new Dictionary(); - } - - [Fact] - public void AddMember_OnDictionaryProperty_ShouldAddKeyValueMember() - { - // Arrange - var expected = "Washington"; - var model = new Class1(); - var patchDoc = new JsonPatchDocument(); - patchDoc.Add("/USStates/WA", expected); - - // Act - patchDoc.ApplyTo(model); - - // Assert - Assert.Equal(1, model.USStates.Count); - Assert.Equal(expected, model.USStates["WA"]); - } - - [Fact] - public void AddMember_OnDictionaryProperty_ShouldAddKeyValueMember_WithSerialization() - { - // Arrange - var expected = "Washington"; - var model = new Class1(); - var patchDoc = new JsonPatchDocument(); - patchDoc.Add("/USStates/WA", expected); - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject>(serialized); - - // Act - deserialized.ApplyTo(model); - - // Assert - Assert.Equal(1, model.USStates.Count); - Assert.Equal(expected, model.USStates["WA"]); - } - - private class Class2 - { - public Class1 Class1Property { get; set; } = new Class1(); - } - - [Fact] - public void AddMember_OnDictionaryPropertyDeeplyNested_ShouldAddKeyValueMember() - { - // Arrange - var expected = "Washington"; - var model = new Class2(); - var patchDoc = new JsonPatchDocument(); - patchDoc.Add("/Class1Property/USStates/WA", expected); - - // Act - patchDoc.ApplyTo(model); - - // Assert - Assert.Equal(1, model.Class1Property.USStates.Count); - Assert.Equal(expected, model.Class1Property.USStates["WA"]); - } - - [Fact] - public void AddMember_OnDictionaryPropertyDeeplyNested_ShouldAddKeyValueMember_WithSerialization() - { - // Arrange - var expected = "Washington"; - var model = new Class2(); - var patchDoc = new JsonPatchDocument(); - patchDoc.Add("/Class1Property/USStates/WA", expected); - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject>(serialized); - - // Act - deserialized.ApplyTo(model); - - // Assert - Assert.Equal(1, model.Class1Property.USStates.Count); - Assert.Equal(expected, model.Class1Property.USStates["WA"]); - } - - [Fact] - public void AddMember_OnDictionaryObjectDirectly_ShouldAddKeyValueMember() - { - // Arrange - var expected = "Washington"; - var model = new Dictionary(); - var patchDoc = new JsonPatchDocument(); - patchDoc.Add("/WA", expected); - - // Act - patchDoc.ApplyTo(model); - - // Assert - Assert.Single(model); - Assert.Equal(expected, model["WA"]); - } - - [Fact] - public void AddMember_OnDictionaryObjectDirectly_ShouldAddKeyValueMember_WithSerialization() - { - // Arrange - var expected = "Washington"; - var model = new Dictionary(); - var patchDoc = new JsonPatchDocument(); - patchDoc.Add("/WA", expected); - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject>>(serialized); - - // Act - deserialized.ApplyTo(model); - - // Assert - Assert.Single(model); - Assert.Equal(expected, model["WA"]); - } - - [Fact] - public void AddElement_ToListDirectly_ShouldAppendValue() - { - // Arrange - var model = new List() { 1, 2, 3 }; - var patchDoc = new JsonPatchDocument(); - patchDoc.Add("/-", value: 4); - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject>>(serialized); - - // Act - deserialized.ApplyTo(model); - - // Assert - Assert.Equal(new List() { 1, 2, 3, 4 }, model); - } - - [Fact] - public void AddElement_ToListDirectly_ShouldAppendValue_WithSerialization() - { - // Arrange - var model = new List() { 1, 2, 3 }; - var patchDoc = new JsonPatchDocument(); - patchDoc.Add("/-", value: 4); - - // Act - patchDoc.ApplyTo(model); - - // Assert - Assert.Equal(new List() { 1, 2, 3, 4 }, model); - } - - [Fact] - public void AddElement_ToListDirectly_ShouldAddValue_AtSuppliedPosition() - { - // Arrange - var model = new List() { 1, 2, 3 }; - var patchDoc = new JsonPatchDocument(); - patchDoc.Add("/0", value: 4); - - // Act - patchDoc.ApplyTo(model); - - // Assert - Assert.Equal(new List() { 4, 1, 2, 3 }, model); - } - - [Fact] - public void AddElement_ToListDirectly_ShouldAddValue_AtSuppliedPosition_WithSerialization() - { - // Arrange - var model = new List() { 1, 2, 3 }; - var patchDoc = new JsonPatchDocument(); - patchDoc.Add("/0", value: 4); - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject>>(serialized); - - // Act - deserialized.ApplyTo(model); - - // Assert - Assert.Equal(new List() { 4, 1, 2, 3 }, model); - } - - class ListOnDictionary - { - public IDictionary> NamesAndBadgeIds { get; set; } = new Dictionary>(); - } - - [Fact] - public void AddElement_ToList_OnDictionary_ShouldAddValue_AtSuppliedPosition() - { - // Arrange - var model = new ListOnDictionary(); - model.NamesAndBadgeIds["James"] = new List(); - var patchDoc = new JsonPatchDocument(); - patchDoc.Add("/NamesAndBadgeIds/James/-", 200); - - // Act - patchDoc.ApplyTo(model); - - // Assert - var list = model.NamesAndBadgeIds["James"]; - Assert.NotNull(list); - Assert.Equal(new List() { 200 }, list); - } - - [Fact] - public void AddElement_ToList_OnPOCO_ShouldAddValue_AtSuppliedPosition() - { - // Arrange - var doc = new SimpleObject() - { - IntegerIList = new List() { 1, 2, 3 } - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Add(o => o.IntegerIList, 4, 0); - - // Act - patchDoc.ApplyTo(doc); - - // Assert - Assert.Equal(new List() { 4, 1, 2, 3 }, doc.IntegerIList); - } - - class Class3 - { - public SimpleObject SimpleObjectProperty { get; set; } = new SimpleObject(); - } - - [Fact] - public void AddElement_ToDeeplyNestedListProperty_OnPOCO_ShouldAddValue_AtSuppliedPosition() - { - // Arrange - var model = new Class3() - { - SimpleObjectProperty = new SimpleObject() - { - IntegerIList = new List() { 1, 2, 3 } - } - }; - var patchDoc = new JsonPatchDocument(); - patchDoc.Add(o => o.SimpleObjectProperty.IntegerIList, value: 4, position: 0); - - // Act - patchDoc.ApplyTo(model); - - // Assert - Assert.Equal(new List() { 4, 1, 2, 3 }, model.SimpleObjectProperty.IntegerIList); - } - - [Fact] - public void AddElement_ToDeeplyNestedListProperty_OnPOCO_ShouldAddValue_AtSuppliedPosition_WithSerialization() - { - // Arrange - var model = new Class3() - { - SimpleObjectProperty = new SimpleObject() - { - IntegerIList = new List() { 1, 2, 3 } - } - }; - var patchDoc = new JsonPatchDocument(); - patchDoc.Add(o => o.SimpleObjectProperty.IntegerIList, value: 4, position: 0); - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject>(serialized); - - // Act - deserialized.ApplyTo(model); - - // Assert - Assert.Equal(new List() { 4, 1, 2, 3 }, model.SimpleObjectProperty.IntegerIList); - } - - class Class4 - { - public int IntegerProperty { get; set; } - } - - [Fact] - public void Remove_OnNonReferenceType_POCOProperty_ShouldSetDefaultValue() - { - // Arrange - var model = new Class4() - { - IntegerProperty = 10 - }; - var patchDoc = new JsonPatchDocument(); - patchDoc.Remove(o => o.IntegerProperty); - - // Act - patchDoc.ApplyTo(model); - - // Assert - Assert.Equal(0, model.IntegerProperty); - } - - [Fact] - public void Remove_OnNonReferenceType_POCOProperty_ShouldSetDefaultValue_WithSerialization() - { - // Arrange - var doc = new SimpleObject() - { - StringProperty = "A" - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Remove(o => o.StringProperty); - - var serialized = JsonConvert.SerializeObject(patchDoc); - var deserialized = JsonConvert.DeserializeObject>(serialized); - - // Act - deserialized.ApplyTo(doc); - - // Assert - Assert.Null(doc.StringProperty); - } - - class ClassWithPrivateProperties - { - public string Name { get; set; } - private int Age { get; set; } = 45; - } - - [Fact] - public void Add_OnPrivateProperties_FailesWithException() - { - // Arrange - var doc = new ClassWithPrivateProperties() - { - Name = "James" - }; - - // create patch - var patchDoc = new JsonPatchDocument(); - patchDoc.Add("/Age", 30); - - // Act & Assert - var exception = Assert.Throws(() => patchDoc.ApplyTo(doc)); - Assert.Equal( - string.Format("The target location specified by path segment '{0}' was not found.", "Age"), - exception.Message); - } - } -} diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/SimpleObjectWithNestedObjectWithNullCheck.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/SimpleObjectWithNestedObjectWithNullCheck.cs deleted file mode 100644 index f2423700d8..0000000000 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/SimpleObjectWithNestedObjectWithNullCheck.cs +++ /dev/null @@ -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 SimpleObjectWithNestedObjectWithNullCheck - { - public SimpleObjectWithNullCheck SimpleObjectWithNullCheck { get; set; } - - public SimpleObjectWithNestedObjectWithNullCheck() - { - SimpleObjectWithNullCheck = new SimpleObjectWithNullCheck(); - } - } -} diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/SimpleObjectWithNullCheck.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/SimpleObjectWithNullCheck.cs deleted file mode 100644 index 83338c5a23..0000000000 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/SimpleObjectWithNullCheck.cs +++ /dev/null @@ -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; - -namespace Microsoft.AspNetCore.JsonPatch -{ - public class SimpleObjectWithNullCheck - { - private string stringProperty; - - public string StringProperty - { - get - { - return stringProperty; - } - - set - { - if (value == null) - { - throw new ArgumentNullException(); - } - - stringProperty = value; - } - } - } -} diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/TestObjectModels/Customer.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/TestObjectModels/Customer.cs new file mode 100644 index 0000000000..c8a5aa22b1 --- /dev/null +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/TestObjectModels/Customer.cs @@ -0,0 +1,17 @@ +// 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 +{ + internal class Customer + { + private string _name; + private int _age; + + public Customer(string name, int age) + { + _name = name; + _age = age; + } + } +} diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/DynamicTestObject.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/TestObjectModels/DynamicTestObject.cs similarity index 98% rename from test/Microsoft.AspNetCore.JsonPatch.Test/DynamicTestObject.cs rename to test/Microsoft.AspNetCore.JsonPatch.Test/TestObjectModels/DynamicTestObject.cs index 4268d5526c..94ecf1685d 100644 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/DynamicTestObject.cs +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/TestObjectModels/DynamicTestObject.cs @@ -4,7 +4,7 @@ using System.Collections.Generic; using System.Dynamic; -namespace Microsoft.AspNetCore.JsonPatch.Internal +namespace Microsoft.AspNetCore.JsonPatch { public class DynamicTestObject : DynamicObject { diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/InheritedObject.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/TestObjectModels/InheritedObject.cs similarity index 100% rename from test/Microsoft.AspNetCore.JsonPatch.Test/InheritedObject.cs rename to test/Microsoft.AspNetCore.JsonPatch.Test/TestObjectModels/InheritedObject.cs diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/NestedObject.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/TestObjectModels/NestedObject.cs similarity index 85% rename from test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/NestedObject.cs rename to test/Microsoft.AspNetCore.JsonPatch.Test/TestObjectModels/NestedObject.cs index 050ad3a3b4..1b42d0d7ef 100644 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/Dynamic/NestedObject.cs +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/TestObjectModels/NestedObject.cs @@ -1,11 +1,11 @@ // 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 +namespace Microsoft.AspNetCore.JsonPatch { public class NestedObject { public string StringProperty { get; set; } public dynamic DynamicProperty { get; set; } } -} +} \ No newline at end of file diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/SimpleObject.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/TestObjectModels/SimpleObject.cs similarity index 86% rename from test/Microsoft.AspNetCore.JsonPatch.Test/SimpleObject.cs rename to test/Microsoft.AspNetCore.JsonPatch.Test/TestObjectModels/SimpleObject.cs index 28a9570c2b..651a91bdcf 100644 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/SimpleObject.cs +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/TestObjectModels/SimpleObject.cs @@ -8,9 +8,11 @@ namespace Microsoft.AspNetCore.JsonPatch { public class SimpleObject { + public List SimpleObjectList { get; set; } public List IntegerList { get; set; } public IList IntegerIList { get; set; } public int IntegerValue { get; set; } + public int AnotherIntegerValue { get; set; } public string StringProperty { get; set; } public string AnotherStringProperty { get; set; } public decimal DecimalValue { get; set; } diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/SimpleObjectWithNestedObject.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/TestObjectModels/SimpleObjectWithNestedObject.cs similarity index 100% rename from test/Microsoft.AspNetCore.JsonPatch.Test/SimpleObjectWithNestedObject.cs rename to test/Microsoft.AspNetCore.JsonPatch.Test/TestObjectModels/SimpleObjectWithNestedObject.cs From 478c640a68bc9e91c25ee5edd81363c67d98c6e0 Mon Sep 17 00:00:00 2001 From: Nate McMaster Date: Wed, 1 Nov 2017 15:11:36 -0700 Subject: [PATCH 165/221] Pin tool and package versions to make builds more repeatable Part of aspnet/Universe#575 --- .gitignore | 1 - Directory.Build.props | 6 +++--- Directory.Build.targets | 17 ++++------------- build/dependencies.props | 19 +++++++++++++++++++ build/repo.props | 11 ++++++----- korebuild-lock.txt | 2 ++ korebuild.json | 4 ++++ src/Directory.Build.props | 2 +- .../Microsoft.AspNetCore.JsonPatch.csproj | 6 +++--- test/Directory.Build.props | 10 +++++----- ...Microsoft.AspNetCore.JsonPatch.Test.csproj | 6 +++--- version.props | 10 ++++++++++ version.xml | 8 -------- 13 files changed, 60 insertions(+), 42 deletions(-) create mode 100644 build/dependencies.props create mode 100644 korebuild-lock.txt create mode 100644 korebuild.json create mode 100644 version.props delete mode 100644 version.xml diff --git a/.gitignore b/.gitignore index 24d990294f..2e8ec28064 100644 --- a/.gitignore +++ b/.gitignore @@ -37,4 +37,3 @@ node_modules *launchSettings.json *.orig global.json -korebuild-lock.txt diff --git a/Directory.Build.props b/Directory.Build.props index fb7dfae923..442db60e74 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -1,5 +1,6 @@ - - + + + Microsoft ASP.NET Core @@ -9,7 +10,6 @@ $(MSBuildThisFileDirectory)build\Key.snk true true - $(VersionSuffix)-$(BuildNumber) true diff --git a/Directory.Build.targets b/Directory.Build.targets index 9989b1046b..e83ff95e39 100644 --- a/Directory.Build.targets +++ b/Directory.Build.targets @@ -1,14 +1,5 @@ - - - - <_BootstrapperFile Condition=" $([MSBuild]::IsOSUnixLike()) ">build.sh - <_BootstrapperFile Condition="! $([MSBuild]::IsOSUnixLike()) ">build.cmd - <_BootstrapperError> - Package references have not been pinned. Run './$(_BootstrapperFile) /t:Pin'. - Also, you can run './$(_BootstrapperFile) /t:Restore' which will pin *and* restore packages. '$(_BootstrapperFile)' can be found in '$(MSBuildThisFileDirectory)'. - - - - - + + + $(MicrosoftNETCoreApp20PackageVersion) + diff --git a/build/dependencies.props b/build/dependencies.props new file mode 100644 index 0000000000..ba20d698d6 --- /dev/null +++ b/build/dependencies.props @@ -0,0 +1,19 @@ + + + $(MSBuildAllProjects);$(MSBuildThisFileFullPath) + + + 2.1.0-preview1-15550 + 2.1.0-preview1-27497 + 4.4.0 + 2.1.0-preview1-27497 + 2.0.0 + 15.3.0 + 4.7.49 + 10.0.1 + 0.7.0 + 2.3.0 + 2.3.0 + + + diff --git a/build/repo.props b/build/repo.props index c5d91e8a2c..b55e651b87 100644 --- a/build/repo.props +++ b/build/repo.props @@ -1,6 +1,7 @@ - - - - - + + + + Internal.AspNetCore.Universe.Lineup + https://dotnet.myget.org/F/aspnetcore-ci-dev/api/v3/index.json + diff --git a/korebuild-lock.txt b/korebuild-lock.txt new file mode 100644 index 0000000000..36d8056037 --- /dev/null +++ b/korebuild-lock.txt @@ -0,0 +1,2 @@ +version:2.1.0-preview1-15550 +commithash:0dd080d0d87b4d1966ec0af9961dc8bacc04f84f diff --git a/korebuild.json b/korebuild.json new file mode 100644 index 0000000000..bd5d51a51b --- /dev/null +++ b/korebuild.json @@ -0,0 +1,4 @@ +{ + "$schema": "https://raw.githubusercontent.com/aspnet/BuildTools/dev/tools/korebuild.schema.json", + "channel": "dev" +} diff --git a/src/Directory.Build.props b/src/Directory.Build.props index 5236edee58..4b89a431e7 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -2,6 +2,6 @@ - + diff --git a/src/Microsoft.AspNetCore.JsonPatch/Microsoft.AspNetCore.JsonPatch.csproj b/src/Microsoft.AspNetCore.JsonPatch/Microsoft.AspNetCore.JsonPatch.csproj index a364de22ef..9bd08214f6 100644 --- a/src/Microsoft.AspNetCore.JsonPatch/Microsoft.AspNetCore.JsonPatch.csproj +++ b/src/Microsoft.AspNetCore.JsonPatch/Microsoft.AspNetCore.JsonPatch.csproj @@ -9,9 +9,9 @@ - - - + + + diff --git a/test/Directory.Build.props b/test/Directory.Build.props index 31ed7dd07c..b10972fadd 100644 --- a/test/Directory.Build.props +++ b/test/Directory.Build.props @@ -2,10 +2,10 @@ - - - - - + + + + + diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/Microsoft.AspNetCore.JsonPatch.Test.csproj b/test/Microsoft.AspNetCore.JsonPatch.Test/Microsoft.AspNetCore.JsonPatch.Test.csproj index 6d7b403a79..241271d58f 100644 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/Microsoft.AspNetCore.JsonPatch.Test.csproj +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/Microsoft.AspNetCore.JsonPatch.Test.csproj @@ -1,4 +1,4 @@ - + netcoreapp2.0;net461 @@ -10,8 +10,8 @@ - - + + diff --git a/version.props b/version.props new file mode 100644 index 0000000000..5c4a7c32d1 --- /dev/null +++ b/version.props @@ -0,0 +1,10 @@ + + + 2.1.0 + preview1 + $(VersionPrefix) + $(VersionPrefix)-$(VersionSuffix)-final + t000 + $(VersionSuffix)-$(BuildNumber) + + diff --git a/version.xml b/version.xml deleted file mode 100644 index 3c05022b7d..0000000000 --- a/version.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - dev - 2.1.0 - preview1 - - From 70c8133fce523b6eb42f39cc4da78e9ac11e99dc Mon Sep 17 00:00:00 2001 From: arerlend <30675661+arerlend@users.noreply.github.com> Date: Tue, 7 Nov 2017 11:24:52 -0800 Subject: [PATCH 166/221] allow paths that contain '.' (#125) * allow paths that contain '.' * remove InvalidPathWithDotShouldThrowException test --- .../Internal/PathHelpers.cs | 2 +- .../JsonPatchDocumentTest.cs | 20 +------------------ 2 files changed, 2 insertions(+), 20 deletions(-) diff --git a/src/Microsoft.AspNetCore.JsonPatch/Internal/PathHelpers.cs b/src/Microsoft.AspNetCore.JsonPatch/Internal/PathHelpers.cs index 7ef8fe7baf..d46314c148 100644 --- a/src/Microsoft.AspNetCore.JsonPatch/Internal/PathHelpers.cs +++ b/src/Microsoft.AspNetCore.JsonPatch/Internal/PathHelpers.cs @@ -13,7 +13,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal // absolutely necessary, but it allows us to already catch mistakes // on creation of the patch document rather than on execute. - if (path.Contains(".") || path.Contains("//") || path.Contains(" ") || path.Contains("\\")) + if (path.Contains("//") || path.Contains(" ") || path.Contains("\\")) { throw new JsonPatchException(Resources.FormatInvalidValueForPath(path), null); } diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/JsonPatchDocumentTest.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/JsonPatchDocumentTest.cs index 6b44b6696c..197e514cee 100644 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/JsonPatchDocumentTest.cs +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/JsonPatchDocumentTest.cs @@ -45,24 +45,6 @@ namespace Microsoft.AspNetCore.JsonPatch exception.Message); } - [Fact] - public void InvalidPathWithDotShouldThrowException() - { - // Arrange - var patchDocument = new JsonPatchDocument(); - - // Act - var exception = Assert.Throws(() => - { - patchDocument.Add("NewInt.Test", 1); - }); - - // Assert - Assert.Equal( - "The provided string 'NewInt.Test' is an invalid path.", - exception.Message); - } - [Fact] public void NonGenericPatchDocToGenericMustSerialize() { @@ -177,4 +159,4 @@ namespace Microsoft.AspNetCore.JsonPatch Assert.Equal("The JSON patch document was malformed and could not be parsed.", exception.Message); } } -} \ No newline at end of file +} From 39db8585c1327d9ff50de3d73ef471e76a536d19 Mon Sep 17 00:00:00 2001 From: Pranav K Date: Fri, 10 Nov 2017 10:19:50 -0800 Subject: [PATCH 167/221] Target netcoreapp2.1 in tests and samples --- Directory.Build.props | 4 ++++ korebuild-lock.txt | 4 ++-- test/Directory.Build.props | 7 +++++++ .../Microsoft.AspNetCore.JsonPatch.Test.csproj | 3 +-- 4 files changed, 14 insertions(+), 4 deletions(-) diff --git a/Directory.Build.props b/Directory.Build.props index 442db60e74..2843f64536 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -1,4 +1,8 @@  + + diff --git a/korebuild-lock.txt b/korebuild-lock.txt index 36d8056037..07a4d73a83 100644 --- a/korebuild-lock.txt +++ b/korebuild-lock.txt @@ -1,2 +1,2 @@ -version:2.1.0-preview1-15550 -commithash:0dd080d0d87b4d1966ec0af9961dc8bacc04f84f +version:2.1.0-preview1-15564 +commithash:1f3f14382764e06b7e691e5ee89d12a280249284 diff --git a/test/Directory.Build.props b/test/Directory.Build.props index b10972fadd..98685a5e13 100644 --- a/test/Directory.Build.props +++ b/test/Directory.Build.props @@ -1,6 +1,13 @@ + + netcoreapp2.1 + $(DeveloperBuildTestTfms) + $(StandardTestTfms);netcoreapp2.0 + $(StandardTestTfms);net461 + + diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/Microsoft.AspNetCore.JsonPatch.Test.csproj b/test/Microsoft.AspNetCore.JsonPatch.Test/Microsoft.AspNetCore.JsonPatch.Test.csproj index 241271d58f..ce1d92802d 100644 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/Microsoft.AspNetCore.JsonPatch.Test.csproj +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/Microsoft.AspNetCore.JsonPatch.Test.csproj @@ -1,8 +1,7 @@ - netcoreapp2.0;net461 - netcoreapp2.0 + $(StandardTestTfms) From bccd5a1244637eed3f23d86367c2ac146e6a7576 Mon Sep 17 00:00:00 2001 From: Pranav K Date: Fri, 17 Nov 2017 13:00:25 -0800 Subject: [PATCH 168/221] Use MicrosoftNETCoreApp21PackageVersion to determine the runtime framework in netcoreapp2.1 --- Directory.Build.targets | 1 + build/dependencies.props | 1 + 2 files changed, 2 insertions(+) diff --git a/Directory.Build.targets b/Directory.Build.targets index e83ff95e39..894b1d0cf8 100644 --- a/Directory.Build.targets +++ b/Directory.Build.targets @@ -1,5 +1,6 @@  $(MicrosoftNETCoreApp20PackageVersion) + $(MicrosoftNETCoreApp21PackageVersion) diff --git a/build/dependencies.props b/build/dependencies.props index ba20d698d6..3072c1d6e4 100644 --- a/build/dependencies.props +++ b/build/dependencies.props @@ -8,6 +8,7 @@ 4.4.0 2.1.0-preview1-27497 2.0.0 + 2.1.0-preview1-25907-02 15.3.0 4.7.49 10.0.1 From 0d4e34e0a1d66e87df2bc580320de93d215d093b Mon Sep 17 00:00:00 2001 From: Nate McMaster Date: Mon, 20 Nov 2017 12:18:17 -0800 Subject: [PATCH 169/221] Use MSBuild to set NuGet feeds instead of NuGet.config --- Directory.Build.props | 1 + NuGet.config | 4 +--- build/sources.props | 16 ++++++++++++++++ 3 files changed, 18 insertions(+), 3 deletions(-) create mode 100644 build/sources.props diff --git a/Directory.Build.props b/Directory.Build.props index 2843f64536..88b93729bb 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -5,6 +5,7 @@ + Microsoft ASP.NET Core diff --git a/NuGet.config b/NuGet.config index 4e8a1f6de1..e32bddfd51 100644 --- a/NuGet.config +++ b/NuGet.config @@ -2,8 +2,6 @@ - - - + diff --git a/build/sources.props b/build/sources.props new file mode 100644 index 0000000000..c03f3ddb60 --- /dev/null +++ b/build/sources.props @@ -0,0 +1,16 @@ + + + + + $(DotNetRestoreSources) + + $(RestoreSources); + https://dotnet.myget.org/F/aspnetcore-ci-dev/api/v3/index.json; + https://dotnet.myget.org/F/aspnetcore-tools/api/v3/index.json; + + + $(RestoreSources); + https://api.nuget.org/v3/index.json; + + + From b5906870fdf158abfdaaef30eb89c6c68503cc84 Mon Sep 17 00:00:00 2001 From: Pranav K Date: Tue, 21 Nov 2017 15:48:09 -0800 Subject: [PATCH 170/221] Replace aspnetcore-ci-dev feed with aspnetcore-dev --- build/dependencies.props | 8 ++++---- build/repo.props | 2 +- build/sources.props | 2 +- korebuild-lock.txt | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/build/dependencies.props b/build/dependencies.props index 3072c1d6e4..34524aaba3 100644 --- a/build/dependencies.props +++ b/build/dependencies.props @@ -1,12 +1,12 @@ - + $(MSBuildAllProjects);$(MSBuildThisFileFullPath) - 2.1.0-preview1-15550 - 2.1.0-preview1-27497 + 2.1.0-preview1-15576 + 2.1.0-preview1-27644 4.4.0 - 2.1.0-preview1-27497 + 2.1.0-preview1-27644 2.0.0 2.1.0-preview1-25907-02 15.3.0 diff --git a/build/repo.props b/build/repo.props index b55e651b87..07c5f08325 100644 --- a/build/repo.props +++ b/build/repo.props @@ -2,6 +2,6 @@ Internal.AspNetCore.Universe.Lineup - https://dotnet.myget.org/F/aspnetcore-ci-dev/api/v3/index.json + https://dotnet.myget.org/F/aspnetcore-dev/api/v3/index.json diff --git a/build/sources.props b/build/sources.props index c03f3ddb60..9feff29d09 100644 --- a/build/sources.props +++ b/build/sources.props @@ -5,7 +5,7 @@ $(DotNetRestoreSources) $(RestoreSources); - https://dotnet.myget.org/F/aspnetcore-ci-dev/api/v3/index.json; + https://dotnet.myget.org/F/aspnetcore-dev/api/v3/index.json; https://dotnet.myget.org/F/aspnetcore-tools/api/v3/index.json; diff --git a/korebuild-lock.txt b/korebuild-lock.txt index 07a4d73a83..1a99066b7c 100644 --- a/korebuild-lock.txt +++ b/korebuild-lock.txt @@ -1,2 +1,2 @@ -version:2.1.0-preview1-15564 -commithash:1f3f14382764e06b7e691e5ee89d12a280249284 +version:2.1.0-preview1-15576 +commithash:2f3856d2ba4f659fcb9253215b83946a06794a27 From fe4d3c7ea9ceff78e3347d3ee40b99a12dcc9631 Mon Sep 17 00:00:00 2001 From: Pranav K Date: Wed, 29 Nov 2017 14:09:27 -0800 Subject: [PATCH 171/221] Specify runtime versions to install --- build/repo.props | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/build/repo.props b/build/repo.props index 07c5f08325..78b0ce5879 100644 --- a/build/repo.props +++ b/build/repo.props @@ -1,7 +1,14 @@  + + Internal.AspNetCore.Universe.Lineup https://dotnet.myget.org/F/aspnetcore-dev/api/v3/index.json + + + + + From a928adee30db55c591eaece34de7fddd2e9ab834 Mon Sep 17 00:00:00 2001 From: Ryan Brandenburg Date: Fri, 1 Dec 2017 10:24:45 -0800 Subject: [PATCH 172/221] Update bootstrappers --- run.ps1 | 17 +++++++++++------ run.sh | 30 +++++++++++++++++++----------- 2 files changed, 30 insertions(+), 17 deletions(-) diff --git a/run.ps1 b/run.ps1 index 49c2899856..27dcf848f8 100644 --- a/run.ps1 +++ b/run.ps1 @@ -29,6 +29,9 @@ Updates KoreBuild to the latest version even if a lock file is present. .PARAMETER ConfigFile The path to the configuration file that stores values. Defaults to korebuild.json. +.PARAMETER ToolsSourceSuffix +The Suffix to append to the end of the ToolsSource. Useful for query strings in blob stores. + .PARAMETER Arguments Arguments to be passed to the command @@ -51,7 +54,7 @@ Example config file: #> [CmdletBinding(PositionalBinding = $false)] param( - [Parameter(Mandatory=$true, Position = 0)] + [Parameter(Mandatory = $true, Position = 0)] [string]$Command, [string]$Path = $PSScriptRoot, [Alias('c')] @@ -63,6 +66,7 @@ param( [Alias('u')] [switch]$Update, [string]$ConfigFile, + [string]$ToolsSourceSuffix, [Parameter(ValueFromRemainingArguments = $true)] [string[]]$Arguments ) @@ -79,7 +83,7 @@ function Get-KoreBuild { $lockFile = Join-Path $Path 'korebuild-lock.txt' if (!(Test-Path $lockFile) -or $Update) { - Get-RemoteFile "$ToolsSource/korebuild/channels/$Channel/latest.txt" $lockFile + Get-RemoteFile "$ToolsSource/korebuild/channels/$Channel/latest.txt" $lockFile $ToolsSourceSuffix } $version = Get-Content $lockFile | Where-Object { $_ -like 'version:*' } | Select-Object -first 1 @@ -96,7 +100,7 @@ function Get-KoreBuild { try { $tmpfile = Join-Path ([IO.Path]::GetTempPath()) "KoreBuild-$([guid]::NewGuid()).zip" - Get-RemoteFile $remotePath $tmpfile + Get-RemoteFile $remotePath $tmpfile $ToolsSourceSuffix if (Get-Command -Name 'Expand-Archive' -ErrorAction Ignore) { # Use built-in commands where possible as they are cross-plat compatible Expand-Archive -Path $tmpfile -DestinationPath $korebuildPath @@ -124,7 +128,7 @@ function Join-Paths([string]$path, [string[]]$childPaths) { return $path } -function Get-RemoteFile([string]$RemotePath, [string]$LocalPath) { +function Get-RemoteFile([string]$RemotePath, [string]$LocalPath, [string]$RemoteSuffix) { if ($RemotePath -notlike 'http*') { Copy-Item $RemotePath $LocalPath return @@ -134,7 +138,7 @@ function Get-RemoteFile([string]$RemotePath, [string]$LocalPath) { while ($retries -gt 0) { $retries -= 1 try { - Invoke-WebRequest -UseBasicParsing -Uri $RemotePath -OutFile $LocalPath + Invoke-WebRequest -UseBasicParsing -Uri $($RemotePath + $RemoteSuffix) -OutFile $LocalPath return } catch { @@ -161,7 +165,8 @@ if (Test-Path $ConfigFile) { if (!($Channel) -and (Get-Member -Name 'channel' -InputObject $config)) { [string] $Channel = $config.channel } if (!($ToolsSource) -and (Get-Member -Name 'toolsSource' -InputObject $config)) { [string] $ToolsSource = $config.toolsSource} } - } catch { + } + catch { Write-Warning "$ConfigFile could not be read. Its settings will be ignored." Write-Warning $Error[0] } diff --git a/run.sh b/run.sh index c278423acc..834961fc3a 100755 --- a/run.sh +++ b/run.sh @@ -17,6 +17,7 @@ update=false repo_path="$DIR" channel='' tools_source='' +tools_source_suffix='' # # Functions @@ -29,13 +30,14 @@ __usage() { echo " ... Arguments passed to the command. Variable number of arguments allowed." echo "" echo "Options:" - echo " --verbose Show verbose output." - echo " -c|--channel The channel of KoreBuild to download. Overrides the value from the config file.." - echo " --config-file The path to the configuration file that stores values. Defaults to korebuild.json." - echo " -d|--dotnet-home The directory where .NET Core tools will be stored. Defaults to '\$DOTNET_HOME' or '\$HOME/.dotnet." - echo " --path The directory to build. Defaults to the directory containing the script." - echo " -s|--tools-source|-ToolsSource The base url where build tools can be downloaded. Overrides the value from the config file." - echo " -u|--update Update to the latest KoreBuild even if the lock file is present." + echo " --verbose Show verbose output." + echo " -c|--channel The channel of KoreBuild to download. Overrides the value from the config file.." + echo " --config-file The path to the configuration file that stores values. Defaults to korebuild.json." + echo " -d|--dotnet-home The directory where .NET Core tools will be stored. Defaults to '\$DOTNET_HOME' or '\$HOME/.dotnet." + echo " --path The directory to build. Defaults to the directory containing the script." + echo " -s|--tools-source|-ToolsSource The base url where build tools can be downloaded. Overrides the value from the config file." + echo " --tools-source-suffix|-ToolsSourceSuffix The suffix to append to tools-source. Useful for query strings." + echo " -u|--update Update to the latest KoreBuild even if the lock file is present." echo "" echo "Description:" echo " This function will create a file \$DIR/korebuild-lock.txt. This lock file can be committed to source, but does not have to be." @@ -50,7 +52,7 @@ get_korebuild() { local version local lock_file="$repo_path/korebuild-lock.txt" if [ ! -f "$lock_file" ] || [ "$update" = true ]; then - __get_remote_file "$tools_source/korebuild/channels/$channel/latest.txt" "$lock_file" + __get_remote_file "$tools_source/korebuild/channels/$channel/latest.txt" "$lock_file" "$tools_source_suffix" fi version="$(grep 'version:*' -m 1 "$lock_file")" if [[ "$version" == '' ]]; then @@ -66,7 +68,7 @@ get_korebuild() { local remote_path="$tools_source/korebuild/artifacts/$version/korebuild.$version.zip" tmpfile="$(mktemp)" echo -e "${MAGENTA}Downloading KoreBuild ${version}${RESET}" - if __get_remote_file "$remote_path" "$tmpfile"; then + if __get_remote_file "$remote_path" "$tmpfile" "$tools_source_suffix"; then unzip -q -d "$korebuild_path" "$tmpfile" fi rm "$tmpfile" || true @@ -98,6 +100,7 @@ __machine_has() { __get_remote_file() { local remote_path=$1 local local_path=$2 + local remote_path_suffix=$3 if [[ "$remote_path" != 'http'* ]]; then cp "$remote_path" "$local_path" @@ -106,14 +109,14 @@ __get_remote_file() { local failed=false if __machine_has wget; then - wget --tries 10 --quiet -O "$local_path" "$remote_path" || failed=true + wget --tries 10 --quiet -O "$local_path" "${remote_path}${remote_path_suffix}" || failed=true else failed=true fi if [ "$failed" = true ] && __machine_has curl; then failed=false - curl --retry 10 -sSL -f --create-dirs -o "$local_path" "$remote_path" || failed=true + curl --retry 10 -sSL -f --create-dirs -o "$local_path" "${remote_path}${remote_path_suffix}" || failed=true fi if [ "$failed" = true ]; then @@ -164,6 +167,11 @@ while [[ $# -gt 0 ]]; do tools_source="${1:-}" [ -z "$tools_source" ] && __usage ;; + --tools-source-suffix|-ToolsSourceSuffix) + shift + tools_source_suffix="${1:-}" + [ -z "$tools_source_suffix" ] && __usage + ;; -u|--update|-Update) update=true ;; From 84194387a22ae103166fe5d59a0b30f335f616fb Mon Sep 17 00:00:00 2001 From: "ASP.NET CI" Date: Sun, 10 Dec 2017 13:01:26 -0800 Subject: [PATCH 173/221] Update dependencies.props [auto-updated: dependencies] --- build/dependencies.props | 16 ++++++++-------- korebuild-lock.txt | 4 ++-- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/build/dependencies.props b/build/dependencies.props index 34524aaba3..1808025509 100644 --- a/build/dependencies.props +++ b/build/dependencies.props @@ -3,18 +3,18 @@ $(MSBuildAllProjects);$(MSBuildThisFileFullPath) - 2.1.0-preview1-15576 - 2.1.0-preview1-27644 - 4.4.0 - 2.1.0-preview1-27644 + 2.1.0-preview1-15618 + 2.1.0-preview1-27773 + 4.5.0-preview1-25914-04 + 2.1.0-preview1-27773 2.0.0 - 2.1.0-preview1-25907-02 + 2.1.0-preview1-25915-01 15.3.0 4.7.49 10.0.1 - 0.7.0 - 2.3.0 - 2.3.0 + 0.8.0 + 2.3.1 + 2.3.1 diff --git a/korebuild-lock.txt b/korebuild-lock.txt index 1a99066b7c..e7cce93009 100644 --- a/korebuild-lock.txt +++ b/korebuild-lock.txt @@ -1,2 +1,2 @@ -version:2.1.0-preview1-15576 -commithash:2f3856d2ba4f659fcb9253215b83946a06794a27 +version:2.1.0-preview1-15618 +commithash:00ce1383114015fe89b221146036e59e6bc11219 From 77de59903060c225b31ee8fb1ef0885d13a6cdf9 Mon Sep 17 00:00:00 2001 From: "ASP.NET CI" Date: Wed, 13 Dec 2017 21:01:02 +0000 Subject: [PATCH 174/221] Update dependencies.props [auto-updated: dependencies] --- build/dependencies.props | 10 +++++----- korebuild-lock.txt | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/build/dependencies.props b/build/dependencies.props index 1808025509..2e1d5008e8 100644 --- a/build/dependencies.props +++ b/build/dependencies.props @@ -3,12 +3,12 @@ $(MSBuildAllProjects);$(MSBuildThisFileFullPath) - 2.1.0-preview1-15618 - 2.1.0-preview1-27773 - 4.5.0-preview1-25914-04 - 2.1.0-preview1-27773 + 2.1.0-preview1-15626 + 2.1.0-preview1-27807 + 4.5.0-preview1-26006-06 + 2.1.0-preview1-27807 2.0.0 - 2.1.0-preview1-25915-01 + 2.1.0-preview1-26008-01 15.3.0 4.7.49 10.0.1 diff --git a/korebuild-lock.txt b/korebuild-lock.txt index e7cce93009..8d52a6128c 100644 --- a/korebuild-lock.txt +++ b/korebuild-lock.txt @@ -1,2 +1,2 @@ -version:2.1.0-preview1-15618 -commithash:00ce1383114015fe89b221146036e59e6bc11219 +version:2.1.0-preview1-15626 +commithash:fd6410e9c90c428bc01238372303ad09cb9ec889 From 1d427b4065d2dcb421b161b3c1abe4dd29796639 Mon Sep 17 00:00:00 2001 From: "ASP.NET CI" Date: Sun, 17 Dec 2017 12:35:17 -0800 Subject: [PATCH 175/221] Update dependencies.props [auto-updated: dependencies] --- build/dependencies.props | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/build/dependencies.props b/build/dependencies.props index 2e1d5008e8..ab34d96520 100644 --- a/build/dependencies.props +++ b/build/dependencies.props @@ -4,11 +4,11 @@ 2.1.0-preview1-15626 - 2.1.0-preview1-27807 - 4.5.0-preview1-26006-06 - 2.1.0-preview1-27807 + 2.1.0-preview1-27838 + 4.5.0-preview1-26014-03 + 2.1.0-preview1-27838 2.0.0 - 2.1.0-preview1-26008-01 + 2.1.0-preview1-26015-01 15.3.0 4.7.49 10.0.1 From a0316af7b207cb94372db1ab727b97ea720651e8 Mon Sep 17 00:00:00 2001 From: "ASP.NET CI" Date: Mon, 18 Dec 2017 17:15:24 -0800 Subject: [PATCH 176/221] Update dependencies.props [auto-updated: dependencies] --- build/dependencies.props | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/build/dependencies.props b/build/dependencies.props index ab34d96520..06cca20623 100644 --- a/build/dependencies.props +++ b/build/dependencies.props @@ -4,11 +4,11 @@ 2.1.0-preview1-15626 - 2.1.0-preview1-27838 - 4.5.0-preview1-26014-03 - 2.1.0-preview1-27838 + 2.1.0-preview1-27849 + 4.5.0-preview1-26016-05 + 2.1.0-preview1-27849 2.0.0 - 2.1.0-preview1-26015-01 + 2.1.0-preview1-26016-05 15.3.0 4.7.49 10.0.1 From a7589fbd7d132b02efb553e8a3c339559c1dfe44 Mon Sep 17 00:00:00 2001 From: "ASP.NET CI" Date: Sun, 31 Dec 2017 21:18:01 +0000 Subject: [PATCH 177/221] Update dependencies.props [auto-updated: dependencies] --- build/dependencies.props | 6 +++--- korebuild-lock.txt | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/build/dependencies.props b/build/dependencies.props index 06cca20623..71f186007d 100644 --- a/build/dependencies.props +++ b/build/dependencies.props @@ -3,10 +3,10 @@ $(MSBuildAllProjects);$(MSBuildThisFileFullPath) - 2.1.0-preview1-15626 - 2.1.0-preview1-27849 + 2.1.0-preview1-15651 + 2.1.0-preview1-27942 4.5.0-preview1-26016-05 - 2.1.0-preview1-27849 + 2.1.0-preview1-27942 2.0.0 2.1.0-preview1-26016-05 15.3.0 diff --git a/korebuild-lock.txt b/korebuild-lock.txt index 8d52a6128c..7c2e97aa79 100644 --- a/korebuild-lock.txt +++ b/korebuild-lock.txt @@ -1,2 +1,2 @@ -version:2.1.0-preview1-15626 -commithash:fd6410e9c90c428bc01238372303ad09cb9ec889 +version:2.1.0-preview1-15651 +commithash:ebf2365121c2c6a6a0fbfa9b0f37bb5effc89323 From 721e8ac93921ee5655f4208f620a19e1edc23b81 Mon Sep 17 00:00:00 2001 From: Eilon Lipton Date: Tue, 2 Jan 2018 14:25:50 -0800 Subject: [PATCH 178/221] Create ISSUE_TEMPLATE.md --- .github/ISSUE_TEMPLATE.md | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE.md diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md new file mode 100644 index 0000000000..101a084f0a --- /dev/null +++ b/.github/ISSUE_TEMPLATE.md @@ -0,0 +1,3 @@ +THIS ISSUE TRACKER IS CLOSED - please log new issues here: https://github.com/aspnet/Home/issues + +For information about this change, see https://github.com/aspnet/Announcements/issues/283 From add34207364e4eb8a918ee46af8ddef1f430f7cb Mon Sep 17 00:00:00 2001 From: "ASP.NET CI" Date: Thu, 4 Jan 2018 01:24:28 +0000 Subject: [PATCH 179/221] Update dependencies.props [auto-updated: dependencies] --- build/dependencies.props | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build/dependencies.props b/build/dependencies.props index 71f186007d..8ebfd2751f 100644 --- a/build/dependencies.props +++ b/build/dependencies.props @@ -4,9 +4,9 @@ 2.1.0-preview1-15651 - 2.1.0-preview1-27942 + 2.1.0-preview1-27965 4.5.0-preview1-26016-05 - 2.1.0-preview1-27942 + 2.1.0-preview1-27965 2.0.0 2.1.0-preview1-26016-05 15.3.0 From 8f09923324ec5f9f9f58adf43e414edf978874c1 Mon Sep 17 00:00:00 2001 From: "ASP.NET CI" Date: Sat, 6 Jan 2018 14:57:37 -0800 Subject: [PATCH 180/221] Update dependencies.props [auto-updated: dependencies] --- korebuild-lock.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/korebuild-lock.txt b/korebuild-lock.txt index 7c2e97aa79..2146d006d7 100644 --- a/korebuild-lock.txt +++ b/korebuild-lock.txt @@ -1,2 +1,2 @@ -version:2.1.0-preview1-15651 -commithash:ebf2365121c2c6a6a0fbfa9b0f37bb5effc89323 +version:2.1.0-preview1-15661 +commithash:c9349d4c8a495d3085d9b879214d80f2f45e2193 From eafe3e7aa39c4023883394d4fbab16131d190295 Mon Sep 17 00:00:00 2001 From: Pranav K Date: Tue, 23 Jan 2018 15:31:40 -0800 Subject: [PATCH 181/221] Branching for 2.1.0-preview1 --- build/dependencies.props | 10 +++++----- build/repo.props | 4 ++-- build/sources.props | 4 ++-- korebuild-lock.txt | 4 ++-- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/build/dependencies.props b/build/dependencies.props index 8ebfd2751f..5382af18d5 100644 --- a/build/dependencies.props +++ b/build/dependencies.props @@ -3,12 +3,12 @@ $(MSBuildAllProjects);$(MSBuildThisFileFullPath) - 2.1.0-preview1-15651 - 2.1.0-preview1-27965 - 4.5.0-preview1-26016-05 - 2.1.0-preview1-27965 + 2.1.0-preview1-15679 + 2.1.0-preview1-28153 + 4.5.0-preview1-26112-01 + 2.1.0-preview1-28153 2.0.0 - 2.1.0-preview1-26016-05 + 2.1.0-preview1-26115-03 15.3.0 4.7.49 10.0.1 diff --git a/build/repo.props b/build/repo.props index 78b0ce5879..d94ff7d00d 100644 --- a/build/repo.props +++ b/build/repo.props @@ -1,10 +1,10 @@ - + Internal.AspNetCore.Universe.Lineup - https://dotnet.myget.org/F/aspnetcore-dev/api/v3/index.json + https://dotnet.myget.org/F/aspnetcore-release/api/v3/index.json diff --git a/build/sources.props b/build/sources.props index 9feff29d09..5d66393335 100644 --- a/build/sources.props +++ b/build/sources.props @@ -1,11 +1,11 @@ - + $(DotNetRestoreSources) $(RestoreSources); - https://dotnet.myget.org/F/aspnetcore-dev/api/v3/index.json; + https://dotnet.myget.org/F/aspnetcore-release/api/v3/index.json; https://dotnet.myget.org/F/aspnetcore-tools/api/v3/index.json; diff --git a/korebuild-lock.txt b/korebuild-lock.txt index 2146d006d7..a474bc0e35 100644 --- a/korebuild-lock.txt +++ b/korebuild-lock.txt @@ -1,2 +1,2 @@ -version:2.1.0-preview1-15661 -commithash:c9349d4c8a495d3085d9b879214d80f2f45e2193 +version:2.1.0-preview1-15679 +commithash:5347461137cb45a77ddcc0b55b2478092de43338 From 8fb433d276a2ce76e706cf26391abb0c02fa24a5 Mon Sep 17 00:00:00 2001 From: Pranav K Date: Wed, 24 Jan 2018 15:00:28 -0800 Subject: [PATCH 182/221] Updating version to preview2 --- version.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.props b/version.props index 5c4a7c32d1..370d5ababd 100644 --- a/version.props +++ b/version.props @@ -1,7 +1,7 @@ 2.1.0 - preview1 + preview2 $(VersionPrefix) $(VersionPrefix)-$(VersionSuffix)-final t000 From 829db1aae540b51ac3b5e369ae8b13863e63ef73 Mon Sep 17 00:00:00 2001 From: Nate McMaster Date: Wed, 31 Jan 2018 15:01:12 -0800 Subject: [PATCH 183/221] Update dependencies.props to 2.1.0-preview-28193, build tools to 2.1.0-preview1-1010 [ci skip] Scripted changes: - updated travis and appveyor.yml files to only build dev, ci, and release branches - updated dependencies.props - updated korebuild-lock.txt - updated korebuild.json to release/2.1 channel --- .appveyor.yml | 15 +++++++-------- .travis.yml | 23 ++++++++++++----------- build/dependencies.props | 10 +++++----- korebuild-lock.txt | 4 ++-- korebuild.json | 4 ++-- 5 files changed, 28 insertions(+), 28 deletions(-) diff --git a/.appveyor.yml b/.appveyor.yml index 46038786c9..4eea96ab69 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -1,18 +1,17 @@ init: - - git config --global core.autocrlf true +- git config --global core.autocrlf true branches: only: - - master - - release - - dev - - /^(.*\/)?ci-.*$/ + - dev + - /^release\/.*$/ + - /^(.*\/)?ci-.*$/ build_script: - - ps: .\run.ps1 default-build +- ps: .\run.ps1 default-build clone_depth: 1 environment: global: DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true DOTNET_CLI_TELEMETRY_OPTOUT: 1 -test: off -deploy: off +test: 'off' +deploy: 'off' os: Visual Studio 2017 diff --git a/.travis.yml b/.travis.yml index b10be14215..64bdbb4441 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,24 +3,25 @@ sudo: false dist: trusty env: global: - - DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true - - DOTNET_CLI_TELEMETRY_OPTOUT: 1 + - DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true + - DOTNET_CLI_TELEMETRY_OPTOUT: 1 mono: none os: - - linux - - osx +- linux +- osx osx_image: xcode8.2 addons: apt: packages: - - libunwind8 + - libunwind8 branches: only: - - master - - release - - dev - - /^(.*\/)?ci-.*$/ + - dev + - /^release\/.*$/ + - /^(.*\/)?ci-.*$/ before_install: - - if test "$TRAVIS_OS_NAME" == "osx"; then brew update; brew install openssl; ln -s /usr/local/opt/openssl/lib/libcrypto.1.0.0.dylib /usr/local/lib/; ln -s /usr/local/opt/openssl/lib/libssl.1.0.0.dylib /usr/local/lib/; fi +- if test "$TRAVIS_OS_NAME" == "osx"; then brew update; brew install openssl; ln -s + /usr/local/opt/openssl/lib/libcrypto.1.0.0.dylib /usr/local/lib/; ln -s /usr/local/opt/openssl/lib/libssl.1.0.0.dylib + /usr/local/lib/; fi script: - - ./build.sh +- ./build.sh diff --git a/build/dependencies.props b/build/dependencies.props index 5382af18d5..9c5ea2b351 100644 --- a/build/dependencies.props +++ b/build/dependencies.props @@ -3,12 +3,12 @@ $(MSBuildAllProjects);$(MSBuildThisFileFullPath) - 2.1.0-preview1-15679 - 2.1.0-preview1-28153 - 4.5.0-preview1-26112-01 - 2.1.0-preview1-28153 + 2.1.0-preview1-1010 + 2.1.0-preview1-28193 + 4.5.0-preview1-26119-06 + 2.1.0-preview1-28193 2.0.0 - 2.1.0-preview1-26115-03 + 2.1.0-preview1-26122-01 15.3.0 4.7.49 10.0.1 diff --git a/korebuild-lock.txt b/korebuild-lock.txt index a474bc0e35..851bfbf203 100644 --- a/korebuild-lock.txt +++ b/korebuild-lock.txt @@ -1,2 +1,2 @@ -version:2.1.0-preview1-15679 -commithash:5347461137cb45a77ddcc0b55b2478092de43338 +version:2.1.0-preview1-1010 +commithash:75ca924dfbd673c38841025b04c4dcd93b84f56d diff --git a/korebuild.json b/korebuild.json index bd5d51a51b..678d8bb948 100644 --- a/korebuild.json +++ b/korebuild.json @@ -1,4 +1,4 @@ { - "$schema": "https://raw.githubusercontent.com/aspnet/BuildTools/dev/tools/korebuild.schema.json", - "channel": "dev" + "$schema": "https://raw.githubusercontent.com/aspnet/BuildTools/release/2.1/tools/korebuild.schema.json", + "channel": "release/2.1" } From 9bdbac7049d530e1f25f6b95ec8c78c04d3b1702 Mon Sep 17 00:00:00 2001 From: "ASP.NET CI" Date: Thu, 1 Feb 2018 03:42:02 +0000 Subject: [PATCH 184/221] Update dependencies.props [auto-updated: dependencies] --- build/dependencies.props | 10 +++++----- korebuild-lock.txt | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/build/dependencies.props b/build/dependencies.props index 8ebfd2751f..4aa9e9db7f 100644 --- a/build/dependencies.props +++ b/build/dependencies.props @@ -3,12 +3,12 @@ $(MSBuildAllProjects);$(MSBuildThisFileFullPath) - 2.1.0-preview1-15651 - 2.1.0-preview1-27965 - 4.5.0-preview1-26016-05 - 2.1.0-preview1-27965 + 2.1.0-preview2-15692 + 2.1.0-preview2-28215 + 4.5.0-preview2-26130-01 + 2.1.0-preview2-28215 2.0.0 - 2.1.0-preview1-26016-05 + 2.1.0-preview2-26130-04 15.3.0 4.7.49 10.0.1 diff --git a/korebuild-lock.txt b/korebuild-lock.txt index 2146d006d7..232cb858c2 100644 --- a/korebuild-lock.txt +++ b/korebuild-lock.txt @@ -1,2 +1,2 @@ -version:2.1.0-preview1-15661 -commithash:c9349d4c8a495d3085d9b879214d80f2f45e2193 +version:2.1.0-preview2-15692 +commithash:5d9f445ce3f8492451a6f461df7e739bbed6a7f8 From a063328ba2c7eab3427dddb068547a99d07ee11b Mon Sep 17 00:00:00 2001 From: "ASP.NET CI" Date: Sat, 3 Feb 2018 02:51:35 +0000 Subject: [PATCH 185/221] Update dependencies.props [auto-updated: dependencies] --- build/dependencies.props | 6 +++--- korebuild-lock.txt | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/build/dependencies.props b/build/dependencies.props index 4aa9e9db7f..875796c3b7 100644 --- a/build/dependencies.props +++ b/build/dependencies.props @@ -3,10 +3,10 @@ $(MSBuildAllProjects);$(MSBuildThisFileFullPath) - 2.1.0-preview2-15692 - 2.1.0-preview2-28215 + 2.1.0-preview2-15694 + 2.1.0-preview2-30020 4.5.0-preview2-26130-01 - 2.1.0-preview2-28215 + 2.1.0-preview2-30020 2.0.0 2.1.0-preview2-26130-04 15.3.0 diff --git a/korebuild-lock.txt b/korebuild-lock.txt index 232cb858c2..6f294ef0e6 100644 --- a/korebuild-lock.txt +++ b/korebuild-lock.txt @@ -1,2 +1,2 @@ -version:2.1.0-preview2-15692 -commithash:5d9f445ce3f8492451a6f461df7e739bbed6a7f8 +version:2.1.0-preview2-15694 +commithash:f61af02b48e89592c9aadb7ebaebe84228666c3b From 6d0dfc114552ab09b1dd1afac133ae5107b7d32d Mon Sep 17 00:00:00 2001 From: "ASP.NET CI" Date: Fri, 9 Feb 2018 11:48:21 -0800 Subject: [PATCH 186/221] Update dependencies.props [auto-updated: dependencies] --- build/dependencies.props | 6 +++--- korebuild-lock.txt | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/build/dependencies.props b/build/dependencies.props index 875796c3b7..399130aab9 100644 --- a/build/dependencies.props +++ b/build/dependencies.props @@ -3,10 +3,10 @@ $(MSBuildAllProjects);$(MSBuildThisFileFullPath) - 2.1.0-preview2-15694 - 2.1.0-preview2-30020 + 2.1.0-preview2-15698 + 2.1.0-preview2-30066 4.5.0-preview2-26130-01 - 2.1.0-preview2-30020 + 2.1.0-preview2-30066 2.0.0 2.1.0-preview2-26130-04 15.3.0 diff --git a/korebuild-lock.txt b/korebuild-lock.txt index 6f294ef0e6..3e2b56b91b 100644 --- a/korebuild-lock.txt +++ b/korebuild-lock.txt @@ -1,2 +1,2 @@ -version:2.1.0-preview2-15694 -commithash:f61af02b48e89592c9aadb7ebaebe84228666c3b +version:2.1.0-preview2-15698 +commithash:7216e5068cb1957e09d45fcbe58a744dd5c2de73 From 55169b1c92400bfbe1347ccf7d6e6379c244af19 Mon Sep 17 00:00:00 2001 From: "ASP.NET CI" Date: Sun, 11 Feb 2018 12:29:38 -0800 Subject: [PATCH 187/221] Update dependencies.props [auto-updated: dependencies] --- build/dependencies.props | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/build/dependencies.props b/build/dependencies.props index 399130aab9..31af71a3d5 100644 --- a/build/dependencies.props +++ b/build/dependencies.props @@ -4,9 +4,9 @@ 2.1.0-preview2-15698 - 2.1.0-preview2-30066 + 2.1.0-preview2-30077 4.5.0-preview2-26130-01 - 2.1.0-preview2-30066 + 2.1.0-preview2-30077 2.0.0 2.1.0-preview2-26130-04 15.3.0 @@ -14,7 +14,7 @@ 10.0.1 0.8.0 2.3.1 - 2.3.1 + 2.4.0-beta.1.build3945 From 686b15825db4368e4738bfaa337d35ce2b138d6d Mon Sep 17 00:00:00 2001 From: "ASP.NET CI" Date: Sun, 18 Feb 2018 12:22:41 -0800 Subject: [PATCH 188/221] Update dependencies.props [auto-updated: dependencies] --- build/dependencies.props | 6 +++--- korebuild-lock.txt | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/build/dependencies.props b/build/dependencies.props index 31af71a3d5..ffa9c07cb7 100644 --- a/build/dependencies.props +++ b/build/dependencies.props @@ -3,10 +3,10 @@ $(MSBuildAllProjects);$(MSBuildThisFileFullPath) - 2.1.0-preview2-15698 - 2.1.0-preview2-30077 + 2.1.0-preview2-15707 + 2.1.0-preview2-30131 4.5.0-preview2-26130-01 - 2.1.0-preview2-30077 + 2.1.0-preview2-30131 2.0.0 2.1.0-preview2-26130-04 15.3.0 diff --git a/korebuild-lock.txt b/korebuild-lock.txt index 3e2b56b91b..89d0ad3d15 100644 --- a/korebuild-lock.txt +++ b/korebuild-lock.txt @@ -1,2 +1,2 @@ -version:2.1.0-preview2-15698 -commithash:7216e5068cb1957e09d45fcbe58a744dd5c2de73 +version:2.1.0-preview2-15707 +commithash:e74e53f129ab34332947fea7ac7b7591b027cb22 From d851546646260e5f7d94d655175d118fff7df368 Mon Sep 17 00:00:00 2001 From: Pranav K Date: Wed, 21 Feb 2018 18:27:01 -0800 Subject: [PATCH 189/221] Use FeatureBranchVersionSuffix when generating VersionSuffix --- version.props | 1 + 1 file changed, 1 insertion(+) diff --git a/version.props b/version.props index 370d5ababd..65c8a07e37 100644 --- a/version.props +++ b/version.props @@ -5,6 +5,7 @@ $(VersionPrefix) $(VersionPrefix)-$(VersionSuffix)-final t000 + $(VersionSuffix)-$([System.Text.RegularExpressions.Regex]::Replace('$(FeatureBranchVersionSuffix)', '[^\w-]', '-')) $(VersionSuffix)-$(BuildNumber) From a1b6c4c7aad396bdd887448de21b41229a268c5f Mon Sep 17 00:00:00 2001 From: "ASP.NET CI" Date: Mon, 26 Feb 2018 11:06:37 -0800 Subject: [PATCH 190/221] Update dependencies.props [auto-updated: dependencies] --- build/dependencies.props | 8 ++++---- korebuild-lock.txt | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/build/dependencies.props b/build/dependencies.props index ffa9c07cb7..4ada242a87 100644 --- a/build/dependencies.props +++ b/build/dependencies.props @@ -3,13 +3,13 @@ $(MSBuildAllProjects);$(MSBuildThisFileFullPath) - 2.1.0-preview2-15707 - 2.1.0-preview2-30131 + 2.1.0-preview2-15721 + 2.1.0-preview2-30187 4.5.0-preview2-26130-01 - 2.1.0-preview2-30131 + 2.1.0-preview2-30187 2.0.0 2.1.0-preview2-26130-04 - 15.3.0 + 15.6.0 4.7.49 10.0.1 0.8.0 diff --git a/korebuild-lock.txt b/korebuild-lock.txt index 89d0ad3d15..e6c7fddffa 100644 --- a/korebuild-lock.txt +++ b/korebuild-lock.txt @@ -1,2 +1,2 @@ -version:2.1.0-preview2-15707 -commithash:e74e53f129ab34332947fea7ac7b7591b027cb22 +version:2.1.0-preview2-15721 +commithash:f9bb4be59e39938ec59a6975257e26099b0d03c1 From 63f03228106c61b6af2965c874f09758f7a5439e Mon Sep 17 00:00:00 2001 From: Ajay Bhargav Baaskaran Date: Tue, 27 Feb 2018 12:41:38 -0800 Subject: [PATCH 191/221] Allow whitespace and backslash in path --- .../Internal/PathHelpers.cs | 7 ++--- .../JsonPatchDocument.cs | 12 ++++----- ...nPatchDocumentJsonPropertyAttributeTest.cs | 26 +++++++++++++++++++ 3 files changed, 36 insertions(+), 9 deletions(-) diff --git a/src/Microsoft.AspNetCore.JsonPatch/Internal/PathHelpers.cs b/src/Microsoft.AspNetCore.JsonPatch/Internal/PathHelpers.cs index d46314c148..f0afedb60e 100644 --- a/src/Microsoft.AspNetCore.JsonPatch/Internal/PathHelpers.cs +++ b/src/Microsoft.AspNetCore.JsonPatch/Internal/PathHelpers.cs @@ -2,23 +2,24 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using Microsoft.AspNetCore.JsonPatch.Exceptions; +using System; namespace Microsoft.AspNetCore.JsonPatch.Internal { internal static class PathHelpers { - internal static string NormalizePath(string path) + internal static string ValidateAndNormalizePath(string path) { // check for most common path errors on create. This is not // absolutely necessary, but it allows us to already catch mistakes // on creation of the patch document rather than on execute. - if (path.Contains("//") || path.Contains(" ") || path.Contains("\\")) + if (path.Contains("//")) { throw new JsonPatchException(Resources.FormatInvalidValueForPath(path), null); } - if (!(path.StartsWith("/"))) + if (!path.StartsWith("/", StringComparison.Ordinal)) { return "/" + path; } diff --git a/src/Microsoft.AspNetCore.JsonPatch/JsonPatchDocument.cs b/src/Microsoft.AspNetCore.JsonPatch/JsonPatchDocument.cs index 4420e576bf..b6539caae8 100644 --- a/src/Microsoft.AspNetCore.JsonPatch/JsonPatchDocument.cs +++ b/src/Microsoft.AspNetCore.JsonPatch/JsonPatchDocument.cs @@ -60,7 +60,7 @@ namespace Microsoft.AspNetCore.JsonPatch throw new ArgumentNullException(nameof(path)); } - Operations.Add(new Operation("add", PathHelpers.NormalizePath(path), null, value)); + Operations.Add(new Operation("add", PathHelpers.ValidateAndNormalizePath(path), null, value)); return this; } @@ -77,7 +77,7 @@ namespace Microsoft.AspNetCore.JsonPatch throw new ArgumentNullException(nameof(path)); } - Operations.Add(new Operation("remove", PathHelpers.NormalizePath(path), null, null)); + Operations.Add(new Operation("remove", PathHelpers.ValidateAndNormalizePath(path), null, null)); return this; } @@ -95,7 +95,7 @@ namespace Microsoft.AspNetCore.JsonPatch throw new ArgumentNullException(nameof(path)); } - Operations.Add(new Operation("replace", PathHelpers.NormalizePath(path), null, value)); + Operations.Add(new Operation("replace", PathHelpers.ValidateAndNormalizePath(path), null, value)); return this; } @@ -113,7 +113,7 @@ namespace Microsoft.AspNetCore.JsonPatch throw new ArgumentNullException(nameof(path)); } - Operations.Add(new Operation("test", PathHelpers.NormalizePath(path), null, value)); + Operations.Add(new Operation("test", PathHelpers.ValidateAndNormalizePath(path), null, value)); return this; } @@ -136,7 +136,7 @@ namespace Microsoft.AspNetCore.JsonPatch throw new ArgumentNullException(nameof(path)); } - Operations.Add(new Operation("move", PathHelpers.NormalizePath(path), PathHelpers.NormalizePath(from))); + Operations.Add(new Operation("move", PathHelpers.ValidateAndNormalizePath(path), PathHelpers.ValidateAndNormalizePath(from))); return this; } @@ -159,7 +159,7 @@ namespace Microsoft.AspNetCore.JsonPatch throw new ArgumentNullException(nameof(path)); } - Operations.Add(new Operation("copy", PathHelpers.NormalizePath(path), PathHelpers.NormalizePath(from))); + Operations.Add(new Operation("copy", PathHelpers.ValidateAndNormalizePath(path), PathHelpers.ValidateAndNormalizePath(from))); return this; } diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/JsonPatchDocumentJsonPropertyAttributeTest.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/JsonPatchDocumentJsonPropertyAttributeTest.cs index f5d6377989..a9c3d8500b 100644 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/JsonPatchDocumentJsonPropertyAttributeTest.cs +++ b/test/Microsoft.AspNetCore.JsonPatch.Test/JsonPatchDocumentJsonPropertyAttributeTest.cs @@ -24,6 +24,23 @@ namespace Microsoft.AspNetCore.JsonPatch Assert.Equal("/AnotherName", pathToCheck); } + [Fact] + public void Add_RespectsJsonPropertyAttribute_WithDotWhitespaceAndBackslashInName() + { + // Arrange + var obj = new JsonPropertyObjectWithStrangeNames(); + var patchDocument = new JsonPatchDocument(); + + // Act + patchDocument.Add("/First Name.", "John"); + patchDocument.Add("Last\\Name", "Doe"); + patchDocument.ApplyTo(obj); + + // Assert + Assert.Equal("John", obj.FirstName); + Assert.Equal("Doe", obj.LastName); + } + [Fact] public void Move_FallsbackToPropertyName_WhenJsonPropertyAttributeName_IsEmpty() { @@ -46,6 +63,15 @@ namespace Microsoft.AspNetCore.JsonPatch public string Name { get; set; } } + private class JsonPropertyObjectWithStrangeNames + { + [JsonProperty("First Name.")] + public string FirstName { get; set; } + + [JsonProperty("Last\\Name")] + public string LastName { get; set; } + } + private class JsonPropertyWithNoPropertyName { [JsonProperty] From a2c82ff883b77fca85d43b3ece416166339a2472 Mon Sep 17 00:00:00 2001 From: Pranav K Date: Tue, 6 Mar 2018 10:04:32 -0800 Subject: [PATCH 192/221] Use dotnet-core feed in repos --- build/sources.props | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/build/sources.props b/build/sources.props index 9feff29d09..9215df9751 100644 --- a/build/sources.props +++ b/build/sources.props @@ -1,10 +1,11 @@ - + $(DotNetRestoreSources) $(RestoreSources); + https://dotnet.myget.org/F/dotnet-core/api/v3/index.json; https://dotnet.myget.org/F/aspnetcore-dev/api/v3/index.json; https://dotnet.myget.org/F/aspnetcore-tools/api/v3/index.json; From 93817a51930e4734b6fa22025afbdc7df48abeae Mon Sep 17 00:00:00 2001 From: Pranav K Date: Tue, 6 Mar 2018 10:04:32 -0800 Subject: [PATCH 193/221] Prepend FeatureBranchVersionPrefix if FeatureBranchVersionSuffix is specified --- version.props | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/version.props b/version.props index 65c8a07e37..a11ea1ed52 100644 --- a/version.props +++ b/version.props @@ -5,7 +5,8 @@ $(VersionPrefix) $(VersionPrefix)-$(VersionSuffix)-final t000 - $(VersionSuffix)-$([System.Text.RegularExpressions.Regex]::Replace('$(FeatureBranchVersionSuffix)', '[^\w-]', '-')) + a- + $(FeatureBranchVersionPrefix)$(VersionSuffix)-$([System.Text.RegularExpressions.Regex]::Replace('$(FeatureBranchVersionSuffix)', '[^\w-]', '-')) $(VersionSuffix)-$(BuildNumber) From 1f29add11975cb7858a6845fbf76b6f571099d64 Mon Sep 17 00:00:00 2001 From: "ASP.NET CI" Date: Thu, 8 Mar 2018 13:05:01 -0800 Subject: [PATCH 194/221] Update dependencies.props [auto-updated: dependencies] --- build/dependencies.props | 10 +++++----- korebuild-lock.txt | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/build/dependencies.props b/build/dependencies.props index 4ada242a87..9335150db5 100644 --- a/build/dependencies.props +++ b/build/dependencies.props @@ -3,12 +3,12 @@ $(MSBuildAllProjects);$(MSBuildThisFileFullPath) - 2.1.0-preview2-15721 - 2.1.0-preview2-30187 - 4.5.0-preview2-26130-01 - 2.1.0-preview2-30187 + 2.1.0-preview2-15728 + 2.1.0-preview2-30272 + 4.5.0-preview2-26224-02 + 2.1.0-preview2-30272 2.0.0 - 2.1.0-preview2-26130-04 + 2.1.0-preview2-26225-03 15.6.0 4.7.49 10.0.1 diff --git a/korebuild-lock.txt b/korebuild-lock.txt index e6c7fddffa..138d848db1 100644 --- a/korebuild-lock.txt +++ b/korebuild-lock.txt @@ -1,2 +1,2 @@ -version:2.1.0-preview2-15721 -commithash:f9bb4be59e39938ec59a6975257e26099b0d03c1 +version:2.1.0-preview2-15728 +commithash:393377068ddcf51dfee0536536d455f57a828b06 From 416dc545af13192f78e6ad286554b1c7923adfcc Mon Sep 17 00:00:00 2001 From: Pranav K Date: Fri, 16 Mar 2018 11:15:22 -0700 Subject: [PATCH 195/221] Branching for 2.1.0-preview2 --- build/dependencies.props | 10 +++++----- build/repo.props | 4 ++-- build/sources.props | 2 +- korebuild-lock.txt | 4 ++-- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/build/dependencies.props b/build/dependencies.props index 9335150db5..e11bd088f7 100644 --- a/build/dependencies.props +++ b/build/dependencies.props @@ -3,12 +3,12 @@ $(MSBuildAllProjects);$(MSBuildThisFileFullPath) - 2.1.0-preview2-15728 - 2.1.0-preview2-30272 - 4.5.0-preview2-26224-02 - 2.1.0-preview2-30272 + 2.1.0-preview2-15742 + 2.1.0-preview2-30355 + 4.5.0-preview2-26313-01 + 2.1.0-preview2-30355 2.0.0 - 2.1.0-preview2-26225-03 + 2.1.0-preview2-26314-02 15.6.0 4.7.49 10.0.1 diff --git a/build/repo.props b/build/repo.props index 78b0ce5879..d94ff7d00d 100644 --- a/build/repo.props +++ b/build/repo.props @@ -1,10 +1,10 @@ - + Internal.AspNetCore.Universe.Lineup - https://dotnet.myget.org/F/aspnetcore-dev/api/v3/index.json + https://dotnet.myget.org/F/aspnetcore-release/api/v3/index.json diff --git a/build/sources.props b/build/sources.props index 9215df9751..36045f12b5 100644 --- a/build/sources.props +++ b/build/sources.props @@ -6,7 +6,7 @@ $(RestoreSources); https://dotnet.myget.org/F/dotnet-core/api/v3/index.json; - https://dotnet.myget.org/F/aspnetcore-dev/api/v3/index.json; + https://dotnet.myget.org/F/aspnetcore-release/api/v3/index.json; https://dotnet.myget.org/F/aspnetcore-tools/api/v3/index.json; diff --git a/korebuild-lock.txt b/korebuild-lock.txt index 138d848db1..e40ef6651b 100644 --- a/korebuild-lock.txt +++ b/korebuild-lock.txt @@ -1,2 +1,2 @@ -version:2.1.0-preview2-15728 -commithash:393377068ddcf51dfee0536536d455f57a828b06 +version:2.1.0-preview2-15742 +commithash:21fbb0f2c3fe4a9216e2d59632b98cfd7d685962 From 39959a72ef8cc0a5cbbb7d078d6cabd592cd6a05 Mon Sep 17 00:00:00 2001 From: Pranav K Date: Fri, 16 Mar 2018 11:26:57 -0700 Subject: [PATCH 196/221] Update version prefix to preview3 --- version.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.props b/version.props index a11ea1ed52..24f2b00a0a 100644 --- a/version.props +++ b/version.props @@ -1,7 +1,7 @@ 2.1.0 - preview2 + preview3 $(VersionPrefix) $(VersionPrefix)-$(VersionSuffix)-final t000 From ed7c645939b3e9ca361b1af5a6c5bc0deeda22a1 Mon Sep 17 00:00:00 2001 From: Pranav K Date: Fri, 16 Mar 2018 12:30:53 -0700 Subject: [PATCH 197/221] Update KoreBuild channel --- korebuild.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/korebuild.json b/korebuild.json index bd5d51a51b..678d8bb948 100644 --- a/korebuild.json +++ b/korebuild.json @@ -1,4 +1,4 @@ { - "$schema": "https://raw.githubusercontent.com/aspnet/BuildTools/dev/tools/korebuild.schema.json", - "channel": "dev" + "$schema": "https://raw.githubusercontent.com/aspnet/BuildTools/release/2.1/tools/korebuild.schema.json", + "channel": "release/2.1" } From 94374a2af5d4e28daf124502b1e630b041506f2d Mon Sep 17 00:00:00 2001 From: "ASP.NET CI" Date: Sun, 25 Mar 2018 15:45:13 -0700 Subject: [PATCH 198/221] Update dependencies.props [auto-updated: dependencies] --- build/dependencies.props | 14 +++++++------- korebuild-lock.txt | 4 ++-- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/build/dependencies.props b/build/dependencies.props index 9335150db5..6678906caa 100644 --- a/build/dependencies.props +++ b/build/dependencies.props @@ -3,15 +3,15 @@ $(MSBuildAllProjects);$(MSBuildThisFileFullPath) - 2.1.0-preview2-15728 - 2.1.0-preview2-30272 - 4.5.0-preview2-26224-02 - 2.1.0-preview2-30272 + 2.1.0-preview3-17001 + 2.1.0-preview3-32037 + 4.5.0-preview2-26313-01 + 2.1.0-preview3-32037 2.0.0 - 2.1.0-preview2-26225-03 - 15.6.0 + 2.1.0-preview2-26314-02 + 15.6.1 4.7.49 - 10.0.1 + 11.0.1 0.8.0 2.3.1 2.4.0-beta.1.build3945 diff --git a/korebuild-lock.txt b/korebuild-lock.txt index 138d848db1..3a326c7d58 100644 --- a/korebuild-lock.txt +++ b/korebuild-lock.txt @@ -1,2 +1,2 @@ -version:2.1.0-preview2-15728 -commithash:393377068ddcf51dfee0536536d455f57a828b06 +version:2.1.0-preview3-17001 +commithash:dda68c56abf0d3b911fe6a2315872c446b314585 From fc1b2ab5489337be36e56b86b3ab7cf71f6596f2 Mon Sep 17 00:00:00 2001 From: "Nate McMaster (automated)" Date: Wed, 28 Mar 2018 10:52:05 -0700 Subject: [PATCH 199/221] Update dependencies.props [auto-updated: dependencies] --- build/dependencies.props | 14 +++++++------- korebuild-lock.txt | 4 ++-- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/build/dependencies.props b/build/dependencies.props index e11bd088f7..47dc1d300d 100644 --- a/build/dependencies.props +++ b/build/dependencies.props @@ -3,15 +3,15 @@ $(MSBuildAllProjects);$(MSBuildThisFileFullPath) - 2.1.0-preview2-15742 - 2.1.0-preview2-30355 - 4.5.0-preview2-26313-01 - 2.1.0-preview2-30355 + 2.1.0-preview2-15749 + 2.1.0-preview2-30478 + 4.5.0-preview2-26326-04 + 2.1.0-preview2-30478 2.0.0 - 2.1.0-preview2-26314-02 - 15.6.0 + 2.1.0-preview2-26326-03 + 15.6.1 4.7.49 - 10.0.1 + 11.0.2 0.8.0 2.3.1 2.4.0-beta.1.build3945 diff --git a/korebuild-lock.txt b/korebuild-lock.txt index e40ef6651b..b8e036fe2c 100644 --- a/korebuild-lock.txt +++ b/korebuild-lock.txt @@ -1,2 +1,2 @@ -version:2.1.0-preview2-15742 -commithash:21fbb0f2c3fe4a9216e2d59632b98cfd7d685962 +version:2.1.0-preview2-15749 +commithash:5544c9ab20fa5e24b9e155d8958a3c3b6f5f9df9 From 9969beccbcf471d8269f40a2196fe25e0f066716 Mon Sep 17 00:00:00 2001 From: "ASP.NET CI" Date: Tue, 3 Apr 2018 22:32:28 +0000 Subject: [PATCH 200/221] Update dependencies.props [auto-updated: dependencies] --- build/dependencies.props | 12 ++++++------ korebuild-lock.txt | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/build/dependencies.props b/build/dependencies.props index 6678906caa..dec32e9f37 100644 --- a/build/dependencies.props +++ b/build/dependencies.props @@ -3,15 +3,15 @@ $(MSBuildAllProjects);$(MSBuildThisFileFullPath) - 2.1.0-preview3-17001 - 2.1.0-preview3-32037 - 4.5.0-preview2-26313-01 - 2.1.0-preview3-32037 + 2.1.0-preview3-17002 + 2.1.0-preview3-32110 + 4.5.0-preview3-26331-02 + 2.1.0-preview3-32110 2.0.0 - 2.1.0-preview2-26314-02 + 2.1.0-preview3-26331-01 15.6.1 4.7.49 - 11.0.1 + 11.0.2 0.8.0 2.3.1 2.4.0-beta.1.build3945 diff --git a/korebuild-lock.txt b/korebuild-lock.txt index 3a326c7d58..b3af0b8bce 100644 --- a/korebuild-lock.txt +++ b/korebuild-lock.txt @@ -1,2 +1,2 @@ -version:2.1.0-preview3-17001 -commithash:dda68c56abf0d3b911fe6a2315872c446b314585 +version:2.1.0-preview3-17002 +commithash:b8e4e6ab104adc94c0719bb74229870e9b584a7f From 4ca59af5469ddd6c38d80430944c19b13b8936f5 Mon Sep 17 00:00:00 2001 From: "ASP.NET CI" Date: Sun, 15 Apr 2018 14:16:23 -0700 Subject: [PATCH 201/221] Update dependencies.props [auto-updated: dependencies] --- build/dependencies.props | 10 +++++----- korebuild-lock.txt | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/build/dependencies.props b/build/dependencies.props index dec32e9f37..1fa3452a34 100644 --- a/build/dependencies.props +++ b/build/dependencies.props @@ -3,12 +3,12 @@ $(MSBuildAllProjects);$(MSBuildThisFileFullPath) - 2.1.0-preview3-17002 - 2.1.0-preview3-32110 - 4.5.0-preview3-26331-02 - 2.1.0-preview3-32110 + 2.1.0-preview3-17018 + 2.1.0-preview3-32233 + 4.5.0-preview3-26413-02 + 2.1.0-preview3-32233 2.0.0 - 2.1.0-preview3-26331-01 + 2.1.0-preview3-26413-05 15.6.1 4.7.49 11.0.2 diff --git a/korebuild-lock.txt b/korebuild-lock.txt index b3af0b8bce..b419d767b9 100644 --- a/korebuild-lock.txt +++ b/korebuild-lock.txt @@ -1,2 +1,2 @@ -version:2.1.0-preview3-17002 -commithash:b8e4e6ab104adc94c0719bb74229870e9b584a7f +version:2.1.0-preview3-17018 +commithash:af264ca131f212b5ba8aafbc5110fc0fc510a2be From 40d5c7f839f86a927bd39777e8b4198aafc098ee Mon Sep 17 00:00:00 2001 From: Ryan Brandenburg Date: Mon, 16 Apr 2018 16:58:44 -0700 Subject: [PATCH 202/221] Branching for 2.1.0-rc1 --- build/repo.props | 3 ++- korebuild.json | 4 ++-- version.props | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/build/repo.props b/build/repo.props index 78b0ce5879..dab1601c88 100644 --- a/build/repo.props +++ b/build/repo.props @@ -1,9 +1,10 @@ - + Internal.AspNetCore.Universe.Lineup + 2.1.0-rc1-* https://dotnet.myget.org/F/aspnetcore-dev/api/v3/index.json diff --git a/korebuild.json b/korebuild.json index bd5d51a51b..678d8bb948 100644 --- a/korebuild.json +++ b/korebuild.json @@ -1,4 +1,4 @@ { - "$schema": "https://raw.githubusercontent.com/aspnet/BuildTools/dev/tools/korebuild.schema.json", - "channel": "dev" + "$schema": "https://raw.githubusercontent.com/aspnet/BuildTools/release/2.1/tools/korebuild.schema.json", + "channel": "release/2.1" } diff --git a/version.props b/version.props index 24f2b00a0a..e27532787e 100644 --- a/version.props +++ b/version.props @@ -1,7 +1,7 @@ 2.1.0 - preview3 + rc1 $(VersionPrefix) $(VersionPrefix)-$(VersionSuffix)-final t000 From 6c6cd890865f4d6f61900c7274bd38bfca9d4f00 Mon Sep 17 00:00:00 2001 From: Nate McMaster Date: Thu, 19 Apr 2018 16:40:16 -0700 Subject: [PATCH 203/221] Set NETStandardImplicitPackageVersion via dependencies.props --- Directory.Build.targets | 1 + build/dependencies.props | 1 + 2 files changed, 2 insertions(+) diff --git a/Directory.Build.targets b/Directory.Build.targets index 894b1d0cf8..53b3f6e1da 100644 --- a/Directory.Build.targets +++ b/Directory.Build.targets @@ -2,5 +2,6 @@ $(MicrosoftNETCoreApp20PackageVersion) $(MicrosoftNETCoreApp21PackageVersion) + $(NETStandardLibrary20PackageVersion) diff --git a/build/dependencies.props b/build/dependencies.props index 1fa3452a34..89f812caa6 100644 --- a/build/dependencies.props +++ b/build/dependencies.props @@ -11,6 +11,7 @@ 2.1.0-preview3-26413-05 15.6.1 4.7.49 + 2.0.1 11.0.2 0.8.0 2.3.1 From 09232faae42de90b96180645f83f82a4989e91b3 Mon Sep 17 00:00:00 2001 From: "ASP.NET CI" Date: Thu, 19 Apr 2018 22:27:34 -0700 Subject: [PATCH 204/221] Update dependencies.props [auto-updated: dependencies] --- build/dependencies.props | 10 +++++----- korebuild-lock.txt | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/build/dependencies.props b/build/dependencies.props index 89f812caa6..649af28432 100644 --- a/build/dependencies.props +++ b/build/dependencies.props @@ -3,12 +3,12 @@ $(MSBuildAllProjects);$(MSBuildThisFileFullPath) - 2.1.0-preview3-17018 - 2.1.0-preview3-32233 - 4.5.0-preview3-26413-02 - 2.1.0-preview3-32233 + 2.1.0-rc1-15774 + 2.1.0-rc1-30613 + 4.5.0-rc1-26419-03 + 2.1.0-rc1-30613 2.0.0 - 2.1.0-preview3-26413-05 + 2.1.0-rc1-26419-02 15.6.1 4.7.49 2.0.1 diff --git a/korebuild-lock.txt b/korebuild-lock.txt index b419d767b9..9d4ef8c888 100644 --- a/korebuild-lock.txt +++ b/korebuild-lock.txt @@ -1,2 +1,2 @@ -version:2.1.0-preview3-17018 -commithash:af264ca131f212b5ba8aafbc5110fc0fc510a2be +version:2.1.0-rc1-15774 +commithash:ed5ca9de3c652347dbb0158a9a65eff3471d2114 From 4f3e31431a0c96d687b2ef41e436f878ae79db31 Mon Sep 17 00:00:00 2001 From: "Nate McMaster (automated)" Date: Mon, 30 Apr 2018 14:51:42 -0700 Subject: [PATCH 205/221] Bump version to 2.1.0-rtm --- version.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.props b/version.props index e27532787e..b9552451d8 100644 --- a/version.props +++ b/version.props @@ -1,7 +1,7 @@ 2.1.0 - rc1 + rtm $(VersionPrefix) $(VersionPrefix)-$(VersionSuffix)-final t000 From 54e6ffce343b4b6113e824ccbb4006f786ad8e8c Mon Sep 17 00:00:00 2001 From: "ASP.NET CI" Date: Fri, 4 May 2018 07:41:29 -0700 Subject: [PATCH 206/221] Update dependencies.props [auto-updated: dependencies] --- build/dependencies.props | 12 ++++++------ korebuild-lock.txt | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/build/dependencies.props b/build/dependencies.props index 649af28432..acedb0a6ca 100644 --- a/build/dependencies.props +++ b/build/dependencies.props @@ -3,15 +3,15 @@ $(MSBuildAllProjects);$(MSBuildThisFileFullPath) - 2.1.0-rc1-15774 - 2.1.0-rc1-30613 - 4.5.0-rc1-26419-03 - 2.1.0-rc1-30613 + 2.1.0-rtm-15783 + 2.1.0-rtm-30721 + 4.5.0-rtm-26502-02 + 2.1.0-rtm-30721 2.0.0 - 2.1.0-rc1-26419-02 + 2.1.0-rtm-26502-02 15.6.1 4.7.49 - 2.0.1 + 2.0.3 11.0.2 0.8.0 2.3.1 diff --git a/korebuild-lock.txt b/korebuild-lock.txt index 9d4ef8c888..3673744db9 100644 --- a/korebuild-lock.txt +++ b/korebuild-lock.txt @@ -1,2 +1,2 @@ -version:2.1.0-rc1-15774 -commithash:ed5ca9de3c652347dbb0158a9a65eff3471d2114 +version:2.1.0-rtm-15783 +commithash:5fc2b2f607f542a2ffde11c19825e786fc1a3774 From e3a21b2a92ddc8d971f4f21c617bb69ca0ae3761 Mon Sep 17 00:00:00 2001 From: "ASP.NET CI" Date: Tue, 29 May 2018 09:44:06 -0700 Subject: [PATCH 207/221] Update dependencies.props [auto-updated: dependencies] --- build/dependencies.props | 10 +++++----- korebuild-lock.txt | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/build/dependencies.props b/build/dependencies.props index acedb0a6ca..5b7c18bdae 100644 --- a/build/dependencies.props +++ b/build/dependencies.props @@ -3,12 +3,12 @@ $(MSBuildAllProjects);$(MSBuildThisFileFullPath) - 2.1.0-rtm-15783 - 2.1.0-rtm-30721 - 4.5.0-rtm-26502-02 - 2.1.0-rtm-30721 + 2.1.1-rtm-15790 + 2.1.0 + 4.5.0 + 2.1.0 2.0.0 - 2.1.0-rtm-26502-02 + 2.1.0 15.6.1 4.7.49 2.0.3 diff --git a/korebuild-lock.txt b/korebuild-lock.txt index 3673744db9..cd5b409a1e 100644 --- a/korebuild-lock.txt +++ b/korebuild-lock.txt @@ -1,2 +1,2 @@ -version:2.1.0-rtm-15783 -commithash:5fc2b2f607f542a2ffde11c19825e786fc1a3774 +version:2.1.1-rtm-15790 +commithash:274c65868e735f29f4078c1884c61c4371ee1fc0 From d89db5fcd7302d08a94a995f280fb30f715b0b16 Mon Sep 17 00:00:00 2001 From: Nate McMaster Date: Tue, 5 Jun 2018 09:11:39 -0700 Subject: [PATCH 208/221] Bumping version from 2.1.0 to 2.1.1 --- version.props | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/version.props b/version.props index b9552451d8..669c874829 100644 --- a/version.props +++ b/version.props @@ -1,6 +1,6 @@ - + - 2.1.0 + 2.1.1 rtm $(VersionPrefix) $(VersionPrefix)-$(VersionSuffix)-final From 1780662ac507c9b21bf7054bc1f68ccd07ed93ff Mon Sep 17 00:00:00 2001 From: "ASP.NET CI" Date: Tue, 12 Jun 2018 19:25:45 +0000 Subject: [PATCH 209/221] Update dependencies.props [auto-updated: dependencies] --- build/dependencies.props | 6 +++--- korebuild-lock.txt | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/build/dependencies.props b/build/dependencies.props index 5b7c18bdae..c7a3e03395 100644 --- a/build/dependencies.props +++ b/build/dependencies.props @@ -3,12 +3,12 @@ $(MSBuildAllProjects);$(MSBuildThisFileFullPath) - 2.1.1-rtm-15790 + 2.1.1-rtm-15793 2.1.0 4.5.0 - 2.1.0 + 2.1.1 2.0.0 - 2.1.0 + 2.1.1 15.6.1 4.7.49 2.0.3 diff --git a/korebuild-lock.txt b/korebuild-lock.txt index cd5b409a1e..bc84e0cd53 100644 --- a/korebuild-lock.txt +++ b/korebuild-lock.txt @@ -1,2 +1,2 @@ -version:2.1.1-rtm-15790 -commithash:274c65868e735f29f4078c1884c61c4371ee1fc0 +version:2.1.1-rtm-15793 +commithash:988313f4b064d6c69fc6f7b845b6384a6af3447a From 78fc55675861ee33f102bd601ac951eff9bdbad3 Mon Sep 17 00:00:00 2001 From: Ryan Brandenburg Date: Thu, 14 Jun 2018 10:28:12 -0700 Subject: [PATCH 210/221] Set 2.1 baselines --- .../baseline.netcore.json | 315 +++++++++++++----- 1 file changed, 230 insertions(+), 85 deletions(-) diff --git a/src/Microsoft.AspNetCore.JsonPatch/baseline.netcore.json b/src/Microsoft.AspNetCore.JsonPatch/baseline.netcore.json index c84771a03c..3d90a8f017 100644 --- a/src/Microsoft.AspNetCore.JsonPatch/baseline.netcore.json +++ b/src/Microsoft.AspNetCore.JsonPatch/baseline.netcore.json @@ -1,6 +1,73 @@ { - "AssemblyIdentity": "Microsoft.AspNetCore.JsonPatch, Version=1.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60", + "AssemblyIdentity": "Microsoft.AspNetCore.JsonPatch, Version=2.1.1.0, Culture=neutral, PublicKeyToken=adb9793829ddae60", "Types": [ + { + "Name": "Microsoft.AspNetCore.JsonPatch.JsonPatchProperty", + "Visibility": "Public", + "Kind": "Class", + "ImplementedInterfaces": [], + "Members": [ + { + "Kind": "Method", + "Name": "get_Property", + "Parameters": [], + "ReturnType": "Newtonsoft.Json.Serialization.JsonProperty", + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "set_Property", + "Parameters": [ + { + "Name": "value", + "Type": "Newtonsoft.Json.Serialization.JsonProperty" + } + ], + "ReturnType": "System.Void", + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "get_Parent", + "Parameters": [], + "ReturnType": "System.Object", + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "set_Parent", + "Parameters": [ + { + "Name": "value", + "Type": "System.Object" + } + ], + "ReturnType": "System.Void", + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Constructor", + "Name": ".ctor", + "Parameters": [ + { + "Name": "property", + "Type": "Newtonsoft.Json.Serialization.JsonProperty" + }, + { + "Name": "parent", + "Type": "System.Object" + } + ], + "Visibility": "Public", + "GenericParameter": [] + } + ], + "GenericParameters": [] + }, { "Name": "Microsoft.AspNetCore.JsonPatch.IJsonPatchDocument", "Visibility": "Public", @@ -127,6 +194,23 @@ "Visibility": "Public", "GenericParameter": [] }, + { + "Kind": "Method", + "Name": "Test", + "Parameters": [ + { + "Name": "path", + "Type": "System.String" + }, + { + "Name": "value", + "Type": "System.Object" + } + ], + "ReturnType": "Microsoft.AspNetCore.JsonPatch.JsonPatchDocument", + "Visibility": "Public", + "GenericParameter": [] + }, { "Kind": "Method", "Name": "Move", @@ -484,6 +568,79 @@ } ] }, + { + "Kind": "Method", + "Name": "Test", + "Parameters": [ + { + "Name": "path", + "Type": "System.Linq.Expressions.Expression>" + }, + { + "Name": "value", + "Type": "T0" + } + ], + "ReturnType": "Microsoft.AspNetCore.JsonPatch.JsonPatchDocument", + "Visibility": "Public", + "GenericParameter": [ + { + "ParameterName": "TProp", + "ParameterPosition": 0, + "BaseTypeOrInterfaces": [] + } + ] + }, + { + "Kind": "Method", + "Name": "Test", + "Parameters": [ + { + "Name": "path", + "Type": "System.Linq.Expressions.Expression>>" + }, + { + "Name": "value", + "Type": "T0" + }, + { + "Name": "position", + "Type": "System.Int32" + } + ], + "ReturnType": "Microsoft.AspNetCore.JsonPatch.JsonPatchDocument", + "Visibility": "Public", + "GenericParameter": [ + { + "ParameterName": "TProp", + "ParameterPosition": 0, + "BaseTypeOrInterfaces": [] + } + ] + }, + { + "Kind": "Method", + "Name": "Test", + "Parameters": [ + { + "Name": "path", + "Type": "System.Linq.Expressions.Expression>>" + }, + { + "Name": "value", + "Type": "T0" + } + ], + "ReturnType": "Microsoft.AspNetCore.JsonPatch.JsonPatchDocument", + "Visibility": "Public", + "GenericParameter": [ + { + "ParameterName": "TProp", + "ParameterPosition": 0, + "BaseTypeOrInterfaces": [] + } + ] + }, { "Kind": "Method", "Name": "Move", @@ -933,73 +1090,6 @@ ], "GenericParameters": [] }, - { - "Name": "Microsoft.AspNetCore.JsonPatch.JsonPatchProperty", - "Visibility": "Public", - "Kind": "Class", - "ImplementedInterfaces": [], - "Members": [ - { - "Kind": "Method", - "Name": "get_Property", - "Parameters": [], - "ReturnType": "Newtonsoft.Json.Serialization.JsonProperty", - "Visibility": "Public", - "GenericParameter": [] - }, - { - "Kind": "Method", - "Name": "set_Property", - "Parameters": [ - { - "Name": "value", - "Type": "Newtonsoft.Json.Serialization.JsonProperty" - } - ], - "ReturnType": "System.Void", - "Visibility": "Public", - "GenericParameter": [] - }, - { - "Kind": "Method", - "Name": "get_Parent", - "Parameters": [], - "ReturnType": "System.Object", - "Visibility": "Public", - "GenericParameter": [] - }, - { - "Kind": "Method", - "Name": "set_Parent", - "Parameters": [ - { - "Name": "value", - "Type": "System.Object" - } - ], - "ReturnType": "System.Void", - "Visibility": "Public", - "GenericParameter": [] - }, - { - "Kind": "Constructor", - "Name": ".ctor", - "Parameters": [ - { - "Name": "property", - "Type": "Newtonsoft.Json.Serialization.JsonProperty" - }, - { - "Name": "parent", - "Type": "System.Object" - } - ], - "Visibility": "Public", - "GenericParameter": [] - } - ], - "GenericParameters": [] - }, { "Name": "Microsoft.AspNetCore.JsonPatch.Operations.Operation", "Visibility": "Public", @@ -1355,6 +1445,13 @@ "Parameters": [], "GenericParameter": [], "Literal": "5" + }, + { + "Kind": "Field", + "Name": "Invalid", + "Parameters": [], + "GenericParameter": [], + "Literal": "6" } ], "GenericParameters": [] @@ -1694,29 +1791,41 @@ "GenericParameters": [] }, { - "Name": "Microsoft.AspNetCore.JsonPatch.Adapters.ObjectAdapter", + "Name": "Microsoft.AspNetCore.JsonPatch.Adapters.IObjectAdapterWithTest", "Visibility": "Public", - "Kind": "Class", + "Kind": "Interface", + "Abstract": true, "ImplementedInterfaces": [ "Microsoft.AspNetCore.JsonPatch.Adapters.IObjectAdapter" ], "Members": [ { "Kind": "Method", - "Name": "get_ContractResolver", - "Parameters": [], - "ReturnType": "Newtonsoft.Json.Serialization.IContractResolver", - "Visibility": "Public", + "Name": "Test", + "Parameters": [ + { + "Name": "operation", + "Type": "Microsoft.AspNetCore.JsonPatch.Operations.Operation" + }, + { + "Name": "objectToApplyTo", + "Type": "System.Object" + } + ], + "ReturnType": "System.Void", "GenericParameter": [] - }, - { - "Kind": "Method", - "Name": "get_LogErrorAction", - "Parameters": [], - "ReturnType": "System.Action", - "Visibility": "Public", - "GenericParameter": [] - }, + } + ], + "GenericParameters": [] + }, + { + "Name": "Microsoft.AspNetCore.JsonPatch.Adapters.ObjectAdapter", + "Visibility": "Public", + "Kind": "Class", + "ImplementedInterfaces": [ + "Microsoft.AspNetCore.JsonPatch.Adapters.IObjectAdapterWithTest" + ], + "Members": [ { "Kind": "Method", "Name": "Add", @@ -1737,6 +1846,26 @@ "Visibility": "Public", "GenericParameter": [] }, + { + "Kind": "Method", + "Name": "Copy", + "Parameters": [ + { + "Name": "operation", + "Type": "Microsoft.AspNetCore.JsonPatch.Operations.Operation" + }, + { + "Name": "objectToApplyTo", + "Type": "System.Object" + } + ], + "ReturnType": "System.Void", + "Sealed": true, + "Virtual": true, + "ImplementedInterface": "Microsoft.AspNetCore.JsonPatch.Adapters.IObjectAdapter", + "Visibility": "Public", + "GenericParameter": [] + }, { "Kind": "Method", "Name": "Move", @@ -1799,7 +1928,23 @@ }, { "Kind": "Method", - "Name": "Copy", + "Name": "get_ContractResolver", + "Parameters": [], + "ReturnType": "Newtonsoft.Json.Serialization.IContractResolver", + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "get_LogErrorAction", + "Parameters": [], + "ReturnType": "System.Action", + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "Test", "Parameters": [ { "Name": "operation", @@ -1813,7 +1958,7 @@ "ReturnType": "System.Void", "Sealed": true, "Virtual": true, - "ImplementedInterface": "Microsoft.AspNetCore.JsonPatch.Adapters.IObjectAdapter", + "ImplementedInterface": "Microsoft.AspNetCore.JsonPatch.Adapters.IObjectAdapterWithTest", "Visibility": "Public", "GenericParameter": [] }, From 5d39e86f1985d99d0c530e312d5b478ddc8682a4 Mon Sep 17 00:00:00 2001 From: Nate McMaster Date: Wed, 27 Jun 2018 13:39:48 -0700 Subject: [PATCH 211/221] Bumping version from 2.1.1 to 2.1.2 --- version.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.props b/version.props index 669c874829..478dfd16ed 100644 --- a/version.props +++ b/version.props @@ -1,6 +1,6 @@  - 2.1.1 + 2.1.2 rtm $(VersionPrefix) $(VersionPrefix)-$(VersionSuffix)-final From 3a16fe8d53d8fd8cf876854268071eba863f4f8d Mon Sep 17 00:00:00 2001 From: Nate McMaster Date: Wed, 11 Jul 2018 15:06:35 -0700 Subject: [PATCH 212/221] Reverting version from 2.1.2 back to 2.1.1 As a result of changing the way we apply servicing updates to aspnet core, this repo did not need the version bump because there are no planned product changes in this repo. --- version.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.props b/version.props index 478dfd16ed..669c874829 100644 --- a/version.props +++ b/version.props @@ -1,6 +1,6 @@  - 2.1.2 + 2.1.1 rtm $(VersionPrefix) $(VersionPrefix)-$(VersionSuffix)-final From 8177229ac88fd6f864a8819ac7e81b4cfc1c4df3 Mon Sep 17 00:00:00 2001 From: Nate McMaster Date: Wed, 11 Jul 2018 18:49:06 -0700 Subject: [PATCH 213/221] Updating dependencies to 2.1.2 and adding a section for pinned variable versions --- build/dependencies.props | 13 ++++++++++--- korebuild-lock.txt | 4 ++-- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/build/dependencies.props b/build/dependencies.props index c7a3e03395..d52f8aee1c 100644 --- a/build/dependencies.props +++ b/build/dependencies.props @@ -2,13 +2,15 @@ $(MSBuildAllProjects);$(MSBuildThisFileFullPath) - - 2.1.1-rtm-15793 + + + + 2.1.3-rtm-15802 2.1.0 4.5.0 2.1.1 2.0.0 - 2.1.1 + 2.1.2 15.6.1 4.7.49 2.0.3 @@ -17,5 +19,10 @@ 2.3.1 2.4.0-beta.1.build3945 + + + + + diff --git a/korebuild-lock.txt b/korebuild-lock.txt index bc84e0cd53..251c227c83 100644 --- a/korebuild-lock.txt +++ b/korebuild-lock.txt @@ -1,2 +1,2 @@ -version:2.1.1-rtm-15793 -commithash:988313f4b064d6c69fc6f7b845b6384a6af3447a +version:2.1.3-rtm-15802 +commithash:a7c08b45b440a7d2058a0aa1eaa3eb6ba811976a From 218064c300a7cf5a76669e133340a98a0c5517a5 Mon Sep 17 00:00:00 2001 From: Nate McMaster Date: Thu, 12 Jul 2018 11:54:35 -0700 Subject: [PATCH 214/221] Pin version variables to the ASP.NET Core 2.1.2 baseline This reverts our previous policy of cascading versions on all servicing updates. This moves variables into the 'pinned' section, and points them to the latest stable release (versions that were used at the time of the 2.1.2 release). --- build/dependencies.props | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/build/dependencies.props b/build/dependencies.props index d52f8aee1c..55c598b536 100644 --- a/build/dependencies.props +++ b/build/dependencies.props @@ -4,11 +4,9 @@ - + 2.1.3-rtm-15802 - 2.1.0 4.5.0 - 2.1.1 2.0.0 2.1.2 15.6.1 @@ -24,5 +22,8 @@ - - + + 2.1.0 + 2.1.1 + + \ No newline at end of file From 74d9728e95b7ed2108e8e1974443ba286859de78 Mon Sep 17 00:00:00 2001 From: Nate McMaster Date: Fri, 9 Nov 2018 12:49:58 -0800 Subject: [PATCH 215/221] Reorganize source code in preparation to move into aspnet/AspNetCore Prior to reorganization, this source code was found in https://github.com/aspnet/JsonPatch/tree/218064c300a7cf5a76669e133340a98a0c5517a5 --- .appveyor.yml | 17 -- .gitattributes | 52 ---- .github/ISSUE_TEMPLATE.md | 3 - .gitignore | 39 --- .travis.yml | 27 -- CONTRIBUTING.md | 4 - Directory.Build.props | 20 -- Directory.Build.targets | 7 - JsonPatch.sln | 63 ----- LICENSE.txt | 14 -- NuGet.config | 7 - NuGetPackageVerifier.json | 7 - README.md | 9 - build.cmd | 2 - build.sh | 8 - build/Key.snk | Bin 596 -> 0 bytes build/dependencies.props | 29 --- build/repo.props | 15 -- build/sources.props | 17 -- korebuild-lock.txt | 2 - korebuild.json | 4 - run.cmd | 2 - run.ps1 | 196 --------------- run.sh | 231 ------------------ src/Directory.Build.props | 7 - .../JsonPatch/src}/Adapters/IObjectAdapter.cs | 0 .../src}/Adapters/IObjectAdapterWithTest.cs | 0 .../JsonPatch/src}/Adapters/ObjectAdapter.cs | 0 .../Converters/JsonPatchDocumentConverter.cs | 0 .../TypedJsonPatchDocumentConverter.cs | 0 .../src}/Exceptions/JsonPatchException.cs | 0 .../JsonPatch/src}/Helpers/GetValueResult.cs | 0 .../src}/Helpers/JsonPatchProperty.cs | 0 .../JsonPatch/src}/IJsonPatchDocument.cs | 0 .../src}/Internal/ConversionResult.cs | 0 .../src}/Internal/ConversionResultProvider.cs | 0 .../src}/Internal/DictionaryAdapterOfTU.cs | 0 .../src}/Internal/DynamicObjectAdapter.cs | 0 .../JsonPatch/src}/Internal/ErrorReporter.cs | 0 .../JsonPatch/src}/Internal/IAdapter.cs | 0 .../JsonPatch/src}/Internal/ListAdapter.cs | 0 .../JsonPatch/src}/Internal/ObjectVisitor.cs | 0 .../JsonPatch/src}/Internal/ParsedPath.cs | 0 .../JsonPatch/src}/Internal/PathHelpers.cs | 0 .../JsonPatch/src}/Internal/PocoAdapter.cs | 0 .../JsonPatch/src}/JsonPatchDocument.cs | 0 .../JsonPatch/src}/JsonPatchDocumentOfT.cs | 0 .../JsonPatch/src}/JsonPatchError.cs | 0 .../Microsoft.AspNetCore.JsonPatch.csproj | 6 +- .../JsonPatch/src}/Operations/Operation.cs | 0 .../src}/Operations/OperationBase.cs | 0 .../JsonPatch/src}/Operations/OperationOfT.cs | 0 .../src}/Operations/OperationType.cs | 0 .../JsonPatch/src/Properties/AssemblyInfo.cs | 7 + .../src}/Properties/Resources.Designer.cs | 0 .../JsonPatch/src}/Resources.resx | 0 .../JsonPatch/src}/baseline.netcore.json | 0 .../test}/CustomNamingStrategyTests.cs | 0 .../AnonymousObjectIntegrationTest.cs | 0 .../DictionaryIntegrationTest.cs | 0 .../DynamicObjectIntegrationTest.cs | 0 .../ExpandoObjectIntegrationTest.cs | 0 .../IntegrationTests/ListIntegrationTest.cs | 0 .../NestedObjectIntegrationTest.cs | 0 .../SimpleObjectIntegrationTest.cs | 0 .../test}/Internal/DictionaryAdapterTest.cs | 0 .../Internal/DynamicObjectAdapterTest.cs | 0 .../test}/Internal/ListAdapterTest.cs | 0 .../test}/Internal/ObjectVisitorTest.cs | 0 .../test}/Internal/ParsedPathTests.cs | 0 .../test}/Internal/PocoAdapterTest.cs | 0 .../test}/JsonPatchDocumentGetPathTest.cs | 0 ...nPatchDocumentJsonPropertyAttributeTest.cs | 0 .../JsonPatch/test}/JsonPatchDocumentTest.cs | 0 ...icrosoft.AspNetCore.JsonPatch.Tests.csproj | 11 + .../JsonPatch/test}/OperationBaseTests.cs | 0 .../JsonPatch/test}/TestErrorLogger.cs | 0 .../test}/TestObjectModels/Customer.cs | 0 .../TestObjectModels/DynamicTestObject.cs | 0 .../test}/TestObjectModels/InheritedObject.cs | 0 .../test}/TestObjectModels/NestedObject.cs | 0 .../test}/TestObjectModels/SimpleObject.cs | 0 .../SimpleObjectWithNestedObject.cs | 0 .../Properties/AssemblyInfo.cs | 7 - test/Directory.Build.props | 18 -- ...Microsoft.AspNetCore.JsonPatch.Test.csproj | 20 -- version.props | 12 - 87 files changed, 21 insertions(+), 842 deletions(-) delete mode 100644 .appveyor.yml delete mode 100644 .gitattributes delete mode 100644 .github/ISSUE_TEMPLATE.md delete mode 100644 .gitignore delete mode 100644 .travis.yml delete mode 100644 CONTRIBUTING.md delete mode 100644 Directory.Build.props delete mode 100644 Directory.Build.targets delete mode 100644 JsonPatch.sln delete mode 100644 LICENSE.txt delete mode 100644 NuGet.config delete mode 100644 NuGetPackageVerifier.json delete mode 100644 README.md delete mode 100644 build.cmd delete mode 100755 build.sh delete mode 100644 build/Key.snk delete mode 100644 build/dependencies.props delete mode 100644 build/repo.props delete mode 100644 build/sources.props delete mode 100644 korebuild-lock.txt delete mode 100644 korebuild.json delete mode 100644 run.cmd delete mode 100644 run.ps1 delete mode 100755 run.sh delete mode 100644 src/Directory.Build.props rename src/{Microsoft.AspNetCore.JsonPatch => Features/JsonPatch/src}/Adapters/IObjectAdapter.cs (100%) rename src/{Microsoft.AspNetCore.JsonPatch => Features/JsonPatch/src}/Adapters/IObjectAdapterWithTest.cs (100%) rename src/{Microsoft.AspNetCore.JsonPatch => Features/JsonPatch/src}/Adapters/ObjectAdapter.cs (100%) rename src/{Microsoft.AspNetCore.JsonPatch => Features/JsonPatch/src}/Converters/JsonPatchDocumentConverter.cs (100%) rename src/{Microsoft.AspNetCore.JsonPatch => Features/JsonPatch/src}/Converters/TypedJsonPatchDocumentConverter.cs (100%) rename src/{Microsoft.AspNetCore.JsonPatch => Features/JsonPatch/src}/Exceptions/JsonPatchException.cs (100%) rename src/{Microsoft.AspNetCore.JsonPatch => Features/JsonPatch/src}/Helpers/GetValueResult.cs (100%) rename src/{Microsoft.AspNetCore.JsonPatch => Features/JsonPatch/src}/Helpers/JsonPatchProperty.cs (100%) rename src/{Microsoft.AspNetCore.JsonPatch => Features/JsonPatch/src}/IJsonPatchDocument.cs (100%) rename src/{Microsoft.AspNetCore.JsonPatch => Features/JsonPatch/src}/Internal/ConversionResult.cs (100%) rename src/{Microsoft.AspNetCore.JsonPatch => Features/JsonPatch/src}/Internal/ConversionResultProvider.cs (100%) rename src/{Microsoft.AspNetCore.JsonPatch => Features/JsonPatch/src}/Internal/DictionaryAdapterOfTU.cs (100%) rename src/{Microsoft.AspNetCore.JsonPatch => Features/JsonPatch/src}/Internal/DynamicObjectAdapter.cs (100%) rename src/{Microsoft.AspNetCore.JsonPatch => Features/JsonPatch/src}/Internal/ErrorReporter.cs (100%) rename src/{Microsoft.AspNetCore.JsonPatch => Features/JsonPatch/src}/Internal/IAdapter.cs (100%) rename src/{Microsoft.AspNetCore.JsonPatch => Features/JsonPatch/src}/Internal/ListAdapter.cs (100%) rename src/{Microsoft.AspNetCore.JsonPatch => Features/JsonPatch/src}/Internal/ObjectVisitor.cs (100%) rename src/{Microsoft.AspNetCore.JsonPatch => Features/JsonPatch/src}/Internal/ParsedPath.cs (100%) rename src/{Microsoft.AspNetCore.JsonPatch => Features/JsonPatch/src}/Internal/PathHelpers.cs (100%) rename src/{Microsoft.AspNetCore.JsonPatch => Features/JsonPatch/src}/Internal/PocoAdapter.cs (100%) rename src/{Microsoft.AspNetCore.JsonPatch => Features/JsonPatch/src}/JsonPatchDocument.cs (100%) rename src/{Microsoft.AspNetCore.JsonPatch => Features/JsonPatch/src}/JsonPatchDocumentOfT.cs (100%) rename src/{Microsoft.AspNetCore.JsonPatch => Features/JsonPatch/src}/JsonPatchError.cs (100%) rename src/{Microsoft.AspNetCore.JsonPatch => Features/JsonPatch/src}/Microsoft.AspNetCore.JsonPatch.csproj (51%) rename src/{Microsoft.AspNetCore.JsonPatch => Features/JsonPatch/src}/Operations/Operation.cs (100%) rename src/{Microsoft.AspNetCore.JsonPatch => Features/JsonPatch/src}/Operations/OperationBase.cs (100%) rename src/{Microsoft.AspNetCore.JsonPatch => Features/JsonPatch/src}/Operations/OperationOfT.cs (100%) rename src/{Microsoft.AspNetCore.JsonPatch => Features/JsonPatch/src}/Operations/OperationType.cs (100%) create mode 100644 src/Features/JsonPatch/src/Properties/AssemblyInfo.cs rename src/{Microsoft.AspNetCore.JsonPatch => Features/JsonPatch/src}/Properties/Resources.Designer.cs (100%) rename src/{Microsoft.AspNetCore.JsonPatch => Features/JsonPatch/src}/Resources.resx (100%) rename src/{Microsoft.AspNetCore.JsonPatch => Features/JsonPatch/src}/baseline.netcore.json (100%) rename {test/Microsoft.AspNetCore.JsonPatch.Test => src/Features/JsonPatch/test}/CustomNamingStrategyTests.cs (100%) rename {test/Microsoft.AspNetCore.JsonPatch.Test => src/Features/JsonPatch/test}/IntegrationTests/AnonymousObjectIntegrationTest.cs (100%) rename {test/Microsoft.AspNetCore.JsonPatch.Test => src/Features/JsonPatch/test}/IntegrationTests/DictionaryIntegrationTest.cs (100%) rename {test/Microsoft.AspNetCore.JsonPatch.Test => src/Features/JsonPatch/test}/IntegrationTests/DynamicObjectIntegrationTest.cs (100%) rename {test/Microsoft.AspNetCore.JsonPatch.Test => src/Features/JsonPatch/test}/IntegrationTests/ExpandoObjectIntegrationTest.cs (100%) rename {test/Microsoft.AspNetCore.JsonPatch.Test => src/Features/JsonPatch/test}/IntegrationTests/ListIntegrationTest.cs (100%) rename {test/Microsoft.AspNetCore.JsonPatch.Test => src/Features/JsonPatch/test}/IntegrationTests/NestedObjectIntegrationTest.cs (100%) rename {test/Microsoft.AspNetCore.JsonPatch.Test => src/Features/JsonPatch/test}/IntegrationTests/SimpleObjectIntegrationTest.cs (100%) rename {test/Microsoft.AspNetCore.JsonPatch.Test => src/Features/JsonPatch/test}/Internal/DictionaryAdapterTest.cs (100%) rename {test/Microsoft.AspNetCore.JsonPatch.Test => src/Features/JsonPatch/test}/Internal/DynamicObjectAdapterTest.cs (100%) rename {test/Microsoft.AspNetCore.JsonPatch.Test => src/Features/JsonPatch/test}/Internal/ListAdapterTest.cs (100%) rename {test/Microsoft.AspNetCore.JsonPatch.Test => src/Features/JsonPatch/test}/Internal/ObjectVisitorTest.cs (100%) rename {test/Microsoft.AspNetCore.JsonPatch.Test => src/Features/JsonPatch/test}/Internal/ParsedPathTests.cs (100%) rename {test/Microsoft.AspNetCore.JsonPatch.Test => src/Features/JsonPatch/test}/Internal/PocoAdapterTest.cs (100%) rename {test/Microsoft.AspNetCore.JsonPatch.Test => src/Features/JsonPatch/test}/JsonPatchDocumentGetPathTest.cs (100%) rename {test/Microsoft.AspNetCore.JsonPatch.Test => src/Features/JsonPatch/test}/JsonPatchDocumentJsonPropertyAttributeTest.cs (100%) rename {test/Microsoft.AspNetCore.JsonPatch.Test => src/Features/JsonPatch/test}/JsonPatchDocumentTest.cs (100%) create mode 100644 src/Features/JsonPatch/test/Microsoft.AspNetCore.JsonPatch.Tests.csproj rename {test/Microsoft.AspNetCore.JsonPatch.Test => src/Features/JsonPatch/test}/OperationBaseTests.cs (100%) rename {test/Microsoft.AspNetCore.JsonPatch.Test => src/Features/JsonPatch/test}/TestErrorLogger.cs (100%) rename {test/Microsoft.AspNetCore.JsonPatch.Test => src/Features/JsonPatch/test}/TestObjectModels/Customer.cs (100%) rename {test/Microsoft.AspNetCore.JsonPatch.Test => src/Features/JsonPatch/test}/TestObjectModels/DynamicTestObject.cs (100%) rename {test/Microsoft.AspNetCore.JsonPatch.Test => src/Features/JsonPatch/test}/TestObjectModels/InheritedObject.cs (100%) rename {test/Microsoft.AspNetCore.JsonPatch.Test => src/Features/JsonPatch/test}/TestObjectModels/NestedObject.cs (100%) rename {test/Microsoft.AspNetCore.JsonPatch.Test => src/Features/JsonPatch/test}/TestObjectModels/SimpleObject.cs (100%) rename {test/Microsoft.AspNetCore.JsonPatch.Test => src/Features/JsonPatch/test}/TestObjectModels/SimpleObjectWithNestedObject.cs (100%) delete mode 100644 src/Microsoft.AspNetCore.JsonPatch/Properties/AssemblyInfo.cs delete mode 100644 test/Directory.Build.props delete mode 100644 test/Microsoft.AspNetCore.JsonPatch.Test/Microsoft.AspNetCore.JsonPatch.Test.csproj delete mode 100644 version.props diff --git a/.appveyor.yml b/.appveyor.yml deleted file mode 100644 index 4eea96ab69..0000000000 --- a/.appveyor.yml +++ /dev/null @@ -1,17 +0,0 @@ -init: -- git config --global core.autocrlf true -branches: - only: - - dev - - /^release\/.*$/ - - /^(.*\/)?ci-.*$/ -build_script: -- ps: .\run.ps1 default-build -clone_depth: 1 -environment: - global: - DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true - DOTNET_CLI_TELEMETRY_OPTOUT: 1 -test: 'off' -deploy: 'off' -os: Visual Studio 2017 diff --git a/.gitattributes b/.gitattributes deleted file mode 100644 index d4ee1cb7f3..0000000000 --- a/.gitattributes +++ /dev/null @@ -1,52 +0,0 @@ -*.doc diff=astextplain -*.DOC diff=astextplain -*.docx diff=astextplain -*.DOCX diff=astextplain -*.dot diff=astextplain -*.DOT diff=astextplain -*.pdf diff=astextplain -*.PDF diff=astextplain -*.rtf diff=astextplain -*.RTF diff=astextplain - -*.jpg binary -*.png binary -*.gif binary - -*.cs text=auto diff=csharp -*.vb text=auto -*.resx text=auto -*.c text=auto -*.cpp text=auto -*.cxx text=auto -*.h text=auto -*.hxx text=auto -*.py text=auto -*.rb text=auto -*.java text=auto -*.html text=auto -*.htm text=auto -*.css text=auto -*.scss text=auto -*.sass text=auto -*.less text=auto -*.js text=auto -*.lisp text=auto -*.clj text=auto -*.sql text=auto -*.php text=auto -*.lua text=auto -*.m text=auto -*.asm text=auto -*.erl text=auto -*.fs text=auto -*.fsx text=auto -*.hs text=auto - -*.csproj text=auto -*.vbproj text=auto -*.fsproj text=auto -*.dbproj text=auto -*.sln text=auto eol=crlf - -*.sh eol=lf diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md deleted file mode 100644 index 101a084f0a..0000000000 --- a/.github/ISSUE_TEMPLATE.md +++ /dev/null @@ -1,3 +0,0 @@ -THIS ISSUE TRACKER IS CLOSED - please log new issues here: https://github.com/aspnet/Home/issues - -For information about this change, see https://github.com/aspnet/Announcements/issues/283 diff --git a/.gitignore b/.gitignore deleted file mode 100644 index 2e8ec28064..0000000000 --- a/.gitignore +++ /dev/null @@ -1,39 +0,0 @@ -[Oo]bj/ -[Bb]in/ -TestResults/ -.nuget/ -.build/ -.testPublish/ -*.sln.ide/ -_ReSharper.*/ -packages/ -artifacts/ -PublishProfiles/ -.vs/ -bower_components/ -node_modules/ -debugSettings.json -project.lock.json -*.user -*.suo -*.cache -*.docstates -_ReSharper.* -nuget.exe -*net45.csproj -*net451.csproj -*k10.csproj -*.psess -*.vsp -*.pidb -*.userprefs -*DS_Store -*.ncrunchsolution -*.*sdf -*.ipch -.settings -*.sln.ide -node_modules -*launchSettings.json -*.orig -global.json diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 64bdbb4441..0000000000 --- a/.travis.yml +++ /dev/null @@ -1,27 +0,0 @@ -language: csharp -sudo: false -dist: trusty -env: - global: - - DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true - - DOTNET_CLI_TELEMETRY_OPTOUT: 1 -mono: none -os: -- linux -- osx -osx_image: xcode8.2 -addons: - apt: - packages: - - libunwind8 -branches: - only: - - dev - - /^release\/.*$/ - - /^(.*\/)?ci-.*$/ -before_install: -- if test "$TRAVIS_OS_NAME" == "osx"; then brew update; brew install openssl; ln -s - /usr/local/opt/openssl/lib/libcrypto.1.0.0.dylib /usr/local/lib/; ln -s /usr/local/opt/openssl/lib/libssl.1.0.0.dylib - /usr/local/lib/; fi -script: -- ./build.sh diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md deleted file mode 100644 index 64ff041d5c..0000000000 --- a/CONTRIBUTING.md +++ /dev/null @@ -1,4 +0,0 @@ -Contributing -====== - -Information on contributing to this repo is in the [Contributing Guide](https://github.com/aspnet/Home/blob/dev/CONTRIBUTING.md) in the Home repo. diff --git a/Directory.Build.props b/Directory.Build.props deleted file mode 100644 index 88b93729bb..0000000000 --- a/Directory.Build.props +++ /dev/null @@ -1,20 +0,0 @@ - - - - - - - - - Microsoft ASP.NET Core - https://github.com/aspnet/JsonPatch - git - $(MSBuildThisFileDirectory) - $(MSBuildThisFileDirectory)build\Key.snk - true - true - true - - diff --git a/Directory.Build.targets b/Directory.Build.targets deleted file mode 100644 index 53b3f6e1da..0000000000 --- a/Directory.Build.targets +++ /dev/null @@ -1,7 +0,0 @@ - - - $(MicrosoftNETCoreApp20PackageVersion) - $(MicrosoftNETCoreApp21PackageVersion) - $(NETStandardLibrary20PackageVersion) - - diff --git a/JsonPatch.sln b/JsonPatch.sln deleted file mode 100644 index f0b6a578f1..0000000000 --- a/JsonPatch.sln +++ /dev/null @@ -1,63 +0,0 @@ -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 15 -VisualStudioVersion = 15.0.26815.3 -MinimumVisualStudioVersion = 15.0.26730.03 -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{430B59ED-F960-4D3A-8FFE-3370008E168D}" - ProjectSection(SolutionItems) = preProject - src\Directory.Build.props = src\Directory.Build.props - EndProjectSection -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{36CD6341-AB44-44EB-B3AA-BF98C89FECDD}" - ProjectSection(SolutionItems) = preProject - test\Directory.Build.props = test\Directory.Build.props - EndProjectSection -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.JsonPatch", "src\Microsoft.AspNetCore.JsonPatch\Microsoft.AspNetCore.JsonPatch.csproj", "{4D55F4D8-633B-462F-A5B1-FEB84BD2D534}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.JsonPatch.Test", "test\Microsoft.AspNetCore.JsonPatch.Test\Microsoft.AspNetCore.JsonPatch.Test.csproj", "{81C20848-E063-4E12-AC40-0B55A532C16C}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{C430C499-382D-47BD-B351-CF8F89C08CD2}" - ProjectSection(SolutionItems) = preProject - .appveyor.yml = .appveyor.yml - .gitattributes = .gitattributes - .gitignore = .gitignore - .travis.yml = .travis.yml - build.cmd = build.cmd - build.ps1 = build.ps1 - build.sh = build.sh - CONTRIBUTING.md = CONTRIBUTING.md - Directory.Build.props = Directory.Build.props - Directory.Build.targets = Directory.Build.targets - LICENSE.txt = LICENSE.txt - NuGet.config = NuGet.config - NuGetPackageVerifier.json = NuGetPackageVerifier.json - README.md = README.md - version.xml = version.xml - EndProjectSection -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Release|Any CPU = Release|Any CPU - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {4D55F4D8-633B-462F-A5B1-FEB84BD2D534}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {4D55F4D8-633B-462F-A5B1-FEB84BD2D534}.Debug|Any CPU.Build.0 = Debug|Any CPU - {4D55F4D8-633B-462F-A5B1-FEB84BD2D534}.Release|Any CPU.ActiveCfg = Release|Any CPU - {4D55F4D8-633B-462F-A5B1-FEB84BD2D534}.Release|Any CPU.Build.0 = Release|Any CPU - {81C20848-E063-4E12-AC40-0B55A532C16C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {81C20848-E063-4E12-AC40-0B55A532C16C}.Debug|Any CPU.Build.0 = Debug|Any CPU - {81C20848-E063-4E12-AC40-0B55A532C16C}.Release|Any CPU.ActiveCfg = Release|Any CPU - {81C20848-E063-4E12-AC40-0B55A532C16C}.Release|Any CPU.Build.0 = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(NestedProjects) = preSolution - {4D55F4D8-633B-462F-A5B1-FEB84BD2D534} = {430B59ED-F960-4D3A-8FFE-3370008E168D} - {81C20848-E063-4E12-AC40-0B55A532C16C} = {36CD6341-AB44-44EB-B3AA-BF98C89FECDD} - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {9FFA3EB9-8740-4434-BC8C-F3D595161B59} - EndGlobalSection -EndGlobal diff --git a/LICENSE.txt b/LICENSE.txt deleted file mode 100644 index 7b2956ecee..0000000000 --- a/LICENSE.txt +++ /dev/null @@ -1,14 +0,0 @@ -Copyright (c) .NET Foundation and Contributors - -All rights reserved. - -Licensed under the Apache License, Version 2.0 (the "License"); you may not use -this file except in compliance with the License. You may obtain a copy of the -License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software distributed -under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR -CONDITIONS OF ANY KIND, either express or implied. See the License for the -specific language governing permissions and limitations under the License. diff --git a/NuGet.config b/NuGet.config deleted file mode 100644 index e32bddfd51..0000000000 --- a/NuGet.config +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/NuGetPackageVerifier.json b/NuGetPackageVerifier.json deleted file mode 100644 index b153ab1515..0000000000 --- a/NuGetPackageVerifier.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "Default": { - "rules": [ - "DefaultCompositeRule" - ] - } -} \ No newline at end of file diff --git a/README.md b/README.md deleted file mode 100644 index 6c27b76d9d..0000000000 --- a/README.md +++ /dev/null @@ -1,9 +0,0 @@ -JsonPatch -=== -AppVeyor: [![AppVeyor](https://ci.appveyor.com/api/projects/status/51gggjks5k3q6pr5/branch/dev?svg=true)](https://ci.appveyor.com/project/aspnetci/JsonPatch/branch/dev) - -Travis: [![Travis](https://travis-ci.org/aspnet/JsonPatch.svg?branch=dev)](https://travis-ci.org/aspnet/JsonPatch) - -This project is part of ASP.NET Core. You can find samples, documentation and getting started instructions for ASP.NET Core at the [Home](https://github.com/aspnet/home) repo. - - diff --git a/build.cmd b/build.cmd deleted file mode 100644 index c0050bda12..0000000000 --- a/build.cmd +++ /dev/null @@ -1,2 +0,0 @@ -@ECHO OFF -PowerShell -NoProfile -NoLogo -ExecutionPolicy unrestricted -Command "[System.Threading.Thread]::CurrentThread.CurrentCulture = ''; [System.Threading.Thread]::CurrentThread.CurrentUICulture = '';& '%~dp0run.ps1' default-build %*; exit $LASTEXITCODE" diff --git a/build.sh b/build.sh deleted file mode 100755 index 98a4b22765..0000000000 --- a/build.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/usr/bin/env bash - -set -euo pipefail -DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" - -# Call "sync" between "chmod" and execution to prevent "text file busy" error in Docker (aufs) -chmod +x "$DIR/run.sh"; sync -"$DIR/run.sh" default-build "$@" diff --git a/build/Key.snk b/build/Key.snk deleted file mode 100644 index e10e4889c125d3120cd9e81582243d70f7cbb806..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 596 zcmV-a0;~N80ssI2Bme+XQ$aES1ONa50098=Iw=HCsnz~#iVhm& zj%TU(_THUee?3yHBjk$37ysB?i5#7WD$={H zV4B!OxRPrb|8)HPg~A}8P>^=#y<)56#=E&NzcjOtPK~<4n6GHt=K$ro*T(lhby_@U zEk(hLzk1H)0yXj{A_5>fk-TgNoP|q6(tP2xo8zt8i%212CWM#AeCd?`hS|4~L({h~Moo(~vy&3Z z1uI}`fd^*>o=rwbAGymj6RM^pZm(*Kfhs+Y1#`-2JPWZMK8@;ZWCk2+9bX4YP);~fj-BU*R zQPvWv$89!{Rl9wM+zR>_TSkn^voYxA?2G iKnV#iZ6Ah`K>b=@=IjYJXrxL124zR(38)nxe+&q_$QXwJ diff --git a/build/dependencies.props b/build/dependencies.props deleted file mode 100644 index 55c598b536..0000000000 --- a/build/dependencies.props +++ /dev/null @@ -1,29 +0,0 @@ - - - $(MSBuildAllProjects);$(MSBuildThisFileFullPath) - - - - - 2.1.3-rtm-15802 - 4.5.0 - 2.0.0 - 2.1.2 - 15.6.1 - 4.7.49 - 2.0.3 - 11.0.2 - 0.8.0 - 2.3.1 - 2.4.0-beta.1.build3945 - - - - - - - - 2.1.0 - 2.1.1 - - \ No newline at end of file diff --git a/build/repo.props b/build/repo.props deleted file mode 100644 index dab1601c88..0000000000 --- a/build/repo.props +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - Internal.AspNetCore.Universe.Lineup - 2.1.0-rc1-* - https://dotnet.myget.org/F/aspnetcore-dev/api/v3/index.json - - - - - - - diff --git a/build/sources.props b/build/sources.props deleted file mode 100644 index 9215df9751..0000000000 --- a/build/sources.props +++ /dev/null @@ -1,17 +0,0 @@ - - - - - $(DotNetRestoreSources) - - $(RestoreSources); - https://dotnet.myget.org/F/dotnet-core/api/v3/index.json; - https://dotnet.myget.org/F/aspnetcore-dev/api/v3/index.json; - https://dotnet.myget.org/F/aspnetcore-tools/api/v3/index.json; - - - $(RestoreSources); - https://api.nuget.org/v3/index.json; - - - diff --git a/korebuild-lock.txt b/korebuild-lock.txt deleted file mode 100644 index 251c227c83..0000000000 --- a/korebuild-lock.txt +++ /dev/null @@ -1,2 +0,0 @@ -version:2.1.3-rtm-15802 -commithash:a7c08b45b440a7d2058a0aa1eaa3eb6ba811976a diff --git a/korebuild.json b/korebuild.json deleted file mode 100644 index 678d8bb948..0000000000 --- a/korebuild.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "$schema": "https://raw.githubusercontent.com/aspnet/BuildTools/release/2.1/tools/korebuild.schema.json", - "channel": "release/2.1" -} diff --git a/run.cmd b/run.cmd deleted file mode 100644 index d52d5c7e68..0000000000 --- a/run.cmd +++ /dev/null @@ -1,2 +0,0 @@ -@ECHO OFF -PowerShell -NoProfile -NoLogo -ExecutionPolicy unrestricted -Command "[System.Threading.Thread]::CurrentThread.CurrentCulture = ''; [System.Threading.Thread]::CurrentThread.CurrentUICulture = '';& '%~dp0run.ps1' %*; exit $LASTEXITCODE" diff --git a/run.ps1 b/run.ps1 deleted file mode 100644 index 27dcf848f8..0000000000 --- a/run.ps1 +++ /dev/null @@ -1,196 +0,0 @@ -#!/usr/bin/env powershell -#requires -version 4 - -<# -.SYNOPSIS -Executes KoreBuild commands. - -.DESCRIPTION -Downloads korebuild if required. Then executes the KoreBuild command. To see available commands, execute with `-Command help`. - -.PARAMETER Command -The KoreBuild command to run. - -.PARAMETER Path -The folder to build. Defaults to the folder containing this script. - -.PARAMETER Channel -The channel of KoreBuild to download. Overrides the value from the config file. - -.PARAMETER DotNetHome -The directory where .NET Core tools will be stored. - -.PARAMETER ToolsSource -The base url where build tools can be downloaded. Overrides the value from the config file. - -.PARAMETER Update -Updates KoreBuild to the latest version even if a lock file is present. - -.PARAMETER ConfigFile -The path to the configuration file that stores values. Defaults to korebuild.json. - -.PARAMETER ToolsSourceSuffix -The Suffix to append to the end of the ToolsSource. Useful for query strings in blob stores. - -.PARAMETER Arguments -Arguments to be passed to the command - -.NOTES -This function will create a file $PSScriptRoot/korebuild-lock.txt. This lock file can be committed to source, but does not have to be. -When the lockfile is not present, KoreBuild will create one using latest available version from $Channel. - -The $ConfigFile is expected to be an JSON file. It is optional, and the configuration values in it are optional as well. Any options set -in the file are overridden by command line parameters. - -.EXAMPLE -Example config file: -```json -{ - "$schema": "https://raw.githubusercontent.com/aspnet/BuildTools/dev/tools/korebuild.schema.json", - "channel": "dev", - "toolsSource": "https://aspnetcore.blob.core.windows.net/buildtools" -} -``` -#> -[CmdletBinding(PositionalBinding = $false)] -param( - [Parameter(Mandatory = $true, Position = 0)] - [string]$Command, - [string]$Path = $PSScriptRoot, - [Alias('c')] - [string]$Channel, - [Alias('d')] - [string]$DotNetHome, - [Alias('s')] - [string]$ToolsSource, - [Alias('u')] - [switch]$Update, - [string]$ConfigFile, - [string]$ToolsSourceSuffix, - [Parameter(ValueFromRemainingArguments = $true)] - [string[]]$Arguments -) - -Set-StrictMode -Version 2 -$ErrorActionPreference = 'Stop' - -# -# Functions -# - -function Get-KoreBuild { - - $lockFile = Join-Path $Path 'korebuild-lock.txt' - - if (!(Test-Path $lockFile) -or $Update) { - Get-RemoteFile "$ToolsSource/korebuild/channels/$Channel/latest.txt" $lockFile $ToolsSourceSuffix - } - - $version = Get-Content $lockFile | Where-Object { $_ -like 'version:*' } | Select-Object -first 1 - if (!$version) { - Write-Error "Failed to parse version from $lockFile. Expected a line that begins with 'version:'" - } - $version = $version.TrimStart('version:').Trim() - $korebuildPath = Join-Paths $DotNetHome ('buildtools', 'korebuild', $version) - - if (!(Test-Path $korebuildPath)) { - Write-Host -ForegroundColor Magenta "Downloading KoreBuild $version" - New-Item -ItemType Directory -Path $korebuildPath | Out-Null - $remotePath = "$ToolsSource/korebuild/artifacts/$version/korebuild.$version.zip" - - try { - $tmpfile = Join-Path ([IO.Path]::GetTempPath()) "KoreBuild-$([guid]::NewGuid()).zip" - Get-RemoteFile $remotePath $tmpfile $ToolsSourceSuffix - if (Get-Command -Name 'Expand-Archive' -ErrorAction Ignore) { - # Use built-in commands where possible as they are cross-plat compatible - Expand-Archive -Path $tmpfile -DestinationPath $korebuildPath - } - else { - # Fallback to old approach for old installations of PowerShell - Add-Type -AssemblyName System.IO.Compression.FileSystem - [System.IO.Compression.ZipFile]::ExtractToDirectory($tmpfile, $korebuildPath) - } - } - catch { - Remove-Item -Recurse -Force $korebuildPath -ErrorAction Ignore - throw - } - finally { - Remove-Item $tmpfile -ErrorAction Ignore - } - } - - return $korebuildPath -} - -function Join-Paths([string]$path, [string[]]$childPaths) { - $childPaths | ForEach-Object { $path = Join-Path $path $_ } - return $path -} - -function Get-RemoteFile([string]$RemotePath, [string]$LocalPath, [string]$RemoteSuffix) { - if ($RemotePath -notlike 'http*') { - Copy-Item $RemotePath $LocalPath - return - } - - $retries = 10 - while ($retries -gt 0) { - $retries -= 1 - try { - Invoke-WebRequest -UseBasicParsing -Uri $($RemotePath + $RemoteSuffix) -OutFile $LocalPath - return - } - catch { - Write-Verbose "Request failed. $retries retries remaining" - } - } - - Write-Error "Download failed: '$RemotePath'." -} - -# -# Main -# - -# Load configuration or set defaults - -$Path = Resolve-Path $Path -if (!$ConfigFile) { $ConfigFile = Join-Path $Path 'korebuild.json' } - -if (Test-Path $ConfigFile) { - try { - $config = Get-Content -Raw -Encoding UTF8 -Path $ConfigFile | ConvertFrom-Json - if ($config) { - if (!($Channel) -and (Get-Member -Name 'channel' -InputObject $config)) { [string] $Channel = $config.channel } - if (!($ToolsSource) -and (Get-Member -Name 'toolsSource' -InputObject $config)) { [string] $ToolsSource = $config.toolsSource} - } - } - catch { - Write-Warning "$ConfigFile could not be read. Its settings will be ignored." - Write-Warning $Error[0] - } -} - -if (!$DotNetHome) { - $DotNetHome = if ($env:DOTNET_HOME) { $env:DOTNET_HOME } ` - elseif ($env:USERPROFILE) { Join-Path $env:USERPROFILE '.dotnet'} ` - elseif ($env:HOME) {Join-Path $env:HOME '.dotnet'}` - else { Join-Path $PSScriptRoot '.dotnet'} -} - -if (!$Channel) { $Channel = 'dev' } -if (!$ToolsSource) { $ToolsSource = 'https://aspnetcore.blob.core.windows.net/buildtools' } - -# Execute - -$korebuildPath = Get-KoreBuild -Import-Module -Force -Scope Local (Join-Path $korebuildPath 'KoreBuild.psd1') - -try { - Set-KoreBuildSettings -ToolsSource $ToolsSource -DotNetHome $DotNetHome -RepoPath $Path -ConfigFile $ConfigFile - Invoke-KoreBuildCommand $Command @Arguments -} -finally { - Remove-Module 'KoreBuild' -ErrorAction Ignore -} diff --git a/run.sh b/run.sh deleted file mode 100755 index 834961fc3a..0000000000 --- a/run.sh +++ /dev/null @@ -1,231 +0,0 @@ -#!/usr/bin/env bash - -set -euo pipefail - -# -# variables -# - -RESET="\033[0m" -RED="\033[0;31m" -YELLOW="\033[0;33m" -MAGENTA="\033[0;95m" -DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" -[ -z "${DOTNET_HOME:-}" ] && DOTNET_HOME="$HOME/.dotnet" -verbose=false -update=false -repo_path="$DIR" -channel='' -tools_source='' -tools_source_suffix='' - -# -# Functions -# -__usage() { - echo "Usage: $(basename "${BASH_SOURCE[0]}") command [options] [[--] ...]" - echo "" - echo "Arguments:" - echo " command The command to be run." - echo " ... Arguments passed to the command. Variable number of arguments allowed." - echo "" - echo "Options:" - echo " --verbose Show verbose output." - echo " -c|--channel The channel of KoreBuild to download. Overrides the value from the config file.." - echo " --config-file The path to the configuration file that stores values. Defaults to korebuild.json." - echo " -d|--dotnet-home The directory where .NET Core tools will be stored. Defaults to '\$DOTNET_HOME' or '\$HOME/.dotnet." - echo " --path The directory to build. Defaults to the directory containing the script." - echo " -s|--tools-source|-ToolsSource The base url where build tools can be downloaded. Overrides the value from the config file." - echo " --tools-source-suffix|-ToolsSourceSuffix The suffix to append to tools-source. Useful for query strings." - echo " -u|--update Update to the latest KoreBuild even if the lock file is present." - echo "" - echo "Description:" - echo " This function will create a file \$DIR/korebuild-lock.txt. This lock file can be committed to source, but does not have to be." - echo " When the lockfile is not present, KoreBuild will create one using latest available version from \$channel." - - if [[ "${1:-}" != '--no-exit' ]]; then - exit 2 - fi -} - -get_korebuild() { - local version - local lock_file="$repo_path/korebuild-lock.txt" - if [ ! -f "$lock_file" ] || [ "$update" = true ]; then - __get_remote_file "$tools_source/korebuild/channels/$channel/latest.txt" "$lock_file" "$tools_source_suffix" - fi - version="$(grep 'version:*' -m 1 "$lock_file")" - if [[ "$version" == '' ]]; then - __error "Failed to parse version from $lock_file. Expected a line that begins with 'version:'" - return 1 - fi - version="$(echo "${version#version:}" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')" - local korebuild_path="$DOTNET_HOME/buildtools/korebuild/$version" - - { - if [ ! -d "$korebuild_path" ]; then - mkdir -p "$korebuild_path" - local remote_path="$tools_source/korebuild/artifacts/$version/korebuild.$version.zip" - tmpfile="$(mktemp)" - echo -e "${MAGENTA}Downloading KoreBuild ${version}${RESET}" - if __get_remote_file "$remote_path" "$tmpfile" "$tools_source_suffix"; then - unzip -q -d "$korebuild_path" "$tmpfile" - fi - rm "$tmpfile" || true - fi - - source "$korebuild_path/KoreBuild.sh" - } || { - if [ -d "$korebuild_path" ]; then - echo "Cleaning up after failed installation" - rm -rf "$korebuild_path" || true - fi - return 1 - } -} - -__error() { - echo -e "${RED}error: $*${RESET}" 1>&2 -} - -__warn() { - echo -e "${YELLOW}warning: $*${RESET}" -} - -__machine_has() { - hash "$1" > /dev/null 2>&1 - return $? -} - -__get_remote_file() { - local remote_path=$1 - local local_path=$2 - local remote_path_suffix=$3 - - if [[ "$remote_path" != 'http'* ]]; then - cp "$remote_path" "$local_path" - return 0 - fi - - local failed=false - if __machine_has wget; then - wget --tries 10 --quiet -O "$local_path" "${remote_path}${remote_path_suffix}" || failed=true - else - failed=true - fi - - if [ "$failed" = true ] && __machine_has curl; then - failed=false - curl --retry 10 -sSL -f --create-dirs -o "$local_path" "${remote_path}${remote_path_suffix}" || failed=true - fi - - if [ "$failed" = true ]; then - __error "Download failed: $remote_path" 1>&2 - return 1 - fi -} - -# -# main -# - -command="${1:-}" -shift - -while [[ $# -gt 0 ]]; do - case $1 in - -\?|-h|--help) - __usage --no-exit - exit 0 - ;; - -c|--channel|-Channel) - shift - channel="${1:-}" - [ -z "$channel" ] && __usage - ;; - --config-file|-ConfigFile) - shift - config_file="${1:-}" - [ -z "$config_file" ] && __usage - if [ ! -f "$config_file" ]; then - __error "Invalid value for --config-file. $config_file does not exist." - exit 1 - fi - ;; - -d|--dotnet-home|-DotNetHome) - shift - DOTNET_HOME="${1:-}" - [ -z "$DOTNET_HOME" ] && __usage - ;; - --path|-Path) - shift - repo_path="${1:-}" - [ -z "$repo_path" ] && __usage - ;; - -s|--tools-source|-ToolsSource) - shift - tools_source="${1:-}" - [ -z "$tools_source" ] && __usage - ;; - --tools-source-suffix|-ToolsSourceSuffix) - shift - tools_source_suffix="${1:-}" - [ -z "$tools_source_suffix" ] && __usage - ;; - -u|--update|-Update) - update=true - ;; - --verbose|-Verbose) - verbose=true - ;; - --) - shift - break - ;; - *) - break - ;; - esac - shift -done - -if ! __machine_has unzip; then - __error 'Missing required command: unzip' - exit 1 -fi - -if ! __machine_has curl && ! __machine_has wget; then - __error 'Missing required command. Either wget or curl is required.' - exit 1 -fi - -[ -z "${config_file:-}" ] && config_file="$repo_path/korebuild.json" -if [ -f "$config_file" ]; then - if __machine_has jq ; then - if jq '.' "$config_file" >/dev/null ; then - config_channel="$(jq -r 'select(.channel!=null) | .channel' "$config_file")" - config_tools_source="$(jq -r 'select(.toolsSource!=null) | .toolsSource' "$config_file")" - else - __warn "$config_file is invalid JSON. Its settings will be ignored." - fi - elif __machine_has python ; then - if python -c "import json,codecs;obj=json.load(codecs.open('$config_file', 'r', 'utf-8-sig'))" >/dev/null ; then - config_channel="$(python -c "import json,codecs;obj=json.load(codecs.open('$config_file', 'r', 'utf-8-sig'));print(obj['channel'] if 'channel' in obj else '')")" - config_tools_source="$(python -c "import json,codecs;obj=json.load(codecs.open('$config_file', 'r', 'utf-8-sig'));print(obj['toolsSource'] if 'toolsSource' in obj else '')")" - else - __warn "$config_file is invalid JSON. Its settings will be ignored." - fi - else - __warn 'Missing required command: jq or pyton. Could not parse the JSON file. Its settings will be ignored.' - fi - - [ ! -z "${config_channel:-}" ] && channel="$config_channel" - [ ! -z "${config_tools_source:-}" ] && tools_source="$config_tools_source" -fi - -[ -z "$channel" ] && channel='dev' -[ -z "$tools_source" ] && tools_source='https://aspnetcore.blob.core.windows.net/buildtools' - -get_korebuild -set_korebuildsettings "$tools_source" "$DOTNET_HOME" "$repo_path" "$config_file" -invoke_korebuild_command "$command" "$@" diff --git a/src/Directory.Build.props b/src/Directory.Build.props deleted file mode 100644 index 4b89a431e7..0000000000 --- a/src/Directory.Build.props +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/src/Microsoft.AspNetCore.JsonPatch/Adapters/IObjectAdapter.cs b/src/Features/JsonPatch/src/Adapters/IObjectAdapter.cs similarity index 100% rename from src/Microsoft.AspNetCore.JsonPatch/Adapters/IObjectAdapter.cs rename to src/Features/JsonPatch/src/Adapters/IObjectAdapter.cs diff --git a/src/Microsoft.AspNetCore.JsonPatch/Adapters/IObjectAdapterWithTest.cs b/src/Features/JsonPatch/src/Adapters/IObjectAdapterWithTest.cs similarity index 100% rename from src/Microsoft.AspNetCore.JsonPatch/Adapters/IObjectAdapterWithTest.cs rename to src/Features/JsonPatch/src/Adapters/IObjectAdapterWithTest.cs diff --git a/src/Microsoft.AspNetCore.JsonPatch/Adapters/ObjectAdapter.cs b/src/Features/JsonPatch/src/Adapters/ObjectAdapter.cs similarity index 100% rename from src/Microsoft.AspNetCore.JsonPatch/Adapters/ObjectAdapter.cs rename to src/Features/JsonPatch/src/Adapters/ObjectAdapter.cs diff --git a/src/Microsoft.AspNetCore.JsonPatch/Converters/JsonPatchDocumentConverter.cs b/src/Features/JsonPatch/src/Converters/JsonPatchDocumentConverter.cs similarity index 100% rename from src/Microsoft.AspNetCore.JsonPatch/Converters/JsonPatchDocumentConverter.cs rename to src/Features/JsonPatch/src/Converters/JsonPatchDocumentConverter.cs diff --git a/src/Microsoft.AspNetCore.JsonPatch/Converters/TypedJsonPatchDocumentConverter.cs b/src/Features/JsonPatch/src/Converters/TypedJsonPatchDocumentConverter.cs similarity index 100% rename from src/Microsoft.AspNetCore.JsonPatch/Converters/TypedJsonPatchDocumentConverter.cs rename to src/Features/JsonPatch/src/Converters/TypedJsonPatchDocumentConverter.cs diff --git a/src/Microsoft.AspNetCore.JsonPatch/Exceptions/JsonPatchException.cs b/src/Features/JsonPatch/src/Exceptions/JsonPatchException.cs similarity index 100% rename from src/Microsoft.AspNetCore.JsonPatch/Exceptions/JsonPatchException.cs rename to src/Features/JsonPatch/src/Exceptions/JsonPatchException.cs diff --git a/src/Microsoft.AspNetCore.JsonPatch/Helpers/GetValueResult.cs b/src/Features/JsonPatch/src/Helpers/GetValueResult.cs similarity index 100% rename from src/Microsoft.AspNetCore.JsonPatch/Helpers/GetValueResult.cs rename to src/Features/JsonPatch/src/Helpers/GetValueResult.cs diff --git a/src/Microsoft.AspNetCore.JsonPatch/Helpers/JsonPatchProperty.cs b/src/Features/JsonPatch/src/Helpers/JsonPatchProperty.cs similarity index 100% rename from src/Microsoft.AspNetCore.JsonPatch/Helpers/JsonPatchProperty.cs rename to src/Features/JsonPatch/src/Helpers/JsonPatchProperty.cs diff --git a/src/Microsoft.AspNetCore.JsonPatch/IJsonPatchDocument.cs b/src/Features/JsonPatch/src/IJsonPatchDocument.cs similarity index 100% rename from src/Microsoft.AspNetCore.JsonPatch/IJsonPatchDocument.cs rename to src/Features/JsonPatch/src/IJsonPatchDocument.cs diff --git a/src/Microsoft.AspNetCore.JsonPatch/Internal/ConversionResult.cs b/src/Features/JsonPatch/src/Internal/ConversionResult.cs similarity index 100% rename from src/Microsoft.AspNetCore.JsonPatch/Internal/ConversionResult.cs rename to src/Features/JsonPatch/src/Internal/ConversionResult.cs diff --git a/src/Microsoft.AspNetCore.JsonPatch/Internal/ConversionResultProvider.cs b/src/Features/JsonPatch/src/Internal/ConversionResultProvider.cs similarity index 100% rename from src/Microsoft.AspNetCore.JsonPatch/Internal/ConversionResultProvider.cs rename to src/Features/JsonPatch/src/Internal/ConversionResultProvider.cs diff --git a/src/Microsoft.AspNetCore.JsonPatch/Internal/DictionaryAdapterOfTU.cs b/src/Features/JsonPatch/src/Internal/DictionaryAdapterOfTU.cs similarity index 100% rename from src/Microsoft.AspNetCore.JsonPatch/Internal/DictionaryAdapterOfTU.cs rename to src/Features/JsonPatch/src/Internal/DictionaryAdapterOfTU.cs diff --git a/src/Microsoft.AspNetCore.JsonPatch/Internal/DynamicObjectAdapter.cs b/src/Features/JsonPatch/src/Internal/DynamicObjectAdapter.cs similarity index 100% rename from src/Microsoft.AspNetCore.JsonPatch/Internal/DynamicObjectAdapter.cs rename to src/Features/JsonPatch/src/Internal/DynamicObjectAdapter.cs diff --git a/src/Microsoft.AspNetCore.JsonPatch/Internal/ErrorReporter.cs b/src/Features/JsonPatch/src/Internal/ErrorReporter.cs similarity index 100% rename from src/Microsoft.AspNetCore.JsonPatch/Internal/ErrorReporter.cs rename to src/Features/JsonPatch/src/Internal/ErrorReporter.cs diff --git a/src/Microsoft.AspNetCore.JsonPatch/Internal/IAdapter.cs b/src/Features/JsonPatch/src/Internal/IAdapter.cs similarity index 100% rename from src/Microsoft.AspNetCore.JsonPatch/Internal/IAdapter.cs rename to src/Features/JsonPatch/src/Internal/IAdapter.cs diff --git a/src/Microsoft.AspNetCore.JsonPatch/Internal/ListAdapter.cs b/src/Features/JsonPatch/src/Internal/ListAdapter.cs similarity index 100% rename from src/Microsoft.AspNetCore.JsonPatch/Internal/ListAdapter.cs rename to src/Features/JsonPatch/src/Internal/ListAdapter.cs diff --git a/src/Microsoft.AspNetCore.JsonPatch/Internal/ObjectVisitor.cs b/src/Features/JsonPatch/src/Internal/ObjectVisitor.cs similarity index 100% rename from src/Microsoft.AspNetCore.JsonPatch/Internal/ObjectVisitor.cs rename to src/Features/JsonPatch/src/Internal/ObjectVisitor.cs diff --git a/src/Microsoft.AspNetCore.JsonPatch/Internal/ParsedPath.cs b/src/Features/JsonPatch/src/Internal/ParsedPath.cs similarity index 100% rename from src/Microsoft.AspNetCore.JsonPatch/Internal/ParsedPath.cs rename to src/Features/JsonPatch/src/Internal/ParsedPath.cs diff --git a/src/Microsoft.AspNetCore.JsonPatch/Internal/PathHelpers.cs b/src/Features/JsonPatch/src/Internal/PathHelpers.cs similarity index 100% rename from src/Microsoft.AspNetCore.JsonPatch/Internal/PathHelpers.cs rename to src/Features/JsonPatch/src/Internal/PathHelpers.cs diff --git a/src/Microsoft.AspNetCore.JsonPatch/Internal/PocoAdapter.cs b/src/Features/JsonPatch/src/Internal/PocoAdapter.cs similarity index 100% rename from src/Microsoft.AspNetCore.JsonPatch/Internal/PocoAdapter.cs rename to src/Features/JsonPatch/src/Internal/PocoAdapter.cs diff --git a/src/Microsoft.AspNetCore.JsonPatch/JsonPatchDocument.cs b/src/Features/JsonPatch/src/JsonPatchDocument.cs similarity index 100% rename from src/Microsoft.AspNetCore.JsonPatch/JsonPatchDocument.cs rename to src/Features/JsonPatch/src/JsonPatchDocument.cs diff --git a/src/Microsoft.AspNetCore.JsonPatch/JsonPatchDocumentOfT.cs b/src/Features/JsonPatch/src/JsonPatchDocumentOfT.cs similarity index 100% rename from src/Microsoft.AspNetCore.JsonPatch/JsonPatchDocumentOfT.cs rename to src/Features/JsonPatch/src/JsonPatchDocumentOfT.cs diff --git a/src/Microsoft.AspNetCore.JsonPatch/JsonPatchError.cs b/src/Features/JsonPatch/src/JsonPatchError.cs similarity index 100% rename from src/Microsoft.AspNetCore.JsonPatch/JsonPatchError.cs rename to src/Features/JsonPatch/src/JsonPatchError.cs diff --git a/src/Microsoft.AspNetCore.JsonPatch/Microsoft.AspNetCore.JsonPatch.csproj b/src/Features/JsonPatch/src/Microsoft.AspNetCore.JsonPatch.csproj similarity index 51% rename from src/Microsoft.AspNetCore.JsonPatch/Microsoft.AspNetCore.JsonPatch.csproj rename to src/Features/JsonPatch/src/Microsoft.AspNetCore.JsonPatch.csproj index 9bd08214f6..3708e92927 100644 --- a/src/Microsoft.AspNetCore.JsonPatch/Microsoft.AspNetCore.JsonPatch.csproj +++ b/src/Features/JsonPatch/src/Microsoft.AspNetCore.JsonPatch.csproj @@ -9,9 +9,9 @@ - - - + + + diff --git a/src/Microsoft.AspNetCore.JsonPatch/Operations/Operation.cs b/src/Features/JsonPatch/src/Operations/Operation.cs similarity index 100% rename from src/Microsoft.AspNetCore.JsonPatch/Operations/Operation.cs rename to src/Features/JsonPatch/src/Operations/Operation.cs diff --git a/src/Microsoft.AspNetCore.JsonPatch/Operations/OperationBase.cs b/src/Features/JsonPatch/src/Operations/OperationBase.cs similarity index 100% rename from src/Microsoft.AspNetCore.JsonPatch/Operations/OperationBase.cs rename to src/Features/JsonPatch/src/Operations/OperationBase.cs diff --git a/src/Microsoft.AspNetCore.JsonPatch/Operations/OperationOfT.cs b/src/Features/JsonPatch/src/Operations/OperationOfT.cs similarity index 100% rename from src/Microsoft.AspNetCore.JsonPatch/Operations/OperationOfT.cs rename to src/Features/JsonPatch/src/Operations/OperationOfT.cs diff --git a/src/Microsoft.AspNetCore.JsonPatch/Operations/OperationType.cs b/src/Features/JsonPatch/src/Operations/OperationType.cs similarity index 100% rename from src/Microsoft.AspNetCore.JsonPatch/Operations/OperationType.cs rename to src/Features/JsonPatch/src/Operations/OperationType.cs diff --git a/src/Features/JsonPatch/src/Properties/AssemblyInfo.cs b/src/Features/JsonPatch/src/Properties/AssemblyInfo.cs new file mode 100644 index 0000000000..11fa956b64 --- /dev/null +++ b/src/Features/JsonPatch/src/Properties/AssemblyInfo.cs @@ -0,0 +1,7 @@ + +// 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.Runtime.CompilerServices; + +[assembly: InternalsVisibleTo("Microsoft.AspNetCore.JsonPatch.Tests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")] diff --git a/src/Microsoft.AspNetCore.JsonPatch/Properties/Resources.Designer.cs b/src/Features/JsonPatch/src/Properties/Resources.Designer.cs similarity index 100% rename from src/Microsoft.AspNetCore.JsonPatch/Properties/Resources.Designer.cs rename to src/Features/JsonPatch/src/Properties/Resources.Designer.cs diff --git a/src/Microsoft.AspNetCore.JsonPatch/Resources.resx b/src/Features/JsonPatch/src/Resources.resx similarity index 100% rename from src/Microsoft.AspNetCore.JsonPatch/Resources.resx rename to src/Features/JsonPatch/src/Resources.resx diff --git a/src/Microsoft.AspNetCore.JsonPatch/baseline.netcore.json b/src/Features/JsonPatch/src/baseline.netcore.json similarity index 100% rename from src/Microsoft.AspNetCore.JsonPatch/baseline.netcore.json rename to src/Features/JsonPatch/src/baseline.netcore.json diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/CustomNamingStrategyTests.cs b/src/Features/JsonPatch/test/CustomNamingStrategyTests.cs similarity index 100% rename from test/Microsoft.AspNetCore.JsonPatch.Test/CustomNamingStrategyTests.cs rename to src/Features/JsonPatch/test/CustomNamingStrategyTests.cs diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/IntegrationTests/AnonymousObjectIntegrationTest.cs b/src/Features/JsonPatch/test/IntegrationTests/AnonymousObjectIntegrationTest.cs similarity index 100% rename from test/Microsoft.AspNetCore.JsonPatch.Test/IntegrationTests/AnonymousObjectIntegrationTest.cs rename to src/Features/JsonPatch/test/IntegrationTests/AnonymousObjectIntegrationTest.cs diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/IntegrationTests/DictionaryIntegrationTest.cs b/src/Features/JsonPatch/test/IntegrationTests/DictionaryIntegrationTest.cs similarity index 100% rename from test/Microsoft.AspNetCore.JsonPatch.Test/IntegrationTests/DictionaryIntegrationTest.cs rename to src/Features/JsonPatch/test/IntegrationTests/DictionaryIntegrationTest.cs diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/IntegrationTests/DynamicObjectIntegrationTest.cs b/src/Features/JsonPatch/test/IntegrationTests/DynamicObjectIntegrationTest.cs similarity index 100% rename from test/Microsoft.AspNetCore.JsonPatch.Test/IntegrationTests/DynamicObjectIntegrationTest.cs rename to src/Features/JsonPatch/test/IntegrationTests/DynamicObjectIntegrationTest.cs diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/IntegrationTests/ExpandoObjectIntegrationTest.cs b/src/Features/JsonPatch/test/IntegrationTests/ExpandoObjectIntegrationTest.cs similarity index 100% rename from test/Microsoft.AspNetCore.JsonPatch.Test/IntegrationTests/ExpandoObjectIntegrationTest.cs rename to src/Features/JsonPatch/test/IntegrationTests/ExpandoObjectIntegrationTest.cs diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/IntegrationTests/ListIntegrationTest.cs b/src/Features/JsonPatch/test/IntegrationTests/ListIntegrationTest.cs similarity index 100% rename from test/Microsoft.AspNetCore.JsonPatch.Test/IntegrationTests/ListIntegrationTest.cs rename to src/Features/JsonPatch/test/IntegrationTests/ListIntegrationTest.cs diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/IntegrationTests/NestedObjectIntegrationTest.cs b/src/Features/JsonPatch/test/IntegrationTests/NestedObjectIntegrationTest.cs similarity index 100% rename from test/Microsoft.AspNetCore.JsonPatch.Test/IntegrationTests/NestedObjectIntegrationTest.cs rename to src/Features/JsonPatch/test/IntegrationTests/NestedObjectIntegrationTest.cs diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/IntegrationTests/SimpleObjectIntegrationTest.cs b/src/Features/JsonPatch/test/IntegrationTests/SimpleObjectIntegrationTest.cs similarity index 100% rename from test/Microsoft.AspNetCore.JsonPatch.Test/IntegrationTests/SimpleObjectIntegrationTest.cs rename to src/Features/JsonPatch/test/IntegrationTests/SimpleObjectIntegrationTest.cs diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/Internal/DictionaryAdapterTest.cs b/src/Features/JsonPatch/test/Internal/DictionaryAdapterTest.cs similarity index 100% rename from test/Microsoft.AspNetCore.JsonPatch.Test/Internal/DictionaryAdapterTest.cs rename to src/Features/JsonPatch/test/Internal/DictionaryAdapterTest.cs diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/Internal/DynamicObjectAdapterTest.cs b/src/Features/JsonPatch/test/Internal/DynamicObjectAdapterTest.cs similarity index 100% rename from test/Microsoft.AspNetCore.JsonPatch.Test/Internal/DynamicObjectAdapterTest.cs rename to src/Features/JsonPatch/test/Internal/DynamicObjectAdapterTest.cs diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/Internal/ListAdapterTest.cs b/src/Features/JsonPatch/test/Internal/ListAdapterTest.cs similarity index 100% rename from test/Microsoft.AspNetCore.JsonPatch.Test/Internal/ListAdapterTest.cs rename to src/Features/JsonPatch/test/Internal/ListAdapterTest.cs diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/Internal/ObjectVisitorTest.cs b/src/Features/JsonPatch/test/Internal/ObjectVisitorTest.cs similarity index 100% rename from test/Microsoft.AspNetCore.JsonPatch.Test/Internal/ObjectVisitorTest.cs rename to src/Features/JsonPatch/test/Internal/ObjectVisitorTest.cs diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/Internal/ParsedPathTests.cs b/src/Features/JsonPatch/test/Internal/ParsedPathTests.cs similarity index 100% rename from test/Microsoft.AspNetCore.JsonPatch.Test/Internal/ParsedPathTests.cs rename to src/Features/JsonPatch/test/Internal/ParsedPathTests.cs diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/Internal/PocoAdapterTest.cs b/src/Features/JsonPatch/test/Internal/PocoAdapterTest.cs similarity index 100% rename from test/Microsoft.AspNetCore.JsonPatch.Test/Internal/PocoAdapterTest.cs rename to src/Features/JsonPatch/test/Internal/PocoAdapterTest.cs diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/JsonPatchDocumentGetPathTest.cs b/src/Features/JsonPatch/test/JsonPatchDocumentGetPathTest.cs similarity index 100% rename from test/Microsoft.AspNetCore.JsonPatch.Test/JsonPatchDocumentGetPathTest.cs rename to src/Features/JsonPatch/test/JsonPatchDocumentGetPathTest.cs diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/JsonPatchDocumentJsonPropertyAttributeTest.cs b/src/Features/JsonPatch/test/JsonPatchDocumentJsonPropertyAttributeTest.cs similarity index 100% rename from test/Microsoft.AspNetCore.JsonPatch.Test/JsonPatchDocumentJsonPropertyAttributeTest.cs rename to src/Features/JsonPatch/test/JsonPatchDocumentJsonPropertyAttributeTest.cs diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/JsonPatchDocumentTest.cs b/src/Features/JsonPatch/test/JsonPatchDocumentTest.cs similarity index 100% rename from test/Microsoft.AspNetCore.JsonPatch.Test/JsonPatchDocumentTest.cs rename to src/Features/JsonPatch/test/JsonPatchDocumentTest.cs diff --git a/src/Features/JsonPatch/test/Microsoft.AspNetCore.JsonPatch.Tests.csproj b/src/Features/JsonPatch/test/Microsoft.AspNetCore.JsonPatch.Tests.csproj new file mode 100644 index 0000000000..5aca855c9c --- /dev/null +++ b/src/Features/JsonPatch/test/Microsoft.AspNetCore.JsonPatch.Tests.csproj @@ -0,0 +1,11 @@ + + + + netcoreapp2.1;net461 + + + + + + + diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/OperationBaseTests.cs b/src/Features/JsonPatch/test/OperationBaseTests.cs similarity index 100% rename from test/Microsoft.AspNetCore.JsonPatch.Test/OperationBaseTests.cs rename to src/Features/JsonPatch/test/OperationBaseTests.cs diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/TestErrorLogger.cs b/src/Features/JsonPatch/test/TestErrorLogger.cs similarity index 100% rename from test/Microsoft.AspNetCore.JsonPatch.Test/TestErrorLogger.cs rename to src/Features/JsonPatch/test/TestErrorLogger.cs diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/TestObjectModels/Customer.cs b/src/Features/JsonPatch/test/TestObjectModels/Customer.cs similarity index 100% rename from test/Microsoft.AspNetCore.JsonPatch.Test/TestObjectModels/Customer.cs rename to src/Features/JsonPatch/test/TestObjectModels/Customer.cs diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/TestObjectModels/DynamicTestObject.cs b/src/Features/JsonPatch/test/TestObjectModels/DynamicTestObject.cs similarity index 100% rename from test/Microsoft.AspNetCore.JsonPatch.Test/TestObjectModels/DynamicTestObject.cs rename to src/Features/JsonPatch/test/TestObjectModels/DynamicTestObject.cs diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/TestObjectModels/InheritedObject.cs b/src/Features/JsonPatch/test/TestObjectModels/InheritedObject.cs similarity index 100% rename from test/Microsoft.AspNetCore.JsonPatch.Test/TestObjectModels/InheritedObject.cs rename to src/Features/JsonPatch/test/TestObjectModels/InheritedObject.cs diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/TestObjectModels/NestedObject.cs b/src/Features/JsonPatch/test/TestObjectModels/NestedObject.cs similarity index 100% rename from test/Microsoft.AspNetCore.JsonPatch.Test/TestObjectModels/NestedObject.cs rename to src/Features/JsonPatch/test/TestObjectModels/NestedObject.cs diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/TestObjectModels/SimpleObject.cs b/src/Features/JsonPatch/test/TestObjectModels/SimpleObject.cs similarity index 100% rename from test/Microsoft.AspNetCore.JsonPatch.Test/TestObjectModels/SimpleObject.cs rename to src/Features/JsonPatch/test/TestObjectModels/SimpleObject.cs diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/TestObjectModels/SimpleObjectWithNestedObject.cs b/src/Features/JsonPatch/test/TestObjectModels/SimpleObjectWithNestedObject.cs similarity index 100% rename from test/Microsoft.AspNetCore.JsonPatch.Test/TestObjectModels/SimpleObjectWithNestedObject.cs rename to src/Features/JsonPatch/test/TestObjectModels/SimpleObjectWithNestedObject.cs diff --git a/src/Microsoft.AspNetCore.JsonPatch/Properties/AssemblyInfo.cs b/src/Microsoft.AspNetCore.JsonPatch/Properties/AssemblyInfo.cs deleted file mode 100644 index 08e6f5e01c..0000000000 --- a/src/Microsoft.AspNetCore.JsonPatch/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,7 +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.Runtime.CompilerServices; - -[assembly: InternalsVisibleTo("Microsoft.AspNetCore.JsonPatch.Test, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")] diff --git a/test/Directory.Build.props b/test/Directory.Build.props deleted file mode 100644 index 98685a5e13..0000000000 --- a/test/Directory.Build.props +++ /dev/null @@ -1,18 +0,0 @@ - - - - - netcoreapp2.1 - $(DeveloperBuildTestTfms) - $(StandardTestTfms);netcoreapp2.0 - $(StandardTestTfms);net461 - - - - - - - - - - diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/Microsoft.AspNetCore.JsonPatch.Test.csproj b/test/Microsoft.AspNetCore.JsonPatch.Test/Microsoft.AspNetCore.JsonPatch.Test.csproj deleted file mode 100644 index ce1d92802d..0000000000 --- a/test/Microsoft.AspNetCore.JsonPatch.Test/Microsoft.AspNetCore.JsonPatch.Test.csproj +++ /dev/null @@ -1,20 +0,0 @@ - - - - $(StandardTestTfms) - - - - - - - - - - - - - - - - diff --git a/version.props b/version.props deleted file mode 100644 index 669c874829..0000000000 --- a/version.props +++ /dev/null @@ -1,12 +0,0 @@ - - - 2.1.1 - rtm - $(VersionPrefix) - $(VersionPrefix)-$(VersionSuffix)-final - t000 - a- - $(FeatureBranchVersionPrefix)$(VersionSuffix)-$([System.Text.RegularExpressions.Regex]::Replace('$(FeatureBranchVersionSuffix)', '[^\w-]', '-')) - $(VersionSuffix)-$(BuildNumber) - - From 59ed8df382a76b8a0d1b19853318614b87ed171d Mon Sep 17 00:00:00 2001 From: Nate McMaster Date: Fri, 9 Nov 2018 13:05:31 -0800 Subject: [PATCH 216/221] Add targets and tools for ensuring consistent package versions between servicing builds --- Directory.Build.props | 8 ++ Directory.Build.targets | 31 ++++ build/SharedFx.targets | 2 +- build/buildorder.props | 2 - build/dependencies.props | 1 + build/repo.props | 15 +- build/repo.targets | 44 +++++- build/submodules.props | 1 - build/tasks/RepoTasks.csproj | 1 + ...ch-updates.md => PreparingPatchUpdates.md} | 10 +- eng/Baseline.props | 100 +++++++++++++ eng/Dependencies.props | 46 ++++++ eng/PatchConfig.props | 13 ++ eng/ProjectReferences.props | 7 + eng/targets/CSharp.Common.props | 14 ++ eng/targets/CSharp.Common.targets | 5 + eng/targets/Packaging.targets | 30 ++++ eng/targets/ResolveReferences.targets | 135 ++++++++++++++++++ .../BaselineGenerator.csproj | 15 ++ eng/tools/BaselineGenerator/Program.cs | 132 +++++++++++++++++ eng/tools/BaselineGenerator/README.md | 10 ++ eng/tools/BaselineGenerator/baseline.xml | 13 ++ eng/tools/Directory.Build.props | 3 + eng/tools/Directory.Build.targets | 2 + eng/tools/tools.sln | 34 +++++ src/DataProtection/Directory.Build.props | 16 --- src/Packages/Directory.Build.props | 4 +- version.props | 5 + 28 files changed, 665 insertions(+), 34 deletions(-) rename docs/{preparing-patch-updates.md => PreparingPatchUpdates.md} (74%) create mode 100644 eng/Baseline.props create mode 100644 eng/Dependencies.props create mode 100644 eng/PatchConfig.props create mode 100644 eng/ProjectReferences.props create mode 100644 eng/targets/CSharp.Common.props create mode 100644 eng/targets/CSharp.Common.targets create mode 100644 eng/targets/Packaging.targets create mode 100644 eng/targets/ResolveReferences.targets create mode 100644 eng/tools/BaselineGenerator/BaselineGenerator.csproj create mode 100644 eng/tools/BaselineGenerator/Program.cs create mode 100644 eng/tools/BaselineGenerator/README.md create mode 100644 eng/tools/BaselineGenerator/baseline.xml create mode 100644 eng/tools/Directory.Build.props create mode 100644 eng/tools/Directory.Build.targets create mode 100644 eng/tools/tools.sln diff --git a/Directory.Build.props b/Directory.Build.props index bdb885cd9f..c0f5b99d35 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -34,5 +34,13 @@ true + + netcoreapp2.1;net461 + + + + + + diff --git a/Directory.Build.targets b/Directory.Build.targets index 30ce3e3322..052fb09136 100644 --- a/Directory.Build.targets +++ b/Directory.Build.targets @@ -1,9 +1,39 @@ + + $(AssemblyName) + false + + + + + + + true + $(PackagesInPatch.Contains(' $(PackageId);')) + + + + + true + + false + + + + + $(BaselinePackageVersion).0 + $(BaselinePackageVersion).0 + $(BaselinePackageVersion) + + true + + false + $(IsImplementationProject) true false @@ -14,4 +44,5 @@ + diff --git a/build/SharedFx.targets b/build/SharedFx.targets index 84d2aee45c..2ab7352634 100644 --- a/build/SharedFx.targets +++ b/build/SharedFx.targets @@ -33,7 +33,7 @@ - + $(_MetapackageSrcRoot)$(MetapackageName)\ $(_WorkRoot)pkg\$(MetapackageName)\ diff --git a/build/buildorder.props b/build/buildorder.props index 1cb0f6cec8..55aceb0800 100644 --- a/build/buildorder.props +++ b/build/buildorder.props @@ -7,7 +7,6 @@ - @@ -30,7 +29,6 @@ - diff --git a/build/dependencies.props b/build/dependencies.props index dda2ffa595..e0fdd5fcc2 100644 --- a/build/dependencies.props +++ b/build/dependencies.props @@ -15,6 +15,7 @@ $(KoreBuildVersion) $(KoreBuildVersion) + 2.1.3-rtm-15842 diff --git a/build/repo.props b/build/repo.props index ec2fe7ab7f..a44dd76881 100644 --- a/build/repo.props +++ b/build/repo.props @@ -2,9 +2,8 @@ true - false - - public + true + false false true @@ -42,6 +41,16 @@ + + + + + + diff --git a/build/repo.targets b/build/repo.targets index cde696935c..0c1125bd51 100644 --- a/build/repo.targets +++ b/build/repo.targets @@ -16,18 +16,52 @@ SetTeamCityBuildNumberToVersion;$(PrepareDependsOn);VerifyPackageArtifactConfig;VerifyExternalDependencyConfig;PrepareOutputPaths $(CleanDependsOn);CleanArtifacts;CleanRepoArtifacts - $(RestoreDependsOn);InstallDotNet - $(CompileDependsOn);BuildRepositories + $(RestoreDependsOn);InstallDotNet;RestoreProjects + $(CompileDependsOn);BuildProjects;PackProjects;BuildRepositories $(PackageDependsOn);BuildMetapackages;CheckExpectedPackagesExist - $(TestDependsOn);_TestRepositories - $(GetArtifactInfoDependsOn);ResolveRepoInfo + $(TestDependsOn);TestProjects;_TestRepositories + $(GetArtifactInfoDependsOn);GetProjectArtifactInfo;ResolveRepoInfo - + + + + + + + + $(MSBuildThisFileDirectory)..\eng\ProjectReferences.props + + + + + @(_ProjectReferenceProvider->'', '%0A ') + + + ]]> + + + + + + + + + + + + + + MicrosoftNETCoreAppPackageVersion=$(MicrosoftNETCoreAppPackageVersion); diff --git a/build/submodules.props b/build/submodules.props index 8b30d5efcb..8030fb219f 100644 --- a/build/submodules.props +++ b/build/submodules.props @@ -77,6 +77,5 @@ - diff --git a/build/tasks/RepoTasks.csproj b/build/tasks/RepoTasks.csproj index 6be1f375d2..20cbf6cce8 100644 --- a/build/tasks/RepoTasks.csproj +++ b/build/tasks/RepoTasks.csproj @@ -6,6 +6,7 @@ + diff --git a/docs/preparing-patch-updates.md b/docs/PreparingPatchUpdates.md similarity index 74% rename from docs/preparing-patch-updates.md rename to docs/PreparingPatchUpdates.md index 87821935de..34813e8162 100644 --- a/docs/preparing-patch-updates.md +++ b/docs/PreparingPatchUpdates.md @@ -10,11 +10,15 @@ In order to prepare this repo to build a new servicing update, the following cha + 8 ``` -* Update the package archive baselines. This is used to make sure each build - of the package archives we give to Azure only contains new files and does +* Update the package archive baselines. This is used to make sure each build of the package archives we give to Azure only contains new files and does not require overwriting existing files. See [src/PackageArchive/ZipManifestGenerator/](/src/PackageArchive/ZipManifestGenerator/README.md) for instructions on how to run this tool. -* Update the list of repositories which will contain changes in [build/submodules.props](/build/submodules.props). +* Update the package baselines. This is used to ensure packages keep a consistent set of dependencies between releases. + See [eng/tools/BaselineGenerator/](/eng/tools/BaselineGenerator/README.md) for instructions on how to run this tool. + +* **For packages with source code in this repo (not a submodule):** Update the list of packages in [eng/PatchConfig.props](/eng/PatchConfig.props) to list which packages should be patching in this release. + +* **For packages still building from submodules:** Update the list of repositories which will contain changes in [build/submodules.props](/build/submodules.props). * `` items represent repos which were released in a previous patch, and will not contain servicing updates in the next patch. * `` items represent repos which will produce new packages in this patch. diff --git a/eng/Baseline.props b/eng/Baseline.props new file mode 100644 index 0000000000..acae8786c0 --- /dev/null +++ b/eng/Baseline.props @@ -0,0 +1,100 @@ + + + + $(MSBuildAllProjects);$(MSBuildThisFileFullPath) + 2.1.6 + + + + 2.1.1 + + + + + 2.1.1 + + + + + + + + + + 2.1.1 + + + + + + + + + + + + + + + 2.1.1 + + + + + 2.1.1 + + + + + + + + + 2.1.1 + + + + + + + + 2.1.1 + + + + + + + + 0.4.1 + + + + + + + + 2.1.1 + + + + + + + + 2.1.1 + + + + + + + + 2.1.1 + + + + + + + \ No newline at end of file diff --git a/eng/Dependencies.props b/eng/Dependencies.props new file mode 100644 index 0000000000..917b401b0a --- /dev/null +++ b/eng/Dependencies.props @@ -0,0 +1,46 @@ + + + + + $(MSBuildAllProjects);$(MSBuildThisFileFullPath) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/eng/PatchConfig.props b/eng/PatchConfig.props new file mode 100644 index 0000000000..91e93a17fe --- /dev/null +++ b/eng/PatchConfig.props @@ -0,0 +1,13 @@ + + + $(MSBuildAllProjects);$(MSBuildThisFileFullPath) + + + + + Microsoft.AspNetCore; + Microsoft.AspNetCore.Server.IISIntegration; + + + + diff --git a/eng/ProjectReferences.props b/eng/ProjectReferences.props new file mode 100644 index 0000000000..7381583fb8 --- /dev/null +++ b/eng/ProjectReferences.props @@ -0,0 +1,7 @@ + + + + + + + diff --git a/eng/targets/CSharp.Common.props b/eng/targets/CSharp.Common.props new file mode 100644 index 0000000000..b3fc97e2d9 --- /dev/null +++ b/eng/targets/CSharp.Common.props @@ -0,0 +1,14 @@ + + + + 7.2 + + + SHA256 + + + + + + + diff --git a/eng/targets/CSharp.Common.targets b/eng/targets/CSharp.Common.targets new file mode 100644 index 0000000000..a7f7b610b6 --- /dev/null +++ b/eng/targets/CSharp.Common.targets @@ -0,0 +1,5 @@ + + + + + diff --git a/eng/targets/Packaging.targets b/eng/targets/Packaging.targets new file mode 100644 index 0000000000..69ad343564 --- /dev/null +++ b/eng/targets/Packaging.targets @@ -0,0 +1,30 @@ + + + + + + + + + + + $(PackageOutputPath)$(PackageId).$(PackageVersion).nupkg + + + + + NuGetPackage + $(PackageId) + $(PackageVersion) + $(RepositoryRoot) + true + + + + diff --git a/eng/targets/ResolveReferences.targets b/eng/targets/ResolveReferences.targets new file mode 100644 index 0000000000..caf44207ee --- /dev/null +++ b/eng/targets/ResolveReferences.targets @@ -0,0 +1,135 @@ + + + + + ResolveCustomReferences; + $(ResolveReferencesDependsOn); + + + + + + true + true + true + false + + + true + true + false + + + + <_ImplicitPackageReference Include="@(PackageReference->WithMetadataValue('IsImplicitlyDefined', 'true'))" /> + <_ExplicitPackageReference Include="@(PackageReference)" Exclude="@(_ImplicitPackageReference)" /> + <_ExplicitPackageReference Remove="Internal.AspNetCore.Sdk" /> + + + + + <_ProjectReferenceByAssemblyName Condition="'$(UseProjectReferences)' == 'true'" + Include="@(ProjectReferenceProvider)" + Exclude="@(UnusedProjectReferenceProvider)" /> + + + + + + + + + + + + <_LatestPackageReferenceWithVersion Include="@(Reference)" Condition=" '$(UseLatestPackageReferences)' == 'true' "> + %(LatestPackageReference.Identity) + %(LatestPackageReference.Version) + + <_LatestPackageReferenceWithVersion Remove="@(_LatestPackageReferenceWithVersion)" Condition="'%(Id)' != '%(Identity)' " /> + + + + + + + <_BaselinePackageReferenceWithVersion Include="@(Reference)" Condition=" '$(IsServicingBuild)' == 'true' OR '$(UseLatestPackageReferences)' != 'true' "> + %(BaselinePackageReference.Identity) + %(BaselinePackageReference.Version) + + + <_BaselinePackageReferenceWithVersion Remove="@(_BaselinePackageReferenceWithVersion)" Condition="'%(Id)' != '%(Identity)' " /> + + + + + + + <_PrivatePackageReferenceWithVersion Include="@(Reference->WithMetadataValue('PrivateAssets', 'All'))"> + %(LatestPackageReference.Identity) + %(LatestPackageReference.Version) + + + <_PrivatePackageReferenceWithVersion Remove="@(_PrivatePackageReferenceWithVersion)" Condition="'%(Id)' != '%(Identity)' " /> + + + + + + + <_LatestPackageReferenceWithVersion Remove="@(_LatestPackageReferenceWithVersion)" /> + <_BaselinePackageReferenceWithVersion Remove="@(_BaselinePackageReferenceWithVersion)" /> + <_PrivatePackageReferenceWithVersion Remove="@(_PrivatePackageReferenceWithVersion)" /> + <_ImplicitPackageReference Remove="@(_ImplicitPackageReference)" /> + + + + + <_ExplicitPackageReference Remove="@(_ExplicitPackageReference)" /> + + + + + + + + + + <_TargetFramework Remove="@(_TargetFramework)" /> + <_TargetFramework Include="$(TargetFramework)" Condition="'$(TargetFramework)' != '' "/> + <_TargetFramework Include="$(TargetFrameworks)" Condition="'$(TargetFramework)' == '' "/> + + + + + + + + + + + $([MSBuild]::MakeRelative($(RepositoryRoot), $(MSBuildProjectFullPath))) + + + + diff --git a/eng/tools/BaselineGenerator/BaselineGenerator.csproj b/eng/tools/BaselineGenerator/BaselineGenerator.csproj new file mode 100644 index 0000000000..625777dbd2 --- /dev/null +++ b/eng/tools/BaselineGenerator/BaselineGenerator.csproj @@ -0,0 +1,15 @@ + + + + Exe + netcoreapp2.1 + -o "$(MSBuildThisFileDirectory)../../Baseline.props" + $(MSBuildProjectDirectory) + + + + + + + + diff --git a/eng/tools/BaselineGenerator/Program.cs b/eng/tools/BaselineGenerator/Program.cs new file mode 100644 index 0000000000..d3d753a5ba --- /dev/null +++ b/eng/tools/BaselineGenerator/Program.cs @@ -0,0 +1,132 @@ +// 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.IO; +using System.Net.Http; +using System.Text; +using System.Threading.Tasks; +using System.Xml; +using System.Xml.Linq; +using Microsoft.Extensions.CommandLineUtils; +using NuGet.Packaging; +using NuGet.Packaging.Core; + +namespace PackageBaselineGenerator +{ + /// + /// This generates Baseline.props with information about the last RTM release. + /// + class Program : CommandLineApplication + { + static void Main(string[] args) + { + new Program().Execute(args); + } + + private readonly CommandOption _source; + private readonly CommandOption _output; + + public Program() + { + _source = Option("-s|--source ", "The NuGet v2 source of the package to fetch", CommandOptionType.SingleValue); + _output = Option("-o|--output ", "The generated file output path", CommandOptionType.SingleValue); + + Invoke = () => Run().GetAwaiter().GetResult(); + } + + private async Task Run() + { + var source = _source.HasValue() + ? _source.Value() + : "https://www.nuget.org/api/v2/package"; + + var packageCache = Environment.GetEnvironmentVariable("NUGET_PACKAGES") != null + ? Environment.GetEnvironmentVariable("NUGET_PACKAGES") + : Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), ".nuget", "packages"); + + var tempDir = Path.Combine(Directory.GetCurrentDirectory(), "obj", "tmp"); + Directory.CreateDirectory(tempDir); + + var input = XDocument.Load(Path.Combine(Directory.GetCurrentDirectory(), "baseline.xml")); + + var output = _output.HasValue() + ? _output.Value() + : Path.Combine(Directory.GetCurrentDirectory(), "Baseline.props"); + + var baselineVersion = input.Root.Attribute("Version").Value; + + var doc = new XDocument( + new XComment(" Auto generated. Do not edit manually, use eng/tools/BaselineGenerator/ to recreate. "), + new XElement("Project", + new XElement("PropertyGroup", + new XElement("MSBuildAllProjects", "$(MSBuildAllProjects);$(MSBuildThisFileFullPath)"), + new XElement("AspNetCoreBaselineVersion", baselineVersion)))); + + var client = new HttpClient(); + + foreach (var pkg in input.Root.Descendants("Package")) + { + var id = pkg.Attribute("Id").Value; + var version = pkg.Attribute("Version").Value; + var packageFileName = $"{id}.{version}.nupkg"; + var nupkgPath = Path.Combine(packageCache, id.ToLowerInvariant(), version, packageFileName); + if (!File.Exists(nupkgPath)) + { + nupkgPath = Path.Combine(tempDir, packageFileName); + } + + if (!File.Exists(nupkgPath)) + { + var url = $"{source}/{id}/{version}"; + using (var file = File.Create(nupkgPath)) + { + Console.WriteLine($"Downloading {url}"); + var response = await client.GetStreamAsync(url); + await response.CopyToAsync(file); + } + } + + + using (var reader = new PackageArchiveReader(nupkgPath)) + { + var first = true; + foreach (var group in reader.NuspecReader.GetDependencyGroups()) + { + if (first) + { + first = false; + doc.Root.Add(new XComment($" Package: {id}")); + + var propertyGroup = new XElement("PropertyGroup", + new XAttribute("Condition", $" '$(PackageId)' == '{id}' "), + new XElement("BaselinePackageVersion", version)); + doc.Root.Add(propertyGroup); + } + + var itemGroup = new XElement("ItemGroup", new XAttribute("Condition", $" '$(PackageId)' == '{id}' AND '$(TargetFramework)' == '{group.TargetFramework.GetShortFolderName()}' ")); + doc.Root.Add(itemGroup); + + foreach (var dependency in group.Packages) + { + itemGroup.Add(new XElement("BaselinePackageReference", new XAttribute("Include", dependency.Id), new XAttribute("Version", dependency.VersionRange.ToString()))); + } + } + } + } + + var settings = new XmlWriterSettings + { + OmitXmlDeclaration = true, + Encoding = Encoding.UTF8, + Indent = true, + }; + using (var writer = XmlWriter.Create(output, settings)) + { + doc.Save(writer); + } + + return 0; + } + } +} diff --git a/eng/tools/BaselineGenerator/README.md b/eng/tools/BaselineGenerator/README.md new file mode 100644 index 0000000000..1afd97d1b5 --- /dev/null +++ b/eng/tools/BaselineGenerator/README.md @@ -0,0 +1,10 @@ +BaselineGenerator +================= + +This tool is used to generate an MSBuild file which sets the "baseline" against which servicing updates are built. + +## Usage + +1. Add to the [baseline.xml](./baseline.xml) a list of package ID's and their latest released versions. The source of this information can typically + be found in the build.xml file generated during ProdCon builds. See https://github.com/dotnet/versions/blob/master/build-info/dotnet/product/cli/release/2.1.6/build.xml for example. +2. Run `dotnet run` on this project. diff --git a/eng/tools/BaselineGenerator/baseline.xml b/eng/tools/BaselineGenerator/baseline.xml new file mode 100644 index 0000000000..3687f918d6 --- /dev/null +++ b/eng/tools/BaselineGenerator/baseline.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/eng/tools/Directory.Build.props b/eng/tools/Directory.Build.props new file mode 100644 index 0000000000..fda3ea0cbe --- /dev/null +++ b/eng/tools/Directory.Build.props @@ -0,0 +1,3 @@ + + + diff --git a/eng/tools/Directory.Build.targets b/eng/tools/Directory.Build.targets new file mode 100644 index 0000000000..f75adf7e4d --- /dev/null +++ b/eng/tools/Directory.Build.targets @@ -0,0 +1,2 @@ + + diff --git a/eng/tools/tools.sln b/eng/tools/tools.sln new file mode 100644 index 0000000000..527e47cbc3 --- /dev/null +++ b/eng/tools/tools.sln @@ -0,0 +1,34 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.26124.0 +MinimumVisualStudioVersion = 15.0.26124.0 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BaselineGenerator", "BaselineGenerator\BaselineGenerator.csproj", "{CF76A947-3A72-4824-87E6-BF029D84218B}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|Any CPU = Release|Any CPU + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {CF76A947-3A72-4824-87E6-BF029D84218B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {CF76A947-3A72-4824-87E6-BF029D84218B}.Debug|Any CPU.Build.0 = Debug|Any CPU + {CF76A947-3A72-4824-87E6-BF029D84218B}.Debug|x64.ActiveCfg = Debug|Any CPU + {CF76A947-3A72-4824-87E6-BF029D84218B}.Debug|x64.Build.0 = Debug|Any CPU + {CF76A947-3A72-4824-87E6-BF029D84218B}.Debug|x86.ActiveCfg = Debug|Any CPU + {CF76A947-3A72-4824-87E6-BF029D84218B}.Debug|x86.Build.0 = Debug|Any CPU + {CF76A947-3A72-4824-87E6-BF029D84218B}.Release|Any CPU.ActiveCfg = Release|Any CPU + {CF76A947-3A72-4824-87E6-BF029D84218B}.Release|Any CPU.Build.0 = Release|Any CPU + {CF76A947-3A72-4824-87E6-BF029D84218B}.Release|x64.ActiveCfg = Release|Any CPU + {CF76A947-3A72-4824-87E6-BF029D84218B}.Release|x64.Build.0 = Release|Any CPU + {CF76A947-3A72-4824-87E6-BF029D84218B}.Release|x86.ActiveCfg = Release|Any CPU + {CF76A947-3A72-4824-87E6-BF029D84218B}.Release|x86.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/src/DataProtection/Directory.Build.props b/src/DataProtection/Directory.Build.props index b18bd3713f..deb7bb4ee6 100644 --- a/src/DataProtection/Directory.Build.props +++ b/src/DataProtection/Directory.Build.props @@ -5,20 +5,4 @@ - - false - - - - - - - - - - - - - - diff --git a/src/Packages/Directory.Build.props b/src/Packages/Directory.Build.props index b917f91a06..fe11cd2f09 100644 --- a/src/Packages/Directory.Build.props +++ b/src/Packages/Directory.Build.props @@ -3,9 +3,7 @@ false + true - - - diff --git a/version.props b/version.props index 3e4178aafa..f0cbed211d 100644 --- a/version.props +++ b/version.props @@ -11,6 +11,8 @@ $(PreReleaseLabel)-$(BuildNumber) $(PreReleaseBrandingLabel) Build $(BuildNumber) + + true false true @@ -32,6 +34,9 @@ $(VersionSuffix)+$(VersionMetadata) release/$(AspNetCoreMajorVersion).$(AspNetCoreMinorVersion) + + + $(AspNetCoreMajorVersion).$(AspNetCoreMinorVersion).$([MSBuild]::Subtract($(AspNetCorePatchVersion), 1)) From 27a47d07c55256368c2fa4b44c1eb7fda94a1a4f Mon Sep 17 00:00:00 2001 From: Nate McMaster Date: Fri, 9 Nov 2018 13:06:13 -0800 Subject: [PATCH 217/221] Reorganize the src/WebSockets/ folder to follow new source code organization conventions --- src/Middleware/Middleware.sln | 120 +++++++++++++++ src/Middleware/WebSockets/README.md | 12 ++ .../AutobahnTestAppAspNet4.csproj.aspnet4 | 0 .../AutobahnTestAppAspNet4/EchoSocket.ashx | 0 .../AutobahnTestAppAspNet4/EchoSocket.ashx.cs | 0 .../Properties/AssemblyInfo.cs | 0 .../AutobahnTestAppAspNet4/Web.Debug.config | 0 .../AutobahnTestAppAspNet4/Web.Release.config | 0 .../samples/AutobahnTestAppAspNet4/Web.config | 0 .../AutobahnTestAppAspNet4/packages.config | 0 .../AutobahnTestAppAspNet4/wstest-spec.json | 0 .../AutobahnTestAppHttpListener/App.config | 0 .../AutobahnTestAppHttpListener.csproj.net461 | 0 .../AutobahnTestAppHttpListener/Program.cs | 0 .../Properties/AssemblyInfo.cs | 0 .../WebSockets/samples/EchoApp/EchoApp.csproj | 16 ++ .../WebSockets/samples/EchoApp/Program.cs | 0 .../EchoApp/Properties/launchSettings.json | 0 .../WebSockets/samples/EchoApp/Startup.cs | 0 .../samples/EchoApp/wwwroot/index.html | 0 .../WebSockets/samples/TestServer/App.config | 0 .../WebSockets/samples/TestServer/Program.cs | 0 .../TestServer/Properties/AssemblyInfo.cs | 0 .../samples/TestServer/TestServer.csproj | 0 .../WebSockets}/setup-wstest.ps1 | 0 .../WebSockets}/setup-wstest.sh | 0 .../src}/ExtendedWebSocketAcceptContext.cs | 0 .../WebSockets/src}/Internal/Constants.cs | 0 .../src}/Internal/HandshakeHelpers.cs | 0 .../Microsoft.AspNetCore.WebSockets.csproj | 6 +- .../WebSockets/src}/WebSocketMiddleware.cs | 0 .../src}/WebSocketMiddlewareExtensions.cs | 0 .../WebSockets/src}/WebSocketOptions.cs | 0 .../WebSockets/src}/baseline.netcore.json | 0 .../AutobahnTestApp/AutobahnTestApp.csproj | 22 +-- .../test/AutobahnTestApp/Program.cs | 0 .../Properties/launchSettings.json | 0 .../WebSockets/test/AutobahnTestApp/README.md | 0 .../test/AutobahnTestApp/Startup.cs | 0 .../TestResources/testCert.pfx | Bin .../TestResources/testCert.txt | 0 .../scripts/RunAutobahnTests.ps1 | 0 .../scripts/autobahn.spec.json | 0 .../Autobahn/AutobahnCaseResult.cs | 0 .../Autobahn/AutobahnExpectations.cs | 0 .../Autobahn/AutobahnResult.cs | 0 .../Autobahn/AutobahnServerResult.cs | 0 .../Autobahn/AutobahnSpec.cs | 0 .../Autobahn/AutobahnTester.cs | 0 .../ConformanceTests}/Autobahn/Executable.cs | 0 .../ConformanceTests}/Autobahn/Expectation.cs | 0 .../ConformanceTests}/Autobahn/ServerSpec.cs | 0 .../test/ConformanceTests}/Autobahn/Wstest.cs | 0 .../test/ConformanceTests}/AutobahnTests.cs | 0 .../test/ConformanceTests}/Helpers.cs | 0 .../test/ConformanceTests}/Http.config | 0 ...NetCore.WebSockets.ConformanceTests.csproj | 15 ++ .../SkipIfWsTestNotPresentAttribute.cs | 0 .../WebSockets/test/Directory.Build.props | 27 ++++ .../test/UnitTests}/BufferStream.cs | 0 .../test/UnitTests}/DuplexStream.cs | 0 .../test/UnitTests}/IWebHostPortExtensions.cs | 0 .../UnitTests}/KestrelWebSocketHelpers.cs | 0 ...crosoft.AspNetCore.WebSockets.Tests.csproj | 14 ++ .../test/UnitTests}/SendReceiveTests.cs | 0 .../UnitTests}/WebSocketMiddlewareTests.cs | 0 .../test/UnitTests}/WebSocketPair.cs | 0 src/WebSockets/.gitignore | 31 ---- src/WebSockets/Directory.Build.props | 20 --- src/WebSockets/Directory.Build.targets | 7 - src/WebSockets/NuGetPackageVerifier.json | 7 - src/WebSockets/README.md | 19 --- src/WebSockets/WebSockets.sln | 145 ------------------ src/WebSockets/build.cmd | 3 - src/WebSockets/build.sh | 7 - src/WebSockets/build/Key.snk | Bin 596 -> 0 bytes src/WebSockets/build/dependencies.props | 39 ----- src/WebSockets/build/repo.props | 18 --- src/WebSockets/build/repo.targets | 9 -- src/WebSockets/build/sources.props | 17 -- src/WebSockets/samples/EchoApp/EchoApp.csproj | 19 --- src/WebSockets/src/Directory.Build.props | 7 - src/WebSockets/test/Directory.Build.props | 22 --- ...pNetCore.WebSockets.ConformanceTest.csproj | 18 --- ...icrosoft.AspNetCore.WebSockets.Test.csproj | 21 --- src/WebSockets/version.props | 12 -- 86 files changed, 218 insertions(+), 435 deletions(-) create mode 100644 src/Middleware/Middleware.sln create mode 100644 src/Middleware/WebSockets/README.md rename src/{ => Middleware}/WebSockets/samples/AutobahnTestAppAspNet4/AutobahnTestAppAspNet4.csproj.aspnet4 (100%) rename src/{ => Middleware}/WebSockets/samples/AutobahnTestAppAspNet4/EchoSocket.ashx (100%) rename src/{ => Middleware}/WebSockets/samples/AutobahnTestAppAspNet4/EchoSocket.ashx.cs (100%) rename src/{ => Middleware}/WebSockets/samples/AutobahnTestAppAspNet4/Properties/AssemblyInfo.cs (100%) rename src/{ => Middleware}/WebSockets/samples/AutobahnTestAppAspNet4/Web.Debug.config (100%) rename src/{ => Middleware}/WebSockets/samples/AutobahnTestAppAspNet4/Web.Release.config (100%) rename src/{ => Middleware}/WebSockets/samples/AutobahnTestAppAspNet4/Web.config (100%) rename src/{ => Middleware}/WebSockets/samples/AutobahnTestAppAspNet4/packages.config (100%) rename src/{ => Middleware}/WebSockets/samples/AutobahnTestAppAspNet4/wstest-spec.json (100%) rename src/{ => Middleware}/WebSockets/samples/AutobahnTestAppHttpListener/App.config (100%) rename src/{ => Middleware}/WebSockets/samples/AutobahnTestAppHttpListener/AutobahnTestAppHttpListener.csproj.net461 (100%) rename src/{ => Middleware}/WebSockets/samples/AutobahnTestAppHttpListener/Program.cs (100%) rename src/{ => Middleware}/WebSockets/samples/AutobahnTestAppHttpListener/Properties/AssemblyInfo.cs (100%) create mode 100644 src/Middleware/WebSockets/samples/EchoApp/EchoApp.csproj rename src/{ => Middleware}/WebSockets/samples/EchoApp/Program.cs (100%) rename src/{ => Middleware}/WebSockets/samples/EchoApp/Properties/launchSettings.json (100%) rename src/{ => Middleware}/WebSockets/samples/EchoApp/Startup.cs (100%) rename src/{ => Middleware}/WebSockets/samples/EchoApp/wwwroot/index.html (100%) rename src/{ => Middleware}/WebSockets/samples/TestServer/App.config (100%) rename src/{ => Middleware}/WebSockets/samples/TestServer/Program.cs (100%) rename src/{ => Middleware}/WebSockets/samples/TestServer/Properties/AssemblyInfo.cs (100%) rename src/{ => Middleware}/WebSockets/samples/TestServer/TestServer.csproj (100%) rename src/{WebSockets/build => Middleware/WebSockets}/setup-wstest.ps1 (100%) rename src/{WebSockets/build => Middleware/WebSockets}/setup-wstest.sh (100%) mode change 100755 => 100644 rename src/{WebSockets/src/Microsoft.AspNetCore.WebSockets => Middleware/WebSockets/src}/ExtendedWebSocketAcceptContext.cs (100%) rename src/{WebSockets/src/Microsoft.AspNetCore.WebSockets => Middleware/WebSockets/src}/Internal/Constants.cs (100%) rename src/{WebSockets/src/Microsoft.AspNetCore.WebSockets => Middleware/WebSockets/src}/Internal/HandshakeHelpers.cs (100%) rename src/{WebSockets/src/Microsoft.AspNetCore.WebSockets => Middleware/WebSockets/src}/Microsoft.AspNetCore.WebSockets.csproj (54%) rename src/{WebSockets/src/Microsoft.AspNetCore.WebSockets => Middleware/WebSockets/src}/WebSocketMiddleware.cs (100%) rename src/{WebSockets/src/Microsoft.AspNetCore.WebSockets => Middleware/WebSockets/src}/WebSocketMiddlewareExtensions.cs (100%) rename src/{WebSockets/src/Microsoft.AspNetCore.WebSockets => Middleware/WebSockets/src}/WebSocketOptions.cs (100%) rename src/{WebSockets/src/Microsoft.AspNetCore.WebSockets => Middleware/WebSockets/src}/baseline.netcore.json (100%) rename src/{ => Middleware}/WebSockets/test/AutobahnTestApp/AutobahnTestApp.csproj (75%) rename src/{ => Middleware}/WebSockets/test/AutobahnTestApp/Program.cs (100%) rename src/{ => Middleware}/WebSockets/test/AutobahnTestApp/Properties/launchSettings.json (100%) rename src/{ => Middleware}/WebSockets/test/AutobahnTestApp/README.md (100%) rename src/{ => Middleware}/WebSockets/test/AutobahnTestApp/Startup.cs (100%) rename src/{ => Middleware}/WebSockets/test/AutobahnTestApp/TestResources/testCert.pfx (100%) rename src/{ => Middleware}/WebSockets/test/AutobahnTestApp/TestResources/testCert.txt (100%) rename src/{ => Middleware}/WebSockets/test/AutobahnTestApp/scripts/RunAutobahnTests.ps1 (100%) rename src/{ => Middleware}/WebSockets/test/AutobahnTestApp/scripts/autobahn.spec.json (100%) rename src/{WebSockets/test/Microsoft.AspNetCore.WebSockets.ConformanceTest => Middleware/WebSockets/test/ConformanceTests}/Autobahn/AutobahnCaseResult.cs (100%) rename src/{WebSockets/test/Microsoft.AspNetCore.WebSockets.ConformanceTest => Middleware/WebSockets/test/ConformanceTests}/Autobahn/AutobahnExpectations.cs (100%) rename src/{WebSockets/test/Microsoft.AspNetCore.WebSockets.ConformanceTest => Middleware/WebSockets/test/ConformanceTests}/Autobahn/AutobahnResult.cs (100%) rename src/{WebSockets/test/Microsoft.AspNetCore.WebSockets.ConformanceTest => Middleware/WebSockets/test/ConformanceTests}/Autobahn/AutobahnServerResult.cs (100%) rename src/{WebSockets/test/Microsoft.AspNetCore.WebSockets.ConformanceTest => Middleware/WebSockets/test/ConformanceTests}/Autobahn/AutobahnSpec.cs (100%) rename src/{WebSockets/test/Microsoft.AspNetCore.WebSockets.ConformanceTest => Middleware/WebSockets/test/ConformanceTests}/Autobahn/AutobahnTester.cs (100%) rename src/{WebSockets/test/Microsoft.AspNetCore.WebSockets.ConformanceTest => Middleware/WebSockets/test/ConformanceTests}/Autobahn/Executable.cs (100%) rename src/{WebSockets/test/Microsoft.AspNetCore.WebSockets.ConformanceTest => Middleware/WebSockets/test/ConformanceTests}/Autobahn/Expectation.cs (100%) rename src/{WebSockets/test/Microsoft.AspNetCore.WebSockets.ConformanceTest => Middleware/WebSockets/test/ConformanceTests}/Autobahn/ServerSpec.cs (100%) rename src/{WebSockets/test/Microsoft.AspNetCore.WebSockets.ConformanceTest => Middleware/WebSockets/test/ConformanceTests}/Autobahn/Wstest.cs (100%) rename src/{WebSockets/test/Microsoft.AspNetCore.WebSockets.ConformanceTest => Middleware/WebSockets/test/ConformanceTests}/AutobahnTests.cs (100%) rename src/{WebSockets/test/Microsoft.AspNetCore.WebSockets.ConformanceTest => Middleware/WebSockets/test/ConformanceTests}/Helpers.cs (100%) rename src/{WebSockets/test/Microsoft.AspNetCore.WebSockets.ConformanceTest => Middleware/WebSockets/test/ConformanceTests}/Http.config (100%) create mode 100644 src/Middleware/WebSockets/test/ConformanceTests/Microsoft.AspNetCore.WebSockets.ConformanceTests.csproj rename src/{WebSockets/test/Microsoft.AspNetCore.WebSockets.ConformanceTest => Middleware/WebSockets/test/ConformanceTests}/SkipIfWsTestNotPresentAttribute.cs (100%) create mode 100644 src/Middleware/WebSockets/test/Directory.Build.props rename src/{WebSockets/test/Microsoft.AspNetCore.WebSockets.Test => Middleware/WebSockets/test/UnitTests}/BufferStream.cs (100%) rename src/{WebSockets/test/Microsoft.AspNetCore.WebSockets.Test => Middleware/WebSockets/test/UnitTests}/DuplexStream.cs (100%) rename src/{WebSockets/test/Microsoft.AspNetCore.WebSockets.Test => Middleware/WebSockets/test/UnitTests}/IWebHostPortExtensions.cs (100%) rename src/{WebSockets/test/Microsoft.AspNetCore.WebSockets.Test => Middleware/WebSockets/test/UnitTests}/KestrelWebSocketHelpers.cs (100%) create mode 100644 src/Middleware/WebSockets/test/UnitTests/Microsoft.AspNetCore.WebSockets.Tests.csproj rename src/{WebSockets/test/Microsoft.AspNetCore.WebSockets.Test => Middleware/WebSockets/test/UnitTests}/SendReceiveTests.cs (100%) rename src/{WebSockets/test/Microsoft.AspNetCore.WebSockets.Test => Middleware/WebSockets/test/UnitTests}/WebSocketMiddlewareTests.cs (100%) rename src/{WebSockets/test/Microsoft.AspNetCore.WebSockets.Test => Middleware/WebSockets/test/UnitTests}/WebSocketPair.cs (100%) delete mode 100644 src/WebSockets/.gitignore delete mode 100644 src/WebSockets/Directory.Build.props delete mode 100644 src/WebSockets/Directory.Build.targets delete mode 100644 src/WebSockets/NuGetPackageVerifier.json delete mode 100644 src/WebSockets/README.md delete mode 100644 src/WebSockets/WebSockets.sln delete mode 100644 src/WebSockets/build.cmd delete mode 100755 src/WebSockets/build.sh delete mode 100644 src/WebSockets/build/Key.snk delete mode 100644 src/WebSockets/build/dependencies.props delete mode 100644 src/WebSockets/build/repo.props delete mode 100644 src/WebSockets/build/repo.targets delete mode 100644 src/WebSockets/build/sources.props delete mode 100644 src/WebSockets/samples/EchoApp/EchoApp.csproj delete mode 100644 src/WebSockets/src/Directory.Build.props delete mode 100644 src/WebSockets/test/Directory.Build.props delete mode 100644 src/WebSockets/test/Microsoft.AspNetCore.WebSockets.ConformanceTest/Microsoft.AspNetCore.WebSockets.ConformanceTest.csproj delete mode 100644 src/WebSockets/test/Microsoft.AspNetCore.WebSockets.Test/Microsoft.AspNetCore.WebSockets.Test.csproj delete mode 100644 src/WebSockets/version.props diff --git a/src/Middleware/Middleware.sln b/src/Middleware/Middleware.sln new file mode 100644 index 0000000000..28a99b57c6 --- /dev/null +++ b/src/Middleware/Middleware.sln @@ -0,0 +1,120 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.26124.0 +MinimumVisualStudioVersion = 15.0.26124.0 +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "WebSockets", "WebSockets", "{E0D9867D-C23D-43EB-8D9C-DE0398A25432}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "samples", "samples", "{A86EE055-ACD3-4BAC-A51D-1B3C71067AE0}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EchoApp", "WebSockets\samples\EchoApp\EchoApp.csproj", "{0792C20B-1D18-4D7C-9C0F-A6F45A0F378E}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestServer", "WebSockets\samples\TestServer\TestServer.csproj", "{4E5F5FCC-172C-44D9-BEA0-39098A79CD0B}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.WebSockets", "WebSockets\src\Microsoft.AspNetCore.WebSockets.csproj", "{BECAA6A1-1AA4-415E-ADF3-07C103333826}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AutobahnTestApp", "WebSockets\test\AutobahnTestApp\AutobahnTestApp.csproj", "{76B25812-AAFB-45BA-A71A-24F0C654ADFB}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.WebSockets.ConformanceTests", "WebSockets\test\ConformanceTests\Microsoft.AspNetCore.WebSockets.ConformanceTests.csproj", "{88BDEE69-4DE3-40B5-A478-677EA355FB52}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.WebSockets.Tests", "WebSockets\test\UnitTests\Microsoft.AspNetCore.WebSockets.Tests.csproj", "{93970702-1BDB-4A8C-B7F6-020294464BB6}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|Any CPU = Release|Any CPU + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {0792C20B-1D18-4D7C-9C0F-A6F45A0F378E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {0792C20B-1D18-4D7C-9C0F-A6F45A0F378E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0792C20B-1D18-4D7C-9C0F-A6F45A0F378E}.Debug|x64.ActiveCfg = Debug|Any CPU + {0792C20B-1D18-4D7C-9C0F-A6F45A0F378E}.Debug|x64.Build.0 = Debug|Any CPU + {0792C20B-1D18-4D7C-9C0F-A6F45A0F378E}.Debug|x86.ActiveCfg = Debug|Any CPU + {0792C20B-1D18-4D7C-9C0F-A6F45A0F378E}.Debug|x86.Build.0 = Debug|Any CPU + {0792C20B-1D18-4D7C-9C0F-A6F45A0F378E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {0792C20B-1D18-4D7C-9C0F-A6F45A0F378E}.Release|Any CPU.Build.0 = Release|Any CPU + {0792C20B-1D18-4D7C-9C0F-A6F45A0F378E}.Release|x64.ActiveCfg = Release|Any CPU + {0792C20B-1D18-4D7C-9C0F-A6F45A0F378E}.Release|x64.Build.0 = Release|Any CPU + {0792C20B-1D18-4D7C-9C0F-A6F45A0F378E}.Release|x86.ActiveCfg = Release|Any CPU + {0792C20B-1D18-4D7C-9C0F-A6F45A0F378E}.Release|x86.Build.0 = Release|Any CPU + {4E5F5FCC-172C-44D9-BEA0-39098A79CD0B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4E5F5FCC-172C-44D9-BEA0-39098A79CD0B}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4E5F5FCC-172C-44D9-BEA0-39098A79CD0B}.Debug|x64.ActiveCfg = Debug|Any CPU + {4E5F5FCC-172C-44D9-BEA0-39098A79CD0B}.Debug|x64.Build.0 = Debug|Any CPU + {4E5F5FCC-172C-44D9-BEA0-39098A79CD0B}.Debug|x86.ActiveCfg = Debug|Any CPU + {4E5F5FCC-172C-44D9-BEA0-39098A79CD0B}.Debug|x86.Build.0 = Debug|Any CPU + {4E5F5FCC-172C-44D9-BEA0-39098A79CD0B}.Release|Any CPU.ActiveCfg = Debug|Any CPU + {4E5F5FCC-172C-44D9-BEA0-39098A79CD0B}.Release|Any CPU.Build.0 = Debug|Any CPU + {4E5F5FCC-172C-44D9-BEA0-39098A79CD0B}.Release|x64.ActiveCfg = Debug|Any CPU + {4E5F5FCC-172C-44D9-BEA0-39098A79CD0B}.Release|x64.Build.0 = Debug|Any CPU + {4E5F5FCC-172C-44D9-BEA0-39098A79CD0B}.Release|x86.ActiveCfg = Debug|Any CPU + {4E5F5FCC-172C-44D9-BEA0-39098A79CD0B}.Release|x86.Build.0 = Debug|Any CPU + {BECAA6A1-1AA4-415E-ADF3-07C103333826}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {BECAA6A1-1AA4-415E-ADF3-07C103333826}.Debug|Any CPU.Build.0 = Debug|Any CPU + {BECAA6A1-1AA4-415E-ADF3-07C103333826}.Debug|x64.ActiveCfg = Debug|Any CPU + {BECAA6A1-1AA4-415E-ADF3-07C103333826}.Debug|x64.Build.0 = Debug|Any CPU + {BECAA6A1-1AA4-415E-ADF3-07C103333826}.Debug|x86.ActiveCfg = Debug|Any CPU + {BECAA6A1-1AA4-415E-ADF3-07C103333826}.Debug|x86.Build.0 = Debug|Any CPU + {BECAA6A1-1AA4-415E-ADF3-07C103333826}.Release|Any CPU.ActiveCfg = Release|Any CPU + {BECAA6A1-1AA4-415E-ADF3-07C103333826}.Release|Any CPU.Build.0 = Release|Any CPU + {BECAA6A1-1AA4-415E-ADF3-07C103333826}.Release|x64.ActiveCfg = Release|Any CPU + {BECAA6A1-1AA4-415E-ADF3-07C103333826}.Release|x64.Build.0 = Release|Any CPU + {BECAA6A1-1AA4-415E-ADF3-07C103333826}.Release|x86.ActiveCfg = Release|Any CPU + {BECAA6A1-1AA4-415E-ADF3-07C103333826}.Release|x86.Build.0 = Release|Any CPU + {76B25812-AAFB-45BA-A71A-24F0C654ADFB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {76B25812-AAFB-45BA-A71A-24F0C654ADFB}.Debug|Any CPU.Build.0 = Debug|Any CPU + {76B25812-AAFB-45BA-A71A-24F0C654ADFB}.Debug|x64.ActiveCfg = Debug|Any CPU + {76B25812-AAFB-45BA-A71A-24F0C654ADFB}.Debug|x64.Build.0 = Debug|Any CPU + {76B25812-AAFB-45BA-A71A-24F0C654ADFB}.Debug|x86.ActiveCfg = Debug|Any CPU + {76B25812-AAFB-45BA-A71A-24F0C654ADFB}.Debug|x86.Build.0 = Debug|Any CPU + {76B25812-AAFB-45BA-A71A-24F0C654ADFB}.Release|Any CPU.ActiveCfg = Release|Any CPU + {76B25812-AAFB-45BA-A71A-24F0C654ADFB}.Release|Any CPU.Build.0 = Release|Any CPU + {76B25812-AAFB-45BA-A71A-24F0C654ADFB}.Release|x64.ActiveCfg = Release|Any CPU + {76B25812-AAFB-45BA-A71A-24F0C654ADFB}.Release|x64.Build.0 = Release|Any CPU + {76B25812-AAFB-45BA-A71A-24F0C654ADFB}.Release|x86.ActiveCfg = Release|Any CPU + {76B25812-AAFB-45BA-A71A-24F0C654ADFB}.Release|x86.Build.0 = Release|Any CPU + {88BDEE69-4DE3-40B5-A478-677EA355FB52}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {88BDEE69-4DE3-40B5-A478-677EA355FB52}.Debug|Any CPU.Build.0 = Debug|Any CPU + {88BDEE69-4DE3-40B5-A478-677EA355FB52}.Debug|x64.ActiveCfg = Debug|Any CPU + {88BDEE69-4DE3-40B5-A478-677EA355FB52}.Debug|x64.Build.0 = Debug|Any CPU + {88BDEE69-4DE3-40B5-A478-677EA355FB52}.Debug|x86.ActiveCfg = Debug|Any CPU + {88BDEE69-4DE3-40B5-A478-677EA355FB52}.Debug|x86.Build.0 = Debug|Any CPU + {88BDEE69-4DE3-40B5-A478-677EA355FB52}.Release|Any CPU.ActiveCfg = Release|Any CPU + {88BDEE69-4DE3-40B5-A478-677EA355FB52}.Release|Any CPU.Build.0 = Release|Any CPU + {88BDEE69-4DE3-40B5-A478-677EA355FB52}.Release|x64.ActiveCfg = Release|Any CPU + {88BDEE69-4DE3-40B5-A478-677EA355FB52}.Release|x64.Build.0 = Release|Any CPU + {88BDEE69-4DE3-40B5-A478-677EA355FB52}.Release|x86.ActiveCfg = Release|Any CPU + {88BDEE69-4DE3-40B5-A478-677EA355FB52}.Release|x86.Build.0 = Release|Any CPU + {93970702-1BDB-4A8C-B7F6-020294464BB6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {93970702-1BDB-4A8C-B7F6-020294464BB6}.Debug|Any CPU.Build.0 = Debug|Any CPU + {93970702-1BDB-4A8C-B7F6-020294464BB6}.Debug|x64.ActiveCfg = Debug|Any CPU + {93970702-1BDB-4A8C-B7F6-020294464BB6}.Debug|x64.Build.0 = Debug|Any CPU + {93970702-1BDB-4A8C-B7F6-020294464BB6}.Debug|x86.ActiveCfg = Debug|Any CPU + {93970702-1BDB-4A8C-B7F6-020294464BB6}.Debug|x86.Build.0 = Debug|Any CPU + {93970702-1BDB-4A8C-B7F6-020294464BB6}.Release|Any CPU.ActiveCfg = Release|Any CPU + {93970702-1BDB-4A8C-B7F6-020294464BB6}.Release|Any CPU.Build.0 = Release|Any CPU + {93970702-1BDB-4A8C-B7F6-020294464BB6}.Release|x64.ActiveCfg = Release|Any CPU + {93970702-1BDB-4A8C-B7F6-020294464BB6}.Release|x64.Build.0 = Release|Any CPU + {93970702-1BDB-4A8C-B7F6-020294464BB6}.Release|x86.ActiveCfg = Release|Any CPU + {93970702-1BDB-4A8C-B7F6-020294464BB6}.Release|x86.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {A86EE055-ACD3-4BAC-A51D-1B3C71067AE0} = {E0D9867D-C23D-43EB-8D9C-DE0398A25432} + {0792C20B-1D18-4D7C-9C0F-A6F45A0F378E} = {A86EE055-ACD3-4BAC-A51D-1B3C71067AE0} + {4E5F5FCC-172C-44D9-BEA0-39098A79CD0B} = {A86EE055-ACD3-4BAC-A51D-1B3C71067AE0} + {BECAA6A1-1AA4-415E-ADF3-07C103333826} = {E0D9867D-C23D-43EB-8D9C-DE0398A25432} + {76B25812-AAFB-45BA-A71A-24F0C654ADFB} = {E0D9867D-C23D-43EB-8D9C-DE0398A25432} + {88BDEE69-4DE3-40B5-A478-677EA355FB52} = {E0D9867D-C23D-43EB-8D9C-DE0398A25432} + {93970702-1BDB-4A8C-B7F6-020294464BB6} = {E0D9867D-C23D-43EB-8D9C-DE0398A25432} + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {83786312-A93B-4BB4-AB06-7C6913A59AFA} + EndGlobalSection +EndGlobal diff --git a/src/Middleware/WebSockets/README.md b/src/Middleware/WebSockets/README.md new file mode 100644 index 0000000000..19061a2ad5 --- /dev/null +++ b/src/Middleware/WebSockets/README.md @@ -0,0 +1,12 @@ +WebSockets +========== + +Contains a managed implementation of the WebSocket protocol, along with server integration components. + +## System Requirements + +This repo has a few special system requirements/prerequisites. + +1. Windows IIS Express tests require IIS Express 10 and Windows 8 for WebSockets support +2. HttpListener/ASP.NET 4.6 samples require at least Windows 8 +3. Autobahn Test Suite requires special installation see the README.md in [test/AutobahnTestApp](./test/AutobahnTestApp/README.md) diff --git a/src/WebSockets/samples/AutobahnTestAppAspNet4/AutobahnTestAppAspNet4.csproj.aspnet4 b/src/Middleware/WebSockets/samples/AutobahnTestAppAspNet4/AutobahnTestAppAspNet4.csproj.aspnet4 similarity index 100% rename from src/WebSockets/samples/AutobahnTestAppAspNet4/AutobahnTestAppAspNet4.csproj.aspnet4 rename to src/Middleware/WebSockets/samples/AutobahnTestAppAspNet4/AutobahnTestAppAspNet4.csproj.aspnet4 diff --git a/src/WebSockets/samples/AutobahnTestAppAspNet4/EchoSocket.ashx b/src/Middleware/WebSockets/samples/AutobahnTestAppAspNet4/EchoSocket.ashx similarity index 100% rename from src/WebSockets/samples/AutobahnTestAppAspNet4/EchoSocket.ashx rename to src/Middleware/WebSockets/samples/AutobahnTestAppAspNet4/EchoSocket.ashx diff --git a/src/WebSockets/samples/AutobahnTestAppAspNet4/EchoSocket.ashx.cs b/src/Middleware/WebSockets/samples/AutobahnTestAppAspNet4/EchoSocket.ashx.cs similarity index 100% rename from src/WebSockets/samples/AutobahnTestAppAspNet4/EchoSocket.ashx.cs rename to src/Middleware/WebSockets/samples/AutobahnTestAppAspNet4/EchoSocket.ashx.cs diff --git a/src/WebSockets/samples/AutobahnTestAppAspNet4/Properties/AssemblyInfo.cs b/src/Middleware/WebSockets/samples/AutobahnTestAppAspNet4/Properties/AssemblyInfo.cs similarity index 100% rename from src/WebSockets/samples/AutobahnTestAppAspNet4/Properties/AssemblyInfo.cs rename to src/Middleware/WebSockets/samples/AutobahnTestAppAspNet4/Properties/AssemblyInfo.cs diff --git a/src/WebSockets/samples/AutobahnTestAppAspNet4/Web.Debug.config b/src/Middleware/WebSockets/samples/AutobahnTestAppAspNet4/Web.Debug.config similarity index 100% rename from src/WebSockets/samples/AutobahnTestAppAspNet4/Web.Debug.config rename to src/Middleware/WebSockets/samples/AutobahnTestAppAspNet4/Web.Debug.config diff --git a/src/WebSockets/samples/AutobahnTestAppAspNet4/Web.Release.config b/src/Middleware/WebSockets/samples/AutobahnTestAppAspNet4/Web.Release.config similarity index 100% rename from src/WebSockets/samples/AutobahnTestAppAspNet4/Web.Release.config rename to src/Middleware/WebSockets/samples/AutobahnTestAppAspNet4/Web.Release.config diff --git a/src/WebSockets/samples/AutobahnTestAppAspNet4/Web.config b/src/Middleware/WebSockets/samples/AutobahnTestAppAspNet4/Web.config similarity index 100% rename from src/WebSockets/samples/AutobahnTestAppAspNet4/Web.config rename to src/Middleware/WebSockets/samples/AutobahnTestAppAspNet4/Web.config diff --git a/src/WebSockets/samples/AutobahnTestAppAspNet4/packages.config b/src/Middleware/WebSockets/samples/AutobahnTestAppAspNet4/packages.config similarity index 100% rename from src/WebSockets/samples/AutobahnTestAppAspNet4/packages.config rename to src/Middleware/WebSockets/samples/AutobahnTestAppAspNet4/packages.config diff --git a/src/WebSockets/samples/AutobahnTestAppAspNet4/wstest-spec.json b/src/Middleware/WebSockets/samples/AutobahnTestAppAspNet4/wstest-spec.json similarity index 100% rename from src/WebSockets/samples/AutobahnTestAppAspNet4/wstest-spec.json rename to src/Middleware/WebSockets/samples/AutobahnTestAppAspNet4/wstest-spec.json diff --git a/src/WebSockets/samples/AutobahnTestAppHttpListener/App.config b/src/Middleware/WebSockets/samples/AutobahnTestAppHttpListener/App.config similarity index 100% rename from src/WebSockets/samples/AutobahnTestAppHttpListener/App.config rename to src/Middleware/WebSockets/samples/AutobahnTestAppHttpListener/App.config diff --git a/src/WebSockets/samples/AutobahnTestAppHttpListener/AutobahnTestAppHttpListener.csproj.net461 b/src/Middleware/WebSockets/samples/AutobahnTestAppHttpListener/AutobahnTestAppHttpListener.csproj.net461 similarity index 100% rename from src/WebSockets/samples/AutobahnTestAppHttpListener/AutobahnTestAppHttpListener.csproj.net461 rename to src/Middleware/WebSockets/samples/AutobahnTestAppHttpListener/AutobahnTestAppHttpListener.csproj.net461 diff --git a/src/WebSockets/samples/AutobahnTestAppHttpListener/Program.cs b/src/Middleware/WebSockets/samples/AutobahnTestAppHttpListener/Program.cs similarity index 100% rename from src/WebSockets/samples/AutobahnTestAppHttpListener/Program.cs rename to src/Middleware/WebSockets/samples/AutobahnTestAppHttpListener/Program.cs diff --git a/src/WebSockets/samples/AutobahnTestAppHttpListener/Properties/AssemblyInfo.cs b/src/Middleware/WebSockets/samples/AutobahnTestAppHttpListener/Properties/AssemblyInfo.cs similarity index 100% rename from src/WebSockets/samples/AutobahnTestAppHttpListener/Properties/AssemblyInfo.cs rename to src/Middleware/WebSockets/samples/AutobahnTestAppHttpListener/Properties/AssemblyInfo.cs diff --git a/src/Middleware/WebSockets/samples/EchoApp/EchoApp.csproj b/src/Middleware/WebSockets/samples/EchoApp/EchoApp.csproj new file mode 100644 index 0000000000..cc5ea2afc1 --- /dev/null +++ b/src/Middleware/WebSockets/samples/EchoApp/EchoApp.csproj @@ -0,0 +1,16 @@ + + + + netcoreapp2.1;net461 + + + + + + + + + + + + diff --git a/src/WebSockets/samples/EchoApp/Program.cs b/src/Middleware/WebSockets/samples/EchoApp/Program.cs similarity index 100% rename from src/WebSockets/samples/EchoApp/Program.cs rename to src/Middleware/WebSockets/samples/EchoApp/Program.cs diff --git a/src/WebSockets/samples/EchoApp/Properties/launchSettings.json b/src/Middleware/WebSockets/samples/EchoApp/Properties/launchSettings.json similarity index 100% rename from src/WebSockets/samples/EchoApp/Properties/launchSettings.json rename to src/Middleware/WebSockets/samples/EchoApp/Properties/launchSettings.json diff --git a/src/WebSockets/samples/EchoApp/Startup.cs b/src/Middleware/WebSockets/samples/EchoApp/Startup.cs similarity index 100% rename from src/WebSockets/samples/EchoApp/Startup.cs rename to src/Middleware/WebSockets/samples/EchoApp/Startup.cs diff --git a/src/WebSockets/samples/EchoApp/wwwroot/index.html b/src/Middleware/WebSockets/samples/EchoApp/wwwroot/index.html similarity index 100% rename from src/WebSockets/samples/EchoApp/wwwroot/index.html rename to src/Middleware/WebSockets/samples/EchoApp/wwwroot/index.html diff --git a/src/WebSockets/samples/TestServer/App.config b/src/Middleware/WebSockets/samples/TestServer/App.config similarity index 100% rename from src/WebSockets/samples/TestServer/App.config rename to src/Middleware/WebSockets/samples/TestServer/App.config diff --git a/src/WebSockets/samples/TestServer/Program.cs b/src/Middleware/WebSockets/samples/TestServer/Program.cs similarity index 100% rename from src/WebSockets/samples/TestServer/Program.cs rename to src/Middleware/WebSockets/samples/TestServer/Program.cs diff --git a/src/WebSockets/samples/TestServer/Properties/AssemblyInfo.cs b/src/Middleware/WebSockets/samples/TestServer/Properties/AssemblyInfo.cs similarity index 100% rename from src/WebSockets/samples/TestServer/Properties/AssemblyInfo.cs rename to src/Middleware/WebSockets/samples/TestServer/Properties/AssemblyInfo.cs diff --git a/src/WebSockets/samples/TestServer/TestServer.csproj b/src/Middleware/WebSockets/samples/TestServer/TestServer.csproj similarity index 100% rename from src/WebSockets/samples/TestServer/TestServer.csproj rename to src/Middleware/WebSockets/samples/TestServer/TestServer.csproj diff --git a/src/WebSockets/build/setup-wstest.ps1 b/src/Middleware/WebSockets/setup-wstest.ps1 similarity index 100% rename from src/WebSockets/build/setup-wstest.ps1 rename to src/Middleware/WebSockets/setup-wstest.ps1 diff --git a/src/WebSockets/build/setup-wstest.sh b/src/Middleware/WebSockets/setup-wstest.sh old mode 100755 new mode 100644 similarity index 100% rename from src/WebSockets/build/setup-wstest.sh rename to src/Middleware/WebSockets/setup-wstest.sh diff --git a/src/WebSockets/src/Microsoft.AspNetCore.WebSockets/ExtendedWebSocketAcceptContext.cs b/src/Middleware/WebSockets/src/ExtendedWebSocketAcceptContext.cs similarity index 100% rename from src/WebSockets/src/Microsoft.AspNetCore.WebSockets/ExtendedWebSocketAcceptContext.cs rename to src/Middleware/WebSockets/src/ExtendedWebSocketAcceptContext.cs diff --git a/src/WebSockets/src/Microsoft.AspNetCore.WebSockets/Internal/Constants.cs b/src/Middleware/WebSockets/src/Internal/Constants.cs similarity index 100% rename from src/WebSockets/src/Microsoft.AspNetCore.WebSockets/Internal/Constants.cs rename to src/Middleware/WebSockets/src/Internal/Constants.cs diff --git a/src/WebSockets/src/Microsoft.AspNetCore.WebSockets/Internal/HandshakeHelpers.cs b/src/Middleware/WebSockets/src/Internal/HandshakeHelpers.cs similarity index 100% rename from src/WebSockets/src/Microsoft.AspNetCore.WebSockets/Internal/HandshakeHelpers.cs rename to src/Middleware/WebSockets/src/Internal/HandshakeHelpers.cs diff --git a/src/WebSockets/src/Microsoft.AspNetCore.WebSockets/Microsoft.AspNetCore.WebSockets.csproj b/src/Middleware/WebSockets/src/Microsoft.AspNetCore.WebSockets.csproj similarity index 54% rename from src/WebSockets/src/Microsoft.AspNetCore.WebSockets/Microsoft.AspNetCore.WebSockets.csproj rename to src/Middleware/WebSockets/src/Microsoft.AspNetCore.WebSockets.csproj index c5c5c8fbfb..5ff6bed15f 100644 --- a/src/WebSockets/src/Microsoft.AspNetCore.WebSockets/Microsoft.AspNetCore.WebSockets.csproj +++ b/src/Middleware/WebSockets/src/Microsoft.AspNetCore.WebSockets.csproj @@ -10,9 +10,9 @@ - - - + + + diff --git a/src/WebSockets/src/Microsoft.AspNetCore.WebSockets/WebSocketMiddleware.cs b/src/Middleware/WebSockets/src/WebSocketMiddleware.cs similarity index 100% rename from src/WebSockets/src/Microsoft.AspNetCore.WebSockets/WebSocketMiddleware.cs rename to src/Middleware/WebSockets/src/WebSocketMiddleware.cs diff --git a/src/WebSockets/src/Microsoft.AspNetCore.WebSockets/WebSocketMiddlewareExtensions.cs b/src/Middleware/WebSockets/src/WebSocketMiddlewareExtensions.cs similarity index 100% rename from src/WebSockets/src/Microsoft.AspNetCore.WebSockets/WebSocketMiddlewareExtensions.cs rename to src/Middleware/WebSockets/src/WebSocketMiddlewareExtensions.cs diff --git a/src/WebSockets/src/Microsoft.AspNetCore.WebSockets/WebSocketOptions.cs b/src/Middleware/WebSockets/src/WebSocketOptions.cs similarity index 100% rename from src/WebSockets/src/Microsoft.AspNetCore.WebSockets/WebSocketOptions.cs rename to src/Middleware/WebSockets/src/WebSocketOptions.cs diff --git a/src/WebSockets/src/Microsoft.AspNetCore.WebSockets/baseline.netcore.json b/src/Middleware/WebSockets/src/baseline.netcore.json similarity index 100% rename from src/WebSockets/src/Microsoft.AspNetCore.WebSockets/baseline.netcore.json rename to src/Middleware/WebSockets/src/baseline.netcore.json diff --git a/src/WebSockets/test/AutobahnTestApp/AutobahnTestApp.csproj b/src/Middleware/WebSockets/test/AutobahnTestApp/AutobahnTestApp.csproj similarity index 75% rename from src/WebSockets/test/AutobahnTestApp/AutobahnTestApp.csproj rename to src/Middleware/WebSockets/test/AutobahnTestApp/AutobahnTestApp.csproj index 175f724c74..5cd27d8a7e 100644 --- a/src/WebSockets/test/AutobahnTestApp/AutobahnTestApp.csproj +++ b/src/Middleware/WebSockets/test/AutobahnTestApp/AutobahnTestApp.csproj @@ -3,6 +3,7 @@ netcoreapp2.1 $(TargetFrameworks);netcoreapp2.0 + true @@ -10,21 +11,20 @@ - + + + + + + + + + + - - - - - - - - - - diff --git a/src/WebSockets/test/AutobahnTestApp/Program.cs b/src/Middleware/WebSockets/test/AutobahnTestApp/Program.cs similarity index 100% rename from src/WebSockets/test/AutobahnTestApp/Program.cs rename to src/Middleware/WebSockets/test/AutobahnTestApp/Program.cs diff --git a/src/WebSockets/test/AutobahnTestApp/Properties/launchSettings.json b/src/Middleware/WebSockets/test/AutobahnTestApp/Properties/launchSettings.json similarity index 100% rename from src/WebSockets/test/AutobahnTestApp/Properties/launchSettings.json rename to src/Middleware/WebSockets/test/AutobahnTestApp/Properties/launchSettings.json diff --git a/src/WebSockets/test/AutobahnTestApp/README.md b/src/Middleware/WebSockets/test/AutobahnTestApp/README.md similarity index 100% rename from src/WebSockets/test/AutobahnTestApp/README.md rename to src/Middleware/WebSockets/test/AutobahnTestApp/README.md diff --git a/src/WebSockets/test/AutobahnTestApp/Startup.cs b/src/Middleware/WebSockets/test/AutobahnTestApp/Startup.cs similarity index 100% rename from src/WebSockets/test/AutobahnTestApp/Startup.cs rename to src/Middleware/WebSockets/test/AutobahnTestApp/Startup.cs diff --git a/src/WebSockets/test/AutobahnTestApp/TestResources/testCert.pfx b/src/Middleware/WebSockets/test/AutobahnTestApp/TestResources/testCert.pfx similarity index 100% rename from src/WebSockets/test/AutobahnTestApp/TestResources/testCert.pfx rename to src/Middleware/WebSockets/test/AutobahnTestApp/TestResources/testCert.pfx diff --git a/src/WebSockets/test/AutobahnTestApp/TestResources/testCert.txt b/src/Middleware/WebSockets/test/AutobahnTestApp/TestResources/testCert.txt similarity index 100% rename from src/WebSockets/test/AutobahnTestApp/TestResources/testCert.txt rename to src/Middleware/WebSockets/test/AutobahnTestApp/TestResources/testCert.txt diff --git a/src/WebSockets/test/AutobahnTestApp/scripts/RunAutobahnTests.ps1 b/src/Middleware/WebSockets/test/AutobahnTestApp/scripts/RunAutobahnTests.ps1 similarity index 100% rename from src/WebSockets/test/AutobahnTestApp/scripts/RunAutobahnTests.ps1 rename to src/Middleware/WebSockets/test/AutobahnTestApp/scripts/RunAutobahnTests.ps1 diff --git a/src/WebSockets/test/AutobahnTestApp/scripts/autobahn.spec.json b/src/Middleware/WebSockets/test/AutobahnTestApp/scripts/autobahn.spec.json similarity index 100% rename from src/WebSockets/test/AutobahnTestApp/scripts/autobahn.spec.json rename to src/Middleware/WebSockets/test/AutobahnTestApp/scripts/autobahn.spec.json diff --git a/src/WebSockets/test/Microsoft.AspNetCore.WebSockets.ConformanceTest/Autobahn/AutobahnCaseResult.cs b/src/Middleware/WebSockets/test/ConformanceTests/Autobahn/AutobahnCaseResult.cs similarity index 100% rename from src/WebSockets/test/Microsoft.AspNetCore.WebSockets.ConformanceTest/Autobahn/AutobahnCaseResult.cs rename to src/Middleware/WebSockets/test/ConformanceTests/Autobahn/AutobahnCaseResult.cs diff --git a/src/WebSockets/test/Microsoft.AspNetCore.WebSockets.ConformanceTest/Autobahn/AutobahnExpectations.cs b/src/Middleware/WebSockets/test/ConformanceTests/Autobahn/AutobahnExpectations.cs similarity index 100% rename from src/WebSockets/test/Microsoft.AspNetCore.WebSockets.ConformanceTest/Autobahn/AutobahnExpectations.cs rename to src/Middleware/WebSockets/test/ConformanceTests/Autobahn/AutobahnExpectations.cs diff --git a/src/WebSockets/test/Microsoft.AspNetCore.WebSockets.ConformanceTest/Autobahn/AutobahnResult.cs b/src/Middleware/WebSockets/test/ConformanceTests/Autobahn/AutobahnResult.cs similarity index 100% rename from src/WebSockets/test/Microsoft.AspNetCore.WebSockets.ConformanceTest/Autobahn/AutobahnResult.cs rename to src/Middleware/WebSockets/test/ConformanceTests/Autobahn/AutobahnResult.cs diff --git a/src/WebSockets/test/Microsoft.AspNetCore.WebSockets.ConformanceTest/Autobahn/AutobahnServerResult.cs b/src/Middleware/WebSockets/test/ConformanceTests/Autobahn/AutobahnServerResult.cs similarity index 100% rename from src/WebSockets/test/Microsoft.AspNetCore.WebSockets.ConformanceTest/Autobahn/AutobahnServerResult.cs rename to src/Middleware/WebSockets/test/ConformanceTests/Autobahn/AutobahnServerResult.cs diff --git a/src/WebSockets/test/Microsoft.AspNetCore.WebSockets.ConformanceTest/Autobahn/AutobahnSpec.cs b/src/Middleware/WebSockets/test/ConformanceTests/Autobahn/AutobahnSpec.cs similarity index 100% rename from src/WebSockets/test/Microsoft.AspNetCore.WebSockets.ConformanceTest/Autobahn/AutobahnSpec.cs rename to src/Middleware/WebSockets/test/ConformanceTests/Autobahn/AutobahnSpec.cs diff --git a/src/WebSockets/test/Microsoft.AspNetCore.WebSockets.ConformanceTest/Autobahn/AutobahnTester.cs b/src/Middleware/WebSockets/test/ConformanceTests/Autobahn/AutobahnTester.cs similarity index 100% rename from src/WebSockets/test/Microsoft.AspNetCore.WebSockets.ConformanceTest/Autobahn/AutobahnTester.cs rename to src/Middleware/WebSockets/test/ConformanceTests/Autobahn/AutobahnTester.cs diff --git a/src/WebSockets/test/Microsoft.AspNetCore.WebSockets.ConformanceTest/Autobahn/Executable.cs b/src/Middleware/WebSockets/test/ConformanceTests/Autobahn/Executable.cs similarity index 100% rename from src/WebSockets/test/Microsoft.AspNetCore.WebSockets.ConformanceTest/Autobahn/Executable.cs rename to src/Middleware/WebSockets/test/ConformanceTests/Autobahn/Executable.cs diff --git a/src/WebSockets/test/Microsoft.AspNetCore.WebSockets.ConformanceTest/Autobahn/Expectation.cs b/src/Middleware/WebSockets/test/ConformanceTests/Autobahn/Expectation.cs similarity index 100% rename from src/WebSockets/test/Microsoft.AspNetCore.WebSockets.ConformanceTest/Autobahn/Expectation.cs rename to src/Middleware/WebSockets/test/ConformanceTests/Autobahn/Expectation.cs diff --git a/src/WebSockets/test/Microsoft.AspNetCore.WebSockets.ConformanceTest/Autobahn/ServerSpec.cs b/src/Middleware/WebSockets/test/ConformanceTests/Autobahn/ServerSpec.cs similarity index 100% rename from src/WebSockets/test/Microsoft.AspNetCore.WebSockets.ConformanceTest/Autobahn/ServerSpec.cs rename to src/Middleware/WebSockets/test/ConformanceTests/Autobahn/ServerSpec.cs diff --git a/src/WebSockets/test/Microsoft.AspNetCore.WebSockets.ConformanceTest/Autobahn/Wstest.cs b/src/Middleware/WebSockets/test/ConformanceTests/Autobahn/Wstest.cs similarity index 100% rename from src/WebSockets/test/Microsoft.AspNetCore.WebSockets.ConformanceTest/Autobahn/Wstest.cs rename to src/Middleware/WebSockets/test/ConformanceTests/Autobahn/Wstest.cs diff --git a/src/WebSockets/test/Microsoft.AspNetCore.WebSockets.ConformanceTest/AutobahnTests.cs b/src/Middleware/WebSockets/test/ConformanceTests/AutobahnTests.cs similarity index 100% rename from src/WebSockets/test/Microsoft.AspNetCore.WebSockets.ConformanceTest/AutobahnTests.cs rename to src/Middleware/WebSockets/test/ConformanceTests/AutobahnTests.cs diff --git a/src/WebSockets/test/Microsoft.AspNetCore.WebSockets.ConformanceTest/Helpers.cs b/src/Middleware/WebSockets/test/ConformanceTests/Helpers.cs similarity index 100% rename from src/WebSockets/test/Microsoft.AspNetCore.WebSockets.ConformanceTest/Helpers.cs rename to src/Middleware/WebSockets/test/ConformanceTests/Helpers.cs diff --git a/src/WebSockets/test/Microsoft.AspNetCore.WebSockets.ConformanceTest/Http.config b/src/Middleware/WebSockets/test/ConformanceTests/Http.config similarity index 100% rename from src/WebSockets/test/Microsoft.AspNetCore.WebSockets.ConformanceTest/Http.config rename to src/Middleware/WebSockets/test/ConformanceTests/Http.config diff --git a/src/Middleware/WebSockets/test/ConformanceTests/Microsoft.AspNetCore.WebSockets.ConformanceTests.csproj b/src/Middleware/WebSockets/test/ConformanceTests/Microsoft.AspNetCore.WebSockets.ConformanceTests.csproj new file mode 100644 index 0000000000..76281207ee --- /dev/null +++ b/src/Middleware/WebSockets/test/ConformanceTests/Microsoft.AspNetCore.WebSockets.ConformanceTests.csproj @@ -0,0 +1,15 @@ + + + + netcoreapp2.1 + $(TargetFrameworks);netcoreapp2.0 + + + + + + + + + + diff --git a/src/WebSockets/test/Microsoft.AspNetCore.WebSockets.ConformanceTest/SkipIfWsTestNotPresentAttribute.cs b/src/Middleware/WebSockets/test/ConformanceTests/SkipIfWsTestNotPresentAttribute.cs similarity index 100% rename from src/WebSockets/test/Microsoft.AspNetCore.WebSockets.ConformanceTest/SkipIfWsTestNotPresentAttribute.cs rename to src/Middleware/WebSockets/test/ConformanceTests/SkipIfWsTestNotPresentAttribute.cs diff --git a/src/Middleware/WebSockets/test/Directory.Build.props b/src/Middleware/WebSockets/test/Directory.Build.props new file mode 100644 index 0000000000..3e2de2026d --- /dev/null +++ b/src/Middleware/WebSockets/test/Directory.Build.props @@ -0,0 +1,27 @@ + + + + + + + true + + + + + + 2.1.1 + 2.1.1 + 2.1.1 + 2.1.1 + 2.1.1 + 0.5.1 + 2.1.2 + 2.1.2 + 2.1.1 + + + diff --git a/src/WebSockets/test/Microsoft.AspNetCore.WebSockets.Test/BufferStream.cs b/src/Middleware/WebSockets/test/UnitTests/BufferStream.cs similarity index 100% rename from src/WebSockets/test/Microsoft.AspNetCore.WebSockets.Test/BufferStream.cs rename to src/Middleware/WebSockets/test/UnitTests/BufferStream.cs diff --git a/src/WebSockets/test/Microsoft.AspNetCore.WebSockets.Test/DuplexStream.cs b/src/Middleware/WebSockets/test/UnitTests/DuplexStream.cs similarity index 100% rename from src/WebSockets/test/Microsoft.AspNetCore.WebSockets.Test/DuplexStream.cs rename to src/Middleware/WebSockets/test/UnitTests/DuplexStream.cs diff --git a/src/WebSockets/test/Microsoft.AspNetCore.WebSockets.Test/IWebHostPortExtensions.cs b/src/Middleware/WebSockets/test/UnitTests/IWebHostPortExtensions.cs similarity index 100% rename from src/WebSockets/test/Microsoft.AspNetCore.WebSockets.Test/IWebHostPortExtensions.cs rename to src/Middleware/WebSockets/test/UnitTests/IWebHostPortExtensions.cs diff --git a/src/WebSockets/test/Microsoft.AspNetCore.WebSockets.Test/KestrelWebSocketHelpers.cs b/src/Middleware/WebSockets/test/UnitTests/KestrelWebSocketHelpers.cs similarity index 100% rename from src/WebSockets/test/Microsoft.AspNetCore.WebSockets.Test/KestrelWebSocketHelpers.cs rename to src/Middleware/WebSockets/test/UnitTests/KestrelWebSocketHelpers.cs diff --git a/src/Middleware/WebSockets/test/UnitTests/Microsoft.AspNetCore.WebSockets.Tests.csproj b/src/Middleware/WebSockets/test/UnitTests/Microsoft.AspNetCore.WebSockets.Tests.csproj new file mode 100644 index 0000000000..fc5fb268d5 --- /dev/null +++ b/src/Middleware/WebSockets/test/UnitTests/Microsoft.AspNetCore.WebSockets.Tests.csproj @@ -0,0 +1,14 @@ + + + + $(StandardTestTfms) + + + + + + + + + + diff --git a/src/WebSockets/test/Microsoft.AspNetCore.WebSockets.Test/SendReceiveTests.cs b/src/Middleware/WebSockets/test/UnitTests/SendReceiveTests.cs similarity index 100% rename from src/WebSockets/test/Microsoft.AspNetCore.WebSockets.Test/SendReceiveTests.cs rename to src/Middleware/WebSockets/test/UnitTests/SendReceiveTests.cs diff --git a/src/WebSockets/test/Microsoft.AspNetCore.WebSockets.Test/WebSocketMiddlewareTests.cs b/src/Middleware/WebSockets/test/UnitTests/WebSocketMiddlewareTests.cs similarity index 100% rename from src/WebSockets/test/Microsoft.AspNetCore.WebSockets.Test/WebSocketMiddlewareTests.cs rename to src/Middleware/WebSockets/test/UnitTests/WebSocketMiddlewareTests.cs diff --git a/src/WebSockets/test/Microsoft.AspNetCore.WebSockets.Test/WebSocketPair.cs b/src/Middleware/WebSockets/test/UnitTests/WebSocketPair.cs similarity index 100% rename from src/WebSockets/test/Microsoft.AspNetCore.WebSockets.Test/WebSocketPair.cs rename to src/Middleware/WebSockets/test/UnitTests/WebSocketPair.cs diff --git a/src/WebSockets/.gitignore b/src/WebSockets/.gitignore deleted file mode 100644 index 0e10f4aa54..0000000000 --- a/src/WebSockets/.gitignore +++ /dev/null @@ -1,31 +0,0 @@ -[Oo]bj/ -[Bb]in/ -TestResults/ -.nuget/ -_ReSharper.*/ -packages/ -artifacts/ -PublishProfiles/ -*.user -*.suo -*.cache -*.docstates -_ReSharper.* -nuget.exe -*net45.csproj -*k10.csproj -*.psess -*.vsp -*.pidb -*.userprefs -*DS_Store -*.ncrunchsolution -*.*sdf -*.ipch -*.sln.ide -/.vs/ -.testPublish/ -.build/ -autobahnreports/ -.vscode/ -global.json diff --git a/src/WebSockets/Directory.Build.props b/src/WebSockets/Directory.Build.props deleted file mode 100644 index 6c76a5608f..0000000000 --- a/src/WebSockets/Directory.Build.props +++ /dev/null @@ -1,20 +0,0 @@ - - - - - - - - - Microsoft ASP.NET Core - https://github.com/aspnet/WebSockets - git - $(MSBuildThisFileDirectory) - $(MSBuildThisFileDirectory)build\Key.snk - true - true - true - - diff --git a/src/WebSockets/Directory.Build.targets b/src/WebSockets/Directory.Build.targets deleted file mode 100644 index 53b3f6e1da..0000000000 --- a/src/WebSockets/Directory.Build.targets +++ /dev/null @@ -1,7 +0,0 @@ - - - $(MicrosoftNETCoreApp20PackageVersion) - $(MicrosoftNETCoreApp21PackageVersion) - $(NETStandardLibrary20PackageVersion) - - diff --git a/src/WebSockets/NuGetPackageVerifier.json b/src/WebSockets/NuGetPackageVerifier.json deleted file mode 100644 index b153ab1515..0000000000 --- a/src/WebSockets/NuGetPackageVerifier.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "Default": { - "rules": [ - "DefaultCompositeRule" - ] - } -} \ No newline at end of file diff --git a/src/WebSockets/README.md b/src/WebSockets/README.md deleted file mode 100644 index c7c69ee89b..0000000000 --- a/src/WebSockets/README.md +++ /dev/null @@ -1,19 +0,0 @@ -WebSockets -================ - -AppVeyor: [![AppVeyor](https://ci.appveyor.com/api/projects/status/lk5hyg6gki03hdqe/branch/dev?svg=true)](https://ci.appveyor.com/project/aspnetci/WebSockets/branch/dev) - -Travis: [![Travis](https://travis-ci.org/aspnet/WebSockets.svg?branch=dev)](https://travis-ci.org/aspnet/WebSockets) - -Contains a managed implementation of the WebSocket protocol, along with server integration components. - -This project is part of ASP.NET Core. You can find samples, documentation and getting started instructions for ASP.NET Core at the [Home](https://github.com/aspnet/home) repo. - - -## System Requirements - -This repo has a few special system requirements/prerequisites. - -1. Windows IIS Express tests require IIS Express 10 and Windows 8 for WebSockets support -2. HttpListener/ASP.NET 4.6 samples require at least Windows 8 -3. Autobahn Test Suite requires special installation see the README.md in test/AutobahnTestApp diff --git a/src/WebSockets/WebSockets.sln b/src/WebSockets/WebSockets.sln deleted file mode 100644 index 6977d2812e..0000000000 --- a/src/WebSockets/WebSockets.sln +++ /dev/null @@ -1,145 +0,0 @@ -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 15 -VisualStudioVersion = 15.0.26730.10 -MinimumVisualStudioVersion = 15.0.26730.03 -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{2C7947A5-9FBD-4267-97C1-2D726D7B3BAF}" - ProjectSection(SolutionItems) = preProject - src\Directory.Build.props = src\Directory.Build.props - EndProjectSection -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{C45106D0-76C8-4776-A140-F7DD83CA2958}" - ProjectSection(SolutionItems) = preProject - test\Directory.Build.props = test\Directory.Build.props - EndProjectSection -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "samples", "samples", "{9E55FC5B-FD9C-4266-AB24-F3AA649D7C8B}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestServer", "samples\TestServer\TestServer.csproj", "{4E5F5FCC-172C-44D9-BEA0-39098A79CD0B}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "scripts", "scripts", "{19595D64-E42E-46FD-AB2E-BDC870724EE7}" - ProjectSection(SolutionItems) = preProject - scripts\UpdateCoreFxCode.ps1 = scripts\UpdateCoreFxCode.ps1 - EndProjectSection -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.WebSockets", "src\Microsoft.AspNetCore.WebSockets\Microsoft.AspNetCore.WebSockets.csproj", "{CDE16880-0374-46FA-8896-99F1B90B4B6F}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.WebSockets.Test", "test\Microsoft.AspNetCore.WebSockets.Test\Microsoft.AspNetCore.WebSockets.Test.csproj", "{5AFA74F5-9B1D-4FC5-815F-EF471F5AC1EF}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.WebSockets.ConformanceTest", "test\Microsoft.AspNetCore.WebSockets.ConformanceTest\Microsoft.AspNetCore.WebSockets.ConformanceTest.csproj", "{74F45408-1959-4FEE-9511-25D40F4913FD}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EchoApp", "samples\EchoApp\EchoApp.csproj", "{421954B0-5C6B-4092-8D4D-EACA4CE60AFB}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AutobahnTestApp", "test\AutobahnTestApp\AutobahnTestApp.csproj", "{150DF5A8-87C6-42F7-8886-CE07BFD02FD2}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "build", "build", "{92CE12E6-E127-433B-96D3-164C0113EA17}" - ProjectSection(SolutionItems) = preProject - build\dependencies.props = build\dependencies.props - build\Key.snk = build\Key.snk - build\repo.props = build\repo.props - build\repo.targets = build\repo.targets - EndProjectSection -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{7A963B09-471B-4D67-B5C0-6039AF0C39EE}" - ProjectSection(SolutionItems) = preProject - Directory.Build.props = Directory.Build.props - Directory.Build.targets = Directory.Build.targets - EndProjectSection -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Debug|x64 = Debug|x64 - Debug|x86 = Debug|x86 - Release|Any CPU = Release|Any CPU - Release|x64 = Release|x64 - Release|x86 = Release|x86 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {4E5F5FCC-172C-44D9-BEA0-39098A79CD0B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {4E5F5FCC-172C-44D9-BEA0-39098A79CD0B}.Debug|Any CPU.Build.0 = Debug|Any CPU - {4E5F5FCC-172C-44D9-BEA0-39098A79CD0B}.Debug|x64.ActiveCfg = Debug|Any CPU - {4E5F5FCC-172C-44D9-BEA0-39098A79CD0B}.Debug|x64.Build.0 = Debug|Any CPU - {4E5F5FCC-172C-44D9-BEA0-39098A79CD0B}.Debug|x86.ActiveCfg = Debug|Any CPU - {4E5F5FCC-172C-44D9-BEA0-39098A79CD0B}.Debug|x86.Build.0 = Debug|Any CPU - {4E5F5FCC-172C-44D9-BEA0-39098A79CD0B}.Release|Any CPU.ActiveCfg = Release|Any CPU - {4E5F5FCC-172C-44D9-BEA0-39098A79CD0B}.Release|Any CPU.Build.0 = Release|Any CPU - {4E5F5FCC-172C-44D9-BEA0-39098A79CD0B}.Release|x64.ActiveCfg = Release|Any CPU - {4E5F5FCC-172C-44D9-BEA0-39098A79CD0B}.Release|x64.Build.0 = Release|Any CPU - {4E5F5FCC-172C-44D9-BEA0-39098A79CD0B}.Release|x86.ActiveCfg = Release|Any CPU - {4E5F5FCC-172C-44D9-BEA0-39098A79CD0B}.Release|x86.Build.0 = Release|Any CPU - {CDE16880-0374-46FA-8896-99F1B90B4B6F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {CDE16880-0374-46FA-8896-99F1B90B4B6F}.Debug|Any CPU.Build.0 = Debug|Any CPU - {CDE16880-0374-46FA-8896-99F1B90B4B6F}.Debug|x64.ActiveCfg = Debug|Any CPU - {CDE16880-0374-46FA-8896-99F1B90B4B6F}.Debug|x64.Build.0 = Debug|Any CPU - {CDE16880-0374-46FA-8896-99F1B90B4B6F}.Debug|x86.ActiveCfg = Debug|Any CPU - {CDE16880-0374-46FA-8896-99F1B90B4B6F}.Debug|x86.Build.0 = Debug|Any CPU - {CDE16880-0374-46FA-8896-99F1B90B4B6F}.Release|Any CPU.ActiveCfg = Release|Any CPU - {CDE16880-0374-46FA-8896-99F1B90B4B6F}.Release|Any CPU.Build.0 = Release|Any CPU - {CDE16880-0374-46FA-8896-99F1B90B4B6F}.Release|x64.ActiveCfg = Release|Any CPU - {CDE16880-0374-46FA-8896-99F1B90B4B6F}.Release|x64.Build.0 = Release|Any CPU - {CDE16880-0374-46FA-8896-99F1B90B4B6F}.Release|x86.ActiveCfg = Release|Any CPU - {CDE16880-0374-46FA-8896-99F1B90B4B6F}.Release|x86.Build.0 = Release|Any CPU - {5AFA74F5-9B1D-4FC5-815F-EF471F5AC1EF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {5AFA74F5-9B1D-4FC5-815F-EF471F5AC1EF}.Debug|Any CPU.Build.0 = Debug|Any CPU - {5AFA74F5-9B1D-4FC5-815F-EF471F5AC1EF}.Debug|x64.ActiveCfg = Debug|Any CPU - {5AFA74F5-9B1D-4FC5-815F-EF471F5AC1EF}.Debug|x64.Build.0 = Debug|Any CPU - {5AFA74F5-9B1D-4FC5-815F-EF471F5AC1EF}.Debug|x86.ActiveCfg = Debug|Any CPU - {5AFA74F5-9B1D-4FC5-815F-EF471F5AC1EF}.Debug|x86.Build.0 = Debug|Any CPU - {5AFA74F5-9B1D-4FC5-815F-EF471F5AC1EF}.Release|Any CPU.ActiveCfg = Release|Any CPU - {5AFA74F5-9B1D-4FC5-815F-EF471F5AC1EF}.Release|Any CPU.Build.0 = Release|Any CPU - {5AFA74F5-9B1D-4FC5-815F-EF471F5AC1EF}.Release|x64.ActiveCfg = Release|Any CPU - {5AFA74F5-9B1D-4FC5-815F-EF471F5AC1EF}.Release|x64.Build.0 = Release|Any CPU - {5AFA74F5-9B1D-4FC5-815F-EF471F5AC1EF}.Release|x86.ActiveCfg = Release|Any CPU - {5AFA74F5-9B1D-4FC5-815F-EF471F5AC1EF}.Release|x86.Build.0 = Release|Any CPU - {74F45408-1959-4FEE-9511-25D40F4913FD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {74F45408-1959-4FEE-9511-25D40F4913FD}.Debug|Any CPU.Build.0 = Debug|Any CPU - {74F45408-1959-4FEE-9511-25D40F4913FD}.Debug|x64.ActiveCfg = Debug|Any CPU - {74F45408-1959-4FEE-9511-25D40F4913FD}.Debug|x64.Build.0 = Debug|Any CPU - {74F45408-1959-4FEE-9511-25D40F4913FD}.Debug|x86.ActiveCfg = Debug|Any CPU - {74F45408-1959-4FEE-9511-25D40F4913FD}.Debug|x86.Build.0 = Debug|Any CPU - {74F45408-1959-4FEE-9511-25D40F4913FD}.Release|Any CPU.ActiveCfg = Release|Any CPU - {74F45408-1959-4FEE-9511-25D40F4913FD}.Release|Any CPU.Build.0 = Release|Any CPU - {74F45408-1959-4FEE-9511-25D40F4913FD}.Release|x64.ActiveCfg = Release|Any CPU - {74F45408-1959-4FEE-9511-25D40F4913FD}.Release|x64.Build.0 = Release|Any CPU - {74F45408-1959-4FEE-9511-25D40F4913FD}.Release|x86.ActiveCfg = Release|Any CPU - {74F45408-1959-4FEE-9511-25D40F4913FD}.Release|x86.Build.0 = Release|Any CPU - {421954B0-5C6B-4092-8D4D-EACA4CE60AFB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {421954B0-5C6B-4092-8D4D-EACA4CE60AFB}.Debug|Any CPU.Build.0 = Debug|Any CPU - {421954B0-5C6B-4092-8D4D-EACA4CE60AFB}.Debug|x64.ActiveCfg = Debug|Any CPU - {421954B0-5C6B-4092-8D4D-EACA4CE60AFB}.Debug|x64.Build.0 = Debug|Any CPU - {421954B0-5C6B-4092-8D4D-EACA4CE60AFB}.Debug|x86.ActiveCfg = Debug|Any CPU - {421954B0-5C6B-4092-8D4D-EACA4CE60AFB}.Debug|x86.Build.0 = Debug|Any CPU - {421954B0-5C6B-4092-8D4D-EACA4CE60AFB}.Release|Any CPU.ActiveCfg = Release|Any CPU - {421954B0-5C6B-4092-8D4D-EACA4CE60AFB}.Release|Any CPU.Build.0 = Release|Any CPU - {421954B0-5C6B-4092-8D4D-EACA4CE60AFB}.Release|x64.ActiveCfg = Release|Any CPU - {421954B0-5C6B-4092-8D4D-EACA4CE60AFB}.Release|x64.Build.0 = Release|Any CPU - {421954B0-5C6B-4092-8D4D-EACA4CE60AFB}.Release|x86.ActiveCfg = Release|Any CPU - {421954B0-5C6B-4092-8D4D-EACA4CE60AFB}.Release|x86.Build.0 = Release|Any CPU - {150DF5A8-87C6-42F7-8886-CE07BFD02FD2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {150DF5A8-87C6-42F7-8886-CE07BFD02FD2}.Debug|Any CPU.Build.0 = Debug|Any CPU - {150DF5A8-87C6-42F7-8886-CE07BFD02FD2}.Debug|x64.ActiveCfg = Debug|Any CPU - {150DF5A8-87C6-42F7-8886-CE07BFD02FD2}.Debug|x64.Build.0 = Debug|Any CPU - {150DF5A8-87C6-42F7-8886-CE07BFD02FD2}.Debug|x86.ActiveCfg = Debug|Any CPU - {150DF5A8-87C6-42F7-8886-CE07BFD02FD2}.Debug|x86.Build.0 = Debug|Any CPU - {150DF5A8-87C6-42F7-8886-CE07BFD02FD2}.Release|Any CPU.ActiveCfg = Release|Any CPU - {150DF5A8-87C6-42F7-8886-CE07BFD02FD2}.Release|Any CPU.Build.0 = Release|Any CPU - {150DF5A8-87C6-42F7-8886-CE07BFD02FD2}.Release|x64.ActiveCfg = Release|Any CPU - {150DF5A8-87C6-42F7-8886-CE07BFD02FD2}.Release|x64.Build.0 = Release|Any CPU - {150DF5A8-87C6-42F7-8886-CE07BFD02FD2}.Release|x86.ActiveCfg = Release|Any CPU - {150DF5A8-87C6-42F7-8886-CE07BFD02FD2}.Release|x86.Build.0 = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(NestedProjects) = preSolution - {4E5F5FCC-172C-44D9-BEA0-39098A79CD0B} = {9E55FC5B-FD9C-4266-AB24-F3AA649D7C8B} - {CDE16880-0374-46FA-8896-99F1B90B4B6F} = {2C7947A5-9FBD-4267-97C1-2D726D7B3BAF} - {5AFA74F5-9B1D-4FC5-815F-EF471F5AC1EF} = {C45106D0-76C8-4776-A140-F7DD83CA2958} - {74F45408-1959-4FEE-9511-25D40F4913FD} = {C45106D0-76C8-4776-A140-F7DD83CA2958} - {421954B0-5C6B-4092-8D4D-EACA4CE60AFB} = {9E55FC5B-FD9C-4266-AB24-F3AA649D7C8B} - {150DF5A8-87C6-42F7-8886-CE07BFD02FD2} = {C45106D0-76C8-4776-A140-F7DD83CA2958} - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {D3542868-F8C6-401B-8071-37FE3C981604} - EndGlobalSection -EndGlobal diff --git a/src/WebSockets/build.cmd b/src/WebSockets/build.cmd deleted file mode 100644 index f4169ea5e4..0000000000 --- a/src/WebSockets/build.cmd +++ /dev/null @@ -1,3 +0,0 @@ -@ECHO OFF -SET RepoRoot="%~dp0..\.." -%RepoRoot%\build.cmd -LockFile %RepoRoot%\korebuild-lock.txt -Path %~dp0 %* diff --git a/src/WebSockets/build.sh b/src/WebSockets/build.sh deleted file mode 100755 index d5bb0cf631..0000000000 --- a/src/WebSockets/build.sh +++ /dev/null @@ -1,7 +0,0 @@ -#!/usr/bin/env bash - -set -euo pipefail - -DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" -repo_root="$DIR/../.." -"$repo_root/build.sh" --path "$DIR" --lockfile "$repo_root/korebuild-lock.txt" "$@" diff --git a/src/WebSockets/build/Key.snk b/src/WebSockets/build/Key.snk deleted file mode 100644 index e10e4889c125d3120cd9e81582243d70f7cbb806..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 596 zcmV-a0;~N80ssI2Bme+XQ$aES1ONa50098=Iw=HCsnz~#iVhm& zj%TU(_THUee?3yHBjk$37ysB?i5#7WD$={H zV4B!OxRPrb|8)HPg~A}8P>^=#y<)56#=E&NzcjOtPK~<4n6GHt=K$ro*T(lhby_@U zEk(hLzk1H)0yXj{A_5>fk-TgNoP|q6(tP2xo8zt8i%212CWM#AeCd?`hS|4~L({h~Moo(~vy&3Z z1uI}`fd^*>o=rwbAGymj6RM^pZm(*Kfhs+Y1#`-2JPWZMK8@;ZWCk2+9bX4YP);~fj-BU*R zQPvWv$89!{Rl9wM+zR>_TSkn^voYxA?2G iKnV#iZ6Ah`K>b=@=IjYJXrxL124zR(38)nxe+&q_$QXwJ diff --git a/src/WebSockets/build/dependencies.props b/src/WebSockets/build/dependencies.props deleted file mode 100644 index 6d1c938c0c..0000000000 --- a/src/WebSockets/build/dependencies.props +++ /dev/null @@ -1,39 +0,0 @@ - - - $(MSBuildAllProjects);$(MSBuildThisFileFullPath) - - - - - 2.1.3-rtm-15802 - 2.0.0 - 2.1.2 - 15.6.1 - 2.0.3 - 4.5.1 - 2.3.1 - 2.4.0-beta.1.build3945 - - - - - - - - 2.1.1 - 2.1.1 - 2.1.1 - 2.1.1 - 2.1.1 - 0.5.1 - 2.1.2 - 2.1.2 - 2.1.1 - 2.1.0 - 2.1.1 - 2.1.1 - 2.1.1 - 2.1.1 - 2.1.1 - - \ No newline at end of file diff --git a/src/WebSockets/build/repo.props b/src/WebSockets/build/repo.props deleted file mode 100644 index de99df697a..0000000000 --- a/src/WebSockets/build/repo.props +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - - - Internal.AspNetCore.Universe.Lineup - 2.1.0-rc1-* - https://dotnet.myget.org/F/aspnetcore-dev/api/v3/index.json - - - - - - - diff --git a/src/WebSockets/build/repo.targets b/src/WebSockets/build/repo.targets deleted file mode 100644 index 1767331014..0000000000 --- a/src/WebSockets/build/repo.targets +++ /dev/null @@ -1,9 +0,0 @@ - - - $(ArtifactsDir)autobahnreports\ - - - - - - diff --git a/src/WebSockets/build/sources.props b/src/WebSockets/build/sources.props deleted file mode 100644 index 9215df9751..0000000000 --- a/src/WebSockets/build/sources.props +++ /dev/null @@ -1,17 +0,0 @@ - - - - - $(DotNetRestoreSources) - - $(RestoreSources); - https://dotnet.myget.org/F/dotnet-core/api/v3/index.json; - https://dotnet.myget.org/F/aspnetcore-dev/api/v3/index.json; - https://dotnet.myget.org/F/aspnetcore-tools/api/v3/index.json; - - - $(RestoreSources); - https://api.nuget.org/v3/index.json; - - - diff --git a/src/WebSockets/samples/EchoApp/EchoApp.csproj b/src/WebSockets/samples/EchoApp/EchoApp.csproj deleted file mode 100644 index f5696ccf03..0000000000 --- a/src/WebSockets/samples/EchoApp/EchoApp.csproj +++ /dev/null @@ -1,19 +0,0 @@ - - - - netcoreapp2.1;net461 - - - - - - - - - - - - - - - diff --git a/src/WebSockets/src/Directory.Build.props b/src/WebSockets/src/Directory.Build.props deleted file mode 100644 index 1e0980f663..0000000000 --- a/src/WebSockets/src/Directory.Build.props +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/src/WebSockets/test/Directory.Build.props b/src/WebSockets/test/Directory.Build.props deleted file mode 100644 index be781a6b15..0000000000 --- a/src/WebSockets/test/Directory.Build.props +++ /dev/null @@ -1,22 +0,0 @@ - - - - - netcoreapp2.1 - $(DeveloperBuildTestTfms) - netcoreapp2.1;netcoreapp2.0 - $(StandardTestTfms);net461 - - - - - true - - - - - - diff --git a/src/WebSockets/test/Microsoft.AspNetCore.WebSockets.ConformanceTest/Microsoft.AspNetCore.WebSockets.ConformanceTest.csproj b/src/WebSockets/test/Microsoft.AspNetCore.WebSockets.ConformanceTest/Microsoft.AspNetCore.WebSockets.ConformanceTest.csproj deleted file mode 100644 index 79e3839b12..0000000000 --- a/src/WebSockets/test/Microsoft.AspNetCore.WebSockets.ConformanceTest/Microsoft.AspNetCore.WebSockets.ConformanceTest.csproj +++ /dev/null @@ -1,18 +0,0 @@ - - - - netcoreapp2.1 - $(TargetFrameworks);netcoreapp2.0 - - - - - - - - - - - - - diff --git a/src/WebSockets/test/Microsoft.AspNetCore.WebSockets.Test/Microsoft.AspNetCore.WebSockets.Test.csproj b/src/WebSockets/test/Microsoft.AspNetCore.WebSockets.Test/Microsoft.AspNetCore.WebSockets.Test.csproj deleted file mode 100644 index c906aa0f91..0000000000 --- a/src/WebSockets/test/Microsoft.AspNetCore.WebSockets.Test/Microsoft.AspNetCore.WebSockets.Test.csproj +++ /dev/null @@ -1,21 +0,0 @@ - - - - $(StandardTestTfms) - - - - - - - - - - - - - - - - - diff --git a/src/WebSockets/version.props b/src/WebSockets/version.props deleted file mode 100644 index 669c874829..0000000000 --- a/src/WebSockets/version.props +++ /dev/null @@ -1,12 +0,0 @@ - - - 2.1.1 - rtm - $(VersionPrefix) - $(VersionPrefix)-$(VersionSuffix)-final - t000 - a- - $(FeatureBranchVersionPrefix)$(VersionSuffix)-$([System.Text.RegularExpressions.Regex]::Replace('$(FeatureBranchVersionSuffix)', '[^\w-]', '-')) - $(VersionSuffix)-$(BuildNumber) - - From 32622d1a0afdd4387e89d454c555a85729451933 Mon Sep 17 00:00:00 2001 From: Nate McMaster Date: Fri, 9 Nov 2018 13:06:34 -0800 Subject: [PATCH 218/221] Remove the JsonPatch git submodule --- .gitmodules | 4 ---- modules/JsonPatch | 1 - 2 files changed, 5 deletions(-) delete mode 160000 modules/JsonPatch diff --git a/.gitmodules b/.gitmodules index 76458daf89..5eaf7683cc 100644 --- a/.gitmodules +++ b/.gitmodules @@ -66,10 +66,6 @@ path = modules/JavaScriptServices url = https://github.com/aspnet/JavaScriptServices.git branch = release/2.1 -[submodule "modules/JsonPatch"] - path = modules/JsonPatch - url = https://github.com/aspnet/JsonPatch.git - branch = release/2.1 [submodule "modules/KestrelHttpServer"] path = modules/KestrelHttpServer url = https://github.com/aspnet/KestrelHttpServer.git diff --git a/modules/JsonPatch b/modules/JsonPatch deleted file mode 160000 index 218064c300..0000000000 --- a/modules/JsonPatch +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 218064c300a7cf5a76669e133340a98a0c5517a5 From 979f72a839dcdc96f74326e2e7086efb9811231d Mon Sep 17 00:00:00 2001 From: Nate McMaster Date: Fri, 9 Nov 2018 13:08:02 -0800 Subject: [PATCH 219/221] Update PR validation to run a real build --- .azure/pipelines/fast-pr-validation.yml | 31 ++++++++----------------- 1 file changed, 10 insertions(+), 21 deletions(-) diff --git a/.azure/pipelines/fast-pr-validation.yml b/.azure/pipelines/fast-pr-validation.yml index c88e0a520a..b634a55889 100644 --- a/.azure/pipelines/fast-pr-validation.yml +++ b/.azure/pipelines/fast-pr-validation.yml @@ -3,28 +3,17 @@ trigger: - release/* jobs: -- template: project-ci.yml +- template: jobs/default-build.yml parameters: - buildArgs: "/t:FastCheck" -- job: RepoBuilds - pool: - vmImage: vs2017-win2016 - strategy: - maxParallel: 3 - matrix: - DataProtection: - _FolderName: DataProtection - WebSockets: - _FolderName: WebSockets - steps: - - script: src/$(_FolderName)/build.cmd -ci - displayName: Run src/$(_FolderName)/build.cmd - - task: PublishTestResults@2 - displayName: Publish test results - condition: always() - inputs: - testRunner: vstest - testResultsFiles: 'src/$(_FolderName)/artifacts/logs/**/*.trx' + jobName: PR_FastCheck + jobDisplayName: Fast Check + agentOs: Windows + buildArgs: "/p:FastCheck" +- template: jobs/default-build.yml + parameters: + jobName: Windows_Build + jobDisplayName: "Build: Windows" + agentOs: Windows - template: jobs/iisintegration-job.yml parameters: variables: From 1c8df01d09984b528b79747f1a5f8faf36cc4df4 Mon Sep 17 00:00:00 2001 From: Nate McMaster Date: Fri, 9 Nov 2018 14:09:09 -0800 Subject: [PATCH 220/221] Update PR validation to fix the FastCheck config and IIS tests --- .azure/pipelines/fast-pr-validation.yml | 5 ++++- .azure/pipelines/jobs/default-build.yml | 1 + 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/.azure/pipelines/fast-pr-validation.yml b/.azure/pipelines/fast-pr-validation.yml index b634a55889..5449521778 100644 --- a/.azure/pipelines/fast-pr-validation.yml +++ b/.azure/pipelines/fast-pr-validation.yml @@ -8,12 +8,15 @@ jobs: jobName: PR_FastCheck jobDisplayName: Fast Check agentOs: Windows - buildArgs: "/p:FastCheck" + buildArgs: "/t:FastCheck" - template: jobs/default-build.yml parameters: jobName: Windows_Build jobDisplayName: "Build: Windows" agentOs: Windows + beforeBuild: + - powershell: "& ./src/IISIntegration/tools/UpdateIISExpressCertificate.ps1" + displayName: Setup IISExpress test certificates" - template: jobs/iisintegration-job.yml parameters: variables: diff --git a/.azure/pipelines/jobs/default-build.yml b/.azure/pipelines/jobs/default-build.yml index d39a7e1e22..065e4d1770 100644 --- a/.azure/pipelines/jobs/default-build.yml +++ b/.azure/pipelines/jobs/default-build.yml @@ -63,6 +63,7 @@ jobs: - job: ${{ coalesce(parameters.jobName, parameters.agentOs) }} displayName: ${{ coalesce(parameters.jobDisplayName, parameters.agentOs) }} dependsOn: ${{ parameters.dependsOn }} + timeoutInMinutes: 90 workspace: clean: all strategy: From dfacde4deee8520bd3c5c165863f426a726e2bb0 Mon Sep 17 00:00:00 2001 From: Nate McMaster Date: Fri, 9 Nov 2018 14:23:04 -0800 Subject: [PATCH 221/221] Fix /t:FastCheck for local-projects --- build/repo.targets | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/build/repo.targets b/build/repo.targets index 0c1125bd51..9e7e303327 100644 --- a/build/repo.targets +++ b/build/repo.targets @@ -250,7 +250,7 @@ - + + + + $(BuildProperties);DesignTimeBuild=true + + + + DependsOnTargets="_SetDesignTimeBuild;ComputeGraph;VerifyPackageArtifactConfig;VerifyAllReposHaveNuGetPackageVerifier" />