Compare commits

..

14 Commits

Author SHA1 Message Date
Stef Heyenrath
be4b0addca 1.5.3 2022-07-29 13:21:22 +02:00
Stef Heyenrath
ae91ed2a79 Update Scriban.Signed to version 5.5.0 (#777) 2022-07-29 13:18:23 +02:00
Stef Heyenrath
968aa598e2 1.5.2 2022-07-24 16:03:30 +02:00
Stef Heyenrath
bdd421e128 JsonPartialMatcher - support Regex (#771)
* JsonPartialMatcher - support Regex

* .

* .

* more tests

* .

* .
2022-07-24 15:54:53 +02:00
Stef Heyenrath
150b448d07 Added some more tests for JsonMatcher + refactored some code to use nullable (#770) 2022-07-09 15:34:17 +02:00
dependabot[bot]
717179fd35 Bump Microsoft.AspNetCore.Server.Kestrel.Core (#769)
Bumps [Microsoft.AspNetCore.Server.Kestrel.Core](https://github.com/aspnet/AspNetCore) from 2.1.3 to 2.1.7.
- [Release notes](https://github.com/aspnet/AspNetCore/releases)
- [Changelog](https://github.com/dotnet/aspnetcore/blob/main/docs/ReleasePlanning.md)
- [Commits](https://github.com/aspnet/AspNetCore/compare/2.1.3...v2.1.7)

---
updated-dependencies:
- dependency-name: Microsoft.AspNetCore.Server.Kestrel.Core
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-07-08 21:52:07 +02:00
Stef Heyenrath
9b7e5908cb 1.5.1 2022-07-08 17:41:43 +02:00
Stef Heyenrath
b1032c9dcd Update WireMock.Org.Abstractions and WireMock.Org.RestClient (#765)
* Update WireMock.Org.Abstractions and WireMock.Org.RestClient

* .

* rename
2022-07-08 11:02:18 +02:00
Stef Heyenrath
4d0f96eabe Rename (WireMock.Pact.Models.V2)-Request to PactRequest and -Response to PactResponse (#767) 2022-07-08 10:32:12 +02:00
dependabot[bot]
ef12cb70cc Bump Microsoft.AspNetCore.Http (#766)
Bumps [Microsoft.AspNetCore.Http](https://github.com/aspnet/AspNetCore) from 2.1.1 to 2.1.22.
- [Release notes](https://github.com/aspnet/AspNetCore/releases)
- [Changelog](https://github.com/dotnet/aspnetcore/blob/main/docs/ReleasePlanning.md)
- [Commits](https://github.com/aspnet/AspNetCore/compare/2.1.1...v2.1.22)

---
updated-dependencies:
- dependency-name: Microsoft.AspNetCore.Http
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-07-08 08:34:19 +02:00
dependabot[bot]
c212d07c53 Bump Newtonsoft.Json in /examples/WireMock.Net.Client.Net472 (#763)
Bumps [Newtonsoft.Json](https://github.com/JamesNK/Newtonsoft.Json) from 6.0.1 to 13.0.1.
- [Release notes](https://github.com/JamesNK/Newtonsoft.Json/releases)
- [Commits](https://github.com/JamesNK/Newtonsoft.Json/compare/6.0.1...13.0.1)

---
updated-dependencies:
- dependency-name: Newtonsoft.Json
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-06-23 11:58:49 +02:00
dependabot[bot]
b9afb126cf Bump Newtonsoft.Json in /examples/WireMock.Net.WebApplication.NETCore2 (#762)
Bumps [Newtonsoft.Json](https://github.com/JamesNK/Newtonsoft.Json) from 11.0.2 to 13.0.1.
- [Release notes](https://github.com/JamesNK/Newtonsoft.Json/releases)
- [Commits](https://github.com/JamesNK/Newtonsoft.Json/compare/11.0.2...13.0.1)

---
updated-dependencies:
- dependency-name: Newtonsoft.Json
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-06-23 10:53:43 +02:00
Stef Heyenrath
8dc9c4b46c 1.5.0 2022-06-09 21:35:44 +02:00
Stef Heyenrath
0441c1d85e Add MatchOperator "Or", "And" and "Average" for patterns (#755)
* wip

* ...

* .

* ...

* ...

* path

* url

* b

* t

* client

* .

* RequestMessageMethodMatcherTests

* .

* h

* .

* fix tests

* .
2022-06-09 21:31:54 +02:00
175 changed files with 9875 additions and 13933 deletions

View File

@@ -1,3 +1,23 @@
# 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 &quot;Or&quot;, &quot;And&quot; and &quot;Average&quot; 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)

View File

@@ -4,7 +4,7 @@
</PropertyGroup>
<PropertyGroup>
<VersionPrefix>1.4.43</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>

View File

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

View File

@@ -1,7 +1,5 @@
# 1.4.43 (21 May 2022)
- #757 Log correct exception message when handling aggregate exceptions
- #759 Add WireMock.Net.xUnit project [feature]
- #756 WireMockConsoleLogger aggregate exception handling bug? [bug]
- #758 Add support for logging to an xUnit ITestOutputHelper [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

View File

@@ -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" />

View File

@@ -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>

View File

@@ -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\"}}")

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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" />

View File

@@ -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'">

View File

@@ -1,5 +1,5 @@
namespace WireMock.Admin.Mappings
{
namespace WireMock.Admin.Mappings;
/// <summary>
/// Body Model
/// </summary>
@@ -15,5 +15,13 @@ namespace WireMock.Admin.Mappings
/// 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; }
}

View File

@@ -1,5 +1,5 @@
namespace WireMock.Admin.Mappings
{
namespace WireMock.Admin.Mappings;
/// <summary>
/// ClientIPModel
/// </summary>
@@ -9,6 +9,14 @@
/// <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; }
}

View File

@@ -1,7 +1,7 @@
using System.Collections.Generic;
namespace WireMock.Admin.Mappings
{
namespace WireMock.Admin.Mappings;
/// <summary>
/// Header Model
/// </summary>
@@ -27,5 +27,13 @@ namespace WireMock.Admin.Mappings
/// 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; }
}

View File

@@ -1,8 +1,8 @@
using System;
using WireMock.Models;
namespace WireMock.Admin.Mappings
{
namespace WireMock.Admin.Mappings;
/// <summary>
/// MappingModel
/// </summary>
@@ -17,17 +17,17 @@ namespace WireMock.Admin.Mappings
/// <summary>
/// Gets or sets the TimeSettings when which this mapping should be used.
/// </summary>
public TimeSettingsModel TimeSettings { get; set; }
public TimeSettingsModel? TimeSettings { get; set; }
/// <summary>
/// The unique title.
/// </summary>
public string Title { get; set; }
public string? Title { get; set; }
/// <summary>
/// The description.
/// </summary>
public string Description { get; set; }
public string? Description { get; set; }
/// <summary>
/// The priority. (A low value means higher priority.)
@@ -37,18 +37,18 @@ namespace WireMock.Admin.Mappings
/// <summary>
/// The Scenario.
/// </summary>
public string Scenario { get; set; }
public string? Scenario { get; set; }
/// <summary>
/// Execution state condition for the current mapping.
/// </summary>
public string WhenStateIs { get; set; }
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; }
public string? SetStateTo { get; set; }
/// <summary>
/// The request model.
@@ -68,11 +68,10 @@ namespace WireMock.Admin.Mappings
/// <summary>
/// The Webhook.
/// </summary>
public WebhookModel Webhook { get; set; }
public WebhookModel? Webhook { get; set; }
/// <summary>
/// The Webhooks.
/// </summary>
public WebhookModel[] Webhooks { get; set; }
}
public WebhookModel[]? Webhooks { get; set; }
}

View File

@@ -1,5 +1,5 @@
namespace WireMock.Admin.Mappings
{
namespace WireMock.Admin.Mappings;
/// <summary>
/// MatcherModel
/// </summary>
@@ -9,7 +9,7 @@ namespace WireMock.Admin.Mappings
/// <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.
@@ -35,5 +35,18 @@ namespace WireMock.Admin.Mappings
/// 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; }
}

View File

@@ -1,5 +1,5 @@
namespace WireMock.Admin.Mappings
{
namespace WireMock.Admin.Mappings;
/// <summary>
/// PathModel
/// </summary>
@@ -10,5 +10,13 @@ namespace WireMock.Admin.Mappings
/// 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; }
}

View File

@@ -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>

View File

@@ -1,5 +1,5 @@
namespace WireMock.Admin.Mappings
{
namespace WireMock.Admin.Mappings;
/// <summary>
/// UrlModel
/// </summary>
@@ -9,6 +9,14 @@
/// <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; }
}

View File

@@ -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.

View File

@@ -3,8 +3,8 @@ using System.Collections.Generic;
using WireMock.Types;
using WireMock.Util;
namespace WireMock
{
namespace WireMock;
/// <summary>
/// IRequestMessage
/// </summary>
@@ -63,17 +63,17 @@ namespace WireMock
/// <summary>
/// Gets the headers.
/// </summary>
IDictionary<string, WireMockList<string>> Headers { get; }
IDictionary<string, WireMockList<string>>? Headers { get; }
/// <summary>
/// Gets the cookies.
/// </summary>
IDictionary<string, string> Cookies { get; }
IDictionary<string, string>? Cookies { get; }
/// <summary>
/// Gets the query.
/// </summary>
IDictionary<string, WireMockList<string>> Query { get; }
IDictionary<string, WireMockList<string>>? Query { get; }
/// <summary>
/// Gets the raw query.
@@ -135,4 +135,3 @@ namespace WireMock
/// </summary>
string Origin { get; }
}
}

View File

@@ -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.

View File

@@ -1,7 +1,5 @@
using JetBrains.Annotations;
namespace WireMock.Matchers.Request;
namespace WireMock.Matchers.Request
{
/// <summary>
/// The RequestMatcher interface.
/// </summary>
@@ -15,6 +13,5 @@ namespace WireMock.Matchers.Request
/// <returns>
/// A value between 0.0 - 1.0 of the similarity.
/// </returns>
double GetMatchingScore([NotNull] IRequestMessage requestMessage, [NotNull] IRequestMatchResult requestMatchResult);
}
double GetMatchingScore(IRequestMessage requestMessage, IRequestMatchResult requestMatchResult);
}

View File

@@ -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.

View File

@@ -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>

View File

@@ -3,15 +3,14 @@ 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>
@@ -42,7 +41,7 @@ namespace WireMock.Matchers
/// 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)
public CSharpCodeMatcher(params AnyOf<string, StringPattern>[] patterns) : this(MatchBehaviour.AcceptOnMatch, MatchOperator.Or, patterns)
{
}
@@ -50,14 +49,14 @@ namespace WireMock.Matchers
/// 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, [NotNull] params AnyOf<string, StringPattern>[] patterns)
public CSharpCodeMatcher(MatchBehaviour matchBehaviour, MatchOperator matchOperator = MatchOperator.Or, params AnyOf<string, StringPattern>[] patterns)
{
Guard.NotNull(patterns, nameof(patterns));
_patterns = Guard.NotNull(patterns);
MatchBehaviour = matchBehaviour;
ThrowException = false;
_patterns = patterns;
MatchOperator = matchOperator;
}
public double IsMatch(string input)
@@ -65,18 +64,18 @@ namespace WireMock.Matchers
return IsMatchInternal(input);
}
public double IsMatch(object input)
public double IsMatch(object? input)
{
return IsMatchInternal(input);
}
public double IsMatchInternal(object input)
public double IsMatchInternal(object? input)
{
double match = MatchScores.Mismatch;
if (input != null)
{
match = MatchScores.ToScore(_patterns.Select(pattern => IsMatch(input, pattern.GetPattern())));
match = MatchScores.ToScore(_patterns.Select(pattern => IsMatch(input, pattern.GetPattern())).ToArray(), MatchOperator);
}
return MatchBehaviourHelper.Convert(MatchBehaviour, match);
@@ -88,7 +87,7 @@ namespace WireMock.Matchers
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
@@ -114,7 +113,7 @@ namespace WireMock.Matchers
throw new WireMockException(string.Join(", ", errors));
}
object helper = compilerResults.CompiledAssembly.CreateInstance("CodeHelper");
var helper = compilerResults.CompiledAssembly?.CreateInstance("CodeHelper");
if (helper == null)
{
throw new WireMockException("CSharpCodeMatcher: Unable to create instance from WireMock.CodeHelper");
@@ -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)
{
@@ -222,7 +217,9 @@ namespace WireMock.Matchers
return _patterns;
}
/// <inheritdoc />
public MatchOperator MatchOperator { get; }
/// <inheritdoc cref="IMatcher.Name"/>
public string Name => "CSharpCodeMatcher";
}
}

View File

@@ -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>

View File

@@ -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);

View File

@@ -3,8 +3,8 @@ using System.Net.Http;
using WireMock.HttpsCertificate;
using WireMock.Settings;
namespace WireMock.Http
{
namespace WireMock.Http;
internal static class HttpClientBuilder
{
public static HttpClient Build(HttpClientSettings settings)
@@ -60,7 +60,6 @@ namespace WireMock.Http
ServicePointManager.ServerCertificateValidationCallback = (message, cert, chain, errors) => true;
#endif
return new HttpClient(handler);
}
return HttpClientFactory2.Create(handler);
}
}

View 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
}
}

View File

@@ -5,11 +5,16 @@ using System.Net.Http;
using System.Threading.Tasks;
using WireMock.Util;
namespace WireMock.Http
{
namespace WireMock.Http;
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 };
@@ -18,13 +23,13 @@ namespace WireMock.Http
if (httpResponseMessage.Content != null)
{
var stream = await httpResponseMessage.Content.ReadAsStreamAsync().ConfigureAwait(false);
IEnumerable<string> contentTypeHeader = null;
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;
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;
@@ -61,4 +66,3 @@ namespace WireMock.Http
return responseMessage;
}
}
}

View File

@@ -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;

View File

@@ -1,4 +1,3 @@
using JetBrains.Annotations;
using System;
using System.Threading.Tasks;
using WireMock.Matchers.Request;
@@ -6,8 +5,8 @@ using WireMock.Models;
using WireMock.ResponseProviders;
using WireMock.Settings;
namespace WireMock
{
namespace WireMock;
/// <summary>
/// The IMapping interface.
/// </summary>
@@ -46,26 +45,22 @@ namespace WireMock
/// <summary>
/// Scenario.
/// </summary>
[CanBeNull]
string Scenario { get; }
string? Scenario { get; }
/// <summary>
/// Execution state condition for the current mapping.
/// </summary>
[CanBeNull]
string ExecutionConditionState { get; }
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; }
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>
@@ -115,7 +110,7 @@ namespace WireMock
/// <summary>
/// The Webhooks.
/// </summary>
IWebhook[] Webhooks { get; }
IWebhook[]? Webhooks { get; }
/// <summary>
/// ProvideResponseAsync
@@ -130,6 +125,5 @@ namespace WireMock
/// <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);
}
IRequestMatchResult GetRequestMatchResult(IRequestMessage requestMessage, string? nextState);
}

View File

@@ -1,24 +1,31 @@
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>
/// Support Regex
/// </summary>
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>
protected AbstractJsonPartialMatcher([NotNull] string value, bool ignoreCase = false, bool throwException = false)
/// <param name="regex">Support Regex.</param>
protected AbstractJsonPartialMatcher(string value, bool ignoreCase = false, bool throwException = false, bool regex = false)
: base(value, ignoreCase, throwException)
{
Regex = regex;
}
/// <summary>
@@ -27,9 +34,11 @@ namespace WireMock.Matchers
/// <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)
/// <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>
@@ -39,19 +48,32 @@ namespace WireMock.Matchers
/// <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)
/// <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)
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;
@@ -86,4 +108,3 @@ namespace WireMock.Matchers
/// </summary>
protected abstract bool IsMatch(string value, string input);
}
}

View File

@@ -3,8 +3,8 @@ using AnyOfTypes;
using JetBrains.Annotations;
using WireMock.Models;
namespace WireMock.Matchers
{
namespace WireMock.Matchers;
/// <summary>
/// ContentTypeMatcher which accepts also all charsets
/// </summary>
@@ -37,7 +37,7 @@ namespace WireMock.Matchers
/// </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)
public ContentTypeMatcher(AnyOf<string, StringPattern>[] patterns, bool ignoreCase = false) : this(MatchBehaviour.AcceptOnMatch, patterns, ignoreCase)
{
}
@@ -48,14 +48,14 @@ namespace WireMock.Matchers
/// <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) :
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)
public override double IsMatch(string? input)
{
if (string.IsNullOrEmpty(input) || !MediaTypeHeaderValue.TryParse(input, out MediaTypeHeaderValue contentType))
{
@@ -74,4 +74,3 @@ namespace WireMock.Matchers
/// <inheritdoc cref="IMatcher.Name"/>
public override string Name => "ContentTypeMatcher";
}
}

View File

@@ -1,12 +1,11 @@
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>
@@ -25,7 +24,7 @@ namespace WireMock.Matchers
/// 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)
public ExactMatcher(params AnyOf<string, StringPattern>[] values) : this(MatchBehaviour.AcceptOnMatch, false, MatchOperator.Or, values)
{
}
@@ -34,25 +33,26 @@ 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="values">The values.</param>
public ExactMatcher(MatchBehaviour matchBehaviour, bool throwException = false, [NotNull] params AnyOf<string, StringPattern>[] values)
public ExactMatcher(
MatchBehaviour matchBehaviour,
bool throwException = false,
MatchOperator matchOperator = MatchOperator.Or,
params AnyOf<string, StringPattern>[] values)
{
Guard.NotNull(values, nameof(values));
_values = Guard.NotNull(values);
MatchBehaviour = matchBehaviour;
ThrowException = throwException;
_values = values;
MatchOperator = matchOperator;
}
/// <inheritdoc cref="IStringMatcher.IsMatch"/>
public double IsMatch(string input)
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)));
double score = MatchScores.ToScore(_values.Select(v => v.GetPattern() == input).ToArray(), MatchOperator);
return MatchBehaviourHelper.Convert(MatchBehaviour, score);
}
/// <inheritdoc cref="IStringMatcher.GetPatterns"/>
@@ -61,7 +61,9 @@ namespace WireMock.Matchers
return _values;
}
/// <inheritdoc />
public MatchOperator MatchOperator { get; }
/// <inheritdoc cref="IMatcher.Name"/>
public string Name => "ExactMatcher";
}
}

