Add ThrowExceptionWhenMatcherFails option to all Matchers (#500)

* .

* ut

* IMatcher.ThrowException

* settings

* more tests

* linq matcher throw

* .

* .
This commit is contained in:
Stef Heyenrath
2020-08-13 08:58:18 +02:00
committed by GitHub
parent 0d102f3af4
commit 06be3aff95
29 changed files with 1798 additions and 1607 deletions
@@ -26,13 +26,18 @@
public int? MaxRequestLogCount { get; set; } public int? MaxRequestLogCount { get; set; }
/// <summary> /// <summary>
/// Gets or sets wether to allow a body for all HTTP methods. /// Allow a Body for all HTTP Methods. (default set to false).
/// </summary> /// </summary>
public bool? AllowBodyForAllHttpMethods { get; set; } public bool? AllowBodyForAllHttpMethods { get; set; }
/// <summary> /// <summary>
/// Gets or sets wether to handle all requests synchronously. /// Handle all requests synchronously. (default set to false).
/// </summary> /// </summary>
public bool? HandleRequestsSynchronously { get; set; } public bool? HandleRequestsSynchronously { get; set; }
/// <summary>
/// Throw an exception when the Matcher fails because of invalid input. (default set to false).
/// </summary>
public bool? ThrowExceptionWhenMatcherFails { get; set; }
} }
} }
@@ -29,6 +29,9 @@ namespace WireMock.Matchers
public MatchBehaviour MatchBehaviour { get; } public MatchBehaviour MatchBehaviour { get; }
/// <inheritdoc cref="IMatcher.ThrowException"/>
public bool ThrowException { get; }
private readonly string[] _patterns; private readonly string[] _patterns;
/// <summary> /// <summary>
@@ -49,6 +52,7 @@ namespace WireMock.Matchers
Check.NotNull(patterns, nameof(patterns)); Check.NotNull(patterns, nameof(patterns));
MatchBehaviour = matchBehaviour; MatchBehaviour = matchBehaviour;
ThrowException = false;
_patterns = patterns; _patterns = patterns;
} }
@@ -156,7 +160,7 @@ namespace WireMock.Matchers
#if NETSTANDARD2_0 #if NETSTANDARD2_0
script = csscript.GenericExtensions.CreateObject(assembly, "*"); script = csscript.GenericExtensions.CreateObject(assembly, "*");
#else #else
script = CSScriptLib.ReflectionExtensions.CreateObject(assembly,"*"); script = CSScriptLib.ReflectionExtensions.CreateObject(assembly, "*");
#endif #endif
} }
catch (Exception ex) catch (Exception ex)
@@ -45,7 +45,9 @@ namespace WireMock.Matchers
/// <param name="matchBehaviour">The match behaviour.</param> /// <param name="matchBehaviour">The match behaviour.</param>
/// <param name="patterns">The patterns.</param> /// <param name="patterns">The patterns.</param>
/// <param name="ignoreCase">IgnoreCase (default false)</param> /// <param name="ignoreCase">IgnoreCase (default false)</param>
public ContentTypeMatcher(MatchBehaviour matchBehaviour, [NotNull] string[] patterns, bool ignoreCase = false) : base(matchBehaviour, patterns, ignoreCase) /// <param name="throwException">Throw an exception when the internal matching fails because of invalid input.</param>
public ContentTypeMatcher(MatchBehaviour matchBehaviour, [NotNull] string[] patterns, bool ignoreCase = false, bool throwException = false) :
base(matchBehaviour, patterns, ignoreCase, throwException)
{ {
_patterns = patterns; _patterns = patterns;
} }
+8 -3
View File
@@ -15,11 +15,14 @@ namespace WireMock.Matchers
/// <inheritdoc cref="IMatcher.MatchBehaviour"/> /// <inheritdoc cref="IMatcher.MatchBehaviour"/>
public MatchBehaviour MatchBehaviour { get; } public MatchBehaviour MatchBehaviour { get; }
/// <inheritdoc cref="IMatcher.ThrowException"/>
public bool ThrowException { get; }
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="ExactMatcher"/> class. /// Initializes a new instance of the <see cref="ExactMatcher"/> class.
/// </summary> /// </summary>
/// <param name="values">The values.</param> /// <param name="values">The values.</param>
public ExactMatcher([NotNull] params string[] values) : this(MatchBehaviour.AcceptOnMatch, values) public ExactMatcher([NotNull] params string[] values) : this(MatchBehaviour.AcceptOnMatch, false, values)
{ {
} }
@@ -27,13 +30,15 @@ namespace WireMock.Matchers
/// Initializes a new instance of the <see cref="ExactMatcher"/> class. /// Initializes a new instance of the <see cref="ExactMatcher"/> class.
/// </summary> /// </summary>
/// <param name="matchBehaviour">The match behaviour.</param> /// <param name="matchBehaviour">The match behaviour.</param>
/// <param name="throwException">Throw an exception when the internal matching fails because of invalid input.</param>
/// <param name="values">The values.</param> /// <param name="values">The values.</param>
public ExactMatcher(MatchBehaviour matchBehaviour, [NotNull] params string[] values) public ExactMatcher(MatchBehaviour matchBehaviour, bool throwException = false, [NotNull] params string[] values)
{ {
Check.HasNoNulls(values, nameof(values)); Check.HasNoNulls(values, nameof(values));
_values = values;
MatchBehaviour = matchBehaviour; MatchBehaviour = matchBehaviour;
ThrowException = throwException;
_values = values;
} }
/// <inheritdoc cref="IStringMatcher.IsMatch"/> /// <inheritdoc cref="IStringMatcher.IsMatch"/>
@@ -23,6 +23,9 @@ namespace WireMock.Matchers
/// <inheritdoc cref="IMatcher.MatchBehaviour"/> /// <inheritdoc cref="IMatcher.MatchBehaviour"/>
public MatchBehaviour MatchBehaviour { get; } public MatchBehaviour MatchBehaviour { get; }
/// <inheritdoc cref="IMatcher.ThrowException"/>
public bool ThrowException { get; }
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="ExactObjectMatcher"/> class. /// Initializes a new instance of the <see cref="ExactObjectMatcher"/> class.
/// </summary> /// </summary>
@@ -56,13 +59,15 @@ namespace WireMock.Matchers
/// Initializes a new instance of the <see cref="ExactObjectMatcher"/> class. /// Initializes a new instance of the <see cref="ExactObjectMatcher"/> class.
/// </summary> /// </summary>
/// <param name="matchBehaviour">The match behaviour.</param> /// <param name="matchBehaviour">The match behaviour.</param>
/// <param name="throwException">Throw an exception when the internal matching fails because of invalid input.</param>
/// <param name="value">The value.</param> /// <param name="value">The value.</param>
public ExactObjectMatcher(MatchBehaviour matchBehaviour, [NotNull] byte[] value) public ExactObjectMatcher(MatchBehaviour matchBehaviour, [NotNull] byte[] value, bool throwException = false)
{ {
Check.NotNull(value, nameof(value)); Check.NotNull(value, nameof(value));
ValueAsBytes = value;
MatchBehaviour = matchBehaviour; MatchBehaviour = matchBehaviour;
ThrowException = throwException;
ValueAsBytes = value;
} }
/// <inheritdoc cref="IObjectMatcher.IsMatch"/> /// <inheritdoc cref="IObjectMatcher.IsMatch"/>
+5
View File
@@ -14,5 +14,10 @@
/// Gets the match behaviour. /// Gets the match behaviour.
/// </summary> /// </summary>
MatchBehaviour MatchBehaviour { get; } MatchBehaviour MatchBehaviour { get; }
/// <summary>
/// Should this matcher throw an exception?
/// </summary>
bool ThrowException { get; }
} }
} }
+15 -4
View File
@@ -18,11 +18,14 @@ namespace WireMock.Matchers
/// <inheritdoc cref="IMatcher.MatchBehaviour"/> /// <inheritdoc cref="IMatcher.MatchBehaviour"/>
public MatchBehaviour MatchBehaviour { get; } public MatchBehaviour MatchBehaviour { get; }
/// <inheritdoc cref="IMatcher.ThrowException"/>
public bool ThrowException { get; }
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="JsonPathMatcher"/> class. /// Initializes a new instance of the <see cref="JsonPathMatcher"/> class.
/// </summary> /// </summary>
/// <param name="patterns">The patterns.</param> /// <param name="patterns">The patterns.</param>
public JsonPathMatcher([NotNull] params string[] patterns) : this(MatchBehaviour.AcceptOnMatch, patterns) public JsonPathMatcher([NotNull] params string[] patterns) : this(MatchBehaviour.AcceptOnMatch, false, patterns)
{ {
} }
@@ -30,12 +33,14 @@ namespace WireMock.Matchers
/// Initializes a new instance of the <see cref="JsonPathMatcher"/> class. /// Initializes a new instance of the <see cref="JsonPathMatcher"/> class.
/// </summary> /// </summary>
/// <param name="matchBehaviour">The match behaviour.</param> /// <param name="matchBehaviour">The match behaviour.</param>
/// <param name="throwException">Throw an exception when the internal matching fails because of invalid input.</param>
/// <param name="patterns">The patterns.</param> /// <param name="patterns">The patterns.</param>
public JsonPathMatcher(MatchBehaviour matchBehaviour, [NotNull] params string[] patterns) public JsonPathMatcher(MatchBehaviour matchBehaviour, bool throwException = false, [NotNull] params string[] patterns)
{ {
Check.NotNull(patterns, nameof(patterns)); Check.NotNull(patterns, nameof(patterns));
MatchBehaviour = matchBehaviour; MatchBehaviour = matchBehaviour;
ThrowException = throwException;
_patterns = patterns; _patterns = patterns;
} }
@@ -52,7 +57,10 @@ namespace WireMock.Matchers
} }
catch (JsonException) catch (JsonException)
{ {
// just ignore JsonException if (ThrowException)
{
throw;
}
} }
} }
@@ -75,7 +83,10 @@ namespace WireMock.Matchers
} }
catch (JsonException) catch (JsonException)
{ {
// just ignore JsonException if (ThrowException)
{
throw;
}
} }
} }
+20 -3
View File
@@ -16,11 +16,23 @@ namespace WireMock.Matchers
/// <inheritdoc cref="IMatcher.MatchBehaviour"/> /// <inheritdoc cref="IMatcher.MatchBehaviour"/>
public MatchBehaviour MatchBehaviour { get; } public MatchBehaviour MatchBehaviour { get; }
/// <inheritdoc cref="IMatcher.ThrowException"/>
public bool ThrowException { get; }
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="JmesPathMatcher"/> class. /// Initializes a new instance of the <see cref="JmesPathMatcher"/> class.
/// </summary> /// </summary>
/// <param name="patterns">The patterns.</param> /// <param name="patterns">The patterns.</param>
public JmesPathMatcher([NotNull] params string[] patterns) : this(MatchBehaviour.AcceptOnMatch, patterns) public JmesPathMatcher([NotNull] params string[] patterns) : this(MatchBehaviour.AcceptOnMatch, false, patterns)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="JmesPathMatcher"/> class.
/// </summary>
/// <param name="throwException">Throw an exception when the internal matching fails because of invalid input.</param>
/// <param name="patterns">The patterns.</param>
public JmesPathMatcher(bool throwException = false, [NotNull] params string[] patterns) : this(MatchBehaviour.AcceptOnMatch, throwException, patterns)
{ {
} }
@@ -28,12 +40,14 @@ namespace WireMock.Matchers
/// Initializes a new instance of the <see cref="JmesPathMatcher"/> class. /// Initializes a new instance of the <see cref="JmesPathMatcher"/> class.
/// </summary> /// </summary>
/// <param name="matchBehaviour">The match behaviour.</param> /// <param name="matchBehaviour">The match behaviour.</param>
/// <param name="throwException">Throw an exception when the internal matching fails because of invalid input.</param>
/// <param name="patterns">The patterns.</param> /// <param name="patterns">The patterns.</param>
public JmesPathMatcher(MatchBehaviour matchBehaviour, [NotNull] params string[] patterns) public JmesPathMatcher(MatchBehaviour matchBehaviour, bool throwException = false, [NotNull] params string[] patterns)
{ {
Check.NotNull(patterns, nameof(patterns)); Check.NotNull(patterns, nameof(patterns));
MatchBehaviour = matchBehaviour; MatchBehaviour = matchBehaviour;
ThrowException = throwException;
_patterns = patterns; _patterns = patterns;
} }
@@ -49,7 +63,10 @@ namespace WireMock.Matchers
} }
catch (JsonException) catch (JsonException)
{ {
// just ignore JsonException if (ThrowException)
{
throw;
}
} }
} }
+42 -46
View File
@@ -1,8 +1,8 @@
using JetBrains.Annotations; using System.Collections;
using System.Linq;
using JetBrains.Annotations;
using Newtonsoft.Json; using Newtonsoft.Json;
using Newtonsoft.Json.Linq; using Newtonsoft.Json.Linq;
using System.Collections;
using System.Linq;
using WireMock.Util; using WireMock.Util;
using WireMock.Validation; using WireMock.Validation;
@@ -25,12 +25,18 @@ namespace WireMock.Matchers
/// <inheritdoc cref="IIgnoreCaseMatcher.IgnoreCase"/> /// <inheritdoc cref="IIgnoreCaseMatcher.IgnoreCase"/>
public bool IgnoreCase { get; } public bool IgnoreCase { get; }
/// <inheritdoc cref="IMatcher.ThrowException"/>
public bool ThrowException { get; }
private readonly JToken _valueAsJToken;
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="JsonMatcher"/> class. /// Initializes a new instance of the <see cref="JsonMatcher"/> class.
/// </summary> /// </summary>
/// <param name="value">The string value to check for equality.</param> /// <param name="value">The string value to check for equality.</param>
/// <param name="ignoreCase">Ignore the case from the PropertyName and PropertyValue (string only).</param> /// <param name="ignoreCase">Ignore the case from the PropertyName and PropertyValue (string only).</param>
public JsonMatcher([NotNull] string value, bool ignoreCase = false) : this(MatchBehaviour.AcceptOnMatch, value, ignoreCase) /// <param name="throwException">Throw an exception when the internal matching fails because of invalid input.</param>
public JsonMatcher([NotNull] string value, bool ignoreCase = false, bool throwException = false) : this(MatchBehaviour.AcceptOnMatch, value, ignoreCase, throwException)
{ {
} }
@@ -39,7 +45,8 @@ namespace WireMock.Matchers
/// </summary> /// </summary>
/// <param name="value">The object value to check for equality.</param> /// <param name="value">The object value to check for equality.</param>
/// <param name="ignoreCase">Ignore the case from the PropertyName and PropertyValue (string only).</param> /// <param name="ignoreCase">Ignore the case from the PropertyName and PropertyValue (string only).</param>
public JsonMatcher([NotNull] object value, bool ignoreCase = false) : this(MatchBehaviour.AcceptOnMatch, value, ignoreCase) /// <param name="throwException">Throw an exception when the internal matching fails because of invalid input.</param>
public JsonMatcher([NotNull] object value, bool ignoreCase = false, bool throwException = false) : this(MatchBehaviour.AcceptOnMatch, value, ignoreCase, throwException)
{ {
} }
@@ -47,30 +54,19 @@ namespace WireMock.Matchers
/// Initializes a new instance of the <see cref="JsonMatcher"/> class. /// Initializes a new instance of the <see cref="JsonMatcher"/> class.
/// </summary> /// </summary>
/// <param name="matchBehaviour">The match behaviour.</param> /// <param name="matchBehaviour">The match behaviour.</param>
/// <param name="value">The string value to check for equality.</param> /// <param name="value">The value to check for equality.</param>
/// <param name="ignoreCase">Ignore the case from the PropertyName and PropertyValue (string only).</param> /// <param name="ignoreCase">Ignore the case from the PropertyName and PropertyValue (string only).</param>
public JsonMatcher(MatchBehaviour matchBehaviour, [NotNull] string value, bool ignoreCase = false) /// <param name="throwException">Throw an exception when the internal matching fails because of invalid input.</param>
public JsonMatcher(MatchBehaviour matchBehaviour, [NotNull] object value, bool ignoreCase = false, bool throwException = false)
{ {
Check.NotNull(value, nameof(value)); Check.NotNull(value, nameof(value));
MatchBehaviour = matchBehaviour; MatchBehaviour = matchBehaviour;
Value = value;
IgnoreCase = ignoreCase; IgnoreCase = ignoreCase;
} ThrowException = throwException;
/// <summary>
/// Initializes a new instance of the <see cref="JsonMatcher"/> class.
/// </summary>
/// <param name="matchBehaviour">The match behaviour.</param>
/// <param name="value">The object value to check for equality.</param>
/// <param name="ignoreCase">Ignore the case from the PropertyName and PropertyValue (string only).</param>
public JsonMatcher(MatchBehaviour matchBehaviour, [NotNull] object value, bool ignoreCase = false)
{
Check.NotNull(value, nameof(value));
MatchBehaviour = matchBehaviour;
Value = value; Value = value;
IgnoreCase = ignoreCase; _valueAsJToken = ConvertValueToJToken(value);
} }
/// <inheritdoc cref="IObjectMatcher.IsMatch"/> /// <inheritdoc cref="IObjectMatcher.IsMatch"/>
@@ -83,41 +79,41 @@ namespace WireMock.Matchers
{ {
try try
{ {
// Check if JToken or object var inputAsJToken = ConvertValueToJToken(input);
JToken jtokenInput = input is JToken tokenInput ? tokenInput : JObject.FromObject(input);
// Check if JToken, string, IEnumerable or object match = DeepEquals(_valueAsJToken, inputAsJToken);
JToken jtokenValue;
switch (Value)
{
case JToken tokenValue:
jtokenValue = tokenValue;
break;
case string stringValue:
jtokenValue = JsonUtils.Parse(stringValue);
break;
case IEnumerable enumerableValue:
jtokenValue = JArray.FromObject(enumerableValue);
break;
default:
jtokenValue = JObject.FromObject(Value);
break;
}
match = DeepEquals(jtokenValue, jtokenInput);
} }
catch (JsonException) catch (JsonException)
{ {
// just ignore JsonException if (ThrowException)
{
throw;
}
} }
} }
return MatchBehaviourHelper.Convert(MatchBehaviour, MatchScores.ToScore(match)); return MatchBehaviourHelper.Convert(MatchBehaviour, MatchScores.ToScore(match));
} }
private static JToken ConvertValueToJToken(object value)
{
// Check if JToken, string, IEnumerable or object
switch (value)
{
case JToken tokenValue:
return tokenValue;
case string stringValue:
return JsonUtils.Parse(stringValue);
case IEnumerable enumerableValue:
return JArray.FromObject(enumerableValue);
default:
return JObject.FromObject(value);
}
}
private bool DeepEquals(JToken value, JToken input) private bool DeepEquals(JToken value, JToken input)
{ {
if (!IgnoreCase) if (!IgnoreCase)
+15 -7
View File
@@ -17,6 +17,8 @@ namespace WireMock.Matchers
/// <inheritdoc cref="IMatcher.MatchBehaviour"/> /// <inheritdoc cref="IMatcher.MatchBehaviour"/>
public MatchBehaviour MatchBehaviour { get; } public MatchBehaviour MatchBehaviour { get; }
/// <inheritdoc cref="IMatcher.ThrowException"/>
public bool ThrowException { get; }
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="LinqMatcher"/> class. /// Initializes a new instance of the <see cref="LinqMatcher"/> class.
@@ -30,7 +32,7 @@ namespace WireMock.Matchers
/// Initializes a new instance of the <see cref="LinqMatcher"/> class. /// Initializes a new instance of the <see cref="LinqMatcher"/> class.
/// </summary> /// </summary>
/// <param name="patterns">The patterns.</param> /// <param name="patterns">The patterns.</param>
public LinqMatcher([NotNull] string[] patterns) : this(MatchBehaviour.AcceptOnMatch, patterns) public LinqMatcher([NotNull] params string[] patterns) : this(MatchBehaviour.AcceptOnMatch, false, patterns)
{ {
} }
@@ -39,7 +41,7 @@ namespace WireMock.Matchers
/// </summary> /// </summary>
/// <param name="matchBehaviour">The match behaviour.</param> /// <param name="matchBehaviour">The match behaviour.</param>
/// <param name="pattern">The pattern.</param> /// <param name="pattern">The pattern.</param>
public LinqMatcher(MatchBehaviour matchBehaviour, [NotNull] string pattern) : this(matchBehaviour, new[] { pattern }) public LinqMatcher(MatchBehaviour matchBehaviour, [NotNull] string pattern) : this(matchBehaviour, false, pattern)
{ {
} }
@@ -48,9 +50,11 @@ namespace WireMock.Matchers
/// </summary> /// </summary>
/// <param name="matchBehaviour">The match behaviour.</param> /// <param name="matchBehaviour">The match behaviour.</param>
/// <param name="patterns">The patterns.</param> /// <param name="patterns">The patterns.</param>
public LinqMatcher(MatchBehaviour matchBehaviour, [NotNull] string[] patterns) /// <param name="throwException">Throw an exception when the internal matching fails because of invalid input.</param>
public LinqMatcher(MatchBehaviour matchBehaviour, bool throwException = false, [NotNull] params string[] patterns)
{ {
MatchBehaviour = matchBehaviour; MatchBehaviour = matchBehaviour;
ThrowException = throwException;
_patterns = patterns; _patterns = patterns;
} }
@@ -71,8 +75,10 @@ namespace WireMock.Matchers
} }
catch catch
{ {
// just ignore exception if (ThrowException)
// TODO add logging? {
throw;
}
} }
return MatchBehaviourHelper.Convert(MatchBehaviour, match); return MatchBehaviourHelper.Convert(MatchBehaviour, match);
@@ -113,8 +119,10 @@ namespace WireMock.Matchers
} }
catch catch
{ {
// just ignore exception if (ThrowException)
// TODO add logging? {
throw;
}
} }
return MatchBehaviourHelper.Convert(MatchBehaviour, match); return MatchBehaviourHelper.Convert(MatchBehaviour, match);
+10 -2
View File
@@ -19,6 +19,9 @@ namespace WireMock.Matchers
/// <inheritdoc cref="IMatcher.MatchBehaviour"/> /// <inheritdoc cref="IMatcher.MatchBehaviour"/>
public MatchBehaviour MatchBehaviour { get; } public MatchBehaviour MatchBehaviour { get; }
/// <inheritdoc cref="IMatcher.ThrowException"/>
public bool ThrowException { get; }
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="RegexMatcher"/> class. /// Initializes a new instance of the <see cref="RegexMatcher"/> class.
/// </summary> /// </summary>
@@ -53,13 +56,15 @@ namespace WireMock.Matchers
/// <param name="matchBehaviour">The match behaviour.</param> /// <param name="matchBehaviour">The match behaviour.</param>
/// <param name="patterns">The patterns.</param> /// <param name="patterns">The patterns.</param>
/// <param name="ignoreCase">Ignore the case from the pattern.</param> /// <param name="ignoreCase">Ignore the case from the pattern.</param>
public RegexMatcher(MatchBehaviour matchBehaviour, [NotNull, RegexPattern] string[] patterns, bool ignoreCase = false) /// <param name="throwException">Throw an exception when the internal matching fails because of invalid input.</param>
public RegexMatcher(MatchBehaviour matchBehaviour, [NotNull, RegexPattern] string[] patterns, bool ignoreCase = false, bool throwException = false)
{ {
Check.NotNull(patterns, nameof(patterns)); Check.NotNull(patterns, nameof(patterns));
_patterns = patterns; _patterns = patterns;
IgnoreCase = ignoreCase; IgnoreCase = ignoreCase;
MatchBehaviour = matchBehaviour; MatchBehaviour = matchBehaviour;
ThrowException = throwException;
RegexOptions options = RegexOptions.Compiled | RegexOptions.Multiline; RegexOptions options = RegexOptions.Compiled | RegexOptions.Multiline;
@@ -83,7 +88,10 @@ namespace WireMock.Matchers
} }
catch (Exception) catch (Exception)
{ {
// just ignore exception if (ThrowException)
{
throw;
}
} }
} }
@@ -51,7 +51,7 @@ namespace WireMock.Matchers.Request
/// <param name="key">The key.</param> /// <param name="key">The key.</param>
/// <param name="ignoreCase">Defines if the key should be matched using case-ignore.</param> /// <param name="ignoreCase">Defines if the key should be matched using case-ignore.</param>
/// <param name="values">The values.</param> /// <param name="values">The values.</param>
public RequestMessageParamMatcher(MatchBehaviour matchBehaviour, [NotNull] string key, bool ignoreCase, [CanBeNull] string[] values) : this(matchBehaviour, key, ignoreCase, values?.Select(value => new ExactMatcher(matchBehaviour, value)).Cast<IStringMatcher>().ToArray()) public RequestMessageParamMatcher(MatchBehaviour matchBehaviour, [NotNull] string key, bool ignoreCase, [CanBeNull] string[] values) : this(matchBehaviour, key, ignoreCase, values?.Select(value => new ExactMatcher(matchBehaviour, false, value)).Cast<IStringMatcher>().ToArray())
{ {
} }
@@ -19,6 +19,9 @@ namespace WireMock.Matchers
/// <inheritdoc cref="IMatcher.MatchBehaviour"/> /// <inheritdoc cref="IMatcher.MatchBehaviour"/>
public MatchBehaviour MatchBehaviour { get; } public MatchBehaviour MatchBehaviour { get; }
/// <inheritdoc cref="IMatcher.ThrowException"/>
public bool ThrowException { get; }
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="SimMetricsMatcher"/> class. /// Initializes a new instance of the <see cref="SimMetricsMatcher"/> class.
/// </summary> /// </summary>
@@ -53,11 +56,14 @@ namespace WireMock.Matchers
/// <param name="matchBehaviour">The match behaviour.</param> /// <param name="matchBehaviour">The match behaviour.</param>
/// <param name="patterns">The patterns.</param> /// <param name="patterns">The patterns.</param>
/// <param name="simMetricType">The SimMetric Type</param> /// <param name="simMetricType">The SimMetric Type</param>
public SimMetricsMatcher(MatchBehaviour matchBehaviour, [NotNull] string[] patterns, SimMetricType simMetricType = SimMetricType.Levenstein) /// <param name="throwException">Throw an exception when the internal matching fails because of invalid input.</param>
public SimMetricsMatcher(MatchBehaviour matchBehaviour, [NotNull] string[] patterns, SimMetricType simMetricType = SimMetricType.Levenstein, bool throwException = false)
{ {
Check.NotNullOrEmpty(patterns, nameof(patterns)); Check.NotNullOrEmpty(patterns, nameof(patterns));
MatchBehaviour = matchBehaviour; MatchBehaviour = matchBehaviour;
ThrowException = throwException;
_patterns = patterns; _patterns = patterns;
_simMetricType = simMetricType; _simMetricType = simMetricType;
} }
+3 -1
View File
@@ -46,7 +46,9 @@ namespace WireMock.Matchers
/// <param name="matchBehaviour">The match behaviour.</param> /// <param name="matchBehaviour">The match behaviour.</param>
/// <param name="patterns">The patterns.</param> /// <param name="patterns">The patterns.</param>
/// <param name="ignoreCase">IgnoreCase</param> /// <param name="ignoreCase">IgnoreCase</param>
public WildcardMatcher(MatchBehaviour matchBehaviour, [NotNull] string[] patterns, bool ignoreCase = false) : base(matchBehaviour, patterns.Select(pattern => "^" + Regex.Escape(pattern).Replace(@"\*", ".*").Replace(@"\?", ".") + "$").ToArray(), ignoreCase) /// <param name="throwException">Throw an exception when the internal matching fails because of invalid input.</param>
public WildcardMatcher(MatchBehaviour matchBehaviour, [NotNull] string[] patterns, bool ignoreCase = false, bool throwException = false) :
base(matchBehaviour, patterns.Select(pattern => "^" + Regex.Escape(pattern).Replace(@"\*", ".*").Replace(@"\?", ".") + "$").ToArray(), ignoreCase, throwException)
{ {
_patterns = patterns; _patterns = patterns;
} }
+11 -4
View File
@@ -20,11 +20,14 @@ namespace WireMock.Matchers
/// <inheritdoc cref="IMatcher.MatchBehaviour"/> /// <inheritdoc cref="IMatcher.MatchBehaviour"/>
public MatchBehaviour MatchBehaviour { get; } public MatchBehaviour MatchBehaviour { get; }
/// <inheritdoc cref="IMatcher.ThrowException"/>
public bool ThrowException { get; }
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="XPathMatcher"/> class. /// Initializes a new instance of the <see cref="XPathMatcher"/> class.
/// </summary> /// </summary>
/// <param name="patterns">The patterns.</param> /// <param name="patterns">The patterns.</param>
public XPathMatcher([NotNull] params string[] patterns) : this(MatchBehaviour.AcceptOnMatch, patterns) public XPathMatcher([NotNull] params string[] patterns) : this(MatchBehaviour.AcceptOnMatch, false, patterns)
{ {
} }
@@ -32,12 +35,14 @@ namespace WireMock.Matchers
/// Initializes a new instance of the <see cref="XPathMatcher"/> class. /// Initializes a new instance of the <see cref="XPathMatcher"/> class.
/// </summary> /// </summary>
/// <param name="matchBehaviour">The match behaviour.</param> /// <param name="matchBehaviour">The match behaviour.</param>
/// <param name="throwException">Throw an exception when the internal matching fails because of invalid input.</param>
/// <param name="patterns">The patterns.</param> /// <param name="patterns">The patterns.</param>
public XPathMatcher(MatchBehaviour matchBehaviour, [NotNull] params string[] patterns) public XPathMatcher(MatchBehaviour matchBehaviour, bool throwException = false, [NotNull] params string[] patterns)
{ {
Check.NotNull(patterns, nameof(patterns)); Check.NotNull(patterns, nameof(patterns));
MatchBehaviour = matchBehaviour; MatchBehaviour = matchBehaviour;
ThrowException = throwException;
_patterns = patterns; _patterns = patterns;
} }
@@ -58,8 +63,10 @@ namespace WireMock.Matchers
} }
catch (Exception) catch (Exception)
{ {
// just ignore exception if (ThrowException)
// TODO add logging? {
throw;
}
} }
} }
+15 -13
View File
@@ -38,6 +38,8 @@ namespace WireMock.Serialization
string[] stringPatterns = matcher.Patterns != null ? matcher.Patterns.OfType<string>().ToArray() : new[] { matcher.Pattern as string }; string[] stringPatterns = matcher.Patterns != null ? matcher.Patterns.OfType<string>().ToArray() : new[] { matcher.Pattern as string };
MatchBehaviour matchBehaviour = matcher.RejectOnMatch == true ? MatchBehaviour.RejectOnMatch : MatchBehaviour.AcceptOnMatch; MatchBehaviour matchBehaviour = matcher.RejectOnMatch == true ? MatchBehaviour.RejectOnMatch : MatchBehaviour.AcceptOnMatch;
bool ignoreCase = matcher.IgnoreCase == true;
bool throwExceptionWhenMatcherFails = _settings.ThrowExceptionWhenMatcherFails == true;
switch (matcherName) switch (matcherName)
{ {
@@ -50,34 +52,34 @@ namespace WireMock.Serialization
throw new NotSupportedException("It's not allowed to use the 'CSharpCodeMatcher' because IWireMockServerSettings.AllowCSharpCodeMatcher is not set to 'true'."); throw new NotSupportedException("It's not allowed to use the 'CSharpCodeMatcher' because IWireMockServerSettings.AllowCSharpCodeMatcher is not set to 'true'.");
case "LinqMatcher": case "LinqMatcher":
return new LinqMatcher(matchBehaviour, stringPatterns); return new LinqMatcher(matchBehaviour, throwExceptionWhenMatcherFails, stringPatterns);
case "ExactMatcher": case "ExactMatcher":
return new ExactMatcher(matchBehaviour, stringPatterns); return new ExactMatcher(matchBehaviour, throwExceptionWhenMatcherFails, stringPatterns);
case "ExactObjectMatcher": case "ExactObjectMatcher":
return CreateExactObjectMatcher(matchBehaviour, stringPatterns[0]); return CreateExactObjectMatcher(matchBehaviour, stringPatterns[0], throwExceptionWhenMatcherFails);
case "RegexMatcher": case "RegexMatcher":
return new RegexMatcher(matchBehaviour, stringPatterns, matcher.IgnoreCase == true); return new RegexMatcher(matchBehaviour, stringPatterns, ignoreCase, throwExceptionWhenMatcherFails);
case "JsonMatcher": case "JsonMatcher":
return new JsonMatcher(matchBehaviour, matcher.Pattern, matcher.IgnoreCase == true); return new JsonMatcher(matchBehaviour, stringPatterns, ignoreCase, throwExceptionWhenMatcherFails);
case "JsonPathMatcher": case "JsonPathMatcher":
return new JsonPathMatcher(matchBehaviour, stringPatterns); return new JsonPathMatcher(matchBehaviour, throwExceptionWhenMatcherFails, stringPatterns);
case "JmesPathMatcher": case "JmesPathMatcher":
return new JmesPathMatcher(matchBehaviour, stringPatterns); return new JmesPathMatcher(matchBehaviour, throwExceptionWhenMatcherFails, stringPatterns);
case "XPathMatcher": case "XPathMatcher":
return new XPathMatcher(matchBehaviour, stringPatterns); return new XPathMatcher(matchBehaviour, throwExceptionWhenMatcherFails, stringPatterns);
case "WildcardMatcher": case "WildcardMatcher":
return new WildcardMatcher(matchBehaviour, stringPatterns, matcher.IgnoreCase == true); return new WildcardMatcher(matchBehaviour, stringPatterns, ignoreCase, throwExceptionWhenMatcherFails);
case "ContentTypeMatcher": case "ContentTypeMatcher":
return new ContentTypeMatcher(matchBehaviour, stringPatterns, matcher.IgnoreCase == true); return new ContentTypeMatcher(matchBehaviour, stringPatterns, ignoreCase, throwExceptionWhenMatcherFails);
case "SimMetricsMatcher": case "SimMetricsMatcher":
SimMetricType type = SimMetricType.Levenstein; SimMetricType type = SimMetricType.Levenstein;
@@ -86,14 +88,14 @@ namespace WireMock.Serialization
throw new NotSupportedException($"Matcher '{matcherName}' with Type '{matcherType}' is not supported."); throw new NotSupportedException($"Matcher '{matcherName}' with Type '{matcherType}' is not supported.");
} }
return new SimMetricsMatcher(matchBehaviour, stringPatterns, type); return new SimMetricsMatcher(matchBehaviour, stringPatterns, type, throwExceptionWhenMatcherFails);
default: default:
throw new NotSupportedException($"Matcher '{matcherName}' is not supported."); throw new NotSupportedException($"Matcher '{matcherName}' is not supported.");
} }
} }
private ExactObjectMatcher CreateExactObjectMatcher(MatchBehaviour matchBehaviour, string stringPattern) private ExactObjectMatcher CreateExactObjectMatcher(MatchBehaviour matchBehaviour, string stringPattern, bool throwException)
{ {
byte[] bytePattern; byte[] bytePattern;
try try
@@ -105,7 +107,7 @@ namespace WireMock.Serialization
throw new ArgumentException($"Matcher 'ExactObjectMatcher' has invalid pattern. The pattern value '{stringPattern}' is not a Base64String.", nameof(stringPattern)); throw new ArgumentException($"Matcher 'ExactObjectMatcher' has invalid pattern. The pattern value '{stringPattern}' is not a Base64String.", nameof(stringPattern));
} }
return new ExactObjectMatcher(matchBehaviour, bytePattern); return new ExactObjectMatcher(matchBehaviour, bytePattern, throwException);
} }
public MatcherModel[] Map([CanBeNull] IEnumerable<IMatcher> matchers) public MatcherModel[] Map([CanBeNull] IEnumerable<IMatcher> matchers)
+24 -12
View File
@@ -1,6 +1,3 @@
using JetBrains.Annotations;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
@@ -9,6 +6,9 @@ using System.Net;
using System.Net.Http; using System.Net.Http;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using JetBrains.Annotations;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using WireMock.Admin.Mappings; using WireMock.Admin.Mappings;
using WireMock.Admin.Scenarios; using WireMock.Admin.Scenarios;
using WireMock.Admin.Settings; using WireMock.Admin.Settings;
@@ -274,7 +274,12 @@ namespace WireMock.Server
if (HttpStatusRangeParser.IsMatch(settings.ProxyAndRecordSettings.SaveMappingForStatusCodePattern, responseMessage.StatusCode) && if (HttpStatusRangeParser.IsMatch(settings.ProxyAndRecordSettings.SaveMappingForStatusCodePattern, responseMessage.StatusCode) &&
(settings.ProxyAndRecordSettings.SaveMapping || settings.ProxyAndRecordSettings.SaveMappingToFile)) (settings.ProxyAndRecordSettings.SaveMapping || settings.ProxyAndRecordSettings.SaveMappingToFile))
{ {
var mapping = ToMapping(requestMessage, responseMessage, settings.ProxyAndRecordSettings.BlackListedHeaders ?? new string[] { }, settings.ProxyAndRecordSettings.BlackListedCookies ?? new string[] { }); var mapping = ToMapping(
requestMessage,
responseMessage,
settings.ProxyAndRecordSettings.BlackListedHeaders ?? new string[] { },
settings.ProxyAndRecordSettings.BlackListedCookies ?? new string[] { }
);
if (settings.ProxyAndRecordSettings.SaveMapping) if (settings.ProxyAndRecordSettings.SaveMapping)
{ {
@@ -314,18 +319,19 @@ namespace WireMock.Server
} }
}); });
bool throwExceptionWhenMatcherFails = _settings.ThrowExceptionWhenMatcherFails == true;
switch (requestMessage.BodyData?.DetectedBodyType) switch (requestMessage.BodyData?.DetectedBodyType)
{ {
case BodyType.Json: case BodyType.Json:
request.WithBody(new JsonMatcher(MatchBehaviour.AcceptOnMatch, requestMessage.BodyData.BodyAsJson)); request.WithBody(new JsonMatcher(MatchBehaviour.AcceptOnMatch, requestMessage.BodyData.BodyAsJson, true, throwExceptionWhenMatcherFails));
break; break;
case BodyType.String: case BodyType.String:
request.WithBody(new ExactMatcher(MatchBehaviour.AcceptOnMatch, requestMessage.BodyData.BodyAsString)); request.WithBody(new ExactMatcher(MatchBehaviour.AcceptOnMatch, throwExceptionWhenMatcherFails, requestMessage.BodyData.BodyAsString));
break; break;
case BodyType.Bytes: case BodyType.Bytes:
request.WithBody(new ExactObjectMatcher(MatchBehaviour.AcceptOnMatch, requestMessage.BodyData.BodyAsBytes)); request.WithBody(new ExactObjectMatcher(MatchBehaviour.AcceptOnMatch, requestMessage.BodyData.BodyAsBytes, throwExceptionWhenMatcherFails));
break; break;
} }
@@ -340,12 +346,13 @@ namespace WireMock.Server
{ {
var model = new SettingsModel var model = new SettingsModel
{ {
AllowPartialMapping = _options.AllowPartialMapping, AllowPartialMapping = _settings.AllowPartialMapping,
MaxRequestLogCount = _options.MaxRequestLogCount, MaxRequestLogCount = _settings.MaxRequestLogCount,
RequestLogExpirationDuration = _options.RequestLogExpirationDuration, RequestLogExpirationDuration = _settings.RequestLogExpirationDuration,
GlobalProcessingDelay = (int?)_options.RequestProcessingDelay?.TotalMilliseconds, GlobalProcessingDelay = (int?)_options.RequestProcessingDelay?.TotalMilliseconds,
AllowBodyForAllHttpMethods = _options.AllowBodyForAllHttpMethods, AllowBodyForAllHttpMethods = _settings.AllowBodyForAllHttpMethods,
HandleRequestsSynchronously = _options.HandleRequestsSynchronously HandleRequestsSynchronously = _settings.HandleRequestsSynchronously,
ThrowExceptionWhenMatcherFails = _settings.ThrowExceptionWhenMatcherFails
}; };
return ToJson(model); return ToJson(model);
@@ -377,6 +384,11 @@ namespace WireMock.Server
_options.HandleRequestsSynchronously = settings.HandleRequestsSynchronously.Value; _options.HandleRequestsSynchronously = settings.HandleRequestsSynchronously.Value;
} }
if (settings.ThrowExceptionWhenMatcherFails != null)
{
_settings.ThrowExceptionWhenMatcherFails = settings.ThrowExceptionWhenMatcherFails.Value;
}
return ResponseMessageBuilder.Create("Settings updated"); return ResponseMessageBuilder.Create("Settings updated");
} }
#endregion Settings #endregion Settings
@@ -3,6 +3,7 @@ using HandlebarsDotNet;
using JetBrains.Annotations; using JetBrains.Annotations;
using WireMock.Handlers; using WireMock.Handlers;
using WireMock.Logging; using WireMock.Logging;
using WireMock.Matchers;
namespace WireMock.Settings namespace WireMock.Settings
{ {
@@ -163,5 +164,11 @@ namespace WireMock.Settings
/// </summary> /// </summary>
[PublicAPI] [PublicAPI]
bool? HandleRequestsSynchronously { get; set; } bool? HandleRequestsSynchronously { get; set; }
/// <summary>
/// Throw an exception when the <see cref="IMatcher"/> fails because of invalid input. (default set to false).
/// </summary>
[PublicAPI]
bool? ThrowExceptionWhenMatcherFails { get; set; }
} }
} }
@@ -117,5 +117,9 @@ namespace WireMock.Settings
/// <inheritdoc cref="IWireMockServerSettings.HandleRequestsSynchronously"/> /// <inheritdoc cref="IWireMockServerSettings.HandleRequestsSynchronously"/>
[PublicAPI] [PublicAPI]
public bool? HandleRequestsSynchronously { get; set; } public bool? HandleRequestsSynchronously { get; set; }
/// <inheritdoc cref="IWireMockServerSettings.ThrowExceptionWhenMatcherFails"/>
[PublicAPI]
public bool? ThrowExceptionWhenMatcherFails { get; set; }
} }
} }
@@ -37,7 +37,8 @@ namespace WireMock.Settings
AllowBodyForAllHttpMethods = parser.GetBoolValue("AllowBodyForAllHttpMethods"), AllowBodyForAllHttpMethods = parser.GetBoolValue("AllowBodyForAllHttpMethods"),
AllowOnlyDefinedHttpStatusCodeInResponse = parser.GetBoolValue("AllowOnlyDefinedHttpStatusCodeInResponse"), AllowOnlyDefinedHttpStatusCodeInResponse = parser.GetBoolValue("AllowOnlyDefinedHttpStatusCodeInResponse"),
DisableJsonBodyParsing = parser.GetBoolValue("DisableJsonBodyParsing"), DisableJsonBodyParsing = parser.GetBoolValue("DisableJsonBodyParsing"),
HandleRequestsSynchronously = parser.GetBoolValue("HandleRequestsSynchronously") HandleRequestsSynchronously = parser.GetBoolValue("HandleRequestsSynchronously"),
ThrowExceptionWhenMatcherFails = parser.GetBoolValue("ThrowExceptionWhenMatcherFails")
}; };
if (logger != null) if (logger != null)
@@ -1,5 +1,5 @@
using HandlebarsDotNet; using System;
using System; using HandlebarsDotNet;
using WireMock.Handlers; using WireMock.Handlers;
namespace WireMock.Transformers namespace WireMock.Transformers
@@ -1,11 +1,10 @@
using HandlebarsDotNet; using System;
using System.Collections.Generic;
using System.Linq;
using HandlebarsDotNet;
using JetBrains.Annotations; using JetBrains.Annotations;
using Newtonsoft.Json; using Newtonsoft.Json;
using Newtonsoft.Json.Linq; using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using WireMock.Types; using WireMock.Types;
using WireMock.Util; using WireMock.Util;
using WireMock.Validation; using WireMock.Validation;
@@ -88,7 +88,7 @@ namespace WireMock.Net.Tests.Matchers
public void ExactMatcher_IsMatch_SinglePattern_AcceptOnMatch() public void ExactMatcher_IsMatch_SinglePattern_AcceptOnMatch()
{ {
// Assign // Assign
var matcher = new ExactMatcher(MatchBehaviour.AcceptOnMatch, "cat"); var matcher = new ExactMatcher(MatchBehaviour.AcceptOnMatch, false, "cat");
// Act // Act
double result = matcher.IsMatch("cat"); double result = matcher.IsMatch("cat");
@@ -101,7 +101,7 @@ namespace WireMock.Net.Tests.Matchers
public void ExactMatcher_IsMatch_SinglePattern_RejectOnMatch() public void ExactMatcher_IsMatch_SinglePattern_RejectOnMatch()
{ {
// Assign // Assign
var matcher = new ExactMatcher(MatchBehaviour.RejectOnMatch, "cat"); var matcher = new ExactMatcher(MatchBehaviour.RejectOnMatch, false, "cat");
// Act // Act
double result = matcher.IsMatch("cat"); double result = matcher.IsMatch("cat");
@@ -154,7 +154,7 @@ namespace WireMock.Net.Tests.Matchers
public void JmesPathMatcher_IsMatch_RejectOnMatch() public void JmesPathMatcher_IsMatch_RejectOnMatch()
{ {
// Assign // Assign
var matcher = new JmesPathMatcher(MatchBehaviour.RejectOnMatch, "things.x == 'RequiredThing'"); var matcher = new JmesPathMatcher(MatchBehaviour.RejectOnMatch, false, "things.x == 'RequiredThing'");
// Act // Act
double match = matcher.IsMatch(JObject.Parse("{ \"things\": { \"x\": \"RequiredThing\" } }")); double match = matcher.IsMatch(JObject.Parse("{ \"things\": { \"x\": \"RequiredThing\" } }"));
@@ -1,4 +1,8 @@
using Newtonsoft.Json.Linq; using System;
using System.IO;
using FluentAssertions;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using NFluent; using NFluent;
using WireMock.Matchers; using WireMock.Matchers;
using Xunit; using Xunit;
@@ -33,6 +37,52 @@ namespace WireMock.Net.Tests.Matchers
Check.That(value).Equals("{}"); Check.That(value).Equals("{}");
} }
[Fact]
public void JsonMatcher_WithInvalidStringValue_Should_ThrowException()
{
// Act
Action action = () => new JsonMatcher(MatchBehaviour.AcceptOnMatch, "{ \"Id\"");
// Assert
action.Should().Throw<JsonException>();
}
[Fact]
public void JsonMatcher_WithInvalidObjectValue_Should_ThrowException()
{
// Act
Action action = () => new JsonMatcher(MatchBehaviour.AcceptOnMatch, new MemoryStream());
// Assert
action.Should().Throw<JsonException>();
}
[Fact]
public void JsonMatcher_IsMatch_WithInvalidValue_And_ThrowExceptionIsFalse_Should_ReturnMismatch()
{
// Assign
var matcher = new JsonMatcher("");
// Act
double match = matcher.IsMatch(new MemoryStream());
// Assert
Check.That(match).IsEqualTo(0);
}
[Fact]
public void JsonMatcher_IsMatch_WithInvalidValue_And_ThrowExceptionIsTrue_Should_ReturnMismatch()
{
// Assign
var matcher = new JsonMatcher("", false, true);
// Act
Action action = () => matcher.IsMatch(new MemoryStream());
// Assert
action.Should().Throw<JsonException>();
}
[Fact] [Fact]
public void JsonMatcher_IsMatch_ByteArray() public void JsonMatcher_IsMatch_ByteArray()
{ {
@@ -150,7 +150,7 @@ namespace WireMock.Net.Tests.Matchers
public void JsonPathMatcher_IsMatch_RejectOnMatch() public void JsonPathMatcher_IsMatch_RejectOnMatch()
{ {
// Assign // Assign
var matcher = new JsonPathMatcher(MatchBehaviour.RejectOnMatch, "$..[?(@.Id == 1)]"); var matcher = new JsonPathMatcher(MatchBehaviour.RejectOnMatch, false, "$..[?(@.Id == 1)]");
// Act // Act
double match = matcher.IsMatch(JObject.Parse("{\"Id\":1,\"Name\":\"Test\"}")); double match = matcher.IsMatch(JObject.Parse("{\"Id\":1,\"Name\":\"Test\"}"));
@@ -57,7 +57,7 @@ namespace WireMock.Net.Tests.Matchers
<todo-list> <todo-list>
<todo-item id='a1'>abc</todo-item> <todo-item id='a1'>abc</todo-item>
</todo-list>"; </todo-list>";
var matcher = new XPathMatcher(MatchBehaviour.RejectOnMatch, "/todo-list[count(todo-item) = 1]"); var matcher = new XPathMatcher(MatchBehaviour.RejectOnMatch, false, "/todo-list[count(todo-item) = 1]");
// Act // Act
double result = matcher.IsMatch(xml); double result = matcher.IsMatch(xml);
@@ -1,4 +1,5 @@
using System; using System;
using FluentAssertions;
using NFluent; using NFluent;
using WireMock.Admin.Mappings; using WireMock.Admin.Mappings;
using WireMock.Matchers; using WireMock.Matchers;
@@ -43,7 +44,8 @@ namespace WireMock.Net.Tests.Serialization
var matcher = (ExactMatcher)_sut.Map(model); var matcher = (ExactMatcher)_sut.Map(model);
// Assert // Assert
Check.That(matcher.GetPatterns()).ContainsExactly("x"); matcher.GetPatterns().Should().ContainSingle("x");
matcher.ThrowException.Should().BeFalse();
} }
[Fact] [Fact]
@@ -63,6 +65,39 @@ namespace WireMock.Net.Tests.Serialization
Check.That(matcher.GetPatterns()).ContainsExactly("x", "y"); Check.That(matcher.GetPatterns()).ContainsExactly("x", "y");
} }
[Theory]
[InlineData(nameof(LinqMatcher))]
[InlineData(nameof(ExactMatcher))]
[InlineData(nameof(ExactObjectMatcher))]
[InlineData(nameof(RegexMatcher))]
[InlineData(nameof(JsonMatcher))]
[InlineData(nameof(JsonPathMatcher))]
[InlineData(nameof(JmesPathMatcher))]
[InlineData(nameof(XPathMatcher))]
[InlineData(nameof(WildcardMatcher))]
[InlineData(nameof(ContentTypeMatcher))]
[InlineData(nameof(SimMetricsMatcher))]
public void MatcherModelMapper_Map_ThrowExceptionWhenMatcherFails_True(string name)
{
// Assign
var settings = new WireMockServerSettings
{
ThrowExceptionWhenMatcherFails = true
};
var sut = new MatcherMapper(settings);
var model = new MatcherModel
{
Name = name,
Patterns = new[] { "" }
};
// Act
var matcher = sut.Map(model);
// Assert
matcher.ThrowException.Should().BeTrue();
}
[Fact] [Fact]
public void MatcherModelMapper_Map_ExactObjectMatcher_ValidBase64StringPattern() public void MatcherModelMapper_Map_ExactObjectMatcher_ValidBase64StringPattern()
{ {