Fix WithBody when using Pact and added more nullable annotations (#783)

* More nullable annotations

* .

* .

* FIX

* pact

* .

* p

* xxx

* ...

* auth

* array

* ...
This commit is contained in:
Stef Heyenrath
2022-08-11 10:57:33 +02:00
committed by GitHub
parent b1af37f044
commit d2a1d0f069
87 changed files with 2578 additions and 2455 deletions

View File

@@ -1,18 +1,17 @@
namespace WireMock.Matchers.Request
namespace WireMock.Matchers.Request;
/// <summary>
/// CompositeMatcherType
/// </summary>
public enum CompositeMatcherType
{
/// <summary>
/// CompositeMatcherType
/// And
/// </summary>
public enum CompositeMatcherType
{
/// <summary>
/// And
/// </summary>
And = 0,
And = 0,
/// <summary>
/// Or
/// </summary>
Or = 1
}
/// <summary>
/// Or
/// </summary>
Or = 1
}

View File

@@ -1,57 +1,56 @@
using System;
using System;
using System.Collections.Generic;
using System.Linq;
namespace WireMock.Matchers.Request
namespace WireMock.Matchers.Request;
/// <summary>
/// RequestMatchResult
/// </summary>
public class RequestMatchResult : IRequestMatchResult
{
/// <inheritdoc cref="IRequestMatchResult.TotalScore" />
public double TotalScore => MatchDetails.Sum(md => md.Score);
/// <inheritdoc cref="IRequestMatchResult.TotalNumber" />
public int TotalNumber => MatchDetails.Count;
/// <inheritdoc cref="IRequestMatchResult.IsPerfectMatch" />
public bool IsPerfectMatch => Math.Abs(TotalScore - TotalNumber) < MatchScores.Tolerance;
/// <inheritdoc cref="IRequestMatchResult.AverageTotalScore" />
public double AverageTotalScore => TotalNumber == 0 ? 0.0 : TotalScore / TotalNumber;
/// <inheritdoc cref="IRequestMatchResult.MatchDetails" />
public IList<MatchDetail> MatchDetails { get; } = new List<MatchDetail>();
/// <summary>
/// RequestMatchResult
/// Adds the score.
/// </summary>
public class RequestMatchResult : IRequestMatchResult
/// <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 cref="IRequestMatchResult.TotalScore" />
public double TotalScore => MatchDetails.Sum(md => md.Score);
MatchDetails.Add(new MatchDetail { MatcherType = matcherType, Score = score });
/// <inheritdoc cref="IRequestMatchResult.TotalNumber" />
public int TotalNumber => MatchDetails.Count;
return score;
}
/// <inheritdoc cref="IRequestMatchResult.IsPerfectMatch" />
public bool IsPerfectMatch => Math.Abs(TotalScore - TotalNumber) < MatchScores.Tolerance;
/// <summary>
/// Compares the current instance with another object of the same type and returns an integer that indicates whether the current instance precedes, follows, or occurs in the same position in the sort order as the other object.
/// </summary>
/// <param name="obj">An object to compare with this instance.</param>
/// <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)
{
var compareObj = (RequestMatchResult)obj;
/// <inheritdoc cref="IRequestMatchResult.AverageTotalScore" />
public double AverageTotalScore => TotalNumber == 0 ? 0.0 : TotalScore / TotalNumber;
int averageTotalScoreResult = compareObj.AverageTotalScore.CompareTo(AverageTotalScore);
/// <inheritdoc cref="IRequestMatchResult.MatchDetails" />
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)
{
MatchDetails.Add(new MatchDetail { MatcherType = matcherType, Score = score });
return score;
}
/// <summary>
/// Compares the current instance with another object of the same type and returns an integer that indicates whether the current instance precedes, follows, or occurs in the same position in the sort order as the other object.
/// </summary>
/// <param name="obj">An object to compare with this instance.</param>
/// <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)
{
var compareObj = (RequestMatchResult)obj;
int 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;
}
// In case the score is equal, prefer the one with the most matchers.
return averageTotalScoreResult == 0 ? compareObj.TotalNumber.CompareTo(TotalNumber) : averageTotalScoreResult;
}
}

