Update MappingConverter to correctly write the Matcher as C# code (#1152)

* Update MappingConverter to correctly write the Matcher as C# code

* .

* CSharpCodeMatcher

* tests

* .
This commit is contained in:
Stef Heyenrath
2024-08-27 19:38:07 +02:00
committed by GitHub
parent 95573eeb96
commit da100298c1
41 changed files with 709 additions and 158 deletions

View File

@@ -33,6 +33,7 @@
<s:Boolean x:Key="/Default/UserDictionary/Words/=Guids/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Heyenrath/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Jmes/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Levenstein/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=openapi/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Pacticipant/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=protobuf/@EntryIndexedValue">True</s:Boolean>

View File

@@ -10,6 +10,7 @@ using Stef.Validation;
using WireMock.Exceptions;
using WireMock.Extensions;
using WireMock.Models;
using WireMock.Util;
namespace WireMock.Matchers;
@@ -92,6 +93,17 @@ internal class CSharpCodeMatcher : ICSharpCodeMatcher
return new MatchResult(MatchBehaviourHelper.Convert(MatchBehaviour, score), exception);
}
/// <inheritdoc />
public string GetCSharpCodeArguments()
{
return $"new {Name}" +
$"(" +
$"{MatchBehaviour.GetFullyQualifiedEnumValue()}, " +
$"{MatchOperator.GetFullyQualifiedEnumValue()}, " +
$"{MappingConverterUtils.ToCSharpCodeArguments(_patterns)}" +
$")";
}
private bool IsMatch(dynamic input, string pattern)
{
var isMatchWithString = input is string;

View File

@@ -42,7 +42,7 @@ internal class AzureADAuthenticationMatcher : IStringMatcher
return EmptyArray<AnyOf<string, StringPattern>>.Value;
}
public MatchOperator MatchOperator { get; } = MatchOperator.Or;
public MatchOperator MatchOperator => MatchOperator.Or;
public MatchResult IsMatch(string? input)
{
@@ -76,5 +76,11 @@ internal class AzureADAuthenticationMatcher : IStringMatcher
return new MatchResult(MatchScores.Mismatch, ex);
}
}
/// <inheritdoc />
public virtual string GetCSharpCodeArguments()
{
throw new NotImplementedException();
}
}
#endif

View File

@@ -130,7 +130,10 @@ public class MappingBuilder : IMappingBuilder
private IMapping[] GetNonAdminMappings()
{
return _options.Mappings.Values.Where(m => !m.IsAdminInterface).OrderBy(m => m.UpdatedAt).ToArray();
return _options.Mappings.Values
.Where(m => !m.IsAdminInterface)
.OrderBy(m => m.Guid)
.ToArray();
}
private void RegisterMapping(IMapping mapping, bool saveToFile)

View File

@@ -2,7 +2,10 @@
using System.Net.Http.Headers;
using AnyOfTypes;
using Stef.Validation;
using WireMock.Extensions;
using WireMock.Models;
using WireMock.Util;
namespace WireMock.Matchers;
@@ -19,7 +22,7 @@ public class ContentTypeMatcher : WildcardMatcher
/// </summary>
/// <param name="pattern">The pattern.</param>
/// <param name="ignoreCase">IgnoreCase (default false)</param>
public ContentTypeMatcher(AnyOf<string, StringPattern> pattern, bool ignoreCase = false) : this(new[] { pattern }, ignoreCase)
public ContentTypeMatcher(AnyOf<string, StringPattern> pattern, bool ignoreCase = false) : this([pattern], ignoreCase)
{
}
@@ -29,7 +32,8 @@ public class ContentTypeMatcher : WildcardMatcher
/// <param name="matchBehaviour">The match behaviour.</param>
/// <param name="pattern">The pattern.</param>
/// <param name="ignoreCase">IgnoreCase (default false)</param>
public ContentTypeMatcher(MatchBehaviour matchBehaviour, AnyOf<string, StringPattern> pattern, bool ignoreCase = false) : this(matchBehaviour, new[] { pattern }, ignoreCase)
public ContentTypeMatcher(MatchBehaviour matchBehaviour, AnyOf<string, StringPattern> pattern, bool ignoreCase = false) : this(matchBehaviour,
[pattern], ignoreCase)
{
}
@@ -50,7 +54,7 @@ public class ContentTypeMatcher : WildcardMatcher
/// <param name="ignoreCase">IgnoreCase (default false)</param>
public ContentTypeMatcher(MatchBehaviour matchBehaviour, AnyOf<string, StringPattern>[] patterns, bool ignoreCase = false) : base(matchBehaviour, patterns, ignoreCase)
{
_patterns = patterns;
_patterns = Guard.NotNull(patterns);
}
/// <inheritdoc />
@@ -72,4 +76,15 @@ public class ContentTypeMatcher : WildcardMatcher
/// <inheritdoc />
public override string Name => nameof(ContentTypeMatcher);
/// <inheritdoc />
public override string GetCSharpCodeArguments()
{
return $"new {Name}" +
$"(" +
$"{MatchBehaviour.GetFullyQualifiedEnumValue()}, " +
$"{MappingConverterUtils.ToCSharpCodeArguments(_patterns)}, " +
$"{CSharpFormatter.ToCSharpBooleanLiteral(IgnoreCase)}" +
$")";
}
}

View File

@@ -4,7 +4,9 @@ using System;
using System.Linq;
using AnyOfTypes;
using Stef.Validation;
using WireMock.Extensions;
using WireMock.Models;
using WireMock.Util;
namespace WireMock.Matchers;
@@ -86,8 +88,20 @@ public class ExactMatcher : IStringMatcher, IIgnoreCaseMatcher
public MatchOperator MatchOperator { get; }
/// <inheritdoc />
public string Name => "ExactMatcher";
public string Name => nameof(ExactMatcher);
/// <inheritdoc />
public bool IgnoreCase { get; }
/// <inheritdoc />
public string GetCSharpCodeArguments()
{
return $"new {Name}" +
$"(" +
$"{MatchBehaviour.GetFullyQualifiedEnumValue()}, " +
$"{CSharpFormatter.ToCSharpBooleanLiteral(IgnoreCase)}, " +
$"{MatchOperator.GetFullyQualifiedEnumValue()}, " +
$"{MappingConverterUtils.ToCSharpCodeArguments(_values)}" +
$")";
}
}

View File

@@ -72,5 +72,11 @@ public class ExactObjectMatcher : IObjectMatcher
}
/// <inheritdoc />
public string Name => "ExactObjectMatcher";
public string Name => nameof(ExactObjectMatcher);
/// <inheritdoc />
public string GetCSharpCodeArguments()
{
return "NotImplemented";
}
}

View File

