mirror of
https://github.com/wiremock/WireMock.Net.git
synced 2026-01-13 22:03:35 +01:00
Compare commits
13 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a25a8cabf8 | ||
|
|
9f9fc85a64 | ||
|
|
b63076a9ac | ||
|
|
05e2aa548b | ||
|
|
b9a8ee4145 | ||
|
|
59aab9e1c3 | ||
|
|
93c87845c2 | ||
|
|
09a302baf2 | ||
|
|
f0139eb837 | ||
|
|
8adf34fb56 | ||
|
|
fd816f0952 | ||
|
|
205c1d598b | ||
|
|
b986633eca |
20
CHANGELOG.md
20
CHANGELOG.md
@@ -1,3 +1,23 @@
|
||||
# 1.5.37 (27 September 2023)
|
||||
- [#998](https://github.com/WireMock-Net/WireMock.Net/pull/998) - Add JmesPathMatcher UnitTests [test] contributed by [StefH](https://github.com/StefH)
|
||||
- [#1004](https://github.com/WireMock-Net/WireMock.Net/pull/1004) - Fix MappingModel to map IgnoreCase and RejectOnMatch for Headers, Cookies and Parameters [bug] contributed by [StefH](https://github.com/StefH)
|
||||
- [#1003](https://github.com/WireMock-Net/WireMock.Net/issues/1003) - Store Mapping per POST request ignores "IgnoreCase" property of HeaderModel [bug]
|
||||
|
||||
# 1.5.36 (21 September 2023)
|
||||
- [#986](https://github.com/WireMock-Net/WireMock.Net/pull/986) - Write logging in case a Matcher throws an exception [feature] contributed by [StefH](https://github.com/StefH)
|
||||
- [#996](https://github.com/WireMock-Net/WireMock.Net/pull/996) - Remove dependency on Microsoft.AspNet.WebApi.Client [feature] contributed by [StefH](https://github.com/StefH)
|
||||
- [#1002](https://github.com/WireMock-Net/WireMock.Net/pull/1002) - Fixed logic for SaveUnmatchedRequests [bug] contributed by [StefH](https://github.com/StefH)
|
||||
- [#974](https://github.com/WireMock-Net/WireMock.Net/issues/974) - HttpClient extension methods causes ambiguous invocations in .NET 7 [bug]
|
||||
- [#1001](https://github.com/WireMock-Net/WireMock.Net/issues/1001) - SaveUnmatchedRequests stopped working [bug]
|
||||
|
||||
# 1.5.35 (19 August 2023)
|
||||
- [#992](https://github.com/WireMock-Net/WireMock.Net/pull/992) - Add extra unit test for WithParam multiple values comma [test] contributed by [StefH](https://github.com/StefH)
|
||||
- [#993](https://github.com/WireMock-Net/WireMock.Net/pull/993) - Update JSONPathMatcher.cs to cover the string path selection to a child contributed by [DayLightDancer](https://github.com/DayLightDancer)
|
||||
|
||||
# 1.5.34 (04 August 2023)
|
||||
- [#989](https://github.com/WireMock-Net/WireMock.Net/pull/989) - Fix MimeKitLite NuGet include [bug] contributed by [StefH](https://github.com/StefH)
|
||||
- [#988](https://github.com/WireMock-Net/WireMock.Net/issues/988) - v1.5.33 Returns always StatusCode 500 [bug]
|
||||
|
||||
# 1.5.33 (03 August 2023)
|
||||
- [#972](https://github.com/WireMock-Net/WireMock.Net/pull/972) - JsonPartialMatcher - match guid and string contributed by [timurnes](https://github.com/timurnes)
|
||||
- [#976](https://github.com/WireMock-Net/WireMock.Net/pull/976) - Upgrade to Handlebars.Net.Helpers 2.4.0 to update XPath.SelectTokens and XPath.EvaluateToString [feature] contributed by [StefH](https://github.com/StefH)
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<VersionPrefix>1.5.33</VersionPrefix>
|
||||
<VersionPrefix>1.5.37</VersionPrefix>
|
||||
<PackageIcon>WireMock.Net-Logo.png</PackageIcon>
|
||||
<PackageProjectUrl>https://github.com/WireMock-Net/WireMock.Net</PackageProjectUrl>
|
||||
<PackageLicenseExpression>Apache-2.0</PackageLicenseExpression>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
rem https://github.com/StefH/GitHubReleaseNotes
|
||||
|
||||
SET version=1.5.33
|
||||
SET version=1.5.37
|
||||
|
||||
GitHubReleaseNotes --output CHANGELOG.md --skip-empty-releases --exclude-labels question invalid doc duplicate --version %version% --token %GH_TOKEN%
|
||||
|
||||
|
||||
@@ -52,4 +52,4 @@ For more details see also [Docker](https://github.com/WireMock-Net/WireMock.Net-
|
||||
More details on using HTTPS (SSL) can be found here [Wiki : HTTPS](https://github.com/WireMock-Net/WireMock.Net/wiki/Using-HTTPS-(SSL))
|
||||
|
||||
## :books: Documentation
|
||||
For more info, see also this WIKI page: [What is WireMock.Net](https://github.com/WireMock-Net/WireMock.Net/wiki/What-Is-WireMock.Net).
|
||||
For more info, see also this WIKI page: [What is WireMock.Net](https://github.com/WireMock-Net/WireMock.Net/wiki/What-Is-WireMock.Net).
|
||||
|
||||
@@ -1,10 +1,6 @@
|
||||
# 1.5.33 (03 August 2023)
|
||||
- #972 JsonPartialMatcher - match guid and string
|
||||
- #976 Upgrade to Handlebars.Net.Helpers 2.4.0 to update XPath.SelectTokens and XPath.EvaluateToString [feature]
|
||||
- #981 Add MultiPart/MimePart Request Matcher [feature]
|
||||
- #968 Using request multipart in response template [feature]
|
||||
- #969 Multipart validation [feature]
|
||||
- #970 Loop through xml elements in handlebars template [feature]
|
||||
- #971 JsonPartialMatcher - match guid and string [feature]
|
||||
# 1.5.37 (27 September 2023)
|
||||
- #998 Add JmesPathMatcher UnitTests [test]
|
||||
- #1004 Fix MappingModel to map IgnoreCase and RejectOnMatch for Headers, Cookies and Parameters [bug]
|
||||
- #1003 Store Mapping per POST request ignores "IgnoreCase" property of HeaderModel [bug]
|
||||
|
||||
The full release notes can be found here: https://github.com/WireMock-Net/WireMock.Net/blob/master/CHANGELOG.md
|
||||
@@ -117,7 +117,9 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WireMock.Net.Testcontainers
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tools", "tools", "{0147029F-FA4A-44B3-B79A-3C3574054EE4}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MultipartUploader", "tools\MultipartUploader\MultipartUploader.csproj", "{07C30227-ADEC-4BDE-8CDC-849D85A690BB}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MultipartUploader", "tools\MultipartUploader\MultipartUploader.csproj", "{07C30227-ADEC-4BDE-8CDC-849D85A690BB}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WireMock.Net.Console.NET7.UsingNuGet", "examples\WireMock.Net.Console.NET7.UsingNuGet\WireMock.Net.Console.NET7.UsingNuGet.csproj", "{941229D6-191B-4B5E-AC81-0905EBF4F19D}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
@@ -285,6 +287,10 @@ Global
|
||||
{07C30227-ADEC-4BDE-8CDC-849D85A690BB}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{07C30227-ADEC-4BDE-8CDC-849D85A690BB}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{07C30227-ADEC-4BDE-8CDC-849D85A690BB}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{941229D6-191B-4B5E-AC81-0905EBF4F19D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{941229D6-191B-4B5E-AC81-0905EBF4F19D}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{941229D6-191B-4B5E-AC81-0905EBF4F19D}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{941229D6-191B-4B5E-AC81-0905EBF4F19D}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
@@ -332,6 +338,7 @@ Global
|
||||
{12B016A5-9D8B-4EFE-96C2-CA51BE43367D} = {8F890C6F-9ACC-438D-928A-AD61CDA862F2}
|
||||
{56A38798-C48B-4A4A-B805-071E05C02CE1} = {985E0ADB-D4B4-473A-AA40-567E279B7946}
|
||||
{07C30227-ADEC-4BDE-8CDC-849D85A690BB} = {0147029F-FA4A-44B3-B79A-3C3574054EE4}
|
||||
{941229D6-191B-4B5E-AC81-0905EBF4F19D} = {985E0ADB-D4B4-473A-AA40-567E279B7946}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {DC539027-9852-430C-B19F-FD035D018458}
|
||||
|
||||
@@ -22,15 +22,10 @@
|
||||
<Compile Remove="__admin\mappings\1.cs" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Remove="__admin\mappings\array.json" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\src\WireMock.Net\WireMock.Net.csproj" />
|
||||
<PackageReference Include="log4net" Version="2.0.15" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration" Version="6.0.0" />
|
||||
<PackageReference Include="MimeKitLite" Version="4.1.0.1" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
@@ -40,15 +35,6 @@
|
||||
<None Update="nlog.config">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="__admin\mappings\791a3f31-6946-4ce7-8e6f-0237c7443275.json">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="__admin\mappings\791a3f31-6946-4ce7-8e6f-0237c7443275.json">
|
||||
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="__admin\mappings\MyXmlResponse.xml">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -0,0 +1,48 @@
|
||||
[
|
||||
{
|
||||
"Guid": "12343f31-6946-4ce7-8e6f-0237c7001000",
|
||||
"Title": "1",
|
||||
"Request": {
|
||||
"Path": {
|
||||
"Matchers": [
|
||||
{
|
||||
"Name": "WildcardMatcher",
|
||||
"Pattern": "/mappings_static_1"
|
||||
}
|
||||
]
|
||||
},
|
||||
"Methods": [
|
||||
"get"
|
||||
]
|
||||
},
|
||||
"Response": {
|
||||
"BodyAsJson": { "result": "mappings static_1" },
|
||||
"Headers": {
|
||||
"Content-Type": "application/json"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"Guid": "12343f31-6946-4ce7-8e6f-0237c7002000",
|
||||
"Title": "2",
|
||||
"Request": {
|
||||
"Path": {
|
||||
"Matchers": [
|
||||
{
|
||||
"Name": "WildcardMatcher",
|
||||
"Pattern": "/mappings_static_2"
|
||||
}
|
||||
]
|
||||
},
|
||||
"Methods": [
|
||||
"get"
|
||||
]
|
||||
},
|
||||
"Response": {
|
||||
"BodyAsJson": { "result": "mappings static_2" },
|
||||
"Headers": {
|
||||
"Content-Type": "application/json"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
34
examples/WireMock.Net.Console.NET7.UsingNuGet/Program.cs
Normal file
34
examples/WireMock.Net.Console.NET7.UsingNuGet/Program.cs
Normal file
@@ -0,0 +1,34 @@
|
||||
using System.Net;
|
||||
using System.Text;
|
||||
using FluentAssertions;
|
||||
using WireMock.Logging;
|
||||
using WireMock.RequestBuilders;
|
||||
using WireMock.ResponseBuilders;
|
||||
using WireMock.Server;
|
||||
using WireMock.Settings;
|
||||
|
||||
namespace WireMock.Net.Console.NET7.UsingNuGet;
|
||||
|
||||
internal class Program
|
||||
{
|
||||
private static async Task Main(string[] args)
|
||||
{
|
||||
var server = WireMockServer.Start(new WireMockServerSettings
|
||||
{
|
||||
Logger = new WireMockConsoleLogger(),
|
||||
});
|
||||
|
||||
server.Given(Request.Create().UsingPost().WithPath("/some/endpoint"))
|
||||
.RespondWith(Response.Create().WithStatusCode(HttpStatusCode.Created));
|
||||
|
||||
var httpClient = new HttpClient { BaseAddress = new Uri(server.Url!) };
|
||||
var requestUri = new Uri(httpClient.BaseAddress!, "some/endpoint");
|
||||
var content = new StringContent(string.Empty, Encoding.UTF8, "application/json");
|
||||
|
||||
// Act
|
||||
var actual = await httpClient.PostAsync(requestUri, content);
|
||||
|
||||
// Assert
|
||||
actual.StatusCode.Should().Be(HttpStatusCode.Created);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="FluentAssertions" Version="6.11.0" />
|
||||
<PackageReference Include="WireMock.Net" Version="1.5.32" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -137,6 +137,7 @@ namespace WireMock.Net.ConsoleApplication
|
||||
Urls = new[] { url1, url2, url3 },
|
||||
StartAdminInterface = true,
|
||||
ReadStaticMappings = true,
|
||||
SaveUnmatchedRequests = true,
|
||||
WatchStaticMappings = true,
|
||||
WatchStaticMappingsInSubdirectories = true,
|
||||
//ProxyAndRecordSettings = new ProxyAndRecordSettings
|
||||
|
||||
@@ -16,6 +16,11 @@ public class ParamModel
|
||||
/// </summary>
|
||||
public bool? IgnoreCase { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the Reject on match for the Param Name.
|
||||
/// </summary>
|
||||
public bool? RejectOnMatch { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the matchers.
|
||||
/// </summary>
|
||||
|
||||
@@ -1,21 +1,25 @@
|
||||
using System;
|
||||
using System;
|
||||
|
||||
namespace WireMock.Admin.Mappings
|
||||
namespace WireMock.Admin.Mappings;
|
||||
|
||||
/// <summary>
|
||||
/// Status
|
||||
/// </summary>
|
||||
[FluentBuilder.AutoGenerateBuilder]
|
||||
public class StatusModel
|
||||
{
|
||||
/// <summary>
|
||||
/// Status
|
||||
/// The optional guid.
|
||||
/// </summary>
|
||||
[FluentBuilder.AutoGenerateBuilder]
|
||||
public class StatusModel
|
||||
{
|
||||
/// <summary>
|
||||
/// The optional guid.
|
||||
/// </summary>
|
||||
public Guid? Guid { get; set; }
|
||||
public Guid? Guid { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The status (can also contain the error message).
|
||||
/// </summary>
|
||||
public string Status { get; set; }
|
||||
}
|
||||
/// <summary>
|
||||
/// The status.
|
||||
/// </summary>
|
||||
public string? Status { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The error message.
|
||||
/// </summary>
|
||||
public string? Error { get; set; }
|
||||
}
|
||||
@@ -62,11 +62,6 @@ public class SettingsModel
|
||||
/// </summary>
|
||||
public bool? HandleRequestsSynchronously { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Throw an exception when the Matcher fails because of invalid input. (default set to <c>false</c>).
|
||||
/// </summary>
|
||||
public bool? ThrowExceptionWhenMatcherFails { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Use the RegexExtended instead of the default <see cref="Regex"/>. (default set to <c>true</c>).
|
||||
/// </summary>
|
||||
|
||||
@@ -1,121 +1,120 @@
|
||||
using JetBrains.Annotations;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace WireMock.Handlers
|
||||
namespace WireMock.Handlers;
|
||||
|
||||
/// <summary>
|
||||
/// Handler to interact with the file system to handle folders and read and write (static mapping) files.
|
||||
/// </summary>
|
||||
public interface IFileSystemHandler
|
||||
{
|
||||
/// <summary>
|
||||
/// Handler to interact with the file system to handle folders and read and write (static mapping) files.
|
||||
/// Gets the folder where the static mappings are located. For local file system, this would be `{CurrentFolder}/__admin/mappings`.
|
||||
/// </summary>
|
||||
public interface IFileSystemHandler
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the folder where the static mappings are located. For local file system, this would be `{CurrentFolder}/__admin/mappings`.
|
||||
/// </summary>
|
||||
/// <returns>The folder name.</returns>
|
||||
string GetMappingFolder();
|
||||
/// <returns>The folder name.</returns>
|
||||
string GetMappingFolder();
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the given path refers to an existing directory on disk.
|
||||
/// </summary>
|
||||
/// <param name="path">The path.</param>
|
||||
/// <returns>true if path refers to an existing directory; false if the directory does not exist or an error occurs when trying to determine if the specified directory exists.</returns>
|
||||
bool FolderExists([NotNull] string path);
|
||||
/// <summary>
|
||||
/// Determines whether the given path refers to an existing directory on disk.
|
||||
/// </summary>
|
||||
/// <param name="path">The path.</param>
|
||||
/// <returns>true if path refers to an existing directory; false if the directory does not exist or an error occurs when trying to determine if the specified directory exists.</returns>
|
||||
bool FolderExists([NotNull] string path);
|
||||
|
||||
/// <summary>
|
||||
/// Creates all directories and subdirectories in the specified path unless they already exist.
|
||||
/// </summary>
|
||||
/// <param name="path">The path.</param>
|
||||
void CreateFolder([NotNull] string path);
|
||||
/// <summary>
|
||||
/// Creates all directories and subdirectories in the specified path unless they already exist.
|
||||
/// </summary>
|
||||
/// <param name="path">The path.</param>
|
||||
void CreateFolder([NotNull] string path);
|
||||
|
||||
/// <summary>
|
||||
/// Returns an enumerable collection of file names in a specified path.
|
||||
/// </summary>
|
||||
/// <param name="path">The path.</param>
|
||||
/// <param name="includeSubdirectories">A value indicating whether subdirectories should also included when enumerating files.</param>
|
||||
/// <returns>An enumerable collection of the full names (including paths) for the files in the directory (and optionally subdirectories) specified by path.</returns>
|
||||
IEnumerable<string> EnumerateFiles([NotNull] string path, bool includeSubdirectories);
|
||||
/// <summary>
|
||||
/// Returns an enumerable collection of file names in a specified path.
|
||||
/// </summary>
|
||||
/// <param name="path">The path.</param>
|
||||
/// <param name="includeSubdirectories">A value indicating whether subdirectories should also included when enumerating files.</param>
|
||||
/// <returns>An enumerable collection of the full names (including paths) for the files in the directory (and optionally subdirectories) specified by path.</returns>
|
||||
IEnumerable<string> EnumerateFiles([NotNull] string path, bool includeSubdirectories);
|
||||
|
||||
/// <summary>
|
||||
/// Read a static mapping file as text.
|
||||
/// </summary>
|
||||
/// <param name="path">The path (folder + filename with .json extension).</param>
|
||||
/// <returns>The file content as text.</returns>
|
||||
string ReadMappingFile([NotNull] string path);
|
||||
/// <summary>
|
||||
/// Read a static mapping file as text.
|
||||
/// </summary>
|
||||
/// <param name="path">The path (folder + filename with .json extension).</param>
|
||||
/// <returns>The file content as text.</returns>
|
||||
string ReadMappingFile([NotNull] string path);
|
||||
|
||||
/// <summary>
|
||||
/// Write the static mapping file.
|
||||
/// </summary>
|
||||
/// <param name="path">The path (folder + filename with .json extension).</param>
|
||||
/// <param name="text">The text.</param>
|
||||
void WriteMappingFile([NotNull] string path, [NotNull] string text);
|
||||
/// <summary>
|
||||
/// Write the static mapping file.
|
||||
/// </summary>
|
||||
/// <param name="path">The path (folder + filename with .json extension).</param>
|
||||
/// <param name="text">The text.</param>
|
||||
void WriteMappingFile([NotNull] string path, [NotNull] string text);
|
||||
|
||||
/// <summary>
|
||||
/// Read a response body file as byte[].
|
||||
/// </summary>
|
||||
/// <param name="path">The path or filename from the file to read.</param>
|
||||
/// <returns>The file content as bytes.</returns>
|
||||
byte[] ReadResponseBodyAsFile([NotNull] string path);
|
||||
/// <summary>
|
||||
/// Read a response body file as byte[].
|
||||
/// </summary>
|
||||
/// <param name="path">The path or filename from the file to read.</param>
|
||||
/// <returns>The file content as bytes.</returns>
|
||||
byte[] ReadResponseBodyAsFile([NotNull] string path);
|
||||
|
||||
/// <summary>
|
||||
/// Read a response body file as text.
|
||||
/// </summary>
|
||||
/// <param name="path">The path or filename from the file to read.</param>
|
||||
/// <returns>The file content as text.</returns>
|
||||
string ReadResponseBodyAsString([NotNull] string path);
|
||||
/// <summary>
|
||||
/// Read a response body file as text.
|
||||
/// </summary>
|
||||
/// <param name="path">The path or filename from the file to read.</param>
|
||||
/// <returns>The file content as text.</returns>
|
||||
string ReadResponseBodyAsString([NotNull] string path);
|
||||
|
||||
/// <summary>
|
||||
/// Delete a file.
|
||||
/// </summary>
|
||||
/// <param name="filename">The filename.</param>
|
||||
void DeleteFile([NotNull] string filename);
|
||||
/// <summary>
|
||||
/// Delete a file.
|
||||
/// </summary>
|
||||
/// <param name="filename">The filename.</param>
|
||||
void DeleteFile([NotNull] string filename);
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the given path refers to an existing file on disk.
|
||||
/// </summary>
|
||||
/// <param name="filename">The filename.</param>
|
||||
/// <returns>true if path refers to an existing file; false if the file does not exist.</returns>
|
||||
bool FileExists([NotNull] string filename);
|
||||
/// <summary>
|
||||
/// Determines whether the given path refers to an existing file on disk.
|
||||
/// </summary>
|
||||
/// <param name="filename">The filename.</param>
|
||||
/// <returns>true if path refers to an existing file; false if the file does not exist.</returns>
|
||||
bool FileExists([NotNull] string filename);
|
||||
|
||||
/// <summary>
|
||||
/// Write a file.
|
||||
/// </summary>
|
||||
/// <param name="filename">The filename.</param>
|
||||
/// <param name="bytes">The bytes.</param>
|
||||
void WriteFile([NotNull] string filename, [NotNull] byte[] bytes);
|
||||
/// <summary>
|
||||
/// Write a file.
|
||||
/// </summary>
|
||||
/// <param name="filename">The filename.</param>
|
||||
/// <param name="bytes">The bytes.</param>
|
||||
void WriteFile([NotNull] string filename, [NotNull] byte[] bytes);
|
||||
|
||||
/// <summary>
|
||||
/// Write a file.
|
||||
/// </summary>
|
||||
/// <param name="folder">The folder.</param>
|
||||
/// <param name="filename">The filename.</param>
|
||||
/// <param name="bytes">The bytes.</param>
|
||||
void WriteFile([NotNull] string folder, [NotNull] string filename, [NotNull] byte[] bytes);
|
||||
/// <summary>
|
||||
/// Write a file.
|
||||
/// </summary>
|
||||
/// <param name="folder">The folder.</param>
|
||||
/// <param name="filename">The filename.</param>
|
||||
/// <param name="bytes">The bytes.</param>
|
||||
void WriteFile([NotNull] string folder, [NotNull] string filename, [NotNull] byte[] bytes);
|
||||
|
||||
/// <summary>
|
||||
/// Read a file as bytes.
|
||||
/// </summary>
|
||||
/// <param name="filename">The filename.</param>
|
||||
/// <returns>The file content as bytes.</returns>
|
||||
byte[] ReadFile([NotNull] string filename);
|
||||
/// <summary>
|
||||
/// Read a file as bytes.
|
||||
/// </summary>
|
||||
/// <param name="filename">The filename.</param>
|
||||
/// <returns>The file content as bytes.</returns>
|
||||
byte[] ReadFile([NotNull] string filename);
|
||||
|
||||
/// <summary>
|
||||
/// Read a file as string.
|
||||
/// </summary>
|
||||
/// <param name="filename">The filename.</param>
|
||||
/// <returns>The file content as a string.</returns>
|
||||
string ReadFileAsString([NotNull] string filename);
|
||||
/// <summary>
|
||||
/// Read a file as string.
|
||||
/// </summary>
|
||||
/// <param name="filename">The filename.</param>
|
||||
/// <returns>The file content as a string.</returns>
|
||||
string ReadFileAsString([NotNull] string filename);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the folder where the unmatched requests should be stored. For local file system, this would be `{CurrentFolder}/requests/unmatched`.
|
||||
/// </summary>
|
||||
/// <returns>The folder name.</returns>
|
||||
string GetUnmatchedRequestsFolder();
|
||||
/// <summary>
|
||||
/// Gets the folder where the unmatched requests should be stored. For local file system, this would be `{CurrentFolder}/requests/unmatched`.
|
||||
/// </summary>
|
||||
/// <returns>The folder name.</returns>
|
||||
string GetUnmatchedRequestsFolder();
|
||||
|
||||
/// <summary>
|
||||
/// Write a unmatched request to the Unmatched RequestsFolder.
|
||||
/// </summary>
|
||||
/// <param name="filename">The filename.</param>
|
||||
/// <param name="text">The text.</param>
|
||||
void WriteUnmatchedRequest([NotNull] string filename, [NotNull] string text);
|
||||
}
|
||||
/// <summary>
|
||||
/// Write a unmatched request to the Unmatched RequestsFolder.
|
||||
/// </summary>
|
||||
/// <param name="filename">The filename.</param>
|
||||
/// <param name="text">The text.</param>
|
||||
void WriteUnmatchedRequest([NotNull] string filename, [NotNull] string text);
|
||||
}
|
||||
@@ -2,65 +2,63 @@ using System;
|
||||
using JetBrains.Annotations;
|
||||
using WireMock.Admin.Requests;
|
||||
|
||||
namespace WireMock.Logging
|
||||
namespace WireMock.Logging;
|
||||
|
||||
/// <summary>
|
||||
/// IWireMockLogger interface
|
||||
/// </summary>
|
||||
[PublicAPI]
|
||||
public interface IWireMockLogger
|
||||
{
|
||||
/// <summary>
|
||||
/// IWireMockLogger interface
|
||||
/// Writes the message at the Debug level using the specified parameters.
|
||||
/// </summary>
|
||||
/// <param name="formatString">The format string.</param>
|
||||
/// <param name="args">The arguments.</param>
|
||||
[PublicAPI]
|
||||
public interface IWireMockLogger
|
||||
{
|
||||
/// <summary>
|
||||
/// Writes the message at the Debug level using the specified parameters.
|
||||
/// </summary>
|
||||
/// <param name="formatString">The format string.</param>
|
||||
/// <param name="args">The arguments.</param>
|
||||
[PublicAPI]
|
||||
[StringFormatMethod("formatString")]
|
||||
void Debug(string formatString, params object[] args);
|
||||
[StringFormatMethod("formatString")]
|
||||
void Debug(string formatString, params object[] args);
|
||||
|
||||
/// <summary>
|
||||
/// Writes the message at the Info level using the specified parameters.
|
||||
/// </summary>
|
||||
/// <param name="formatString">The format string.</param>
|
||||
/// <param name="args">The arguments.</param>
|
||||
[PublicAPI]
|
||||
[StringFormatMethod("formatString")]
|
||||
void Info(string formatString, params object[] args);
|
||||
/// <summary>
|
||||
/// Writes the message at the Info level using the specified parameters.
|
||||
/// </summary>
|
||||
/// <param name="formatString">The format string.</param>
|
||||
/// <param name="args">The arguments.</param>
|
||||
[PublicAPI]
|
||||
[StringFormatMethod("formatString")]
|
||||
void Info(string formatString, params object[] args);
|
||||
|
||||
/// <summary>
|
||||
/// Writes the message at the Warning level using the specified parameters.
|
||||
/// </summary>
|
||||
/// <param name="formatString">The format string.</param>
|
||||
/// <param name="args">The arguments.</param>
|
||||
[PublicAPI]
|
||||
[StringFormatMethod("formatString")]
|
||||
void Warn(string formatString, params object[] args);
|
||||
/// <summary>
|
||||
/// Writes the message at the Warning level using the specified parameters.
|
||||
/// </summary>
|
||||
/// <param name="formatString">The format string.</param>
|
||||
/// <param name="args">The arguments.</param>
|
||||
[PublicAPI]
|
||||
[StringFormatMethod("formatString")]
|
||||
void Warn(string formatString, params object[] args);
|
||||
|
||||
/// <summary>
|
||||
/// Writes the message at the Error level using the specified parameters.
|
||||
/// </summary>
|
||||
/// <param name="formatString">The format string.</param>
|
||||
/// <param name="args">The arguments.</param>
|
||||
[PublicAPI]
|
||||
[StringFormatMethod("formatString")]
|
||||
void Error(string formatString, params object[] args);
|
||||
/// <summary>
|
||||
/// Writes the message at the Error level using the specified parameters.
|
||||
/// </summary>
|
||||
/// <param name="formatString">The format string.</param>
|
||||
/// <param name="args">The arguments.</param>
|
||||
[PublicAPI]
|
||||
[StringFormatMethod("formatString")]
|
||||
void Error(string formatString, params object[] args);
|
||||
|
||||
/// <summary>
|
||||
/// Writes the message at the Error level using the specified exception.
|
||||
/// </summary>
|
||||
/// <param name="formatString">The format string.</param>
|
||||
/// <param name="exception">The exception.</param>
|
||||
[PublicAPI]
|
||||
[StringFormatMethod("formatString")]
|
||||
void Error(string formatString, Exception exception);
|
||||
/// <summary>
|
||||
/// Writes the message at the Error level using the specified exception.
|
||||
/// </summary>
|
||||
/// <param name="formatString">The format string.</param>
|
||||
/// <param name="exception">The exception.</param>
|
||||
[PublicAPI]
|
||||
void Error(string formatString, Exception exception);
|
||||
|
||||
/// <summary>
|
||||
/// Writes the LogEntryModel (LogRequestModel, LogResponseModel and more).
|
||||
/// </summary>
|
||||
/// <param name="logEntryModel">The Request Log Model.</param>
|
||||
/// <param name="isAdminRequest">Defines if this request is an admin request.</param>
|
||||
[PublicAPI]
|
||||
void DebugRequestResponse(LogEntryModel logEntryModel, bool isAdminRequest);
|
||||
}
|
||||
/// <summary>
|
||||
/// Writes the LogEntryModel (LogRequestModel, LogResponseModel and more).
|
||||
/// </summary>
|
||||
/// <param name="logEntryModel">The Request Log Model.</param>
|
||||
/// <param name="isAdminRequest">Defines if this request is an admin request.</param>
|
||||
[PublicAPI]
|
||||
void DebugRequestResponse(LogEntryModel logEntryModel, bool isAdminRequest);
|
||||
}
|
||||
@@ -1,56 +1,56 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace WireMock.Matchers.Request
|
||||
namespace WireMock.Matchers.Request;
|
||||
|
||||
/// <summary>
|
||||
/// IRequestMatchResult
|
||||
/// </summary>
|
||||
public interface IRequestMatchResult : IComparable
|
||||
{
|
||||
/// <summary>
|
||||
/// IRequestMatchResult
|
||||
/// Gets the match percentage.
|
||||
/// </summary>
|
||||
public interface IRequestMatchResult : IComparable
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the match percentage.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The match percentage.
|
||||
/// </value>
|
||||
double AverageTotalScore { get; }
|
||||
/// <value>
|
||||
/// The match percentage.
|
||||
/// </value>
|
||||
double AverageTotalScore { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether this instance is perfect match.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// <c>true</c> if this instance is perfect match; otherwise, <c>false</c>.
|
||||
/// </value>
|
||||
bool IsPerfectMatch { get; }
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether this instance is perfect match.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// <c>true</c> if this instance is perfect match; otherwise, <c>false</c>.
|
||||
/// </value>
|
||||
bool IsPerfectMatch { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the match details.
|
||||
/// </summary>
|
||||
IList<MatchDetail> MatchDetails { get; }
|
||||
/// <summary>
|
||||
/// Gets the match details.
|
||||
/// </summary>
|
||||
IList<MatchDetail> MatchDetails { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the total number of matches.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The total number of matches.
|
||||
/// </value>
|
||||
int TotalNumber { get; }
|
||||
/// <summary>
|
||||
/// Gets or sets the total number of matches.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The total number of matches.
|
||||
/// </value>
|
||||
int TotalNumber { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the match-score.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The match-score.
|
||||
/// </value>
|
||||
double TotalScore { get; }
|
||||
/// <summary>
|
||||
/// Gets or sets the match-score.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The match-score.
|
||||
/// </value>
|
||||
double TotalScore { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Adds the score.
|
||||
/// </summary>
|
||||
/// <param name="matcherType">The matcher Type.</param>
|
||||
/// <param name="score">The score.</param>
|
||||
/// <returns>The score.</returns>
|
||||
double AddScore(Type matcherType, double score);
|
||||
}
|
||||
/// <summary>
|
||||
/// Adds the score.
|
||||
/// </summary>
|
||||
/// <param name="matcherType">The matcher Type.</param>
|
||||
/// <param name="score">The score.</param>
|
||||
/// <param name="exception">The exception [Optional].</param>
|
||||
/// <returns>The score.</returns>
|
||||
double AddScore(Type matcherType, double score, Exception? exception);
|
||||
}
|
||||
@@ -1,20 +1,25 @@
|
||||
using System;
|
||||
using System;
|
||||
|
||||
namespace WireMock.Matchers.Request
|
||||
namespace WireMock.Matchers.Request;
|
||||
|
||||
/// <summary>
|
||||
/// MatchDetail
|
||||
/// </summary>
|
||||
public class MatchDetail
|
||||
{
|
||||
/// <summary>
|
||||
/// MatchDetail
|
||||
/// Gets or sets the type of the matcher.
|
||||
/// </summary>
|
||||
public class MatchDetail
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the type of the matcher.
|
||||
/// </summary>
|
||||
public Type MatcherType { get; set; }
|
||||
public Type MatcherType { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the score between 0.0 and 1.0
|
||||
/// </summary>
|
||||
public double Score { get; set; }
|
||||
}
|
||||
/// <summary>
|
||||
/// Gets or sets the score between 0.0 and 1.0
|
||||
/// </summary>
|
||||
public double Score { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The exception in case the Matcher throws exception.
|
||||
/// [Optional]
|
||||
/// </summary>
|
||||
public Exception? Exception { get; set; }
|
||||
}
|
||||
@@ -30,11 +30,9 @@ internal class CSharpCodeMatcher : ICSharpCodeMatcher
|
||||
"Newtonsoft.Json.Linq"
|
||||
};
|
||||
|
||||
/// <inheritdoc />
|
||||
public MatchBehaviour MatchBehaviour { get; }
|
||||
|
||||
/// <inheritdoc cref="IMatcher.ThrowException"/>
|
||||
public bool ThrowException { get; }
|
||||
|
||||
private readonly AnyOf<string, StringPattern>[] _patterns;
|
||||
|
||||
/// <summary>
|
||||
@@ -55,37 +53,44 @@ internal class CSharpCodeMatcher : ICSharpCodeMatcher
|
||||
{
|
||||
_patterns = Guard.NotNull(patterns);
|
||||
MatchBehaviour = matchBehaviour;
|
||||
ThrowException = false;
|
||||
MatchOperator = matchOperator;
|
||||
}
|
||||
|
||||
public double IsMatch(string? input)
|
||||
public MatchResult IsMatch(string? input)
|
||||
{
|
||||
return IsMatchInternal(input);
|
||||
}
|
||||
|
||||
public double IsMatch(object? input)
|
||||
public MatchResult IsMatch(object? input)
|
||||
{
|
||||
return IsMatchInternal(input);
|
||||
}
|
||||
|
||||
public double IsMatchInternal(object? input)
|
||||
public MatchResult IsMatchInternal(object? input)
|
||||
{
|
||||
double match = MatchScores.Mismatch;
|
||||
var score = MatchScores.Mismatch;
|
||||
Exception? exception = null;
|
||||
|
||||
if (input != null)
|
||||
{
|
||||
match = MatchScores.ToScore(_patterns.Select(pattern => IsMatch(input, pattern.GetPattern())).ToArray(), MatchOperator);
|
||||
try
|
||||
{
|
||||
score = MatchScores.ToScore(_patterns.Select(pattern => IsMatch(input, pattern.GetPattern())).ToArray(), MatchOperator);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
exception = ex;
|
||||
}
|
||||
}
|
||||
|
||||
return MatchBehaviourHelper.Convert(MatchBehaviour, match);
|
||||
return new MatchResult(MatchBehaviourHelper.Convert(MatchBehaviour, score), exception);
|
||||
}
|
||||
|
||||
private bool IsMatch(dynamic input, string pattern)
|
||||
{
|
||||
bool isMatchWithString = input is string;
|
||||
var isMatchWithString = input is string;
|
||||
var inputValue = isMatchWithString ? input : JObject.FromObject(input);
|
||||
string source = GetSourceForIsMatchWithString(pattern, isMatchWithString);
|
||||
var source = GetSourceForIsMatchWithString(pattern, isMatchWithString);
|
||||
|
||||
object? result;
|
||||
|
||||
@@ -155,7 +160,7 @@ internal class CSharpCodeMatcher : ICSharpCodeMatcher
|
||||
}
|
||||
|
||||
#elif (NETSTANDARD2_0 || NETSTANDARD2_1 || NETCOREAPP3_1 || NET5_0 || NET6_0 || NET7_0)
|
||||
Assembly assembly;
|
||||
Assembly assembly;
|
||||
try
|
||||
{
|
||||
assembly = CSScriptLib.CSScript.Evaluator.CompileCode(source);
|
||||
@@ -198,10 +203,10 @@ internal class CSharpCodeMatcher : ICSharpCodeMatcher
|
||||
|
||||
private string GetSourceForIsMatchWithString(string pattern, bool isMatchWithString)
|
||||
{
|
||||
string template = isMatchWithString ? TemplateForIsMatchWithString : TemplateForIsMatchWithDynamic;
|
||||
var template = isMatchWithString ? TemplateForIsMatchWithString : TemplateForIsMatchWithDynamic;
|
||||
|
||||
var stringBuilder = new StringBuilder();
|
||||
foreach (string @using in _usings)
|
||||
foreach (var @using in _usings)
|
||||
{
|
||||
stringBuilder.AppendLine($"using {@using};");
|
||||
}
|
||||
@@ -211,7 +216,7 @@ internal class CSharpCodeMatcher : ICSharpCodeMatcher
|
||||
return stringBuilder.ToString();
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IStringMatcher.GetPatterns"/>
|
||||
/// <inheritdoc />
|
||||
public AnyOf<string, StringPattern>[] GetPatterns()
|
||||
{
|
||||
return _patterns;
|
||||
@@ -220,6 +225,6 @@ internal class CSharpCodeMatcher : ICSharpCodeMatcher
|
||||
/// <inheritdoc />
|
||||
public MatchOperator MatchOperator { get; }
|
||||
|
||||
/// <inheritdoc cref="IMatcher.Name"/>
|
||||
public string Name => "CSharpCodeMatcher";
|
||||
/// <inheritdoc />
|
||||
public string Name => nameof(CSharpCodeMatcher);
|
||||
}
|
||||
@@ -19,12 +19,15 @@
|
||||
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Include="..\WireMock.Net\Http\HttpClientFactory2.cs" Link="Http\HttpClientFactory2.cs" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="IsExternalInit" Version="1.0.3">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.AspNet.WebApi.Client" Version="5.2.9" />
|
||||
<PackageReference Include="Stef.Validation" Version="0.1.1" />
|
||||
<PackageReference Include="Testcontainers" Version="3.2.0" />
|
||||
<PackageReference Include="JetBrains.Annotations" VersionOverride="2022.3.1" PrivateAssets="All" Version="2022.3.1" />
|
||||
@@ -33,4 +36,8 @@
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\WireMock.Net.RestClient\WireMock.Net.RestClient.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Folder Include="Http\" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -8,6 +8,7 @@ using Microsoft.Extensions.Logging;
|
||||
using RestEase;
|
||||
using Stef.Validation;
|
||||
using WireMock.Client;
|
||||
using WireMock.Http;
|
||||
|
||||
namespace WireMock.Net.Testcontainers;
|
||||
|
||||
@@ -71,7 +72,7 @@ public sealed class WireMockContainer : DockerContainer
|
||||
{
|
||||
ValidateIfRunning();
|
||||
|
||||
var client = HttpClientFactory.Create(handlers);
|
||||
var client = HttpClientFactory2.Create(handlers);
|
||||
client.BaseAddress = GetPublicUri();
|
||||
return client;
|
||||
}
|
||||
@@ -93,7 +94,7 @@ public sealed class WireMockContainer : DockerContainer
|
||||
{
|
||||
ValidateIfRunning();
|
||||
|
||||
var client = HttpClientFactory.Create(innerHandler, handlers);
|
||||
var client = HttpClientFactory2.Create(innerHandler, handlers);
|
||||
client.BaseAddress = GetPublicUri();
|
||||
return client;
|
||||
}
|
||||
|
||||
@@ -34,8 +34,6 @@ internal class AzureADAuthenticationMatcher : IStringMatcher
|
||||
|
||||
public MatchBehaviour MatchBehaviour => MatchBehaviour.AcceptOnMatch;
|
||||
|
||||
public bool ThrowException => false;
|
||||
|
||||
public AnyOf<string, StringPattern>[] GetPatterns()
|
||||
{
|
||||
return EmptyArray<AnyOf<string, StringPattern>>.Value;
|
||||
@@ -43,7 +41,7 @@ internal class AzureADAuthenticationMatcher : IStringMatcher
|
||||
|
||||
public MatchOperator MatchOperator { get; } = MatchOperator.Or;
|
||||
|
||||
public double IsMatch(string? input)
|
||||
public MatchResult IsMatch(string? input)
|
||||
{
|
||||
if (string.IsNullOrEmpty(input))
|
||||
{
|
||||
@@ -70,9 +68,9 @@ internal class AzureADAuthenticationMatcher : IStringMatcher
|
||||
|
||||
return MatchScores.Perfect;
|
||||
}
|
||||
catch
|
||||
catch (Exception ex)
|
||||
{
|
||||
return MatchScores.Mismatch;
|
||||
return new MatchResult(MatchScores.Mismatch, ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,4 +8,6 @@ internal static class WireMockConstants
|
||||
|
||||
public const string ContentTypeJson = "application/json";
|
||||
public const string ContentTypeTextPlain = "text/plain";
|
||||
|
||||
public const string NoMatchingFound = "No matching mapping found";
|
||||
}
|
||||
16
src/WireMock.Net/Extensions/ExceptionExtensions.cs
Normal file
16
src/WireMock.Net/Extensions/ExceptionExtensions.cs
Normal file
@@ -0,0 +1,16 @@
|
||||
using System;
|
||||
|
||||
namespace WireMock.Extensions;
|
||||
|
||||
internal static class ExceptionExtensions
|
||||
{
|
||||
public static Exception? ToException(this Exception[] exceptions)
|
||||
{
|
||||
return exceptions.Length switch
|
||||
{
|
||||
1 => exceptions[0],
|
||||
> 1 => new AggregateException(exceptions),
|
||||
_ => null
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -82,7 +82,7 @@ public class LocalFileSystemHandler : IFileSystemHandler
|
||||
public virtual byte[] ReadResponseBodyAsFile(string path)
|
||||
{
|
||||
Guard.NotNullOrEmpty(path);
|
||||
path = PathUtils.CleanPath(path);
|
||||
path = PathUtils.CleanPath(path)!;
|
||||
// If the file exists at the given path relative to the MappingsFolder, then return that.
|
||||
// Else the path will just be as-is.
|
||||
return File.ReadAllBytes(File.Exists(PathUtils.Combine(GetMappingFolder(), path)) ? PathUtils.Combine(GetMappingFolder(), path) : path);
|
||||
@@ -92,7 +92,7 @@ public class LocalFileSystemHandler : IFileSystemHandler
|
||||
public virtual string ReadResponseBodyAsString(string path)
|
||||
{
|
||||
Guard.NotNullOrEmpty(path);
|
||||
path = PathUtils.CleanPath(path);
|
||||
path = PathUtils.CleanPath(path)!;
|
||||
// In case the path is a filename, the path will be adjusted to the MappingFolder.
|
||||
// Else the path will just be as-is.
|
||||
return File.ReadAllText(File.Exists(PathUtils.Combine(GetMappingFolder(), path)) ? PathUtils.Combine(GetMappingFolder(), path) : path);
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
|
||||
namespace WireMock.Http;
|
||||
@@ -6,19 +7,31 @@ internal static class HttpClientFactory2
|
||||
{
|
||||
public static HttpClient Create(params DelegatingHandler[] handlers)
|
||||
{
|
||||
#if NETSTANDARD1_3
|
||||
return new HttpClient();
|
||||
#else
|
||||
return HttpClientFactory.Create(handlers);
|
||||
#endif
|
||||
var handler = CreateHandlerPipeline(new HttpClientHandler(), handlers);
|
||||
return new HttpClient(handler);
|
||||
}
|
||||
|
||||
public static HttpClient Create(HttpMessageHandler innerHandler, params DelegatingHandler[] handlers)
|
||||
{
|
||||
#if NETSTANDARD1_3
|
||||
return new HttpClient(innerHandler);
|
||||
#else
|
||||
return HttpClientFactory.Create(innerHandler, handlers);
|
||||
#endif
|
||||
var handler = CreateHandlerPipeline(innerHandler, handlers);
|
||||
return new HttpClient(handler);
|
||||
}
|
||||
|
||||
private static HttpMessageHandler CreateHandlerPipeline(HttpMessageHandler handler, params DelegatingHandler[] delegatingHandlers)
|
||||
{
|
||||
if (delegatingHandlers.Length == 0)
|
||||
{
|
||||
return handler;
|
||||
}
|
||||
|
||||
var next = handler;
|
||||
|
||||
foreach (var delegatingHandler in delegatingHandlers.Reverse())
|
||||
{
|
||||
delegatingHandler.InnerHandler = next;
|
||||
next = delegatingHandler;
|
||||
}
|
||||
|
||||
return next;
|
||||
}
|
||||
}
|
||||
@@ -139,13 +139,13 @@ public class Mapping : IMapping
|
||||
Probability = probability;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IMapping.ProvideResponseAsync" />
|
||||
/// <inheritdoc />
|
||||
public Task<(IResponseMessage Message, IMapping? Mapping)> ProvideResponseAsync(IRequestMessage requestMessage)
|
||||
{
|
||||
return Provider.ProvideResponseAsync(this, requestMessage, Settings);
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IMapping.GetRequestMatchResult" />
|
||||
/// <inheritdoc />
|
||||
public IRequestMatchResult GetRequestMatchResult(IRequestMessage requestMessage, string? nextState)
|
||||
{
|
||||
var result = new RequestMatchResult();
|
||||
|
||||
@@ -20,10 +20,8 @@ public abstract class AbstractJsonPartialMatcher : JsonMatcher
|
||||
/// </summary>
|
||||
/// <param name="value">The string value to check for equality.</param>
|
||||
/// <param name="ignoreCase">Ignore the case from the PropertyName and PropertyValue (string only).</param>
|
||||
/// <param name="throwException">Throw an exception when the internal matching fails because of invalid input.</param>
|
||||
/// <param name="regex">Support Regex.</param>
|
||||
protected AbstractJsonPartialMatcher(string value, bool ignoreCase = false, bool throwException = false, bool regex = false)
|
||||
: base(value, ignoreCase, throwException)
|
||||
protected AbstractJsonPartialMatcher(string value, bool ignoreCase = false, bool regex = false) : base(value, ignoreCase)
|
||||
{
|
||||
Regex = regex;
|
||||
}
|
||||
@@ -33,10 +31,8 @@ public abstract class AbstractJsonPartialMatcher : JsonMatcher
|
||||
/// </summary>
|
||||
/// <param name="value">The object value to check for equality.</param>
|
||||
/// <param name="ignoreCase">Ignore the case from the PropertyName and PropertyValue (string only).</param>
|
||||
/// <param name="throwException">Throw an exception when the internal matching fails because of invalid input.</param>
|
||||
/// <param name="regex">Support Regex.</param>
|
||||
protected AbstractJsonPartialMatcher(object value, bool ignoreCase = false, bool throwException = false, bool regex = false)
|
||||
: base(value, ignoreCase, throwException)
|
||||
protected AbstractJsonPartialMatcher(object value, bool ignoreCase = false, bool regex = false) : base(value, ignoreCase)
|
||||
{
|
||||
Regex = regex;
|
||||
}
|
||||
@@ -47,10 +43,8 @@ public abstract class AbstractJsonPartialMatcher : JsonMatcher
|
||||
/// <param name="matchBehaviour">The match behaviour.</param>
|
||||
/// <param name="value">The value to check for equality.</param>
|
||||
/// <param name="ignoreCase">Ignore the case from the PropertyName and PropertyValue (string only).</param>
|
||||
/// <param name="throwException">Throw an exception when the internal matching fails because of invalid input.</param>
|
||||
/// <param name="regex">Support Regex.</param>
|
||||
protected AbstractJsonPartialMatcher(MatchBehaviour matchBehaviour, object value, bool ignoreCase = false, bool throwException = false, bool regex = false)
|
||||
: base(matchBehaviour, value, ignoreCase, throwException)
|
||||
protected AbstractJsonPartialMatcher(MatchBehaviour matchBehaviour, object value, bool ignoreCase = false, bool regex = false) : base(matchBehaviour, value, ignoreCase)
|
||||
{
|
||||
Regex = regex;
|
||||
}
|
||||
@@ -66,7 +60,7 @@ public abstract class AbstractJsonPartialMatcher : JsonMatcher
|
||||
if (Regex && value.Type == JTokenType.String && input != null)
|
||||
{
|
||||
var valueAsString = value.ToString();
|
||||
|
||||
|
||||
var (valid, result) = RegexUtils.MatchRegex(valueAsString, input.ToString());
|
||||
if (valid)
|
||||
{
|
||||
@@ -75,10 +69,10 @@ public abstract class AbstractJsonPartialMatcher : JsonMatcher
|
||||
}
|
||||
|
||||
if (input != null &&
|
||||
((value.Type == JTokenType.Guid && input.Type == JTokenType.String) ||
|
||||
(value.Type == JTokenType.String && input.Type == JTokenType.Guid)))
|
||||
((value.Type == JTokenType.Guid && input.Type == JTokenType.String) ||
|
||||
(value.Type == JTokenType.String && input.Type == JTokenType.Guid)))
|
||||
{
|
||||
return IsMatch(value.ToString(), input.ToString());
|
||||
return IsMatch(value.ToString(), input.ToString());
|
||||
}
|
||||
|
||||
if (input == null || value.Type != input.Type)
|
||||
|
||||
@@ -46,15 +46,13 @@ public class ContentTypeMatcher : WildcardMatcher
|
||||
/// <param name="matchBehaviour">The match behaviour.</param>
|
||||
/// <param name="patterns">The patterns.</param>
|
||||
/// <param name="ignoreCase">IgnoreCase (default false)</param>
|
||||
/// <param name="throwException">Throw an exception when the internal matching fails because of invalid input.</param>
|
||||
public ContentTypeMatcher(MatchBehaviour matchBehaviour, AnyOf<string, StringPattern>[] patterns, bool ignoreCase = false, bool throwException = false) :
|
||||
base(matchBehaviour, patterns, ignoreCase, throwException)
|
||||
public ContentTypeMatcher(MatchBehaviour matchBehaviour, AnyOf<string, StringPattern>[] patterns, bool ignoreCase = false) : base(matchBehaviour, patterns, ignoreCase)
|
||||
{
|
||||
_patterns = patterns;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="RegexMatcher.IsMatch"/>
|
||||
public override double IsMatch(string? input)
|
||||
/// <inheritdoc />
|
||||
public override MatchResult IsMatch(string? input)
|
||||
{
|
||||
if (string.IsNullOrEmpty(input) || !MediaTypeHeaderValue.TryParse(input, out var contentType))
|
||||
{
|
||||
@@ -64,12 +62,12 @@ public class ContentTypeMatcher : WildcardMatcher
|
||||
return base.IsMatch(contentType.MediaType);
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IStringMatcher.GetPatterns"/>
|
||||
/// <inheritdoc />
|
||||
public override AnyOf<string, StringPattern>[] GetPatterns()
|
||||
{
|
||||
return _patterns;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IMatcher.Name"/>
|
||||
public override string Name => "ContentTypeMatcher";
|
||||
/// <inheritdoc />
|
||||
public override string Name => nameof(ContentTypeMatcher);
|
||||
}
|
||||
@@ -14,17 +14,14 @@ public class ExactMatcher : IStringMatcher, IIgnoreCaseMatcher
|
||||
{
|
||||
private readonly AnyOf<string, StringPattern>[] _values;
|
||||
|
||||
/// <inheritdoc cref="IMatcher.MatchBehaviour"/>
|
||||
/// <inheritdoc />
|
||||
public MatchBehaviour MatchBehaviour { get; }
|
||||
|
||||
/// <inheritdoc cref="IMatcher.ThrowException"/>
|
||||
public bool ThrowException { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ExactMatcher"/> class.
|
||||
/// </summary>
|
||||
/// <param name="values">The values.</param>
|
||||
public ExactMatcher(params AnyOf<string, StringPattern>[] values) : this(MatchBehaviour.AcceptOnMatch, false, false, MatchOperator.Or, values)
|
||||
public ExactMatcher(params AnyOf<string, StringPattern>[] values) : this(MatchBehaviour.AcceptOnMatch, false, MatchOperator.Or, values)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -33,7 +30,7 @@ public class ExactMatcher : IStringMatcher, IIgnoreCaseMatcher
|
||||
/// </summary>
|
||||
/// <param name="ignoreCase">Ignore the case from the pattern(s).</param>
|
||||
/// <param name="values">The values.</param>
|
||||
public ExactMatcher(bool ignoreCase, params AnyOf<string, StringPattern>[] values) : this(MatchBehaviour.AcceptOnMatch, ignoreCase, false, MatchOperator.Or, values)
|
||||
public ExactMatcher(bool ignoreCase, params AnyOf<string, StringPattern>[] values) : this(MatchBehaviour.AcceptOnMatch, ignoreCase, MatchOperator.Or, values)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -42,36 +39,33 @@ public class ExactMatcher : IStringMatcher, IIgnoreCaseMatcher
|
||||
/// </summary>
|
||||
/// <param name="matchBehaviour">The match behaviour.</param>
|
||||
/// <param name="ignoreCase">Ignore the case from the pattern(s).</param>
|
||||
/// <param name="throwException">Throw an exception when the internal matching fails because of invalid input.</param>
|
||||
/// <param name="matchOperator">The <see cref="Matchers.MatchOperator"/> to use. (default = "Or")</param>
|
||||
/// <param name="values">The values.</param>
|
||||
public ExactMatcher(
|
||||
MatchBehaviour matchBehaviour,
|
||||
bool ignoreCase = false,
|
||||
bool throwException = false,
|
||||
MatchOperator matchOperator = MatchOperator.Or,
|
||||
params AnyOf<string, StringPattern>[] values)
|
||||
{
|
||||
_values = Guard.NotNull(values);
|
||||
|
||||
MatchBehaviour = matchBehaviour;
|
||||
ThrowException = throwException;
|
||||
IgnoreCase = ignoreCase;
|
||||
MatchOperator = matchOperator;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IStringMatcher.IsMatch"/>
|
||||
public double IsMatch(string? input)
|
||||
/// <inheritdoc />
|
||||
public MatchResult IsMatch(string? input)
|
||||
{
|
||||
Func<string?, bool> equals = IgnoreCase
|
||||
? pattern => string.Equals(pattern, input, StringComparison.OrdinalIgnoreCase)
|
||||
: pattern => pattern == input;
|
||||
|
||||
double score = MatchScores.ToScore(_values.Select(v => equals(v)).ToArray(), MatchOperator);
|
||||
return MatchBehaviourHelper.Convert(MatchBehaviour, score);
|
||||
var score = MatchScores.ToScore(_values.Select(v => equals(v)).ToArray(), MatchOperator);
|
||||
return new MatchResult(MatchBehaviourHelper.Convert(MatchBehaviour, score));
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IStringMatcher.GetPatterns"/>
|
||||
/// <inheritdoc />
|
||||
public AnyOf<string, StringPattern>[] GetPatterns()
|
||||
{
|
||||
return _values;
|
||||
@@ -80,7 +74,7 @@ public class ExactMatcher : IStringMatcher, IIgnoreCaseMatcher
|
||||
/// <inheritdoc />
|
||||
public MatchOperator MatchOperator { get; }
|
||||
|
||||
/// <inheritdoc cref="IMatcher.Name"/>
|
||||
/// <inheritdoc />
|
||||
public string Name => "ExactMatcher";
|
||||
|
||||
/// <inheritdoc />
|
||||
|
||||
@@ -19,12 +19,9 @@ public class ExactObjectMatcher : IObjectMatcher
|
||||
/// </summary>
|
||||
public byte[]? ValueAsBytes { get; }
|
||||
|
||||
/// <inheritdoc cref="IMatcher.MatchBehaviour"/>
|
||||
/// <inheritdoc />
|
||||
public MatchBehaviour MatchBehaviour { get; }
|
||||
|
||||
/// <inheritdoc cref="IMatcher.ThrowException"/>
|
||||
public bool ThrowException { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ExactObjectMatcher"/> class.
|
||||
/// </summary>
|
||||
@@ -56,17 +53,15 @@ public class ExactObjectMatcher : IObjectMatcher
|
||||
/// Initializes a new instance of the <see cref="ExactObjectMatcher"/> class.
|
||||
/// </summary>
|
||||
/// <param name="matchBehaviour">The match behaviour.</param>
|
||||
/// <param name="throwException">Throw an exception when the internal matching fails because of invalid input.</param>
|
||||
/// <param name="value">The value.</param>
|
||||
public ExactObjectMatcher(MatchBehaviour matchBehaviour, byte[] value, bool throwException = false)
|
||||
public ExactObjectMatcher(MatchBehaviour matchBehaviour, byte[] value)
|
||||
{
|
||||
ValueAsBytes = Guard.NotNull(value);
|
||||
MatchBehaviour = matchBehaviour;
|
||||
ThrowException = throwException;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IObjectMatcher.IsMatch"/>
|
||||
public double IsMatch(object? input)
|
||||
/// <inheritdoc />
|
||||
public MatchResult IsMatch(object? input)
|
||||
{
|
||||
bool equals = false;
|
||||
if (ValueAsObject != null)
|
||||
@@ -81,6 +76,6 @@ public class ExactObjectMatcher : IObjectMatcher
|
||||
return MatchBehaviourHelper.Convert(MatchBehaviour, MatchScores.ToScore(equals));
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IMatcher.Name"/>
|
||||
/// <inheritdoc />
|
||||
public string Name => "ExactObjectMatcher";
|
||||
}
|
||||
@@ -1,12 +1,14 @@
|
||||
#if GRAPHQL
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Linq;
|
||||
using AnyOfTypes;
|
||||
using GraphQL;
|
||||
using GraphQL.Types;
|
||||
using Newtonsoft.Json;
|
||||
using Stef.Validation;
|
||||
using WireMock.Extensions;
|
||||
using WireMock.Models;
|
||||
|
||||
namespace WireMock.Matchers;
|
||||
@@ -19,8 +21,10 @@ public class GraphQLMatcher : IStringMatcher
|
||||
{
|
||||
private sealed class GraphQLRequest
|
||||
{
|
||||
// ReSharper disable once UnusedAutoPropertyAccessor.Local
|
||||
public string? Query { get; set; }
|
||||
|
||||
// ReSharper disable once UnusedAutoPropertyAccessor.Local
|
||||
public Dictionary<string, object?>? Variables { get; set; }
|
||||
}
|
||||
|
||||
@@ -31,21 +35,16 @@ public class GraphQLMatcher : IStringMatcher
|
||||
/// <inheritdoc />
|
||||
public MatchBehaviour MatchBehaviour { get; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool ThrowException { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="LinqMatcher"/> class.
|
||||
/// </summary>
|
||||
/// <param name="schema">The schema.</param>
|
||||
/// <param name="matchBehaviour">The match behaviour.</param>
|
||||
/// <param name="throwException">Throw an exception when the internal matching fails because of invalid input.</param>
|
||||
/// <param name="matchOperator">The <see cref="Matchers.MatchOperator"/> to use. (default = "Or")</param>
|
||||
public GraphQLMatcher(AnyOf<string, StringPattern, ISchema> schema, MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch, bool throwException = false, MatchOperator matchOperator = MatchOperator.Or)
|
||||
public GraphQLMatcher(AnyOf<string, StringPattern, ISchema> schema, MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch, MatchOperator matchOperator = MatchOperator.Or)
|
||||
{
|
||||
Guard.NotNull(schema);
|
||||
MatchBehaviour = matchBehaviour;
|
||||
ThrowException = throwException;
|
||||
MatchOperator = matchOperator;
|
||||
|
||||
var patterns = new List<AnyOf<string, StringPattern>>();
|
||||
@@ -72,51 +71,44 @@ public class GraphQLMatcher : IStringMatcher
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public double IsMatch(string? input)
|
||||
public MatchResult IsMatch(string? input)
|
||||
{
|
||||
var match = MatchScores.Mismatch;
|
||||
var score = MatchScores.Mismatch;
|
||||
Exception? exception = null;
|
||||
|
||||
try
|
||||
if (input != null && TryGetGraphQLRequest(input, out var graphQLRequest))
|
||||
{
|
||||
var graphQLRequest = JsonConvert.DeserializeObject<GraphQLRequest>(input!)!;
|
||||
|
||||
var executionResult = new DocumentExecuter().ExecuteAsync(_ =>
|
||||
try
|
||||
{
|
||||
_.ThrowOnUnhandledException = true;
|
||||
|
||||
_.Schema = _schema;
|
||||
_.Query = graphQLRequest.Query;
|
||||
|
||||
if (graphQLRequest.Variables != null)
|
||||
var executionResult = new DocumentExecuter().ExecuteAsync(_ =>
|
||||
{
|
||||
_.Variables = new Inputs(graphQLRequest.Variables);
|
||||
}
|
||||
}).GetAwaiter().GetResult();
|
||||
_.ThrowOnUnhandledException = true;
|
||||
|
||||
if (executionResult.Errors == null || executionResult.Errors.Count == 0)
|
||||
{
|
||||
match = MatchScores.Perfect;
|
||||
}
|
||||
else
|
||||
{
|
||||
var exceptions = executionResult.Errors.OfType<Exception>().ToArray();
|
||||
if (exceptions.Length == 1)
|
||||
_.Schema = _schema;
|
||||
_.Query = graphQLRequest.Query;
|
||||
|
||||
if (graphQLRequest.Variables != null)
|
||||
{
|
||||
_.Variables = new Inputs(graphQLRequest.Variables);
|
||||
}
|
||||
}).GetAwaiter().GetResult();
|
||||
|
||||
if (executionResult.Errors == null || executionResult.Errors.Count == 0)
|
||||
{
|
||||
throw exceptions[0];
|
||||
score = MatchScores.Perfect;
|
||||
}
|
||||
else
|
||||
{
|
||||
exception = executionResult.Errors.OfType<Exception>().ToArray().ToException();
|
||||
}
|
||||
|
||||
throw new AggregateException(exceptions);
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
if (ThrowException)
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw;
|
||||
exception = ex;
|
||||
}
|
||||
}
|
||||
|
||||
return MatchBehaviourHelper.Convert(MatchBehaviour, match);
|
||||
return new MatchResult(MatchBehaviourHelper.Convert(MatchBehaviour, score), exception);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
@@ -131,6 +123,20 @@ public class GraphQLMatcher : IStringMatcher
|
||||
/// <inheritdoc />
|
||||
public string Name => nameof(GraphQLMatcher);
|
||||
|
||||
private static bool TryGetGraphQLRequest(string input, [NotNullWhen(true)] out GraphQLRequest? graphQLRequest)
|
||||
{
|
||||
try
|
||||
{
|
||||
graphQLRequest = JsonConvert.DeserializeObject<GraphQLRequest>(input);
|
||||
return graphQLRequest != null;
|
||||
}
|
||||
catch
|
||||
{
|
||||
graphQLRequest = default;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private static ISchema BuildSchema(string schema)
|
||||
{
|
||||
return Schema.For(schema);
|
||||
|
||||
@@ -6,7 +6,7 @@ namespace WireMock.Matchers.Helpers;
|
||||
|
||||
internal static class BodyDataMatchScoreCalculator
|
||||
{
|
||||
public static double CalculateMatchScore(IBodyData? requestMessage, IMatcher matcher)
|
||||
public static MatchResult CalculateMatchScore(IBodyData? requestMessage, IMatcher matcher)
|
||||
{
|
||||
Guard.NotNull(matcher);
|
||||
|
||||
@@ -23,7 +23,7 @@ internal static class BodyDataMatchScoreCalculator
|
||||
return notNullOrEmptyMatcher.IsMatch(requestMessage.BodyAsBytes);
|
||||
|
||||
default:
|
||||
return MatchScores.Mismatch;
|
||||
return default;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -63,16 +63,6 @@ internal static class BodyDataMatchScoreCalculator
|
||||
}
|
||||
}
|
||||
|
||||
#if MIMEKIT_XXX
|
||||
if (matcher is MultiPartMatcher multiPartMatcher)
|
||||
{
|
||||
// If the body is a String or MultiPart, use the BodyAsString to match on.
|
||||
if (requestMessage?.DetectedBodyType is BodyType.String or BodyType.MultiPart)
|
||||
{
|
||||
return multiPartMatcher.IsMatch(requestMessage.BodyAsString);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return MatchScores.Mismatch;
|
||||
return default;
|
||||
}
|
||||
}
|
||||
@@ -14,9 +14,4 @@ public interface IMatcher
|
||||
/// Gets the match behaviour.
|
||||
/// </summary>
|
||||
MatchBehaviour MatchBehaviour { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Should this matcher throw an exception?
|
||||
/// </summary>
|
||||
bool ThrowException { get; }
|
||||
}
|
||||
@@ -9,6 +9,6 @@ public interface IObjectMatcher : IMatcher
|
||||
/// Determines whether the specified input is match.
|
||||
/// </summary>
|
||||
/// <param name="input">The input.</param>
|
||||
/// <returns>A value between 0.0 - 1.0 of the similarity.</returns>
|
||||
double IsMatch(object? input);
|
||||
/// <returns>MatchResult</returns>
|
||||
MatchResult IsMatch(object? input);
|
||||
}
|
||||
@@ -13,8 +13,8 @@ public interface IStringMatcher : IMatcher
|
||||
/// Determines whether the specified input is match.
|
||||
/// </summary>
|
||||
/// <param name="input">The input.</param>
|
||||
/// <returns>A value between 0.0 - 1.0 of the similarity.</returns>
|
||||
double IsMatch(string? input);
|
||||
/// <returns>MatchResult</returns>
|
||||
MatchResult IsMatch(string? input);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the patterns.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using AnyOfTypes;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Stef.Validation;
|
||||
using WireMock.Extensions;
|
||||
@@ -17,17 +17,15 @@ public class JsonPathMatcher : IStringMatcher, IObjectMatcher
|
||||
{
|
||||
private readonly AnyOf<string, StringPattern>[] _patterns;
|
||||
|
||||
/// <inheritdoc cref="IMatcher.MatchBehaviour"/>
|
||||
/// <inheritdoc />
|
||||
public MatchBehaviour MatchBehaviour { get; }
|
||||
|
||||
/// <inheritdoc cref="IMatcher.ThrowException"/>
|
||||
public bool ThrowException { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="JsonPathMatcher"/> class.
|
||||
/// </summary>
|
||||
/// <param name="patterns">The patterns.</param>
|
||||
public JsonPathMatcher(params string[] patterns) : this(MatchBehaviour.AcceptOnMatch, false, MatchOperator.Or, patterns.ToAnyOfPatterns())
|
||||
public JsonPathMatcher(params string[] patterns) : this(MatchBehaviour.AcceptOnMatch, MatchOperator.Or,
|
||||
patterns.ToAnyOfPatterns())
|
||||
{
|
||||
}
|
||||
|
||||
@@ -35,7 +33,8 @@ public class JsonPathMatcher : IStringMatcher, IObjectMatcher
|
||||
/// Initializes a new instance of the <see cref="JsonPathMatcher"/> class.
|
||||
/// </summary>
|
||||
/// <param name="patterns">The patterns.</param>
|
||||
public JsonPathMatcher(params AnyOf<string, StringPattern>[] patterns) : this(MatchBehaviour.AcceptOnMatch, false, MatchOperator.Or, patterns)
|
||||
public JsonPathMatcher(params AnyOf<string, StringPattern>[] patterns) : this(MatchBehaviour.AcceptOnMatch,
|
||||
MatchOperator.Or, patterns)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -43,48 +42,45 @@ public class JsonPathMatcher : IStringMatcher, IObjectMatcher
|
||||
/// Initializes a new instance of the <see cref="JsonPathMatcher"/> class.
|
||||
/// </summary>
|
||||
/// <param name="matchBehaviour">The match behaviour.</param>
|
||||
/// <param name="throwException">Throw an exception when the internal matching fails because of invalid input.</param>
|
||||
/// <param name="matchOperator">The <see cref="Matchers.MatchOperator"/> to use. (default = "Or")</param>
|
||||
/// <param name="patterns">The patterns.</param>
|
||||
public JsonPathMatcher(
|
||||
MatchBehaviour matchBehaviour,
|
||||
bool throwException = false,
|
||||
MatchOperator matchOperator = MatchOperator.Or,
|
||||
params AnyOf<string, StringPattern>[] patterns)
|
||||
{
|
||||
_patterns = Guard.NotNull(patterns);
|
||||
MatchBehaviour = matchBehaviour;
|
||||
ThrowException = throwException;
|
||||
MatchOperator = matchOperator;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IStringMatcher.IsMatch"/>
|
||||
public double IsMatch(string? input)
|
||||
/// <inheritdoc />
|
||||
public MatchResult IsMatch(string? input)
|
||||
{
|
||||
double match = MatchScores.Mismatch;
|
||||
var score = MatchScores.Mismatch;
|
||||
Exception? exception = null;
|
||||
|
||||
if (input != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
var jToken = JToken.Parse(input);
|
||||
match = IsMatch(jToken);
|
||||
score = IsMatch(jToken);
|
||||
}
|
||||
catch (JsonException)
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (ThrowException)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
exception = ex;
|
||||
}
|
||||
}
|
||||
|
||||
return MatchBehaviourHelper.Convert(MatchBehaviour, match);
|
||||
return new MatchResult(MatchBehaviourHelper.Convert(MatchBehaviour, score), exception);
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IObjectMatcher.IsMatch"/>
|
||||
public double IsMatch(object? input)
|
||||
/// <inheritdoc />
|
||||
public MatchResult IsMatch(object? input)
|
||||
{
|
||||
double match = MatchScores.Mismatch;
|
||||
var score = MatchScores.Mismatch;
|
||||
Exception? exception = null;
|
||||
|
||||
// When input is null or byte[], return Mismatch.
|
||||
if (input != null && !(input is byte[]))
|
||||
@@ -93,18 +89,15 @@ public class JsonPathMatcher : IStringMatcher, IObjectMatcher
|
||||
{
|
||||
// Check if JToken or object
|
||||
JToken jToken = input as JToken ?? JObject.FromObject(input);
|
||||
match = IsMatch(jToken);
|
||||
score = IsMatch(jToken);
|
||||
}
|
||||
catch (JsonException)
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (ThrowException)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
exception = ex;
|
||||
}
|
||||
}
|
||||
|
||||
return MatchBehaviourHelper.Convert(MatchBehaviour, match);
|
||||
return new MatchResult(MatchBehaviourHelper.Convert(MatchBehaviour, score), exception);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
@@ -116,14 +109,18 @@ public class JsonPathMatcher : IStringMatcher, IObjectMatcher
|
||||
/// <inheritdoc />
|
||||
public MatchOperator MatchOperator { get; }
|
||||
|
||||
/// <inheritdoc cref="IMatcher.Name"/>
|
||||
/// <inheritdoc />
|
||||
public string Name => "JsonPathMatcher";
|
||||
|
||||
private double IsMatch(JToken jToken)
|
||||
{
|
||||
var array = ConvertJTokenToJArrayIfNeeded(jToken);
|
||||
|
||||
return MatchScores.ToScore(_patterns.Select(pattern => array.SelectToken(pattern.GetPattern())?.Any() == true).ToArray(), MatchOperator);
|
||||
// The SelectToken method can accept a string path to a child token ( i.e. "Manufacturers[0].Products[0].Price").
|
||||
// In that case it will return a JValue (some type) which does not implement the IEnumerable interface.
|
||||
var values = _patterns.Select(pattern => array.SelectToken(pattern.GetPattern()) != null).ToArray();
|
||||
|
||||
return MatchScores.ToScore(values, MatchOperator);
|
||||
}
|
||||
|
||||
// https://github.com/WireMock-Net/WireMock.Net/issues/965
|
||||
@@ -138,9 +135,9 @@ public class JsonPathMatcher : IStringMatcher, IObjectMatcher
|
||||
var item = property.First();
|
||||
if (item is JArray)
|
||||
{
|
||||
return jToken;
|
||||
return jToken;
|
||||
}
|
||||
|
||||
|
||||
return new JObject
|
||||
{
|
||||
[property.Path] = new JArray(item)
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using AnyOfTypes;
|
||||
using DevLab.JmesPath;
|
||||
@@ -15,17 +16,14 @@ public class JmesPathMatcher : IStringMatcher, IObjectMatcher
|
||||
{
|
||||
private readonly AnyOf<string, StringPattern>[] _patterns;
|
||||
|
||||
/// <inheritdoc cref="IMatcher.MatchBehaviour"/>
|
||||
/// <inheritdoc />
|
||||
public MatchBehaviour MatchBehaviour { get; }
|
||||
|
||||
/// <inheritdoc cref="IMatcher.ThrowException"/>
|
||||
public bool ThrowException { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="JmesPathMatcher"/> class.
|
||||
/// </summary>
|
||||
/// <param name="patterns">The patterns.</param>
|
||||
public JmesPathMatcher(params string[] patterns) : this(MatchBehaviour.AcceptOnMatch, false, MatchOperator.Or, patterns.ToAnyOfPatterns())
|
||||
public JmesPathMatcher(params string[] patterns) : this(MatchBehaviour.AcceptOnMatch, MatchOperator.Or, patterns.ToAnyOfPatterns())
|
||||
{
|
||||
}
|
||||
|
||||
@@ -33,18 +31,17 @@ public class JmesPathMatcher : IStringMatcher, IObjectMatcher
|
||||
/// Initializes a new instance of the <see cref="JmesPathMatcher"/> class.
|
||||
/// </summary>
|
||||
/// <param name="patterns">The patterns.</param>
|
||||
public JmesPathMatcher(params AnyOf<string, StringPattern>[] patterns) : this(MatchBehaviour.AcceptOnMatch, false, MatchOperator.Or, patterns)
|
||||
public JmesPathMatcher(params AnyOf<string, StringPattern>[] patterns) : this(MatchBehaviour.AcceptOnMatch, MatchOperator.Or, patterns)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="JmesPathMatcher"/> class.
|
||||
/// </summary>
|
||||
/// <param name="throwException">Throw an exception when the internal matching fails because of invalid input.</param>
|
||||
/// <param name="matchOperator">The <see cref="Matchers.MatchOperator"/> to use.</param>
|
||||
/// <param name="patterns">The patterns.</param>
|
||||
public JmesPathMatcher(bool throwException = false, MatchOperator matchOperator = MatchOperator.Or, params AnyOf<string, StringPattern>[] patterns) :
|
||||
this(MatchBehaviour.AcceptOnMatch, throwException, matchOperator, patterns)
|
||||
public JmesPathMatcher(MatchOperator matchOperator = MatchOperator.Or, params AnyOf<string, StringPattern>[] patterns) :
|
||||
this(MatchBehaviour.AcceptOnMatch, matchOperator, patterns)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -52,60 +49,56 @@ public class JmesPathMatcher : IStringMatcher, IObjectMatcher
|
||||
/// Initializes a new instance of the <see cref="JmesPathMatcher"/> class.
|
||||
/// </summary>
|
||||
/// <param name="matchBehaviour">The match behaviour.</param>
|
||||
/// <param name="throwException">Throw an exception when the internal matching fails because of invalid input.</param>
|
||||
/// <param name="matchOperator">The <see cref="Matchers.MatchOperator"/> to use.</param>
|
||||
/// <param name="patterns">The patterns.</param>
|
||||
public JmesPathMatcher(
|
||||
MatchBehaviour matchBehaviour,
|
||||
bool throwException = false,
|
||||
MatchOperator matchOperator = MatchOperator.Or,
|
||||
params AnyOf<string, StringPattern>[] patterns)
|
||||
{
|
||||
_patterns = Guard.NotNull(patterns);
|
||||
MatchBehaviour = matchBehaviour;
|
||||
ThrowException = throwException;
|
||||
MatchOperator = matchOperator;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IStringMatcher.IsMatch"/>
|
||||
public double IsMatch(string? input)
|
||||
/// <inheritdoc />
|
||||
public MatchResult IsMatch(string? input)
|
||||
{
|
||||
double match = MatchScores.Mismatch;
|
||||
var score = MatchScores.Mismatch;
|
||||
Exception? exception = null;
|
||||
|
||||
if (input != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
var results = _patterns.Select(pattern => bool.Parse(new JmesPath().Transform(input, pattern.GetPattern()))).ToArray();
|
||||
match = MatchScores.ToScore(results, MatchOperator);
|
||||
score = MatchScores.ToScore(results, MatchOperator);
|
||||
}
|
||||
catch (JsonException)
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (ThrowException)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
exception = ex;
|
||||
}
|
||||
}
|
||||
|
||||
return MatchBehaviourHelper.Convert(MatchBehaviour, match);
|
||||
return new MatchResult(MatchBehaviourHelper.Convert(MatchBehaviour, score), exception);
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IObjectMatcher.IsMatch"/>
|
||||
public double IsMatch(object? input)
|
||||
/// <inheritdoc />
|
||||
public MatchResult IsMatch(object? input)
|
||||
{
|
||||
double match = MatchScores.Mismatch;
|
||||
var score = MatchScores.Mismatch;
|
||||
|
||||
// When input is null or byte[], return Mismatch.
|
||||
if (input != null && !(input is byte[]))
|
||||
{
|
||||
string inputAsString = JsonConvert.SerializeObject(input);
|
||||
var inputAsString = JsonConvert.SerializeObject(input);
|
||||
return IsMatch(inputAsString);
|
||||
}
|
||||
|
||||
return MatchBehaviourHelper.Convert(MatchBehaviour, match);
|
||||
return MatchBehaviourHelper.Convert(MatchBehaviour, score);
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IStringMatcher.GetPatterns"/>
|
||||
/// <inheritdoc />
|
||||
public AnyOf<string, StringPattern>[] GetPatterns()
|
||||
{
|
||||
return _patterns;
|
||||
@@ -114,6 +107,6 @@ public class JmesPathMatcher : IStringMatcher, IObjectMatcher
|
||||
/// <inheritdoc />
|
||||
public MatchOperator MatchOperator { get; }
|
||||
|
||||
/// <inheritdoc cref="IMatcher.Name"/>
|
||||
public string Name => "JmesPathMatcher";
|
||||
/// <inheritdoc />
|
||||
public string Name => nameof(JmesPathMatcher);
|
||||
}
|
||||
@@ -1,7 +1,6 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Linq;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Stef.Validation;
|
||||
using WireMock.Util;
|
||||
@@ -13,21 +12,18 @@ namespace WireMock.Matchers;
|
||||
/// </summary>
|
||||
public class JsonMatcher : IValueMatcher, IIgnoreCaseMatcher
|
||||
{
|
||||
/// <inheritdoc cref="IMatcher.Name"/>
|
||||
/// <inheritdoc />
|
||||
public virtual string Name => "JsonMatcher";
|
||||
|
||||
/// <inheritdoc cref="IValueMatcher.Value"/>
|
||||
public object Value { get; }
|
||||
|
||||
/// <inheritdoc cref="IMatcher.MatchBehaviour"/>
|
||||
|
||||
/// <inheritdoc />
|
||||
public MatchBehaviour MatchBehaviour { get; }
|
||||
|
||||
/// <inheritdoc cref="IIgnoreCaseMatcher.IgnoreCase"/>
|
||||
public bool IgnoreCase { get; }
|
||||
|
||||
/// <inheritdoc cref="IMatcher.ThrowException"/>
|
||||
public bool ThrowException { get; }
|
||||
|
||||
private readonly JToken _valueAsJToken;
|
||||
private readonly Func<JToken, JToken> _jTokenConverter;
|
||||
|
||||
@@ -36,8 +32,7 @@ public class JsonMatcher : IValueMatcher, IIgnoreCaseMatcher
|
||||
/// </summary>
|
||||
/// <param name="value">The string value to check for equality.</param>
|
||||
/// <param name="ignoreCase">Ignore the case from the PropertyName and PropertyValue (string only).</param>
|
||||
/// <param name="throwException">Throw an exception when the internal matching fails because of invalid input.</param>
|
||||
public JsonMatcher(string value, bool ignoreCase = false, bool throwException = false) : this(MatchBehaviour.AcceptOnMatch, value, ignoreCase, throwException)
|
||||
public JsonMatcher(string value, bool ignoreCase = false) : this(MatchBehaviour.AcceptOnMatch, value, ignoreCase)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -46,8 +41,7 @@ public class JsonMatcher : IValueMatcher, IIgnoreCaseMatcher
|
||||
/// </summary>
|
||||
/// <param name="value">The object value to check for equality.</param>
|
||||
/// <param name="ignoreCase">Ignore the case from the PropertyName and PropertyValue (string only).</param>
|
||||
/// <param name="throwException">Throw an exception when the internal matching fails because of invalid input.</param>
|
||||
public JsonMatcher(object value, bool ignoreCase = false, bool throwException = false) : this(MatchBehaviour.AcceptOnMatch, value, ignoreCase, throwException)
|
||||
public JsonMatcher(object value, bool ignoreCase = false) : this(MatchBehaviour.AcceptOnMatch, value, ignoreCase)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -57,24 +51,23 @@ public class JsonMatcher : IValueMatcher, IIgnoreCaseMatcher
|
||||
/// <param name="matchBehaviour">The match behaviour.</param>
|
||||
/// <param name="value">The value to check for equality.</param>
|
||||
/// <param name="ignoreCase">Ignore the case from the PropertyName and PropertyValue (string only).</param>
|
||||
/// <param name="throwException">Throw an exception when the internal matching fails because of invalid input.</param>
|
||||
public JsonMatcher(MatchBehaviour matchBehaviour, object value, bool ignoreCase = false, bool throwException = false)
|
||||
public JsonMatcher(MatchBehaviour matchBehaviour, object value, bool ignoreCase = false)
|
||||
{
|
||||
Guard.NotNull(value, nameof(value));
|
||||
|
||||
MatchBehaviour = matchBehaviour;
|
||||
IgnoreCase = ignoreCase;
|
||||
ThrowException = throwException;
|
||||
|
||||
Value = value;
|
||||
_valueAsJToken = ConvertValueToJToken(value);
|
||||
_jTokenConverter = ignoreCase ? Rename : jToken => jToken;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IObjectMatcher.IsMatch"/>
|
||||
public double IsMatch(object? input)
|
||||
/// <inheritdoc />
|
||||
public MatchResult IsMatch(object? input)
|
||||
{
|
||||
bool match = false;
|
||||
var score = MatchScores.Mismatch;
|
||||
Exception? error = null;
|
||||
|
||||
// When input is null or byte[], return Mismatch.
|
||||
if (input != null && input is not byte[])
|
||||
@@ -83,20 +76,16 @@ public class JsonMatcher : IValueMatcher, IIgnoreCaseMatcher
|
||||
{
|
||||
var inputAsJToken = ConvertValueToJToken(input);
|
||||
|
||||
match = IsMatch(
|
||||
_jTokenConverter(_valueAsJToken),
|
||||
_jTokenConverter(inputAsJToken));
|
||||
var match = IsMatch(_jTokenConverter(_valueAsJToken), _jTokenConverter(inputAsJToken));
|
||||
score = MatchScores.ToScore(match);
|
||||
}
|
||||
catch (JsonException)
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (ThrowException)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
error = ex;
|
||||
}
|
||||
}
|
||||
|
||||
return MatchBehaviourHelper.Convert(MatchBehaviour, MatchScores.ToScore(match));
|
||||
return new MatchResult(MatchBehaviourHelper.Convert(MatchBehaviour, score), error);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -9,27 +9,27 @@ public class JsonPartialMatcher : AbstractJsonPartialMatcher
|
||||
public override string Name => nameof(JsonPartialMatcher);
|
||||
|
||||
/// <inheritdoc />
|
||||
public JsonPartialMatcher(string value, bool ignoreCase = false, bool throwException = false, bool regex = false)
|
||||
: base(value, ignoreCase, throwException, regex)
|
||||
public JsonPartialMatcher(string value, bool ignoreCase = false, bool regex = false)
|
||||
: base(value, ignoreCase, regex)
|
||||
{
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public JsonPartialMatcher(object value, bool ignoreCase = false, bool throwException = false, bool regex = false)
|
||||
: base(value, ignoreCase, throwException, regex)
|
||||
public JsonPartialMatcher(object value, bool ignoreCase = false, bool regex = false)
|
||||
: base(value, ignoreCase, regex)
|
||||
{
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public JsonPartialMatcher(MatchBehaviour matchBehaviour, object value, bool ignoreCase = false, bool throwException = false, bool regex = false)
|
||||
: base(matchBehaviour, value, ignoreCase, throwException, regex)
|
||||
public JsonPartialMatcher(MatchBehaviour matchBehaviour, object value, bool ignoreCase = false, bool regex = false)
|
||||
: base(matchBehaviour, value, ignoreCase, regex)
|
||||
{
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override bool IsMatch(string value, string input)
|
||||
{
|
||||
var exactStringMatcher = new ExactMatcher(MatchBehaviour.AcceptOnMatch, IgnoreCase, ThrowException, MatchOperator.Or, value);
|
||||
return MatchScores.IsPerfect(exactStringMatcher.IsMatch(input));
|
||||
var exactStringMatcher = new ExactMatcher(MatchBehaviour.AcceptOnMatch, IgnoreCase, MatchOperator.Or, value);
|
||||
return exactStringMatcher.IsMatch(input).IsPerfect();
|
||||
}
|
||||
}
|
||||
@@ -9,20 +9,20 @@ public class JsonPartialWildcardMatcher : AbstractJsonPartialMatcher
|
||||
public override string Name => nameof(JsonPartialWildcardMatcher);
|
||||
|
||||
/// <inheritdoc />
|
||||
public JsonPartialWildcardMatcher(string value, bool ignoreCase = false, bool throwException = false, bool regex = false)
|
||||
: base(value, ignoreCase, throwException, regex)
|
||||
public JsonPartialWildcardMatcher(string value, bool ignoreCase = false, bool regex = false)
|
||||
: base(value, ignoreCase, regex)
|
||||
{
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public JsonPartialWildcardMatcher(object value, bool ignoreCase = false, bool throwException = false, bool regex = false)
|
||||
: base(value, ignoreCase, throwException, regex)
|
||||
public JsonPartialWildcardMatcher(object value, bool ignoreCase = false, bool regex = false)
|
||||
: base(value, ignoreCase, regex)
|
||||
{
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public JsonPartialWildcardMatcher(MatchBehaviour matchBehaviour, object value, bool ignoreCase = false, bool throwException = false, bool regex = false)
|
||||
: base(matchBehaviour, value, ignoreCase, throwException, regex)
|
||||
public JsonPartialWildcardMatcher(MatchBehaviour matchBehaviour, object value, bool ignoreCase = false, bool regex = false)
|
||||
: base(matchBehaviour, value, ignoreCase, regex)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -30,6 +30,6 @@ public class JsonPartialWildcardMatcher : AbstractJsonPartialMatcher
|
||||
protected override bool IsMatch(string value, string input)
|
||||
{
|
||||
var wildcardStringMatcher = new WildcardMatcher(MatchBehaviour.AcceptOnMatch, value, IgnoreCase);
|
||||
return MatchScores.IsPerfect(wildcardStringMatcher.IsMatch(input));
|
||||
return wildcardStringMatcher.IsMatch(input).IsPerfect();
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Linq.Dynamic.Core;
|
||||
using AnyOfTypes;
|
||||
@@ -18,12 +19,9 @@ public class LinqMatcher : IObjectMatcher, IStringMatcher
|
||||
{
|
||||
private readonly AnyOf<string, StringPattern>[] _patterns;
|
||||
|
||||
/// <inheritdoc cref="IMatcher.MatchBehaviour"/>
|
||||
/// <inheritdoc />
|
||||
public MatchBehaviour MatchBehaviour { get; }
|
||||
|
||||
/// <inheritdoc cref="IMatcher.ThrowException"/>
|
||||
public bool ThrowException { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="LinqMatcher"/> class.
|
||||
/// </summary>
|
||||
@@ -36,7 +34,7 @@ public class LinqMatcher : IObjectMatcher, IStringMatcher
|
||||
/// Initializes a new instance of the <see cref="LinqMatcher"/> class.
|
||||
/// </summary>
|
||||
/// <param name="patterns">The patterns.</param>
|
||||
public LinqMatcher(params AnyOf<string, StringPattern>[] patterns) : this(MatchBehaviour.AcceptOnMatch, false, MatchOperator.Or, patterns)
|
||||
public LinqMatcher(params AnyOf<string, StringPattern>[] patterns) : this(MatchBehaviour.AcceptOnMatch, MatchOperator.Or, patterns)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -45,7 +43,7 @@ public class LinqMatcher : IObjectMatcher, IStringMatcher
|
||||
/// </summary>
|
||||
/// <param name="matchBehaviour">The match behaviour.</param>
|
||||
/// <param name="pattern">The pattern.</param>
|
||||
public LinqMatcher(MatchBehaviour matchBehaviour, AnyOf<string, StringPattern> pattern) : this(matchBehaviour, false, MatchOperator.Or, pattern)
|
||||
public LinqMatcher(MatchBehaviour matchBehaviour, AnyOf<string, StringPattern> pattern) : this(matchBehaviour, MatchOperator.Or, pattern)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -53,25 +51,23 @@ public class LinqMatcher : IObjectMatcher, IStringMatcher
|
||||
/// Initializes a new instance of the <see cref="LinqMatcher"/> class.
|
||||
/// </summary>
|
||||
/// <param name="matchBehaviour">The match behaviour.</param>
|
||||
/// <param name="throwException">Throw an exception when the internal matching fails because of invalid input.</param>
|
||||
/// <param name="matchOperator">The <see cref="Matchers.MatchOperator"/> to use. (default = "Or")</param>
|
||||
/// <param name="patterns">The patterns.</param>
|
||||
public LinqMatcher(
|
||||
MatchBehaviour matchBehaviour,
|
||||
bool throwException = false,
|
||||
MatchOperator matchOperator = MatchOperator.Or,
|
||||
params AnyOf<string, StringPattern>[] patterns)
|
||||
{
|
||||
_patterns = Guard.NotNull(patterns);
|
||||
MatchBehaviour = matchBehaviour;
|
||||
ThrowException = throwException;
|
||||
MatchOperator = matchOperator;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public double IsMatch(string? input)
|
||||
public MatchResult IsMatch(string? input)
|
||||
{
|
||||
double match = MatchScores.Mismatch;
|
||||
var score = MatchScores.Mismatch;
|
||||
Exception? error = null;
|
||||
|
||||
// Convert a single input string to a Queryable string-list with 1 entry.
|
||||
IQueryable queryable = new[] { input }.AsQueryable();
|
||||
@@ -79,25 +75,21 @@ public class LinqMatcher : IObjectMatcher, IStringMatcher
|
||||
try
|
||||
{
|
||||
// Use the Any(...) method to check if the result matches
|
||||
match = MatchScores.ToScore(_patterns.Select(pattern => queryable.Any(pattern.GetPattern())).ToArray(), MatchOperator);
|
||||
|
||||
return MatchBehaviourHelper.Convert(MatchBehaviour, match);
|
||||
score = MatchScores.ToScore(_patterns.Select(pattern => queryable.Any(pattern.GetPattern())).ToArray(), MatchOperator);
|
||||
}
|
||||
catch
|
||||
catch (Exception e)
|
||||
{
|
||||
if (ThrowException)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
error = e;
|
||||
}
|
||||
|
||||
return MatchBehaviourHelper.Convert(MatchBehaviour, match);
|
||||
return new MatchResult(MatchBehaviourHelper.Convert(MatchBehaviour, score), error);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public double IsMatch(object? input)
|
||||
public MatchResult IsMatch(object? input)
|
||||
{
|
||||
double match = MatchScores.Mismatch;
|
||||
var score = MatchScores.Mismatch;
|
||||
Exception? error = null;
|
||||
|
||||
JArray jArray;
|
||||
try
|
||||
@@ -106,7 +98,7 @@ public class LinqMatcher : IObjectMatcher, IStringMatcher
|
||||
}
|
||||
catch
|
||||
{
|
||||
jArray = new JArray { JToken.FromObject(input) };
|
||||
jArray = input == null ? new JArray() : new JArray { JToken.FromObject(input) };
|
||||
}
|
||||
|
||||
// Convert a single object to a Queryable JObject-list with 1 entry.
|
||||
@@ -117,19 +109,14 @@ public class LinqMatcher : IObjectMatcher, IStringMatcher
|
||||
var patternsAsStringArray = _patterns.Select(p => p.GetPattern()).ToArray();
|
||||
var scores = patternsAsStringArray.Select(p => queryable.Any(p)).ToArray();
|
||||
|
||||
match = MatchScores.ToScore(scores, MatchOperator);
|
||||
|
||||
return MatchBehaviourHelper.Convert(MatchBehaviour, match);
|
||||
score = MatchScores.ToScore(scores, MatchOperator);
|
||||
}
|
||||
catch
|
||||
catch (Exception e)
|
||||
{
|
||||
if (ThrowException)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
error = e;
|
||||
}
|
||||
|
||||
return MatchBehaviourHelper.Convert(MatchBehaviour, match);
|
||||
return new MatchResult(MatchBehaviourHelper.Convert(MatchBehaviour, score), error);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
@@ -142,5 +129,5 @@ public class LinqMatcher : IObjectMatcher, IStringMatcher
|
||||
public MatchOperator MatchOperator { get; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public string Name => "LinqMatcher";
|
||||
public string Name => nameof(LinqMatcher);
|
||||
}
|
||||
89
src/WireMock.Net/Matchers/MatchResult.cs
Normal file
89
src/WireMock.Net/Matchers/MatchResult.cs
Normal file
@@ -0,0 +1,89 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Stef.Validation;
|
||||
using WireMock.Extensions;
|
||||
|
||||
namespace WireMock.Matchers;
|
||||
|
||||
/// <summary>
|
||||
/// The MatchResult which contains the score (value between 0.0 - 1.0 of the similarity) and an optional error message.
|
||||
/// </summary>
|
||||
public struct MatchResult
|
||||
{
|
||||
/// <summary>
|
||||
/// A value between 0.0 - 1.0 of the similarity.
|
||||
/// </summary>
|
||||
public double Score { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The exception message) in case the matching fails.
|
||||
/// [Optional]
|
||||
/// </summary>
|
||||
public Exception? Exception { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Create a MatchResult
|
||||
/// </summary>
|
||||
/// <param name="score">A value between 0.0 - 1.0 of the similarity.</param>
|
||||
/// <param name="exception">The exception in case the matching fails. [Optional]</param>
|
||||
public MatchResult(double score, Exception? exception = null)
|
||||
{
|
||||
Score = score;
|
||||
Exception = exception;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create a MatchResult
|
||||
/// </summary>
|
||||
/// <param name="exception">The exception in case the matching fails.</param>
|
||||
public MatchResult(Exception exception)
|
||||
{
|
||||
Exception = Guard.NotNull(exception);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Implicitly converts a double to a MatchResult.
|
||||
/// </summary>
|
||||
/// <param name="score">The score</param>
|
||||
public static implicit operator MatchResult(double score)
|
||||
{
|
||||
return new MatchResult(score);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Is the value a perfect match?
|
||||
/// </summary>
|
||||
public bool IsPerfect() => MatchScores.IsPerfect(Score);
|
||||
|
||||
/// <summary>
|
||||
/// Create a MatchResult from multiple MatchResults.
|
||||
/// </summary>
|
||||
/// <param name="matchResults">A list of MatchResults.</param>
|
||||
/// <param name="matchOperator">The MatchOperator</param>
|
||||
/// <returns>MatchResult</returns>
|
||||
public static MatchResult From(IReadOnlyList<MatchResult> matchResults, MatchOperator matchOperator)
|
||||
{
|
||||
Guard.NotNullOrEmpty(matchResults);
|
||||
|
||||
if (matchResults.Count == 1)
|
||||
{
|
||||
return matchResults[0];
|
||||
}
|
||||
|
||||
return new MatchResult
|
||||
{
|
||||
Score = MatchScores.ToScore(matchResults.Select(r => r.Score).ToArray(), matchOperator),
|
||||
Exception = matchResults.Select(m => m.Exception).OfType<Exception>().ToArray().ToException()
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Expand to Tuple
|
||||
/// </summary>
|
||||
/// <returns>Tuple : Score and Exception</returns>
|
||||
public (double Score, Exception? Exception) Expand()
|
||||
{
|
||||
return (Score, Exception);
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,9 @@
|
||||
#if MIMEKIT
|
||||
using System;
|
||||
using MimeKit;
|
||||
using WireMock.Matchers;
|
||||
using WireMock.Matchers.Helpers;
|
||||
using WireMock.Models;
|
||||
using WireMock.Util;
|
||||
|
||||
namespace WireMock.Matchers;
|
||||
@@ -11,7 +13,7 @@ namespace WireMock.Matchers;
|
||||
/// </summary>
|
||||
public class MimePartMatcher : IMatcher
|
||||
{
|
||||
private readonly Func<MimePart, double>[] _funcs;
|
||||
private readonly Func<MimePart, MatchResult>[] _funcs;
|
||||
|
||||
/// <inheritdoc />
|
||||
public string Name => nameof(MimePartMatcher);
|
||||
@@ -39,9 +41,6 @@ public class MimePartMatcher : IMatcher
|
||||
/// <inheritdoc />
|
||||
public MatchBehaviour MatchBehaviour { get; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool ThrowException { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="MimePartMatcher"/> class.
|
||||
/// </summary>
|
||||
@@ -50,8 +49,7 @@ public class MimePartMatcher : IMatcher
|
||||
IStringMatcher? contentTypeMatcher,
|
||||
IStringMatcher? contentDispositionMatcher,
|
||||
IStringMatcher? contentTransferEncodingMatcher,
|
||||
IMatcher? contentMatcher,
|
||||
bool throwException = false
|
||||
IMatcher? contentMatcher
|
||||
)
|
||||
{
|
||||
MatchBehaviour = matchBehaviour;
|
||||
@@ -59,7 +57,6 @@ public class MimePartMatcher : IMatcher
|
||||
ContentDispositionMatcher = contentDispositionMatcher;
|
||||
ContentTransferEncodingMatcher = contentTransferEncodingMatcher;
|
||||
ContentMatcher = contentMatcher;
|
||||
ThrowException = throwException;
|
||||
|
||||
_funcs = new[]
|
||||
{
|
||||
@@ -75,29 +72,27 @@ public class MimePartMatcher : IMatcher
|
||||
/// </summary>
|
||||
/// <param name="mimePart">The MimePart.</param>
|
||||
/// <returns>A value between 0.0 - 1.0 of the similarity.</returns>
|
||||
public double IsMatch(MimePart mimePart)
|
||||
public MatchResult IsMatch(MimePart mimePart)
|
||||
{
|
||||
var match = MatchScores.Mismatch;
|
||||
var score = MatchScores.Mismatch;
|
||||
Exception? exception = null;
|
||||
|
||||
try
|
||||
{
|
||||
if (Array.TrueForAll(_funcs, func => MatchScores.IsPerfect(func(mimePart))))
|
||||
if (Array.TrueForAll(_funcs, func => func(mimePart).IsPerfect()))
|
||||
{
|
||||
match = MatchScores.Perfect;
|
||||
score = MatchScores.Perfect;
|
||||
}
|
||||
}
|
||||
catch
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (ThrowException)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
exception = ex;
|
||||
}
|
||||
|
||||
return MatchBehaviourHelper.Convert(MatchBehaviour, match);
|
||||
return new MatchResult(MatchBehaviourHelper.Convert(MatchBehaviour, score), exception);
|
||||
}
|
||||
|
||||
private double MatchOnContent(MimePart mimePart)
|
||||
private MatchResult MatchOnContent(MimePart mimePart)
|
||||
{
|
||||
if (ContentMatcher == null)
|
||||
{
|
||||
|
||||
@@ -11,15 +11,12 @@ namespace WireMock.Matchers;
|
||||
/// <seealso cref="IObjectMatcher" />
|
||||
public class NotNullOrEmptyMatcher : IObjectMatcher, IStringMatcher
|
||||
{
|
||||
/// <inheritdoc cref="IMatcher.Name"/>
|
||||
public string Name => "NotNullOrEmptyMatcher";
|
||||
/// <inheritdoc />
|
||||
public string Name => nameof(NotNullOrEmptyMatcher);
|
||||
|
||||
/// <inheritdoc cref="IMatcher.MatchBehaviour"/>
|
||||
/// <inheritdoc />
|
||||
public MatchBehaviour MatchBehaviour { get; }
|
||||
|
||||
/// <inheritdoc cref="IMatcher.ThrowException"/>
|
||||
public bool ThrowException { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="NotNullOrEmptyMatcher"/> class.
|
||||
/// </summary>
|
||||
@@ -29,8 +26,8 @@ public class NotNullOrEmptyMatcher : IObjectMatcher, IStringMatcher
|
||||
MatchBehaviour = matchBehaviour;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IObjectMatcher.IsMatch"/>
|
||||
public double IsMatch(object? input)
|
||||
/// <inheritdoc />
|
||||
public MatchResult IsMatch(object? input)
|
||||
{
|
||||
bool match;
|
||||
|
||||
@@ -52,15 +49,15 @@ public class NotNullOrEmptyMatcher : IObjectMatcher, IStringMatcher
|
||||
return MatchBehaviourHelper.Convert(MatchBehaviour, MatchScores.ToScore(match));
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IStringMatcher.IsMatch"/>
|
||||
public double IsMatch(string? input)
|
||||
/// <inheritdoc />
|
||||
public MatchResult IsMatch(string? input)
|
||||
{
|
||||
var match = !string.IsNullOrEmpty(input);
|
||||
|
||||
return MatchBehaviourHelper.Convert(MatchBehaviour, MatchScores.ToScore(match));
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IStringMatcher.GetPatterns"/>
|
||||
/// <inheritdoc />
|
||||
public AnyOf<string, StringPattern>[] GetPatterns()
|
||||
{
|
||||
return EmptyArray<AnyOf<string, StringPattern>>.Value;
|
||||
|
||||
@@ -20,27 +20,22 @@ public class RegexMatcher : IStringMatcher, IIgnoreCaseMatcher
|
||||
private readonly AnyOf<string, StringPattern>[] _patterns;
|
||||
private readonly Regex[] _expressions;
|
||||
|
||||
/// <inheritdoc cref="IMatcher.MatchBehaviour"/>
|
||||
/// <inheritdoc />
|
||||
public MatchBehaviour MatchBehaviour { get; }
|
||||
|
||||
/// <inheritdoc cref="IMatcher.ThrowException"/>
|
||||
public bool ThrowException { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RegexMatcher"/> class.
|
||||
/// </summary>
|
||||
/// <param name="pattern">The pattern.</param>
|
||||
/// <param name="ignoreCase">Ignore the case from the pattern.</param>
|
||||
/// <param name="throwException">Throw an exception when the internal matching fails because of invalid input.</param>
|
||||
/// <param name="useRegexExtended">Use RegexExtended (default = true).</param>
|
||||
/// <param name="matchOperator">The <see cref="Matchers.MatchOperator"/> to use. (default = "Or")</param>
|
||||
public RegexMatcher(
|
||||
[RegexPattern] AnyOf<string, StringPattern> pattern,
|
||||
bool ignoreCase = false,
|
||||
bool throwException = false,
|
||||
bool useRegexExtended = true,
|
||||
MatchOperator matchOperator = MatchOperator.Or) :
|
||||
this(MatchBehaviour.AcceptOnMatch, new[] { pattern }, ignoreCase, throwException, useRegexExtended, matchOperator)
|
||||
this(MatchBehaviour.AcceptOnMatch, new[] { pattern }, ignoreCase, useRegexExtended, matchOperator)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -50,17 +45,15 @@ public class RegexMatcher : IStringMatcher, IIgnoreCaseMatcher
|
||||
/// <param name="matchBehaviour">The match behaviour.</param>
|
||||
/// <param name="pattern">The pattern.</param>
|
||||
/// <param name="ignoreCase">Ignore the case from the pattern.</param>
|
||||
/// <param name="throwException">Throw an exception when the internal matching fails because of invalid input.</param>
|
||||
/// <param name="useRegexExtended">Use RegexExtended (default = true).</param>
|
||||
/// <param name="matchOperator">The <see cref="Matchers.MatchOperator"/> to use. (default = "Or")</param>
|
||||
public RegexMatcher(
|
||||
MatchBehaviour matchBehaviour,
|
||||
[RegexPattern] AnyOf<string, StringPattern> pattern,
|
||||
bool ignoreCase = false,
|
||||
bool throwException = false,
|
||||
bool useRegexExtended = true,
|
||||
MatchOperator matchOperator = MatchOperator.Or) :
|
||||
this(matchBehaviour, new[] { pattern }, ignoreCase, throwException, useRegexExtended, matchOperator)
|
||||
this(matchBehaviour, new[] { pattern }, ignoreCase, useRegexExtended, matchOperator)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -70,21 +63,18 @@ public class RegexMatcher : IStringMatcher, IIgnoreCaseMatcher
|
||||
/// <param name="matchBehaviour">The match behaviour.</param>
|
||||
/// <param name="patterns">The patterns.</param>
|
||||
/// <param name="ignoreCase">Ignore the case from the pattern.</param>
|
||||
/// <param name="throwException">Throw an exception when the internal matching fails because of invalid input.</param>
|
||||
/// <param name="useRegexExtended">Use RegexExtended (default = true).</param>
|
||||
/// <param name="matchOperator">The <see cref="Matchers.MatchOperator"/> to use. (default = "Or")</param>
|
||||
public RegexMatcher(
|
||||
MatchBehaviour matchBehaviour,
|
||||
[RegexPattern] AnyOf<string, StringPattern>[] patterns,
|
||||
bool ignoreCase = false,
|
||||
bool throwException = false,
|
||||
bool useRegexExtended = true,
|
||||
MatchOperator matchOperator = MatchOperator.Or)
|
||||
{
|
||||
_patterns = Guard.NotNull(patterns);
|
||||
IgnoreCase = ignoreCase;
|
||||
MatchBehaviour = matchBehaviour;
|
||||
ThrowException = throwException;
|
||||
MatchOperator = matchOperator;
|
||||
|
||||
RegexOptions options = RegexOptions.Compiled | RegexOptions.Multiline;
|
||||
@@ -97,26 +87,25 @@ public class RegexMatcher : IStringMatcher, IIgnoreCaseMatcher
|
||||
_expressions = patterns.Select(p => useRegexExtended ? new RegexExtended(p.GetPattern(), options) : new Regex(p.GetPattern(), options)).ToArray();
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IStringMatcher.IsMatch"/>
|
||||
public virtual double IsMatch(string? input)
|
||||
/// <inheritdoc />
|
||||
public virtual MatchResult IsMatch(string? input)
|
||||
{
|
||||
double match = MatchScores.Mismatch;
|
||||
var score = MatchScores.Mismatch;
|
||||
Exception? exception = null;
|
||||
|
||||
if (input != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
match = MatchScores.ToScore(_expressions.Select(e => e.IsMatch(input)).ToArray(), MatchOperator);
|
||||
score = MatchScores.ToScore(_expressions.Select(e => e.IsMatch(input)).ToArray(), MatchOperator);
|
||||
}
|
||||
catch (Exception)
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (ThrowException)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
exception = ex;
|
||||
}
|
||||
}
|
||||
|
||||
return MatchBehaviourHelper.Convert(MatchBehaviour, match);
|
||||
return new MatchResult(MatchBehaviourHelper.Convert(MatchBehaviour, score), exception);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
|
||||
@@ -9,30 +9,25 @@ namespace WireMock.Matchers.Request;
|
||||
/// </summary>
|
||||
public class RequestMatchResult : IRequestMatchResult
|
||||
{
|
||||
/// <inheritdoc cref="IRequestMatchResult.TotalScore" />
|
||||
/// <inheritdoc />
|
||||
public double TotalScore => MatchDetails.Sum(md => md.Score);
|
||||
|
||||
/// <inheritdoc cref="IRequestMatchResult.TotalNumber" />
|
||||
/// <inheritdoc />
|
||||
public int TotalNumber => MatchDetails.Count;
|
||||
|
||||
/// <inheritdoc cref="IRequestMatchResult.IsPerfectMatch" />
|
||||
/// <inheritdoc />
|
||||
public bool IsPerfectMatch => Math.Abs(TotalScore - TotalNumber) < MatchScores.Tolerance;
|
||||
|
||||
/// <inheritdoc cref="IRequestMatchResult.AverageTotalScore" />
|
||||
public double AverageTotalScore => TotalNumber == 0 ? 0.0 : TotalScore / TotalNumber;
|
||||
/// <inheritdoc />
|
||||
public double AverageTotalScore => TotalNumber == 0 ? MatchScores.Mismatch : TotalScore / TotalNumber;
|
||||
|
||||
/// <inheritdoc cref="IRequestMatchResult.MatchDetails" />
|
||||
/// <inheritdoc />
|
||||
public IList<MatchDetail> MatchDetails { get; } = new List<MatchDetail>();
|
||||
|
||||
/// <summary>
|
||||
/// Adds the score.
|
||||
/// </summary>
|
||||
/// <param name="matcherType">The matcher Type.</param>
|
||||
/// <param name="score">The score.</param>
|
||||
/// <returns>The score.</returns>
|
||||
public double AddScore(Type matcherType, double score)
|
||||
/// <inheritdoc />
|
||||
public double AddScore(Type matcherType, double score, Exception? exception)
|
||||
{
|
||||
MatchDetails.Add(new MatchDetail { MatcherType = matcherType, Score = score });
|
||||
MatchDetails.Add(new MatchDetail { MatcherType = matcherType, Score = score, Exception = exception });
|
||||
|
||||
return score;
|
||||
}
|
||||
@@ -44,11 +39,16 @@ public class RequestMatchResult : IRequestMatchResult
|
||||
/// <returns>
|
||||
/// A value that indicates the relative order of the objects being compared. The return value has these meanings: Value Meaning Less than zero This instance precedes <paramref name="obj" /> in the sort order. Zero This instance occurs in the same position in the sort order as <paramref name="obj" />. Greater than zero This instance follows <paramref name="obj" /> in the sort order.
|
||||
/// </returns>
|
||||
public int CompareTo(object obj)
|
||||
public int CompareTo(object? obj)
|
||||
{
|
||||
if (obj == null)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
var compareObj = (RequestMatchResult)obj;
|
||||
|
||||
int averageTotalScoreResult = compareObj.AverageTotalScore.CompareTo(AverageTotalScore);
|
||||
var averageTotalScoreResult = compareObj.AverageTotalScore.CompareTo(AverageTotalScore);
|
||||
|
||||
// In case the score is equal, prefer the one with the most matchers.
|
||||
return averageTotalScoreResult == 0 ? compareObj.TotalNumber.CompareTo(TotalNumber) : averageTotalScoreResult;
|
||||
|
||||
@@ -145,16 +145,16 @@ public class RequestMessageBodyMatcher : IRequestMatcher
|
||||
/// <inheritdoc />
|
||||
public double GetMatchingScore(IRequestMessage requestMessage, IRequestMatchResult requestMatchResult)
|
||||
{
|
||||
double score = CalculateMatchScore(requestMessage);
|
||||
return requestMatchResult.AddScore(GetType(), score);
|
||||
var (score, exception) = CalculateMatchScore(requestMessage).Expand();
|
||||
return requestMatchResult.AddScore(GetType(), score, exception);
|
||||
}
|
||||
|
||||
private double CalculateMatchScore(IRequestMessage requestMessage)
|
||||
private MatchResult CalculateMatchScore(IRequestMessage requestMessage)
|
||||
{
|
||||
if (Matchers != null)
|
||||
if (Matchers != null && Matchers.Any())
|
||||
{
|
||||
var matchersResult = Matchers.Select(matcher => BodyDataMatchScoreCalculator.CalculateMatchScore(requestMessage.BodyData, matcher)).ToArray();
|
||||
return MatchScores.ToScore(matchersResult, MatchOperator);
|
||||
var results = Matchers.Select(matcher => BodyDataMatchScoreCalculator.CalculateMatchScore(requestMessage.BodyData, matcher)).ToArray();
|
||||
return MatchResult.From(results, MatchOperator);
|
||||
}
|
||||
|
||||
if (Func != null)
|
||||
@@ -182,6 +182,6 @@ public class RequestMessageBodyMatcher : IRequestMatcher
|
||||
return MatchScores.ToScore(BodyDataFunc(requestMessage.BodyData));
|
||||
}
|
||||
|
||||
return MatchScores.Mismatch;
|
||||
return default;
|
||||
}
|
||||
}
|
||||
@@ -43,7 +43,7 @@ public class RequestMessageClientIPMatcher : IRequestMatcher
|
||||
MatchOperator matchOperator,
|
||||
params string[] clientIPs) :
|
||||
this(matchBehaviour, matchOperator, clientIPs
|
||||
.Select(clientIP => new WildcardMatcher(matchBehaviour, new AnyOf<string, StringPattern>[] { clientIP }, false, false, matchOperator))
|
||||
.Select(clientIP => new WildcardMatcher(matchBehaviour, new AnyOf<string, StringPattern>[] { clientIP }, false, matchOperator))
|
||||
.Cast<IStringMatcher>().ToArray())
|
||||
{
|
||||
Behaviour = matchBehaviour;
|
||||
@@ -75,16 +75,16 @@ public class RequestMessageClientIPMatcher : IRequestMatcher
|
||||
/// <inheritdoc />
|
||||
public double GetMatchingScore(IRequestMessage requestMessage, IRequestMatchResult requestMatchResult)
|
||||
{
|
||||
double score = IsMatch(requestMessage);
|
||||
return requestMatchResult.AddScore(GetType(), score);
|
||||
var (score, exception) = GetMatchResult(requestMessage).Expand();
|
||||
return requestMatchResult.AddScore(GetType(), score, exception);
|
||||
}
|
||||
|
||||
private double IsMatch(IRequestMessage requestMessage)
|
||||
private MatchResult GetMatchResult(IRequestMessage requestMessage)
|
||||
{
|
||||
if (Matchers != null)
|
||||
{
|
||||
var results = Matchers.Select(m => m.IsMatch(requestMessage.ClientIP)).ToArray();
|
||||
return MatchScores.ToScore(results, MatchOperator);
|
||||
return MatchResult.From(results, MatchOperator);
|
||||
}
|
||||
|
||||
if (Funcs != null)
|
||||
@@ -93,6 +93,6 @@ public class RequestMessageClientIPMatcher : IRequestMatcher
|
||||
return MatchScores.ToScore(results, MatchOperator);
|
||||
}
|
||||
|
||||
return MatchScores.Mismatch;
|
||||
return default;
|
||||
}
|
||||
}
|
||||
@@ -11,9 +11,15 @@ namespace WireMock.Matchers.Request;
|
||||
/// <inheritdoc cref="IRequestMatcher"/>
|
||||
public class RequestMessageCookieMatcher : IRequestMatcher
|
||||
{
|
||||
private readonly MatchBehaviour _matchBehaviour;
|
||||
/// <summary>
|
||||
/// MatchBehaviour
|
||||
/// </summary>
|
||||
public MatchBehaviour MatchBehaviour { get; }
|
||||
|
||||
private readonly bool _ignoreCase;
|
||||
/// <summary>
|
||||
/// IgnoreCase
|
||||
/// </summary>
|
||||
public bool IgnoreCase { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The functions
|
||||
@@ -39,8 +45,8 @@ public class RequestMessageCookieMatcher : IRequestMatcher
|
||||
/// <param name="matchBehaviour">The match behaviour.</param>
|
||||
public RequestMessageCookieMatcher(MatchBehaviour matchBehaviour, string name, string pattern, bool ignoreCase)
|
||||
{
|
||||
_matchBehaviour = matchBehaviour;
|
||||
_ignoreCase = ignoreCase;
|
||||
MatchBehaviour = matchBehaviour;
|
||||
IgnoreCase = ignoreCase;
|
||||
Name = Guard.NotNull(name);
|
||||
Matchers = new IStringMatcher[] { new WildcardMatcher(matchBehaviour, Guard.NotNull(pattern), ignoreCase) };
|
||||
}
|
||||
@@ -67,10 +73,10 @@ public class RequestMessageCookieMatcher : IRequestMatcher
|
||||
/// <param name="ignoreCase">Ignore the case from the pattern.</param>
|
||||
public RequestMessageCookieMatcher(MatchBehaviour matchBehaviour, string name, bool ignoreCase, params IStringMatcher[] matchers)
|
||||
{
|
||||
_matchBehaviour = matchBehaviour;
|
||||
MatchBehaviour = matchBehaviour;
|
||||
Name = Guard.NotNull(name);
|
||||
Matchers = Guard.NotNull(matchers);
|
||||
_ignoreCase = ignoreCase;
|
||||
IgnoreCase = ignoreCase;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -88,19 +94,19 @@ public class RequestMessageCookieMatcher : IRequestMatcher
|
||||
/// <inheritdoc />
|
||||
public double GetMatchingScore(IRequestMessage requestMessage, IRequestMatchResult requestMatchResult)
|
||||
{
|
||||
double score = IsMatch(requestMessage);
|
||||
return requestMatchResult.AddScore(GetType(), score);
|
||||
var (score, exception) = GetMatchResult(requestMessage).Expand();
|
||||
return requestMatchResult.AddScore(GetType(), score, exception);
|
||||
}
|
||||
|
||||
private double IsMatch(IRequestMessage requestMessage)
|
||||
private MatchResult GetMatchResult(IRequestMessage requestMessage)
|
||||
{
|
||||
if (requestMessage.Cookies == null)
|
||||
{
|
||||
return MatchBehaviourHelper.Convert(_matchBehaviour, MatchScores.Mismatch);
|
||||
return MatchBehaviourHelper.Convert(MatchBehaviour, MatchScores.Mismatch);
|
||||
}
|
||||
|
||||
// Check if we want to use IgnoreCase to compare the Cookie-Name and Cookie-Value
|
||||
var cookies = !_ignoreCase ? requestMessage.Cookies : new Dictionary<string, string>(requestMessage.Cookies, StringComparer.OrdinalIgnoreCase);
|
||||
var cookies = !IgnoreCase ? requestMessage.Cookies : new Dictionary<string, string>(requestMessage.Cookies, StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
if (Funcs != null)
|
||||
{
|
||||
@@ -109,15 +115,14 @@ public class RequestMessageCookieMatcher : IRequestMatcher
|
||||
|
||||
if (Matchers == null)
|
||||
{
|
||||
return MatchScores.Mismatch;
|
||||
return default;
|
||||
}
|
||||
|
||||
if (!cookies.ContainsKey(Name))
|
||||
{
|
||||
return MatchBehaviourHelper.Convert(_matchBehaviour, MatchScores.Mismatch);
|
||||
return MatchBehaviourHelper.Convert(MatchBehaviour, MatchScores.Mismatch);
|
||||
}
|
||||
|
||||
string value = cookies[Name];
|
||||
return Matchers.Max(m => m.IsMatch(value));
|
||||
return Matchers.Max(m => m.IsMatch(cookies[Name]));
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Stef.Validation;
|
||||
using WireMock.Types;
|
||||
@@ -64,11 +65,13 @@ public class RequestMessageGraphQLMatcher : IRequestMatcher
|
||||
/// <inheritdoc />
|
||||
public double GetMatchingScore(IRequestMessage requestMessage, IRequestMatchResult requestMatchResult)
|
||||
{
|
||||
var score = CalculateMatchScore(requestMessage);
|
||||
return requestMatchResult.AddScore(GetType(), score);
|
||||
var results = CalculateMatchResults(requestMessage);
|
||||
var (score, exception) = MatchResult.From(results, MatchOperator).Expand();
|
||||
|
||||
return requestMatchResult.AddScore(GetType(), score, exception);
|
||||
}
|
||||
|
||||
private static double CalculateMatchScore(IRequestMessage requestMessage, IMatcher matcher)
|
||||
private static MatchResult CalculateMatchResult(IRequestMessage requestMessage, IMatcher matcher)
|
||||
{
|
||||
// Check if the matcher is a IStringMatcher
|
||||
// If the body is a Json or a String, use the BodyAsString to match on.
|
||||
@@ -77,18 +80,12 @@ public class RequestMessageGraphQLMatcher : IRequestMatcher
|
||||
return stringMatcher.IsMatch(requestMessage.BodyData.BodyAsString);
|
||||
}
|
||||
|
||||
return MatchScores.Mismatch;
|
||||
return default;
|
||||
}
|
||||
|
||||
private double CalculateMatchScore(IRequestMessage requestMessage)
|
||||
private IReadOnlyList<MatchResult> CalculateMatchResults(IRequestMessage requestMessage)
|
||||
{
|
||||
if (Matchers == null)
|
||||
{
|
||||
return MatchScores.Mismatch;
|
||||
}
|
||||
|
||||
var matchersResult = Matchers.Select(matcher => CalculateMatchScore(requestMessage, matcher)).ToArray();
|
||||
return MatchScores.ToScore(matchersResult, MatchOperator);
|
||||
return Matchers == null ? new[] { new MatchResult() } : Matchers.Select(matcher => CalculateMatchResult(requestMessage, matcher)).ToArray();
|
||||
}
|
||||
|
||||
#if GRAPHQL
|
||||
|
||||
@@ -12,8 +12,15 @@ namespace WireMock.Matchers.Request;
|
||||
/// <inheritdoc cref="IRequestMatcher"/>
|
||||
public class RequestMessageHeaderMatcher : IRequestMatcher
|
||||
{
|
||||
private readonly MatchBehaviour _matchBehaviour;
|
||||
private readonly bool _ignoreCase;
|
||||
/// <summary>
|
||||
/// MatchBehaviour
|
||||
/// </summary>
|
||||
public MatchBehaviour MatchBehaviour { get; }
|
||||
|
||||
/// <summary>
|
||||
/// IgnoreCase
|
||||
/// </summary>
|
||||
public bool IgnoreCase { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The functions
|
||||
@@ -47,8 +54,8 @@ public class RequestMessageHeaderMatcher : IRequestMatcher
|
||||
Guard.NotNull(name);
|
||||
Guard.NotNull(pattern);
|
||||
|
||||
_matchBehaviour = matchBehaviour;
|
||||
_ignoreCase = ignoreCase;
|
||||
MatchBehaviour = matchBehaviour;
|
||||
IgnoreCase = ignoreCase;
|
||||
Name = name;
|
||||
Matchers = new IStringMatcher[] { new WildcardMatcher(matchBehaviour, pattern, ignoreCase) };
|
||||
}
|
||||
@@ -80,11 +87,11 @@ public class RequestMessageHeaderMatcher : IRequestMatcher
|
||||
Guard.NotNull(name);
|
||||
Guard.NotNull(matchers);
|
||||
|
||||
_matchBehaviour = matchBehaviour;
|
||||
MatchBehaviour = matchBehaviour;
|
||||
MatchOperator = matchOperator;
|
||||
Name = name;
|
||||
Matchers = matchers;
|
||||
_ignoreCase = ignoreCase;
|
||||
IgnoreCase = ignoreCase;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -100,19 +107,19 @@ public class RequestMessageHeaderMatcher : IRequestMatcher
|
||||
/// <inheritdoc />
|
||||
public double GetMatchingScore(IRequestMessage requestMessage, IRequestMatchResult requestMatchResult)
|
||||
{
|
||||
double score = IsMatch(requestMessage);
|
||||
return requestMatchResult.AddScore(GetType(), score);
|
||||
var (score, exception) = GetMatchResult(requestMessage).Expand();
|
||||
return requestMatchResult.AddScore(GetType(), score, exception);
|
||||
}
|
||||
|
||||
private double IsMatch(IRequestMessage requestMessage)
|
||||
private MatchResult GetMatchResult(IRequestMessage requestMessage)
|
||||
{
|
||||
if (requestMessage.Headers == null)
|
||||
{
|
||||
return MatchBehaviourHelper.Convert(_matchBehaviour, MatchScores.Mismatch);
|
||||
return MatchBehaviourHelper.Convert(MatchBehaviour, MatchScores.Mismatch);
|
||||
}
|
||||
|
||||
// Check if we want to use IgnoreCase to compare the Header-Name and Header-Value(s)
|
||||
var headers = !_ignoreCase ? requestMessage.Headers : new Dictionary<string, WireMockList<string>>(requestMessage.Headers, StringComparer.OrdinalIgnoreCase);
|
||||
var headers = !IgnoreCase ? requestMessage.Headers : new Dictionary<string, WireMockList<string>>(requestMessage.Headers, StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
if (Funcs != null)
|
||||
{
|
||||
@@ -124,20 +131,20 @@ public class RequestMessageHeaderMatcher : IRequestMatcher
|
||||
{
|
||||
if (!headers.ContainsKey(Name))
|
||||
{
|
||||
return MatchBehaviourHelper.Convert(_matchBehaviour, MatchScores.Mismatch);
|
||||
return MatchBehaviourHelper.Convert(MatchBehaviour, MatchScores.Mismatch);
|
||||
}
|
||||
|
||||
var results = new List<double>();
|
||||
var results = new List<MatchResult>();
|
||||
foreach (var matcher in Matchers)
|
||||
{
|
||||
var resultsPerMatcher = headers[Name].Select(v => matcher.IsMatch(v)).ToArray();
|
||||
var resultsPerMatcher = headers[Name].Select(matcher.IsMatch).ToArray();
|
||||
|
||||
results.Add(MatchScores.ToScore(resultsPerMatcher, MatchOperator.And));
|
||||
results.Add(MatchResult.From(resultsPerMatcher, MatchOperator.And));
|
||||
}
|
||||
|
||||
return MatchScores.ToScore(results, MatchOperator);
|
||||
return MatchResult.From(results, MatchOperator);
|
||||
}
|
||||
|
||||
return MatchBehaviourHelper.Convert(_matchBehaviour, MatchScores.Mismatch);
|
||||
return MatchBehaviourHelper.Convert(MatchBehaviour, MatchScores.Mismatch);
|
||||
}
|
||||
}
|
||||
@@ -39,14 +39,9 @@ internal class RequestMessageMethodMatcher : IRequestMatcher
|
||||
|
||||
/// <inheritdoc />
|
||||
public double GetMatchingScore(IRequestMessage requestMessage, IRequestMatchResult requestMatchResult)
|
||||
{
|
||||
double score = MatchBehaviourHelper.Convert(MatchBehaviour, IsMatch(requestMessage));
|
||||
return requestMatchResult.AddScore(GetType(), score);
|
||||
}
|
||||
|
||||
private double IsMatch(IRequestMessage requestMessage)
|
||||
{
|
||||
var scores = Methods.Select(m => string.Equals(m, requestMessage.Method, StringComparison.OrdinalIgnoreCase)).ToArray();
|
||||
return MatchScores.ToScore(scores, MatchOperator);
|
||||
var score = MatchScores.ToScore(scores, MatchOperator);
|
||||
return requestMatchResult.AddScore(GetType(), score, null);
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Stef.Validation;
|
||||
using WireMock.Http;
|
||||
using WireMock.Util;
|
||||
|
||||
namespace WireMock.Matchers.Request;
|
||||
@@ -54,27 +54,31 @@ public class RequestMessageMultiPartMatcher : IRequestMatcher
|
||||
#if !MIMEKIT
|
||||
throw new System.NotSupportedException("The MultiPartMatcher can not be used for .NETStandard1.3 or .NET Framework 4.6.1 or lower.");
|
||||
#else
|
||||
var match = MatchScores.Mismatch;
|
||||
var score = MatchScores.Mismatch;
|
||||
Exception? exception = null;
|
||||
|
||||
if (Matchers?.Any() != true)
|
||||
{
|
||||
return requestMatchResult.AddScore(GetType(), match);
|
||||
return requestMatchResult.AddScore(GetType(), score, null);
|
||||
}
|
||||
|
||||
if (!MimeKitUtils.TryGetMimeMessage(requestMessage, out var message))
|
||||
{
|
||||
return requestMatchResult.AddScore(GetType(), score, null);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
var message = MimeKitUtils.GetMimeMessage(requestMessage.BodyData!, requestMessage.Headers![HttpKnownHeaderNames.ContentType].ToString());
|
||||
|
||||
var mimePartMatchers = Matchers.OfType<MimePartMatcher>().ToArray();
|
||||
|
||||
foreach (var mimePart in message.BodyParts.OfType<MimeKit.MimePart>())
|
||||
{
|
||||
var matchesForMimePart = new List<double> { MatchScores.Mismatch };
|
||||
var matchesForMimePart = new List<MatchResult> { default };
|
||||
matchesForMimePart.AddRange(mimePartMatchers.Select(matcher => matcher.IsMatch(mimePart)));
|
||||
|
||||
match = matchesForMimePart.Max();
|
||||
score = matchesForMimePart.Select(m => m.Score).Max();
|
||||
|
||||
if (MatchScores.IsPerfect(match))
|
||||
if (MatchScores.IsPerfect(score))
|
||||
{
|
||||
if (MatchOperator == MatchOperator.Or)
|
||||
{
|
||||
@@ -83,17 +87,17 @@ public class RequestMessageMultiPartMatcher : IRequestMatcher
|
||||
}
|
||||
else
|
||||
{
|
||||
match = MatchScores.Mismatch;
|
||||
score = MatchScores.Mismatch;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch
|
||||
catch (Exception ex)
|
||||
{
|
||||
// Empty
|
||||
exception = ex;
|
||||
}
|
||||
|
||||
return requestMatchResult.AddScore(GetType(), match);
|
||||
return requestMatchResult.AddScore(GetType(), score, exception);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -29,7 +29,7 @@ public class RequestMessageParamMatcher : IRequestMatcher
|
||||
/// <summary>
|
||||
/// Defines if the key should be matched using case-ignore.
|
||||
/// </summary>
|
||||
public bool? IgnoreCase { get; }
|
||||
public bool IgnoreCase { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The matchers.
|
||||
@@ -54,7 +54,7 @@ public class RequestMessageParamMatcher : IRequestMatcher
|
||||
/// <param name="ignoreCase">Defines if the key should be matched using case-ignore.</param>
|
||||
/// <param name="values">The values.</param>
|
||||
public RequestMessageParamMatcher(MatchBehaviour matchBehaviour, string key, bool ignoreCase, params string[]? values) :
|
||||
this(matchBehaviour, key, ignoreCase, values?.Select(value => new ExactMatcher(matchBehaviour, ignoreCase, false, MatchOperator.And, value)).Cast<IStringMatcher>().ToArray())
|
||||
this(matchBehaviour, key, ignoreCase, values?.Select(value => new ExactMatcher(matchBehaviour, ignoreCase, MatchOperator.And, value)).Cast<IStringMatcher>().ToArray())
|
||||
{
|
||||
}
|
||||
|
||||
@@ -85,22 +85,22 @@ public class RequestMessageParamMatcher : IRequestMatcher
|
||||
/// <inheritdoc />
|
||||
public double GetMatchingScore(IRequestMessage requestMessage, IRequestMatchResult requestMatchResult)
|
||||
{
|
||||
double score = MatchBehaviourHelper.Convert(MatchBehaviour, IsMatch(requestMessage));
|
||||
return requestMatchResult.AddScore(GetType(), score);
|
||||
var (score, exception) = GetMatchResult(requestMessage).Expand();
|
||||
return requestMatchResult.AddScore(GetType(), score, exception);
|
||||
}
|
||||
|
||||
private double IsMatch(IRequestMessage requestMessage)
|
||||
private MatchResult GetMatchResult(IRequestMessage requestMessage)
|
||||
{
|
||||
if (Funcs != null)
|
||||
{
|
||||
return MatchScores.ToScore(requestMessage.Query != null && Funcs.Any(f => f(requestMessage.Query)));
|
||||
}
|
||||
|
||||
var valuesPresentInRequestMessage = ((RequestMessage)requestMessage).GetParameter(Key, IgnoreCase ?? false);
|
||||
var valuesPresentInRequestMessage = ((RequestMessage)requestMessage).GetParameter(Key, IgnoreCase);
|
||||
if (valuesPresentInRequestMessage == null)
|
||||
{
|
||||
// Key is not present at all, just return Mismatch
|
||||
return MatchScores.Mismatch;
|
||||
return default;
|
||||
}
|
||||
|
||||
if (Matchers != null && Matchers.Any())
|
||||
@@ -115,10 +115,10 @@ public class RequestMessageParamMatcher : IRequestMatcher
|
||||
return MatchScores.Perfect;
|
||||
}
|
||||
|
||||
return MatchScores.Mismatch;
|
||||
return default;
|
||||
}
|
||||
|
||||
private double CalculateScore(IReadOnlyList<IStringMatcher> matchers, WireMockList<string> valuesPresentInRequestMessage)
|
||||
private static MatchResult CalculateScore(IReadOnlyList<IStringMatcher> matchers, WireMockList<string> valuesPresentInRequestMessage)
|
||||
{
|
||||
var total = new List<double>();
|
||||
|
||||
@@ -130,7 +130,7 @@ public class RequestMessageParamMatcher : IRequestMatcher
|
||||
double score = 0d;
|
||||
foreach (string valuePresentInRequestMessage in valuesPresentInRequestMessage)
|
||||
{
|
||||
score += matcher.IsMatch(valuePresentInRequestMessage) / matcher.GetPatterns().Length;
|
||||
score += matcher.IsMatch(valuePresentInRequestMessage).Score / matcher.GetPatterns().Length;
|
||||
}
|
||||
|
||||
total.Add(score);
|
||||
@@ -140,11 +140,11 @@ public class RequestMessageParamMatcher : IRequestMatcher
|
||||
{
|
||||
foreach (string valuePresentInRequestMessage in valuesPresentInRequestMessage)
|
||||
{
|
||||
double score = matchers.Max(m => m.IsMatch(valuePresentInRequestMessage));
|
||||
var score = matchers.Max(m => m.IsMatch(valuePresentInRequestMessage).Score);
|
||||
total.Add(score);
|
||||
}
|
||||
}
|
||||
|
||||
return total.Any() ? MatchScores.ToScore(total, MatchOperator.Average) : MatchScores.Mismatch;
|
||||
return total.Any() ? MatchScores.ToScore(total, MatchOperator.Average) : default;
|
||||
}
|
||||
}
|
||||
@@ -43,7 +43,7 @@ public class RequestMessagePathMatcher : IRequestMatcher
|
||||
MatchOperator matchOperator,
|
||||
params string[] paths) :
|
||||
this(matchBehaviour, matchOperator, paths
|
||||
.Select(path => new WildcardMatcher(matchBehaviour, new AnyOf<string, StringPattern>[] { path }, false, false, matchOperator))
|
||||
.Select(path => new WildcardMatcher(matchBehaviour, new AnyOf<string, StringPattern>[] { path }, false, matchOperator))
|
||||
.Cast<IStringMatcher>().ToArray())
|
||||
{
|
||||
Behaviour = matchBehaviour;
|
||||
@@ -75,16 +75,16 @@ public class RequestMessagePathMatcher : IRequestMatcher
|
||||
/// <inheritdoc />
|
||||
public double GetMatchingScore(IRequestMessage requestMessage, IRequestMatchResult requestMatchResult)
|
||||
{
|
||||
double score = IsMatch(requestMessage);
|
||||
return requestMatchResult.AddScore(GetType(), score);
|
||||
var (score, exception) = GetMatchResult(requestMessage).Expand();
|
||||
return requestMatchResult.AddScore(GetType(), score, exception);
|
||||
}
|
||||
|
||||
private double IsMatch(IRequestMessage requestMessage)
|
||||
private MatchResult GetMatchResult(IRequestMessage requestMessage)
|
||||
{
|
||||
if (Matchers != null)
|
||||
{
|
||||
var results = Matchers.Select(m => m.IsMatch(requestMessage.Path)).ToArray();
|
||||
return MatchScores.ToScore(results, MatchOperator);
|
||||
return MatchResult.From(results, MatchOperator);
|
||||
}
|
||||
|
||||
if (Funcs != null)
|
||||
@@ -93,6 +93,6 @@ public class RequestMessagePathMatcher : IRequestMatcher
|
||||
return MatchScores.ToScore(results, MatchOperator);
|
||||
}
|
||||
|
||||
return MatchScores.Mismatch;
|
||||
return default;
|
||||
}
|
||||
}
|
||||
@@ -30,11 +30,10 @@ internal class RequestMessageScenarioAndStateMatcher : IRequestMatcher
|
||||
/// <inheritdoc />
|
||||
public double GetMatchingScore(IRequestMessage requestMessage, IRequestMatchResult requestMatchResult)
|
||||
{
|
||||
double score = IsMatch();
|
||||
return requestMatchResult.AddScore(GetType(), score);
|
||||
return requestMatchResult.AddScore(GetType(), GetScore(), null);
|
||||
}
|
||||
|
||||
private double IsMatch()
|
||||
private double GetScore()
|
||||
{
|
||||
return Equals(_executionConditionState, _nextState) ? MatchScores.Perfect : MatchScores.Mismatch;
|
||||
}
|
||||
|
||||
@@ -43,7 +43,7 @@ public class RequestMessageUrlMatcher : IRequestMatcher
|
||||
MatchOperator matchOperator,
|
||||
params string[] urls) :
|
||||
this(matchBehaviour, matchOperator, urls
|
||||
.Select(url => new WildcardMatcher(matchBehaviour, new AnyOf<string, StringPattern>[] { url }, false, false, matchOperator))
|
||||
.Select(url => new WildcardMatcher(matchBehaviour, new AnyOf<string, StringPattern>[] { url }, false, matchOperator))
|
||||
.Cast<IStringMatcher>().ToArray())
|
||||
{
|
||||
Behaviour = matchBehaviour;
|
||||
@@ -75,16 +75,16 @@ public class RequestMessageUrlMatcher : IRequestMatcher
|
||||
/// <inheritdoc />
|
||||
public double GetMatchingScore(IRequestMessage requestMessage, IRequestMatchResult requestMatchResult)
|
||||
{
|
||||
double score = IsMatch(requestMessage);
|
||||
return requestMatchResult.AddScore(GetType(), score);
|
||||
var (score, exception) = GetMatchResult(requestMessage).Expand();
|
||||
return requestMatchResult.AddScore(GetType(), score, exception);
|
||||
}
|
||||
|
||||
private double IsMatch(IRequestMessage requestMessage)
|
||||
private MatchResult GetMatchResult(IRequestMessage requestMessage)
|
||||
{
|
||||
if (Matchers != null)
|
||||
{
|
||||
var results = Matchers.Select(m => m.IsMatch(requestMessage.Url)).ToArray();
|
||||
return MatchScores.ToScore(results, MatchOperator);
|
||||
return MatchResult.From(results, MatchOperator);
|
||||
}
|
||||
|
||||
if (Funcs != null)
|
||||
@@ -93,6 +93,6 @@ public class RequestMessageUrlMatcher : IRequestMatcher
|
||||
return MatchScores.ToScore(results, MatchOperator);
|
||||
}
|
||||
|
||||
return MatchScores.Mismatch;
|
||||
return default;
|
||||
}
|
||||
}
|
||||
@@ -18,12 +18,9 @@ public class SimMetricsMatcher : IStringMatcher
|
||||
private readonly AnyOf<string, StringPattern>[] _patterns;
|
||||
private readonly SimMetricType _simMetricType;
|
||||
|
||||
/// <inheritdoc cref="IMatcher.MatchBehaviour"/>
|
||||
/// <inheritdoc />
|
||||
public MatchBehaviour MatchBehaviour { get; }
|
||||
|
||||
/// <inheritdoc cref="IMatcher.ThrowException"/>
|
||||
public bool ThrowException { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="SimMetricsMatcher"/> class.
|
||||
/// </summary>
|
||||
@@ -67,24 +64,21 @@ public class SimMetricsMatcher : IStringMatcher
|
||||
/// <param name="matchBehaviour">The match behaviour.</param>
|
||||
/// <param name="patterns">The patterns.</param>
|
||||
/// <param name="simMetricType">The SimMetric Type</param>
|
||||
/// <param name="throwException">Throw an exception when the internal matching fails because of invalid input.</param>
|
||||
/// <param name="matchOperator">The <see cref="Matchers.MatchOperator"/> to use. (default = "Or")</param>
|
||||
public SimMetricsMatcher(
|
||||
MatchBehaviour matchBehaviour,
|
||||
AnyOf<string, StringPattern>[] patterns,
|
||||
SimMetricType simMetricType = SimMetricType.Levenstein,
|
||||
bool throwException = false,
|
||||
MatchOperator matchOperator = MatchOperator.Average)
|
||||
{
|
||||
_patterns = Guard.NotNull(patterns);
|
||||
_simMetricType = simMetricType;
|
||||
MatchBehaviour = matchBehaviour;
|
||||
ThrowException = throwException;
|
||||
MatchOperator = matchOperator;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IStringMatcher.IsMatch"/>
|
||||
public double IsMatch(string input)
|
||||
/// <inheritdoc />
|
||||
public MatchResult IsMatch(string? input)
|
||||
{
|
||||
IStringMetric stringMetricType = GetStringMetricType();
|
||||
|
||||
@@ -94,48 +88,30 @@ public class SimMetricsMatcher : IStringMatcher
|
||||
|
||||
private IStringMetric GetStringMetricType()
|
||||
{
|
||||
switch (_simMetricType)
|
||||
return _simMetricType switch
|
||||
{
|
||||
case SimMetricType.BlockDistance:
|
||||
return new BlockDistance();
|
||||
case SimMetricType.ChapmanLengthDeviation:
|
||||
return new ChapmanLengthDeviation();
|
||||
case SimMetricType.CosineSimilarity:
|
||||
return new CosineSimilarity();
|
||||
case SimMetricType.DiceSimilarity:
|
||||
return new DiceSimilarity();
|
||||
case SimMetricType.EuclideanDistance:
|
||||
return new EuclideanDistance();
|
||||
case SimMetricType.JaccardSimilarity:
|
||||
return new JaccardSimilarity();
|
||||
case SimMetricType.Jaro:
|
||||
return new Jaro();
|
||||
case SimMetricType.JaroWinkler:
|
||||
return new JaroWinkler();
|
||||
case SimMetricType.MatchingCoefficient:
|
||||
return new MatchingCoefficient();
|
||||
case SimMetricType.MongeElkan:
|
||||
return new MongeElkan();
|
||||
case SimMetricType.NeedlemanWunch:
|
||||
return new NeedlemanWunch();
|
||||
case SimMetricType.OverlapCoefficient:
|
||||
return new OverlapCoefficient();
|
||||
case SimMetricType.QGramsDistance:
|
||||
return new QGramsDistance();
|
||||
case SimMetricType.SmithWaterman:
|
||||
return new SmithWaterman();
|
||||
case SimMetricType.SmithWatermanGotoh:
|
||||
return new SmithWatermanGotoh();
|
||||
case SimMetricType.SmithWatermanGotohWindowedAffine:
|
||||
return new SmithWatermanGotohWindowedAffine();
|
||||
case SimMetricType.ChapmanMeanLength:
|
||||
return new ChapmanMeanLength();
|
||||
default:
|
||||
return new Levenstein();
|
||||
}
|
||||
SimMetricType.BlockDistance => new BlockDistance(),
|
||||
SimMetricType.ChapmanLengthDeviation => new ChapmanLengthDeviation(),
|
||||
SimMetricType.CosineSimilarity => new CosineSimilarity(),
|
||||
SimMetricType.DiceSimilarity => new DiceSimilarity(),
|
||||
SimMetricType.EuclideanDistance => new EuclideanDistance(),
|
||||
SimMetricType.JaccardSimilarity => new JaccardSimilarity(),
|
||||
SimMetricType.Jaro => new Jaro(),
|
||||
SimMetricType.JaroWinkler => new JaroWinkler(),
|
||||
SimMetricType.MatchingCoefficient => new MatchingCoefficient(),
|
||||
SimMetricType.MongeElkan => new MongeElkan(),
|
||||
SimMetricType.NeedlemanWunch => new NeedlemanWunch(),
|
||||
SimMetricType.OverlapCoefficient => new OverlapCoefficient(),
|
||||
SimMetricType.QGramsDistance => new QGramsDistance(),
|
||||
SimMetricType.SmithWaterman => new SmithWaterman(),
|
||||
SimMetricType.SmithWatermanGotoh => new SmithWatermanGotoh(),
|
||||
SimMetricType.SmithWatermanGotohWindowedAffine => new SmithWatermanGotohWindowedAffine(),
|
||||
SimMetricType.ChapmanMeanLength => new ChapmanMeanLength(),
|
||||
_ => new Levenstein()
|
||||
};
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IStringMatcher.GetPatterns"/>
|
||||
/// <inheritdoc />
|
||||
public AnyOf<string, StringPattern>[] GetPatterns()
|
||||
{
|
||||
return _patterns;
|
||||
@@ -144,6 +120,6 @@ public class SimMetricsMatcher : IStringMatcher
|
||||
/// <inheritdoc />
|
||||
public MatchOperator MatchOperator { get; } = MatchOperator.Average;
|
||||
|
||||
/// <inheritdoc cref="IMatcher.Name"/>
|
||||
/// <inheritdoc />
|
||||
public string Name => $"SimMetricsMatcher.{_simMetricType}";
|
||||
}
|
||||
@@ -49,15 +49,12 @@ public class WildcardMatcher : RegexMatcher
|
||||
/// <param name="matchBehaviour">The match behaviour.</param>
|
||||
/// <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>
|
||||
/// <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)
|
||||
MatchOperator matchOperator = MatchOperator.Or) : base(matchBehaviour, CreateArray(patterns), ignoreCase, true, matchOperator)
|
||||
{
|
||||
_patterns = Guard.NotNull(patterns);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
using System;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Linq;
|
||||
using System.Xml;
|
||||
using System.Xml.XPath;
|
||||
using AnyOfTypes;
|
||||
using WireMock.Extensions;
|
||||
using WireMock.Models;
|
||||
@@ -9,86 +11,91 @@ using Stef.Validation;
|
||||
using Wmhelp.XPath2;
|
||||
#endif
|
||||
|
||||
namespace WireMock.Matchers
|
||||
namespace WireMock.Matchers;
|
||||
|
||||
/// <summary>
|
||||
/// XPath2Matcher
|
||||
/// </summary>
|
||||
/// <seealso cref="IStringMatcher" />
|
||||
public class XPathMatcher : IStringMatcher
|
||||
{
|
||||
private readonly AnyOf<string, StringPattern>[] _patterns;
|
||||
|
||||
/// <inheritdoc />
|
||||
public MatchBehaviour MatchBehaviour { get; }
|
||||
|
||||
/// <summary>
|
||||
/// XPath2Matcher
|
||||
/// Initializes a new instance of the <see cref="XPathMatcher"/> class.
|
||||
/// </summary>
|
||||
/// <seealso cref="IStringMatcher" />
|
||||
public class XPathMatcher : IStringMatcher
|
||||
/// <param name="patterns">The patterns.</param>
|
||||
public XPathMatcher(params AnyOf<string, StringPattern>[] patterns) : this(MatchBehaviour.AcceptOnMatch, MatchOperator.Or, patterns)
|
||||
{
|
||||
private readonly AnyOf<string, StringPattern>[] _patterns;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IMatcher.MatchBehaviour"/>
|
||||
public MatchBehaviour MatchBehaviour { get; }
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="XPathMatcher"/> 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 XPathMatcher(
|
||||
MatchBehaviour matchBehaviour,
|
||||
MatchOperator matchOperator = MatchOperator.Or,
|
||||
params AnyOf<string, StringPattern>[] patterns)
|
||||
{
|
||||
_patterns = Guard.NotNull(patterns);
|
||||
MatchBehaviour = matchBehaviour;
|
||||
MatchOperator = matchOperator;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IMatcher.ThrowException"/>
|
||||
public bool ThrowException { get; }
|
||||
/// <inheritdoc />
|
||||
public MatchResult IsMatch(string? input)
|
||||
{
|
||||
var score = MatchScores.Mismatch;
|
||||
Exception? exception = null;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="XPathMatcher"/> class.
|
||||
/// </summary>
|
||||
/// <param name="patterns">The patterns.</param>
|
||||
public XPathMatcher(params AnyOf<string, StringPattern>[] patterns) : this(MatchBehaviour.AcceptOnMatch, false, MatchOperator.Or, patterns)
|
||||
if (input != null && TryGetXPathNavigator(input, out var nav))
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="XPathMatcher"/> class.
|
||||
/// </summary>
|
||||
/// <param name="matchBehaviour">The match behaviour.</param>
|
||||
/// <param name="throwException">Throw an exception when the internal matching fails because of invalid input.</param>
|
||||
/// <param name="matchOperator">The <see cref="Matchers.MatchOperator"/> to use. (default = "Or")</param>
|
||||
/// <param name="patterns">The patterns.</param>
|
||||
public XPathMatcher(
|
||||
MatchBehaviour matchBehaviour,
|
||||
bool throwException = false,
|
||||
MatchOperator matchOperator = MatchOperator.Or,
|
||||
params AnyOf<string, StringPattern>[] patterns)
|
||||
{
|
||||
_patterns = Guard.NotNull(patterns);
|
||||
MatchBehaviour = matchBehaviour;
|
||||
ThrowException = throwException;
|
||||
MatchOperator = matchOperator;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IStringMatcher.IsMatch"/>
|
||||
public double IsMatch(string? input)
|
||||
{
|
||||
double match = MatchScores.Mismatch;
|
||||
if (input != null)
|
||||
try
|
||||
{
|
||||
try
|
||||
{
|
||||
var nav = new XmlDocument { InnerXml = input }.CreateNavigator();
|
||||
#if NETSTANDARD1_3
|
||||
match = MatchScores.ToScore(_patterns.Select(p => true.Equals(nav.Evaluate($"boolean({p.GetPattern()})"))).ToArray(), MatchOperator);
|
||||
score = 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()})"))).ToArray(), MatchOperator);
|
||||
score = MatchScores.ToScore(_patterns.Select(p => true.Equals(nav.XPath2Evaluate($"boolean({p.GetPattern()})"))).ToArray(), MatchOperator);
|
||||
#endif
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
if (ThrowException)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return MatchBehaviourHelper.Convert(MatchBehaviour, match);
|
||||
catch (Exception ex)
|
||||
{
|
||||
exception = ex;
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IStringMatcher.GetPatterns"/>
|
||||
public AnyOf<string, StringPattern>[] GetPatterns()
|
||||
return new MatchResult(MatchBehaviourHelper.Convert(MatchBehaviour, score), exception);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public AnyOf<string, StringPattern>[] GetPatterns()
|
||||
{
|
||||
return _patterns;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public MatchOperator MatchOperator { get; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public string Name => nameof(XPathMatcher);
|
||||
|
||||
private static bool TryGetXPathNavigator(string input, [NotNullWhen(true)] out XPathNavigator? nav)
|
||||
{
|
||||
try
|
||||
{
|
||||
return _patterns;
|
||||
nav = new XmlDocument { InnerXml = input }.CreateNavigator()!;
|
||||
return true;
|
||||
}
|
||||
catch
|
||||
{
|
||||
nav = default;
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public MatchOperator MatchOperator { get; }
|
||||
|
||||
/// <inheritdoc cref="IMatcher.Name"/>
|
||||
public string Name => "XPathMatcher";
|
||||
}
|
||||
}
|
||||
@@ -70,6 +70,7 @@ namespace WireMock.Owin
|
||||
services.AddSingleton<IRandomizerDoubleBetween0And1, RandomizerDoubleBetween0And1>();
|
||||
services.AddSingleton<IOwinRequestMapper, OwinRequestMapper>();
|
||||
services.AddSingleton<IOwinResponseMapper, OwinResponseMapper>();
|
||||
services.AddSingleton<IGuidUtils, GuidUtils>();
|
||||
|
||||
#if NETCOREAPP3_1 || NET5_0 || NET6_0 || NET7_0
|
||||
AddCors(services);
|
||||
|
||||
@@ -67,7 +67,7 @@ namespace WireMock.Owin
|
||||
catch (Exception ex)
|
||||
{
|
||||
_options.Logger.Error("HttpStatusCode set to 500 {0}", ex);
|
||||
await _responseMapper.MapAsync(ResponseMessageBuilder.Create(JsonConvert.SerializeObject(ex), 500), ctx.Response).ConfigureAwait(false);
|
||||
await _responseMapper.MapAsync(ResponseMessageBuilder.Create(500, JsonConvert.SerializeObject(ex)), ctx.Response).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,7 +50,7 @@ namespace WireMock.Owin.Mappers
|
||||
_options = Guard.NotNull(options);
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IOwinResponseMapper.MapAsync"/>
|
||||
/// <inheritdoc />
|
||||
public async Task MapAsync(IResponseMessage? responseMessage, IResponse response)
|
||||
{
|
||||
if (responseMessage == null)
|
||||
@@ -134,10 +134,8 @@ namespace WireMock.Owin.Mappers
|
||||
return (responseMessage.BodyData.Encoding ?? _utf8NoBom).GetBytes(responseMessage.BodyData.BodyAsString!);
|
||||
|
||||
case BodyType.Json:
|
||||
var formatting = responseMessage.BodyData.BodyAsJsonIndented == true
|
||||
? Formatting.Indented
|
||||
: Formatting.None;
|
||||
string jsonBody = JsonConvert.SerializeObject(responseMessage.BodyData.BodyAsJson, new JsonSerializerSettings { Formatting = formatting, NullValueHandling = NullValueHandling.Ignore });
|
||||
var formatting = responseMessage.BodyData.BodyAsJsonIndented == true ? Formatting.Indented : Formatting.None;
|
||||
var jsonBody = JsonConvert.SerializeObject(responseMessage.BodyData.BodyAsJson, new JsonSerializerSettings { Formatting = formatting, NullValueHandling = NullValueHandling.Ignore });
|
||||
return (responseMessage.BodyData.Encoding ?? _utf8NoBom).GetBytes(jsonBody);
|
||||
|
||||
case BodyType.Bytes:
|
||||
|
||||
@@ -35,15 +35,32 @@ internal class MappingMatcher : IMappingMatcher
|
||||
{
|
||||
var nextState = GetNextState(mapping);
|
||||
|
||||
possibleMappings.Add(new MappingMatcherResult
|
||||
var mappingMatcherResult = new MappingMatcherResult
|
||||
{
|
||||
Mapping = mapping,
|
||||
RequestMatchResult = mapping.GetRequestMatchResult(request, nextState)
|
||||
});
|
||||
};
|
||||
|
||||
var exceptions = mappingMatcherResult.RequestMatchResult.MatchDetails
|
||||
.Where(md => md.Exception != null)
|
||||
.Select(md => md.Exception)
|
||||
.ToArray();
|
||||
|
||||
if (!exceptions.Any())
|
||||
{
|
||||
possibleMappings.Add(mappingMatcherResult);
|
||||
}
|
||||
else if (!request.AbsolutePath.StartsWith("/__admin", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
foreach (var ex in exceptions)
|
||||
{
|
||||
LogException(mapping, ex!);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_options.Logger.Error($"Getting a Request MatchResult for Mapping '{mapping.Guid}' failed. This mapping will not be evaluated. Exception: {ex}");
|
||||
LogException(mapping, ex);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -66,6 +83,11 @@ internal class MappingMatcher : IMappingMatcher
|
||||
return (match, partialMatch);
|
||||
}
|
||||
|
||||
private void LogException(IMapping mapping, Exception ex)
|
||||
{
|
||||
_options.Logger.Error($"Getting a Request MatchResult for Mapping '{mapping.Guid}' failed. This mapping will not be evaluated. Exception: {ex}");
|
||||
}
|
||||
|
||||
private string? GetNextState(IMapping mapping)
|
||||
{
|
||||
// If the mapping does not have a scenario or _options.Scenarios does not contain this scenario from the mapping,
|
||||
|
||||
@@ -9,9 +9,8 @@ using JetBrains.Annotations;
|
||||
using WireMock.Logging;
|
||||
using WireMock.Owin.Mappers;
|
||||
using Stef.Validation;
|
||||
using RandomDataGenerator.FieldOptions;
|
||||
using RandomDataGenerator.Randomizers;
|
||||
using WireMock.Services;
|
||||
using WireMock.Util;
|
||||
|
||||
namespace WireMock.Owin;
|
||||
|
||||
@@ -63,7 +62,7 @@ internal class OwinSelfHost : IOwinSelfHost
|
||||
private void StartServers()
|
||||
{
|
||||
#if NET46
|
||||
_logger.Info("Server using .net 4.6.1 or higher");
|
||||
_logger.Info("Server using .net 4.6");
|
||||
#else
|
||||
_logger.Info("Server using .net 4.5.x");
|
||||
#endif
|
||||
@@ -74,12 +73,13 @@ internal class OwinSelfHost : IOwinSelfHost
|
||||
var requestMapper = new OwinRequestMapper();
|
||||
var responseMapper = new OwinResponseMapper(_options);
|
||||
var matcher = new MappingMatcher(_options, new RandomizerDoubleBetween0And1());
|
||||
var guidUtils = new GuidUtils();
|
||||
|
||||
Action<IAppBuilder> startup = app =>
|
||||
{
|
||||
app.Use<GlobalExceptionMiddleware>(_options, responseMapper);
|
||||
_options.PreWireMockMiddlewareInit?.Invoke(app);
|
||||
app.Use<WireMockMiddleware>(_options, requestMapper, responseMapper, matcher);
|
||||
app.Use<WireMockMiddleware>(_options, requestMapper, responseMapper, matcher, guidUtils);
|
||||
_options.PostWireMockMiddlewareInit?.Invoke(app);
|
||||
};
|
||||
|
||||
|
||||
@@ -12,6 +12,8 @@ using WireMock.Types;
|
||||
using WireMock.ResponseBuilders;
|
||||
using WireMock.Settings;
|
||||
using System.Collections.Generic;
|
||||
using WireMock.Constants;
|
||||
using WireMock.Util;
|
||||
#if !USE_ASPNETCORE
|
||||
using IContext = Microsoft.Owin.IOwinContext;
|
||||
using OwinMiddleware = Microsoft.Owin.OwinMiddleware;
|
||||
@@ -28,29 +30,47 @@ namespace WireMock.Owin
|
||||
{
|
||||
private readonly object _lock = new();
|
||||
private static readonly Task CompletedTask = Task.FromResult(false);
|
||||
|
||||
private readonly IWireMockMiddlewareOptions _options;
|
||||
private readonly IOwinRequestMapper _requestMapper;
|
||||
private readonly IOwinResponseMapper _responseMapper;
|
||||
private readonly IMappingMatcher _mappingMatcher;
|
||||
private readonly LogEntryMapper _logEntryMapper;
|
||||
private readonly IGuidUtils _guidUtils;
|
||||
|
||||
#if !USE_ASPNETCORE
|
||||
public WireMockMiddleware(Next next, IWireMockMiddlewareOptions options, IOwinRequestMapper requestMapper, IOwinResponseMapper responseMapper, IMappingMatcher mappingMatcher) : base(next)
|
||||
public WireMockMiddleware(
|
||||
Next next,
|
||||
IWireMockMiddlewareOptions options,
|
||||
IOwinRequestMapper requestMapper,
|
||||
IOwinResponseMapper responseMapper,
|
||||
IMappingMatcher mappingMatcher,
|
||||
IGuidUtils guidUtils
|
||||
) : base(next)
|
||||
{
|
||||
_options = Guard.NotNull(options);
|
||||
_requestMapper = Guard.NotNull(requestMapper);
|
||||
_responseMapper = Guard.NotNull(responseMapper);
|
||||
_mappingMatcher = Guard.NotNull(mappingMatcher);
|
||||
_logEntryMapper = new LogEntryMapper(options);
|
||||
_guidUtils = Guard.NotNull(guidUtils);
|
||||
}
|
||||
#else
|
||||
public WireMockMiddleware(Next next, IWireMockMiddlewareOptions options, IOwinRequestMapper requestMapper, IOwinResponseMapper responseMapper, IMappingMatcher mappingMatcher)
|
||||
public WireMockMiddleware(
|
||||
Next next,
|
||||
IWireMockMiddlewareOptions options,
|
||||
IOwinRequestMapper requestMapper,
|
||||
IOwinResponseMapper responseMapper,
|
||||
IMappingMatcher mappingMatcher,
|
||||
IGuidUtils guidUtils
|
||||
)
|
||||
{
|
||||
_options = Guard.NotNull(options);
|
||||
_requestMapper = Guard.NotNull(requestMapper);
|
||||
_responseMapper = Guard.NotNull(responseMapper);
|
||||
_mappingMatcher = Guard.NotNull(mappingMatcher);
|
||||
_logEntryMapper = new LogEntryMapper(options);
|
||||
_guidUtils = Guard.NotNull(guidUtils);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -105,7 +125,7 @@ namespace WireMock.Owin
|
||||
{
|
||||
logRequest = true;
|
||||
_options.Logger.Warn("HttpStatusCode set to 404 : No matching mapping found");
|
||||
response = ResponseMessageBuilder.Create("No matching mapping found", 404);
|
||||
response = ResponseMessageBuilder.Create(HttpStatusCode.NotFound, WireMockConstants.NoMatchingFound);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -113,11 +133,11 @@ namespace WireMock.Owin
|
||||
|
||||
if (targetMapping.IsAdminInterface && _options.AuthenticationMatcher != null && request.Headers != null)
|
||||
{
|
||||
bool present = request.Headers.TryGetValue(HttpKnownHeaderNames.Authorization, out WireMockList<string> authorization);
|
||||
if (!present || _options.AuthenticationMatcher.IsMatch(authorization!.ToString()) < MatchScores.Perfect)
|
||||
bool present = request.Headers.TryGetValue(HttpKnownHeaderNames.Authorization, out WireMockList<string>? authorization);
|
||||
if (!present || _options.AuthenticationMatcher.IsMatch(authorization!.ToString()).Score < MatchScores.Perfect)
|
||||
{
|
||||
_options.Logger.Error("HttpStatusCode set to 401");
|
||||
response = ResponseMessageBuilder.Create(null, HttpStatusCode.Unauthorized);
|
||||
response = ResponseMessageBuilder.Create(HttpStatusCode.Unauthorized, null);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -161,14 +181,14 @@ namespace WireMock.Owin
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_options.Logger.Error($"Providing a Response for Mapping '{result.Match?.Mapping?.Guid}' failed. HttpStatusCode set to 500. Exception: {ex}");
|
||||
response = ResponseMessageBuilder.Create(ex.Message, 500);
|
||||
_options.Logger.Error($"Providing a Response for Mapping '{result.Match?.Mapping.Guid}' failed. HttpStatusCode set to 500. Exception: {ex}");
|
||||
response = ResponseMessageBuilder.Create(500, ex.Message);
|
||||
}
|
||||
finally
|
||||
{
|
||||
var log = new LogEntry
|
||||
{
|
||||
Guid = Guid.NewGuid(),
|
||||
Guid = _guidUtils.NewGuid(),
|
||||
RequestMessage = request,
|
||||
ResponseMessage = response,
|
||||
|
||||
@@ -185,10 +205,10 @@ namespace WireMock.Owin
|
||||
|
||||
try
|
||||
{
|
||||
if (_options.SaveUnmatchedRequests == true && result.Match?.RequestMatchResult.IsPerfectMatch != true)
|
||||
if (_options.SaveUnmatchedRequests == true && result.Match?.RequestMatchResult is not { IsPerfectMatch: true })
|
||||
{
|
||||
var filename = $"{log.Guid}.LogEntry.json";
|
||||
_options.FileSystemHandler?.WriteUnmatchedRequest(filename, Util.JsonUtils.Serialize(log));
|
||||
_options.FileSystemHandler?.WriteUnmatchedRequest(filename, JsonUtils.Serialize(log));
|
||||
}
|
||||
}
|
||||
catch
|
||||
@@ -196,7 +216,17 @@ namespace WireMock.Owin
|
||||
// Empty catch
|
||||
}
|
||||
|
||||
await _responseMapper.MapAsync(response, ctx.Response).ConfigureAwait(false);
|
||||
try
|
||||
{
|
||||
await _responseMapper.MapAsync(response, ctx.Response).ConfigureAwait(false);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_options.Logger.Error("HttpStatusCode set to 404 : No matching mapping found", ex);
|
||||
|
||||
var notFoundResponse = ResponseMessageBuilder.Create(HttpStatusCode.NotFound, WireMockConstants.NoMatchingFound);
|
||||
await _responseMapper.MapAsync(notFoundResponse, ctx.Response).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
||||
await CompletedTask.ConfigureAwait(false);
|
||||
|
||||
@@ -4,11 +4,11 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using Newtonsoft.Json;
|
||||
#if USE_ASPNETCORE
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
#endif
|
||||
using Stef.Validation;
|
||||
using WireMock.Http;
|
||||
using WireMock.Models;
|
||||
using WireMock.Owin;
|
||||
using WireMock.Types;
|
||||
@@ -80,6 +80,7 @@ public class RequestMessage : IRequestMessage
|
||||
|
||||
#if MIMEKIT
|
||||
/// <inheritdoc />
|
||||
[JsonIgnore] // Issue 1001
|
||||
public object? BodyAsMimeMessage { get; }
|
||||
#endif
|
||||
|
||||
@@ -112,7 +113,7 @@ public class RequestMessage : IRequestMessage
|
||||
/// <summary>
|
||||
/// Used for Unit Testing
|
||||
/// </summary>
|
||||
public RequestMessage(
|
||||
internal RequestMessage(
|
||||
UrlDetails urlDetails,
|
||||
string method,
|
||||
string clientIP,
|
||||
@@ -122,19 +123,6 @@ public class RequestMessage : IRequestMessage
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RequestMessage"/> class.
|
||||
/// </summary>
|
||||
/// <param name="options">The<seealso cref="IWireMockMiddlewareOptions"/>.</param>
|
||||
/// <param name="urlDetails">The original url details.</param>
|
||||
/// <param name="method">The HTTP method.</param>
|
||||
/// <param name="clientIP">The client IP Address.</param>
|
||||
/// <param name="bodyData">The BodyData.</param>
|
||||
/// <param name="headers">The headers.</param>
|
||||
/// <param name="cookies">The cookies.</param>
|
||||
#if USE_ASPNETCORE
|
||||
/// <param name="clientCertificate">The client certificate</param>
|
||||
#endif
|
||||
internal RequestMessage(
|
||||
IWireMockMiddlewareOptions? options,
|
||||
UrlDetails urlDetails, string method,
|
||||
@@ -177,25 +165,29 @@ public class RequestMessage : IRequestMessage
|
||||
DetectedBodyTypeFromContentType = BodyData?.DetectedBodyTypeFromContentType.ToString();
|
||||
DetectedCompression = BodyData?.DetectedCompression;
|
||||
|
||||
#if MIMEKIT
|
||||
try
|
||||
{
|
||||
BodyAsMimeMessage = MimeKitUtils.GetMimeMessage(BodyData, headers![HttpKnownHeaderNames.ContentType].First());
|
||||
}
|
||||
catch
|
||||
{
|
||||
// Ignore exception from MimeMessage.Load
|
||||
}
|
||||
#endif
|
||||
|
||||
Headers = headers?.ToDictionary(header => header.Key, header => new WireMockList<string>(header.Value));
|
||||
Cookies = cookies;
|
||||
RawQuery = urlDetails.Url.Query;
|
||||
Query = QueryStringParser.Parse(RawQuery, options?.QueryParameterMultipleValueSupport);
|
||||
QueryIgnoreCase = new Dictionary<string, WireMockList<string>>(Query, StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
#if USE_ASPNETCORE
|
||||
ClientCertificate = clientCertificate;
|
||||
#endif
|
||||
|
||||
#if MIMEKIT
|
||||
try
|
||||
{
|
||||
if (MimeKitUtils.TryGetMimeMessage(this, out var mimeMessage))
|
||||
{
|
||||
BodyAsMimeMessage = mimeMessage;
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
// Ignore exception from MimeMessage.Load
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
|
||||
@@ -16,12 +16,17 @@ internal static class ResponseMessageBuilder
|
||||
{ HttpKnownHeaderNames.ContentType, new WireMockList<string> { WireMockConstants.ContentTypeJson } }
|
||||
};
|
||||
|
||||
internal static ResponseMessage Create(string? message, HttpStatusCode statusCode, Guid? guid = null)
|
||||
internal static ResponseMessage Create(HttpStatusCode statusCode, string? status, Guid? guid = null)
|
||||
{
|
||||
return Create(message, (int)statusCode, guid);
|
||||
return Create((int)statusCode, status, guid);
|
||||
}
|
||||
|
||||
internal static ResponseMessage Create(string? message, int statusCode = 200, Guid? guid = null)
|
||||
internal static ResponseMessage Create(int statusCode, string? status, Guid? guid = null)
|
||||
{
|
||||
return Create(statusCode, status, null, guid);
|
||||
}
|
||||
|
||||
internal static ResponseMessage Create(int statusCode, string? status, string? error, Guid? guid = null)
|
||||
{
|
||||
var response = new ResponseMessage
|
||||
{
|
||||
@@ -29,7 +34,7 @@ internal static class ResponseMessageBuilder
|
||||
Headers = ContentTypeJsonHeaders
|
||||
};
|
||||
|
||||
if (message != null)
|
||||
if (status != null || error != null)
|
||||
{
|
||||
response.BodyData = new BodyData
|
||||
{
|
||||
@@ -37,7 +42,8 @@ internal static class ResponseMessageBuilder
|
||||
BodyAsJson = new StatusModel
|
||||
{
|
||||
Guid = guid,
|
||||
Status = message
|
||||
Status = status,
|
||||
Error = error
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -45,7 +51,7 @@ internal static class ResponseMessageBuilder
|
||||
return response;
|
||||
}
|
||||
|
||||
internal static ResponseMessage Create(int statusCode)
|
||||
internal static ResponseMessage Create(HttpStatusCode statusCode)
|
||||
{
|
||||
return new ResponseMessage
|
||||
{
|
||||
|
||||
@@ -139,7 +139,6 @@ internal class MappingConverter
|
||||
sb.AppendLine(@$" .WithBody(new JsonPartialMatcher(
|
||||
value: {ToCSharpStringLiteral(jsonPartialMatcher.Value.ToString())},
|
||||
ignoreCase: {ToCSharpBooleanLiteral(jsonPartialMatcher.IgnoreCase)},
|
||||
throwException: {ToCSharpBooleanLiteral(jsonPartialMatcher.ThrowException)},
|
||||
regex: {ToCSharpBooleanLiteral(jsonPartialMatcher.Regex)}
|
||||
))");
|
||||
}
|
||||
@@ -148,7 +147,6 @@ internal class MappingConverter
|
||||
sb.AppendLine(@$" .WithBody(new JsonPartialWildcardMatcher(
|
||||
value: {ToCSharpStringLiteral(jsonPartialWildcardMatcher.Value.ToString())},
|
||||
ignoreCase: {ToCSharpBooleanLiteral(jsonPartialWildcardMatcher.IgnoreCase)},
|
||||
throwException: {ToCSharpBooleanLiteral(jsonPartialWildcardMatcher.ThrowException)},
|
||||
regex: {ToCSharpBooleanLiteral(jsonPartialWildcardMatcher.Regex)}
|
||||
))");
|
||||
}
|
||||
@@ -261,19 +259,24 @@ internal class MappingConverter
|
||||
Headers = headerMatchers.Any() ? headerMatchers.Select(hm => new HeaderModel
|
||||
{
|
||||
Name = hm.Name,
|
||||
Matchers = _mapper.Map(hm.Matchers)
|
||||
IgnoreCase = hm.IgnoreCase ? true : null,
|
||||
RejectOnMatch = hm.MatchBehaviour == MatchBehaviour.RejectOnMatch ? true : null,
|
||||
Matchers = _mapper.Map(hm.Matchers),
|
||||
}).ToList() : null,
|
||||
|
||||
Cookies = cookieMatchers.Any() ? cookieMatchers.Select(cm => new CookieModel
|
||||
{
|
||||
Name = cm.Name,
|
||||
IgnoreCase = cm.IgnoreCase ? true : null,
|
||||
RejectOnMatch = cm.MatchBehaviour == MatchBehaviour.RejectOnMatch ? true : null,
|
||||
Matchers = _mapper.Map(cm.Matchers)
|
||||
}).ToList() : null,
|
||||
|
||||
Params = paramsMatchers.Any() ? paramsMatchers.Select(pm => new ParamModel
|
||||
{
|
||||
Name = pm.Key,
|
||||
IgnoreCase = pm.IgnoreCase == true ? true : null,
|
||||
IgnoreCase = pm.IgnoreCase ? true : null,
|
||||
RejectOnMatch = pm.MatchBehaviour == MatchBehaviour.RejectOnMatch ? true : null,
|
||||
Matchers = _mapper.Map(pm.Matchers)
|
||||
}).ToList() : null
|
||||
},
|
||||
|
||||
@@ -46,7 +46,6 @@ internal class MatcherMapper
|
||||
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;
|
||||
|
||||
@@ -64,51 +63,51 @@ internal class MatcherMapper
|
||||
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, matchOperator, stringPatterns);
|
||||
return new LinqMatcher(matchBehaviour, matchOperator, stringPatterns);
|
||||
|
||||
case nameof(ExactMatcher):
|
||||
return new ExactMatcher(matchBehaviour, ignoreCase, throwExceptionWhenMatcherFails, matchOperator, stringPatterns);
|
||||
return new ExactMatcher(matchBehaviour, ignoreCase, matchOperator, stringPatterns);
|
||||
|
||||
case nameof(ExactObjectMatcher):
|
||||
return CreateExactObjectMatcher(matchBehaviour, stringPatterns[0], throwExceptionWhenMatcherFails);
|
||||
return CreateExactObjectMatcher(matchBehaviour, stringPatterns[0]);
|
||||
#if GRAPHQL
|
||||
case nameof(GraphQLMatcher):
|
||||
return new GraphQLMatcher(stringPatterns[0].GetPattern(), matchBehaviour, throwExceptionWhenMatcherFails, matchOperator);
|
||||
return new GraphQLMatcher(stringPatterns[0].GetPattern(), matchBehaviour, matchOperator);
|
||||
#endif
|
||||
|
||||
#if MIMEKIT
|
||||
case nameof(MimePartMatcher):
|
||||
return CreateMimePartMatcher(matchBehaviour, matcher, throwExceptionWhenMatcherFails);
|
||||
return CreateMimePartMatcher(matchBehaviour, matcher);
|
||||
#endif
|
||||
case nameof(RegexMatcher):
|
||||
return new RegexMatcher(matchBehaviour, stringPatterns, ignoreCase, throwExceptionWhenMatcherFails, useRegexExtended, matchOperator);
|
||||
return new RegexMatcher(matchBehaviour, stringPatterns, ignoreCase, useRegexExtended, matchOperator);
|
||||
|
||||
case nameof(JsonMatcher):
|
||||
var valueForJsonMatcher = matcher.Pattern ?? matcher.Patterns;
|
||||
return new JsonMatcher(matchBehaviour, valueForJsonMatcher!, ignoreCase, throwExceptionWhenMatcherFails);
|
||||
return new JsonMatcher(matchBehaviour, valueForJsonMatcher!, ignoreCase);
|
||||
|
||||
case nameof(JsonPartialMatcher):
|
||||
var valueForJsonPartialMatcher = matcher.Pattern ?? matcher.Patterns;
|
||||
return new JsonPartialMatcher(matchBehaviour, valueForJsonPartialMatcher!, ignoreCase, throwExceptionWhenMatcherFails, useRegex);
|
||||
return new JsonPartialMatcher(matchBehaviour, valueForJsonPartialMatcher!, ignoreCase, useRegex);
|
||||
|
||||
case nameof(JsonPartialWildcardMatcher):
|
||||
var valueForJsonPartialWildcardMatcher = matcher.Pattern ?? matcher.Patterns;
|
||||
return new JsonPartialWildcardMatcher(matchBehaviour, valueForJsonPartialWildcardMatcher!, ignoreCase, throwExceptionWhenMatcherFails, useRegex);
|
||||
return new JsonPartialWildcardMatcher(matchBehaviour, valueForJsonPartialWildcardMatcher!, ignoreCase, useRegex);
|
||||
|
||||
case nameof(JsonPathMatcher):
|
||||
return new JsonPathMatcher(matchBehaviour, throwExceptionWhenMatcherFails, matchOperator, stringPatterns);
|
||||
return new JsonPathMatcher(matchBehaviour, matchOperator, stringPatterns);
|
||||
|
||||
case nameof(JmesPathMatcher):
|
||||
return new JmesPathMatcher(matchBehaviour, throwExceptionWhenMatcherFails, matchOperator, stringPatterns);
|
||||
return new JmesPathMatcher(matchBehaviour, matchOperator, stringPatterns);
|
||||
|
||||
case nameof(XPathMatcher):
|
||||
return new XPathMatcher(matchBehaviour, throwExceptionWhenMatcherFails, matchOperator, stringPatterns);
|
||||
return new XPathMatcher(matchBehaviour, matchOperator, stringPatterns);
|
||||
|
||||
case nameof(WildcardMatcher):
|
||||
return new WildcardMatcher(matchBehaviour, stringPatterns, ignoreCase, throwExceptionWhenMatcherFails, matchOperator);
|
||||
return new WildcardMatcher(matchBehaviour, stringPatterns, ignoreCase, matchOperator);
|
||||
|
||||
case nameof(ContentTypeMatcher):
|
||||
return new ContentTypeMatcher(matchBehaviour, stringPatterns, ignoreCase, throwExceptionWhenMatcherFails);
|
||||
return new ContentTypeMatcher(matchBehaviour, stringPatterns, ignoreCase);
|
||||
|
||||
case nameof(SimMetricsMatcher):
|
||||
SimMetricType type = SimMetricType.Levenstein;
|
||||
@@ -117,7 +116,7 @@ internal class MatcherMapper
|
||||
throw new NotSupportedException($"Matcher '{matcherName}' with Type '{matcherType}' is not supported.");
|
||||
}
|
||||
|
||||
return new SimMetricsMatcher(matchBehaviour, stringPatterns, type, throwExceptionWhenMatcherFails);
|
||||
return new SimMetricsMatcher(matchBehaviour, stringPatterns, type);
|
||||
|
||||
default:
|
||||
if (_settings.CustomMatcherMappings != null && _settings.CustomMatcherMappings.ContainsKey(matcherName))
|
||||
@@ -236,7 +235,7 @@ internal class MatcherMapper
|
||||
return EmptyArray<AnyOf<string, StringPattern>>.Value;
|
||||
}
|
||||
|
||||
private static ExactObjectMatcher CreateExactObjectMatcher(MatchBehaviour matchBehaviour, AnyOf<string, StringPattern> stringPattern, bool throwException)
|
||||
private static ExactObjectMatcher CreateExactObjectMatcher(MatchBehaviour matchBehaviour, AnyOf<string, StringPattern> stringPattern)
|
||||
{
|
||||
byte[] bytePattern;
|
||||
try
|
||||
@@ -248,18 +247,18 @@ internal class MatcherMapper
|
||||
throw new ArgumentException($"Matcher 'ExactObjectMatcher' has invalid pattern. The pattern value '{stringPattern}' is not a Base64String.", nameof(stringPattern));
|
||||
}
|
||||
|
||||
return new ExactObjectMatcher(matchBehaviour, bytePattern, throwException);
|
||||
return new ExactObjectMatcher(matchBehaviour, bytePattern);
|
||||
}
|
||||
|
||||
#if MIMEKIT
|
||||
private MimePartMatcher CreateMimePartMatcher(MatchBehaviour matchBehaviour, MatcherModel? matcher, bool throwExceptionWhenMatcherFails)
|
||||
private MimePartMatcher CreateMimePartMatcher(MatchBehaviour matchBehaviour, MatcherModel? matcher)
|
||||
{
|
||||
var contentTypeMatcher = Map(matcher?.ContentTypeMatcher) as IStringMatcher;
|
||||
var contentDispositionMatcher = Map(matcher?.ContentDispositionMatcher) as IStringMatcher;
|
||||
var contentTransferEncodingMatcher = Map(matcher?.ContentTransferEncodingMatcher) as IStringMatcher;
|
||||
var contentMatcher = Map(matcher?.ContentMatcher);
|
||||
|
||||
return new MimePartMatcher(matchBehaviour, contentTypeMatcher, contentDispositionMatcher, contentTransferEncodingMatcher, contentMatcher, throwExceptionWhenMatcherFails);
|
||||
return new MimePartMatcher(matchBehaviour, contentTypeMatcher, contentDispositionMatcher, contentTransferEncodingMatcher, contentMatcher);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -30,8 +30,8 @@ internal class ProxyMappingConverter
|
||||
{
|
||||
var useDefinedRequestMatchers = proxyAndRecordSettings.UseDefinedRequestMatchers;
|
||||
var excludedHeaders = new List<string>(proxyAndRecordSettings.ExcludedHeaders ?? new string[] { }) { "Cookie" };
|
||||
var excludedCookies = proxyAndRecordSettings.ExcludedCookies ?? new string[0];
|
||||
var excludedParams = proxyAndRecordSettings.ExcludedParams ?? new string[0];
|
||||
var excludedCookies = proxyAndRecordSettings.ExcludedCookies ?? EmptyArray<string>.Value;
|
||||
var excludedParams = proxyAndRecordSettings.ExcludedParams ?? EmptyArray<string>.Value;
|
||||
|
||||
var request = (Request?)mapping?.RequestMatcher;
|
||||
var clientIPMatcher = request?.GetRequestMessageMatcher<RequestMessageClientIPMatcher>();
|
||||
@@ -137,7 +137,6 @@ internal class ProxyMappingConverter
|
||||
}
|
||||
|
||||
// Body
|
||||
bool throwExceptionWhenMatcherFails = _settings.ThrowExceptionWhenMatcherFails == true;
|
||||
if (useDefinedRequestMatchers && bodyMatcher?.Matchers is not null)
|
||||
{
|
||||
newRequest.WithBody(bodyMatcher.Matchers);
|
||||
@@ -147,16 +146,16 @@ internal class ProxyMappingConverter
|
||||
switch (requestMessage.BodyData?.DetectedBodyType)
|
||||
{
|
||||
case BodyType.Json:
|
||||
newRequest.WithBody(new JsonMatcher(MatchBehaviour.AcceptOnMatch, requestMessage.BodyData.BodyAsJson!, true, throwExceptionWhenMatcherFails));
|
||||
newRequest.WithBody(new JsonMatcher(MatchBehaviour.AcceptOnMatch, requestMessage.BodyData.BodyAsJson!, true));
|
||||
break;
|
||||
|
||||
case BodyType.String:
|
||||
case BodyType.FormUrlEncoded:
|
||||
newRequest.WithBody(new ExactMatcher(MatchBehaviour.AcceptOnMatch, true, throwExceptionWhenMatcherFails, MatchOperator.Or, requestMessage.BodyData.BodyAsString!));
|
||||
newRequest.WithBody(new ExactMatcher(MatchBehaviour.AcceptOnMatch, true, MatchOperator.Or, requestMessage.BodyData.BodyAsString!));
|
||||
break;
|
||||
|
||||
case BodyType.Bytes:
|
||||
newRequest.WithBody(new ExactObjectMatcher(MatchBehaviour.AcceptOnMatch, requestMessage.BodyData.BodyAsBytes!, throwExceptionWhenMatcherFails));
|
||||
newRequest.WithBody(new ExactObjectMatcher(MatchBehaviour.AcceptOnMatch, requestMessage.BodyData.BodyAsBytes!));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -237,7 +237,6 @@ public partial class WireMockServer
|
||||
ReadStaticMappings = _settings.ReadStaticMappings,
|
||||
RequestLogExpirationDuration = _settings.RequestLogExpirationDuration,
|
||||
SaveUnmatchedRequests = _settings.SaveUnmatchedRequests,
|
||||
ThrowExceptionWhenMatcherFails = _settings.ThrowExceptionWhenMatcherFails,
|
||||
UseRegexExtended = _settings.UseRegexExtended,
|
||||
WatchStaticMappings = _settings.WatchStaticMappings,
|
||||
WatchStaticMappingsInSubdirectories = _settings.WatchStaticMappingsInSubdirectories,
|
||||
@@ -273,7 +272,6 @@ public partial class WireMockServer
|
||||
_settings.ReadStaticMappings = settings.ReadStaticMappings;
|
||||
_settings.RequestLogExpirationDuration = settings.RequestLogExpirationDuration;
|
||||
_settings.SaveUnmatchedRequests = settings.SaveUnmatchedRequests;
|
||||
_settings.ThrowExceptionWhenMatcherFails = settings.ThrowExceptionWhenMatcherFails;
|
||||
_settings.UseRegexExtended = settings.UseRegexExtended;
|
||||
_settings.WatchStaticMappings = settings.WatchStaticMappings;
|
||||
_settings.WatchStaticMappingsInSubdirectories = settings.WatchStaticMappingsInSubdirectories;
|
||||
@@ -303,7 +301,7 @@ public partial class WireMockServer
|
||||
_options.AcceptAnyClientCertificate = _settings.AcceptAnyClientCertificate;
|
||||
#endif
|
||||
|
||||
return ResponseMessageBuilder.Create("Settings updated");
|
||||
return ResponseMessageBuilder.Create(200, "Settings updated");
|
||||
}
|
||||
#endregion Settings
|
||||
|
||||
@@ -314,7 +312,7 @@ public partial class WireMockServer
|
||||
if (mapping == null)
|
||||
{
|
||||
_settings.Logger.Warn("HttpStatusCode set to 404 : Mapping not found");
|
||||
return ResponseMessageBuilder.Create("Mapping not found", HttpStatusCode.NotFound);
|
||||
return ResponseMessageBuilder.Create(HttpStatusCode.NotFound, "Mapping not found");
|
||||
}
|
||||
|
||||
var model = _mappingConverter.ToMappingModel(mapping);
|
||||
@@ -330,14 +328,14 @@ public partial class WireMockServer
|
||||
if (code is null)
|
||||
{
|
||||
_settings.Logger.Warn("HttpStatusCode set to 404 : Mapping not found");
|
||||
return ResponseMessageBuilder.Create("Mapping not found", HttpStatusCode.NotFound);
|
||||
return ResponseMessageBuilder.Create(HttpStatusCode.NotFound, "Mapping not found");
|
||||
}
|
||||
|
||||
return ToResponseMessage(code);
|
||||
}
|
||||
|
||||
_settings.Logger.Warn("HttpStatusCode set to 400");
|
||||
return ResponseMessageBuilder.Create("GUID is missing", HttpStatusCode.BadRequest);
|
||||
return ResponseMessageBuilder.Create(HttpStatusCode.BadRequest, "GUID is missing");
|
||||
}
|
||||
|
||||
private static MappingConverterType GetMappingConverterType(IRequestMessage requestMessage)
|
||||
@@ -365,22 +363,22 @@ public partial class WireMockServer
|
||||
var mappingModel = DeserializeObject<MappingModel>(requestMessage);
|
||||
var guidFromPut = ConvertMappingAndRegisterAsRespondProvider(mappingModel, guid);
|
||||
|
||||
return ResponseMessageBuilder.Create("Mapping added or updated", HttpStatusCode.OK, guidFromPut);
|
||||
return ResponseMessageBuilder.Create(HttpStatusCode.OK, "Mapping added or updated", guidFromPut);
|
||||
}
|
||||
|
||||
_settings.Logger.Warn("HttpStatusCode set to 404 : Mapping not found");
|
||||
return ResponseMessageBuilder.Create("Mapping not found", HttpStatusCode.NotFound);
|
||||
return ResponseMessageBuilder.Create(HttpStatusCode.NotFound, "Mapping not found");
|
||||
}
|
||||
|
||||
private IResponseMessage MappingDelete(IRequestMessage requestMessage)
|
||||
{
|
||||
if (TryParseGuidFromRequestMessage(requestMessage, out var guid) && DeleteMapping(guid))
|
||||
{
|
||||
return ResponseMessageBuilder.Create("Mapping removed", HttpStatusCode.OK, guid);
|
||||
return ResponseMessageBuilder.Create(HttpStatusCode.OK, "Mapping removed", guid);
|
||||
}
|
||||
|
||||
_settings.Logger.Warn("HttpStatusCode set to 404 : Mapping not found");
|
||||
return ResponseMessageBuilder.Create("Mapping not found", HttpStatusCode.NotFound);
|
||||
return ResponseMessageBuilder.Create(HttpStatusCode.NotFound, "Mapping not found");
|
||||
}
|
||||
|
||||
private static bool TryParseGuidFromRequestMessage(IRequestMessage requestMessage, out Guid guid)
|
||||
@@ -409,7 +407,7 @@ public partial class WireMockServer
|
||||
{
|
||||
SaveStaticMappings();
|
||||
|
||||
return ResponseMessageBuilder.Create("Mappings saved to disk");
|
||||
return ResponseMessageBuilder.Create(200, "Mappings saved to disk");
|
||||
}
|
||||
|
||||
private MappingModel[] ToMappingModels()
|
||||
@@ -439,22 +437,22 @@ public partial class WireMockServer
|
||||
if (mappingModels.Length == 1)
|
||||
{
|
||||
Guid? guid = ConvertMappingAndRegisterAsRespondProvider(mappingModels[0]);
|
||||
return ResponseMessageBuilder.Create("Mapping added", 201, guid);
|
||||
return ResponseMessageBuilder.Create(201, "Mapping added", guid);
|
||||
}
|
||||
|
||||
ConvertMappingsAndRegisterAsRespondProvider(mappingModels);
|
||||
|
||||
return ResponseMessageBuilder.Create("Mappings added", 201);
|
||||
return ResponseMessageBuilder.Create(201, "Mappings added");
|
||||
}
|
||||
catch (ArgumentException a)
|
||||
{
|
||||
_settings.Logger.Error("HttpStatusCode set to 400 {0}", a);
|
||||
return ResponseMessageBuilder.Create(a.Message, 400);
|
||||
return ResponseMessageBuilder.Create(400, a.Message);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_settings.Logger.Error("HttpStatusCode set to 500 {0}", e);
|
||||
return ResponseMessageBuilder.Create(e.ToString(), 500);
|
||||
return ResponseMessageBuilder.Create(500, e.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -465,18 +463,18 @@ public partial class WireMockServer
|
||||
var deletedGuids = MappingsDeleteMappingFromBody(requestMessage);
|
||||
if (deletedGuids != null)
|
||||
{
|
||||
return ResponseMessageBuilder.Create($"Mappings deleted. Affected GUIDs: [{string.Join(", ", deletedGuids.ToArray())}]");
|
||||
return ResponseMessageBuilder.Create(200, $"Mappings deleted. Affected GUIDs: [{string.Join(", ", deletedGuids.ToArray())}]");
|
||||
}
|
||||
|
||||
// return bad request
|
||||
return ResponseMessageBuilder.Create("Poorly formed mapping JSON.", 400);
|
||||
return ResponseMessageBuilder.Create(400, "Poorly formed mapping JSON.");
|
||||
}
|
||||
|
||||
ResetMappings();
|
||||
|
||||
ResetScenarios();
|
||||
|
||||
return ResponseMessageBuilder.Create("Mappings deleted");
|
||||
return ResponseMessageBuilder.Create(200, "Mappings deleted");
|
||||
}
|
||||
|
||||
private IEnumerable<Guid>? MappingsDeleteMappingFromBody(IRequestMessage requestMessage)
|
||||
@@ -528,7 +526,7 @@ public partial class WireMockServer
|
||||
message = $"{message} and static mappings reloaded";
|
||||
}
|
||||
|
||||
return ResponseMessageBuilder.Create(message);
|
||||
return ResponseMessageBuilder.Create(200, message);
|
||||
}
|
||||
#endregion Mappings
|
||||
|
||||
@@ -546,18 +544,18 @@ public partial class WireMockServer
|
||||
}
|
||||
|
||||
_settings.Logger.Warn("HttpStatusCode set to 404 : Request not found");
|
||||
return ResponseMessageBuilder.Create("Request not found", HttpStatusCode.NotFound);
|
||||
return ResponseMessageBuilder.Create(HttpStatusCode.NotFound, "Request not found");
|
||||
}
|
||||
|
||||
private IResponseMessage RequestDelete(IRequestMessage requestMessage)
|
||||
{
|
||||
if (TryParseGuidFromRequestMessage(requestMessage, out var guid) && DeleteLogEntry(guid))
|
||||
{
|
||||
return ResponseMessageBuilder.Create("Request removed");
|
||||
return ResponseMessageBuilder.Create(200, "Request removed");
|
||||
}
|
||||
|
||||
_settings.Logger.Warn("HttpStatusCode set to 404 : Request not found");
|
||||
return ResponseMessageBuilder.Create("Request not found", HttpStatusCode.NotFound);
|
||||
return ResponseMessageBuilder.Create(HttpStatusCode.NotFound, "Request not found");
|
||||
}
|
||||
#endregion Request/{guid}
|
||||
|
||||
@@ -576,7 +574,7 @@ public partial class WireMockServer
|
||||
{
|
||||
ResetLogEntries();
|
||||
|
||||
return ResponseMessageBuilder.Create("Requests deleted");
|
||||
return ResponseMessageBuilder.Create(200, "Requests deleted");
|
||||
}
|
||||
#endregion Requests
|
||||
|
||||
@@ -623,7 +621,7 @@ public partial class WireMockServer
|
||||
{
|
||||
ResetScenarios();
|
||||
|
||||
return ResponseMessageBuilder.Create("Scenarios reset");
|
||||
return ResponseMessageBuilder.Create(200, "Scenarios reset");
|
||||
}
|
||||
|
||||
private IResponseMessage ScenarioReset(IRequestMessage requestMessage)
|
||||
@@ -633,8 +631,8 @@ public partial class WireMockServer
|
||||
requestMessage.Path.Split('/').Reverse().Skip(1).First();
|
||||
|
||||
return ResetScenario(name) ?
|
||||
ResponseMessageBuilder.Create("Scenario reset") :
|
||||
ResponseMessageBuilder.Create($"No scenario found by name '{name}'.", HttpStatusCode.NotFound);
|
||||
ResponseMessageBuilder.Create(200, "Scenario reset") :
|
||||
ResponseMessageBuilder.Create(HttpStatusCode.NotFound, $"No scenario found by name '{name}'.");
|
||||
}
|
||||
#endregion
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Text;
|
||||
using WireMock.Matchers;
|
||||
using WireMock.Types;
|
||||
@@ -25,7 +26,7 @@ namespace WireMock.Server
|
||||
|
||||
_settings.FileSystemHandler.WriteFile(filename, requestMessage.BodyAsBytes);
|
||||
|
||||
return ResponseMessageBuilder.Create("File created");
|
||||
return ResponseMessageBuilder.Create(200, "File created");
|
||||
}
|
||||
|
||||
private IResponseMessage FilePut(IRequestMessage requestMessage)
|
||||
@@ -35,12 +36,12 @@ namespace WireMock.Server
|
||||
if (!_settings.FileSystemHandler.FileExists(filename))
|
||||
{
|
||||
_settings.Logger.Info("The file '{0}' does not exist, updating file will be skipped.", filename);
|
||||
return ResponseMessageBuilder.Create("File is not found", 404);
|
||||
return ResponseMessageBuilder.Create(404, "File is not found");
|
||||
}
|
||||
|
||||
_settings.FileSystemHandler.WriteFile(filename, requestMessage.BodyAsBytes);
|
||||
|
||||
return ResponseMessageBuilder.Create("File updated");
|
||||
return ResponseMessageBuilder.Create(200, "File updated");
|
||||
}
|
||||
|
||||
private IResponseMessage FileGet(IRequestMessage requestMessage)
|
||||
@@ -50,7 +51,7 @@ namespace WireMock.Server
|
||||
if (!_settings.FileSystemHandler.FileExists(filename))
|
||||
{
|
||||
_settings.Logger.Info("The file '{0}' does not exist.", filename);
|
||||
return ResponseMessageBuilder.Create("File is not found", 404);
|
||||
return ResponseMessageBuilder.Create(404, "File is not found");
|
||||
}
|
||||
|
||||
byte[] bytes = _settings.FileSystemHandler.ReadFile(filename);
|
||||
@@ -86,10 +87,10 @@ namespace WireMock.Server
|
||||
if (!_settings.FileSystemHandler.FileExists(filename))
|
||||
{
|
||||
_settings.Logger.Info("The file '{0}' does not exist.", filename);
|
||||
return ResponseMessageBuilder.Create(404);
|
||||
return ResponseMessageBuilder.Create(HttpStatusCode.NotFound);
|
||||
}
|
||||
|
||||
return ResponseMessageBuilder.Create(204);
|
||||
return ResponseMessageBuilder.Create(HttpStatusCode.NoContent);
|
||||
}
|
||||
|
||||
private IResponseMessage FileDelete(IRequestMessage requestMessage)
|
||||
@@ -99,11 +100,11 @@ namespace WireMock.Server
|
||||
if (!_settings.FileSystemHandler.FileExists(filename))
|
||||
{
|
||||
_settings.Logger.Info("The file '{0}' does not exist.", filename);
|
||||
return ResponseMessageBuilder.Create("File is not deleted", 404);
|
||||
return ResponseMessageBuilder.Create(404, "File is not deleted");
|
||||
}
|
||||
|
||||
_settings.FileSystemHandler.DeleteFile(filename);
|
||||
return ResponseMessageBuilder.Create("File deleted.");
|
||||
return ResponseMessageBuilder.Create(200, "File deleted.");
|
||||
}
|
||||
|
||||
private string GetFileNameFromRequestMessage(IRequestMessage requestMessage)
|
||||
|
||||
@@ -52,7 +52,7 @@ public partial class WireMockServer
|
||||
if (mappingModels.Length == 1)
|
||||
{
|
||||
Guid? guid = ConvertWireMockOrgMappingAndRegisterAsRespondProvider(mappingModels[0]);
|
||||
return ResponseMessageBuilder.Create("Mapping added", 201, guid);
|
||||
return ResponseMessageBuilder.Create(201, "Mapping added", guid);
|
||||
}
|
||||
|
||||
foreach (var mappingModel in mappingModels)
|
||||
@@ -60,17 +60,17 @@ public partial class WireMockServer
|
||||
ConvertWireMockOrgMappingAndRegisterAsRespondProvider(mappingModel);
|
||||
}
|
||||
|
||||
return ResponseMessageBuilder.Create("Mappings added", 201);
|
||||
return ResponseMessageBuilder.Create(201, "Mappings added");
|
||||
}
|
||||
catch (ArgumentException a)
|
||||
{
|
||||
_settings.Logger.Error("HttpStatusCode set to 400 {0}", a);
|
||||
return ResponseMessageBuilder.Create(a.Message, 400);
|
||||
return ResponseMessageBuilder.Create(400, a.Message);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_settings.Logger.Error("HttpStatusCode set to 500 {0}", e);
|
||||
return ResponseMessageBuilder.Create(e.ToString(), 500);
|
||||
return ResponseMessageBuilder.Create(500, e.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
using System.Net;
|
||||
#if OPENAPIPARSER
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using WireMock.Net.OpenApiParser;
|
||||
#endif
|
||||
|
||||
@@ -14,16 +14,16 @@ public partial class WireMockServer
|
||||
#if OPENAPIPARSER
|
||||
try
|
||||
{
|
||||
var mappingModels = new WireMockOpenApiParser().FromText(requestMessage.Body, out var diagnostic);
|
||||
var mappingModels = new WireMockOpenApiParser().FromText(requestMessage.Body!, out var diagnostic);
|
||||
return diagnostic.Errors.Any() ? ToJson(diagnostic, false, HttpStatusCode.BadRequest) : ToJson(mappingModels);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_settings.Logger.Error("HttpStatusCode set to {0} {1}", HttpStatusCode.BadRequest, e);
|
||||
return ResponseMessageBuilder.Create(e.Message, HttpStatusCode.BadRequest);
|
||||
return ResponseMessageBuilder.Create(HttpStatusCode.BadRequest, e.Message);
|
||||
}
|
||||
#else
|
||||
return ResponseMessageBuilder.Create("Not supported for .NETStandard 1.3 and .NET 4.5.2 or lower.", 400);
|
||||
return ResponseMessageBuilder.Create(HttpStatusCode.BadRequest, "Not supported for .NETStandard 1.3 and .NET 4.5.2 or lower.");
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@ public partial class WireMockServer
|
||||
#if OPENAPIPARSER
|
||||
try
|
||||
{
|
||||
var mappingModels = new WireMockOpenApiParser().FromText(requestMessage.Body, out var diagnostic);
|
||||
var mappingModels = new WireMockOpenApiParser().FromText(requestMessage.Body!, out var diagnostic);
|
||||
if (diagnostic.Errors.Any())
|
||||
{
|
||||
return ToJson(diagnostic, false, HttpStatusCode.BadRequest);
|
||||
@@ -40,15 +40,15 @@ public partial class WireMockServer
|
||||
|
||||
ConvertMappingsAndRegisterAsRespondProvider(mappingModels);
|
||||
|
||||
return ResponseMessageBuilder.Create("OpenApi document converted to Mappings", HttpStatusCode.Created);
|
||||
return ResponseMessageBuilder.Create(HttpStatusCode.Created, "OpenApi document converted to Mappings");
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_settings.Logger.Error("HttpStatusCode set to {0} {1}", HttpStatusCode.BadRequest, e);
|
||||
return ResponseMessageBuilder.Create(e.Message, HttpStatusCode.BadRequest);
|
||||
return ResponseMessageBuilder.Create(HttpStatusCode.BadRequest, e.Message);
|
||||
}
|
||||
#else
|
||||
return ResponseMessageBuilder.Create("Not supported for .NETStandard 1.3 and .NET 4.5.2 or lower.", 400);
|
||||
return ResponseMessageBuilder.Create(HttpStatusCode.BadRequest, "Not supported for .NETStandard 1.3 and .NET 4.5.2 or lower.");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -4,6 +4,7 @@ using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Threading;
|
||||
using JetBrains.Annotations;
|
||||
@@ -11,6 +12,7 @@ using Newtonsoft.Json;
|
||||
using Stef.Validation;
|
||||
using WireMock.Admin.Mappings;
|
||||
using WireMock.Authentication;
|
||||
using WireMock.Constants;
|
||||
using WireMock.Exceptions;
|
||||
using WireMock.Handlers;
|
||||
using WireMock.Http;
|
||||
@@ -391,7 +393,7 @@ public partial class WireMockServer : IWireMockServer
|
||||
Given(Request.Create().WithPath("/*").UsingAnyMethod())
|
||||
.WithGuid(Guid.Parse("90008000-0000-4444-a17e-669cd84f1f05"))
|
||||
.AtPriority(1000)
|
||||
.RespondWith(new DynamicResponseProvider(_ => ResponseMessageBuilder.Create("No matching mapping found", 404)));
|
||||
.RespondWith(new DynamicResponseProvider(_ => ResponseMessageBuilder.Create(HttpStatusCode.NotFound, WireMockConstants.NoMatchingFound)));
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IWireMockServer.Reset" />
|
||||
|
||||
@@ -221,12 +221,6 @@ public class WireMockServerSettings
|
||||
[PublicAPI]
|
||||
public bool? HandleRequestsSynchronously { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Throw an exception when the <see cref="IMatcher"/> fails because of invalid input. (default set to <c>false</c>).
|
||||
/// </summary>
|
||||
[PublicAPI]
|
||||
public bool? ThrowExceptionWhenMatcherFails { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// If https is used, these settings can be used to configure the CertificateSettings in case a custom certificate instead the default .NET certificate should be used.
|
||||
///
|
||||
|
||||
@@ -57,7 +57,6 @@ public static class WireMockServerSettingsParser
|
||||
SaveUnmatchedRequests = parser.GetBoolValue(nameof(WireMockServerSettings.SaveUnmatchedRequests)),
|
||||
StartAdminInterface = parser.GetBoolValue("StartAdminInterface", true),
|
||||
StartTimeout = parser.GetIntValue(nameof(WireMockServerSettings.StartTimeout), WireMockServerSettings.DefaultStartTimeout),
|
||||
ThrowExceptionWhenMatcherFails = parser.GetBoolValue("ThrowExceptionWhenMatcherFails"),
|
||||
UseRegexExtended = parser.GetBoolValue(nameof(WireMockServerSettings.UseRegexExtended), true),
|
||||
WatchStaticMappings = parser.GetBoolValue("WatchStaticMappings"),
|
||||
WatchStaticMappingsInSubdirectories = parser.GetBoolValue("WatchStaticMappingsInSubdirectories"),
|
||||
|
||||
@@ -85,27 +85,27 @@ internal static class BodyParser
|
||||
|
||||
public static BodyType DetectBodyTypeFromContentType(string? contentTypeValue)
|
||||
{
|
||||
if (string.IsNullOrEmpty(contentTypeValue) || !MediaTypeHeaderValue.TryParse(contentTypeValue, out MediaTypeHeaderValue contentType))
|
||||
if (string.IsNullOrEmpty(contentTypeValue) || !MediaTypeHeaderValue.TryParse(contentTypeValue, out MediaTypeHeaderValue? contentType))
|
||||
{
|
||||
return BodyType.Bytes;
|
||||
}
|
||||
|
||||
if (MatchScores.IsPerfect(FormUrlEncodedMatcher.IsMatch(contentType.MediaType)))
|
||||
if (FormUrlEncodedMatcher.IsMatch(contentType.MediaType).IsPerfect())
|
||||
{
|
||||
return BodyType.FormUrlEncoded;
|
||||
}
|
||||
|
||||
if (TextContentTypeMatchers.Any(matcher => MatchScores.IsPerfect(matcher.IsMatch(contentType.MediaType))))
|
||||
if (TextContentTypeMatchers.Any(matcher => matcher.IsMatch(contentType.MediaType).IsPerfect()))
|
||||
{
|
||||
return BodyType.String;
|
||||
}
|
||||
|
||||
if (JsonContentTypesMatchers.Any(matcher => MatchScores.IsPerfect(matcher.IsMatch(contentType.MediaType))))
|
||||
if (JsonContentTypesMatchers.Any(matcher => matcher.IsMatch(contentType.MediaType).IsPerfect()))
|
||||
{
|
||||
return BodyType.Json;
|
||||
}
|
||||
|
||||
if (MultipartContentTypesMatchers.Any(matcher => MatchScores.IsPerfect(matcher.IsMatch(contentType.MediaType))))
|
||||
if (MultipartContentTypesMatchers.Any(matcher => matcher.IsMatch(contentType.MediaType).IsPerfect()))
|
||||
{
|
||||
return BodyType.MultiPart;
|
||||
}
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
#if MIMEKIT
|
||||
using System;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using MimeKit;
|
||||
using Stef.Validation;
|
||||
using WireMock.Http;
|
||||
using WireMock.Types;
|
||||
|
||||
@@ -10,21 +13,39 @@ namespace WireMock.Util;
|
||||
|
||||
internal static class MimeKitUtils
|
||||
{
|
||||
public static MimeMessage GetMimeMessage(IBodyData? bodyData, string contentTypeHeaderValue)
|
||||
public static bool TryGetMimeMessage(IRequestMessage requestMessage, [NotNullWhen(true)] out MimeMessage? mimeMessage)
|
||||
{
|
||||
var bytes = bodyData?.DetectedBodyType switch
|
||||
Guard.NotNull(requestMessage);
|
||||
|
||||
if (requestMessage.BodyData != null &&
|
||||
requestMessage.Headers?.TryGetValue(HttpKnownHeaderNames.ContentType, out var contentTypeHeader) == true &&
|
||||
StartsWithMultiPart(contentTypeHeader) // Only parse when "multipart/mixed"
|
||||
)
|
||||
{
|
||||
// If the body is bytes, use the BodyAsBytes to match on.
|
||||
BodyType.Bytes => bodyData.BodyAsBytes!,
|
||||
var bytes = requestMessage.BodyData?.DetectedBodyType switch
|
||||
{
|
||||
// If the body is bytes, use the BodyAsBytes to match on.
|
||||
BodyType.Bytes => requestMessage.BodyData.BodyAsBytes!,
|
||||
|
||||
// If the body is a String or MultiPart, use the BodyAsString to match on.
|
||||
BodyType.String or BodyType.MultiPart => Encoding.UTF8.GetBytes(bodyData.BodyAsString!),
|
||||
// If the body is a String or MultiPart, use the BodyAsString to match on.
|
||||
BodyType.String or BodyType.MultiPart => Encoding.UTF8.GetBytes(requestMessage.BodyData.BodyAsString!),
|
||||
|
||||
_ => throw new NotSupportedException()
|
||||
};
|
||||
_ => throw new NotSupportedException()
|
||||
};
|
||||
|
||||
var fixedBytes = FixBytes(bytes, contentTypeHeaderValue);
|
||||
return MimeMessage.Load(new MemoryStream(fixedBytes));
|
||||
var fixedBytes = FixBytes(bytes, contentTypeHeader[0]);
|
||||
|
||||
mimeMessage = MimeMessage.Load(new MemoryStream(fixedBytes));
|
||||
return true;
|
||||
}
|
||||
|
||||
mimeMessage = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
private static bool StartsWithMultiPart(WireMockList<string> contentTypeHeader)
|
||||
{
|
||||
return contentTypeHeader.Any(ct => ct.TrimStart().StartsWith("multipart/", StringComparison.OrdinalIgnoreCase));
|
||||
}
|
||||
|
||||
private static byte[] FixBytes(byte[] bytes, WireMockList<string> contentType)
|
||||
|
||||
@@ -82,7 +82,6 @@
|
||||
<ItemGroup Condition=" '$(TargetFramework)' != 'netstandard1.3' ">
|
||||
<PackageReference Include="XPath2.Extensions" Version="1.1.3" />
|
||||
<PackageReference Include="Microsoft.IdentityModel.Protocols.OpenIdConnect" Version="6.12.2" />
|
||||
<PackageReference Include="Microsoft.AspNet.WebApi.Client" Version="5.2.8" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition=" '$(TargetFramework)' == 'net451' or '$(TargetFramework)' == 'net452' ">
|
||||
@@ -161,7 +160,7 @@
|
||||
<ItemGroup Condition="'$(TargetFramework)' != 'netstandard1.3' and '$(TargetFramework)' != 'net451' and '$(TargetFramework)' != 'net452' and '$(TargetFramework)' != 'net46' and '$(TargetFramework)' != 'net461'">
|
||||
<PackageReference Include="GraphQL" Version="7.5.0" />
|
||||
<PackageReference Include="GraphQL.NewtonsoftJson" Version="7.5.0" />
|
||||
<PackageReference Include="MimeKitLite" Version="4.1.0.1" PrivateAssets="all" />
|
||||
<PackageReference Include="MimeKitLite" Version="4.1.0.1" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition=" '$(TargetFramework)' == 'netcoreapp3.1' ">
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
using FluentAssertions;
|
||||
using NFluent;
|
||||
using WireMock.Matchers;
|
||||
using Xunit;
|
||||
@@ -11,12 +12,13 @@ public class CSharpCodeMatcherTests
|
||||
{
|
||||
// Assign
|
||||
string input = "x";
|
||||
|
||||
// Act
|
||||
var matcher = new CSharpCodeMatcher("return it == \"x\";");
|
||||
|
||||
// Act
|
||||
var score = matcher.IsMatch(input).Score;
|
||||
|
||||
// Assert
|
||||
Check.That(matcher.IsMatch(input)).IsEqualTo(1.0d);
|
||||
score.Should().Be(MatchScores.Perfect);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -24,12 +26,13 @@ public class CSharpCodeMatcherTests
|
||||
{
|
||||
// Assign
|
||||
string input = "y";
|
||||
|
||||
// Act
|
||||
var matcher = new CSharpCodeMatcher("return it == \"x\";");
|
||||
|
||||
// Act
|
||||
var score = matcher.IsMatch(input).Score;
|
||||
|
||||
// Assert
|
||||
Check.That(matcher.IsMatch(input)).IsEqualTo(0.0d);
|
||||
score.Should().Be(MatchScores.Mismatch);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -37,12 +40,13 @@ public class CSharpCodeMatcherTests
|
||||
{
|
||||
// Assign
|
||||
string input = "x";
|
||||
|
||||
// Act
|
||||
var matcher = new CSharpCodeMatcher(MatchBehaviour.RejectOnMatch, MatchOperator.Or, "return it == \"x\";");
|
||||
|
||||
// Act
|
||||
var score = matcher.IsMatch(input).Score;
|
||||
|
||||
// Assert
|
||||
Check.That(matcher.IsMatch(input)).IsEqualTo(0.0d);
|
||||
score.Should().Be(MatchScores.Mismatch);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -55,12 +59,13 @@ public class CSharpCodeMatcherTests
|
||||
Name = "Test"
|
||||
};
|
||||
|
||||
// Act
|
||||
var matcher = new CSharpCodeMatcher("return it.Id > 1 && it.Name == \"Test\";");
|
||||
double match = matcher.IsMatch(input);
|
||||
|
||||
// Act
|
||||
var score = matcher.IsMatch(input).Score;
|
||||
|
||||
// Assert
|
||||
Assert.Equal(1.0, match);
|
||||
score.Should().Be(MatchScores.Perfect);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
using FluentAssertions;
|
||||
using NFluent;
|
||||
using WireMock.Matchers;
|
||||
using Xunit;
|
||||
@@ -14,7 +15,12 @@ public class ContentTypeMatcherTests
|
||||
public void ContentTypeMatcher_IsMatchWithIgnoreCaseFalse_Positive(string contentType)
|
||||
{
|
||||
var matcher = new ContentTypeMatcher("application/json");
|
||||
Check.That(matcher.IsMatch(contentType)).IsEqualTo(1.0d);
|
||||
|
||||
// Act
|
||||
var score = matcher.IsMatch(contentType).Score;
|
||||
|
||||
// Assert
|
||||
score.Should().Be(MatchScores.Perfect);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
@@ -26,7 +32,12 @@ public class ContentTypeMatcherTests
|
||||
public void ContentTypeMatcher_IsMatchWithIgnoreCaseTrue_Positive(string contentType)
|
||||
{
|
||||
var matcher = new ContentTypeMatcher("application/json", true);
|
||||
Check.That(matcher.IsMatch(contentType)).IsEqualTo(1.0d);
|
||||
|
||||
// Act
|
||||
var score = matcher.IsMatch(contentType).Score;
|
||||
|
||||
// Assert
|
||||
score.Should().Be(MatchScores.Perfect);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
||||
@@ -39,7 +39,7 @@ public class ExactMatcherTests
|
||||
var matcher = new ExactMatcher(true, "x");
|
||||
|
||||
// Act
|
||||
double result = matcher.IsMatch("X");
|
||||
double result = matcher.IsMatch("X").Score;
|
||||
|
||||
// Assert
|
||||
Check.That(result).IsEqualTo(1.0);
|
||||
@@ -52,7 +52,7 @@ public class ExactMatcherTests
|
||||
var matcher = new ExactMatcher("x");
|
||||
|
||||
// Act
|
||||
double result = matcher.IsMatch("x");
|
||||
double result = matcher.IsMatch("x").Score;
|
||||
|
||||
// Assert
|
||||
Check.That(result).IsEqualTo(1.0);
|
||||
@@ -65,7 +65,7 @@ public class ExactMatcherTests
|
||||
var matcher = new ExactMatcher("x");
|
||||
|
||||
// Act
|
||||
double result = matcher.IsMatch("y");
|
||||
double result = matcher.IsMatch("y").Score;
|
||||
|
||||
// Assert
|
||||
Check.That(result).IsEqualTo(0.0);
|
||||
@@ -78,7 +78,7 @@ public class ExactMatcherTests
|
||||
var matcher = new ExactMatcher("x", "y");
|
||||
|
||||
// Act
|
||||
double result = matcher.IsMatch("x");
|
||||
double result = matcher.IsMatch("x").Score;
|
||||
|
||||
// Assert
|
||||
Check.That(result).IsEqualTo(1.0);
|
||||
@@ -91,7 +91,7 @@ public class ExactMatcherTests
|
||||
var matcher = new ExactMatcher("x", "y");
|
||||
|
||||
// Act
|
||||
double result = matcher.IsMatch("x");
|
||||
double result = matcher.IsMatch("x").Score;
|
||||
|
||||
// Assert
|
||||
Check.That(result).IsEqualTo(1.0);
|
||||
@@ -104,10 +104,10 @@ public class ExactMatcherTests
|
||||
public void ExactMatcher_IsMatch_WithMultiplePatterns_Average_ReturnsMatch(MatchOperator matchOperator, double score)
|
||||
{
|
||||
// Assign
|
||||
var matcher = new ExactMatcher(MatchBehaviour.AcceptOnMatch, false, false, matchOperator, "x", "y");
|
||||
var matcher = new ExactMatcher(MatchBehaviour.AcceptOnMatch, false, matchOperator, "x", "y");
|
||||
|
||||
// Act
|
||||
double result = matcher.IsMatch("x");
|
||||
double result = matcher.IsMatch("x").Score;
|
||||
|
||||
// Assert
|
||||
Check.That(result).IsEqualTo(score);
|
||||
@@ -120,7 +120,7 @@ public class ExactMatcherTests
|
||||
var matcher = new ExactMatcher("cat");
|
||||
|
||||
// Act
|
||||
double result = matcher.IsMatch("caR");
|
||||
double result = matcher.IsMatch("caR").Score;
|
||||
|
||||
// Assert
|
||||
Check.That(result).IsEqualTo(0.0);
|
||||
@@ -130,10 +130,10 @@ public class ExactMatcherTests
|
||||
public void ExactMatcher_IsMatch_SinglePattern_AcceptOnMatch()
|
||||
{
|
||||
// Assign
|
||||
var matcher = new ExactMatcher(MatchBehaviour.AcceptOnMatch, false, false, MatchOperator.Or, "cat");
|
||||
var matcher = new ExactMatcher(MatchBehaviour.AcceptOnMatch, false, MatchOperator.Or, "cat");
|
||||
|
||||
// Act
|
||||
double result = matcher.IsMatch("cat");
|
||||
double result = matcher.IsMatch("cat").Score;
|
||||
|
||||
// Assert
|
||||
Check.That(result).IsEqualTo(1.0);
|
||||
@@ -143,10 +143,10 @@ public class ExactMatcherTests
|
||||
public void ExactMatcher_IsMatch_SinglePattern_RejectOnMatch()
|
||||
{
|
||||
// Assign
|
||||
var matcher = new ExactMatcher(MatchBehaviour.RejectOnMatch, false, false, MatchOperator.Or, "cat");
|
||||
var matcher = new ExactMatcher(MatchBehaviour.RejectOnMatch, false, MatchOperator.Or, "cat");
|
||||
|
||||
// Act
|
||||
double result = matcher.IsMatch("cat");
|
||||
double result = matcher.IsMatch("cat").Score;
|
||||
|
||||
// Assert
|
||||
Check.That(result).IsEqualTo(0.0);
|
||||
|
||||
@@ -14,7 +14,7 @@ public class ExactObjectMatcherTests
|
||||
|
||||
// Act
|
||||
var matcher = new ExactObjectMatcher(obj);
|
||||
string name = matcher.Name;
|
||||
var name = matcher.Name;
|
||||
|
||||
// Assert
|
||||
Check.That(name).Equals("ExactObjectMatcher");
|
||||
@@ -28,10 +28,10 @@ public class ExactObjectMatcherTests
|
||||
|
||||
// Act
|
||||
var matcher = new ExactObjectMatcher(new byte[] { 1, 2 });
|
||||
double result = matcher.IsMatch(checkValue);
|
||||
var score = matcher.IsMatch(checkValue).Score;
|
||||
|
||||
// Assert
|
||||
Check.That(result).IsEqualTo(1.0);
|
||||
Check.That(score).IsEqualTo(1.0);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -42,10 +42,10 @@ public class ExactObjectMatcherTests
|
||||
|
||||
// Act
|
||||
var matcher = new ExactObjectMatcher(obj);
|
||||
double result = matcher.IsMatch(new { x = 500, s = "s" });
|
||||
var score = matcher.IsMatch(new { x = 500, s = "s" }).Score;
|
||||
|
||||
// Assert
|
||||
Check.That(result).IsEqualTo(1.0);
|
||||
Check.That(score).IsEqualTo(1.0);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -56,9 +56,9 @@ public class ExactObjectMatcherTests
|
||||
|
||||
// Act
|
||||
var matcher = new ExactObjectMatcher(MatchBehaviour.RejectOnMatch, obj);
|
||||
double result = matcher.IsMatch(new { x = 500, s = "s" });
|
||||
var score = matcher.IsMatch(new { x = 500, s = "s" }).Score;
|
||||
|
||||
// Assert
|
||||
Check.That(result).IsEqualTo(0.0);
|
||||
Check.That(score).IsEqualTo(0.0);
|
||||
}
|
||||
}
|
||||
@@ -51,7 +51,7 @@ public class GraphQLMatcherTests
|
||||
var result = matcher.IsMatch(input);
|
||||
|
||||
// Assert
|
||||
result.Should().Be(MatchScores.Perfect);
|
||||
result.Score.Should().Be(MatchScores.Perfect);
|
||||
|
||||
matcher.GetPatterns().Should().Contain(TestSchema);
|
||||
}
|
||||
@@ -71,7 +71,7 @@ public class GraphQLMatcherTests
|
||||
var result = matcher.IsMatch(input);
|
||||
|
||||
// Assert
|
||||
result.Should().Be(MatchScores.Perfect);
|
||||
result.Score.Should().Be(MatchScores.Perfect);
|
||||
|
||||
matcher.GetPatterns().Should().Contain(TestSchema);
|
||||
}
|
||||
@@ -93,7 +93,7 @@ public class GraphQLMatcherTests
|
||||
var result = matcher.IsMatch(input);
|
||||
|
||||
// Assert
|
||||
result.Should().Be(MatchScores.Mismatch);
|
||||
result.Score.Should().Be(MatchScores.Mismatch);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -111,21 +111,22 @@ public class GraphQLMatcherTests
|
||||
var result = matcher.IsMatch(input);
|
||||
|
||||
// Assert
|
||||
result.Should().Be(MatchScores.Perfect);
|
||||
result.Score.Should().Be(MatchScores.Perfect);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GraphQLMatcher_For_ValidSchema_And_IncorrectQueryWithError_WithThrowExceptionTrue_ThrowsException()
|
||||
public void GraphQLMatcher_For_ValidSchema_And_IncorrectQueryWithError_WithThrowExceptionTrue_ReturnsError()
|
||||
{
|
||||
// Arrange
|
||||
var input = "{\"query\":\"{\\r\\n studentsX {\\r\\n fullName\\r\\n X\\r\\n }\\r\\n}\"}";
|
||||
|
||||
// Act
|
||||
var matcher = new GraphQLMatcher(TestSchema, MatchBehaviour.AcceptOnMatch, true);
|
||||
Action action = () => matcher.IsMatch(input);
|
||||
var matcher = new GraphQLMatcher(TestSchema);
|
||||
var result = matcher.IsMatch(input);
|
||||
|
||||
// Assert
|
||||
action.Should().Throw<Exception>();
|
||||
result.Score.Should().Be(MatchScores.Mismatch);
|
||||
result.Exception!.Message.Should().StartWith("Cannot query field 'studentsX' on type 'Query'");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using FluentAssertions;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using NFluent;
|
||||
using WireMock.Matchers;
|
||||
@@ -42,7 +43,7 @@ public class JmesPathMatcherTests
|
||||
var matcher = new JmesPathMatcher("");
|
||||
|
||||
// Act
|
||||
double match = matcher.IsMatch(bytes);
|
||||
double match = matcher.IsMatch(bytes).Score;
|
||||
|
||||
// Assert
|
||||
Check.That(match).IsEqualTo(0);
|
||||
@@ -56,7 +57,7 @@ public class JmesPathMatcherTests
|
||||
var matcher = new JmesPathMatcher("");
|
||||
|
||||
// Act
|
||||
double match = matcher.IsMatch(s);
|
||||
double match = matcher.IsMatch(s).Score;
|
||||
|
||||
// Assert
|
||||
Check.That(match).IsEqualTo(0);
|
||||
@@ -70,7 +71,7 @@ public class JmesPathMatcherTests
|
||||
var matcher = new JmesPathMatcher("");
|
||||
|
||||
// Act
|
||||
double match = matcher.IsMatch(o);
|
||||
double match = matcher.IsMatch(o).Score;
|
||||
|
||||
// Assert
|
||||
Check.That(match).IsEqualTo(0);
|
||||
@@ -83,7 +84,7 @@ public class JmesPathMatcherTests
|
||||
var matcher = new JmesPathMatcher("xxx");
|
||||
|
||||
// Act
|
||||
double match = matcher.IsMatch("");
|
||||
double match = matcher.IsMatch("").Score;
|
||||
|
||||
// Assert
|
||||
Check.That(match).IsEqualTo(0);
|
||||
@@ -96,7 +97,7 @@ public class JmesPathMatcherTests
|
||||
var matcher = new JmesPathMatcher("");
|
||||
|
||||
// Act
|
||||
double match = matcher.IsMatch("x");
|
||||
double match = matcher.IsMatch("x").Score;
|
||||
|
||||
// Assert
|
||||
Check.That(match).IsEqualTo(0);
|
||||
@@ -109,7 +110,7 @@ public class JmesPathMatcherTests
|
||||
var matcher = new JmesPathMatcher("things.name == 'RequiredThing'");
|
||||
|
||||
// Act
|
||||
double match = matcher.IsMatch(new { things = new { name = "RequiredThing" } });
|
||||
double match = matcher.IsMatch(new { things = new { name = "RequiredThing" } }).Score;
|
||||
|
||||
// Assert
|
||||
Check.That(match).IsEqualTo(1);
|
||||
@@ -132,7 +133,7 @@ public class JmesPathMatcherTests
|
||||
{ "Id", new JValue(1) },
|
||||
{ "things", sub }
|
||||
};
|
||||
double match = matcher.IsMatch(jobject);
|
||||
double match = matcher.IsMatch(jobject).Score;
|
||||
|
||||
// Assert
|
||||
Check.That(match).IsEqualTo(1);
|
||||
@@ -145,7 +146,7 @@ public class JmesPathMatcherTests
|
||||
var matcher = new JmesPathMatcher("things.x == 'RequiredThing'");
|
||||
|
||||
// Act
|
||||
double match = matcher.IsMatch(JObject.Parse("{ \"things\": { \"x\": \"RequiredThing\" } }"));
|
||||
double match = matcher.IsMatch(JObject.Parse("{ \"things\": { \"x\": \"RequiredThing\" } }")).Score;
|
||||
|
||||
// Assert
|
||||
Check.That(match).IsEqualTo(1);
|
||||
@@ -155,12 +156,38 @@ public class JmesPathMatcherTests
|
||||
public void JmesPathMatcher_IsMatch_RejectOnMatch()
|
||||
{
|
||||
// Assign
|
||||
var matcher = new JmesPathMatcher(MatchBehaviour.RejectOnMatch, false, MatchOperator.Or, "things.x == 'RequiredThing'");
|
||||
var matcher = new JmesPathMatcher(MatchBehaviour.RejectOnMatch, MatchOperator.Or, "things.x == 'RequiredThing'");
|
||||
|
||||
// Act
|
||||
double match = matcher.IsMatch(JObject.Parse("{ \"things\": { \"x\": \"RequiredThing\" } }"));
|
||||
double match = matcher.IsMatch(JObject.Parse("{ \"things\": { \"x\": \"RequiredThing\" } }")).Score;
|
||||
|
||||
// Assert
|
||||
Check.That(match).IsEqualTo(0.0);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void JmesPathMatcher_IsMatch_MultiplePatternsUsingMatchOperatorAnd()
|
||||
{
|
||||
// Assign
|
||||
var matcher = new JmesPathMatcher(MatchOperator.And, "things.x == 'RequiredThing'", "things.x == 'abc'");
|
||||
|
||||
// Act
|
||||
double score = matcher.IsMatch(JObject.Parse("{ \"things\": { \"x\": \"RequiredThing\" } }")).Score;
|
||||
|
||||
// Assert
|
||||
score.Should().Be(0);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void JmesPathMatcher_IsMatch_MultiplePatternsUsingMatchOperatorOr()
|
||||
{
|
||||
// Assign
|
||||
var matcher = new JmesPathMatcher(MatchOperator.Or, "things.x == 'RequiredThing'", "things.x == 'abc'");
|
||||
|
||||
// Act
|
||||
double score = matcher.IsMatch(JObject.Parse("{ \"things\": { \"x\": \"RequiredThing\" } }")).Score;
|
||||
|
||||
// Assert
|
||||
score.Should().Be(1);
|
||||
}
|
||||
}
|
||||
@@ -82,29 +82,17 @@ public class JsonMatcherTests
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void JsonMatcher_IsMatch_WithInvalidValue_And_ThrowExceptionIsFalse_Should_ReturnMismatch()
|
||||
public void JsonMatcher_IsMatch_WithInvalidValue_Should_ReturnMismatch_And_Exception_ShouldBeSet()
|
||||
{
|
||||
// Assign
|
||||
var matcher = new JsonMatcher("");
|
||||
|
||||
// Act
|
||||
double match = matcher.IsMatch(new MemoryStream());
|
||||
var result = matcher.IsMatch(new MemoryStream());
|
||||
|
||||
// Assert
|
||||
Check.That(match).IsEqualTo(0);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void JsonMatcher_IsMatch_WithInvalidValue_And_ThrowExceptionIsTrue_Should_ReturnMismatch()
|
||||
{
|
||||
// Assign
|
||||
var matcher = new JsonMatcher("", false, true);
|
||||
|
||||
// Act
|
||||
Action action = () => matcher.IsMatch(new MemoryStream());
|
||||
|
||||
// Assert
|
||||
action.Should().Throw<JsonException>();
|
||||
result.Score.Should().Be(MatchScores.Mismatch);
|
||||
result.Exception.Should().BeAssignableTo<JsonException>();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -115,7 +103,7 @@ public class JsonMatcherTests
|
||||
var matcher = new JsonMatcher("");
|
||||
|
||||
// Act
|
||||
double match = matcher.IsMatch(bytes);
|
||||
double match = matcher.IsMatch(bytes).Score;
|
||||
|
||||
// Assert
|
||||
Check.That(match).IsEqualTo(0);
|
||||
@@ -129,7 +117,7 @@ public class JsonMatcherTests
|
||||
var matcher = new JsonMatcher("");
|
||||
|
||||
// Act
|
||||
double match = matcher.IsMatch(s);
|
||||
double match = matcher.IsMatch(s).Score;
|
||||
|
||||
// Assert
|
||||
Check.That(match).IsEqualTo(0);
|
||||
@@ -143,7 +131,7 @@ public class JsonMatcherTests
|
||||
var matcher = new JsonMatcher("");
|
||||
|
||||
// Act
|
||||
double match = matcher.IsMatch(o);
|
||||
double match = matcher.IsMatch(o).Score;
|
||||
|
||||
// Assert
|
||||
Check.That(match).IsEqualTo(0);
|
||||
@@ -161,7 +149,7 @@ public class JsonMatcherTests
|
||||
"x",
|
||||
"y"
|
||||
};
|
||||
double match = matcher.IsMatch(jArray);
|
||||
double match = matcher.IsMatch(jArray).Score;
|
||||
|
||||
// Assert
|
||||
Assert.Equal(1.0, match);
|
||||
@@ -179,7 +167,7 @@ public class JsonMatcherTests
|
||||
{ "Id", new JValue(1) },
|
||||
{ "Name", new JValue("Test") }
|
||||
};
|
||||
double match = matcher.IsMatch(jObject);
|
||||
double match = matcher.IsMatch(jObject).Score;
|
||||
|
||||
// Assert
|
||||
Assert.Equal(1.0, match);
|
||||
@@ -197,7 +185,7 @@ public class JsonMatcherTests
|
||||
{ "Id", new JValue(1) },
|
||||
{ "NaMe", new JValue("Test") }
|
||||
};
|
||||
double match = matcher.IsMatch(jObject);
|
||||
double match = matcher.IsMatch(jObject).Score;
|
||||
|
||||
// Assert
|
||||
Assert.Equal(1.0, match);
|
||||
@@ -211,7 +199,7 @@ public class JsonMatcherTests
|
||||
|
||||
// Act
|
||||
var jObject = JObject.Parse("{ \"Id\" : 1, \"Name\" : \"Test\" }");
|
||||
double match = matcher.IsMatch(jObject);
|
||||
double match = matcher.IsMatch(jObject).Score;
|
||||
|
||||
// Assert
|
||||
Assert.Equal(1.0, match);
|
||||
@@ -225,7 +213,7 @@ public class JsonMatcherTests
|
||||
|
||||
// Act
|
||||
var jObject = JObject.Parse("{ \"Id\" : 1, \"Name\" : \"Test\" }");
|
||||
double match = matcher.IsMatch(jObject);
|
||||
double match = matcher.IsMatch(jObject).Score;
|
||||
|
||||
// Assert
|
||||
Assert.Equal(1.0, match);
|
||||
@@ -243,7 +231,7 @@ public class JsonMatcherTests
|
||||
"x",
|
||||
"y"
|
||||
};
|
||||
double match = matcher.IsMatch(jArray);
|
||||
double match = matcher.IsMatch(jArray).Score;
|
||||
|
||||
// Assert
|
||||
Assert.Equal(1.0, match);
|
||||
@@ -261,7 +249,7 @@ public class JsonMatcherTests
|
||||
{ "Id", new JValue(1) },
|
||||
{ "Name", new JValue("Test") }
|
||||
};
|
||||
double match = matcher.IsMatch(jObject);
|
||||
double match = matcher.IsMatch(jObject).Score;
|
||||
|
||||
// Assert
|
||||
Assert.Equal(1.0, match);
|
||||
@@ -279,7 +267,7 @@ public class JsonMatcherTests
|
||||
{ "Id", new JValue(1) },
|
||||
{ "Name", new JValue("Test") }
|
||||
};
|
||||
double match = matcher.IsMatch(jObject);
|
||||
double match = matcher.IsMatch(jObject).Score;
|
||||
|
||||
// Assert
|
||||
Assert.Equal(1.0, match);
|
||||
@@ -297,7 +285,7 @@ public class JsonMatcherTests
|
||||
{ "Id", new JValue(1) },
|
||||
{ "Name", new JValue("Test") }
|
||||
};
|
||||
double match = matcher.IsMatch(jObject);
|
||||
double match = matcher.IsMatch(jObject).Score;
|
||||
|
||||
// Assert
|
||||
Assert.Equal(0.0, match);
|
||||
@@ -314,7 +302,7 @@ public class JsonMatcherTests
|
||||
{
|
||||
{ "preferredAt", new JValue("2019-11-21T10:32:53.2210009+00:00") }
|
||||
};
|
||||
double match = matcher.IsMatch(jObject);
|
||||
double match = matcher.IsMatch(jObject).Score;
|
||||
|
||||
// Assert
|
||||
Assert.Equal(1.0, match);
|
||||
@@ -331,7 +319,7 @@ public class JsonMatcherTests
|
||||
{
|
||||
{ "NormalEnum", new JValue(0) }
|
||||
};
|
||||
double match = matcher.IsMatch(jObject);
|
||||
double match = matcher.IsMatch(jObject).Score;
|
||||
|
||||
// Assert
|
||||
match.Should().Be(1.0);
|
||||
@@ -348,7 +336,7 @@ public class JsonMatcherTests
|
||||
{
|
||||
{ "EnumWithJsonConverter", new JValue("Type1") }
|
||||
};
|
||||
double match = matcher.IsMatch(jObject);
|
||||
double match = matcher.IsMatch(jObject).Score;
|
||||
|
||||
// Assert
|
||||
match.Should().Be(1.0);
|
||||
|
||||
@@ -60,29 +60,17 @@ public class JsonPartialMatcherTests
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void JsonPartialMatcher_IsMatch_WithInvalidValue_And_ThrowExceptionIsFalse_Should_ReturnMismatch()
|
||||
public void JsonPartialMatcher_IsMatch_WithInvalidValue_Should_ReturnMismatch_And_Exception_ShouldBeSet()
|
||||
{
|
||||
// Assign
|
||||
var matcher = new JsonPartialMatcher("");
|
||||
|
||||
// Act
|
||||
double match = matcher.IsMatch(new MemoryStream());
|
||||
var result = matcher.IsMatch(new MemoryStream());
|
||||
|
||||
// Assert
|
||||
Check.That(match).IsEqualTo(0);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void JsonPartialMatcher_IsMatch_WithInvalidValue_And_ThrowExceptionIsTrue_Should_ReturnMismatch()
|
||||
{
|
||||
// Assign
|
||||
var matcher = new JsonPartialMatcher("", false, true);
|
||||
|
||||
// Act
|
||||
Action action = () => matcher.IsMatch(new MemoryStream());
|
||||
|
||||
// Assert
|
||||
action.Should().Throw<JsonException>();
|
||||
result.Score.Should().Be(MatchScores.Mismatch);
|
||||
result.Exception.Should().BeAssignableTo<JsonException>();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -93,7 +81,7 @@ public class JsonPartialMatcherTests
|
||||
var matcher = new JsonPartialMatcher("");
|
||||
|
||||
// Act
|
||||
double match = matcher.IsMatch(bytes);
|
||||
double match = matcher.IsMatch(bytes).Score;
|
||||
|
||||
// Assert
|
||||
Check.That(match).IsEqualTo(0);
|
||||
@@ -107,7 +95,7 @@ public class JsonPartialMatcherTests
|
||||
var matcher = new JsonPartialMatcher("");
|
||||
|
||||
// Act
|
||||
double match = matcher.IsMatch(s);
|
||||
double match = matcher.IsMatch(s).Score;
|
||||
|
||||
// Assert
|
||||
Check.That(match).IsEqualTo(0);
|
||||
@@ -121,7 +109,7 @@ public class JsonPartialMatcherTests
|
||||
var matcher = new JsonPartialMatcher("");
|
||||
|
||||
// Act
|
||||
double match = matcher.IsMatch(o);
|
||||
double match = matcher.IsMatch(o).Score;
|
||||
|
||||
// Assert
|
||||
Check.That(match).IsEqualTo(0);
|
||||
@@ -139,7 +127,7 @@ public class JsonPartialMatcherTests
|
||||
"x",
|
||||
"y"
|
||||
};
|
||||
double match = matcher.IsMatch(jArray);
|
||||
double match = matcher.IsMatch(jArray).Score;
|
||||
|
||||
// Assert
|
||||
Assert.Equal(1.0, match);
|
||||
@@ -157,7 +145,7 @@ public class JsonPartialMatcherTests
|
||||
{ "Id", new JValue(1) },
|
||||
{ "Name", new JValue("Test") }
|
||||
};
|
||||
double match = matcher.IsMatch(jObject);
|
||||
double match = matcher.IsMatch(jObject).Score;
|
||||
|
||||
// Assert
|
||||
Assert.Equal(1.0, match);
|
||||
@@ -167,7 +155,7 @@ public class JsonPartialMatcherTests
|
||||
public void JsonPartialMatcher_IsMatch_WithRegexTrue()
|
||||
{
|
||||
// Assign
|
||||
var matcher = new JsonPartialMatcher(new { Id = "^\\d+$", Name = "Test" }, false, false, true);
|
||||
var matcher = new JsonPartialMatcher(new { Id = "^\\d+$", Name = "Test" }, false, true);
|
||||
|
||||
// Act
|
||||
var jObject = new JObject
|
||||
@@ -175,7 +163,7 @@ public class JsonPartialMatcherTests
|
||||
{ "Id", new JValue(1) },
|
||||
{ "Name", new JValue("Test") }
|
||||
};
|
||||
double match = matcher.IsMatch(jObject);
|
||||
double match = matcher.IsMatch(jObject).Score;
|
||||
|
||||
// Assert
|
||||
Assert.Equal(1.0, match);
|
||||
@@ -193,7 +181,7 @@ public class JsonPartialMatcherTests
|
||||
{ "Id", new JValue(1) },
|
||||
{ "Name", new JValue("Test") }
|
||||
};
|
||||
double match = matcher.IsMatch(jObject);
|
||||
double match = matcher.IsMatch(jObject).Score;
|
||||
|
||||
// Assert
|
||||
Assert.Equal(0.0, match);
|
||||
@@ -203,10 +191,11 @@ public class JsonPartialMatcherTests
|
||||
public void JsonPartialMatcher_IsMatch_GuidAsString_UsingRegex()
|
||||
{
|
||||
var guid = new Guid("1111238e-b775-44a9-a263-95e570135c94");
|
||||
var matcher = new JsonPartialMatcher(new {
|
||||
var matcher = new JsonPartialMatcher(new
|
||||
{
|
||||
Id = 1,
|
||||
Name = "^1111[a-fA-F0-9]{4}(-[a-fA-F0-9]{4}){3}-[a-fA-F0-9]{12}$"
|
||||
}, false, false, true);
|
||||
}, false, true);
|
||||
|
||||
// Act
|
||||
var jObject = new JObject
|
||||
@@ -214,7 +203,7 @@ public class JsonPartialMatcherTests
|
||||
{ "Id", new JValue(1) },
|
||||
{ "Name", new JValue(guid) }
|
||||
};
|
||||
double match = matcher.IsMatch(jObject);
|
||||
double match = matcher.IsMatch(jObject).Score;
|
||||
|
||||
// Assert
|
||||
Assert.Equal(1.0, match);
|
||||
@@ -232,7 +221,7 @@ public class JsonPartialMatcherTests
|
||||
{ "Id", new JValue(1) },
|
||||
{ "NaMe", new JValue("Test") }
|
||||
};
|
||||
double match = matcher.IsMatch(jObject);
|
||||
double match = matcher.IsMatch(jObject).Score;
|
||||
|
||||
// Assert
|
||||
Assert.Equal(1.0, match);
|
||||
@@ -246,7 +235,7 @@ public class JsonPartialMatcherTests
|
||||
|
||||
// Act
|
||||
var jObject = JObject.Parse("{ \"Id\" : 1, \"Name\" : \"Test\" }");
|
||||
double match = matcher.IsMatch(jObject);
|
||||
double match = matcher.IsMatch(jObject).Score;
|
||||
|
||||
// Assert
|
||||
Assert.Equal(1.0, match);
|
||||
@@ -260,7 +249,7 @@ public class JsonPartialMatcherTests
|
||||
|
||||
// Act
|
||||
var jObject = JObject.Parse("{ \"Id\" : 1, \"Name\" : \"Test\" }");
|
||||
double match = matcher.IsMatch(jObject);
|
||||
double match = matcher.IsMatch(jObject).Score;
|
||||
|
||||
// Assert
|
||||
Assert.Equal(1.0, match);
|
||||
@@ -278,7 +267,7 @@ public class JsonPartialMatcherTests
|
||||
"x",
|
||||
"y"
|
||||
};
|
||||
double match = matcher.IsMatch(jArray);
|
||||
double match = matcher.IsMatch(jArray).Score;
|
||||
|
||||
// Assert
|
||||
Assert.Equal(1.0, match);
|
||||
@@ -296,7 +285,7 @@ public class JsonPartialMatcherTests
|
||||
{ "Id", new JValue(1) },
|
||||
{ "Name", new JValue("Test") }
|
||||
};
|
||||
double match = matcher.IsMatch(jObject);
|
||||
double match = matcher.IsMatch(jObject).Score;
|
||||
|
||||
// Assert
|
||||
Assert.Equal(1.0, match);
|
||||
@@ -305,20 +294,20 @@ public class JsonPartialMatcherTests
|
||||
[Fact]
|
||||
public void JsonPartialMatcher_IsMatch_GuidAsString()
|
||||
{
|
||||
// Assign
|
||||
var guid = Guid.NewGuid();
|
||||
var matcher = new JsonPartialMatcher(new { Id = 1, Name = guid });
|
||||
// Assign
|
||||
var guid = Guid.NewGuid();
|
||||
var matcher = new JsonPartialMatcher(new { Id = 1, Name = guid });
|
||||
|
||||
// Act
|
||||
var jObject = new JObject
|
||||
{
|
||||
{ "Id", new JValue(1) },
|
||||
{ "Name", new JValue(guid.ToString()) }
|
||||
};
|
||||
double match = matcher.IsMatch(jObject);
|
||||
// Act
|
||||
var jObject = new JObject
|
||||
{
|
||||
{ "Id", new JValue(1) },
|
||||
{ "Name", new JValue(guid.ToString()) }
|
||||
};
|
||||
double match = matcher.IsMatch(jObject).Score;
|
||||
|
||||
// Assert
|
||||
Assert.Equal(1.0, match);
|
||||
// Assert
|
||||
Assert.Equal(1.0, match);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -333,7 +322,7 @@ public class JsonPartialMatcherTests
|
||||
{ "Id", new JValue(1) },
|
||||
{ "Name", new JValue("Test") }
|
||||
};
|
||||
double match = matcher.IsMatch(jObject);
|
||||
double match = matcher.IsMatch(jObject).Score;
|
||||
|
||||
// Assert
|
||||
Assert.Equal(1.0, match);
|
||||
@@ -351,7 +340,7 @@ public class JsonPartialMatcherTests
|
||||
{ "Id", new JValue(1) },
|
||||
{ "Name", new JValue("Test") }
|
||||
};
|
||||
double match = matcher.IsMatch(jObject);
|
||||
double match = matcher.IsMatch(jObject).Score;
|
||||
|
||||
// Assert
|
||||
Assert.Equal(0.0, match);
|
||||
@@ -368,7 +357,7 @@ public class JsonPartialMatcherTests
|
||||
{
|
||||
{ "preferredAt", new JValue("2019-11-21T10:32:53.2210009+00:00") }
|
||||
};
|
||||
double match = matcher.IsMatch(jObject);
|
||||
double match = matcher.IsMatch(jObject).Score;
|
||||
|
||||
// Assert
|
||||
Assert.Equal(1.0, match);
|
||||
@@ -391,7 +380,7 @@ public class JsonPartialMatcherTests
|
||||
var matcher = new JsonPartialMatcher(value);
|
||||
|
||||
// Act
|
||||
double match = matcher.IsMatch(input);
|
||||
double match = matcher.IsMatch(input).Score;
|
||||
|
||||
// Assert
|
||||
Assert.Equal(1.0, match);
|
||||
@@ -415,7 +404,7 @@ public class JsonPartialMatcherTests
|
||||
var matcher = new JsonPartialMatcher(value);
|
||||
|
||||
// Act
|
||||
double match = matcher.IsMatch(input);
|
||||
double match = matcher.IsMatch(input).Score;
|
||||
|
||||
// Assert
|
||||
Assert.Equal(0.0, match);
|
||||
@@ -434,7 +423,7 @@ public class JsonPartialMatcherTests
|
||||
var matcher = new JsonPartialMatcher(value);
|
||||
|
||||
// Act
|
||||
double match = matcher.IsMatch(input);
|
||||
double match = matcher.IsMatch(input).Score;
|
||||
|
||||
// Assert
|
||||
Assert.Equal(1.0, match);
|
||||
@@ -453,7 +442,7 @@ public class JsonPartialMatcherTests
|
||||
var matcher = new JsonPartialMatcher(value);
|
||||
|
||||
// Act
|
||||
double match = matcher.IsMatch(input);
|
||||
double match = matcher.IsMatch(input).Score;
|
||||
|
||||
// Assert
|
||||
Assert.Equal(0.0, match);
|
||||
|
||||
@@ -60,29 +60,17 @@ public class JsonPartialWildcardMatcherTests
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void JsonPartialWildcardMatcher_IsMatch_WithInvalidValue_And_ThrowExceptionIsFalse_Should_ReturnMismatch()
|
||||
public void JsonPartialWildcardMatcher_IsMatch_WithInvalidValue_Should_ReturnMismatch_And_Exception_ShouldBeSet()
|
||||
{
|
||||
// Assign
|
||||
var matcher = new JsonPartialWildcardMatcher("");
|
||||
|
||||
// Act
|
||||
double match = matcher.IsMatch(new MemoryStream());
|
||||
var result = matcher.IsMatch(new MemoryStream());
|
||||
|
||||
// Assert
|
||||
Check.That(match).IsEqualTo(0);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void JsonPartialWildcardMatcher_IsMatch_WithInvalidValue_And_ThrowExceptionIsTrue_Should_ReturnMismatch()
|
||||
{
|
||||
// Assign
|
||||
var matcher = new JsonPartialWildcardMatcher("", false, true);
|
||||
|
||||
// Act
|
||||
Action action = () => matcher.IsMatch(new MemoryStream());
|
||||
|
||||
// Assert
|
||||
action.Should().Throw<JsonException>();
|
||||
result.Score.Should().Be(MatchScores.Mismatch);
|
||||
result.Exception.Should().BeAssignableTo<JsonException>();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -93,7 +81,7 @@ public class JsonPartialWildcardMatcherTests
|
||||
var matcher = new JsonPartialWildcardMatcher("");
|
||||
|
||||
// Act
|
||||
double match = matcher.IsMatch(bytes);
|
||||
double match = matcher.IsMatch(bytes).Score;
|
||||
|
||||
// Assert
|
||||
Check.That(match).IsEqualTo(0);
|
||||
@@ -107,7 +95,7 @@ public class JsonPartialWildcardMatcherTests
|
||||
var matcher = new JsonPartialWildcardMatcher("");
|
||||
|
||||
// Act
|
||||
double match = matcher.IsMatch(s);
|
||||
double match = matcher.IsMatch(s).Score;
|
||||
|
||||
// Assert
|
||||
Check.That(match).IsEqualTo(0);
|
||||
@@ -121,7 +109,7 @@ public class JsonPartialWildcardMatcherTests
|
||||
var matcher = new JsonPartialWildcardMatcher("");
|
||||
|
||||
// Act
|
||||
double match = matcher.IsMatch(o);
|
||||
double match = matcher.IsMatch(o).Score;
|
||||
|
||||
// Assert
|
||||
Check.That(match).IsEqualTo(0);
|
||||
@@ -139,7 +127,7 @@ public class JsonPartialWildcardMatcherTests
|
||||
"x",
|
||||
"y"
|
||||
};
|
||||
double match = matcher.IsMatch(jArray);
|
||||
double match = matcher.IsMatch(jArray).Score;
|
||||
|
||||
// Assert
|
||||
Assert.Equal(1.0, match);
|
||||
@@ -157,7 +145,7 @@ public class JsonPartialWildcardMatcherTests
|
||||
{ "Id", new JValue(1) },
|
||||
{ "Name", new JValue("Test") }
|
||||
};
|
||||
double match = matcher.IsMatch(jObject);
|
||||
double match = matcher.IsMatch(jObject).Score;
|
||||
|
||||
// Assert
|
||||
Assert.Equal(1.0, match);
|
||||
@@ -175,7 +163,7 @@ public class JsonPartialWildcardMatcherTests
|
||||
{ "Id", new JValue(1) },
|
||||
{ "NaMe", new JValue("Test") }
|
||||
};
|
||||
double match = matcher.IsMatch(jObject);
|
||||
double match = matcher.IsMatch(jObject).Score;
|
||||
|
||||
// Assert
|
||||
Assert.Equal(1.0, match);
|
||||
@@ -189,7 +177,7 @@ public class JsonPartialWildcardMatcherTests
|
||||
|
||||
// Act
|
||||
var jObject = JObject.Parse("{ \"Id\" : 1, \"Name\" : \"Test\" }");
|
||||
double match = matcher.IsMatch(jObject);
|
||||
double match = matcher.IsMatch(jObject).Score;
|
||||
|
||||
// Assert
|
||||
Assert.Equal(1.0, match);
|
||||
@@ -203,7 +191,7 @@ public class JsonPartialWildcardMatcherTests
|
||||
|
||||
// Act
|
||||
var jObject = JObject.Parse("{ \"Id\" : 1, \"Name\" : \"Test\" }");
|
||||
double match = matcher.IsMatch(jObject);
|
||||
double match = matcher.IsMatch(jObject).Score;
|
||||
|
||||
// Assert
|
||||
Assert.Equal(1.0, match);
|
||||
@@ -221,7 +209,7 @@ public class JsonPartialWildcardMatcherTests
|
||||
"x",
|
||||
"y"
|
||||
};
|
||||
double match = matcher.IsMatch(jArray);
|
||||
double match = matcher.IsMatch(jArray).Score;
|
||||
|
||||
// Assert
|
||||
Assert.Equal(1.0, match);
|
||||
@@ -239,7 +227,7 @@ public class JsonPartialWildcardMatcherTests
|
||||
{ "Id", new JValue(1) },
|
||||
{ "Name", new JValue("Test") }
|
||||
};
|
||||
double match = matcher.IsMatch(jObject);
|
||||
double match = matcher.IsMatch(jObject).Score;
|
||||
|
||||
// Assert
|
||||
Assert.Equal(1.0, match);
|
||||
@@ -257,7 +245,7 @@ public class JsonPartialWildcardMatcherTests
|
||||
{ "Id", new JValue(1) },
|
||||
{ "Name", new JValue("Test") }
|
||||
};
|
||||
double match = matcher.IsMatch(jObject);
|
||||
double match = matcher.IsMatch(jObject).Score;
|
||||
|
||||
// Assert
|
||||
Assert.Equal(1.0, match);
|
||||
@@ -275,7 +263,7 @@ public class JsonPartialWildcardMatcherTests
|
||||
{ "Id", new JValue(1) },
|
||||
{ "Name", new JValue("Test") }
|
||||
};
|
||||
double match = matcher.IsMatch(jObject);
|
||||
double match = matcher.IsMatch(jObject).Score;
|
||||
|
||||
// Assert
|
||||
Assert.Equal(0.0, match);
|
||||
@@ -292,7 +280,7 @@ public class JsonPartialWildcardMatcherTests
|
||||
{
|
||||
{ "preferredAt", new JValue("2019-11-21T10:32:53.2210009+00:00") }
|
||||
};
|
||||
double match = matcher.IsMatch(jObject);
|
||||
double match = matcher.IsMatch(jObject).Score;
|
||||
|
||||
// Assert
|
||||
Assert.Equal(1.0, match);
|
||||
@@ -315,7 +303,7 @@ public class JsonPartialWildcardMatcherTests
|
||||
var matcher = new JsonPartialWildcardMatcher(value);
|
||||
|
||||
// Act
|
||||
double match = matcher.IsMatch(input);
|
||||
double match = matcher.IsMatch(input).Score;
|
||||
|
||||
// Assert
|
||||
Assert.Equal(1.0, match);
|
||||
@@ -330,7 +318,7 @@ public class JsonPartialWildcardMatcherTests
|
||||
var matcher = new JsonPartialWildcardMatcher(value);
|
||||
|
||||
// Act
|
||||
double match = matcher.IsMatch(input);
|
||||
double match = matcher.IsMatch(input).Score;
|
||||
|
||||
// Assert
|
||||
match.Should().Be(1.0);
|
||||
@@ -354,7 +342,7 @@ public class JsonPartialWildcardMatcherTests
|
||||
var matcher = new JsonPartialWildcardMatcher(value);
|
||||
|
||||
// Act
|
||||
double match = matcher.IsMatch(input);
|
||||
double match = matcher.IsMatch(input).Score;
|
||||
|
||||
// Assert
|
||||
Assert.Equal(0.0, match);
|
||||
@@ -373,7 +361,7 @@ public class JsonPartialWildcardMatcherTests
|
||||
var matcher = new JsonPartialWildcardMatcher(value);
|
||||
|
||||
// Act
|
||||
double match = matcher.IsMatch(input);
|
||||
double match = matcher.IsMatch(input).Score;
|
||||
|
||||
// Assert
|
||||
Assert.Equal(1.0, match);
|
||||
@@ -392,7 +380,7 @@ public class JsonPartialWildcardMatcherTests
|
||||
var matcher = new JsonPartialWildcardMatcher(value);
|
||||
|
||||
// Act
|
||||
double match = matcher.IsMatch(input);
|
||||
double match = matcher.IsMatch(input).Score;
|
||||
|
||||
// Assert
|
||||
Assert.Equal(0.0, match);
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using FluentAssertions;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using NFluent;
|
||||
using WireMock.Matchers;
|
||||
@@ -42,7 +43,7 @@ public class JsonPathMatcherTests
|
||||
var matcher = new JsonPathMatcher("");
|
||||
|
||||
// Act
|
||||
double match = matcher.IsMatch(bytes);
|
||||
double match = matcher.IsMatch(bytes).Score;
|
||||
|
||||
// Assert
|
||||
Check.That(match).IsEqualTo(0);
|
||||
@@ -56,7 +57,7 @@ public class JsonPathMatcherTests
|
||||
var matcher = new JsonPathMatcher("");
|
||||
|
||||
// Act
|
||||
double match = matcher.IsMatch(s);
|
||||
double match = matcher.IsMatch(s).Score;
|
||||
|
||||
// Assert
|
||||
Check.That(match).IsEqualTo(0);
|
||||
@@ -70,7 +71,7 @@ public class JsonPathMatcherTests
|
||||
var matcher = new JsonPathMatcher("");
|
||||
|
||||
// Act
|
||||
double match = matcher.IsMatch(o);
|
||||
double match = matcher.IsMatch(o).Score;
|
||||
|
||||
// Assert
|
||||
Check.That(match).IsEqualTo(0);
|
||||
@@ -83,7 +84,7 @@ public class JsonPathMatcherTests
|
||||
var matcher = new JsonPathMatcher("xxx");
|
||||
|
||||
// Act
|
||||
double match = matcher.IsMatch("");
|
||||
double match = matcher.IsMatch("").Score;
|
||||
|
||||
// Assert
|
||||
Check.That(match).IsEqualTo(0);
|
||||
@@ -96,7 +97,7 @@ public class JsonPathMatcherTests
|
||||
var matcher = new JsonPathMatcher("");
|
||||
|
||||
// Act
|
||||
double match = matcher.IsMatch("x");
|
||||
double match = matcher.IsMatch("x").Score;
|
||||
|
||||
// Assert
|
||||
Check.That(match).IsEqualTo(0);
|
||||
@@ -109,7 +110,7 @@ public class JsonPathMatcherTests
|
||||
var matcher = new JsonPathMatcher("$..[?(@.Id == 1)]");
|
||||
|
||||
// Act
|
||||
double match = matcher.IsMatch(new { Id = 1, Name = "Test" });
|
||||
double match = matcher.IsMatch(new { Id = 1, Name = "Test" }).Score;
|
||||
|
||||
// Assert
|
||||
Check.That(match).IsEqualTo(1);
|
||||
@@ -122,7 +123,7 @@ public class JsonPathMatcherTests
|
||||
var matcher = new JsonPathMatcher("$.things[?(@.name == 'x')]");
|
||||
|
||||
// Act
|
||||
double match = matcher.IsMatch(new { things = new { name = "x" } });
|
||||
double match = matcher.IsMatch(new { things = new { name = "x" } }).Score;
|
||||
|
||||
// Assert
|
||||
Check.That(match).IsEqualTo(1);
|
||||
@@ -136,7 +137,7 @@ public class JsonPathMatcherTests
|
||||
var matcher = new JsonPathMatcher("$.things[?(@.name == 'x')]");
|
||||
|
||||
// Act
|
||||
double match = matcher.IsMatch(json);
|
||||
double match = matcher.IsMatch(json).Score;
|
||||
|
||||
// Assert
|
||||
Check.That(match).IsEqualTo(1);
|
||||
@@ -150,7 +151,7 @@ public class JsonPathMatcherTests
|
||||
var matcher = new JsonPathMatcher("$.things[?(@.name == 'x')]");
|
||||
|
||||
// Act
|
||||
double match = matcher.IsMatch(json);
|
||||
double match = matcher.IsMatch(json).Score;
|
||||
|
||||
// Assert
|
||||
Check.That(match).IsEqualTo(0);
|
||||
@@ -169,7 +170,7 @@ public class JsonPathMatcherTests
|
||||
{ "Id", new JValue(1) },
|
||||
{ "Name", new JValue("Test") }
|
||||
};
|
||||
double match = matcher.IsMatch(jobject);
|
||||
double match = matcher.IsMatch(jobject).Score;
|
||||
|
||||
// Assert
|
||||
Check.That(match).IsEqualTo(1);
|
||||
@@ -182,7 +183,7 @@ public class JsonPathMatcherTests
|
||||
var matcher = new JsonPathMatcher("$..[?(@.Id == 1)]");
|
||||
|
||||
// Act
|
||||
double match = matcher.IsMatch(JObject.Parse("{\"Id\":1,\"Name\":\"Test\"}"));
|
||||
double match = matcher.IsMatch(JObject.Parse("{\"Id\":1,\"Name\":\"Test\"}")).Score;
|
||||
|
||||
// Assert
|
||||
Check.That(match).IsEqualTo(1);
|
||||
@@ -192,12 +193,184 @@ public class JsonPathMatcherTests
|
||||
public void JsonPathMatcher_IsMatch_RejectOnMatch()
|
||||
{
|
||||
// Arrange
|
||||
var matcher = new JsonPathMatcher(MatchBehaviour.RejectOnMatch, false, MatchOperator.Or, "$..[?(@.Id == 1)]");
|
||||
var matcher = new JsonPathMatcher(MatchBehaviour.RejectOnMatch, MatchOperator.Or, "$..[?(@.Id == 1)]");
|
||||
|
||||
// Act
|
||||
double match = matcher.IsMatch(JObject.Parse("{\"Id\":1,\"Name\":\"Test\"}"));
|
||||
double match = matcher.IsMatch(JObject.Parse("{\"Id\":1,\"Name\":\"Test\"}")).Score;
|
||||
|
||||
// Assert
|
||||
Check.That(match).IsEqualTo(0.0);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void JsonPathMatcher_IsMatch_ArrayOneLevel()
|
||||
{
|
||||
// Arrange
|
||||
var matcher = new JsonPathMatcher("$.arr[0].line1");
|
||||
|
||||
// Act
|
||||
double match = matcher.IsMatch(JObject.Parse(@"{
|
||||
""name"": ""PathSelectorTest"",
|
||||
""test"": ""test"",
|
||||
""test2"": ""test2"",
|
||||
""arr"": [{
|
||||
""line1"": ""line1"",
|
||||
}]
|
||||
}")).Score;
|
||||
|
||||
// Assert
|
||||
Check.That(match).IsEqualTo(1.0);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void JsonPathMatcher_IsMatch_ObjectMatch()
|
||||
{
|
||||
// Arrange
|
||||
var matcher = new JsonPathMatcher("$.test");
|
||||
|
||||
// Act
|
||||
double match = matcher.IsMatch(JObject.Parse(@"{
|
||||
""name"": ""PathSelectorTest"",
|
||||
""test"": ""test"",
|
||||
""test2"": ""test2"",
|
||||
""arr"": [
|
||||
{
|
||||
""line1"": ""line1"",
|
||||
}
|
||||
]
|
||||
}")).Score;
|
||||
|
||||
// Assert
|
||||
Check.That(match).IsEqualTo(1.0);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void JsonPathMatcher_IsMatch_DoesntMatch()
|
||||
{
|
||||
// Arrange
|
||||
var matcher = new JsonPathMatcher("$.test3");
|
||||
|
||||
// Act
|
||||
double match = matcher.IsMatch(JObject.Parse(@"{
|
||||
""name"": ""PathSelectorTest"",
|
||||
""test"": ""test"",
|
||||
""test2"": ""test2"",
|
||||
""arr"": [
|
||||
{
|
||||
""line1"": ""line1"",
|
||||
}
|
||||
]
|
||||
}")).Score;
|
||||
|
||||
// Assert
|
||||
Check.That(match).IsEqualTo(0.0);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void JsonPathMatcher_IsMatch_DoesntMatchInArray()
|
||||
{
|
||||
// Arrange
|
||||
var matcher = new JsonPathMatcher("$arr[0].line1");
|
||||
|
||||
// Act
|
||||
double match = matcher.IsMatch(JObject.Parse(@"{
|
||||
""name"": ""PathSelectorTest"",
|
||||
""test"": ""test"",
|
||||
""test2"": ""test2"",
|
||||
""arr"": []
|
||||
}")).Score;
|
||||
|
||||
// Assert
|
||||
Check.That(match).IsEqualTo(0.0);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void JsonPathMatcher_IsMatch_DoesntMatchNoObjectsInArray()
|
||||
{
|
||||
// Arrange
|
||||
var matcher = new JsonPathMatcher("$arr[2].line1");
|
||||
|
||||
// Act
|
||||
double match = matcher.IsMatch(JObject.Parse(@"{
|
||||
""name"": ""PathSelectorTest"",
|
||||
""test"": ""test"",
|
||||
""test2"": ""test2"",
|
||||
""arr"": []
|
||||
}")).Score;
|
||||
|
||||
// Assert
|
||||
Check.That(match).IsEqualTo(0.0);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void JsonPathMatcher_IsMatch_NestedArrays()
|
||||
{
|
||||
// Arrange
|
||||
var matcher = new JsonPathMatcher("$.arr[0].sub[0].subline1");
|
||||
|
||||
// Act
|
||||
double match = matcher.IsMatch(JObject.Parse(@"{
|
||||
""name"": ""PathSelectorTest"",
|
||||
""test"": ""test"",
|
||||
""test2"": ""test2"",
|
||||
""arr"": [{
|
||||
""line1"": ""line1"",
|
||||
""sub"":[
|
||||
{
|
||||
""subline1"":""subline1""
|
||||
}]
|
||||
}]
|
||||
}")).Score;
|
||||
|
||||
// Assert
|
||||
Check.That(match).IsEqualTo(1.0);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void JsonPathMatcher_IsMatch_MultiplePatternsUsingMatchOperatorAnd()
|
||||
{
|
||||
// Assign
|
||||
var matcher = new JsonPathMatcher(MatchBehaviour.AcceptOnMatch, MatchOperator.And, "$.arr[0].sub[0].subline1", "$.arr[0].line2");
|
||||
|
||||
// Act
|
||||
double match = matcher.IsMatch(JObject.Parse(@"{
|
||||
""name"": ""PathSelectorTest"",
|
||||
""test"": ""test"",
|
||||
""test2"": ""test2"",
|
||||
""arr"": [{
|
||||
""line1"": ""line1"",
|
||||
""sub"":[
|
||||
{
|
||||
""subline1"":""subline1""
|
||||
}]
|
||||
}]
|
||||
}")).Score;
|
||||
|
||||
// Assert
|
||||
match.Should().Be(0);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void JsonPathMatcher_IsMatch_MultiplePatternsUsingMatchOperatorOr()
|
||||
{
|
||||
// Assign
|
||||
var matcher = new JsonPathMatcher(MatchBehaviour.AcceptOnMatch, MatchOperator.Or, "$.arr[0].sub[0].subline2", "$.arr[0].line1");
|
||||
|
||||
// Act
|
||||
double match = matcher.IsMatch(JObject.Parse(@"{
|
||||
""name"": ""PathSelectorTest"",
|
||||
""test"": ""test"",
|
||||
""test2"": ""test2"",
|
||||
""arr"": [{
|
||||
""line1"": ""line1"",
|
||||
""sub"":[
|
||||
{
|
||||
""subline1"":""subline1""
|
||||
}]
|
||||
}]
|
||||
}")).Score;
|
||||
|
||||
// Assert
|
||||
match.Should().Be(1);
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
using FluentAssertions;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using NFluent;
|
||||
using WireMock.Matchers;
|
||||
@@ -17,7 +18,8 @@ public class LinqMatcherTests
|
||||
var matcher = new LinqMatcher("DateTime.Parse(it) > \"2018-08-01 13:50:00\"");
|
||||
|
||||
// Assert
|
||||
Check.That(matcher.IsMatch(input)).IsEqualTo(1.0d);
|
||||
var score = matcher.IsMatch(input).Score;
|
||||
score.Should().Be(MatchScores.Perfect);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -30,7 +32,8 @@ public class LinqMatcherTests
|
||||
var matcher = new LinqMatcher("DateTime.Parse(it) > \"2019-01-01 00:00:00\"");
|
||||
|
||||
// Assert
|
||||
Check.That(matcher.IsMatch(input)).IsEqualTo(0.0d);
|
||||
var score = matcher.IsMatch(input).Score;
|
||||
score.Should().Be(MatchScores.Mismatch);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -43,7 +46,8 @@ public class LinqMatcherTests
|
||||
var matcher = new LinqMatcher(MatchBehaviour.RejectOnMatch, "DateTime.Parse(it) > \"2018-08-01 13:50:00\"");
|
||||
|
||||
// Assert
|
||||
Check.That(matcher.IsMatch(input)).IsEqualTo(0.0d);
|
||||
var score = matcher.IsMatch(input).Score;
|
||||
score.Should().Be(MatchScores.Mismatch);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -58,7 +62,7 @@ public class LinqMatcherTests
|
||||
|
||||
// Act
|
||||
var matcher = new LinqMatcher("Id > 1 AND Name == \"Test\"");
|
||||
double match = matcher.IsMatch(input);
|
||||
double match = matcher.IsMatch(input).Score;
|
||||
|
||||
// Assert
|
||||
Assert.Equal(1.0, match);
|
||||
@@ -77,7 +81,7 @@ public class LinqMatcherTests
|
||||
|
||||
// Act
|
||||
var matcher = new LinqMatcher("IntegerId > 1 AND LongId > 1 && Name == \"Test\"");
|
||||
double match = matcher.IsMatch(input);
|
||||
double match = matcher.IsMatch(input).Score;
|
||||
|
||||
// Assert
|
||||
Assert.Equal(1.0, match);
|
||||
|
||||
@@ -55,7 +55,7 @@ AAAADElEQVR4XmMQYNgAAADkAMHebX3mAAAAAElFTkSuQmCC
|
||||
|
||||
// Assert
|
||||
matcher.Name.Should().Be("MimePartMatcher");
|
||||
result.Should().Be(MatchScores.Perfect);
|
||||
result.Score.Should().Be(MatchScores.Perfect);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -73,7 +73,7 @@ AAAADElEQVR4XmMQYNgAAADkAMHebX3mAAAAAElFTkSuQmCC
|
||||
var result = matcher.IsMatch(part);
|
||||
|
||||
// Assert
|
||||
result.Should().Be(MatchScores.Perfect);
|
||||
result.Score.Should().Be(MatchScores.Perfect);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -93,7 +93,7 @@ AAAADElEQVR4XmMQYNgAAADkAMHebX3mAAAAAElFTkSuQmCC
|
||||
var result = matcher.IsMatch(part);
|
||||
|
||||
// Assert
|
||||
result.Should().Be(MatchScores.Perfect);
|
||||
result.Score.Should().Be(MatchScores.Perfect);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -12,7 +12,7 @@ public class NotNullOrEmptyMatcherTests
|
||||
{
|
||||
// Act
|
||||
var matcher = new NotNullOrEmptyMatcher();
|
||||
string name = matcher.Name;
|
||||
var name = matcher.Name;
|
||||
|
||||
// Assert
|
||||
Check.That(name).Equals("NotNullOrEmptyMatcher");
|
||||
@@ -26,7 +26,7 @@ public class NotNullOrEmptyMatcherTests
|
||||
{
|
||||
// Act
|
||||
var matcher = new NotNullOrEmptyMatcher();
|
||||
double result = matcher.IsMatch(data);
|
||||
var result = matcher.IsMatch(data).Score;
|
||||
|
||||
// Assert
|
||||
result.Should().Be(expected);
|
||||
@@ -40,7 +40,7 @@ public class NotNullOrEmptyMatcherTests
|
||||
{
|
||||
// Act
|
||||
var matcher = new NotNullOrEmptyMatcher();
|
||||
double result = matcher.IsMatch(@string);
|
||||
var result = matcher.IsMatch(@string).Score;
|
||||
|
||||
// Assert
|
||||
result.Should().Be(expected);
|
||||
@@ -54,7 +54,7 @@ public class NotNullOrEmptyMatcherTests
|
||||
{
|
||||
// Act
|
||||
var matcher = new NotNullOrEmptyMatcher();
|
||||
double result = matcher.IsMatch((object)@string);
|
||||
var result = matcher.IsMatch((object)@string).Score;
|
||||
|
||||
// Assert
|
||||
result.Should().Be(expected);
|
||||
@@ -65,7 +65,7 @@ public class NotNullOrEmptyMatcherTests
|
||||
{
|
||||
// Act
|
||||
var matcher = new NotNullOrEmptyMatcher();
|
||||
double result = matcher.IsMatch(new { x = "x" });
|
||||
var result = matcher.IsMatch(new { x = "x" }).Score;
|
||||
|
||||
// Assert
|
||||
result.Should().Be(1.0);
|
||||
|
||||
@@ -53,7 +53,7 @@ public class RegexMatcherTests
|
||||
var matcher = new RegexMatcher("H.*o");
|
||||
|
||||
// Act
|
||||
double result = matcher.IsMatch("Hello world!");
|
||||
double result = matcher.IsMatch("Hello world!").Score;
|
||||
|
||||
// Assert
|
||||
Check.That(result).IsEqualTo(1.0d);
|
||||
@@ -66,7 +66,7 @@ public class RegexMatcherTests
|
||||
var matcher = new RegexMatcher("H.*o");
|
||||
|
||||
// Act
|
||||
double result = matcher.IsMatch(null);
|
||||
double result = matcher.IsMatch(null).Score;
|
||||
|
||||
// Assert
|
||||
Check.That(result).IsEqualTo(0.0d);
|
||||
@@ -79,7 +79,7 @@ public class RegexMatcherTests
|
||||
var matcher = new RegexMatcher(@"\GUIDB", true);
|
||||
|
||||
// Act
|
||||
double result = matcher.IsMatch(Guid.NewGuid().ToString("B"));
|
||||
double result = matcher.IsMatch(Guid.NewGuid().ToString("B")).Score;
|
||||
|
||||
// Assert
|
||||
result.Should().Be(1.0);
|
||||
@@ -89,10 +89,10 @@ public class RegexMatcherTests
|
||||
public void RegexMatcher_IsMatch_Regex_Guid()
|
||||
{
|
||||
// Assign
|
||||
var matcher = new RegexMatcher(@"\GUIDB", true, false, false);
|
||||
var matcher = new RegexMatcher(@"\GUIDB", true, false);
|
||||
|
||||
// Act
|
||||
double result = matcher.IsMatch(Guid.NewGuid().ToString("B"));
|
||||
double result = matcher.IsMatch(Guid.NewGuid().ToString("B")).Score;
|
||||
|
||||
// Assert
|
||||
result.Should().Be(0);
|
||||
@@ -105,7 +105,7 @@ public class RegexMatcherTests
|
||||
var matcher = new RegexMatcher("H.*o", true);
|
||||
|
||||
// Act
|
||||
double result = matcher.IsMatch("hello");
|
||||
double result = matcher.IsMatch("hello").Score;
|
||||
|
||||
// Assert
|
||||
Check.That(result).IsEqualTo(1.0d);
|
||||
@@ -118,7 +118,7 @@ public class RegexMatcherTests
|
||||
var matcher = new RegexMatcher(MatchBehaviour.RejectOnMatch, "h.*o");
|
||||
|
||||
// Act
|
||||
double result = matcher.IsMatch("hello");
|
||||
double result = matcher.IsMatch("hello").Score;
|
||||
|
||||
// Assert
|
||||
Check.That(result).IsEqualTo(0.0);
|
||||
|
||||
@@ -13,12 +13,12 @@ public class RequestMatchResultTests
|
||||
{
|
||||
// Arrange
|
||||
var result1 = new RequestMatchResult();
|
||||
result1.AddScore(typeof(WildcardMatcher), 1);
|
||||
result1.AddScore(typeof(WildcardMatcher), 0.9);
|
||||
result1.AddScore(typeof(WildcardMatcher), 1, null);
|
||||
result1.AddScore(typeof(WildcardMatcher), 0.9, null);
|
||||
|
||||
var result2 = new RequestMatchResult();
|
||||
result2.AddScore(typeof(LinqMatcher), 1);
|
||||
result2.AddScore(typeof(LinqMatcher), 1);
|
||||
result2.AddScore(typeof(LinqMatcher), 1, null);
|
||||
result2.AddScore(typeof(LinqMatcher), 1, null);
|
||||
|
||||
var results = new[] { result1, result2 };
|
||||
|
||||
@@ -34,13 +34,13 @@ public class RequestMatchResultTests
|
||||
{
|
||||
// Arrange
|
||||
var result1 = new RequestMatchResult();
|
||||
result1.AddScore(typeof(WildcardMatcher), 1);
|
||||
result1.AddScore(typeof(WildcardMatcher), 1);
|
||||
result1.AddScore(typeof(WildcardMatcher), 1, null);
|
||||
result1.AddScore(typeof(WildcardMatcher), 1, null);
|
||||
|
||||
var result2 = new RequestMatchResult();
|
||||
result2.AddScore(typeof(LinqMatcher), 1);
|
||||
result2.AddScore(typeof(LinqMatcher), 1);
|
||||
result2.AddScore(typeof(LinqMatcher), 1);
|
||||
result2.AddScore(typeof(LinqMatcher), 1, null);
|
||||
result2.AddScore(typeof(LinqMatcher), 1, null);
|
||||
result2.AddScore(typeof(LinqMatcher), 1, null);
|
||||
|
||||
var results = new[] { result1, result2 };
|
||||
|
||||
|
||||
@@ -39,7 +39,7 @@ public class SimMetricsMatcherTests
|
||||
var matcher = new SimMetricsMatcher("The cat walks in the street.");
|
||||
|
||||
// Act
|
||||
double result = matcher.IsMatch("The car drives in the street.");
|
||||
double result = matcher.IsMatch("The car drives in the street.").Score;
|
||||
|
||||
// Assert
|
||||
Check.That(result).IsStrictlyLessThan(1.0).And.IsStrictlyGreaterThan(0.5);
|
||||
@@ -52,7 +52,7 @@ public class SimMetricsMatcherTests
|
||||
var matcher = new SimMetricsMatcher("The cat walks in the street.");
|
||||
|
||||
// Act
|
||||
double result = matcher.IsMatch("Hello");
|
||||
double result = matcher.IsMatch("Hello").Score;
|
||||
|
||||
// Assert
|
||||
Check.That(result).IsStrictlyLessThan(0.1).And.IsStrictlyGreaterThan(0.05);
|
||||
@@ -65,7 +65,7 @@ public class SimMetricsMatcherTests
|
||||
var matcher = new SimMetricsMatcher("test");
|
||||
|
||||
// Act
|
||||
double result = matcher.IsMatch("test");
|
||||
double result = matcher.IsMatch("test").Score;
|
||||
|
||||
// Assert
|
||||
Check.That(result).IsEqualTo(1.0);
|
||||
@@ -78,7 +78,7 @@ public class SimMetricsMatcherTests
|
||||
var matcher = new SimMetricsMatcher(MatchBehaviour.RejectOnMatch, "test");
|
||||
|
||||
// Act
|
||||
double result = matcher.IsMatch("test");
|
||||
double result = matcher.IsMatch("test").Score;
|
||||
|
||||
// Assert
|
||||
Check.That(result).IsEqualTo(0.0);
|
||||
|
||||
@@ -19,11 +19,13 @@ public class WildcardMatcherTest
|
||||
PatternAsFile = "pf"
|
||||
};
|
||||
|
||||
// Act
|
||||
var matcher = new WildcardMatcher(pattern);
|
||||
|
||||
// Act
|
||||
var score = matcher.IsMatch("a").Score;
|
||||
|
||||
// Assert
|
||||
matcher.IsMatch("a").Should().Be(1.0d);
|
||||
score.Should().Be(1.0d);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -39,11 +41,13 @@ public class WildcardMatcherTest
|
||||
Pattern = "b"
|
||||
};
|
||||
|
||||
// Act
|
||||
var matcher = new WildcardMatcher(new [] { pattern1, pattern2 });
|
||||
|
||||
// Act
|
||||
var score = matcher.IsMatch("a").Score;
|
||||
|
||||
// Assert
|
||||
matcher.IsMatch("a").Should().Be(1.0d);
|
||||
score.Should().Be(1.0d);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -69,7 +73,12 @@ public class WildcardMatcherTest
|
||||
foreach (var test in tests)
|
||||
{
|
||||
var matcher = new WildcardMatcher(test.p);
|
||||
matcher.IsMatch(test.i).Should().Be(1.0d, $"Pattern '{test.p}' with value '{test.i}' should be 1.0");
|
||||
|
||||
// Act
|
||||
var score = matcher.IsMatch(test.i).Score;
|
||||
|
||||
// Assert
|
||||
score.Should().Be(MatchScores.Perfect, $"Pattern '{test.p}' with value '{test.i}' should be 1.0");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -94,7 +103,12 @@ public class WildcardMatcherTest
|
||||
foreach (var test in tests)
|
||||
{
|
||||
var matcher = new WildcardMatcher(test.p);
|
||||
Check.That(matcher.IsMatch(test.i)).IsEqualTo(0.0);
|
||||
|
||||
// Act
|
||||
var score = matcher.IsMatch(test.i).Score;
|
||||
|
||||
// Assert
|
||||
score.Should().Be(MatchScores.Mismatch);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -105,7 +119,7 @@ public class WildcardMatcherTest
|
||||
var matcher = new WildcardMatcher("x");
|
||||
|
||||
// Act
|
||||
string name = matcher.Name;
|
||||
var name = matcher.Name;
|
||||
|
||||
// Assert
|
||||
Check.That(name).Equals("WildcardMatcher");
|
||||
@@ -131,7 +145,7 @@ public class WildcardMatcherTest
|
||||
var matcher = new WildcardMatcher(MatchBehaviour.RejectOnMatch, "m");
|
||||
|
||||
// Act
|
||||
double result = matcher.IsMatch("m");
|
||||
var result = matcher.IsMatch("m").Score;
|
||||
|
||||
Check.That(result).IsEqualTo(0.0);
|
||||
}
|
||||
|
||||
@@ -43,7 +43,7 @@ public class XPathMatcherTests
|
||||
var matcher = new XPathMatcher("/todo-list[count(todo-item) = 1]");
|
||||
|
||||
// Act
|
||||
double result = matcher.IsMatch(xml);
|
||||
double result = matcher.IsMatch(xml).Score;
|
||||
|
||||
// Assert
|
||||
Check.That(result).IsEqualTo(1.0);
|
||||
@@ -57,10 +57,10 @@ public class XPathMatcherTests
|
||||
<todo-list>
|
||||
<todo-item id='a1'>abc</todo-item>
|
||||
</todo-list>";
|
||||
var matcher = new XPathMatcher(MatchBehaviour.RejectOnMatch, false, MatchOperator.Or, "/todo-list[count(todo-item) = 1]");
|
||||
var matcher = new XPathMatcher(MatchBehaviour.RejectOnMatch, MatchOperator.Or, "/todo-list[count(todo-item) = 1]");
|
||||
|
||||
// Act
|
||||
double result = matcher.IsMatch(xml);
|
||||
double result = matcher.IsMatch(xml).Score;
|
||||
|
||||
// Assert
|
||||
Check.That(result).IsEqualTo(0.0);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user