View File

@@ -3,50 +3,49 @@ using System.Linq;
using JetBrains.Annotations;
using Stef.Validation;
namespace WireMock.Matchers.Request
namespace WireMock.Matchers.Request;
/// <summary>
/// The composite request matcher.
/// </summary>
public abstract class RequestMessageCompositeMatcher : IRequestMatcher
{
private readonly CompositeMatcherType _type;
/// <summary>
/// The composite request matcher.
/// Gets the request matchers.
/// </summary>
public abstract class RequestMessageCompositeMatcher : IRequestMatcher
/// <value>
/// The request matchers.
/// </value>
private IEnumerable<IRequestMatcher> RequestMatchers { get; }
/// <summary>
/// Initializes a new instance of the <see cref="RequestMessageCompositeMatcher"/> class.
/// </summary>
/// <param name="requestMatchers">The request matchers.</param>
/// <param name="type">The CompositeMatcherType type (Defaults to 'And')</param>
protected RequestMessageCompositeMatcher([NotNull] IEnumerable<IRequestMatcher> requestMatchers, CompositeMatcherType type = CompositeMatcherType.And)
{
private readonly CompositeMatcherType _type;
Guard.NotNull(requestMatchers, nameof(requestMatchers));
/// <summary>
/// Gets the request matchers.
/// </summary>
/// <value>
/// The request matchers.
/// </value>
private IEnumerable<IRequestMatcher> RequestMatchers { get; }
_type = type;
RequestMatchers = requestMatchers;
}
/// <summary>
/// Initializes a new instance of the <see cref="RequestMessageCompositeMatcher"/> class.
/// </summary>
/// <param name="requestMatchers">The request matchers.</param>
/// <param name="type">The CompositeMatcherType type (Defaults to 'And')</param>
protected RequestMessageCompositeMatcher([NotNull] IEnumerable<IRequestMatcher> requestMatchers, CompositeMatcherType type = CompositeMatcherType.And)
/// <inheritdoc />
public double GetMatchingScore(IRequestMessage requestMessage, IRequestMatchResult requestMatchResult)
{
if (!RequestMatchers.Any())
{
Guard.NotNull(requestMatchers, nameof(requestMatchers));
_type = type;
RequestMatchers = requestMatchers;
return MatchScores.Mismatch;
}
/// <inheritdoc />
public double GetMatchingScore(IRequestMessage requestMessage, IRequestMatchResult requestMatchResult)
if (_type == CompositeMatcherType.And)
{
if (!RequestMatchers.Any())
{
return MatchScores.Mismatch;
}
if (_type == CompositeMatcherType.And)
{
return RequestMatchers.Average(requestMatcher => requestMatcher.GetMatchingScore(requestMessage, requestMatchResult));
}
return RequestMatchers.Max(requestMatcher => requestMatcher.GetMatchingScore(requestMessage, requestMatchResult));
return RequestMatchers.Average(requestMatcher => requestMatcher.GetMatchingScore(requestMessage, requestMatchResult));
}
return RequestMatchers.Max(requestMatcher => requestMatcher.GetMatchingScore(requestMessage, requestMatchResult));
}
}

View File