View File

@@ -1,9 +1,8 @@
using JetBrains.Annotations;
using System.Linq;
using Stef.Validation;
namespace WireMock.Matchers
{
namespace WireMock.Matchers;
/// <summary>
/// ExactObjectMatcher
/// </summary>
@@ -13,12 +12,12 @@ namespace WireMock.Matchers
/// <summary>
/// Gets the value as object.
/// </summary>
public object ValueAsObject { get; }
public object? ValueAsObject { get; }
/// <summary>
/// Gets the value as byte[].
/// </summary>
public byte[] ValueAsBytes { get; }
public byte[]? ValueAsBytes { get; }
/// <inheritdoc cref="IMatcher.MatchBehaviour"/>
public MatchBehaviour MatchBehaviour { get; }
@@ -30,7 +29,7 @@ namespace WireMock.Matchers
/// 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)
public ExactObjectMatcher(object value) : this(MatchBehaviour.AcceptOnMatch, value)
{
}
@@ -39,11 +38,9 @@ namespace WireMock.Matchers
/// </summary>
/// <param name="matchBehaviour">The match behaviour.</param>
/// <param name="value">The value.</param>
public ExactObjectMatcher(MatchBehaviour matchBehaviour, [NotNull] object value)
public ExactObjectMatcher(MatchBehaviour matchBehaviour, object value)
{
Guard.NotNull(value, nameof(value));
ValueAsObject = value;
ValueAsObject = Guard.NotNull(value);
MatchBehaviour = matchBehaviour;
}
@@ -51,7 +48,7 @@ namespace WireMock.Matchers
/// 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)
public ExactObjectMatcher(byte[] value) : this(MatchBehaviour.AcceptOnMatch, value)
{
}
@@ -61,23 +58,29 @@ namespace WireMock.Matchers
/// <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)
public ExactObjectMatcher(MatchBehaviour matchBehaviour, byte[] value, bool throwException = false)
{
Guard.NotNull(value, nameof(value));
ValueAsBytes = Guard.NotNull(value);
MatchBehaviour = matchBehaviour;
ThrowException = throwException;
ValueAsBytes = value;
}
/// <inheritdoc cref="IObjectMatcher.IsMatch"/>
public double IsMatch(object input)
public double IsMatch(object? input)
{
bool equals = ValueAsObject != null ? Equals(ValueAsObject, input) : ValueAsBytes.SequenceEqual((byte[])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";
}
}

View File

@@ -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);
}
}

View File

@@ -1,8 +1,8 @@
using AnyOfTypes;
using WireMock.Models;
namespace WireMock.Matchers
{
namespace WireMock.Matchers;
/// <summary>
/// IStringMatcher
/// </summary>
@@ -14,12 +14,16 @@ namespace WireMock.Matchers
/// </summary>
/// <param name="input">The input.</param>
/// <returns>A value between 0.0 - 1.0 of the similarity.</returns>
double IsMatch(string input);
double IsMatch(string? input);
/// <summary>
/// Gets the patterns.
/// </summary>
/// <returns>Patterns</returns>
AnyOf<string, StringPattern>[] GetPatterns();
}
/// <summary>
/// The <see cref="Matchers.MatchOperator"/>.
/// </summary>
MatchOperator MatchOperator { get; }
}

View File

@@ -1,14 +1,13 @@
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>
@@ -28,7 +27,7 @@ namespace WireMock.Matchers
/// 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())
public JsonPathMatcher(params string[] patterns) : this(MatchBehaviour.AcceptOnMatch, false, MatchOperator.Or, patterns.ToAnyOfPatterns())
{
}
@@ -36,7 +35,7 @@ namespace WireMock.Matchers
/// 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)
public JsonPathMatcher(params AnyOf<string, StringPattern>[] patterns) : this(MatchBehaviour.AcceptOnMatch, false, MatchOperator.Or, patterns)
{
}
@@ -45,18 +44,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 JsonPathMatcher(MatchBehaviour matchBehaviour, bool throwException = false, [NotNull] params AnyOf<string, StringPattern>[] patterns)
public JsonPathMatcher(
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)
@@ -79,7 +82,7 @@ namespace WireMock.Matchers
}
/// <inheritdoc cref="IObjectMatcher.IsMatch"/>
public double IsMatch(object input)
public double IsMatch(object? input)
{
double match = MatchScores.Mismatch;
@@ -89,7 +92,7 @@ namespace WireMock.Matchers
try
{
// Check if JToken or object
JToken jToken = input is JToken token ? token : JObject.FromObject(input);
JToken jToken = input as JToken ?? JObject.FromObject(input);
match = IsMatch(jToken);
}
catch (JsonException)
@@ -104,18 +107,20 @@ namespace WireMock.Matchers
return MatchBehaviourHelper.Convert(MatchBehaviour, match);
}
/// <inheritdoc cref="IStringMatcher.GetPatterns"/>
/// <inheritdoc />
public AnyOf<string, StringPattern>[] GetPatterns()
{
return _patterns;
}
/// <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));
}
return MatchScores.ToScore(_patterns.Select(pattern => jToken.SelectToken(pattern.GetPattern()) != null).ToArray(), MatchOperator);
}
}

View File

@@ -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";
}

View File

@@ -6,19 +6,19 @@ 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="IValueMatcher.Value"/>
public object Value { get; }
/// <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; }
@@ -68,9 +68,7 @@ namespace WireMock.Matchers
Value = value;
_valueAsJToken = ConvertValueToJToken(value);
_jTokenConverter = ignoreCase
? (Func<JToken, JToken>)Rename
: jToken => jToken;
_jTokenConverter = ignoreCase ? Rename : jToken => jToken;
}
/// <inheritdoc cref="IObjectMatcher.IsMatch"/>
@@ -121,7 +119,7 @@ namespace WireMock.Matchers
return tokenValue;
case string stringValue:
return JsonUtils.Parse(stringValue);
return JsonUtils.Parse(stringValue)!;
case IEnumerable enumerableValue:
return JArray.FromObject(enumerableValue);
@@ -144,11 +142,11 @@ namespace WireMock.Matchers
JToken propertyValue = property.Value;
if (propertyValue.Type == JTokenType.String)
{
string stringValue = propertyValue.Value<string>();
string stringValue = propertyValue.Value<string>()!;
propertyValue = ToUpper(stringValue);
}
return new JProperty(ToUpper(property.Name), Rename(propertyValue));
return new JProperty(ToUpper(property.Name)!, Rename(propertyValue));
}
if (json is JArray array)
@@ -166,4 +164,3 @@ namespace WireMock.Matchers
return json;
}
}
}

View File

@@ -1,7 +1,5 @@
using JetBrains.Annotations;
namespace WireMock.Matchers;
namespace WireMock.Matchers
{
/// <summary>
/// JsonPartialMatcher
/// </summary>
@@ -11,28 +9,27 @@ namespace WireMock.Matchers
public override string Name => nameof(JsonPartialMatcher);
/// <inheritdoc />
public JsonPartialMatcher([NotNull] string value, bool ignoreCase = false, bool throwException = false)
: base(value, ignoreCase, throwException)
public JsonPartialMatcher(string value, bool ignoreCase = false, bool throwException = false, bool regex = false)
: base(value, ignoreCase, throwException, regex)
{
}
/// <inheritdoc />
public JsonPartialMatcher([NotNull] object value, bool ignoreCase = false, bool throwException = false)
: base(value, ignoreCase, throwException)
public JsonPartialMatcher(object value, bool ignoreCase = false, bool throwException = false, bool regex = false)
: base(value, ignoreCase, throwException, regex)
{
}
/// <inheritdoc />
public JsonPartialMatcher(MatchBehaviour matchBehaviour, [NotNull] object value, bool ignoreCase = false, bool throwException = false)
: base(matchBehaviour, value, ignoreCase, throwException)
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, value);
var exactStringMatcher = new ExactMatcher(MatchBehaviour.AcceptOnMatch, ThrowException, MatchOperator.Or, value);
return MatchScores.IsPerfect(exactStringMatcher.IsMatch(input));
}
}
}

