mirror of
https://github.com/wiremock/WireMock.Net.git
synced 2026-01-11 22:30:41 +01:00
WildcardMatcher and other fixes
This commit is contained in:
@@ -46,7 +46,7 @@ namespace WireMock.Net.ConsoleApplication
|
||||
.WithBody(@"{ ""result"": ""data posted with FUNC 201""}"));
|
||||
|
||||
server
|
||||
.Given(Request.Create().WithUrl("/data").UsingPost())
|
||||
.Given(Request.Create().WithUrl("/data", "/ax").UsingPost())
|
||||
.RespondWith(Response.Create()
|
||||
.WithStatusCode(201)
|
||||
.WithHeader("Content-Type", "application/json")
|
||||
|
||||
@@ -17,7 +17,7 @@ namespace WireMock.Matchers
|
||||
/// Initializes a new instance of the <see cref="RegexMatcher"/> class.
|
||||
/// </summary>
|
||||
/// <param name="pattern">The pattern.</param>
|
||||
public RegexMatcher([NotNull] string pattern)
|
||||
public RegexMatcher([NotNull, RegexPattern] string pattern)
|
||||
{
|
||||
Check.NotNull(pattern, nameof(pattern));
|
||||
|
||||
|
||||
18
src/WireMock/Matchers/Request/CompositeMatcherType.cs
Normal file
18
src/WireMock/Matchers/Request/CompositeMatcherType.cs
Normal file
@@ -0,0 +1,18 @@
|
||||
namespace WireMock.Matchers.Request
|
||||
{
|
||||
/// <summary>
|
||||
/// CompositeMatcherType
|
||||
/// </summary>
|
||||
public enum CompositeMatcherType
|
||||
{
|
||||
/// <summary>
|
||||
/// And
|
||||
/// </summary>
|
||||
And = 0,
|
||||
|
||||
/// <summary>
|
||||
/// Or
|
||||
/// </summary>
|
||||
Or = 1
|
||||
}
|
||||
}
|
||||
@@ -10,7 +10,12 @@ namespace WireMock.Matchers.Request
|
||||
public class RequestMessageBodyMatcher : IRequestMatcher
|
||||
{
|
||||
/// <summary>
|
||||
/// The bodyRegex.
|
||||
/// The body.
|
||||
/// </summary>
|
||||
private readonly string _body;
|
||||
|
||||
/// <summary>
|
||||
/// The body as byte[].
|
||||
/// </summary>
|
||||
private readonly byte[] _bodyData;
|
||||
|
||||
@@ -35,10 +40,10 @@ namespace WireMock.Matchers.Request
|
||||
/// <param name="body">
|
||||
/// The body Regex pattern.
|
||||
/// </param>
|
||||
public RequestMessageBodyMatcher([NotNull, RegexPattern] string body)
|
||||
public RequestMessageBodyMatcher([NotNull] string body)
|
||||
{
|
||||
Check.NotNull(body, nameof(body));
|
||||
_matcher = new RegexMatcher(body);
|
||||
_body = body;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -101,6 +106,9 @@ namespace WireMock.Matchers.Request
|
||||
if (_matcher != null)
|
||||
return _matcher.IsMatch(requestMessage.Body);
|
||||
|
||||
if (_body != null)
|
||||
return requestMessage.Body == _body;
|
||||
|
||||
if (_bodyData != null)
|
||||
return requestMessage.BodyAsBytes == _bodyData;
|
||||
|
||||
|
||||
@@ -1,13 +1,16 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using JetBrains.Annotations;
|
||||
|
||||
namespace WireMock.Matchers.Request
|
||||
{
|
||||
/// <summary>
|
||||
/// The composite request matcher.
|
||||
/// </summary>
|
||||
public abstract class RequestMessageCompositeMatcher : IRequestMatcher
|
||||
public class RequestMessageCompositeMatcher : IRequestMatcher
|
||||
{
|
||||
private readonly CompositeMatcherType _type;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the request matchers.
|
||||
/// </summary>
|
||||
@@ -17,14 +20,13 @@ namespace WireMock.Matchers.Request
|
||||
public IEnumerable<IRequestMatcher> RequestMatchers { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RequestMessageCompositeMatcher"/> class.
|
||||
/// The constructor.
|
||||
/// Initializes a new instance of the <see cref="RequestMessageCompositeMatcher"/> class.
|
||||
/// </summary>
|
||||
/// <param name="requestMatchers">
|
||||
/// The <see cref="IEnumerable<IRequestMatcher>"/> request matchers.
|
||||
/// </param>
|
||||
protected RequestMessageCompositeMatcher(IEnumerable<IRequestMatcher> requestMatchers)
|
||||
/// <param name="requestMatchers">The request matchers.</param>
|
||||
/// <param name="type">The CompositeMatcherType type (Defaults to 'And')</param>
|
||||
public RequestMessageCompositeMatcher([NotNull] IEnumerable<IRequestMatcher> requestMatchers, CompositeMatcherType type = CompositeMatcherType.And)
|
||||
{
|
||||
_type = type;
|
||||
RequestMatchers = requestMatchers;
|
||||
}
|
||||
|
||||
@@ -37,7 +39,9 @@ namespace WireMock.Matchers.Request
|
||||
/// </returns>
|
||||
public bool IsMatch(RequestMessage requestMessage)
|
||||
{
|
||||
return RequestMatchers.All(spec => spec.IsMatch(requestMessage));
|
||||
return _type == CompositeMatcherType.And ?
|
||||
RequestMatchers.All(spec => spec.IsMatch(requestMessage)) :
|
||||
RequestMatchers.Any(spec => spec.IsMatch(requestMessage));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text.RegularExpressions;
|
||||
using JetBrains.Annotations;
|
||||
using WireMock.Validation;
|
||||
|
||||
@@ -17,9 +16,9 @@ namespace WireMock.Matchers.Request
|
||||
private readonly string _name;
|
||||
|
||||
/// <summary>
|
||||
/// The patternRegex.
|
||||
/// The matcher.
|
||||
/// </summary>
|
||||
private readonly Regex _patternRegex;
|
||||
private readonly IMatcher _matcher;
|
||||
|
||||
/// <summary>
|
||||
/// The header function
|
||||
@@ -29,17 +28,16 @@ namespace WireMock.Matchers.Request
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RequestMessageHeaderMatcher"/> class.
|
||||
/// </summary>
|
||||
/// <param name="name">
|
||||
/// The name.
|
||||
/// </param>
|
||||
/// <param name="pattern">
|
||||
/// The pattern.
|
||||
/// </param>
|
||||
/// <param name="name">The name.</param>
|
||||
/// <param name="pattern">The pattern.</param>
|
||||
/// <param name="ignoreCase">The ignoreCase.</param>
|
||||
public RequestMessageHeaderMatcher([NotNull] string name, [NotNull, RegexPattern] string pattern, bool ignoreCase = true)
|
||||
public RequestMessageHeaderMatcher([NotNull] string name, [NotNull] string pattern, bool ignoreCase = true)
|
||||
{
|
||||
Check.NotNull(name, nameof(name));
|
||||
Check.NotNull(pattern, nameof(pattern));
|
||||
|
||||
_name = name;
|
||||
_patternRegex = ignoreCase ? new Regex(pattern, RegexOptions.IgnoreCase) : new Regex(pattern);
|
||||
_matcher = new WildcardMatcher(pattern, ignoreCase);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -63,11 +61,11 @@ namespace WireMock.Matchers.Request
|
||||
/// </returns>
|
||||
public bool IsMatch(RequestMessage requestMessage)
|
||||
{
|
||||
if (_patternRegex == null)
|
||||
if (_headerFunc != null)
|
||||
return _headerFunc(requestMessage.Headers);
|
||||
|
||||
string headerValue = requestMessage.Headers[_name];
|
||||
return _patternRegex.IsMatch(headerValue);
|
||||
return _matcher.IsMatch(headerValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,4 @@
|
||||
using System;
|
||||
using System.Text.RegularExpressions;
|
||||
using JetBrains.Annotations;
|
||||
using WireMock.Validation;
|
||||
|
||||
@@ -11,32 +10,45 @@ namespace WireMock.Matchers.Request
|
||||
public class RequestMessagePathMatcher : IRequestMatcher
|
||||
{
|
||||
/// <summary>
|
||||
/// The pathRegex.
|
||||
/// The matcher.
|
||||
/// </summary>
|
||||
private readonly Regex _pathRegex;
|
||||
private readonly string _path;
|
||||
|
||||
/// <summary>
|
||||
/// The url function
|
||||
/// The matcher.
|
||||
/// </summary>
|
||||
private readonly IMatcher _matcher;
|
||||
|
||||
/// <summary>
|
||||
/// The path function
|
||||
/// </summary>
|
||||
private readonly Func<string, bool> _pathFunc;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RequestMessagePathMatcher"/> class.
|
||||
/// </summary>
|
||||
/// <param name="path">
|
||||
/// The path Regex pattern.
|
||||
/// </param>
|
||||
public RequestMessagePathMatcher([NotNull, RegexPattern] string path)
|
||||
/// <param name="path">The path.</param>
|
||||
public RequestMessagePathMatcher([NotNull] string path)
|
||||
{
|
||||
Check.NotNull(path, nameof(path));
|
||||
_pathRegex = new Regex(path);
|
||||
_path = path;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RequestMessagePathMatcher"/> class.
|
||||
/// </summary>
|
||||
/// <param name="matcher">The matcher.</param>
|
||||
public RequestMessagePathMatcher([NotNull] IMatcher matcher)
|
||||
{
|
||||
Check.NotNull(matcher, nameof(matcher));
|
||||
_matcher = matcher;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RequestMessagePathMatcher"/> class.
|
||||
/// </summary>
|
||||
/// <param name="func">
|
||||
/// The url func.
|
||||
/// The path func.
|
||||
/// </param>
|
||||
public RequestMessagePathMatcher([NotNull] Func<string, bool> func)
|
||||
{
|
||||
@@ -53,7 +65,16 @@ namespace WireMock.Matchers.Request
|
||||
/// </returns>
|
||||
public bool IsMatch(RequestMessage requestMessage)
|
||||
{
|
||||
return _pathRegex?.IsMatch(requestMessage.Path) ?? _pathFunc(requestMessage.Path);
|
||||
if (_path != null)
|
||||
return string.CompareOrdinal(_path, requestMessage.Path) == 0;
|
||||
|
||||
if (_matcher != null)
|
||||
return _matcher.IsMatch(requestMessage.Path);
|
||||
|
||||
if (_pathFunc != null)
|
||||
return _pathFunc(requestMessage.Path);
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,4 @@
|
||||
using System;
|
||||
using System.Text.RegularExpressions;
|
||||
using JetBrains.Annotations;
|
||||
using WireMock.Validation;
|
||||
|
||||
@@ -11,9 +10,9 @@ namespace WireMock.Matchers.Request
|
||||
public class RequestMessageUrlMatcher : IRequestMatcher
|
||||
{
|
||||
/// <summary>
|
||||
/// The urlRegex.
|
||||
/// The matcher.
|
||||
/// </summary>
|
||||
private readonly Regex _urlRegex;
|
||||
private readonly IMatcher _matcher;
|
||||
|
||||
/// <summary>
|
||||
/// The url function
|
||||
@@ -23,13 +22,20 @@ namespace WireMock.Matchers.Request
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RequestMessageUrlMatcher"/> class.
|
||||
/// </summary>
|
||||
/// <param name="url">
|
||||
/// The url Regex pattern.
|
||||
/// </param>
|
||||
public RequestMessageUrlMatcher([NotNull, RegexPattern] string url)
|
||||
/// <param name="url">The url.</param>
|
||||
public RequestMessageUrlMatcher([NotNull] string url) : this(new WildcardMatcher(url))
|
||||
{
|
||||
Check.NotNull(url, nameof(url));
|
||||
_urlRegex = new Regex(url);
|
||||
_matcher = new WildcardMatcher(url);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RequestMessageUrlMatcher"/> class.
|
||||
/// </summary>
|
||||
/// <param name="matcher">The matcher.</param>
|
||||
public RequestMessageUrlMatcher([NotNull] IMatcher matcher)
|
||||
{
|
||||
Check.NotNull(matcher, nameof(matcher));
|
||||
_matcher = matcher;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -38,7 +44,7 @@ namespace WireMock.Matchers.Request
|
||||
/// <param name="func">
|
||||
/// The url func.
|
||||
/// </param>
|
||||
public RequestMessageUrlMatcher(Func<string, bool> func)
|
||||
public RequestMessageUrlMatcher([NotNull] Func<string, bool> func)
|
||||
{
|
||||
Check.NotNull(func, nameof(func));
|
||||
_urlFunc = func;
|
||||
@@ -53,7 +59,13 @@ namespace WireMock.Matchers.Request
|
||||
/// </returns>
|
||||
public bool IsMatch(RequestMessage requestMessage)
|
||||
{
|
||||
return _urlRegex?.IsMatch(requestMessage.Url) ?? _urlFunc(requestMessage.Url);
|
||||
if (_matcher != null)
|
||||
return _matcher.IsMatch(requestMessage.Path);
|
||||
|
||||
if (_urlFunc != null)
|
||||
return _urlFunc(requestMessage.Url);
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
102
src/WireMock/Matchers/WildcardMatcher.cs
Normal file
102
src/WireMock/Matchers/WildcardMatcher.cs
Normal file
@@ -0,0 +1,102 @@
|
||||
using JetBrains.Annotations;
|
||||
using WireMock.Validation;
|
||||
|
||||
namespace WireMock.Matchers
|
||||
{
|
||||
/// <summary>
|
||||
/// WildcardMatcher
|
||||
/// </summary>
|
||||
/// <seealso cref="WireMock.Matchers.IMatcher" />
|
||||
public class WildcardMatcher : IMatcher
|
||||
{
|
||||
private readonly string _pattern;
|
||||
private readonly bool _ignoreCase;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RegexMatcher"/> class.
|
||||
/// </summary>
|
||||
/// <param name="pattern">The pattern.</param>
|
||||
/// <param name="ignoreCase">IgnoreCase</param>
|
||||
public WildcardMatcher([NotNull] string pattern, bool ignoreCase = false)
|
||||
{
|
||||
Check.NotNull(pattern, nameof(pattern));
|
||||
|
||||
_pattern = pattern;
|
||||
_ignoreCase = ignoreCase;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the specified input is match.
|
||||
/// </summary>
|
||||
/// <param name="input">The input.</param>
|
||||
/// <returns>
|
||||
/// <c>true</c> if the specified input is match; otherwise, <c>false</c>.
|
||||
/// </returns>
|
||||
public bool IsMatch(string input)
|
||||
{
|
||||
return MatchWildcardString(_pattern, input);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Copy/paste from http://www.codeproject.com/Tips/57304/Use-wildcard-characters-and-to-compare-strings
|
||||
/// </summary>
|
||||
private bool MatchWildcardString(string pattern, string input)
|
||||
{
|
||||
if (input != null && _ignoreCase)
|
||||
input = input.ToLower();
|
||||
|
||||
if (pattern != null && _ignoreCase)
|
||||
pattern = pattern.ToLower();
|
||||
|
||||
if (string.CompareOrdinal(pattern, input) == 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(input))
|
||||
{
|
||||
return string.IsNullOrEmpty(pattern.Trim('*'));
|
||||
}
|
||||
|
||||
if (pattern.Length == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (pattern[0] == '?')
|
||||
{
|
||||
return MatchWildcardString(pattern.Substring(1), input.Substring(1));
|
||||
}
|
||||
|
||||
if (pattern[pattern.Length - 1] == '?')
|
||||
{
|
||||
return MatchWildcardString(pattern.Substring(0, pattern.Length - 1), input.Substring(0, input.Length - 1));
|
||||
}
|
||||
|
||||
if (pattern[0] == '*')
|
||||
{
|
||||
if (MatchWildcardString(pattern.Substring(1), input))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return MatchWildcardString(pattern, input.Substring(1));
|
||||
}
|
||||
|
||||
if (pattern[pattern.Length - 1] == '*')
|
||||
{
|
||||
if (MatchWildcardString(pattern.Substring(0, pattern.Length - 1), input))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return MatchWildcardString(pattern, input.Substring(0, input.Length - 1));
|
||||
}
|
||||
|
||||
if (pattern[0] == input[0])
|
||||
{
|
||||
return MatchWildcardString(pattern.Substring(1), input.Substring(1));
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -34,6 +34,6 @@ namespace WireMock.RequestBuilders
|
||||
/// <returns>
|
||||
/// The <see cref="IHeadersRequestBuilder"/>.
|
||||
/// </returns>
|
||||
IHeadersRequestBuilder WithHeader([NotNull] Func<IDictionary<string, string>, bool> func);
|
||||
IHeadersRequestBuilder WithHeader([NotNull] params Func<IDictionary<string, string>, bool>[] func);
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using JetBrains.Annotations;
|
||||
using WireMock.Matchers;
|
||||
|
||||
namespace WireMock.RequestBuilders
|
||||
{
|
||||
@@ -8,32 +9,46 @@ namespace WireMock.RequestBuilders
|
||||
/// </summary>
|
||||
public interface IUrlAndPathRequestBuilder : IVerbRequestBuilder
|
||||
{
|
||||
/// <summary>
|
||||
/// The with url.
|
||||
/// </summary>
|
||||
/// <param name="matcher">The matcher.</param>
|
||||
/// <returns>The <see cref="IUrlAndPathRequestBuilder"/>.</returns>
|
||||
IUrlAndPathRequestBuilder WithUrl([NotNull] IMatcher matcher);
|
||||
|
||||
/// <summary>
|
||||
/// The with url.
|
||||
/// </summary>
|
||||
/// <param name="url">The url.</param>
|
||||
/// <returns>The <see cref="IUrlAndPathRequestBuilder"/>.</returns>
|
||||
IUrlAndPathRequestBuilder WithUrl([NotNull] string url);
|
||||
IUrlAndPathRequestBuilder WithUrl([NotNull] params string[] url);
|
||||
|
||||
/// <summary>
|
||||
/// The with url.
|
||||
/// </summary>
|
||||
/// <param name="func">The url func.</param>
|
||||
/// <returns>The <see cref="IUrlAndPathRequestBuilder"/>.</returns>
|
||||
IUrlAndPathRequestBuilder WithUrl([NotNull] Func<string, bool> func);
|
||||
IUrlAndPathRequestBuilder WithUrl([NotNull] params Func<string, bool>[] func);
|
||||
|
||||
/// <summary>
|
||||
/// The with path.
|
||||
/// </summary>
|
||||
/// <param name="matcher">The matcher.</param>
|
||||
/// <returns>The <see cref="IUrlAndPathRequestBuilder"/>.</returns>
|
||||
IUrlAndPathRequestBuilder WithPath([NotNull] IMatcher matcher);
|
||||
|
||||
/// <summary>
|
||||
/// The with path.
|
||||
/// </summary>
|
||||
/// <param name="path">The path.</param>
|
||||
/// <returns>The <see cref="IUrlAndPathRequestBuilder"/>.</returns>
|
||||
IUrlAndPathRequestBuilder WithPath([NotNull] string path);
|
||||
IUrlAndPathRequestBuilder WithPath([NotNull] params string[] path);
|
||||
|
||||
/// <summary>
|
||||
/// The with path.
|
||||
/// </summary>
|
||||
/// <param name="func">The path func.</param>
|
||||
/// <returns>The <see cref="IUrlAndPathRequestBuilder"/>.</returns>
|
||||
IUrlAndPathRequestBuilder WithPath([NotNull] Func<string, bool> func);
|
||||
IUrlAndPathRequestBuilder WithPath([NotNull] params Func<string, bool>[] func);
|
||||
}
|
||||
}
|
||||
@@ -34,44 +34,76 @@ namespace WireMock.RequestBuilders
|
||||
/// <summary>
|
||||
/// The with url.
|
||||
/// </summary>
|
||||
/// <param name="url">The url.</param>
|
||||
/// <param name="matcher">The matcher.</param>
|
||||
/// <returns>The <see cref="IUrlAndPathRequestBuilder"/>.</returns>
|
||||
public IUrlAndPathRequestBuilder WithUrl(string url)
|
||||
public IUrlAndPathRequestBuilder WithUrl(IMatcher matcher)
|
||||
{
|
||||
_requestMatchers.Add(new RequestMessageUrlMatcher(url));
|
||||
_requestMatchers.Add(new RequestMessageUrlMatcher(matcher));
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The with url.
|
||||
/// </summary>
|
||||
/// <param name="func">The url func.</param>
|
||||
/// <param name="urls">The urls.</param>
|
||||
/// <returns>The <see cref="IUrlAndPathRequestBuilder"/>.</returns>
|
||||
public IUrlAndPathRequestBuilder WithUrl(Func<string, bool> func)
|
||||
public IUrlAndPathRequestBuilder WithUrl(params string[] urls)
|
||||
{
|
||||
_requestMatchers.Add(new RequestMessageUrlMatcher(func));
|
||||
var or = new RequestMessageCompositeMatcher(urls.Select(url => new RequestMessageUrlMatcher(url)), CompositeMatcherType.Or);
|
||||
_requestMatchers.Add(or);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The with url.
|
||||
/// </summary>
|
||||
/// <param name="funcs">The url func.</param>
|
||||
/// <returns>The <see cref="IUrlAndPathRequestBuilder"/>.</returns>
|
||||
public IUrlAndPathRequestBuilder WithUrl(params Func<string, bool>[] funcs)
|
||||
{
|
||||
var or = new RequestMessageCompositeMatcher(funcs.Select(func => new RequestMessageUrlMatcher(func)), CompositeMatcherType.Or);
|
||||
_requestMatchers.Add(or);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The with url.
|
||||
/// </summary>
|
||||
/// <param name="matcher">The matcher.</param>
|
||||
/// <returns>The <see cref="IUrlAndPathRequestBuilder"/>.</returns>
|
||||
public IUrlAndPathRequestBuilder WithPath(IMatcher matcher)
|
||||
{
|
||||
_requestMatchers.Add(new RequestMessagePathMatcher(matcher));
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The with path.
|
||||
/// </summary>
|
||||
/// <param name="path">The path.</param>
|
||||
/// <param name="paths">The path.</param>
|
||||
/// <returns>The <see cref="IUrlAndPathRequestBuilder"/>.</returns>
|
||||
public IUrlAndPathRequestBuilder WithPath(string path)
|
||||
public IUrlAndPathRequestBuilder WithPath(params string[] paths)
|
||||
{
|
||||
_requestMatchers.Add(new RequestMessagePathMatcher(path));
|
||||
var or = new RequestMessageCompositeMatcher(paths.Select(path => new RequestMessageUrlMatcher(path)), CompositeMatcherType.Or);
|
||||
_requestMatchers.Add(or);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The with path.
|
||||
/// </summary>
|
||||
/// <param name="func">The path func.</param>
|
||||
/// <param name="funcs">The path func.</param>
|
||||
/// <returns>The <see cref="IUrlAndPathRequestBuilder"/>.</returns>
|
||||
public IUrlAndPathRequestBuilder WithPath(Func<string, bool> func)
|
||||
public IUrlAndPathRequestBuilder WithPath(params Func<string, bool>[] funcs)
|
||||
{
|
||||
_requestMatchers.Add(new RequestMessagePathMatcher(func));
|
||||
var or = new RequestMessageCompositeMatcher(funcs.Select(func => new RequestMessageUrlMatcher(func)), CompositeMatcherType.Or);
|
||||
_requestMatchers.Add(or);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -295,15 +327,15 @@ namespace WireMock.RequestBuilders
|
||||
/// <summary>
|
||||
/// The with header.
|
||||
/// </summary>
|
||||
/// <param name="func">
|
||||
/// The func.
|
||||
/// </param>
|
||||
/// <param name="funcs">The func.</param>
|
||||
/// <returns>
|
||||
/// The <see cref="IHeadersRequestBuilder"/>.
|
||||
/// </returns>
|
||||
public IHeadersRequestBuilder WithHeader(Func<IDictionary<string, string>, bool> func)
|
||||
public IHeadersRequestBuilder WithHeader(params Func<IDictionary<string, string>, bool>[] funcs)
|
||||
{
|
||||
_requestMatchers.Add(new RequestMessageHeaderMatcher(func));
|
||||
var or = new RequestMessageCompositeMatcher(funcs.Select(func => new RequestMessageHeaderMatcher(func)), CompositeMatcherType.Or);
|
||||
_requestMatchers.Add(or);
|
||||
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
using NFluent;
|
||||
using NUnit.Framework;
|
||||
using WireMock.Matchers;
|
||||
using WireMock.RequestBuilders;
|
||||
using WireMock.ResponseBuilders;
|
||||
using WireMock.Server;
|
||||
@@ -113,7 +114,7 @@ namespace WireMock.Net.Tests
|
||||
await new HttpClient().GetAsync("http://localhost:" + _server.Port + "/bar");
|
||||
|
||||
// then
|
||||
var result = _server.SearchLogsFor(Request.Create().WithUrl("/b.*")).ToList();
|
||||
var result = _server.SearchLogsFor(Request.Create().WithUrl(new RegexMatcher("^/b.*"))).ToList();
|
||||
Check.That(result).HasSize(1);
|
||||
|
||||
var requestLogged = result.First();
|
||||
@@ -195,7 +196,7 @@ namespace WireMock.Net.Tests
|
||||
.WithUrl("/*"))
|
||||
.RespondWith(Response.Create()
|
||||
.WithBody(@"{ msg: ""Hello world!""}")
|
||||
.WithDelay(TimeSpan.FromMilliseconds(2000)));
|
||||
.WithDelay(TimeSpan.FromMilliseconds(200)));
|
||||
|
||||
// when
|
||||
var watch = new Stopwatch();
|
||||
@@ -204,7 +205,7 @@ namespace WireMock.Net.Tests
|
||||
watch.Stop();
|
||||
|
||||
// then
|
||||
Check.That(watch.ElapsedMilliseconds).IsGreaterThan(2000);
|
||||
Check.That(watch.ElapsedMilliseconds).IsGreaterThan(200);
|
||||
}
|
||||
|
||||
[Test]
|
||||
@@ -212,12 +213,10 @@ namespace WireMock.Net.Tests
|
||||
{
|
||||
// given
|
||||
_server = FluentMockServer.Start();
|
||||
_server.AddRequestProcessingDelay(TimeSpan.FromMilliseconds(2000));
|
||||
_server.AddRequestProcessingDelay(TimeSpan.FromMilliseconds(200));
|
||||
_server
|
||||
.Given(Request.Create()
|
||||
.WithUrl("/*"))
|
||||
.RespondWith(Response.Create()
|
||||
.WithBody(@"{ msg: ""Hello world!""}"));
|
||||
.Given(Request.Create().WithUrl("/*"))
|
||||
.RespondWith(Response.Create().WithBody(@"{ msg: ""Hello world!""}"));
|
||||
|
||||
// when
|
||||
var watch = new Stopwatch();
|
||||
@@ -226,7 +225,7 @@ namespace WireMock.Net.Tests
|
||||
watch.Stop();
|
||||
|
||||
// then
|
||||
Check.That(watch.ElapsedMilliseconds).IsGreaterThan(2000);
|
||||
Check.That(watch.ElapsedMilliseconds).IsGreaterThan(200);
|
||||
}
|
||||
|
||||
[TearDown]
|
||||
|
||||
@@ -26,11 +26,25 @@ namespace WireMock.Net.Tests
|
||||
Check.That(spec.IsMatch(request)).IsTrue();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Should_specify_requests_matching_given_urls()
|
||||
{
|
||||
var requestBuilder = Request.Create().WithUrl("/x1", "/x2");
|
||||
|
||||
string bodyAsString = "whatever";
|
||||
byte[] body = Encoding.UTF8.GetBytes(bodyAsString);
|
||||
var request1 = new RequestMessage(new Uri("http://localhost/x1"), "blabla", body, bodyAsString);
|
||||
var request2 = new RequestMessage(new Uri("http://localhost/x2"), "blabla", body, bodyAsString);
|
||||
|
||||
Check.That(requestBuilder.IsMatch(request1)).IsTrue();
|
||||
Check.That(requestBuilder.IsMatch(request2)).IsTrue();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Should_specify_requests_matching_given_url_prefix()
|
||||
{
|
||||
// given
|
||||
var spec = Request.Create().WithUrl("/foo*");
|
||||
var spec = Request.Create().WithUrl(new RegexMatcher("^/foo"));
|
||||
|
||||
// when
|
||||
string bodyAsString = "whatever";
|
||||
@@ -230,7 +244,7 @@ namespace WireMock.Net.Tests
|
||||
// when
|
||||
string bodyAsString = "whatever";
|
||||
byte[] body = Encoding.UTF8.GetBytes(bodyAsString);
|
||||
var request = new RequestMessage(new Uri("http://localhost/foo"), "PUT", body, bodyAsString, new Dictionary<string, string> { { "X-toto", "TaTaTa" } });
|
||||
var request = new RequestMessage(new Uri("http://localhost/foo"), "PUT", body, bodyAsString, new Dictionary<string, string> { { "X-toto", "TaTa" } });
|
||||
|
||||
// then
|
||||
Check.That(spec.IsMatch(request)).IsTrue();
|
||||
@@ -252,10 +266,10 @@ namespace WireMock.Net.Tests
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Should_specify_requests_matching_given_body_as_regex()
|
||||
public void Should_specify_requests_matching_given_body_as_wildcard()
|
||||
{
|
||||
// given
|
||||
var spec = Request.Create().WithUrl("/foo").UsingAnyVerb().WithBody("H.*o");
|
||||
var spec = Request.Create().WithUrl("/foo").UsingAnyVerb().WithBody(new WildcardMatcher("H*o*"));
|
||||
|
||||
// when
|
||||
string bodyAsString = "Hello world!";
|
||||
|
||||
59
test/WireMock.Net.Tests/WildcardMatcherTest.cs
Normal file
59
test/WireMock.Net.Tests/WildcardMatcherTest.cs
Normal file
@@ -0,0 +1,59 @@
|
||||
using NUnit.Framework;
|
||||
using WireMock.Matchers;
|
||||
|
||||
namespace WireMock.Net.Tests
|
||||
{
|
||||
[TestFixture]
|
||||
public class WildcardMatcherTest
|
||||
{
|
||||
[Test]
|
||||
public void WildcardMatcher_patterns_positive()
|
||||
{
|
||||
var tests = new[]
|
||||
{
|
||||
new { p = "*", i = "" },
|
||||
new { p = "?", i = " " },
|
||||
new { p = "*", i = "a" },
|
||||
new { p = "*", i = "ab" },
|
||||
new { p = "?", i = "a" },
|
||||
new { p = "*?", i = "abc" },
|
||||
new { p = "?*", i = "abc" },
|
||||
new { p = "abc", i = "abc" },
|
||||
new { p = "abc*", i = "abc" },
|
||||
new { p = "abc*", i = "abcd" },
|
||||
new { p = "*abc*", i = "abc" },
|
||||
new { p = "*a*bc*", i = "abc" },
|
||||
new { p = "*a*b?", i = "aXXXbc" }
|
||||
};
|
||||
foreach (var test in tests)
|
||||
{
|
||||
var matcher = new WildcardMatcher(test.p);
|
||||
Assert.IsTrue(matcher.IsMatch(test.i), "p = " + test.p + ", i = " + test.i);
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void WildcardMatcher_patterns_negative()
|
||||
{
|
||||
var tests = new[]
|
||||
{
|
||||
new { p = "*a", i = ""},
|
||||
new { p = "a*", i = ""},
|
||||
new { p = "?", i = ""},
|
||||
new { p = "*b*", i = "a"},
|
||||
new { p = "b*a", i = "ab"},
|
||||
new { p = "??", i = "a"},
|
||||
new { p = "*?", i = ""},
|
||||
new { p = "??*", i = "a"},
|
||||
new { p = "*abc", i = "abX"},
|
||||
new { p = "*abc*", i = "Xbc"},
|
||||
new { p = "*a*bc*", i = "ac"}
|
||||
};
|
||||
foreach (var test in tests)
|
||||
{
|
||||
var matcher = new WildcardMatcher(test.p);
|
||||
Assert.IsFalse(matcher.IsMatch(test.i), "p = " + test.p + ", i = " + test.i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -67,6 +67,7 @@
|
||||
<Compile Include="RequestTests.cs" />
|
||||
<Compile Include="RequestMessageTests.cs" />
|
||||
<Compile Include="ResponseTests.cs" />
|
||||
<Compile Include="WildcardMatcherTest.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="packages.config" />
|
||||
|
||||
Reference in New Issue
Block a user