@@ -4,6 +4,7 @@ using System.Collections.Generic;
using System.Linq;
using AnyOfTypes;
using Stef.Validation;
using WireMock.Extensions;
using WireMock.Models;
using WireMock.Util;
@@ -163,4 +164,16 @@ public class FormUrlEncodedMatcher : IStringMatcher, IIgnoreCaseMatcher
/// <inheritdoc />
public MatchOperator MatchOperator { get; }
/// <inheritdoc />
public string GetCSharpCodeArguments()
{
return $"new {Name}" +
$"(" +
$"{MatchBehaviour.GetFullyQualifiedEnumValue()}, " +
$"{MappingConverterUtils.ToCSharpCodeArguments(_patterns)}, " +
$"{CSharpFormatter.ToCSharpBooleanLiteral(IgnoreCase)}, " +
$"{MatchOperator.GetFullyQualifiedEnumValue()}" +
$")";
}
}

View File

@@ -156,6 +156,12 @@ public class GraphQLMatcher : IStringMatcher
/// <inheritdoc />
public string Name => nameof(GraphQLMatcher);
/// <inheritdoc />
public string GetCSharpCodeArguments()
{
return "NotImplemented";
}
private static bool TryGetGraphQLRequest(string input, [NotNullWhen(true)] out GraphQLRequest? graphQLRequest)
{
try

View File

@@ -16,4 +16,10 @@ public interface IMatcher
/// Gets the match behaviour.
/// </summary>
MatchBehaviour MatchBehaviour { get; }
/// <summary>
/// Get the C# code arguments.
/// </summary>
/// <returns></returns>
string GetCSharpCodeArguments();
}

View File

@@ -7,6 +7,7 @@ using Newtonsoft.Json.Linq;
using Stef.Validation;
using WireMock.Extensions;
using WireMock.Models;
using WireMock.Util;
namespace WireMock.Matchers;
@@ -89,7 +90,7 @@ public class JsonPathMatcher : IStringMatcher, IObjectMatcher
Exception? exception = null;
// When input is null or byte[], return Mismatch.
if (input != null && !(input is byte[]))
if (input != null && input is not byte[])
{
try
{
@@ -116,7 +117,18 @@ public class JsonPathMatcher : IStringMatcher, IObjectMatcher
public MatchOperator MatchOperator { get; }
/// <inheritdoc />
public string Name => "JsonPathMatcher";
public string Name => nameof(JsonPathMatcher);
/// <inheritdoc />
public string GetCSharpCodeArguments()
{
return $"new {Name}" +
$"(" +
$"{MatchBehaviour.GetFullyQualifiedEnumValue()}, " +
$"{MatchOperator.GetFullyQualifiedEnumValue()}, " +
$"{MappingConverterUtils.ToCSharpCodeArguments(_patterns)}" +
$")";
}
private double IsMatch(JToken jToken)
{

View File

@@ -8,6 +8,7 @@ using Newtonsoft.Json;
using Stef.Validation;
using WireMock.Extensions;
using WireMock.Models;
using WireMock.Util;
namespace WireMock.Matchers;
@@ -115,4 +116,15 @@ public class JmesPathMatcher : IStringMatcher, IObjectMatcher
/// <inheritdoc />
public string Name => nameof(JmesPathMatcher);
/// <inheritdoc />
public string GetCSharpCodeArguments()
{
return $"new {Name}" +
$"(" +
$"{MatchBehaviour.GetFullyQualifiedEnumValue()}, " +
$"{MatchOperator.GetFullyQualifiedEnumValue()}, " +
$"{MappingConverterUtils.ToCSharpCodeArguments(_patterns)}" +
$")";
}
}

View File

@@ -5,6 +5,7 @@ using System.Collections.Generic;
using System.Linq;
using Newtonsoft.Json.Linq;
using Stef.Validation;
using WireMock.Extensions;
using WireMock.Util;
using JsonUtils = WireMock.Util.JsonUtils;
@@ -98,6 +99,18 @@ public class JsonMatcher : IJsonMatcher
return new MatchResult(MatchBehaviourHelper.Convert(MatchBehaviour, score), error);
}
/// <inheritdoc />
public virtual string GetCSharpCodeArguments()
{
return $"new {Name}" +
$"(" +
$"{MatchBehaviour.GetFullyQualifiedEnumValue()}, " +
$"{CSharpFormatter.ConvertToAnonymousObjectDefinition(Value, 3)}, " +
$"{CSharpFormatter.ToCSharpBooleanLiteral(IgnoreCase)}, " +
$"{CSharpFormatter.ToCSharpBooleanLiteral(Regex)}" +
$")";
}
/// <summary>
/// Compares the input against the matcher value
/// </summary>

View File

@@ -1,5 +1,8 @@
// Copyright © WireMock.Net
using WireMock.Extensions;
using WireMock.Util;
namespace WireMock.Matchers;
/// <summary>
@@ -34,4 +37,16 @@ public class JsonPartialMatcher : AbstractJsonPartialMatcher
var exactStringMatcher = new ExactMatcher(MatchBehaviour.AcceptOnMatch, IgnoreCase, MatchOperator.Or, value);
return exactStringMatcher.IsMatch(input).IsPerfect();
}
/// <inheritdoc />
public override string GetCSharpCodeArguments()
{
return $"new {Name}" +
$"(" +
$"{MatchBehaviour.GetFullyQualifiedEnumValue()}, " +
$"{CSharpFormatter.ConvertToAnonymousObjectDefinition(Value, 3)}, " +
$"{CSharpFormatter.ToCSharpBooleanLiteral(IgnoreCase)}, " +
$"{CSharpFormatter.ToCSharpBooleanLiteral(Regex)}" +
$")";
}
}

View File

@@ -1,5 +1,8 @@
// Copyright © WireMock.Net
using WireMock.Extensions;
using WireMock.Util;
namespace WireMock.Matchers;
/// <summary>
@@ -34,4 +37,16 @@ public class JsonPartialWildcardMatcher : AbstractJsonPartialMatcher
var wildcardStringMatcher = new WildcardMatcher(MatchBehaviour.AcceptOnMatch, value, IgnoreCase);
return wildcardStringMatcher.IsMatch(input).IsPerfect();
}
/// <inheritdoc />
public override string GetCSharpCodeArguments()
{
return $"new {Name}" +
$"(" +
$"{MatchBehaviour.GetFullyQualifiedEnumValue()}, " +
$"{CSharpFormatter.ConvertToAnonymousObjectDefinition(Value, 3)}, " +
$"{CSharpFormatter.ToCSharpBooleanLiteral(IgnoreCase)}, " +
$"{CSharpFormatter.ToCSharpBooleanLiteral(Regex)}" +
$")";
}
}

View File

@@ -9,6 +9,7 @@ using Stef.Validation;
using WireMock.Extensions;
using WireMock.Json;
using WireMock.Models;
using WireMock.Util;
namespace WireMock.Matchers;
@@ -136,4 +137,15 @@ public class LinqMatcher : IObjectMatcher, IStringMatcher
/// <inheritdoc />
public string Name => nameof(LinqMatcher);
/// <inheritdoc />
public string GetCSharpCodeArguments()
{
return $"new {Name}" +
$"(" +
$"{MatchBehaviour.GetFullyQualifiedEnumValue()}, " +
$"{MatchOperator.GetFullyQualifiedEnumValue()}, " +
$"{MappingConverterUtils.ToCSharpCodeArguments(_patterns)}" +
$")";
}
}

