Compare commits

..

5 Commits

Author SHA1 Message Date
Stef Heyenrath
dabe3a2a10 Merge branch 'master' into stef-IgnoreOpenApiErrors 2023-06-03 17:01:15 +02:00
Stef Heyenrath
b609191095 . 2023-06-01 21:14:13 +02:00
Stef Heyenrath
b1ae9aaf46 Merge branch 'master' into stef-IgnoreOpenApiErrors 2023-06-01 21:04:21 +02:00
Stef Heyenrath
ad3ef83c5e . 2023-05-30 21:41:30 +02:00
Stef Heyenrath
35ffbbc7d9 RegexExampleValueGenerator 2023-05-28 23:10:09 +02:00
207 changed files with 2655 additions and 5809 deletions

View File

@@ -1,51 +1,3 @@
# 1.5.36 (21 September 2023)
- [#986](https://github.com/WireMock-Net/WireMock.Net/pull/986) - Write logging in case a Matcher throws an exception [feature] contributed by [StefH](https://github.com/StefH)
- [#996](https://github.com/WireMock-Net/WireMock.Net/pull/996) - Remove dependency on Microsoft.AspNet.WebApi.Client [feature] contributed by [StefH](https://github.com/StefH)
- [#1002](https://github.com/WireMock-Net/WireMock.Net/pull/1002) - Fixed logic for SaveUnmatchedRequests [bug] contributed by [StefH](https://github.com/StefH)
- [#974](https://github.com/WireMock-Net/WireMock.Net/issues/974) - HttpClient extension methods causes ambiguous invocations in .NET 7 [bug]
- [#1001](https://github.com/WireMock-Net/WireMock.Net/issues/1001) - SaveUnmatchedRequests stopped working [bug]
# 1.5.35 (19 August 2023)
- [#992](https://github.com/WireMock-Net/WireMock.Net/pull/992) - Add extra unit test for WithParam multiple values comma [test] contributed by [StefH](https://github.com/StefH)
- [#993](https://github.com/WireMock-Net/WireMock.Net/pull/993) - Update JSONPathMatcher.cs to cover the string path selection to a child contributed by [DayLightDancer](https://github.com/DayLightDancer)
# 1.5.34 (04 August 2023)
- [#989](https://github.com/WireMock-Net/WireMock.Net/pull/989) - Fix MimeKitLite NuGet include [bug] contributed by [StefH](https://github.com/StefH)
- [#988](https://github.com/WireMock-Net/WireMock.Net/issues/988) - v1.5.33 Returns always StatusCode 500 [bug]
# 1.5.33 (03 August 2023)
- [#972](https://github.com/WireMock-Net/WireMock.Net/pull/972) - JsonPartialMatcher - match guid and string contributed by [timurnes](https://github.com/timurnes)
- [#976](https://github.com/WireMock-Net/WireMock.Net/pull/976) - Upgrade to Handlebars.Net.Helpers 2.4.0 to update XPath.SelectTokens and XPath.EvaluateToString [feature] contributed by [StefH](https://github.com/StefH)
- [#981](https://github.com/WireMock-Net/WireMock.Net/pull/981) - Add MultiPart/MimePart Request Matcher [feature] contributed by [StefH](https://github.com/StefH)
- [#968](https://github.com/WireMock-Net/WireMock.Net/issues/968) - Using request multipart in response template [feature]
- [#969](https://github.com/WireMock-Net/WireMock.Net/issues/969) - Multipart validation [feature]
- [#970](https://github.com/WireMock-Net/WireMock.Net/issues/970) - Loop through xml elements in handlebars template [feature]
- [#971](https://github.com/WireMock-Net/WireMock.Net/issues/971) - JsonPartialMatcher - match guid and string [feature]
# 1.5.32 (15 July 2023)
- [#966](https://github.com/WireMock-Net/WireMock.Net/pull/966) - Fixed JsonPathMatcher to match nested objects [bug] contributed by [StefH](https://github.com/StefH)
- [#965](https://github.com/WireMock-Net/WireMock.Net/issues/965) - JsonPathMatcher does not match json body nested objects [bug]
- [#967](https://github.com/WireMock-Net/WireMock.Net/issues/967) - ⭐10 million downloads ! ⭐ [feature]
# 1.5.31 (08 July 2023)
- [#964](https://github.com/WireMock-Net/WireMock.Net/pull/964) - Add GraphQL Schema matching [feature] contributed by [StefH](https://github.com/StefH)
# 1.5.30 (28 June 2023)
- [#959](https://github.com/WireMock-Net/WireMock.Net/pull/959) - Fixed logic for FluentAssertions WithHeader [bug] contributed by [StefH](https://github.com/StefH)
- [#961](https://github.com/WireMock-Net/WireMock.Net/pull/961) - Add unit-test for Param MatcherModel LinqMatcher [test] contributed by [StefH](https://github.com/StefH)
- [#962](https://github.com/WireMock-Net/WireMock.Net/pull/962) - Bump System.Linq.Dynamic.Core from 1.2.23 to 1.3.0 in /examples/WireMock.Net.Console.Net472.Classic [dependencies] contributed by [dependabot[bot]](https://github.com/apps/dependabot)
- [#963](https://github.com/WireMock-Net/WireMock.Net/pull/963) - Bump System.Linq.Dynamic.Core from 1.2.23 to 1.3.0 in /examples/WireMock.Net.StandAlone.Net461 [dependencies] contributed by [dependabot[bot]](https://github.com/apps/dependabot)
- [#958](https://github.com/WireMock-Net/WireMock.Net/issues/958) - [FluentAssertions] Should().HaveReceivedACall().WithHeader() only checks the first header with the matching key. [bug]
# 1.5.29 (22 June 2023)
- [#954](https://github.com/WireMock-Net/WireMock.Net/pull/954) - Support setting WireMockServerSettings via Environment [feature] contributed by [StefH](https://github.com/StefH)
- [#955](https://github.com/WireMock-Net/WireMock.Net/pull/955) - Fix some SonarCloud issues [refactor] contributed by [StefH](https://github.com/StefH)
- [#953](https://github.com/WireMock-Net/WireMock.Net/issues/953) - How to use environment variable [feature]
# 1.5.28 (11 June 2023)
- [#948](https://github.com/WireMock-Net/WireMock.Net/pull/948) - WireMock.Net.Testcontainers [feature] contributed by [StefH](https://github.com/StefH)
- [#951](https://github.com/WireMock-Net/WireMock.Net/pull/951) - Allow setting the Content-Length header for a HTTP method HEAD [feature] contributed by [StefH](https://github.com/StefH)
# 1.5.27 (03 June 2023) # 1.5.27 (03 June 2023)
- [#946](https://github.com/WireMock-Net/WireMock.Net/pull/946) - Add warning logging when sending a request to a Webhook does not return status 200 [feature] contributed by [StefH](https://github.com/StefH) - [#946](https://github.com/WireMock-Net/WireMock.Net/pull/946) - Add warning logging when sending a request to a Webhook does not return status 200 [feature] contributed by [StefH](https://github.com/StefH)
- [#949](https://github.com/WireMock-Net/WireMock.Net/pull/949) - Add ".NET Framework 4.7" to WireMock.Net.FluentAssertions [feature] contributed by [StefH](https://github.com/StefH) - [#949](https://github.com/WireMock-Net/WireMock.Net/pull/949) - Add ".NET Framework 4.7" to WireMock.Net.FluentAssertions [feature] contributed by [StefH](https://github.com/StefH)
@@ -994,7 +946,7 @@
- [#86](https://github.com/WireMock-Net/WireMock.Net/issues/86) - Feature : Add FileSystemWatcher logic for watching static mapping files [feature] - [#86](https://github.com/WireMock-Net/WireMock.Net/issues/86) - Feature : Add FileSystemWatcher logic for watching static mapping files [feature]
# 1.0.2.13 (23 January 2018) # 1.0.2.13 (23 January 2018)
- [#79](https://github.com/WireMock-Net/WireMock.Net/pull/79) - Fix missed content headers contributed by [volodymyr-fed](https://github.com/volodymyr-fed) - [#79](https://github.com/WireMock-Net/WireMock.Net/pull/79) - Fix missed content headers contributed by [vladimir-fed](https://github.com/vladimir-fed)
- [#57](https://github.com/WireMock-Net/WireMock.Net/issues/57) - ProxyAndRecord does not save query-parameters, headers and body [bug] - [#57](https://github.com/WireMock-Net/WireMock.Net/issues/57) - ProxyAndRecord does not save query-parameters, headers and body [bug]
- [#78](https://github.com/WireMock-Net/WireMock.Net/issues/78) - WireMock not working when attempting to access from anything other than localhost. - [#78](https://github.com/WireMock-Net/WireMock.Net/issues/78) - WireMock not working when attempting to access from anything other than localhost.
@@ -1021,7 +973,7 @@
# 1.0.2.7 (18 November 2017) # 1.0.2.7 (18 November 2017)
- [#62](https://github.com/WireMock-Net/WireMock.Net/pull/62) - Add the Host, Protocol, Port and Origin to the Request message so they can be used in templating contributed by [alastairtree](https://github.com/alastairtree) - [#62](https://github.com/WireMock-Net/WireMock.Net/pull/62) - Add the Host, Protocol, Port and Origin to the Request message so they can be used in templating contributed by [alastairtree](https://github.com/alastairtree)
- [#63](https://github.com/WireMock-Net/WireMock.Net/pull/63) - Fix issue with concurrent logging contributed by [volodymyr-fed](https://github.com/volodymyr-fed) - [#63](https://github.com/WireMock-Net/WireMock.Net/pull/63) - Fix issue with concurrent logging contributed by [vladimir-fed](https://github.com/vladimir-fed)
- [#27](https://github.com/WireMock-Net/WireMock.Net/issues/27) - New feature: Record and Save - [#27](https://github.com/WireMock-Net/WireMock.Net/issues/27) - New feature: Record and Save
- [#42](https://github.com/WireMock-Net/WireMock.Net/issues/42) - Enhancement - Save/load request logs to/from disk [feature] - [#42](https://github.com/WireMock-Net/WireMock.Net/issues/42) - Enhancement - Save/load request logs to/from disk [feature]
- [#53](https://github.com/WireMock-Net/WireMock.Net/issues/53) - New feature request: Access to Owin pipeline - [#53](https://github.com/WireMock-Net/WireMock.Net/issues/53) - New feature request: Access to Owin pipeline

View File

@@ -4,7 +4,7 @@
</PropertyGroup> </PropertyGroup>
<PropertyGroup> <PropertyGroup>
<VersionPrefix>1.5.36</VersionPrefix> <VersionPrefix>1.5.27</VersionPrefix>
<PackageIcon>WireMock.Net-Logo.png</PackageIcon> <PackageIcon>WireMock.Net-Logo.png</PackageIcon>
<PackageProjectUrl>https://github.com/WireMock-Net/WireMock.Net</PackageProjectUrl> <PackageProjectUrl>https://github.com/WireMock-Net/WireMock.Net</PackageProjectUrl>
<PackageLicenseExpression>Apache-2.0</PackageLicenseExpression> <PackageLicenseExpression>Apache-2.0</PackageLicenseExpression>

View File

@@ -1,6 +1,6 @@
rem https://github.com/StefH/GitHubReleaseNotes rem https://github.com/StefH/GitHubReleaseNotes
SET version=1.5.36 SET version=1.5.27
GitHubReleaseNotes --output CHANGELOG.md --skip-empty-releases --exclude-labels question invalid doc duplicate --version %version% --token %GH_TOKEN% GitHubReleaseNotes --output CHANGELOG.md --skip-empty-releases --exclude-labels question invalid doc duplicate --version %version% --token %GH_TOKEN%

View File

@@ -52,4 +52,4 @@ For more details see also [Docker](https://github.com/WireMock-Net/WireMock.Net-
More details on using HTTPS (SSL) can be found here [Wiki : HTTPS](https://github.com/WireMock-Net/WireMock.Net/wiki/Using-HTTPS-(SSL)) More details on using HTTPS (SSL) can be found here [Wiki : HTTPS](https://github.com/WireMock-Net/WireMock.Net/wiki/Using-HTTPS-(SSL))
## :books: Documentation ## :books: Documentation
For more info, see also this WIKI page: [What is WireMock.Net](https://github.com/WireMock-Net/WireMock.Net/wiki/What-Is-WireMock.Net). For more info, see also this WIKI page: [What is WireMock.Net](https://github.com/WireMock-Net/WireMock.Net/wiki/What-Is-WireMock.Net).

View File

@@ -1,8 +1,7 @@
# 1.5.36 (21 September 2023) # 1.5.27 (03 June 2023)
- #986 Write logging in case a Matcher throws an exception [feature] - #946 Add warning logging when sending a request to a Webhook does not return status 200 [feature]
- #996 Remove dependency on Microsoft.AspNet.WebApi.Client [feature] - #949 Add &quot;.NET Framework 4.7&quot; to WireMock.Net.FluentAssertions [feature]
- #1002 Fixed logic for SaveUnmatchedRequests [bug] - #928 TypeLoadException when using WithHeader method. [bug]
- #974 HttpClient extension methods causes ambiguous invocations in .NET 7 [bug] - #945 Webhook logging [feature]
- #1001 SaveUnmatchedRequests stopped working [bug]
The full release notes can be found here: https://github.com/WireMock-Net/WireMock.Net/blob/master/CHANGELOG.md The full release notes can be found here: https://github.com/WireMock-Net/WireMock.Net/blob/master/CHANGELOG.md

View File

@@ -42,7 +42,6 @@ For more info, see also this WIKI page: [What is WireMock.Net](https://github.co
| &nbsp;&nbsp;**WireMock.Net.OpenApiParser** | [![NuGet Badge WireMock.Net.OpenApiParser](https://buildstats.info/nuget/WireMock.Net.OpenApiParser)](https://www.nuget.org/packages/WireMock.Net.OpenApiParser) | [![MyGet Badge WireMock.Net.OpenApiParser](https://buildstats.info/myget/wiremock-net/WireMock.Net.OpenApiParser?includePreReleases=true)](https://www.myget.org/feed/wiremock-net/package/nuget/WireMock.Net.OpenApiParser) | &nbsp;&nbsp;**WireMock.Net.OpenApiParser** | [![NuGet Badge WireMock.Net.OpenApiParser](https://buildstats.info/nuget/WireMock.Net.OpenApiParser)](https://www.nuget.org/packages/WireMock.Net.OpenApiParser) | [![MyGet Badge WireMock.Net.OpenApiParser](https://buildstats.info/myget/wiremock-net/WireMock.Net.OpenApiParser?includePreReleases=true)](https://www.myget.org/feed/wiremock-net/package/nuget/WireMock.Net.OpenApiParser)
| &nbsp;&nbsp;**WireMock.Net.RestClient** | [![NuGet Badge WireMock.Net.RestClient](https://buildstats.info/nuget/WireMock.Net.RestClient)](https://www.nuget.org/packages/WireMock.Net.RestClient) | [![MyGet Badge WireMock.Net.RestClient](https://buildstats.info/myget/wiremock-net/WireMock.Net.RestClient?includePreReleases=true)](https://www.myget.org/feed/wiremock-net/package/nuget/WireMock.Net.RestClient) | &nbsp;&nbsp;**WireMock.Net.RestClient** | [![NuGet Badge WireMock.Net.RestClient](https://buildstats.info/nuget/WireMock.Net.RestClient)](https://www.nuget.org/packages/WireMock.Net.RestClient) | [![MyGet Badge WireMock.Net.RestClient](https://buildstats.info/myget/wiremock-net/WireMock.Net.RestClient?includePreReleases=true)](https://www.myget.org/feed/wiremock-net/package/nuget/WireMock.Net.RestClient)
| &nbsp;&nbsp;**WireMock.Net.xUnit** | [![NuGet Badge WireMock.Net.xUnit](https://buildstats.info/nuget/WireMock.Net.xUnit)](https://www.nuget.org/packages/WireMock.Net.xUnit) | [![MyGet Badge WireMock.Net.xUnit](https://buildstats.info/myget/wiremock-net/WireMock.Net.xUnit?includePreReleases=true)](https://www.myget.org/feed/wiremock-net/package/nuget/WireMock.Net.xUnit) | &nbsp;&nbsp;**WireMock.Net.xUnit** | [![NuGet Badge WireMock.Net.xUnit](https://buildstats.info/nuget/WireMock.Net.xUnit)](https://www.nuget.org/packages/WireMock.Net.xUnit) | [![MyGet Badge WireMock.Net.xUnit](https://buildstats.info/myget/wiremock-net/WireMock.Net.xUnit?includePreReleases=true)](https://www.myget.org/feed/wiremock-net/package/nuget/WireMock.Net.xUnit)
| &nbsp;&nbsp;**WireMock.Net.Testcontainers** | [![NuGet Badge WireMock.Net.Testcontainers](https://buildstats.info/nuget/WireMock.Net.Testcontainers)](https://www.nuget.org/packages/WireMock.Net.Testcontainers) | [![MyGet Badge WireMock.Net.Testcontainers](https://buildstats.info/myget/wiremock-net/WireMock.Net.Testcontainers?includePreReleases=true)](https://www.myget.org/feed/wiremock-net/package/nuget/WireMock.Net.Testcontainers)
| &nbsp;&nbsp;**WireMock.Org.RestClient** | [![NuGet Badge WireMock.Org.RestClient](https://buildstats.info/nuget/WireMock.Org.RestClient)](https://www.nuget.org/packages/WireMock.Org.RestClient) | [![MyGet Badge WireMock.Org.RestClient](https://buildstats.info/myget/wiremock-net/WireMock.Org.RestClient?includePreReleases=true)](https://www.myget.org/feed/wiremock-net/package/nuget/WireMock.Org.RestClient) | &nbsp;&nbsp;**WireMock.Org.RestClient** | [![NuGet Badge WireMock.Org.RestClient](https://buildstats.info/nuget/WireMock.Org.RestClient)](https://www.nuget.org/packages/WireMock.Org.RestClient) | [![MyGet Badge WireMock.Org.RestClient](https://buildstats.info/myget/wiremock-net/WireMock.Org.RestClient?includePreReleases=true)](https://www.myget.org/feed/wiremock-net/package/nuget/WireMock.Org.RestClient)
@@ -69,15 +68,13 @@ WireMock.Net can be used in several ways:
You can use your favorite test framework and use WireMock within your tests, see You can use your favorite test framework and use WireMock within your tests, see
[Wiki : UnitTesting](https://github.com/StefH/WireMock.Net/wiki/Using-WireMock-in-UnitTests). [Wiki : UnitTesting](https://github.com/StefH/WireMock.Net/wiki/Using-WireMock-in-UnitTests).
### Unit/Integration Testing using Testcontainers.DotNet
You can use [Wiki : WireMock.Net.Testcontainers](https://github.com/WireMock-Net/WireMock.Net/wiki/Using-WireMock.Net.Testcontainers) to build a WireMock.Net Docker container which can be used in Unit/Integration testing.
### As a dotnet tool ### As a dotnet tool
It's simple to install WireMock.Net as (global) dotnet tool, see [Wiki : dotnet tool](https://github.com/StefH/WireMock.Net/wiki/WireMock-as-dotnet-tool). It's simple to install WireMock.Net as (global) dotnet tool, see [Wiki : dotnet tool](https://github.com/StefH/WireMock.Net/wiki/WireMock-as-dotnet-tool).
### As standalone process / console application ### As standalone process / console application
This is quite straight forward to launch a mock server within a console application, see [Wiki : Standalone Process](https://github.com/StefH/WireMock.Net/wiki/WireMock-as-a-standalone-process). This is quite straight forward to launch a mock server within a console application, see [Wiki : Standalone Process](https://github.com/StefH/WireMock.Net/wiki/WireMock-as-a-standalone-process).
### As a Windows Service ### As a Windows Service
You can also run WireMock.Net as a Windows Service, follow this [WireMock-as-a-Windows-Service](https://github.com/WireMock-Net/WireMock.Net/wiki/WireMock-as-a-Windows-Service). You can also run WireMock.Net as a Windows Service, follow this [WireMock-as-a-Windows-Service](https://github.com/WireMock-Net/WireMock.Net/wiki/WireMock-as-a-Windows-Service).

View File

@@ -111,16 +111,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WireMockAzureQueueExample",
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WireMockAzureQueueProxy", "examples\WireMockAzureQueueProxy\WireMockAzureQueueProxy.csproj", "{ADB557D8-D66B-4387-912B-3F73E290B478}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WireMockAzureQueueProxy", "examples\WireMockAzureQueueProxy\WireMockAzureQueueProxy.csproj", "{ADB557D8-D66B-4387-912B-3F73E290B478}"
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WireMock.Net.Testcontainers", "src\WireMock.Net.Testcontainers\WireMock.Net.Testcontainers.csproj", "{12B016A5-9D8B-4EFE-96C2-CA51BE43367D}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WireMock.Net.TestcontainersExample", "examples\WireMock.Net.TestcontainersExample\WireMock.Net.TestcontainersExample.csproj", "{56A38798-C48B-4A4A-B805-071E05C02CE1}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tools", "tools", "{0147029F-FA4A-44B3-B79A-3C3574054EE4}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MultipartUploader", "tools\MultipartUploader\MultipartUploader.csproj", "{07C30227-ADEC-4BDE-8CDC-849D85A690BB}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WireMock.Net.Console.NET7.UsingNuGet", "examples\WireMock.Net.Console.NET7.UsingNuGet\WireMock.Net.Console.NET7.UsingNuGet.csproj", "{941229D6-191B-4B5E-AC81-0905EBF4F19D}"
EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU Debug|Any CPU = Debug|Any CPU
@@ -275,22 +265,6 @@ Global
{ADB557D8-D66B-4387-912B-3F73E290B478}.Debug|Any CPU.Build.0 = Debug|Any CPU {ADB557D8-D66B-4387-912B-3F73E290B478}.Debug|Any CPU.Build.0 = Debug|Any CPU
{ADB557D8-D66B-4387-912B-3F73E290B478}.Release|Any CPU.ActiveCfg = Release|Any CPU {ADB557D8-D66B-4387-912B-3F73E290B478}.Release|Any CPU.ActiveCfg = Release|Any CPU
{ADB557D8-D66B-4387-912B-3F73E290B478}.Release|Any CPU.Build.0 = Release|Any CPU {ADB557D8-D66B-4387-912B-3F73E290B478}.Release|Any CPU.Build.0 = Release|Any CPU
{12B016A5-9D8B-4EFE-96C2-CA51BE43367D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{12B016A5-9D8B-4EFE-96C2-CA51BE43367D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{12B016A5-9D8B-4EFE-96C2-CA51BE43367D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{12B016A5-9D8B-4EFE-96C2-CA51BE43367D}.Release|Any CPU.Build.0 = Release|Any CPU
{56A38798-C48B-4A4A-B805-071E05C02CE1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{56A38798-C48B-4A4A-B805-071E05C02CE1}.Debug|Any CPU.Build.0 = Debug|Any CPU
{56A38798-C48B-4A4A-B805-071E05C02CE1}.Release|Any CPU.ActiveCfg = Release|Any CPU
{56A38798-C48B-4A4A-B805-071E05C02CE1}.Release|Any CPU.Build.0 = Release|Any CPU
{07C30227-ADEC-4BDE-8CDC-849D85A690BB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{07C30227-ADEC-4BDE-8CDC-849D85A690BB}.Debug|Any CPU.Build.0 = Debug|Any CPU
{07C30227-ADEC-4BDE-8CDC-849D85A690BB}.Release|Any CPU.ActiveCfg = Release|Any CPU
{07C30227-ADEC-4BDE-8CDC-849D85A690BB}.Release|Any CPU.Build.0 = Release|Any CPU
{941229D6-191B-4B5E-AC81-0905EBF4F19D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{941229D6-191B-4B5E-AC81-0905EBF4F19D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{941229D6-191B-4B5E-AC81-0905EBF4F19D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{941229D6-191B-4B5E-AC81-0905EBF4F19D}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE
@@ -335,10 +309,6 @@ Global
{7C2A9DE8-C89F-4841-9058-6B9BF81E5E34} = {985E0ADB-D4B4-473A-AA40-567E279B7946} {7C2A9DE8-C89F-4841-9058-6B9BF81E5E34} = {985E0ADB-D4B4-473A-AA40-567E279B7946}
{BAA9EC2A-874B-45CE-8E51-A73622DC7F3D} = {985E0ADB-D4B4-473A-AA40-567E279B7946} {BAA9EC2A-874B-45CE-8E51-A73622DC7F3D} = {985E0ADB-D4B4-473A-AA40-567E279B7946}
{ADB557D8-D66B-4387-912B-3F73E290B478} = {985E0ADB-D4B4-473A-AA40-567E279B7946} {ADB557D8-D66B-4387-912B-3F73E290B478} = {985E0ADB-D4B4-473A-AA40-567E279B7946}
{12B016A5-9D8B-4EFE-96C2-CA51BE43367D} = {8F890C6F-9ACC-438D-928A-AD61CDA862F2}
{56A38798-C48B-4A4A-B805-071E05C02CE1} = {985E0ADB-D4B4-473A-AA40-567E279B7946}
{07C30227-ADEC-4BDE-8CDC-849D85A690BB} = {0147029F-FA4A-44B3-B79A-3C3574054EE4}
{941229D6-191B-4B5E-AC81-0905EBF4F19D} = {985E0ADB-D4B4-473A-AA40-567E279B7946}
EndGlobalSection EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {DC539027-9852-430C-B19F-FD035D018458} SolutionGuid = {DC539027-9852-430C-B19F-FD035D018458}

View File

@@ -10,11 +10,9 @@
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=IP/@EntryIndexedValue">IP</s:String> <s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=IP/@EntryIndexedValue">IP</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=MD/@EntryIndexedValue">MD5</s:String> <s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=MD/@EntryIndexedValue">MD5</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=OPTIONS/@EntryIndexedValue">OPTIONS</s:String> <s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=OPTIONS/@EntryIndexedValue">OPTIONS</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=OS/@EntryIndexedValue">OS</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=PATCH/@EntryIndexedValue">PATCH</s:String> <s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=PATCH/@EntryIndexedValue">PATCH</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=POST/@EntryIndexedValue">POST</s:String> <s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=POST/@EntryIndexedValue">POST</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=PUT/@EntryIndexedValue">PUT</s:String> <s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=PUT/@EntryIndexedValue">PUT</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=QL/@EntryIndexedValue">QL</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=RSA/@EntryIndexedValue">RSA</s:String> <s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=RSA/@EntryIndexedValue">RSA</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=SSL/@EntryIndexedValue">SSL</s:String> <s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=SSL/@EntryIndexedValue">SSL</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=TE/@EntryIndexedValue">TE</s:String> <s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=TE/@EntryIndexedValue">TE</s:String>
@@ -34,7 +32,6 @@
<s:Boolean x:Key="/Default/UserDictionary/Words/=Raml/@EntryIndexedValue">True</s:Boolean> <s:Boolean x:Key="/Default/UserDictionary/Words/=Raml/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=randomizer/@EntryIndexedValue">True</s:Boolean> <s:Boolean x:Key="/Default/UserDictionary/Words/=randomizer/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Scriban/@EntryIndexedValue">True</s:Boolean> <s:Boolean x:Key="/Default/UserDictionary/Words/=Scriban/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=sheyenrath/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Sigil/@EntryIndexedValue">True</s:Boolean> <s:Boolean x:Key="/Default/UserDictionary/Words/=Sigil/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Stef/@EntryIndexedValue">True</s:Boolean> <s:Boolean x:Key="/Default/UserDictionary/Words/=Stef/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=templated/@EntryIndexedValue">True</s:Boolean> <s:Boolean x:Key="/Default/UserDictionary/Words/=templated/@EntryIndexedValue">True</s:Boolean>

View File

@@ -73,6 +73,7 @@ class Program
var settingsViaBuilder = new SettingsModelBuilder() var settingsViaBuilder = new SettingsModelBuilder()
.WithGlobalProcessingDelay(1077) .WithGlobalProcessingDelay(1077)
.WithoutGlobalProcessingDelay()
.Build(); .Build();
settings1.GlobalProcessingDelay = 1077; settings1.GlobalProcessingDelay = 1077;

View File

@@ -28,10 +28,10 @@
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\..\src\WireMock.Net\WireMock.Net.csproj" /> <ProjectReference Include="..\..\src\WireMock.Net\WireMock.Net.csproj" />
<PackageReference Include="Handlebars.Net.Helpers" Version="2.4.0" /> <PackageReference Include="Handlebars.Net.Helpers" Version="2.*" />
<PackageReference Include="log4net" Version="2.0.15" /> <PackageReference Include="log4net" Version="2.0.15" />
<PackageReference Include="Microsoft.Extensions.Configuration" Version="5.0.0" /> <PackageReference Include="Microsoft.Extensions.Configuration" Version="5.0.0" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" /> <PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View File

@@ -3,7 +3,6 @@
<PropertyGroup> <PropertyGroup>
<OutputType>Exe</OutputType> <OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework> <TargetFramework>net6.0</TargetFramework>
<DefineConstants>$(DefineConstants);GRAPHQL;MIMEKIT</DefineConstants>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
@@ -22,10 +21,16 @@
<Compile Remove="__admin\mappings\1.cs" /> <Compile Remove="__admin\mappings\1.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<None Remove="__admin\mappings\array.json" />
</ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\..\src\WireMock.Net\WireMock.Net.csproj" /> <ProjectReference Include="..\..\src\WireMock.Net\WireMock.Net.csproj" />
<!--<PackageReference Include="Handlebars.Net.Helpers" Version="2.*" />-->
<PackageReference Include="log4net" Version="2.0.15" /> <PackageReference Include="log4net" Version="2.0.15" />
<PackageReference Include="Microsoft.Extensions.Configuration" Version="6.0.0" /> <PackageReference Include="Microsoft.Extensions.Configuration" Version="6.0.0" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
@@ -35,6 +40,15 @@
<None Update="nlog.config"> <None Update="nlog.config">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None> </None>
<None Update="__admin\mappings\791a3f31-6946-4ce7-8e6f-0237c7443275.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="__admin\mappings\791a3f31-6946-4ce7-8e6f-0237c7443275.json">
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
</None>
<None Update="__admin\mappings\MyXmlResponse.xml">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@@ -1,48 +0,0 @@
[
{
"Guid": "12343f31-6946-4ce7-8e6f-0237c7001000",
"Title": "1",
"Request": {
"Path": {
"Matchers": [
{
"Name": "WildcardMatcher",
"Pattern": "/mappings_static_1"
}
]
},
"Methods": [
"get"
]
},
"Response": {
"BodyAsJson": { "result": "mappings static_1" },
"Headers": {
"Content-Type": "application/json"
}
}
},
{
"Guid": "12343f31-6946-4ce7-8e6f-0237c7002000",
"Title": "2",
"Request": {
"Path": {
"Matchers": [
{
"Name": "WildcardMatcher",
"Pattern": "/mappings_static_2"
}
]
},
"Methods": [
"get"
]
},
"Response": {
"BodyAsJson": { "result": "mappings static_2" },
"Headers": {
"Content-Type": "application/json"
}
}
}
]

View File

@@ -1,34 +0,0 @@
using System.Net;
using System.Text;
using FluentAssertions;
using WireMock.Logging;
using WireMock.RequestBuilders;
using WireMock.ResponseBuilders;
using WireMock.Server;
using WireMock.Settings;
namespace WireMock.Net.Console.NET7.UsingNuGet;
internal class Program
{
private static async Task Main(string[] args)
{
var server = WireMockServer.Start(new WireMockServerSettings
{
Logger = new WireMockConsoleLogger(),
});
server.Given(Request.Create().UsingPost().WithPath("/some/endpoint"))
.RespondWith(Response.Create().WithStatusCode(HttpStatusCode.Created));
var httpClient = new HttpClient { BaseAddress = new Uri(server.Url!) };
var requestUri = new Uri(httpClient.BaseAddress!, "some/endpoint");
var content = new StringContent(string.Empty, Encoding.UTF8, "application/json");
// Act
var actual = await httpClient.PostAsync(requestUri, content);
// Assert
actual.StatusCode.Should().Be(HttpStatusCode.Created);
}
}

View File

@@ -1,15 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net7.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="FluentAssertions" Version="6.11.0" />
<PackageReference Include="WireMock.Net" Version="1.5.32" />
</ItemGroup>
</Project>

View File

@@ -19,14 +19,14 @@
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\..\src\WireMock.Net\WireMock.Net.csproj" /> <ProjectReference Include="..\..\src\WireMock.Net\WireMock.Net.csproj" />
<PackageReference Include="Handlebars.Net.Helpers" Version="2.4.0" /> <PackageReference Include="Handlebars.Net.Helpers" Version="2.*" />
<PackageReference Include="Handlebars.Net.Helpers.DynamicLinq" Version="2.4.0" /> <PackageReference Include="Handlebars.Net.Helpers.DynamicLinq" Version="2.*" />
<PackageReference Include="Handlebars.Net.Helpers.Json" Version="2.4.0" /> <PackageReference Include="Handlebars.Net.Helpers.Json" Version="2.3.*" />
<PackageReference Include="Handlebars.Net.Helpers.XPath" Version="2.4.0" /> <PackageReference Include="Handlebars.Net.Helpers.XPath" Version="2.*" />
<PackageReference Include="Handlebars.Net.Helpers.Xeger" Version="2.4.0" /> <PackageReference Include="Handlebars.Net.Helpers.Xeger" Version="2.3.*" />
<PackageReference Include="Handlebars.Net.Helpers.Random" Version="2.4.0" /> <PackageReference Include="Handlebars.Net.Helpers.Random" Version="2.3.*" />
<PackageReference Include="log4net" Version="2.0.15" /> <PackageReference Include="log4net" Version="2.0.15" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" /> <PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View File

@@ -31,14 +31,14 @@
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\..\src\WireMock.Net\WireMock.Net.csproj" /> <ProjectReference Include="..\..\src\WireMock.Net\WireMock.Net.csproj" />
<PackageReference Include="Handlebars.Net.Helpers" Version="2.4.0" /> <PackageReference Include="Handlebars.Net.Helpers" Version="2.*" />
<PackageReference Include="Handlebars.Net.Helpers.DynamicLinq" Version="2.4.0" /> <PackageReference Include="Handlebars.Net.Helpers.DynamicLinq" Version="2.*" />
<PackageReference Include="Handlebars.Net.Helpers.Json" Version="2.4.0" /> <PackageReference Include="Handlebars.Net.Helpers.Json" Version="2.3.*" />
<PackageReference Include="Handlebars.Net.Helpers.XPath" Version="2.4.0" /> <PackageReference Include="Handlebars.Net.Helpers.XPath" Version="2.*" />
<PackageReference Include="Handlebars.Net.Helpers.Xeger" Version="2.4.0" /> <PackageReference Include="Handlebars.Net.Helpers.Xeger" Version="2.3.*" />
<PackageReference Include="Handlebars.Net.Helpers.Random" Version="2.4.0" /> <PackageReference Include="Handlebars.Net.Helpers.Random" Version="2.3.*" />
<PackageReference Include="log4net" Version="2.0.15" /> <PackageReference Include="log4net" Version="2.0.15" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" /> <PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View File

@@ -28,14 +28,14 @@
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\..\src\WireMock.Net\WireMock.Net.csproj" /> <ProjectReference Include="..\..\src\WireMock.Net\WireMock.Net.csproj" />
<PackageReference Include="Handlebars.Net.Helpers" Version="2.4.0" /> <PackageReference Include="Handlebars.Net.Helpers" Version="2.*" />
<PackageReference Include="Handlebars.Net.Helpers.DynamicLinq" Version="2.4.0" /> <PackageReference Include="Handlebars.Net.Helpers.DynamicLinq" Version="2.*" />
<PackageReference Include="Handlebars.Net.Helpers.Json" Version="2.4.0" /> <PackageReference Include="Handlebars.Net.Helpers.Json" Version="2.3.*" />
<PackageReference Include="Handlebars.Net.Helpers.XPath" Version="2.4.0" /> <PackageReference Include="Handlebars.Net.Helpers.XPath" Version="2.*" />
<PackageReference Include="Handlebars.Net.Helpers.Xeger" Version="2.4.0" /> <PackageReference Include="Handlebars.Net.Helpers.Xeger" Version="2.3.*" />
<PackageReference Include="Handlebars.Net.Helpers.Random" Version="2.4.0" /> <PackageReference Include="Handlebars.Net.Helpers.Random" Version="2.3.*" />
<PackageReference Include="log4net" Version="2.0.15" /> <PackageReference Include="log4net" Version="2.0.15" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" /> <PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View File

@@ -42,36 +42,6 @@ namespace WireMock.Net.ConsoleApplication
public static class MainApp public static class MainApp
{ {
private const string TestSchema = @"
input MessageInput {
content: String
author: String
}
type Message {
id: ID!
content: String
author: String
}
type Mutation {
createMessage(input: MessageInput): Message
updateMessage(id: ID!, input: MessageInput): Message
}
type Query {
greeting:String
students:[Student]
studentById(id:ID!):Student
}
type Student {
id:ID!
firstName:String
lastName:String
fullName:String
}";
public static void Run() public static void Run()
{ {
var mappingBuilder = new MappingBuilder(); var mappingBuilder = new MappingBuilder();
@@ -137,7 +107,6 @@ namespace WireMock.Net.ConsoleApplication
Urls = new[] { url1, url2, url3 }, Urls = new[] { url1, url2, url3 },
StartAdminInterface = true, StartAdminInterface = true,
ReadStaticMappings = true, ReadStaticMappings = true,
SaveUnmatchedRequests = true,
WatchStaticMappings = true, WatchStaticMappings = true,
WatchStaticMappingsInSubdirectories = true, WatchStaticMappingsInSubdirectories = true,
//ProxyAndRecordSettings = new ProxyAndRecordSettings //ProxyAndRecordSettings = new ProxyAndRecordSettings
@@ -167,51 +136,7 @@ namespace WireMock.Net.ConsoleApplication
//server.SetAzureADAuthentication("6c2a4722-f3b9-4970-b8fc-fac41e29stef", "8587fde1-7824-42c7-8592-faf92b04stef"); //server.SetAzureADAuthentication("6c2a4722-f3b9-4970-b8fc-fac41e29stef", "8587fde1-7824-42c7-8592-faf92b04stef");
// server.AllowPartialMapping(); // server.AllowPartialMapping();
#if GRAPHQL
server
.Given(Request.Create()
.WithPath("/graphql")
.UsingPost()
.WithGraphQLSchema(TestSchema)
)
.RespondWith(Response.Create()
.WithBody("GraphQL is ok")
);
#endif
#if MIMEKIT
var textPlainContentTypeMatcher = new ContentTypeMatcher("text/plain");
var textPlainContentMatcher = new ExactMatcher("This is some plain text");
var textPlainMatcher = new MimePartMatcher(MatchBehaviour.AcceptOnMatch, textPlainContentTypeMatcher, null, null, textPlainContentMatcher);
var textJsonContentTypeMatcher = new ContentTypeMatcher("text/json");
var textJsonContentMatcher = new JsonMatcher(new { Key = "Value" }, true);
var textJsonMatcher = new MimePartMatcher(MatchBehaviour.AcceptOnMatch, textJsonContentTypeMatcher, null, null, textJsonContentMatcher);
var imagePngContentTypeMatcher = new ContentTypeMatcher("image/png");
var imagePngContentDispositionMatcher = new ExactMatcher("attachment; filename=\"image.png\"");
var imagePngContentTransferEncodingMatcher = new ExactMatcher("base64");
var imagePngContentMatcher = new ExactObjectMatcher(Convert.FromBase64String("iVBORw0KGgoAAAANSUhEUgAAAAIAAAACAgMAAAAP2OW3AAAADFBMVEX/tID/vpH/pWX/sHidUyjlAAAADElEQVR4XmMQYNgAAADkAMHebX3mAAAAAElFTkSuQmCC"));
var imagePngMatcher = new MimePartMatcher(MatchBehaviour.AcceptOnMatch, imagePngContentTypeMatcher, imagePngContentDispositionMatcher, imagePngContentTransferEncodingMatcher, imagePngContentMatcher);
var matchers = new IMatcher[]
{
textPlainMatcher,
textJsonMatcher,
imagePngMatcher
};
server
.Given(Request.Create()
.WithPath("/multipart")
.UsingPost()
.WithMultiPart(matchers)
)
.WithGuid("b9c82182-e469-41da-bcaf-b6e3157fefdb")
.RespondWith(Response.Create()
.WithBody("MultiPart is ok")
);
#endif
// 400 ms // 400 ms
server server
.Given(Request.Create() .Given(Request.Create()
@@ -751,9 +676,8 @@ namespace WireMock.Net.ConsoleApplication
})); }));
server.Given(Request.Create().WithPath(new WildcardMatcher("/multi-webhook", true)).UsingPost()) server.Given(Request.Create().WithPath(new WildcardMatcher("/multi-webhook", true)).UsingPost())
.WithWebhook .WithWebhook(new[] {
( new Webhook()
new Webhook
{ {
Request = new WebhookRequest Request = new WebhookRequest
{ {
@@ -761,13 +685,12 @@ namespace WireMock.Net.ConsoleApplication
Method = "post", Method = "post",
BodyData = new BodyData BodyData = new BodyData
{ {
BodyAsString = "OK 1!", BodyAsString = "OK 1!", DetectedBodyType = BodyType.String
DetectedBodyType = BodyType.String
}, },
Delay = 1000 Delay = 1000
} }
}, },
new Webhook new Webhook()
{ {
Request = new WebhookRequest Request = new WebhookRequest
{ {
@@ -782,7 +705,7 @@ namespace WireMock.Net.ConsoleApplication
MaximumRandomDelay = 7000 MaximumRandomDelay = 7000
} }
} }
) })
.WithWebhookFireAndForget(true) .WithWebhookFireAndForget(true)
.RespondWith(Response.Create().WithBody("a-response")); .RespondWith(Response.Create().WithBody("a-response"));

View File

@@ -39,14 +39,14 @@
<Reference Include="AnyOf, Version=0.3.0.0, Culture=neutral, PublicKeyToken=b35e6abbb527c6b1, processorArchitecture=MSIL"> <Reference Include="AnyOf, Version=0.3.0.0, Culture=neutral, PublicKeyToken=b35e6abbb527c6b1, processorArchitecture=MSIL">
<HintPath>..\..\packages\AnyOf.0.3.0\lib\net45\AnyOf.dll</HintPath> <HintPath>..\..\packages\AnyOf.0.3.0\lib\net45\AnyOf.dll</HintPath>
</Reference> </Reference>
<Reference Include="Handlebars, Version=2.1.4.0, Culture=neutral, PublicKeyToken=22225d0bf33cd661, processorArchitecture=MSIL"> <Reference Include="Handlebars, Version=2.1.2.0, Culture=neutral, PublicKeyToken=22225d0bf33cd661, processorArchitecture=MSIL">
<HintPath>..\..\packages\Handlebars.Net.2.1.4\lib\net452\Handlebars.dll</HintPath> <HintPath>..\..\packages\Handlebars.Net.2.1.2\lib\net452\Handlebars.dll</HintPath>
</Reference> </Reference>
<Reference Include="Handlebars.Net.Helpers, Version=2.4.0.0, Culture=neutral, PublicKeyToken=00d131fae0c250bc, processorArchitecture=MSIL"> <Reference Include="Handlebars.Net.Helpers, Version=2.3.12.0, Culture=neutral, PublicKeyToken=00d131fae0c250bc, processorArchitecture=MSIL">
<HintPath>..\..\packages\Handlebars.Net.Helpers.2.4.0\lib\net452\Handlebars.Net.Helpers.dll</HintPath> <HintPath>..\..\packages\Handlebars.Net.Helpers.2.3.12\lib\net452\Handlebars.Net.Helpers.dll</HintPath>
</Reference> </Reference>
<Reference Include="HandlebarsDotNet.Helpers.Core, Version=2.4.0.0, Culture=neutral, PublicKeyToken=00d131fae0c250bc, processorArchitecture=MSIL"> <Reference Include="HandlebarsDotNet.Helpers.Core, Version=2.3.12.0, Culture=neutral, PublicKeyToken=00d131fae0c250bc, processorArchitecture=MSIL">
<HintPath>..\..\packages\Handlebars.Net.Helpers.Core.2.4.0\lib\net452\HandlebarsDotNet.Helpers.Core.dll</HintPath> <HintPath>..\..\packages\Handlebars.Net.Helpers.Core.2.3.12\lib\net452\HandlebarsDotNet.Helpers.Core.dll</HintPath>
</Reference> </Reference>
<Reference Include="log4net, Version=2.0.15.0, Culture=neutral, PublicKeyToken=669e0ddf0bb1aa2a, processorArchitecture=MSIL"> <Reference Include="log4net, Version=2.0.15.0, Culture=neutral, PublicKeyToken=669e0ddf0bb1aa2a, processorArchitecture=MSIL">
<HintPath>..\..\packages\log4net.2.0.15\lib\net45\log4net.dll</HintPath> <HintPath>..\..\packages\log4net.2.0.15\lib\net45\log4net.dll</HintPath>
@@ -56,7 +56,7 @@
<HintPath>..\..\packages\Microsoft.Owin.Host.HttpListener.3.1.0\lib\net45\Microsoft.Owin.Host.HttpListener.dll</HintPath> <HintPath>..\..\packages\Microsoft.Owin.Host.HttpListener.3.1.0\lib\net45\Microsoft.Owin.Host.HttpListener.dll</HintPath>
</Reference> </Reference>
<Reference Include="Newtonsoft.Json, Version=13.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL"> <Reference Include="Newtonsoft.Json, Version=13.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\..\packages\Newtonsoft.Json.13.0.3\lib\net45\Newtonsoft.Json.dll</HintPath> <HintPath>..\..\packages\Newtonsoft.Json.13.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference> </Reference>
<Reference Include="SimMetrics.Net, Version=1.0.5.0, Culture=neutral, PublicKeyToken=c58dc06d59f3391b, processorArchitecture=MSIL"> <Reference Include="SimMetrics.Net, Version=1.0.5.0, Culture=neutral, PublicKeyToken=c58dc06d59f3391b, processorArchitecture=MSIL">
<HintPath>..\..\packages\SimMetrics.Net.1.0.5\lib\net45\SimMetrics.Net.dll</HintPath> <HintPath>..\..\packages\SimMetrics.Net.1.0.5\lib\net45\SimMetrics.Net.dll</HintPath>
@@ -67,7 +67,6 @@
<Reference Include="System" /> <Reference Include="System" />
<Reference Include="System.Configuration" /> <Reference Include="System.Configuration" />
<Reference Include="System.Core" /> <Reference Include="System.Core" />
<Reference Include="System.Net.Http" />
<Reference Include="System.ValueTuple, Version=4.0.3.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL"> <Reference Include="System.ValueTuple, Version=4.0.3.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\..\packages\System.ValueTuple.4.5.0\lib\netstandard1.0\System.ValueTuple.dll</HintPath> <HintPath>..\..\packages\System.ValueTuple.4.5.0\lib\netstandard1.0\System.ValueTuple.dll</HintPath>
</Reference> </Reference>

View File

@@ -1,12 +1,12 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<packages> <packages>
<package id="AnyOf" version="0.3.0" targetFramework="net452" /> <package id="AnyOf" version="0.3.0" targetFramework="net452" />
<package id="Handlebars.Net" version="2.1.4" targetFramework="net452" /> <package id="Handlebars.Net" version="2.1.2" targetFramework="net452" />
<package id="Handlebars.Net.Helpers" version="2.4.0" targetFramework="net452" /> <package id="Handlebars.Net.Helpers" version="2.3.12" targetFramework="net452" />
<package id="Handlebars.Net.Helpers.Core" version="2.4.0" targetFramework="net452" /> <package id="Handlebars.Net.Helpers.Core" version="2.3.12" targetFramework="net452" />
<package id="log4net" version="2.0.15" targetFramework="net452" /> <package id="log4net" version="2.0.15" targetFramework="net452" />
<package id="Microsoft.Owin.Host.HttpListener" version="3.1.0" targetFramework="net452" /> <package id="Microsoft.Owin.Host.HttpListener" version="3.1.0" targetFramework="net452" />
<package id="Newtonsoft.Json" version="13.0.3" targetFramework="net452" /> <package id="Newtonsoft.Json" version="13.0.1" targetFramework="net452" />
<package id="SimMetrics.Net" version="1.0.5" targetFramework="net452" /> <package id="SimMetrics.Net" version="1.0.5" targetFramework="net452" />
<package id="Stef.Validation" version="0.1.1" targetFramework="net452" /> <package id="Stef.Validation" version="0.1.1" targetFramework="net452" />
<package id="System.ValueTuple" version="4.5.0" targetFramework="net452" /> <package id="System.ValueTuple" version="4.5.0" targetFramework="net452" />

View File

@@ -38,14 +38,14 @@
<Reference Include="AnyOf, Version=0.3.0.0, Culture=neutral, PublicKeyToken=b35e6abbb527c6b1, processorArchitecture=MSIL"> <Reference Include="AnyOf, Version=0.3.0.0, Culture=neutral, PublicKeyToken=b35e6abbb527c6b1, processorArchitecture=MSIL">
<HintPath>..\..\packages\AnyOf.0.3.0\lib\net45\AnyOf.dll</HintPath> <HintPath>..\..\packages\AnyOf.0.3.0\lib\net45\AnyOf.dll</HintPath>
</Reference> </Reference>
<Reference Include="Handlebars, Version=2.1.4.0, Culture=neutral, PublicKeyToken=22225d0bf33cd661, processorArchitecture=MSIL"> <Reference Include="Handlebars, Version=2.1.2.0, Culture=neutral, PublicKeyToken=22225d0bf33cd661, processorArchitecture=MSIL">
<HintPath>..\..\packages\Handlebars.Net.2.1.4\lib\net46\Handlebars.dll</HintPath> <HintPath>..\..\packages\Handlebars.Net.2.1.2\lib\net46\Handlebars.dll</HintPath>
</Reference> </Reference>
<Reference Include="Handlebars.Net.Helpers, Version=2.4.0.0, Culture=neutral, PublicKeyToken=00d131fae0c250bc, processorArchitecture=MSIL"> <Reference Include="Handlebars.Net.Helpers, Version=2.3.12.0, Culture=neutral, PublicKeyToken=00d131fae0c250bc, processorArchitecture=MSIL">
<HintPath>..\..\packages\Handlebars.Net.Helpers.2.4.0\lib\net46\Handlebars.Net.Helpers.dll</HintPath> <HintPath>..\..\packages\Handlebars.Net.Helpers.2.3.12\lib\net46\Handlebars.Net.Helpers.dll</HintPath>
</Reference> </Reference>
<Reference Include="HandlebarsDotNet.Helpers.Core, Version=2.4.0.0, Culture=neutral, PublicKeyToken=00d131fae0c250bc, processorArchitecture=MSIL"> <Reference Include="HandlebarsDotNet.Helpers.Core, Version=2.3.12.0, Culture=neutral, PublicKeyToken=00d131fae0c250bc, processorArchitecture=MSIL">
<HintPath>..\..\packages\Handlebars.Net.Helpers.Core.2.4.0\lib\net46\HandlebarsDotNet.Helpers.Core.dll</HintPath> <HintPath>..\..\packages\Handlebars.Net.Helpers.Core.2.3.12\lib\net46\HandlebarsDotNet.Helpers.Core.dll</HintPath>
</Reference> </Reference>
<Reference Include="log4net, Version=2.0.15.0, Culture=neutral, PublicKeyToken=669e0ddf0bb1aa2a, processorArchitecture=MSIL"> <Reference Include="log4net, Version=2.0.15.0, Culture=neutral, PublicKeyToken=669e0ddf0bb1aa2a, processorArchitecture=MSIL">
<HintPath>..\..\packages\log4net.2.0.15\lib\net45\log4net.dll</HintPath> <HintPath>..\..\packages\log4net.2.0.15\lib\net45\log4net.dll</HintPath>
@@ -54,7 +54,7 @@
<HintPath>..\..\packages\Microsoft.Extensions.DependencyInjection.Abstractions.2.2.0\lib\netstandard2.0\Microsoft.Extensions.DependencyInjection.Abstractions.dll</HintPath> <HintPath>..\..\packages\Microsoft.Extensions.DependencyInjection.Abstractions.2.2.0\lib\netstandard2.0\Microsoft.Extensions.DependencyInjection.Abstractions.dll</HintPath>
</Reference> </Reference>
<Reference Include="Newtonsoft.Json, Version=13.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL"> <Reference Include="Newtonsoft.Json, Version=13.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\..\packages\Newtonsoft.Json.13.0.3\lib\net45\Newtonsoft.Json.dll</HintPath> <HintPath>..\..\packages\Newtonsoft.Json.13.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference> </Reference>
<Reference Include="SimMetrics.Net, Version=1.0.5.0, Culture=neutral, PublicKeyToken=c58dc06d59f3391b, processorArchitecture=MSIL"> <Reference Include="SimMetrics.Net, Version=1.0.5.0, Culture=neutral, PublicKeyToken=c58dc06d59f3391b, processorArchitecture=MSIL">
<HintPath>..\..\packages\SimMetrics.Net.1.0.5\lib\net45\SimMetrics.Net.dll</HintPath> <HintPath>..\..\packages\SimMetrics.Net.1.0.5\lib\net45\SimMetrics.Net.dll</HintPath>

View File

@@ -1,12 +1,12 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<packages> <packages>
<package id="AnyOf" version="0.3.0" targetFramework="net461" /> <package id="AnyOf" version="0.3.0" targetFramework="net461" />
<package id="Handlebars.Net" version="2.1.4" targetFramework="net461" /> <package id="Handlebars.Net" version="2.1.2" targetFramework="net461" />
<package id="Handlebars.Net.Helpers" version="2.4.0" targetFramework="net461" /> <package id="Handlebars.Net.Helpers" version="2.3.12" targetFramework="net461" />
<package id="Handlebars.Net.Helpers.Core" version="2.4.0" targetFramework="net461" /> <package id="Handlebars.Net.Helpers.Core" version="2.3.12" targetFramework="net461" />
<package id="log4net" version="2.0.15" targetFramework="net461" /> <package id="log4net" version="2.0.15" targetFramework="net461" />
<package id="Microsoft.Extensions.DependencyInjection.Abstractions" version="2.2.0" targetFramework="net461" /> <package id="Microsoft.Extensions.DependencyInjection.Abstractions" version="2.2.0" targetFramework="net461" />
<package id="Newtonsoft.Json" version="13.0.3" targetFramework="net461" /> <package id="Newtonsoft.Json" version="13.0.1" targetFramework="net461" />
<package id="SimMetrics.Net" version="1.0.5" targetFramework="net461" /> <package id="SimMetrics.Net" version="1.0.5" targetFramework="net461" />
<package id="Stef.Validation" version="0.1.1" targetFramework="net461" /> <package id="Stef.Validation" version="0.1.1" targetFramework="net461" />
<package id="System.ValueTuple" version="4.5.0" targetFramework="net461" /> <package id="System.ValueTuple" version="4.5.0" targetFramework="net461" />

View File

@@ -101,10 +101,6 @@
<assemblyIdentity name="System.IdentityModel.Tokens.Jwt" publicKeyToken="31bf3856ad364e35" culture="neutral" /> <assemblyIdentity name="System.IdentityModel.Tokens.Jwt" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-6.25.0.0" newVersion="6.25.0.0" /> <bindingRedirect oldVersion="0.0.0.0-6.25.0.0" newVersion="6.25.0.0" />
</dependentAssembly> </dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="NJsonSchema" publicKeyToken="c2f9c3bdfae56102" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-10.7.2.0" newVersion="10.7.2.0" />
</dependentAssembly>
</assemblyBinding> </assemblyBinding>
</runtime> </runtime>
</configuration> </configuration>

View File

@@ -46,32 +46,32 @@
<Reference Include="Fare, Version=2.2.0.0, Culture=neutral, PublicKeyToken=ea68d375bf33a7c8, processorArchitecture=MSIL"> <Reference Include="Fare, Version=2.2.0.0, Culture=neutral, PublicKeyToken=ea68d375bf33a7c8, processorArchitecture=MSIL">
<HintPath>..\..\packages\Fare.2.2.1\lib\net35\Fare.dll</HintPath> <HintPath>..\..\packages\Fare.2.2.1\lib\net35\Fare.dll</HintPath>
</Reference> </Reference>
<Reference Include="Handlebars, Version=2.1.4.0, Culture=neutral, PublicKeyToken=22225d0bf33cd661, processorArchitecture=MSIL"> <Reference Include="Handlebars, Version=2.1.2.0, Culture=neutral, PublicKeyToken=22225d0bf33cd661, processorArchitecture=MSIL">
<HintPath>..\..\packages\Handlebars.Net.2.1.4\lib\net46\Handlebars.dll</HintPath> <HintPath>..\..\packages\Handlebars.Net.2.1.2\lib\net46\Handlebars.dll</HintPath>
</Reference> </Reference>
<Reference Include="Handlebars.Net.Helpers, Version=2.4.0.0, Culture=neutral, PublicKeyToken=00d131fae0c250bc, processorArchitecture=MSIL"> <Reference Include="Handlebars.Net.Helpers, Version=2.3.12.0, Culture=neutral, PublicKeyToken=00d131fae0c250bc, processorArchitecture=MSIL">
<HintPath>..\..\packages\Handlebars.Net.Helpers.2.4.0\lib\net46\Handlebars.Net.Helpers.dll</HintPath> <HintPath>..\..\packages\Handlebars.Net.Helpers.2.3.12\lib\net46\Handlebars.Net.Helpers.dll</HintPath>
</Reference> </Reference>
<Reference Include="HandlebarsDotNet.Helpers.Core, Version=2.4.0.0, Culture=neutral, PublicKeyToken=00d131fae0c250bc, processorArchitecture=MSIL"> <Reference Include="HandlebarsDotNet.Helpers.Core, Version=2.3.12.0, Culture=neutral, PublicKeyToken=00d131fae0c250bc, processorArchitecture=MSIL">
<HintPath>..\..\packages\Handlebars.Net.Helpers.Core.2.4.0\lib\net46\HandlebarsDotNet.Helpers.Core.dll</HintPath> <HintPath>..\..\packages\Handlebars.Net.Helpers.Core.2.3.12\lib\net46\HandlebarsDotNet.Helpers.Core.dll</HintPath>
</Reference> </Reference>
<Reference Include="HandlebarsDotNet.Helpers.DynamicLinq, Version=2.4.0.0, Culture=neutral, PublicKeyToken=00d131fae0c250bc, processorArchitecture=MSIL"> <Reference Include="HandlebarsDotNet.Helpers.DynamicLinq, Version=2.3.12.0, Culture=neutral, PublicKeyToken=00d131fae0c250bc, processorArchitecture=MSIL">
<HintPath>..\..\packages\Handlebars.Net.Helpers.DynamicLinq.2.4.0\lib\net46\HandlebarsDotNet.Helpers.DynamicLinq.dll</HintPath> <HintPath>..\..\packages\Handlebars.Net.Helpers.DynamicLinq.2.3.12\lib\net46\HandlebarsDotNet.Helpers.DynamicLinq.dll</HintPath>
</Reference> </Reference>
<Reference Include="HandlebarsDotNet.Helpers.Humanizer, Version=2.4.0.0, Culture=neutral, PublicKeyToken=00d131fae0c250bc, processorArchitecture=MSIL"> <Reference Include="HandlebarsDotNet.Helpers.Humanizer, Version=2.3.12.0, Culture=neutral, PublicKeyToken=00d131fae0c250bc, processorArchitecture=MSIL">
<HintPath>..\..\packages\Handlebars.Net.Helpers.Humanizer.2.4.0\lib\net46\HandlebarsDotNet.Helpers.Humanizer.dll</HintPath> <HintPath>..\..\packages\Handlebars.Net.Helpers.Humanizer.2.3.12\lib\net46\HandlebarsDotNet.Helpers.Humanizer.dll</HintPath>
</Reference> </Reference>
<Reference Include="HandlebarsDotNet.Helpers.Json, Version=2.4.0.0, Culture=neutral, PublicKeyToken=00d131fae0c250bc, processorArchitecture=MSIL"> <Reference Include="HandlebarsDotNet.Helpers.Json, Version=2.3.12.0, Culture=neutral, PublicKeyToken=00d131fae0c250bc, processorArchitecture=MSIL">
<HintPath>..\..\packages\Handlebars.Net.Helpers.Json.2.4.0\lib\net46\HandlebarsDotNet.Helpers.Json.dll</HintPath> <HintPath>..\..\packages\Handlebars.Net.Helpers.Json.2.3.12\lib\net46\HandlebarsDotNet.Helpers.Json.dll</HintPath>
</Reference> </Reference>
<Reference Include="HandlebarsDotNet.Helpers.Random, Version=2.4.0.0, Culture=neutral, PublicKeyToken=00d131fae0c250bc, processorArchitecture=MSIL"> <Reference Include="HandlebarsDotNet.Helpers.Random, Version=2.3.12.0, Culture=neutral, PublicKeyToken=00d131fae0c250bc, processorArchitecture=MSIL">
<HintPath>..\..\packages\Handlebars.Net.Helpers.Random.2.4.0\lib\net46\HandlebarsDotNet.Helpers.Random.dll</HintPath> <HintPath>..\..\packages\Handlebars.Net.Helpers.Random.2.3.12\lib\net46\HandlebarsDotNet.Helpers.Random.dll</HintPath>
</Reference> </Reference>
<Reference Include="HandlebarsDotNet.Helpers.Xeger, Version=2.4.0.0, Culture=neutral, PublicKeyToken=00d131fae0c250bc, processorArchitecture=MSIL"> <Reference Include="HandlebarsDotNet.Helpers.Xeger, Version=2.3.12.0, Culture=neutral, PublicKeyToken=00d131fae0c250bc, processorArchitecture=MSIL">
<HintPath>..\..\packages\Handlebars.Net.Helpers.Xeger.2.4.0\lib\net46\HandlebarsDotNet.Helpers.Xeger.dll</HintPath> <HintPath>..\..\packages\Handlebars.Net.Helpers.Xeger.2.3.12\lib\net46\HandlebarsDotNet.Helpers.Xeger.dll</HintPath>
</Reference> </Reference>
<Reference Include="HandlebarsDotNet.Helpers.XPath, Version=2.4.0.0, Culture=neutral, PublicKeyToken=00d131fae0c250bc, processorArchitecture=MSIL"> <Reference Include="HandlebarsDotNet.Helpers.XPath, Version=2.3.12.0, Culture=neutral, PublicKeyToken=00d131fae0c250bc, processorArchitecture=MSIL">
<HintPath>..\..\packages\Handlebars.Net.Helpers.XPath.2.4.0\lib\net46\HandlebarsDotNet.Helpers.XPath.dll</HintPath> <HintPath>..\..\packages\Handlebars.Net.Helpers.XPath.2.3.12\lib\net46\HandlebarsDotNet.Helpers.XPath.dll</HintPath>
</Reference> </Reference>
<Reference Include="Humanizer, Version=2.14.0.0, Culture=neutral, PublicKeyToken=979442b78dfc278e, processorArchitecture=MSIL"> <Reference Include="Humanizer, Version=2.14.0.0, Culture=neutral, PublicKeyToken=979442b78dfc278e, processorArchitecture=MSIL">
<HintPath>..\..\packages\Humanizer.Core.2.14.1\lib\netstandard2.0\Humanizer.dll</HintPath> <HintPath>..\..\packages\Humanizer.Core.2.14.1\lib\netstandard2.0\Humanizer.dll</HintPath>
@@ -257,16 +257,16 @@
<HintPath>..\..\packages\Namotion.Reflection.2.0.10\lib\net45\Namotion.Reflection.dll</HintPath> <HintPath>..\..\packages\Namotion.Reflection.2.0.10\lib\net45\Namotion.Reflection.dll</HintPath>
</Reference> </Reference>
<Reference Include="Newtonsoft.Json, Version=13.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL"> <Reference Include="Newtonsoft.Json, Version=13.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\..\packages\Newtonsoft.Json.13.0.3\lib\net45\Newtonsoft.Json.dll</HintPath> <HintPath>..\..\packages\Newtonsoft.Json.13.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference> </Reference>
<Reference Include="NJsonSchema, Version=10.7.2.0, Culture=neutral, PublicKeyToken=c2f9c3bdfae56102, processorArchitecture=MSIL"> <Reference Include="NJsonSchema, Version=10.6.10.0, Culture=neutral, PublicKeyToken=c2f9c3bdfae56102, processorArchitecture=MSIL">
<HintPath>..\..\packages\NJsonSchema.10.7.2\lib\net45\NJsonSchema.dll</HintPath> <HintPath>..\..\packages\NJsonSchema.10.6.10\lib\net45\NJsonSchema.dll</HintPath>
</Reference> </Reference>
<Reference Include="NJsonSchema.Extensions, Version=0.1.0.0, Culture=neutral, PublicKeyToken=e52fadf300daf456, processorArchitecture=MSIL"> <Reference Include="NJsonSchema.Extensions, Version=0.1.0.0, Culture=neutral, PublicKeyToken=e52fadf300daf456, processorArchitecture=MSIL">
<HintPath>..\..\packages\NJsonSchema.Extensions.0.1.0\lib\net45\NJsonSchema.Extensions.dll</HintPath> <HintPath>..\..\packages\NJsonSchema.Extensions.0.1.0\lib\net45\NJsonSchema.Extensions.dll</HintPath>
</Reference> </Reference>
<Reference Include="NSwag.Core, Version=13.16.1.0, Culture=neutral, PublicKeyToken=c2d88086e098d109, processorArchitecture=MSIL"> <Reference Include="NSwag.Core, Version=13.15.10.0, Culture=neutral, PublicKeyToken=c2d88086e098d109, processorArchitecture=MSIL">
<HintPath>..\..\packages\NSwag.Core.13.16.1\lib\net45\NSwag.Core.dll</HintPath> <HintPath>..\..\packages\NSwag.Core.13.15.10\lib\net45\NSwag.Core.dll</HintPath>
</Reference> </Reference>
<Reference Include="RandomDataGenerator, Version=1.0.16.0, Culture=neutral, PublicKeyToken=ae5c571d29a3b8d9, processorArchitecture=MSIL"> <Reference Include="RandomDataGenerator, Version=1.0.16.0, Culture=neutral, PublicKeyToken=ae5c571d29a3b8d9, processorArchitecture=MSIL">
<HintPath>..\..\packages\RandomDataGenerator.Net.1.0.17\lib\net45\RandomDataGenerator.dll</HintPath> <HintPath>..\..\packages\RandomDataGenerator.Net.1.0.17\lib\net45\RandomDataGenerator.dll</HintPath>
@@ -302,8 +302,8 @@
<Reference Include="System.IO.Pipelines, Version=4.0.0.1, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL"> <Reference Include="System.IO.Pipelines, Version=4.0.0.1, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\..\packages\System.IO.Pipelines.4.5.3\lib\netstandard2.0\System.IO.Pipelines.dll</HintPath> <HintPath>..\..\packages\System.IO.Pipelines.4.5.3\lib\netstandard2.0\System.IO.Pipelines.dll</HintPath>
</Reference> </Reference>
<Reference Include="System.Linq.Dynamic.Core, Version=1.3.1.0, Culture=neutral, PublicKeyToken=0f07ec44de6ac832, processorArchitecture=MSIL"> <Reference Include="System.Linq.Dynamic.Core, Version=1.2.23.0, Culture=neutral, PublicKeyToken=0f07ec44de6ac832, processorArchitecture=MSIL">
<HintPath>..\..\packages\System.Linq.Dynamic.Core.1.3.1\lib\net46\System.Linq.Dynamic.Core.dll</HintPath> <HintPath>..\..\packages\System.Linq.Dynamic.Core.1.2.23\lib\net46\System.Linq.Dynamic.Core.dll</HintPath>
</Reference> </Reference>
<Reference Include="System.Memory, Version=4.0.1.1, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL"> <Reference Include="System.Memory, Version=4.0.1.1, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\..\packages\System.Memory.4.5.4\lib\net461\System.Memory.dll</HintPath> <HintPath>..\..\packages\System.Memory.4.5.4\lib\net461\System.Memory.dll</HintPath>

View File

@@ -2,15 +2,15 @@
<packages> <packages>
<package id="AnyOf" version="0.3.0" targetFramework="net472" /> <package id="AnyOf" version="0.3.0" targetFramework="net472" />
<package id="Fare" version="2.2.1" targetFramework="net472" /> <package id="Fare" version="2.2.1" targetFramework="net472" />
<package id="Handlebars.Net" version="2.1.4" targetFramework="net472" /> <package id="Handlebars.Net" version="2.1.2" targetFramework="net472" />
<package id="Handlebars.Net.Helpers" version="2.4.0" targetFramework="net472" /> <package id="Handlebars.Net.Helpers" version="2.3.12" targetFramework="net472" />
<package id="Handlebars.Net.Helpers.Core" version="2.4.0" targetFramework="net472" /> <package id="Handlebars.Net.Helpers.Core" version="2.3.12" targetFramework="net472" />
<package id="Handlebars.Net.Helpers.DynamicLinq" version="2.4.0" targetFramework="net472" /> <package id="Handlebars.Net.Helpers.DynamicLinq" version="2.3.12" targetFramework="net472" />
<package id="Handlebars.Net.Helpers.Humanizer" version="2.4.0" targetFramework="net472" /> <package id="Handlebars.Net.Helpers.Humanizer" version="2.3.12" targetFramework="net472" />
<package id="Handlebars.Net.Helpers.Json" version="2.4.0" targetFramework="net472" /> <package id="Handlebars.Net.Helpers.Json" version="2.3.12" targetFramework="net472" />
<package id="Handlebars.Net.Helpers.Random" version="2.4.0" targetFramework="net472" /> <package id="Handlebars.Net.Helpers.Random" version="2.3.12" targetFramework="net472" />
<package id="Handlebars.Net.Helpers.Xeger" version="2.4.0" targetFramework="net472" /> <package id="Handlebars.Net.Helpers.Xeger" version="2.3.12" targetFramework="net472" />
<package id="Handlebars.Net.Helpers.XPath" version="2.4.0" targetFramework="net472" /> <package id="Handlebars.Net.Helpers.XPath" version="2.3.12" targetFramework="net472" />
<package id="Humanizer" version="2.14.1" targetFramework="net472" /> <package id="Humanizer" version="2.14.1" targetFramework="net472" />
<package id="Humanizer.Core" version="2.14.1" targetFramework="net472" /> <package id="Humanizer.Core" version="2.14.1" targetFramework="net472" />
<package id="Humanizer.Core.af" version="2.14.1" targetFramework="net472" /> <package id="Humanizer.Core.af" version="2.14.1" targetFramework="net472" />
@@ -123,10 +123,10 @@
<package id="Microsoft.IdentityModel.Tokens" version="6.25.0" targetFramework="net472" /> <package id="Microsoft.IdentityModel.Tokens" version="6.25.0" targetFramework="net472" />
<package id="Microsoft.Net.Http.Headers" version="2.2.0" targetFramework="net472" /> <package id="Microsoft.Net.Http.Headers" version="2.2.0" targetFramework="net472" />
<package id="Namotion.Reflection" version="2.0.10" targetFramework="net472" /> <package id="Namotion.Reflection" version="2.0.10" targetFramework="net472" />
<package id="Newtonsoft.Json" version="13.0.3" targetFramework="net472" /> <package id="Newtonsoft.Json" version="13.0.1" targetFramework="net472" />
<package id="NJsonSchema" version="10.7.2" targetFramework="net472" /> <package id="NJsonSchema" version="10.6.10" targetFramework="net472" />
<package id="NJsonSchema.Extensions" version="0.1.0" targetFramework="net472" /> <package id="NJsonSchema.Extensions" version="0.1.0" targetFramework="net472" />
<package id="NSwag.Core" version="13.16.1" targetFramework="net472" /> <package id="NSwag.Core" version="13.15.10" targetFramework="net472" />
<package id="Nullable" version="1.3.1" targetFramework="net472" developmentDependency="true" /> <package id="Nullable" version="1.3.1" targetFramework="net472" developmentDependency="true" />
<package id="RandomDataGenerator.Net" version="1.0.17" targetFramework="net472" /> <package id="RandomDataGenerator.Net" version="1.0.17" targetFramework="net472" />
<package id="Scriban.Signed" version="2.1.4" targetFramework="net472" /> <package id="Scriban.Signed" version="2.1.4" targetFramework="net472" />
@@ -138,7 +138,7 @@
<package id="System.Diagnostics.DiagnosticSource" version="4.5.0" targetFramework="net472" /> <package id="System.Diagnostics.DiagnosticSource" version="4.5.0" targetFramework="net472" />
<package id="System.IdentityModel.Tokens.Jwt" version="6.25.0" targetFramework="net472" /> <package id="System.IdentityModel.Tokens.Jwt" version="6.25.0" targetFramework="net472" />
<package id="System.IO.Pipelines" version="4.5.3" targetFramework="net472" /> <package id="System.IO.Pipelines" version="4.5.3" targetFramework="net472" />
<package id="System.Linq.Dynamic.Core" version="1.3.1" targetFramework="net472" /> <package id="System.Linq.Dynamic.Core" version="1.2.23" targetFramework="net472" />
<package id="System.Memory" version="4.5.4" targetFramework="net472" /> <package id="System.Memory" version="4.5.4" targetFramework="net472" />
<package id="System.Numerics.Vectors" version="4.5.0" targetFramework="net472" /> <package id="System.Numerics.Vectors" version="4.5.0" targetFramework="net472" />
<package id="System.Reflection.Metadata" version="1.6.0" targetFramework="net472" /> <package id="System.Reflection.Metadata" version="1.6.0" targetFramework="net472" />

View File

@@ -9,7 +9,7 @@
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\..\src\WireMock.Net\WireMock.Net.csproj" /> <ProjectReference Include="..\..\src\WireMock.Net\WireMock.Net.csproj" />
<ProjectReference Include="..\..\src\WireMock.Net.Abstractions\WireMock.Net.Abstractions.csproj" /> <ProjectReference Include="..\..\src\WireMock.Net.Abstractions\WireMock.Net.Abstractions.csproj" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" /> <PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View File

@@ -7,7 +7,7 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" /> <PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View File

@@ -72,7 +72,7 @@
<HintPath>..\..\packages\Microsoft.Owin.Host.HttpListener.3.1.0\lib\net45\Microsoft.Owin.Host.HttpListener.dll</HintPath> <HintPath>..\..\packages\Microsoft.Owin.Host.HttpListener.3.1.0\lib\net45\Microsoft.Owin.Host.HttpListener.dll</HintPath>
</Reference> </Reference>
<Reference Include="Newtonsoft.Json, Version=13.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL"> <Reference Include="Newtonsoft.Json, Version=13.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\..\packages\Newtonsoft.Json.13.0.3\lib\net45\Newtonsoft.Json.dll</HintPath> <HintPath>..\..\packages\Newtonsoft.Json.13.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference> </Reference>
<Reference Include="System" /> <Reference Include="System" />
<Reference Include="System.Core" /> <Reference Include="System.Core" />

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<packages> <packages>
<package id="Microsoft.Owin.Host.HttpListener" version="3.1.0" targetFramework="net452" /> <package id="Microsoft.Owin.Host.HttpListener" version="3.1.0" targetFramework="net452" />
<package id="Newtonsoft.Json" version="13.0.3" targetFramework="net452" /> <package id="Newtonsoft.Json" version="13.0.1" targetFramework="net452" />
</packages> </packages>

View File

@@ -1,5 +1,6 @@
using System; using System;
using System.IO; using System.IO;
using WireMock.Net.OpenApiParser.Types;
using WireMock.RequestBuilders; using WireMock.RequestBuilders;
using WireMock.ResponseBuilders; using WireMock.ResponseBuilders;
@@ -18,7 +19,7 @@ class Program
private static void RunMockServerWithDynamicExampleGeneration() private static void RunMockServerWithDynamicExampleGeneration()
{ {
// Run your mocking framework specifying your Example Values generator class. // Run your mocking framework specifying your Example Values generator class.
var serverCustomer_V2_json = Run.RunServer(Path.Combine(Folder, "Swagger_Customer_V2.0.json"), "http://localhost:8090/", true, new DynamicDataGeneration(), Types.ExampleValueType.Value, Types.ExampleValueType.Value); var serverCustomer_V2_json = Run.RunServer(Path.Combine(Folder, "Swagger_Customer_V2.0.json"), "http://localhost:8090/", true, new DynamicDataGeneration(), ExampleValueType.Value, ExampleValueType.Value);
Console.WriteLine("Press any key to stop the servers"); Console.WriteLine("Press any key to stop the servers");
Console.ReadKey(); Console.ReadKey();

View File

@@ -46,7 +46,7 @@
<HintPath>..\..\packages\Microsoft.Owin.Hosting.2.0.2\lib\net45\Microsoft.Owin.Hosting.dll</HintPath> <HintPath>..\..\packages\Microsoft.Owin.Hosting.2.0.2\lib\net45\Microsoft.Owin.Hosting.dll</HintPath>
</Reference> </Reference>
<Reference Include="Newtonsoft.Json, Version=13.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL"> <Reference Include="Newtonsoft.Json, Version=13.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\..\packages\Newtonsoft.Json.13.0.3\lib\net45\Newtonsoft.Json.dll</HintPath> <HintPath>..\..\packages\Newtonsoft.Json.13.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference> </Reference>
<Reference Include="Owin, Version=1.0.0.0, Culture=neutral, PublicKeyToken=f0ebd12fd5e55cc5, processorArchitecture=MSIL"> <Reference Include="Owin, Version=1.0.0.0, Culture=neutral, PublicKeyToken=f0ebd12fd5e55cc5, processorArchitecture=MSIL">
<HintPath>..\..\packages\Owin.1.0\lib\net40\Owin.dll</HintPath> <HintPath>..\..\packages\Owin.1.0\lib\net40\Owin.dll</HintPath>

View File

@@ -8,7 +8,7 @@
<package id="Microsoft.Owin" version="4.2.2" targetFramework="net452" /> <package id="Microsoft.Owin" version="4.2.2" targetFramework="net452" />
<package id="Microsoft.Owin.Host.HttpListener" version="2.0.2" targetFramework="net452" /> <package id="Microsoft.Owin.Host.HttpListener" version="2.0.2" targetFramework="net452" />
<package id="Microsoft.Owin.Hosting" version="2.0.2" targetFramework="net452" /> <package id="Microsoft.Owin.Hosting" version="2.0.2" targetFramework="net452" />
<package id="Newtonsoft.Json" version="13.0.3" targetFramework="net48" /> <package id="Newtonsoft.Json" version="13.0.1" targetFramework="net452" />
<package id="Owin" version="1.0" targetFramework="net452" /> <package id="Owin" version="1.0" targetFramework="net452" />
<package id="SimMetrics.Net" version="1.0.5" targetFramework="net452" /> <package id="SimMetrics.Net" version="1.0.5" targetFramework="net452" />
<package id="System.Net.Http" version="4.3.4" targetFramework="net452" requireReinstallation="true" /> <package id="System.Net.Http" version="4.3.4" targetFramework="net452" requireReinstallation="true" />

View File

@@ -29,7 +29,7 @@ static class Program
XmlConfigurator.Configure(LogRepository, new FileInfo("log4net.config")); XmlConfigurator.Configure(LogRepository, new FileInfo("log4net.config"));
if (!WireMockServerSettingsParser.TryParseArguments(args, Environment.GetEnvironmentVariables(), out var settings, new WireMockLog4NetLogger())) if (!WireMockServerSettingsParser.TryParseArguments(args, out var settings, new WireMockLog4NetLogger()))
{ {
return; return;
} }

View File

@@ -13,7 +13,7 @@ public class Program
{ {
XmlConfigurator.Configure(new FileInfo("log4net.config")); XmlConfigurator.Configure(new FileInfo("log4net.config"));
if (WireMockServerSettingsParser.TryParseArguments(args, Environment.GetEnvironmentVariables(), out var settings)) if (WireMockServerSettingsParser.TryParseArguments(args, out var settings))
{ {
Console.WriteLine("WireMock.Net server arguments [{0}]", string.Join(", ", args.Select(a => $"'{a}'"))); Console.WriteLine("WireMock.Net server arguments [{0}]", string.Join(", ", args.Select(a => $"'{a}'")));

View File

@@ -46,7 +46,7 @@
<HintPath>..\..\packages\Microsoft.Owin.Host.HttpListener.4.0.0\lib\net451\Microsoft.Owin.Host.HttpListener.dll</HintPath> <HintPath>..\..\packages\Microsoft.Owin.Host.HttpListener.4.0.0\lib\net451\Microsoft.Owin.Host.HttpListener.dll</HintPath>
</Reference> </Reference>
<Reference Include="Newtonsoft.Json, Version=13.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL"> <Reference Include="Newtonsoft.Json, Version=13.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\..\packages\Newtonsoft.Json.13.0.3\lib\net45\Newtonsoft.Json.dll</HintPath> <HintPath>..\..\packages\Newtonsoft.Json.13.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference> </Reference>
<Reference Include="System" /> <Reference Include="System" />
<Reference Include="System.Configuration" /> <Reference Include="System.Configuration" />

View File

@@ -3,5 +3,5 @@
<package id="log4net" version="2.0.15" targetFramework="net452" /> <package id="log4net" version="2.0.15" targetFramework="net452" />
<package id="Microsoft.AspNet.WebApi.Client" version="5.2.6" targetFramework="net452" /> <package id="Microsoft.AspNet.WebApi.Client" version="5.2.6" targetFramework="net452" />
<package id="Microsoft.Owin.Host.HttpListener" version="4.0.0" targetFramework="net452" /> <package id="Microsoft.Owin.Host.HttpListener" version="4.0.0" targetFramework="net452" />
<package id="Newtonsoft.Json" version="13.0.3" targetFramework="net452" /> <package id="Newtonsoft.Json" version="13.0.1" targetFramework="net452" />
</packages> </packages>

View File

@@ -9,7 +9,7 @@ static class Program
{ {
static void Main(string[] args) static void Main(string[] args)
{ {
if (WireMockServerSettingsParser.TryParseArguments(args, Environment.GetEnvironmentVariables(), out var settings)) if (WireMockServerSettingsParser.TryParseArguments(args, out var settings))
{ {
Console.WriteLine("WireMock.Net server arguments [{0}]", string.Join(", ", args.Select(a => $"'{a}'"))); Console.WriteLine("WireMock.Net server arguments [{0}]", string.Join(", ", args.Select(a => $"'{a}'")));

View File

@@ -39,8 +39,8 @@
<StartupObject>WireMock.Net.StandAlone.Net461.Program</StartupObject> <StartupObject>WireMock.Net.StandAlone.Net461.Program</StartupObject>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<Reference Include="Handlebars, Version=2.1.4.0, Culture=neutral, PublicKeyToken=22225d0bf33cd661, processorArchitecture=MSIL"> <Reference Include="Handlebars, Version=2.1.2.0, Culture=neutral, PublicKeyToken=22225d0bf33cd661, processorArchitecture=MSIL">
<HintPath>..\..\packages\Handlebars.Net.2.1.4\lib\net46\Handlebars.dll</HintPath> <HintPath>..\..\packages\Handlebars.Net.2.1.2\lib\net46\Handlebars.dll</HintPath>
</Reference> </Reference>
<Reference Include="Microsoft.AspNetCore, Version=2.2.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL"> <Reference Include="Microsoft.AspNetCore, Version=2.2.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.AspNetCore.2.2.0\lib\netstandard2.0\Microsoft.AspNetCore.dll</HintPath> <HintPath>..\..\packages\Microsoft.AspNetCore.2.2.0\lib\netstandard2.0\Microsoft.AspNetCore.dll</HintPath>
@@ -205,7 +205,7 @@
<HintPath>..\..\packages\MimeKitLite.2.0.7\lib\net45\MimeKitLite.dll</HintPath> <HintPath>..\..\packages\MimeKitLite.2.0.7\lib\net45\MimeKitLite.dll</HintPath>
</Reference> </Reference>
<Reference Include="Newtonsoft.Json, Version=13.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL"> <Reference Include="Newtonsoft.Json, Version=13.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\..\packages\Newtonsoft.Json.13.0.3\lib\net45\Newtonsoft.Json.dll</HintPath> <HintPath>..\..\packages\Newtonsoft.Json.13.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference> </Reference>
<Reference Include="Owin, Version=1.0.0.0, Culture=neutral, PublicKeyToken=f0ebd12fd5e55cc5, processorArchitecture=MSIL"> <Reference Include="Owin, Version=1.0.0.0, Culture=neutral, PublicKeyToken=f0ebd12fd5e55cc5, processorArchitecture=MSIL">
<HintPath>..\..\packages\Owin.1.0\lib\net40\Owin.dll</HintPath> <HintPath>..\..\packages\Owin.1.0\lib\net40\Owin.dll</HintPath>
@@ -235,8 +235,8 @@
<Reference Include="System.IO.Pipelines, Version=4.0.0.1, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL"> <Reference Include="System.IO.Pipelines, Version=4.0.0.1, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\..\packages\System.IO.Pipelines.4.5.3\lib\netstandard2.0\System.IO.Pipelines.dll</HintPath> <HintPath>..\..\packages\System.IO.Pipelines.4.5.3\lib\netstandard2.0\System.IO.Pipelines.dll</HintPath>
</Reference> </Reference>
<Reference Include="System.Linq.Dynamic.Core, Version=1.3.1.0, Culture=neutral, PublicKeyToken=0f07ec44de6ac832, processorArchitecture=MSIL"> <Reference Include="System.Linq.Dynamic.Core, Version=1.2.23.0, Culture=neutral, PublicKeyToken=0f07ec44de6ac832, processorArchitecture=MSIL">
<HintPath>..\..\packages\System.Linq.Dynamic.Core.1.3.1\lib\net46\System.Linq.Dynamic.Core.dll</HintPath> <HintPath>..\..\packages\System.Linq.Dynamic.Core.1.2.23\lib\net46\System.Linq.Dynamic.Core.dll</HintPath>
</Reference> </Reference>
<Reference Include="System.Memory, Version=4.0.1.1, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL"> <Reference Include="System.Memory, Version=4.0.1.1, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\..\packages\System.Memory.4.5.4\lib\net461\System.Memory.dll</HintPath> <HintPath>..\..\packages\System.Memory.4.5.4\lib\net461\System.Memory.dll</HintPath>

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<packages> <packages>
<package id="Handlebars.Net" version="2.1.4" targetFramework="net461" /> <package id="Handlebars.Net" version="2.1.2" targetFramework="net461" />
<package id="Microsoft.AspNet.WebApi.Client" version="5.2.9" targetFramework="net461" /> <package id="Microsoft.AspNet.WebApi.Client" version="5.2.9" targetFramework="net461" />
<package id="Microsoft.AspNet.WebApi.Core" version="5.2.9" targetFramework="net461" /> <package id="Microsoft.AspNet.WebApi.Core" version="5.2.9" targetFramework="net461" />
<package id="Microsoft.AspNet.WebApi.Owin" version="5.2.9" targetFramework="net461" /> <package id="Microsoft.AspNet.WebApi.Owin" version="5.2.9" targetFramework="net461" />
@@ -59,7 +59,7 @@
<package id="Microsoft.Owin.Host.HttpListener" version="4.2.2" targetFramework="net461" /> <package id="Microsoft.Owin.Host.HttpListener" version="4.2.2" targetFramework="net461" />
<package id="Microsoft.Owin.Hosting" version="4.2.2" targetFramework="net461" /> <package id="Microsoft.Owin.Hosting" version="4.2.2" targetFramework="net461" />
<package id="MimeKitLite" version="2.0.7" targetFramework="net461" /> <package id="MimeKitLite" version="2.0.7" targetFramework="net461" />
<package id="Newtonsoft.Json" version="13.0.3" targetFramework="net461" /> <package id="Newtonsoft.Json" version="13.0.1" targetFramework="net461" />
<package id="Owin" version="1.0" targetFramework="net461" /> <package id="Owin" version="1.0" targetFramework="net461" />
<package id="RestEase" version="1.5.7" targetFramework="net461" /> <package id="RestEase" version="1.5.7" targetFramework="net461" />
<package id="SimMetrics.Net" version="1.0.5" targetFramework="net461" /> <package id="SimMetrics.Net" version="1.0.5" targetFramework="net461" />
@@ -68,7 +68,7 @@
<package id="System.ComponentModel.Annotations" version="4.5.0" targetFramework="net461" /> <package id="System.ComponentModel.Annotations" version="4.5.0" targetFramework="net461" />
<package id="System.Diagnostics.DiagnosticSource" version="4.5.1" targetFramework="net461" /> <package id="System.Diagnostics.DiagnosticSource" version="4.5.1" targetFramework="net461" />
<package id="System.IO.Pipelines" version="4.5.3" targetFramework="net461" /> <package id="System.IO.Pipelines" version="4.5.3" targetFramework="net461" />
<package id="System.Linq.Dynamic.Core" version="1.3.1" targetFramework="net461" /> <package id="System.Linq.Dynamic.Core" version="1.2.23" targetFramework="net461" />
<package id="System.Memory" version="4.5.4" targetFramework="net461" /> <package id="System.Memory" version="4.5.4" targetFramework="net461" />
<package id="System.Numerics.Vectors" version="4.5.0" targetFramework="net461" /> <package id="System.Numerics.Vectors" version="4.5.0" targetFramework="net461" />
<package id="System.Reflection.Metadata" version="1.6.0" targetFramework="net461" /> <package id="System.Reflection.Metadata" version="1.6.0" targetFramework="net461" />

View File

@@ -1,43 +0,0 @@
using Newtonsoft.Json;
using Testcontainers.MsSql;
using WireMock.Net.Testcontainers;
namespace WireMock.Net.TestcontainersExample;
internal class Program
{
private static async Task Main(string[] args)
{
var container = new WireMockContainerBuilder()
.WithAdminUserNameAndPassword("x", "y")
.WithMappings(@"C:\Dev\GitHub\WireMock.Net\examples\WireMock.Net.Console.NET6\__admin\mappings")
.WithWatchStaticMappings(true)
.WithAutoRemove(true)
.WithCleanUp(true)
.Build();
await container.StartAsync().ConfigureAwait(false);
var logs = await container.GetLogsAsync(DateTime.Now.AddDays(-1)).ConfigureAwait(false);
Console.WriteLine("logs = " + logs.Stdout);
var restEaseApiClient = container.CreateWireMockAdminClient();
var settings = await restEaseApiClient.GetSettingsAsync();
Console.WriteLine("settings = " + JsonConvert.SerializeObject(settings, Formatting.Indented));
var mappings = await restEaseApiClient.GetMappingsAsync();
Console.WriteLine("mappings = " + JsonConvert.SerializeObject(mappings, Formatting.Indented));
var client = container.CreateClient();
var result = await client.GetStringAsync("/static/mapping");
Console.WriteLine("result = " + result);
await container.StopAsync();
var sql = new MsSqlBuilder()
.WithAutoRemove(true)
.WithCleanUp(true)
.Build();
}
}

View File

@@ -1,24 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Testcontainers.MsSql" Version="3.2.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\WireMock.Net.Testcontainers\WireMock.Net.Testcontainers.csproj" />
</ItemGroup>
<ItemGroup>
<None Update="873d495f-940e-4b86-a1f4-4f0fc7be8b8b.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
</Project>

View File

@@ -12,7 +12,7 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="6.0.0" /> <PackageReference Include="Microsoft.Extensions.Logging.Console" Version="6.0.0" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" /> <PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View File

@@ -12,13 +12,13 @@
<ItemGroup Condition=" '$(TargetFramework)' == 'netcoreapp2.0'"> <ItemGroup Condition=" '$(TargetFramework)' == 'netcoreapp2.0'">
<DotNetCliToolReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Tools" Version="2.0.2" /> <DotNetCliToolReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Tools" Version="2.0.2" />
<PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.9" /> <PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.9" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" /> <PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
</ItemGroup> </ItemGroup>
<ItemGroup Condition=" '$(TargetFramework)' == 'netcoreapp2.1'"> <ItemGroup Condition=" '$(TargetFramework)' == 'netcoreapp2.1'">
<DotNetCliToolReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Tools" Version="2.0.4" /> <DotNetCliToolReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Tools" Version="2.0.4" />
<PackageReference Include="Microsoft.AspNetCore.All" /> <PackageReference Include="Microsoft.AspNetCore.All" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" /> <PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View File

@@ -12,7 +12,7 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="3.1.8" /> <PackageReference Include="Microsoft.Extensions.Logging.Console" Version="3.1.8" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" /> <PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View File

@@ -6,7 +6,7 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" /> <PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View File

@@ -39,38 +39,14 @@ public class MatcherModel
/// <summary> /// <summary>
/// The Operator to use when multiple patterns are defined. Optional. /// The Operator to use when multiple patterns are defined. Optional.
/// - null = Same as "or". /// - null = Same as "or".
/// - "or" = Only one pattern is required to match. /// - "or" = Only one pattern should match.
/// - "and" = All patterns should match. /// - "and" = All patterns should match.
/// - "average" = The average value from all patterns. /// - "average" = The average value from all patterns.
/// </summary> /// </summary>
public string? MatchOperator { get; set; } public string? MatchOperator { get; set; }
#region JsonPartialMatcher and JsonPartialWildcardMatcher
/// <summary> /// <summary>
/// Support Regex. /// Support Regex, only used for JsonPartialMatcher.
/// </summary> /// </summary>
public bool? Regex { get; set; } public bool? Regex { get; set; }
#endregion
#region MimePartMatcher
/// <summary>
/// ContentType Matcher (image/png; name=image.png)
/// </summary>
public MatcherModel? ContentTypeMatcher { get; set; }
/// <summary>
/// ContentDisposition Matcher (attachment; filename=image.png)
/// </summary>
public MatcherModel? ContentDispositionMatcher { get; set; }
/// <summary>
/// ContentTransferEncoding Matcher (base64)
/// </summary>
public MatcherModel? ContentTransferEncodingMatcher { get; set; }
/// <summary>
/// Content Matcher
/// </summary>
public MatcherModel? ContentMatcher { get; set; }
#endregion
} }

View File

@@ -1,25 +1,21 @@
using System; using System;
namespace WireMock.Admin.Mappings; namespace WireMock.Admin.Mappings
/// <summary>
/// Status
/// </summary>
[FluentBuilder.AutoGenerateBuilder]
public class StatusModel
{ {
/// <summary> /// <summary>
/// The optional guid. /// Status
/// </summary> /// </summary>
public Guid? Guid { get; set; } [FluentBuilder.AutoGenerateBuilder]
public class StatusModel
{
/// <summary>
/// The optional guid.
/// </summary>
public Guid? Guid { get; set; }
/// <summary> /// <summary>
/// The status. /// The status (can also contain the error message).
/// </summary> /// </summary>
public string? Status { get; set; } public string Status { get; set; }
}
/// <summary>
/// The error message.
/// </summary>
public string? Error { get; set; }
} }

View File

@@ -62,6 +62,11 @@ public class SettingsModel
/// </summary> /// </summary>
public bool? HandleRequestsSynchronously { get; set; } public bool? HandleRequestsSynchronously { get; set; }
/// <summary>
/// Throw an exception when the Matcher fails because of invalid input. (default set to <c>false</c>).
/// </summary>
public bool? ThrowExceptionWhenMatcherFails { get; set; }
/// <summary> /// <summary>
/// Use the RegexExtended instead of the default <see cref="Regex"/>. (default set to <c>true</c>). /// Use the RegexExtended instead of the default <see cref="Regex"/>. (default set to <c>true</c>).
/// </summary> /// </summary>

View File

@@ -1,120 +1,121 @@
using JetBrains.Annotations; using JetBrains.Annotations;
using System.Collections.Generic; using System.Collections.Generic;
namespace WireMock.Handlers; namespace WireMock.Handlers
/// <summary>
/// Handler to interact with the file system to handle folders and read and write (static mapping) files.
/// </summary>
public interface IFileSystemHandler
{ {
/// <summary> /// <summary>
/// Gets the folder where the static mappings are located. For local file system, this would be `{CurrentFolder}/__admin/mappings`. /// Handler to interact with the file system to handle folders and read and write (static mapping) files.
/// </summary> /// </summary>
/// <returns>The folder name.</returns> public interface IFileSystemHandler
string GetMappingFolder(); {
/// <summary>
/// Gets the folder where the static mappings are located. For local file system, this would be `{CurrentFolder}/__admin/mappings`.
/// </summary>
/// <returns>The folder name.</returns>
string GetMappingFolder();
/// <summary> /// <summary>
/// Determines whether the given path refers to an existing directory on disk. /// Determines whether the given path refers to an existing directory on disk.
/// </summary> /// </summary>
/// <param name="path">The path.</param> /// <param name="path">The path.</param>
/// <returns>true if path refers to an existing directory; false if the directory does not exist or an error occurs when trying to determine if the specified directory exists.</returns> /// <returns>true if path refers to an existing directory; false if the directory does not exist or an error occurs when trying to determine if the specified directory exists.</returns>
bool FolderExists([NotNull] string path); bool FolderExists([NotNull] string path);
/// <summary> /// <summary>
/// Creates all directories and subdirectories in the specified path unless they already exist. /// Creates all directories and subdirectories in the specified path unless they already exist.
/// </summary> /// </summary>
/// <param name="path">The path.</param> /// <param name="path">The path.</param>
void CreateFolder([NotNull] string path); void CreateFolder([NotNull] string path);
/// <summary> /// <summary>
/// Returns an enumerable collection of file names in a specified path. /// Returns an enumerable collection of file names in a specified path.
/// </summary> /// </summary>
/// <param name="path">The path.</param> /// <param name="path">The path.</param>
/// <param name="includeSubdirectories">A value indicating whether subdirectories should also included when enumerating files.</param> /// <param name="includeSubdirectories">A value indicating whether subdirectories should also included when enumerating files.</param>
/// <returns>An enumerable collection of the full names (including paths) for the files in the directory (and optionally subdirectories) specified by path.</returns> /// <returns>An enumerable collection of the full names (including paths) for the files in the directory (and optionally subdirectories) specified by path.</returns>
IEnumerable<string> EnumerateFiles([NotNull] string path, bool includeSubdirectories); IEnumerable<string> EnumerateFiles([NotNull] string path, bool includeSubdirectories);
/// <summary> /// <summary>
/// Read a static mapping file as text. /// Read a static mapping file as text.
/// </summary> /// </summary>
/// <param name="path">The path (folder + filename with .json extension).</param> /// <param name="path">The path (folder + filename with .json extension).</param>
/// <returns>The file content as text.</returns> /// <returns>The file content as text.</returns>
string ReadMappingFile([NotNull] string path); string ReadMappingFile([NotNull] string path);
/// <summary> /// <summary>
/// Write the static mapping file. /// Write the static mapping file.
/// </summary> /// </summary>
/// <param name="path">The path (folder + filename with .json extension).</param> /// <param name="path">The path (folder + filename with .json extension).</param>
/// <param name="text">The text.</param> /// <param name="text">The text.</param>
void WriteMappingFile([NotNull] string path, [NotNull] string text); void WriteMappingFile([NotNull] string path, [NotNull] string text);
/// <summary> /// <summary>
/// Read a response body file as byte[]. /// Read a response body file as byte[].
/// </summary> /// </summary>
/// <param name="path">The path or filename from the file to read.</param> /// <param name="path">The path or filename from the file to read.</param>
/// <returns>The file content as bytes.</returns> /// <returns>The file content as bytes.</returns>
byte[] ReadResponseBodyAsFile([NotNull] string path); byte[] ReadResponseBodyAsFile([NotNull] string path);
/// <summary> /// <summary>
/// Read a response body file as text. /// Read a response body file as text.
/// </summary> /// </summary>
/// <param name="path">The path or filename from the file to read.</param> /// <param name="path">The path or filename from the file to read.</param>
/// <returns>The file content as text.</returns> /// <returns>The file content as text.</returns>
string ReadResponseBodyAsString([NotNull] string path); string ReadResponseBodyAsString([NotNull] string path);
/// <summary> /// <summary>
/// Delete a file. /// Delete a file.
/// </summary> /// </summary>
/// <param name="filename">The filename.</param> /// <param name="filename">The filename.</param>
void DeleteFile([NotNull] string filename); void DeleteFile([NotNull] string filename);
/// <summary> /// <summary>
/// Determines whether the given path refers to an existing file on disk. /// Determines whether the given path refers to an existing file on disk.
/// </summary> /// </summary>
/// <param name="filename">The filename.</param> /// <param name="filename">The filename.</param>
/// <returns>true if path refers to an existing file; false if the file does not exist.</returns> /// <returns>true if path refers to an existing file; false if the file does not exist.</returns>
bool FileExists([NotNull] string filename); bool FileExists([NotNull] string filename);
/// <summary> /// <summary>
/// Write a file. /// Write a file.
/// </summary> /// </summary>
/// <param name="filename">The filename.</param> /// <param name="filename">The filename.</param>
/// <param name="bytes">The bytes.</param> /// <param name="bytes">The bytes.</param>
void WriteFile([NotNull] string filename, [NotNull] byte[] bytes); void WriteFile([NotNull] string filename, [NotNull] byte[] bytes);
/// <summary> /// <summary>
/// Write a file. /// Write a file.
/// </summary> /// </summary>
/// <param name="folder">The folder.</param> /// <param name="folder">The folder.</param>
/// <param name="filename">The filename.</param> /// <param name="filename">The filename.</param>
/// <param name="bytes">The bytes.</param> /// <param name="bytes">The bytes.</param>
void WriteFile([NotNull] string folder, [NotNull] string filename, [NotNull] byte[] bytes); void WriteFile([NotNull] string folder, [NotNull] string filename, [NotNull] byte[] bytes);
/// <summary> /// <summary>
/// Read a file as bytes. /// Read a file as bytes.
/// </summary> /// </summary>
/// <param name="filename">The filename.</param> /// <param name="filename">The filename.</param>
/// <returns>The file content as bytes.</returns> /// <returns>The file content as bytes.</returns>
byte[] ReadFile([NotNull] string filename); byte[] ReadFile([NotNull] string filename);
/// <summary> /// <summary>
/// Read a file as string. /// Read a file as string.
/// </summary> /// </summary>
/// <param name="filename">The filename.</param> /// <param name="filename">The filename.</param>
/// <returns>The file content as a string.</returns> /// <returns>The file content as a string.</returns>
string ReadFileAsString([NotNull] string filename); string ReadFileAsString([NotNull] string filename);
/// <summary> /// <summary>
/// Gets the folder where the unmatched requests should be stored. For local file system, this would be `{CurrentFolder}/requests/unmatched`. /// Gets the folder where the unmatched requests should be stored. For local file system, this would be `{CurrentFolder}/requests/unmatched`.
/// </summary> /// </summary>
/// <returns>The folder name.</returns> /// <returns>The folder name.</returns>
string GetUnmatchedRequestsFolder(); string GetUnmatchedRequestsFolder();
/// <summary> /// <summary>
/// Write a unmatched request to the Unmatched RequestsFolder. /// Write a unmatched request to the Unmatched RequestsFolder.
/// </summary> /// </summary>
/// <param name="filename">The filename.</param> /// <param name="filename">The filename.</param>
/// <param name="text">The text.</param> /// <param name="text">The text.</param>
void WriteUnmatchedRequest([NotNull] string filename, [NotNull] string text); void WriteUnmatchedRequest([NotNull] string filename, [NotNull] string text);
}
} }

View File

@@ -96,39 +96,32 @@ public interface IRequestMessage
/// <summary> /// <summary>
/// The original body as string. Convenience getter for Handlebars. /// The original body as string. Convenience getter for Handlebars.
/// </summary> /// </summary>
string? Body { get; } string Body { get; }
/// <summary> /// <summary>
/// The body (as JSON object). Convenience getter for Handlebars. /// The body (as JSON object). Convenience getter for Handlebars.
/// </summary> /// </summary>
object? BodyAsJson { get; } object BodyAsJson { get; }
/// <summary> /// <summary>
/// The body (as bytearray). Convenience getter for Handlebars. /// The body (as bytearray). Convenience getter for Handlebars.
/// </summary> /// </summary>
byte[]? BodyAsBytes { get; } byte[] BodyAsBytes { get; }
#if MIMEKIT
/// <summary>
/// The original body as MimeMessage. Convenience getter for Handlebars.
/// </summary>
object? BodyAsMimeMessage { get; }
#endif
/// <summary> /// <summary>
/// The detected body type. Convenience getter for Handlebars. /// The detected body type. Convenience getter for Handlebars.
/// </summary> /// </summary>
string? DetectedBodyType { get; } string DetectedBodyType { get; }
/// <summary> /// <summary>
/// The detected body type from the Content-Type header. Convenience getter for Handlebars. /// The detected body type from the Content-Type header. Convenience getter for Handlebars.
/// </summary> /// </summary>
string? DetectedBodyTypeFromContentType { get; } string DetectedBodyTypeFromContentType { get; }
/// <summary> /// <summary>
/// The detected compression from the Content-Encoding header. Convenience getter for Handlebars. /// The detected compression from the Content-Encoding header. Convenience getter for Handlebars.
/// </summary> /// </summary>
string? DetectedCompression { get; } string DetectedCompression { get; }
/// <summary> /// <summary>
/// Gets the Host /// Gets the Host

View File

@@ -2,63 +2,65 @@ using System;
using JetBrains.Annotations; using JetBrains.Annotations;
using WireMock.Admin.Requests; using WireMock.Admin.Requests;
namespace WireMock.Logging; namespace WireMock.Logging
/// <summary>
/// IWireMockLogger interface
/// </summary>
[PublicAPI]
public interface IWireMockLogger
{ {
/// <summary> /// <summary>
/// Writes the message at the Debug level using the specified parameters. /// IWireMockLogger interface
/// </summary> /// </summary>
/// <param name="formatString">The format string.</param>
/// <param name="args">The arguments.</param>
[PublicAPI] [PublicAPI]
[StringFormatMethod("formatString")] public interface IWireMockLogger
void Debug(string formatString, params object[] args); {
/// <summary>
/// Writes the message at the Debug level using the specified parameters.
/// </summary>
/// <param name="formatString">The format string.</param>
/// <param name="args">The arguments.</param>
[PublicAPI]
[StringFormatMethod("formatString")]
void Debug(string formatString, params object[] args);
/// <summary> /// <summary>
/// Writes the message at the Info level using the specified parameters. /// Writes the message at the Info level using the specified parameters.
/// </summary> /// </summary>
/// <param name="formatString">The format string.</param> /// <param name="formatString">The format string.</param>
/// <param name="args">The arguments.</param> /// <param name="args">The arguments.</param>
[PublicAPI] [PublicAPI]
[StringFormatMethod("formatString")] [StringFormatMethod("formatString")]
void Info(string formatString, params object[] args); void Info(string formatString, params object[] args);
/// <summary> /// <summary>
/// Writes the message at the Warning level using the specified parameters. /// Writes the message at the Warning level using the specified parameters.
/// </summary> /// </summary>
/// <param name="formatString">The format string.</param> /// <param name="formatString">The format string.</param>
/// <param name="args">The arguments.</param> /// <param name="args">The arguments.</param>
[PublicAPI] [PublicAPI]
[StringFormatMethod("formatString")] [StringFormatMethod("formatString")]
void Warn(string formatString, params object[] args); void Warn(string formatString, params object[] args);
/// <summary> /// <summary>
/// Writes the message at the Error level using the specified parameters. /// Writes the message at the Error level using the specified parameters.
/// </summary> /// </summary>
/// <param name="formatString">The format string.</param> /// <param name="formatString">The format string.</param>
/// <param name="args">The arguments.</param> /// <param name="args">The arguments.</param>
[PublicAPI] [PublicAPI]
[StringFormatMethod("formatString")] [StringFormatMethod("formatString")]
void Error(string formatString, params object[] args); void Error(string formatString, params object[] args);
/// <summary> /// <summary>
/// Writes the message at the Error level using the specified exception. /// Writes the message at the Error level using the specified exception.
/// </summary> /// </summary>
/// <param name="formatString">The format string.</param> /// <param name="formatString">The format string.</param>
/// <param name="exception">The exception.</param> /// <param name="exception">The exception.</param>
[PublicAPI] [PublicAPI]
void Error(string formatString, Exception exception); [StringFormatMethod("formatString")]
void Error(string formatString, Exception exception);
/// <summary> /// <summary>
/// Writes the LogEntryModel (LogRequestModel, LogResponseModel and more). /// Writes the LogEntryModel (LogRequestModel, LogResponseModel and more).
/// </summary> /// </summary>
/// <param name="logEntryModel">The Request Log Model.</param> /// <param name="logEntryModel">The Request Log Model.</param>
/// <param name="isAdminRequest">Defines if this request is an admin request.</param> /// <param name="isAdminRequest">Defines if this request is an admin request.</param>
[PublicAPI] [PublicAPI]
void DebugRequestResponse(LogEntryModel logEntryModel, bool isAdminRequest); void DebugRequestResponse(LogEntryModel logEntryModel, bool isAdminRequest);
}
} }

View File

@@ -1,56 +1,56 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
namespace WireMock.Matchers.Request; namespace WireMock.Matchers.Request
/// <summary>
/// IRequestMatchResult
/// </summary>
public interface IRequestMatchResult : IComparable
{ {
/// <summary> /// <summary>
/// Gets the match percentage. /// IRequestMatchResult
/// </summary> /// </summary>
/// <value> public interface IRequestMatchResult : IComparable
/// The match percentage. {
/// </value> /// <summary>
double AverageTotalScore { get; } /// Gets the match percentage.
/// </summary>
/// <value>
/// The match percentage.
/// </value>
double AverageTotalScore { get; }
/// <summary> /// <summary>
/// Gets or sets a value indicating whether this instance is perfect match. /// Gets or sets a value indicating whether this instance is perfect match.
/// </summary> /// </summary>
/// <value> /// <value>
/// <c>true</c> if this instance is perfect match; otherwise, <c>false</c>. /// <c>true</c> if this instance is perfect match; otherwise, <c>false</c>.
/// </value> /// </value>
bool IsPerfectMatch { get; } bool IsPerfectMatch { get; }
/// <summary> /// <summary>
/// Gets the match details. /// Gets the match details.
/// </summary> /// </summary>
IList<MatchDetail> MatchDetails { get; } IList<MatchDetail> MatchDetails { get; }
/// <summary> /// <summary>
/// Gets or sets the total number of matches. /// Gets or sets the total number of matches.
/// </summary> /// </summary>
/// <value> /// <value>
/// The total number of matches. /// The total number of matches.
/// </value> /// </value>
int TotalNumber { get; } int TotalNumber { get; }
/// <summary> /// <summary>
/// Gets or sets the match-score. /// Gets or sets the match-score.
/// </summary> /// </summary>
/// <value> /// <value>
/// The match-score. /// The match-score.
/// </value> /// </value>
double TotalScore { get; } double TotalScore { get; }
/// <summary> /// <summary>
/// Adds the score. /// Adds the score.
/// </summary> /// </summary>
/// <param name="matcherType">The matcher Type.</param> /// <param name="matcherType">The matcher Type.</param>
/// <param name="score">The score.</param> /// <param name="score">The score.</param>
/// <param name="exception">The exception [Optional].</param> /// <returns>The score.</returns>
/// <returns>The score.</returns> double AddScore(Type matcherType, double score);
double AddScore(Type matcherType, double score, Exception? exception); }
} }

View File

@@ -1,25 +1,20 @@
using System; using System;
namespace WireMock.Matchers.Request; namespace WireMock.Matchers.Request
/// <summary>
/// MatchDetail
/// </summary>
public class MatchDetail
{ {
/// <summary> /// <summary>
/// Gets or sets the type of the matcher. /// MatchDetail
/// </summary> /// </summary>
public Type MatcherType { get; set; } = null!; public class MatchDetail
{
/// <summary>
/// Gets or sets the type of the matcher.
/// </summary>
public Type MatcherType { get; set; }
/// <summary> /// <summary>
/// Gets or sets the score between 0.0 and 1.0 /// Gets or sets the score between 0.0 and 1.0
/// </summary> /// </summary>
public double Score { get; set; } public double Score { get; set; }
}
/// <summary>
/// The exception in case the Matcher throws exception.
/// [Optional]
/// </summary>
public Exception? Exception { get; set; }
} }

View File

@@ -30,10 +30,6 @@
<GeneratePackageOnBuild>true</GeneratePackageOnBuild> <GeneratePackageOnBuild>true</GeneratePackageOnBuild>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition=" '$(TargetFramework)' == 'netstandard2.0' or '$(TargetFramework)' == 'netstandard2.1'" >
<DefineConstants>$(DefineConstants);GRAPHQL;MIMEKIT</DefineConstants>
</PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="JetBrains.Annotations" Version="2022.3.1" PrivateAssets="All" /> <PackageReference Include="JetBrains.Annotations" Version="2022.3.1" PrivateAssets="All" />
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.1.1" PrivateAssets="All" /> <PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.1.1" PrivateAssets="All" />

View File

@@ -149,15 +149,15 @@ public class WireMockAssertions
using (new AssertionScope($"header \"{expectedKey}\" from requests sent with value(s)")) using (new AssertionScope($"header \"{expectedKey}\" from requests sent with value(s)"))
{ {
var matchingHeaderValues = _headers.Where(h => h.Key == expectedKey).SelectMany(h => h.Value.ToArray()).ToArray(); var headerValues = _headers.First(h => h.Key == expectedKey).Value;
if (expectedValues.Length == 1) if (expectedValues.Length == 1)
{ {
matchingHeaderValues.Should().Contain(expectedValues.First(), because, becauseArgs); headerValues.Should().Contain(expectedValues.First(), because, becauseArgs);
} }
else else
{ {
var trimmedHeaderValues = string.Join(",", matchingHeaderValues.Select(x => x)).Split(',').Select(x => x.Trim()).ToList(); var trimmedHeaderValues = string.Join(",", headerValues.Select(x => x)).Split(',').Select(x => x.Trim()).ToList();
foreach (var expectedValue in expectedValues) foreach (var expectedValue in expectedValues)
{ {
trimmedHeaderValues.Should().Contain(expectedValue, because, becauseArgs); trimmedHeaderValues.Should().Contain(expectedValue, because, becauseArgs);

View File

@@ -30,9 +30,11 @@ internal class CSharpCodeMatcher : ICSharpCodeMatcher
"Newtonsoft.Json.Linq" "Newtonsoft.Json.Linq"
}; };
/// <inheritdoc />
public MatchBehaviour MatchBehaviour { get; } public MatchBehaviour MatchBehaviour { get; }
/// <inheritdoc cref="IMatcher.ThrowException"/>
public bool ThrowException { get; }
private readonly AnyOf<string, StringPattern>[] _patterns; private readonly AnyOf<string, StringPattern>[] _patterns;
/// <summary> /// <summary>
@@ -53,44 +55,37 @@ internal class CSharpCodeMatcher : ICSharpCodeMatcher
{ {
_patterns = Guard.NotNull(patterns); _patterns = Guard.NotNull(patterns);
MatchBehaviour = matchBehaviour; MatchBehaviour = matchBehaviour;
ThrowException = false;
MatchOperator = matchOperator; MatchOperator = matchOperator;
} }
public MatchResult IsMatch(string? input) public double IsMatch(string? input)
{ {
return IsMatchInternal(input); return IsMatchInternal(input);
} }
public MatchResult IsMatch(object? input) public double IsMatch(object? input)
{ {
return IsMatchInternal(input); return IsMatchInternal(input);
} }
public MatchResult IsMatchInternal(object? input) public double IsMatchInternal(object? input)
{ {
var score = MatchScores.Mismatch; double match = MatchScores.Mismatch;
Exception? exception = null;
if (input != null) if (input != null)
{ {
try match = MatchScores.ToScore(_patterns.Select(pattern => IsMatch(input, pattern.GetPattern())).ToArray(), MatchOperator);
{
score = MatchScores.ToScore(_patterns.Select(pattern => IsMatch(input, pattern.GetPattern())).ToArray(), MatchOperator);
}
catch (Exception ex)
{
exception = ex;
}
} }
return new MatchResult(MatchBehaviourHelper.Convert(MatchBehaviour, score), exception); return MatchBehaviourHelper.Convert(MatchBehaviour, match);
} }
private bool IsMatch(dynamic input, string pattern) private bool IsMatch(dynamic input, string pattern)
{ {
var isMatchWithString = input is string; bool isMatchWithString = input is string;
var inputValue = isMatchWithString ? input : JObject.FromObject(input); var inputValue = isMatchWithString ? input : JObject.FromObject(input);
var source = GetSourceForIsMatchWithString(pattern, isMatchWithString); string source = GetSourceForIsMatchWithString(pattern, isMatchWithString);
object? result; object? result;
@@ -160,7 +155,7 @@ internal class CSharpCodeMatcher : ICSharpCodeMatcher
} }
#elif (NETSTANDARD2_0 || NETSTANDARD2_1 || NETCOREAPP3_1 || NET5_0 || NET6_0 || NET7_0) #elif (NETSTANDARD2_0 || NETSTANDARD2_1 || NETCOREAPP3_1 || NET5_0 || NET6_0 || NET7_0)
Assembly assembly; Assembly assembly;
try try
{ {
assembly = CSScriptLib.CSScript.Evaluator.CompileCode(source); assembly = CSScriptLib.CSScript.Evaluator.CompileCode(source);
@@ -203,10 +198,10 @@ internal class CSharpCodeMatcher : ICSharpCodeMatcher
private string GetSourceForIsMatchWithString(string pattern, bool isMatchWithString) private string GetSourceForIsMatchWithString(string pattern, bool isMatchWithString)
{ {
var template = isMatchWithString ? TemplateForIsMatchWithString : TemplateForIsMatchWithDynamic; string template = isMatchWithString ? TemplateForIsMatchWithString : TemplateForIsMatchWithDynamic;
var stringBuilder = new StringBuilder(); var stringBuilder = new StringBuilder();
foreach (var @using in _usings) foreach (string @using in _usings)
{ {
stringBuilder.AppendLine($"using {@using};"); stringBuilder.AppendLine($"using {@using};");
} }
@@ -216,7 +211,7 @@ internal class CSharpCodeMatcher : ICSharpCodeMatcher
return stringBuilder.ToString(); return stringBuilder.ToString();
} }
/// <inheritdoc /> /// <inheritdoc cref="IStringMatcher.GetPatterns"/>
public AnyOf<string, StringPattern>[] GetPatterns() public AnyOf<string, StringPattern>[] GetPatterns()
{ {
return _patterns; return _patterns;
@@ -225,6 +220,6 @@ internal class CSharpCodeMatcher : ICSharpCodeMatcher
/// <inheritdoc /> /// <inheritdoc />
public MatchOperator MatchOperator { get; } public MatchOperator MatchOperator { get; }
/// <inheritdoc /> /// <inheritdoc cref="IMatcher.Name"/>
public string Name => nameof(CSharpCodeMatcher); public string Name => "CSharpCodeMatcher";
} }

View File

@@ -23,12 +23,14 @@ internal class OpenApiPathsMapper
private const string HeaderContentType = "Content-Type"; private const string HeaderContentType = "Content-Type";
private readonly WireMockOpenApiParserSettings _settings; private readonly WireMockOpenApiParserSettings _settings;
private readonly ExampleValueGenerator _exampleValueGenerator; private readonly IExampleValueGenerator _exampleValueGenerator;
private readonly IExampleValueGenerator _regexExampleValueGenerator;
public OpenApiPathsMapper(WireMockOpenApiParserSettings settings) public OpenApiPathsMapper(WireMockOpenApiParserSettings settings)
{ {
_settings = Guard.NotNull(settings); _settings = Guard.NotNull(settings);
_exampleValueGenerator = new ExampleValueGenerator(settings); _exampleValueGenerator = new ExampleValueGenerator(settings);
_regexExampleValueGenerator = new RegexExampleValueGenerator(settings);
} }
public IReadOnlyList<MappingModel> ToMappingModels(OpenApiPaths? paths, IList<OpenApiServer> servers) public IReadOnlyList<MappingModel> ToMappingModels(OpenApiPaths? paths, IList<OpenApiServer> servers)
@@ -37,18 +39,7 @@ internal class OpenApiPathsMapper
.OrderBy(p => p.Key) .OrderBy(p => p.Key)
.Select(p => MapPath(p.Key, p.Value, servers)) .Select(p => MapPath(p.Key, p.Value, servers))
.SelectMany(x => x) .SelectMany(x => x)
.ToArray() ?? .ToArray() ?? Array.Empty<MappingModel>();
Array.Empty<MappingModel>();
}
private IReadOnlyList<MappingModel> MapPaths(OpenApiPaths? paths, IList<OpenApiServer> servers)
{
return paths?
.OrderBy(p => p.Key)
.Select(p => MapPath(p.Key, p.Value, servers))
.SelectMany(x => x)
.ToArray() ??
Array.Empty<MappingModel>();
} }
private IReadOnlyList<MappingModel> MapPath(string path, OpenApiPathItem pathItem, IList<OpenApiServer> servers) private IReadOnlyList<MappingModel> MapPath(string path, OpenApiPathItem pathItem, IList<OpenApiServer> servers)
@@ -280,54 +271,19 @@ internal class OpenApiPathsMapper
return newPath; return newPath;
} }
private string MapBasePath(IList<OpenApiServer>? servers)
{
if (servers == null || servers.Count == 0)
{
return string.Empty;
}
OpenApiServer server = servers.First();
if (Uri.TryCreate(server.Url, UriKind.RelativeOrAbsolute, out Uri uriResult))
{
return uriResult.IsAbsoluteUri ? uriResult.AbsolutePath : uriResult.ToString();
}
return string.Empty;
}
private JToken? MapOpenApiAnyToJToken(IOpenApiAny? any)
{
if (any == null)
{
return null;
}
using var outputString = new StringWriter();
var writer = new OpenApiJsonWriter(outputString);
any.Write(writer, OpenApiSpecVersion.OpenApi3_0);
if (any.AnyType == AnyType.Array)
{
return JArray.Parse(outputString.ToString());
}
return JObject.Parse(outputString.ToString());
}
private IDictionary<string, object>? MapHeaders(string? responseContentType, IDictionary<string, OpenApiHeader>? headers) private IDictionary<string, object>? MapHeaders(string? responseContentType, IDictionary<string, OpenApiHeader>? headers)
{ {
var mappedHeaders = headers?.ToDictionary( var mappedHeaders = headers?.ToDictionary(
item => item.Key, item => item.Key,
_ => GetExampleMatcherModel(null, _settings.HeaderPatternToUse).Pattern! _ => GetExampleMatcherModel(null, _settings.HeaderPatternToUse).Pattern!
) ?? new Dictionary<string, object>(); );
if (!string.IsNullOrEmpty(responseContentType)) if (!string.IsNullOrEmpty(responseContentType))
{ {
mappedHeaders.TryAdd(HeaderContentType, responseContentType!); mappedHeaders.TryAdd(HeaderContentType, responseContentType!);
} }
return mappedHeaders.Keys.Any() ? mappedHeaders : null; return mappedHeaders?.Keys.Any() == true ? mappedHeaders : null;
} }
private IList<ParamModel>? MapQueryParameters(IEnumerable<OpenApiParameter> queryParameters) private IList<ParamModel>? MapQueryParameters(IEnumerable<OpenApiParameter> queryParameters)
@@ -366,28 +322,38 @@ internal class OpenApiPathsMapper
return list.Any() ? list : null; return list.Any() ? list : null;
} }
private MatcherModel GetExampleMatcherModel(OpenApiSchema? schema, ExampleValueType type) private MatcherModel GetExampleMatcherModel(OpenApiSchema? schema, ExampleValueType exampleValueType)
{ {
return type switch return exampleValueType switch
{ {
ExampleValueType.Value => new MatcherModel ExampleValueType.Value => new MatcherModel
{ {
Name = "ExactMatcher", Name = "ExactMatcher",
Pattern = GetExampleValueAsStringForSchemaType(schema), Pattern = GetExampleValueAsStringForSchemaType(schema, exampleValueType),
IgnoreCase = _settings.IgnoreCaseExampleValues
},
ExampleValueType.Regex => new MatcherModel
{
Name = "RegexMatcher",
Pattern = GetExampleValueAsStringForSchemaType(schema, exampleValueType),
IgnoreCase = _settings.IgnoreCaseExampleValues IgnoreCase = _settings.IgnoreCaseExampleValues
}, },
_ => new MatcherModel _ => new MatcherModel
{ {
Name = "WildcardMatcher", Name = "WildcardMatcher",
Pattern = "*" Pattern = "*",
IgnoreCase = _settings.IgnoreCaseExampleValues
} }
}; };
} }
private string GetExampleValueAsStringForSchemaType(OpenApiSchema? schema) private string GetExampleValueAsStringForSchemaType(OpenApiSchema? schema, ExampleValueType exampleValueType)
{ {
var value = _exampleValueGenerator.GetExampleValue(schema); var value = exampleValueType == ExampleValueType.Regex ?
_regexExampleValueGenerator.GetExampleValue(schema) :
_exampleValueGenerator.GetExampleValue(schema);
return value switch return value switch
{ {
@@ -396,4 +362,39 @@ internal class OpenApiPathsMapper
_ => value.ToString(), _ => value.ToString(),
}; };
} }
private static string MapBasePath(IList<OpenApiServer>? servers)
{
if (servers == null || servers.Count == 0)
{
return string.Empty;
}
var server = servers.First();
if (Uri.TryCreate(server.Url, UriKind.RelativeOrAbsolute, out Uri uriResult))
{
return uriResult.IsAbsoluteUri ? uriResult.AbsolutePath : uriResult.ToString();
}
return string.Empty;
}
private static JToken? MapOpenApiAnyToJToken(IOpenApiAny? any)
{
if (any == null)
{
return null;
}
using var outputString = new StringWriter();
var writer = new OpenApiJsonWriter(outputString);
any.Write(writer, OpenApiSpecVersion.OpenApi3_0);
if (any.AnyType == AnyType.Array)
{
return JArray.Parse(outputString.ToString());
}
return JObject.Parse(outputString.ToString());
}
} }

View File

@@ -1,7 +1,7 @@
namespace WireMock.Net.OpenApiParser.Types; namespace WireMock.Net.OpenApiParser.Types;
/// <summary> /// <summary>
/// The example value to use /// The (example) value pattern to use.
/// </summary> /// </summary>
public enum ExampleValueType public enum ExampleValueType
{ {
@@ -12,6 +12,11 @@ public enum ExampleValueType
/// </summary> /// </summary>
Value, Value,
/// <summary>
/// Build a Regex based on the SchemaType.
/// </summary>
Regex,
/// <summary> /// <summary>
/// Just use a Wildcard (*) character. /// Just use a Wildcard (*) character.
/// </summary> /// </summary>

View File

@@ -8,7 +8,7 @@ using WireMock.Net.OpenApiParser.Types;
namespace WireMock.Net.OpenApiParser.Utils; namespace WireMock.Net.OpenApiParser.Utils;
internal class ExampleValueGenerator internal class ExampleValueGenerator : IExampleValueGenerator
{ {
private readonly IWireMockOpenApiParserExampleValues _exampleValues; private readonly IWireMockOpenApiParserExampleValues _exampleValues;

View File

@@ -0,0 +1,8 @@
using Microsoft.OpenApi.Models;
namespace WireMock.Net.OpenApiParser.Utils;
internal interface IExampleValueGenerator
{
object GetExampleValue(OpenApiSchema? schema);
}

View File

@@ -0,0 +1,40 @@
using Microsoft.OpenApi.Models;
using Stef.Validation;
using WireMock.Net.OpenApiParser.Extensions;
using WireMock.Net.OpenApiParser.Settings;
using WireMock.Net.OpenApiParser.Types;
namespace WireMock.Net.OpenApiParser.Utils;
internal class RegexExampleValueGenerator : IExampleValueGenerator
{
public RegexExampleValueGenerator(WireMockOpenApiParserSettings settings)
{
Guard.NotNull(settings);
}
public object GetExampleValue(OpenApiSchema? schema)
{
switch (schema?.GetSchemaType())
{
case SchemaType.Boolean:
return @"(true|false)";
case SchemaType.Integer:
return @"-?\d+";
case SchemaType.Number:
return @"[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?";
default:
return schema?.GetSchemaFormat() switch
{
SchemaFormat.Date => @"(\d{4})-([01]\d)-([0-3]\d)",
SchemaFormat.DateTime => @"(\d{4})-([01]\d)-([0-3]\d)T([0-2]\d):([0-5]\d):([0-5]\d)(\.\d+)?(Z|[+-][0-2]\d:[0-5]\d)",
SchemaFormat.Byte => @"(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)",
SchemaFormat.Binary => @"[a-zA-Z0-9\+/]*={0,3}",
_ => ".*"
};
}
}
}

View File

@@ -20,7 +20,7 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" /> <PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
<PackageReference Include="Microsoft.OpenApi.Readers" Version="1.2.3" /> <PackageReference Include="Microsoft.OpenApi.Readers" Version="1.2.3" />
<PackageReference Include="Nullable" Version="1.3.1"> <PackageReference Include="Nullable" Version="1.3.1">
<PrivateAssets>all</PrivateAssets> <PrivateAssets>all</PrivateAssets>

View File

@@ -9,6 +9,7 @@ using RamlToOpenApiConverter;
using WireMock.Admin.Mappings; using WireMock.Admin.Mappings;
using WireMock.Net.OpenApiParser.Mappers; using WireMock.Net.OpenApiParser.Mappers;
using WireMock.Net.OpenApiParser.Settings; using WireMock.Net.OpenApiParser.Settings;
using WireMock.Net.OpenApiParser.Types;
namespace WireMock.Net.OpenApiParser; namespace WireMock.Net.OpenApiParser;
@@ -17,13 +18,20 @@ namespace WireMock.Net.OpenApiParser;
/// </summary> /// </summary>
public class WireMockOpenApiParser : IWireMockOpenApiParser public class WireMockOpenApiParser : IWireMockOpenApiParser
{ {
private readonly WireMockOpenApiParserSettings _wireMockOpenApiParserSettings = new WireMockOpenApiParserSettings
{
HeaderPatternToUse = ExampleValueType.Regex,
QueryParameterPatternToUse = ExampleValueType.Regex,
PathPatternToUse = ExampleValueType.Regex
};
private readonly OpenApiStreamReader _reader = new(); private readonly OpenApiStreamReader _reader = new();
/// <inheritdoc /> /// <inheritdoc />
[PublicAPI] [PublicAPI]
public IReadOnlyList<MappingModel> FromFile(string path, out OpenApiDiagnostic diagnostic) public IReadOnlyList<MappingModel> FromFile(string path, out OpenApiDiagnostic diagnostic)
{ {
return FromFile(path, new WireMockOpenApiParserSettings(), out diagnostic); return FromFile(path, _wireMockOpenApiParserSettings, out diagnostic);
} }
/// <inheritdoc /> /// <inheritdoc />
@@ -47,9 +55,9 @@ public class WireMockOpenApiParser : IWireMockOpenApiParser
/// <inheritdoc /> /// <inheritdoc />
[PublicAPI] [PublicAPI]
public IReadOnlyList<MappingModel> FromDocument(OpenApiDocument document, WireMockOpenApiParserSettings? settings = null) public IReadOnlyList<MappingModel> FromDocument(OpenApiDocument openApiDocument, WireMockOpenApiParserSettings? settings = null)
{ {
return new OpenApiPathsMapper(settings ?? new WireMockOpenApiParserSettings()).ToMappingModels(document.Paths, document.Servers); return new OpenApiPathsMapper(settings ?? _wireMockOpenApiParserSettings).ToMappingModels(openApiDocument.Paths, openApiDocument.Servers);
} }
/// <inheritdoc /> /// <inheritdoc />

View File

@@ -1,4 +1,3 @@
using System;
using System.Diagnostics.CodeAnalysis; using System.Diagnostics.CodeAnalysis;
using System.Linq; using System.Linq;
using System.Reflection; using System.Reflection;
@@ -25,7 +24,7 @@ public static class StandAloneApp
[PublicAPI] [PublicAPI]
public static WireMockServer Start(WireMockServerSettings settings) public static WireMockServer Start(WireMockServerSettings settings)
{ {
Guard.NotNull(settings); Guard.NotNull(settings, nameof(settings));
var server = WireMockServer.Start(settings); var server = WireMockServer.Start(settings);
@@ -43,7 +42,7 @@ public static class StandAloneApp
[PublicAPI] [PublicAPI]
public static WireMockServer Start(string[] args, IWireMockLogger? logger = null) public static WireMockServer Start(string[] args, IWireMockLogger? logger = null)
{ {
Guard.NotNull(args); Guard.NotNull(args, nameof(args));
if (TryStart(args, out var server, logger)) if (TryStart(args, out var server, logger))
{ {
@@ -62,9 +61,9 @@ public static class StandAloneApp
[PublicAPI] [PublicAPI]
public static bool TryStart(string[] args, [NotNullWhen(true)] out WireMockServer? server, IWireMockLogger? logger = null) public static bool TryStart(string[] args, [NotNullWhen(true)] out WireMockServer? server, IWireMockLogger? logger = null)
{ {
Guard.NotNull(args); Guard.NotNull(args, nameof(args));
if (WireMockServerSettingsParser.TryParseArguments(args, Environment.GetEnvironmentVariables(), out var settings, logger)) if (WireMockServerSettingsParser.TryParseArguments(args, out var settings, logger))
{ {
settings.Logger?.Info("Version [{0}]", Version); settings.Logger?.Info("Version [{0}]", Version);
settings.Logger?.Debug("Server arguments [{0}]", string.Join(", ", args.Select(a => $"'{a}'"))); settings.Logger?.Debug("Server arguments [{0}]", string.Join(", ", args.Select(a => $"'{a}'")));

View File

@@ -1,7 +0,0 @@
namespace WireMock.Net.Testcontainers.Models;
internal record ContainerInfo
(
string Image,
string MappingsPath
);

View File

@@ -1,43 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<Description>A fluent testcontainer builder for the Docker version of WireMock.Net</Description>
<TargetFrameworks>netstandard2.0;netstandard2.1</TargetFrameworks>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<PackageTags>wiremock;docker;testcontainer;testcontainers</PackageTags>
<ProjectGuid>{12B016A5-9D8B-4EFE-96C2-CA51BE43367D}</ProjectGuid>
<PublishRepositoryUrl>true</PublishRepositoryUrl>
<CodeAnalysisRuleSet>../WireMock.Net/WireMock.Net.ruleset</CodeAnalysisRuleSet>
<SignAssembly>true</SignAssembly>
<AssemblyOriginatorKeyFile>../WireMock.Net/WireMock.Net.snk</AssemblyOriginatorKeyFile>
<PublicSign Condition=" '$(OS)' != 'Windows_NT' ">true</PublicSign>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
<LangVersion>10</LangVersion>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)' == 'Release'">
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
</PropertyGroup>
<ItemGroup>
<Compile Include="..\WireMock.Net\Http\HttpClientFactory2.cs" Link="Http\HttpClientFactory2.cs" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="IsExternalInit" Version="1.0.3">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Stef.Validation" Version="0.1.1" />
<PackageReference Include="Testcontainers" Version="3.2.0" />
<PackageReference Include="JetBrains.Annotations" VersionOverride="2022.3.1" PrivateAssets="All" Version="2022.3.1" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\WireMock.Net.RestClient\WireMock.Net.RestClient.csproj" />
</ItemGroup>
<ItemGroup>
<Folder Include="Http\" />
</ItemGroup>
</Project>

View File

@@ -1,66 +0,0 @@
using Docker.DotNet.Models;
using DotNet.Testcontainers.Builders;
using DotNet.Testcontainers.Configurations;
using JetBrains.Annotations;
namespace WireMock.Net.Testcontainers;
/// <inheritdoc cref="ContainerConfiguration" />
[PublicAPI]
public sealed class WireMockConfiguration : ContainerConfiguration
{
#pragma warning disable CS1591
public string? Username { get; }
public string? Password { get; }
public bool HasBasicAuthentication => !string.IsNullOrEmpty(Username) && !string.IsNullOrEmpty(Password);
public WireMockConfiguration(
string? username = null,
string? password = null
)
{
Username = username;
Password = password;
}
#pragma warning restore CS1591
/// <summary>
/// Initializes a new instance of the <see cref="WireMockConfiguration" /> class.
/// </summary>
/// <param name="resourceConfiguration">The Docker resource configuration.</param>
public WireMockConfiguration(IResourceConfiguration<CreateContainerParameters> resourceConfiguration) : base(resourceConfiguration)
{
// Passes the configuration upwards to the base implementations to create an updated immutable copy.
}
/// <summary>
/// Initializes a new instance of the <see cref="WireMockConfiguration" /> class.
/// </summary>
/// <param name="resourceConfiguration">The Docker resource configuration.</param>
public WireMockConfiguration(IContainerConfiguration resourceConfiguration) : base(resourceConfiguration)
{
// Passes the configuration upwards to the base implementations to create an updated immutable copy.
}
/// <summary>
/// Initializes a new instance of the <see cref="WireMockConfiguration" /> class.
/// </summary>
/// <param name="resourceConfiguration">The Docker resource configuration.</param>
public WireMockConfiguration(WireMockConfiguration resourceConfiguration) : this(new WireMockConfiguration(), resourceConfiguration)
{
// Passes the configuration upwards to the base implementations to create an updated immutable copy.
}
/// <summary>
/// Initializes a new instance of the <see cref="WireMockConfiguration" /> class.
/// </summary>
/// <param name="oldValue">The old Docker resource configuration.</param>
/// <param name="newValue">The new Docker resource configuration.</param>
public WireMockConfiguration(WireMockConfiguration oldValue, WireMockConfiguration newValue) : base(oldValue, newValue)
{
Username = BuildConfiguration.Combine(oldValue.Username, newValue.Username);
Password = BuildConfiguration.Combine(oldValue.Password, newValue.Password);
}
}

View File

@@ -1,111 +0,0 @@
using System;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using DotNet.Testcontainers.Containers;
using JetBrains.Annotations;
using Microsoft.Extensions.Logging;
using RestEase;
using Stef.Validation;
using WireMock.Client;
using WireMock.Http;
namespace WireMock.Net.Testcontainers;
/// <summary>
/// A container for running WireMock in a docker environment.
/// </summary>
public sealed class WireMockContainer : DockerContainer
{
internal const int ContainerPort = 80;
private readonly WireMockConfiguration _configuration;
/// <summary>
/// Initializes a new instance of the <see cref="WireMockContainer" /> class.
/// </summary>
/// <param name="configuration">The container configuration.</param>
/// <param name="logger">The logger.</param>
public WireMockContainer(WireMockConfiguration configuration, ILogger logger) : base(configuration, logger)
{
_configuration = Guard.NotNull(configuration);
}
/// <summary>
/// Gets the public Url.
/// </summary>
[PublicAPI]
public string GetPublicUrl() => GetPublicUri().ToString();
/// <summary>
/// Create a RestEase Admin client which can be used to call the admin REST endpoint.
/// </summary>
/// <returns>A <see cref="IWireMockAdminApi"/></returns>
[PublicAPI]
public IWireMockAdminApi CreateWireMockAdminClient()
{
ValidateIfRunning();
var api = RestClient.For<IWireMockAdminApi>(GetPublicUri());
if (_configuration.HasBasicAuthentication)
{
api.Authorization = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(Encoding.ASCII.GetBytes($"{_configuration.Username}:{_configuration.Password}")));
}
return api;
}
/// <summary>
/// Create a <see cref="HttpClient"/> which can be used to call this instance.
/// <param name="handlers">
/// An ordered list of System.Net.Http.DelegatingHandler instances to be invoked
/// as an System.Net.Http.HttpRequestMessage travels from the System.Net.Http.HttpClient
/// to the network and an System.Net.Http.HttpResponseMessage travels from the network
/// back to System.Net.Http.HttpClient. The handlers are invoked in a top-down fashion.
/// That is, the first entry is invoked first for an outbound request message but
/// last for an inbound response message.
/// </param>
/// </summary>
[PublicAPI]
public HttpClient CreateClient(params DelegatingHandler[] handlers)
{
ValidateIfRunning();
var client = HttpClientFactory2.Create(handlers);
client.BaseAddress = GetPublicUri();
return client;
}
/// <summary>
/// Create a <see cref="HttpClient"/> (one for each URL) which can be used to call this instance.
/// <param name="innerHandler">The inner handler represents the destination of the HTTP message channel.</param>
/// <param name="handlers">
/// An ordered list of System.Net.Http.DelegatingHandler instances to be invoked
/// as an System.Net.Http.HttpRequestMessage travels from the System.Net.Http.HttpClient
/// to the network and an System.Net.Http.HttpResponseMessage travels from the network
/// back to System.Net.Http.HttpClient. The handlers are invoked in a top-down fashion.
/// That is, the first entry is invoked first for an outbound request message but
/// last for an inbound response message.
/// </param>
/// </summary>
[PublicAPI]
public HttpClient CreateClient(HttpMessageHandler innerHandler, params DelegatingHandler[] handlers)
{
ValidateIfRunning();
var client = HttpClientFactory2.Create(innerHandler, handlers);
client.BaseAddress = GetPublicUri();
return client;
}
private void ValidateIfRunning()
{
if (State != TestcontainersStates.Running)
{
throw new InvalidOperationException("Unable to create HttpClient because the WireMock.Net is not yet running.");
}
}
private Uri GetPublicUri() => new UriBuilder(Uri.UriSchemeHttp, Hostname, GetMappedPublicPort(ContainerPort)).Uri;
}

View File

@@ -1,175 +0,0 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Docker.DotNet.Models;
using DotNet.Testcontainers.Builders;
using DotNet.Testcontainers.Configurations;
using JetBrains.Annotations;
using Stef.Validation;
using WireMock.Net.Testcontainers.Models;
namespace WireMock.Net.Testcontainers;
/// <summary>
/// An specific fluent Docker container builder for WireMock.Net
/// </summary>
public sealed class WireMockContainerBuilder : ContainerBuilder<WireMockContainerBuilder, WireMockContainer, WireMockConfiguration>
{
private readonly Dictionary<bool, ContainerInfo> _info = new()
{
{ false, new ContainerInfo("sheyenrath/wiremock.net:latest", "/app/__admin/mappings") },
{ true, new ContainerInfo("sheyenrath/wiremock.net-windows:latest", @"c:\app\__admin\mappings") }
};
private const string DefaultLogger = "WireMockConsoleLogger";
private readonly Lazy<Task<bool>> _isWindowsAsLazy = new(async () =>
{
using var dockerClientConfig = TestcontainersSettings.OS.DockerEndpointAuthConfig.GetDockerClientConfiguration();
using var dockerClient = dockerClientConfig.CreateClient();
var version = await dockerClient.System.GetVersionAsync();
return version.Os.IndexOf("Windows", StringComparison.OrdinalIgnoreCase) > -1;
});
/// <summary>
/// Initializes a new instance of the <see cref="ContainerBuilder" /> class.
/// </summary>
public WireMockContainerBuilder() : this(new WireMockConfiguration())
{
DockerResourceConfiguration = Init().DockerResourceConfiguration;
}
/// <summary>
/// Automatically set the correct image (Linux or Windows) for WireMock which to create the container.
/// </summary>
/// <returns>A configured instance of <see cref="WireMockContainerBuilder"/></returns>
[PublicAPI]
public WireMockContainerBuilder WithImage()
{
var isWindows = _isWindowsAsLazy.Value.GetAwaiter().GetResult();
return WithImage(_info[isWindows].Image);
}
/// <summary>
/// Set the admin username and password for the container (basic authentication).
/// </summary>
/// <param name="username">The admin username.</param>
/// <param name="password">The admin password.</param>
/// <returns>A configured instance of <see cref="WireMockContainerBuilder"/></returns>
public WireMockContainerBuilder WithAdminUserNameAndPassword(string username, string password)
{
Guard.NotNull(username);
Guard.NotNull(password);
if (string.IsNullOrEmpty(username) && string.IsNullOrEmpty(password))
{
return this;
}
return Merge(DockerResourceConfiguration, new WireMockConfiguration(username, password))
.WithCommand($"--AdminUserName {username}", $"--AdminPassword {password}");
}
/// <summary>
/// Use the WireMockNullLogger.
/// </summary>
/// <returns>A configured instance of <see cref="WireMockContainerBuilder"/></returns>
[PublicAPI]
public WireMockContainerBuilder WithNullLogger()
{
return WithCommand("--WireMockLogger WireMockNullLogger");
}
/// <summary>
/// Defines if the static mappings should be read at startup (default set to false).
/// </summary>
/// <returns>A configured instance of <see cref="WireMockContainerBuilder"/></returns>
[PublicAPI]
public WireMockContainerBuilder WithReadStaticMappings()
{
return WithCommand("--ReadStaticMappings true");
}
/// <summary>
/// Watch the static mapping files + folder for changes when running.
/// </summary>
/// <returns>A configured instance of <see cref="WireMockContainerBuilder"/></returns>
[PublicAPI]
public WireMockContainerBuilder WithWatchStaticMappings(bool includeSubDirectories)
{
return WithCommand("--WatchStaticMappings true").WithCommand($"--WatchStaticMappingsInSubdirectories {includeSubDirectories}");
}
/// <summary>
/// Specifies the path for the (static) mapping json files.
/// </summary>
/// <param name="path">The path</param>
/// <returns></returns>
[PublicAPI]
public WireMockContainerBuilder WithMappings(string path)
{
Guard.NotNullOrEmpty(path);
var isWindows = _isWindowsAsLazy.Value.GetAwaiter().GetResult();
return WithReadStaticMappings().WithBindMount(path, _info[isWindows].MappingsPath);
}
/// <summary>
/// Initializes a new instance of the <see cref="WireMockContainerBuilder" /> class.
/// </summary>
/// <param name="dockerResourceConfiguration">The Docker resource configuration.</param>
private WireMockContainerBuilder(WireMockConfiguration dockerResourceConfiguration) : base(dockerResourceConfiguration)
{
DockerResourceConfiguration = dockerResourceConfiguration;
}
/// <inheritdoc />
protected override WireMockConfiguration DockerResourceConfiguration { get; }
/// <inheritdoc />
public override WireMockContainer Build()
{
Validate();
return new WireMockContainer(DockerResourceConfiguration, TestcontainersSettings.Logger);
}
/// <inheritdoc />
protected override WireMockContainerBuilder Init()
{
var builder = base.Init();
// In case no image has been set, set the image using internal logic.
if (builder.DockerResourceConfiguration.Image == null)
{
builder = builder.WithImage();
}
var isWindows = _isWindowsAsLazy.Value.GetAwaiter().GetResult();
var waitForContainerOS = isWindows ? Wait.ForWindowsContainer() : Wait.ForUnixContainer();
return builder
.WithPortBinding(WireMockContainer.ContainerPort, true)
.WithCommand($"--WireMockLogger {DefaultLogger}")
.WithWaitStrategy(waitForContainerOS.UntilMessageIsLogged("By Stef Heyenrath"));
}
/// <inheritdoc />
protected override WireMockContainerBuilder Clone(IContainerConfiguration resourceConfiguration)
{
return Merge(DockerResourceConfiguration, new WireMockConfiguration(resourceConfiguration));
}
/// <inheritdoc />
protected override WireMockContainerBuilder Clone(IResourceConfiguration<CreateContainerParameters> resourceConfiguration)
{
return Merge(DockerResourceConfiguration, new WireMockConfiguration(resourceConfiguration));
}
/// <inheritdoc />
protected override WireMockContainerBuilder Merge(WireMockConfiguration oldValue, WireMockConfiguration newValue)
{
return new WireMockContainerBuilder(new WireMockConfiguration(oldValue, newValue));
}
}

View File

@@ -26,7 +26,7 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.1.1" PrivateAssets="All" /> <PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.1.1" PrivateAssets="All" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" /> <PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
<PackageReference Include="Stef.Validation" Version="0.1.1" /> <PackageReference Include="Stef.Validation" Version="0.1.1" />
<PackageReference Include="xUnit.abstractions" Version="2.0.3" /> <PackageReference Include="xUnit.abstractions" Version="2.0.3" />
</ItemGroup> </ItemGroup>

View File

@@ -34,6 +34,8 @@ internal class AzureADAuthenticationMatcher : IStringMatcher
public MatchBehaviour MatchBehaviour => MatchBehaviour.AcceptOnMatch; public MatchBehaviour MatchBehaviour => MatchBehaviour.AcceptOnMatch;
public bool ThrowException => false;
public AnyOf<string, StringPattern>[] GetPatterns() public AnyOf<string, StringPattern>[] GetPatterns()
{ {
return EmptyArray<AnyOf<string, StringPattern>>.Value; return EmptyArray<AnyOf<string, StringPattern>>.Value;
@@ -41,7 +43,7 @@ internal class AzureADAuthenticationMatcher : IStringMatcher
public MatchOperator MatchOperator { get; } = MatchOperator.Or; public MatchOperator MatchOperator { get; } = MatchOperator.Or;
public MatchResult IsMatch(string? input) public double IsMatch(string? input)
{ {
if (string.IsNullOrEmpty(input)) if (string.IsNullOrEmpty(input))
{ {
@@ -68,9 +70,9 @@ internal class AzureADAuthenticationMatcher : IStringMatcher
return MatchScores.Perfect; return MatchScores.Perfect;
} }
catch (Exception ex) catch
{ {
return new MatchResult(MatchScores.Mismatch, ex); return MatchScores.Mismatch;
} }
} }
} }

View File

@@ -8,6 +8,4 @@ internal static class WireMockConstants
public const string ContentTypeJson = "application/json"; public const string ContentTypeJson = "application/json";
public const string ContentTypeTextPlain = "text/plain"; public const string ContentTypeTextPlain = "text/plain";
public const string NoMatchingFound = "No matching mapping found";
} }

View File

@@ -1,29 +0,0 @@
using System.Collections;
using System.Diagnostics.CodeAnalysis;
using Stef.Validation;
namespace WireMock.Extensions;
internal static class DictionaryExtensions
{
public static bool TryGetStringValue(this IDictionary dictionary, string key, [NotNullWhen(true)] out string? value)
{
Guard.NotNull(dictionary);
if (dictionary[key] is string valueIsString)
{
value = valueIsString;
return true;
}
var valueToString = dictionary[key]?.ToString();
if (valueToString != null)
{
value = valueToString;
return true;
}
value = default;
return false;
}
}

View File

@@ -1,16 +0,0 @@
using System;
namespace WireMock.Extensions;
internal static class ExceptionExtensions
{
public static Exception? ToException(this Exception[] exceptions)
{
return exceptions.Length switch
{
1 => exceptions[0],
> 1 => new AggregateException(exceptions),
_ => null
};
}
}

View File

@@ -82,7 +82,7 @@ public class LocalFileSystemHandler : IFileSystemHandler
public virtual byte[] ReadResponseBodyAsFile(string path) public virtual byte[] ReadResponseBodyAsFile(string path)
{ {
Guard.NotNullOrEmpty(path); Guard.NotNullOrEmpty(path);
path = PathUtils.CleanPath(path)!; path = PathUtils.CleanPath(path);
// If the file exists at the given path relative to the MappingsFolder, then return that. // If the file exists at the given path relative to the MappingsFolder, then return that.
// Else the path will just be as-is. // Else the path will just be as-is.
return File.ReadAllBytes(File.Exists(PathUtils.Combine(GetMappingFolder(), path)) ? PathUtils.Combine(GetMappingFolder(), path) : path); return File.ReadAllBytes(File.Exists(PathUtils.Combine(GetMappingFolder(), path)) ? PathUtils.Combine(GetMappingFolder(), path) : path);
@@ -92,7 +92,7 @@ public class LocalFileSystemHandler : IFileSystemHandler
public virtual string ReadResponseBodyAsString(string path) public virtual string ReadResponseBodyAsString(string path)
{ {
Guard.NotNullOrEmpty(path); Guard.NotNullOrEmpty(path);
path = PathUtils.CleanPath(path)!; path = PathUtils.CleanPath(path);
// In case the path is a filename, the path will be adjusted to the MappingFolder. // In case the path is a filename, the path will be adjusted to the MappingFolder.
// Else the path will just be as-is. // Else the path will just be as-is.
return File.ReadAllText(File.Exists(PathUtils.Combine(GetMappingFolder(), path)) ? PathUtils.Combine(GetMappingFolder(), path) : path); return File.ReadAllText(File.Exists(PathUtils.Combine(GetMappingFolder(), path)) ? PathUtils.Combine(GetMappingFolder(), path) : path);

View File

@@ -1,4 +1,3 @@
using System.Linq;
using System.Net.Http; using System.Net.Http;
namespace WireMock.Http; namespace WireMock.Http;
@@ -7,31 +6,19 @@ internal static class HttpClientFactory2
{ {
public static HttpClient Create(params DelegatingHandler[] handlers) public static HttpClient Create(params DelegatingHandler[] handlers)
{ {
var handler = CreateHandlerPipeline(new HttpClientHandler(), handlers); #if NETSTANDARD1_3
return new HttpClient(handler); return new HttpClient();
#else
return HttpClientFactory.Create(handlers);
#endif
} }
public static HttpClient Create(HttpMessageHandler innerHandler, params DelegatingHandler[] handlers) public static HttpClient Create(HttpMessageHandler innerHandler, params DelegatingHandler[] handlers)
{ {
var handler = CreateHandlerPipeline(innerHandler, handlers); #if NETSTANDARD1_3
return new HttpClient(handler); return new HttpClient(innerHandler);
} #else
return HttpClientFactory.Create(innerHandler, handlers);
private static HttpMessageHandler CreateHandlerPipeline(HttpMessageHandler handler, params DelegatingHandler[] delegatingHandlers) #endif
{
if (delegatingHandlers.Length == 0)
{
return handler;
}
var next = handler;
foreach (var delegatingHandler in delegatingHandlers.Reverse())
{
delegatingHandler.InnerHandler = next;
next = delegatingHandler;
}
return next;
} }
} }

View File

@@ -5,18 +5,12 @@ using System.Net.Http;
using System.Net.Http.Headers; using System.Net.Http.Headers;
using Newtonsoft.Json; using Newtonsoft.Json;
using Stef.Validation; using Stef.Validation;
using WireMock.Constants;
using WireMock.Types; using WireMock.Types;
namespace WireMock.Http; namespace WireMock.Http;
internal static class HttpRequestMessageHelper internal static class HttpRequestMessageHelper
{ {
private static readonly IDictionary<string, bool> ContentLengthHeaderAllowed = new Dictionary<string, bool>(StringComparer.OrdinalIgnoreCase)
{
{ HttpRequestMethod.HEAD, true }
};
internal static HttpRequestMessage Create(IRequestMessage requestMessage, string url) internal static HttpRequestMessage Create(IRequestMessage requestMessage, string url)
{ {
Guard.NotNull(requestMessage); Guard.NotNull(requestMessage);
@@ -31,14 +25,21 @@ internal static class HttpRequestMessageHelper
MediaTypeHeaderValue.TryParse(value, out contentType); MediaTypeHeaderValue.TryParse(value, out contentType);
} }
httpRequestMessage.Content = requestMessage.BodyData?.DetectedBodyType switch switch (requestMessage.BodyData?.DetectedBodyType)
{ {
BodyType.Bytes => ByteArrayContentHelper.Create(requestMessage.BodyData.BodyAsBytes!, contentType), case BodyType.Bytes:
BodyType.Json => StringContentHelper.Create(JsonConvert.SerializeObject(requestMessage.BodyData.BodyAsJson), contentType), httpRequestMessage.Content = ByteArrayContentHelper.Create(requestMessage.BodyData.BodyAsBytes!, contentType);
BodyType.String => StringContentHelper.Create(requestMessage.BodyData.BodyAsString!, contentType), break;
BodyType.FormUrlEncoded => StringContentHelper.Create(requestMessage.BodyData.BodyAsString!, contentType),
_ => httpRequestMessage.Content case BodyType.Json:
}; httpRequestMessage.Content = StringContentHelper.Create(JsonConvert.SerializeObject(requestMessage.BodyData.BodyAsJson), contentType);
break;
case BodyType.String:
case BodyType.FormUrlEncoded:
httpRequestMessage.Content = StringContentHelper.Create(requestMessage.BodyData.BodyAsString!, contentType);
break;
}
// Overwrite the host header // Overwrite the host header
httpRequestMessage.Headers.Host = new Uri(url).Authority; httpRequestMessage.Headers.Host = new Uri(url).Authority;
@@ -49,19 +50,7 @@ internal static class HttpRequestMessageHelper
return httpRequestMessage; return httpRequestMessage;
} }
var excludeHeaders = new List<string> { HttpKnownHeaderNames.Host }; var excludeHeaders = new List<string> { HttpKnownHeaderNames.Host, HttpKnownHeaderNames.ContentLength };
var contentLengthHeaderAllowed = ContentLengthHeaderAllowed.TryGetValue(requestMessage.Method, out var allowed) && allowed;
if (contentLengthHeaderAllowed)
{
// Set Content to empty ByteArray to be able to set the Content-Length on the content in case of a HEAD method.
httpRequestMessage.Content ??= new ByteArrayContent(EmptyArray<byte>.Value);
}
else
{
excludeHeaders.Add(HttpKnownHeaderNames.ContentLength);
}
if (contentType != null) if (contentType != null)
{ {
// Content-Type should be set on the content // Content-Type should be set on the content

View File

@@ -139,13 +139,13 @@ public class Mapping : IMapping
Probability = probability; Probability = probability;
} }
/// <inheritdoc /> /// <inheritdoc cref="IMapping.ProvideResponseAsync" />
public Task<(IResponseMessage Message, IMapping? Mapping)> ProvideResponseAsync(IRequestMessage requestMessage) public Task<(IResponseMessage Message, IMapping? Mapping)> ProvideResponseAsync(IRequestMessage requestMessage)
{ {
return Provider.ProvideResponseAsync(this, requestMessage, Settings); return Provider.ProvideResponseAsync(this, requestMessage, Settings);
} }
/// <inheritdoc /> /// <inheritdoc cref="IMapping.GetRequestMatchResult" />
public IRequestMatchResult GetRequestMatchResult(IRequestMessage requestMessage, string? nextState) public IRequestMatchResult GetRequestMatchResult(IRequestMessage requestMessage, string? nextState)
{ {
var result = new RequestMatchResult(); var result = new RequestMatchResult();

View File

@@ -20,8 +20,10 @@ public abstract class AbstractJsonPartialMatcher : JsonMatcher
/// </summary> /// </summary>
/// <param name="value">The string value to check for equality.</param> /// <param name="value">The string value to check for equality.</param>
/// <param name="ignoreCase">Ignore the case from the PropertyName and PropertyValue (string only).</param> /// <param name="ignoreCase">Ignore the case from the PropertyName and PropertyValue (string only).</param>
/// <param name="throwException">Throw an exception when the internal matching fails because of invalid input.</param>
/// <param name="regex">Support Regex.</param> /// <param name="regex">Support Regex.</param>
protected AbstractJsonPartialMatcher(string value, bool ignoreCase = false, bool regex = false) : base(value, ignoreCase) protected AbstractJsonPartialMatcher(string value, bool ignoreCase = false, bool throwException = false, bool regex = false)
: base(value, ignoreCase, throwException)
{ {
Regex = regex; Regex = regex;
} }
@@ -31,8 +33,10 @@ public abstract class AbstractJsonPartialMatcher : JsonMatcher
/// </summary> /// </summary>
/// <param name="value">The object value to check for equality.</param> /// <param name="value">The object value to check for equality.</param>
/// <param name="ignoreCase">Ignore the case from the PropertyName and PropertyValue (string only).</param> /// <param name="ignoreCase">Ignore the case from the PropertyName and PropertyValue (string only).</param>
/// <param name="throwException">Throw an exception when the internal matching fails because of invalid input.</param>
/// <param name="regex">Support Regex.</param> /// <param name="regex">Support Regex.</param>
protected AbstractJsonPartialMatcher(object value, bool ignoreCase = false, bool regex = false) : base(value, ignoreCase) protected AbstractJsonPartialMatcher(object value, bool ignoreCase = false, bool throwException = false, bool regex = false)
: base(value, ignoreCase, throwException)
{ {
Regex = regex; Regex = regex;
} }
@@ -43,8 +47,10 @@ public abstract class AbstractJsonPartialMatcher : JsonMatcher
/// <param name="matchBehaviour">The match behaviour.</param> /// <param name="matchBehaviour">The match behaviour.</param>
/// <param name="value">The value to check for equality.</param> /// <param name="value">The value to check for equality.</param>
/// <param name="ignoreCase">Ignore the case from the PropertyName and PropertyValue (string only).</param> /// <param name="ignoreCase">Ignore the case from the PropertyName and PropertyValue (string only).</param>
/// <param name="throwException">Throw an exception when the internal matching fails because of invalid input.</param>
/// <param name="regex">Support Regex.</param> /// <param name="regex">Support Regex.</param>
protected AbstractJsonPartialMatcher(MatchBehaviour matchBehaviour, object value, bool ignoreCase = false, bool regex = false) : base(matchBehaviour, value, ignoreCase) protected AbstractJsonPartialMatcher(MatchBehaviour matchBehaviour, object value, bool ignoreCase = false, bool throwException = false, bool regex = false)
: base(matchBehaviour, value, ignoreCase, throwException)
{ {
Regex = regex; Regex = regex;
} }
@@ -60,7 +66,7 @@ public abstract class AbstractJsonPartialMatcher : JsonMatcher
if (Regex && value.Type == JTokenType.String && input != null) if (Regex && value.Type == JTokenType.String && input != null)
{ {
var valueAsString = value.ToString(); var valueAsString = value.ToString();
var (valid, result) = RegexUtils.MatchRegex(valueAsString, input.ToString()); var (valid, result) = RegexUtils.MatchRegex(valueAsString, input.ToString());
if (valid) if (valid)
{ {
@@ -68,13 +74,6 @@ public abstract class AbstractJsonPartialMatcher : JsonMatcher
} }
} }
if (input != null &&
((value.Type == JTokenType.Guid && input.Type == JTokenType.String) ||
(value.Type == JTokenType.String && input.Type == JTokenType.Guid)))
{
return IsMatch(value.ToString(), input.ToString());
}
if (input == null || value.Type != input.Type) if (input == null || value.Type != input.Type)
{ {
return false; return false;

View File

@@ -46,13 +46,15 @@ public class ContentTypeMatcher : WildcardMatcher
/// <param name="matchBehaviour">The match behaviour.</param> /// <param name="matchBehaviour">The match behaviour.</param>
/// <param name="patterns">The patterns.</param> /// <param name="patterns">The patterns.</param>
/// <param name="ignoreCase">IgnoreCase (default false)</param> /// <param name="ignoreCase">IgnoreCase (default false)</param>
public ContentTypeMatcher(MatchBehaviour matchBehaviour, AnyOf<string, StringPattern>[] patterns, bool ignoreCase = false) : base(matchBehaviour, patterns, ignoreCase) /// <param name="throwException">Throw an exception when the internal matching fails because of invalid input.</param>
public ContentTypeMatcher(MatchBehaviour matchBehaviour, AnyOf<string, StringPattern>[] patterns, bool ignoreCase = false, bool throwException = false) :
base(matchBehaviour, patterns, ignoreCase, throwException)
{ {
_patterns = patterns; _patterns = patterns;
} }
/// <inheritdoc /> /// <inheritdoc cref="RegexMatcher.IsMatch"/>
public override MatchResult IsMatch(string? input) public override double IsMatch(string? input)
{ {
if (string.IsNullOrEmpty(input) || !MediaTypeHeaderValue.TryParse(input, out var contentType)) if (string.IsNullOrEmpty(input) || !MediaTypeHeaderValue.TryParse(input, out var contentType))
{ {
@@ -62,12 +64,12 @@ public class ContentTypeMatcher : WildcardMatcher
return base.IsMatch(contentType.MediaType); return base.IsMatch(contentType.MediaType);
} }
/// <inheritdoc /> /// <inheritdoc cref="IStringMatcher.GetPatterns"/>
public override AnyOf<string, StringPattern>[] GetPatterns() public override AnyOf<string, StringPattern>[] GetPatterns()
{ {
return _patterns; return _patterns;
} }
/// <inheritdoc /> /// <inheritdoc cref="IMatcher.Name"/>
public override string Name => nameof(ContentTypeMatcher); public override string Name => "ContentTypeMatcher";
} }

View File

@@ -14,14 +14,17 @@ public class ExactMatcher : IStringMatcher, IIgnoreCaseMatcher
{ {
private readonly AnyOf<string, StringPattern>[] _values; private readonly AnyOf<string, StringPattern>[] _values;
/// <inheritdoc /> /// <inheritdoc cref="IMatcher.MatchBehaviour"/>
public MatchBehaviour MatchBehaviour { get; } public MatchBehaviour MatchBehaviour { get; }
/// <inheritdoc cref="IMatcher.ThrowException"/>
public bool ThrowException { get; }
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="ExactMatcher"/> class. /// Initializes a new instance of the <see cref="ExactMatcher"/> class.
/// </summary> /// </summary>
/// <param name="values">The values.</param> /// <param name="values">The values.</param>
public ExactMatcher(params AnyOf<string, StringPattern>[] values) : this(MatchBehaviour.AcceptOnMatch, false, MatchOperator.Or, values) public ExactMatcher(params AnyOf<string, StringPattern>[] values) : this(MatchBehaviour.AcceptOnMatch, false, false, MatchOperator.Or, values)
{ {
} }
@@ -30,7 +33,7 @@ public class ExactMatcher : IStringMatcher, IIgnoreCaseMatcher
/// </summary> /// </summary>
/// <param name="ignoreCase">Ignore the case from the pattern(s).</param> /// <param name="ignoreCase">Ignore the case from the pattern(s).</param>
/// <param name="values">The values.</param> /// <param name="values">The values.</param>
public ExactMatcher(bool ignoreCase, params AnyOf<string, StringPattern>[] values) : this(MatchBehaviour.AcceptOnMatch, ignoreCase, MatchOperator.Or, values) public ExactMatcher(bool ignoreCase, params AnyOf<string, StringPattern>[] values) : this(MatchBehaviour.AcceptOnMatch, ignoreCase, false, MatchOperator.Or, values)
{ {
} }
@@ -39,33 +42,36 @@ public class ExactMatcher : IStringMatcher, IIgnoreCaseMatcher
/// </summary> /// </summary>
/// <param name="matchBehaviour">The match behaviour.</param> /// <param name="matchBehaviour">The match behaviour.</param>
/// <param name="ignoreCase">Ignore the case from the pattern(s).</param> /// <param name="ignoreCase">Ignore the case from the pattern(s).</param>
/// <param name="throwException">Throw an exception when the internal matching fails because of invalid input.</param>
/// <param name="matchOperator">The <see cref="Matchers.MatchOperator"/> to use. (default = "Or")</param> /// <param name="matchOperator">The <see cref="Matchers.MatchOperator"/> to use. (default = "Or")</param>
/// <param name="values">The values.</param> /// <param name="values">The values.</param>
public ExactMatcher( public ExactMatcher(
MatchBehaviour matchBehaviour, MatchBehaviour matchBehaviour,
bool ignoreCase = false, bool ignoreCase = false,
bool throwException = false,
MatchOperator matchOperator = MatchOperator.Or, MatchOperator matchOperator = MatchOperator.Or,
params AnyOf<string, StringPattern>[] values) params AnyOf<string, StringPattern>[] values)
{ {
_values = Guard.NotNull(values); _values = Guard.NotNull(values);
MatchBehaviour = matchBehaviour; MatchBehaviour = matchBehaviour;
ThrowException = throwException;
IgnoreCase = ignoreCase; IgnoreCase = ignoreCase;
MatchOperator = matchOperator; MatchOperator = matchOperator;
} }
/// <inheritdoc /> /// <inheritdoc cref="IStringMatcher.IsMatch"/>
public MatchResult IsMatch(string? input) public double IsMatch(string? input)
{ {
Func<string?, bool> equals = IgnoreCase Func<string?, bool> equals = IgnoreCase
? pattern => string.Equals(pattern, input, StringComparison.OrdinalIgnoreCase) ? pattern => string.Equals(pattern, input, StringComparison.OrdinalIgnoreCase)
: pattern => pattern == input; : pattern => pattern == input;
var score = MatchScores.ToScore(_values.Select(v => equals(v)).ToArray(), MatchOperator); double score = MatchScores.ToScore(_values.Select(v => equals(v)).ToArray(), MatchOperator);
return new MatchResult(MatchBehaviourHelper.Convert(MatchBehaviour, score)); return MatchBehaviourHelper.Convert(MatchBehaviour, score);
} }
/// <inheritdoc /> /// <inheritdoc cref="IStringMatcher.GetPatterns"/>
public AnyOf<string, StringPattern>[] GetPatterns() public AnyOf<string, StringPattern>[] GetPatterns()
{ {
return _values; return _values;
@@ -74,7 +80,7 @@ public class ExactMatcher : IStringMatcher, IIgnoreCaseMatcher
/// <inheritdoc /> /// <inheritdoc />
public MatchOperator MatchOperator { get; } public MatchOperator MatchOperator { get; }
/// <inheritdoc /> /// <inheritdoc cref="IMatcher.Name"/>
public string Name => "ExactMatcher"; public string Name => "ExactMatcher";
/// <inheritdoc /> /// <inheritdoc />

View File

@@ -19,9 +19,12 @@ public class ExactObjectMatcher : IObjectMatcher
/// </summary> /// </summary>
public byte[]? ValueAsBytes { get; } public byte[]? ValueAsBytes { get; }
/// <inheritdoc /> /// <inheritdoc cref="IMatcher.MatchBehaviour"/>
public MatchBehaviour MatchBehaviour { get; } public MatchBehaviour MatchBehaviour { get; }
/// <inheritdoc cref="IMatcher.ThrowException"/>
public bool ThrowException { get; }
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="ExactObjectMatcher"/> class. /// Initializes a new instance of the <see cref="ExactObjectMatcher"/> class.
/// </summary> /// </summary>
@@ -53,15 +56,17 @@ public class ExactObjectMatcher : IObjectMatcher
/// Initializes a new instance of the <see cref="ExactObjectMatcher"/> class. /// Initializes a new instance of the <see cref="ExactObjectMatcher"/> class.
/// </summary> /// </summary>
/// <param name="matchBehaviour">The match behaviour.</param> /// <param name="matchBehaviour">The match behaviour.</param>
/// <param name="throwException">Throw an exception when the internal matching fails because of invalid input.</param>
/// <param name="value">The value.</param> /// <param name="value">The value.</param>
public ExactObjectMatcher(MatchBehaviour matchBehaviour, byte[] value) public ExactObjectMatcher(MatchBehaviour matchBehaviour, byte[] value, bool throwException = false)
{ {
ValueAsBytes = Guard.NotNull(value); ValueAsBytes = Guard.NotNull(value);
MatchBehaviour = matchBehaviour; MatchBehaviour = matchBehaviour;
ThrowException = throwException;
} }
/// <inheritdoc /> /// <inheritdoc cref="IObjectMatcher.IsMatch"/>
public MatchResult IsMatch(object? input) public double IsMatch(object? input)
{ {
bool equals = false; bool equals = false;
if (ValueAsObject != null) if (ValueAsObject != null)
@@ -76,6 +81,6 @@ public class ExactObjectMatcher : IObjectMatcher
return MatchBehaviourHelper.Convert(MatchBehaviour, MatchScores.ToScore(equals)); return MatchBehaviourHelper.Convert(MatchBehaviour, MatchScores.ToScore(equals));
} }
/// <inheritdoc /> /// <inheritdoc cref="IMatcher.Name"/>
public string Name => "ExactObjectMatcher"; public string Name => "ExactObjectMatcher";
} }

View File

@@ -1,145 +0,0 @@
#if GRAPHQL
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using AnyOfTypes;
using GraphQL;
using GraphQL.Types;
using Newtonsoft.Json;
using Stef.Validation;
using WireMock.Extensions;
using WireMock.Models;
namespace WireMock.Matchers;
/// <summary>
/// GrapQLMatcher Schema Matcher
/// </summary>
/// <inheritdoc cref="IStringMatcher"/>
public class GraphQLMatcher : IStringMatcher
{
private sealed class GraphQLRequest
{
// ReSharper disable once UnusedAutoPropertyAccessor.Local
public string? Query { get; set; }
// ReSharper disable once UnusedAutoPropertyAccessor.Local
public Dictionary<string, object?>? Variables { get; set; }
}
private readonly AnyOf<string, StringPattern>[] _patterns;
private readonly ISchema _schema;
/// <inheritdoc />
public MatchBehaviour MatchBehaviour { get; }
/// <summary>
/// Initializes a new instance of the <see cref="LinqMatcher"/> class.
/// </summary>
/// <param name="schema">The schema.</param>
/// <param name="matchBehaviour">The match behaviour.</param>
/// <param name="matchOperator">The <see cref="Matchers.MatchOperator"/> to use. (default = "Or")</param>
public GraphQLMatcher(AnyOf<string, StringPattern, ISchema> schema, MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch, MatchOperator matchOperator = MatchOperator.Or)
{
Guard.NotNull(schema);
MatchBehaviour = matchBehaviour;
MatchOperator = matchOperator;
var patterns = new List<AnyOf<string, StringPattern>>();
switch (schema.CurrentType)
{
case AnyOfType.First:
patterns.Add(schema.First);
_schema = BuildSchema(schema);
break;
case AnyOfType.Second:
patterns.Add(schema.Second);
_schema = BuildSchema(schema.Second.Pattern);
break;
case AnyOfType.Third:
_schema = schema.Third;
break;
default:
throw new NotSupportedException();
}
_patterns = patterns.ToArray();
}
/// <inheritdoc />
public MatchResult IsMatch(string? input)
{
var score = MatchScores.Mismatch;
Exception? exception = null;
if (input != null && TryGetGraphQLRequest(input, out var graphQLRequest))
{
try
{
var executionResult = new DocumentExecuter().ExecuteAsync(_ =>
{
_.ThrowOnUnhandledException = true;
_.Schema = _schema;
_.Query = graphQLRequest.Query;
if (graphQLRequest.Variables != null)
{
_.Variables = new Inputs(graphQLRequest.Variables);
}
}).GetAwaiter().GetResult();
if (executionResult.Errors == null || executionResult.Errors.Count == 0)
{
score = MatchScores.Perfect;
}
else
{
exception = executionResult.Errors.OfType<Exception>().ToArray().ToException();
}
}
catch (Exception ex)
{
exception = ex;
}
}
return new MatchResult(MatchBehaviourHelper.Convert(MatchBehaviour, score), exception);
}
/// <inheritdoc />
public AnyOf<string, StringPattern>[] GetPatterns()
{
return _patterns;
}
/// <inheritdoc />
public MatchOperator MatchOperator { get; }
/// <inheritdoc />
public string Name => nameof(GraphQLMatcher);
private static bool TryGetGraphQLRequest(string input, [NotNullWhen(true)] out GraphQLRequest? graphQLRequest)
{
try
{
graphQLRequest = JsonConvert.DeserializeObject<GraphQLRequest>(input);
return graphQLRequest != null;
}
catch
{
graphQLRequest = default;
return false;
}
}
private static ISchema BuildSchema(string schema)
{
return Schema.For(schema);
}
}
#endif

View File

@@ -1,68 +0,0 @@
using Stef.Validation;
using WireMock.Types;
using WireMock.Util;
namespace WireMock.Matchers.Helpers;
internal static class BodyDataMatchScoreCalculator
{
public static MatchResult CalculateMatchScore(IBodyData? requestMessage, IMatcher matcher)
{
Guard.NotNull(matcher);
if (matcher is NotNullOrEmptyMatcher notNullOrEmptyMatcher)
{
switch (requestMessage?.DetectedBodyType)
{
case BodyType.Json:
case BodyType.String:
case BodyType.FormUrlEncoded:
return notNullOrEmptyMatcher.IsMatch(requestMessage.BodyAsString);
case BodyType.Bytes:
return notNullOrEmptyMatcher.IsMatch(requestMessage.BodyAsBytes);
default:
return default;
}
}
if (matcher is ExactObjectMatcher exactObjectMatcher)
{
// If the body is a byte array, try to match.
var detectedBodyType = requestMessage?.DetectedBodyType;
if (detectedBodyType is BodyType.Bytes or BodyType.String or BodyType.FormUrlEncoded)
{
return exactObjectMatcher.IsMatch(requestMessage?.BodyAsBytes);
}
}
// Check if the matcher is a IObjectMatcher
if (matcher is IObjectMatcher objectMatcher)
{
// If the body is a JSON object, try to match.
if (requestMessage?.DetectedBodyType == BodyType.Json)
{
return objectMatcher.IsMatch(requestMessage.BodyAsJson);
}
// If the body is a byte array, try to match.
if (requestMessage?.DetectedBodyType == BodyType.Bytes)
{
return objectMatcher.IsMatch(requestMessage.BodyAsBytes);
}
}
// Check if the matcher is a IStringMatcher
if (matcher is IStringMatcher stringMatcher)
{
// If the body is a Json or a String, use the BodyAsString to match on.
if (requestMessage?.DetectedBodyType is BodyType.Json or BodyType.String or BodyType.FormUrlEncoded)
{
return stringMatcher.IsMatch(requestMessage.BodyAsString);
}
}
return default;
}
}

View File

@@ -14,4 +14,9 @@ public interface IMatcher
/// Gets the match behaviour. /// Gets the match behaviour.
/// </summary> /// </summary>
MatchBehaviour MatchBehaviour { get; } MatchBehaviour MatchBehaviour { get; }
/// <summary>
/// Should this matcher throw an exception?
/// </summary>
bool ThrowException { get; }
} }

View File

@@ -9,6 +9,6 @@ public interface IObjectMatcher : IMatcher
/// Determines whether the specified input is match. /// Determines whether the specified input is match.
/// </summary> /// </summary>
/// <param name="input">The input.</param> /// <param name="input">The input.</param>
/// <returns>MatchResult</returns> /// <returns>A value between 0.0 - 1.0 of the similarity.</returns>
MatchResult IsMatch(object? input); double IsMatch(object? input);
} }

View File

@@ -13,8 +13,8 @@ public interface IStringMatcher : IMatcher
/// Determines whether the specified input is match. /// Determines whether the specified input is match.
/// </summary> /// </summary>
/// <param name="input">The input.</param> /// <param name="input">The input.</param>
/// <returns>MatchResult</returns> /// <returns>A value between 0.0 - 1.0 of the similarity.</returns>
MatchResult IsMatch(string? input); double IsMatch(string? input);
/// <summary> /// <summary>
/// Gets the patterns. /// Gets the patterns.

View File

@@ -1,6 +1,6 @@
using System;
using System.Linq; using System.Linq;
using AnyOfTypes; using AnyOfTypes;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq; using Newtonsoft.Json.Linq;
using Stef.Validation; using Stef.Validation;
using WireMock.Extensions; using WireMock.Extensions;
@@ -17,15 +17,17 @@ public class JsonPathMatcher : IStringMatcher, IObjectMatcher
{ {
private readonly AnyOf<string, StringPattern>[] _patterns; private readonly AnyOf<string, StringPattern>[] _patterns;
/// <inheritdoc /> /// <inheritdoc cref="IMatcher.MatchBehaviour"/>
public MatchBehaviour MatchBehaviour { get; } public MatchBehaviour MatchBehaviour { get; }
/// <inheritdoc cref="IMatcher.ThrowException"/>
public bool ThrowException { get; }
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="JsonPathMatcher"/> class. /// Initializes a new instance of the <see cref="JsonPathMatcher"/> class.
/// </summary> /// </summary>
/// <param name="patterns">The patterns.</param> /// <param name="patterns">The patterns.</param>
public JsonPathMatcher(params string[] patterns) : this(MatchBehaviour.AcceptOnMatch, MatchOperator.Or, public JsonPathMatcher(params string[] patterns) : this(MatchBehaviour.AcceptOnMatch, false, MatchOperator.Or, patterns.ToAnyOfPatterns())
patterns.ToAnyOfPatterns())
{ {
} }
@@ -33,8 +35,7 @@ public class JsonPathMatcher : IStringMatcher, IObjectMatcher
/// Initializes a new instance of the <see cref="JsonPathMatcher"/> class. /// Initializes a new instance of the <see cref="JsonPathMatcher"/> class.
/// </summary> /// </summary>
/// <param name="patterns">The patterns.</param> /// <param name="patterns">The patterns.</param>
public JsonPathMatcher(params AnyOf<string, StringPattern>[] patterns) : this(MatchBehaviour.AcceptOnMatch, public JsonPathMatcher(params AnyOf<string, StringPattern>[] patterns) : this(MatchBehaviour.AcceptOnMatch, false, MatchOperator.Or, patterns)
MatchOperator.Or, patterns)
{ {
} }
@@ -42,45 +43,48 @@ public class JsonPathMatcher : IStringMatcher, IObjectMatcher
/// Initializes a new instance of the <see cref="JsonPathMatcher"/> class. /// Initializes a new instance of the <see cref="JsonPathMatcher"/> class.
/// </summary> /// </summary>
/// <param name="matchBehaviour">The match behaviour.</param> /// <param name="matchBehaviour">The match behaviour.</param>
/// <param name="throwException">Throw an exception when the internal matching fails because of invalid input.</param>
/// <param name="matchOperator">The <see cref="Matchers.MatchOperator"/> to use. (default = "Or")</param> /// <param name="matchOperator">The <see cref="Matchers.MatchOperator"/> to use. (default = "Or")</param>
/// <param name="patterns">The patterns.</param> /// <param name="patterns">The patterns.</param>
public JsonPathMatcher( public JsonPathMatcher(
MatchBehaviour matchBehaviour, MatchBehaviour matchBehaviour,
bool throwException = false,
MatchOperator matchOperator = MatchOperator.Or, MatchOperator matchOperator = MatchOperator.Or,
params AnyOf<string, StringPattern>[] patterns) params AnyOf<string, StringPattern>[] patterns)
{ {
_patterns = Guard.NotNull(patterns); _patterns = Guard.NotNull(patterns);
MatchBehaviour = matchBehaviour; MatchBehaviour = matchBehaviour;
ThrowException = throwException;
MatchOperator = matchOperator; MatchOperator = matchOperator;
} }
/// <inheritdoc /> /// <inheritdoc cref="IStringMatcher.IsMatch"/>
public MatchResult IsMatch(string? input) public double IsMatch(string? input)
{ {
var score = MatchScores.Mismatch; double match = MatchScores.Mismatch;
Exception? exception = null;
if (input != null) if (input != null)
{ {
try try
{ {
var jToken = JToken.Parse(input); var jToken = JToken.Parse(input);
score = IsMatch(jToken); match = IsMatch(jToken);
} }
catch (Exception ex) catch (JsonException)
{ {
exception = ex; if (ThrowException)
{
throw;
}
} }
} }
return new MatchResult(MatchBehaviourHelper.Convert(MatchBehaviour, score), exception); return MatchBehaviourHelper.Convert(MatchBehaviour, match);
} }
/// <inheritdoc /> /// <inheritdoc cref="IObjectMatcher.IsMatch"/>
public MatchResult IsMatch(object? input) public double IsMatch(object? input)
{ {
var score = MatchScores.Mismatch; double match = MatchScores.Mismatch;
Exception? exception = null;
// When input is null or byte[], return Mismatch. // When input is null or byte[], return Mismatch.
if (input != null && !(input is byte[])) if (input != null && !(input is byte[]))
@@ -89,15 +93,18 @@ public class JsonPathMatcher : IStringMatcher, IObjectMatcher
{ {
// Check if JToken or object // Check if JToken or object
JToken jToken = input as JToken ?? JObject.FromObject(input); JToken jToken = input as JToken ?? JObject.FromObject(input);
score = IsMatch(jToken); match = IsMatch(jToken);
} }
catch (Exception ex) catch (JsonException)
{ {
exception = ex; if (ThrowException)
{
throw;
}
} }
} }
return new MatchResult(MatchBehaviourHelper.Convert(MatchBehaviour, score), exception); return MatchBehaviourHelper.Convert(MatchBehaviour, match);
} }
/// <inheritdoc /> /// <inheritdoc />
@@ -109,40 +116,11 @@ public class JsonPathMatcher : IStringMatcher, IObjectMatcher
/// <inheritdoc /> /// <inheritdoc />
public MatchOperator MatchOperator { get; } public MatchOperator MatchOperator { get; }
/// <inheritdoc /> /// <inheritdoc cref="IMatcher.Name"/>
public string Name => "JsonPathMatcher"; public string Name => "JsonPathMatcher";
private double IsMatch(JToken jToken) private double IsMatch(JToken jToken)
{ {
var array = ConvertJTokenToJArrayIfNeeded(jToken); return MatchScores.ToScore(_patterns.Select(pattern => jToken.SelectToken(pattern.GetPattern()) != null).ToArray(), MatchOperator);
// The SelectToken method can accept a string path to a child token ( i.e. "Manufacturers[0].Products[0].Price").
// In that case it will return a JValue (some type) which does not implement the IEnumerable interface.
return MatchScores.ToScore(
_patterns.Select(pattern => array.SelectToken(pattern.GetPattern()) != null).ToArray(), MatchOperator);
}
// https://github.com/WireMock-Net/WireMock.Net/issues/965
// https://stackoverflow.com/questions/66922188/newtonsoft-jsonpath-with-c-sharp-syntax
// Filtering using SelectToken() isn't guaranteed to work for objects inside objects -- only objects inside arrays.
// So this code checks if it's an JArray, if it's not an array, construct a new JArray.
private static JToken ConvertJTokenToJArrayIfNeeded(JToken jToken)
{
if (jToken.Count() == 1)
{
var property = jToken.First();
var item = property.First();
if (item is JArray)
{
return jToken;
}
return new JObject
{
[property.Path] = new JArray(item)
};
}
return jToken;
} }
} }

View File

@@ -1,4 +1,3 @@
using System;
using System.Linq; using System.Linq;
using AnyOfTypes; using AnyOfTypes;
using DevLab.JmesPath; using DevLab.JmesPath;
@@ -16,14 +15,17 @@ public class JmesPathMatcher : IStringMatcher, IObjectMatcher
{ {
private readonly AnyOf<string, StringPattern>[] _patterns; private readonly AnyOf<string, StringPattern>[] _patterns;
/// <inheritdoc /> /// <inheritdoc cref="IMatcher.MatchBehaviour"/>
public MatchBehaviour MatchBehaviour { get; } public MatchBehaviour MatchBehaviour { get; }
/// <inheritdoc cref="IMatcher.ThrowException"/>
public bool ThrowException { get; }
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="JmesPathMatcher"/> class. /// Initializes a new instance of the <see cref="JmesPathMatcher"/> class.
/// </summary> /// </summary>
/// <param name="patterns">The patterns.</param> /// <param name="patterns">The patterns.</param>
public JmesPathMatcher(params string[] patterns) : this(MatchBehaviour.AcceptOnMatch, MatchOperator.Or, patterns.ToAnyOfPatterns()) public JmesPathMatcher(params string[] patterns) : this(MatchBehaviour.AcceptOnMatch, false, MatchOperator.Or, patterns.ToAnyOfPatterns())
{ {
} }
@@ -31,17 +33,18 @@ public class JmesPathMatcher : IStringMatcher, IObjectMatcher
/// Initializes a new instance of the <see cref="JmesPathMatcher"/> class. /// Initializes a new instance of the <see cref="JmesPathMatcher"/> class.
/// </summary> /// </summary>
/// <param name="patterns">The patterns.</param> /// <param name="patterns">The patterns.</param>
public JmesPathMatcher(params AnyOf<string, StringPattern>[] patterns) : this(MatchBehaviour.AcceptOnMatch, MatchOperator.Or, patterns) public JmesPathMatcher(params AnyOf<string, StringPattern>[] patterns) : this(MatchBehaviour.AcceptOnMatch, false, MatchOperator.Or, patterns)
{ {
} }
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="JmesPathMatcher"/> class. /// Initializes a new instance of the <see cref="JmesPathMatcher"/> class.
/// </summary> /// </summary>
/// <param name="throwException">Throw an exception when the internal matching fails because of invalid input.</param>
/// <param name="matchOperator">The <see cref="Matchers.MatchOperator"/> to use.</param> /// <param name="matchOperator">The <see cref="Matchers.MatchOperator"/> to use.</param>
/// <param name="patterns">The patterns.</param> /// <param name="patterns">The patterns.</param>
public JmesPathMatcher(MatchOperator matchOperator = MatchOperator.Or, params AnyOf<string, StringPattern>[] patterns) : public JmesPathMatcher(bool throwException = false, MatchOperator matchOperator = MatchOperator.Or, params AnyOf<string, StringPattern>[] patterns) :
this(MatchBehaviour.AcceptOnMatch, matchOperator, patterns) this(MatchBehaviour.AcceptOnMatch, throwException, matchOperator, patterns)
{ {
} }
@@ -49,56 +52,60 @@ public class JmesPathMatcher : IStringMatcher, IObjectMatcher
/// Initializes a new instance of the <see cref="JmesPathMatcher"/> class. /// Initializes a new instance of the <see cref="JmesPathMatcher"/> class.
/// </summary> /// </summary>
/// <param name="matchBehaviour">The match behaviour.</param> /// <param name="matchBehaviour">The match behaviour.</param>
/// <param name="throwException">Throw an exception when the internal matching fails because of invalid input.</param>
/// <param name="matchOperator">The <see cref="Matchers.MatchOperator"/> to use.</param> /// <param name="matchOperator">The <see cref="Matchers.MatchOperator"/> to use.</param>
/// <param name="patterns">The patterns.</param> /// <param name="patterns">The patterns.</param>
public JmesPathMatcher( public JmesPathMatcher(
MatchBehaviour matchBehaviour, MatchBehaviour matchBehaviour,
bool throwException = false,
MatchOperator matchOperator = MatchOperator.Or, MatchOperator matchOperator = MatchOperator.Or,
params AnyOf<string, StringPattern>[] patterns) params AnyOf<string, StringPattern>[] patterns)
{ {
_patterns = Guard.NotNull(patterns); _patterns = Guard.NotNull(patterns);
MatchBehaviour = matchBehaviour; MatchBehaviour = matchBehaviour;
ThrowException = throwException;
MatchOperator = matchOperator; MatchOperator = matchOperator;
} }
/// <inheritdoc /> /// <inheritdoc cref="IStringMatcher.IsMatch"/>
public MatchResult IsMatch(string? input) public double IsMatch(string? input)
{ {
var score = MatchScores.Mismatch; double match = MatchScores.Mismatch;
Exception? exception = null;
if (input != null) if (input != null)
{ {
try try
{ {
var results = _patterns.Select(pattern => bool.Parse(new JmesPath().Transform(input, pattern.GetPattern()))).ToArray(); var results = _patterns.Select(pattern => bool.Parse(new JmesPath().Transform(input, pattern.GetPattern()))).ToArray();
score = MatchScores.ToScore(results, MatchOperator); match = MatchScores.ToScore(results, MatchOperator);
} }
catch (Exception ex) catch (JsonException)
{ {
exception = ex; if (ThrowException)
{
throw;
}
} }
} }
return new MatchResult(MatchBehaviourHelper.Convert(MatchBehaviour, score), exception); return MatchBehaviourHelper.Convert(MatchBehaviour, match);
} }
/// <inheritdoc /> /// <inheritdoc cref="IObjectMatcher.IsMatch"/>
public MatchResult IsMatch(object? input) public double IsMatch(object? input)
{ {
var score = MatchScores.Mismatch; double match = MatchScores.Mismatch;
// When input is null or byte[], return Mismatch. // When input is null or byte[], return Mismatch.
if (input != null && !(input is byte[])) if (input != null && !(input is byte[]))
{ {
var inputAsString = JsonConvert.SerializeObject(input); string inputAsString = JsonConvert.SerializeObject(input);
return IsMatch(inputAsString); return IsMatch(inputAsString);
} }
return MatchBehaviourHelper.Convert(MatchBehaviour, score); return MatchBehaviourHelper.Convert(MatchBehaviour, match);
} }
/// <inheritdoc /> /// <inheritdoc cref="IStringMatcher.GetPatterns"/>
public AnyOf<string, StringPattern>[] GetPatterns() public AnyOf<string, StringPattern>[] GetPatterns()
{ {
return _patterns; return _patterns;
@@ -107,6 +114,6 @@ public class JmesPathMatcher : IStringMatcher, IObjectMatcher
/// <inheritdoc /> /// <inheritdoc />
public MatchOperator MatchOperator { get; } public MatchOperator MatchOperator { get; }
/// <inheritdoc /> /// <inheritdoc cref="IMatcher.Name"/>
public string Name => nameof(JmesPathMatcher); public string Name => "JmesPathMatcher";
} }

View File

@@ -1,6 +1,7 @@
using System; using System;
using System.Collections; using System.Collections;
using System.Linq; using System.Linq;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq; using Newtonsoft.Json.Linq;
using Stef.Validation; using Stef.Validation;
using WireMock.Util; using WireMock.Util;
@@ -12,18 +13,21 @@ namespace WireMock.Matchers;
/// </summary> /// </summary>
public class JsonMatcher : IValueMatcher, IIgnoreCaseMatcher public class JsonMatcher : IValueMatcher, IIgnoreCaseMatcher
{ {
/// <inheritdoc /> /// <inheritdoc cref="IMatcher.Name"/>
public virtual string Name => "JsonMatcher"; public virtual string Name => "JsonMatcher";
/// <inheritdoc cref="IValueMatcher.Value"/> /// <inheritdoc cref="IValueMatcher.Value"/>
public object Value { get; } public object Value { get; }
/// <inheritdoc /> /// <inheritdoc cref="IMatcher.MatchBehaviour"/>
public MatchBehaviour MatchBehaviour { get; } public MatchBehaviour MatchBehaviour { get; }
/// <inheritdoc cref="IIgnoreCaseMatcher.IgnoreCase"/> /// <inheritdoc cref="IIgnoreCaseMatcher.IgnoreCase"/>
public bool IgnoreCase { get; } public bool IgnoreCase { get; }
/// <inheritdoc cref="IMatcher.ThrowException"/>
public bool ThrowException { get; }
private readonly JToken _valueAsJToken; private readonly JToken _valueAsJToken;
private readonly Func<JToken, JToken> _jTokenConverter; private readonly Func<JToken, JToken> _jTokenConverter;
@@ -32,7 +36,8 @@ public class JsonMatcher : IValueMatcher, IIgnoreCaseMatcher
/// </summary> /// </summary>
/// <param name="value">The string value to check for equality.</param> /// <param name="value">The string value to check for equality.</param>
/// <param name="ignoreCase">Ignore the case from the PropertyName and PropertyValue (string only).</param> /// <param name="ignoreCase">Ignore the case from the PropertyName and PropertyValue (string only).</param>
public JsonMatcher(string value, bool ignoreCase = false) : this(MatchBehaviour.AcceptOnMatch, value, ignoreCase) /// <param name="throwException">Throw an exception when the internal matching fails because of invalid input.</param>
public JsonMatcher(string value, bool ignoreCase = false, bool throwException = false) : this(MatchBehaviour.AcceptOnMatch, value, ignoreCase, throwException)
{ {
} }
@@ -41,7 +46,8 @@ public class JsonMatcher : IValueMatcher, IIgnoreCaseMatcher
/// </summary> /// </summary>
/// <param name="value">The object value to check for equality.</param> /// <param name="value">The object value to check for equality.</param>
/// <param name="ignoreCase">Ignore the case from the PropertyName and PropertyValue (string only).</param> /// <param name="ignoreCase">Ignore the case from the PropertyName and PropertyValue (string only).</param>
public JsonMatcher(object value, bool ignoreCase = false) : this(MatchBehaviour.AcceptOnMatch, value, ignoreCase) /// <param name="throwException">Throw an exception when the internal matching fails because of invalid input.</param>
public JsonMatcher(object value, bool ignoreCase = false, bool throwException = false) : this(MatchBehaviour.AcceptOnMatch, value, ignoreCase, throwException)
{ {
} }
@@ -51,23 +57,24 @@ public class JsonMatcher : IValueMatcher, IIgnoreCaseMatcher
/// <param name="matchBehaviour">The match behaviour.</param> /// <param name="matchBehaviour">The match behaviour.</param>
/// <param name="value">The value to check for equality.</param> /// <param name="value">The value to check for equality.</param>
/// <param name="ignoreCase">Ignore the case from the PropertyName and PropertyValue (string only).</param> /// <param name="ignoreCase">Ignore the case from the PropertyName and PropertyValue (string only).</param>
public JsonMatcher(MatchBehaviour matchBehaviour, object value, bool ignoreCase = false) /// <param name="throwException">Throw an exception when the internal matching fails because of invalid input.</param>
public JsonMatcher(MatchBehaviour matchBehaviour, object value, bool ignoreCase = false, bool throwException = false)
{ {
Guard.NotNull(value, nameof(value)); Guard.NotNull(value, nameof(value));
MatchBehaviour = matchBehaviour; MatchBehaviour = matchBehaviour;
IgnoreCase = ignoreCase; IgnoreCase = ignoreCase;
ThrowException = throwException;
Value = value; Value = value;
_valueAsJToken = ConvertValueToJToken(value); _valueAsJToken = ConvertValueToJToken(value);
_jTokenConverter = ignoreCase ? Rename : jToken => jToken; _jTokenConverter = ignoreCase ? Rename : jToken => jToken;
} }
/// <inheritdoc /> /// <inheritdoc cref="IObjectMatcher.IsMatch"/>
public MatchResult IsMatch(object? input) public double IsMatch(object? input)
{ {
var score = MatchScores.Mismatch; bool match = false;
Exception? error = null;
// When input is null or byte[], return Mismatch. // When input is null or byte[], return Mismatch.
if (input != null && input is not byte[]) if (input != null && input is not byte[])
@@ -76,16 +83,20 @@ public class JsonMatcher : IValueMatcher, IIgnoreCaseMatcher
{ {
var inputAsJToken = ConvertValueToJToken(input); var inputAsJToken = ConvertValueToJToken(input);
var match = IsMatch(_jTokenConverter(_valueAsJToken), _jTokenConverter(inputAsJToken)); match = IsMatch(
score = MatchScores.ToScore(match); _jTokenConverter(_valueAsJToken),
_jTokenConverter(inputAsJToken));
} }
catch (Exception ex) catch (JsonException)
{ {
error = ex; if (ThrowException)
{
throw;
}
} }
} }
return new MatchResult(MatchBehaviourHelper.Convert(MatchBehaviour, score), error); return MatchBehaviourHelper.Convert(MatchBehaviour, MatchScores.ToScore(match));
} }
/// <summary> /// <summary>

View File

@@ -9,27 +9,27 @@ public class JsonPartialMatcher : AbstractJsonPartialMatcher
public override string Name => nameof(JsonPartialMatcher); public override string Name => nameof(JsonPartialMatcher);
/// <inheritdoc /> /// <inheritdoc />
public JsonPartialMatcher(string value, bool ignoreCase = false, bool regex = false) public JsonPartialMatcher(string value, bool ignoreCase = false, bool throwException = false, bool regex = false)
: base(value, ignoreCase, regex) : base(value, ignoreCase, throwException, regex)
{ {
} }
/// <inheritdoc /> /// <inheritdoc />
public JsonPartialMatcher(object value, bool ignoreCase = false, bool regex = false) public JsonPartialMatcher(object value, bool ignoreCase = false, bool throwException = false, bool regex = false)
: base(value, ignoreCase, regex) : base(value, ignoreCase, throwException, regex)
{ {
} }
/// <inheritdoc /> /// <inheritdoc />
public JsonPartialMatcher(MatchBehaviour matchBehaviour, object value, bool ignoreCase = false, bool regex = false) public JsonPartialMatcher(MatchBehaviour matchBehaviour, object value, bool ignoreCase = false, bool throwException = false, bool regex = false)
: base(matchBehaviour, value, ignoreCase, regex) : base(matchBehaviour, value, ignoreCase, throwException, regex)
{ {
} }
/// <inheritdoc /> /// <inheritdoc />
protected override bool IsMatch(string value, string input) protected override bool IsMatch(string value, string input)
{ {
var exactStringMatcher = new ExactMatcher(MatchBehaviour.AcceptOnMatch, IgnoreCase, MatchOperator.Or, value); var exactStringMatcher = new ExactMatcher(MatchBehaviour.AcceptOnMatch, IgnoreCase, ThrowException, MatchOperator.Or, value);
return exactStringMatcher.IsMatch(input).IsPerfect(); return MatchScores.IsPerfect(exactStringMatcher.IsMatch(input));
} }
} }

View File

@@ -9,20 +9,20 @@ public class JsonPartialWildcardMatcher : AbstractJsonPartialMatcher
public override string Name => nameof(JsonPartialWildcardMatcher); public override string Name => nameof(JsonPartialWildcardMatcher);
/// <inheritdoc /> /// <inheritdoc />
public JsonPartialWildcardMatcher(string value, bool ignoreCase = false, bool regex = false) public JsonPartialWildcardMatcher(string value, bool ignoreCase = false, bool throwException = false, bool regex = false)
: base(value, ignoreCase, regex) : base(value, ignoreCase, throwException, regex)
{ {
} }
/// <inheritdoc /> /// <inheritdoc />
public JsonPartialWildcardMatcher(object value, bool ignoreCase = false, bool regex = false) public JsonPartialWildcardMatcher(object value, bool ignoreCase = false, bool throwException = false, bool regex = false)
: base(value, ignoreCase, regex) : base(value, ignoreCase, throwException, regex)
{ {
} }
/// <inheritdoc /> /// <inheritdoc />
public JsonPartialWildcardMatcher(MatchBehaviour matchBehaviour, object value, bool ignoreCase = false, bool regex = false) public JsonPartialWildcardMatcher(MatchBehaviour matchBehaviour, object value, bool ignoreCase = false, bool throwException = false, bool regex = false)
: base(matchBehaviour, value, ignoreCase, regex) : base(matchBehaviour, value, ignoreCase, throwException, regex)
{ {
} }
@@ -30,6 +30,6 @@ public class JsonPartialWildcardMatcher : AbstractJsonPartialMatcher
protected override bool IsMatch(string value, string input) protected override bool IsMatch(string value, string input)
{ {
var wildcardStringMatcher = new WildcardMatcher(MatchBehaviour.AcceptOnMatch, value, IgnoreCase); var wildcardStringMatcher = new WildcardMatcher(MatchBehaviour.AcceptOnMatch, value, IgnoreCase);
return wildcardStringMatcher.IsMatch(input).IsPerfect(); return MatchScores.IsPerfect(wildcardStringMatcher.IsMatch(input));
} }
} }

View File

@@ -19,9 +19,12 @@ public class LinqMatcher : IObjectMatcher, IStringMatcher
{ {
private readonly AnyOf<string, StringPattern>[] _patterns; private readonly AnyOf<string, StringPattern>[] _patterns;
/// <inheritdoc /> /// <inheritdoc cref="IMatcher.MatchBehaviour"/>
public MatchBehaviour MatchBehaviour { get; } public MatchBehaviour MatchBehaviour { get; }
/// <inheritdoc cref="IMatcher.ThrowException"/>
public bool ThrowException { get; }
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="LinqMatcher"/> class. /// Initializes a new instance of the <see cref="LinqMatcher"/> class.
/// </summary> /// </summary>
@@ -34,7 +37,7 @@ public class LinqMatcher : IObjectMatcher, IStringMatcher
/// Initializes a new instance of the <see cref="LinqMatcher"/> class. /// Initializes a new instance of the <see cref="LinqMatcher"/> class.
/// </summary> /// </summary>
/// <param name="patterns">The patterns.</param> /// <param name="patterns">The patterns.</param>
public LinqMatcher(params AnyOf<string, StringPattern>[] patterns) : this(MatchBehaviour.AcceptOnMatch, MatchOperator.Or, patterns) public LinqMatcher(params AnyOf<string, StringPattern>[] patterns) : this(MatchBehaviour.AcceptOnMatch, false, MatchOperator.Or, patterns)
{ {
} }
@@ -43,7 +46,7 @@ public class LinqMatcher : IObjectMatcher, IStringMatcher
/// </summary> /// </summary>
/// <param name="matchBehaviour">The match behaviour.</param> /// <param name="matchBehaviour">The match behaviour.</param>
/// <param name="pattern">The pattern.</param> /// <param name="pattern">The pattern.</param>
public LinqMatcher(MatchBehaviour matchBehaviour, AnyOf<string, StringPattern> pattern) : this(matchBehaviour, MatchOperator.Or, pattern) public LinqMatcher(MatchBehaviour matchBehaviour, AnyOf<string, StringPattern> pattern) : this(matchBehaviour, false, MatchOperator.Or, pattern)
{ {
} }
@@ -51,23 +54,25 @@ public class LinqMatcher : IObjectMatcher, IStringMatcher
/// Initializes a new instance of the <see cref="LinqMatcher"/> class. /// Initializes a new instance of the <see cref="LinqMatcher"/> class.
/// </summary> /// </summary>
/// <param name="matchBehaviour">The match behaviour.</param> /// <param name="matchBehaviour">The match behaviour.</param>
/// <param name="throwException">Throw an exception when the internal matching fails because of invalid input.</param>
/// <param name="matchOperator">The <see cref="Matchers.MatchOperator"/> to use. (default = "Or")</param> /// <param name="matchOperator">The <see cref="Matchers.MatchOperator"/> to use. (default = "Or")</param>
/// <param name="patterns">The patterns.</param> /// <param name="patterns">The patterns.</param>
public LinqMatcher( public LinqMatcher(
MatchBehaviour matchBehaviour, MatchBehaviour matchBehaviour,
bool throwException = false,
MatchOperator matchOperator = MatchOperator.Or, MatchOperator matchOperator = MatchOperator.Or,
params AnyOf<string, StringPattern>[] patterns) params AnyOf<string, StringPattern>[] patterns)
{ {
_patterns = Guard.NotNull(patterns); _patterns = Guard.NotNull(patterns);
MatchBehaviour = matchBehaviour; MatchBehaviour = matchBehaviour;
ThrowException = throwException;
MatchOperator = matchOperator; MatchOperator = matchOperator;
} }
/// <inheritdoc /> /// <inheritdoc cref="IStringMatcher.IsMatch"/>
public MatchResult IsMatch(string? input) public double IsMatch(string? input)
{ {
var score = MatchScores.Mismatch; double match = MatchScores.Mismatch;
Exception? error = null;
// Convert a single input string to a Queryable string-list with 1 entry. // Convert a single input string to a Queryable string-list with 1 entry.
IQueryable queryable = new[] { input }.AsQueryable(); IQueryable queryable = new[] { input }.AsQueryable();
@@ -75,21 +80,25 @@ public class LinqMatcher : IObjectMatcher, IStringMatcher
try try
{ {
// Use the Any(...) method to check if the result matches // Use the Any(...) method to check if the result matches
score = MatchScores.ToScore(_patterns.Select(pattern => queryable.Any(pattern.GetPattern())).ToArray(), MatchOperator); match = MatchScores.ToScore(_patterns.Select(pattern => queryable.Any(pattern.GetPattern())).ToArray(), MatchOperator);
return MatchBehaviourHelper.Convert(MatchBehaviour, match);
} }
catch (Exception e) catch
{ {
error = e; if (ThrowException)
{
throw;
}
} }
return new MatchResult(MatchBehaviourHelper.Convert(MatchBehaviour, score), error); return MatchBehaviourHelper.Convert(MatchBehaviour, match);
} }
/// <inheritdoc /> /// <inheritdoc cref="IObjectMatcher.IsMatch"/>
public MatchResult IsMatch(object? input) public double IsMatch(object? input)
{ {
var score = MatchScores.Mismatch; double match = MatchScores.Mismatch;
Exception? error = null;
JArray jArray; JArray jArray;
try try
@@ -98,28 +107,59 @@ public class LinqMatcher : IObjectMatcher, IStringMatcher
} }
catch catch
{ {
jArray = input == null ? new JArray() : new JArray { JToken.FromObject(input) }; jArray = new JArray { JToken.FromObject(input) };
} }
//enumerable = jArray.ToDynamicClassArray();
//JObject value;
//switch (input)
//{
// case JObject valueAsJObject:
// value = valueAsJObject;
// break;
// case { } valueAsObject:
// value = JObject.FromObject(valueAsObject);
// break;
// default:
// return MatchScores.Mismatch;
//}
// Convert a single object to a Queryable JObject-list with 1 entry. // Convert a single object to a Queryable JObject-list with 1 entry.
//var queryable1 = new[] { value }.AsQueryable();
var queryable = jArray.ToDynamicClassArray().AsQueryable(); var queryable = jArray.ToDynamicClassArray().AsQueryable();
try try
{ {
// Generate the DynamicLinq select statement.
//string dynamicSelect = JsonUtils.GenerateDynamicLinqStatement(value);
// Execute DynamicLinq Select statement.
//var queryable2 = queryable1.Select(dynamicSelect);
// Use the Any(...) method to check if the result matches.
var patternsAsStringArray = _patterns.Select(p => p.GetPattern()).ToArray(); var patternsAsStringArray = _patterns.Select(p => p.GetPattern()).ToArray();
var scores = patternsAsStringArray.Select(p => queryable.Any(p)).ToArray(); var scores = patternsAsStringArray.Select(p => queryable.Any(p)).ToArray();
score = MatchScores.ToScore(scores, MatchOperator); match = MatchScores.ToScore(_patterns.Select(pattern => queryable.Any(pattern.GetPattern())).ToArray(), MatchOperator);
return MatchBehaviourHelper.Convert(MatchBehaviour, match);
} }
catch (Exception e) catch (Exception e)
{ {
error = e; if (ThrowException)
{
throw;
}
} }
return new MatchResult(MatchBehaviourHelper.Convert(MatchBehaviour, score), error); return MatchBehaviourHelper.Convert(MatchBehaviour, match);
} }
/// <inheritdoc /> /// <inheritdoc cref="IStringMatcher.GetPatterns"/>
public AnyOf<string, StringPattern>[] GetPatterns() public AnyOf<string, StringPattern>[] GetPatterns()
{ {
return _patterns; return _patterns;
@@ -128,6 +168,6 @@ public class LinqMatcher : IObjectMatcher, IStringMatcher
/// <inheritdoc /> /// <inheritdoc />
public MatchOperator MatchOperator { get; } public MatchOperator MatchOperator { get; }
/// <inheritdoc /> /// <inheritdoc cref="IMatcher.Name"/>
public string Name => nameof(LinqMatcher); public string Name => "LinqMatcher";
} }

View File

@@ -1,7 +1,7 @@
namespace WireMock.Matchers; namespace WireMock.Matchers;
/// <summary> /// <summary>
/// MatchBehaviour (Accept or Reject) /// MatchBehaviour
/// </summary> /// </summary>
public enum MatchBehaviour public enum MatchBehaviour
{ {

View File

@@ -1,89 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Stef.Validation;
using WireMock.Extensions;
namespace WireMock.Matchers;
/// <summary>
/// The MatchResult which contains the score (value between 0.0 - 1.0 of the similarity) and an optional error message.
/// </summary>
public struct MatchResult
{
/// <summary>
/// A value between 0.0 - 1.0 of the similarity.
/// </summary>
public double Score { get; set; }
/// <summary>
/// The exception message) in case the matching fails.
/// [Optional]
/// </summary>
public Exception? Exception { get; set; }
/// <summary>
/// Create a MatchResult
/// </summary>
/// <param name="score">A value between 0.0 - 1.0 of the similarity.</param>
/// <param name="exception">The exception in case the matching fails. [Optional]</param>
public MatchResult(double score, Exception? exception = null)
{
Score = score;
Exception = exception;
}
/// <summary>
/// Create a MatchResult
/// </summary>
/// <param name="exception">The exception in case the matching fails.</param>
public MatchResult(Exception exception)
{
Exception = Guard.NotNull(exception);
}
/// <summary>
/// Implicitly converts a double to a MatchResult.
/// </summary>
/// <param name="score">The score</param>
public static implicit operator MatchResult(double score)
{
return new MatchResult(score);
}
/// <summary>
/// Is the value a perfect match?
/// </summary>
public bool IsPerfect() => MatchScores.IsPerfect(Score);
/// <summary>
/// Create a MatchResult from multiple MatchResults.
/// </summary>
/// <param name="matchResults">A list of MatchResults.</param>
/// <param name="matchOperator">The MatchOperator</param>
/// <returns>MatchResult</returns>
public static MatchResult From(IReadOnlyList<MatchResult> matchResults, MatchOperator matchOperator)
{
Guard.NotNullOrEmpty(matchResults);
if (matchResults.Count == 1)
{
return matchResults[0];
}
return new MatchResult
{
Score = MatchScores.ToScore(matchResults.Select(r => r.Score).ToArray(), matchOperator),
Exception = matchResults.Select(m => m.Exception).OfType<Exception>().ToArray().ToException()
};
}
/// <summary>
/// Expand to Tuple
/// </summary>
/// <returns>Tuple : Score and Exception</returns>
public (double Score, Exception? Exception) Expand()
{
return (Score, Exception);
}
}

View File

@@ -1,120 +0,0 @@
#if MIMEKIT
using System;
using MimeKit;
using WireMock.Matchers;
using WireMock.Matchers.Helpers;
using WireMock.Models;
using WireMock.Util;
namespace WireMock.Matchers;
/// <summary>
/// MimePartMatcher
/// </summary>
public class MimePartMatcher : IMatcher
{
private readonly Func<MimePart, MatchResult>[] _funcs;
/// <inheritdoc />
public string Name => nameof(MimePartMatcher);
/// <summary>
/// ContentType Matcher (image/png; name=image.png.)
/// </summary>
public IStringMatcher? ContentTypeMatcher { get; }
/// <summary>
/// ContentDisposition Matcher (attachment; filename=image.png)
/// </summary>
public IStringMatcher? ContentDispositionMatcher { get; }
/// <summary>
/// ContentTransferEncoding Matcher (base64)
/// </summary>
public IStringMatcher? ContentTransferEncodingMatcher { get; }
/// <summary>
/// Content Matcher
/// </summary>
public IMatcher? ContentMatcher { get; }
/// <inheritdoc />
public MatchBehaviour MatchBehaviour { get; }
/// <summary>
/// Initializes a new instance of the <see cref="MimePartMatcher"/> class.
/// </summary>
public MimePartMatcher(
MatchBehaviour matchBehaviour,
IStringMatcher? contentTypeMatcher,
IStringMatcher? contentDispositionMatcher,
IStringMatcher? contentTransferEncodingMatcher,
IMatcher? contentMatcher
)
{
MatchBehaviour = matchBehaviour;
ContentTypeMatcher = contentTypeMatcher;
ContentDispositionMatcher = contentDispositionMatcher;
ContentTransferEncodingMatcher = contentTransferEncodingMatcher;
ContentMatcher = contentMatcher;
_funcs = new[]
{
mp => ContentTypeMatcher?.IsMatch(GetContentTypeAsString(mp.ContentType)) ?? MatchScores.Perfect,
mp => ContentDispositionMatcher?.IsMatch(mp.ContentDisposition.ToString().Replace("Content-Disposition: ", string.Empty)) ?? MatchScores.Perfect,
mp => ContentTransferEncodingMatcher?.IsMatch(mp.ContentTransferEncoding.ToString().ToLowerInvariant()) ?? MatchScores.Perfect,
MatchOnContent
};
}
/// <summary>
/// Determines whether the specified MimePart is match.
/// </summary>
/// <param name="mimePart">The MimePart.</param>
/// <returns>A value between 0.0 - 1.0 of the similarity.</returns>
public MatchResult IsMatch(MimePart mimePart)
{
var score = MatchScores.Mismatch;
Exception? exception = null;
try
{
if (Array.TrueForAll(_funcs, func => func(mimePart).IsPerfect()))
{
score = MatchScores.Perfect;
}
}
catch (Exception ex)
{
exception = ex;
}
return new MatchResult(MatchBehaviourHelper.Convert(MatchBehaviour, score), exception);
}
private MatchResult MatchOnContent(MimePart mimePart)
{
if (ContentMatcher == null)
{
return MatchScores.Perfect;
}
var bodyParserSettings = new BodyParserSettings
{
Stream = mimePart.Content.Open(),
ContentType = GetContentTypeAsString(mimePart.ContentType),
DeserializeJson = true,
ContentEncoding = null, // mimePart.ContentType.CharsetEncoding.ToString(),
DecompressGZipAndDeflate = true
};
var bodyData = BodyParser.ParseAsync(bodyParserSettings).ConfigureAwait(false).GetAwaiter().GetResult();
return BodyDataMatchScoreCalculator.CalculateMatchScore(bodyData, ContentMatcher);
}
private static string? GetContentTypeAsString(ContentType? contentType)
{
return contentType?.ToString().Replace("Content-Type: ", string.Empty);
}
}
#endif

View File

@@ -11,12 +11,15 @@ namespace WireMock.Matchers;
/// <seealso cref="IObjectMatcher" /> /// <seealso cref="IObjectMatcher" />
public class NotNullOrEmptyMatcher : IObjectMatcher, IStringMatcher public class NotNullOrEmptyMatcher : IObjectMatcher, IStringMatcher
{ {
/// <inheritdoc /> /// <inheritdoc cref="IMatcher.Name"/>
public string Name => nameof(NotNullOrEmptyMatcher); public string Name => "NotNullOrEmptyMatcher";
/// <inheritdoc /> /// <inheritdoc cref="IMatcher.MatchBehaviour"/>
public MatchBehaviour MatchBehaviour { get; } public MatchBehaviour MatchBehaviour { get; }
/// <inheritdoc cref="IMatcher.ThrowException"/>
public bool ThrowException { get; }
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="NotNullOrEmptyMatcher"/> class. /// Initializes a new instance of the <see cref="NotNullOrEmptyMatcher"/> class.
/// </summary> /// </summary>
@@ -26,8 +29,8 @@ public class NotNullOrEmptyMatcher : IObjectMatcher, IStringMatcher
MatchBehaviour = matchBehaviour; MatchBehaviour = matchBehaviour;
} }
/// <inheritdoc /> /// <inheritdoc cref="IObjectMatcher.IsMatch"/>
public MatchResult IsMatch(object? input) public double IsMatch(object? input)
{ {
bool match; bool match;
@@ -49,15 +52,15 @@ public class NotNullOrEmptyMatcher : IObjectMatcher, IStringMatcher
return MatchBehaviourHelper.Convert(MatchBehaviour, MatchScores.ToScore(match)); return MatchBehaviourHelper.Convert(MatchBehaviour, MatchScores.ToScore(match));
} }
/// <inheritdoc /> /// <inheritdoc cref="IStringMatcher.IsMatch"/>
public MatchResult IsMatch(string? input) public double IsMatch(string? input)
{ {
var match = !string.IsNullOrEmpty(input); var match = !string.IsNullOrEmpty(input);
return MatchBehaviourHelper.Convert(MatchBehaviour, MatchScores.ToScore(match)); return MatchBehaviourHelper.Convert(MatchBehaviour, MatchScores.ToScore(match));
} }
/// <inheritdoc /> /// <inheritdoc cref="IStringMatcher.GetPatterns"/>
public AnyOf<string, StringPattern>[] GetPatterns() public AnyOf<string, StringPattern>[] GetPatterns()
{ {
return EmptyArray<AnyOf<string, StringPattern>>.Value; return EmptyArray<AnyOf<string, StringPattern>>.Value;

View File

@@ -20,22 +20,27 @@ public class RegexMatcher : IStringMatcher, IIgnoreCaseMatcher
private readonly AnyOf<string, StringPattern>[] _patterns; private readonly AnyOf<string, StringPattern>[] _patterns;
private readonly Regex[] _expressions; private readonly Regex[] _expressions;
/// <inheritdoc /> /// <inheritdoc cref="IMatcher.MatchBehaviour"/>
public MatchBehaviour MatchBehaviour { get; } public MatchBehaviour MatchBehaviour { get; }
/// <inheritdoc cref="IMatcher.ThrowException"/>
public bool ThrowException { get; }
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="RegexMatcher"/> class. /// Initializes a new instance of the <see cref="RegexMatcher"/> class.
/// </summary> /// </summary>
/// <param name="pattern">The pattern.</param> /// <param name="pattern">The pattern.</param>
/// <param name="ignoreCase">Ignore the case from the pattern.</param> /// <param name="ignoreCase">Ignore the case from the pattern.</param>
/// <param name="throwException">Throw an exception when the internal matching fails because of invalid input.</param>
/// <param name="useRegexExtended">Use RegexExtended (default = true).</param> /// <param name="useRegexExtended">Use RegexExtended (default = true).</param>
/// <param name="matchOperator">The <see cref="Matchers.MatchOperator"/> to use. (default = "Or")</param> /// <param name="matchOperator">The <see cref="Matchers.MatchOperator"/> to use. (default = "Or")</param>
public RegexMatcher( public RegexMatcher(
[RegexPattern] AnyOf<string, StringPattern> pattern, [RegexPattern] AnyOf<string, StringPattern> pattern,
bool ignoreCase = false, bool ignoreCase = false,
bool throwException = false,
bool useRegexExtended = true, bool useRegexExtended = true,
MatchOperator matchOperator = MatchOperator.Or) : MatchOperator matchOperator = MatchOperator.Or) :
this(MatchBehaviour.AcceptOnMatch, new[] { pattern }, ignoreCase, useRegexExtended, matchOperator) this(MatchBehaviour.AcceptOnMatch, new[] { pattern }, ignoreCase, throwException, useRegexExtended, matchOperator)
{ {
} }
@@ -45,15 +50,17 @@ public class RegexMatcher : IStringMatcher, IIgnoreCaseMatcher
/// <param name="matchBehaviour">The match behaviour.</param> /// <param name="matchBehaviour">The match behaviour.</param>
/// <param name="pattern">The pattern.</param> /// <param name="pattern">The pattern.</param>
/// <param name="ignoreCase">Ignore the case from the pattern.</param> /// <param name="ignoreCase">Ignore the case from the pattern.</param>
/// <param name="throwException">Throw an exception when the internal matching fails because of invalid input.</param>
/// <param name="useRegexExtended">Use RegexExtended (default = true).</param> /// <param name="useRegexExtended">Use RegexExtended (default = true).</param>
/// <param name="matchOperator">The <see cref="Matchers.MatchOperator"/> to use. (default = "Or")</param> /// <param name="matchOperator">The <see cref="Matchers.MatchOperator"/> to use. (default = "Or")</param>
public RegexMatcher( public RegexMatcher(
MatchBehaviour matchBehaviour, MatchBehaviour matchBehaviour,
[RegexPattern] AnyOf<string, StringPattern> pattern, [RegexPattern] AnyOf<string, StringPattern> pattern,
bool ignoreCase = false, bool ignoreCase = false,
bool throwException = false,
bool useRegexExtended = true, bool useRegexExtended = true,
MatchOperator matchOperator = MatchOperator.Or) : MatchOperator matchOperator = MatchOperator.Or) :
this(matchBehaviour, new[] { pattern }, ignoreCase, useRegexExtended, matchOperator) this(matchBehaviour, new[] { pattern }, ignoreCase, throwException, useRegexExtended, matchOperator)
{ {
} }
@@ -63,18 +70,21 @@ public class RegexMatcher : IStringMatcher, IIgnoreCaseMatcher
/// <param name="matchBehaviour">The match behaviour.</param> /// <param name="matchBehaviour">The match behaviour.</param>
/// <param name="patterns">The patterns.</param> /// <param name="patterns">The patterns.</param>
/// <param name="ignoreCase">Ignore the case from the pattern.</param> /// <param name="ignoreCase">Ignore the case from the pattern.</param>
/// <param name="throwException">Throw an exception when the internal matching fails because of invalid input.</param>
/// <param name="useRegexExtended">Use RegexExtended (default = true).</param> /// <param name="useRegexExtended">Use RegexExtended (default = true).</param>
/// <param name="matchOperator">The <see cref="Matchers.MatchOperator"/> to use. (default = "Or")</param> /// <param name="matchOperator">The <see cref="Matchers.MatchOperator"/> to use. (default = "Or")</param>
public RegexMatcher( public RegexMatcher(
MatchBehaviour matchBehaviour, MatchBehaviour matchBehaviour,
[RegexPattern] AnyOf<string, StringPattern>[] patterns, [RegexPattern] AnyOf<string, StringPattern>[] patterns,
bool ignoreCase = false, bool ignoreCase = false,
bool throwException = false,
bool useRegexExtended = true, bool useRegexExtended = true,
MatchOperator matchOperator = MatchOperator.Or) MatchOperator matchOperator = MatchOperator.Or)
{ {
_patterns = Guard.NotNull(patterns); _patterns = Guard.NotNull(patterns);
IgnoreCase = ignoreCase; IgnoreCase = ignoreCase;
MatchBehaviour = matchBehaviour; MatchBehaviour = matchBehaviour;
ThrowException = throwException;
MatchOperator = matchOperator; MatchOperator = matchOperator;
RegexOptions options = RegexOptions.Compiled | RegexOptions.Multiline; RegexOptions options = RegexOptions.Compiled | RegexOptions.Multiline;
@@ -87,25 +97,26 @@ public class RegexMatcher : IStringMatcher, IIgnoreCaseMatcher
_expressions = patterns.Select(p => useRegexExtended ? new RegexExtended(p.GetPattern(), options) : new Regex(p.GetPattern(), options)).ToArray(); _expressions = patterns.Select(p => useRegexExtended ? new RegexExtended(p.GetPattern(), options) : new Regex(p.GetPattern(), options)).ToArray();
} }
/// <inheritdoc /> /// <inheritdoc cref="IStringMatcher.IsMatch"/>
public virtual MatchResult IsMatch(string? input) public virtual double IsMatch(string? input)
{ {
var score = MatchScores.Mismatch; double match = MatchScores.Mismatch;
Exception? exception = null;
if (input != null) if (input != null)
{ {
try try
{ {
score = MatchScores.ToScore(_expressions.Select(e => e.IsMatch(input)).ToArray(), MatchOperator); match = MatchScores.ToScore(_expressions.Select(e => e.IsMatch(input)).ToArray(), MatchOperator);
} }
catch (Exception ex) catch (Exception)
{ {
exception = ex; if (ThrowException)
{
throw;
}
} }
} }
return new MatchResult(MatchBehaviourHelper.Convert(MatchBehaviour, score), exception); return MatchBehaviourHelper.Convert(MatchBehaviour, match);
} }
/// <inheritdoc /> /// <inheritdoc />

View File

@@ -9,25 +9,30 @@ namespace WireMock.Matchers.Request;
/// </summary> /// </summary>
public class RequestMatchResult : IRequestMatchResult public class RequestMatchResult : IRequestMatchResult
{ {
/// <inheritdoc /> /// <inheritdoc cref="IRequestMatchResult.TotalScore" />
public double TotalScore => MatchDetails.Sum(md => md.Score); public double TotalScore => MatchDetails.Sum(md => md.Score);
/// <inheritdoc /> /// <inheritdoc cref="IRequestMatchResult.TotalNumber" />
public int TotalNumber => MatchDetails.Count; public int TotalNumber => MatchDetails.Count;
/// <inheritdoc /> /// <inheritdoc cref="IRequestMatchResult.IsPerfectMatch" />
public bool IsPerfectMatch => Math.Abs(TotalScore - TotalNumber) < MatchScores.Tolerance; public bool IsPerfectMatch => Math.Abs(TotalScore - TotalNumber) < MatchScores.Tolerance;
/// <inheritdoc /> /// <inheritdoc cref="IRequestMatchResult.AverageTotalScore" />
public double AverageTotalScore => TotalNumber == 0 ? MatchScores.Mismatch : TotalScore / TotalNumber; public double AverageTotalScore => TotalNumber == 0 ? 0.0 : TotalScore / TotalNumber;
/// <inheritdoc /> /// <inheritdoc cref="IRequestMatchResult.MatchDetails" />
public IList<MatchDetail> MatchDetails { get; } = new List<MatchDetail>(); public IList<MatchDetail> MatchDetails { get; } = new List<MatchDetail>();
/// <inheritdoc /> /// <summary>
public double AddScore(Type matcherType, double score, Exception? exception) /// Adds the score.
/// </summary>
/// <param name="matcherType">The matcher Type.</param>
/// <param name="score">The score.</param>
/// <returns>The score.</returns>
public double AddScore(Type matcherType, double score)
{ {
MatchDetails.Add(new MatchDetail { MatcherType = matcherType, Score = score, Exception = exception }); MatchDetails.Add(new MatchDetail { MatcherType = matcherType, Score = score });
return score; return score;
} }
@@ -39,16 +44,11 @@ public class RequestMatchResult : IRequestMatchResult
/// <returns> /// <returns>
/// A value that indicates the relative order of the objects being compared. The return value has these meanings: Value Meaning Less than zero This instance precedes <paramref name="obj" /> in the sort order. Zero This instance occurs in the same position in the sort order as <paramref name="obj" />. Greater than zero This instance follows <paramref name="obj" /> in the sort order. /// A value that indicates the relative order of the objects being compared. The return value has these meanings: Value Meaning Less than zero This instance precedes <paramref name="obj" /> in the sort order. Zero This instance occurs in the same position in the sort order as <paramref name="obj" />. Greater than zero This instance follows <paramref name="obj" /> in the sort order.
/// </returns> /// </returns>
public int CompareTo(object? obj) public int CompareTo(object obj)
{ {
if (obj == null)
{
return -1;
}
var compareObj = (RequestMatchResult)obj; var compareObj = (RequestMatchResult)obj;
var averageTotalScoreResult = compareObj.AverageTotalScore.CompareTo(AverageTotalScore); int averageTotalScoreResult = compareObj.AverageTotalScore.CompareTo(AverageTotalScore);
// In case the score is equal, prefer the one with the most matchers. // In case the score is equal, prefer the one with the most matchers.
return averageTotalScoreResult == 0 ? compareObj.TotalNumber.CompareTo(TotalNumber) : averageTotalScoreResult; return averageTotalScoreResult == 0 ? compareObj.TotalNumber.CompareTo(TotalNumber) : averageTotalScoreResult;

View File

@@ -2,7 +2,7 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using Stef.Validation; using Stef.Validation;
using WireMock.Matchers.Helpers; using WireMock.Types;
using WireMock.Util; using WireMock.Util;
namespace WireMock.Matchers.Request; namespace WireMock.Matchers.Request;
@@ -145,16 +145,74 @@ public class RequestMessageBodyMatcher : IRequestMatcher
/// <inheritdoc /> /// <inheritdoc />
public double GetMatchingScore(IRequestMessage requestMessage, IRequestMatchResult requestMatchResult) public double GetMatchingScore(IRequestMessage requestMessage, IRequestMatchResult requestMatchResult)
{ {
var (score, exception) = CalculateMatchScore(requestMessage).Expand(); double score = CalculateMatchScore(requestMessage);
return requestMatchResult.AddScore(GetType(), score, exception); return requestMatchResult.AddScore(GetType(), score);
} }
private MatchResult CalculateMatchScore(IRequestMessage requestMessage) private static double CalculateMatchScore(IRequestMessage requestMessage, IMatcher matcher)
{ {
if (Matchers != null && Matchers.Any()) if (matcher is NotNullOrEmptyMatcher notNullOrEmptyMatcher)
{ {
var results = Matchers.Select(matcher => BodyDataMatchScoreCalculator.CalculateMatchScore(requestMessage.BodyData, matcher)).ToArray(); switch (requestMessage.BodyData?.DetectedBodyType)
return MatchResult.From(results, MatchOperator); {
case BodyType.Json:
case BodyType.String:
case BodyType.FormUrlEncoded:
return notNullOrEmptyMatcher.IsMatch(requestMessage.BodyData.BodyAsString);
case BodyType.Bytes:
return notNullOrEmptyMatcher.IsMatch(requestMessage.BodyData.BodyAsBytes);
default:
return MatchScores.Mismatch;
}
}
if (matcher is ExactObjectMatcher exactObjectMatcher)
{
// If the body is a byte array, try to match.
var detectedBodyType = requestMessage.BodyData?.DetectedBodyType;
if (detectedBodyType is BodyType.Bytes or BodyType.String or BodyType.FormUrlEncoded)
{
return exactObjectMatcher.IsMatch(requestMessage.BodyData?.BodyAsBytes);
}
}
// Check if the matcher is a IObjectMatcher
if (matcher is IObjectMatcher objectMatcher)
{
// If the body is a JSON object, try to match.
if (requestMessage?.BodyData?.DetectedBodyType == BodyType.Json)
{
return objectMatcher.IsMatch(requestMessage.BodyData.BodyAsJson);
}
// If the body is a byte array, try to match.
if (requestMessage?.BodyData?.DetectedBodyType == BodyType.Bytes)
{
return objectMatcher.IsMatch(requestMessage.BodyData.BodyAsBytes);
}
}
// Check if the matcher is a IStringMatcher
if (matcher is IStringMatcher stringMatcher)
{
// If the body is a Json or a String, use the BodyAsString to match on.
if (requestMessage?.BodyData?.DetectedBodyType is BodyType.Json or BodyType.String or BodyType.FormUrlEncoded)
{
return stringMatcher.IsMatch(requestMessage.BodyData.BodyAsString);
}
}
return MatchScores.Mismatch;
}
private double CalculateMatchScore(IRequestMessage requestMessage)
{
if (Matchers != null)
{
var matchersResult = Matchers.Select(matcher => CalculateMatchScore(requestMessage, matcher)).ToArray();
return MatchScores.ToScore(matchersResult, MatchOperator);
} }
if (Func != null) if (Func != null)
@@ -182,6 +240,6 @@ public class RequestMessageBodyMatcher : IRequestMatcher
return MatchScores.ToScore(BodyDataFunc(requestMessage.BodyData)); return MatchScores.ToScore(BodyDataFunc(requestMessage.BodyData));
} }
return default; return MatchScores.Mismatch;
} }
} }

Some files were not shown because too many files have changed in this diff Show More