View File

@@ -1,7 +1,5 @@
using JetBrains.Annotations;
namespace WireMock.Matchers;
namespace WireMock.Matchers
{
/// <summary>
/// JsonPartialWildCardMatcher
/// </summary>
@@ -11,20 +9,20 @@ namespace WireMock.Matchers
public override string Name => nameof(JsonPartialWildcardMatcher);
/// <inheritdoc />
public JsonPartialWildcardMatcher([NotNull] string value, bool ignoreCase = false, bool throwException = false)
: base(value, ignoreCase, throwException)
public JsonPartialWildcardMatcher(string value, bool ignoreCase = false, bool throwException = false, bool regex = false)
: base(value, ignoreCase, throwException, regex)
{
}
/// <inheritdoc />
public JsonPartialWildcardMatcher([NotNull] object value, bool ignoreCase = false, bool throwException = false)
: base(value, ignoreCase, throwException)
public JsonPartialWildcardMatcher(object value, bool ignoreCase = false, bool throwException = false, bool regex = false)
: base(value, ignoreCase, throwException, regex)
{
}
/// <inheritdoc />
public JsonPartialWildcardMatcher(MatchBehaviour matchBehaviour, [NotNull] object value, bool ignoreCase = false, bool throwException = false)
: base(matchBehaviour, value, ignoreCase, throwException)
public JsonPartialWildcardMatcher(MatchBehaviour matchBehaviour, object value, bool ignoreCase = false, bool throwException = false, bool regex = false)
: base(matchBehaviour, value, ignoreCase, throwException, regex)
{
}
@@ -35,4 +33,3 @@ namespace WireMock.Matchers
return MatchScores.IsPerfect(wildcardStringMatcher.IsMatch(input));
}
}
}

View File

@@ -1,15 +1,14 @@
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>
@@ -28,7 +27,7 @@ namespace WireMock.Matchers
/// 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 })
public LinqMatcher(AnyOf<string, StringPattern> pattern) : this(new[] { pattern })
{
}
@@ -36,7 +35,7 @@ namespace WireMock.Matchers
/// 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)
public LinqMatcher(params AnyOf<string, StringPattern>[] patterns) : this(MatchBehaviour.AcceptOnMatch, false, MatchOperator.Or, patterns)
{
}
@@ -45,7 +44,7 @@ namespace WireMock.Matchers
/// </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)
public LinqMatcher(MatchBehaviour matchBehaviour, AnyOf<string, StringPattern> pattern) : this(matchBehaviour, false, MatchOperator.Or, pattern)
{
}
@@ -53,15 +52,19 @@ namespace WireMock.Matchers
/// 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)
/// <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)
{
Guard.NotNull(patterns, nameof(patterns));
_patterns = Guard.NotNull(patterns);
MatchBehaviour = matchBehaviour;
ThrowException = throwException;
_patterns = patterns;
MatchOperator = matchOperator;
}
/// <inheritdoc cref="IStringMatcher.IsMatch"/>
@@ -75,7 +78,7 @@ namespace WireMock.Matchers
try
{
// Use the Any(...) method to check if the result matches
match = MatchScores.ToScore(_patterns.Select(pattern => queryable.Any(pattern.GetPattern())));
match = MatchScores.ToScore(_patterns.Select(pattern => queryable.Any(pattern.GetPattern())).ToArray(), MatchOperator);
return MatchBehaviourHelper.Convert(MatchBehaviour, match);
}
@@ -119,7 +122,7 @@ namespace WireMock.Matchers
var queryable2 = queryable1.Select(dynamicSelect);
// Use the Any(...) method to check if the result matches.
match = MatchScores.ToScore(_patterns.Select(pattern => queryable2.Any(pattern)));
match = MatchScores.ToScore(_patterns.Select(pattern => queryable2.Any(pattern)).ToArray(), MatchOperator);
return MatchBehaviourHelper.Convert(MatchBehaviour, match);
}
@@ -140,7 +143,9 @@ namespace WireMock.Matchers
return _patterns;
}
/// <inheritdoc />
public MatchOperator MatchOperator { get; }
/// <inheritdoc cref="IMatcher.Name"/>
public string Name => "LinqMatcher";
}
}

View 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,
}

View File

@@ -1,10 +1,10 @@
using System;
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
namespace WireMock.Matchers
{
namespace WireMock.Matchers;
/// <summary>
/// MatchScores
/// </summary>
@@ -54,22 +54,31 @@ namespace WireMock.Matchers
/// 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>
[SuppressMessage("ReSharper", "PossibleMultipleEnumeration")]
public static double ToScore(IEnumerable<bool> values)
public static double ToScore(IReadOnlyCollection<bool> values, MatchOperator matchOperator)
{
return values.Any() ? values.Select(ToScore).Average() : Mismatch;
return ToScore(values.Select(ToScore).ToArray(), matchOperator);
}
/// <summary>
/// Calculates the score from multiple values.
/// </summary>
/// <param name="values">The values.</param>
/// <param name="matchOperator"></param>
/// <returns>average score</returns>
[SuppressMessage("ReSharper", "PossibleMultipleEnumeration")]
public static double ToScore(IEnumerable<double> values)
public static double ToScore(IReadOnlyCollection<double> values, MatchOperator matchOperator)
{
return values.Any() ? values.Average() : Mismatch;
}
if (!values.Any())
{
return Mismatch;
}
return matchOperator switch
{
MatchOperator.Or => ToScore(values.Any(IsPerfect)),
MatchOperator.And => ToScore(values.All(IsPerfect)),
_ => values.Average()
};
}
}

View File

@@ -2,8 +2,8 @@ using System.Linq;
using AnyOfTypes;
using WireMock.Models;
namespace WireMock.Matchers
{
namespace WireMock.Matchers;
/// <summary>
/// NotNullOrEmptyMatcher
/// </summary>
@@ -29,7 +29,7 @@ namespace WireMock.Matchers
}
/// <inheritdoc cref="IObjectMatcher.IsMatch"/>
public double IsMatch(object input)
public double IsMatch(object? input)
{
bool match;
@@ -40,7 +40,7 @@ namespace WireMock.Matchers
break;
case byte[] bytes:
match = bytes != null && bytes.Any();
match = bytes.Any();
break;
default:
@@ -52,7 +52,7 @@ namespace WireMock.Matchers
}
/// <inheritdoc cref="IStringMatcher.IsMatch"/>
public double IsMatch(string input)
public double IsMatch(string? input)
{
var match = !string.IsNullOrEmpty(input);
@@ -64,5 +64,7 @@ namespace WireMock.Matchers
{
return new AnyOf<string, StringPattern>[0];
}
}
/// <inheritdoc />
public MatchOperator MatchOperator { get; } = MatchOperator.Or;
}

View File

@@ -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; }
}

View File

@@ -1,12 +1,13 @@
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>
@@ -15,34 +16,40 @@ namespace WireMock.Matchers.Request
/// <summary>
/// The body function
/// </summary>
public Func<string, bool> Func { get; }
public Func<string, bool>? Func { get; }
/// <summary>
/// The body data function for byte[]
/// </summary>
public Func<byte[], bool> DataFunc { get; }
public Func<byte[], bool>? DataFunc { get; }
/// <summary>
/// The body data function for json
/// </summary>
public Func<object, bool> JsonFunc { get; }
public Func<object, bool>? JsonFunc { get; }
/// <summary>
/// The body data function for BodyData
/// </summary>
public Func<IBodyData, bool> BodyDataFunc { get; }
public Func<IBodyData, bool>? BodyDataFunc { get; }
/// <summary>
/// The matchers.
/// </summary>
public IMatcher[] Matchers { get; }
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, [NotNull] string body) : this(new[] { new WildcardMatcher(matchBehaviour, body) }.Cast<IMatcher>().ToArray())
public RequestMessageBodyMatcher(MatchBehaviour matchBehaviour, string body) :
this(new[] { new WildcardMatcher(matchBehaviour, body) }.Cast<IMatcher>().ToArray())
{
}
@@ -51,7 +58,8 @@ namespace WireMock.Matchers.Request
/// </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())
public RequestMessageBodyMatcher(MatchBehaviour matchBehaviour, byte[] body) :
this(new[] { new ExactObjectMatcher(matchBehaviour, body) }.Cast<IMatcher>().ToArray())
{
}
@@ -60,7 +68,8 @@ namespace WireMock.Matchers.Request
/// </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())
public RequestMessageBodyMatcher(MatchBehaviour matchBehaviour, object body) :
this(new[] { new ExactObjectMatcher(matchBehaviour, body) }.Cast<IMatcher>().ToArray())
{
}
@@ -68,50 +77,56 @@ namespace WireMock.Matchers.Request
/// Initializes a new instance of the <see cref="RequestMessageBodyMatcher"/> class.
/// </summary>
/// <param name="func">The function.</param>
public RequestMessageBodyMatcher([NotNull] Func<string, bool> func)
public RequestMessageBodyMatcher(Func<string, bool> func)
{
Guard.NotNull(func, nameof(func));
Func = func;
Func = Guard.NotNull(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)
public RequestMessageBodyMatcher(Func<byte[], bool> func)
{
Guard.NotNull(func, nameof(func));
DataFunc = func;
DataFunc = Guard.NotNull(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)
public RequestMessageBodyMatcher(Func<object, bool> func)
{
Guard.NotNull(func, nameof(func));
JsonFunc = 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([NotNull] Func<IBodyData, bool> func)
public RequestMessageBodyMatcher(Func<IBodyData, bool> func)
{
Guard.NotNull(func, nameof(func));
BodyDataFunc = 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([NotNull] params IMatcher[] matchers)
public RequestMessageBodyMatcher(params IMatcher[] matchers)
{
Guard.NotNull(matchers, nameof(matchers));
Matchers = 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 />
@@ -121,11 +136,11 @@ namespace WireMock.Matchers.Request
return requestMatchResult.AddScore(GetType(), score);
}
private double CalculateMatchScore(IRequestMessage requestMessage, IMatcher matcher)
private static 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:
@@ -142,7 +157,7 @@ namespace WireMock.Matchers.Request
if (matcher is ExactObjectMatcher exactObjectMatcher)
{
// If the body is a byte array, try to match.
var detectedBodyType = requestMessage?.BodyData?.DetectedBodyType;
var detectedBodyType = requestMessage.BodyData?.DetectedBodyType;
if (detectedBodyType == BodyType.Bytes || detectedBodyType == BodyType.String)
{
return exactObjectMatcher.IsMatch(requestMessage.BodyData.BodyAsBytes);
@@ -180,32 +195,32 @@ namespace WireMock.Matchers.Request
private double CalculateMatchScore(IRequestMessage requestMessage)
{
if (Matchers != null && Matchers.Any())
if (Matchers != null)
{
return Matchers.Max(matcher => CalculateMatchScore(requestMessage, matcher));
var matchersResult = Matchers.Select(matcher => CalculateMatchScore(requestMessage, matcher)).ToArray();
return MatchScores.ToScore(matchersResult, MatchOperator);
}
if (Func != null)
{
return MatchScores.ToScore(Func(requestMessage?.BodyData?.BodyAsString));
return MatchScores.ToScore(Func(requestMessage.BodyData?.BodyAsString));
}
if (JsonFunc != null)
{
return MatchScores.ToScore(JsonFunc(requestMessage?.BodyData?.BodyAsJson));
return MatchScores.ToScore(JsonFunc(requestMessage.BodyData?.BodyAsJson));
}
if (DataFunc != null)
{
return MatchScores.ToScore(DataFunc(requestMessage?.BodyData?.BodyAsBytes));
return MatchScores.ToScore(DataFunc(requestMessage.BodyData?.BodyAsBytes));
}
if (BodyDataFunc != null)
{
return MatchScores.ToScore(BodyDataFunc(requestMessage?.BodyData));
return MatchScores.ToScore(BodyDataFunc(requestMessage.BodyData));
}
return MatchScores.Mismatch;
}
}
}

View File

@@ -1,53 +1,75 @@
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.
/// The request clientIP matcher.
/// </summary>
public class RequestMessageClientIPMatcher : IRequestMatcher
{
/// <summary>
/// The matchers.
/// The matchers
/// </summary>
public IReadOnlyList<IStringMatcher> Matchers { get; }
public IReadOnlyList<IStringMatcher>? Matchers { get; }
/// <summary>
/// The ClientIP functions.
/// The clientIP functions
/// </summary>
public Func<string, bool>[] Funcs { get; }
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="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())
/// <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())
{
Behaviour = matchBehaviour;
MatchOperator = matchOperator;
}
/// <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([NotNull] params IStringMatcher[] matchers)
public RequestMessageClientIPMatcher(MatchBehaviour matchBehaviour, MatchOperator matchOperator, params IStringMatcher[] matchers)
{
Guard.NotNull(matchers, nameof(matchers));
Matchers = matchers;
Matchers = Guard.NotNull(matchers);
Behaviour = matchBehaviour;
MatchOperator = 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)
public RequestMessageClientIPMatcher(params Func<string, bool>[] funcs)
{
Guard.NotNull(funcs, nameof(funcs));
Funcs = funcs;
Funcs = Guard.NotNull(funcs);
}
/// <inheritdoc />
@@ -61,15 +83,16 @@ namespace WireMock.Matchers.Request
{
if (Matchers != null)
{
return Matchers.Max(matcher => matcher.IsMatch(requestMessage.ClientIP));
var results = Matchers.Select(m => m.IsMatch(requestMessage.ClientIP)).ToArray();
return MatchScores.ToScore(results, MatchOperator);
}
if (Funcs != null)
{
return MatchScores.ToScore(requestMessage.ClientIP != null && Funcs.Any(func => func(requestMessage.ClientIP)));
var results = Funcs.Select(func => func(requestMessage.ClientIP)).ToArray();
return MatchScores.ToScore(results, MatchOperator);
}
return MatchScores.Mismatch;
}
}
}

View File

@@ -1,12 +1,11 @@
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>
@@ -19,7 +18,7 @@ namespace WireMock.Matchers.Request
/// <summary>
/// The functions
/// </summary>
public Func<IDictionary<string, string[]>, bool>[] Funcs { get; }
public Func<IDictionary<string, string[]>, bool>[]? Funcs { get; }
/// <summary>
/// The name
@@ -29,7 +28,12 @@ namespace WireMock.Matchers.Request
/// <value>
/// The matchers.
/// </value>
public IStringMatcher[] Matchers { get; }
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.
@@ -38,10 +42,10 @@ namespace WireMock.Matchers.Request
/// <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)
public RequestMessageHeaderMatcher(MatchBehaviour matchBehaviour, string name, string pattern, bool ignoreCase)
{
Guard.NotNull(name, nameof(name));
Guard.NotNull(pattern, nameof(pattern));
Guard.NotNull(name);
Guard.NotNull(pattern);
_matchBehaviour = matchBehaviour;
_ignoreCase = ignoreCase;
@@ -53,28 +57,31 @@ namespace WireMock.Matchers.Request
/// 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, [NotNull] string name, bool ignoreCase, [NotNull] params string[] patterns) :
this(matchBehaviour, name, ignoreCase, patterns.Select(pattern => new WildcardMatcher(matchBehaviour, pattern, ignoreCase)).Cast<IStringMatcher>().ToArray())
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, nameof(patterns));
Guard.NotNull(patterns);
}
/// <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, [NotNull] string name, bool ignoreCase, [NotNull] params IStringMatcher[] matchers)
public RequestMessageHeaderMatcher(MatchBehaviour matchBehaviour, MatchOperator matchOperator, string name, bool ignoreCase, params IStringMatcher[] matchers)
{
Guard.NotNull(name, nameof(name));
Guard.NotNull(matchers, nameof(matchers));
Guard.NotNull(name);
Guard.NotNull(matchers);
_matchBehaviour = matchBehaviour;
MatchOperator = matchOperator;
Name = name;
Matchers = matchers;
_ignoreCase = ignoreCase;
@@ -84,11 +91,10 @@ namespace WireMock.Matchers.Request
/// 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)
public RequestMessageHeaderMatcher(params Func<IDictionary<string, string[]>, bool>[] funcs)
{
Guard.NotNull(funcs, nameof(funcs));
Funcs = funcs;
Funcs = Guard.NotNull(funcs);
Name = string.Empty; // Not used when Func, but set to a non-null valid value.
}
/// <inheritdoc />
@@ -110,21 +116,28 @@ namespace WireMock.Matchers.Request
if (Funcs != null)
{
return MatchScores.ToScore(Funcs.Any(f => f(headers.ToDictionary(entry => entry.Key, entry => entry.Value.ToArray()))));
var funcResults = Funcs.Select(f => f(headers.ToDictionary(entry => entry.Key, entry => entry.Value.ToArray()))).ToArray();
return MatchScores.ToScore(funcResults, MatchOperator);
}
if (Matchers == null)
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);
}
}