View File

@@ -3,6 +3,7 @@
#if MIMEKIT
using System;
using MimeKit;
using WireMock.Extensions;
using WireMock.Matchers;
using WireMock.Matchers.Helpers;
using WireMock.Models;
@@ -60,13 +61,13 @@ public class MimePartMatcher : IMatcher
ContentTransferEncodingMatcher = contentTransferEncodingMatcher;
ContentMatcher = contentMatcher;
_funcs = new[]
{
_funcs =
[
mp => ContentTypeMatcher?.IsMatch(GetContentTypeAsString(mp.ContentType)) ?? MatchScores.Perfect,
mp => ContentDispositionMatcher?.IsMatch(mp.ContentDisposition.ToString().Replace("Content-Disposition: ", string.Empty)) ?? MatchScores.Perfect,
mp => ContentTransferEncodingMatcher?.IsMatch(mp.ContentTransferEncoding.ToString().ToLowerInvariant()) ?? MatchScores.Perfect,
MatchOnContent
};
];
}
/// <summary>
@@ -94,6 +95,12 @@ public class MimePartMatcher : IMatcher
return new MatchResult(MatchBehaviourHelper.Convert(MatchBehaviour, score), exception);
}
/// <inheritdoc />
public string GetCSharpCodeArguments()
{
return "NotImplemented";
}
private MatchResult MatchOnContent(MimePart mimePart)
{
if (ContentMatcher == null)

View File

@@ -3,7 +3,9 @@
using System;
using System.Linq;
using AnyOfTypes;
using WireMock.Extensions;
using WireMock.Models;
using WireMock.Util;
namespace WireMock.Matchers;
@@ -70,5 +72,14 @@ public class NotNullOrEmptyMatcher : IObjectMatcher, IStringMatcher
}
/// <inheritdoc />
public MatchOperator MatchOperator { get; } = MatchOperator.Or;
public MatchOperator MatchOperator => MatchOperator.Or;
/// <inheritdoc />
public string GetCSharpCodeArguments()
{
return $"new {Name}" +
$"(" +
$"{MatchBehaviour.GetFullyQualifiedEnumValue()}" +
$")";
}
}

View File

