mirror of
https://github.com/wiremock/WireMock.Net.git
synced 2026-04-01 07:03:29 +02:00
mm
This commit is contained in:
@@ -68,7 +68,7 @@ public class ExactObjectMatcher : IObjectMatcher
|
||||
equals = Equals(Value, input);
|
||||
}
|
||||
|
||||
return MatchBehaviourHelper.Convert(MatchBehaviour, MatchScores.ToScore(equals));
|
||||
return MatchResult.From(Name, MatchBehaviourHelper.Convert(MatchBehaviour, MatchScores.ToScore(equals)));
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
|
||||
@@ -8,66 +8,68 @@ namespace WireMock.Matchers.Helpers;
|
||||
|
||||
internal static class BodyDataMatchScoreCalculator
|
||||
{
|
||||
internal static MatchResult CalculateMatchScore(IBodyData? requestMessage, IMatcher matcher)
|
||||
private static string _name = nameof(BodyDataMatchScoreCalculator);
|
||||
|
||||
internal static MatchResult CalculateMatchScore(IBodyData? bodyData, IMatcher matcher)
|
||||
{
|
||||
Guard.NotNull(matcher);
|
||||
|
||||
if (requestMessage == null)
|
||||
if (bodyData == null)
|
||||
{
|
||||
return default;
|
||||
return MatchResult.From(_name);
|
||||
}
|
||||
|
||||
if (matcher is NotNullOrEmptyMatcher notNullOrEmptyMatcher)
|
||||
{
|
||||
switch (requestMessage.DetectedBodyType)
|
||||
switch (bodyData.DetectedBodyType)
|
||||
{
|
||||
case BodyType.Json:
|
||||
case BodyType.String:
|
||||
case BodyType.FormUrlEncoded:
|
||||
return notNullOrEmptyMatcher.IsMatch(requestMessage.BodyAsString);
|
||||
return notNullOrEmptyMatcher.IsMatch(bodyData.BodyAsString);
|
||||
|
||||
case BodyType.Bytes:
|
||||
return notNullOrEmptyMatcher.IsMatch(requestMessage.BodyAsBytes);
|
||||
return notNullOrEmptyMatcher.IsMatch(bodyData.BodyAsBytes);
|
||||
|
||||
default:
|
||||
return default;
|
||||
return MatchResult.From(_name);
|
||||
}
|
||||
}
|
||||
|
||||
if (matcher is ExactObjectMatcher { Value: byte[] } exactObjectMatcher)
|
||||
{
|
||||
// If the body is a byte array, try to match.
|
||||
return exactObjectMatcher.IsMatch(requestMessage.BodyAsBytes);
|
||||
return exactObjectMatcher.IsMatch(bodyData.BodyAsBytes);
|
||||
}
|
||||
|
||||
// Check if the matcher is a IObjectMatcher
|
||||
if (matcher is IObjectMatcher objectMatcher)
|
||||
{
|
||||
// If the body is a JSON object, try to match.
|
||||
if (requestMessage.DetectedBodyType == BodyType.Json)
|
||||
if (bodyData.DetectedBodyType == BodyType.Json)
|
||||
{
|
||||
return objectMatcher.IsMatch(requestMessage.BodyAsJson);
|
||||
return objectMatcher.IsMatch(bodyData.BodyAsJson);
|
||||
}
|
||||
|
||||
// If the body is a byte array, try to match.
|
||||
if (requestMessage.DetectedBodyType == BodyType.Bytes)
|
||||
if (bodyData.DetectedBodyType == BodyType.Bytes)
|
||||
{
|
||||
return objectMatcher.IsMatch(requestMessage.BodyAsBytes);
|
||||
return objectMatcher.IsMatch(bodyData.BodyAsBytes);
|
||||
}
|
||||
}
|
||||
|
||||
// In case the matcher is a IStringMatcher and If body is a Json or a String, use the BodyAsString to match on.
|
||||
if (matcher is IStringMatcher stringMatcher && requestMessage.DetectedBodyType is BodyType.Json or BodyType.String or BodyType.FormUrlEncoded)
|
||||
// In case the matcher is a IStringMatcher and if body is a Json or a String, use the BodyAsString to match on.
|
||||
if (matcher is IStringMatcher stringMatcher && bodyData.DetectedBodyType is BodyType.Json or BodyType.String or BodyType.FormUrlEncoded)
|
||||
{
|
||||
return stringMatcher.IsMatch(requestMessage.BodyAsString);
|
||||
return stringMatcher.IsMatch(bodyData.BodyAsString);
|
||||
}
|
||||
|
||||
// In case the matcher is a IProtoBufMatcher, use the BodyAsBytes to match on.
|
||||
if (matcher is IProtoBufMatcher protoBufMatcher)
|
||||
{
|
||||
return protoBufMatcher.IsMatchAsync(requestMessage.BodyAsBytes).GetAwaiter().GetResult();
|
||||
return protoBufMatcher.IsMatchAsync(bodyData.BodyAsBytes).GetAwaiter().GetResult();
|
||||
}
|
||||
|
||||
return default;
|
||||
return MatchResult.From(_name);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -36,6 +36,6 @@ internal static class MatchBehaviourHelper
|
||||
/// <returns>match result</returns>
|
||||
internal static MatchResult Convert(MatchBehaviour matchBehaviour, MatchResult result)
|
||||
{
|
||||
return matchBehaviour == MatchBehaviour.AcceptOnMatch ? result : new MatchResult(Convert(matchBehaviour, result.Score), result.Exception);
|
||||
return matchBehaviour == MatchBehaviour.AcceptOnMatch ? result : MatchResult.From(result.Name, Convert(matchBehaviour, result.Score), result.Exception);
|
||||
}
|
||||
}
|
||||
@@ -5,13 +5,14 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Stef.Validation;
|
||||
using WireMock.Extensions;
|
||||
using WireMock.Matchers.Request;
|
||||
|
||||
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
|
||||
public class MatchResult
|
||||
{
|
||||
/// <summary>
|
||||
/// A value between 0.0 - 1.0 of the similarity.
|
||||
@@ -25,46 +26,55 @@ public struct MatchResult
|
||||
public Exception? Exception { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Create a MatchResult
|
||||
/// The name or description of the matcher.
|
||||
/// </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;
|
||||
}
|
||||
public required string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Create a MatchResult
|
||||
/// The child MatchResults in case of multiple matchers.
|
||||
/// </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);
|
||||
}
|
||||
public MatchResult[]? MatchResults { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Is the value a perfect match?
|
||||
/// </summary>
|
||||
public bool IsPerfect() => MatchScores.IsPerfect(Score);
|
||||
|
||||
/// <summary>
|
||||
/// Create a MatchResult.
|
||||
/// </summary>
|
||||
/// <param name="name">The name or description of the matcher.</param>
|
||||
/// <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 static MatchResult From(string name, double score = 0, Exception? exception = null)
|
||||
{
|
||||
return new MatchResult
|
||||
{
|
||||
Name = name,
|
||||
Score = score,
|
||||
Exception = exception
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create a MatchResult from exception.
|
||||
/// </summary>
|
||||
/// <param name="name">The name or description of the matcher.</param>
|
||||
/// <param name="exception">The exception in case the matching fails.</param>
|
||||
/// <returns>MatchResult</returns>
|
||||
public static MatchResult From(string name, Exception exception)
|
||||
{
|
||||
return From(name, MatchScores.Mismatch, exception);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create a MatchResult from multiple MatchResults.
|
||||
/// </summary>
|
||||
/// <param name="name">The name or description of the matcher.</param>
|
||||
/// <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)
|
||||
public static MatchResult From(string name, IReadOnlyList<MatchResult> matchResults, MatchOperator matchOperator)
|
||||
{
|
||||
Guard.NotNullOrEmpty(matchResults);
|
||||
|
||||
@@ -75,6 +85,8 @@ public struct MatchResult
|
||||
|
||||
return new MatchResult
|
||||
{
|
||||
Name = name,
|
||||
MatchResults = matchResults.ToArray(),
|
||||
Score = MatchScores.ToScore(matchResults.Select(r => r.Score).ToArray(), matchOperator),
|
||||
Exception = matchResults.Select(m => m.Exception).OfType<Exception>().ToArray().ToException()
|
||||
};
|
||||
@@ -88,4 +100,19 @@ public struct MatchResult
|
||||
{
|
||||
return (Score, Exception);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert to <see cref="MatchResult"/>.
|
||||
/// </summary>
|
||||
public MatchDetail ToMatchDetail()
|
||||
{
|
||||
return new MatchDetail
|
||||
{
|
||||
Name = Name,
|
||||
MatcherType = typeof(MatchResult),
|
||||
Score = Score,
|
||||
Exception = Exception,
|
||||
MatchDetails = MatchResults?.Select(mr => mr.ToMatchDetail()).ToArray()
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,5 @@
|
||||
// Copyright © WireMock.Net
|
||||
|
||||
using System;
|
||||
using System.Linq;
|
||||
using AnyOfTypes;
|
||||
using WireMock.Extensions;
|
||||
@@ -53,7 +52,7 @@ public class NotNullOrEmptyMatcher : IObjectMatcher, IStringMatcher
|
||||
break;
|
||||
}
|
||||
|
||||
return MatchBehaviourHelper.Convert(MatchBehaviour, MatchScores.ToScore(match));
|
||||
return MatchResult.From(Name, MatchBehaviourHelper.Convert(MatchBehaviour, MatchScores.ToScore(match)));
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
@@ -61,7 +60,7 @@ public class NotNullOrEmptyMatcher : IObjectMatcher, IStringMatcher
|
||||
{
|
||||
var match = !string.IsNullOrEmpty(input);
|
||||
|
||||
return MatchBehaviourHelper.Convert(MatchBehaviour, MatchScores.ToScore(match));
|
||||
return MatchResult.From(Name, MatchBehaviourHelper.Convert(MatchBehaviour, MatchScores.ToScore(match)));
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
|
||||
@@ -111,7 +111,7 @@ public class RegexMatcher : IStringMatcher, IIgnoreCaseMatcher
|
||||
}
|
||||
}
|
||||
|
||||
return new MatchResult(MatchBehaviourHelper.Convert(MatchBehaviour, score), exception);
|
||||
return MatchResult.From(Name, MatchBehaviourHelper.Convert(MatchBehaviour, score), exception);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
|
||||
@@ -73,7 +73,7 @@ public class RequestMessageGraphQLMatcher : IRequestMatcher
|
||||
public double GetMatchingScore(IRequestMessage requestMessage, IRequestMatchResult requestMatchResult)
|
||||
{
|
||||
var results = CalculateMatchResults(requestMessage);
|
||||
var (score, exception) = MatchResult.From(results, MatchOperator).Expand();
|
||||
var (score, exception) = MatchResult.From(nameof(RequestMessageGraphQLMatcher), results, MatchOperator).Expand();
|
||||
|
||||
return requestMatchResult.AddScore(GetType(), score, exception);
|
||||
}
|
||||
@@ -86,12 +86,12 @@ public class RequestMessageGraphQLMatcher : IRequestMatcher
|
||||
return stringMatcher.IsMatch(requestMessage.BodyData.BodyAsString);
|
||||
}
|
||||
|
||||
return default;
|
||||
return MatchResult.From(nameof(RequestMessageGraphQLMatcher));
|
||||
}
|
||||
|
||||
private IReadOnlyList<MatchResult> CalculateMatchResults(IRequestMessage requestMessage)
|
||||
{
|
||||
return Matchers == null ? [new MatchResult()] : Matchers.Select(matcher => CalculateMatchResult(requestMessage, matcher)).ToArray();
|
||||
return Matchers == null ? [MatchResult.From(nameof(RequestMessageGraphQLMatcher))] : Matchers.Select(matcher => CalculateMatchResult(requestMessage, matcher)).ToArray();
|
||||
}
|
||||
|
||||
private static IMatcher[] CreateMatcherArray(
|
||||
|
||||
@@ -23,7 +23,7 @@ public interface IMultiPartRequestBuilder : IHttpVersionBuilder
|
||||
/// <param name="matchBehaviour">The <see cref="MatchBehaviour"/> to use.</param>
|
||||
/// <param name="matchOperator">The <see cref="MatchOperator"/> to use.</param>
|
||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||
IRequestBuilder WithMultiPart(IMatcher[] matchers, MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch, MatchOperator matchOperator = MatchOperator.Or);
|
||||
IRequestBuilder WithMultiPart(IMatcher[] matchers, MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch, MatchOperator matchOperator = MatchOperator.And);
|
||||
|
||||
/// <summary>
|
||||
/// WithMultiPart: MatchBehaviour and IMatcher[]
|
||||
|
||||
Reference in New Issue
Block a user