View File

@@ -1,16 +1,23 @@
using System;
using System.Linq;
using JetBrains.Annotations;
using Stef.Validation;
namespace WireMock.Matchers.Request
{
namespace WireMock.Matchers.Request;
/// <summary>
/// The request verb matcher.
/// The request method matcher.
/// </summary>
internal class RequestMessageMethodMatcher : IRequestMatcher
{
private readonly MatchBehaviour _matchBehaviour;
/// <summary>
/// The <see cref="Matchers.MatchBehaviour"/>
/// </summary>
public MatchBehaviour MatchBehaviour { get; }
/// <summary>
/// The <see cref="Matchers.MatchOperator"/>
/// </summary>
public MatchOperator MatchOperator { get; }
/// <summary>
/// The methods
@@ -21,25 +28,25 @@ namespace WireMock.Matchers.Request
/// 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, [NotNull] params string[] methods)
public RequestMessageMethodMatcher(MatchBehaviour matchBehaviour, MatchOperator matchOperator, params string[] methods)
{
Guard.NotNull(methods, nameof(methods));
_matchBehaviour = matchBehaviour;
Methods = methods;
Methods = Guard.NotNull(methods);
MatchBehaviour = matchBehaviour;
MatchOperator = matchOperator;
}
/// <inheritdoc />
public double GetMatchingScore(IRequestMessage requestMessage, IRequestMatchResult requestMatchResult)
{
double score = MatchBehaviourHelper.Convert(_matchBehaviour, IsMatch(requestMessage));
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));
}
var scores = Methods.Select(m => string.Equals(m, requestMessage.Method, StringComparison.OrdinalIgnoreCase)).ToArray();
return MatchScores.ToScore(scores, MatchOperator);
}
}

View File

@@ -1,12 +1,11 @@
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>
@@ -17,22 +16,22 @@ namespace WireMock.Matchers.Request
/// <summary>
/// The funcs
/// </summary>
public Func<IDictionary<string, WireMockList<string>>, bool>[] Funcs { get; }
public Func<IDictionary<string, WireMockList<string>>, bool>[]? Funcs { get; }
/// <summary>
/// The key
/// </summary>
public string Key { get; }
public string? Key { get; }
/// <summary>
/// Defines if the key should be matched using case-ignore.
/// </summary>
public bool? IgnoreCase { get; private set; }
public bool? IgnoreCase { get; }
/// <summary>
/// The matchers.
/// </summary>
public IReadOnlyList<IStringMatcher> Matchers { get; }
public IReadOnlyList<IStringMatcher>? Matchers { get; }
/// <summary>
/// Initializes a new instance of the <see cref="RequestMessageParamMatcher"/> class.
@@ -40,7 +39,7 @@ namespace WireMock.Matchers.Request
/// <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)
public RequestMessageParamMatcher(MatchBehaviour matchBehaviour, string key, bool ignoreCase) : this(matchBehaviour, key, ignoreCase, (IStringMatcher[]?)null)
{
}
@@ -51,7 +50,7 @@ namespace WireMock.Matchers.Request
/// <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())
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())
{
}
@@ -62,12 +61,10 @@ namespace WireMock.Matchers.Request
/// <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)
public RequestMessageParamMatcher(MatchBehaviour matchBehaviour, string key, bool ignoreCase, IStringMatcher[]? matchers)
{
Guard.NotNull(key, nameof(key));
_matchBehaviour = matchBehaviour;
Key = key;
Key = Guard.NotNull(key);
IgnoreCase = ignoreCase;
Matchers = matchers;
}
@@ -76,11 +73,9 @@ namespace WireMock.Matchers.Request
/// 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)
public RequestMessageParamMatcher(params Func<IDictionary<string, WireMockList<string>>, bool>[] funcs)
{
Guard.NotNull(funcs, nameof(funcs));
Funcs = funcs;
Funcs = Guard.NotNull(funcs);
}
/// <inheritdoc />
@@ -97,7 +92,7 @@ namespace WireMock.Matchers.Request
return MatchScores.ToScore(requestMessage.Query != null && Funcs.Any(f => f(requestMessage.Query)));
}
WireMockList<string> valuesPresentInRequestMessage = ((RequestMessage) requestMessage).GetParameter(Key, IgnoreCase ?? false);
var valuesPresentInRequestMessage = ((RequestMessage)requestMessage).GetParameter(Key!, IgnoreCase ?? false);
if (valuesPresentInRequestMessage == null)
{
// Key is not present at all, just return Mismatch
@@ -107,7 +102,7 @@ namespace WireMock.Matchers.Request
if (Matchers != null && Matchers.Any())
{
// Return the score based on Matchers and valuesPresentInRequestMessage
return CalculateScore(valuesPresentInRequestMessage);
return CalculateScore(Matchers, valuesPresentInRequestMessage);
}
if (Matchers == null || !Matchers.Any())
@@ -119,14 +114,14 @@ namespace WireMock.Matchers.Request
return MatchScores.Mismatch;
}
private double CalculateScore(WireMockList<string> valuesPresentInRequestMessage)
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)
if (matchers.Sum(m => m.GetPatterns().Length) > valuesPresentInRequestMessage.Count)
{
foreach (var matcher in Matchers)
foreach (var matcher in matchers)
{
double score = 0d;
foreach (string valuePresentInRequestMessage in valuesPresentInRequestMessage)
@@ -141,12 +136,11 @@ namespace WireMock.Matchers.Request
{
foreach (string valuePresentInRequestMessage in valuesPresentInRequestMessage)
{
double score = Matchers.Max(m => m.IsMatch(valuePresentInRequestMessage));
double score = matchers.Max(m => m.IsMatch(valuePresentInRequestMessage));
total.Add(score);
}
}
return total.Any() ? MatchScores.ToScore(total) : MatchScores.Mismatch;
}
return total.Any() ? MatchScores.ToScore(total, MatchOperator.Average) : MatchScores.Mismatch;
}
}

View File

@@ -1,11 +1,12 @@
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>
@@ -14,45 +15,64 @@ namespace WireMock.Matchers.Request
/// <summary>
/// The matchers
/// </summary>
public IReadOnlyList<IStringMatcher> Matchers { get; }
public IReadOnlyList<IStringMatcher>? Matchers { get; }
/// <summary>
/// The path functions
/// </summary>
public Func<string, bool>[] Funcs { get; }
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, [NotNull] params string[] paths) : this(paths.Select(path => new WildcardMatcher(matchBehaviour, path)).Cast<IStringMatcher>().ToArray())
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())
{
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="matchOperator">The <see cref="MatchOperator"/> to use.</param>
/// <param name="matchers">The matchers.</param>
public RequestMessagePathMatcher([NotNull] params IStringMatcher[] matchers)
public RequestMessagePathMatcher(MatchBehaviour matchBehaviour, MatchOperator matchOperator, params IStringMatcher[] matchers)
{
Guard.NotNull(matchers, nameof(matchers));
Matchers = matchers;
Matchers = Guard.NotNull(matchers);
Behaviour = matchBehaviour;
MatchOperator = 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)
public RequestMessagePathMatcher(params Func<string, bool>[] funcs)
{
Guard.NotNull(funcs, nameof(funcs));
Funcs = funcs;
Funcs = Guard.NotNull(funcs);
}
/// <inheritdoc cref="IRequestMatcher.GetMatchingScore"/>
/// <inheritdoc />
public double GetMatchingScore(IRequestMessage requestMessage, IRequestMatchResult requestMatchResult)
{
double score = IsMatch(requestMessage);
@@ -63,15 +83,16 @@ namespace WireMock.Matchers.Request
{
if (Matchers != null)
{
return Matchers.Max(m => m.IsMatch(requestMessage.Path));
var results = Matchers.Select(m => m.IsMatch(requestMessage.Path)).ToArray();
return MatchScores.ToScore(results, MatchOperator);
}
if (Funcs != null)
{
return MatchScores.ToScore(requestMessage.Path != null && Funcs.Any(func => func(requestMessage.Path)));
var results = Funcs.Select(func => func(requestMessage.Path)).ToArray();
return MatchScores.ToScore(results, MatchOperator);
}
return MatchScores.Mismatch;
}
}
}

View File