@@ -89,6 +89,12 @@ public class ProtoBufMatcher : IProtoBufMatcher
return DecodeAsync(input, false, cancellationToken);
}
/// <inheritdoc />
public string GetCSharpCodeArguments()
{
return "NotImplemented";
}
private async Task<object?> DecodeAsync(byte[]? input, bool throwException, CancellationToken cancellationToken)
{
if (input == null)

View File

@@ -10,6 +10,7 @@ using WireMock.Constants;
using WireMock.Extensions;
using WireMock.Models;
using WireMock.RegularExpressions;
using WireMock.Util;
namespace WireMock.Matchers;
@@ -22,6 +23,7 @@ public class RegexMatcher : IStringMatcher, IIgnoreCaseMatcher
{
private readonly AnyOf<string, StringPattern>[] _patterns;
private readonly Regex[] _expressions;
private readonly bool _useRegexExtended;
/// <inheritdoc />
public MatchBehaviour MatchBehaviour { get; }
@@ -77,10 +79,11 @@ public class RegexMatcher : IStringMatcher, IIgnoreCaseMatcher
{
_patterns = Guard.NotNull(patterns);
IgnoreCase = ignoreCase;
_useRegexExtended = useRegexExtended;
MatchBehaviour = matchBehaviour;
MatchOperator = matchOperator;
RegexOptions options = RegexOptions.Compiled | RegexOptions.Multiline;
var options = RegexOptions.Compiled | RegexOptions.Multiline;
if (ignoreCase)
{
@@ -126,4 +129,16 @@ public class RegexMatcher : IStringMatcher, IIgnoreCaseMatcher
/// <inheritdoc />
public MatchOperator MatchOperator { get; }
/// <inheritdoc />
public virtual string GetCSharpCodeArguments()
{
return $"new {Name}" +
$"(" +
$"{MatchBehaviour.GetFullyQualifiedEnumValue()}, " +
$"{MappingConverterUtils.ToCSharpCodeArguments(_patterns)}, " +
$"{CSharpFormatter.ToCSharpBooleanLiteral(IgnoreCase)}, " +
$"{CSharpFormatter.ToCSharpBooleanLiteral(_useRegexExtended)}, " +
$"{MatchOperator.GetFullyQualifiedEnumValue()}" +
$")";
}
}

View File

@@ -8,6 +8,7 @@ using SimMetrics.Net.Metric;
using Stef.Validation;
using WireMock.Extensions;
using WireMock.Models;
using WireMock.Util;
namespace WireMock.Matchers;
@@ -88,6 +89,18 @@ public class SimMetricsMatcher : IStringMatcher
return MatchBehaviourHelper.Convert(MatchBehaviour, score);
}
/// <inheritdoc />
public virtual string GetCSharpCodeArguments()
{
return $"new {Name}" +
$"(" +
$"{MatchBehaviour.GetFullyQualifiedEnumValue()}, " +
$"{MappingConverterUtils.ToCSharpCodeArguments(_patterns)}, " +
$"{_simMetricType.GetFullyQualifiedEnumValue()}, " +
$"{MatchOperator.GetFullyQualifiedEnumValue()}" +
$")";
}
private IStringMetric GetStringMetricType()
{
return _simMetricType switch

View File

@@ -6,6 +6,7 @@ using AnyOfTypes;
using Stef.Validation;
using WireMock.Extensions;
using WireMock.Models;
using WireMock.Util;
namespace WireMock.Matchers;
@@ -70,6 +71,18 @@ public class WildcardMatcher : RegexMatcher
/// <inheritdoc />
public override string Name => nameof(WildcardMatcher);
/// <inheritdoc />
public override string GetCSharpCodeArguments()
{
return $"new {Name}" +
$"(" +
$"{MatchBehaviour.GetFullyQualifiedEnumValue()}, " +
$"{MappingConverterUtils.ToCSharpCodeArguments(_patterns)}, " +
$"{CSharpFormatter.ToCSharpBooleanLiteral(IgnoreCase)}, " +
$"{MatchOperator.GetFullyQualifiedEnumValue()}" +
$")";
}
private static AnyOf<string, StringPattern>[] CreateArray(AnyOf<string, StringPattern>[] patterns)
{
return patterns

View File

@@ -10,6 +10,7 @@ using WireMock.Extensions;
using WireMock.Models;
using Stef.Validation;
using WireMock.Admin.Mappings;
using WireMock.Util;
#if !NETSTANDARD1_3
using Wmhelp.XPath2;
#endif
@@ -89,11 +90,6 @@ public class XPathMatcher : IStringMatcher
return CreateMatchResult(score);
}
private MatchResult CreateMatchResult(double score, Exception? exception = null)
{
return new MatchResult(MatchBehaviourHelper.Convert(MatchBehaviour, score), exception);
}
/// <inheritdoc />
public AnyOf<string, StringPattern>[] GetPatterns()
{
@@ -106,6 +102,23 @@ public class XPathMatcher : IStringMatcher
/// <inheritdoc />
public string Name => nameof(XPathMatcher);
/// <inheritdoc />
public string GetCSharpCodeArguments()
{
return $"new {Name}" +
$"(" +
$"{MatchBehaviour.GetFullyQualifiedEnumValue()}, " +
$"{MatchOperator.GetFullyQualifiedEnumValue()}, " +
$"null, " +
$"{MappingConverterUtils.ToCSharpCodeArguments(_patterns)}" +
$")";
}
private MatchResult CreateMatchResult(double score, Exception? exception = null)
{
return new MatchResult(MatchBehaviourHelper.Convert(MatchBehaviour, score), exception);
}
private sealed class XPathEvaluator
{
private XmlDocument? _xmlDocument;
@@ -130,6 +143,7 @@ public class XPathMatcher : IStringMatcher
{
return _xpathNavigator == null ? [] : patterns.Select(pattern => true.Equals(Evaluate(_xpathNavigator, pattern, xmlNamespaceMap))).ToArray();
}
private object Evaluate(XPathNavigator navigator, AnyOf<string, StringPattern> pattern, IEnumerable<XmlNamespace>? xmlNamespaceMap)
{
var xpath = $"boolean({pattern.GetPattern()})";

View File

@@ -23,16 +23,11 @@ using static WireMock.Util.CSharpFormatter;
namespace WireMock.Serialization;
internal class MappingConverter
internal class MappingConverter(MatcherMapper mapper)
{
private static readonly string AcceptOnMatch = MatchBehaviour.AcceptOnMatch.GetFullyQualifiedEnumValue();
private readonly MatcherMapper _mapper;
public MappingConverter(MatcherMapper mapper)
{
_mapper = Guard.NotNull(mapper);
}
private readonly MatcherMapper _mapper = Guard.NotNull(mapper);
public string ToCSharpCode(IMapping mapping, MappingConverterSettings? settings = null)
{
@@ -77,26 +72,26 @@ internal class MappingConverter
sb.AppendLine(" .Given(Request.Create()");
sb.AppendLine($" .UsingMethod({To1Or2Or3Arguments(methodMatcher?.MatchBehaviour, methodMatcher?.MatchOperator, methodMatcher?.Methods, HttpRequestMethod.GET)})");
if (pathMatcher is { Matchers: { } })
if (pathMatcher?.Matchers != null)
{
sb.AppendLine($" .WithPath({To1Or2Arguments(pathMatcher.MatchOperator, pathMatcher.Matchers)})");
}
else if (urlMatcher is { Matchers: { } })
else if (urlMatcher?.Matchers != null)
{
sb.AppendLine($" .WithUrl({To1Or2Arguments(urlMatcher.MatchOperator, urlMatcher.Matchers)})");
}
foreach (var paramsMatcher in paramsMatchers)
foreach (var paramsMatcher in paramsMatchers.Where(pm => pm.Matchers != null))
{
sb.AppendLine($" .WithParam({To1Or2Or3Arguments(paramsMatcher.Key, paramsMatcher.MatchBehaviour, paramsMatcher.Matchers!)})");
sb.AppendLine($" .WithParam({To2Or3Arguments(paramsMatcher.Key, paramsMatcher.MatchBehaviour, paramsMatcher.Matchers!)})");
}
if (clientIPMatcher is { Matchers: { } })
if (clientIPMatcher?.Matchers != null)
{
sb.AppendLine($" .WithClientIP({ToValueArguments(GetStringArray(clientIPMatcher.Matchers))})");
}
foreach (var headerMatcher in headerMatchers.Where(h => h.Matchers is { }))
foreach (var headerMatcher in headerMatchers.Where(h => h.Matchers != null))
{
var headerBuilder = new StringBuilder($"\"{headerMatcher.Name}\", {ToValueArguments(GetStringArray(headerMatcher.Matchers!))}, true");
if (headerMatcher.MatchOperator != MatchOperator.Or)
@@ -106,7 +101,7 @@ internal class MappingConverter
sb.AppendLine($" .WithHeader({headerBuilder})");
}
foreach (var cookieMatcher in cookieMatchers.Where(h => h.Matchers is { }))
foreach (var cookieMatcher in cookieMatchers.Where(c => c.Matchers != null))
{
sb.AppendLine($" .WithCookie(\"{cookieMatcher.Name}\", {ToValueArguments(GetStringArray(cookieMatcher.Matchers!))}, true)");
}
@@ -117,7 +112,7 @@ internal class MappingConverter
}
#if GRAPHQL
if (requestMessageGraphQLMatcher is { Matchers: { } })
if (requestMessageGraphQLMatcher?.Matchers != null)
{
if (requestMessageGraphQLMatcher.Matchers.OfType<GraphQLMatcher>().FirstOrDefault() is { } graphQLMatcher && graphQLMatcher.GetPatterns().Any())
{
@@ -127,7 +122,7 @@ internal class MappingConverter
#endif
#if MIMEKIT
if (requestMessageMultiPartMatcher is { Matchers: { } })
if (requestMessageMultiPartMatcher?.Matchers != null)
{
if (requestMessageMultiPartMatcher.Matchers.OfType<MimePartMatcher>().Any())
{
@@ -137,13 +132,13 @@ internal class MappingConverter
#endif
#if PROTOBUF
if (requestMessageProtoBufMatcher is { Matcher: { } })
if (requestMessageProtoBufMatcher?.Matcher != null)
{
sb.AppendLine(" // .WithBodyAsProtoBuf() is not yet supported");
}
#endif
if (requestMessageBodyMatcher is { Matchers: { } })
if (requestMessageBodyMatcher?.Matchers != null)
{
var firstMatcher = requestMessageBodyMatcher.Matchers.FirstOrDefault();
@@ -154,15 +149,15 @@ internal class MappingConverter
break;
case JsonMatcher jsonMatcher:
{
var matcherType = jsonMatcher.GetType().Name;
sb.AppendLine($" .WithBody(new {matcherType}(");
sb.AppendLine($" value: {ConvertToAnonymousObjectDefinition(jsonMatcher.Value, 3)},");
sb.AppendLine($" ignoreCase: {ToCSharpBooleanLiteral(jsonMatcher.IgnoreCase)},");
sb.AppendLine($" regex: {ToCSharpBooleanLiteral(jsonMatcher.Regex)}");
sb.AppendLine(@" ))");
break;
}
{
var matcherType = jsonMatcher.GetType().Name;
sb.AppendLine($" .WithBody(new {matcherType}(");
sb.AppendLine($" value: {ConvertToAnonymousObjectDefinition(jsonMatcher.Value, 3)},");
sb.AppendLine($" ignoreCase: {ToCSharpBooleanLiteral(jsonMatcher.IgnoreCase)},");
sb.AppendLine($" regex: {ToCSharpBooleanLiteral(jsonMatcher.Regex)}");
sb.AppendLine(@" ))");
break;
}
}
}
@@ -309,7 +304,7 @@ internal class MappingConverter
Response = new ResponseModel()
};
if (methodMatcher is { Methods: { } })
if (methodMatcher != null)
{
mappingModel.Request.Methods = methodMatcher.Methods;
mappingModel.Request.MethodsRejectOnMatch = methodMatcher.MatchBehaviour == MatchBehaviour.RejectOnMatch ? true : null;
@@ -321,7 +316,7 @@ internal class MappingConverter
mappingModel.Request.HttpVersion = httpVersionMatcher.HttpVersion;
}
if (clientIPMatcher is { Matchers: { } })
if (clientIPMatcher?.Matchers != null)
{
var clientIPMatchers = _mapper.Map(clientIPMatcher.Matchers);
mappingModel.Request.Path = new ClientIPModel
@@ -331,7 +326,7 @@ internal class MappingConverter
};
}
if (pathMatcher is { Matchers: { } })
if (pathMatcher?.Matchers != null)
{
var pathMatchers = _mapper.Map(pathMatcher.Matchers);
mappingModel.Request.Path = new PathModel
@@ -340,7 +335,7 @@ internal class MappingConverter
MatchOperator = pathMatchers?.Length > 1 ? pathMatcher.MatchOperator.ToString() : null
};
}
else if (urlMatcher is { Matchers: { } })
else if (urlMatcher?.Matchers != null)
{
var urlMatchers = _mapper.Map(urlMatcher.Matchers);
mappingModel.Request.Url = new UrlModel
@@ -538,7 +533,7 @@ internal class MappingConverter
return stringMatchers.SelectMany(m => m.GetPatterns()).Select(p => p.GetPattern()).ToArray();
}
private static string To1Or2Or3Arguments(string key, MatchBehaviour? matchBehaviour, IReadOnlyList<IStringMatcher> matchers)
private static string To2Or3Arguments(string key, MatchBehaviour? matchBehaviour, IReadOnlyList<IStringMatcher> matchers)
{
var sb = new StringBuilder($"\"{key}\", ");
@@ -547,7 +542,7 @@ internal class MappingConverter
sb.AppendFormat("{0}, ", matchBehaviour.Value.GetFullyQualifiedEnumValue());
}
sb.AppendFormat("{0}", ToValueArguments(GetStringArray(matchers), string.Empty));
sb.AppendFormat("{0}", MappingConverterUtils.ToCSharpCodeArguments(matchers));
return sb.ToString();
}
@@ -566,7 +561,16 @@ internal class MappingConverter
private static string To1Or2Arguments(MatchOperator? matchOperator, IReadOnlyList<IStringMatcher> matchers)
{
return To1Or2Arguments(matchOperator, GetStringArray(matchers), string.Empty);
var sb = new StringBuilder();
if (matchOperator.HasValue && matchOperator != MatchOperator.Or)
{
sb.AppendFormat("{0}, ", matchOperator.Value.GetFullyQualifiedEnumValue());
}
sb.AppendFormat("{0}", MappingConverterUtils.ToCSharpCodeArguments(matchers));
return sb.ToString();
}
private static string To1Or2Arguments(MatchOperator? matchOperator, string[]? values, string defaultValue)

View File

@@ -0,0 +1,23 @@
// Copyright © WireMock.Net
using System.Collections.Generic;
using System.Linq;
using AnyOfTypes;
using WireMock.Extensions;
using WireMock.Matchers;
using WireMock.Models;
namespace WireMock.Util;
internal static class MappingConverterUtils
{
internal static string ToCSharpCodeArguments(IReadOnlyList<IMatcher> matchers)
{
return string.Join(", ", matchers.Select(m => m.GetCSharpCodeArguments()));
}
internal static string ToCSharpCodeArguments(AnyOf<string, StringPattern>[] patterns)
{
return string.Join(", ", patterns.Select(p => CSharpFormatter.ToCSharpStringLiteral(p.GetPattern())));
}
}

View File

@@ -47,6 +47,7 @@ message HelloReply {
.WithPath("/grpc/greet.Greeter/SayHello")
.WithBodyAsProtoBuf(ProtoDefinition, "greet.HelloRequest", protoBufJsonMatcher)
)
.WithGuid(_guidUtilsMock.Object.NewGuid())
.RespondWith(Response.Create()
.WithHeader("Content-Type", "application/grpc")
.WithBodyAsProtoBuf(ProtoDefinition, "greet.HelloReply",
@@ -66,6 +67,7 @@ message HelloReply {
.WithBodyAsProtoBuf("greet.HelloRequest", protoBufJsonMatcher)
)
.WithProtoDefinition(ProtoDefinition)
.WithGuid(_guidUtilsMock.Object.NewGuid())
.RespondWith(Response.Create()
.WithHeader("Content-Type", "application/grpc")
.WithBodyAsProtoBuf("greet.HelloReply",
@@ -86,6 +88,7 @@ message HelloReply {
.WithBodyAsProtoBuf("greet.HelloRequest", protoBufJsonMatcher)
)
.WithProtoDefinition("my-greeter")
.WithGuid(_guidUtilsMock.Object.NewGuid())
.RespondWith(Response.Create()
.WithHeader("Content-Type", "application/grpc")
.WithBodyAsProtoBuf("greet.HelloReply",
@@ -106,6 +109,7 @@ message HelloReply {
.WithBodyAsProtoBuf("greet.HelloRequest")
)
.WithProtoDefinition("my-greeter")
.WithGuid(_guidUtilsMock.Object.NewGuid())
.RespondWith(Response.Create()
.WithHeader("Content-Type", "application/grpc")
.WithBodyAsProtoBuf("greet.HelloReply",

View File

@@ -2,8 +2,8 @@
server
.Given(Request.Create()
.UsingMethod("GET")
.WithPath("/foo1")
.WithParam("p1", "xyz")
.WithPath(new WildcardMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, "/foo1", false, WireMock.Matchers.MatchOperator.Or))
.WithParam("p1", new ExactMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, false, WireMock.Matchers.MatchOperator.And, "xyz"))
)
.WithGuid("90356dba-b36c-469a-a17e-669cd84f1f05")
.RespondWith(Response.Create()

View File

@@ -2,25 +2,7 @@
server
.Given(Request.Create()
.UsingMethod("POST")
.WithPath("/users/post1")
.WithBody(new JsonMatcher(
value: new
{
city = "Amsterdam",
country = "The Netherlands"
},
ignoreCase: false,
regex: false
))
)
.WithGuid("90356dba-b36c-469a-a17e-669cd84f1f05")
.RespondWith(Response.Create()
);
server
.Given(Request.Create()
.UsingMethod("POST")
.WithPath("/users/post2")
.WithPath(new WildcardMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, "/users/post2", false, WireMock.Matchers.MatchOperator.Or))
.WithBody(new JsonPartialMatcher(
value: new
{
@@ -37,23 +19,11 @@ server
Some ""value"" in Line2")
);
server
.Given(Request.Create()
.UsingMethod("GET")
.WithPath("/foo1")
.WithParam("p1", "xyz")
)
.WithGuid("f74fd144-df53-404f-8e35-da22a640bd5f")
.RespondWith(Response.Create()
.WithStatusCode(200)
.WithBody("1")
);
server
.Given(Request.Create()
.UsingMethod("POST")
.WithPath("/foo2")
.WithParam("p2", "abc")
.WithPath(new WildcardMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, "/foo2", false, WireMock.Matchers.MatchOperator.Or))
.WithParam("p2", new ExactMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, false, WireMock.Matchers.MatchOperator.And, "abc"))
.WithHeader("h1", "W/\"234f2q3r\"", true)
)
.WithGuid("4126dec8-470b-4eff-93bb-c24f83b8b1fd")
@@ -64,10 +34,28 @@ server
.WithBody("2")
);
server
.Given(Request.Create()
.UsingMethod("POST")
.WithPath(new WildcardMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, "/users/post1", false, WireMock.Matchers.MatchOperator.Or))
.WithBody(new JsonMatcher(
value: new
{
city = "Amsterdam",
country = "The Netherlands"
},
ignoreCase: false,
regex: false
))
)
.WithGuid("90356dba-b36c-469a-a17e-669cd84f1f05")
.RespondWith(Response.Create()
);
server
.Given(Request.Create()
.UsingMethod("DELETE")
.WithUrl("https://localhost/test")
.WithUrl(new WildcardMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, "https://localhost/test", false, WireMock.Matchers.MatchOperator.Or))
)
.WithGuid("c9929240-7ae8-4a5d-8ed8-0913479f6eeb")
.RespondWith(Response.Create()
@@ -108,3 +96,15 @@ text
})
);
server
.Given(Request.Create()
.UsingMethod("GET")
.WithPath(new WildcardMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, "/foo1", false, WireMock.Matchers.MatchOperator.Or))
.WithParam("p1", new ExactMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, false, WireMock.Matchers.MatchOperator.And, "xyz"))
)
.WithGuid("f74fd144-df53-404f-8e35-da22a640bd5f")
.RespondWith(Response.Create()
.WithStatusCode(200)
.WithBody("1")
);

View File

@@ -30,6 +30,7 @@ using WireMock.ResponseBuilders;
using WireMock.Server;
using WireMock.Settings;
using WireMock.Types;
using WireMock.Util;
using Xunit;
namespace WireMock.Net.Tests.AdminApi;
@@ -39,6 +40,14 @@ public partial class WireMockAdminApiTests
{
private static readonly VerifySettings VerifySettings = new();
private readonly Mock<IGuidUtils> _guidUtilsMock = new();
public WireMockAdminApiTests()
{
var startGuid = 1000;
_guidUtilsMock.Setup(g => g.NewGuid()).Returns(() => new Guid($"98fae52e-76df-47d9-876f-2ee32e93{startGuid++}"));
}
static WireMockAdminApiTests()
{
VerifyNewtonsoftJson.Enable(VerifySettings);

View File

@@ -32,6 +32,35 @@
Body: { msg: "Hello world!"}
}
},
{
Guid: 98fae52e-76df-47d9-876f-2ee32e931001,
UpdatedAt: 2023-01-14 15:16:17,
Request: {
Path: {
Matchers: [
{
Name: WildcardMatcher,
Pattern: /users/post1,
IgnoreCase: false
}
]
},
Methods: [
POST
],
Body: {
Matcher: {
Name: JsonMatcher,
Pattern: {
Request: Hello?
},
IgnoreCase: false,
Regex: false
}
}
},
Response: {}
},
{
Guid: 98fae52e-76df-47d9-876f-2ee32e931002,
UpdatedAt: 2023-01-14 15:16:17,
@@ -106,31 +135,33 @@
Response: {}
},
{
Guid: 98fae52e-76df-47d9-876f-2ee32e931001,
Guid: 98fae52e-76df-47d9-876f-2ee32e931004,
UpdatedAt: 2023-01-14 15:16:17,
Request: {
Path: {
Matchers: [
{
Name: WildcardMatcher,
Pattern: /users/post1,
Pattern: /regex,
IgnoreCase: false
}
]
},
Methods: [
POST
GET
],
Body: {
Matcher: {
Name: JsonMatcher,
Pattern: {
Request: Hello?
},
IgnoreCase: false,
Regex: false
Params: [
{
Name: foo,
Matchers: [
{
Name: RegexMatcher,
Pattern: .*,
IgnoreCase: false
}
]
}
}
]
},
Response: {}
}

View File

@@ -2,8 +2,8 @@
builder
.Given(Request.Create()
.UsingMethod("GET")
.WithPath("/foo")
.WithParam("test", "it.Length < 10")
.WithPath(new WildcardMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, "/foo", false, WireMock.Matchers.MatchOperator.Or))
.WithParam("test", new LinqMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, WireMock.Matchers.MatchOperator.Or, "it.Length < 10"))
)
.WithGuid("41372914-1838-4c67-916b-b9aacdd096ce")
.RespondWith(Response.Create()
@@ -13,7 +13,24 @@ builder
builder
.Given(Request.Create()
.UsingMethod("POST")
.WithPath("/users/post2")
.WithPath(new WildcardMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, "/users/post1", false, WireMock.Matchers.MatchOperator.Or))
.WithBody(new JsonMatcher(
value: new
{
Request = "Hello?"
},
ignoreCase: false,
regex: false
))
)
.WithGuid("98fae52e-76df-47d9-876f-2ee32e931001")
.RespondWith(Response.Create()
);
builder
.Given(Request.Create()
.UsingMethod("POST")
.WithPath(new WildcardMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, "/users/post2", false, WireMock.Matchers.MatchOperator.Or))
.WithBody(new JsonMatcher(
value: new
{
@@ -31,7 +48,7 @@ builder
builder
.Given(Request.Create()
.UsingMethod("POST")
.WithPath("/form-urlencoded")
.WithPath(new WildcardMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, "/form-urlencoded", false, WireMock.Matchers.MatchOperator.Or))
.WithHeader("Content-Type", "application/x-www-form-urlencoded", true)
.WithBody("name=John Doe")
)
@@ -41,18 +58,11 @@ builder
builder
.Given(Request.Create()
.UsingMethod("POST")
.WithPath("/users/post1")
.WithBody(new JsonMatcher(
value: new
{
Request = "Hello?"
},
ignoreCase: false,
regex: false
))
.UsingMethod("GET")
.WithPath(new WildcardMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, "/regex", false, WireMock.Matchers.MatchOperator.Or))
.WithParam("foo", new RegexMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, ".*", false, true, WireMock.Matchers.MatchOperator.Or))
)
.WithGuid("98fae52e-76df-47d9-876f-2ee32e931001")
.WithGuid("98fae52e-76df-47d9-876f-2ee32e931004")
.RespondWith(Response.Create()
);

View File

@@ -2,8 +2,8 @@
server
.Given(Request.Create()
.UsingMethod("GET")
.WithPath("/foo")
.WithParam("test", "it.Length < 10")
.WithPath(new WildcardMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, "/foo", false, WireMock.Matchers.MatchOperator.Or))
.WithParam("test", new LinqMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, WireMock.Matchers.MatchOperator.Or, "it.Length < 10"))
)
.WithGuid("41372914-1838-4c67-916b-b9aacdd096ce")
.RespondWith(Response.Create()
@@ -13,7 +13,24 @@ server
server
.Given(Request.Create()
.UsingMethod("POST")
.WithPath("/users/post2")
.WithPath(new WildcardMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, "/users/post1", false, WireMock.Matchers.MatchOperator.Or))
.WithBody(new JsonMatcher(
value: new
{
Request = "Hello?"
},
ignoreCase: false,
regex: false
))
)
.WithGuid("98fae52e-76df-47d9-876f-2ee32e931001")
.RespondWith(Response.Create()
);
server
.Given(Request.Create()
.UsingMethod("POST")
.WithPath(new WildcardMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, "/users/post2", false, WireMock.Matchers.MatchOperator.Or))
.WithBody(new JsonMatcher(
value: new
{
@@ -31,7 +48,7 @@ server
server
.Given(Request.Create()
.UsingMethod("POST")
.WithPath("/form-urlencoded")
.WithPath(new WildcardMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, "/form-urlencoded", false, WireMock.Matchers.MatchOperator.Or))
.WithHeader("Content-Type", "application/x-www-form-urlencoded", true)
.WithBody("name=John Doe")
)
@@ -41,18 +58,11 @@ server
server
.Given(Request.Create()
.UsingMethod("POST")
.WithPath("/users/post1")
.WithBody(new JsonMatcher(
value: new
{
Request = "Hello?"
},
ignoreCase: false,
regex: false
))
.UsingMethod("GET")
.WithPath(new WildcardMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, "/regex", false, WireMock.Matchers.MatchOperator.Or))
.WithParam("foo", new RegexMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, ".*", false, true, WireMock.Matchers.MatchOperator.Or))
)
.WithGuid("98fae52e-76df-47d9-876f-2ee32e931001")
.WithGuid("98fae52e-76df-47d9-876f-2ee32e931004")
.RespondWith(Response.Create()
);

View File

@@ -32,6 +32,34 @@
Body: { msg: "Hello world!"}
}
},
{
Guid: 98fae52e-76df-47d9-876f-2ee32e931001,
UpdatedAt: 2023-01-14T15:16:17,
Request: {
Path: {
Matchers: [
{
Name: WildcardMatcher,
Pattern: /users/post1,
IgnoreCase: false
}
]
},
Methods: [
POST
],
Body: {
Matcher: {
Name: JsonMatcher,
Pattern: {
Request: Hello?
},
IgnoreCase: false,
Regex: false
}
}
}
},
{
Guid: 98fae52e-76df-47d9-876f-2ee32e931002,
UpdatedAt: 2023-01-14T15:16:17,
@@ -104,31 +132,33 @@
}
},
{
Guid: 98fae52e-76df-47d9-876f-2ee32e931001,
Guid: 98fae52e-76df-47d9-876f-2ee32e931004,
UpdatedAt: 2023-01-14T15:16:17,
Request: {
Path: {
Matchers: [
{
Name: WildcardMatcher,
Pattern: /users/post1,
Pattern: /regex,
IgnoreCase: false
}
]
},
Methods: [
POST
GET
],
Body: {
Matcher: {
Name: JsonMatcher,
Pattern: {
Request: Hello?
},
IgnoreCase: false,
Regex: false
Params: [
{
Name: foo,
Matchers: [
{
Name: RegexMatcher,
Pattern: .*,
IgnoreCase: false
}
]
}
}
]
}
}
]