@@ -4,126 +4,125 @@ using System.Linq;
using JetBrains.Annotations;
using Stef.Validation;
namespace WireMock.Matchers.Request
namespace WireMock.Matchers.Request;
/// <summary>
/// The request cookie matcher.
/// </summary>
/// <inheritdoc cref="IRequestMatcher"/>
public class RequestMessageCookieMatcher : IRequestMatcher
{
private readonly MatchBehaviour _matchBehaviour;
private readonly bool _ignoreCase;
/// <summary>
/// The request cookie matcher.
/// The functions
/// </summary>
/// <inheritdoc cref="IRequestMatcher"/>
public class RequestMessageCookieMatcher : IRequestMatcher
public Func<IDictionary<string, string>, bool>[] Funcs { get; }
/// <summary>
/// The name
/// </summary>
public string Name { get; }
/// <value>
/// The matchers.
/// </value>
public IStringMatcher[] Matchers { get; }
/// <summary>
/// Initializes a new instance of the <see cref="RequestMessageCookieMatcher"/> class.
/// </summary>
/// <param name="name">The name.</param>
/// <param name="pattern">The pattern.</param>
/// <param name="ignoreCase">Ignore the case from the pattern.</param>
/// <param name="matchBehaviour">The match behaviour.</param>
public RequestMessageCookieMatcher(MatchBehaviour matchBehaviour, [NotNull] string name, [NotNull] string pattern, bool ignoreCase)
{
private readonly MatchBehaviour _matchBehaviour;
private readonly bool _ignoreCase;
Guard.NotNull(name, nameof(name));
Guard.NotNull(pattern, nameof(pattern));
/// <summary>
/// The functions
/// </summary>
public Func<IDictionary<string, string>, bool>[] Funcs { get; }
_matchBehaviour = matchBehaviour;
_ignoreCase = ignoreCase;
Name = name;
Matchers = new IStringMatcher[] { new WildcardMatcher(matchBehaviour, pattern, ignoreCase) };
}
/// <summary>
/// The name
/// </summary>
public string Name { get; }
/// <summary>
/// Initializes a new instance of the <see cref="RequestMessageCookieMatcher"/> class.
/// </summary>
/// <param name="matchBehaviour">The match behaviour.</param>
/// <param name="name">The name.</param>
/// <param name="patterns">The patterns.</param>
/// <param name="ignoreCase">Ignore the case from the pattern.</param>
public RequestMessageCookieMatcher(MatchBehaviour matchBehaviour, [NotNull] string name, bool ignoreCase, [NotNull] params string[] patterns) :
this(matchBehaviour, name, ignoreCase, patterns.Select(pattern => new WildcardMatcher(matchBehaviour, pattern, ignoreCase)).Cast<IStringMatcher>().ToArray())
{
Guard.NotNull(patterns, nameof(patterns));
}
/// <value>
/// The matchers.
/// </value>
public IStringMatcher[] Matchers { get; }
/// <summary>
/// Initializes a new instance of the <see cref="RequestMessageCookieMatcher"/> class.
/// </summary>
/// <param name="matchBehaviour">The match behaviour.</param>
/// <param name="name">The name.</param>
/// <param name="matchers">The matchers.</param>
/// <param name="ignoreCase">Ignore the case from the pattern.</param>
public RequestMessageCookieMatcher(MatchBehaviour matchBehaviour, [NotNull] string name, bool ignoreCase, [NotNull] params IStringMatcher[] matchers)
{
Guard.NotNull(name, nameof(name));
Guard.NotNull(matchers, nameof(matchers));
/// <summary>
/// Initializes a new instance of the <see cref="RequestMessageCookieMatcher"/> class.
/// </summary>
/// <param name="name">The name.</param>
/// <param name="pattern">The pattern.</param>
/// <param name="ignoreCase">Ignore the case from the pattern.</param>
/// <param name="matchBehaviour">The match behaviour.</param>
public RequestMessageCookieMatcher(MatchBehaviour matchBehaviour, [NotNull] string name, [NotNull] string pattern, bool ignoreCase)
_matchBehaviour = matchBehaviour;
Name = name;
Matchers = matchers;
_ignoreCase = ignoreCase;
}
/// <summary>
/// Initializes a new instance of the <see cref="RequestMessageCookieMatcher"/> class.
/// </summary>
/// <param name="funcs">The funcs.</param>
public RequestMessageCookieMatcher([NotNull] params Func<IDictionary<string, string>, bool>[] funcs)
{
Guard.NotNull(funcs, nameof(funcs));
Funcs = funcs;
}
/// <inheritdoc />
public double GetMatchingScore(IRequestMessage requestMessage, IRequestMatchResult requestMatchResult)
{
double score = IsMatch(requestMessage);
return requestMatchResult.AddScore(GetType(), score);
}
private double IsMatch(IRequestMessage requestMessage)
{
if (requestMessage.Cookies == null)
{
Guard.NotNull(name, nameof(name));
Guard.NotNull(pattern, nameof(pattern));
_matchBehaviour = matchBehaviour;
_ignoreCase = ignoreCase;
Name = name;
Matchers = new IStringMatcher[] { new WildcardMatcher(matchBehaviour, pattern, ignoreCase) };
return MatchBehaviourHelper.Convert(_matchBehaviour, MatchScores.Mismatch);
}
/// <summary>
/// Initializes a new instance of the <see cref="RequestMessageCookieMatcher"/> class.
/// </summary>
/// <param name="matchBehaviour">The match behaviour.</param>
/// <param name="name">The name.</param>
/// <param name="patterns">The patterns.</param>
/// <param name="ignoreCase">Ignore the case from the pattern.</param>
public RequestMessageCookieMatcher(MatchBehaviour matchBehaviour, [NotNull] string name, bool ignoreCase, [NotNull] params string[] patterns) :
this(matchBehaviour, name, ignoreCase, patterns.Select(pattern => new WildcardMatcher(matchBehaviour, pattern, ignoreCase)).Cast<IStringMatcher>().ToArray())
// Check if we want to use IgnoreCase to compare the Cookie-Name and Cookie-Value
var cookies = !_ignoreCase ? requestMessage.Cookies : new Dictionary<string, string>(requestMessage.Cookies, StringComparer.OrdinalIgnoreCase);
if (Funcs != null)
{
Guard.NotNull(patterns, nameof(patterns));
return MatchScores.ToScore(Funcs.Any(f => f(cookies)));
}
/// <summary>
/// Initializes a new instance of the <see cref="RequestMessageCookieMatcher"/> class.
/// </summary>
/// <param name="matchBehaviour">The match behaviour.</param>
/// <param name="name">The name.</param>
/// <param name="matchers">The matchers.</param>
/// <param name="ignoreCase">Ignore the case from the pattern.</param>
public RequestMessageCookieMatcher(MatchBehaviour matchBehaviour, [NotNull] string name, bool ignoreCase, [NotNull] params IStringMatcher[] matchers)
if (Matchers == null)
{
Guard.NotNull(name, nameof(name));
Guard.NotNull(matchers, nameof(matchers));
_matchBehaviour = matchBehaviour;
Name = name;
Matchers = matchers;
_ignoreCase = ignoreCase;
return MatchScores.Mismatch;
}
/// <summary>
/// Initializes a new instance of the <see cref="RequestMessageCookieMatcher"/> class.
/// </summary>
/// <param name="funcs">The funcs.</param>
public RequestMessageCookieMatcher([NotNull] params Func<IDictionary<string, string>, bool>[] funcs)
if (!cookies.ContainsKey(Name))
{
Guard.NotNull(funcs, nameof(funcs));
Funcs = funcs;
return MatchBehaviourHelper.Convert(_matchBehaviour, MatchScores.Mismatch);
}
/// <inheritdoc />
public double GetMatchingScore(IRequestMessage requestMessage, IRequestMatchResult requestMatchResult)
{
double score = IsMatch(requestMessage);
return requestMatchResult.AddScore(GetType(), score);
}
private double IsMatch(IRequestMessage requestMessage)
{
if (requestMessage.Cookies == null)
{
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);
if (Funcs != null)
{
return MatchScores.ToScore(Funcs.Any(f => f(cookies)));
}
if (Matchers == null)
{
return MatchScores.Mismatch;
}
if (!cookies.ContainsKey(Name))
{
return MatchBehaviourHelper.Convert(_matchBehaviour, MatchScores.Mismatch);
}
string value = cookies[Name];
return Matchers.Max(m => m.IsMatch(value));
}
string value = cookies[Name];
return Matchers.Max(m => m.IsMatch(value));
}
}