@@ -1,53 +1,75 @@
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 matchers.
/// The matchers
/// </summary>
public IReadOnlyList<IStringMatcher> Matchers { get; }
public IReadOnlyList<IStringMatcher>? Matchers { get; }
/// <summary>
/// The url functions.
/// The url functions
/// </summary>
public Func<string, bool>[] Funcs { get; }
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, [NotNull] params string[] urls) : this(urls.Select(url => new WildcardMatcher(matchBehaviour, url)).Cast<IStringMatcher>().ToArray())
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())
{
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="matchOperator">The <see cref="MatchOperator"/> to use. (default = "Or")</param>
/// <param name="matchers">The matchers.</param>
public RequestMessageUrlMatcher([NotNull] params IStringMatcher[] matchers)
public RequestMessageUrlMatcher(MatchBehaviour matchBehaviour, MatchOperator matchOperator, params IStringMatcher[] matchers)
{
Guard.NotNull(matchers, nameof(matchers));
Matchers = matchers;
Matchers = Guard.NotNull(matchers);
Behaviour = matchBehaviour;
MatchOperator = 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)
public RequestMessageUrlMatcher(params Func<string, bool>[] funcs)
{
Guard.NotNull(funcs, nameof(funcs));
Funcs = funcs;
Funcs = Guard.NotNull(funcs);
}
/// <inheritdoc />
@@ -61,15 +83,16 @@ namespace WireMock.Matchers.Request
{
if (Matchers != null)
{
return Matchers.Max(matcher => matcher.IsMatch(requestMessage.Url));
var results = Matchers.Select(m => m.IsMatch(requestMessage.Url)).ToArray();
return MatchScores.ToScore(results, MatchOperator);
}
if (Funcs != null)
{
return MatchScores.ToScore(requestMessage.Url != null && Funcs.Any(func => func(requestMessage.Url)));
var results = Funcs.Select(func => func(requestMessage.Url)).ToArray();
return MatchScores.ToScore(results, MatchOperator);
}
return MatchScores.Mismatch;
}
}
}

View File

@@ -1,15 +1,14 @@
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>
@@ -30,7 +29,7 @@ namespace WireMock.Matchers
/// </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)
public SimMetricsMatcher(AnyOf<string, StringPattern> pattern, SimMetricType simMetricType = SimMetricType.Levenstein) : this(new[] { pattern }, simMetricType)
{
}
@@ -40,7 +39,7 @@ namespace WireMock.Matchers
/// <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)
public SimMetricsMatcher(MatchBehaviour matchBehaviour, AnyOf<string, StringPattern> pattern, SimMetricType simMetricType = SimMetricType.Levenstein) : this(matchBehaviour, new[] { pattern }, simMetricType)
{
}
@@ -49,7 +48,7 @@ namespace WireMock.Matchers
/// </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)
public SimMetricsMatcher(string[] patterns, SimMetricType simMetricType = SimMetricType.Levenstein) : this(MatchBehaviour.AcceptOnMatch, patterns.ToAnyOfPatterns(), simMetricType)
{
}
@@ -58,7 +57,7 @@ namespace WireMock.Matchers
/// </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)
public SimMetricsMatcher(AnyOf<string, StringPattern>[] patterns, SimMetricType simMetricType = SimMetricType.Levenstein) : this(MatchBehaviour.AcceptOnMatch, patterns, simMetricType)
{
}
@@ -69,15 +68,19 @@ namespace WireMock.Matchers
/// <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)
/// <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)
{
Guard.NotNull(patterns, nameof(patterns));
_patterns = Guard.NotNull(patterns);
_simMetricType = simMetricType;
MatchBehaviour = matchBehaviour;
ThrowException = throwException;
_patterns = patterns;
_simMetricType = simMetricType;
MatchOperator = matchOperator;
}
/// <inheritdoc cref="IStringMatcher.IsMatch"/>
@@ -85,7 +88,8 @@ namespace WireMock.Matchers
{
IStringMetric stringMetricType = GetStringMetricType();
return MatchBehaviourHelper.Convert(MatchBehaviour, MatchScores.ToScore(_patterns.Select(p => stringMetricType.GetSimilarity(p.GetPattern(), input))));
var score = MatchScores.ToScore(_patterns.Select(p => stringMetricType.GetSimilarity(p.GetPattern(), input)).ToArray(), MatchOperator);
return MatchBehaviourHelper.Convert(MatchBehaviour, score);
}
private IStringMetric GetStringMetricType()
@@ -137,7 +141,9 @@ namespace WireMock.Matchers
return _patterns;
}
/// <inheritdoc />
public MatchOperator MatchOperator { get; } = MatchOperator.Average;
/// <inheritdoc cref="IMatcher.Name"/>
public string Name => $"SimMetricsMatcher.{_simMetricType}";
}
}

View File

@@ -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(@"\?", ".") + "$",

View File

@@ -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";
}

View File

@@ -1,5 +1,5 @@
namespace WireMock.Models
{
namespace WireMock.Models;
/// <summary>
/// StringPattern which defines the Pattern as a string, and optionally the filepath pattern file.
/// </summary>
@@ -13,6 +13,5 @@ namespace WireMock.Models
/// <summary>
/// The filepath (optionally)
/// </summary>
public string PatternAsFile { get; set; }
}
public string? PatternAsFile { get; set; }
}

View File

@@ -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; }

View File

@@ -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

View File

@@ -1,13 +1,12 @@
namespace WireMock.Pact.Models.V2
{
namespace WireMock.Pact.Models.V2;
public class Interaction
{
public string Description { get; set; } = string.Empty;
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();
}

View File

@@ -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; }

View File

@@ -2,7 +2,7 @@ using System.Collections.Generic;
namespace WireMock.Pact.Models.V2;
public class Response
public class PactResponse
{
public object? Body { get; set; }

View File

@@ -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,24 +11,23 @@ using WireMock.ResponseBuilders;
using WireMock.Settings;
using WireMock.Types;
using WireMock.Util;
using Stef.Validation;
namespace WireMock.Proxy
{
namespace WireMock.Proxy;
internal class ProxyHelper
{
private readonly WireMockServerSettings _settings;
public ProxyHelper([NotNull] WireMockServerSettings settings)
public ProxyHelper(WireMockServerSettings settings)
{
_settings = Guard.NotNull(settings, nameof(settings));
_settings = Guard.NotNull(settings);
}
public async Task<(IResponseMessage Message, IMapping Mapping)> SendAsync(
[NotNull] ProxyAndRecordSettings proxyAndRecordSettings,
[NotNull] HttpClient client,
[NotNull] IRequestMessage requestMessage,
[NotNull] string url)
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));
@@ -49,7 +48,7 @@ namespace WireMock.Proxy
var responseMessage = await HttpResponseMessageHelper.CreateAsync(httpResponseMessage, requiredUri, originalUri, deserializeJson, decompressGzipAndDeflate).ConfigureAwait(false);
IMapping mapping = null;
IMapping? mapping = null;
if (HttpStatusRangeParser.IsMatch(proxyAndRecordSettings.SaveMappingForStatusCodePattern, responseMessage.StatusCode) &&
(proxyAndRecordSettings.SaveMapping || proxyAndRecordSettings.SaveMappingToFile))
{
@@ -61,15 +60,15 @@ namespace WireMock.Proxy
private IMapping ToMapping(ProxyAndRecordSettings proxyAndRecordSettings, IRequestMessage requestMessage, ResponseMessage responseMessage)
{
string[] excludedHeaders = proxyAndRecordSettings.ExcludedHeaders ?? new string[] { };
string[] excludedCookies = proxyAndRecordSettings.ExcludedCookies ?? new string[] { };
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) =>
requestMessage.Query?.Loop((key, value) => request.WithParam(key, false, value.ToArray()));
requestMessage.Cookies?.Loop((key, value) =>
{
if (!excludedCookies.Contains(key, StringComparer.OrdinalIgnoreCase))
{
@@ -78,7 +77,7 @@ namespace WireMock.Proxy
});
var allExcludedHeaders = new List<string>(excludedHeaders) { "Cookie" };
requestMessage.Headers.Loop((key, value) =>
requestMessage.Headers?.Loop((key, value) =>
{
if (!allExcludedHeaders.Contains(key, StringComparer.OrdinalIgnoreCase))
{
@@ -90,11 +89,11 @@ namespace WireMock.Proxy
switch (requestMessage.BodyData?.DetectedBodyType)
{
case BodyType.Json:
request.WithBody(new JsonMatcher(MatchBehaviour.AcceptOnMatch, requestMessage.BodyData.BodyAsJson, true, throwExceptionWhenMatcherFails));
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));
request.WithBody(new ExactMatcher(MatchBehaviour.AcceptOnMatch, throwExceptionWhenMatcherFails, MatchOperator.Or, requestMessage.BodyData.BodyAsString));
break;
case BodyType.Bytes:
@@ -107,4 +106,3 @@ namespace WireMock.Proxy
return new Mapping(Guid.NewGuid(), string.Empty, string.Empty, null, _settings, request, response, 0, null, null, null, null, null, null);
}
}
}

View File

@@ -3,8 +3,8 @@ 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>
@@ -38,7 +38,7 @@ namespace WireMock.RegularExpressions
}
#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>
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}\})" },
@@ -87,4 +87,3 @@ namespace WireMock.RegularExpressions
return pattern;
}
}
}

View File

@@ -1,11 +1,10 @@
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>
@@ -16,14 +15,15 @@ namespace WireMock.RequestBuilders
/// </summary>
/// <param name="matcher">The matcher.</param>
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
IRequestBuilder WithBody([NotNull] IMatcher matcher);
IRequestBuilder WithBody(IMatcher matcher);
/// <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([NotNull] IMatcher[] matchers);
IRequestBuilder WithBody(IMatcher[] matchers, MatchOperator matchOperator = MatchOperator.Or);
/// <summary>
/// WithBody: Body as string
@@ -54,27 +54,26 @@ namespace WireMock.RequestBuilders
/// </summary>
/// <param name="func">The function.</param>
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
IRequestBuilder WithBody([NotNull] Func<string, bool> func);
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);
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);
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);
}
IRequestBuilder WithBody(Func<IBodyData, bool> func);
}

View File

@@ -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>
/// WithClientIP: add matching on ClientIP matchers.
/// WithClientIP: add clientIP matching based on IStringMatchers.
/// </summary>
/// <param name="matchers">The matchers.</param>
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
IRequestBuilder WithClientIP([NotNull] params IStringMatcher[] matchers);
IRequestBuilder WithClientIP(params IStringMatcher[] matchers);
/// <summary>
/// WithClientIP: add matching on clientIPs.
/// 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 clientIP matching based on clientIPs.
/// </summary>
/// <param name="clientIPs">The clientIPs.</param>
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
IRequestBuilder WithClientIP([NotNull] params string[] clientIPs);
IRequestBuilder WithClientIP(params string[] clientIPs);
/// <summary>
/// WithClientIP: add matching on clientIPs and matchBehaviour.
/// WithClientIP: add clientIP matching based on clientIPs , matchBehaviour and MatchOperator.
/// </summary>
/// <param name="matchBehaviour">The match behaviour.</param>
/// <param name="matchOperator">The <see cref="MatchOperator"/> to use.</param>
/// <param name="clientIPs">The clientIPs.</param>
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
IRequestBuilder WithClientIP(MatchBehaviour matchBehaviour, [NotNull] params string[] clientIPs);
IRequestBuilder WithClientIP(MatchOperator matchOperator, params string[] clientIPs);
/// <summary>
/// WithClientIP: add matching on ClientIP funcs.
/// WithClientIP: add clientIP matching based on functions.
/// </summary>
/// <param name="funcs">The path funcs.</param>
/// <param name="funcs">The clientIP funcs.</param>
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
IRequestBuilder WithClientIP([NotNull] params Func<string, bool>[] funcs);
}
IRequestBuilder WithClientIP(params Func<string, bool>[] funcs);
}

View File

@@ -1,10 +1,9 @@
using JetBrains.Annotations;
using System;
using System.Collections.Generic;
using WireMock.Matchers;
namespace WireMock.RequestBuilders
{
namespace WireMock.RequestBuilders;
/// <summary>
/// The HeadersRequestBuilder interface.
/// </summary>
@@ -17,7 +16,7 @@ namespace WireMock.RequestBuilders
/// <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);
IRequestBuilder WithHeader(string name, string pattern, MatchBehaviour matchBehaviour);
/// <summary>
/// WithHeader: matching based on name, pattern, ignoreCase and matchBehaviour.
@@ -27,7 +26,7 @@ namespace WireMock.RequestBuilders
/// <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);
IRequestBuilder WithHeader(string name, string pattern, bool ignoreCase = true, MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch);
/// <summary>
/// WithHeader: matching based on name, patterns and matchBehaviour.
@@ -35,8 +34,9 @@ namespace WireMock.RequestBuilders
/// <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([NotNull] string name, string[] patterns, MatchBehaviour matchBehaviour);
IRequestBuilder WithHeader(string name, string[] patterns, MatchBehaviour matchBehaviour, MatchOperator matchOperator = MatchOperator.Or);
/// <summary>
/// WithHeader: matching based on name, patterns, ignoreCase and matchBehaviour.
@@ -45,8 +45,9 @@ namespace WireMock.RequestBuilders
/// <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([NotNull] string name, string[] patterns, bool ignoreCase = true, MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch);
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[].
@@ -54,7 +55,7 @@ namespace WireMock.RequestBuilders
/// <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);
IRequestBuilder WithHeader(string name, params IStringMatcher[] matchers);
/// <summary>
/// WithHeader: matching based on name, ignoreCase and IStringMatcher[].
@@ -63,7 +64,7 @@ namespace WireMock.RequestBuilders
/// <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);
IRequestBuilder WithHeader(string name, bool ignoreCase, params IStringMatcher[] matchers);
/// <summary>
/// WithHeader: matching based on name, ignoreCase, matchBehaviour and IStringMatcher[].
@@ -71,15 +72,15 @@ namespace WireMock.RequestBuilders
/// <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([NotNull] string name, bool ignoreCase, MatchBehaviour matchBehaviour, [NotNull] params IStringMatcher[] matchers);
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);
}
IRequestBuilder WithHeader(params Func<IDictionary<string, string[]>, bool>[] funcs);
}