View File

@@ -102,6 +102,13 @@ public class MappingBuilderTests
.WithHeader("Content-Type", "application/x-www-form-urlencoded")
.WithBody(new FormUrlEncodedMatcher(["name=John Doe", "email=johndoe@example.com"]))
).RespondWith(Response.Create());
_sut.Given(Request.Create()
.WithPath("/regex")
.WithParam("foo", new RegexMatcher(".*"))
.UsingGet()
)
.RespondWith(Response.Create());
}
[Fact]
@@ -190,9 +197,9 @@ public class MappingBuilderTests
_sut.SaveMappingsToFolder(null);
// Verify
_fileSystemHandlerMock.Verify(fs => fs.GetMappingFolder(), Times.Exactly(4));
_fileSystemHandlerMock.Verify(fs => fs.FolderExists(mappingFolder), Times.Exactly(4));
_fileSystemHandlerMock.Verify(fs => fs.WriteMappingFile(It.IsAny<string>(), It.IsAny<string>()), Times.Exactly(4));
_fileSystemHandlerMock.Verify(fs => fs.GetMappingFolder(), Times.Exactly(5));
_fileSystemHandlerMock.Verify(fs => fs.FolderExists(mappingFolder), Times.Exactly(5));
_fileSystemHandlerMock.Verify(fs => fs.WriteMappingFile(It.IsAny<string>(), It.IsAny<string>()), Times.Exactly(5));
_fileSystemHandlerMock.VerifyNoOtherCalls();
}
@@ -208,8 +215,8 @@ public class MappingBuilderTests
// Verify
_fileSystemHandlerMock.Verify(fs => fs.GetMappingFolder(), Times.Never);
_fileSystemHandlerMock.Verify(fs => fs.FolderExists(path), Times.Exactly(4));
_fileSystemHandlerMock.Verify(fs => fs.WriteMappingFile(It.IsAny<string>(), It.IsAny<string>()), Times.Exactly(4));
_fileSystemHandlerMock.Verify(fs => fs.FolderExists(path), Times.Exactly(5));
_fileSystemHandlerMock.Verify(fs => fs.WriteMappingFile(It.IsAny<string>(), It.IsAny<string>()), Times.Exactly(5));
_fileSystemHandlerMock.VerifyNoOtherCalls();
}
}

