mirror of
https://github.com/wiremock/WireMock.Net.git
synced 2026-02-05 09:59:32 +01:00
Compare commits
17 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
be4b0addca | ||
|
|
ae91ed2a79 | ||
|
|
968aa598e2 | ||
|
|
bdd421e128 | ||
|
|
150b448d07 | ||
|
|
717179fd35 | ||
|
|
9b7e5908cb | ||
|
|
b1032c9dcd | ||
|
|
4d0f96eabe | ||
|
|
ef12cb70cc | ||
|
|
c212d07c53 | ||
|
|
b9afb126cf | ||
|
|
8dc9c4b46c | ||
|
|
0441c1d85e | ||
|
|
1f23022460 | ||
|
|
8d57f37261 | ||
|
|
ca6c39c63a |
26
CHANGELOG.md
26
CHANGELOG.md
@@ -1,3 +1,29 @@
|
||||
# 1.5.3 (29 July 2022)
|
||||
- [#777](https://github.com/WireMock-Net/WireMock.Net/pull/777) - Update Scriban.Signed to version 5.5.0 [feature] contributed by [StefH](https://github.com/StefH)
|
||||
- [#776](https://github.com/WireMock-Net/WireMock.Net/issues/776) - Update Scriban.Signed to support more functions, e.g math.random [feature]
|
||||
|
||||
# 1.5.2 (24 July 2022)
|
||||
- [#769](https://github.com/WireMock-Net/WireMock.Net/pull/769) - Bump Microsoft.AspNetCore.Server.Kestrel.Core from 2.1.3 to 2.1.7 in /examples/WireMock.Net.StandAlone.Net461 [dependencies] contributed by [dependabot[bot]](https://github.com/apps/dependabot)
|
||||
- [#770](https://github.com/WireMock-Net/WireMock.Net/pull/770) - Added some more tests for JsonMatcher + refactored some code to use nullable [test] contributed by [StefH](https://github.com/StefH)
|
||||
- [#771](https://github.com/WireMock-Net/WireMock.Net/pull/771) - JsonPartialMatcher - support Regex [feature] contributed by [StefH](https://github.com/StefH)
|
||||
|
||||
# 1.5.1 (08 July 2022)
|
||||
- [#762](https://github.com/WireMock-Net/WireMock.Net/pull/762) - Bump Newtonsoft.Json from 11.0.2 to 13.0.1 in /examples/WireMock.Net.WebApplication.NETCore2 [dependencies] contributed by [dependabot[bot]](https://github.com/apps/dependabot)
|
||||
- [#763](https://github.com/WireMock-Net/WireMock.Net/pull/763) - Bump Newtonsoft.Json from 6.0.1 to 13.0.1 in /examples/WireMock.Net.Client.Net472 [dependencies] contributed by [dependabot[bot]](https://github.com/apps/dependabot)
|
||||
- [#765](https://github.com/WireMock-Net/WireMock.Net/pull/765) - Update WireMock.Org.Abstractions and WireMock.Org.RestClient [feature] contributed by [StefH](https://github.com/StefH)
|
||||
- [#766](https://github.com/WireMock-Net/WireMock.Net/pull/766) - Bump Microsoft.AspNetCore.Http from 2.1.1 to 2.1.22 in /examples/WireMock.Net.StandAlone.Net461 [dependencies] contributed by [dependabot[bot]](https://github.com/apps/dependabot)
|
||||
- [#767](https://github.com/WireMock-Net/WireMock.Net/pull/767) - Rename (WireMock.Pact.Models.V2)-Request to PactRequest and -Response to PactResponse [feature] contributed by [StefH](https://github.com/StefH)
|
||||
- [#764](https://github.com/WireMock-Net/WireMock.Net/issues/764) - Wrong mapping of method GetAdminMappingsAsync from IWireMockOrgApi [bug]
|
||||
|
||||
# 1.5.0 (09 June 2022)
|
||||
- [#755](https://github.com/WireMock-Net/WireMock.Net/pull/755) - Add MatchOperator "Or", "And" and "Average" for patterns [feature] contributed by [StefH](https://github.com/StefH)
|
||||
|
||||
# 1.4.43 (21 May 2022)
|
||||
- [#757](https://github.com/WireMock-Net/WireMock.Net/pull/757) - Log correct exception message when handling aggregate exceptions contributed by [siewers](https://github.com/siewers)
|
||||
- [#759](https://github.com/WireMock-Net/WireMock.Net/pull/759) - Add WireMock.Net.xUnit project [feature] contributed by [StefH](https://github.com/StefH)
|
||||
- [#756](https://github.com/WireMock-Net/WireMock.Net/issues/756) - WireMockConsoleLogger aggregate exception handling bug? [bug]
|
||||
- [#758](https://github.com/WireMock-Net/WireMock.Net/issues/758) - Add support for logging to an xUnit ITestOutputHelper [feature]
|
||||
|
||||
# 1.4.42 (13 May 2022)
|
||||
- [#748](https://github.com/WireMock-Net/WireMock.Net/pull/748) - Initial support for converting the mappings to a Pact(flow) json file [feature] contributed by [StefH](https://github.com/StefH)
|
||||
- [#749](https://github.com/WireMock-Net/WireMock.Net/pull/749) - Swagger support [feature] contributed by [StefH](https://github.com/StefH)
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<VersionPrefix>1.4.42</VersionPrefix>
|
||||
<VersionPrefix>1.5.3</VersionPrefix>
|
||||
<PackageIcon>WireMock.Net-Logo.png</PackageIcon>
|
||||
<PackageProjectUrl>https://github.com/WireMock-Net/WireMock.Net</PackageProjectUrl>
|
||||
<PackageLicenseExpression>Apache-2.0</PackageLicenseExpression>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
rem https://github.com/StefH/GitHubReleaseNotes
|
||||
|
||||
SET version=1.4.42
|
||||
SET version=1.5.3
|
||||
|
||||
GitHubReleaseNotes --output CHANGELOG.md --skip-empty-releases --exclude-labels question invalid doc duplicate --version %version% --token %GH_TOKEN%
|
||||
|
||||
|
||||
@@ -1,9 +1,5 @@
|
||||
# 1.4.42 (13 May 2022)
|
||||
- #748 Initial support for converting the mappings to a Pact(flow) json file [feature]
|
||||
- #749 Swagger support [feature]
|
||||
- #750 [Snyk] Security upgrade Newtonsoft.Json from 11.0.2 to 13.0.1
|
||||
- #751 Update NuGets packages [feature]
|
||||
- #741 Integrate with Pact [feature]
|
||||
- #753 FluentAssertions - assert the server has not received a call [feature]
|
||||
# 1.5.3 (29 July 2022)
|
||||
- #777 Update Scriban.Signed to version 5.5.0 [feature]
|
||||
- #776 Update Scriban.Signed to support more functions, e.g math.random [feature]
|
||||
|
||||
The full release notes can be found here: https://github.com/WireMock-Net/WireMock.Net/blob/master/CHANGELOG.md
|
||||
@@ -37,6 +37,7 @@ For more info, see also this WIKI page: [What is WireMock.Net](https://github.co
|
||||
| **WireMock.Net.Matchers.CSharpCode** | [](https://www.nuget.org/packages/WireMock.Net.Matchers.CSharpCode) | [](https://www.myget.org/feed/wiremock-net/package/nuget/WireMock.Net.Matchers.CSharpCode)
|
||||
| **WireMock.Net.OpenApiParser** | [](https://www.nuget.org/packages/WireMock.Net.OpenApiParser) | [](https://www.myget.org/feed/wiremock-net/package/nuget/WireMock.Net.OpenApiParser)
|
||||
| **WireMock.Net.RestClient** | [](https://www.nuget.org/packages/WireMock.Net.RestClient) | [](https://www.myget.org/feed/wiremock-net/package/nuget/WireMock.Net.RestClient)
|
||||
| **WireMock.Net.xUnit** | [](https://www.nuget.org/packages/WireMock.Net.xUnit) | [](https://www.myget.org/feed/wiremock-net/package/nuget/WireMock.Net.xUnit)
|
||||
| **WireMock.Org.RestClient** | [](https://www.nuget.org/packages/WireMock.Org.RestClient) | [](https://www.myget.org/feed/wiremock-net/package/nuget/WireMock.Org.RestClient)
|
||||
|
||||
|
||||
|
||||
@@ -101,6 +101,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WireMock.Net.WebApplication
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WireMock.Net.Console.Proxy.NETCoreApp", "examples\WireMock.Net.Console.Proxy.NETCoreApp\WireMock.Net.Console.Proxy.NETCoreApp.csproj", "{670C7562-C154-442E-A249-7D26849BCD13}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WireMock.Net.xUnit", "src\WireMock.Net.xUnit\WireMock.Net.xUnit.csproj", "{0DE0954F-8C00-4E8D-B94A-4361FC1CBE44}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
@@ -239,6 +241,10 @@ Global
|
||||
{670C7562-C154-442E-A249-7D26849BCD13}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{670C7562-C154-442E-A249-7D26849BCD13}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{670C7562-C154-442E-A249-7D26849BCD13}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{0DE0954F-8C00-4E8D-B94A-4361FC1CBE44}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{0DE0954F-8C00-4E8D-B94A-4361FC1CBE44}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{0DE0954F-8C00-4E8D-B94A-4361FC1CBE44}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{0DE0954F-8C00-4E8D-B94A-4361FC1CBE44}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
@@ -279,6 +285,7 @@ Global
|
||||
{2215055B-594E-4C2F-99B2-6DF337F02893} = {985E0ADB-D4B4-473A-AA40-567E279B7946}
|
||||
{3F7AA023-6833-4856-A08A-4B5717B592B8} = {985E0ADB-D4B4-473A-AA40-567E279B7946}
|
||||
{670C7562-C154-442E-A249-7D26849BCD13} = {985E0ADB-D4B4-473A-AA40-567E279B7946}
|
||||
{0DE0954F-8C00-4E8D-B94A-4361FC1CBE44} = {8F890C6F-9ACC-438D-928A-AD61CDA862F2}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {DC539027-9852-430C-B19F-FD035D018458}
|
||||
|
||||
@@ -25,4 +25,5 @@
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Webhook/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Webhooks/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=wiremockserver/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=xunit/@EntryIndexedValue">True</s:Boolean>
|
||||
</wpf:ResourceDictionary>
|
||||
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="Brutal.Dev.StrongNameSigner" version="2.7.1" targetFramework="net472" />
|
||||
<package id="Newtonsoft.Json" version="6.0.1" targetFramework="net472" />
|
||||
<package id="Newtonsoft.Json" version="13.0.1" targetFramework="net472" />
|
||||
<package id="RestEase" version="1.4.10" targetFramework="net472" />
|
||||
<package id="WireMock.Net.Abstractions" version="1.2.0" targetFramework="net472" />
|
||||
<package id="WireMock.Net.RestClient" version="1.2.0" targetFramework="net472" />
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
|
||||
<PackageReference Include="RestEase" Version="1.5.6" />
|
||||
<PackageReference Include="RestEase" Version="1.5.7" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -79,7 +79,7 @@ namespace WireMock.Net.ConsoleApplication
|
||||
|
||||
// server.AllowPartialMapping();
|
||||
|
||||
server.Given(Request.Create().WithPath("/mypath").UsingPost())
|
||||
server.Given(Request.Create().WithPath(MatchOperator.Or, "/mypath", "/mypath1", "/mypath2").UsingPost())
|
||||
.RespondWith(Response.Create()
|
||||
.WithHeader("Content-Type", "application/json")
|
||||
.WithBodyAsJson("{{JsonPath.SelectToken request.body \"..name\"}}")
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
// <auto-generated>
|
||||
// This code file has automatically been added by the "Nullable" NuGet package (https://www.nuget.org/packages/Nullable).
|
||||
// Please see https://github.com/manuelroemer/Nullable for more information.
|
||||
//
|
||||
// IMPORTANT:
|
||||
// DO NOT DELETE THIS FILE if you are using a "packages.config" file to manage your NuGet references.
|
||||
// Consider migrating to PackageReferences instead:
|
||||
// https://docs.microsoft.com/en-us/nuget/consume-packages/migrate-packages-config-to-package-reference
|
||||
// Migrating brings the following benefits:
|
||||
// * The "Nullable" folder and the nullable "*Attribute.cs" files don't appear in your project.
|
||||
// * The added files are immutable and can therefore not be modified by coincidence.
|
||||
// * Updating/Uninstalling the package will work flawlessly.
|
||||
// </auto-generated>
|
||||
|
||||
#region License
|
||||
// MIT License
|
||||
//
|
||||
// Copyright (c) Manuel Römer
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
#endregion
|
||||
|
||||
#if !NULLABLE_ATTRIBUTES_DISABLE
|
||||
#nullable enable
|
||||
#pragma warning disable
|
||||
|
||||
namespace System.Diagnostics.CodeAnalysis
|
||||
{
|
||||
using global::System;
|
||||
|
||||
#if DEBUG
|
||||
/// <summary>
|
||||
/// Specifies that <see langword="null"/> is allowed as an input even if the
|
||||
/// corresponding type disallows it.
|
||||
/// </summary>
|
||||
#endif
|
||||
[AttributeUsage(
|
||||
AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.Property,
|
||||
Inherited = false
|
||||
)]
|
||||
#if !NULLABLE_ATTRIBUTES_INCLUDE_IN_CODE_COVERAGE
|
||||
[DebuggerNonUserCode]
|
||||
#endif
|
||||
internal sealed class AllowNullAttribute : Attribute
|
||||
{
|
||||
#if DEBUG
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="AllowNullAttribute"/> class.
|
||||
/// </summary>
|
||||
#endif
|
||||
public AllowNullAttribute() { }
|
||||
}
|
||||
}
|
||||
|
||||
#pragma warning restore
|
||||
#nullable restore
|
||||
#endif // NULLABLE_ATTRIBUTES_DISABLE
|
||||
@@ -0,0 +1,73 @@
|
||||
// <auto-generated>
|
||||
// This code file has automatically been added by the "Nullable" NuGet package (https://www.nuget.org/packages/Nullable).
|
||||
// Please see https://github.com/manuelroemer/Nullable for more information.
|
||||
//
|
||||
// IMPORTANT:
|
||||
// DO NOT DELETE THIS FILE if you are using a "packages.config" file to manage your NuGet references.
|
||||
// Consider migrating to PackageReferences instead:
|
||||
// https://docs.microsoft.com/en-us/nuget/consume-packages/migrate-packages-config-to-package-reference
|
||||
// Migrating brings the following benefits:
|
||||
// * The "Nullable" folder and the nullable "*Attribute.cs" files don't appear in your project.
|
||||
// * The added files are immutable and can therefore not be modified by coincidence.
|
||||
// * Updating/Uninstalling the package will work flawlessly.
|
||||
// </auto-generated>
|
||||
|
||||
#region License
|
||||
// MIT License
|
||||
//
|
||||
// Copyright (c) Manuel Römer
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
#endregion
|
||||
|
||||
#if !NULLABLE_ATTRIBUTES_DISABLE
|
||||
#nullable enable
|
||||
#pragma warning disable
|
||||
|
||||
namespace System.Diagnostics.CodeAnalysis
|
||||
{
|
||||
using global::System;
|
||||
|
||||
#if DEBUG
|
||||
/// <summary>
|
||||
/// Specifies that <see langword="null"/> is disallowed as an input even if the
|
||||
/// corresponding type allows it.
|
||||
/// </summary>
|
||||
#endif
|
||||
[AttributeUsage(
|
||||
AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.Property,
|
||||
Inherited = false
|
||||
)]
|
||||
#if !NULLABLE_ATTRIBUTES_INCLUDE_IN_CODE_COVERAGE
|
||||
[DebuggerNonUserCode]
|
||||
#endif
|
||||
internal sealed class DisallowNullAttribute : Attribute
|
||||
{
|
||||
#if DEBUG
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="DisallowNullAttribute"/> class.
|
||||
/// </summary>
|
||||
#endif
|
||||
public DisallowNullAttribute() { }
|
||||
}
|
||||
}
|
||||
|
||||
#pragma warning restore
|
||||
#nullable restore
|
||||
#endif // NULLABLE_ATTRIBUTES_DISABLE
|
||||
@@ -0,0 +1,70 @@
|
||||
// <auto-generated>
|
||||
// This code file has automatically been added by the "Nullable" NuGet package (https://www.nuget.org/packages/Nullable).
|
||||
// Please see https://github.com/manuelroemer/Nullable for more information.
|
||||
//
|
||||
// IMPORTANT:
|
||||
// DO NOT DELETE THIS FILE if you are using a "packages.config" file to manage your NuGet references.
|
||||
// Consider migrating to PackageReferences instead:
|
||||
// https://docs.microsoft.com/en-us/nuget/consume-packages/migrate-packages-config-to-package-reference
|
||||
// Migrating brings the following benefits:
|
||||
// * The "Nullable" folder and the nullable "*Attribute.cs" files don't appear in your project.
|
||||
// * The added files are immutable and can therefore not be modified by coincidence.
|
||||
// * Updating/Uninstalling the package will work flawlessly.
|
||||
// </auto-generated>
|
||||
|
||||
#region License
|
||||
// MIT License
|
||||
//
|
||||
// Copyright (c) Manuel Römer
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
#endregion
|
||||
|
||||
#if !NULLABLE_ATTRIBUTES_DISABLE
|
||||
#nullable enable
|
||||
#pragma warning disable
|
||||
|
||||
namespace System.Diagnostics.CodeAnalysis
|
||||
{
|
||||
using global::System;
|
||||
|
||||
#if DEBUG
|
||||
/// <summary>
|
||||
/// Specifies that a method that will never return under any circumstance.
|
||||
/// </summary>
|
||||
#endif
|
||||
[AttributeUsage(AttributeTargets.Method, Inherited = false)]
|
||||
#if !NULLABLE_ATTRIBUTES_INCLUDE_IN_CODE_COVERAGE
|
||||
[DebuggerNonUserCode]
|
||||
#endif
|
||||
internal sealed class DoesNotReturnAttribute : Attribute
|
||||
{
|
||||
#if DEBUG
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="DoesNotReturnAttribute"/> class.
|
||||
/// </summary>
|
||||
///
|
||||
#endif
|
||||
public DoesNotReturnAttribute() { }
|
||||
}
|
||||
}
|
||||
|
||||
#pragma warning restore
|
||||
#nullable restore
|
||||
#endif // NULLABLE_ATTRIBUTES_DISABLE
|
||||
@@ -0,0 +1,88 @@
|
||||
// <auto-generated>
|
||||
// This code file has automatically been added by the "Nullable" NuGet package (https://www.nuget.org/packages/Nullable).
|
||||
// Please see https://github.com/manuelroemer/Nullable for more information.
|
||||
//
|
||||
// IMPORTANT:
|
||||
// DO NOT DELETE THIS FILE if you are using a "packages.config" file to manage your NuGet references.
|
||||
// Consider migrating to PackageReferences instead:
|
||||
// https://docs.microsoft.com/en-us/nuget/consume-packages/migrate-packages-config-to-package-reference
|
||||
// Migrating brings the following benefits:
|
||||
// * The "Nullable" folder and the nullable "*Attribute.cs" files don't appear in your project.
|
||||
// * The added files are immutable and can therefore not be modified by coincidence.
|
||||
// * Updating/Uninstalling the package will work flawlessly.
|
||||
// </auto-generated>
|
||||
|
||||
#region License
|
||||
// MIT License
|
||||
//
|
||||
// Copyright (c) Manuel Römer
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
#endregion
|
||||
|
||||
#if !NULLABLE_ATTRIBUTES_DISABLE
|
||||
#nullable enable
|
||||
#pragma warning disable
|
||||
|
||||
namespace System.Diagnostics.CodeAnalysis
|
||||
{
|
||||
using global::System;
|
||||
|
||||
#if DEBUG
|
||||
/// <summary>
|
||||
/// Specifies that the method will not return if the associated <see cref="Boolean"/>
|
||||
/// parameter is passed the specified value.
|
||||
/// </summary>
|
||||
#endif
|
||||
[AttributeUsage(AttributeTargets.Parameter, Inherited = false)]
|
||||
#if !NULLABLE_ATTRIBUTES_INCLUDE_IN_CODE_COVERAGE
|
||||
[DebuggerNonUserCode]
|
||||
#endif
|
||||
internal sealed class DoesNotReturnIfAttribute : Attribute
|
||||
{
|
||||
#if DEBUG
|
||||
/// <summary>
|
||||
/// Gets the condition parameter value.
|
||||
/// Code after the method is considered unreachable by diagnostics if the argument
|
||||
/// to the associated parameter matches this value.
|
||||
/// </summary>
|
||||
#endif
|
||||
public bool ParameterValue { get; }
|
||||
|
||||
#if DEBUG
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="DoesNotReturnIfAttribute"/>
|
||||
/// class with the specified parameter value.
|
||||
/// </summary>
|
||||
/// <param name="parameterValue">
|
||||
/// The condition parameter value.
|
||||
/// Code after the method is considered unreachable by diagnostics if the argument
|
||||
/// to the associated parameter matches this value.
|
||||
/// </param>
|
||||
#endif
|
||||
public DoesNotReturnIfAttribute(bool parameterValue)
|
||||
{
|
||||
ParameterValue = parameterValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#pragma warning restore
|
||||
#nullable restore
|
||||
#endif // NULLABLE_ATTRIBUTES_DISABLE
|
||||
@@ -0,0 +1,74 @@
|
||||
// <auto-generated>
|
||||
// This code file has automatically been added by the "Nullable" NuGet package (https://www.nuget.org/packages/Nullable).
|
||||
// Please see https://github.com/manuelroemer/Nullable for more information.
|
||||
//
|
||||
// IMPORTANT:
|
||||
// DO NOT DELETE THIS FILE if you are using a "packages.config" file to manage your NuGet references.
|
||||
// Consider migrating to PackageReferences instead:
|
||||
// https://docs.microsoft.com/en-us/nuget/consume-packages/migrate-packages-config-to-package-reference
|
||||
// Migrating brings the following benefits:
|
||||
// * The "Nullable" folder and the nullable "*Attribute.cs" files don't appear in your project.
|
||||
// * The added files are immutable and can therefore not be modified by coincidence.
|
||||
// * Updating/Uninstalling the package will work flawlessly.
|
||||
// </auto-generated>
|
||||
|
||||
#region License
|
||||
// MIT License
|
||||
//
|
||||
// Copyright (c) Manuel Römer
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
#endregion
|
||||
|
||||
#if !NULLABLE_ATTRIBUTES_DISABLE
|
||||
#nullable enable
|
||||
#pragma warning disable
|
||||
|
||||
namespace System.Diagnostics.CodeAnalysis
|
||||
{
|
||||
using global::System;
|
||||
|
||||
#if DEBUG
|
||||
/// <summary>
|
||||
/// Specifies that an output may be <see langword="null"/> even if the
|
||||
/// corresponding type disallows it.
|
||||
/// </summary>
|
||||
#endif
|
||||
[AttributeUsage(
|
||||
AttributeTargets.Field | AttributeTargets.Parameter |
|
||||
AttributeTargets.Property | AttributeTargets.ReturnValue,
|
||||
Inherited = false
|
||||
)]
|
||||
#if !NULLABLE_ATTRIBUTES_INCLUDE_IN_CODE_COVERAGE
|
||||
[DebuggerNonUserCode]
|
||||
#endif
|
||||
internal sealed class MaybeNullAttribute : Attribute
|
||||
{
|
||||
#if DEBUG
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="MaybeNullAttribute"/> class.
|
||||
/// </summary>
|
||||
#endif
|
||||
public MaybeNullAttribute() { }
|
||||
}
|
||||
}
|
||||
|
||||
#pragma warning restore
|
||||
#nullable restore
|
||||
#endif // NULLABLE_ATTRIBUTES_DISABLE
|
||||
@@ -0,0 +1,85 @@
|
||||
// <auto-generated>
|
||||
// This code file has automatically been added by the "Nullable" NuGet package (https://www.nuget.org/packages/Nullable).
|
||||
// Please see https://github.com/manuelroemer/Nullable for more information.
|
||||
//
|
||||
// IMPORTANT:
|
||||
// DO NOT DELETE THIS FILE if you are using a "packages.config" file to manage your NuGet references.
|
||||
// Consider migrating to PackageReferences instead:
|
||||
// https://docs.microsoft.com/en-us/nuget/consume-packages/migrate-packages-config-to-package-reference
|
||||
// Migrating brings the following benefits:
|
||||
// * The "Nullable" folder and the nullable "*Attribute.cs" files don't appear in your project.
|
||||
// * The added files are immutable and can therefore not be modified by coincidence.
|
||||
// * Updating/Uninstalling the package will work flawlessly.
|
||||
// </auto-generated>
|
||||
|
||||
#region License
|
||||
// MIT License
|
||||
//
|
||||
// Copyright (c) Manuel Römer
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
#endregion
|
||||
|
||||
#if !NULLABLE_ATTRIBUTES_DISABLE
|
||||
#nullable enable
|
||||
#pragma warning disable
|
||||
|
||||
namespace System.Diagnostics.CodeAnalysis
|
||||
{
|
||||
using global::System;
|
||||
|
||||
#if DEBUG
|
||||
/// <summary>
|
||||
/// Specifies that when a method returns <see cref="ReturnValue"/>,
|
||||
/// the parameter may be <see langword="null"/> even if the corresponding type disallows it.
|
||||
/// </summary>
|
||||
#endif
|
||||
[AttributeUsage(AttributeTargets.Parameter, Inherited = false)]
|
||||
#if !NULLABLE_ATTRIBUTES_INCLUDE_IN_CODE_COVERAGE
|
||||
[DebuggerNonUserCode]
|
||||
#endif
|
||||
internal sealed class MaybeNullWhenAttribute : Attribute
|
||||
{
|
||||
#if DEBUG
|
||||
/// <summary>
|
||||
/// Gets the return value condition.
|
||||
/// If the method returns this value, the associated parameter may be <see langword="null"/>.
|
||||
/// </summary>
|
||||
#endif
|
||||
public bool ReturnValue { get; }
|
||||
|
||||
#if DEBUG
|
||||
/// <summary>
|
||||
/// Initializes the attribute with the specified return value condition.
|
||||
/// </summary>
|
||||
/// <param name="returnValue">
|
||||
/// The return value condition.
|
||||
/// If the method returns this value, the associated parameter may be <see langword="null"/>.
|
||||
/// </param>
|
||||
#endif
|
||||
public MaybeNullWhenAttribute(bool returnValue)
|
||||
{
|
||||
ReturnValue = returnValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#pragma warning restore
|
||||
#nullable restore
|
||||
#endif // NULLABLE_ATTRIBUTES_DISABLE
|
||||
@@ -0,0 +1,96 @@
|
||||
// <auto-generated>
|
||||
// This code file has automatically been added by the "Nullable" NuGet package (https://www.nuget.org/packages/Nullable).
|
||||
// Please see https://github.com/manuelroemer/Nullable for more information.
|
||||
//
|
||||
// IMPORTANT:
|
||||
// DO NOT DELETE THIS FILE if you are using a "packages.config" file to manage your NuGet references.
|
||||
// Consider migrating to PackageReferences instead:
|
||||
// https://docs.microsoft.com/en-us/nuget/consume-packages/migrate-packages-config-to-package-reference
|
||||
// Migrating brings the following benefits:
|
||||
// * The "Nullable" folder and the nullable "*Attribute.cs" files don't appear in your project.
|
||||
// * The added files are immutable and can therefore not be modified by coincidence.
|
||||
// * Updating/Uninstalling the package will work flawlessly.
|
||||
// </auto-generated>
|
||||
|
||||
#region License
|
||||
// MIT License
|
||||
//
|
||||
// Copyright (c) Manuel Römer
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
#endregion
|
||||
|
||||
#if !NULLABLE_ATTRIBUTES_DISABLE
|
||||
#nullable enable
|
||||
#pragma warning disable
|
||||
|
||||
namespace System.Diagnostics.CodeAnalysis
|
||||
{
|
||||
using global::System;
|
||||
|
||||
#if DEBUG
|
||||
/// <summary>
|
||||
/// Specifies that the method or property will ensure that the listed field and property members have
|
||||
/// not-<see langword="null"/> values.
|
||||
/// </summary>
|
||||
#endif
|
||||
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Property, Inherited = false, AllowMultiple = true)]
|
||||
#if !NULLABLE_ATTRIBUTES_INCLUDE_IN_CODE_COVERAGE
|
||||
[DebuggerNonUserCode]
|
||||
#endif
|
||||
internal sealed class MemberNotNullAttribute : Attribute
|
||||
{
|
||||
#if DEBUG
|
||||
/// <summary>
|
||||
/// Gets field or property member names.
|
||||
/// </summary>
|
||||
#endif
|
||||
public string[] Members { get; }
|
||||
|
||||
#if DEBUG
|
||||
/// <summary>
|
||||
/// Initializes the attribute with a field or property member.
|
||||
/// </summary>
|
||||
/// <param name="member">
|
||||
/// The field or property member that is promised to be not-null.
|
||||
/// </param>
|
||||
#endif
|
||||
public MemberNotNullAttribute(string member)
|
||||
{
|
||||
Members = new[] { member };
|
||||
}
|
||||
|
||||
#if DEBUG
|
||||
/// <summary>
|
||||
/// Initializes the attribute with the list of field and property members.
|
||||
/// </summary>
|
||||
/// <param name="members">
|
||||
/// The list of field and property members that are promised to be not-null.
|
||||
/// </param>
|
||||
#endif
|
||||
public MemberNotNullAttribute(params string[] members)
|
||||
{
|
||||
Members = members;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#pragma warning restore
|
||||
#nullable restore
|
||||
#endif // NULLABLE_ATTRIBUTES_DISABLE
|
||||
@@ -0,0 +1,114 @@
|
||||
// <auto-generated>
|
||||
// This code file has automatically been added by the "Nullable" NuGet package (https://www.nuget.org/packages/Nullable).
|
||||
// Please see https://github.com/manuelroemer/Nullable for more information.
|
||||
//
|
||||
// IMPORTANT:
|
||||
// DO NOT DELETE THIS FILE if you are using a "packages.config" file to manage your NuGet references.
|
||||
// Consider migrating to PackageReferences instead:
|
||||
// https://docs.microsoft.com/en-us/nuget/consume-packages/migrate-packages-config-to-package-reference
|
||||
// Migrating brings the following benefits:
|
||||
// * The "Nullable" folder and the nullable "*Attribute.cs" files don't appear in your project.
|
||||
// * The added files are immutable and can therefore not be modified by coincidence.
|
||||
// * Updating/Uninstalling the package will work flawlessly.
|
||||
// </auto-generated>
|
||||
|
||||
#region License
|
||||
// MIT License
|
||||
//
|
||||
// Copyright (c) Manuel Römer
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
#endregion
|
||||
|
||||
#if !NULLABLE_ATTRIBUTES_DISABLE
|
||||
#nullable enable
|
||||
#pragma warning disable
|
||||
|
||||
namespace System.Diagnostics.CodeAnalysis
|
||||
{
|
||||
using global::System;
|
||||
|
||||
#if DEBUG
|
||||
/// <summary>
|
||||
/// Specifies that the method or property will ensure that the listed field and property members have
|
||||
/// non-<see langword="null"/> values when returning with the specified return value condition.
|
||||
/// </summary>
|
||||
#endif
|
||||
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Property, Inherited = false, AllowMultiple = true)]
|
||||
#if !NULLABLE_ATTRIBUTES_INCLUDE_IN_CODE_COVERAGE
|
||||
[DebuggerNonUserCode]
|
||||
#endif
|
||||
internal sealed class MemberNotNullWhenAttribute : Attribute
|
||||
{
|
||||
#if DEBUG
|
||||
/// <summary>
|
||||
/// Gets the return value condition.
|
||||
/// </summary>
|
||||
#endif
|
||||
public bool ReturnValue { get; }
|
||||
|
||||
#if DEBUG
|
||||
/// <summary>
|
||||
/// Gets field or property member names.
|
||||
/// </summary>
|
||||
#endif
|
||||
public string[] Members { get; }
|
||||
|
||||
#if DEBUG
|
||||
/// <summary>
|
||||
/// Initializes the attribute with the specified return value condition and a field or property member.
|
||||
/// </summary>
|
||||
/// <param name="returnValue">
|
||||
/// The return value condition. If the method returns this value,
|
||||
/// the associated parameter will not be <see langword="null"/>.
|
||||
/// </param>
|
||||
/// <param name="member">
|
||||
/// The field or property member that is promised to be not-<see langword="null"/>.
|
||||
/// </param>
|
||||
#endif
|
||||
public MemberNotNullWhenAttribute(bool returnValue, string member)
|
||||
{
|
||||
ReturnValue = returnValue;
|
||||
Members = new[] { member };
|
||||
}
|
||||
|
||||
#if DEBUG
|
||||
/// <summary>
|
||||
/// Initializes the attribute with the specified return value condition and list
|
||||
/// of field and property members.
|
||||
/// </summary>
|
||||
/// <param name="returnValue">
|
||||
/// The return value condition. If the method returns this value,
|
||||
/// the associated parameter will not be <see langword="null"/>.
|
||||
/// </param>
|
||||
/// <param name="members">
|
||||
/// The list of field and property members that are promised to be not-null.
|
||||
/// </param>
|
||||
#endif
|
||||
public MemberNotNullWhenAttribute(bool returnValue, params string[] members)
|
||||
{
|
||||
ReturnValue = returnValue;
|
||||
Members = members;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#pragma warning restore
|
||||
#nullable restore
|
||||
#endif // NULLABLE_ATTRIBUTES_DISABLE
|
||||
@@ -0,0 +1,74 @@
|
||||
// <auto-generated>
|
||||
// This code file has automatically been added by the "Nullable" NuGet package (https://www.nuget.org/packages/Nullable).
|
||||
// Please see https://github.com/manuelroemer/Nullable for more information.
|
||||
//
|
||||
// IMPORTANT:
|
||||
// DO NOT DELETE THIS FILE if you are using a "packages.config" file to manage your NuGet references.
|
||||
// Consider migrating to PackageReferences instead:
|
||||
// https://docs.microsoft.com/en-us/nuget/consume-packages/migrate-packages-config-to-package-reference
|
||||
// Migrating brings the following benefits:
|
||||
// * The "Nullable" folder and the nullable "*Attribute.cs" files don't appear in your project.
|
||||
// * The added files are immutable and can therefore not be modified by coincidence.
|
||||
// * Updating/Uninstalling the package will work flawlessly.
|
||||
// </auto-generated>
|
||||
|
||||
#region License
|
||||
// MIT License
|
||||
//
|
||||
// Copyright (c) Manuel Römer
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
#endregion
|
||||
|
||||
#if !NULLABLE_ATTRIBUTES_DISABLE
|
||||
#nullable enable
|
||||
#pragma warning disable
|
||||
|
||||
namespace System.Diagnostics.CodeAnalysis
|
||||
{
|
||||
using global::System;
|
||||
|
||||
#if DEBUG
|
||||
/// <summary>
|
||||
/// Specifies that an output is not <see langword="null"/> even if the
|
||||
/// corresponding type allows it.
|
||||
/// </summary>
|
||||
#endif
|
||||
[AttributeUsage(
|
||||
AttributeTargets.Field | AttributeTargets.Parameter |
|
||||
AttributeTargets.Property | AttributeTargets.ReturnValue,
|
||||
Inherited = false
|
||||
)]
|
||||
#if !NULLABLE_ATTRIBUTES_INCLUDE_IN_CODE_COVERAGE
|
||||
[DebuggerNonUserCode]
|
||||
#endif
|
||||
internal sealed class NotNullAttribute : Attribute
|
||||
{
|
||||
#if DEBUG
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="NotNullAttribute"/> class.
|
||||
/// </summary>
|
||||
#endif
|
||||
public NotNullAttribute() { }
|
||||
}
|
||||
}
|
||||
|
||||
#pragma warning restore
|
||||
#nullable restore
|
||||
#endif // NULLABLE_ATTRIBUTES_DISABLE
|
||||
@@ -0,0 +1,91 @@
|
||||
// <auto-generated>
|
||||
// This code file has automatically been added by the "Nullable" NuGet package (https://www.nuget.org/packages/Nullable).
|
||||
// Please see https://github.com/manuelroemer/Nullable for more information.
|
||||
//
|
||||
// IMPORTANT:
|
||||
// DO NOT DELETE THIS FILE if you are using a "packages.config" file to manage your NuGet references.
|
||||
// Consider migrating to PackageReferences instead:
|
||||
// https://docs.microsoft.com/en-us/nuget/consume-packages/migrate-packages-config-to-package-reference
|
||||
// Migrating brings the following benefits:
|
||||
// * The "Nullable" folder and the nullable "*Attribute.cs" files don't appear in your project.
|
||||
// * The added files are immutable and can therefore not be modified by coincidence.
|
||||
// * Updating/Uninstalling the package will work flawlessly.
|
||||
// </auto-generated>
|
||||
|
||||
#region License
|
||||
// MIT License
|
||||
//
|
||||
// Copyright (c) Manuel Römer
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
#endregion
|
||||
|
||||
#if !NULLABLE_ATTRIBUTES_DISABLE
|
||||
#nullable enable
|
||||
#pragma warning disable
|
||||
|
||||
namespace System.Diagnostics.CodeAnalysis
|
||||
{
|
||||
using global::System;
|
||||
|
||||
#if DEBUG
|
||||
/// <summary>
|
||||
/// Specifies that the output will be non-<see langword="null"/> if the
|
||||
/// named parameter is non-<see langword="null"/>.
|
||||
/// </summary>
|
||||
#endif
|
||||
[AttributeUsage(
|
||||
AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.ReturnValue,
|
||||
AllowMultiple = true,
|
||||
Inherited = false
|
||||
)]
|
||||
#if !NULLABLE_ATTRIBUTES_INCLUDE_IN_CODE_COVERAGE
|
||||
[DebuggerNonUserCode]
|
||||
#endif
|
||||
internal sealed class NotNullIfNotNullAttribute : Attribute
|
||||
{
|
||||
#if DEBUG
|
||||
/// <summary>
|
||||
/// Gets the associated parameter name.
|
||||
/// The output will be non-<see langword="null"/> if the argument to the
|
||||
/// parameter specified is non-<see langword="null"/>.
|
||||
/// </summary>
|
||||
#endif
|
||||
public string ParameterName { get; }
|
||||
|
||||
#if DEBUG
|
||||
/// <summary>
|
||||
/// Initializes the attribute with the associated parameter name.
|
||||
/// </summary>
|
||||
/// <param name="parameterName">
|
||||
/// The associated parameter name.
|
||||
/// The output will be non-<see langword="null"/> if the argument to the
|
||||
/// parameter specified is non-<see langword="null"/>.
|
||||
/// </param>
|
||||
#endif
|
||||
public NotNullIfNotNullAttribute(string parameterName)
|
||||
{
|
||||
ParameterName = parameterName;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#pragma warning restore
|
||||
#nullable restore
|
||||
#endif // NULLABLE_ATTRIBUTES_DISABLE
|
||||
@@ -0,0 +1,85 @@
|
||||
// <auto-generated>
|
||||
// This code file has automatically been added by the "Nullable" NuGet package (https://www.nuget.org/packages/Nullable).
|
||||
// Please see https://github.com/manuelroemer/Nullable for more information.
|
||||
//
|
||||
// IMPORTANT:
|
||||
// DO NOT DELETE THIS FILE if you are using a "packages.config" file to manage your NuGet references.
|
||||
// Consider migrating to PackageReferences instead:
|
||||
// https://docs.microsoft.com/en-us/nuget/consume-packages/migrate-packages-config-to-package-reference
|
||||
// Migrating brings the following benefits:
|
||||
// * The "Nullable" folder and the nullable "*Attribute.cs" files don't appear in your project.
|
||||
// * The added files are immutable and can therefore not be modified by coincidence.
|
||||
// * Updating/Uninstalling the package will work flawlessly.
|
||||
// </auto-generated>
|
||||
|
||||
#region License
|
||||
// MIT License
|
||||
//
|
||||
// Copyright (c) Manuel Römer
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
#endregion
|
||||
|
||||
#if !NULLABLE_ATTRIBUTES_DISABLE
|
||||
#nullable enable
|
||||
#pragma warning disable
|
||||
|
||||
namespace System.Diagnostics.CodeAnalysis
|
||||
{
|
||||
using global::System;
|
||||
|
||||
#if DEBUG
|
||||
/// <summary>
|
||||
/// Specifies that when a method returns <see cref="ReturnValue"/>,
|
||||
/// the parameter will not be <see langword="null"/> even if the corresponding type allows it.
|
||||
/// </summary>
|
||||
#endif
|
||||
[AttributeUsage(AttributeTargets.Parameter, Inherited = false)]
|
||||
#if !NULLABLE_ATTRIBUTES_INCLUDE_IN_CODE_COVERAGE
|
||||
[DebuggerNonUserCode]
|
||||
#endif
|
||||
internal sealed class NotNullWhenAttribute : Attribute
|
||||
{
|
||||
#if DEBUG
|
||||
/// <summary>
|
||||
/// Gets the return value condition.
|
||||
/// If the method returns this value, the associated parameter will not be <see langword="null"/>.
|
||||
/// </summary>
|
||||
#endif
|
||||
public bool ReturnValue { get; }
|
||||
|
||||
#if DEBUG
|
||||
/// <summary>
|
||||
/// Initializes the attribute with the specified return value condition.
|
||||
/// </summary>
|
||||
/// <param name="returnValue">
|
||||
/// The return value condition.
|
||||
/// If the method returns this value, the associated parameter will not be <see langword="null"/>.
|
||||
/// </param>
|
||||
#endif
|
||||
public NotNullWhenAttribute(bool returnValue)
|
||||
{
|
||||
ReturnValue = returnValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#pragma warning restore
|
||||
#nullable restore
|
||||
#endif // NULLABLE_ATTRIBUTES_DISABLE
|
||||
@@ -54,23 +54,23 @@
|
||||
<Reference Include="HandlebarsDotNet.Helpers.Core, Version=2.3.5.0, Culture=neutral, PublicKeyToken=00d131fae0c250bc, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\Handlebars.Net.Helpers.Core.2.3.5\lib\net452\HandlebarsDotNet.Helpers.Core.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="HandlebarsDotNet.Helpers.DynamicLinq, Version=2.3.3.0, Culture=neutral, PublicKeyToken=00d131fae0c250bc, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\Handlebars.Net.Helpers.DynamicLinq.2.3.3\lib\net452\HandlebarsDotNet.Helpers.DynamicLinq.dll</HintPath>
|
||||
<Reference Include="HandlebarsDotNet.Helpers.DynamicLinq, Version=2.3.5.0, Culture=neutral, PublicKeyToken=00d131fae0c250bc, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\Handlebars.Net.Helpers.DynamicLinq.2.3.5\lib\net452\HandlebarsDotNet.Helpers.DynamicLinq.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="HandlebarsDotNet.Helpers.Humanizer, Version=2.3.3.0, Culture=neutral, PublicKeyToken=00d131fae0c250bc, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\Handlebars.Net.Helpers.Humanizer.2.3.3\lib\net452\HandlebarsDotNet.Helpers.Humanizer.dll</HintPath>
|
||||
<Reference Include="HandlebarsDotNet.Helpers.Humanizer, Version=2.3.5.0, Culture=neutral, PublicKeyToken=00d131fae0c250bc, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\Handlebars.Net.Helpers.Humanizer.2.3.5\lib\net452\HandlebarsDotNet.Helpers.Humanizer.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="HandlebarsDotNet.Helpers.Json, Version=2.3.3.0, Culture=neutral, PublicKeyToken=00d131fae0c250bc, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\Handlebars.Net.Helpers.Json.2.3.3\lib\net452\HandlebarsDotNet.Helpers.Json.dll</HintPath>
|
||||
<Reference Include="HandlebarsDotNet.Helpers.Json, Version=2.3.5.0, Culture=neutral, PublicKeyToken=00d131fae0c250bc, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\Handlebars.Net.Helpers.Json.2.3.5\lib\net452\HandlebarsDotNet.Helpers.Json.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="HandlebarsDotNet.Helpers.Random, Version=2.3.3.0, Culture=neutral, PublicKeyToken=00d131fae0c250bc, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\Handlebars.Net.Helpers.Random.2.3.3\lib\net452\HandlebarsDotNet.Helpers.Random.dll</HintPath>
|
||||
<Reference Include="HandlebarsDotNet.Helpers.Random, Version=2.3.5.0, Culture=neutral, PublicKeyToken=00d131fae0c250bc, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\Handlebars.Net.Helpers.Random.2.3.5\lib\net452\HandlebarsDotNet.Helpers.Random.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="HandlebarsDotNet.Helpers.Xeger, Version=2.3.3.0, Culture=neutral, PublicKeyToken=00d131fae0c250bc, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\Handlebars.Net.Helpers.Xeger.2.3.3\lib\net452\HandlebarsDotNet.Helpers.Xeger.dll</HintPath>
|
||||
<Reference Include="HandlebarsDotNet.Helpers.Xeger, Version=2.3.5.0, Culture=neutral, PublicKeyToken=00d131fae0c250bc, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\Handlebars.Net.Helpers.Xeger.2.3.5\lib\net452\HandlebarsDotNet.Helpers.Xeger.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="HandlebarsDotNet.Helpers.XPath, Version=2.3.3.0, Culture=neutral, PublicKeyToken=00d131fae0c250bc, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\Handlebars.Net.Helpers.XPath.2.3.3\lib\net452\HandlebarsDotNet.Helpers.XPath.dll</HintPath>
|
||||
<Reference Include="HandlebarsDotNet.Helpers.XPath, Version=2.3.5.0, Culture=neutral, PublicKeyToken=00d131fae0c250bc, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\Handlebars.Net.Helpers.XPath.2.3.5\lib\net452\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>
|
||||
@@ -246,11 +246,23 @@
|
||||
<Reference Include="Microsoft.Net.Http.Headers, Version=2.2.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\Microsoft.Net.Http.Headers.2.2.0\lib\netstandard2.0\Microsoft.Net.Http.Headers.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Namotion.Reflection, Version=2.0.10.0, Culture=neutral, PublicKeyToken=c2f9c3bdfae56102, processorArchitecture=MSIL">
|
||||
<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.1\lib\net45\Newtonsoft.Json.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RandomDataGenerator, Version=1.0.13.0, Culture=neutral, PublicKeyToken=ae5c571d29a3b8d9, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\RandomDataGenerator.Net.1.0.14\lib\net45\RandomDataGenerator.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.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.15.0, Culture=neutral, PublicKeyToken=ae5c571d29a3b8d9, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\RandomDataGenerator.Net.1.0.15\lib\net45\RandomDataGenerator.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Scriban.Signed, Version=2.1.4.0, Culture=neutral, PublicKeyToken=5675fb69b15f2433, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\Scriban.Signed.2.1.4\lib\net45\Scriban.Signed.dll</HintPath>
|
||||
@@ -289,6 +301,10 @@
|
||||
<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>
|
||||
</Reference>
|
||||
<Reference Include="System.Net" />
|
||||
<Reference Include="System.Net.Http.Formatting, Version=5.2.8.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\Microsoft.AspNet.WebApi.Client.5.2.8\lib\net45\System.Net.Http.Formatting.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Net.Http.WebRequest" />
|
||||
<Reference Include="System.Numerics" />
|
||||
<Reference Include="System.Numerics.Vectors, Version=4.1.4.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
@@ -300,6 +316,7 @@
|
||||
<Reference Include="System.Runtime.CompilerServices.Unsafe, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\System.Runtime.CompilerServices.Unsafe.5.0.0\lib\net45\System.Runtime.CompilerServices.Unsafe.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Runtime.Serialization" />
|
||||
<Reference Include="System.Security.Cryptography.Cng, Version=4.3.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\System.Security.Cryptography.Cng.4.5.0\lib\net47\System.Security.Cryptography.Cng.dll</HintPath>
|
||||
</Reference>
|
||||
@@ -325,14 +342,14 @@
|
||||
<Reference Include="TinyMapper, Version=3.0.1.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\TinyMapper.3.0.3\lib\net40\TinyMapper.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="WireMock.Net, Version=1.4.41.0, Culture=neutral, PublicKeyToken=c8d65537854e1f03, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\WireMock.Net.1.4.41\lib\net461\WireMock.Net.dll</HintPath>
|
||||
<Reference Include="WireMock.Net, Version=1.5.1.0, Culture=neutral, PublicKeyToken=c8d65537854e1f03, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\WireMock.Net.1.5.1\lib\net461\WireMock.Net.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="WireMock.Net.Abstractions, Version=1.4.41.0, Culture=neutral, PublicKeyToken=c8d65537854e1f03, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\WireMock.Net.Abstractions.1.4.41\lib\net451\WireMock.Net.Abstractions.dll</HintPath>
|
||||
<Reference Include="WireMock.Net.Abstractions, Version=1.5.1.0, Culture=neutral, PublicKeyToken=c8d65537854e1f03, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\WireMock.Net.Abstractions.1.5.1\lib\net451\WireMock.Net.Abstractions.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="WireMock.Org.Abstractions, Version=1.4.41.0, Culture=neutral, PublicKeyToken=c8d65537854e1f03, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\WireMock.Org.Abstractions.1.4.41\lib\net45\WireMock.Org.Abstractions.dll</HintPath>
|
||||
<Reference Include="WireMock.Org.Abstractions, Version=1.5.1.0, Culture=neutral, PublicKeyToken=c8d65537854e1f03, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\WireMock.Org.Abstractions.1.5.1\lib\net45\WireMock.Org.Abstractions.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="XPath2, Version=1.1.3.0, Culture=neutral, PublicKeyToken=463c6d7fb740c7e5, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\XPath2.1.1.3\lib\net452\XPath2.dll</HintPath>
|
||||
@@ -351,6 +368,17 @@
|
||||
<Compile Include="..\WireMock.Net.Console.Net452.Classic\Program.cs">
|
||||
<Link>Program.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="Nullable\AllowNullAttribute.cs" />
|
||||
<Compile Include="Nullable\DisallowNullAttribute.cs" />
|
||||
<Compile Include="Nullable\DoesNotReturnAttribute.cs" />
|
||||
<Compile Include="Nullable\DoesNotReturnIfAttribute.cs" />
|
||||
<Compile Include="Nullable\MaybeNullAttribute.cs" />
|
||||
<Compile Include="Nullable\MaybeNullWhenAttribute.cs" />
|
||||
<Compile Include="Nullable\MemberNotNullAttribute.cs" />
|
||||
<Compile Include="Nullable\MemberNotNullWhenAttribute.cs" />
|
||||
<Compile Include="Nullable\NotNullAttribute.cs" />
|
||||
<Compile Include="Nullable\NotNullIfNotNullAttribute.cs" />
|
||||
<Compile Include="Nullable\NotNullWhenAttribute.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
||||
@@ -5,12 +5,12 @@
|
||||
<package id="Handlebars.Net" version="2.1.2" targetFramework="net472" />
|
||||
<package id="Handlebars.Net.Helpers" version="2.3.5" targetFramework="net472" />
|
||||
<package id="Handlebars.Net.Helpers.Core" version="2.3.5" targetFramework="net472" />
|
||||
<package id="Handlebars.Net.Helpers.DynamicLinq" version="2.3.3" targetFramework="net472" />
|
||||
<package id="Handlebars.Net.Helpers.Humanizer" version="2.3.3" targetFramework="net472" />
|
||||
<package id="Handlebars.Net.Helpers.Json" version="2.3.3" targetFramework="net472" />
|
||||
<package id="Handlebars.Net.Helpers.Random" version="2.3.3" targetFramework="net472" />
|
||||
<package id="Handlebars.Net.Helpers.Xeger" version="2.3.3" targetFramework="net472" />
|
||||
<package id="Handlebars.Net.Helpers.XPath" version="2.3.3" targetFramework="net472" />
|
||||
<package id="Handlebars.Net.Helpers.DynamicLinq" version="2.3.5" targetFramework="net472" />
|
||||
<package id="Handlebars.Net.Helpers.Humanizer" version="2.3.5" targetFramework="net472" />
|
||||
<package id="Handlebars.Net.Helpers.Json" version="2.3.5" targetFramework="net472" />
|
||||
<package id="Handlebars.Net.Helpers.Random" version="2.3.5" targetFramework="net472" />
|
||||
<package id="Handlebars.Net.Helpers.Xeger" version="2.3.5" targetFramework="net472" />
|
||||
<package id="Handlebars.Net.Helpers.XPath" version="2.3.5" 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" />
|
||||
@@ -63,6 +63,7 @@
|
||||
<package id="Humanizer.Core.zh-Hant" version="2.14.1" targetFramework="net472" />
|
||||
<package id="JmesPath.Net" version="1.0.125" targetFramework="net472" />
|
||||
<package id="log4net" version="2.0.14" targetFramework="net472" />
|
||||
<package id="Microsoft.AspNet.WebApi.Client" version="5.2.8" targetFramework="net472" />
|
||||
<package id="Microsoft.AspNetCore" version="2.2.0" targetFramework="net472" />
|
||||
<package id="Microsoft.AspNetCore.Authentication.Abstractions" version="2.2.0" targetFramework="net472" />
|
||||
<package id="Microsoft.AspNetCore.Authentication.Core" version="2.2.0" targetFramework="net472" />
|
||||
@@ -119,8 +120,13 @@
|
||||
<package id="Microsoft.IdentityModel.Protocols.OpenIdConnect" version="6.12.2" targetFramework="net472" />
|
||||
<package id="Microsoft.IdentityModel.Tokens" version="6.12.2" 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.1" targetFramework="net472" />
|
||||
<package id="RandomDataGenerator.Net" version="1.0.14" 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.15.10" targetFramework="net472" />
|
||||
<package id="Nullable" version="1.3.0" targetFramework="net472" developmentDependency="true" />
|
||||
<package id="RandomDataGenerator.Net" version="1.0.15" targetFramework="net472" />
|
||||
<package id="Scriban.Signed" version="2.1.4" targetFramework="net472" />
|
||||
<package id="SimMetrics.Net" version="1.0.5" targetFramework="net461" />
|
||||
<package id="Stef.Validation" version="0.1.0" targetFramework="net472" />
|
||||
@@ -141,9 +147,9 @@
|
||||
<package id="System.Threading.Tasks.Extensions" version="4.5.1" targetFramework="net472" />
|
||||
<package id="System.ValueTuple" version="4.5.0" targetFramework="net472" />
|
||||
<package id="TinyMapper" version="3.0.3" targetFramework="net472" />
|
||||
<package id="WireMock.Net" version="1.4.41" targetFramework="net472" />
|
||||
<package id="WireMock.Net.Abstractions" version="1.4.41" targetFramework="net472" />
|
||||
<package id="WireMock.Org.Abstractions" version="1.4.41" targetFramework="net472" />
|
||||
<package id="WireMock.Net" version="1.5.1" targetFramework="net472" />
|
||||
<package id="WireMock.Net.Abstractions" version="1.5.1" targetFramework="net472" />
|
||||
<package id="WireMock.Org.Abstractions" version="1.5.1" targetFramework="net472" />
|
||||
<package id="XPath2" version="1.1.3" targetFramework="net472" />
|
||||
<package id="XPath2.Extensions" version="1.1.3" targetFramework="net472" />
|
||||
</packages>
|
||||
@@ -204,8 +204,8 @@
|
||||
<Reference Include="Owin, Version=1.0.0.0, Culture=neutral, PublicKeyToken=f0ebd12fd5e55cc5, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\Owin.1.0\lib\net40\Owin.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RestEase, Version=1.5.5.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\RestEase.1.5.5\lib\net45\RestEase.dll</HintPath>
|
||||
<Reference Include="RestEase, Version=1.5.7.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\RestEase.1.5.7\lib\net452\RestEase.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>
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
<package id="Microsoft.AspNetCore.Hosting" version="2.1.1" targetFramework="net461" />
|
||||
<package id="Microsoft.AspNetCore.Hosting.Abstractions" version="2.1.1" targetFramework="net461" />
|
||||
<package id="Microsoft.AspNetCore.Hosting.Server.Abstractions" version="2.1.1" targetFramework="net461" />
|
||||
<package id="Microsoft.AspNetCore.Http" version="2.1.1" targetFramework="net461" />
|
||||
<package id="Microsoft.AspNetCore.Http" version="2.1.22" targetFramework="net461" />
|
||||
<package id="Microsoft.AspNetCore.Http.Abstractions" version="2.1.1" targetFramework="net461" />
|
||||
<package id="Microsoft.AspNetCore.Http.Extensions" version="2.1.1" targetFramework="net461" />
|
||||
<package id="Microsoft.AspNetCore.Http.Features" version="2.1.1" targetFramework="net461" />
|
||||
@@ -24,7 +24,7 @@
|
||||
<package id="Microsoft.AspNetCore.Routing.Abstractions" version="2.1.1" targetFramework="net461" />
|
||||
<package id="Microsoft.AspNetCore.Server.IISIntegration" version="2.1.2" targetFramework="net461" />
|
||||
<package id="Microsoft.AspNetCore.Server.Kestrel" version="2.1.3" targetFramework="net461" />
|
||||
<package id="Microsoft.AspNetCore.Server.Kestrel.Core" version="2.1.3" targetFramework="net461" />
|
||||
<package id="Microsoft.AspNetCore.Server.Kestrel.Core" version="2.1.7" targetFramework="net461" />
|
||||
<package id="Microsoft.AspNetCore.Server.Kestrel.Https" version="2.1.3" targetFramework="net461" />
|
||||
<package id="Microsoft.AspNetCore.Server.Kestrel.Transport.Abstractions" version="2.1.3" targetFramework="net461" />
|
||||
<package id="Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets" version="2.1.3" targetFramework="net461" />
|
||||
@@ -59,7 +59,7 @@
|
||||
<package id="MimeKitLite" version="2.0.7" 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.5" targetFramework="net461" />
|
||||
<package id="RestEase" version="1.5.7" targetFramework="net461" />
|
||||
<package id="SimMetrics.Net" version="1.0.5" targetFramework="net461" />
|
||||
<package id="System.Buffers" version="4.5.0" targetFramework="net461" />
|
||||
<package id="System.Collections.Immutable" version="1.5.0" targetFramework="net461" />
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
<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="11.0.2" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition=" '$(TargetFramework)' == 'netcoreapp2.1'">
|
||||
|
||||
@@ -1,19 +1,27 @@
|
||||
namespace WireMock.Admin.Mappings
|
||||
namespace WireMock.Admin.Mappings;
|
||||
|
||||
/// <summary>
|
||||
/// Body Model
|
||||
/// </summary>
|
||||
[FluentBuilder.AutoGenerateBuilder]
|
||||
public class BodyModel
|
||||
{
|
||||
/// <summary>
|
||||
/// Body Model
|
||||
/// Gets or sets the matcher.
|
||||
/// </summary>
|
||||
[FluentBuilder.AutoGenerateBuilder]
|
||||
public class BodyModel
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the matcher.
|
||||
/// </summary>
|
||||
public MatcherModel? Matcher { get; set; }
|
||||
public MatcherModel? Matcher { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the matchers.
|
||||
/// </summary>
|
||||
public MatcherModel[]? Matchers { get; set; }
|
||||
}
|
||||
/// <summary>
|
||||
/// Gets or sets the matchers.
|
||||
/// </summary>
|
||||
public MatcherModel[]? Matchers { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The Operator to use when matchers are defined. [Optional]
|
||||
/// - null = Same as "or".
|
||||
/// - "or" = Only one pattern should match.
|
||||
/// - "and" = All patterns should match.
|
||||
/// - "average" = The average value from all patterns.
|
||||
/// </summary>
|
||||
public string? MatchOperator { get; set; }
|
||||
}
|
||||
@@ -1,14 +1,22 @@
|
||||
namespace WireMock.Admin.Mappings
|
||||
namespace WireMock.Admin.Mappings;
|
||||
|
||||
/// <summary>
|
||||
/// ClientIPModel
|
||||
/// </summary>
|
||||
[FluentBuilder.AutoGenerateBuilder]
|
||||
public class ClientIPModel
|
||||
{
|
||||
/// <summary>
|
||||
/// ClientIPModel
|
||||
/// Gets or sets the matchers.
|
||||
/// </summary>
|
||||
[FluentBuilder.AutoGenerateBuilder]
|
||||
public class ClientIPModel
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the matchers.
|
||||
/// </summary>
|
||||
public MatcherModel[] Matchers { get; set; }
|
||||
}
|
||||
public MatcherModel[]? Matchers { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The Operator to use when matchers are defined. [Optional]
|
||||
/// - null = Same as "or".
|
||||
/// - "or" = Only one pattern should match.
|
||||
/// - "and" = All patterns should match.
|
||||
/// - "average" = The average value from all patterns.
|
||||
/// </summary>
|
||||
public string? MatchOperator { get; set; }
|
||||
}
|
||||
@@ -1,31 +1,39 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace WireMock.Admin.Mappings
|
||||
namespace WireMock.Admin.Mappings;
|
||||
|
||||
/// <summary>
|
||||
/// Header Model
|
||||
/// </summary>
|
||||
[FluentBuilder.AutoGenerateBuilder]
|
||||
public class HeaderModel
|
||||
{
|
||||
/// <summary>
|
||||
/// Header Model
|
||||
/// Gets or sets the name.
|
||||
/// </summary>
|
||||
[FluentBuilder.AutoGenerateBuilder]
|
||||
public class HeaderModel
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the name.
|
||||
/// </summary>
|
||||
public string Name { get; set; } = null!;
|
||||
public string Name { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the matchers.
|
||||
/// </summary>
|
||||
public IList<MatcherModel>? Matchers { get; set; }
|
||||
/// <summary>
|
||||
/// Gets or sets the matchers.
|
||||
/// </summary>
|
||||
public IList<MatcherModel>? Matchers { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the ignore case.
|
||||
/// </summary>
|
||||
public bool? IgnoreCase { get; set; }
|
||||
/// <summary>
|
||||
/// Gets or sets the ignore case.
|
||||
/// </summary>
|
||||
public bool? IgnoreCase { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Reject on match.
|
||||
/// </summary>
|
||||
public bool? RejectOnMatch { get; set; }
|
||||
}
|
||||
/// <summary>
|
||||
/// Reject on match.
|
||||
/// </summary>
|
||||
public bool? RejectOnMatch { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The Operator to use when matchers are defined. [Optional]
|
||||
/// - null = Same as "or".
|
||||
/// - "or" = Only one pattern should match.
|
||||
/// - "and" = All patterns should match.
|
||||
/// - "average" = The average value from all patterns.
|
||||
/// </summary>
|
||||
public string? MatchOperator { get; set; }
|
||||
}
|
||||
@@ -1,78 +1,77 @@
|
||||
using System;
|
||||
using WireMock.Models;
|
||||
|
||||
namespace WireMock.Admin.Mappings
|
||||
namespace WireMock.Admin.Mappings;
|
||||
|
||||
/// <summary>
|
||||
/// MappingModel
|
||||
/// </summary>
|
||||
[FluentBuilder.AutoGenerateBuilder]
|
||||
public class MappingModel
|
||||
{
|
||||
/// <summary>
|
||||
/// MappingModel
|
||||
/// Gets or sets the unique identifier.
|
||||
/// </summary>
|
||||
[FluentBuilder.AutoGenerateBuilder]
|
||||
public class MappingModel
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the unique identifier.
|
||||
/// </summary>
|
||||
public Guid? Guid { get; set; }
|
||||
public Guid? Guid { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the TimeSettings when which this mapping should be used.
|
||||
/// </summary>
|
||||
public TimeSettingsModel TimeSettings { get; set; }
|
||||
/// <summary>
|
||||
/// Gets or sets the TimeSettings when which this mapping should be used.
|
||||
/// </summary>
|
||||
public TimeSettingsModel? TimeSettings { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The unique title.
|
||||
/// </summary>
|
||||
public string Title { get; set; }
|
||||
/// <summary>
|
||||
/// The unique title.
|
||||
/// </summary>
|
||||
public string? Title { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The description.
|
||||
/// </summary>
|
||||
public string Description { get; set; }
|
||||
/// <summary>
|
||||
/// The description.
|
||||
/// </summary>
|
||||
public string? Description { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The priority. (A low value means higher priority.)
|
||||
/// </summary>
|
||||
public int? Priority { get; set; }
|
||||
/// <summary>
|
||||
/// The priority. (A low value means higher priority.)
|
||||
/// </summary>
|
||||
public int? Priority { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The Scenario.
|
||||
/// </summary>
|
||||
public string Scenario { get; set; }
|
||||
/// <summary>
|
||||
/// The Scenario.
|
||||
/// </summary>
|
||||
public string? Scenario { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Execution state condition for the current mapping.
|
||||
/// </summary>
|
||||
public string WhenStateIs { get; set; }
|
||||
/// <summary>
|
||||
/// Execution state condition for the current mapping.
|
||||
/// </summary>
|
||||
public string? WhenStateIs { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The next state which will be signaled after the current mapping execution.
|
||||
/// In case the value is null state will not be changed.
|
||||
/// </summary>
|
||||
public string SetStateTo { get; set; }
|
||||
/// <summary>
|
||||
/// The next state which will be signaled after the current mapping execution.
|
||||
/// In case the value is null state will not be changed.
|
||||
/// </summary>
|
||||
public string? SetStateTo { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The request model.
|
||||
/// </summary>
|
||||
public RequestModel Request { get; set; }
|
||||
/// <summary>
|
||||
/// The request model.
|
||||
/// </summary>
|
||||
public RequestModel Request { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The response model.
|
||||
/// </summary>
|
||||
public ResponseModel Response { get; set; }
|
||||
/// <summary>
|
||||
/// The response model.
|
||||
/// </summary>
|
||||
public ResponseModel Response { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Saves this mapping as a static mapping file.
|
||||
/// </summary>
|
||||
public bool? SaveToFile { get; set; }
|
||||
/// <summary>
|
||||
/// Saves this mapping as a static mapping file.
|
||||
/// </summary>
|
||||
public bool? SaveToFile { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The Webhook.
|
||||
/// </summary>
|
||||
public WebhookModel Webhook { get; set; }
|
||||
/// <summary>
|
||||
/// The Webhook.
|
||||
/// </summary>
|
||||
public WebhookModel? Webhook { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The Webhooks.
|
||||
/// </summary>
|
||||
public WebhookModel[] Webhooks { get; set; }
|
||||
}
|
||||
/// <summary>
|
||||
/// The Webhooks.
|
||||
/// </summary>
|
||||
public WebhookModel[]? Webhooks { get; set; }
|
||||
}
|
||||
@@ -1,39 +1,52 @@
|
||||
namespace WireMock.Admin.Mappings
|
||||
namespace WireMock.Admin.Mappings;
|
||||
|
||||
/// <summary>
|
||||
/// MatcherModel
|
||||
/// </summary>
|
||||
[FluentBuilder.AutoGenerateBuilder]
|
||||
public class MatcherModel
|
||||
{
|
||||
/// <summary>
|
||||
/// MatcherModel
|
||||
/// Gets or sets the name.
|
||||
/// </summary>
|
||||
[FluentBuilder.AutoGenerateBuilder]
|
||||
public class MatcherModel
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the name.
|
||||
/// </summary>
|
||||
public string Name { get; set; }
|
||||
public string Name { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the pattern. Can be a string (default) or an object.
|
||||
/// </summary>
|
||||
public object? Pattern { get; set; }
|
||||
/// <summary>
|
||||
/// Gets or sets the pattern. Can be a string (default) or an object.
|
||||
/// </summary>
|
||||
public object? Pattern { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the patterns. Can be array of strings (default) or an array of objects.
|
||||
/// </summary>
|
||||
public object[]? Patterns { get; set; }
|
||||
/// <summary>
|
||||
/// Gets or sets the patterns. Can be array of strings (default) or an array of objects.
|
||||
/// </summary>
|
||||
public object[]? Patterns { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the pattern as a file.
|
||||
/// </summary>
|
||||
public string? PatternAsFile { get; set; }
|
||||
/// <summary>
|
||||
/// Gets or sets the pattern as a file.
|
||||
/// </summary>
|
||||
public string? PatternAsFile { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the ignore case.
|
||||
/// </summary>
|
||||
public bool? IgnoreCase { get; set; }
|
||||
/// <summary>
|
||||
/// Gets or sets the ignore case.
|
||||
/// </summary>
|
||||
public bool? IgnoreCase { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Reject on match.
|
||||
/// </summary>
|
||||
public bool? RejectOnMatch { get; set; }
|
||||
}
|
||||
/// <summary>
|
||||
/// Reject on match.
|
||||
/// </summary>
|
||||
public bool? RejectOnMatch { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The Operator to use when multiple patterns are defined. Optional.
|
||||
/// - null = Same as "or".
|
||||
/// - "or" = Only one pattern should match.
|
||||
/// - "and" = All patterns should match.
|
||||
/// - "average" = The average value from all patterns.
|
||||
/// </summary>
|
||||
public string? MatchOperator { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Support Regex, only used for JsonPartialMatcher.
|
||||
/// </summary>
|
||||
public bool? Regex { get; set; }
|
||||
}
|
||||
@@ -1,14 +1,22 @@
|
||||
namespace WireMock.Admin.Mappings
|
||||
namespace WireMock.Admin.Mappings;
|
||||
|
||||
/// <summary>
|
||||
/// PathModel
|
||||
/// </summary>
|
||||
[FluentBuilder.AutoGenerateBuilder]
|
||||
public class PathModel
|
||||
{
|
||||
/// <summary>
|
||||
/// PathModel
|
||||
/// Gets or sets the matchers.
|
||||
/// </summary>
|
||||
[FluentBuilder.AutoGenerateBuilder]
|
||||
public class PathModel
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the matchers.
|
||||
/// </summary>
|
||||
public MatcherModel[]? Matchers { get; set; }
|
||||
}
|
||||
public MatcherModel[]? Matchers { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The Operator to use when matchers are defined. [Optional]
|
||||
/// - null = Same as "or".
|
||||
/// - "or" = Only one pattern should match.
|
||||
/// - "and" = All patterns should match.
|
||||
/// - "average" = The average value from all patterns.
|
||||
/// </summary>
|
||||
public string? MatchOperator { get; set; }
|
||||
}
|
||||
@@ -28,6 +28,20 @@ public class RequestModel
|
||||
/// </summary>
|
||||
public string[]? Methods { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Reject on match for Methods.
|
||||
/// </summary>
|
||||
public bool? MethodsRejectOnMatch { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The Operator to use when Methods are defined. [Optional]
|
||||
/// - null = Same as "or".
|
||||
/// - "or" = Only one method should match.
|
||||
/// - "and" = All methods should match.
|
||||
/// - "average" = The average value from all methods.
|
||||
/// </summary>
|
||||
public string? MethodsMatchOperator { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the Headers.
|
||||
/// </summary>
|
||||
|
||||
@@ -1,14 +1,22 @@
|
||||
namespace WireMock.Admin.Mappings
|
||||
namespace WireMock.Admin.Mappings;
|
||||
|
||||
/// <summary>
|
||||
/// UrlModel
|
||||
/// </summary>
|
||||
[FluentBuilder.AutoGenerateBuilder]
|
||||
public class UrlModel
|
||||
{
|
||||
/// <summary>
|
||||
/// UrlModel
|
||||
/// Gets or sets the matchers.
|
||||
/// </summary>
|
||||
[FluentBuilder.AutoGenerateBuilder]
|
||||
public class UrlModel
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the matchers.
|
||||
/// </summary>
|
||||
public MatcherModel[] Matchers { get; set; }
|
||||
}
|
||||
}
|
||||
public MatcherModel[]? Matchers { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The Operator to use when matchers are defined. [Optional]
|
||||
/// - null = Same as "or".
|
||||
/// - "or" = Only one pattern should match.
|
||||
/// - "and" = All patterns should match.
|
||||
/// - "average" = The average value from all patterns.
|
||||
/// </summary>
|
||||
public string? MatchOperator { get; set; }
|
||||
}
|
||||
@@ -15,24 +15,24 @@ namespace WireMock.Admin.Mappings
|
||||
public string Url { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The methods
|
||||
/// The method
|
||||
/// </summary>
|
||||
public string Method { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the headers.
|
||||
/// </summary>
|
||||
public IDictionary<string, string> Headers { get; set; }
|
||||
public IDictionary<string, string>? Headers { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the body.
|
||||
/// </summary>
|
||||
public string Body { get; set; }
|
||||
public string? Body { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the body (as JSON object).
|
||||
/// </summary>
|
||||
public object BodyAsJson { get; set; }
|
||||
public object? BodyAsJson { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Use ResponseMessage Transformer.
|
||||
|
||||
@@ -3,136 +3,135 @@ using System.Collections.Generic;
|
||||
using WireMock.Types;
|
||||
using WireMock.Util;
|
||||
|
||||
namespace WireMock
|
||||
namespace WireMock;
|
||||
|
||||
/// <summary>
|
||||
/// IRequestMessage
|
||||
/// </summary>
|
||||
public interface IRequestMessage
|
||||
{
|
||||
/// <summary>
|
||||
/// IRequestMessage
|
||||
/// Gets the Client IP Address.
|
||||
/// </summary>
|
||||
public interface IRequestMessage
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the Client IP Address.
|
||||
/// </summary>
|
||||
string ClientIP { get; }
|
||||
string ClientIP { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the url (relative).
|
||||
/// </summary>
|
||||
string Url { get; }
|
||||
/// <summary>
|
||||
/// Gets the url (relative).
|
||||
/// </summary>
|
||||
string Url { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the AbsoluteUrl.
|
||||
/// </summary>
|
||||
string AbsoluteUrl { get; }
|
||||
/// <summary>
|
||||
/// Gets the AbsoluteUrl.
|
||||
/// </summary>
|
||||
string AbsoluteUrl { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The ProxyUrl (if a proxy is used).
|
||||
/// </summary>
|
||||
string ProxyUrl { get; set; }
|
||||
/// <summary>
|
||||
/// The ProxyUrl (if a proxy is used).
|
||||
/// </summary>
|
||||
string ProxyUrl { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the DateTime.
|
||||
/// </summary>
|
||||
DateTime DateTime { get; }
|
||||
/// <summary>
|
||||
/// Gets the DateTime.
|
||||
/// </summary>
|
||||
DateTime DateTime { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the path (relative).
|
||||
/// </summary>
|
||||
string Path { get; }
|
||||
/// <summary>
|
||||
/// Gets the path (relative).
|
||||
/// </summary>
|
||||
string Path { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the AbsolutePath.
|
||||
/// </summary>
|
||||
string AbsolutePath { get; }
|
||||
/// <summary>
|
||||
/// Gets the AbsolutePath.
|
||||
/// </summary>
|
||||
string AbsolutePath { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the path segments.
|
||||
/// </summary>
|
||||
string[] PathSegments { get; }
|
||||
/// <summary>
|
||||
/// Gets the path segments.
|
||||
/// </summary>
|
||||
string[] PathSegments { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the absolute path segments.
|
||||
/// </summary>
|
||||
string[] AbsolutePathSegments { get; }
|
||||
/// <summary>
|
||||
/// Gets the absolute path segments.
|
||||
/// </summary>
|
||||
string[] AbsolutePathSegments { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the method.
|
||||
/// </summary>
|
||||
string Method { get; }
|
||||
/// <summary>
|
||||
/// Gets the method.
|
||||
/// </summary>
|
||||
string Method { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the headers.
|
||||
/// </summary>
|
||||
IDictionary<string, WireMockList<string>> Headers { get; }
|
||||
/// <summary>
|
||||
/// Gets the headers.
|
||||
/// </summary>
|
||||
IDictionary<string, WireMockList<string>>? Headers { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the cookies.
|
||||
/// </summary>
|
||||
IDictionary<string, string> Cookies { get; }
|
||||
/// <summary>
|
||||
/// Gets the cookies.
|
||||
/// </summary>
|
||||
IDictionary<string, string>? Cookies { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the query.
|
||||
/// </summary>
|
||||
IDictionary<string, WireMockList<string>> Query { get; }
|
||||
/// <summary>
|
||||
/// Gets the query.
|
||||
/// </summary>
|
||||
IDictionary<string, WireMockList<string>>? Query { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the raw query.
|
||||
/// </summary>
|
||||
string RawQuery { get; }
|
||||
/// <summary>
|
||||
/// Gets the raw query.
|
||||
/// </summary>
|
||||
string RawQuery { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The body.
|
||||
/// </summary>
|
||||
IBodyData? BodyData { get; }
|
||||
/// <summary>
|
||||
/// The body.
|
||||
/// </summary>
|
||||
IBodyData? BodyData { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The original body as string. Convenience getter for Handlebars.
|
||||
/// </summary>
|
||||
string Body { get; }
|
||||
/// <summary>
|
||||
/// The original body as string. Convenience getter for Handlebars.
|
||||
/// </summary>
|
||||
string Body { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The body (as JSON object). Convenience getter for Handlebars.
|
||||
/// </summary>
|
||||
object BodyAsJson { get; }
|
||||
/// <summary>
|
||||
/// The body (as JSON object). Convenience getter for Handlebars.
|
||||
/// </summary>
|
||||
object BodyAsJson { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The body (as bytearray). Convenience getter for Handlebars.
|
||||
/// </summary>
|
||||
byte[] BodyAsBytes { get; }
|
||||
/// <summary>
|
||||
/// The body (as bytearray). Convenience getter for Handlebars.
|
||||
/// </summary>
|
||||
byte[] BodyAsBytes { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The detected body type. Convenience getter for Handlebars.
|
||||
/// </summary>
|
||||
string DetectedBodyType { get; }
|
||||
/// <summary>
|
||||
/// The detected body type. Convenience getter for Handlebars.
|
||||
/// </summary>
|
||||
string DetectedBodyType { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The detected body type from the Content-Type header. Convenience getter for Handlebars.
|
||||
/// </summary>
|
||||
string DetectedBodyTypeFromContentType { get; }
|
||||
/// <summary>
|
||||
/// The detected body type from the Content-Type header. Convenience getter for Handlebars.
|
||||
/// </summary>
|
||||
string DetectedBodyTypeFromContentType { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The detected compression from the Content-Encoding header. Convenience getter for Handlebars.
|
||||
/// </summary>
|
||||
string DetectedCompression { get; }
|
||||
/// <summary>
|
||||
/// The detected compression from the Content-Encoding header. Convenience getter for Handlebars.
|
||||
/// </summary>
|
||||
string DetectedCompression { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the Host
|
||||
/// </summary>
|
||||
string Host { get; }
|
||||
/// <summary>
|
||||
/// Gets the Host
|
||||
/// </summary>
|
||||
string Host { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the protocol
|
||||
/// </summary>
|
||||
string Protocol { get; }
|
||||
/// <summary>
|
||||
/// Gets the protocol
|
||||
/// </summary>
|
||||
string Protocol { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the port
|
||||
/// </summary>
|
||||
int Port { get; }
|
||||
/// <summary>
|
||||
/// Gets the port
|
||||
/// </summary>
|
||||
int Port { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the origin
|
||||
/// </summary>
|
||||
string Origin { get; }
|
||||
}
|
||||
/// <summary>
|
||||
/// Gets the origin
|
||||
/// </summary>
|
||||
string Origin { get; }
|
||||
}
|
||||
@@ -38,7 +38,7 @@ namespace WireMock
|
||||
/// <summary>
|
||||
/// Gets the headers.
|
||||
/// </summary>
|
||||
IDictionary<string, WireMockList<string>> Headers { get; }
|
||||
IDictionary<string, WireMockList<string>>? Headers { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the status code.
|
||||
|
||||
@@ -1,20 +1,17 @@
|
||||
using JetBrains.Annotations;
|
||||
namespace WireMock.Matchers.Request;
|
||||
|
||||
namespace WireMock.Matchers.Request
|
||||
/// <summary>
|
||||
/// The RequestMatcher interface.
|
||||
/// </summary>
|
||||
public interface IRequestMatcher
|
||||
{
|
||||
/// <summary>
|
||||
/// The RequestMatcher interface.
|
||||
/// Determines whether the specified RequestMessage is match.
|
||||
/// </summary>
|
||||
public interface IRequestMatcher
|
||||
{
|
||||
/// <summary>
|
||||
/// Determines whether the specified RequestMessage is match.
|
||||
/// </summary>
|
||||
/// <param name="requestMessage">The RequestMessage.</param>
|
||||
/// <param name="requestMatchResult">The RequestMatchResult.</param>
|
||||
/// <returns>
|
||||
/// A value between 0.0 - 1.0 of the similarity.
|
||||
/// </returns>
|
||||
double GetMatchingScore([NotNull] IRequestMessage requestMessage, [NotNull] IRequestMatchResult requestMatchResult);
|
||||
}
|
||||
/// <param name="requestMessage">The RequestMessage.</param>
|
||||
/// <param name="requestMatchResult">The RequestMatchResult.</param>
|
||||
/// <returns>
|
||||
/// A value between 0.0 - 1.0 of the similarity.
|
||||
/// </returns>
|
||||
double GetMatchingScore(IRequestMessage requestMessage, IRequestMatchResult requestMatchResult);
|
||||
}
|
||||
@@ -22,12 +22,12 @@ namespace WireMock.Models
|
||||
/// <summary>
|
||||
/// The Headers to send.
|
||||
/// </summary>
|
||||
IDictionary<string, WireMockList<string>> Headers { get; }
|
||||
IDictionary<string, WireMockList<string>>? Headers { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The body to send.
|
||||
/// </summary>
|
||||
IBodyData BodyData { get; set; }
|
||||
IBodyData? BodyData { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Use Transformer.
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.1.1" PrivateAssets="All" />
|
||||
|
||||
<!-- See also https://mstack.nl/blog/20210801-source-generators -->
|
||||
<PackageReference Include="FluentBuilder" Version="0.4.4">
|
||||
<PackageReference Include="FluentBuilder" Version="0.4.9">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
|
||||
@@ -3,138 +3,137 @@ using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using AnyOfTypes;
|
||||
using JetBrains.Annotations;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Stef.Validation;
|
||||
using WireMock.Exceptions;
|
||||
using WireMock.Extensions;
|
||||
using WireMock.Models;
|
||||
using Stef.Validation;
|
||||
|
||||
namespace WireMock.Matchers
|
||||
namespace WireMock.Matchers;
|
||||
|
||||
/// <summary>
|
||||
/// CSharpCode / CS-Script Matcher
|
||||
/// </summary>
|
||||
/// <inheritdoc cref="ICSharpCodeMatcher"/>
|
||||
internal class CSharpCodeMatcher : ICSharpCodeMatcher
|
||||
{
|
||||
/// <summary>
|
||||
/// CSharpCode / CS-Script Matcher
|
||||
/// </summary>
|
||||
/// <inheritdoc cref="ICSharpCodeMatcher"/>
|
||||
internal class CSharpCodeMatcher : ICSharpCodeMatcher
|
||||
private const string TemplateForIsMatchWithString = "public class CodeHelper {{ public bool IsMatch(string it) {{ {0} }} }}";
|
||||
|
||||
private const string TemplateForIsMatchWithDynamic = "public class CodeHelper {{ public bool IsMatch(dynamic it) {{ {0} }} }}";
|
||||
|
||||
private readonly string[] _usings =
|
||||
{
|
||||
private const string TemplateForIsMatchWithString = "public class CodeHelper {{ public bool IsMatch(string it) {{ {0} }} }}";
|
||||
"System",
|
||||
"System.Linq",
|
||||
"System.Collections.Generic",
|
||||
"Microsoft.CSharp",
|
||||
"Newtonsoft.Json.Linq"
|
||||
};
|
||||
|
||||
private const string TemplateForIsMatchWithDynamic = "public class CodeHelper {{ public bool IsMatch(dynamic it) {{ {0} }} }}";
|
||||
public MatchBehaviour MatchBehaviour { get; }
|
||||
|
||||
private readonly string[] _usings =
|
||||
{
|
||||
"System",
|
||||
"System.Linq",
|
||||
"System.Collections.Generic",
|
||||
"Microsoft.CSharp",
|
||||
"Newtonsoft.Json.Linq"
|
||||
};
|
||||
|
||||
public MatchBehaviour MatchBehaviour { get; }
|
||||
|
||||
/// <inheritdoc cref="IMatcher.ThrowException"/>
|
||||
public bool ThrowException { get; }
|
||||
|
||||
private readonly AnyOf<string, StringPattern>[] _patterns;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="CSharpCodeMatcher"/> class.
|
||||
/// </summary>
|
||||
/// <param name="patterns">The patterns.</param>
|
||||
public CSharpCodeMatcher([NotNull] params AnyOf<string, StringPattern>[] patterns) : this(MatchBehaviour.AcceptOnMatch, patterns)
|
||||
/// <inheritdoc cref="IMatcher.ThrowException"/>
|
||||
public bool ThrowException { get; }
|
||||
|
||||
private readonly AnyOf<string, StringPattern>[] _patterns;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="CSharpCodeMatcher"/> class.
|
||||
/// </summary>
|
||||
/// <param name="patterns">The patterns.</param>
|
||||
public CSharpCodeMatcher(params AnyOf<string, StringPattern>[] patterns) : this(MatchBehaviour.AcceptOnMatch, MatchOperator.Or, patterns)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="CSharpCodeMatcher"/> class.
|
||||
/// </summary>
|
||||
/// <param name="matchBehaviour">The match behaviour.</param>
|
||||
/// <param name="matchOperator">The <see cref="Matchers.MatchOperator"/> to use. (default = "Or")</param>
|
||||
/// <param name="patterns">The patterns.</param>
|
||||
public CSharpCodeMatcher(MatchBehaviour matchBehaviour, MatchOperator matchOperator = MatchOperator.Or, params AnyOf<string, StringPattern>[] patterns)
|
||||
{
|
||||
_patterns = Guard.NotNull(patterns);
|
||||
MatchBehaviour = matchBehaviour;
|
||||
ThrowException = false;
|
||||
MatchOperator = matchOperator;
|
||||
}
|
||||
|
||||
public double IsMatch(string input)
|
||||
{
|
||||
return IsMatchInternal(input);
|
||||
}
|
||||
|
||||
public double IsMatch(object? input)
|
||||
{
|
||||
return IsMatchInternal(input);
|
||||
}
|
||||
|
||||
public double IsMatchInternal(object? input)
|
||||
{
|
||||
double match = MatchScores.Mismatch;
|
||||
|
||||
if (input != null)
|
||||
{
|
||||
match = MatchScores.ToScore(_patterns.Select(pattern => IsMatch(input, pattern.GetPattern())).ToArray(), MatchOperator);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="CSharpCodeMatcher"/> class.
|
||||
/// </summary>
|
||||
/// <param name="matchBehaviour">The match behaviour.</param>
|
||||
/// <param name="patterns">The patterns.</param>
|
||||
public CSharpCodeMatcher(MatchBehaviour matchBehaviour, [NotNull] params AnyOf<string, StringPattern>[] patterns)
|
||||
{
|
||||
Guard.NotNull(patterns, nameof(patterns));
|
||||
return MatchBehaviourHelper.Convert(MatchBehaviour, match);
|
||||
}
|
||||
|
||||
MatchBehaviour = matchBehaviour;
|
||||
ThrowException = false;
|
||||
_patterns = patterns;
|
||||
}
|
||||
private bool IsMatch(dynamic input, string pattern)
|
||||
{
|
||||
bool isMatchWithString = input is string;
|
||||
var inputValue = isMatchWithString ? input : JObject.FromObject(input);
|
||||
string source = GetSourceForIsMatchWithString(pattern, isMatchWithString);
|
||||
|
||||
public double IsMatch(string input)
|
||||
{
|
||||
return IsMatchInternal(input);
|
||||
}
|
||||
|
||||
public double IsMatch(object input)
|
||||
{
|
||||
return IsMatchInternal(input);
|
||||
}
|
||||
|
||||
public double IsMatchInternal(object input)
|
||||
{
|
||||
double match = MatchScores.Mismatch;
|
||||
|
||||
if (input != null)
|
||||
{
|
||||
match = MatchScores.ToScore(_patterns.Select(pattern => IsMatch(input, pattern.GetPattern())));
|
||||
}
|
||||
|
||||
return MatchBehaviourHelper.Convert(MatchBehaviour, match);
|
||||
}
|
||||
|
||||
private bool IsMatch(dynamic input, string pattern)
|
||||
{
|
||||
bool isMatchWithString = input is string;
|
||||
var inputValue = isMatchWithString ? input : JObject.FromObject(input);
|
||||
string source = GetSourceForIsMatchWithString(pattern, isMatchWithString);
|
||||
|
||||
object result = null;
|
||||
object? result;
|
||||
|
||||
#if (NET451 || NET452)
|
||||
var compilerParams = new System.CodeDom.Compiler.CompilerParameters
|
||||
var compilerParams = new System.CodeDom.Compiler.CompilerParameters
|
||||
{
|
||||
GenerateInMemory = true,
|
||||
GenerateExecutable = false,
|
||||
ReferencedAssemblies =
|
||||
{
|
||||
GenerateInMemory = true,
|
||||
GenerateExecutable = false,
|
||||
ReferencedAssemblies =
|
||||
{
|
||||
"System.dll",
|
||||
"System.Core.dll",
|
||||
"Microsoft.CSharp.dll",
|
||||
"Newtonsoft.Json.dll"
|
||||
}
|
||||
};
|
||||
|
||||
using (var codeProvider = new Microsoft.CSharp.CSharpCodeProvider())
|
||||
{
|
||||
var compilerResults = codeProvider.CompileAssemblyFromSource(compilerParams, source);
|
||||
|
||||
if (compilerResults.Errors.Count != 0)
|
||||
{
|
||||
var errors = from System.CodeDom.Compiler.CompilerError er in compilerResults.Errors select er.ToString();
|
||||
throw new WireMockException(string.Join(", ", errors));
|
||||
}
|
||||
|
||||
object helper = compilerResults.CompiledAssembly.CreateInstance("CodeHelper");
|
||||
if (helper == null)
|
||||
{
|
||||
throw new WireMockException("CSharpCodeMatcher: Unable to create instance from WireMock.CodeHelper");
|
||||
}
|
||||
|
||||
var methodInfo = helper.GetType().GetMethod("IsMatch");
|
||||
if (methodInfo == null)
|
||||
{
|
||||
throw new WireMockException("CSharpCodeMatcher: Unable to find method 'IsMatch' in WireMock.CodeHelper");
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
result = methodInfo.Invoke(helper, new[] { inputValue });
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new WireMockException("CSharpCodeMatcher: Unable to call method 'IsMatch' in WireMock.CodeHelper", ex);
|
||||
}
|
||||
"System.dll",
|
||||
"System.Core.dll",
|
||||
"Microsoft.CSharp.dll",
|
||||
"Newtonsoft.Json.dll"
|
||||
}
|
||||
};
|
||||
|
||||
using (var codeProvider = new Microsoft.CSharp.CSharpCodeProvider())
|
||||
{
|
||||
var compilerResults = codeProvider.CompileAssemblyFromSource(compilerParams, source);
|
||||
|
||||
if (compilerResults.Errors.Count != 0)
|
||||
{
|
||||
var errors = from System.CodeDom.Compiler.CompilerError er in compilerResults.Errors select er.ToString();
|
||||
throw new WireMockException(string.Join(", ", errors));
|
||||
}
|
||||
|
||||
var helper = compilerResults.CompiledAssembly?.CreateInstance("CodeHelper");
|
||||
if (helper == null)
|
||||
{
|
||||
throw new WireMockException("CSharpCodeMatcher: Unable to create instance from WireMock.CodeHelper");
|
||||
}
|
||||
|
||||
var methodInfo = helper.GetType().GetMethod("IsMatch");
|
||||
if (methodInfo == null)
|
||||
{
|
||||
throw new WireMockException("CSharpCodeMatcher: Unable to find method 'IsMatch' in WireMock.CodeHelper");
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
result = methodInfo.Invoke(helper, new[] { inputValue });
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new WireMockException("CSharpCodeMatcher: Unable to call method 'IsMatch' in WireMock.CodeHelper", ex);
|
||||
}
|
||||
}
|
||||
#elif (NET46 || NET461)
|
||||
dynamic script;
|
||||
try
|
||||
@@ -169,11 +168,7 @@ namespace WireMock.Matchers
|
||||
dynamic script;
|
||||
try
|
||||
{
|
||||
//#if NETSTANDARD2_0
|
||||
// script = csscript.GenericExtensions.CreateObject(assembly, "*");
|
||||
//#else
|
||||
script = CSScripting.ReflectionExtensions.CreateObject(assembly, "*");
|
||||
//#endif
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -191,38 +186,40 @@ namespace WireMock.Matchers
|
||||
#else
|
||||
throw new NotSupportedException("The 'CSharpCodeMatcher' cannot be used in netstandard 1.3");
|
||||
#endif
|
||||
try
|
||||
{
|
||||
return (bool)result;
|
||||
}
|
||||
catch
|
||||
{
|
||||
throw new WireMockException($"Unable to cast result '{result}' to bool");
|
||||
}
|
||||
}
|
||||
|
||||
private string GetSourceForIsMatchWithString(string pattern, bool isMatchWithString)
|
||||
try
|
||||
{
|
||||
string template = isMatchWithString ? TemplateForIsMatchWithString : TemplateForIsMatchWithDynamic;
|
||||
|
||||
var stringBuilder = new StringBuilder();
|
||||
foreach (string @using in _usings)
|
||||
{
|
||||
stringBuilder.AppendLine($"using {@using};");
|
||||
}
|
||||
stringBuilder.AppendLine();
|
||||
stringBuilder.AppendFormat(template, pattern);
|
||||
|
||||
return stringBuilder.ToString();
|
||||
return (bool)result;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IStringMatcher.GetPatterns"/>
|
||||
public AnyOf<string, StringPattern>[] GetPatterns()
|
||||
catch
|
||||
{
|
||||
return _patterns;
|
||||
throw new WireMockException($"Unable to cast result '{result}' to bool");
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IMatcher.Name"/>
|
||||
public string Name => "CSharpCodeMatcher";
|
||||
}
|
||||
|
||||
private string GetSourceForIsMatchWithString(string pattern, bool isMatchWithString)
|
||||
{
|
||||
string template = isMatchWithString ? TemplateForIsMatchWithString : TemplateForIsMatchWithDynamic;
|
||||
|
||||
var stringBuilder = new StringBuilder();
|
||||
foreach (string @using in _usings)
|
||||
{
|
||||
stringBuilder.AppendLine($"using {@using};");
|
||||
}
|
||||
stringBuilder.AppendLine();
|
||||
stringBuilder.AppendFormat(template, pattern);
|
||||
|
||||
return stringBuilder.ToString();
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IStringMatcher.GetPatterns"/>
|
||||
public AnyOf<string, StringPattern>[] GetPatterns()
|
||||
{
|
||||
return _patterns;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public MatchOperator MatchOperator { get; }
|
||||
|
||||
/// <inheritdoc cref="IMatcher.Name"/>
|
||||
public string Name => "CSharpCodeMatcher";
|
||||
}
|
||||
@@ -31,7 +31,7 @@
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.1.1" PrivateAssets="All" />
|
||||
<PackageReference Include="RestEase" Version="1.5.6" />
|
||||
<PackageReference Include="RestEase" Version="1.5.7" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
79
src/WireMock.Net.xUnit/TestOutputHelperWireMockLogger.cs
Normal file
79
src/WireMock.Net.xUnit/TestOutputHelperWireMockLogger.cs
Normal file
@@ -0,0 +1,79 @@
|
||||
using System;
|
||||
using Newtonsoft.Json;
|
||||
using Stef.Validation;
|
||||
using WireMock.Admin.Requests;
|
||||
using WireMock.Logging;
|
||||
using Xunit.Abstractions;
|
||||
|
||||
namespace WireMock.Net.Xunit;
|
||||
|
||||
/// <summary>
|
||||
/// When using xUnit, this class enables to log the output from WireMock.Net to the <see cref="ITestOutputHelper"/>.
|
||||
/// </summary>
|
||||
public sealed class TestOutputHelperWireMockLogger : IWireMockLogger
|
||||
{
|
||||
private readonly ITestOutputHelper _testOutputHelper;
|
||||
|
||||
/// <summary>
|
||||
/// Create a new instance on the <see cref="TestOutputHelperWireMockLogger"/>.
|
||||
/// </summary>
|
||||
/// <param name="testOutputHelper">Represents a class which can be used to provide test output.</param>
|
||||
public TestOutputHelperWireMockLogger(ITestOutputHelper testOutputHelper)
|
||||
{
|
||||
_testOutputHelper = Guard.NotNull(testOutputHelper);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void Debug(string formatString, params object[] args)
|
||||
{
|
||||
_testOutputHelper.WriteLine(Format("Debug", formatString, args));
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void Info(string formatString, params object[] args)
|
||||
{
|
||||
_testOutputHelper.WriteLine(Format("Info", formatString, args));
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void Warn(string formatString, params object[] args)
|
||||
{
|
||||
_testOutputHelper.WriteLine(Format("Warning", formatString, args));
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void Error(string formatString, params object[] args)
|
||||
{
|
||||
_testOutputHelper.WriteLine(Format("Error", formatString, args));
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void Error(string formatString, Exception exception)
|
||||
{
|
||||
_testOutputHelper.WriteLine(Format("Error", formatString, exception.Message));
|
||||
|
||||
if (exception is AggregateException ae)
|
||||
{
|
||||
ae.Handle(ex =>
|
||||
{
|
||||
_testOutputHelper.WriteLine(Format("Error", "Exception {0}", ex.Message));
|
||||
return true;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void DebugRequestResponse(LogEntryModel logEntryModel, bool isAdminRequest)
|
||||
{
|
||||
var message = JsonConvert.SerializeObject(logEntryModel, Formatting.Indented);
|
||||
_testOutputHelper.WriteLine(Format("DebugRequestResponse", "Admin[{0}] {1}", isAdminRequest, message));
|
||||
}
|
||||
|
||||
private static string Format(string level, string formatString, params object[] args)
|
||||
{
|
||||
Guard.NotNull(formatString);
|
||||
|
||||
var message = args.Length > 0 ? string.Format(formatString, args) : formatString;
|
||||
return $"{DateTime.UtcNow} [{level}] : {message}";
|
||||
}
|
||||
}
|
||||
37
src/WireMock.Net.xUnit/WireMock.Net.xUnit.csproj
Normal file
37
src/WireMock.Net.xUnit/WireMock.Net.xUnit.csproj
Normal file
@@ -0,0 +1,37 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<Description>Some extensions for xUnit (ITestOutputHelper)</Description>
|
||||
<AssemblyTitle>WireMock.Net.xUnit</AssemblyTitle>
|
||||
<Authors>Stef Heyenrath</Authors>
|
||||
<TargetFrameworks>net45;net451;netstandard1.0;netstandard2.0;netstandard2.1</TargetFrameworks>
|
||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||
<AssemblyName>WireMock.Net.xUnit</AssemblyName>
|
||||
<RootNamespace>WireMock.Net.Xunit</RootNamespace>
|
||||
<PackageId>WireMock.Net.xUnit</PackageId>
|
||||
<PackageTags>tdd;wiremock;test;unittest;xunit</PackageTags>
|
||||
<ProjectGuid>{0DE0954F-8C00-4E8D-B94A-4361FC1CBE44}</ProjectGuid>
|
||||
<PublishRepositoryUrl>true</PublishRepositoryUrl>
|
||||
<AllowedOutputExtensionsInPackageBuildOutputFolder>$(AllowedOutputExtensionsInPackageBuildOutputFolder);.pdb</AllowedOutputExtensionsInPackageBuildOutputFolder>
|
||||
<EmbedUntrackedSources>true</EmbedUntrackedSources>
|
||||
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
|
||||
<GenerateBindingRedirectsOutputType>true</GenerateBindingRedirectsOutputType>
|
||||
<SignAssembly>true</SignAssembly>
|
||||
<AssemblyOriginatorKeyFile>../WireMock.Net/WireMock.Net.snk</AssemblyOriginatorKeyFile>
|
||||
<PublicSign Condition=" '$(OS)' != 'Windows_NT' ">true</PublicSign>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
|
||||
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.1.1" PrivateAssets="All" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
|
||||
<PackageReference Include="Stef.Validation" Version="0.1.0" />
|
||||
<PackageReference Include="xUnit.abstractions" Version="2.0.3" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\WireMock.Net.Abstractions\WireMock.Net.Abstractions.csproj" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -39,6 +39,8 @@ namespace WireMock.Authentication
|
||||
return new AnyOf<string, StringPattern>[0];
|
||||
}
|
||||
|
||||
public MatchOperator MatchOperator { get; } = MatchOperator.Or;
|
||||
|
||||
public double IsMatch(string input)
|
||||
{
|
||||
var token = Regex.Replace(input, BearerPrefix, string.Empty, RegexOptions.IgnoreCase);
|
||||
|
||||
@@ -3,64 +3,63 @@ using System.Net.Http;
|
||||
using WireMock.HttpsCertificate;
|
||||
using WireMock.Settings;
|
||||
|
||||
namespace WireMock.Http
|
||||
namespace WireMock.Http;
|
||||
|
||||
internal static class HttpClientBuilder
|
||||
{
|
||||
internal static class HttpClientBuilder
|
||||
public static HttpClient Build(HttpClientSettings settings)
|
||||
{
|
||||
public static HttpClient Build(HttpClientSettings settings)
|
||||
{
|
||||
#if NETSTANDARD || NETCOREAPP3_1 || NET5_0 || NET6_0
|
||||
var handler = new HttpClientHandler
|
||||
{
|
||||
CheckCertificateRevocationList = false,
|
||||
SslProtocols = System.Security.Authentication.SslProtocols.Tls12 | System.Security.Authentication.SslProtocols.Tls11 | System.Security.Authentication.SslProtocols.Tls,
|
||||
ServerCertificateCustomValidationCallback = (message, cert, chain, errors) => true,
|
||||
AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate
|
||||
};
|
||||
var handler = new HttpClientHandler
|
||||
{
|
||||
CheckCertificateRevocationList = false,
|
||||
SslProtocols = System.Security.Authentication.SslProtocols.Tls12 | System.Security.Authentication.SslProtocols.Tls11 | System.Security.Authentication.SslProtocols.Tls,
|
||||
ServerCertificateCustomValidationCallback = (message, cert, chain, errors) => true,
|
||||
AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate
|
||||
};
|
||||
#elif NET46
|
||||
var handler = new HttpClientHandler
|
||||
{
|
||||
ServerCertificateCustomValidationCallback = (message, cert, chain, errors) => true,
|
||||
AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate
|
||||
};
|
||||
var handler = new HttpClientHandler
|
||||
{
|
||||
ServerCertificateCustomValidationCallback = (message, cert, chain, errors) => true,
|
||||
AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate
|
||||
};
|
||||
#else
|
||||
var handler = new WebRequestHandler
|
||||
{
|
||||
ServerCertificateValidationCallback = (sender, certificate, chain, errors) => true,
|
||||
AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate
|
||||
};
|
||||
var handler = new WebRequestHandler
|
||||
{
|
||||
ServerCertificateValidationCallback = (sender, certificate, chain, errors) => true,
|
||||
AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate
|
||||
};
|
||||
#endif
|
||||
|
||||
if (!string.IsNullOrEmpty(settings.ClientX509Certificate2ThumbprintOrSubjectName))
|
||||
if (!string.IsNullOrEmpty(settings.ClientX509Certificate2ThumbprintOrSubjectName))
|
||||
{
|
||||
handler.ClientCertificateOptions = ClientCertificateOption.Manual;
|
||||
|
||||
var x509Certificate2 = CertificateLoader.LoadCertificate(settings.ClientX509Certificate2ThumbprintOrSubjectName);
|
||||
handler.ClientCertificates.Add(x509Certificate2);
|
||||
}
|
||||
|
||||
handler.AllowAutoRedirect = settings.AllowAutoRedirect == true;
|
||||
|
||||
// If UseCookies enabled, httpClient ignores Cookie header
|
||||
handler.UseCookies = false;
|
||||
|
||||
if (settings.WebProxySettings != null)
|
||||
{
|
||||
handler.UseProxy = true;
|
||||
|
||||
handler.Proxy = new WebProxy(settings.WebProxySettings.Address);
|
||||
if (settings.WebProxySettings.UserName != null && settings.WebProxySettings.Password != null)
|
||||
{
|
||||
handler.ClientCertificateOptions = ClientCertificateOption.Manual;
|
||||
|
||||
var x509Certificate2 = CertificateLoader.LoadCertificate(settings.ClientX509Certificate2ThumbprintOrSubjectName);
|
||||
handler.ClientCertificates.Add(x509Certificate2);
|
||||
}
|
||||
|
||||
handler.AllowAutoRedirect = settings.AllowAutoRedirect == true;
|
||||
|
||||
// If UseCookies enabled, httpClient ignores Cookie header
|
||||
handler.UseCookies = false;
|
||||
|
||||
if (settings.WebProxySettings != null)
|
||||
{
|
||||
handler.UseProxy = true;
|
||||
|
||||
handler.Proxy = new WebProxy(settings.WebProxySettings.Address);
|
||||
if (settings.WebProxySettings.UserName != null && settings.WebProxySettings.Password != null)
|
||||
{
|
||||
handler.Proxy.Credentials = new NetworkCredential(settings.WebProxySettings.UserName, settings.WebProxySettings.Password);
|
||||
}
|
||||
handler.Proxy.Credentials = new NetworkCredential(settings.WebProxySettings.UserName, settings.WebProxySettings.Password);
|
||||
}
|
||||
}
|
||||
|
||||
#if !NETSTANDARD1_3
|
||||
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls;
|
||||
ServicePointManager.ServerCertificateValidationCallback = (message, cert, chain, errors) => true;
|
||||
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls;
|
||||
ServicePointManager.ServerCertificateValidationCallback = (message, cert, chain, errors) => true;
|
||||
#endif
|
||||
|
||||
return new HttpClient(handler);
|
||||
}
|
||||
return HttpClientFactory2.Create(handler);
|
||||
}
|
||||
}
|
||||
24
src/WireMock.Net/Http/HttpClientFactory2.cs
Normal file
24
src/WireMock.Net/Http/HttpClientFactory2.cs
Normal file
@@ -0,0 +1,24 @@
|
||||
using System.Net.Http;
|
||||
|
||||
namespace WireMock.Http;
|
||||
|
||||
internal static class HttpClientFactory2
|
||||
{
|
||||
public static HttpClient Create(params DelegatingHandler[] handlers)
|
||||
{
|
||||
#if NETSTANDARD1_3
|
||||
return new HttpClient();
|
||||
#else
|
||||
return HttpClientFactory.Create(handlers);
|
||||
#endif
|
||||
}
|
||||
|
||||
public static HttpClient Create(HttpMessageHandler innerHandler, params DelegatingHandler[] handlers)
|
||||
{
|
||||
#if NETSTANDARD1_3
|
||||
return new HttpClient(innerHandler);
|
||||
#else
|
||||
return HttpClientFactory.Create(innerHandler, handlers);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -5,60 +5,64 @@ using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
using WireMock.Util;
|
||||
|
||||
namespace WireMock.Http
|
||||
namespace WireMock.Http;
|
||||
|
||||
internal static class HttpResponseMessageHelper
|
||||
{
|
||||
internal static class HttpResponseMessageHelper
|
||||
public static async Task<ResponseMessage> CreateAsync(
|
||||
HttpResponseMessage httpResponseMessage,
|
||||
Uri requiredUri,
|
||||
Uri originalUri,
|
||||
bool deserializeJson,
|
||||
bool decompressGzipAndDeflate)
|
||||
{
|
||||
public static async Task<ResponseMessage> CreateAsync(HttpResponseMessage httpResponseMessage, Uri requiredUri, Uri originalUri, bool deserializeJson, bool decompressGzipAndDeflate)
|
||||
var responseMessage = new ResponseMessage { StatusCode = (int)httpResponseMessage.StatusCode };
|
||||
|
||||
// Set both content and response headers, replacing URLs in values
|
||||
var headers = (httpResponseMessage.Content?.Headers.Union(httpResponseMessage.Headers) ?? Enumerable.Empty<KeyValuePair<string, IEnumerable<string>>>()).ToArray();
|
||||
if (httpResponseMessage.Content != null)
|
||||
{
|
||||
var responseMessage = new ResponseMessage { StatusCode = (int)httpResponseMessage.StatusCode };
|
||||
|
||||
// Set both content and response headers, replacing URLs in values
|
||||
var headers = (httpResponseMessage.Content?.Headers.Union(httpResponseMessage.Headers) ?? Enumerable.Empty<KeyValuePair<string, IEnumerable<string>>>()).ToArray();
|
||||
if (httpResponseMessage.Content != null)
|
||||
var stream = await httpResponseMessage.Content.ReadAsStreamAsync().ConfigureAwait(false);
|
||||
IEnumerable<string>? contentTypeHeader = null;
|
||||
if (headers.Any(header => string.Equals(header.Key, HttpKnownHeaderNames.ContentType, StringComparison.OrdinalIgnoreCase)))
|
||||
{
|
||||
var stream = await httpResponseMessage.Content.ReadAsStreamAsync().ConfigureAwait(false);
|
||||
IEnumerable<string> contentTypeHeader = null;
|
||||
if (headers.Any(header => string.Equals(header.Key, HttpKnownHeaderNames.ContentType, StringComparison.OrdinalIgnoreCase)))
|
||||
{
|
||||
contentTypeHeader = headers.First(header => string.Equals(header.Key, HttpKnownHeaderNames.ContentType, StringComparison.OrdinalIgnoreCase)).Value;
|
||||
}
|
||||
|
||||
IEnumerable<string> contentEncodingHeader = null;
|
||||
if (headers.Any(header => string.Equals(header.Key, HttpKnownHeaderNames.ContentEncoding, StringComparison.OrdinalIgnoreCase)))
|
||||
{
|
||||
contentEncodingHeader = headers.First(header => string.Equals(header.Key, HttpKnownHeaderNames.ContentEncoding, StringComparison.OrdinalIgnoreCase)).Value;
|
||||
}
|
||||
|
||||
var bodyParserSettings = new BodyParserSettings
|
||||
{
|
||||
Stream = stream,
|
||||
ContentType = contentTypeHeader?.FirstOrDefault(),
|
||||
DeserializeJson = deserializeJson,
|
||||
ContentEncoding = contentEncodingHeader?.FirstOrDefault(),
|
||||
DecompressGZipAndDeflate = decompressGzipAndDeflate
|
||||
};
|
||||
responseMessage.BodyData = await BodyParser.ParseAsync(bodyParserSettings).ConfigureAwait(false);
|
||||
contentTypeHeader = headers.First(header => string.Equals(header.Key, HttpKnownHeaderNames.ContentType, StringComparison.OrdinalIgnoreCase)).Value;
|
||||
}
|
||||
|
||||
foreach (var header in headers)
|
||||
IEnumerable<string>? contentEncodingHeader = null;
|
||||
if (headers.Any(header => string.Equals(header.Key, HttpKnownHeaderNames.ContentEncoding, StringComparison.OrdinalIgnoreCase)))
|
||||
{
|
||||
// If Location header contains absolute redirect URL, and base URL is one that we proxy to,
|
||||
// we need to replace it to original one.
|
||||
if (string.Equals(header.Key, HttpKnownHeaderNames.Location, StringComparison.OrdinalIgnoreCase)
|
||||
&& Uri.TryCreate(header.Value.First(), UriKind.Absolute, out Uri absoluteLocationUri)
|
||||
&& string.Equals(absoluteLocationUri.Host, requiredUri.Host, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
var replacedLocationUri = new Uri(originalUri, absoluteLocationUri.PathAndQuery);
|
||||
responseMessage.AddHeader(header.Key, replacedLocationUri.ToString());
|
||||
}
|
||||
else
|
||||
{
|
||||
responseMessage.AddHeader(header.Key, header.Value.ToArray());
|
||||
}
|
||||
contentEncodingHeader = headers.First(header => string.Equals(header.Key, HttpKnownHeaderNames.ContentEncoding, StringComparison.OrdinalIgnoreCase)).Value;
|
||||
}
|
||||
|
||||
return responseMessage;
|
||||
var bodyParserSettings = new BodyParserSettings
|
||||
{
|
||||
Stream = stream,
|
||||
ContentType = contentTypeHeader?.FirstOrDefault(),
|
||||
DeserializeJson = deserializeJson,
|
||||
ContentEncoding = contentEncodingHeader?.FirstOrDefault(),
|
||||
DecompressGZipAndDeflate = decompressGzipAndDeflate
|
||||
};
|
||||
responseMessage.BodyData = await BodyParser.ParseAsync(bodyParserSettings).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
foreach (var header in headers)
|
||||
{
|
||||
// If Location header contains absolute redirect URL, and base URL is one that we proxy to,
|
||||
// we need to replace it to original one.
|
||||
if (string.Equals(header.Key, HttpKnownHeaderNames.Location, StringComparison.OrdinalIgnoreCase)
|
||||
&& Uri.TryCreate(header.Value.First(), UriKind.Absolute, out Uri absoluteLocationUri)
|
||||
&& string.Equals(absoluteLocationUri.Host, requiredUri.Host, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
var replacedLocationUri = new Uri(originalUri, absoluteLocationUri.PathAndQuery);
|
||||
responseMessage.AddHeader(header.Key, replacedLocationUri.ToString());
|
||||
}
|
||||
else
|
||||
{
|
||||
responseMessage.AddHeader(header.Key, header.Value.ToArray());
|
||||
}
|
||||
}
|
||||
|
||||
return responseMessage;
|
||||
}
|
||||
}
|
||||
@@ -26,15 +26,15 @@ namespace WireMock.Http
|
||||
_settings = settings ?? throw new ArgumentNullException(nameof(settings));
|
||||
}
|
||||
|
||||
public Task<HttpResponseMessage> SendAsync([NotNull] HttpClient client, [NotNull] IWebhookRequest request, [NotNull] IRequestMessage originalRequestMessage, [NotNull] IResponseMessage originalResponseMessage)
|
||||
public Task<HttpResponseMessage> SendAsync(HttpClient client, IWebhookRequest request, IRequestMessage originalRequestMessage, IResponseMessage originalResponseMessage)
|
||||
{
|
||||
Guard.NotNull(client, nameof(client));
|
||||
Guard.NotNull(request, nameof(request));
|
||||
Guard.NotNull(originalRequestMessage, nameof(originalRequestMessage));
|
||||
Guard.NotNull(originalResponseMessage, nameof(originalResponseMessage));
|
||||
Guard.NotNull(client);
|
||||
Guard.NotNull(request);
|
||||
Guard.NotNull(originalRequestMessage);
|
||||
Guard.NotNull(originalResponseMessage);
|
||||
|
||||
IBodyData bodyData;
|
||||
IDictionary<string, WireMockList<string>> headers;
|
||||
IBodyData? bodyData;
|
||||
IDictionary<string, WireMockList<string>>? headers;
|
||||
if (request.UseTransformer == true)
|
||||
{
|
||||
ITransformer responseMessageTransformer;
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
using JetBrains.Annotations;
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using WireMock.Matchers.Request;
|
||||
@@ -6,130 +5,125 @@ using WireMock.Models;
|
||||
using WireMock.ResponseProviders;
|
||||
using WireMock.Settings;
|
||||
|
||||
namespace WireMock
|
||||
namespace WireMock;
|
||||
|
||||
/// <summary>
|
||||
/// The IMapping interface.
|
||||
/// </summary>
|
||||
public interface IMapping
|
||||
{
|
||||
/// <summary>
|
||||
/// The IMapping interface.
|
||||
/// Gets the unique identifier.
|
||||
/// </summary>
|
||||
public interface IMapping
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the unique identifier.
|
||||
/// </summary>
|
||||
Guid Guid { get; }
|
||||
Guid Guid { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the TimeSettings (Start, End and TTL).
|
||||
/// </summary>
|
||||
ITimeSettings TimeSettings { get; }
|
||||
/// <summary>
|
||||
/// Gets the TimeSettings (Start, End and TTL).
|
||||
/// </summary>
|
||||
ITimeSettings TimeSettings { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the unique title.
|
||||
/// </summary>
|
||||
string Title { get; }
|
||||
/// <summary>
|
||||
/// Gets the unique title.
|
||||
/// </summary>
|
||||
string Title { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the description.
|
||||
/// </summary>
|
||||
string Description { get; }
|
||||
/// <summary>
|
||||
/// Gets the description.
|
||||
/// </summary>
|
||||
string Description { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The full filename path for this mapping (only defined for static mappings).
|
||||
/// </summary>
|
||||
string Path { get; set; }
|
||||
/// <summary>
|
||||
/// The full filename path for this mapping (only defined for static mappings).
|
||||
/// </summary>
|
||||
string Path { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the priority. (A low value means higher priority.)
|
||||
/// </summary>
|
||||
int Priority { get; }
|
||||
/// <summary>
|
||||
/// Gets the priority. (A low value means higher priority.)
|
||||
/// </summary>
|
||||
int Priority { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Scenario.
|
||||
/// </summary>
|
||||
[CanBeNull]
|
||||
string Scenario { get; }
|
||||
/// <summary>
|
||||
/// Scenario.
|
||||
/// </summary>
|
||||
string? Scenario { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Execution state condition for the current mapping.
|
||||
/// </summary>
|
||||
[CanBeNull]
|
||||
string ExecutionConditionState { get; }
|
||||
/// <summary>
|
||||
/// Execution state condition for the current mapping.
|
||||
/// </summary>
|
||||
string? ExecutionConditionState { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The next state which will be signaled after the current mapping execution.
|
||||
/// In case the value is null, state will not be changed.
|
||||
/// </summary>
|
||||
[CanBeNull]
|
||||
string NextState { get; }
|
||||
/// <summary>
|
||||
/// The next state which will be signaled after the current mapping execution.
|
||||
/// In case the value is null, state will not be changed.
|
||||
/// </summary>
|
||||
string? NextState { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The number of times this match should be matched before the state will be changed to the next state.
|
||||
/// </summary>
|
||||
[CanBeNull]
|
||||
int? StateTimes { get; }
|
||||
/// <summary>
|
||||
/// The number of times this match should be matched before the state will be changed to the next state.
|
||||
/// </summary>
|
||||
int? StateTimes { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The Request matcher.
|
||||
/// </summary>
|
||||
IRequestMatcher RequestMatcher { get; }
|
||||
/// <summary>
|
||||
/// The Request matcher.
|
||||
/// </summary>
|
||||
IRequestMatcher RequestMatcher { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The Provider.
|
||||
/// </summary>
|
||||
IResponseProvider Provider { get; }
|
||||
/// <summary>
|
||||
/// The Provider.
|
||||
/// </summary>
|
||||
IResponseProvider Provider { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The WireMockServerSettings.
|
||||
/// </summary>
|
||||
WireMockServerSettings Settings { get; }
|
||||
/// <summary>
|
||||
/// The WireMockServerSettings.
|
||||
/// </summary>
|
||||
WireMockServerSettings Settings { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Is State started ?
|
||||
/// </summary>
|
||||
bool IsStartState { get; }
|
||||
/// <summary>
|
||||
/// Is State started ?
|
||||
/// </summary>
|
||||
bool IsStartState { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether this mapping is an Admin Interface.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// <c>true</c> if this mapping is an Admin Interface; otherwise, <c>false</c>.
|
||||
/// </value>
|
||||
bool IsAdminInterface { get; }
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether this mapping is an Admin Interface.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// <c>true</c> if this mapping is an Admin Interface; otherwise, <c>false</c>.
|
||||
/// </value>
|
||||
bool IsAdminInterface { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether this mapping is a Proxy Mapping.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// <c>true</c> if this mapping is a Proxy Mapping; otherwise, <c>false</c>.
|
||||
/// </value>
|
||||
bool IsProxy { get; }
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether this mapping is a Proxy Mapping.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// <c>true</c> if this mapping is a Proxy Mapping; otherwise, <c>false</c>.
|
||||
/// </value>
|
||||
bool IsProxy { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether this mapping to be logged.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// <c>true</c> if this mapping to be logged; otherwise, <c>false</c>.
|
||||
/// </value>
|
||||
bool LogMapping { get; }
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether this mapping to be logged.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// <c>true</c> if this mapping to be logged; otherwise, <c>false</c>.
|
||||
/// </value>
|
||||
bool LogMapping { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The Webhooks.
|
||||
/// </summary>
|
||||
IWebhook[] Webhooks { get; }
|
||||
/// <summary>
|
||||
/// The Webhooks.
|
||||
/// </summary>
|
||||
IWebhook[]? Webhooks { get; }
|
||||
|
||||
/// <summary>
|
||||
/// ProvideResponseAsync
|
||||
/// </summary>
|
||||
/// <param name="requestMessage">The request message.</param>
|
||||
/// <returns>The <see cref="ResponseMessage"/> including a new (optional) <see cref="IMapping"/>.</returns>
|
||||
Task<(IResponseMessage Message, IMapping Mapping)> ProvideResponseAsync(IRequestMessage requestMessage);
|
||||
/// <summary>
|
||||
/// ProvideResponseAsync
|
||||
/// </summary>
|
||||
/// <param name="requestMessage">The request message.</param>
|
||||
/// <returns>The <see cref="ResponseMessage"/> including a new (optional) <see cref="IMapping"/>.</returns>
|
||||
Task<(IResponseMessage Message, IMapping Mapping)> ProvideResponseAsync(IRequestMessage requestMessage);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the RequestMatchResult based on the RequestMessage.
|
||||
/// </summary>
|
||||
/// <param name="requestMessage">The request message.</param>
|
||||
/// <param name="nextState">The Next State.</param>
|
||||
/// <returns>The <see cref="IRequestMatchResult"/>.</returns>
|
||||
IRequestMatchResult GetRequestMatchResult(IRequestMessage requestMessage, [CanBeNull] string nextState);
|
||||
}
|
||||
/// <summary>
|
||||
/// Gets the RequestMatchResult based on the RequestMessage.
|
||||
/// </summary>
|
||||
/// <param name="requestMessage">The request message.</param>
|
||||
/// <param name="nextState">The Next State.</param>
|
||||
/// <returns>The <see cref="IRequestMatchResult"/>.</returns>
|
||||
IRequestMatchResult GetRequestMatchResult(IRequestMessage requestMessage, string? nextState);
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using WireMock.Admin.Requests;
|
||||
|
||||
@@ -51,7 +51,7 @@ namespace WireMock.Logging
|
||||
{
|
||||
ae.Handle(ex =>
|
||||
{
|
||||
Console.WriteLine(Format("Error", "Exception {0}", exception.Message));
|
||||
Console.WriteLine(Format("Error", "Exception {0}", ex.Message));
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1,89 +1,110 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using JetBrains.Annotations;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using WireMock.Util;
|
||||
|
||||
namespace WireMock.Matchers
|
||||
namespace WireMock.Matchers;
|
||||
|
||||
/// <summary>
|
||||
/// Generic AbstractJsonPartialMatcher
|
||||
/// </summary>
|
||||
public abstract class AbstractJsonPartialMatcher : JsonMatcher
|
||||
{
|
||||
/// <summary>
|
||||
/// Generic AbstractJsonPartialMatcher
|
||||
/// Support Regex
|
||||
/// </summary>
|
||||
public abstract class AbstractJsonPartialMatcher : JsonMatcher
|
||||
public bool Regex { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="AbstractJsonPartialMatcher"/> class.
|
||||
/// </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 throwException = false, bool regex = false)
|
||||
: base(value, ignoreCase, throwException)
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="AbstractJsonPartialMatcher"/> class.
|
||||
/// </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>
|
||||
protected AbstractJsonPartialMatcher([NotNull] string value, bool ignoreCase = false, bool throwException = false)
|
||||
: base(value, ignoreCase, throwException)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="AbstractJsonPartialMatcher"/> class.
|
||||
/// </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>
|
||||
protected AbstractJsonPartialMatcher([NotNull] object value, bool ignoreCase = false, bool throwException = false)
|
||||
: base(value, ignoreCase, throwException)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="AbstractJsonPartialMatcher"/> class.
|
||||
/// </summary>
|
||||
/// <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>
|
||||
protected AbstractJsonPartialMatcher(MatchBehaviour matchBehaviour, [NotNull] object value, bool ignoreCase = false, bool throwException = false)
|
||||
: base(matchBehaviour, value, ignoreCase, throwException)
|
||||
{
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override bool IsMatch(JToken value, JToken input)
|
||||
{
|
||||
if (value == null || value == input)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (input == null || value.Type != input.Type)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (value.Type)
|
||||
{
|
||||
case JTokenType.Object:
|
||||
var nestedValues = value.ToObject<Dictionary<string, JToken>>();
|
||||
return nestedValues?.Any() != true ||
|
||||
nestedValues.All(pair => IsMatch(pair.Value, input.SelectToken(pair.Key)));
|
||||
|
||||
case JTokenType.Array:
|
||||
var valuesArray = value.ToObject<JToken[]>();
|
||||
var tokenArray = input.ToObject<JToken[]>();
|
||||
|
||||
if (valuesArray?.Any() != true)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return tokenArray?.Any() == true &&
|
||||
valuesArray.All(subFilter => tokenArray.Any(subToken => IsMatch(subFilter, subToken)));
|
||||
|
||||
default:
|
||||
return IsMatch(value.ToString(), input.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Check if two strings are a match (matching can be done exact or wildcard)
|
||||
/// </summary>
|
||||
protected abstract bool IsMatch(string value, string input);
|
||||
Regex = regex;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="AbstractJsonPartialMatcher"/> class.
|
||||
/// </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 throwException = false, bool regex = false)
|
||||
: base(value, ignoreCase, throwException)
|
||||
{
|
||||
Regex = regex;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="AbstractJsonPartialMatcher"/> class.
|
||||
/// </summary>
|
||||
/// <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 throwException = false, bool regex = false)
|
||||
: base(matchBehaviour, value, ignoreCase, throwException)
|
||||
{
|
||||
Regex = regex;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override bool IsMatch(JToken? value, JToken? input)
|
||||
{
|
||||
if (value == null || value == input)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (Regex && value.Type == JTokenType.String && input != null)
|
||||
{
|
||||
var valueAsString = value.ToString();
|
||||
|
||||
var (valid, result) = RegexUtils.MatchRegex(valueAsString, input.ToString());
|
||||
if (valid)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
if (input == null || value.Type != input.Type)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (value.Type)
|
||||
{
|
||||
case JTokenType.Object:
|
||||
var nestedValues = value.ToObject<Dictionary<string, JToken>>();
|
||||
return nestedValues?.Any() != true ||
|
||||
nestedValues.All(pair => IsMatch(pair.Value, input.SelectToken(pair.Key)));
|
||||
|
||||
case JTokenType.Array:
|
||||
var valuesArray = value.ToObject<JToken[]>();
|
||||
var tokenArray = input.ToObject<JToken[]>();
|
||||
|
||||
if (valuesArray?.Any() != true)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return tokenArray?.Any() == true &&
|
||||
valuesArray.All(subFilter => tokenArray.Any(subToken => IsMatch(subFilter, subToken)));
|
||||
|
||||
default:
|
||||
return IsMatch(value.ToString(), input.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Check if two strings are a match (matching can be done exact or wildcard)
|
||||
/// </summary>
|
||||
protected abstract bool IsMatch(string value, string input);
|
||||
}
|
||||
@@ -3,75 +3,74 @@ using AnyOfTypes;
|
||||
using JetBrains.Annotations;
|
||||
using WireMock.Models;
|
||||
|
||||
namespace WireMock.Matchers
|
||||
namespace WireMock.Matchers;
|
||||
|
||||
/// <summary>
|
||||
/// ContentTypeMatcher which accepts also all charsets
|
||||
/// </summary>
|
||||
/// <seealso cref="RegexMatcher" />
|
||||
public class ContentTypeMatcher : WildcardMatcher
|
||||
{
|
||||
private readonly AnyOf<string, StringPattern>[] _patterns;
|
||||
|
||||
/// <summary>
|
||||
/// ContentTypeMatcher which accepts also all charsets
|
||||
/// Initializes a new instance of the <see cref="ContentTypeMatcher"/> class.
|
||||
/// </summary>
|
||||
/// <seealso cref="RegexMatcher" />
|
||||
public class ContentTypeMatcher : WildcardMatcher
|
||||
/// <param name="pattern">The pattern.</param>
|
||||
/// <param name="ignoreCase">IgnoreCase (default false)</param>
|
||||
public ContentTypeMatcher([NotNull] AnyOf<string, StringPattern> pattern, bool ignoreCase = false) : this(new[] { pattern }, ignoreCase)
|
||||
{
|
||||
private readonly AnyOf<string, StringPattern>[] _patterns;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ContentTypeMatcher"/> class.
|
||||
/// </summary>
|
||||
/// <param name="pattern">The pattern.</param>
|
||||
/// <param name="ignoreCase">IgnoreCase (default false)</param>
|
||||
public ContentTypeMatcher([NotNull] AnyOf<string, StringPattern> pattern, bool ignoreCase = false) : this(new[] { pattern }, ignoreCase)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ContentTypeMatcher"/> class.
|
||||
/// </summary>
|
||||
/// <param name="matchBehaviour">The match behaviour.</param>
|
||||
/// <param name="pattern">The pattern.</param>
|
||||
/// <param name="ignoreCase">IgnoreCase (default false)</param>
|
||||
public ContentTypeMatcher(MatchBehaviour matchBehaviour, [NotNull] AnyOf<string, StringPattern> pattern, bool ignoreCase = false) : this(matchBehaviour, new[] { pattern }, ignoreCase)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ContentTypeMatcher"/> class.
|
||||
/// </summary>
|
||||
/// <param name="patterns">The patterns.</param>
|
||||
/// <param name="ignoreCase">IgnoreCase (default false)</param>
|
||||
public ContentTypeMatcher([NotNull] AnyOf<string, StringPattern>[] patterns, bool ignoreCase = false) : this(MatchBehaviour.AcceptOnMatch, patterns, ignoreCase)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ContentTypeMatcher"/> class.
|
||||
/// </summary>
|
||||
/// <param name="matchBehaviour">The match behaviour.</param>
|
||||
/// <param name="patterns">The patterns.</param>
|
||||
/// <param name="ignoreCase">IgnoreCase (default false)</param>
|
||||
/// <param name="throwException">Throw an exception when the internal matching fails because of invalid input.</param>
|
||||
public ContentTypeMatcher(MatchBehaviour matchBehaviour, [NotNull] AnyOf<string, StringPattern>[] patterns, bool ignoreCase = false, bool throwException = false) :
|
||||
base(matchBehaviour, patterns, ignoreCase, throwException)
|
||||
{
|
||||
_patterns = patterns;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="RegexMatcher.IsMatch"/>
|
||||
public override double IsMatch(string input)
|
||||
{
|
||||
if (string.IsNullOrEmpty(input) || !MediaTypeHeaderValue.TryParse(input, out MediaTypeHeaderValue contentType))
|
||||
{
|
||||
return MatchBehaviourHelper.Convert(MatchBehaviour, MatchScores.Mismatch);
|
||||
}
|
||||
|
||||
return base.IsMatch(contentType.MediaType);
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IStringMatcher.GetPatterns"/>
|
||||
public override AnyOf<string, StringPattern>[] GetPatterns()
|
||||
{
|
||||
return _patterns;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IMatcher.Name"/>
|
||||
public override string Name => "ContentTypeMatcher";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ContentTypeMatcher"/> class.
|
||||
/// </summary>
|
||||
/// <param name="matchBehaviour">The match behaviour.</param>
|
||||
/// <param name="pattern">The pattern.</param>
|
||||
/// <param name="ignoreCase">IgnoreCase (default false)</param>
|
||||
public ContentTypeMatcher(MatchBehaviour matchBehaviour, [NotNull] AnyOf<string, StringPattern> pattern, bool ignoreCase = false) : this(matchBehaviour, new[] { pattern }, ignoreCase)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ContentTypeMatcher"/> class.
|
||||
/// </summary>
|
||||
/// <param name="patterns">The patterns.</param>
|
||||
/// <param name="ignoreCase">IgnoreCase (default false)</param>
|
||||
public ContentTypeMatcher(AnyOf<string, StringPattern>[] patterns, bool ignoreCase = false) : this(MatchBehaviour.AcceptOnMatch, patterns, ignoreCase)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ContentTypeMatcher"/> class.
|
||||
/// </summary>
|
||||
/// <param name="matchBehaviour">The match behaviour.</param>
|
||||
/// <param name="patterns">The patterns.</param>
|
||||
/// <param name="ignoreCase">IgnoreCase (default false)</param>
|
||||
/// <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 cref="RegexMatcher.IsMatch"/>
|
||||
public override double IsMatch(string? input)
|
||||
{
|
||||
if (string.IsNullOrEmpty(input) || !MediaTypeHeaderValue.TryParse(input, out MediaTypeHeaderValue contentType))
|
||||
{
|
||||
return MatchBehaviourHelper.Convert(MatchBehaviour, MatchScores.Mismatch);
|
||||
}
|
||||
|
||||
return base.IsMatch(contentType.MediaType);
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IStringMatcher.GetPatterns"/>
|
||||
public override AnyOf<string, StringPattern>[] GetPatterns()
|
||||
{
|
||||
return _patterns;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IMatcher.Name"/>
|
||||
public override string Name => "ContentTypeMatcher";
|
||||
}
|
||||
@@ -1,67 +1,69 @@
|
||||
using System.Linq;
|
||||
using AnyOfTypes;
|
||||
using JetBrains.Annotations;
|
||||
using Stef.Validation;
|
||||
using WireMock.Extensions;
|
||||
using WireMock.Models;
|
||||
using Stef.Validation;
|
||||
|
||||
namespace WireMock.Matchers
|
||||
namespace WireMock.Matchers;
|
||||
|
||||
/// <summary>
|
||||
/// ExactMatcher
|
||||
/// </summary>
|
||||
/// <seealso cref="IStringMatcher" />
|
||||
public class ExactMatcher : IStringMatcher
|
||||
{
|
||||
private readonly AnyOf<string, StringPattern>[] _values;
|
||||
|
||||
/// <inheritdoc cref="IMatcher.MatchBehaviour"/>
|
||||
public MatchBehaviour MatchBehaviour { get; }
|
||||
|
||||
/// <inheritdoc cref="IMatcher.ThrowException"/>
|
||||
public bool ThrowException { get; }
|
||||
|
||||
/// <summary>
|
||||
/// ExactMatcher
|
||||
/// Initializes a new instance of the <see cref="ExactMatcher"/> class.
|
||||
/// </summary>
|
||||
/// <seealso cref="IStringMatcher" />
|
||||
public class ExactMatcher : IStringMatcher
|
||||
/// <param name="values">The values.</param>
|
||||
public ExactMatcher(params AnyOf<string, StringPattern>[] values) : this(MatchBehaviour.AcceptOnMatch, false, MatchOperator.Or, values)
|
||||
{
|
||||
private readonly AnyOf<string, StringPattern>[] _values;
|
||||
|
||||
/// <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([NotNull] params AnyOf<string, StringPattern>[] values) : this(MatchBehaviour.AcceptOnMatch, false, values)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ExactMatcher"/> 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="values">The values.</param>
|
||||
public ExactMatcher(MatchBehaviour matchBehaviour, bool throwException = false, [NotNull] params AnyOf<string, StringPattern>[] values)
|
||||
{
|
||||
Guard.NotNull(values, nameof(values));
|
||||
|
||||
MatchBehaviour = matchBehaviour;
|
||||
ThrowException = throwException;
|
||||
_values = values;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IStringMatcher.IsMatch"/>
|
||||
public double IsMatch(string input)
|
||||
{
|
||||
if (_values.Length == 1)
|
||||
{
|
||||
return MatchBehaviourHelper.Convert(MatchBehaviour, MatchScores.ToScore(_values[0].GetPattern() == input));
|
||||
}
|
||||
|
||||
return MatchBehaviourHelper.Convert(MatchBehaviour, MatchScores.ToScore(_values.Select(v => v.GetPattern()).Contains(input)));
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IStringMatcher.GetPatterns"/>
|
||||
public AnyOf<string, StringPattern>[] GetPatterns()
|
||||
{
|
||||
return _values;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IMatcher.Name"/>
|
||||
public string Name => "ExactMatcher";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ExactMatcher"/> 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="values">The values.</param>
|
||||
public ExactMatcher(
|
||||
MatchBehaviour matchBehaviour,
|
||||
bool throwException = false,
|
||||
MatchOperator matchOperator = MatchOperator.Or,
|
||||
params AnyOf<string, StringPattern>[] values)
|
||||
{
|
||||
_values = Guard.NotNull(values);
|
||||
|
||||
MatchBehaviour = matchBehaviour;
|
||||
ThrowException = throwException;
|
||||
MatchOperator = matchOperator;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IStringMatcher.IsMatch"/>
|
||||
public double IsMatch(string? input)
|
||||
{
|
||||
double score = MatchScores.ToScore(_values.Select(v => v.GetPattern() == input).ToArray(), MatchOperator);
|
||||
return MatchBehaviourHelper.Convert(MatchBehaviour, score);
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IStringMatcher.GetPatterns"/>
|
||||
public AnyOf<string, StringPattern>[] GetPatterns()
|
||||
{
|
||||
return _values;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public MatchOperator MatchOperator { get; }
|
||||
|
||||
/// <inheritdoc cref="IMatcher.Name"/>
|
||||
public string Name => "ExactMatcher";
|
||||
}
|
||||
@@ -1,83 +1,86 @@
|
||||
using JetBrains.Annotations;
|
||||
using System.Linq;
|
||||
using Stef.Validation;
|
||||
|
||||
namespace WireMock.Matchers
|
||||
namespace WireMock.Matchers;
|
||||
|
||||
/// <summary>
|
||||
/// ExactObjectMatcher
|
||||
/// </summary>
|
||||
/// <seealso cref="IObjectMatcher" />
|
||||
public class ExactObjectMatcher : IObjectMatcher
|
||||
{
|
||||
/// <summary>
|
||||
/// ExactObjectMatcher
|
||||
/// Gets the value as object.
|
||||
/// </summary>
|
||||
/// <seealso cref="IObjectMatcher" />
|
||||
public class ExactObjectMatcher : IObjectMatcher
|
||||
public object? ValueAsObject { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the value as byte[].
|
||||
/// </summary>
|
||||
public byte[]? ValueAsBytes { get; }
|
||||
|
||||
/// <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>
|
||||
/// <param name="value">The value.</param>
|
||||
public ExactObjectMatcher(object value) : this(MatchBehaviour.AcceptOnMatch, value)
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the value as object.
|
||||
/// </summary>
|
||||
public object ValueAsObject { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the value as byte[].
|
||||
/// </summary>
|
||||
public byte[] ValueAsBytes { get; }
|
||||
|
||||
/// <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>
|
||||
/// <param name="value">The value.</param>
|
||||
public ExactObjectMatcher([NotNull] object value) : this(MatchBehaviour.AcceptOnMatch, value)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ExactObjectMatcher"/> class.
|
||||
/// </summary>
|
||||
/// <param name="matchBehaviour">The match behaviour.</param>
|
||||
/// <param name="value">The value.</param>
|
||||
public ExactObjectMatcher(MatchBehaviour matchBehaviour, [NotNull] object value)
|
||||
{
|
||||
Guard.NotNull(value, nameof(value));
|
||||
|
||||
ValueAsObject = value;
|
||||
MatchBehaviour = matchBehaviour;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ExactObjectMatcher"/> class.
|
||||
/// </summary>
|
||||
/// <param name="value">The value.</param>
|
||||
public ExactObjectMatcher([NotNull] byte[] value) : this(MatchBehaviour.AcceptOnMatch, value)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 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, [NotNull] byte[] value, bool throwException = false)
|
||||
{
|
||||
Guard.NotNull(value, nameof(value));
|
||||
|
||||
MatchBehaviour = matchBehaviour;
|
||||
ThrowException = throwException;
|
||||
ValueAsBytes = value;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IObjectMatcher.IsMatch"/>
|
||||
public double IsMatch(object input)
|
||||
{
|
||||
bool equals = ValueAsObject != null ? Equals(ValueAsObject, input) : ValueAsBytes.SequenceEqual((byte[])input);
|
||||
return MatchBehaviourHelper.Convert(MatchBehaviour, MatchScores.ToScore(equals));
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IMatcher.Name"/>
|
||||
public string Name => "ExactObjectMatcher";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ExactObjectMatcher"/> class.
|
||||
/// </summary>
|
||||
/// <param name="matchBehaviour">The match behaviour.</param>
|
||||
/// <param name="value">The value.</param>
|
||||
public ExactObjectMatcher(MatchBehaviour matchBehaviour, object value)
|
||||
{
|
||||
ValueAsObject = Guard.NotNull(value);
|
||||
MatchBehaviour = matchBehaviour;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ExactObjectMatcher"/> class.
|
||||
/// </summary>
|
||||
/// <param name="value">The value.</param>
|
||||
public ExactObjectMatcher(byte[] value) : this(MatchBehaviour.AcceptOnMatch, value)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 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, bool throwException = false)
|
||||
{
|
||||
ValueAsBytes = Guard.NotNull(value);
|
||||
MatchBehaviour = matchBehaviour;
|
||||
ThrowException = throwException;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IObjectMatcher.IsMatch"/>
|
||||
public double IsMatch(object? input)
|
||||
{
|
||||
bool equals = false;
|
||||
if (ValueAsObject != null)
|
||||
{
|
||||
equals = Equals(ValueAsObject, input);
|
||||
}
|
||||
else if (input != null)
|
||||
{
|
||||
equals = ValueAsBytes?.SequenceEqual((byte[])input) == true;
|
||||
}
|
||||
|
||||
return MatchBehaviourHelper.Convert(MatchBehaviour, MatchScores.ToScore(equals));
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IMatcher.Name"/>
|
||||
public string Name => "ExactObjectMatcher";
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
namespace WireMock.Matchers
|
||||
namespace WireMock.Matchers
|
||||
{
|
||||
/// <summary>
|
||||
/// IObjectMatcher
|
||||
@@ -10,6 +10,6 @@
|
||||
/// </summary>
|
||||
/// <param name="input">The input.</param>
|
||||
/// <returns>A value between 0.0 - 1.0 of the similarity.</returns>
|
||||
double IsMatch(object input);
|
||||
double IsMatch(object? input);
|
||||
}
|
||||
}
|
||||
@@ -1,25 +1,29 @@
|
||||
using AnyOfTypes;
|
||||
using WireMock.Models;
|
||||
|
||||
namespace WireMock.Matchers
|
||||
namespace WireMock.Matchers;
|
||||
|
||||
/// <summary>
|
||||
/// IStringMatcher
|
||||
/// </summary>
|
||||
/// <inheritdoc cref="IMatcher"/>
|
||||
public interface IStringMatcher : IMatcher
|
||||
{
|
||||
/// <summary>
|
||||
/// IStringMatcher
|
||||
/// Determines whether the specified input is match.
|
||||
/// </summary>
|
||||
/// <inheritdoc cref="IMatcher"/>
|
||||
public interface IStringMatcher : IMatcher
|
||||
{
|
||||
/// <summary>
|
||||
/// Determines whether the specified input is match.
|
||||
/// </summary>
|
||||
/// <param name="input">The input.</param>
|
||||
/// <returns>A value between 0.0 - 1.0 of the similarity.</returns>
|
||||
double IsMatch(string input);
|
||||
/// <param name="input">The input.</param>
|
||||
/// <returns>A value between 0.0 - 1.0 of the similarity.</returns>
|
||||
double IsMatch(string? input);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the patterns.
|
||||
/// </summary>
|
||||
/// <returns>Patterns</returns>
|
||||
AnyOf<string, StringPattern>[] GetPatterns();
|
||||
}
|
||||
/// <summary>
|
||||
/// Gets the patterns.
|
||||
/// </summary>
|
||||
/// <returns>Patterns</returns>
|
||||
AnyOf<string, StringPattern>[] GetPatterns();
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="Matchers.MatchOperator"/>.
|
||||
/// </summary>
|
||||
MatchOperator MatchOperator { get; }
|
||||
}
|
||||
@@ -1,121 +1,126 @@
|
||||
using System.Linq;
|
||||
using AnyOfTypes;
|
||||
using JetBrains.Annotations;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Stef.Validation;
|
||||
using WireMock.Extensions;
|
||||
using WireMock.Models;
|
||||
using Stef.Validation;
|
||||
|
||||
namespace WireMock.Matchers
|
||||
namespace WireMock.Matchers;
|
||||
|
||||
/// <summary>
|
||||
/// JsonPathMatcher
|
||||
/// </summary>
|
||||
/// <seealso cref="IMatcher" />
|
||||
/// <seealso cref="IObjectMatcher" />
|
||||
public class JsonPathMatcher : IStringMatcher, IObjectMatcher
|
||||
{
|
||||
private readonly AnyOf<string, StringPattern>[] _patterns;
|
||||
|
||||
/// <inheritdoc cref="IMatcher.MatchBehaviour"/>
|
||||
public MatchBehaviour MatchBehaviour { get; }
|
||||
|
||||
/// <inheritdoc cref="IMatcher.ThrowException"/>
|
||||
public bool ThrowException { get; }
|
||||
|
||||
/// <summary>
|
||||
/// JsonPathMatcher
|
||||
/// Initializes a new instance of the <see cref="JsonPathMatcher"/> class.
|
||||
/// </summary>
|
||||
/// <seealso cref="IMatcher" />
|
||||
/// <seealso cref="IObjectMatcher" />
|
||||
public class JsonPathMatcher : IStringMatcher, IObjectMatcher
|
||||
/// <param name="patterns">The patterns.</param>
|
||||
public JsonPathMatcher(params string[] patterns) : this(MatchBehaviour.AcceptOnMatch, false, MatchOperator.Or, patterns.ToAnyOfPatterns())
|
||||
{
|
||||
private readonly AnyOf<string, StringPattern>[] _patterns;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IMatcher.MatchBehaviour"/>
|
||||
public MatchBehaviour MatchBehaviour { get; }
|
||||
/// <summary>
|
||||
/// 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, false, MatchOperator.Or, patterns)
|
||||
{
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IMatcher.ThrowException"/>
|
||||
public bool ThrowException { get; }
|
||||
/// <summary>
|
||||
/// 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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="JsonPathMatcher"/> class.
|
||||
/// </summary>
|
||||
/// <param name="patterns">The patterns.</param>
|
||||
public JsonPathMatcher([NotNull] params string[] patterns) : this(MatchBehaviour.AcceptOnMatch, false, patterns.ToAnyOfPatterns())
|
||||
/// <inheritdoc cref="IStringMatcher.IsMatch"/>
|
||||
public double IsMatch(string? input)
|
||||
{
|
||||
double match = MatchScores.Mismatch;
|
||||
if (input != null)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="JsonPathMatcher"/> class.
|
||||
/// </summary>
|
||||
/// <param name="patterns">The patterns.</param>
|
||||
public JsonPathMatcher([NotNull] params AnyOf<string, StringPattern>[] patterns) : this(MatchBehaviour.AcceptOnMatch, false, patterns)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 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="patterns">The patterns.</param>
|
||||
public JsonPathMatcher(MatchBehaviour matchBehaviour, bool throwException = false, [NotNull] params AnyOf<string, StringPattern>[] patterns)
|
||||
{
|
||||
Guard.NotNull(patterns, nameof(patterns));
|
||||
|
||||
MatchBehaviour = matchBehaviour;
|
||||
ThrowException = throwException;
|
||||
_patterns = patterns;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IStringMatcher.IsMatch"/>
|
||||
public double IsMatch(string input)
|
||||
{
|
||||
double match = MatchScores.Mismatch;
|
||||
if (input != null)
|
||||
try
|
||||
{
|
||||
try
|
||||
var jToken = JToken.Parse(input);
|
||||
match = IsMatch(jToken);
|
||||
}
|
||||
catch (JsonException)
|
||||
{
|
||||
if (ThrowException)
|
||||
{
|
||||
var jToken = JToken.Parse(input);
|
||||
match = IsMatch(jToken);
|
||||
}
|
||||
catch (JsonException)
|
||||
{
|
||||
if (ThrowException)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
return MatchBehaviourHelper.Convert(MatchBehaviour, match);
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IObjectMatcher.IsMatch"/>
|
||||
public double IsMatch(object input)
|
||||
{
|
||||
double match = MatchScores.Mismatch;
|
||||
return MatchBehaviourHelper.Convert(MatchBehaviour, match);
|
||||
}
|
||||
|
||||
// When input is null or byte[], return Mismatch.
|
||||
if (input != null && !(input is byte[]))
|
||||
/// <inheritdoc cref="IObjectMatcher.IsMatch"/>
|
||||
public double IsMatch(object? input)
|
||||
{
|
||||
double match = MatchScores.Mismatch;
|
||||
|
||||
// When input is null or byte[], return Mismatch.
|
||||
if (input != null && !(input is byte[]))
|
||||
{
|
||||
try
|
||||
{
|
||||
try
|
||||
// Check if JToken or object
|
||||
JToken jToken = input as JToken ?? JObject.FromObject(input);
|
||||
match = IsMatch(jToken);
|
||||
}
|
||||
catch (JsonException)
|
||||
{
|
||||
if (ThrowException)
|
||||
{
|
||||
// Check if JToken or object
|
||||
JToken jToken = input is JToken token ? token : JObject.FromObject(input);
|
||||
match = IsMatch(jToken);
|
||||
}
|
||||
catch (JsonException)
|
||||
{
|
||||
if (ThrowException)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
return MatchBehaviourHelper.Convert(MatchBehaviour, match);
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IStringMatcher.GetPatterns"/>
|
||||
public AnyOf<string, StringPattern>[] GetPatterns()
|
||||
{
|
||||
return _patterns;
|
||||
}
|
||||
return MatchBehaviourHelper.Convert(MatchBehaviour, match);
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IMatcher.Name"/>
|
||||
public string Name => "JsonPathMatcher";
|
||||
/// <inheritdoc />
|
||||
public AnyOf<string, StringPattern>[] GetPatterns()
|
||||
{
|
||||
return _patterns;
|
||||
}
|
||||
|
||||
private double IsMatch(JToken jToken)
|
||||
{
|
||||
return MatchScores.ToScore(_patterns.Select(pattern => jToken.SelectToken(pattern.GetPattern()) != null));
|
||||
}
|
||||
/// <inheritdoc />
|
||||
public MatchOperator MatchOperator { get; }
|
||||
|
||||
/// <inheritdoc cref="IMatcher.Name"/>
|
||||
public string Name => "JsonPathMatcher";
|
||||
|
||||
private double IsMatch(JToken jToken)
|
||||
{
|
||||
return MatchScores.ToScore(_patterns.Select(pattern => jToken.SelectToken(pattern.GetPattern()) != null).ToArray(), MatchOperator);
|
||||
}
|
||||
}
|
||||
@@ -1,11 +1,10 @@
|
||||
using System.Linq;
|
||||
using AnyOfTypes;
|
||||
using DevLab.JmesPath;
|
||||
using JetBrains.Annotations;
|
||||
using Newtonsoft.Json;
|
||||
using System.Linq;
|
||||
using Stef.Validation;
|
||||
using WireMock.Extensions;
|
||||
using WireMock.Models;
|
||||
using Stef.Validation;
|
||||
|
||||
namespace WireMock.Matchers
|
||||
{
|
||||
@@ -26,7 +25,7 @@ namespace WireMock.Matchers
|
||||
/// Initializes a new instance of the <see cref="JmesPathMatcher"/> class.
|
||||
/// </summary>
|
||||
/// <param name="patterns">The patterns.</param>
|
||||
public JmesPathMatcher([NotNull] params string[] patterns) : this(MatchBehaviour.AcceptOnMatch, false, patterns.ToAnyOfPatterns())
|
||||
public JmesPathMatcher(params string[] patterns) : this(MatchBehaviour.AcceptOnMatch, false, MatchOperator.Or, patterns.ToAnyOfPatterns())
|
||||
{
|
||||
}
|
||||
|
||||
@@ -34,7 +33,7 @@ namespace WireMock.Matchers
|
||||
/// Initializes a new instance of the <see cref="JmesPathMatcher"/> class.
|
||||
/// </summary>
|
||||
/// <param name="patterns">The patterns.</param>
|
||||
public JmesPathMatcher([NotNull] params AnyOf<string, StringPattern>[] patterns) : this(MatchBehaviour.AcceptOnMatch, false, patterns)
|
||||
public JmesPathMatcher(params AnyOf<string, StringPattern>[] patterns) : this(MatchBehaviour.AcceptOnMatch, false, MatchOperator.Or, patterns)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -42,8 +41,10 @@ namespace WireMock.Matchers
|
||||
/// 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(bool throwException = false, [NotNull] params AnyOf<string, StringPattern>[] patterns) : this(MatchBehaviour.AcceptOnMatch, throwException, patterns)
|
||||
public JmesPathMatcher(bool throwException = false, MatchOperator matchOperator = MatchOperator.Or, params AnyOf<string, StringPattern>[] patterns) :
|
||||
this(MatchBehaviour.AcceptOnMatch, throwException, matchOperator, patterns)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -52,25 +53,30 @@ namespace WireMock.Matchers
|
||||
/// </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, [NotNull] params AnyOf<string, StringPattern>[] patterns)
|
||||
public JmesPathMatcher(
|
||||
MatchBehaviour matchBehaviour,
|
||||
bool throwException = false,
|
||||
MatchOperator matchOperator = MatchOperator.Or,
|
||||
params AnyOf<string, StringPattern>[] patterns)
|
||||
{
|
||||
Guard.NotNull(patterns, nameof(patterns));
|
||||
|
||||
_patterns = Guard.NotNull(patterns);
|
||||
MatchBehaviour = matchBehaviour;
|
||||
ThrowException = throwException;
|
||||
_patterns = patterns;
|
||||
MatchOperator = matchOperator;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IStringMatcher.IsMatch"/>
|
||||
public double IsMatch(string input)
|
||||
public double IsMatch(string? input)
|
||||
{
|
||||
double match = MatchScores.Mismatch;
|
||||
if (input != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
match = MatchScores.ToScore(_patterns.Select(pattern => bool.Parse(new JmesPath().Transform(input, pattern.GetPattern()))));
|
||||
var results = _patterns.Select(pattern => bool.Parse(new JmesPath().Transform(input, pattern.GetPattern()))).ToArray();
|
||||
match = MatchScores.ToScore(results, MatchOperator);
|
||||
}
|
||||
catch (JsonException)
|
||||
{
|
||||
@@ -85,7 +91,7 @@ namespace WireMock.Matchers
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IObjectMatcher.IsMatch"/>
|
||||
public double IsMatch(object input)
|
||||
public double IsMatch(object? input)
|
||||
{
|
||||
double match = MatchScores.Mismatch;
|
||||
|
||||
@@ -105,6 +111,9 @@ namespace WireMock.Matchers
|
||||
return _patterns;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public MatchOperator MatchOperator { get; }
|
||||
|
||||
/// <inheritdoc cref="IMatcher.Name"/>
|
||||
public string Name => "JmesPathMatcher";
|
||||
}
|
||||
|
||||
@@ -6,164 +6,161 @@ using Newtonsoft.Json.Linq;
|
||||
using Stef.Validation;
|
||||
using WireMock.Util;
|
||||
|
||||
namespace WireMock.Matchers
|
||||
namespace WireMock.Matchers;
|
||||
|
||||
/// <summary>
|
||||
/// JsonMatcher
|
||||
/// </summary>
|
||||
public class JsonMatcher : IValueMatcher, IIgnoreCaseMatcher
|
||||
{
|
||||
/// <inheritdoc cref="IMatcher.Name"/>
|
||||
public virtual string Name => "JsonMatcher";
|
||||
|
||||
/// <inheritdoc cref="IValueMatcher.Value"/>
|
||||
public object Value { get; }
|
||||
|
||||
/// <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;
|
||||
|
||||
/// <summary>
|
||||
/// JsonMatcher
|
||||
/// Initializes a new instance of the <see cref="JsonMatcher"/> class.
|
||||
/// </summary>
|
||||
public class JsonMatcher : IValueMatcher, IIgnoreCaseMatcher
|
||||
/// <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>
|
||||
public JsonMatcher(string value, bool ignoreCase = false, bool throwException = false) : this(MatchBehaviour.AcceptOnMatch, value, ignoreCase, throwException)
|
||||
{
|
||||
/// <inheritdoc cref="IValueMatcher.Value"/>
|
||||
public object Value { get; }
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IMatcher.Name"/>
|
||||
public virtual string Name => "JsonMatcher";
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="JsonMatcher"/> class.
|
||||
/// </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>
|
||||
public JsonMatcher(object value, bool ignoreCase = false, bool throwException = false) : this(MatchBehaviour.AcceptOnMatch, value, ignoreCase, throwException)
|
||||
{
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IMatcher.MatchBehaviour"/>
|
||||
public MatchBehaviour MatchBehaviour { get; }
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="JsonMatcher"/> class.
|
||||
/// </summary>
|
||||
/// <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>
|
||||
public JsonMatcher(MatchBehaviour matchBehaviour, object value, bool ignoreCase = false, bool throwException = false)
|
||||
{
|
||||
Guard.NotNull(value, nameof(value));
|
||||
|
||||
/// <inheritdoc cref="IIgnoreCaseMatcher.IgnoreCase"/>
|
||||
public bool IgnoreCase { get; }
|
||||
MatchBehaviour = matchBehaviour;
|
||||
IgnoreCase = ignoreCase;
|
||||
ThrowException = throwException;
|
||||
|
||||
/// <inheritdoc cref="IMatcher.ThrowException"/>
|
||||
public bool ThrowException { get; }
|
||||
Value = value;
|
||||
_valueAsJToken = ConvertValueToJToken(value);
|
||||
_jTokenConverter = ignoreCase ? Rename : jToken => jToken;
|
||||
}
|
||||
|
||||
private readonly JToken _valueAsJToken;
|
||||
private readonly Func<JToken, JToken> _jTokenConverter;
|
||||
/// <inheritdoc cref="IObjectMatcher.IsMatch"/>
|
||||
public double IsMatch(object? input)
|
||||
{
|
||||
bool match = false;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="JsonMatcher"/> class.
|
||||
/// </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>
|
||||
public JsonMatcher(string value, bool ignoreCase = false, bool throwException = false) : this(MatchBehaviour.AcceptOnMatch, value, ignoreCase, throwException)
|
||||
// When input is null or byte[], return Mismatch.
|
||||
if (input != null && input is not byte[])
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="JsonMatcher"/> class.
|
||||
/// </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>
|
||||
public JsonMatcher(object value, bool ignoreCase = false, bool throwException = false) : this(MatchBehaviour.AcceptOnMatch, value, ignoreCase, throwException)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="JsonMatcher"/> class.
|
||||
/// </summary>
|
||||
/// <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>
|
||||
public JsonMatcher(MatchBehaviour matchBehaviour, object value, bool ignoreCase = false, bool throwException = false)
|
||||
{
|
||||
Guard.NotNull(value, nameof(value));
|
||||
|
||||
MatchBehaviour = matchBehaviour;
|
||||
IgnoreCase = ignoreCase;
|
||||
ThrowException = throwException;
|
||||
|
||||
Value = value;
|
||||
_valueAsJToken = ConvertValueToJToken(value);
|
||||
_jTokenConverter = ignoreCase
|
||||
? (Func<JToken, JToken>)Rename
|
||||
: jToken => jToken;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IObjectMatcher.IsMatch"/>
|
||||
public double IsMatch(object? input)
|
||||
{
|
||||
bool match = false;
|
||||
|
||||
// When input is null or byte[], return Mismatch.
|
||||
if (input != null && input is not byte[])
|
||||
try
|
||||
{
|
||||
try
|
||||
{
|
||||
var inputAsJToken = ConvertValueToJToken(input);
|
||||
var inputAsJToken = ConvertValueToJToken(input);
|
||||
|
||||
match = IsMatch(
|
||||
_jTokenConverter(_valueAsJToken),
|
||||
_jTokenConverter(inputAsJToken));
|
||||
}
|
||||
catch (JsonException)
|
||||
match = IsMatch(
|
||||
_jTokenConverter(_valueAsJToken),
|
||||
_jTokenConverter(inputAsJToken));
|
||||
}
|
||||
catch (JsonException)
|
||||
{
|
||||
if (ThrowException)
|
||||
{
|
||||
if (ThrowException)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
return MatchBehaviourHelper.Convert(MatchBehaviour, MatchScores.ToScore(match));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Compares the input against the matcher value
|
||||
/// </summary>
|
||||
/// <param name="value">Matcher value</param>
|
||||
/// <param name="input">Input value</param>
|
||||
/// <returns></returns>
|
||||
protected virtual bool IsMatch(JToken value, JToken input)
|
||||
return MatchBehaviourHelper.Convert(MatchBehaviour, MatchScores.ToScore(match));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Compares the input against the matcher value
|
||||
/// </summary>
|
||||
/// <param name="value">Matcher value</param>
|
||||
/// <param name="input">Input value</param>
|
||||
/// <returns></returns>
|
||||
protected virtual bool IsMatch(JToken value, JToken input)
|
||||
{
|
||||
return JToken.DeepEquals(value, input);
|
||||
}
|
||||
|
||||
private static JToken ConvertValueToJToken(object value)
|
||||
{
|
||||
// Check if JToken, string, IEnumerable or object
|
||||
switch (value)
|
||||
{
|
||||
return JToken.DeepEquals(value, input);
|
||||
}
|
||||
case JToken tokenValue:
|
||||
return tokenValue;
|
||||
|
||||
private static JToken ConvertValueToJToken(object value)
|
||||
{
|
||||
// Check if JToken, string, IEnumerable or object
|
||||
switch (value)
|
||||
{
|
||||
case JToken tokenValue:
|
||||
return tokenValue;
|
||||
case string stringValue:
|
||||
return JsonUtils.Parse(stringValue)!;
|
||||
|
||||
case string stringValue:
|
||||
return JsonUtils.Parse(stringValue);
|
||||
case IEnumerable enumerableValue:
|
||||
return JArray.FromObject(enumerableValue);
|
||||
|
||||
case IEnumerable enumerableValue:
|
||||
return JArray.FromObject(enumerableValue);
|
||||
|
||||
default:
|
||||
return JObject.FromObject(value);
|
||||
}
|
||||
}
|
||||
|
||||
private static string? ToUpper(string? input)
|
||||
{
|
||||
return input?.ToUpperInvariant();
|
||||
}
|
||||
|
||||
// https://stackoverflow.com/questions/11679804/json-net-rename-properties
|
||||
private static JToken Rename(JToken json)
|
||||
{
|
||||
if (json is JProperty property)
|
||||
{
|
||||
JToken propertyValue = property.Value;
|
||||
if (propertyValue.Type == JTokenType.String)
|
||||
{
|
||||
string stringValue = propertyValue.Value<string>();
|
||||
propertyValue = ToUpper(stringValue);
|
||||
}
|
||||
|
||||
return new JProperty(ToUpper(property.Name), Rename(propertyValue));
|
||||
}
|
||||
|
||||
if (json is JArray array)
|
||||
{
|
||||
var renamedValues = array.Select(Rename);
|
||||
return new JArray(renamedValues);
|
||||
}
|
||||
|
||||
if (json is JObject obj)
|
||||
{
|
||||
var renamedProperties = obj.Properties().Select(Rename);
|
||||
return new JObject(renamedProperties);
|
||||
}
|
||||
|
||||
return json;
|
||||
default:
|
||||
return JObject.FromObject(value);
|
||||
}
|
||||
}
|
||||
|
||||
private static string? ToUpper(string? input)
|
||||
{
|
||||
return input?.ToUpperInvariant();
|
||||
}
|
||||
|
||||
// https://stackoverflow.com/questions/11679804/json-net-rename-properties
|
||||
private static JToken Rename(JToken json)
|
||||
{
|
||||
if (json is JProperty property)
|
||||
{
|
||||
JToken propertyValue = property.Value;
|
||||
if (propertyValue.Type == JTokenType.String)
|
||||
{
|
||||
string stringValue = propertyValue.Value<string>()!;
|
||||
propertyValue = ToUpper(stringValue);
|
||||
}
|
||||
|
||||
return new JProperty(ToUpper(property.Name)!, Rename(propertyValue));
|
||||
}
|
||||
|
||||
if (json is JArray array)
|
||||
{
|
||||
var renamedValues = array.Select(Rename);
|
||||
return new JArray(renamedValues);
|
||||
}
|
||||
|
||||
if (json is JObject obj)
|
||||
{
|
||||
var renamedProperties = obj.Properties().Select(Rename);
|
||||
return new JObject(renamedProperties);
|
||||
}
|
||||
|
||||
return json;
|
||||
}
|
||||
}
|
||||
@@ -1,38 +1,35 @@
|
||||
using JetBrains.Annotations;
|
||||
namespace WireMock.Matchers;
|
||||
|
||||
namespace WireMock.Matchers
|
||||
/// <summary>
|
||||
/// JsonPartialMatcher
|
||||
/// </summary>
|
||||
public class JsonPartialMatcher : AbstractJsonPartialMatcher
|
||||
{
|
||||
/// <summary>
|
||||
/// JsonPartialMatcher
|
||||
/// </summary>
|
||||
public class JsonPartialMatcher : AbstractJsonPartialMatcher
|
||||
/// <inheritdoc />
|
||||
public override string Name => nameof(JsonPartialMatcher);
|
||||
|
||||
/// <inheritdoc />
|
||||
public JsonPartialMatcher(string value, bool ignoreCase = false, bool throwException = false, bool regex = false)
|
||||
: base(value, ignoreCase, throwException, regex)
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public override string Name => nameof(JsonPartialMatcher);
|
||||
|
||||
/// <inheritdoc />
|
||||
public JsonPartialMatcher([NotNull] string value, bool ignoreCase = false, bool throwException = false)
|
||||
: base(value, ignoreCase, throwException)
|
||||
{
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public JsonPartialMatcher([NotNull] object value, bool ignoreCase = false, bool throwException = false)
|
||||
: base(value, ignoreCase, throwException)
|
||||
{
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public JsonPartialMatcher(MatchBehaviour matchBehaviour, [NotNull] object value, bool ignoreCase = false, bool throwException = false)
|
||||
: base(matchBehaviour, value, ignoreCase, throwException)
|
||||
{
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override bool IsMatch(string value, string input)
|
||||
{
|
||||
var exactStringMatcher = new ExactMatcher(MatchBehaviour.AcceptOnMatch, ThrowException, value);
|
||||
return MatchScores.IsPerfect(exactStringMatcher.IsMatch(input));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
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 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, ThrowException, MatchOperator.Or, value);
|
||||
return MatchScores.IsPerfect(exactStringMatcher.IsMatch(input));
|
||||
}
|
||||
}
|
||||
@@ -1,38 +1,35 @@
|
||||
using JetBrains.Annotations;
|
||||
namespace WireMock.Matchers;
|
||||
|
||||
namespace WireMock.Matchers
|
||||
/// <summary>
|
||||
/// JsonPartialWildCardMatcher
|
||||
/// </summary>
|
||||
public class JsonPartialWildcardMatcher : AbstractJsonPartialMatcher
|
||||
{
|
||||
/// <summary>
|
||||
/// JsonPartialWildCardMatcher
|
||||
/// </summary>
|
||||
public class JsonPartialWildcardMatcher : AbstractJsonPartialMatcher
|
||||
/// <inheritdoc />
|
||||
public override string Name => nameof(JsonPartialWildcardMatcher);
|
||||
|
||||
/// <inheritdoc />
|
||||
public JsonPartialWildcardMatcher(string value, bool ignoreCase = false, bool throwException = false, bool regex = false)
|
||||
: base(value, ignoreCase, throwException, regex)
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public override string Name => nameof(JsonPartialWildcardMatcher);
|
||||
|
||||
/// <inheritdoc />
|
||||
public JsonPartialWildcardMatcher([NotNull] string value, bool ignoreCase = false, bool throwException = false)
|
||||
: base(value, ignoreCase, throwException)
|
||||
{
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public JsonPartialWildcardMatcher([NotNull] object value, bool ignoreCase = false, bool throwException = false)
|
||||
: base(value, ignoreCase, throwException)
|
||||
{
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public JsonPartialWildcardMatcher(MatchBehaviour matchBehaviour, [NotNull] object value, bool ignoreCase = false, bool throwException = false)
|
||||
: base(matchBehaviour, value, ignoreCase, throwException)
|
||||
{
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override bool IsMatch(string value, string input)
|
||||
{
|
||||
var wildcardStringMatcher = new WildcardMatcher(MatchBehaviour.AcceptOnMatch, value, IgnoreCase);
|
||||
return MatchScores.IsPerfect(wildcardStringMatcher.IsMatch(input));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
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 throwException = false, bool regex = false)
|
||||
: base(matchBehaviour, value, ignoreCase, throwException, regex)
|
||||
{
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override bool IsMatch(string value, string input)
|
||||
{
|
||||
var wildcardStringMatcher = new WildcardMatcher(MatchBehaviour.AcceptOnMatch, value, IgnoreCase);
|
||||
return MatchScores.IsPerfect(wildcardStringMatcher.IsMatch(input));
|
||||
}
|
||||
}
|
||||
@@ -1,146 +1,151 @@
|
||||
using System.Linq;
|
||||
using System.Linq.Dynamic.Core;
|
||||
using AnyOfTypes;
|
||||
using JetBrains.Annotations;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Stef.Validation;
|
||||
using WireMock.Extensions;
|
||||
using WireMock.Models;
|
||||
using WireMock.Util;
|
||||
using Stef.Validation;
|
||||
|
||||
namespace WireMock.Matchers
|
||||
namespace WireMock.Matchers;
|
||||
|
||||
/// <summary>
|
||||
/// System.Linq.Dynamic.Core Expression Matcher
|
||||
/// </summary>
|
||||
/// <inheritdoc cref="IObjectMatcher"/>
|
||||
/// <inheritdoc cref="IStringMatcher"/>
|
||||
public class LinqMatcher : IObjectMatcher, IStringMatcher
|
||||
{
|
||||
private readonly AnyOf<string, StringPattern>[] _patterns;
|
||||
|
||||
/// <inheritdoc cref="IMatcher.MatchBehaviour"/>
|
||||
public MatchBehaviour MatchBehaviour { get; }
|
||||
/// <inheritdoc cref="IMatcher.ThrowException"/>
|
||||
public bool ThrowException { get; }
|
||||
|
||||
/// <summary>
|
||||
/// System.Linq.Dynamic.Core Expression Matcher
|
||||
/// Initializes a new instance of the <see cref="LinqMatcher"/> class.
|
||||
/// </summary>
|
||||
/// <inheritdoc cref="IObjectMatcher"/>
|
||||
/// <inheritdoc cref="IStringMatcher"/>
|
||||
public class LinqMatcher : IObjectMatcher, IStringMatcher
|
||||
/// <param name="pattern">The pattern.</param>
|
||||
public LinqMatcher(AnyOf<string, StringPattern> pattern) : this(new[] { pattern })
|
||||
{
|
||||
private readonly AnyOf<string, StringPattern>[] _patterns;
|
||||
|
||||
/// <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>
|
||||
/// <param name="pattern">The pattern.</param>
|
||||
public LinqMatcher([NotNull] AnyOf<string, StringPattern> pattern) : this(new[] { pattern })
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="LinqMatcher"/> class.
|
||||
/// </summary>
|
||||
/// <param name="patterns">The patterns.</param>
|
||||
public LinqMatcher([NotNull] params AnyOf<string, StringPattern>[] patterns) : this(MatchBehaviour.AcceptOnMatch, false, patterns)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="LinqMatcher"/> class.
|
||||
/// </summary>
|
||||
/// <param name="matchBehaviour">The match behaviour.</param>
|
||||
/// <param name="pattern">The pattern.</param>
|
||||
public LinqMatcher(MatchBehaviour matchBehaviour, [NotNull] AnyOf<string, StringPattern> pattern) : this(matchBehaviour, false, pattern)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="LinqMatcher"/> class.
|
||||
/// </summary>
|
||||
/// <param name="matchBehaviour">The match behaviour.</param>
|
||||
/// <param name="patterns">The patterns.</param>
|
||||
/// <param name="throwException">Throw an exception when the internal matching fails because of invalid input.</param>
|
||||
public LinqMatcher(MatchBehaviour matchBehaviour, bool throwException = false, [NotNull] params AnyOf<string, StringPattern>[] patterns)
|
||||
{
|
||||
Guard.NotNull(patterns, nameof(patterns));
|
||||
|
||||
MatchBehaviour = matchBehaviour;
|
||||
ThrowException = throwException;
|
||||
_patterns = patterns;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IStringMatcher.IsMatch"/>
|
||||
public double IsMatch(string input)
|
||||
{
|
||||
double match = MatchScores.Mismatch;
|
||||
|
||||
// Convert a single input string to a Queryable string-list with 1 entry.
|
||||
IQueryable queryable = new[] { input }.AsQueryable();
|
||||
|
||||
try
|
||||
{
|
||||
// Use the Any(...) method to check if the result matches
|
||||
match = MatchScores.ToScore(_patterns.Select(pattern => queryable.Any(pattern.GetPattern())));
|
||||
|
||||
return MatchBehaviourHelper.Convert(MatchBehaviour, match);
|
||||
}
|
||||
catch
|
||||
{
|
||||
if (ThrowException)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
return MatchBehaviourHelper.Convert(MatchBehaviour, match);
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IObjectMatcher.IsMatch"/>
|
||||
public double IsMatch(object input)
|
||||
{
|
||||
double match = MatchScores.Mismatch;
|
||||
|
||||
JObject value;
|
||||
switch (input)
|
||||
{
|
||||
case JObject valueAsJObject:
|
||||
value = valueAsJObject;
|
||||
break;
|
||||
|
||||
default:
|
||||
value = JObject.FromObject(input);
|
||||
break;
|
||||
}
|
||||
|
||||
// Convert a single object to a Queryable JObject-list with 1 entry.
|
||||
var queryable1 = new[] { value }.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.
|
||||
match = MatchScores.ToScore(_patterns.Select(pattern => queryable2.Any(pattern)));
|
||||
|
||||
return MatchBehaviourHelper.Convert(MatchBehaviour, match);
|
||||
}
|
||||
catch
|
||||
{
|
||||
if (ThrowException)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
return MatchBehaviourHelper.Convert(MatchBehaviour, match);
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IStringMatcher.GetPatterns"/>
|
||||
public AnyOf<string, StringPattern>[] GetPatterns()
|
||||
{
|
||||
return _patterns;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IMatcher.Name"/>
|
||||
public string Name => "LinqMatcher";
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 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, false, MatchOperator.Or, patterns)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="LinqMatcher"/> class.
|
||||
/// </summary>
|
||||
/// <param name="matchBehaviour">The match behaviour.</param>
|
||||
/// <param name="pattern">The pattern.</param>
|
||||
public LinqMatcher(MatchBehaviour matchBehaviour, AnyOf<string, StringPattern> pattern) : this(matchBehaviour, false, MatchOperator.Or, pattern)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 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 cref="IStringMatcher.IsMatch"/>
|
||||
public double IsMatch(string input)
|
||||
{
|
||||
double match = MatchScores.Mismatch;
|
||||
|
||||
// Convert a single input string to a Queryable string-list with 1 entry.
|
||||
IQueryable queryable = new[] { input }.AsQueryable();
|
||||
|
||||
try
|
||||
{
|
||||
// Use the Any(...) method to check if the result matches
|
||||
match = MatchScores.ToScore(_patterns.Select(pattern => queryable.Any(pattern.GetPattern())).ToArray(), MatchOperator);
|
||||
|
||||
return MatchBehaviourHelper.Convert(MatchBehaviour, match);
|
||||
}
|
||||
catch
|
||||
{
|
||||
if (ThrowException)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
return MatchBehaviourHelper.Convert(MatchBehaviour, match);
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IObjectMatcher.IsMatch"/>
|
||||
public double IsMatch(object input)
|
||||
{
|
||||
double match = MatchScores.Mismatch;
|
||||
|
||||
JObject value;
|
||||
switch (input)
|
||||
{
|
||||
case JObject valueAsJObject:
|
||||
value = valueAsJObject;
|
||||
break;
|
||||
|
||||
default:
|
||||
value = JObject.FromObject(input);
|
||||
break;
|
||||
}
|
||||
|
||||
// Convert a single object to a Queryable JObject-list with 1 entry.
|
||||
var queryable1 = new[] { value }.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.
|
||||
match = MatchScores.ToScore(_patterns.Select(pattern => queryable2.Any(pattern)).ToArray(), MatchOperator);
|
||||
|
||||
return MatchBehaviourHelper.Convert(MatchBehaviour, match);
|
||||
}
|
||||
catch
|
||||
{
|
||||
if (ThrowException)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
return MatchBehaviourHelper.Convert(MatchBehaviour, match);
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IStringMatcher.GetPatterns"/>
|
||||
public AnyOf<string, StringPattern>[] GetPatterns()
|
||||
{
|
||||
return _patterns;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public MatchOperator MatchOperator { get; }
|
||||
|
||||
/// <inheritdoc cref="IMatcher.Name"/>
|
||||
public string Name => "LinqMatcher";
|
||||
}
|
||||
22
src/WireMock.Net/Matchers/MatchOperator.cs
Normal file
22
src/WireMock.Net/Matchers/MatchOperator.cs
Normal file
@@ -0,0 +1,22 @@
|
||||
namespace WireMock.Matchers;
|
||||
|
||||
/// <summary>
|
||||
/// The Operator to use when multiple patterns are defined.
|
||||
/// </summary>
|
||||
public enum MatchOperator
|
||||
{
|
||||
/// <summary>
|
||||
/// Only one pattern needs to match. [Default]
|
||||
/// </summary>
|
||||
Or,
|
||||
|
||||
/// <summary>
|
||||
/// All patterns should match.
|
||||
/// </summary>
|
||||
And,
|
||||
|
||||
/// <summary>
|
||||
/// The average value from all patterns.
|
||||
/// </summary>
|
||||
Average,
|
||||
}
|
||||
@@ -1,75 +1,84 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Linq;
|
||||
|
||||
namespace WireMock.Matchers
|
||||
namespace WireMock.Matchers;
|
||||
|
||||
/// <summary>
|
||||
/// MatchScores
|
||||
/// </summary>
|
||||
public static class MatchScores
|
||||
{
|
||||
/// <summary>
|
||||
/// MatchScores
|
||||
/// The tolerance
|
||||
/// </summary>
|
||||
public static class MatchScores
|
||||
public const double Tolerance = 0.000001;
|
||||
|
||||
/// <summary>
|
||||
/// The default mismatch score
|
||||
/// </summary>
|
||||
public const double Mismatch = 0.0;
|
||||
|
||||
/// <summary>
|
||||
/// The default perfect match score
|
||||
/// </summary>
|
||||
public const double Perfect = 1.0;
|
||||
|
||||
/// <summary>
|
||||
/// The almost perfect match score
|
||||
/// </summary>
|
||||
public const double AlmostPerfect = 0.99;
|
||||
|
||||
/// <summary>
|
||||
/// Is the value a perfect match?
|
||||
/// </summary>
|
||||
/// <param name="value">The value.</param>
|
||||
/// <returns>true/false</returns>
|
||||
public static bool IsPerfect(double value)
|
||||
{
|
||||
/// <summary>
|
||||
/// The tolerance
|
||||
/// </summary>
|
||||
public const double Tolerance = 0.000001;
|
||||
return Math.Abs(value - Perfect) < Tolerance;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The default mismatch score
|
||||
/// </summary>
|
||||
public const double Mismatch = 0.0;
|
||||
/// <summary>
|
||||
/// Convert a bool to the score.
|
||||
/// </summary>
|
||||
/// <param name="value">if set to <c>true</c> [value].</param>
|
||||
/// <returns>score</returns>
|
||||
public static double ToScore(bool value)
|
||||
{
|
||||
return value ? Perfect : Mismatch;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The default perfect match score
|
||||
/// </summary>
|
||||
public const double Perfect = 1.0;
|
||||
/// <summary>
|
||||
/// Calculates the score from multiple values.
|
||||
/// </summary>
|
||||
/// <param name="values">The values.</param>
|
||||
/// <param name="matchOperator">The <see cref="MatchOperator"/>.</param>
|
||||
/// <returns>average score</returns>
|
||||
public static double ToScore(IReadOnlyCollection<bool> values, MatchOperator matchOperator)
|
||||
{
|
||||
return ToScore(values.Select(ToScore).ToArray(), matchOperator);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The almost perfect match score
|
||||
/// </summary>
|
||||
public const double AlmostPerfect = 0.99;
|
||||
|
||||
/// <summary>
|
||||
/// Is the value a perfect match?
|
||||
/// </summary>
|
||||
/// <param name="value">The value.</param>
|
||||
/// <returns>true/false</returns>
|
||||
public static bool IsPerfect(double value)
|
||||
/// <summary>
|
||||
/// Calculates the score from multiple values.
|
||||
/// </summary>
|
||||
/// <param name="values">The values.</param>
|
||||
/// <param name="matchOperator"></param>
|
||||
/// <returns>average score</returns>
|
||||
public static double ToScore(IReadOnlyCollection<double> values, MatchOperator matchOperator)
|
||||
{
|
||||
if (!values.Any())
|
||||
{
|
||||
return Math.Abs(value - Perfect) < Tolerance;
|
||||
return Mismatch;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert a bool to the score.
|
||||
/// </summary>
|
||||
/// <param name="value">if set to <c>true</c> [value].</param>
|
||||
/// <returns>score</returns>
|
||||
public static double ToScore(bool value)
|
||||
return matchOperator switch
|
||||
{
|
||||
return value ? Perfect : Mismatch;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calculates the score from multiple values.
|
||||
/// </summary>
|
||||
/// <param name="values">The values.</param>
|
||||
/// <returns>average score</returns>
|
||||
[SuppressMessage("ReSharper", "PossibleMultipleEnumeration")]
|
||||
public static double ToScore(IEnumerable<bool> values)
|
||||
{
|
||||
return values.Any() ? values.Select(ToScore).Average() : Mismatch;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calculates the score from multiple values.
|
||||
/// </summary>
|
||||
/// <param name="values">The values.</param>
|
||||
/// <returns>average score</returns>
|
||||
[SuppressMessage("ReSharper", "PossibleMultipleEnumeration")]
|
||||
public static double ToScore(IEnumerable<double> values)
|
||||
{
|
||||
return values.Any() ? values.Average() : Mismatch;
|
||||
}
|
||||
MatchOperator.Or => ToScore(values.Any(IsPerfect)),
|
||||
MatchOperator.And => ToScore(values.All(IsPerfect)),
|
||||
_ => values.Average()
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -2,67 +2,69 @@ using System.Linq;
|
||||
using AnyOfTypes;
|
||||
using WireMock.Models;
|
||||
|
||||
namespace WireMock.Matchers
|
||||
namespace WireMock.Matchers;
|
||||
|
||||
/// <summary>
|
||||
/// NotNullOrEmptyMatcher
|
||||
/// </summary>
|
||||
/// <seealso cref="IObjectMatcher" />
|
||||
public class NotNullOrEmptyMatcher : IObjectMatcher, IStringMatcher
|
||||
{
|
||||
/// <inheritdoc cref="IMatcher.Name"/>
|
||||
public string Name => "NotNullOrEmptyMatcher";
|
||||
|
||||
/// <inheritdoc cref="IMatcher.MatchBehaviour"/>
|
||||
public MatchBehaviour MatchBehaviour { get; }
|
||||
|
||||
/// <inheritdoc cref="IMatcher.ThrowException"/>
|
||||
public bool ThrowException { get; }
|
||||
|
||||
/// <summary>
|
||||
/// NotNullOrEmptyMatcher
|
||||
/// Initializes a new instance of the <see cref="NotNullOrEmptyMatcher"/> class.
|
||||
/// </summary>
|
||||
/// <seealso cref="IObjectMatcher" />
|
||||
public class NotNullOrEmptyMatcher : IObjectMatcher, IStringMatcher
|
||||
/// <param name="matchBehaviour">The match behaviour.</param>
|
||||
public NotNullOrEmptyMatcher(MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
|
||||
{
|
||||
/// <inheritdoc cref="IMatcher.Name"/>
|
||||
public string Name => "NotNullOrEmptyMatcher";
|
||||
|
||||
/// <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>
|
||||
/// <param name="matchBehaviour">The match behaviour.</param>
|
||||
public NotNullOrEmptyMatcher(MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
|
||||
{
|
||||
MatchBehaviour = matchBehaviour;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IObjectMatcher.IsMatch"/>
|
||||
public double IsMatch(object input)
|
||||
{
|
||||
bool match;
|
||||
|
||||
switch (input)
|
||||
{
|
||||
case string @string:
|
||||
match = !string.IsNullOrEmpty(@string);
|
||||
break;
|
||||
|
||||
case byte[] bytes:
|
||||
match = bytes != null && bytes.Any();
|
||||
break;
|
||||
|
||||
default:
|
||||
match = input != null;
|
||||
break;
|
||||
}
|
||||
|
||||
return MatchBehaviourHelper.Convert(MatchBehaviour, MatchScores.ToScore(match));
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IStringMatcher.IsMatch"/>
|
||||
public double IsMatch(string input)
|
||||
{
|
||||
var match = !string.IsNullOrEmpty(input);
|
||||
|
||||
return MatchBehaviourHelper.Convert(MatchBehaviour, MatchScores.ToScore(match));
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IStringMatcher.GetPatterns"/>
|
||||
public AnyOf<string, StringPattern>[] GetPatterns()
|
||||
{
|
||||
return new AnyOf<string, StringPattern>[0];
|
||||
}
|
||||
MatchBehaviour = matchBehaviour;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IObjectMatcher.IsMatch"/>
|
||||
public double IsMatch(object? input)
|
||||
{
|
||||
bool match;
|
||||
|
||||
switch (input)
|
||||
{
|
||||
case string @string:
|
||||
match = !string.IsNullOrEmpty(@string);
|
||||
break;
|
||||
|
||||
case byte[] bytes:
|
||||
match = bytes.Any();
|
||||
break;
|
||||
|
||||
default:
|
||||
match = input != null;
|
||||
break;
|
||||
}
|
||||
|
||||
return MatchBehaviourHelper.Convert(MatchBehaviour, MatchScores.ToScore(match));
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IStringMatcher.IsMatch"/>
|
||||
public double IsMatch(string? input)
|
||||
{
|
||||
var match = !string.IsNullOrEmpty(input);
|
||||
|
||||
return MatchBehaviourHelper.Convert(MatchBehaviour, MatchScores.ToScore(match));
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IStringMatcher.GetPatterns"/>
|
||||
public AnyOf<string, StringPattern>[] GetPatterns()
|
||||
{
|
||||
return new AnyOf<string, StringPattern>[0];
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public MatchOperator MatchOperator { get; } = MatchOperator.Or;
|
||||
}
|
||||
@@ -33,8 +33,14 @@ public class RegexMatcher : IStringMatcher, IIgnoreCaseMatcher
|
||||
/// <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>
|
||||
public RegexMatcher([NotNull, RegexPattern] AnyOf<string, StringPattern> pattern, bool ignoreCase = false, bool throwException = false, bool useRegexExtended = true) :
|
||||
this(MatchBehaviour.AcceptOnMatch, new[] { pattern }, ignoreCase, throwException, useRegexExtended)
|
||||
/// <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, throwException, useRegexExtended, matchOperator)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -46,8 +52,15 @@ public class RegexMatcher : IStringMatcher, IIgnoreCaseMatcher
|
||||
/// <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>
|
||||
public RegexMatcher(MatchBehaviour matchBehaviour, [NotNull, RegexPattern] AnyOf<string, StringPattern> pattern, bool ignoreCase = false, bool throwException = false, bool useRegexExtended = true) :
|
||||
this(matchBehaviour, new[] { pattern }, ignoreCase, throwException, useRegexExtended)
|
||||
/// <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, throwException, useRegexExtended, matchOperator)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -59,14 +72,20 @@ public class RegexMatcher : IStringMatcher, IIgnoreCaseMatcher
|
||||
/// <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>
|
||||
public RegexMatcher(MatchBehaviour matchBehaviour, [NotNull, RegexPattern] AnyOf<string, StringPattern>[] patterns, bool ignoreCase = false, bool throwException = false, bool useRegexExtended = true)
|
||||
/// <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)
|
||||
{
|
||||
Guard.NotNull(patterns, nameof(patterns));
|
||||
|
||||
_patterns = patterns;
|
||||
_patterns = Guard.NotNull(patterns);
|
||||
IgnoreCase = ignoreCase;
|
||||
MatchBehaviour = matchBehaviour;
|
||||
ThrowException = throwException;
|
||||
MatchOperator = matchOperator;
|
||||
|
||||
RegexOptions options = RegexOptions.Compiled | RegexOptions.Multiline;
|
||||
|
||||
@@ -79,14 +98,14 @@ public class RegexMatcher : IStringMatcher, IIgnoreCaseMatcher
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IStringMatcher.IsMatch"/>
|
||||
public virtual double IsMatch(string input)
|
||||
public virtual double IsMatch(string? input)
|
||||
{
|
||||
double match = MatchScores.Mismatch;
|
||||
if (input != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
match = MatchScores.ToScore(_expressions.Select(e => e.IsMatch(input)));
|
||||
match = MatchScores.ToScore(_expressions.Select(e => e.IsMatch(input)).ToArray(), MatchOperator);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
@@ -111,4 +130,8 @@ public class RegexMatcher : IStringMatcher, IIgnoreCaseMatcher
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool IgnoreCase { get; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public MatchOperator MatchOperator { get; }
|
||||
|
||||
}
|
||||
@@ -1,211 +1,226 @@
|
||||
using JetBrains.Annotations;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using AnyOfTypes;
|
||||
using Stef.Validation;
|
||||
using WireMock.Models;
|
||||
using WireMock.Types;
|
||||
using WireMock.Util;
|
||||
using Stef.Validation;
|
||||
|
||||
namespace WireMock.Matchers.Request
|
||||
namespace WireMock.Matchers.Request;
|
||||
|
||||
/// <summary>
|
||||
/// The request body matcher.
|
||||
/// </summary>
|
||||
public class RequestMessageBodyMatcher : IRequestMatcher
|
||||
{
|
||||
/// <summary>
|
||||
/// The request body matcher.
|
||||
/// The body function
|
||||
/// </summary>
|
||||
public class RequestMessageBodyMatcher : IRequestMatcher
|
||||
public Func<string, bool>? Func { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The body data function for byte[]
|
||||
/// </summary>
|
||||
public Func<byte[], bool>? DataFunc { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The body data function for json
|
||||
/// </summary>
|
||||
public Func<object, bool>? JsonFunc { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The body data function for BodyData
|
||||
/// </summary>
|
||||
public Func<IBodyData, bool>? BodyDataFunc { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The matchers.
|
||||
/// </summary>
|
||||
public IMatcher[]? Matchers { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="MatchOperator"/>
|
||||
/// </summary>
|
||||
public MatchOperator MatchOperator { get; } = MatchOperator.Or;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RequestMessageBodyMatcher"/> class.
|
||||
/// </summary>
|
||||
/// <param name="matchBehaviour">The match behaviour.</param>
|
||||
/// <param name="body">The body.</param>
|
||||
public RequestMessageBodyMatcher(MatchBehaviour matchBehaviour, string body) :
|
||||
this(new[] { new WildcardMatcher(matchBehaviour, body) }.Cast<IMatcher>().ToArray())
|
||||
{
|
||||
/// <summary>
|
||||
/// The body function
|
||||
/// </summary>
|
||||
public Func<string, bool> Func { get; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The body data function for byte[]
|
||||
/// </summary>
|
||||
public Func<byte[], bool> DataFunc { get; }
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RequestMessageBodyMatcher"/> class.
|
||||
/// </summary>
|
||||
/// <param name="matchBehaviour">The match behaviour.</param>
|
||||
/// <param name="body">The body.</param>
|
||||
public RequestMessageBodyMatcher(MatchBehaviour matchBehaviour, byte[] body) :
|
||||
this(new[] { new ExactObjectMatcher(matchBehaviour, body) }.Cast<IMatcher>().ToArray())
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The body data function for json
|
||||
/// </summary>
|
||||
public Func<object, bool> JsonFunc { get; }
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RequestMessageBodyMatcher"/> class.
|
||||
/// </summary>
|
||||
/// <param name="matchBehaviour">The match behaviour.</param>
|
||||
/// <param name="body">The body.</param>
|
||||
public RequestMessageBodyMatcher(MatchBehaviour matchBehaviour, object body) :
|
||||
this(new[] { new ExactObjectMatcher(matchBehaviour, body) }.Cast<IMatcher>().ToArray())
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The body data function for BodyData
|
||||
/// </summary>
|
||||
public Func<IBodyData, bool> BodyDataFunc { get; }
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RequestMessageBodyMatcher"/> class.
|
||||
/// </summary>
|
||||
/// <param name="func">The function.</param>
|
||||
public RequestMessageBodyMatcher(Func<string, bool> func)
|
||||
{
|
||||
Func = Guard.NotNull(func);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The matchers.
|
||||
/// </summary>
|
||||
public IMatcher[] Matchers { get; }
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RequestMessageBodyMatcher"/> class.
|
||||
/// </summary>
|
||||
/// <param name="func">The function.</param>
|
||||
public RequestMessageBodyMatcher(Func<byte[], bool> func)
|
||||
{
|
||||
DataFunc = Guard.NotNull(func);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RequestMessageBodyMatcher"/> class.
|
||||
/// </summary>
|
||||
/// <param name="matchBehaviour">The match behaviour.</param>
|
||||
/// <param name="body">The body.</param>
|
||||
public RequestMessageBodyMatcher(MatchBehaviour matchBehaviour, [NotNull] string body) : this(new[] { new WildcardMatcher(matchBehaviour, body) }.Cast<IMatcher>().ToArray())
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RequestMessageBodyMatcher"/> class.
|
||||
/// </summary>
|
||||
/// <param name="func">The function.</param>
|
||||
public RequestMessageBodyMatcher(Func<object, bool> func)
|
||||
{
|
||||
JsonFunc = Guard.NotNull(func);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RequestMessageBodyMatcher"/> class.
|
||||
/// </summary>
|
||||
/// <param name="func">The function.</param>
|
||||
public RequestMessageBodyMatcher(Func<IBodyData, bool> func)
|
||||
{
|
||||
BodyDataFunc = Guard.NotNull(func);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RequestMessageBodyMatcher"/> class.
|
||||
/// </summary>
|
||||
/// <param name="matchers">The matchers.</param>
|
||||
public RequestMessageBodyMatcher(params IMatcher[] matchers)
|
||||
{
|
||||
Matchers = Guard.NotNull(matchers);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RequestMessageBodyMatcher"/> class.
|
||||
/// </summary>
|
||||
/// <param name="matchers">The matchers.</param>
|
||||
/// <param name="matchOperator">The <see cref="MatchOperator"/> to use.</param>
|
||||
public RequestMessageBodyMatcher(MatchOperator matchOperator, params IMatcher[] matchers)
|
||||
{
|
||||
Matchers = Guard.NotNull(matchers);
|
||||
MatchOperator = matchOperator;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public double GetMatchingScore(IRequestMessage requestMessage, IRequestMatchResult requestMatchResult)
|
||||
{
|
||||
double score = CalculateMatchScore(requestMessage);
|
||||
return requestMatchResult.AddScore(GetType(), score);
|
||||
}
|
||||
|
||||
private static double CalculateMatchScore(IRequestMessage requestMessage, IMatcher matcher)
|
||||
{
|
||||
if (matcher is NotNullOrEmptyMatcher notNullOrEmptyMatcher)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RequestMessageBodyMatcher"/> class.
|
||||
/// </summary>
|
||||
/// <param name="matchBehaviour">The match behaviour.</param>
|
||||
/// <param name="body">The body.</param>
|
||||
public RequestMessageBodyMatcher(MatchBehaviour matchBehaviour, [NotNull] byte[] body) : this(new[] { new ExactObjectMatcher(matchBehaviour, body) }.Cast<IMatcher>().ToArray())
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RequestMessageBodyMatcher"/> class.
|
||||
/// </summary>
|
||||
/// <param name="matchBehaviour">The match behaviour.</param>
|
||||
/// <param name="body">The body.</param>
|
||||
public RequestMessageBodyMatcher(MatchBehaviour matchBehaviour, [NotNull] object body) : this(new[] { new ExactObjectMatcher(matchBehaviour, body) }.Cast<IMatcher>().ToArray())
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RequestMessageBodyMatcher"/> class.
|
||||
/// </summary>
|
||||
/// <param name="func">The function.</param>
|
||||
public RequestMessageBodyMatcher([NotNull] Func<string, bool> func)
|
||||
{
|
||||
Guard.NotNull(func, nameof(func));
|
||||
Func = func;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RequestMessageBodyMatcher"/> class.
|
||||
/// </summary>
|
||||
/// <param name="func">The function.</param>
|
||||
public RequestMessageBodyMatcher([NotNull] Func<byte[], bool> func)
|
||||
{
|
||||
Guard.NotNull(func, nameof(func));
|
||||
DataFunc = func;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RequestMessageBodyMatcher"/> class.
|
||||
/// </summary>
|
||||
/// <param name="func">The function.</param>
|
||||
public RequestMessageBodyMatcher([NotNull] Func<object, bool> func)
|
||||
{
|
||||
Guard.NotNull(func, nameof(func));
|
||||
JsonFunc = func;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RequestMessageBodyMatcher"/> class.
|
||||
/// </summary>
|
||||
/// <param name="func">The function.</param>
|
||||
public RequestMessageBodyMatcher([NotNull] Func<IBodyData, bool> func)
|
||||
{
|
||||
Guard.NotNull(func, nameof(func));
|
||||
BodyDataFunc = func;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RequestMessageBodyMatcher"/> class.
|
||||
/// </summary>
|
||||
/// <param name="matchers">The matchers.</param>
|
||||
public RequestMessageBodyMatcher([NotNull] params IMatcher[] matchers)
|
||||
{
|
||||
Guard.NotNull(matchers, nameof(matchers));
|
||||
Matchers = matchers;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public double GetMatchingScore(IRequestMessage requestMessage, IRequestMatchResult requestMatchResult)
|
||||
{
|
||||
double score = CalculateMatchScore(requestMessage);
|
||||
return requestMatchResult.AddScore(GetType(), score);
|
||||
}
|
||||
|
||||
private double CalculateMatchScore(IRequestMessage requestMessage, IMatcher matcher)
|
||||
{
|
||||
if (matcher is NotNullOrEmptyMatcher notNullOrEmptyMatcher)
|
||||
switch (requestMessage.BodyData?.DetectedBodyType)
|
||||
{
|
||||
switch (requestMessage?.BodyData?.DetectedBodyType)
|
||||
{
|
||||
case BodyType.Json:
|
||||
case BodyType.String:
|
||||
return notNullOrEmptyMatcher.IsMatch(requestMessage.BodyData.BodyAsString);
|
||||
case BodyType.Json:
|
||||
case BodyType.String:
|
||||
return notNullOrEmptyMatcher.IsMatch(requestMessage.BodyData.BodyAsString);
|
||||
|
||||
case BodyType.Bytes:
|
||||
return notNullOrEmptyMatcher.IsMatch(requestMessage.BodyData.BodyAsBytes);
|
||||
case BodyType.Bytes:
|
||||
return notNullOrEmptyMatcher.IsMatch(requestMessage.BodyData.BodyAsBytes);
|
||||
|
||||
default:
|
||||
return MatchScores.Mismatch;
|
||||
}
|
||||
default:
|
||||
return MatchScores.Mismatch;
|
||||
}
|
||||
}
|
||||
|
||||
if (matcher is ExactObjectMatcher exactObjectMatcher)
|
||||
{
|
||||
// If the body is a byte array, try to match.
|
||||
var detectedBodyType = requestMessage.BodyData?.DetectedBodyType;
|
||||
if (detectedBodyType == BodyType.Bytes || detectedBodyType == BodyType.String)
|
||||
{
|
||||
return exactObjectMatcher.IsMatch(requestMessage.BodyData.BodyAsBytes);
|
||||
}
|
||||
}
|
||||
|
||||
// Check if the matcher is a IObjectMatcher
|
||||
if (matcher is IObjectMatcher objectMatcher)
|
||||
{
|
||||
// If the body is a JSON object, try to match.
|
||||
if (requestMessage?.BodyData?.DetectedBodyType == BodyType.Json)
|
||||
{
|
||||
return objectMatcher.IsMatch(requestMessage.BodyData.BodyAsJson);
|
||||
}
|
||||
|
||||
if (matcher is ExactObjectMatcher exactObjectMatcher)
|
||||
// If the body is a byte array, try to match.
|
||||
if (requestMessage?.BodyData?.DetectedBodyType == BodyType.Bytes)
|
||||
{
|
||||
// If the body is a byte array, try to match.
|
||||
var detectedBodyType = requestMessage?.BodyData?.DetectedBodyType;
|
||||
if (detectedBodyType == BodyType.Bytes || detectedBodyType == BodyType.String)
|
||||
{
|
||||
return exactObjectMatcher.IsMatch(requestMessage.BodyData.BodyAsBytes);
|
||||
}
|
||||
return objectMatcher.IsMatch(requestMessage.BodyData.BodyAsBytes);
|
||||
}
|
||||
|
||||
// Check if the matcher is a IObjectMatcher
|
||||
if (matcher is IObjectMatcher objectMatcher)
|
||||
{
|
||||
// If the body is a JSON object, try to match.
|
||||
if (requestMessage?.BodyData?.DetectedBodyType == BodyType.Json)
|
||||
{
|
||||
return objectMatcher.IsMatch(requestMessage.BodyData.BodyAsJson);
|
||||
}
|
||||
|
||||
// If the body is a byte array, try to match.
|
||||
if (requestMessage?.BodyData?.DetectedBodyType == BodyType.Bytes)
|
||||
{
|
||||
return objectMatcher.IsMatch(requestMessage.BodyData.BodyAsBytes);
|
||||
}
|
||||
}
|
||||
|
||||
// Check if the matcher is a IStringMatcher
|
||||
if (matcher is IStringMatcher stringMatcher)
|
||||
{
|
||||
// If the body is a Json or a String, use the BodyAsString to match on.
|
||||
if (requestMessage?.BodyData?.DetectedBodyType == BodyType.Json || requestMessage?.BodyData?.DetectedBodyType == BodyType.String)
|
||||
{
|
||||
return stringMatcher.IsMatch(requestMessage.BodyData.BodyAsString);
|
||||
}
|
||||
}
|
||||
|
||||
return MatchScores.Mismatch;
|
||||
}
|
||||
|
||||
private double CalculateMatchScore(IRequestMessage requestMessage)
|
||||
// Check if the matcher is a IStringMatcher
|
||||
if (matcher is IStringMatcher stringMatcher)
|
||||
{
|
||||
if (Matchers != null && Matchers.Any())
|
||||
// If the body is a Json or a String, use the BodyAsString to match on.
|
||||
if (requestMessage?.BodyData?.DetectedBodyType == BodyType.Json || requestMessage?.BodyData?.DetectedBodyType == BodyType.String)
|
||||
{
|
||||
return Matchers.Max(matcher => CalculateMatchScore(requestMessage, matcher));
|
||||
return stringMatcher.IsMatch(requestMessage.BodyData.BodyAsString);
|
||||
}
|
||||
|
||||
if (Func != null)
|
||||
{
|
||||
return MatchScores.ToScore(Func(requestMessage?.BodyData?.BodyAsString));
|
||||
}
|
||||
|
||||
if (JsonFunc != null)
|
||||
{
|
||||
return MatchScores.ToScore(JsonFunc(requestMessage?.BodyData?.BodyAsJson));
|
||||
}
|
||||
|
||||
if (DataFunc != null)
|
||||
{
|
||||
return MatchScores.ToScore(DataFunc(requestMessage?.BodyData?.BodyAsBytes));
|
||||
}
|
||||
|
||||
if (BodyDataFunc != null)
|
||||
{
|
||||
return MatchScores.ToScore(BodyDataFunc(requestMessage?.BodyData));
|
||||
}
|
||||
|
||||
return MatchScores.Mismatch;
|
||||
}
|
||||
|
||||
return MatchScores.Mismatch;
|
||||
}
|
||||
|
||||
private double CalculateMatchScore(IRequestMessage requestMessage)
|
||||
{
|
||||
if (Matchers != null)
|
||||
{
|
||||
var matchersResult = Matchers.Select(matcher => CalculateMatchScore(requestMessage, matcher)).ToArray();
|
||||
return MatchScores.ToScore(matchersResult, MatchOperator);
|
||||
}
|
||||
|
||||
if (Func != null)
|
||||
{
|
||||
return MatchScores.ToScore(Func(requestMessage.BodyData?.BodyAsString));
|
||||
}
|
||||
|
||||
if (JsonFunc != null)
|
||||
{
|
||||
return MatchScores.ToScore(JsonFunc(requestMessage.BodyData?.BodyAsJson));
|
||||
}
|
||||
|
||||
if (DataFunc != null)
|
||||
{
|
||||
return MatchScores.ToScore(DataFunc(requestMessage.BodyData?.BodyAsBytes));
|
||||
}
|
||||
|
||||
if (BodyDataFunc != null)
|
||||
{
|
||||
return MatchScores.ToScore(BodyDataFunc(requestMessage.BodyData));
|
||||
}
|
||||
|
||||
return MatchScores.Mismatch;
|
||||
}
|
||||
}
|
||||
@@ -1,75 +1,98 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using JetBrains.Annotations;
|
||||
using AnyOfTypes;
|
||||
using Stef.Validation;
|
||||
using WireMock.Models;
|
||||
|
||||
namespace WireMock.Matchers.Request
|
||||
namespace WireMock.Matchers.Request;
|
||||
|
||||
/// <summary>
|
||||
/// The request clientIP matcher.
|
||||
/// </summary>
|
||||
public class RequestMessageClientIPMatcher : IRequestMatcher
|
||||
{
|
||||
/// <summary>
|
||||
/// The request ClientIP matcher.
|
||||
/// The matchers
|
||||
/// </summary>
|
||||
public class RequestMessageClientIPMatcher : IRequestMatcher
|
||||
public IReadOnlyList<IStringMatcher>? Matchers { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The clientIP functions
|
||||
/// </summary>
|
||||
public Func<string, bool>[]? Funcs { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="MatchBehaviour"/>
|
||||
/// </summary>
|
||||
public MatchBehaviour Behaviour { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="MatchOperator"/>
|
||||
/// </summary>
|
||||
public MatchOperator MatchOperator { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RequestMessageClientIPMatcher"/> class.
|
||||
/// </summary>
|
||||
/// <param name="matchBehaviour">The match behaviour.</param>
|
||||
/// <param name="matchOperator">The <see cref="MatchOperator"/> to use.</param>
|
||||
/// <param name="clientIPs">The clientIPs.</param>
|
||||
public RequestMessageClientIPMatcher(
|
||||
MatchBehaviour matchBehaviour,
|
||||
MatchOperator matchOperator,
|
||||
params string[] clientIPs) :
|
||||
this(matchBehaviour, matchOperator, clientIPs
|
||||
.Select(clientIP => new WildcardMatcher(matchBehaviour, new AnyOf<string, StringPattern>[] { clientIP }, false, false, matchOperator))
|
||||
.Cast<IStringMatcher>().ToArray())
|
||||
{
|
||||
/// <summary>
|
||||
/// The matchers.
|
||||
/// </summary>
|
||||
public IReadOnlyList<IStringMatcher> Matchers { get; }
|
||||
Behaviour = matchBehaviour;
|
||||
MatchOperator = matchOperator;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The ClientIP functions.
|
||||
/// </summary>
|
||||
public Func<string, bool>[] Funcs { get; }
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RequestMessageClientIPMatcher"/> class.
|
||||
/// </summary>
|
||||
/// <param name="matchBehaviour">The match behaviour.</param>
|
||||
/// <param name="matchOperator">The <see cref="MatchOperator"/> to use.</param>
|
||||
/// <param name="matchers">The matchers.</param>
|
||||
public RequestMessageClientIPMatcher(MatchBehaviour matchBehaviour, MatchOperator matchOperator, params IStringMatcher[] matchers)
|
||||
{
|
||||
Matchers = Guard.NotNull(matchers);
|
||||
Behaviour = matchBehaviour;
|
||||
MatchOperator = matchOperator;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RequestMessageClientIPMatcher"/> class.
|
||||
/// </summary>
|
||||
/// <param name="clientIPs">The clientIPs.</param>
|
||||
/// <param name="matchBehaviour">The match behaviour.</param>
|
||||
public RequestMessageClientIPMatcher(MatchBehaviour matchBehaviour, [NotNull] params string[] clientIPs) : this(clientIPs.Select(ip => new WildcardMatcher(matchBehaviour, ip)).Cast<IStringMatcher>().ToArray())
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RequestMessageClientIPMatcher"/> class.
|
||||
/// </summary>
|
||||
/// <param name="funcs">The clientIP functions.</param>
|
||||
public RequestMessageClientIPMatcher(params Func<string, bool>[] funcs)
|
||||
{
|
||||
Funcs = Guard.NotNull(funcs);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public double GetMatchingScore(IRequestMessage requestMessage, IRequestMatchResult requestMatchResult)
|
||||
{
|
||||
double score = IsMatch(requestMessage);
|
||||
return requestMatchResult.AddScore(GetType(), score);
|
||||
}
|
||||
|
||||
private double IsMatch(IRequestMessage requestMessage)
|
||||
{
|
||||
if (Matchers != null)
|
||||
{
|
||||
var results = Matchers.Select(m => m.IsMatch(requestMessage.ClientIP)).ToArray();
|
||||
return MatchScores.ToScore(results, MatchOperator);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RequestMessageClientIPMatcher"/> class.
|
||||
/// </summary>
|
||||
/// <param name="matchers">The matchers.</param>
|
||||
public RequestMessageClientIPMatcher([NotNull] params IStringMatcher[] matchers)
|
||||
if (Funcs != null)
|
||||
{
|
||||
Guard.NotNull(matchers, nameof(matchers));
|
||||
Matchers = matchers;
|
||||
var results = Funcs.Select(func => func(requestMessage.ClientIP)).ToArray();
|
||||
return MatchScores.ToScore(results, MatchOperator);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RequestMessageClientIPMatcher"/> class.
|
||||
/// </summary>
|
||||
/// <param name="funcs">The clientIP functions.</param>
|
||||
public RequestMessageClientIPMatcher([NotNull] params Func<string, bool>[] funcs)
|
||||
{
|
||||
Guard.NotNull(funcs, nameof(funcs));
|
||||
Funcs = funcs;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public double GetMatchingScore(IRequestMessage requestMessage, IRequestMatchResult requestMatchResult)
|
||||
{
|
||||
double score = IsMatch(requestMessage);
|
||||
return requestMatchResult.AddScore(GetType(), score);
|
||||
}
|
||||
|
||||
private double IsMatch(IRequestMessage requestMessage)
|
||||
{
|
||||
if (Matchers != null)
|
||||
{
|
||||
return Matchers.Max(matcher => matcher.IsMatch(requestMessage.ClientIP));
|
||||
}
|
||||
|
||||
if (Funcs != null)
|
||||
{
|
||||
return MatchScores.ToScore(requestMessage.ClientIP != null && Funcs.Any(func => func(requestMessage.ClientIP)));
|
||||
}
|
||||
|
||||
return MatchScores.Mismatch;
|
||||
}
|
||||
return MatchScores.Mismatch;
|
||||
}
|
||||
}
|
||||
@@ -1,130 +1,143 @@
|
||||
using JetBrains.Annotations;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using WireMock.Types;
|
||||
using Stef.Validation;
|
||||
using WireMock.Types;
|
||||
|
||||
namespace WireMock.Matchers.Request
|
||||
namespace WireMock.Matchers.Request;
|
||||
|
||||
/// <summary>
|
||||
/// The request header matcher.
|
||||
/// </summary>
|
||||
/// <inheritdoc cref="IRequestMatcher"/>
|
||||
public class RequestMessageHeaderMatcher : IRequestMatcher
|
||||
{
|
||||
private readonly MatchBehaviour _matchBehaviour;
|
||||
private readonly bool _ignoreCase;
|
||||
|
||||
/// <summary>
|
||||
/// The request header matcher.
|
||||
/// The functions
|
||||
/// </summary>
|
||||
/// <inheritdoc cref="IRequestMatcher"/>
|
||||
public class RequestMessageHeaderMatcher : IRequestMatcher
|
||||
public Func<IDictionary<string, string[]>, bool>[]? Funcs { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The name
|
||||
/// </summary>
|
||||
public string Name { get; }
|
||||
|
||||
/// <value>
|
||||
/// The matchers.
|
||||
/// </value>
|
||||
public IStringMatcher[]? Matchers { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="MatchOperator"/>
|
||||
/// </summary>
|
||||
public MatchOperator MatchOperator { get; } = MatchOperator.Or;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RequestMessageHeaderMatcher"/> class.
|
||||
/// </summary>
|
||||
/// <param name="name">The name.</param>
|
||||
/// <param name="pattern">The pattern.</param>
|
||||
/// <param name="ignoreCase">Ignore the case from the pattern.</param>
|
||||
/// <param name="matchBehaviour">The match behaviour.</param>
|
||||
public RequestMessageHeaderMatcher(MatchBehaviour matchBehaviour, string name, string pattern, bool ignoreCase)
|
||||
{
|
||||
private readonly MatchBehaviour _matchBehaviour;
|
||||
private readonly bool _ignoreCase;
|
||||
Guard.NotNull(name);
|
||||
Guard.NotNull(pattern);
|
||||
|
||||
/// <summary>
|
||||
/// The functions
|
||||
/// </summary>
|
||||
public Func<IDictionary<string, string[]>, bool>[] Funcs { get; }
|
||||
_matchBehaviour = matchBehaviour;
|
||||
_ignoreCase = ignoreCase;
|
||||
Name = name;
|
||||
Matchers = new IStringMatcher[] { new WildcardMatcher(matchBehaviour, pattern, ignoreCase) };
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The name
|
||||
/// </summary>
|
||||
public string Name { get; }
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RequestMessageHeaderMatcher"/> class.
|
||||
/// </summary>
|
||||
/// <param name="matchBehaviour">The match behaviour.</param>
|
||||
/// <param name="matchOperator">The <see cref="MatchOperator"/> to use.</param>
|
||||
/// <param name="name">The name.</param>
|
||||
/// <param name="patterns">The patterns.</param>
|
||||
/// <param name="ignoreCase">Ignore the case from the pattern.</param>
|
||||
public RequestMessageHeaderMatcher(MatchBehaviour matchBehaviour, MatchOperator matchOperator, string name, bool ignoreCase, params string[] patterns) :
|
||||
this(matchBehaviour, matchOperator, name, ignoreCase, patterns.Select(pattern => new WildcardMatcher(matchBehaviour, pattern, ignoreCase)).Cast<IStringMatcher>().ToArray())
|
||||
{
|
||||
Guard.NotNull(patterns);
|
||||
}
|
||||
|
||||
/// <value>
|
||||
/// The matchers.
|
||||
/// </value>
|
||||
public IStringMatcher[] Matchers { get; }
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RequestMessageHeaderMatcher"/> class.
|
||||
/// </summary>
|
||||
/// <param name="matchBehaviour">The match behaviour.</param>
|
||||
/// <param name="matchOperator">The <see cref="MatchOperator"/> to use.</param>
|
||||
/// <param name="name">The name.</param>
|
||||
/// <param name="matchers">The matchers.</param>
|
||||
/// <param name="ignoreCase">Ignore the case from the pattern.</param>
|
||||
public RequestMessageHeaderMatcher(MatchBehaviour matchBehaviour, MatchOperator matchOperator, string name, bool ignoreCase, params IStringMatcher[] matchers)
|
||||
{
|
||||
Guard.NotNull(name);
|
||||
Guard.NotNull(matchers);
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RequestMessageHeaderMatcher"/> class.
|
||||
/// </summary>
|
||||
/// <param name="name">The name.</param>
|
||||
/// <param name="pattern">The pattern.</param>
|
||||
/// <param name="ignoreCase">Ignore the case from the pattern.</param>
|
||||
/// <param name="matchBehaviour">The match behaviour.</param>
|
||||
public RequestMessageHeaderMatcher(MatchBehaviour matchBehaviour, [NotNull] string name, [NotNull] string pattern, bool ignoreCase)
|
||||
_matchBehaviour = matchBehaviour;
|
||||
MatchOperator = matchOperator;
|
||||
Name = name;
|
||||
Matchers = matchers;
|
||||
_ignoreCase = ignoreCase;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RequestMessageHeaderMatcher"/> class.
|
||||
/// </summary>
|
||||
/// <param name="funcs">The funcs.</param>
|
||||
public RequestMessageHeaderMatcher(params Func<IDictionary<string, string[]>, bool>[] funcs)
|
||||
{
|
||||
Funcs = Guard.NotNull(funcs);
|
||||
Name = string.Empty; // Not used when Func, but set to a non-null valid value.
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public double GetMatchingScore(IRequestMessage requestMessage, IRequestMatchResult requestMatchResult)
|
||||
{
|
||||
double score = IsMatch(requestMessage);
|
||||
return requestMatchResult.AddScore(GetType(), score);
|
||||
}
|
||||
|
||||
private double IsMatch(IRequestMessage requestMessage)
|
||||
{
|
||||
if (requestMessage.Headers == null)
|
||||
{
|
||||
Guard.NotNull(name, nameof(name));
|
||||
Guard.NotNull(pattern, nameof(pattern));
|
||||
|
||||
_matchBehaviour = matchBehaviour;
|
||||
_ignoreCase = ignoreCase;
|
||||
Name = name;
|
||||
Matchers = new IStringMatcher[] { new WildcardMatcher(matchBehaviour, pattern, ignoreCase) };
|
||||
return MatchBehaviourHelper.Convert(_matchBehaviour, MatchScores.Mismatch);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RequestMessageHeaderMatcher"/> class.
|
||||
/// </summary>
|
||||
/// <param name="matchBehaviour">The match behaviour.</param>
|
||||
/// <param name="name">The name.</param>
|
||||
/// <param name="patterns">The patterns.</param>
|
||||
/// <param name="ignoreCase">Ignore the case from the pattern.</param>
|
||||
public RequestMessageHeaderMatcher(MatchBehaviour matchBehaviour, [NotNull] string name, bool ignoreCase, [NotNull] params string[] patterns) :
|
||||
this(matchBehaviour, name, ignoreCase, patterns.Select(pattern => new WildcardMatcher(matchBehaviour, pattern, ignoreCase)).Cast<IStringMatcher>().ToArray())
|
||||
// Check if we want to use IgnoreCase to compare the Header-Name and Header-Value(s)
|
||||
var headers = !_ignoreCase ? requestMessage.Headers : new Dictionary<string, WireMockList<string>>(requestMessage.Headers, StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
if (Funcs != null)
|
||||
{
|
||||
Guard.NotNull(patterns, nameof(patterns));
|
||||
var funcResults = Funcs.Select(f => f(headers.ToDictionary(entry => entry.Key, entry => entry.Value.ToArray()))).ToArray();
|
||||
return MatchScores.ToScore(funcResults, MatchOperator);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RequestMessageHeaderMatcher"/> class.
|
||||
/// </summary>
|
||||
/// <param name="matchBehaviour">The match behaviour.</param>
|
||||
/// <param name="name">The name.</param>
|
||||
/// <param name="matchers">The matchers.</param>
|
||||
/// <param name="ignoreCase">Ignore the case from the pattern.</param>
|
||||
public RequestMessageHeaderMatcher(MatchBehaviour matchBehaviour, [NotNull] string name, bool ignoreCase, [NotNull] params IStringMatcher[] matchers)
|
||||
if (Matchers != null)
|
||||
{
|
||||
Guard.NotNull(name, nameof(name));
|
||||
Guard.NotNull(matchers, nameof(matchers));
|
||||
|
||||
_matchBehaviour = matchBehaviour;
|
||||
Name = name;
|
||||
Matchers = matchers;
|
||||
_ignoreCase = ignoreCase;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RequestMessageHeaderMatcher"/> class.
|
||||
/// </summary>
|
||||
/// <param name="funcs">The funcs.</param>
|
||||
public RequestMessageHeaderMatcher([NotNull] params Func<IDictionary<string, string[]>, bool>[] funcs)
|
||||
{
|
||||
Guard.NotNull(funcs, nameof(funcs));
|
||||
|
||||
Funcs = funcs;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public double GetMatchingScore(IRequestMessage requestMessage, IRequestMatchResult requestMatchResult)
|
||||
{
|
||||
double score = IsMatch(requestMessage);
|
||||
return requestMatchResult.AddScore(GetType(), score);
|
||||
}
|
||||
|
||||
private double IsMatch(IRequestMessage requestMessage)
|
||||
{
|
||||
if (requestMessage.Headers == null)
|
||||
{
|
||||
return MatchBehaviourHelper.Convert(_matchBehaviour, MatchScores.Mismatch);
|
||||
}
|
||||
|
||||
// Check if we want to use IgnoreCase to compare the Header-Name and Header-Value(s)
|
||||
var headers = !_ignoreCase ? requestMessage.Headers : new Dictionary<string, WireMockList<string>>(requestMessage.Headers, StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
if (Funcs != null)
|
||||
{
|
||||
return MatchScores.ToScore(Funcs.Any(f => f(headers.ToDictionary(entry => entry.Key, entry => entry.Value.ToArray()))));
|
||||
}
|
||||
|
||||
if (Matchers == null)
|
||||
{
|
||||
return MatchScores.Mismatch;
|
||||
}
|
||||
|
||||
if (!headers.ContainsKey(Name))
|
||||
{
|
||||
return MatchBehaviourHelper.Convert(_matchBehaviour, MatchScores.Mismatch);
|
||||
}
|
||||
|
||||
WireMockList<string> list = headers[Name];
|
||||
return Matchers.Max(m => list.Max(m.IsMatch)); // TODO : is this correct ?
|
||||
var results = new List<double>();
|
||||
foreach (var matcher in Matchers)
|
||||
{
|
||||
var resultsPerMatcher = headers[Name].Select(v => matcher.IsMatch(v)).ToArray();
|
||||
|
||||
results.Add(MatchScores.ToScore(resultsPerMatcher, MatchOperator.And));
|
||||
}
|
||||
|
||||
return MatchBehaviourHelper.Convert(_matchBehaviour, MatchScores.ToScore(results, MatchOperator));
|
||||
}
|
||||
|
||||
return MatchBehaviourHelper.Convert(_matchBehaviour, MatchScores.Mismatch);
|
||||
}
|
||||
}
|
||||
@@ -1,45 +1,52 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using JetBrains.Annotations;
|
||||
using Stef.Validation;
|
||||
|
||||
namespace WireMock.Matchers.Request
|
||||
namespace WireMock.Matchers.Request;
|
||||
|
||||
/// <summary>
|
||||
/// The request method matcher.
|
||||
/// </summary>
|
||||
internal class RequestMessageMethodMatcher : IRequestMatcher
|
||||
{
|
||||
/// <summary>
|
||||
/// The request verb matcher.
|
||||
/// The <see cref="Matchers.MatchBehaviour"/>
|
||||
/// </summary>
|
||||
internal class RequestMessageMethodMatcher : IRequestMatcher
|
||||
public MatchBehaviour MatchBehaviour { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="Matchers.MatchOperator"/>
|
||||
/// </summary>
|
||||
public MatchOperator MatchOperator { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The methods
|
||||
/// </summary>
|
||||
public string[] Methods { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RequestMessageMethodMatcher"/> class.
|
||||
/// </summary>
|
||||
/// <param name="matchBehaviour">The match behaviour.</param>
|
||||
/// <param name="matchOperator">The <see cref="Matchers.MatchOperator"/> to use.</param>
|
||||
/// <param name="methods">The methods.</param>
|
||||
public RequestMessageMethodMatcher(MatchBehaviour matchBehaviour, MatchOperator matchOperator, params string[] methods)
|
||||
{
|
||||
private readonly MatchBehaviour _matchBehaviour;
|
||||
Methods = Guard.NotNull(methods);
|
||||
MatchBehaviour = matchBehaviour;
|
||||
MatchOperator = matchOperator;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The methods
|
||||
/// </summary>
|
||||
public string[] Methods { get; }
|
||||
/// <inheritdoc />
|
||||
public double GetMatchingScore(IRequestMessage requestMessage, IRequestMatchResult requestMatchResult)
|
||||
{
|
||||
double score = MatchBehaviourHelper.Convert(MatchBehaviour, IsMatch(requestMessage));
|
||||
return requestMatchResult.AddScore(GetType(), score);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RequestMessageMethodMatcher"/> class.
|
||||
/// </summary>
|
||||
/// <param name="matchBehaviour">The match behaviour.</param>
|
||||
/// <param name="methods">The methods.</param>
|
||||
public RequestMessageMethodMatcher(MatchBehaviour matchBehaviour, [NotNull] params string[] methods)
|
||||
{
|
||||
Guard.NotNull(methods, nameof(methods));
|
||||
_matchBehaviour = matchBehaviour;
|
||||
|
||||
Methods = methods;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public double GetMatchingScore(IRequestMessage requestMessage, IRequestMatchResult requestMatchResult)
|
||||
{
|
||||
double score = MatchBehaviourHelper.Convert(_matchBehaviour, IsMatch(requestMessage));
|
||||
return requestMatchResult.AddScore(GetType(), score);
|
||||
}
|
||||
|
||||
private double IsMatch(IRequestMessage requestMessage)
|
||||
{
|
||||
return MatchScores.ToScore(Methods.Contains(requestMessage.Method, StringComparer.OrdinalIgnoreCase));
|
||||
}
|
||||
private double IsMatch(IRequestMessage requestMessage)
|
||||
{
|
||||
var scores = Methods.Select(m => string.Equals(m, requestMessage.Method, StringComparison.OrdinalIgnoreCase)).ToArray();
|
||||
return MatchScores.ToScore(scores, MatchOperator);
|
||||
}
|
||||
}
|
||||
@@ -1,152 +1,146 @@
|
||||
using JetBrains.Annotations;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using WireMock.Types;
|
||||
using Stef.Validation;
|
||||
using WireMock.Types;
|
||||
|
||||
namespace WireMock.Matchers.Request
|
||||
namespace WireMock.Matchers.Request;
|
||||
|
||||
/// <summary>
|
||||
/// The request parameters matcher.
|
||||
/// </summary>
|
||||
public class RequestMessageParamMatcher : IRequestMatcher
|
||||
{
|
||||
private readonly MatchBehaviour _matchBehaviour;
|
||||
|
||||
/// <summary>
|
||||
/// The request parameters matcher.
|
||||
/// The funcs
|
||||
/// </summary>
|
||||
public class RequestMessageParamMatcher : IRequestMatcher
|
||||
public Func<IDictionary<string, WireMockList<string>>, bool>[]? Funcs { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The key
|
||||
/// </summary>
|
||||
public string? Key { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Defines if the key should be matched using case-ignore.
|
||||
/// </summary>
|
||||
public bool? IgnoreCase { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The matchers.
|
||||
/// </summary>
|
||||
public IReadOnlyList<IStringMatcher>? Matchers { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RequestMessageParamMatcher"/> class.
|
||||
/// </summary>
|
||||
/// <param name="matchBehaviour">The match behaviour.</param>
|
||||
/// <param name="key">The key.</param>
|
||||
/// <param name="ignoreCase">Defines if the key should be matched using case-ignore.</param>
|
||||
public RequestMessageParamMatcher(MatchBehaviour matchBehaviour, string key, bool ignoreCase) : this(matchBehaviour, key, ignoreCase, (IStringMatcher[]?)null)
|
||||
{
|
||||
private readonly MatchBehaviour _matchBehaviour;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The funcs
|
||||
/// </summary>
|
||||
public Func<IDictionary<string, WireMockList<string>>, bool>[] Funcs { get; }
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RequestMessageParamMatcher"/> class.
|
||||
/// </summary>
|
||||
/// <param name="matchBehaviour">The match behaviour.</param>
|
||||
/// <param name="key">The key.</param>
|
||||
/// <param name="ignoreCase">Defines if the key should be matched using case-ignore.</param>
|
||||
/// <param name="values">The values.</param>
|
||||
public RequestMessageParamMatcher(MatchBehaviour matchBehaviour, string key, bool ignoreCase, string[]? values) : this(matchBehaviour, key, ignoreCase, values?.Select(value => new ExactMatcher(matchBehaviour, false, MatchOperator.And, value)).Cast<IStringMatcher>().ToArray())
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The key
|
||||
/// </summary>
|
||||
public string Key { get; }
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RequestMessageParamMatcher"/> class.
|
||||
/// </summary>
|
||||
/// <param name="matchBehaviour">The match behaviour.</param>
|
||||
/// <param name="key">The key.</param>
|
||||
/// <param name="ignoreCase">Defines if the key should be matched using case-ignore.</param>
|
||||
/// <param name="matchers">The matchers.</param>
|
||||
public RequestMessageParamMatcher(MatchBehaviour matchBehaviour, string key, bool ignoreCase, IStringMatcher[]? matchers)
|
||||
{
|
||||
_matchBehaviour = matchBehaviour;
|
||||
Key = Guard.NotNull(key);
|
||||
IgnoreCase = ignoreCase;
|
||||
Matchers = matchers;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Defines if the key should be matched using case-ignore.
|
||||
/// </summary>
|
||||
public bool? IgnoreCase { get; private set; }
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RequestMessageParamMatcher"/> class.
|
||||
/// </summary>
|
||||
/// <param name="funcs">The funcs.</param>
|
||||
public RequestMessageParamMatcher(params Func<IDictionary<string, WireMockList<string>>, bool>[] funcs)
|
||||
{
|
||||
Funcs = Guard.NotNull(funcs);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The matchers.
|
||||
/// </summary>
|
||||
public IReadOnlyList<IStringMatcher> Matchers { get; }
|
||||
/// <inheritdoc />
|
||||
public double GetMatchingScore(IRequestMessage requestMessage, IRequestMatchResult requestMatchResult)
|
||||
{
|
||||
double score = MatchBehaviourHelper.Convert(_matchBehaviour, IsMatch(requestMessage));
|
||||
return requestMatchResult.AddScore(GetType(), score);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RequestMessageParamMatcher"/> class.
|
||||
/// </summary>
|
||||
/// <param name="matchBehaviour">The match behaviour.</param>
|
||||
/// <param name="key">The key.</param>
|
||||
/// <param name="ignoreCase">Defines if the key should be matched using case-ignore.</param>
|
||||
public RequestMessageParamMatcher(MatchBehaviour matchBehaviour, [NotNull] string key, bool ignoreCase) : this(matchBehaviour, key, ignoreCase, (IStringMatcher[])null)
|
||||
private double IsMatch(IRequestMessage requestMessage)
|
||||
{
|
||||
if (Funcs != null)
|
||||
{
|
||||
return MatchScores.ToScore(requestMessage.Query != null && Funcs.Any(f => f(requestMessage.Query)));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RequestMessageParamMatcher"/> class.
|
||||
/// </summary>
|
||||
/// <param name="matchBehaviour">The match behaviour.</param>
|
||||
/// <param name="key">The key.</param>
|
||||
/// <param name="ignoreCase">Defines if the key should be matched using case-ignore.</param>
|
||||
/// <param name="values">The values.</param>
|
||||
public RequestMessageParamMatcher(MatchBehaviour matchBehaviour, [NotNull] string key, bool ignoreCase, [CanBeNull] string[] values) : this(matchBehaviour, key, ignoreCase, values?.Select(value => new ExactMatcher(matchBehaviour, false, value)).Cast<IStringMatcher>().ToArray())
|
||||
var valuesPresentInRequestMessage = ((RequestMessage)requestMessage).GetParameter(Key!, IgnoreCase ?? false);
|
||||
if (valuesPresentInRequestMessage == null)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RequestMessageParamMatcher"/> class.
|
||||
/// </summary>
|
||||
/// <param name="matchBehaviour">The match behaviour.</param>
|
||||
/// <param name="key">The key.</param>
|
||||
/// <param name="ignoreCase">Defines if the key should be matched using case-ignore.</param>
|
||||
/// <param name="matchers">The matchers.</param>
|
||||
public RequestMessageParamMatcher(MatchBehaviour matchBehaviour, [NotNull] string key, bool ignoreCase, [CanBeNull] IStringMatcher[] matchers)
|
||||
{
|
||||
Guard.NotNull(key, nameof(key));
|
||||
|
||||
_matchBehaviour = matchBehaviour;
|
||||
Key = key;
|
||||
IgnoreCase = ignoreCase;
|
||||
Matchers = matchers;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RequestMessageParamMatcher"/> class.
|
||||
/// </summary>
|
||||
/// <param name="funcs">The funcs.</param>
|
||||
public RequestMessageParamMatcher([NotNull] params Func<IDictionary<string, WireMockList<string>>, bool>[] funcs)
|
||||
{
|
||||
Guard.NotNull(funcs, nameof(funcs));
|
||||
|
||||
Funcs = funcs;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public double GetMatchingScore(IRequestMessage requestMessage, IRequestMatchResult requestMatchResult)
|
||||
{
|
||||
double score = MatchBehaviourHelper.Convert(_matchBehaviour, IsMatch(requestMessage));
|
||||
return requestMatchResult.AddScore(GetType(), score);
|
||||
}
|
||||
|
||||
private double IsMatch(IRequestMessage requestMessage)
|
||||
{
|
||||
if (Funcs != null)
|
||||
{
|
||||
return MatchScores.ToScore(requestMessage.Query != null && Funcs.Any(f => f(requestMessage.Query)));
|
||||
}
|
||||
|
||||
WireMockList<string> valuesPresentInRequestMessage = ((RequestMessage) requestMessage).GetParameter(Key, IgnoreCase ?? false);
|
||||
if (valuesPresentInRequestMessage == null)
|
||||
{
|
||||
// Key is not present at all, just return Mismatch
|
||||
return MatchScores.Mismatch;
|
||||
}
|
||||
|
||||
if (Matchers != null && Matchers.Any())
|
||||
{
|
||||
// Return the score based on Matchers and valuesPresentInRequestMessage
|
||||
return CalculateScore(valuesPresentInRequestMessage);
|
||||
}
|
||||
|
||||
if (Matchers == null || !Matchers.Any())
|
||||
{
|
||||
// Matchers are null or not defined, and Key is present, just return Perfect.
|
||||
return MatchScores.Perfect;
|
||||
}
|
||||
|
||||
// Key is not present at all, just return Mismatch
|
||||
return MatchScores.Mismatch;
|
||||
}
|
||||
|
||||
private double CalculateScore(WireMockList<string> valuesPresentInRequestMessage)
|
||||
if (Matchers != null && Matchers.Any())
|
||||
{
|
||||
var total = new List<double>();
|
||||
// Return the score based on Matchers and valuesPresentInRequestMessage
|
||||
return CalculateScore(Matchers, valuesPresentInRequestMessage);
|
||||
}
|
||||
|
||||
// If the total patterns in all matchers > values in message, use the matcher as base
|
||||
if (Matchers.Sum(m => m.GetPatterns().Length) > valuesPresentInRequestMessage.Count)
|
||||
{
|
||||
foreach (var matcher in Matchers)
|
||||
{
|
||||
double score = 0d;
|
||||
foreach (string valuePresentInRequestMessage in valuesPresentInRequestMessage)
|
||||
{
|
||||
score += matcher.IsMatch(valuePresentInRequestMessage) / matcher.GetPatterns().Length;
|
||||
}
|
||||
if (Matchers == null || !Matchers.Any())
|
||||
{
|
||||
// Matchers are null or not defined, and Key is present, just return Perfect.
|
||||
return MatchScores.Perfect;
|
||||
}
|
||||
|
||||
total.Add(score);
|
||||
}
|
||||
}
|
||||
else
|
||||
return MatchScores.Mismatch;
|
||||
}
|
||||
|
||||
private double CalculateScore(IReadOnlyList<IStringMatcher> matchers, WireMockList<string> valuesPresentInRequestMessage)
|
||||
{
|
||||
var total = new List<double>();
|
||||
|
||||
// If the total patterns in all matchers > values in message, use the matcher as base
|
||||
if (matchers.Sum(m => m.GetPatterns().Length) > valuesPresentInRequestMessage.Count)
|
||||
{
|
||||
foreach (var matcher in matchers)
|
||||
{
|
||||
double score = 0d;
|
||||
foreach (string valuePresentInRequestMessage in valuesPresentInRequestMessage)
|
||||
{
|
||||
double score = Matchers.Max(m => m.IsMatch(valuePresentInRequestMessage));
|
||||
total.Add(score);
|
||||
score += matcher.IsMatch(valuePresentInRequestMessage) / matcher.GetPatterns().Length;
|
||||
}
|
||||
}
|
||||
|
||||
return total.Any() ? MatchScores.ToScore(total) : MatchScores.Mismatch;
|
||||
total.Add(score);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (string valuePresentInRequestMessage in valuesPresentInRequestMessage)
|
||||
{
|
||||
double score = matchers.Max(m => m.IsMatch(valuePresentInRequestMessage));
|
||||
total.Add(score);
|
||||
}
|
||||
}
|
||||
|
||||
return total.Any() ? MatchScores.ToScore(total, MatchOperator.Average) : MatchScores.Mismatch;
|
||||
}
|
||||
}
|
||||
@@ -1,77 +1,98 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using JetBrains.Annotations;
|
||||
using AnyOfTypes;
|
||||
using Stef.Validation;
|
||||
using WireMock.Models;
|
||||
|
||||
namespace WireMock.Matchers.Request
|
||||
namespace WireMock.Matchers.Request;
|
||||
|
||||
/// <summary>
|
||||
/// The request path matcher.
|
||||
/// </summary>
|
||||
public class RequestMessagePathMatcher : IRequestMatcher
|
||||
{
|
||||
/// <summary>
|
||||
/// The request path matcher.
|
||||
/// The matchers
|
||||
/// </summary>
|
||||
public class RequestMessagePathMatcher : IRequestMatcher
|
||||
public IReadOnlyList<IStringMatcher>? Matchers { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The path functions
|
||||
/// </summary>
|
||||
public Func<string, bool>[]? Funcs { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="MatchBehaviour"/>
|
||||
/// </summary>
|
||||
public MatchBehaviour Behaviour { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="MatchOperator"/>
|
||||
/// </summary>
|
||||
public MatchOperator MatchOperator { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RequestMessagePathMatcher"/> class.
|
||||
/// </summary>
|
||||
/// <param name="matchBehaviour">The match behaviour.</param>
|
||||
/// <param name="matchOperator">The <see cref="MatchOperator"/> to use.</param>
|
||||
/// <param name="paths">The paths.</param>
|
||||
public RequestMessagePathMatcher(
|
||||
MatchBehaviour matchBehaviour,
|
||||
MatchOperator matchOperator,
|
||||
params string[] paths) :
|
||||
this(matchBehaviour, matchOperator, paths
|
||||
.Select(path => new WildcardMatcher(matchBehaviour, new AnyOf<string, StringPattern>[] { path }, false, false, matchOperator))
|
||||
.Cast<IStringMatcher>().ToArray())
|
||||
{
|
||||
/// <summary>
|
||||
/// The matchers
|
||||
/// </summary>
|
||||
public IReadOnlyList<IStringMatcher> Matchers { get; }
|
||||
Behaviour = matchBehaviour;
|
||||
MatchOperator = matchOperator;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The path functions
|
||||
/// </summary>
|
||||
public Func<string, bool>[] Funcs { get; }
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RequestMessagePathMatcher"/> class.
|
||||
/// </summary>
|
||||
/// <param name="matchBehaviour">The match behaviour.</param>
|
||||
/// <param name="matchOperator">The <see cref="MatchOperator"/> to use.</param>
|
||||
/// <param name="matchers">The matchers.</param>
|
||||
public RequestMessagePathMatcher(MatchBehaviour matchBehaviour, MatchOperator matchOperator, params IStringMatcher[] matchers)
|
||||
{
|
||||
Matchers = Guard.NotNull(matchers);
|
||||
Behaviour = matchBehaviour;
|
||||
MatchOperator = matchOperator;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RequestMessagePathMatcher"/> class.
|
||||
/// </summary>
|
||||
/// <param name="matchBehaviour">The match behaviour.</param>
|
||||
/// <param name="paths">The paths.</param>
|
||||
public RequestMessagePathMatcher(MatchBehaviour matchBehaviour, [NotNull] params string[] paths) : this(paths.Select(path => new WildcardMatcher(matchBehaviour, path)).Cast<IStringMatcher>().ToArray())
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RequestMessagePathMatcher"/> class.
|
||||
/// </summary>
|
||||
/// <param name="funcs">The path functions.</param>
|
||||
public RequestMessagePathMatcher(params Func<string, bool>[] funcs)
|
||||
{
|
||||
Funcs = Guard.NotNull(funcs);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public double GetMatchingScore(IRequestMessage requestMessage, IRequestMatchResult requestMatchResult)
|
||||
{
|
||||
double score = IsMatch(requestMessage);
|
||||
return requestMatchResult.AddScore(GetType(), score);
|
||||
}
|
||||
|
||||
private double IsMatch(IRequestMessage requestMessage)
|
||||
{
|
||||
if (Matchers != null)
|
||||
{
|
||||
var results = Matchers.Select(m => m.IsMatch(requestMessage.Path)).ToArray();
|
||||
return MatchScores.ToScore(results, MatchOperator);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RequestMessagePathMatcher"/> class.
|
||||
/// </summary>
|
||||
/// <param name="matchers">The matchers.</param>
|
||||
public RequestMessagePathMatcher([NotNull] params IStringMatcher[] matchers)
|
||||
if (Funcs != null)
|
||||
{
|
||||
Guard.NotNull(matchers, nameof(matchers));
|
||||
|
||||
Matchers = matchers;
|
||||
var results = Funcs.Select(func => func(requestMessage.Path)).ToArray();
|
||||
return MatchScores.ToScore(results, MatchOperator);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RequestMessagePathMatcher"/> class.
|
||||
/// </summary>
|
||||
/// <param name="funcs">The path functions.</param>
|
||||
public RequestMessagePathMatcher([NotNull] params Func<string, bool>[] funcs)
|
||||
{
|
||||
Guard.NotNull(funcs, nameof(funcs));
|
||||
|
||||
Funcs = funcs;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IRequestMatcher.GetMatchingScore"/>
|
||||
public double GetMatchingScore(IRequestMessage requestMessage, IRequestMatchResult requestMatchResult)
|
||||
{
|
||||
double score = IsMatch(requestMessage);
|
||||
return requestMatchResult.AddScore(GetType(), score);
|
||||
}
|
||||
|
||||
private double IsMatch(IRequestMessage requestMessage)
|
||||
{
|
||||
if (Matchers != null)
|
||||
{
|
||||
return Matchers.Max(m => m.IsMatch(requestMessage.Path));
|
||||
}
|
||||
|
||||
if (Funcs != null)
|
||||
{
|
||||
return MatchScores.ToScore(requestMessage.Path != null && Funcs.Any(func => func(requestMessage.Path)));
|
||||
}
|
||||
|
||||
return MatchScores.Mismatch;
|
||||
}
|
||||
return MatchScores.Mismatch;
|
||||
}
|
||||
}
|
||||
@@ -1,75 +1,98 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using JetBrains.Annotations;
|
||||
using AnyOfTypes;
|
||||
using Stef.Validation;
|
||||
using WireMock.Models;
|
||||
|
||||
namespace WireMock.Matchers.Request
|
||||
namespace WireMock.Matchers.Request;
|
||||
|
||||
/// <summary>
|
||||
/// The request url matcher.
|
||||
/// </summary>
|
||||
public class RequestMessageUrlMatcher : IRequestMatcher
|
||||
{
|
||||
/// <summary>
|
||||
/// The request url matcher.
|
||||
/// The matchers
|
||||
/// </summary>
|
||||
public class RequestMessageUrlMatcher : IRequestMatcher
|
||||
public IReadOnlyList<IStringMatcher>? Matchers { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The url functions
|
||||
/// </summary>
|
||||
public Func<string, bool>[]? Funcs { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="MatchBehaviour"/>
|
||||
/// </summary>
|
||||
public MatchBehaviour Behaviour { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="MatchOperator"/>
|
||||
/// </summary>
|
||||
public MatchOperator MatchOperator { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RequestMessageUrlMatcher"/> class.
|
||||
/// </summary>
|
||||
/// <param name="matchBehaviour">The match behaviour.</param>
|
||||
/// <param name="matchOperator">The <see cref="MatchOperator"/> to use.</param>
|
||||
/// <param name="urls">The urls.</param>
|
||||
public RequestMessageUrlMatcher(
|
||||
MatchBehaviour matchBehaviour,
|
||||
MatchOperator matchOperator,
|
||||
params string[] urls) :
|
||||
this(matchBehaviour, matchOperator, urls
|
||||
.Select(url => new WildcardMatcher(matchBehaviour, new AnyOf<string, StringPattern>[] { url }, false, false, matchOperator))
|
||||
.Cast<IStringMatcher>().ToArray())
|
||||
{
|
||||
/// <summary>
|
||||
/// The matchers.
|
||||
/// </summary>
|
||||
public IReadOnlyList<IStringMatcher> Matchers { get; }
|
||||
Behaviour = matchBehaviour;
|
||||
MatchOperator = matchOperator;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The url functions.
|
||||
/// </summary>
|
||||
public Func<string, bool>[] Funcs { get; }
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RequestMessageUrlMatcher"/> class.
|
||||
/// </summary>
|
||||
/// <param name="matchBehaviour">The match behaviour.</param>
|
||||
/// <param name="matchOperator">The <see cref="MatchOperator"/> to use. (default = "Or")</param>
|
||||
/// <param name="matchers">The matchers.</param>
|
||||
public RequestMessageUrlMatcher(MatchBehaviour matchBehaviour, MatchOperator matchOperator, params IStringMatcher[] matchers)
|
||||
{
|
||||
Matchers = Guard.NotNull(matchers);
|
||||
Behaviour = matchBehaviour;
|
||||
MatchOperator = matchOperator;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RequestMessageUrlMatcher"/> class.
|
||||
/// </summary>
|
||||
/// <param name="matchBehaviour">The match behaviour.</param>
|
||||
/// <param name="urls">The urls.</param>
|
||||
public RequestMessageUrlMatcher(MatchBehaviour matchBehaviour, [NotNull] params string[] urls) : this(urls.Select(url => new WildcardMatcher(matchBehaviour, url)).Cast<IStringMatcher>().ToArray())
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RequestMessageUrlMatcher"/> class.
|
||||
/// </summary>
|
||||
/// <param name="funcs">The url functions.</param>
|
||||
public RequestMessageUrlMatcher(params Func<string, bool>[] funcs)
|
||||
{
|
||||
Funcs = Guard.NotNull(funcs);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public double GetMatchingScore(IRequestMessage requestMessage, IRequestMatchResult requestMatchResult)
|
||||
{
|
||||
double score = IsMatch(requestMessage);
|
||||
return requestMatchResult.AddScore(GetType(), score);
|
||||
}
|
||||
|
||||
private double IsMatch(IRequestMessage requestMessage)
|
||||
{
|
||||
if (Matchers != null)
|
||||
{
|
||||
var results = Matchers.Select(m => m.IsMatch(requestMessage.Url)).ToArray();
|
||||
return MatchScores.ToScore(results, MatchOperator);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RequestMessageUrlMatcher"/> class.
|
||||
/// </summary>
|
||||
/// <param name="matchers">The matchers.</param>
|
||||
public RequestMessageUrlMatcher([NotNull] params IStringMatcher[] matchers)
|
||||
if (Funcs != null)
|
||||
{
|
||||
Guard.NotNull(matchers, nameof(matchers));
|
||||
Matchers = matchers;
|
||||
var results = Funcs.Select(func => func(requestMessage.Url)).ToArray();
|
||||
return MatchScores.ToScore(results, MatchOperator);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RequestMessageUrlMatcher"/> class.
|
||||
/// </summary>
|
||||
/// <param name="funcs">The url functions.</param>
|
||||
public RequestMessageUrlMatcher([NotNull] params Func<string, bool>[] funcs)
|
||||
{
|
||||
Guard.NotNull(funcs, nameof(funcs));
|
||||
Funcs = funcs;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public double GetMatchingScore(IRequestMessage requestMessage, IRequestMatchResult requestMatchResult)
|
||||
{
|
||||
double score = IsMatch(requestMessage);
|
||||
return requestMatchResult.AddScore(GetType(), score);
|
||||
}
|
||||
|
||||
private double IsMatch(IRequestMessage requestMessage)
|
||||
{
|
||||
if (Matchers != null)
|
||||
{
|
||||
return Matchers.Max(matcher => matcher.IsMatch(requestMessage.Url));
|
||||
}
|
||||
|
||||
if (Funcs != null)
|
||||
{
|
||||
return MatchScores.ToScore(requestMessage.Url != null && Funcs.Any(func => func(requestMessage.Url)));
|
||||
}
|
||||
|
||||
return MatchScores.Mismatch;
|
||||
}
|
||||
return MatchScores.Mismatch;
|
||||
}
|
||||
}
|
||||
@@ -1,143 +1,149 @@
|
||||
using System.Linq;
|
||||
using AnyOfTypes;
|
||||
using JetBrains.Annotations;
|
||||
using SimMetrics.Net;
|
||||
using SimMetrics.Net.API;
|
||||
using SimMetrics.Net.Metric;
|
||||
using Stef.Validation;
|
||||
using WireMock.Extensions;
|
||||
using WireMock.Models;
|
||||
using Stef.Validation;
|
||||
|
||||
namespace WireMock.Matchers
|
||||
namespace WireMock.Matchers;
|
||||
|
||||
/// <summary>
|
||||
/// SimMetricsMatcher
|
||||
/// </summary>
|
||||
/// <seealso cref="IStringMatcher" />
|
||||
public class SimMetricsMatcher : IStringMatcher
|
||||
{
|
||||
private readonly AnyOf<string, StringPattern>[] _patterns;
|
||||
private readonly SimMetricType _simMetricType;
|
||||
|
||||
/// <inheritdoc cref="IMatcher.MatchBehaviour"/>
|
||||
public MatchBehaviour MatchBehaviour { get; }
|
||||
|
||||
/// <inheritdoc cref="IMatcher.ThrowException"/>
|
||||
public bool ThrowException { get; }
|
||||
|
||||
/// <summary>
|
||||
/// SimMetricsMatcher
|
||||
/// Initializes a new instance of the <see cref="SimMetricsMatcher"/> class.
|
||||
/// </summary>
|
||||
/// <seealso cref="IStringMatcher" />
|
||||
public class SimMetricsMatcher : IStringMatcher
|
||||
/// <param name="pattern">The pattern.</param>
|
||||
/// <param name="simMetricType">The SimMetric Type</param>
|
||||
public SimMetricsMatcher(AnyOf<string, StringPattern> pattern, SimMetricType simMetricType = SimMetricType.Levenstein) : this(new[] { pattern }, simMetricType)
|
||||
{
|
||||
private readonly AnyOf<string, StringPattern>[] _patterns;
|
||||
private readonly SimMetricType _simMetricType;
|
||||
|
||||
/// <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="SimMetricsMatcher"/> class.
|
||||
/// </summary>
|
||||
/// <param name="pattern">The pattern.</param>
|
||||
/// <param name="simMetricType">The SimMetric Type</param>
|
||||
public SimMetricsMatcher([NotNull] AnyOf<string, StringPattern> pattern, SimMetricType simMetricType = SimMetricType.Levenstein) : this(new[] { pattern }, simMetricType)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="SimMetricsMatcher"/> class.
|
||||
/// </summary>
|
||||
/// <param name="matchBehaviour">The match behaviour.</param>
|
||||
/// <param name="pattern">The pattern.</param>
|
||||
/// <param name="simMetricType">The SimMetric Type</param>
|
||||
public SimMetricsMatcher(MatchBehaviour matchBehaviour, [NotNull] AnyOf<string, StringPattern> pattern, SimMetricType simMetricType = SimMetricType.Levenstein) : this(matchBehaviour, new[] { pattern }, simMetricType)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="SimMetricsMatcher"/> class.
|
||||
/// </summary>
|
||||
/// <param name="patterns">The patterns.</param>
|
||||
/// <param name="simMetricType">The SimMetric Type</param>
|
||||
public SimMetricsMatcher([NotNull] string[] patterns, SimMetricType simMetricType = SimMetricType.Levenstein) : this(MatchBehaviour.AcceptOnMatch, patterns.ToAnyOfPatterns(), simMetricType)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="SimMetricsMatcher"/> class.
|
||||
/// </summary>
|
||||
/// <param name="patterns">The patterns.</param>
|
||||
/// <param name="simMetricType">The SimMetric Type</param>
|
||||
public SimMetricsMatcher([NotNull] AnyOf<string, StringPattern>[] patterns, SimMetricType simMetricType = SimMetricType.Levenstein) : this(MatchBehaviour.AcceptOnMatch, patterns, simMetricType)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="SimMetricsMatcher"/> class.
|
||||
/// </summary>
|
||||
/// <param name="matchBehaviour">The match behaviour.</param>
|
||||
/// <param name="patterns">The patterns.</param>
|
||||
/// <param name="simMetricType">The SimMetric Type</param>
|
||||
/// <param name="throwException">Throw an exception when the internal matching fails because of invalid input.</param>
|
||||
public SimMetricsMatcher(MatchBehaviour matchBehaviour, [NotNull] AnyOf<string, StringPattern>[] patterns, SimMetricType simMetricType = SimMetricType.Levenstein, bool throwException = false)
|
||||
{
|
||||
Guard.NotNull(patterns, nameof(patterns));
|
||||
|
||||
MatchBehaviour = matchBehaviour;
|
||||
ThrowException = throwException;
|
||||
|
||||
_patterns = patterns;
|
||||
_simMetricType = simMetricType;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IStringMatcher.IsMatch"/>
|
||||
public double IsMatch(string input)
|
||||
{
|
||||
IStringMetric stringMetricType = GetStringMetricType();
|
||||
|
||||
return MatchBehaviourHelper.Convert(MatchBehaviour, MatchScores.ToScore(_patterns.Select(p => stringMetricType.GetSimilarity(p.GetPattern(), input))));
|
||||
}
|
||||
|
||||
private IStringMetric GetStringMetricType()
|
||||
{
|
||||
switch (_simMetricType)
|
||||
{
|
||||
case SimMetricType.BlockDistance:
|
||||
return new BlockDistance();
|
||||
case SimMetricType.ChapmanLengthDeviation:
|
||||
return new ChapmanLengthDeviation();
|
||||
case SimMetricType.CosineSimilarity:
|
||||
return new CosineSimilarity();
|
||||
case SimMetricType.DiceSimilarity:
|
||||
return new DiceSimilarity();
|
||||
case SimMetricType.EuclideanDistance:
|
||||
return new EuclideanDistance();
|
||||
case SimMetricType.JaccardSimilarity:
|
||||
return new JaccardSimilarity();
|
||||
case SimMetricType.Jaro:
|
||||
return new Jaro();
|
||||
case SimMetricType.JaroWinkler:
|
||||
return new JaroWinkler();
|
||||
case SimMetricType.MatchingCoefficient:
|
||||
return new MatchingCoefficient();
|
||||
case SimMetricType.MongeElkan:
|
||||
return new MongeElkan();
|
||||
case SimMetricType.NeedlemanWunch:
|
||||
return new NeedlemanWunch();
|
||||
case SimMetricType.OverlapCoefficient:
|
||||
return new OverlapCoefficient();
|
||||
case SimMetricType.QGramsDistance:
|
||||
return new QGramsDistance();
|
||||
case SimMetricType.SmithWaterman:
|
||||
return new SmithWaterman();
|
||||
case SimMetricType.SmithWatermanGotoh:
|
||||
return new SmithWatermanGotoh();
|
||||
case SimMetricType.SmithWatermanGotohWindowedAffine:
|
||||
return new SmithWatermanGotohWindowedAffine();
|
||||
case SimMetricType.ChapmanMeanLength:
|
||||
return new ChapmanMeanLength();
|
||||
default:
|
||||
return new Levenstein();
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IStringMatcher.GetPatterns"/>
|
||||
public AnyOf<string, StringPattern>[] GetPatterns()
|
||||
{
|
||||
return _patterns;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IMatcher.Name"/>
|
||||
public string Name => $"SimMetricsMatcher.{_simMetricType}";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="SimMetricsMatcher"/> class.
|
||||
/// </summary>
|
||||
/// <param name="matchBehaviour">The match behaviour.</param>
|
||||
/// <param name="pattern">The pattern.</param>
|
||||
/// <param name="simMetricType">The SimMetric Type</param>
|
||||
public SimMetricsMatcher(MatchBehaviour matchBehaviour, AnyOf<string, StringPattern> pattern, SimMetricType simMetricType = SimMetricType.Levenstein) : this(matchBehaviour, new[] { pattern }, simMetricType)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="SimMetricsMatcher"/> class.
|
||||
/// </summary>
|
||||
/// <param name="patterns">The patterns.</param>
|
||||
/// <param name="simMetricType">The SimMetric Type</param>
|
||||
public SimMetricsMatcher(string[] patterns, SimMetricType simMetricType = SimMetricType.Levenstein) : this(MatchBehaviour.AcceptOnMatch, patterns.ToAnyOfPatterns(), simMetricType)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="SimMetricsMatcher"/> class.
|
||||
/// </summary>
|
||||
/// <param name="patterns">The patterns.</param>
|
||||
/// <param name="simMetricType">The SimMetric Type</param>
|
||||
public SimMetricsMatcher(AnyOf<string, StringPattern>[] patterns, SimMetricType simMetricType = SimMetricType.Levenstein) : this(MatchBehaviour.AcceptOnMatch, patterns, simMetricType)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="SimMetricsMatcher"/> class.
|
||||
/// </summary>
|
||||
/// <param name="matchBehaviour">The match behaviour.</param>
|
||||
/// <param name="patterns">The patterns.</param>
|
||||
/// <param name="simMetricType">The SimMetric Type</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>
|
||||
public SimMetricsMatcher(
|
||||
MatchBehaviour matchBehaviour,
|
||||
AnyOf<string, StringPattern>[] patterns,
|
||||
SimMetricType simMetricType = SimMetricType.Levenstein,
|
||||
bool throwException = false,
|
||||
MatchOperator matchOperator = MatchOperator.Average)
|
||||
{
|
||||
_patterns = Guard.NotNull(patterns);
|
||||
_simMetricType = simMetricType;
|
||||
MatchBehaviour = matchBehaviour;
|
||||
ThrowException = throwException;
|
||||
MatchOperator = matchOperator;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IStringMatcher.IsMatch"/>
|
||||
public double IsMatch(string input)
|
||||
{
|
||||
IStringMetric stringMetricType = GetStringMetricType();
|
||||
|
||||
var score = MatchScores.ToScore(_patterns.Select(p => stringMetricType.GetSimilarity(p.GetPattern(), input)).ToArray(), MatchOperator);
|
||||
return MatchBehaviourHelper.Convert(MatchBehaviour, score);
|
||||
}
|
||||
|
||||
private IStringMetric GetStringMetricType()
|
||||
{
|
||||
switch (_simMetricType)
|
||||
{
|
||||
case SimMetricType.BlockDistance:
|
||||
return new BlockDistance();
|
||||
case SimMetricType.ChapmanLengthDeviation:
|
||||
return new ChapmanLengthDeviation();
|
||||
case SimMetricType.CosineSimilarity:
|
||||
return new CosineSimilarity();
|
||||
case SimMetricType.DiceSimilarity:
|
||||
return new DiceSimilarity();
|
||||
case SimMetricType.EuclideanDistance:
|
||||
return new EuclideanDistance();
|
||||
case SimMetricType.JaccardSimilarity:
|
||||
return new JaccardSimilarity();
|
||||
case SimMetricType.Jaro:
|
||||
return new Jaro();
|
||||
case SimMetricType.JaroWinkler:
|
||||
return new JaroWinkler();
|
||||
case SimMetricType.MatchingCoefficient:
|
||||
return new MatchingCoefficient();
|
||||
case SimMetricType.MongeElkan:
|
||||
return new MongeElkan();
|
||||
case SimMetricType.NeedlemanWunch:
|
||||
return new NeedlemanWunch();
|
||||
case SimMetricType.OverlapCoefficient:
|
||||
return new OverlapCoefficient();
|
||||
case SimMetricType.QGramsDistance:
|
||||
return new QGramsDistance();
|
||||
case SimMetricType.SmithWaterman:
|
||||
return new SmithWaterman();
|
||||
case SimMetricType.SmithWatermanGotoh:
|
||||
return new SmithWatermanGotoh();
|
||||
case SimMetricType.SmithWatermanGotohWindowedAffine:
|
||||
return new SmithWatermanGotohWindowedAffine();
|
||||
case SimMetricType.ChapmanMeanLength:
|
||||
return new ChapmanMeanLength();
|
||||
default:
|
||||
return new Levenstein();
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IStringMatcher.GetPatterns"/>
|
||||
public AnyOf<string, StringPattern>[] GetPatterns()
|
||||
{
|
||||
return _patterns;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public MatchOperator MatchOperator { get; } = MatchOperator.Average;
|
||||
|
||||
/// <inheritdoc cref="IMatcher.Name"/>
|
||||
public string Name => $"SimMetricsMatcher.{_simMetricType}";
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
using AnyOfTypes;
|
||||
using JetBrains.Annotations;
|
||||
using Stef.Validation;
|
||||
using WireMock.Extensions;
|
||||
using WireMock.Models;
|
||||
|
||||
@@ -20,7 +20,7 @@ public class WildcardMatcher : RegexMatcher
|
||||
/// </summary>
|
||||
/// <param name="pattern">The pattern.</param>
|
||||
/// <param name="ignoreCase">IgnoreCase</param>
|
||||
public WildcardMatcher([NotNull] AnyOf<string, StringPattern> pattern, bool ignoreCase = false) : this(new[] { pattern }, ignoreCase)
|
||||
public WildcardMatcher(AnyOf<string, StringPattern> pattern, bool ignoreCase = false) : this(new[] { pattern }, ignoreCase)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@ public class WildcardMatcher : RegexMatcher
|
||||
/// <param name="matchBehaviour">The match behaviour.</param>
|
||||
/// <param name="pattern">The pattern.</param>
|
||||
/// <param name="ignoreCase">IgnoreCase</param>
|
||||
public WildcardMatcher(MatchBehaviour matchBehaviour, [NotNull] AnyOf<string, StringPattern> pattern, bool ignoreCase = false) : this(matchBehaviour, new[] { pattern }, ignoreCase)
|
||||
public WildcardMatcher(MatchBehaviour matchBehaviour, AnyOf<string, StringPattern> pattern, bool ignoreCase = false) : this(matchBehaviour, new[] { pattern }, ignoreCase)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -39,7 +39,7 @@ public class WildcardMatcher : RegexMatcher
|
||||
/// </summary>
|
||||
/// <param name="patterns">The patterns.</param>
|
||||
/// <param name="ignoreCase">IgnoreCase</param>
|
||||
public WildcardMatcher([NotNull] AnyOf<string, StringPattern>[] patterns, bool ignoreCase = false) : this(MatchBehaviour.AcceptOnMatch, patterns, ignoreCase)
|
||||
public WildcardMatcher(AnyOf<string, StringPattern>[] patterns, bool ignoreCase = false) : this(MatchBehaviour.AcceptOnMatch, patterns, ignoreCase)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -50,10 +50,16 @@ public class WildcardMatcher : RegexMatcher
|
||||
/// <param name="patterns">The patterns.</param>
|
||||
/// <param name="ignoreCase">IgnoreCase</param>
|
||||
/// <param name="throwException">Throw an exception when the internal matching fails because of invalid input.</param>
|
||||
public WildcardMatcher(MatchBehaviour matchBehaviour, [NotNull] AnyOf<string, StringPattern>[] patterns, bool ignoreCase = false, bool throwException = false) :
|
||||
base(matchBehaviour, CreateArray(patterns), ignoreCase, throwException)
|
||||
/// <param name="matchOperator">The <see cref="MatchOperator"/> to use. (default = "Or")</param>
|
||||
public WildcardMatcher(
|
||||
MatchBehaviour matchBehaviour,
|
||||
AnyOf<string, StringPattern>[] patterns,
|
||||
bool ignoreCase = false,
|
||||
bool throwException = false,
|
||||
MatchOperator matchOperator = MatchOperator.Or) :
|
||||
base(matchBehaviour, CreateArray(patterns), ignoreCase, throwException, true, matchOperator)
|
||||
{
|
||||
_patterns = patterns;
|
||||
_patterns = Guard.NotNull(patterns);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
@@ -67,7 +73,8 @@ public class WildcardMatcher : RegexMatcher
|
||||
|
||||
private static AnyOf<string, StringPattern>[] CreateArray(AnyOf<string, StringPattern>[] patterns)
|
||||
{
|
||||
return patterns.Select(pattern => new AnyOf<string, StringPattern>(
|
||||
return patterns
|
||||
.Select(pattern => new AnyOf<string, StringPattern>(
|
||||
new StringPattern
|
||||
{
|
||||
Pattern = "^" + Regex.Escape(pattern.GetPattern()).Replace(@"\*", ".*").Replace(@"\?", ".") + "$",
|
||||
|
||||
@@ -2,7 +2,6 @@ using System;
|
||||
using System.Linq;
|
||||
using System.Xml;
|
||||
using AnyOfTypes;
|
||||
using JetBrains.Annotations;
|
||||
using WireMock.Extensions;
|
||||
using WireMock.Models;
|
||||
using Stef.Validation;
|
||||
@@ -30,7 +29,7 @@ namespace WireMock.Matchers
|
||||
/// Initializes a new instance of the <see cref="XPathMatcher"/> class.
|
||||
/// </summary>
|
||||
/// <param name="patterns">The patterns.</param>
|
||||
public XPathMatcher([NotNull] params AnyOf<string, StringPattern>[] patterns) : this(MatchBehaviour.AcceptOnMatch, false, patterns)
|
||||
public XPathMatcher(params AnyOf<string, StringPattern>[] patterns) : this(MatchBehaviour.AcceptOnMatch, false, MatchOperator.Or, patterns)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -39,18 +38,22 @@ namespace WireMock.Matchers
|
||||
/// </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 XPathMatcher(MatchBehaviour matchBehaviour, bool throwException = false, [NotNull] params AnyOf<string, StringPattern>[] patterns)
|
||||
public XPathMatcher(
|
||||
MatchBehaviour matchBehaviour,
|
||||
bool throwException = false,
|
||||
MatchOperator matchOperator = MatchOperator.Or,
|
||||
params AnyOf<string, StringPattern>[] patterns)
|
||||
{
|
||||
Guard.NotNull(patterns, nameof(patterns));
|
||||
|
||||
_patterns = Guard.NotNull(patterns);
|
||||
MatchBehaviour = matchBehaviour;
|
||||
ThrowException = throwException;
|
||||
_patterns = patterns;
|
||||
MatchOperator = matchOperator;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IStringMatcher.IsMatch"/>
|
||||
public double IsMatch(string input)
|
||||
public double IsMatch(string? input)
|
||||
{
|
||||
double match = MatchScores.Mismatch;
|
||||
if (input != null)
|
||||
@@ -59,9 +62,9 @@ namespace WireMock.Matchers
|
||||
{
|
||||
var nav = new XmlDocument { InnerXml = input }.CreateNavigator();
|
||||
#if NETSTANDARD1_3
|
||||
match = MatchScores.ToScore(_patterns.Select(p => true.Equals(nav.Evaluate($"boolean({p.GetPattern()})"))));
|
||||
match = MatchScores.ToScore(_patterns.Select(p => true.Equals(nav.Evaluate($"boolean({p.GetPattern()})"))).ToArray(), MatchOperator);
|
||||
#else
|
||||
match = MatchScores.ToScore(_patterns.Select(p => true.Equals(nav.XPath2Evaluate($"boolean({p.GetPattern()})"))));
|
||||
match = MatchScores.ToScore(_patterns.Select(p => true.Equals(nav.XPath2Evaluate($"boolean({p.GetPattern()})"))).ToArray(), MatchOperator);
|
||||
#endif
|
||||
}
|
||||
catch (Exception)
|
||||
@@ -82,6 +85,9 @@ namespace WireMock.Matchers
|
||||
return _patterns;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public MatchOperator MatchOperator { get; }
|
||||
|
||||
/// <inheritdoc cref="IMatcher.Name"/>
|
||||
public string Name => "XPathMatcher";
|
||||
}
|
||||
|
||||
@@ -1,18 +1,17 @@
|
||||
namespace WireMock.Models
|
||||
namespace WireMock.Models;
|
||||
|
||||
/// <summary>
|
||||
/// StringPattern which defines the Pattern as a string, and optionally the filepath pattern file.
|
||||
/// </summary>
|
||||
public struct StringPattern
|
||||
{
|
||||
/// <summary>
|
||||
/// StringPattern which defines the Pattern as a string, and optionally the filepath pattern file.
|
||||
/// The pattern as string.
|
||||
/// </summary>
|
||||
public struct StringPattern
|
||||
{
|
||||
/// <summary>
|
||||
/// The pattern as string.
|
||||
/// </summary>
|
||||
public string Pattern { get; set; }
|
||||
public string Pattern { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The filepath (optionally)
|
||||
/// </summary>
|
||||
public string PatternAsFile { get; set; }
|
||||
}
|
||||
/// <summary>
|
||||
/// The filepath (optionally)
|
||||
/// </summary>
|
||||
public string? PatternAsFile { get; set; }
|
||||
}
|
||||
@@ -16,10 +16,10 @@ namespace WireMock.Models
|
||||
public string Method { get; set; }
|
||||
|
||||
/// <inheritdoc cref="IWebhookRequest.Headers"/>
|
||||
public IDictionary<string, WireMockList<string>> Headers { get; set; }
|
||||
public IDictionary<string, WireMockList<string>>? Headers { get; set; }
|
||||
|
||||
/// <inheritdoc cref="IWebhookRequest.BodyData"/>
|
||||
public IBodyData BodyData { get; set; }
|
||||
public IBodyData? BodyData { get; set; }
|
||||
|
||||
/// <inheritdoc cref="IWebhookRequest.UseTransformer"/>
|
||||
public bool? UseTransformer { get; set; }
|
||||
|
||||
@@ -27,8 +27,8 @@ namespace WireMock.Owin.Mappers
|
||||
|
||||
string method = request.Method;
|
||||
|
||||
Dictionary<string, string[]> headers = null;
|
||||
IEnumerable<string> contentEncodingHeader = null;
|
||||
Dictionary<string, string[]>? headers = null;
|
||||
IEnumerable<string>? contentEncodingHeader = null;
|
||||
if (request.Headers.Any())
|
||||
{
|
||||
headers = new Dictionary<string, string[]>();
|
||||
@@ -43,7 +43,7 @@ namespace WireMock.Owin.Mappers
|
||||
}
|
||||
}
|
||||
|
||||
IDictionary<string, string> cookies = null;
|
||||
IDictionary<string, string>? cookies = null;
|
||||
if (request.Cookies.Any())
|
||||
{
|
||||
cookies = new Dictionary<string, string>();
|
||||
@@ -53,7 +53,7 @@ namespace WireMock.Owin.Mappers
|
||||
}
|
||||
}
|
||||
|
||||
IBodyData body = null;
|
||||
IBodyData? body = null;
|
||||
if (request.Body != null && BodyParser.ShouldParseBody(method, options.AllowBodyForAllHttpMethods == true))
|
||||
{
|
||||
var bodyParserSettings = new BodyParserSettings
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
namespace WireMock.Pact.Models.V2
|
||||
namespace WireMock.Pact.Models.V2;
|
||||
|
||||
public class Interaction
|
||||
{
|
||||
public class Interaction
|
||||
{
|
||||
public string Description { get; set; } = string.Empty;
|
||||
public string Description { get; set; } = string.Empty;
|
||||
|
||||
public string ProviderState { get; set; }
|
||||
public string ProviderState { get; set; }
|
||||
|
||||
public Request Request { get; set; } = new Request();
|
||||
public PactRequest Request { get; set; } = new PactRequest();
|
||||
|
||||
public Response Response { get; set; } = new Response();
|
||||
}
|
||||
public PactResponse Response { get; set; } = new PactResponse();
|
||||
}
|
||||
@@ -2,7 +2,7 @@ using System.Collections.Generic;
|
||||
|
||||
namespace WireMock.Pact.Models.V2;
|
||||
|
||||
public class Request
|
||||
public class PactRequest
|
||||
{
|
||||
public IDictionary<string, string>? Headers { get; set; }
|
||||
|
||||
@@ -2,7 +2,7 @@ using System.Collections.Generic;
|
||||
|
||||
namespace WireMock.Pact.Models.V2;
|
||||
|
||||
public class Response
|
||||
public class PactResponse
|
||||
{
|
||||
public object? Body { get; set; }
|
||||
|
||||
@@ -3,7 +3,7 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
using JetBrains.Annotations;
|
||||
using Stef.Validation;
|
||||
using WireMock.Http;
|
||||
using WireMock.Matchers;
|
||||
using WireMock.RequestBuilders;
|
||||
@@ -11,100 +11,98 @@ using WireMock.ResponseBuilders;
|
||||
using WireMock.Settings;
|
||||
using WireMock.Types;
|
||||
using WireMock.Util;
|
||||
using Stef.Validation;
|
||||
|
||||
namespace WireMock.Proxy
|
||||
namespace WireMock.Proxy;
|
||||
|
||||
internal class ProxyHelper
|
||||
{
|
||||
internal class ProxyHelper
|
||||
private readonly WireMockServerSettings _settings;
|
||||
|
||||
public ProxyHelper(WireMockServerSettings settings)
|
||||
{
|
||||
private readonly WireMockServerSettings _settings;
|
||||
_settings = Guard.NotNull(settings);
|
||||
}
|
||||
|
||||
public ProxyHelper([NotNull] WireMockServerSettings settings)
|
||||
public async Task<(IResponseMessage Message, IMapping? Mapping)> SendAsync(
|
||||
ProxyAndRecordSettings proxyAndRecordSettings,
|
||||
HttpClient client,
|
||||
IRequestMessage requestMessage,
|
||||
string url)
|
||||
{
|
||||
Guard.NotNull(client, nameof(client));
|
||||
Guard.NotNull(requestMessage, nameof(requestMessage));
|
||||
Guard.NotNull(url, nameof(url));
|
||||
|
||||
var originalUri = new Uri(requestMessage.Url);
|
||||
var requiredUri = new Uri(url);
|
||||
|
||||
// Create HttpRequestMessage
|
||||
var httpRequestMessage = HttpRequestMessageHelper.Create(requestMessage, url);
|
||||
|
||||
// Call the URL
|
||||
var httpResponseMessage = await client.SendAsync(httpRequestMessage, HttpCompletionOption.ResponseContentRead).ConfigureAwait(false);
|
||||
|
||||
// Create ResponseMessage
|
||||
bool deserializeJson = !_settings.DisableJsonBodyParsing.GetValueOrDefault(false);
|
||||
bool decompressGzipAndDeflate = !_settings.DisableRequestBodyDecompressing.GetValueOrDefault(false);
|
||||
|
||||
var responseMessage = await HttpResponseMessageHelper.CreateAsync(httpResponseMessage, requiredUri, originalUri, deserializeJson, decompressGzipAndDeflate).ConfigureAwait(false);
|
||||
|
||||
IMapping? mapping = null;
|
||||
if (HttpStatusRangeParser.IsMatch(proxyAndRecordSettings.SaveMappingForStatusCodePattern, responseMessage.StatusCode) &&
|
||||
(proxyAndRecordSettings.SaveMapping || proxyAndRecordSettings.SaveMappingToFile))
|
||||
{
|
||||
_settings = Guard.NotNull(settings, nameof(settings));
|
||||
mapping = ToMapping(proxyAndRecordSettings, requestMessage, responseMessage);
|
||||
}
|
||||
|
||||
public async Task<(IResponseMessage Message, IMapping Mapping)> SendAsync(
|
||||
[NotNull] ProxyAndRecordSettings proxyAndRecordSettings,
|
||||
[NotNull] HttpClient client,
|
||||
[NotNull] IRequestMessage requestMessage,
|
||||
[NotNull] string url)
|
||||
return (responseMessage, mapping);
|
||||
}
|
||||
|
||||
private IMapping ToMapping(ProxyAndRecordSettings proxyAndRecordSettings, IRequestMessage requestMessage, ResponseMessage responseMessage)
|
||||
{
|
||||
var excludedHeaders = proxyAndRecordSettings.ExcludedHeaders ?? new string[] { };
|
||||
var excludedCookies = proxyAndRecordSettings.ExcludedCookies ?? new string[] { };
|
||||
|
||||
var request = Request.Create();
|
||||
request.WithPath(requestMessage.Path);
|
||||
request.UsingMethod(requestMessage.Method);
|
||||
|
||||
requestMessage.Query?.Loop((key, value) => request.WithParam(key, false, value.ToArray()));
|
||||
requestMessage.Cookies?.Loop((key, value) =>
|
||||
{
|
||||
Guard.NotNull(client, nameof(client));
|
||||
Guard.NotNull(requestMessage, nameof(requestMessage));
|
||||
Guard.NotNull(url, nameof(url));
|
||||
|
||||
var originalUri = new Uri(requestMessage.Url);
|
||||
var requiredUri = new Uri(url);
|
||||
|
||||
// Create HttpRequestMessage
|
||||
var httpRequestMessage = HttpRequestMessageHelper.Create(requestMessage, url);
|
||||
|
||||
// Call the URL
|
||||
var httpResponseMessage = await client.SendAsync(httpRequestMessage, HttpCompletionOption.ResponseContentRead).ConfigureAwait(false);
|
||||
|
||||
// Create ResponseMessage
|
||||
bool deserializeJson = !_settings.DisableJsonBodyParsing.GetValueOrDefault(false);
|
||||
bool decompressGzipAndDeflate = !_settings.DisableRequestBodyDecompressing.GetValueOrDefault(false);
|
||||
|
||||
var responseMessage = await HttpResponseMessageHelper.CreateAsync(httpResponseMessage, requiredUri, originalUri, deserializeJson, decompressGzipAndDeflate).ConfigureAwait(false);
|
||||
|
||||
IMapping mapping = null;
|
||||
if (HttpStatusRangeParser.IsMatch(proxyAndRecordSettings.SaveMappingForStatusCodePattern, responseMessage.StatusCode) &&
|
||||
(proxyAndRecordSettings.SaveMapping || proxyAndRecordSettings.SaveMappingToFile))
|
||||
if (!excludedCookies.Contains(key, StringComparer.OrdinalIgnoreCase))
|
||||
{
|
||||
mapping = ToMapping(proxyAndRecordSettings, requestMessage, responseMessage);
|
||||
request.WithCookie(key, value);
|
||||
}
|
||||
});
|
||||
|
||||
return (responseMessage, mapping);
|
||||
}
|
||||
|
||||
private IMapping ToMapping(ProxyAndRecordSettings proxyAndRecordSettings, IRequestMessage requestMessage, ResponseMessage responseMessage)
|
||||
var allExcludedHeaders = new List<string>(excludedHeaders) { "Cookie" };
|
||||
requestMessage.Headers?.Loop((key, value) =>
|
||||
{
|
||||
string[] excludedHeaders = proxyAndRecordSettings.ExcludedHeaders ?? new string[] { };
|
||||
string[] excludedCookies = proxyAndRecordSettings.ExcludedCookies ?? new string[] { };
|
||||
|
||||
var request = Request.Create();
|
||||
request.WithPath(requestMessage.Path);
|
||||
request.UsingMethod(requestMessage.Method);
|
||||
|
||||
requestMessage.Query.Loop((key, value) => request.WithParam(key, false, value.ToArray()));
|
||||
requestMessage.Cookies.Loop((key, value) =>
|
||||
if (!allExcludedHeaders.Contains(key, StringComparer.OrdinalIgnoreCase))
|
||||
{
|
||||
if (!excludedCookies.Contains(key, StringComparer.OrdinalIgnoreCase))
|
||||
{
|
||||
request.WithCookie(key, value);
|
||||
}
|
||||
});
|
||||
|
||||
var allExcludedHeaders = new List<string>(excludedHeaders) { "Cookie" };
|
||||
requestMessage.Headers.Loop((key, value) =>
|
||||
{
|
||||
if (!allExcludedHeaders.Contains(key, StringComparer.OrdinalIgnoreCase))
|
||||
{
|
||||
request.WithHeader(key, value.ToArray());
|
||||
}
|
||||
});
|
||||
|
||||
bool throwExceptionWhenMatcherFails = _settings.ThrowExceptionWhenMatcherFails == true;
|
||||
switch (requestMessage.BodyData?.DetectedBodyType)
|
||||
{
|
||||
case BodyType.Json:
|
||||
request.WithBody(new JsonMatcher(MatchBehaviour.AcceptOnMatch, requestMessage.BodyData.BodyAsJson, true, throwExceptionWhenMatcherFails));
|
||||
break;
|
||||
|
||||
case BodyType.String:
|
||||
request.WithBody(new ExactMatcher(MatchBehaviour.AcceptOnMatch, throwExceptionWhenMatcherFails, requestMessage.BodyData.BodyAsString));
|
||||
break;
|
||||
|
||||
case BodyType.Bytes:
|
||||
request.WithBody(new ExactObjectMatcher(MatchBehaviour.AcceptOnMatch, requestMessage.BodyData.BodyAsBytes, throwExceptionWhenMatcherFails));
|
||||
break;
|
||||
request.WithHeader(key, value.ToArray());
|
||||
}
|
||||
});
|
||||
|
||||
var response = Response.Create(responseMessage);
|
||||
bool throwExceptionWhenMatcherFails = _settings.ThrowExceptionWhenMatcherFails == true;
|
||||
switch (requestMessage.BodyData?.DetectedBodyType)
|
||||
{
|
||||
case BodyType.Json:
|
||||
request.WithBody(new JsonMatcher(MatchBehaviour.AcceptOnMatch, requestMessage.BodyData.BodyAsJson!, true, throwExceptionWhenMatcherFails));
|
||||
break;
|
||||
|
||||
return new Mapping(Guid.NewGuid(), string.Empty, string.Empty, null, _settings, request, response, 0, null, null, null, null, null, null);
|
||||
case BodyType.String:
|
||||
request.WithBody(new ExactMatcher(MatchBehaviour.AcceptOnMatch, throwExceptionWhenMatcherFails, MatchOperator.Or, requestMessage.BodyData.BodyAsString));
|
||||
break;
|
||||
|
||||
case BodyType.Bytes:
|
||||
request.WithBody(new ExactObjectMatcher(MatchBehaviour.AcceptOnMatch, requestMessage.BodyData.BodyAsBytes, throwExceptionWhenMatcherFails));
|
||||
break;
|
||||
}
|
||||
|
||||
var response = Response.Create(responseMessage);
|
||||
|
||||
return new Mapping(Guid.NewGuid(), string.Empty, string.Empty, null, _settings, request, response, 0, null, null, null, null, null, null);
|
||||
}
|
||||
}
|
||||
@@ -3,88 +3,87 @@ using System.Collections.Generic;
|
||||
using System.Text.RegularExpressions;
|
||||
using Stef.Validation;
|
||||
|
||||
namespace WireMock.RegularExpressions
|
||||
namespace WireMock.RegularExpressions;
|
||||
|
||||
/// <summary>
|
||||
/// Extension to the <see cref="Regex"/> object, adding support for GUID tokens for matching on.
|
||||
/// </summary>
|
||||
#if !NETSTANDARD1_3
|
||||
[Serializable]
|
||||
#endif
|
||||
internal class RegexExtended : Regex
|
||||
{
|
||||
/// <summary>
|
||||
/// Extension to the <see cref="Regex"/> object, adding support for GUID tokens for matching on.
|
||||
/// </summary>
|
||||
#if !NETSTANDARD1_3
|
||||
[Serializable]
|
||||
#endif
|
||||
internal class RegexExtended : Regex
|
||||
/// <inheritdoc cref="Regex"/>
|
||||
public RegexExtended(string pattern) : this(pattern, RegexOptions.None)
|
||||
{
|
||||
/// <inheritdoc cref="Regex"/>
|
||||
public RegexExtended(string pattern) : this(pattern, RegexOptions.None)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="Regex"/>
|
||||
public RegexExtended(string pattern, RegexOptions options) :
|
||||
this(pattern, options, Regex.InfiniteMatchTimeout)
|
||||
{
|
||||
}
|
||||
/// <inheritdoc cref="Regex"/>
|
||||
public RegexExtended(string pattern, RegexOptions options) :
|
||||
this(pattern, options, Regex.InfiniteMatchTimeout)
|
||||
{
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="Regex"/>
|
||||
public RegexExtended(string pattern, RegexOptions options, TimeSpan matchTimeout) :
|
||||
base(ReplaceGuidPattern(pattern), options, matchTimeout)
|
||||
{
|
||||
}
|
||||
/// <inheritdoc cref="Regex"/>
|
||||
public RegexExtended(string pattern, RegexOptions options, TimeSpan matchTimeout) :
|
||||
base(ReplaceGuidPattern(pattern), options, matchTimeout)
|
||||
{
|
||||
}
|
||||
|
||||
#if !NETSTANDARD1_3
|
||||
/// <inheritdoc cref="Regex"/>
|
||||
protected RegexExtended(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) :
|
||||
base(info, context)
|
||||
{
|
||||
}
|
||||
/// <inheritdoc cref="Regex"/>
|
||||
protected RegexExtended(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) :
|
||||
base(info, context)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
// Dictionary of various Guid tokens with a corresponding regular expression pattern to use instead.
|
||||
private static readonly Dictionary<string, string> GuidTokenPatterns = new Dictionary<string, string>
|
||||
// Dictionary of various Guid tokens with a corresponding regular expression pattern to use instead.
|
||||
private static readonly Dictionary<string, string> GuidTokenPatterns = new()
|
||||
{
|
||||
// Lower case format `B` Guid pattern
|
||||
{ @"\guidb", @"(\{[a-z0-9]{8}-([a-z0-9]{4}-){3}[a-z0-9]{12}\})" },
|
||||
|
||||
// Upper case format `B` Guid pattern
|
||||
{ @"\GUIDB", @"(\{[A-Z0-9]{8}-([A-Z0-9]{4}-){3}[A-Z0-9]{12}\})" },
|
||||
|
||||
// Lower case format `D` Guid pattern
|
||||
{ @"\guidd", "([a-z0-9]{8}-([a-z0-9]{4}-){3}[a-z0-9]{12})" },
|
||||
|
||||
// Upper case format `D` Guid pattern
|
||||
{ @"\GUIDD", "([A-Z0-9]{8}-([A-Z0-9]{4}-){3}[A-Z0-9]{12})" },
|
||||
|
||||
// Lower case format `N` Guid pattern
|
||||
{ @"\guidn", "([a-z0-9]{32})" },
|
||||
|
||||
// Upper case format `N` Guid pattern
|
||||
{ @"\GUIDN", "([A-Z0-9]{32})" },
|
||||
|
||||
// Lower case format `P` Guid pattern
|
||||
{ @"\guidp", @"(\([a-z0-9]{8}-([a-z0-9]{4}-){3}[a-z0-9]{12}\))" },
|
||||
|
||||
// Upper case format `P` Guid pattern
|
||||
{ @"\GUIDP", @"(\([A-Z0-9]{8}-([A-Z0-9]{4}-){3}[A-Z0-9]{12}\))" },
|
||||
|
||||
// Lower case format `X` Guid pattern
|
||||
{ @"\guidx", @"(\{0x[a-f0-9]{8},0x[a-f0-9]{4},0x[a-f0-9]{4},\{(0x[a-f0-9]{2},){7}(0x[a-f0-9]{2})\}\})" },
|
||||
|
||||
// Upper case format `X` Guid pattern
|
||||
{ @"\GUIDX", @"(\{0x[A-F0-9]{8},0x[A-F0-9]{4},0x[A-F0-9]{4},\{(0x[A-F0-9]{2},){7}(0x[A-F0-9]{2})\}\})" },
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Replaces all instances of valid GUID tokens with the correct regular expression to match.
|
||||
/// </summary>
|
||||
/// <param name="pattern">Pattern to replace token for.</param>
|
||||
private static string ReplaceGuidPattern(string pattern)
|
||||
{
|
||||
Guard.NotNull(pattern, nameof(pattern));
|
||||
|
||||
foreach (var tokenPattern in GuidTokenPatterns)
|
||||
{
|
||||
// Lower case format `B` Guid pattern
|
||||
{ @"\guidb", @"(\{[a-z0-9]{8}-([a-z0-9]{4}-){3}[a-z0-9]{12}\})" },
|
||||
|
||||
// Upper case format `B` Guid pattern
|
||||
{ @"\GUIDB", @"(\{[A-Z0-9]{8}-([A-Z0-9]{4}-){3}[A-Z0-9]{12}\})" },
|
||||
|
||||
// Lower case format `D` Guid pattern
|
||||
{ @"\guidd", "([a-z0-9]{8}-([a-z0-9]{4}-){3}[a-z0-9]{12})" },
|
||||
|
||||
// Upper case format `D` Guid pattern
|
||||
{ @"\GUIDD", "([A-Z0-9]{8}-([A-Z0-9]{4}-){3}[A-Z0-9]{12})" },
|
||||
|
||||
// Lower case format `N` Guid pattern
|
||||
{ @"\guidn", "([a-z0-9]{32})" },
|
||||
|
||||
// Upper case format `N` Guid pattern
|
||||
{ @"\GUIDN", "([A-Z0-9]{32})" },
|
||||
|
||||
// Lower case format `P` Guid pattern
|
||||
{ @"\guidp", @"(\([a-z0-9]{8}-([a-z0-9]{4}-){3}[a-z0-9]{12}\))" },
|
||||
|
||||
// Upper case format `P` Guid pattern
|
||||
{ @"\GUIDP", @"(\([A-Z0-9]{8}-([A-Z0-9]{4}-){3}[A-Z0-9]{12}\))" },
|
||||
|
||||
// Lower case format `X` Guid pattern
|
||||
{ @"\guidx", @"(\{0x[a-f0-9]{8},0x[a-f0-9]{4},0x[a-f0-9]{4},\{(0x[a-f0-9]{2},){7}(0x[a-f0-9]{2})\}\})" },
|
||||
|
||||
// Upper case format `X` Guid pattern
|
||||
{ @"\GUIDX", @"(\{0x[A-F0-9]{8},0x[A-F0-9]{4},0x[A-F0-9]{4},\{(0x[A-F0-9]{2},){7}(0x[A-F0-9]{2})\}\})" },
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Replaces all instances of valid GUID tokens with the correct regular expression to match.
|
||||
/// </summary>
|
||||
/// <param name="pattern">Pattern to replace token for.</param>
|
||||
private static string ReplaceGuidPattern(string pattern)
|
||||
{
|
||||
Guard.NotNull(pattern, nameof(pattern));
|
||||
|
||||
foreach (var tokenPattern in GuidTokenPatterns)
|
||||
{
|
||||
pattern = pattern.Replace(tokenPattern.Key, tokenPattern.Value);
|
||||
}
|
||||
|
||||
return pattern;
|
||||
pattern = pattern.Replace(tokenPattern.Key, tokenPattern.Value);
|
||||
}
|
||||
|
||||
return pattern;
|
||||
}
|
||||
}
|
||||
@@ -1,80 +1,79 @@
|
||||
using JetBrains.Annotations;
|
||||
using System;
|
||||
using WireMock.Matchers;
|
||||
using WireMock.Matchers.Request;
|
||||
using WireMock.Util;
|
||||
|
||||
namespace WireMock.RequestBuilders
|
||||
namespace WireMock.RequestBuilders;
|
||||
|
||||
/// <summary>
|
||||
/// The BodyRequestBuilder interface.
|
||||
/// </summary>
|
||||
public interface IBodyRequestBuilder : IRequestMatcher
|
||||
{
|
||||
/// <summary>
|
||||
/// The BodyRequestBuilder interface.
|
||||
/// WithBody: IMatcher
|
||||
/// </summary>
|
||||
public interface IBodyRequestBuilder : IRequestMatcher
|
||||
{
|
||||
/// <summary>
|
||||
/// WithBody: IMatcher
|
||||
/// </summary>
|
||||
/// <param name="matcher">The matcher.</param>
|
||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||
IRequestBuilder WithBody([NotNull] IMatcher matcher);
|
||||
/// <param name="matcher">The matcher.</param>
|
||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||
IRequestBuilder WithBody(IMatcher matcher);
|
||||
|
||||
/// <summary>
|
||||
/// WithBody: IMatcher[]
|
||||
/// </summary>
|
||||
/// <param name="matchers">The matchers.</param>
|
||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||
IRequestBuilder WithBody([NotNull] IMatcher[] matchers);
|
||||
/// <summary>
|
||||
/// WithBody: IMatcher[]
|
||||
/// </summary>
|
||||
/// <param name="matchers">The matchers.</param>
|
||||
/// <param name="matchOperator">The <see cref="MatchOperator"/> to use.</param>
|
||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||
IRequestBuilder WithBody(IMatcher[] matchers, MatchOperator matchOperator = MatchOperator.Or);
|
||||
|
||||
/// <summary>
|
||||
/// WithBody: Body as string
|
||||
/// </summary>
|
||||
/// <param name="body">The body.</param>
|
||||
/// <param name="matchBehaviour">The match behaviour.</param>
|
||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||
IRequestBuilder WithBody(string body, MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch);
|
||||
/// <summary>
|
||||
/// WithBody: Body as string
|
||||
/// </summary>
|
||||
/// <param name="body">The body.</param>
|
||||
/// <param name="matchBehaviour">The match behaviour.</param>
|
||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||
IRequestBuilder WithBody(string body, MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch);
|
||||
|
||||
/// <summary>
|
||||
/// WithBody: Body as byte[]
|
||||
/// </summary>
|
||||
/// <param name="body">The body.</param>
|
||||
/// <param name="matchBehaviour">The match behaviour.</param>
|
||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||
IRequestBuilder WithBody(byte[] body, MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch);
|
||||
/// <summary>
|
||||
/// WithBody: Body as byte[]
|
||||
/// </summary>
|
||||
/// <param name="body">The body.</param>
|
||||
/// <param name="matchBehaviour">The match behaviour.</param>
|
||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||
IRequestBuilder WithBody(byte[] body, MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch);
|
||||
|
||||
/// <summary>
|
||||
/// WithBody: Body as object
|
||||
/// </summary>
|
||||
/// <param name="body">The body.</param>
|
||||
/// <param name="matchBehaviour">The match behaviour.</param>
|
||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||
IRequestBuilder WithBody(object body, MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch);
|
||||
/// <summary>
|
||||
/// WithBody: Body as object
|
||||
/// </summary>
|
||||
/// <param name="body">The body.</param>
|
||||
/// <param name="matchBehaviour">The match behaviour.</param>
|
||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||
IRequestBuilder WithBody(object body, MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch);
|
||||
|
||||
/// <summary>
|
||||
/// WithBody: func (string)
|
||||
/// </summary>
|
||||
/// <param name="func">The function.</param>
|
||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||
IRequestBuilder WithBody([NotNull] Func<string, bool> func);
|
||||
/// <summary>
|
||||
/// WithBody: func (string)
|
||||
/// </summary>
|
||||
/// <param name="func">The function.</param>
|
||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||
IRequestBuilder WithBody(Func<string, bool> func);
|
||||
|
||||
/// <summary>
|
||||
/// WithBody: func (byte[])
|
||||
/// </summary>
|
||||
/// <param name="func">The function.</param>
|
||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||
IRequestBuilder WithBody([NotNull] Func<byte[], bool> func);
|
||||
/// <summary>
|
||||
/// WithBody: func (byte[])
|
||||
/// </summary>
|
||||
/// <param name="func">The function.</param>
|
||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||
IRequestBuilder WithBody(Func<byte[], bool> func);
|
||||
|
||||
/// <summary>
|
||||
/// WithBody: func (json object)
|
||||
/// </summary>
|
||||
/// <param name="func">The function.</param>
|
||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||
IRequestBuilder WithBody([NotNull] Func<object, bool> func);
|
||||
/// <summary>
|
||||
/// WithBody: func (json object)
|
||||
/// </summary>
|
||||
/// <param name="func">The function.</param>
|
||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||
IRequestBuilder WithBody(Func<object, bool> func);
|
||||
|
||||
/// <summary>
|
||||
/// WithBody: func (BodyData object)
|
||||
/// </summary>
|
||||
/// <param name="func">The function.</param>
|
||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||
IRequestBuilder WithBody([NotNull] Func<IBodyData, bool> func);
|
||||
}
|
||||
/// <summary>
|
||||
/// WithBody: func (BodyData object)
|
||||
/// </summary>
|
||||
/// <param name="func">The function.</param>
|
||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||
IRequestBuilder WithBody(Func<IBodyData, bool> func);
|
||||
}
|
||||
@@ -1,41 +1,47 @@
|
||||
using System;
|
||||
using JetBrains.Annotations;
|
||||
using System;
|
||||
using WireMock.Matchers;
|
||||
|
||||
namespace WireMock.RequestBuilders
|
||||
namespace WireMock.RequestBuilders;
|
||||
|
||||
/// <summary>
|
||||
/// The IClientIPRequestBuilder interface.
|
||||
/// </summary>
|
||||
public interface IClientIPRequestBuilder : IUrlAndPathRequestBuilder
|
||||
{
|
||||
/// <summary>
|
||||
/// The IClientIPRequestBuilder interface.
|
||||
/// WithClientIP: add clientIP matching based on IStringMatchers.
|
||||
/// </summary>
|
||||
public interface IClientIPRequestBuilder : IUrlAndPathRequestBuilder
|
||||
{
|
||||
/// <summary>
|
||||
/// WithClientIP: add matching on ClientIP matchers.
|
||||
/// </summary>
|
||||
/// <param name="matchers">The matchers.</param>
|
||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||
IRequestBuilder WithClientIP([NotNull] params IStringMatcher[] matchers);
|
||||
/// <param name="matchers">The matchers.</param>
|
||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||
IRequestBuilder WithClientIP(params IStringMatcher[] matchers);
|
||||
|
||||
/// <summary>
|
||||
/// WithClientIP: add matching on clientIPs.
|
||||
/// </summary>
|
||||
/// <param name="clientIPs">The clientIPs.</param>
|
||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||
IRequestBuilder WithClientIP([NotNull] params string[] clientIPs);
|
||||
/// <summary>
|
||||
/// WithClientIP: add clientIP matching based on MatchOperator and IStringMatchers.
|
||||
/// </summary>
|
||||
/// <param name="matchOperator">The <see cref="MatchOperator"/> to use.</param>
|
||||
/// <param name="matchers">The matchers.</param>
|
||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||
IRequestBuilder WithClientIP(MatchOperator matchOperator, params IStringMatcher[] matchers);
|
||||
|
||||
/// <summary>
|
||||
/// WithClientIP: add matching on clientIPs and matchBehaviour.
|
||||
/// </summary>
|
||||
/// <param name="matchBehaviour">The match behaviour.</param>
|
||||
/// <param name="clientIPs">The clientIPs.</param>
|
||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||
IRequestBuilder WithClientIP(MatchBehaviour matchBehaviour, [NotNull] params string[] clientIPs);
|
||||
/// <summary>
|
||||
/// WithClientIP: add clientIP matching based on clientIPs.
|
||||
/// </summary>
|
||||
/// <param name="clientIPs">The clientIPs.</param>
|
||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||
IRequestBuilder WithClientIP(params string[] clientIPs);
|
||||
|
||||
/// <summary>
|
||||
/// WithClientIP: add matching on ClientIP funcs.
|
||||
/// </summary>
|
||||
/// <param name="funcs">The path funcs.</param>
|
||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||
IRequestBuilder WithClientIP([NotNull] params Func<string, bool>[] funcs);
|
||||
}
|
||||
/// <summary>
|
||||
/// WithClientIP: add clientIP matching based on clientIPs , matchBehaviour and MatchOperator.
|
||||
/// </summary>
|
||||
/// <param name="matchOperator">The <see cref="MatchOperator"/> to use.</param>
|
||||
/// <param name="clientIPs">The clientIPs.</param>
|
||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||
IRequestBuilder WithClientIP(MatchOperator matchOperator, params string[] clientIPs);
|
||||
|
||||
/// <summary>
|
||||
/// WithClientIP: add clientIP matching based on functions.
|
||||
/// </summary>
|
||||
/// <param name="funcs">The clientIP funcs.</param>
|
||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||
IRequestBuilder WithClientIP(params Func<string, bool>[] funcs);
|
||||
}
|
||||
@@ -1,85 +1,86 @@
|
||||
using JetBrains.Annotations;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using WireMock.Matchers;
|
||||
|
||||
namespace WireMock.RequestBuilders
|
||||
namespace WireMock.RequestBuilders;
|
||||
|
||||
/// <summary>
|
||||
/// The HeadersRequestBuilder interface.
|
||||
/// </summary>
|
||||
public interface IHeadersRequestBuilder : ICookiesRequestBuilder
|
||||
{
|
||||
/// <summary>
|
||||
/// The HeadersRequestBuilder interface.
|
||||
/// WithHeader: matching based on name, pattern and matchBehaviour.
|
||||
/// </summary>
|
||||
public interface IHeadersRequestBuilder : ICookiesRequestBuilder
|
||||
{
|
||||
/// <summary>
|
||||
/// WithHeader: matching based on name, pattern and matchBehaviour.
|
||||
/// </summary>
|
||||
/// <param name="name">The name.</param>
|
||||
/// <param name="pattern">The pattern.</param>
|
||||
/// <param name="matchBehaviour">The match behaviour.</param>
|
||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||
IRequestBuilder WithHeader([NotNull] string name, string pattern, MatchBehaviour matchBehaviour);
|
||||
/// <param name="name">The name.</param>
|
||||
/// <param name="pattern">The pattern.</param>
|
||||
/// <param name="matchBehaviour">The match behaviour.</param>
|
||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||
IRequestBuilder WithHeader(string name, string pattern, MatchBehaviour matchBehaviour);
|
||||
|
||||
/// <summary>
|
||||
/// WithHeader: matching based on name, pattern, ignoreCase and matchBehaviour.
|
||||
/// </summary>
|
||||
/// <param name="name">The name.</param>
|
||||
/// <param name="pattern">The pattern.</param>
|
||||
/// <param name="ignoreCase">Ignore the case from the pattern.</param>
|
||||
/// <param name="matchBehaviour">The match behaviour.</param>
|
||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||
IRequestBuilder WithHeader([NotNull] string name, string pattern, bool ignoreCase = true, MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch);
|
||||
/// <summary>
|
||||
/// WithHeader: matching based on name, pattern, ignoreCase and matchBehaviour.
|
||||
/// </summary>
|
||||
/// <param name="name">The name.</param>
|
||||
/// <param name="pattern">The pattern.</param>
|
||||
/// <param name="ignoreCase">Ignore the case from the pattern.</param>
|
||||
/// <param name="matchBehaviour">The match behaviour.</param>
|
||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||
IRequestBuilder WithHeader(string name, string pattern, bool ignoreCase = true, MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch);
|
||||
|
||||
/// <summary>
|
||||
/// WithHeader: matching based on name, patterns and matchBehaviour.
|
||||
/// </summary>
|
||||
/// <param name="name">The name.</param>
|
||||
/// <param name="patterns">The patterns.</param>
|
||||
/// <param name="matchBehaviour">The match behaviour.</param>
|
||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||
IRequestBuilder WithHeader([NotNull] string name, string[] patterns, MatchBehaviour matchBehaviour);
|
||||
/// <summary>
|
||||
/// WithHeader: matching based on name, patterns and matchBehaviour.
|
||||
/// </summary>
|
||||
/// <param name="name">The name.</param>
|
||||
/// <param name="patterns">The patterns.</param>
|
||||
/// <param name="matchBehaviour">The match behaviour.</param>
|
||||
/// <param name="matchOperator">The <see cref="MatchOperator"/> to use.</param>
|
||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||
IRequestBuilder WithHeader(string name, string[] patterns, MatchBehaviour matchBehaviour, MatchOperator matchOperator = MatchOperator.Or);
|
||||
|
||||
/// <summary>
|
||||
/// WithHeader: matching based on name, patterns, ignoreCase and matchBehaviour.
|
||||
/// </summary>
|
||||
/// <param name="name">The name.</param>
|
||||
/// <param name="patterns">The patterns.</param>
|
||||
/// <param name="ignoreCase">Ignore the case from the pattern.</param>
|
||||
/// <param name="matchBehaviour">The match behaviour.</param>
|
||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||
IRequestBuilder WithHeader([NotNull] string name, string[] patterns, bool ignoreCase = true, MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch);
|
||||
/// <summary>
|
||||
/// WithHeader: matching based on name, patterns, ignoreCase and matchBehaviour.
|
||||
/// </summary>
|
||||
/// <param name="name">The name.</param>
|
||||
/// <param name="patterns">The patterns.</param>
|
||||
/// <param name="ignoreCase">Ignore the case from the pattern.</param>
|
||||
/// <param name="matchBehaviour">The match behaviour.</param>
|
||||
/// <param name="matchOperator">The <see cref="MatchOperator"/> to use.</param>
|
||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||
IRequestBuilder WithHeader(string name, string[] patterns, bool ignoreCase = true, MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch, MatchOperator matchOperator = MatchOperator.Or);
|
||||
|
||||
/// <summary>
|
||||
/// WithHeader: matching based on name and IStringMatcher[].
|
||||
/// </summary>
|
||||
/// <param name="name">The name.</param>
|
||||
/// <param name="matchers">The matchers.</param>
|
||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||
IRequestBuilder WithHeader([NotNull] string name, [NotNull] params IStringMatcher[] matchers);
|
||||
/// <summary>
|
||||
/// WithHeader: matching based on name and IStringMatcher[].
|
||||
/// </summary>
|
||||
/// <param name="name">The name.</param>
|
||||
/// <param name="matchers">The matchers.</param>
|
||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||
IRequestBuilder WithHeader(string name, params IStringMatcher[] matchers);
|
||||
|
||||
/// <summary>
|
||||
/// WithHeader: matching based on name, ignoreCase and IStringMatcher[].
|
||||
/// </summary>
|
||||
/// <param name="name">The name.</param>
|
||||
/// <param name="ignoreCase">Ignore the case from the header-keys.</param>
|
||||
/// <param name="matchers">The matchers.</param>
|
||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||
IRequestBuilder WithHeader([NotNull] string name, bool ignoreCase, [NotNull] params IStringMatcher[] matchers);
|
||||
/// <summary>
|
||||
/// WithHeader: matching based on name, ignoreCase and IStringMatcher[].
|
||||
/// </summary>
|
||||
/// <param name="name">The name.</param>
|
||||
/// <param name="ignoreCase">Ignore the case from the header-keys.</param>
|
||||
/// <param name="matchers">The matchers.</param>
|
||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||
IRequestBuilder WithHeader(string name, bool ignoreCase, params IStringMatcher[] matchers);
|
||||
|
||||
/// <summary>
|
||||
/// WithHeader: matching based on name, ignoreCase, matchBehaviour and IStringMatcher[].
|
||||
/// </summary>
|
||||
/// <param name="name">The name.</param>
|
||||
/// <param name="ignoreCase">Ignore the case from the header-keys.</param>
|
||||
/// <param name="matchBehaviour">The match behaviour.</param>
|
||||
/// <param name="matchers">The matchers.</param>
|
||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||
IRequestBuilder WithHeader([NotNull] string name, bool ignoreCase, MatchBehaviour matchBehaviour, [NotNull] params IStringMatcher[] matchers);
|
||||
/// <summary>
|
||||
/// WithHeader: matching based on name, ignoreCase, matchBehaviour and IStringMatcher[].
|
||||
/// </summary>
|
||||
/// <param name="name">The name.</param>
|
||||
/// <param name="ignoreCase">Ignore the case from the header-keys.</param>
|
||||
/// <param name="matchBehaviour">The match behaviour.</param>
|
||||
/// <param name="matchOperator">The <see cref="MatchOperator"/> to use.</param>
|
||||
/// <param name="matchers">The matchers.</param>
|
||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||
IRequestBuilder WithHeader(string name, bool ignoreCase, MatchBehaviour matchBehaviour, MatchOperator matchOperator = MatchOperator.Or, params IStringMatcher[] matchers);
|
||||
|
||||
/// <summary>
|
||||
/// WithHeader: matching based on functions.
|
||||
/// </summary>
|
||||
/// <param name="funcs">The headers funcs.</param>
|
||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||
IRequestBuilder WithHeader([NotNull] params Func<IDictionary<string, string[]>, bool>[] funcs);
|
||||
}
|
||||
/// <summary>
|
||||
/// WithHeader: matching based on functions.
|
||||
/// </summary>
|
||||
/// <param name="funcs">The headers funcs.</param>
|
||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||
IRequestBuilder WithHeader(params Func<IDictionary<string, string[]>, bool>[] funcs);
|
||||
}
|
||||
@@ -1,111 +1,96 @@
|
||||
using System;
|
||||
using System;
|
||||
using JetBrains.Annotations;
|
||||
using WireMock.Matchers;
|
||||
|
||||
namespace WireMock.RequestBuilders
|
||||
namespace WireMock.RequestBuilders;
|
||||
|
||||
/// <summary>
|
||||
/// The MethodRequestBuilder interface.
|
||||
/// </summary>
|
||||
public interface IMethodRequestBuilder : IHeadersRequestBuilder
|
||||
{
|
||||
/// <summary>
|
||||
/// The MethodRequestBuilder interface.
|
||||
/// UsingConnect: add HTTP Method matching on `CONNECT` and matchBehaviour (optional).
|
||||
/// </summary>
|
||||
public interface IMethodRequestBuilder : IHeadersRequestBuilder
|
||||
{
|
||||
/// <summary>
|
||||
/// UsingConnect: add HTTP Method matching on `CONNECT` and matchBehaviour (optional).
|
||||
/// </summary>
|
||||
/// <param name="matchBehaviour">The match behaviour.</param>
|
||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||
IRequestBuilder UsingConnect(MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch);
|
||||
/// <param name="matchBehaviour">The match behaviour.</param>
|
||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||
IRequestBuilder UsingConnect(MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch);
|
||||
|
||||
/// <summary>
|
||||
/// UsingDelete: add HTTP Method matching on `DELETE` and matchBehaviour (optional).
|
||||
/// </summary>
|
||||
/// <param name="matchBehaviour">The match behaviour.</param>
|
||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||
IRequestBuilder UsingDelete(MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch);
|
||||
/// <summary>
|
||||
/// UsingDelete: add HTTP Method matching on `DELETE` and matchBehaviour (optional).
|
||||
/// </summary>
|
||||
/// <param name="matchBehaviour">The match behaviour.</param>
|
||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||
IRequestBuilder UsingDelete(MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch);
|
||||
|
||||
/// <summary>
|
||||
/// UsingGet: add HTTP Method matching on `GET` and matchBehaviour (optional).
|
||||
/// </summary>
|
||||
/// <param name="matchBehaviour">The match behaviour.</param>
|
||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||
IRequestBuilder UsingGet(MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch);
|
||||
/// <summary>
|
||||
/// UsingGet: add HTTP Method matching on `GET` and matchBehaviour (optional).
|
||||
/// </summary>
|
||||
/// <param name="matchBehaviour">The match behaviour.</param>
|
||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||
IRequestBuilder UsingGet(MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch);
|
||||
|
||||
/// <summary>
|
||||
/// UsingHead: Add HTTP Method matching on `HEAD` and matchBehaviour (optional).
|
||||
/// </summary>
|
||||
/// <param name="matchBehaviour">The match behaviour.</param>
|
||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||
IRequestBuilder UsingHead(MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch);
|
||||
/// <summary>
|
||||
/// UsingHead: Add HTTP Method matching on `HEAD` and matchBehaviour (optional).
|
||||
/// </summary>
|
||||
/// <param name="matchBehaviour">The match behaviour.</param>
|
||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||
IRequestBuilder UsingHead(MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch);
|
||||
|
||||
/// <summary>
|
||||
/// UsingPost: add HTTP Method matching on `POST` and matchBehaviour (optional).
|
||||
/// </summary>
|
||||
/// <param name="matchBehaviour">The match behaviour.</param>
|
||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||
IRequestBuilder UsingPost(MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch);
|
||||
/// <summary>
|
||||
/// UsingPost: add HTTP Method matching on `POST` and matchBehaviour (optional).
|
||||
/// </summary>
|
||||
/// <param name="matchBehaviour">The match behaviour.</param>
|
||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||
IRequestBuilder UsingPost(MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch);
|
||||
|
||||
/// <summary>
|
||||
/// UsingPatch: add HTTP Method matching on `PATCH` and matchBehaviour (optional).
|
||||
/// </summary>
|
||||
/// <param name="matchBehaviour">The match behaviour.</param>
|
||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||
IRequestBuilder UsingPatch(MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch);
|
||||
/// <summary>
|
||||
/// UsingPatch: add HTTP Method matching on `PATCH` and matchBehaviour (optional).
|
||||
/// </summary>
|
||||
/// <param name="matchBehaviour">The match behaviour.</param>
|
||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||
IRequestBuilder UsingPatch(MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch);
|
||||
|
||||
/// <summary>
|
||||
/// UsingPut: add HTTP Method matching on `OPTIONS` and matchBehaviour (optional).
|
||||
/// </summary>
|
||||
/// <param name="matchBehaviour">The match behaviour.</param>
|
||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||
IRequestBuilder UsingOptions(MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch);
|
||||
/// <summary>
|
||||
/// UsingPut: add HTTP Method matching on `OPTIONS` and matchBehaviour (optional).
|
||||
/// </summary>
|
||||
/// <param name="matchBehaviour">The match behaviour.</param>
|
||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||
IRequestBuilder UsingOptions(MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch);
|
||||
|
||||
/// <summary>
|
||||
/// UsingPut: add HTTP Method matching on `PUT` and matchBehaviour (optional).
|
||||
/// </summary>
|
||||
/// <param name="matchBehaviour">The match behaviour.</param>
|
||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||
IRequestBuilder UsingPut(MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch);
|
||||
/// <summary>
|
||||
/// UsingPut: add HTTP Method matching on `PUT` and matchBehaviour (optional).
|
||||
/// </summary>
|
||||
/// <param name="matchBehaviour">The match behaviour.</param>
|
||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||
IRequestBuilder UsingPut(MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch);
|
||||
|
||||
/// <summary>
|
||||
/// UsingTrace: add HTTP Method matching on `TRACE` and matchBehaviour (optional).
|
||||
/// </summary>
|
||||
/// <param name="matchBehaviour">The match behaviour.</param>
|
||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||
IRequestBuilder UsingTrace(MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch);
|
||||
/// <summary>
|
||||
/// UsingTrace: add HTTP Method matching on `TRACE` and matchBehaviour (optional).
|
||||
/// </summary>
|
||||
/// <param name="matchBehaviour">The match behaviour.</param>
|
||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||
IRequestBuilder UsingTrace(MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch);
|
||||
|
||||
/// <summary>
|
||||
/// UsingAnyMethod: add HTTP Method matching on any method.
|
||||
/// </summary>
|
||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||
IRequestBuilder UsingAnyMethod();
|
||||
/// <summary>
|
||||
/// UsingAnyMethod: add HTTP Method matching on any method.
|
||||
/// </summary>
|
||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||
IRequestBuilder UsingAnyMethod();
|
||||
|
||||
/// <summary>
|
||||
/// UsingAnyVerb: add HTTP Method matching on any method.
|
||||
/// </summary>
|
||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||
[Obsolete("Use the method UsingAnyMethod().")]
|
||||
IRequestBuilder UsingAnyVerb();
|
||||
/// <summary>
|
||||
/// UsingMethod: add HTTP Method matching on any methods and matchBehaviour.
|
||||
/// </summary>
|
||||
/// <param name="matchBehaviour">The match behaviour.</param>
|
||||
/// <param name="matchOperator">The <see cref="MatchOperator"/> to use.</param>
|
||||
/// <param name="methods">The method or methods.</param>
|
||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||
IRequestBuilder UsingMethod(MatchBehaviour matchBehaviour, MatchOperator matchOperator, params string[] methods);
|
||||
|
||||
/// <summary>
|
||||
/// UsingMethod: add HTTP Method matching on any methods and matchBehaviour.
|
||||
/// </summary>
|
||||
/// <param name="matchBehaviour">The match behaviour.</param>
|
||||
/// <param name="methods">The method or methods.</param>
|
||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||
IRequestBuilder UsingMethod(MatchBehaviour matchBehaviour, [NotNull] params string[] methods);
|
||||
|
||||
/// <summary>
|
||||
/// UsingMethod: add HTTP Method matching on any methods.
|
||||
/// </summary>
|
||||
/// <param name="methods">The method or methods.</param>
|
||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||
IRequestBuilder UsingMethod([NotNull] params string[] methods);
|
||||
|
||||
/// <summary>
|
||||
/// UsingVerb: add HTTP Method matching on any methods.
|
||||
/// </summary>
|
||||
/// <param name="verbs">The method or methods.</param>
|
||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||
[Obsolete("Use the method UsingMethod(...).")]
|
||||
IRequestBuilder UsingVerb([NotNull] params string[] verbs);
|
||||
}
|
||||
/// <summary>
|
||||
/// UsingMethod: add HTTP Method matching on any methods.
|
||||
/// </summary>
|
||||
/// <param name="methods">The method or methods.</param>
|
||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||
IRequestBuilder UsingMethod(params string[] methods);
|
||||
}
|
||||
@@ -1,110 +1,108 @@
|
||||
using JetBrains.Annotations;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using WireMock.Matchers;
|
||||
using WireMock.Types;
|
||||
|
||||
namespace WireMock.RequestBuilders
|
||||
namespace WireMock.RequestBuilders;
|
||||
|
||||
/// <summary>
|
||||
/// The ParamsRequestBuilder interface.
|
||||
/// </summary>
|
||||
public interface IParamsRequestBuilder : IBodyRequestBuilder
|
||||
{
|
||||
/// <summary>
|
||||
/// The ParamsRequestBuilder interface.
|
||||
/// WithParam: matching on key only.
|
||||
/// </summary>
|
||||
public interface IParamsRequestBuilder : IBodyRequestBuilder
|
||||
{
|
||||
/// <summary>
|
||||
/// WithParam: matching on key only.
|
||||
/// </summary>
|
||||
/// <param name="key">The key.</param>
|
||||
/// <param name="matchBehaviour">The match behaviour (optional).</param>
|
||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||
IRequestBuilder WithParam([NotNull] string key, MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch);
|
||||
/// <param name="key">The key.</param>
|
||||
/// <param name="matchBehaviour">The match behaviour (optional).</param>
|
||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||
IRequestBuilder WithParam(string key, MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch);
|
||||
|
||||
/// <summary>
|
||||
/// WithParam: matching on key only.
|
||||
/// </summary>
|
||||
/// <param name="key">The key.</param>
|
||||
/// <param name="ignoreCase">Defines if the key should be matched using case-ignore.</param>
|
||||
/// <param name="matchBehaviour">The match behaviour (optional).</param>
|
||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||
IRequestBuilder WithParam([NotNull] string key, bool ignoreCase, MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch);
|
||||
/// <summary>
|
||||
/// WithParam: matching on key only.
|
||||
/// </summary>
|
||||
/// <param name="key">The key.</param>
|
||||
/// <param name="ignoreCase">Defines if the key should be matched using case-ignore.</param>
|
||||
/// <param name="matchBehaviour">The match behaviour (optional).</param>
|
||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||
IRequestBuilder WithParam(string key, bool ignoreCase, MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch);
|
||||
|
||||
/// <summary>
|
||||
/// WithParam: matching on key and values.
|
||||
/// </summary>
|
||||
/// <param name="key">The key.</param>
|
||||
/// <param name="values">The values.</param>
|
||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||
IRequestBuilder WithParam([NotNull] string key, [CanBeNull] params string[] values);
|
||||
/// <summary>
|
||||
/// WithParam: matching on key and values.
|
||||
/// </summary>
|
||||
/// <param name="key">The key.</param>
|
||||
/// <param name="values">The values.</param>
|
||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||
IRequestBuilder WithParam(string key, params string[] values);
|
||||
|
||||
/// <summary>
|
||||
/// WithParam: matching on key and values.
|
||||
/// </summary>
|
||||
/// <param name="key">The key.</param>
|
||||
/// <param name="ignoreCase">Defines if the key should be matched using case-ignore.</param>
|
||||
/// <param name="values">The values.</param>
|
||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||
IRequestBuilder WithParam([NotNull] string key, bool ignoreCase, [CanBeNull] params string[] values);
|
||||
/// <summary>
|
||||
/// WithParam: matching on key and values.
|
||||
/// </summary>
|
||||
/// <param name="key">The key.</param>
|
||||
/// <param name="ignoreCase">Defines if the key should be matched using case-ignore.</param>
|
||||
/// <param name="values">The values.</param>
|
||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||
IRequestBuilder WithParam(string key, bool ignoreCase, params string[] values);
|
||||
|
||||
/// <summary>
|
||||
/// WithParam: matching on key and matchers.
|
||||
/// </summary>
|
||||
/// <param name="key">The key.</param>
|
||||
/// <param name="matchers">The matchers.</param>
|
||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||
IRequestBuilder WithParam([NotNull] string key, [CanBeNull] params IStringMatcher[] matchers);
|
||||
/// <summary>
|
||||
/// WithParam: matching on key and matchers.
|
||||
/// </summary>
|
||||
/// <param name="key">The key.</param>
|
||||
/// <param name="matchers">The matchers.</param>
|
||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||
IRequestBuilder WithParam(string key, params IStringMatcher[] matchers);
|
||||
|
||||
/// <summary>
|
||||
/// WithParam: matching on key and matchers.
|
||||
/// </summary>
|
||||
/// <param name="key">The key.</param>
|
||||
/// <param name="ignoreCase">Defines if the key should be matched using case-ignore.</param>
|
||||
/// <param name="matchers">The matchers.</param>
|
||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||
IRequestBuilder WithParam([NotNull] string key, bool ignoreCase, [CanBeNull] params IStringMatcher[] matchers);
|
||||
/// <summary>
|
||||
/// WithParam: matching on key and matchers.
|
||||
/// </summary>
|
||||
/// <param name="key">The key.</param>
|
||||
/// <param name="ignoreCase">Defines if the key should be matched using case-ignore.</param>
|
||||
/// <param name="matchers">The matchers.</param>
|
||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||
IRequestBuilder WithParam(string key, bool ignoreCase, params IStringMatcher[] matchers);
|
||||
|
||||
/// <summary>
|
||||
/// WithParam: matching on key, values and matchBehaviour.
|
||||
/// </summary>
|
||||
/// <param name="key">The key.</param>
|
||||
/// <param name="values">The values.</param>
|
||||
/// <param name="matchBehaviour">The match behaviour.</param>
|
||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||
IRequestBuilder WithParam([NotNull] string key, MatchBehaviour matchBehaviour, [CanBeNull] params string[] values);
|
||||
/// <summary>
|
||||
/// WithParam: matching on key, values and matchBehaviour.
|
||||
/// </summary>
|
||||
/// <param name="key">The key.</param>
|
||||
/// <param name="values">The values.</param>
|
||||
/// <param name="matchBehaviour">The match behaviour.</param>
|
||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||
IRequestBuilder WithParam(string key, MatchBehaviour matchBehaviour, params string[] values);
|
||||
|
||||
/// <summary>
|
||||
/// WithParam: matching on key, values and matchBehaviour.
|
||||
/// </summary>
|
||||
/// <param name="key">The key.</param>
|
||||
/// <param name="ignoreCase">Defines if the key should be matched using case-ignore.</param>
|
||||
/// <param name="values">The values.</param>
|
||||
/// <param name="matchBehaviour">The match behaviour.</param>
|
||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||
IRequestBuilder WithParam([NotNull] string key, MatchBehaviour matchBehaviour, bool ignoreCase = false, [CanBeNull] params string[] values);
|
||||
/// <summary>
|
||||
/// WithParam: matching on key, values and matchBehaviour.
|
||||
/// </summary>
|
||||
/// <param name="key">The key.</param>
|
||||
/// <param name="ignoreCase">Defines if the key should be matched using case-ignore.</param>
|
||||
/// <param name="values">The values.</param>
|
||||
/// <param name="matchBehaviour">The match behaviour.</param>
|
||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||
IRequestBuilder WithParam(string key, MatchBehaviour matchBehaviour, bool ignoreCase = false, params string[] values);
|
||||
|
||||
/// <summary>
|
||||
/// WithParam: matching on key, matchers and matchBehaviour.
|
||||
/// </summary>
|
||||
/// <param name="key">The key.</param>
|
||||
/// <param name="matchers">The matchers.</param>
|
||||
/// <param name="matchBehaviour">The match behaviour.</param>
|
||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||
IRequestBuilder WithParam([NotNull] string key, MatchBehaviour matchBehaviour, [CanBeNull] params IStringMatcher[] matchers);
|
||||
/// <summary>
|
||||
/// WithParam: matching on key, matchers and matchBehaviour.
|
||||
/// </summary>
|
||||
/// <param name="key">The key.</param>
|
||||
/// <param name="matchers">The matchers.</param>
|
||||
/// <param name="matchBehaviour">The match behaviour.</param>
|
||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||
IRequestBuilder WithParam(string key, MatchBehaviour matchBehaviour, params IStringMatcher[] matchers);
|
||||
|
||||
/// <summary>
|
||||
/// WithParam: matching on key, matchers and matchBehaviour.
|
||||
/// </summary>
|
||||
/// <param name="key">The key.</param>
|
||||
/// <param name="ignoreCase">Defines if the key should be matched using case-ignore.</param>
|
||||
/// <param name="matchers">The matchers.</param>
|
||||
/// <param name="matchBehaviour">The match behaviour.</param>
|
||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||
IRequestBuilder WithParam([NotNull] string key, MatchBehaviour matchBehaviour, bool ignoreCase = false, [CanBeNull] params IStringMatcher[] matchers);
|
||||
/// <summary>
|
||||
/// WithParam: matching on key, matchers and matchBehaviour.
|
||||
/// </summary>
|
||||
/// <param name="key">The key.</param>
|
||||
/// <param name="ignoreCase">Defines if the key should be matched using case-ignore.</param>
|
||||
/// <param name="matchers">The matchers.</param>
|
||||
/// <param name="matchBehaviour">The match behaviour.</param>
|
||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||
IRequestBuilder WithParam(string key, MatchBehaviour matchBehaviour, bool ignoreCase = false, params IStringMatcher[] matchers);
|
||||
|
||||
/// <summary>
|
||||
/// WithParam: matching on functions.
|
||||
/// </summary>
|
||||
/// <param name="funcs">The funcs.</param>
|
||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||
IRequestBuilder WithParam([NotNull] params Func<IDictionary<string, WireMockList<string>>, bool>[] funcs);
|
||||
}
|
||||
/// <summary>
|
||||
/// WithParam: matching on functions.
|
||||
/// </summary>
|
||||
/// <param name="funcs">The funcs.</param>
|
||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||
IRequestBuilder WithParam(params Func<IDictionary<string, WireMockList<string>>, bool>[] funcs);
|
||||
}
|
||||
@@ -1,70 +1,84 @@
|
||||
using System;
|
||||
using JetBrains.Annotations;
|
||||
using System;
|
||||
using WireMock.Matchers;
|
||||
|
||||
namespace WireMock.RequestBuilders
|
||||
namespace WireMock.RequestBuilders;
|
||||
|
||||
/// <summary>
|
||||
/// IUrlAndPathRequestBuilder
|
||||
/// </summary>
|
||||
public interface IUrlAndPathRequestBuilder : IMethodRequestBuilder
|
||||
{
|
||||
/// <summary>
|
||||
/// IUrlAndPathRequestBuilder
|
||||
/// WithPath: add path matching based on IStringMatchers.
|
||||
/// </summary>
|
||||
public interface IUrlAndPathRequestBuilder : IMethodRequestBuilder
|
||||
{
|
||||
/// <summary>
|
||||
/// WithPath: add path matching based on IStringMatchers.
|
||||
/// </summary>
|
||||
/// <param name="matchers">The matchers.</param>
|
||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||
IRequestBuilder WithPath([NotNull] params IStringMatcher[] matchers);
|
||||
/// <param name="matchers">The matchers.</param>
|
||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||
IRequestBuilder WithPath(params IStringMatcher[] matchers);
|
||||
|
||||
/// <summary>
|
||||
/// WithPath: add path matching based on paths.
|
||||
/// </summary>
|
||||
/// <param name="paths">The paths.</param>
|
||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||
IRequestBuilder WithPath([NotNull] params string[] paths);
|
||||
/// <summary>
|
||||
/// WithPath: add path matching based on MatchOperator and IStringMatchers.
|
||||
/// </summary>
|
||||
/// <param name="matchOperator">The <see cref="MatchOperator"/> to use.</param>
|
||||
/// <param name="matchers">The matchers.</param>
|
||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||
IRequestBuilder WithPath(MatchOperator matchOperator, params IStringMatcher[] matchers);
|
||||
|
||||
/// <summary>
|
||||
/// WithPath: add path matching based on paths and matchBehaviour.
|
||||
/// </summary>
|
||||
/// <param name="matchBehaviour">The match behaviour.</param>
|
||||
/// <param name="paths">The paths.</param>
|
||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||
IRequestBuilder WithPath(MatchBehaviour matchBehaviour, [NotNull] params string[] paths);
|
||||
/// <summary>
|
||||
/// WithPath: add path matching based on paths.
|
||||
/// </summary>
|
||||
/// <param name="paths">The paths.</param>
|
||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||
IRequestBuilder WithPath(params string[] paths);
|
||||
|
||||
/// <summary>
|
||||
/// WithPath: add path matching based on functions.
|
||||
/// </summary>
|
||||
/// <param name="funcs">The path funcs.</param>
|
||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||
IRequestBuilder WithPath([NotNull] params Func<string, bool>[] funcs);
|
||||
/// <summary>
|
||||
/// WithPath: add path matching based on paths , matchBehaviour and MatchOperator.
|
||||
/// </summary>
|
||||
/// <param name="matchOperator">The <see cref="MatchOperator"/> to use.</param>
|
||||
/// <param name="paths">The paths.</param>
|
||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||
IRequestBuilder WithPath(MatchOperator matchOperator, params string[] paths);
|
||||
|
||||
/// <summary>
|
||||
/// WithUrl: add url matching based on IStringMatcher[].
|
||||
/// </summary>
|
||||
/// <param name="matchers">The matchers.</param>
|
||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||
IRequestBuilder WithUrl([NotNull] params IStringMatcher[] matchers);
|
||||
/// <summary>
|
||||
/// WithPath: add path matching based on functions.
|
||||
/// </summary>
|
||||
/// <param name="funcs">The path funcs.</param>
|
||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||
IRequestBuilder WithPath(params Func<string, bool>[] funcs);
|
||||
|
||||
/// <summary>
|
||||
/// WithUrl: add url matching based on urls.
|
||||
/// </summary>
|
||||
/// <param name="urls">The urls.</param>
|
||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||
IRequestBuilder WithUrl([NotNull] params string[] urls);
|
||||
/// <summary>
|
||||
/// WithUrl: add url matching based on IStringMatcher[].
|
||||
/// </summary>
|
||||
/// <param name="matchers">The matchers.</param>
|
||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||
IRequestBuilder WithUrl(params IStringMatcher[] matchers);
|
||||
|
||||
/// <summary>
|
||||
/// WithUrl: add url matching based on urls.
|
||||
/// </summary>
|
||||
/// <param name="matchBehaviour">The match behaviour.</param>
|
||||
/// <param name="urls">The urls.</param>
|
||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||
IRequestBuilder WithUrl(MatchBehaviour matchBehaviour, [NotNull] params string[] urls);
|
||||
/// <summary>
|
||||
/// WithUrl: add url matching based on MatchOperator and IStringMatchers.
|
||||
/// </summary>
|
||||
/// <param name="matchOperator">The <see cref="MatchOperator"/> to use.</param>
|
||||
/// <param name="matchers">The matchers.</param>
|
||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||
IRequestBuilder WithUrl(MatchOperator matchOperator, params IStringMatcher[] matchers);
|
||||
|
||||
/// <summary>
|
||||
/// WithUrl: add url matching based on functions.
|
||||
/// </summary>
|
||||
/// <param name="funcs">The url functions.</param>
|
||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||
IRequestBuilder WithUrl([NotNull] params Func<string, bool>[] funcs);
|
||||
}
|
||||
/// <summary>
|
||||
/// WithUrl: add url matching based on urls.
|
||||
/// </summary>
|
||||
/// <param name="urls">The urls.</param>
|
||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||
IRequestBuilder WithUrl(params string[] urls);
|
||||
|
||||
/// <summary>
|
||||
/// WithUrl: add url matching based on urls.
|
||||
/// </summary>
|
||||
/// <param name="matchOperator">The <see cref="MatchOperator"/> to use.</param>
|
||||
/// <param name="urls">The urls.</param>
|
||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||
IRequestBuilder WithUrl(MatchOperator matchOperator, params string[] urls);
|
||||
|
||||
/// <summary>
|
||||
/// WithUrl: add url matching based on functions.
|
||||
/// </summary>
|
||||
/// <param name="funcs">The url functions.</param>
|
||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||
IRequestBuilder WithUrl(params Func<string, bool>[] funcs);
|
||||
}
|
||||
48
src/WireMock.Net/RequestBuilders/Request.ClientIP.cs
Normal file
48
src/WireMock.Net/RequestBuilders/Request.ClientIP.cs
Normal file
@@ -0,0 +1,48 @@
|
||||
using System;
|
||||
using Stef.Validation;
|
||||
using WireMock.Matchers;
|
||||
using WireMock.Matchers.Request;
|
||||
|
||||
namespace WireMock.RequestBuilders;
|
||||
|
||||
public partial class Request
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public IRequestBuilder WithClientIP(params IStringMatcher[] matchers)
|
||||
{
|
||||
return WithClientIP(MatchOperator.Or, matchers);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public IRequestBuilder WithClientIP(MatchOperator matchOperator, params IStringMatcher[] matchers)
|
||||
{
|
||||
Guard.NotNullOrEmpty(matchers);
|
||||
|
||||
_requestMatchers.Add(new RequestMessageClientIPMatcher(MatchBehaviour.AcceptOnMatch, MatchOperator.Or, matchers));
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public IRequestBuilder WithClientIP(params string[] paths)
|
||||
{
|
||||
return WithClientIP(MatchOperator.Or, paths);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public IRequestBuilder WithClientIP(MatchOperator matchOperator, params string[] paths)
|
||||
{
|
||||
Guard.NotNullOrEmpty(paths);
|
||||
|
||||
_requestMatchers.Add(new RequestMessageClientIPMatcher(MatchBehaviour.AcceptOnMatch, matchOperator, paths));
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public IRequestBuilder WithClientIP(params Func<string, bool>[] funcs)
|
||||
{
|
||||
Guard.NotNullOrEmpty(funcs);
|
||||
|
||||
_requestMatchers.Add(new RequestMessageClientIPMatcher(funcs));
|
||||
return this;
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
// This source file is based on mock4net by Alexandre Victoor which is licensed under the Apache 2.0 License.
|
||||
// This source file is based on mock4net by Alexandre Victoor which is licensed under the Apache 2.0 License.
|
||||
// For more details see 'mock4net/LICENSE.txt' and 'mock4net/readme.md' in this project root.
|
||||
using System.Linq;
|
||||
using WireMock.Http;
|
||||
@@ -6,110 +6,97 @@ using WireMock.Matchers;
|
||||
using WireMock.Matchers.Request;
|
||||
using Stef.Validation;
|
||||
|
||||
namespace WireMock.RequestBuilders
|
||||
namespace WireMock.RequestBuilders;
|
||||
|
||||
public partial class Request
|
||||
{
|
||||
public partial class Request
|
||||
/// <inheritdoc />
|
||||
public IRequestBuilder UsingConnect(MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
|
||||
{
|
||||
/// <inheritdoc cref="IMethodRequestBuilder.UsingConnect(MatchBehaviour)"/>
|
||||
public IRequestBuilder UsingConnect(MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
|
||||
_requestMatchers.Add(new RequestMessageMethodMatcher(matchBehaviour, MatchOperator.Or, HttpRequestMethods.CONNECT));
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public IRequestBuilder UsingDelete(MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
|
||||
{
|
||||
_requestMatchers.Add(new RequestMessageMethodMatcher(matchBehaviour, MatchOperator.Or, HttpRequestMethods.DELETE));
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public IRequestBuilder UsingGet(MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
|
||||
{
|
||||
_requestMatchers.Add(new RequestMessageMethodMatcher(matchBehaviour, MatchOperator.Or, HttpRequestMethods.GET));
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public IRequestBuilder UsingHead(MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
|
||||
{
|
||||
_requestMatchers.Add(new RequestMessageMethodMatcher(matchBehaviour, MatchOperator.Or, HttpRequestMethods.HEAD));
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public IRequestBuilder UsingOptions(MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
|
||||
{
|
||||
_requestMatchers.Add(new RequestMessageMethodMatcher(matchBehaviour, MatchOperator.Or, HttpRequestMethods.OPTIONS));
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public IRequestBuilder UsingPost(MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
|
||||
{
|
||||
_requestMatchers.Add(new RequestMessageMethodMatcher(matchBehaviour, MatchOperator.Or, HttpRequestMethods.POST));
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public IRequestBuilder UsingPatch(MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
|
||||
{
|
||||
_requestMatchers.Add(new RequestMessageMethodMatcher(matchBehaviour, MatchOperator.Or, HttpRequestMethods.PATCH));
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public IRequestBuilder UsingPut(MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
|
||||
{
|
||||
_requestMatchers.Add(new RequestMessageMethodMatcher(matchBehaviour, MatchOperator.Or, HttpRequestMethods.PUT));
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public IRequestBuilder UsingTrace(MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
|
||||
{
|
||||
_requestMatchers.Add(new RequestMessageMethodMatcher(matchBehaviour, MatchOperator.Or, HttpRequestMethods.TRACE));
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public IRequestBuilder UsingAnyMethod()
|
||||
{
|
||||
var matchers = _requestMatchers.Where(m => m is RequestMessageMethodMatcher).ToList();
|
||||
foreach (var matcher in matchers)
|
||||
{
|
||||
_requestMatchers.Add(new RequestMessageMethodMatcher(matchBehaviour, HttpRequestMethods.CONNECT));
|
||||
return this;
|
||||
_requestMatchers.Remove(matcher);
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IMethodRequestBuilder.UsingDelete(MatchBehaviour)"/>
|
||||
public IRequestBuilder UsingDelete(MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
|
||||
{
|
||||
_requestMatchers.Add(new RequestMessageMethodMatcher(matchBehaviour, HttpRequestMethods.DELETE));
|
||||
return this;
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IMethodRequestBuilder.UsingGet(MatchBehaviour)"/>
|
||||
public IRequestBuilder UsingGet(MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
|
||||
{
|
||||
_requestMatchers.Add(new RequestMessageMethodMatcher(matchBehaviour, HttpRequestMethods.GET));
|
||||
return this;
|
||||
}
|
||||
/// <inheritdoc />
|
||||
public IRequestBuilder UsingMethod(params string[] methods)
|
||||
{
|
||||
return UsingMethod(MatchBehaviour.AcceptOnMatch, MatchOperator.Or, methods);
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IMethodRequestBuilder.UsingHead(MatchBehaviour)"/>
|
||||
public IRequestBuilder UsingHead(MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
|
||||
{
|
||||
_requestMatchers.Add(new RequestMessageMethodMatcher(matchBehaviour, HttpRequestMethods.HEAD));
|
||||
return this;
|
||||
}
|
||||
/// <inheritdoc />
|
||||
public IRequestBuilder UsingMethod(MatchBehaviour matchBehaviour, MatchOperator matchOperator, params string[] methods)
|
||||
{
|
||||
Guard.NotNullOrEmpty(methods);
|
||||
|
||||
/// <inheritdoc cref="IMethodRequestBuilder.UsingOptions(MatchBehaviour)"/>
|
||||
public IRequestBuilder UsingOptions(MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
|
||||
{
|
||||
_requestMatchers.Add(new RequestMessageMethodMatcher(matchBehaviour, HttpRequestMethods.OPTIONS));
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IMethodRequestBuilder.UsingPost(MatchBehaviour)"/>
|
||||
public IRequestBuilder UsingPost(MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
|
||||
{
|
||||
_requestMatchers.Add(new RequestMessageMethodMatcher(matchBehaviour, HttpRequestMethods.POST));
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IMethodRequestBuilder.UsingPatch(MatchBehaviour)"/>
|
||||
public IRequestBuilder UsingPatch(MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
|
||||
{
|
||||
_requestMatchers.Add(new RequestMessageMethodMatcher(matchBehaviour, HttpRequestMethods.PATCH));
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IMethodRequestBuilder.UsingPut(MatchBehaviour)"/>
|
||||
public IRequestBuilder UsingPut(MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
|
||||
{
|
||||
_requestMatchers.Add(new RequestMessageMethodMatcher(matchBehaviour, HttpRequestMethods.PUT));
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IMethodRequestBuilder.UsingTrace(MatchBehaviour)"/>
|
||||
public IRequestBuilder UsingTrace(MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
|
||||
{
|
||||
_requestMatchers.Add(new RequestMessageMethodMatcher(matchBehaviour, HttpRequestMethods.TRACE));
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IMethodRequestBuilder.UsingAnyMethod"/>
|
||||
public IRequestBuilder UsingAnyMethod()
|
||||
{
|
||||
var matchers = _requestMatchers.Where(m => m is RequestMessageMethodMatcher).ToList();
|
||||
foreach (var matcher in matchers)
|
||||
{
|
||||
_requestMatchers.Remove(matcher);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IMethodRequestBuilder.UsingAnyVerb"/>
|
||||
public IRequestBuilder UsingAnyVerb()
|
||||
{
|
||||
return UsingAnyMethod();
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IMethodRequestBuilder.UsingMethod(string[])"/>
|
||||
public IRequestBuilder UsingMethod(params string[] methods)
|
||||
{
|
||||
return UsingMethod(MatchBehaviour.AcceptOnMatch, methods);
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IMethodRequestBuilder.UsingVerb(string[])"/>
|
||||
public IRequestBuilder UsingVerb(params string[] verbs)
|
||||
{
|
||||
return UsingMethod(verbs);
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IMethodRequestBuilder.UsingMethod(MatchBehaviour, string[])"/>
|
||||
public IRequestBuilder UsingMethod(MatchBehaviour matchBehaviour, params string[] methods)
|
||||
{
|
||||
Guard.NotNullOrEmpty(methods, nameof(methods));
|
||||
|
||||
_requestMatchers.Add(new RequestMessageMethodMatcher(matchBehaviour, methods));
|
||||
return this;
|
||||
}
|
||||
_requestMatchers.Add(new RequestMessageMethodMatcher(matchBehaviour, matchOperator, methods));
|
||||
return this;
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
// This source file is based on mock4net by Alexandre Victoor which is licensed under the Apache 2.0 License.
|
||||
// This source file is based on mock4net by Alexandre Victoor which is licensed under the Apache 2.0 License.
|
||||
// For more details see 'mock4net/LICENSE.txt' and 'mock4net/readme.md' in this project root.
|
||||
using System;
|
||||
using WireMock.Matchers;
|
||||
@@ -6,80 +6,79 @@ using WireMock.Matchers.Request;
|
||||
using WireMock.Util;
|
||||
using Stef.Validation;
|
||||
|
||||
namespace WireMock.RequestBuilders
|
||||
namespace WireMock.RequestBuilders;
|
||||
|
||||
public partial class Request
|
||||
{
|
||||
public partial class Request
|
||||
/// <inheritdoc cref="IBodyRequestBuilder.WithBody(string, MatchBehaviour)"/>
|
||||
public IRequestBuilder WithBody(string body, MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
|
||||
{
|
||||
/// <inheritdoc cref="IBodyRequestBuilder.WithBody(string, MatchBehaviour)"/>
|
||||
public IRequestBuilder WithBody(string body, MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
|
||||
{
|
||||
_requestMatchers.Add(new RequestMessageBodyMatcher(matchBehaviour, body));
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IBodyRequestBuilder.WithBody(byte[], MatchBehaviour)"/>
|
||||
public IRequestBuilder WithBody(byte[] body, MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
|
||||
{
|
||||
_requestMatchers.Add(new RequestMessageBodyMatcher(matchBehaviour, body));
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IBodyRequestBuilder.WithBody(object, MatchBehaviour)"/>
|
||||
public IRequestBuilder WithBody(object body, MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
|
||||
{
|
||||
_requestMatchers.Add(new RequestMessageBodyMatcher(matchBehaviour, body));
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IBodyRequestBuilder.WithBody(IMatcher[])"/>
|
||||
public IRequestBuilder WithBody(IMatcher matcher)
|
||||
{
|
||||
return WithBody(new[] { matcher });
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IBodyRequestBuilder.WithBody(IMatcher[])"/>
|
||||
public IRequestBuilder WithBody(IMatcher[] matchers)
|
||||
{
|
||||
Guard.NotNull(matchers, nameof(matchers));
|
||||
|
||||
_requestMatchers.Add(new RequestMessageBodyMatcher(matchers));
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IBodyRequestBuilder.WithBody(Func{string, bool})"/>
|
||||
public IRequestBuilder WithBody(Func<string, bool> func)
|
||||
{
|
||||
Guard.NotNull(func, nameof(func));
|
||||
|
||||
_requestMatchers.Add(new RequestMessageBodyMatcher(func));
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IBodyRequestBuilder.WithBody(Func{byte[], bool})"/>
|
||||
public IRequestBuilder WithBody(Func<byte[], bool> func)
|
||||
{
|
||||
Guard.NotNull(func, nameof(func));
|
||||
|
||||
_requestMatchers.Add(new RequestMessageBodyMatcher(func));
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IBodyRequestBuilder.WithBody(Func{object, bool})"/>
|
||||
public IRequestBuilder WithBody(Func<object, bool> func)
|
||||
{
|
||||
Guard.NotNull(func, nameof(func));
|
||||
|
||||
_requestMatchers.Add(new RequestMessageBodyMatcher(func));
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IBodyRequestBuilder.WithBody(Func{IBodyData, bool})"/>
|
||||
public IRequestBuilder WithBody(Func<IBodyData, bool> func)
|
||||
{
|
||||
Guard.NotNull(func, nameof(func));
|
||||
|
||||
_requestMatchers.Add(new RequestMessageBodyMatcher(func));
|
||||
return this;
|
||||
}
|
||||
_requestMatchers.Add(new RequestMessageBodyMatcher(matchBehaviour, body));
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IBodyRequestBuilder.WithBody(byte[], MatchBehaviour)"/>
|
||||
public IRequestBuilder WithBody(byte[] body, MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
|
||||
{
|
||||
_requestMatchers.Add(new RequestMessageBodyMatcher(matchBehaviour, body));
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IBodyRequestBuilder.WithBody(object, MatchBehaviour)"/>
|
||||
public IRequestBuilder WithBody(object body, MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
|
||||
{
|
||||
_requestMatchers.Add(new RequestMessageBodyMatcher(matchBehaviour, body));
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public IRequestBuilder WithBody(IMatcher matcher)
|
||||
{
|
||||
return WithBody(new[] { matcher });
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public IRequestBuilder WithBody(IMatcher[] matchers, MatchOperator matchOperator = MatchOperator.Or)
|
||||
{
|
||||
Guard.NotNull(matchers);
|
||||
|
||||
_requestMatchers.Add(new RequestMessageBodyMatcher(matchOperator, matchers));
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IBodyRequestBuilder.WithBody(Func{string, bool})"/>
|
||||
public IRequestBuilder WithBody(Func<string, bool> func)
|
||||
{
|
||||
Guard.NotNull(func, nameof(func));
|
||||
|
||||
_requestMatchers.Add(new RequestMessageBodyMatcher(func));
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IBodyRequestBuilder.WithBody(Func{byte[], bool})"/>
|
||||
public IRequestBuilder WithBody(Func<byte[], bool> func)
|
||||
{
|
||||
Guard.NotNull(func, nameof(func));
|
||||
|
||||
_requestMatchers.Add(new RequestMessageBodyMatcher(func));
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IBodyRequestBuilder.WithBody(Func{object, bool})"/>
|
||||
public IRequestBuilder WithBody(Func<object, bool> func)
|
||||
{
|
||||
Guard.NotNull(func, nameof(func));
|
||||
|
||||
_requestMatchers.Add(new RequestMessageBodyMatcher(func));
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IBodyRequestBuilder.WithBody(Func{IBodyData, bool})"/>
|
||||
public IRequestBuilder WithBody(Func<IBodyData, bool> func)
|
||||
{
|
||||
Guard.NotNull(func, nameof(func));
|
||||
|
||||
_requestMatchers.Add(new RequestMessageBodyMatcher(func));
|
||||
return this;
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
// This source file is based on mock4net by Alexandre Victoor which is licensed under the Apache 2.0 License.
|
||||
// This source file is based on mock4net by Alexandre Victoor which is licensed under the Apache 2.0 License.
|
||||
// For more details see 'mock4net/LICENSE.txt' and 'mock4net/readme.md' in this project root.
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
@@ -6,79 +6,78 @@ using WireMock.Matchers;
|
||||
using WireMock.Matchers.Request;
|
||||
using Stef.Validation;
|
||||
|
||||
namespace WireMock.RequestBuilders
|
||||
namespace WireMock.RequestBuilders;
|
||||
|
||||
public partial class Request
|
||||
{
|
||||
public partial class Request
|
||||
/// <inheritdoc cref="IHeadersRequestBuilder.WithHeader(string, string, MatchBehaviour)"/>
|
||||
public IRequestBuilder WithHeader(string name, string pattern, MatchBehaviour matchBehaviour)
|
||||
{
|
||||
/// <inheritdoc cref="IHeadersRequestBuilder.WithHeader(string, string, MatchBehaviour)"/>
|
||||
public IRequestBuilder WithHeader(string name, string pattern, MatchBehaviour matchBehaviour)
|
||||
{
|
||||
return WithHeader(name, pattern, true, matchBehaviour);
|
||||
}
|
||||
return WithHeader(name, pattern, true, matchBehaviour);
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IHeadersRequestBuilder.WithHeader(string, string, bool, MatchBehaviour)"/>
|
||||
public IRequestBuilder WithHeader(string name, string pattern, bool ignoreCase = true, MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
|
||||
{
|
||||
Guard.NotNull(name, nameof(name));
|
||||
Guard.NotNull(pattern, nameof(pattern));
|
||||
/// <inheritdoc cref="IHeadersRequestBuilder.WithHeader(string, string, bool, MatchBehaviour)"/>
|
||||
public IRequestBuilder WithHeader(string name, string pattern, bool ignoreCase = true, MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
|
||||
{
|
||||
Guard.NotNull(name);
|
||||
Guard.NotNull(pattern);
|
||||
|
||||
_requestMatchers.Add(new RequestMessageHeaderMatcher(matchBehaviour, name, pattern, ignoreCase));
|
||||
return this;
|
||||
}
|
||||
_requestMatchers.Add(new RequestMessageHeaderMatcher(matchBehaviour, name, pattern, ignoreCase));
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IHeadersRequestBuilder.WithHeader(string, string[], MatchBehaviour)"/>
|
||||
public IRequestBuilder WithHeader(string name, string[] patterns, MatchBehaviour matchBehaviour)
|
||||
{
|
||||
return WithHeader(name, patterns, true, matchBehaviour);
|
||||
}
|
||||
/// <inheritdoc />
|
||||
public IRequestBuilder WithHeader(string name, string[] patterns, MatchBehaviour matchBehaviour, MatchOperator matchOperator = MatchOperator.Or)
|
||||
{
|
||||
return WithHeader(name, patterns, true, matchBehaviour, matchOperator);
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IHeadersRequestBuilder.WithHeader(string, string[], bool, MatchBehaviour)"/>
|
||||
public IRequestBuilder WithHeader(string name, string[] patterns, bool ignoreCase = true, MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
|
||||
{
|
||||
Guard.NotNull(name, nameof(name));
|
||||
Guard.NotNull(patterns, nameof(patterns));
|
||||
/// <inheritdoc />
|
||||
public IRequestBuilder WithHeader(string name, string[] patterns, bool ignoreCase = true, MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch, MatchOperator matchOperator = MatchOperator.Or)
|
||||
{
|
||||
Guard.NotNull(name);
|
||||
Guard.NotNull(patterns);
|
||||
|
||||
_requestMatchers.Add(new RequestMessageHeaderMatcher(matchBehaviour, name, ignoreCase, patterns));
|
||||
return this;
|
||||
}
|
||||
_requestMatchers.Add(new RequestMessageHeaderMatcher(matchBehaviour, matchOperator, name, ignoreCase, patterns));
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IHeadersRequestBuilder.WithHeader(string, IStringMatcher[])"/>
|
||||
public IRequestBuilder WithHeader(string name, params IStringMatcher[] matchers)
|
||||
{
|
||||
Guard.NotNull(name, nameof(name));
|
||||
Guard.NotNullOrEmpty(matchers, nameof(matchers));
|
||||
/// <inheritdoc />
|
||||
public IRequestBuilder WithHeader(string name, params IStringMatcher[] matchers)
|
||||
{
|
||||
Guard.NotNull(name);
|
||||
Guard.NotNullOrEmpty(matchers);
|
||||
|
||||
_requestMatchers.Add(new RequestMessageHeaderMatcher(MatchBehaviour.AcceptOnMatch, name, false, matchers));
|
||||
return this;
|
||||
}
|
||||
_requestMatchers.Add(new RequestMessageHeaderMatcher(MatchBehaviour.AcceptOnMatch, MatchOperator.Or, name, false, matchers));
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IHeadersRequestBuilder.WithHeader(string, bool, IStringMatcher[])"/>
|
||||
public IRequestBuilder WithHeader(string name, bool ignoreCase, params IStringMatcher[] matchers)
|
||||
{
|
||||
Guard.NotNull(name, nameof(name));
|
||||
Guard.NotNullOrEmpty(matchers, nameof(matchers));
|
||||
/// <inheritdoc />
|
||||
public IRequestBuilder WithHeader(string name, bool ignoreCase, params IStringMatcher[] matchers)
|
||||
{
|
||||
Guard.NotNull(name);
|
||||
Guard.NotNullOrEmpty(matchers);
|
||||
|
||||
_requestMatchers.Add(new RequestMessageHeaderMatcher(MatchBehaviour.AcceptOnMatch, name, ignoreCase, matchers));
|
||||
return this;
|
||||
}
|
||||
_requestMatchers.Add(new RequestMessageHeaderMatcher(MatchBehaviour.AcceptOnMatch, MatchOperator.Or, name, ignoreCase, matchers));
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IHeadersRequestBuilder.WithHeader(string, IStringMatcher[])"/>
|
||||
public IRequestBuilder WithHeader(string name, bool ignoreCase, MatchBehaviour matchBehaviour, params IStringMatcher[] matchers)
|
||||
{
|
||||
Guard.NotNull(name, nameof(name));
|
||||
Guard.NotNullOrEmpty(matchers, nameof(matchers));
|
||||
/// <inheritdoc />
|
||||
public IRequestBuilder WithHeader(string name, bool ignoreCase, MatchBehaviour matchBehaviour, MatchOperator matchOperator, params IStringMatcher[] matchers)
|
||||
{
|
||||
Guard.NotNull(name);
|
||||
Guard.NotNullOrEmpty(matchers);
|
||||
|
||||
_requestMatchers.Add(new RequestMessageHeaderMatcher(matchBehaviour, name, ignoreCase, matchers));
|
||||
return this;
|
||||
}
|
||||
_requestMatchers.Add(new RequestMessageHeaderMatcher(matchBehaviour, matchOperator, name, ignoreCase, matchers));
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IHeadersRequestBuilder.WithHeader(Func{IDictionary{string, string[]}, bool}[])"/>
|
||||
public IRequestBuilder WithHeader(params Func<IDictionary<string, string[]>, bool>[] funcs)
|
||||
{
|
||||
Guard.NotNullOrEmpty(funcs, nameof(funcs));
|
||||
/// <inheritdoc />
|
||||
public IRequestBuilder WithHeader(params Func<IDictionary<string, string[]>, bool>[] funcs)
|
||||
{
|
||||
Guard.NotNullOrEmpty(funcs);
|
||||
|
||||
_requestMatchers.Add(new RequestMessageHeaderMatcher(funcs));
|
||||
return this;
|
||||
}
|
||||
_requestMatchers.Add(new RequestMessageHeaderMatcher(funcs));
|
||||
return this;
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
// This source file is based on mock4net by Alexandre Victoor which is licensed under the Apache 2.0 License.
|
||||
// This source file is based on mock4net by Alexandre Victoor which is licensed under the Apache 2.0 License.
|
||||
// For more details see 'mock4net/LICENSE.txt' and 'mock4net/readme.md' in this project root.
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
@@ -59,7 +59,7 @@ namespace WireMock.RequestBuilders
|
||||
/// <inheritdoc cref="IParamsRequestBuilder.WithParam(string, MatchBehaviour, bool, string[])"/>
|
||||
public IRequestBuilder WithParam(string key, MatchBehaviour matchBehaviour, bool ignoreCase = false, params string[] values)
|
||||
{
|
||||
Guard.NotNull(key, nameof(key));
|
||||
Guard.NotNull(key);
|
||||
|
||||
_requestMatchers.Add(new RequestMessageParamMatcher(matchBehaviour, key, ignoreCase, values));
|
||||
return this;
|
||||
@@ -74,7 +74,7 @@ namespace WireMock.RequestBuilders
|
||||
/// <inheritdoc cref="IParamsRequestBuilder.WithParam(string, MatchBehaviour, bool, IStringMatcher[])"/>
|
||||
public IRequestBuilder WithParam(string key, MatchBehaviour matchBehaviour, bool ignoreCase, params IStringMatcher[] matchers)
|
||||
{
|
||||
Guard.NotNull(key, nameof(key));
|
||||
Guard.NotNull(key);
|
||||
|
||||
_requestMatchers.Add(new RequestMessageParamMatcher(matchBehaviour, key, ignoreCase, matchers));
|
||||
return this;
|
||||
|
||||
48
src/WireMock.Net/RequestBuilders/Request.WithPath.cs
Normal file
48
src/WireMock.Net/RequestBuilders/Request.WithPath.cs
Normal file
@@ -0,0 +1,48 @@
|
||||
using System;
|
||||
using Stef.Validation;
|
||||
using WireMock.Matchers;
|
||||
using WireMock.Matchers.Request;
|
||||
|
||||
namespace WireMock.RequestBuilders;
|
||||
|
||||
public partial class Request
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public IRequestBuilder WithPath(params IStringMatcher[] matchers)
|
||||
{
|
||||
return WithPath(MatchOperator.Or, matchers);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public IRequestBuilder WithPath(MatchOperator matchOperator, params IStringMatcher[] matchers)
|
||||
{
|
||||
Guard.NotNullOrEmpty(matchers);
|
||||
|
||||
_requestMatchers.Add(new RequestMessagePathMatcher(MatchBehaviour.AcceptOnMatch, MatchOperator.Or, matchers));
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public IRequestBuilder WithPath(params string[] paths)
|
||||
{
|
||||
return WithPath(MatchOperator.Or, paths);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public IRequestBuilder WithPath(MatchOperator matchOperator, params string[] paths)
|
||||
{
|
||||
Guard.NotNullOrEmpty(paths);
|
||||
|
||||
_requestMatchers.Add(new RequestMessagePathMatcher(MatchBehaviour.AcceptOnMatch, matchOperator, paths));
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public IRequestBuilder WithPath(params Func<string, bool>[] funcs)
|
||||
{
|
||||
Guard.NotNullOrEmpty(funcs);
|
||||
|
||||
_requestMatchers.Add(new RequestMessagePathMatcher(funcs));
|
||||
return this;
|
||||
}
|
||||
}
|
||||
49
src/WireMock.Net/RequestBuilders/Request.WithUrl.cs
Normal file
49
src/WireMock.Net/RequestBuilders/Request.WithUrl.cs
Normal file
@@ -0,0 +1,49 @@
|
||||
using System;
|
||||
using Stef.Validation;
|
||||
using WireMock.Matchers;
|
||||
using WireMock.Matchers.Request;
|
||||
|
||||
namespace WireMock.RequestBuilders
|
||||
{
|
||||
public partial class Request
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public IRequestBuilder WithUrl(params IStringMatcher[] matchers)
|
||||
{
|
||||
return WithUrl(MatchOperator.Or, matchers);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public IRequestBuilder WithUrl(MatchOperator matchOperator, params IStringMatcher[] matchers)
|
||||
{
|
||||
Guard.NotNullOrEmpty(matchers);
|
||||
|
||||
_requestMatchers.Add(new RequestMessageUrlMatcher(MatchBehaviour.AcceptOnMatch, matchOperator, matchers));
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public IRequestBuilder WithUrl(params string[] urls)
|
||||
{
|
||||
return WithUrl(MatchOperator.Or, urls);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public IRequestBuilder WithUrl(MatchOperator matchOperator, params string[] urls)
|
||||
{
|
||||
Guard.NotNullOrEmpty(urls);
|
||||
|
||||
_requestMatchers.Add(new RequestMessageUrlMatcher(MatchBehaviour.AcceptOnMatch, matchOperator, urls));
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IUrlAndPathRequestBuilder.WithUrl(Func{string, bool}[])"/>
|
||||
public IRequestBuilder WithUrl(params Func<string, bool>[] funcs)
|
||||
{
|
||||
Guard.NotNullOrEmpty(funcs);
|
||||
|
||||
_requestMatchers.Add(new RequestMessageUrlMatcher(funcs));
|
||||
return this;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,167 +1,67 @@
|
||||
// This source file is based on mock4net by Alexandre Victoor which is licensed under the Apache 2.0 License.
|
||||
// This source file is based on mock4net by Alexandre Victoor which is licensed under the Apache 2.0 License.
|
||||
// For more details see 'mock4net/LICENSE.txt' and 'mock4net/readme.md' in this project root.
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
using WireMock.Matchers;
|
||||
using WireMock.Matchers.Request;
|
||||
using Stef.Validation;
|
||||
using WireMock.Matchers.Request;
|
||||
|
||||
namespace WireMock.RequestBuilders
|
||||
namespace WireMock.RequestBuilders;
|
||||
|
||||
/// <summary>
|
||||
/// The Request Builder
|
||||
/// </summary>
|
||||
public partial class Request : RequestMessageCompositeMatcher, IRequestBuilder
|
||||
{
|
||||
private readonly IList<IRequestMatcher> _requestMatchers;
|
||||
|
||||
/// <summary>
|
||||
/// The requests.
|
||||
/// Creates this instance.
|
||||
/// </summary>
|
||||
public partial class Request : RequestMessageCompositeMatcher, IRequestBuilder
|
||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||
public static IRequestBuilder Create()
|
||||
{
|
||||
private readonly IList<IRequestMatcher> _requestMatchers;
|
||||
|
||||
/// <summary>
|
||||
/// Creates this instance.
|
||||
/// </summary>
|
||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||
public static IRequestBuilder Create()
|
||||
{
|
||||
return new Request(new List<IRequestMatcher>());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Request"/> class.
|
||||
/// </summary>
|
||||
/// <param name="requestMatchers">The request matchers.</param>
|
||||
private Request(IList<IRequestMatcher> requestMatchers) : base(requestMatchers)
|
||||
{
|
||||
_requestMatchers = requestMatchers;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the request message matchers.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">Type of IRequestMatcher</typeparam>
|
||||
/// <returns>A List{T}</returns>
|
||||
public IList<T> GetRequestMessageMatchers<T>() where T : IRequestMatcher
|
||||
{
|
||||
return new ReadOnlyCollection<T>(_requestMatchers.OfType<T>().ToList());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the request message matcher.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">Type of IRequestMatcher</typeparam>
|
||||
/// <returns>A RequestMatcher</returns>
|
||||
public T GetRequestMessageMatcher<T>() where T : IRequestMatcher
|
||||
{
|
||||
return _requestMatchers.OfType<T>().FirstOrDefault();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the request message matcher.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">Type of IRequestMatcher</typeparam>
|
||||
/// <returns>A RequestMatcher</returns>
|
||||
public T GetRequestMessageMatcher<T>(Func<T, bool> func) where T : IRequestMatcher
|
||||
{
|
||||
return _requestMatchers.OfType<T>().FirstOrDefault(func);
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IClientIPRequestBuilder.WithClientIP(IStringMatcher[])"/>
|
||||
public IRequestBuilder WithClientIP(params IStringMatcher[] matchers)
|
||||
{
|
||||
Guard.NotNullOrEmpty(matchers, nameof(matchers));
|
||||
|
||||
_requestMatchers.Add(new RequestMessageClientIPMatcher(matchers));
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IClientIPRequestBuilder.WithClientIP(string[])"/>
|
||||
public IRequestBuilder WithClientIP(params string[] clientIPs)
|
||||
{
|
||||
return WithClientIP(MatchBehaviour.AcceptOnMatch, clientIPs);
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IClientIPRequestBuilder.WithClientIP(string[])"/>
|
||||
public IRequestBuilder WithClientIP(MatchBehaviour matchBehaviour, params string[] clientIPs)
|
||||
{
|
||||
Guard.NotNullOrEmpty(clientIPs, nameof(clientIPs));
|
||||
|
||||
_requestMatchers.Add(new RequestMessageClientIPMatcher(matchBehaviour, clientIPs));
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IClientIPRequestBuilder.WithClientIP(Func{string, bool}[])"/>
|
||||
public IRequestBuilder WithClientIP(params Func<string, bool>[] funcs)
|
||||
{
|
||||
Guard.NotNullOrEmpty(funcs, nameof(funcs));
|
||||
|
||||
_requestMatchers.Add(new RequestMessageClientIPMatcher(funcs));
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IUrlAndPathRequestBuilder.WithPath(IStringMatcher[])"/>
|
||||
public IRequestBuilder WithPath(params IStringMatcher[] matchers)
|
||||
{
|
||||
Guard.NotNullOrEmpty(matchers, nameof(matchers));
|
||||
|
||||
_requestMatchers.Add(new RequestMessagePathMatcher(matchers));
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IUrlAndPathRequestBuilder.WithPath(string[])"/>
|
||||
public IRequestBuilder WithPath(params string[] paths)
|
||||
{
|
||||
return WithPath(MatchBehaviour.AcceptOnMatch, paths);
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IUrlAndPathRequestBuilder.WithPath(MatchBehaviour, string[])"/>
|
||||
public IRequestBuilder WithPath(MatchBehaviour matchBehaviour, params string[] paths)
|
||||
{
|
||||
Guard.NotNullOrEmpty(paths, nameof(paths));
|
||||
|
||||
_requestMatchers.Add(new RequestMessagePathMatcher(matchBehaviour, paths));
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IUrlAndPathRequestBuilder.WithPath(Func{string, bool}[])"/>
|
||||
public IRequestBuilder WithPath(params Func<string, bool>[] funcs)
|
||||
{
|
||||
Guard.NotNullOrEmpty(funcs, nameof(funcs));
|
||||
|
||||
_requestMatchers.Add(new RequestMessagePathMatcher(funcs));
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IUrlAndPathRequestBuilder.WithUrl(IStringMatcher[])"/>
|
||||
public IRequestBuilder WithUrl(params IStringMatcher[] matchers)
|
||||
{
|
||||
Guard.NotNullOrEmpty(matchers, nameof(matchers));
|
||||
|
||||
_requestMatchers.Add(new RequestMessageUrlMatcher(matchers));
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IUrlAndPathRequestBuilder.WithUrl(string[])"/>
|
||||
public IRequestBuilder WithUrl(params string[] urls)
|
||||
{
|
||||
return WithUrl(MatchBehaviour.AcceptOnMatch, urls);
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IUrlAndPathRequestBuilder.WithUrl(MatchBehaviour, string[])"/>
|
||||
public IRequestBuilder WithUrl(MatchBehaviour matchBehaviour, params string[] urls)
|
||||
{
|
||||
Guard.NotNullOrEmpty(urls, nameof(urls));
|
||||
|
||||
_requestMatchers.Add(new RequestMessageUrlMatcher(matchBehaviour, urls));
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IUrlAndPathRequestBuilder.WithUrl(Func{string, bool}[])"/>
|
||||
public IRequestBuilder WithUrl(params Func<string, bool>[] funcs)
|
||||
{
|
||||
Guard.NotNullOrEmpty(funcs, nameof(funcs));
|
||||
|
||||
_requestMatchers.Add(new RequestMessageUrlMatcher(funcs));
|
||||
return this;
|
||||
}
|
||||
return new Request(new List<IRequestMatcher>());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Request"/> class.
|
||||
/// </summary>
|
||||
/// <param name="requestMatchers">The request matchers.</param>
|
||||
private Request(IList<IRequestMatcher> requestMatchers) : base(requestMatchers)
|
||||
{
|
||||
_requestMatchers = Guard.NotNull(requestMatchers);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the request message matchers.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">Type of IRequestMatcher</typeparam>
|
||||
/// <returns>A List{T}</returns>
|
||||
public IList<T> GetRequestMessageMatchers<T>() where T : IRequestMatcher
|
||||
{
|
||||
return new ReadOnlyCollection<T>(_requestMatchers.OfType<T>().ToList());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the request message matcher.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">Type of IRequestMatcher</typeparam>
|
||||
/// <returns>A RequestMatcher</returns>
|
||||
public T? GetRequestMessageMatcher<T>() where T : IRequestMatcher
|
||||
{
|
||||
return _requestMatchers.OfType<T>().FirstOrDefault();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the request message matcher.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">Type of IRequestMatcher</typeparam>
|
||||
/// <returns>A RequestMatcher</returns>
|
||||
public T? GetRequestMessageMatcher<T>(Func<T, bool> func) where T : IRequestMatcher
|
||||
{
|
||||
return _requestMatchers.OfType<T>().FirstOrDefault(func);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,159 +1,157 @@
|
||||
// This source file is based on mock4net by Alexandre Victoor which is licensed under the Apache 2.0 License.
|
||||
// This source file is based on mock4net by Alexandre Victoor which is licensed under the Apache 2.0 License.
|
||||
// For more details see 'mock4net/LICENSE.txt' and 'mock4net/readme.md' in this project root.
|
||||
using JetBrains.Annotations;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using Stef.Validation;
|
||||
using WireMock.Models;
|
||||
using WireMock.Types;
|
||||
using WireMock.Util;
|
||||
using Stef.Validation;
|
||||
|
||||
namespace WireMock
|
||||
namespace WireMock;
|
||||
|
||||
/// <summary>
|
||||
/// The RequestMessage.
|
||||
/// </summary>
|
||||
public class RequestMessage : IRequestMessage
|
||||
{
|
||||
/// <inheritdoc cref="IRequestMessage.ClientIP" />
|
||||
public string ClientIP { get; }
|
||||
|
||||
/// <inheritdoc cref="IRequestMessage.Url" />
|
||||
public string Url { get; }
|
||||
|
||||
/// <inheritdoc cref="IRequestMessage.AbsoluteUrl" />
|
||||
public string AbsoluteUrl { get; }
|
||||
|
||||
/// <inheritdoc cref="IRequestMessage.ProxyUrl" />
|
||||
public string ProxyUrl { get; set; }
|
||||
|
||||
/// <inheritdoc cref="IRequestMessage.DateTime" />
|
||||
public DateTime DateTime { get; set; }
|
||||
|
||||
/// <inheritdoc cref="IRequestMessage.Path" />
|
||||
public string Path { get; }
|
||||
|
||||
/// <inheritdoc cref="IRequestMessage.AbsolutePath" />
|
||||
public string AbsolutePath { get; }
|
||||
|
||||
/// <inheritdoc cref="IRequestMessage.PathSegments" />
|
||||
public string[] PathSegments { get; }
|
||||
|
||||
/// <inheritdoc cref="IRequestMessage.AbsolutePathSegments" />
|
||||
public string[] AbsolutePathSegments { get; }
|
||||
|
||||
/// <inheritdoc cref="IRequestMessage.Method" />
|
||||
public string Method { get; }
|
||||
|
||||
/// <inheritdoc cref="IRequestMessage.Headers" />
|
||||
public IDictionary<string, WireMockList<string>>? Headers { get; }
|
||||
|
||||
/// <inheritdoc cref="IRequestMessage.Cookies" />
|
||||
public IDictionary<string, string>? Cookies { get; }
|
||||
|
||||
/// <inheritdoc cref="IRequestMessage.Query" />
|
||||
public IDictionary<string, WireMockList<string>>? Query { get; }
|
||||
|
||||
/// <inheritdoc cref="IRequestMessage.RawQuery" />
|
||||
public string RawQuery { get; }
|
||||
|
||||
/// <inheritdoc cref="IRequestMessage.BodyData" />
|
||||
public IBodyData? BodyData { get; }
|
||||
|
||||
/// <inheritdoc cref="IRequestMessage.Body" />
|
||||
public string Body { get; }
|
||||
|
||||
/// <inheritdoc cref="IRequestMessage.BodyAsJson" />
|
||||
public object BodyAsJson { get; }
|
||||
|
||||
/// <inheritdoc cref="IRequestMessage.BodyAsBytes" />
|
||||
public byte[] BodyAsBytes { get; }
|
||||
|
||||
/// <inheritdoc cref="IRequestMessage.DetectedBodyType" />
|
||||
public string DetectedBodyType { get; }
|
||||
|
||||
/// <inheritdoc cref="IRequestMessage.DetectedBodyTypeFromContentType" />
|
||||
public string DetectedBodyTypeFromContentType { get; }
|
||||
|
||||
/// <inheritdoc cref="IRequestMessage.DetectedCompression" />
|
||||
public string DetectedCompression { get; }
|
||||
|
||||
/// <inheritdoc cref="IRequestMessage.Host" />
|
||||
public string Host { get; }
|
||||
|
||||
/// <inheritdoc cref="IRequestMessage.Protocol" />
|
||||
public string Protocol { get; }
|
||||
|
||||
/// <inheritdoc cref="IRequestMessage.Port" />
|
||||
public int Port { get; }
|
||||
|
||||
/// <inheritdoc cref="IRequestMessage.Origin" />
|
||||
public string Origin { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The RequestMessage.
|
||||
/// Initializes a new instance of the <see cref="RequestMessage"/> class.
|
||||
/// </summary>
|
||||
public class RequestMessage : IRequestMessage
|
||||
/// <param name="urlDetails">The original url details.</param>
|
||||
/// <param name="method">The HTTP method.</param>
|
||||
/// <param name="clientIP">The client IP Address.</param>
|
||||
/// <param name="bodyData">The BodyData.</param>
|
||||
/// <param name="headers">The headers.</param>
|
||||
/// <param name="cookies">The cookies.</param>
|
||||
public RequestMessage(UrlDetails urlDetails, string method, string clientIP, IBodyData? bodyData = null, IDictionary<string, string[]>? headers = null, IDictionary<string, string>? cookies = null)
|
||||
{
|
||||
/// <inheritdoc cref="IRequestMessage.ClientIP" />
|
||||
public string ClientIP { get; }
|
||||
Guard.NotNull(urlDetails, nameof(urlDetails));
|
||||
Guard.NotNull(method, nameof(method));
|
||||
Guard.NotNull(clientIP, nameof(clientIP));
|
||||
|
||||
/// <inheritdoc cref="IRequestMessage.Url" />
|
||||
public string Url { get; }
|
||||
AbsoluteUrl = urlDetails.AbsoluteUrl.ToString();
|
||||
Url = urlDetails.Url.ToString();
|
||||
Protocol = urlDetails.Url.Scheme;
|
||||
Host = urlDetails.Url.Host;
|
||||
Port = urlDetails.Url.Port;
|
||||
Origin = $"{Protocol}://{Host}:{Port}";
|
||||
|
||||
/// <inheritdoc cref="IRequestMessage.AbsoluteUrl" />
|
||||
public string AbsoluteUrl { get; }
|
||||
AbsolutePath = WebUtility.UrlDecode(urlDetails.AbsoluteUrl.AbsolutePath);
|
||||
Path = WebUtility.UrlDecode(urlDetails.Url.AbsolutePath);
|
||||
PathSegments = Path.Split('/').Skip(1).ToArray();
|
||||
AbsolutePathSegments = AbsolutePath.Split('/').Skip(1).ToArray();
|
||||
|
||||
/// <inheritdoc cref="IRequestMessage.ProxyUrl" />
|
||||
public string ProxyUrl { get; set; }
|
||||
Method = method;
|
||||
ClientIP = clientIP;
|
||||
|
||||
/// <inheritdoc cref="IRequestMessage.DateTime" />
|
||||
public DateTime DateTime { get; set; }
|
||||
BodyData = bodyData;
|
||||
|
||||
/// <inheritdoc cref="IRequestMessage.Path" />
|
||||
public string Path { get; }
|
||||
// Convenience getters for e.g. Handlebars
|
||||
Body = BodyData?.BodyAsString;
|
||||
BodyAsJson = BodyData?.BodyAsJson;
|
||||
BodyAsBytes = BodyData?.BodyAsBytes;
|
||||
DetectedBodyType = BodyData?.DetectedBodyType.ToString();
|
||||
DetectedBodyTypeFromContentType = BodyData?.DetectedBodyTypeFromContentType.ToString();
|
||||
DetectedCompression = BodyData?.DetectedCompression;
|
||||
|
||||
/// <inheritdoc cref="IRequestMessage.AbsolutePath" />
|
||||
public string AbsolutePath { get; }
|
||||
Headers = headers?.ToDictionary(header => header.Key, header => new WireMockList<string>(header.Value));
|
||||
Cookies = cookies;
|
||||
RawQuery = urlDetails.Url.Query;
|
||||
Query = QueryStringParser.Parse(RawQuery);
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IRequestMessage.PathSegments" />
|
||||
public string[] PathSegments { get; }
|
||||
|
||||
/// <inheritdoc cref="IRequestMessage.AbsolutePathSegments" />
|
||||
public string[] AbsolutePathSegments { get; }
|
||||
|
||||
/// <inheritdoc cref="IRequestMessage.Method" />
|
||||
public string Method { get; }
|
||||
|
||||
/// <inheritdoc cref="IRequestMessage.Headers" />
|
||||
public IDictionary<string, WireMockList<string>> Headers { get; }
|
||||
|
||||
/// <inheritdoc cref="IRequestMessage.Cookies" />
|
||||
public IDictionary<string, string> Cookies { get; }
|
||||
|
||||
/// <inheritdoc cref="IRequestMessage.Query" />
|
||||
public IDictionary<string, WireMockList<string>> Query { get; }
|
||||
|
||||
/// <inheritdoc cref="IRequestMessage.RawQuery" />
|
||||
public string RawQuery { get; }
|
||||
|
||||
/// <inheritdoc cref="IRequestMessage.BodyData" />
|
||||
public IBodyData BodyData { get; }
|
||||
|
||||
/// <inheritdoc cref="IRequestMessage.Body" />
|
||||
public string Body { get; }
|
||||
|
||||
/// <inheritdoc cref="IRequestMessage.BodyAsJson" />
|
||||
public object BodyAsJson { get; }
|
||||
|
||||
/// <inheritdoc cref="IRequestMessage.BodyAsBytes" />
|
||||
public byte[] BodyAsBytes { get; }
|
||||
|
||||
/// <inheritdoc cref="IRequestMessage.DetectedBodyType" />
|
||||
public string DetectedBodyType { get; }
|
||||
|
||||
/// <inheritdoc cref="IRequestMessage.DetectedBodyTypeFromContentType" />
|
||||
public string DetectedBodyTypeFromContentType { get; }
|
||||
|
||||
/// <inheritdoc cref="IRequestMessage.DetectedCompression" />
|
||||
public string DetectedCompression { get; }
|
||||
|
||||
/// <inheritdoc cref="IRequestMessage.Host" />
|
||||
public string Host { get; }
|
||||
|
||||
/// <inheritdoc cref="IRequestMessage.Protocol" />
|
||||
public string Protocol { get; }
|
||||
|
||||
/// <inheritdoc cref="IRequestMessage.Port" />
|
||||
public int Port { get; }
|
||||
|
||||
/// <inheritdoc cref="IRequestMessage.Origin" />
|
||||
public string Origin { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RequestMessage"/> class.
|
||||
/// </summary>
|
||||
/// <param name="urlDetails">The original url details.</param>
|
||||
/// <param name="method">The HTTP method.</param>
|
||||
/// <param name="clientIP">The client IP Address.</param>
|
||||
/// <param name="bodyData">The BodyData.</param>
|
||||
/// <param name="headers">The headers.</param>
|
||||
/// <param name="cookies">The cookies.</param>
|
||||
public RequestMessage([NotNull] UrlDetails urlDetails, [NotNull] string method, [NotNull] string clientIP, [CanBeNull] IBodyData bodyData = null, [CanBeNull] IDictionary<string, string[]> headers = null, [CanBeNull] IDictionary<string, string> cookies = null)
|
||||
/// <summary>
|
||||
/// Get a query parameter.
|
||||
/// </summary>
|
||||
/// <param name="key">The key.</param>
|
||||
/// <param name="ignoreCase">Defines if the key should be matched using case-ignore.</param>
|
||||
/// <returns>The query parameter.</returns>
|
||||
public WireMockList<string>? GetParameter(string key, bool ignoreCase = false)
|
||||
{
|
||||
if (Query == null)
|
||||
{
|
||||
Guard.NotNull(urlDetails, nameof(urlDetails));
|
||||
Guard.NotNull(method, nameof(method));
|
||||
Guard.NotNull(clientIP, nameof(clientIP));
|
||||
|
||||
AbsoluteUrl = urlDetails.AbsoluteUrl.ToString();
|
||||
Url = urlDetails.Url.ToString();
|
||||
Protocol = urlDetails.Url.Scheme;
|
||||
Host = urlDetails.Url.Host;
|
||||
Port = urlDetails.Url.Port;
|
||||
Origin = $"{Protocol}://{Host}:{Port}";
|
||||
|
||||
AbsolutePath = WebUtility.UrlDecode(urlDetails.AbsoluteUrl.AbsolutePath);
|
||||
Path = WebUtility.UrlDecode(urlDetails.Url.AbsolutePath);
|
||||
PathSegments = Path.Split('/').Skip(1).ToArray();
|
||||
AbsolutePathSegments = AbsolutePath.Split('/').Skip(1).ToArray();
|
||||
|
||||
Method = method;
|
||||
ClientIP = clientIP;
|
||||
|
||||
BodyData = bodyData;
|
||||
|
||||
// Convenience getters for e.g. Handlebars
|
||||
Body = BodyData?.BodyAsString;
|
||||
BodyAsJson = BodyData?.BodyAsJson;
|
||||
BodyAsBytes = BodyData?.BodyAsBytes;
|
||||
DetectedBodyType = BodyData?.DetectedBodyType.ToString();
|
||||
DetectedBodyTypeFromContentType = BodyData?.DetectedBodyTypeFromContentType.ToString();
|
||||
DetectedCompression = BodyData?.DetectedCompression;
|
||||
|
||||
Headers = headers?.ToDictionary(header => header.Key, header => new WireMockList<string>(header.Value));
|
||||
Cookies = cookies;
|
||||
RawQuery = urlDetails.Url.Query;
|
||||
Query = QueryStringParser.Parse(RawQuery);
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get a query parameter.
|
||||
/// </summary>
|
||||
/// <param name="key">The key.</param>
|
||||
/// <param name="ignoreCase">Defines if the key should be matched using case-ignore.</param>
|
||||
/// <returns>The query parameter.</returns>
|
||||
public WireMockList<string> GetParameter(string key, bool ignoreCase = false)
|
||||
{
|
||||
if (Query == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
var query = !ignoreCase ? Query : new Dictionary<string, WireMockList<string>>(Query, StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
var query = !ignoreCase ? Query : new Dictionary<string, WireMockList<string>>(Query, StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
return query.ContainsKey(key) ? query[key] : null;
|
||||
}
|
||||
return query.ContainsKey(key) ? query[key] : null;
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user