View File

@@ -1,9 +1,9 @@
using System;
using System;
using JetBrains.Annotations;
using WireMock.Matchers;
namespace WireMock.RequestBuilders
{
namespace WireMock.RequestBuilders;
/// <summary>
/// The MethodRequestBuilder interface.
/// </summary>
@@ -78,34 +78,19 @@ namespace WireMock.RequestBuilders
/// <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, [NotNull] params string[] methods);
IRequestBuilder UsingMethod(MatchBehaviour matchBehaviour, MatchOperator matchOperator, 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);
}
IRequestBuilder UsingMethod(params string[] methods);
}

View File

@@ -1,11 +1,10 @@
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>
@@ -17,7 +16,7 @@ namespace WireMock.RequestBuilders
/// <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);
IRequestBuilder WithParam(string key, MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch);
/// <summary>
/// WithParam: matching on key only.
@@ -26,7 +25,7 @@ namespace WireMock.RequestBuilders
/// <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);
IRequestBuilder WithParam(string key, bool ignoreCase, MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch);
/// <summary>
/// WithParam: matching on key and values.
@@ -34,7 +33,7 @@ namespace WireMock.RequestBuilders
/// <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);
IRequestBuilder WithParam(string key, params string[] values);
/// <summary>
/// WithParam: matching on key and values.
@@ -43,7 +42,7 @@ namespace WireMock.RequestBuilders
/// <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);
IRequestBuilder WithParam(string key, bool ignoreCase, params string[] values);
/// <summary>
/// WithParam: matching on key and matchers.
@@ -51,7 +50,7 @@ namespace WireMock.RequestBuilders
/// <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);
IRequestBuilder WithParam(string key, params IStringMatcher[] matchers);
/// <summary>
/// WithParam: matching on key and matchers.
@@ -60,7 +59,7 @@ namespace WireMock.RequestBuilders
/// <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);
IRequestBuilder WithParam(string key, bool ignoreCase, params IStringMatcher[] matchers);
/// <summary>
/// WithParam: matching on key, values and matchBehaviour.
@@ -69,7 +68,7 @@ namespace WireMock.RequestBuilders
/// <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);
IRequestBuilder WithParam(string key, MatchBehaviour matchBehaviour, params string[] values);
/// <summary>
/// WithParam: matching on key, values and matchBehaviour.
@@ -79,7 +78,7 @@ namespace WireMock.RequestBuilders
/// <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);
IRequestBuilder WithParam(string key, MatchBehaviour matchBehaviour, bool ignoreCase = false, params string[] values);
/// <summary>
/// WithParam: matching on key, matchers and matchBehaviour.
@@ -88,7 +87,7 @@ namespace WireMock.RequestBuilders
/// <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);
IRequestBuilder WithParam(string key, MatchBehaviour matchBehaviour, params IStringMatcher[] matchers);
/// <summary>
/// WithParam: matching on key, matchers and matchBehaviour.
@@ -98,13 +97,12 @@ namespace WireMock.RequestBuilders
/// <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);
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);
}
IRequestBuilder WithParam(params Func<IDictionary<string, WireMockList<string>>, bool>[] funcs);
}

View File

@@ -1,9 +1,8 @@
using System;
using JetBrains.Annotations;
using System;
using WireMock.Matchers;
namespace WireMock.RequestBuilders
{
namespace WireMock.RequestBuilders;
/// <summary>
/// IUrlAndPathRequestBuilder
/// </summary>
@@ -14,57 +13,72 @@ namespace WireMock.RequestBuilders
/// </summary>
/// <param name="matchers">The matchers.</param>
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
IRequestBuilder WithPath([NotNull] params IStringMatcher[] matchers);
IRequestBuilder WithPath(params IStringMatcher[] matchers);
/// <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.
/// </summary>
/// <param name="paths">The paths.</param>
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
IRequestBuilder WithPath([NotNull] params string[] paths);
IRequestBuilder WithPath(params string[] paths);
/// <summary>
/// WithPath: add path matching based on paths and matchBehaviour.
/// WithPath: add path matching based on paths , matchBehaviour and MatchOperator.
/// </summary>
/// <param name="matchBehaviour">The match behaviour.</param>
/// <param name="matchOperator">The <see cref="MatchOperator"/> to use.</param>
/// <param name="paths">The paths.</param>
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
IRequestBuilder WithPath(MatchBehaviour matchBehaviour, [NotNull] params string[] paths);
IRequestBuilder WithPath(MatchOperator matchOperator, 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);
IRequestBuilder WithPath(params Func<string, bool>[] funcs);
/// <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);
IRequestBuilder WithUrl(params IStringMatcher[] matchers);
/// <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 urls.
/// </summary>
/// <param name="urls">The urls.</param>
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
IRequestBuilder WithUrl([NotNull] params string[] urls);
IRequestBuilder WithUrl(params string[] urls);
/// <summary>
/// WithUrl: add url matching based on urls.
/// </summary>
/// <param name="matchBehaviour">The match behaviour.</param>
/// <param name="matchOperator">The <see cref="MatchOperator"/> to use.</param>
/// <param name="urls">The urls.</param>
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
IRequestBuilder WithUrl(MatchBehaviour matchBehaviour, [NotNull] params string[] urls);
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([NotNull] params Func<string, bool>[] funcs);
}
IRequestBuilder WithUrl(params Func<string, bool>[] funcs);
}

View 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;
}
}

View File

@@ -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,74 +6,74 @@ using WireMock.Matchers;
using WireMock.Matchers.Request;
using Stef.Validation;
namespace WireMock.RequestBuilders
{
namespace WireMock.RequestBuilders;
public partial class Request
{
/// <inheritdoc cref="IMethodRequestBuilder.UsingConnect(MatchBehaviour)"/>
/// <inheritdoc />
public IRequestBuilder UsingConnect(MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
{
_requestMatchers.Add(new RequestMessageMethodMatcher(matchBehaviour, HttpRequestMethods.CONNECT));
_requestMatchers.Add(new RequestMessageMethodMatcher(matchBehaviour, MatchOperator.Or, HttpRequestMethods.CONNECT));
return this;
}
/// <inheritdoc cref="IMethodRequestBuilder.UsingDelete(MatchBehaviour)"/>
/// <inheritdoc />
public IRequestBuilder UsingDelete(MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
{
_requestMatchers.Add(new RequestMessageMethodMatcher(matchBehaviour, HttpRequestMethods.DELETE));
_requestMatchers.Add(new RequestMessageMethodMatcher(matchBehaviour, MatchOperator.Or, HttpRequestMethods.DELETE));
return this;
}
/// <inheritdoc cref="IMethodRequestBuilder.UsingGet(MatchBehaviour)"/>
/// <inheritdoc />
public IRequestBuilder UsingGet(MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
{
_requestMatchers.Add(new RequestMessageMethodMatcher(matchBehaviour, HttpRequestMethods.GET));
_requestMatchers.Add(new RequestMessageMethodMatcher(matchBehaviour, MatchOperator.Or, HttpRequestMethods.GET));
return this;
}
/// <inheritdoc cref="IMethodRequestBuilder.UsingHead(MatchBehaviour)"/>
/// <inheritdoc />
public IRequestBuilder UsingHead(MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
{
_requestMatchers.Add(new RequestMessageMethodMatcher(matchBehaviour, HttpRequestMethods.HEAD));
_requestMatchers.Add(new RequestMessageMethodMatcher(matchBehaviour, MatchOperator.Or, HttpRequestMethods.HEAD));
return this;
}
/// <inheritdoc cref="IMethodRequestBuilder.UsingOptions(MatchBehaviour)"/>
/// <inheritdoc />
public IRequestBuilder UsingOptions(MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
{
_requestMatchers.Add(new RequestMessageMethodMatcher(matchBehaviour, HttpRequestMethods.OPTIONS));
_requestMatchers.Add(new RequestMessageMethodMatcher(matchBehaviour, MatchOperator.Or, HttpRequestMethods.OPTIONS));
return this;
}
/// <inheritdoc cref="IMethodRequestBuilder.UsingPost(MatchBehaviour)"/>
/// <inheritdoc />
public IRequestBuilder UsingPost(MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
{
_requestMatchers.Add(new RequestMessageMethodMatcher(matchBehaviour, HttpRequestMethods.POST));
_requestMatchers.Add(new RequestMessageMethodMatcher(matchBehaviour, MatchOperator.Or, HttpRequestMethods.POST));
return this;
}
/// <inheritdoc cref="IMethodRequestBuilder.UsingPatch(MatchBehaviour)"/>
/// <inheritdoc />
public IRequestBuilder UsingPatch(MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
{
_requestMatchers.Add(new RequestMessageMethodMatcher(matchBehaviour, HttpRequestMethods.PATCH));
_requestMatchers.Add(new RequestMessageMethodMatcher(matchBehaviour, MatchOperator.Or, HttpRequestMethods.PATCH));
return this;
}
/// <inheritdoc cref="IMethodRequestBuilder.UsingPut(MatchBehaviour)"/>
/// <inheritdoc />
public IRequestBuilder UsingPut(MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
{
_requestMatchers.Add(new RequestMessageMethodMatcher(matchBehaviour, HttpRequestMethods.PUT));
_requestMatchers.Add(new RequestMessageMethodMatcher(matchBehaviour, MatchOperator.Or, HttpRequestMethods.PUT));
return this;
}
/// <inheritdoc cref="IMethodRequestBuilder.UsingTrace(MatchBehaviour)"/>
/// <inheritdoc />
public IRequestBuilder UsingTrace(MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
{
_requestMatchers.Add(new RequestMessageMethodMatcher(matchBehaviour, HttpRequestMethods.TRACE));
_requestMatchers.Add(new RequestMessageMethodMatcher(matchBehaviour, MatchOperator.Or, HttpRequestMethods.TRACE));
return this;
}
/// <inheritdoc cref="IMethodRequestBuilder.UsingAnyMethod"/>
/// <inheritdoc />
public IRequestBuilder UsingAnyMethod()
{
var matchers = _requestMatchers.Where(m => m is RequestMessageMethodMatcher).ToList();
@@ -85,31 +85,18 @@ namespace WireMock.RequestBuilders
return this;
}
/// <inheritdoc cref="IMethodRequestBuilder.UsingAnyVerb"/>
public IRequestBuilder UsingAnyVerb()
{
return UsingAnyMethod();
}
/// <inheritdoc cref="IMethodRequestBuilder.UsingMethod(string[])"/>
/// <inheritdoc />
public IRequestBuilder UsingMethod(params string[] methods)
{
return UsingMethod(MatchBehaviour.AcceptOnMatch, methods);
return UsingMethod(MatchBehaviour.AcceptOnMatch, MatchOperator.Or, methods);
}
/// <inheritdoc cref="IMethodRequestBuilder.UsingVerb(string[])"/>
public IRequestBuilder UsingVerb(params string[] verbs)
/// <inheritdoc />
public IRequestBuilder UsingMethod(MatchBehaviour matchBehaviour, MatchOperator matchOperator, params string[] methods)
{
return UsingMethod(verbs);
}
Guard.NotNullOrEmpty(methods);
/// <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));
_requestMatchers.Add(new RequestMessageMethodMatcher(matchBehaviour, matchOperator, methods));
return this;
}
}
}

View File

@@ -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,8 +6,8 @@ using WireMock.Matchers.Request;
using WireMock.Util;
using Stef.Validation;
namespace WireMock.RequestBuilders
{
namespace WireMock.RequestBuilders;
public partial class Request
{
/// <inheritdoc cref="IBodyRequestBuilder.WithBody(string, MatchBehaviour)"/>
@@ -31,18 +31,18 @@ namespace WireMock.RequestBuilders
return this;
}
/// <inheritdoc cref="IBodyRequestBuilder.WithBody(IMatcher[])"/>
/// <inheritdoc />
public IRequestBuilder WithBody(IMatcher matcher)
{
return WithBody(new[] { matcher });
}
/// <inheritdoc cref="IBodyRequestBuilder.WithBody(IMatcher[])"/>
public IRequestBuilder WithBody(IMatcher[] matchers)
/// <inheritdoc />
public IRequestBuilder WithBody(IMatcher[] matchers, MatchOperator matchOperator = MatchOperator.Or)
{
Guard.NotNull(matchers, nameof(matchers));
Guard.NotNull(matchers);
_requestMatchers.Add(new RequestMessageBodyMatcher(matchers));
_requestMatchers.Add(new RequestMessageBodyMatcher(matchOperator, matchers));
return this;
}
@@ -82,4 +82,3 @@ namespace WireMock.RequestBuilders
return this;
}
}
}

View File

@@ -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,8 +6,8 @@ using WireMock.Matchers;
using WireMock.Matchers.Request;
using Stef.Validation;
namespace WireMock.RequestBuilders
{
namespace WireMock.RequestBuilders;
public partial class Request
{
/// <inheritdoc cref="IHeadersRequestBuilder.WithHeader(string, string, MatchBehaviour)"/>
@@ -19,66 +19,65 @@ namespace WireMock.RequestBuilders
/// <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));
Guard.NotNull(name);
Guard.NotNull(pattern);
_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)
/// <inheritdoc />
public IRequestBuilder WithHeader(string name, string[] patterns, MatchBehaviour matchBehaviour, MatchOperator matchOperator = MatchOperator.Or)
{
return WithHeader(name, patterns, true, matchBehaviour);
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)
/// <inheritdoc />
public IRequestBuilder WithHeader(string name, string[] patterns, bool ignoreCase = true, MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch, MatchOperator matchOperator = MatchOperator.Or)
{
Guard.NotNull(name, nameof(name));
Guard.NotNull(patterns, nameof(patterns));
Guard.NotNull(name);
Guard.NotNull(patterns);
_requestMatchers.Add(new RequestMessageHeaderMatcher(matchBehaviour, name, ignoreCase, patterns));
_requestMatchers.Add(new RequestMessageHeaderMatcher(matchBehaviour, matchOperator, name, ignoreCase, patterns));
return this;
}
/// <inheritdoc cref="IHeadersRequestBuilder.WithHeader(string, IStringMatcher[])"/>
/// <inheritdoc />
public IRequestBuilder WithHeader(string name, params IStringMatcher[] matchers)
{
Guard.NotNull(name, nameof(name));
Guard.NotNullOrEmpty(matchers, nameof(matchers));
Guard.NotNull(name);
Guard.NotNullOrEmpty(matchers);
_requestMatchers.Add(new RequestMessageHeaderMatcher(MatchBehaviour.AcceptOnMatch, name, false, matchers));
_requestMatchers.Add(new RequestMessageHeaderMatcher(MatchBehaviour.AcceptOnMatch, MatchOperator.Or, name, false, matchers));
return this;
}
/// <inheritdoc cref="IHeadersRequestBuilder.WithHeader(string, bool, IStringMatcher[])"/>
/// <inheritdoc />
public IRequestBuilder WithHeader(string name, bool ignoreCase, params IStringMatcher[] matchers)
{
Guard.NotNull(name, nameof(name));
Guard.NotNullOrEmpty(matchers, nameof(matchers));
Guard.NotNull(name);
Guard.NotNullOrEmpty(matchers);
_requestMatchers.Add(new RequestMessageHeaderMatcher(MatchBehaviour.AcceptOnMatch, name, ignoreCase, matchers));
_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)
/// <inheritdoc />
public IRequestBuilder WithHeader(string name, bool ignoreCase, MatchBehaviour matchBehaviour, MatchOperator matchOperator, params IStringMatcher[] matchers)
{
Guard.NotNull(name, nameof(name));
Guard.NotNullOrEmpty(matchers, nameof(matchers));
Guard.NotNull(name);
Guard.NotNullOrEmpty(matchers);
_requestMatchers.Add(new RequestMessageHeaderMatcher(matchBehaviour, name, ignoreCase, matchers));
_requestMatchers.Add(new RequestMessageHeaderMatcher(matchBehaviour, matchOperator, name, ignoreCase, matchers));
return this;
}
/// <inheritdoc cref="IHeadersRequestBuilder.WithHeader(Func{IDictionary{string, string[]}, bool}[])"/>
/// <inheritdoc />
public IRequestBuilder WithHeader(params Func<IDictionary<string, string[]>, bool>[] funcs)
{
Guard.NotNullOrEmpty(funcs, nameof(funcs));
Guard.NotNullOrEmpty(funcs);
_requestMatchers.Add(new RequestMessageHeaderMatcher(funcs));
return this;
}
}
}

View File

@@ -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;

View 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;
}
}

View 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;
}
}
}