View File

@@ -29,7 +29,7 @@ public class ExactObjectMatcherTests
object checkValue = new byte[] { 1, 2 };
// Act
var matcher = new ExactObjectMatcher(new byte[] { 1, 2 });
var matcher = new ExactObjectMatcher([1, 2]);
var score = matcher.IsMatch(checkValue).Score;
// Assert

View File

@@ -0,0 +1,177 @@
using FluentAssertions;
using WireMock.Matchers;
using Xunit;
namespace WireMock.Net.Tests.Matchers;
public class MatcherTests
{
[Fact]
public void ContentTypeMatcher_GetCSharpCodeArguments_ShouldReturnCorrectArguments()
{
// Arrange
var matcher = new ContentTypeMatcher("application/json");
// Act
var result = matcher.GetCSharpCodeArguments();
// Assert
result.Should().Be("new ContentTypeMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, \"application/json\", false)");
}
[Fact]
public void ExactMatcher_GetCSharpCodeArguments_ShouldReturnCorrectArguments()
{
// Arrange
var matcher = new ExactMatcher("test");
// Act
var result = matcher.GetCSharpCodeArguments();
// Assert
result.Should().Be("new ExactMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, false, WireMock.Matchers.MatchOperator.Or, \"test\")");
}
[Fact]
public void ExactObjectMatcher_GetCSharpCodeArguments_ShouldReturnNotImplemented()
{
// Arrange
var matcher = new ExactObjectMatcher(new { Name = "test" });
// Act
var result = matcher.GetCSharpCodeArguments();
// Assert
result.Should().Be("NotImplemented");
}
[Fact]
public void FormUrlEncodedMatcher_GetCSharpCodeArguments_ShouldReturnCorrectArguments()
{
// Arrange
var matcher = new FormUrlEncodedMatcher("key=value");
// Act
var result = matcher.GetCSharpCodeArguments();
// Assert
result.Should().Be("new FormUrlEncodedMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, \"key=value\", false, WireMock.Matchers.MatchOperator.Or)");
}
[Fact]
public void JmesPathMatcher_GetCSharpCodeArguments_ShouldReturnCorrectArguments()
{
// Arrange
var matcher = new JmesPathMatcher("expression");
// Act
var result = matcher.GetCSharpCodeArguments();
// Assert
result.Should().Be("new JmesPathMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, WireMock.Matchers.MatchOperator.Or, \"expression\")");
}
[Fact]
public void JsonMatcher_GetCSharpCodeArguments_ShouldReturnCorrectArguments()
{
// Arrange
var matcher = new JsonMatcher(new { key = "value" });
// Act
var result = matcher.GetCSharpCodeArguments();
// Assert
result.Should().StartWith("new JsonMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch,");
}
[Fact]
public void JsonPartialMatcher_GetCSharpCodeArguments_ShouldReturnCorrectArguments()
{
// Arrange
var matcher = new JsonPartialMatcher(new { key = "value" });
// Act
var result = matcher.GetCSharpCodeArguments();
// Assert
result.Should().StartWith("new JsonPartialMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch,");
}
[Fact]
public void JsonPartialWildcardMatcher_GetCSharpCodeArguments_ShouldReturnCorrectArguments()
{
// Arrange
var matcher = new JsonPartialWildcardMatcher(new { key = "value" });
// Act
var result = matcher.GetCSharpCodeArguments();
// Assert
result.Should().StartWith("new JsonPartialWildcardMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch,");
}
[Fact]
public void LinqMatcher_GetCSharpCodeArguments_ShouldReturnCorrectArguments()
{
// Arrange
var matcher = new LinqMatcher("it.Contains(\"test\"");
// Act
var result = matcher.GetCSharpCodeArguments();
// Assert
result.Should().Be("new LinqMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, WireMock.Matchers.MatchOperator.Or, \"it.Contains(\\\"test\\\"\")");
}
[Fact]
public void RegexMatcher_GetCSharpCodeArguments_ShouldReturnCorrectArguments()
{
// Arrange
var matcher = new RegexMatcher("pattern");
// Act
var result = matcher.GetCSharpCodeArguments();
// Assert
result.Should().Be("new RegexMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, \"pattern\", false, true, WireMock.Matchers.MatchOperator.Or)");
}
[Fact]
public void SimMetricsMatcher_GetCSharpCodeArguments_ShouldReturnCorrectArguments()
{
// Arrange
var matcher = new SimMetricsMatcher("test");
// Act
var result = matcher.GetCSharpCodeArguments();
// Assert
result.Should().Be("new SimMetricsMatcher.Levenstein(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, \"test\", SimMetrics.Net.SimMetricType.Levenstein, WireMock.Matchers.MatchOperator.Average)");
}
[Fact]
public void WildcardMatcher_GetCSharpCodeArguments_ShouldReturnCorrectArguments()
{
// Arrange
var matcher = new WildcardMatcher("pattern");
// Act
var result = matcher.GetCSharpCodeArguments();
// Assert
result.Should().Be("new WildcardMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, \"pattern\", false, WireMock.Matchers.MatchOperator.Or)");
}
[Fact]
public void XPathMatcher_GetCSharpCodeArguments_ShouldReturnCorrectArguments()
{
// Arrange
var matcher = new XPathMatcher("pattern1");
// Act
var result = matcher.GetCSharpCodeArguments();
// Assert
result.Should().Be("new XPathMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, WireMock.Matchers.MatchOperator.Or, null, \"pattern1\")");
}
}

