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
211 changed files with 2678 additions and 6442 deletions

View File

@@ -1,63 +1,3 @@
# 1.5.39 (09 October 2023)
- [#1006](https://github.com/WireMock-Net/WireMock.Net/pull/1006) - Fix RequestMessageParamMatcher : RejectOnMatch [bug] contributed by [StefH](https://github.com/StefH)
- [#997](https://github.com/WireMock-Net/WireMock.Net/issues/997) - JmesPathMatcher or and MatchOperator working in version 1.5.34 but not 1.5.35 [bug]
# 1.5.38 (02 October 2023)
- [#1005](https://github.com/WireMock-Net/WireMock.Net/pull/1005) - Support for xml namespaces in XPathMatcher [feature] contributed by [cal-schleupen](https://github.com/cal-schleupen)
# 1.5.37 (27 September 2023)
- [#998](https://github.com/WireMock-Net/WireMock.Net/pull/998) - Add JmesPathMatcher UnitTests [test] contributed by [StefH](https://github.com/StefH)
- [#1004](https://github.com/WireMock-Net/WireMock.Net/pull/1004) - Fix MappingModel to map IgnoreCase and RejectOnMatch for Headers, Cookies and Parameters [bug] contributed by [StefH](https://github.com/StefH)
- [#1003](https://github.com/WireMock-Net/WireMock.Net/issues/1003) - Store Mapping per POST request ignores "IgnoreCase" property of HeaderModel [bug]
# 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)
- [#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)
@@ -1006,7 +946,7 @@
- [#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)
- [#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]
- [#78](https://github.com/WireMock-Net/WireMock.Net/issues/78) - WireMock not working when attempting to access from anything other than localhost.
@@ -1033,7 +973,7 @@
# 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)
- [#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
- [#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

View File

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

View File

@@ -1,6 +1,6 @@
rem https://github.com/StefH/GitHubReleaseNotes
SET version=1.5.39
SET version=1.5.27
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))
## :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,5 +1,7 @@
# 1.5.39 (09 October 2023)
- #1006 Fix RequestMessageParamMatcher : RejectOnMatch [bug]
- #997 JmesPathMatcher or and MatchOperator working in version 1.5.34 but not 1.5.35 [bug]
# 1.5.27 (03 June 2023)
- #946 Add warning logging when sending a request to a Webhook does not return status 200 [feature]
- #949 Add &quot;.NET Framework 4.7&quot; to WireMock.Net.FluentAssertions [feature]
- #928 TypeLoadException when using WithHeader method. [bug]
- #945 Webhook logging [feature]
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.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.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)
@@ -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
[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
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
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
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
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WireMockAzureQueueProxy", "examples\WireMockAzureQueueProxy\WireMockAzureQueueProxy.csproj", "{ADB557D8-D66B-4387-912B-3F73E290B478}"
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
GlobalSection(SolutionConfigurationPlatforms) = preSolution
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}.Release|Any CPU.ActiveCfg = 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
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -335,10 +309,6 @@ Global
{7C2A9DE8-C89F-4841-9058-6B9BF81E5E34} = {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}
{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
GlobalSection(ExtensibilityGlobals) = postSolution
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/=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/=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/=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/=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/=SSL/@EntryIndexedValue">SSL</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/=randomizer/@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/=Stef/@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()
.WithGlobalProcessingDelay(1077)
.WithoutGlobalProcessingDelay()
.Build();
settings1.GlobalProcessingDelay = 1077;

View File

@@ -28,10 +28,10 @@
<ItemGroup>
<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="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>

View File

@@ -3,7 +3,6 @@
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
<DefineConstants>$(DefineConstants);GRAPHQL;MIMEKIT</DefineConstants>
</PropertyGroup>
<ItemGroup>
@@ -22,10 +21,16 @@
<Compile Remove="__admin\mappings\1.cs" />
</ItemGroup>
<ItemGroup>
<None Remove="__admin\mappings\array.json" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\WireMock.Net\WireMock.Net.csproj" />
<!--<PackageReference Include="Handlebars.Net.Helpers" Version="2.*" />-->
<PackageReference Include="log4net" Version="2.0.15" />
<PackageReference Include="Microsoft.Extensions.Configuration" Version="6.0.0" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
</ItemGroup>
<ItemGroup>
@@ -35,6 +40,15 @@
<None Update="nlog.config">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</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>
</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>
<ProjectReference Include="..\..\src\WireMock.Net\WireMock.Net.csproj" />
<PackageReference Include="Handlebars.Net.Helpers" Version="2.4.0" />
<PackageReference Include="Handlebars.Net.Helpers.DynamicLinq" Version="2.4.0" />
<PackageReference Include="Handlebars.Net.Helpers.Json" Version="2.4.0" />
<PackageReference Include="Handlebars.Net.Helpers.XPath" Version="2.4.0" />
<PackageReference Include="Handlebars.Net.Helpers.Xeger" Version="2.4.0" />
<PackageReference Include="Handlebars.Net.Helpers.Random" Version="2.4.0" />
<PackageReference Include="Handlebars.Net.Helpers" Version="2.*" />
<PackageReference Include="Handlebars.Net.Helpers.DynamicLinq" Version="2.*" />
<PackageReference Include="Handlebars.Net.Helpers.Json" Version="2.3.*" />
<PackageReference Include="Handlebars.Net.Helpers.XPath" Version="2.*" />
<PackageReference Include="Handlebars.Net.Helpers.Xeger" Version="2.3.*" />
<PackageReference Include="Handlebars.Net.Helpers.Random" Version="2.3.*" />
<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>

View File

@@ -31,14 +31,14 @@
<ItemGroup>
<ProjectReference Include="..\..\src\WireMock.Net\WireMock.Net.csproj" />
<PackageReference Include="Handlebars.Net.Helpers" Version="2.4.0" />
<PackageReference Include="Handlebars.Net.Helpers.DynamicLinq" Version="2.4.0" />
<PackageReference Include="Handlebars.Net.Helpers.Json" Version="2.4.0" />
<PackageReference Include="Handlebars.Net.Helpers.XPath" Version="2.4.0" />
<PackageReference Include="Handlebars.Net.Helpers.Xeger" Version="2.4.0" />
<PackageReference Include="Handlebars.Net.Helpers.Random" Version="2.4.0" />
<PackageReference Include="Handlebars.Net.Helpers" Version="2.*" />
<PackageReference Include="Handlebars.Net.Helpers.DynamicLinq" Version="2.*" />
<PackageReference Include="Handlebars.Net.Helpers.Json" Version="2.3.*" />
<PackageReference Include="Handlebars.Net.Helpers.XPath" Version="2.*" />
<PackageReference Include="Handlebars.Net.Helpers.Xeger" Version="2.3.*" />
<PackageReference Include="Handlebars.Net.Helpers.Random" Version="2.3.*" />
<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>

View File

@@ -28,14 +28,14 @@
<ItemGroup>
<ProjectReference Include="..\..\src\WireMock.Net\WireMock.Net.csproj" />
<PackageReference Include="Handlebars.Net.Helpers" Version="2.4.0" />
<PackageReference Include="Handlebars.Net.Helpers.DynamicLinq" Version="2.4.0" />
<PackageReference Include="Handlebars.Net.Helpers.Json" Version="2.4.0" />
<PackageReference Include="Handlebars.Net.Helpers.XPath" Version="2.4.0" />
<PackageReference Include="Handlebars.Net.Helpers.Xeger" Version="2.4.0" />
<PackageReference Include="Handlebars.Net.Helpers.Random" Version="2.4.0" />
<PackageReference Include="Handlebars.Net.Helpers" Version="2.*" />
<PackageReference Include="Handlebars.Net.Helpers.DynamicLinq" Version="2.*" />
<PackageReference Include="Handlebars.Net.Helpers.Json" Version="2.3.*" />
<PackageReference Include="Handlebars.Net.Helpers.XPath" Version="2.*" />
<PackageReference Include="Handlebars.Net.Helpers.Xeger" Version="2.3.*" />
<PackageReference Include="Handlebars.Net.Helpers.Random" Version="2.3.*" />
<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>

View File

@@ -42,36 +42,6 @@ namespace WireMock.Net.ConsoleApplication
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()
{
var mappingBuilder = new MappingBuilder();
@@ -137,7 +107,6 @@ namespace WireMock.Net.ConsoleApplication
Urls = new[] { url1, url2, url3 },
StartAdminInterface = true,
ReadStaticMappings = true,
SaveUnmatchedRequests = true,
WatchStaticMappings = true,
WatchStaticMappingsInSubdirectories = true,
//ProxyAndRecordSettings = new ProxyAndRecordSettings
@@ -167,51 +136,7 @@ namespace WireMock.Net.ConsoleApplication
//server.SetAzureADAuthentication("6c2a4722-f3b9-4970-b8fc-fac41e29stef", "8587fde1-7824-42c7-8592-faf92b04stef");
// 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
server
.Given(Request.Create()
@@ -751,9 +676,8 @@ namespace WireMock.Net.ConsoleApplication
}));
server.Given(Request.Create().WithPath(new WildcardMatcher("/multi-webhook", true)).UsingPost())
.WithWebhook
(
new Webhook
.WithWebhook(new[] {
new Webhook()
{
Request = new WebhookRequest
{
@@ -761,13 +685,12 @@ namespace WireMock.Net.ConsoleApplication
Method = "post",
BodyData = new BodyData
{
BodyAsString = "OK 1!",
DetectedBodyType = BodyType.String
BodyAsString = "OK 1!", DetectedBodyType = BodyType.String
},
Delay = 1000
}
},
new Webhook
new Webhook()
{
Request = new WebhookRequest
{
@@ -782,7 +705,7 @@ namespace WireMock.Net.ConsoleApplication
MaximumRandomDelay = 7000
}
}
)
})
.WithWebhookFireAndForget(true)
.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">
<HintPath>..\..\packages\AnyOf.0.3.0\lib\net45\AnyOf.dll</HintPath>
</Reference>
<Reference Include="Handlebars, Version=2.1.4.0, Culture=neutral, PublicKeyToken=22225d0bf33cd661, processorArchitecture=MSIL">
<HintPath>..\..\packages\Handlebars.Net.2.1.4\lib\net452\Handlebars.dll</HintPath>
<Reference Include="Handlebars, Version=2.1.2.0, Culture=neutral, PublicKeyToken=22225d0bf33cd661, processorArchitecture=MSIL">
<HintPath>..\..\packages\Handlebars.Net.2.1.2\lib\net452\Handlebars.dll</HintPath>
</Reference>
<Reference Include="Handlebars.Net.Helpers, Version=2.4.0.0, Culture=neutral, PublicKeyToken=00d131fae0c250bc, processorArchitecture=MSIL">
<HintPath>..\..\packages\Handlebars.Net.Helpers.2.4.0\lib\net452\Handlebars.Net.Helpers.dll</HintPath>
<Reference Include="Handlebars.Net.Helpers, Version=2.3.12.0, Culture=neutral, PublicKeyToken=00d131fae0c250bc, processorArchitecture=MSIL">
<HintPath>..\..\packages\Handlebars.Net.Helpers.2.3.12\lib\net452\Handlebars.Net.Helpers.dll</HintPath>
</Reference>
<Reference Include="HandlebarsDotNet.Helpers.Core, Version=2.4.0.0, Culture=neutral, PublicKeyToken=00d131fae0c250bc, processorArchitecture=MSIL">
<HintPath>..\..\packages\Handlebars.Net.Helpers.Core.2.4.0\lib\net452\HandlebarsDotNet.Helpers.Core.dll</HintPath>
<Reference Include="HandlebarsDotNet.Helpers.Core, Version=2.3.12.0, Culture=neutral, PublicKeyToken=00d131fae0c250bc, processorArchitecture=MSIL">
<HintPath>..\..\packages\Handlebars.Net.Helpers.Core.2.3.12\lib\net452\HandlebarsDotNet.Helpers.Core.dll</HintPath>
</Reference>
<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>
@@ -56,7 +56,7 @@
<HintPath>..\..\packages\Microsoft.Owin.Host.HttpListener.3.1.0\lib\net45\Microsoft.Owin.Host.HttpListener.dll</HintPath>
</Reference>
<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 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>
@@ -67,7 +67,6 @@
<Reference Include="System" />
<Reference Include="System.Configuration" />
<Reference Include="System.Core" />
<Reference Include="System.Net.Http" />
<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>
</Reference>

View File

@@ -1,12 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="AnyOf" version="0.3.0" targetFramework="net452" />
<package id="Handlebars.Net" version="2.1.4" targetFramework="net452" />
<package id="Handlebars.Net.Helpers" version="2.4.0" targetFramework="net452" />
<package id="Handlebars.Net.Helpers.Core" version="2.4.0" targetFramework="net452" />
<package id="Handlebars.Net" version="2.1.2" targetFramework="net452" />
<package id="Handlebars.Net.Helpers" version="2.3.12" 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="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="Stef.Validation" version="0.1.1" 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">
<HintPath>..\..\packages\AnyOf.0.3.0\lib\net45\AnyOf.dll</HintPath>
</Reference>
<Reference Include="Handlebars, Version=2.1.4.0, Culture=neutral, PublicKeyToken=22225d0bf33cd661, processorArchitecture=MSIL">
<HintPath>..\..\packages\Handlebars.Net.2.1.4\lib\net46\Handlebars.dll</HintPath>
<Reference Include="Handlebars, Version=2.1.2.0, Culture=neutral, PublicKeyToken=22225d0bf33cd661, processorArchitecture=MSIL">
<HintPath>..\..\packages\Handlebars.Net.2.1.2\lib\net46\Handlebars.dll</HintPath>
</Reference>
<Reference Include="Handlebars.Net.Helpers, Version=2.4.0.0, Culture=neutral, PublicKeyToken=00d131fae0c250bc, processorArchitecture=MSIL">
<HintPath>..\..\packages\Handlebars.Net.Helpers.2.4.0\lib\net46\Handlebars.Net.Helpers.dll</HintPath>
<Reference Include="Handlebars.Net.Helpers, Version=2.3.12.0, Culture=neutral, PublicKeyToken=00d131fae0c250bc, processorArchitecture=MSIL">
<HintPath>..\..\packages\Handlebars.Net.Helpers.2.3.12\lib\net46\Handlebars.Net.Helpers.dll</HintPath>
</Reference>
<Reference Include="HandlebarsDotNet.Helpers.Core, Version=2.4.0.0, Culture=neutral, PublicKeyToken=00d131fae0c250bc, processorArchitecture=MSIL">
<HintPath>..\..\packages\Handlebars.Net.Helpers.Core.2.4.0\lib\net46\HandlebarsDotNet.Helpers.Core.dll</HintPath>
<Reference Include="HandlebarsDotNet.Helpers.Core, Version=2.3.12.0, Culture=neutral, PublicKeyToken=00d131fae0c250bc, processorArchitecture=MSIL">
<HintPath>..\..\packages\Handlebars.Net.Helpers.Core.2.3.12\lib\net46\HandlebarsDotNet.Helpers.Core.dll</HintPath>
</Reference>
<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>
@@ -54,7 +54,7 @@
<HintPath>..\..\packages\Microsoft.Extensions.DependencyInjection.Abstractions.2.2.0\lib\netstandard2.0\Microsoft.Extensions.DependencyInjection.Abstractions.dll</HintPath>
</Reference>
<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 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>

View File

@@ -1,12 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="AnyOf" version="0.3.0" targetFramework="net461" />
<package id="Handlebars.Net" version="2.1.4" targetFramework="net461" />
<package id="Handlebars.Net.Helpers" version="2.4.0" targetFramework="net461" />
<package id="Handlebars.Net.Helpers.Core" version="2.4.0" targetFramework="net461" />
<package id="Handlebars.Net" version="2.1.2" targetFramework="net461" />
<package id="Handlebars.Net.Helpers" version="2.3.12" 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="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="Stef.Validation" version="0.1.1" 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" />
<bindingRedirect oldVersion="0.0.0.0-6.25.0.0" newVersion="6.25.0.0" />
</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>
</runtime>
</configuration>

View File

@@ -46,32 +46,32 @@
<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>
</Reference>
<Reference Include="Handlebars, Version=2.1.4.0, Culture=neutral, PublicKeyToken=22225d0bf33cd661, processorArchitecture=MSIL">
<HintPath>..\..\packages\Handlebars.Net.2.1.4\lib\net46\Handlebars.dll</HintPath>
<Reference Include="Handlebars, Version=2.1.2.0, Culture=neutral, PublicKeyToken=22225d0bf33cd661, processorArchitecture=MSIL">
<HintPath>..\..\packages\Handlebars.Net.2.1.2\lib\net46\Handlebars.dll</HintPath>
</Reference>
<Reference Include="Handlebars.Net.Helpers, Version=2.4.0.0, Culture=neutral, PublicKeyToken=00d131fae0c250bc, processorArchitecture=MSIL">
<HintPath>..\..\packages\Handlebars.Net.Helpers.2.4.0\lib\net46\Handlebars.Net.Helpers.dll</HintPath>
<Reference Include="Handlebars.Net.Helpers, Version=2.3.12.0, Culture=neutral, PublicKeyToken=00d131fae0c250bc, processorArchitecture=MSIL">
<HintPath>..\..\packages\Handlebars.Net.Helpers.2.3.12\lib\net46\Handlebars.Net.Helpers.dll</HintPath>
</Reference>
<Reference Include="HandlebarsDotNet.Helpers.Core, Version=2.4.0.0, Culture=neutral, PublicKeyToken=00d131fae0c250bc, processorArchitecture=MSIL">
<HintPath>..\..\packages\Handlebars.Net.Helpers.Core.2.4.0\lib\net46\HandlebarsDotNet.Helpers.Core.dll</HintPath>
<Reference Include="HandlebarsDotNet.Helpers.Core, Version=2.3.12.0, Culture=neutral, PublicKeyToken=00d131fae0c250bc, processorArchitecture=MSIL">
<HintPath>..\..\packages\Handlebars.Net.Helpers.Core.2.3.12\lib\net46\HandlebarsDotNet.Helpers.Core.dll</HintPath>
</Reference>
<Reference Include="HandlebarsDotNet.Helpers.DynamicLinq, Version=2.4.0.0, Culture=neutral, PublicKeyToken=00d131fae0c250bc, processorArchitecture=MSIL">
<HintPath>..\..\packages\Handlebars.Net.Helpers.DynamicLinq.2.4.0\lib\net46\HandlebarsDotNet.Helpers.DynamicLinq.dll</HintPath>
<Reference Include="HandlebarsDotNet.Helpers.DynamicLinq, Version=2.3.12.0, Culture=neutral, PublicKeyToken=00d131fae0c250bc, processorArchitecture=MSIL">
<HintPath>..\..\packages\Handlebars.Net.Helpers.DynamicLinq.2.3.12\lib\net46\HandlebarsDotNet.Helpers.DynamicLinq.dll</HintPath>
</Reference>
<Reference Include="HandlebarsDotNet.Helpers.Humanizer, Version=2.4.0.0, Culture=neutral, PublicKeyToken=00d131fae0c250bc, processorArchitecture=MSIL">
<HintPath>..\..\packages\Handlebars.Net.Helpers.Humanizer.2.4.0\lib\net46\HandlebarsDotNet.Helpers.Humanizer.dll</HintPath>
<Reference Include="HandlebarsDotNet.Helpers.Humanizer, Version=2.3.12.0, Culture=neutral, PublicKeyToken=00d131fae0c250bc, processorArchitecture=MSIL">
<HintPath>..\..\packages\Handlebars.Net.Helpers.Humanizer.2.3.12\lib\net46\HandlebarsDotNet.Helpers.Humanizer.dll</HintPath>
</Reference>
<Reference Include="HandlebarsDotNet.Helpers.Json, Version=2.4.0.0, Culture=neutral, PublicKeyToken=00d131fae0c250bc, processorArchitecture=MSIL">
<HintPath>..\..\packages\Handlebars.Net.Helpers.Json.2.4.0\lib\net46\HandlebarsDotNet.Helpers.Json.dll</HintPath>
<Reference Include="HandlebarsDotNet.Helpers.Json, Version=2.3.12.0, Culture=neutral, PublicKeyToken=00d131fae0c250bc, processorArchitecture=MSIL">
<HintPath>..\..\packages\Handlebars.Net.Helpers.Json.2.3.12\lib\net46\HandlebarsDotNet.Helpers.Json.dll</HintPath>
</Reference>
<Reference Include="HandlebarsDotNet.Helpers.Random, Version=2.4.0.0, Culture=neutral, PublicKeyToken=00d131fae0c250bc, processorArchitecture=MSIL">
<HintPath>..\..\packages\Handlebars.Net.Helpers.Random.2.4.0\lib\net46\HandlebarsDotNet.Helpers.Random.dll</HintPath>
<Reference Include="HandlebarsDotNet.Helpers.Random, Version=2.3.12.0, Culture=neutral, PublicKeyToken=00d131fae0c250bc, processorArchitecture=MSIL">
<HintPath>..\..\packages\Handlebars.Net.Helpers.Random.2.3.12\lib\net46\HandlebarsDotNet.Helpers.Random.dll</HintPath>
</Reference>
<Reference Include="HandlebarsDotNet.Helpers.Xeger, Version=2.4.0.0, Culture=neutral, PublicKeyToken=00d131fae0c250bc, processorArchitecture=MSIL">
<HintPath>..\..\packages\Handlebars.Net.Helpers.Xeger.2.4.0\lib\net46\HandlebarsDotNet.Helpers.Xeger.dll</HintPath>
<Reference Include="HandlebarsDotNet.Helpers.Xeger, Version=2.3.12.0, Culture=neutral, PublicKeyToken=00d131fae0c250bc, processorArchitecture=MSIL">
<HintPath>..\..\packages\Handlebars.Net.Helpers.Xeger.2.3.12\lib\net46\HandlebarsDotNet.Helpers.Xeger.dll</HintPath>
</Reference>
<Reference Include="HandlebarsDotNet.Helpers.XPath, Version=2.4.0.0, Culture=neutral, PublicKeyToken=00d131fae0c250bc, processorArchitecture=MSIL">
<HintPath>..\..\packages\Handlebars.Net.Helpers.XPath.2.4.0\lib\net46\HandlebarsDotNet.Helpers.XPath.dll</HintPath>
<Reference Include="HandlebarsDotNet.Helpers.XPath, Version=2.3.12.0, Culture=neutral, PublicKeyToken=00d131fae0c250bc, processorArchitecture=MSIL">
<HintPath>..\..\packages\Handlebars.Net.Helpers.XPath.2.3.12\lib\net46\HandlebarsDotNet.Helpers.XPath.dll</HintPath>
</Reference>
<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>
@@ -257,16 +257,16 @@
<HintPath>..\..\packages\Namotion.Reflection.2.0.10\lib\net45\Namotion.Reflection.dll</HintPath>
</Reference>
<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 Include="NJsonSchema, Version=10.7.2.0, Culture=neutral, PublicKeyToken=c2f9c3bdfae56102, processorArchitecture=MSIL">
<HintPath>..\..\packages\NJsonSchema.10.7.2\lib\net45\NJsonSchema.dll</HintPath>
<Reference Include="NJsonSchema, Version=10.6.10.0, Culture=neutral, PublicKeyToken=c2f9c3bdfae56102, processorArchitecture=MSIL">
<HintPath>..\..\packages\NJsonSchema.10.6.10\lib\net45\NJsonSchema.dll</HintPath>
</Reference>
<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>
</Reference>
<Reference Include="NSwag.Core, Version=13.16.1.0, Culture=neutral, PublicKeyToken=c2d88086e098d109, processorArchitecture=MSIL">
<HintPath>..\..\packages\NSwag.Core.13.16.1\lib\net45\NSwag.Core.dll</HintPath>
<Reference Include="NSwag.Core, Version=13.15.10.0, Culture=neutral, PublicKeyToken=c2d88086e098d109, processorArchitecture=MSIL">
<HintPath>..\..\packages\NSwag.Core.13.15.10\lib\net45\NSwag.Core.dll</HintPath>
</Reference>
<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>
@@ -302,8 +302,8 @@
<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>
</Reference>
<Reference Include="System.Linq.Dynamic.Core, Version=1.3.1.0, Culture=neutral, PublicKeyToken=0f07ec44de6ac832, processorArchitecture=MSIL">
<HintPath>..\..\packages\System.Linq.Dynamic.Core.1.3.1\lib\net46\System.Linq.Dynamic.Core.dll</HintPath>
<Reference Include="System.Linq.Dynamic.Core, Version=1.2.23.0, Culture=neutral, PublicKeyToken=0f07ec44de6ac832, processorArchitecture=MSIL">
<HintPath>..\..\packages\System.Linq.Dynamic.Core.1.2.23\lib\net46\System.Linq.Dynamic.Core.dll</HintPath>
</Reference>
<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>

View File

@@ -2,15 +2,15 @@
<packages>
<package id="AnyOf" version="0.3.0" 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.Helpers" version="2.4.0" targetFramework="net472" />
<package id="Handlebars.Net.Helpers.Core" version="2.4.0" targetFramework="net472" />
<package id="Handlebars.Net.Helpers.DynamicLinq" version="2.4.0" targetFramework="net472" />
<package id="Handlebars.Net.Helpers.Humanizer" version="2.4.0" targetFramework="net472" />
<package id="Handlebars.Net.Helpers.Json" version="2.4.0" targetFramework="net472" />
<package id="Handlebars.Net.Helpers.Random" version="2.4.0" targetFramework="net472" />
<package id="Handlebars.Net.Helpers.Xeger" version="2.4.0" targetFramework="net472" />
<package id="Handlebars.Net.Helpers.XPath" version="2.4.0" targetFramework="net472" />
<package id="Handlebars.Net" version="2.1.2" targetFramework="net472" />
<package id="Handlebars.Net.Helpers" version="2.3.12" targetFramework="net472" />
<package id="Handlebars.Net.Helpers.Core" version="2.3.12" targetFramework="net472" />
<package id="Handlebars.Net.Helpers.DynamicLinq" version="2.3.12" targetFramework="net472" />
<package id="Handlebars.Net.Helpers.Humanizer" version="2.3.12" targetFramework="net472" />
<package id="Handlebars.Net.Helpers.Json" version="2.3.12" targetFramework="net472" />
<package id="Handlebars.Net.Helpers.Random" version="2.3.12" targetFramework="net472" />
<package id="Handlebars.Net.Helpers.Xeger" version="2.3.12" 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.Core" 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.Net.Http.Headers" version="2.2.0" targetFramework="net472" />
<package id="Namotion.Reflection" version="2.0.10" targetFramework="net472" />
<package id="Newtonsoft.Json" version="13.0.3" targetFramework="net472" />
<package id="NJsonSchema" version="10.7.2" targetFramework="net472" />
<package id="Newtonsoft.Json" version="13.0.1" targetFramework="net472" />
<package id="NJsonSchema" version="10.6.10" 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="RandomDataGenerator.Net" version="1.0.17" 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.IdentityModel.Tokens.Jwt" version="6.25.0" 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.Numerics.Vectors" version="4.5.0" targetFramework="net472" />
<package id="System.Reflection.Metadata" version="1.6.0" targetFramework="net472" />

View File

@@ -9,7 +9,7 @@
<ItemGroup>
<ProjectReference Include="..\..\src\WireMock.Net\WireMock.Net.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>

View File

@@ -7,7 +7,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
</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>
</Reference>
<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 Include="System" />
<Reference Include="System.Core" />

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<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>

View File

@@ -1,5 +1,6 @@
using System;
using System.IO;
using WireMock.Net.OpenApiParser.Types;
using WireMock.RequestBuilders;
using WireMock.ResponseBuilders;
@@ -18,7 +19,7 @@ class Program
private static void RunMockServerWithDynamicExampleGeneration()
{
// 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.ReadKey();

View File

@@ -46,7 +46,7 @@
<HintPath>..\..\packages\Microsoft.Owin.Hosting.2.0.2\lib\net45\Microsoft.Owin.Hosting.dll</HintPath>
</Reference>
<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 Include="Owin, Version=1.0.0.0, Culture=neutral, PublicKeyToken=f0ebd12fd5e55cc5, processorArchitecture=MSIL">
<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.Host.HttpListener" 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="SimMetrics.Net" version="1.0.5" targetFramework="net452" />
<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"));
if (!WireMockServerSettingsParser.TryParseArguments(args, Environment.GetEnvironmentVariables(), out var settings, new WireMockLog4NetLogger()))
if (!WireMockServerSettingsParser.TryParseArguments(args, out var settings, new WireMockLog4NetLogger()))
{
return;
}

View File

@@ -13,7 +13,7 @@ public class Program
{
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}'")));

View File

@@ -46,7 +46,7 @@
<HintPath>..\..\packages\Microsoft.Owin.Host.HttpListener.4.0.0\lib\net451\Microsoft.Owin.Host.HttpListener.dll</HintPath>
</Reference>
<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 Include="System" />
<Reference Include="System.Configuration" />

View File

@@ -3,5 +3,5 @@
<package id="log4net" version="2.0.15" 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="Newtonsoft.Json" version="13.0.3" targetFramework="net452" />
<package id="Newtonsoft.Json" version="13.0.1" targetFramework="net452" />
</packages>

View File

@@ -9,7 +9,7 @@ static class Program
{
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}'")));

View File

@@ -39,8 +39,8 @@
<StartupObject>WireMock.Net.StandAlone.Net461.Program</StartupObject>
</PropertyGroup>
<ItemGroup>
<Reference Include="Handlebars, Version=2.1.4.0, Culture=neutral, PublicKeyToken=22225d0bf33cd661, processorArchitecture=MSIL">
<HintPath>..\..\packages\Handlebars.Net.2.1.4\lib\net46\Handlebars.dll</HintPath>
<Reference Include="Handlebars, Version=2.1.2.0, Culture=neutral, PublicKeyToken=22225d0bf33cd661, processorArchitecture=MSIL">
<HintPath>..\..\packages\Handlebars.Net.2.1.2\lib\net46\Handlebars.dll</HintPath>
</Reference>
<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>
@@ -205,7 +205,7 @@
<HintPath>..\..\packages\MimeKitLite.2.0.7\lib\net45\MimeKitLite.dll</HintPath>
</Reference>
<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 Include="Owin, Version=1.0.0.0, Culture=neutral, PublicKeyToken=f0ebd12fd5e55cc5, processorArchitecture=MSIL">
<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">
<HintPath>..\..\packages\System.IO.Pipelines.4.5.3\lib\netstandard2.0\System.IO.Pipelines.dll</HintPath>
</Reference>
<Reference Include="System.Linq.Dynamic.Core, Version=1.3.1.0, Culture=neutral, PublicKeyToken=0f07ec44de6ac832, processorArchitecture=MSIL">
<HintPath>..\..\packages\System.Linq.Dynamic.Core.1.3.1\lib\net46\System.Linq.Dynamic.Core.dll</HintPath>
<Reference Include="System.Linq.Dynamic.Core, Version=1.2.23.0, Culture=neutral, PublicKeyToken=0f07ec44de6ac832, processorArchitecture=MSIL">
<HintPath>..\..\packages\System.Linq.Dynamic.Core.1.2.23\lib\net46\System.Linq.Dynamic.Core.dll</HintPath>
</Reference>
<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>

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<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.Core" 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.Hosting" version="4.2.2" 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="RestEase" version="1.5.7" 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.Diagnostics.DiagnosticSource" version="4.5.1" 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.Numerics.Vectors" version="4.5.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>
<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>

View File

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

View File

@@ -12,7 +12,7 @@
<ItemGroup>
<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>

View File

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

View File

@@ -39,42 +39,14 @@ public class MatcherModel
/// <summary>
/// The Operator to use when multiple patterns are defined. Optional.
/// - null = Same as "or".
/// - "or" = Only one pattern is required to match.
/// - "or" = Only one pattern should match.
/// - "and" = All patterns should match.
/// - "average" = The average value from all patterns.
/// </summary>
public string? MatchOperator { get; set; }
#region JsonPartialMatcher and JsonPartialWildcardMatcher
/// <summary>
/// Support Regex.
/// Support Regex, only used for JsonPartialMatcher.
/// </summary>
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
#region XPathMatcher
public XmlNamespace[]? XmlNamespaceMap { get; set; }
#endregion
}

View File

@@ -16,11 +16,6 @@ public class ParamModel
/// </summary>
public bool? IgnoreCase { get; set; }
/// <summary>
/// Gets or sets the Reject on match for the Param Name.
/// </summary>
public bool? RejectOnMatch { get; set; }
/// <summary>
/// Gets or sets the matchers.
/// </summary>

View File

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

View File

@@ -1,21 +0,0 @@
namespace WireMock.Admin.Mappings;
/// <summary>
/// Defines an xml namespace consisting of prefix and uri.
/// <example>xmlns:i="http://www.w3.org/2001/XMLSchema-instance"</example>
/// </summary>
[FluentBuilder.AutoGenerateBuilder]
public class XmlNamespace
{
/// <summary>
/// The prefix.
/// <example>i</example>
/// </summary>
public string Prefix { get; set; } = null!;
/// <summary>
/// The uri.
/// <example>http://www.w3.org/2001/XMLSchema-instance</example>
/// </summary>
public string Uri { get; set; } = null!;
}

View File

@@ -62,6 +62,11 @@ public class SettingsModel
/// </summary>
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>
/// Use the RegexExtended instead of the default <see cref="Regex"/>. (default set to <c>true</c>).
/// </summary>

View File

@@ -1,120 +1,121 @@
using JetBrains.Annotations;
using System.Collections.Generic;
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
namespace WireMock.Handlers
{
/// <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>
/// <returns>The folder name.</returns>
string GetMappingFolder();
public interface IFileSystemHandler
{
/// <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>
/// Determines whether the given path refers to an existing directory on disk.
/// </summary>
/// <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>
bool FolderExists([NotNull] string path);
/// <summary>
/// Determines whether the given path refers to an existing directory on disk.
/// </summary>
/// <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>
bool FolderExists([NotNull] string path);
/// <summary>
/// Creates all directories and subdirectories in the specified path unless they already exist.
/// </summary>
/// <param name="path">The path.</param>
void CreateFolder([NotNull] string path);
/// <summary>
/// Creates all directories and subdirectories in the specified path unless they already exist.
/// </summary>
/// <param name="path">The path.</param>
void CreateFolder([NotNull] string path);
/// <summary>
/// Returns an enumerable collection of file names in a specified path.
/// </summary>
/// <param name="path">The path.</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>
IEnumerable<string> EnumerateFiles([NotNull] string path, bool includeSubdirectories);
/// <summary>
/// Returns an enumerable collection of file names in a specified path.
/// </summary>
/// <param name="path">The path.</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>
IEnumerable<string> EnumerateFiles([NotNull] string path, bool includeSubdirectories);
/// <summary>
/// Read a static mapping file as text.
/// </summary>
/// <param name="path">The path (folder + filename with .json extension).</param>
/// <returns>The file content as text.</returns>
string ReadMappingFile([NotNull] string path);
/// <summary>
/// Read a static mapping file as text.
/// </summary>
/// <param name="path">The path (folder + filename with .json extension).</param>
/// <returns>The file content as text.</returns>
string ReadMappingFile([NotNull] string path);
/// <summary>
/// Write the static mapping file.
/// </summary>
/// <param name="path">The path (folder + filename with .json extension).</param>
/// <param name="text">The text.</param>
void WriteMappingFile([NotNull] string path, [NotNull] string text);
/// <summary>
/// Write the static mapping file.
/// </summary>
/// <param name="path">The path (folder + filename with .json extension).</param>
/// <param name="text">The text.</param>
void WriteMappingFile([NotNull] string path, [NotNull] string text);
/// <summary>
/// Read a response body file as byte[].
/// </summary>
/// <param name="path">The path or filename from the file to read.</param>
/// <returns>The file content as bytes.</returns>
byte[] ReadResponseBodyAsFile([NotNull] string path);
/// <summary>
/// Read a response body file as byte[].
/// </summary>
/// <param name="path">The path or filename from the file to read.</param>
/// <returns>The file content as bytes.</returns>
byte[] ReadResponseBodyAsFile([NotNull] string path);
/// <summary>
/// Read a response body file as text.
/// </summary>
/// <param name="path">The path or filename from the file to read.</param>
/// <returns>The file content as text.</returns>
string ReadResponseBodyAsString([NotNull] string path);
/// <summary>
/// Read a response body file as text.
/// </summary>
/// <param name="path">The path or filename from the file to read.</param>
/// <returns>The file content as text.</returns>
string ReadResponseBodyAsString([NotNull] string path);
/// <summary>
/// Delete a file.
/// </summary>
/// <param name="filename">The filename.</param>
void DeleteFile([NotNull] string filename);
/// <summary>
/// Delete a file.
/// </summary>
/// <param name="filename">The filename.</param>
void DeleteFile([NotNull] string filename);
/// <summary>
/// Determines whether the given path refers to an existing file on disk.
/// </summary>
/// <param name="filename">The filename.</param>
/// <returns>true if path refers to an existing file; false if the file does not exist.</returns>
bool FileExists([NotNull] string filename);
/// <summary>
/// Determines whether the given path refers to an existing file on disk.
/// </summary>
/// <param name="filename">The filename.</param>
/// <returns>true if path refers to an existing file; false if the file does not exist.</returns>
bool FileExists([NotNull] string filename);
/// <summary>
/// Write a file.
/// </summary>
/// <param name="filename">The filename.</param>
/// <param name="bytes">The bytes.</param>
void WriteFile([NotNull] string filename, [NotNull] byte[] bytes);
/// <summary>
/// Write a file.
/// </summary>
/// <param name="filename">The filename.</param>
/// <param name="bytes">The bytes.</param>
void WriteFile([NotNull] string filename, [NotNull] byte[] bytes);
/// <summary>
/// Write a file.
/// </summary>
/// <param name="folder">The folder.</param>
/// <param name="filename">The filename.</param>
/// <param name="bytes">The bytes.</param>
void WriteFile([NotNull] string folder, [NotNull] string filename, [NotNull] byte[] bytes);
/// <summary>
/// Write a file.
/// </summary>
/// <param name="folder">The folder.</param>
/// <param name="filename">The filename.</param>
/// <param name="bytes">The bytes.</param>
void WriteFile([NotNull] string folder, [NotNull] string filename, [NotNull] byte[] bytes);
/// <summary>
/// Read a file as bytes.
/// </summary>
/// <param name="filename">The filename.</param>
/// <returns>The file content as bytes.</returns>
byte[] ReadFile([NotNull] string filename);
/// <summary>
/// Read a file as bytes.
/// </summary>
/// <param name="filename">The filename.</param>
/// <returns>The file content as bytes.</returns>
byte[] ReadFile([NotNull] string filename);
/// <summary>
/// Read a file as string.
/// </summary>
/// <param name="filename">The filename.</param>
/// <returns>The file content as a string.</returns>
string ReadFileAsString([NotNull] string filename);
/// <summary>
/// Read a file as string.
/// </summary>
/// <param name="filename">The filename.</param>
/// <returns>The file content as a string.</returns>
string ReadFileAsString([NotNull] string filename);
/// <summary>
/// Gets the folder where the unmatched requests should be stored. For local file system, this would be `{CurrentFolder}/requests/unmatched`.
/// </summary>
/// <returns>The folder name.</returns>
string GetUnmatchedRequestsFolder();
/// <summary>
/// Gets the folder where the unmatched requests should be stored. For local file system, this would be `{CurrentFolder}/requests/unmatched`.
/// </summary>
/// <returns>The folder name.</returns>
string GetUnmatchedRequestsFolder();
/// <summary>
/// Write a unmatched request to the Unmatched RequestsFolder.
/// </summary>
/// <param name="filename">The filename.</param>
/// <param name="text">The text.</param>
void WriteUnmatchedRequest([NotNull] string filename, [NotNull] string text);
/// <summary>
/// Write a unmatched request to the Unmatched RequestsFolder.
/// </summary>
/// <param name="filename">The filename.</param>
/// <param name="text">The text.</param>
void WriteUnmatchedRequest([NotNull] string filename, [NotNull] string text);
}
}

View File

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

View File

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

View File

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

View File

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

View File

@@ -30,10 +30,6 @@
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
</PropertyGroup>
<PropertyGroup Condition=" '$(TargetFramework)' == 'netstandard2.0' or '$(TargetFramework)' == 'netstandard2.1'" >
<DefineConstants>$(DefineConstants);GRAPHQL;MIMEKIT</DefineConstants>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="JetBrains.Annotations" Version="2022.3.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)"))
{
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)
{
matchingHeaderValues.Should().Contain(expectedValues.First(), because, becauseArgs);
headerValues.Should().Contain(expectedValues.First(), because, becauseArgs);
}
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)
{
trimmedHeaderValues.Should().Contain(expectedValue, because, becauseArgs);

View File

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

View File

@@ -23,12 +23,14 @@ internal class OpenApiPathsMapper
private const string HeaderContentType = "Content-Type";
private readonly WireMockOpenApiParserSettings _settings;
private readonly ExampleValueGenerator _exampleValueGenerator;
private readonly IExampleValueGenerator _exampleValueGenerator;
private readonly IExampleValueGenerator _regexExampleValueGenerator;
public OpenApiPathsMapper(WireMockOpenApiParserSettings settings)
{
_settings = Guard.NotNull(settings);
_exampleValueGenerator = new ExampleValueGenerator(settings);
_regexExampleValueGenerator = new RegexExampleValueGenerator(settings);
}
public IReadOnlyList<MappingModel> ToMappingModels(OpenApiPaths? paths, IList<OpenApiServer> servers)
@@ -37,18 +39,7 @@ internal class OpenApiPathsMapper
.OrderBy(p => p.Key)
.Select(p => MapPath(p.Key, p.Value, servers))
.SelectMany(x => x)
.ToArray() ??
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>();
.ToArray() ?? Array.Empty<MappingModel>();
}
private IReadOnlyList<MappingModel> MapPath(string path, OpenApiPathItem pathItem, IList<OpenApiServer> servers)
@@ -280,54 +271,19 @@ internal class OpenApiPathsMapper
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)
{
var mappedHeaders = headers?.ToDictionary(
item => item.Key,
_ => GetExampleMatcherModel(null, _settings.HeaderPatternToUse).Pattern!
) ?? new Dictionary<string, object>();
);
if (!string.IsNullOrEmpty(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)
@@ -366,28 +322,38 @@ internal class OpenApiPathsMapper
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
{
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
},
_ => new MatcherModel
{
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
{
@@ -396,4 +362,39 @@ internal class OpenApiPathsMapper
_ => 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;
/// <summary>
/// The example value to use
/// The (example) value pattern to use.
/// </summary>
public enum ExampleValueType
{
@@ -12,6 +12,11 @@ public enum ExampleValueType
/// </summary>
Value,
/// <summary>
/// Build a Regex based on the SchemaType.
/// </summary>
Regex,
/// <summary>
/// Just use a Wildcard (*) character.
/// </summary>

View File

@@ -8,7 +8,7 @@ using WireMock.Net.OpenApiParser.Types;
namespace WireMock.Net.OpenApiParser.Utils;
internal class ExampleValueGenerator
internal class ExampleValueGenerator : IExampleValueGenerator
{
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>
<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="Nullable" Version="1.3.1">
<PrivateAssets>all</PrivateAssets>

View File

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

View File

@@ -1,4 +1,3 @@
using System;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Reflection;
@@ -25,7 +24,7 @@ public static class StandAloneApp
[PublicAPI]
public static WireMockServer Start(WireMockServerSettings settings)
{
Guard.NotNull(settings);
Guard.NotNull(settings, nameof(settings));
var server = WireMockServer.Start(settings);
@@ -43,7 +42,7 @@ public static class StandAloneApp
[PublicAPI]
public static WireMockServer Start(string[] args, IWireMockLogger? logger = null)
{
Guard.NotNull(args);
Guard.NotNull(args, nameof(args));
if (TryStart(args, out var server, logger))
{
@@ -62,9 +61,9 @@ public static class StandAloneApp
[PublicAPI]
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?.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>
<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="xUnit.abstractions" Version="2.0.3" />
</ItemGroup>

View File

@@ -34,6 +34,8 @@ internal class AzureADAuthenticationMatcher : IStringMatcher
public MatchBehaviour MatchBehaviour => MatchBehaviour.AcceptOnMatch;
public bool ThrowException => false;
public AnyOf<string, StringPattern>[] GetPatterns()
{
return EmptyArray<AnyOf<string, StringPattern>>.Value;
@@ -41,7 +43,7 @@ internal class AzureADAuthenticationMatcher : IStringMatcher
public MatchOperator MatchOperator { get; } = MatchOperator.Or;
public MatchResult IsMatch(string? input)
public double IsMatch(string? input)
{
if (string.IsNullOrEmpty(input))
{
@@ -68,9 +70,9 @@ internal class AzureADAuthenticationMatcher : IStringMatcher
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 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)
{
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.
// Else the path will just be as-is.
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)
{
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.
// Else the path will just be as-is.
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;
namespace WireMock.Http;
@@ -7,31 +6,19 @@ internal static class HttpClientFactory2
{
public static HttpClient Create(params DelegatingHandler[] handlers)
{
var handler = CreateHandlerPipeline(new HttpClientHandler(), handlers);
return new HttpClient(handler);
#if NETSTANDARD1_3
return new HttpClient();
#else
return HttpClientFactory.Create(handlers);
#endif
}
public static HttpClient Create(HttpMessageHandler innerHandler, params DelegatingHandler[] handlers)
{
var handler = CreateHandlerPipeline(innerHandler, handlers);
return new HttpClient(handler);
}
private static HttpMessageHandler CreateHandlerPipeline(HttpMessageHandler handler, params DelegatingHandler[] delegatingHandlers)
{
if (delegatingHandlers.Length == 0)
{
return handler;
}
var next = handler;
foreach (var delegatingHandler in delegatingHandlers.Reverse())
{
delegatingHandler.InnerHandler = next;
next = delegatingHandler;
}
return next;
#if NETSTANDARD1_3
return new HttpClient(innerHandler);
#else
return HttpClientFactory.Create(innerHandler, handlers);
#endif
}
}

View File

@@ -5,18 +5,12 @@ using System.Net.Http;
using System.Net.Http.Headers;
using Newtonsoft.Json;
using Stef.Validation;
using WireMock.Constants;
using WireMock.Types;
namespace WireMock.Http;
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)
{
Guard.NotNull(requestMessage);
@@ -31,14 +25,21 @@ internal static class HttpRequestMessageHelper
MediaTypeHeaderValue.TryParse(value, out contentType);
}
httpRequestMessage.Content = requestMessage.BodyData?.DetectedBodyType switch
switch (requestMessage.BodyData?.DetectedBodyType)
{
BodyType.Bytes => ByteArrayContentHelper.Create(requestMessage.BodyData.BodyAsBytes!, contentType),
BodyType.Json => StringContentHelper.Create(JsonConvert.SerializeObject(requestMessage.BodyData.BodyAsJson), contentType),
BodyType.String => StringContentHelper.Create(requestMessage.BodyData.BodyAsString!, contentType),
BodyType.FormUrlEncoded => StringContentHelper.Create(requestMessage.BodyData.BodyAsString!, contentType),
_ => httpRequestMessage.Content
};
case BodyType.Bytes:
httpRequestMessage.Content = ByteArrayContentHelper.Create(requestMessage.BodyData.BodyAsBytes!, contentType);
break;
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
httpRequestMessage.Headers.Host = new Uri(url).Authority;
@@ -49,19 +50,7 @@ internal static class HttpRequestMessageHelper
return httpRequestMessage;
}
var excludeHeaders = new List<string> { HttpKnownHeaderNames.Host };
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);
}
var excludeHeaders = new List<string> { HttpKnownHeaderNames.Host, HttpKnownHeaderNames.ContentLength };
if (contentType != null)
{
// Content-Type should be set on the content

View File

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

View File

@@ -20,8 +20,10 @@ public abstract class AbstractJsonPartialMatcher : JsonMatcher
/// </summary>
/// <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="throwException">Throw an exception when the internal matching fails because of invalid input.</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;
}
@@ -31,8 +33,10 @@ public abstract class AbstractJsonPartialMatcher : JsonMatcher
/// </summary>
/// <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="throwException">Throw an exception when the internal matching fails because of invalid input.</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;
}
@@ -43,8 +47,10 @@ public abstract class AbstractJsonPartialMatcher : JsonMatcher
/// <param name="matchBehaviour">The match behaviour.</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="throwException">Throw an exception when the internal matching fails because of invalid input.</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;
}
@@ -60,7 +66,7 @@ public abstract class AbstractJsonPartialMatcher : JsonMatcher
if (Regex && value.Type == JTokenType.String && input != null)
{
var valueAsString = value.ToString();
var (valid, result) = RegexUtils.MatchRegex(valueAsString, input.ToString());
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)
{
return false;

View File

@@ -46,13 +46,15 @@ public class ContentTypeMatcher : WildcardMatcher
/// <param name="matchBehaviour">The match behaviour.</param>
/// <param name="patterns">The patterns.</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;
}
/// <inheritdoc />
public override MatchResult IsMatch(string? input)
/// <inheritdoc cref="RegexMatcher.IsMatch"/>
public override double IsMatch(string? input)
{
if (string.IsNullOrEmpty(input) || !MediaTypeHeaderValue.TryParse(input, out var contentType))
{
@@ -62,12 +64,12 @@ public class ContentTypeMatcher : WildcardMatcher
return base.IsMatch(contentType.MediaType);
}
/// <inheritdoc />
/// <inheritdoc cref="IStringMatcher.GetPatterns"/>
public override AnyOf<string, StringPattern>[] GetPatterns()
{
return _patterns;
}
/// <inheritdoc />
public override string Name => nameof(ContentTypeMatcher);
/// <inheritdoc cref="IMatcher.Name"/>
public override string Name => "ContentTypeMatcher";
}

View File

@@ -14,14 +14,17 @@ public class ExactMatcher : IStringMatcher, IIgnoreCaseMatcher
{
private readonly AnyOf<string, StringPattern>[] _values;
/// <inheritdoc />
/// <inheritdoc cref="IMatcher.MatchBehaviour"/>
public MatchBehaviour MatchBehaviour { get; }
/// <inheritdoc cref="IMatcher.ThrowException"/>
public bool ThrowException { get; }
/// <summary>
/// Initializes a new instance of the <see cref="ExactMatcher"/> class.
/// </summary>
/// <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>
/// <param name="ignoreCase">Ignore the case from the pattern(s).</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>
/// <param name="matchBehaviour">The match behaviour.</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="values">The values.</param>
public ExactMatcher(
MatchBehaviour matchBehaviour,
bool ignoreCase = false,
bool throwException = false,
MatchOperator matchOperator = MatchOperator.Or,
params AnyOf<string, StringPattern>[] values)
{
_values = Guard.NotNull(values);
MatchBehaviour = matchBehaviour;
ThrowException = throwException;
IgnoreCase = ignoreCase;
MatchOperator = matchOperator;
}
/// <inheritdoc />
public MatchResult IsMatch(string? input)
/// <inheritdoc cref="IStringMatcher.IsMatch"/>
public double IsMatch(string? input)
{
Func<string?, bool> equals = IgnoreCase
? pattern => string.Equals(pattern, input, StringComparison.OrdinalIgnoreCase)
: pattern => pattern == input;
var score = MatchScores.ToScore(_values.Select(v => equals(v)).ToArray(), MatchOperator);
return new MatchResult(MatchBehaviourHelper.Convert(MatchBehaviour, score));
double score = MatchScores.ToScore(_values.Select(v => equals(v)).ToArray(), MatchOperator);
return MatchBehaviourHelper.Convert(MatchBehaviour, score);
}
/// <inheritdoc />
/// <inheritdoc cref="IStringMatcher.GetPatterns"/>
public AnyOf<string, StringPattern>[] GetPatterns()
{
return _values;
@@ -74,7 +80,7 @@ public class ExactMatcher : IStringMatcher, IIgnoreCaseMatcher
/// <inheritdoc />
public MatchOperator MatchOperator { get; }
/// <inheritdoc />
/// <inheritdoc cref="IMatcher.Name"/>
public string Name => "ExactMatcher";
/// <inheritdoc />

View File

@@ -19,9 +19,12 @@ public class ExactObjectMatcher : IObjectMatcher
/// </summary>
public byte[]? ValueAsBytes { get; }
/// <inheritdoc />
/// <inheritdoc cref="IMatcher.MatchBehaviour"/>
public MatchBehaviour MatchBehaviour { get; }
/// <inheritdoc cref="IMatcher.ThrowException"/>
public bool ThrowException { get; }
/// <summary>
/// Initializes a new instance of the <see cref="ExactObjectMatcher"/> class.
/// </summary>
@@ -53,15 +56,17 @@ public class ExactObjectMatcher : IObjectMatcher
/// Initializes a new instance of the <see cref="ExactObjectMatcher"/> class.
/// </summary>
/// <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>
public ExactObjectMatcher(MatchBehaviour matchBehaviour, byte[] value)
public ExactObjectMatcher(MatchBehaviour matchBehaviour, byte[] value, bool throwException = false)
{
ValueAsBytes = Guard.NotNull(value);
MatchBehaviour = matchBehaviour;
ThrowException = throwException;
}
/// <inheritdoc />
public MatchResult IsMatch(object? input)
/// <inheritdoc cref="IObjectMatcher.IsMatch"/>
public double IsMatch(object? input)
{
bool equals = false;
if (ValueAsObject != null)
@@ -76,6 +81,6 @@ public class ExactObjectMatcher : IObjectMatcher
return MatchBehaviourHelper.Convert(MatchBehaviour, MatchScores.ToScore(equals));
}
/// <inheritdoc />
/// <inheritdoc cref="IMatcher.Name"/>
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.
/// </summary>
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.
/// </summary>
/// <param name="input">The input.</param>
/// <returns>MatchResult</returns>
MatchResult IsMatch(object? input);
/// <returns>A value between 0.0 - 1.0 of the similarity.</returns>
double IsMatch(object? input);
}

View File

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

View File

@@ -1,6 +1,6 @@
using System;
using System.Linq;
using AnyOfTypes;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Stef.Validation;
using WireMock.Extensions;
@@ -17,15 +17,17 @@ public class JsonPathMatcher : IStringMatcher, IObjectMatcher
{
private readonly AnyOf<string, StringPattern>[] _patterns;
/// <inheritdoc />
/// <inheritdoc cref="IMatcher.MatchBehaviour"/>
public MatchBehaviour MatchBehaviour { get; }
/// <inheritdoc cref="IMatcher.ThrowException"/>
public bool ThrowException { get; }
/// <summary>
/// Initializes a new instance of the <see cref="JsonPathMatcher"/> class.
/// </summary>
/// <param name="patterns">The patterns.</param>
public JsonPathMatcher(params string[] patterns) : this(MatchBehaviour.AcceptOnMatch, MatchOperator.Or,
patterns.ToAnyOfPatterns())
public JsonPathMatcher(params string[] patterns) : this(MatchBehaviour.AcceptOnMatch, false, MatchOperator.Or, patterns.ToAnyOfPatterns())
{
}
@@ -33,8 +35,7 @@ public class JsonPathMatcher : IStringMatcher, IObjectMatcher
/// Initializes a new instance of the <see cref="JsonPathMatcher"/> class.
/// </summary>
/// <param name="patterns">The patterns.</param>
public JsonPathMatcher(params AnyOf<string, StringPattern>[] patterns) : this(MatchBehaviour.AcceptOnMatch,
MatchOperator.Or, patterns)
public JsonPathMatcher(params AnyOf<string, StringPattern>[] patterns) : this(MatchBehaviour.AcceptOnMatch, false, MatchOperator.Or, patterns)
{
}
@@ -42,45 +43,48 @@ public class JsonPathMatcher : IStringMatcher, IObjectMatcher
/// Initializes a new instance of the <see cref="JsonPathMatcher"/> class.
/// </summary>
/// <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="patterns">The patterns.</param>
public JsonPathMatcher(
MatchBehaviour matchBehaviour,
bool throwException = false,
MatchOperator matchOperator = MatchOperator.Or,
params AnyOf<string, StringPattern>[] patterns)
{
_patterns = Guard.NotNull(patterns);
MatchBehaviour = matchBehaviour;
ThrowException = throwException;
MatchOperator = matchOperator;
}
/// <inheritdoc />
public MatchResult IsMatch(string? input)
/// <inheritdoc cref="IStringMatcher.IsMatch"/>
public double IsMatch(string? input)
{
var score = MatchScores.Mismatch;
Exception? exception = null;
double match = MatchScores.Mismatch;
if (input != null)
{
try
{
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 />
public MatchResult IsMatch(object? input)
/// <inheritdoc cref="IObjectMatcher.IsMatch"/>
public double IsMatch(object? input)
{
var score = MatchScores.Mismatch;
Exception? exception = null;
double match = MatchScores.Mismatch;
// When input is null or byte[], return Mismatch.
if (input != null && !(input is byte[]))
@@ -89,15 +93,18 @@ public class JsonPathMatcher : IStringMatcher, IObjectMatcher
{
// Check if JToken or object
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 />
@@ -109,41 +116,11 @@ public class JsonPathMatcher : IStringMatcher, IObjectMatcher
/// <inheritdoc />
public MatchOperator MatchOperator { get; }
/// <inheritdoc />
/// <inheritdoc cref="IMatcher.Name"/>
public string Name => "JsonPathMatcher";
private double IsMatch(JToken jToken)
{
var array = ConvertJTokenToJArrayIfNeeded(jToken);
// 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.
var values = _patterns.Select(pattern => array.SelectToken(pattern.GetPattern()) != null).ToArray();
return MatchScores.ToScore(values, 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;
return MatchScores.ToScore(_patterns.Select(pattern => jToken.SelectToken(pattern.GetPattern()) != null).ToArray(), MatchOperator);
}
}

View File

@@ -1,4 +1,3 @@
using System;
using System.Linq;
using AnyOfTypes;
using DevLab.JmesPath;
@@ -16,14 +15,17 @@ public class JmesPathMatcher : IStringMatcher, IObjectMatcher
{
private readonly AnyOf<string, StringPattern>[] _patterns;
/// <inheritdoc />
/// <inheritdoc cref="IMatcher.MatchBehaviour"/>
public MatchBehaviour MatchBehaviour { get; }
/// <inheritdoc cref="IMatcher.ThrowException"/>
public bool ThrowException { get; }
/// <summary>
/// Initializes a new instance of the <see cref="JmesPathMatcher"/> class.
/// </summary>
/// <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.
/// </summary>
/// <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>
/// Initializes a new instance of the <see cref="JmesPathMatcher"/> class.
/// </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="patterns">The patterns.</param>
public JmesPathMatcher(MatchOperator matchOperator = MatchOperator.Or, params AnyOf<string, StringPattern>[] patterns) :
this(MatchBehaviour.AcceptOnMatch, matchOperator, patterns)
public JmesPathMatcher(bool throwException = false, MatchOperator matchOperator = MatchOperator.Or, params AnyOf<string, StringPattern>[] 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.
/// </summary>
/// <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="patterns">The patterns.</param>
public JmesPathMatcher(
MatchBehaviour matchBehaviour,
bool throwException = false,
MatchOperator matchOperator = MatchOperator.Or,
params AnyOf<string, StringPattern>[] patterns)
{
_patterns = Guard.NotNull(patterns);
MatchBehaviour = matchBehaviour;
ThrowException = throwException;
MatchOperator = matchOperator;
}
/// <inheritdoc />
public MatchResult IsMatch(string? input)
/// <inheritdoc cref="IStringMatcher.IsMatch"/>
public double IsMatch(string? input)
{
var score = MatchScores.Mismatch;
Exception? exception = null;
double match = MatchScores.Mismatch;
if (input != null)
{
try
{
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 />
public MatchResult IsMatch(object? input)
/// <inheritdoc cref="IObjectMatcher.IsMatch"/>
public double IsMatch(object? input)
{
var score = MatchScores.Mismatch;
double match = MatchScores.Mismatch;
// When input is null or byte[], return Mismatch.
if (input != null && !(input is byte[]))
{
var inputAsString = JsonConvert.SerializeObject(input);
string inputAsString = JsonConvert.SerializeObject(input);
return IsMatch(inputAsString);
}
return MatchBehaviourHelper.Convert(MatchBehaviour, score);
return MatchBehaviourHelper.Convert(MatchBehaviour, match);
}
/// <inheritdoc />
/// <inheritdoc cref="IStringMatcher.GetPatterns"/>
public AnyOf<string, StringPattern>[] GetPatterns()
{
return _patterns;
@@ -107,6 +114,6 @@ public class JmesPathMatcher : IStringMatcher, IObjectMatcher
/// <inheritdoc />
public MatchOperator MatchOperator { get; }
/// <inheritdoc />
public string Name => nameof(JmesPathMatcher);
/// <inheritdoc cref="IMatcher.Name"/>
public string Name => "JmesPathMatcher";
}

View File

@@ -1,6 +1,7 @@
using System;
using System.Collections;
using System.Linq;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Stef.Validation;
using WireMock.Util;
@@ -12,18 +13,21 @@ namespace WireMock.Matchers;
/// </summary>
public class JsonMatcher : IValueMatcher, IIgnoreCaseMatcher
{
/// <inheritdoc />
/// <inheritdoc cref="IMatcher.Name"/>
public virtual string Name => "JsonMatcher";
/// <inheritdoc cref="IValueMatcher.Value"/>
public object Value { get; }
/// <inheritdoc />
/// <inheritdoc cref="IMatcher.MatchBehaviour"/>
public MatchBehaviour MatchBehaviour { get; }
/// <inheritdoc cref="IIgnoreCaseMatcher.IgnoreCase"/>
public bool IgnoreCase { get; }
/// <inheritdoc cref="IMatcher.ThrowException"/>
public bool ThrowException { get; }
private readonly JToken _valueAsJToken;
private readonly Func<JToken, JToken> _jTokenConverter;
@@ -32,7 +36,8 @@ public class JsonMatcher : IValueMatcher, IIgnoreCaseMatcher
/// </summary>
/// <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>
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>
/// <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>
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="value">The value to check for equality.</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);
Guard.NotNull(value, nameof(value));
MatchBehaviour = matchBehaviour;
IgnoreCase = ignoreCase;
ThrowException = throwException;
Value = value;
_valueAsJToken = ConvertValueToJToken(value);
_jTokenConverter = ignoreCase ? Rename : jToken => jToken;
}
/// <inheritdoc />
public MatchResult IsMatch(object? input)
/// <inheritdoc cref="IObjectMatcher.IsMatch"/>
public double IsMatch(object? input)
{
var score = MatchScores.Mismatch;
Exception? error = null;
bool match = false;
// When input is null or byte[], return Mismatch.
if (input != null && input is not byte[])
@@ -76,16 +83,20 @@ public class JsonMatcher : IValueMatcher, IIgnoreCaseMatcher
{
var inputAsJToken = ConvertValueToJToken(input);
var match = IsMatch(_jTokenConverter(_valueAsJToken), _jTokenConverter(inputAsJToken));
score = MatchScores.ToScore(match);
match = IsMatch(
_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>

View File

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

View File

@@ -9,20 +9,20 @@ public class JsonPartialWildcardMatcher : AbstractJsonPartialMatcher
public override string Name => nameof(JsonPartialWildcardMatcher);
/// <inheritdoc />
public JsonPartialWildcardMatcher(string value, bool ignoreCase = false, bool regex = false)
: base(value, ignoreCase, regex)
public JsonPartialWildcardMatcher(string value, bool ignoreCase = false, bool throwException = false, bool regex = false)
: base(value, ignoreCase, throwException, regex)
{
}
/// <inheritdoc />
public JsonPartialWildcardMatcher(object value, bool ignoreCase = false, bool regex = false)
: base(value, ignoreCase, regex)
public JsonPartialWildcardMatcher(object value, bool ignoreCase = false, bool throwException = false, bool regex = false)
: base(value, ignoreCase, throwException, regex)
{
}
/// <inheritdoc />
public JsonPartialWildcardMatcher(MatchBehaviour matchBehaviour, object value, bool ignoreCase = false, bool regex = false)
: base(matchBehaviour, value, ignoreCase, regex)
public JsonPartialWildcardMatcher(MatchBehaviour matchBehaviour, object value, bool ignoreCase = false, bool throwException = false, bool regex = false)
: base(matchBehaviour, value, ignoreCase, throwException, regex)
{
}
@@ -30,6 +30,6 @@ public class JsonPartialWildcardMatcher : AbstractJsonPartialMatcher
protected override bool IsMatch(string value, string input)
{
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;
/// <inheritdoc />
/// <inheritdoc cref="IMatcher.MatchBehaviour"/>
public MatchBehaviour MatchBehaviour { get; }
/// <inheritdoc cref="IMatcher.ThrowException"/>
public bool ThrowException { get; }
/// <summary>
/// Initializes a new instance of the <see cref="LinqMatcher"/> class.
/// </summary>
@@ -34,7 +37,7 @@ public class LinqMatcher : IObjectMatcher, IStringMatcher
/// Initializes a new instance of the <see cref="LinqMatcher"/> class.
/// </summary>
/// <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>
/// <param name="matchBehaviour">The match behaviour.</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.
/// </summary>
/// <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="patterns">The patterns.</param>
public LinqMatcher(
MatchBehaviour matchBehaviour,
bool throwException = false,
MatchOperator matchOperator = MatchOperator.Or,
params AnyOf<string, StringPattern>[] patterns)
{
_patterns = Guard.NotNull(patterns);
MatchBehaviour = matchBehaviour;
ThrowException = throwException;
MatchOperator = matchOperator;
}
/// <inheritdoc />
public MatchResult IsMatch(string? input)
/// <inheritdoc cref="IStringMatcher.IsMatch"/>
public double IsMatch(string? input)
{
var score = MatchScores.Mismatch;
Exception? error = null;
double match = MatchScores.Mismatch;
// Convert a single input string to a Queryable string-list with 1 entry.
IQueryable queryable = new[] { input }.AsQueryable();
@@ -75,21 +80,25 @@ public class LinqMatcher : IObjectMatcher, IStringMatcher
try
{
// 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 />
public MatchResult IsMatch(object? input)
/// <inheritdoc cref="IObjectMatcher.IsMatch"/>
public double IsMatch(object? input)
{
var score = MatchScores.Mismatch;
Exception? error = null;
double match = MatchScores.Mismatch;
JArray jArray;
try
@@ -98,28 +107,59 @@ public class LinqMatcher : IObjectMatcher, IStringMatcher
}
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.
//var queryable1 = new[] { value }.AsQueryable();
var queryable = jArray.ToDynamicClassArray().AsQueryable();
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 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)
{
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()
{
return _patterns;
@@ -128,6 +168,6 @@ public class LinqMatcher : IObjectMatcher, IStringMatcher
/// <inheritdoc />
public MatchOperator MatchOperator { get; }
/// <inheritdoc />
public string Name => nameof(LinqMatcher);
/// <inheritdoc cref="IMatcher.Name"/>
public string Name => "LinqMatcher";
}

View File

@@ -1,7 +1,7 @@
namespace WireMock.Matchers;
/// <summary>
/// MatchBehaviour (Accept or Reject)
/// MatchBehaviour
/// </summary>
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" />
public class NotNullOrEmptyMatcher : IObjectMatcher, IStringMatcher
{
/// <inheritdoc />
public string Name => nameof(NotNullOrEmptyMatcher);
/// <inheritdoc cref="IMatcher.Name"/>
public string Name => "NotNullOrEmptyMatcher";
/// <inheritdoc />
/// <inheritdoc cref="IMatcher.MatchBehaviour"/>
public MatchBehaviour MatchBehaviour { get; }
/// <inheritdoc cref="IMatcher.ThrowException"/>
public bool ThrowException { get; }
/// <summary>
/// Initializes a new instance of the <see cref="NotNullOrEmptyMatcher"/> class.
/// </summary>
@@ -26,8 +29,8 @@ public class NotNullOrEmptyMatcher : IObjectMatcher, IStringMatcher
MatchBehaviour = matchBehaviour;
}
/// <inheritdoc />
public MatchResult IsMatch(object? input)
/// <inheritdoc cref="IObjectMatcher.IsMatch"/>
public double IsMatch(object? input)
{
bool match;
@@ -49,15 +52,15 @@ public class NotNullOrEmptyMatcher : IObjectMatcher, IStringMatcher
return MatchBehaviourHelper.Convert(MatchBehaviour, MatchScores.ToScore(match));
}
/// <inheritdoc />
public MatchResult IsMatch(string? input)
/// <inheritdoc cref="IStringMatcher.IsMatch"/>
public double IsMatch(string? input)
{
var match = !string.IsNullOrEmpty(input);
return MatchBehaviourHelper.Convert(MatchBehaviour, MatchScores.ToScore(match));
}
/// <inheritdoc />
/// <inheritdoc cref="IStringMatcher.GetPatterns"/>
public AnyOf<string, StringPattern>[] GetPatterns()
{
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 Regex[] _expressions;
/// <inheritdoc />
/// <inheritdoc cref="IMatcher.MatchBehaviour"/>
public MatchBehaviour MatchBehaviour { get; }
/// <inheritdoc cref="IMatcher.ThrowException"/>
public bool ThrowException { get; }
/// <summary>
/// Initializes a new instance of the <see cref="RegexMatcher"/> class.
/// </summary>
/// <param name="pattern">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="matchOperator">The <see cref="Matchers.MatchOperator"/> to use. (default = "Or")</param>
public RegexMatcher(
[RegexPattern] AnyOf<string, StringPattern> pattern,
bool ignoreCase = false,
bool throwException = false,
bool useRegexExtended = true,
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="pattern">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="matchOperator">The <see cref="Matchers.MatchOperator"/> to use. (default = "Or")</param>
public RegexMatcher(
MatchBehaviour matchBehaviour,
[RegexPattern] AnyOf<string, StringPattern> pattern,
bool ignoreCase = false,
bool throwException = false,
bool useRegexExtended = true,
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="patterns">The patterns.</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="matchOperator">The <see cref="Matchers.MatchOperator"/> to use. (default = "Or")</param>
public RegexMatcher(
MatchBehaviour matchBehaviour,
[RegexPattern] AnyOf<string, StringPattern>[] patterns,
bool ignoreCase = false,
bool throwException = false,
bool useRegexExtended = true,
MatchOperator matchOperator = MatchOperator.Or)
{
_patterns = Guard.NotNull(patterns);
IgnoreCase = ignoreCase;
MatchBehaviour = matchBehaviour;
ThrowException = throwException;
MatchOperator = matchOperator;
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();
}
/// <inheritdoc />
public virtual MatchResult IsMatch(string? input)
/// <inheritdoc cref="IStringMatcher.IsMatch"/>
public virtual double IsMatch(string? input)
{
var score = MatchScores.Mismatch;
Exception? exception = null;
double match = MatchScores.Mismatch;
if (input != null)
{
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 />

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