View File

@@ -1,17 +1,16 @@
// 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 requests.
/// The Request Builder
/// </summary>
public partial class Request : RequestMessageCompositeMatcher, IRequestBuilder
{
@@ -32,7 +31,7 @@ namespace WireMock.RequestBuilders
/// <param name="requestMatchers">The request matchers.</param>
private Request(IList<IRequestMatcher> requestMatchers) : base(requestMatchers)
{
_requestMatchers = requestMatchers;
_requestMatchers = Guard.NotNull(requestMatchers);
}
/// <summary>
@@ -50,7 +49,7 @@ namespace WireMock.RequestBuilders
/// </summary>
/// <typeparam name="T">Type of IRequestMatcher</typeparam>
/// <returns>A RequestMatcher</returns>
public T GetRequestMessageMatcher<T>() where T : IRequestMatcher
public T? GetRequestMessageMatcher<T>() where T : IRequestMatcher
{
return _requestMatchers.OfType<T>().FirstOrDefault();
}
@@ -60,108 +59,9 @@ namespace WireMock.RequestBuilders
/// </summary>
/// <typeparam name="T">Type of IRequestMatcher</typeparam>
/// <returns>A RequestMatcher</returns>
public T GetRequestMessageMatcher<T>(Func<T, bool> func) where T : IRequestMatcher
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;
}
}
}

View File

@@ -1,17 +1,16 @@
// 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>
@@ -48,19 +47,19 @@ namespace WireMock
public string Method { get; }
/// <inheritdoc cref="IRequestMessage.Headers" />
public IDictionary<string, WireMockList<string>> Headers { get; }
public IDictionary<string, WireMockList<string>>? Headers { get; }
/// <inheritdoc cref="IRequestMessage.Cookies" />
public IDictionary<string, string> Cookies { get; }
public IDictionary<string, string>? Cookies { get; }
/// <inheritdoc cref="IRequestMessage.Query" />
public IDictionary<string, WireMockList<string>> Query { get; }
public IDictionary<string, WireMockList<string>>? Query { get; }
/// <inheritdoc cref="IRequestMessage.RawQuery" />
public string RawQuery { get; }
/// <inheritdoc cref="IRequestMessage.BodyData" />
public IBodyData BodyData { get; }
public IBodyData? BodyData { get; }
/// <inheritdoc cref="IRequestMessage.Body" />
public string Body { get; }
@@ -101,7 +100,7 @@ namespace WireMock
/// <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)
public RequestMessage(UrlDetails urlDetails, string method, string clientIP, IBodyData? bodyData = null, IDictionary<string, string[]>? headers = null, IDictionary<string, string>? cookies = null)
{
Guard.NotNull(urlDetails, nameof(urlDetails));
Guard.NotNull(method, nameof(method));
@@ -144,7 +143,7 @@ namespace WireMock
/// <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)
public WireMockList<string>? GetParameter(string key, bool ignoreCase = false)
{
if (Query == null)
{
@@ -156,4 +155,3 @@ namespace WireMock
return query.ContainsKey(key) ? query[key] : null;
}
}
}

View File

@@ -1,9 +1,9 @@
using JetBrains.Annotations;
using JetBrains.Annotations;
using System.Collections.Generic;
using WireMock.Types;
namespace WireMock.ResponseBuilders
{
namespace WireMock.ResponseBuilders;
/// <summary>
/// The HeadersResponseBuilder interface.
/// </summary>
@@ -15,27 +15,26 @@ namespace WireMock.ResponseBuilders
/// <param name="name">The name.</param>
/// <param name="values">The values.</param>
/// <returns>The <see cref="IResponseBuilder"/>.</returns>
IResponseBuilder WithHeader([NotNull] string name, params string[] values);
IResponseBuilder WithHeader(string name, params string[] values);
/// <summary>
/// The with headers.
/// </summary>
/// <param name="headers">The headers.</param>
/// <returns>The <see cref="IResponseBuilder"/>.</returns>
IResponseBuilder WithHeaders([NotNull] IDictionary<string, string> headers);
IResponseBuilder WithHeaders(IDictionary<string, string> headers);
/// <summary>
/// The with headers.
/// </summary>
/// <param name="headers">The headers.</param>
/// <returns>The <see cref="IResponseBuilder"/>.</returns>
IResponseBuilder WithHeaders([NotNull] IDictionary<string, string[]> headers);
IResponseBuilder WithHeaders(IDictionary<string, string[]> headers);
/// <summary>
/// The with headers.
/// </summary>
/// <param name="headers">The headers.</param>
/// <returns>The <see cref="IResponseBuilder"/>.</returns>
IResponseBuilder WithHeaders([NotNull] IDictionary<string, WireMockList<string>> headers);
}
IResponseBuilder WithHeaders(IDictionary<string, WireMockList<string>> headers);
}

View File