View File

@@ -92,11 +92,17 @@ public class CustomPathParamMatcher : IStringMatcher
public MatchOperator MatchOperator { get; }
/// <inheritdoc />
public string GetCSharpCodeArguments()
{
return "// TODO: CustomPathParamMatcher";
}
private static string[] GetPathParts(string? path)
{
if (path is null)
{
return new string[0];
return [];
}
var hashMarkIndex = path.IndexOf('#');

View File

@@ -1,8 +1,8 @@
builder
.Given(Request.Create()
.UsingMethod("GET")
.WithPath("test_path")
.WithParam("q", "42")
.WithPath(new WildcardMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, "test_path", false, WireMock.Matchers.MatchOperator.Or))
.WithParam("q", new ExactMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, false, WireMock.Matchers.MatchOperator.And, "42"))
.WithClientIP("112.123.100.99")
.WithHeader("h-key", "h-value", true)
.WithCookie("c-key", "c-value", true)

View File

@@ -2,8 +2,8 @@
builder
.Given(Request.Create()
.UsingMethod("GET")
.WithPath("test_path")
.WithParam("q", "42")
.WithPath(new WildcardMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, "test_path", false, WireMock.Matchers.MatchOperator.Or))
.WithParam("q", new ExactMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, false, WireMock.Matchers.MatchOperator.And, "42"))
.WithClientIP("112.123.100.99")
.WithHeader("h-key", "h-value", true)
.WithCookie("c-key", "c-value", true)

View File

@@ -1,8 +1,8 @@
server
.Given(Request.Create()
.UsingMethod("GET")
.WithPath("test_path")
.WithParam("q", "42")
.WithPath(new WildcardMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, "test_path", false, WireMock.Matchers.MatchOperator.Or))
.WithParam("q", new ExactMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, false, WireMock.Matchers.MatchOperator.And, "42"))
.WithClientIP("112.123.100.99")
.WithHeader("h-key", "h-value", true)
.WithCookie("c-key", "c-value", true)

View File

@@ -2,8 +2,8 @@
server
.Given(Request.Create()
.UsingMethod("GET")
.WithPath("test_path")
.WithParam("q", "42")
.WithPath(new WildcardMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, "test_path", false, WireMock.Matchers.MatchOperator.Or))
.WithParam("q", new ExactMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, false, WireMock.Matchers.MatchOperator.And, "42"))
.WithClientIP("112.123.100.99")
.WithHeader("h-key", "h-value", true)
.WithCookie("c-key", "c-value", true)