@@ -3,8 +3,8 @@ using WireMock.Http;
using WireMock.Settings;
using Stef.Validation;
namespace WireMock.ResponseBuilders
{
namespace WireMock.ResponseBuilders;
public partial class Response
{
private HttpClient _httpClientForProxy;
@@ -12,12 +12,12 @@ namespace WireMock.ResponseBuilders
/// <summary>
/// The WebProxy settings.
/// </summary>
public ProxyAndRecordSettings ProxyAndRecordSettings { get; private set; }
public ProxyAndRecordSettings? ProxyAndRecordSettings { get; private set; }
/// <inheritdoc cref="IProxyResponseBuilder.WithProxy(string, string)"/>
public IResponseBuilder WithProxy(string proxyUrl, string clientX509Certificate2ThumbprintOrSubjectName = null)
/// <inheritdoc />
public IResponseBuilder WithProxy(string proxyUrl, string? clientX509Certificate2ThumbprintOrSubjectName = null)
{
Guard.NotNullOrEmpty(proxyUrl, nameof(proxyUrl));
Guard.NotNullOrEmpty(proxyUrl);
var settings = new ProxyAndRecordSettings
{
@@ -28,10 +28,10 @@ namespace WireMock.ResponseBuilders
return WithProxy(settings);
}
/// <inheritdoc cref="IProxyResponseBuilder.WithProxy(ProxyAndRecordSettings)"/>
/// <inheritdoc />
public IResponseBuilder WithProxy(ProxyAndRecordSettings settings)
{
Guard.NotNull(settings, nameof(settings));
Guard.NotNull(settings);
ProxyAndRecordSettings = settings;
@@ -39,4 +39,3 @@ namespace WireMock.ResponseBuilders
return this;
}
}
}

View File

@@ -15,7 +15,7 @@ namespace WireMock
public class ResponseMessage : IResponseMessage
{
/// <inheritdoc cref="IResponseMessage.Headers" />
public IDictionary<string, WireMockList<string>> Headers { get; set; } = new Dictionary<string, WireMockList<string>>();
public IDictionary<string, WireMockList<string>>? Headers { get; set; } = new Dictionary<string, WireMockList<string>>();
/// <inheritdoc cref="IResponseMessage.StatusCode" />
public object StatusCode { get; set; }

View File

@@ -4,14 +4,15 @@ using System.Linq;
using System.Threading;
using Stef.Validation;
using WireMock.Admin.Mappings;
using WireMock.Matchers;
using WireMock.Matchers.Request;
using WireMock.RequestBuilders;
using WireMock.ResponseBuilders;
using WireMock.Settings;
using WireMock.Types;
namespace WireMock.Serialization
{
namespace WireMock.Serialization;
internal class MappingConverter
{
private readonly MatcherMapper _mapper;
@@ -26,9 +27,9 @@ namespace WireMock.Serialization
var request = (Request)mapping.RequestMatcher;
var response = (Response)mapping.Provider;
var clientIPMatchers = request.GetRequestMessageMatchers<RequestMessageClientIPMatcher>().Where(m => m.Matchers != null).SelectMany(m => m.Matchers).ToList();
var pathMatchers = request.GetRequestMessageMatchers<RequestMessagePathMatcher>().Where(m => m.Matchers != null).SelectMany(m => m.Matchers).ToList();
var urlMatchers = request.GetRequestMessageMatchers<RequestMessageUrlMatcher>().Where(m => m.Matchers != null).SelectMany(m => m.Matchers).ToList();
var clientIPMatcher = request.GetRequestMessageMatcher<RequestMessageClientIPMatcher>();
var pathMatcher = request.GetRequestMessageMatcher<RequestMessagePathMatcher>();
var urlMatcher = request.GetRequestMessageMatcher<RequestMessageUrlMatcher>();
var headerMatchers = request.GetRequestMessageMatchers<RequestMessageHeaderMatcher>();
var cookieMatchers = request.GetRequestMessageMatchers<RequestMessageCookieMatcher>();
var paramsMatchers = request.GetRequestMessageMatchers<RequestMessageParamMatcher>();
@@ -41,29 +42,12 @@ namespace WireMock.Serialization
TimeSettings = TimeSettingsMapper.Map(mapping.TimeSettings),
Title = mapping.Title,
Description = mapping.Description,
Priority = mapping.Priority != 0 ? mapping.Priority : (int?)null,
Priority = mapping.Priority != 0 ? mapping.Priority : null,
Scenario = mapping.Scenario,
WhenStateIs = mapping.ExecutionConditionState,
SetStateTo = mapping.NextState,
Request = new RequestModel
{
ClientIP = clientIPMatchers.Any() ? new ClientIPModel
{
Matchers = _mapper.Map(clientIPMatchers)
} : null,
Path = pathMatchers.Any() ? new PathModel
{
Matchers = _mapper.Map(pathMatchers)
} : null,
Url = urlMatchers.Any() ? new UrlModel
{
Matchers = _mapper.Map(urlMatchers)
} : null,
Methods = methodMatcher?.Methods,
Headers = headerMatchers.Any() ? headerMatchers.Select(hm => new HeaderModel
{
Name = hm.Name,
@@ -79,13 +63,49 @@ namespace WireMock.Serialization
Params = paramsMatchers.Any() ? paramsMatchers.Select(pm => new ParamModel
{
Name = pm.Key,
IgnoreCase = pm.IgnoreCase == true ? true : (bool?)null,
IgnoreCase = pm.IgnoreCase == true ? true : null,
Matchers = _mapper.Map(pm.Matchers)
}).ToList() : null
},
Response = new ResponseModel()
};
if (methodMatcher is { Methods: { } })
{
mappingModel.Request.Methods = methodMatcher.Methods;
mappingModel.Request.MethodsRejectOnMatch = methodMatcher.MatchBehaviour == MatchBehaviour.RejectOnMatch ? true : null;
mappingModel.Request.MethodsMatchOperator = methodMatcher.Methods.Length > 1 ? methodMatcher.MatchOperator.ToString() : null;
}
if (clientIPMatcher is { Matchers: { } })
{
var clientIPMatchers = _mapper.Map(clientIPMatcher.Matchers);
mappingModel.Request.Path = new ClientIPModel
{
Matchers = clientIPMatchers,
MatchOperator = clientIPMatchers?.Length > 1 ? clientIPMatcher.MatchOperator.ToString() : null
};
}
if (pathMatcher is { Matchers: { } })
{
var pathMatchers = _mapper.Map(pathMatcher.Matchers);
mappingModel.Request.Path = new PathModel
{
Matchers = pathMatchers,
MatchOperator = pathMatchers?.Length > 1 ? pathMatcher.MatchOperator.ToString() : null
};
}
else if (urlMatcher is { Matchers: { } })
{
var urlMatchers = _mapper.Map(urlMatcher.Matchers);
mappingModel.Request.Url = new UrlModel
{
Matchers = urlMatchers,
MatchOperator = urlMatchers?.Length > 1 ? urlMatcher.MatchOperator.ToString() : null
};
}
if (response.MinimumDelayMilliseconds >= 0 || response.MaximumDelayMilliseconds > 0)
{
mappingModel.Response.MinimumRandomDelay = response.MinimumDelayMilliseconds;
@@ -116,6 +136,7 @@ namespace WireMock.Serialization
else if (bodyMatcher.Matchers.Length > 1)
{
mappingModel.Request.Body.Matchers = _mapper.Map(bodyMatcher.Matchers);
mappingModel.Request.Body.MatchOperator = bodyMatcher.MatchOperator.ToString();
}
}
@@ -212,7 +233,7 @@ namespace WireMock.Serialization
return mappingModel;
}
private static WebProxyModel MapWebProxy(WebProxySettings settings)
private static WebProxyModel? MapWebProxy(WebProxySettings? settings)
{
return settings != null ? new WebProxyModel
{
@@ -227,11 +248,10 @@ namespace WireMock.Serialization
var newDictionary = new Dictionary<string, object>();
foreach (var entry in dictionary)
{
object value = entry.Value.Count == 1 ? (object)entry.Value.ToString() : entry.Value;
object value = entry.Value.Count == 1 ? entry.Value.ToString() : entry.Value;
newDictionary.Add(entry.Key, value);
}
return newDictionary;
}
}
}

View File

@@ -9,9 +9,10 @@ using WireMock.Matchers;
using WireMock.Models;
using WireMock.Plugin;
using WireMock.Settings;
using WireMock.Util;
namespace WireMock.Serialization;
namespace WireMock.Serialization
{
internal class MatcherMapper
{
private readonly WireMockServerSettings _settings;
@@ -21,9 +22,13 @@ namespace WireMock.Serialization
_settings = settings ?? throw new ArgumentNullException(nameof(settings));
}
public IMatcher[] Map(IEnumerable<MatcherModel>? matchers)
public IMatcher[]? Map(IEnumerable<MatcherModel>? matchers)
{
return matchers?.Select(Map).Where(m => m != null).ToArray();
if (matchers == null)
{
return null;
}
return matchers.Select(Map).Where(m => m != null).ToArray()!;
}
public IMatcher? Map(MatcherModel? matcher)
@@ -38,9 +43,11 @@ namespace WireMock.Serialization
string? matcherType = parts.Length > 1 ? parts[1] : null;
var stringPatterns = ParseStringPatterns(matcher);
var matchBehaviour = matcher.RejectOnMatch == true ? MatchBehaviour.RejectOnMatch : MatchBehaviour.AcceptOnMatch;
var matchOperator = StringUtils.ParseMatchOperator(matcher.MatchOperator);
bool ignoreCase = matcher.IgnoreCase == true;
bool throwExceptionWhenMatcherFails = _settings.ThrowExceptionWhenMatcherFails == true;
bool useRegexExtended = _settings.UseRegexExtended == true;
bool useRegex = matcher.Regex == true;
switch (matcherName)
{
@@ -50,22 +57,22 @@ namespace WireMock.Serialization
case "CSharpCodeMatcher":
if (_settings.AllowCSharpCodeMatcher == true)
{
return PluginLoader.Load<ICSharpCodeMatcher>(matchBehaviour, stringPatterns);
return PluginLoader.Load<ICSharpCodeMatcher>(matchBehaviour, matchOperator, stringPatterns);
}
throw new NotSupportedException("It's not allowed to use the 'CSharpCodeMatcher' because WireMockServerSettings.AllowCSharpCodeMatcher is not set to 'true'.");
case nameof(LinqMatcher):
return new LinqMatcher(matchBehaviour, throwExceptionWhenMatcherFails, stringPatterns);
return new LinqMatcher(matchBehaviour, throwExceptionWhenMatcherFails, matchOperator, stringPatterns);
case nameof(ExactMatcher):
return new ExactMatcher(matchBehaviour, throwExceptionWhenMatcherFails, stringPatterns);
return new ExactMatcher(matchBehaviour, throwExceptionWhenMatcherFails, matchOperator, stringPatterns);
case nameof(ExactObjectMatcher):
return CreateExactObjectMatcher(matchBehaviour, stringPatterns[0], throwExceptionWhenMatcherFails);
case nameof(RegexMatcher):
return new RegexMatcher(matchBehaviour, stringPatterns, ignoreCase, throwExceptionWhenMatcherFails, useRegexExtended);
return new RegexMatcher(matchBehaviour, stringPatterns, ignoreCase, throwExceptionWhenMatcherFails, useRegexExtended, matchOperator);
case nameof(JsonMatcher):
var valueForJsonMatcher = matcher.Pattern ?? matcher.Patterns;
@@ -73,23 +80,23 @@ namespace WireMock.Serialization
case nameof(JsonPartialMatcher):
var valueForJsonPartialMatcher = matcher.Pattern ?? matcher.Patterns;
return new JsonPartialMatcher(matchBehaviour, valueForJsonPartialMatcher!, ignoreCase, throwExceptionWhenMatcherFails);
return new JsonPartialMatcher(matchBehaviour, valueForJsonPartialMatcher!, ignoreCase, throwExceptionWhenMatcherFails, useRegex);
case nameof(JsonPartialWildcardMatcher):
var valueForJsonPartialWildcardMatcher = matcher.Pattern ?? matcher.Patterns;
return new JsonPartialWildcardMatcher(matchBehaviour, valueForJsonPartialWildcardMatcher!, ignoreCase, throwExceptionWhenMatcherFails);
return new JsonPartialWildcardMatcher(matchBehaviour, valueForJsonPartialWildcardMatcher!, ignoreCase, throwExceptionWhenMatcherFails, useRegex);
case nameof(JsonPathMatcher):
return new JsonPathMatcher(matchBehaviour, throwExceptionWhenMatcherFails, stringPatterns);
return new JsonPathMatcher(matchBehaviour, throwExceptionWhenMatcherFails, matchOperator, stringPatterns);
case nameof(JmesPathMatcher):
return new JmesPathMatcher(matchBehaviour, throwExceptionWhenMatcherFails, stringPatterns);
return new JmesPathMatcher(matchBehaviour, throwExceptionWhenMatcherFails, matchOperator, stringPatterns);
case nameof(XPathMatcher):
return new XPathMatcher(matchBehaviour, throwExceptionWhenMatcherFails, stringPatterns);
return new XPathMatcher(matchBehaviour, throwExceptionWhenMatcherFails, matchOperator, stringPatterns);
case nameof(WildcardMatcher):
return new WildcardMatcher(matchBehaviour, stringPatterns, ignoreCase, throwExceptionWhenMatcherFails);
return new WildcardMatcher(matchBehaviour, stringPatterns, ignoreCase, throwExceptionWhenMatcherFails, matchOperator);
case nameof(ContentTypeMatcher):
return new ContentTypeMatcher(matchBehaviour, stringPatterns, ignoreCase, throwExceptionWhenMatcherFails);
@@ -113,9 +120,14 @@ namespace WireMock.Serialization
}
}
public MatcherModel[] Map(IEnumerable<IMatcher>? matchers)
public MatcherModel[]? Map(IEnumerable<IMatcher>? matchers)
{
return matchers?.Select(Map).Where(m => m != null).ToArray();
if (matchers == null)
{
return null;
}
return matchers.Where(m => m != null).Select(Map).ToArray()!;
}
public MatcherModel? Map(IMatcher? matcher)
@@ -125,8 +137,8 @@ namespace WireMock.Serialization
return null;
}
bool? ignoreCase = matcher is IIgnoreCaseMatcher ignoreCaseMatcher ? ignoreCaseMatcher.IgnoreCase : (bool?)null;
bool? rejectOnMatch = matcher.MatchBehaviour == MatchBehaviour.RejectOnMatch ? true : (bool?)null;
bool? ignoreCase = matcher is IIgnoreCaseMatcher ignoreCaseMatcher ? ignoreCaseMatcher.IgnoreCase : null;
bool? rejectOnMatch = matcher.MatchBehaviour == MatchBehaviour.RejectOnMatch ? true : null;
var model = new MatcherModel
{
@@ -137,7 +149,18 @@ namespace WireMock.Serialization
switch (matcher)
{
// If the matcher is a IStringMatcher, get the patterns.
case JsonPartialMatcher jsonPartialMatcher:
model.Regex = jsonPartialMatcher.Regex;
break;
case JsonPartialWildcardMatcher jsonPartialWildcardMatcher:
model.Regex = jsonPartialWildcardMatcher.Regex;
break;
}
switch (matcher)
{
// If the matcher is a IStringMatcher, get the operator & patterns.
case IStringMatcher stringMatcher:
var stringPatterns = stringMatcher.GetPatterns();
if (stringPatterns.Length == 1)
@@ -155,6 +178,7 @@ namespace WireMock.Serialization
else
{
model.Patterns = stringPatterns.Select(p => p.GetPattern()).Cast<object>().ToArray();
model.MatchOperator = stringMatcher.MatchOperator.ToString();
}
break;
@@ -191,14 +215,15 @@ namespace WireMock.Serialization
if (!string.IsNullOrEmpty(matcher.PatternAsFile))
{
var pattern = _settings.FileSystemHandler.ReadFileAsString(matcher.PatternAsFile);
return new[] { new AnyOf<string, StringPattern>(new StringPattern { Pattern = pattern, PatternAsFile = matcher.PatternAsFile }) };
var patternAsFile = matcher.PatternAsFile!;
var pattern = _settings.FileSystemHandler.ReadFileAsString(patternAsFile);
return new[] { new AnyOf<string, StringPattern>(new StringPattern { Pattern = pattern, PatternAsFile = patternAsFile }) };
}
return new AnyOf<string, StringPattern>[0];
}
private ExactObjectMatcher CreateExactObjectMatcher(MatchBehaviour matchBehaviour, AnyOf<string, StringPattern> stringPattern, bool throwException)
private static ExactObjectMatcher CreateExactObjectMatcher(MatchBehaviour matchBehaviour, AnyOf<string, StringPattern> stringPattern, bool throwException)
{
byte[] bytePattern;
try
@@ -213,4 +238,3 @@ namespace WireMock.Serialization
return new ExactObjectMatcher(matchBehaviour, bytePattern, throwException);
}
}
}

View File

@@ -53,9 +53,9 @@ internal static class PactMapper
return (filename, JsonUtils.SerializeAsPactFile(pact));
}
private static Request MapRequest(RequestModel request, string path)
private static PactRequest MapRequest(RequestModel request, string path)
{
return new Request
return new PactRequest
{
Method = request.Methods?.FirstOrDefault() ?? DefaultMethod,
Path = path,
@@ -65,14 +65,14 @@ internal static class PactMapper
};
}
private static Response MapResponse(ResponseModel? response)
private static PactResponse MapResponse(ResponseModel? response)
{
if (response == null)
{
return new Response();
return new PactResponse();
}
return new Response
return new PactResponse
{
Status = MapStatusCode(response.StatusCode),
Headers = MapResponseHeaders(response.Headers),

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