diff --git a/src/WireMock.Net.Abstractions/Admin/Settings/SettingsModel.cs b/src/WireMock.Net.Abstractions/Admin/Settings/SettingsModel.cs index 2cda87b9..128dd64f 100644 --- a/src/WireMock.Net.Abstractions/Admin/Settings/SettingsModel.cs +++ b/src/WireMock.Net.Abstractions/Admin/Settings/SettingsModel.cs @@ -26,13 +26,18 @@ public int? MaxRequestLogCount { get; set; } /// - /// Gets or sets wether to allow a body for all HTTP methods. + /// Allow a Body for all HTTP Methods. (default set to false). /// public bool? AllowBodyForAllHttpMethods { get; set; } /// - /// Gets or sets wether to handle all requests synchronously. + /// Handle all requests synchronously. (default set to false). /// public bool? HandleRequestsSynchronously { get; set; } + + /// + /// Throw an exception when the Matcher fails because of invalid input. (default set to false). + /// + public bool? ThrowExceptionWhenMatcherFails { get; set; } } } \ No newline at end of file diff --git a/src/WireMock.Net/Matchers/CSharpCodeMatcher.cs b/src/WireMock.Net/Matchers/CSharpCodeMatcher.cs index dbf166ba..8be93248 100644 --- a/src/WireMock.Net/Matchers/CSharpCodeMatcher.cs +++ b/src/WireMock.Net/Matchers/CSharpCodeMatcher.cs @@ -29,6 +29,9 @@ namespace WireMock.Matchers public MatchBehaviour MatchBehaviour { get; } + /// + public bool ThrowException { get; } + private readonly string[] _patterns; /// @@ -49,6 +52,7 @@ namespace WireMock.Matchers Check.NotNull(patterns, nameof(patterns)); MatchBehaviour = matchBehaviour; + ThrowException = false; _patterns = patterns; } @@ -156,7 +160,7 @@ namespace WireMock.Matchers #if NETSTANDARD2_0 script = csscript.GenericExtensions.CreateObject(assembly, "*"); #else - script = CSScriptLib.ReflectionExtensions.CreateObject(assembly,"*"); + script = CSScriptLib.ReflectionExtensions.CreateObject(assembly, "*"); #endif } catch (Exception ex) diff --git a/src/WireMock.Net/Matchers/ContentTypeMatcher.cs b/src/WireMock.Net/Matchers/ContentTypeMatcher.cs index 3f0f1cfc..7c9ba1a1 100644 --- a/src/WireMock.Net/Matchers/ContentTypeMatcher.cs +++ b/src/WireMock.Net/Matchers/ContentTypeMatcher.cs @@ -1,73 +1,75 @@ -using System.Net.Http.Headers; -using JetBrains.Annotations; - -namespace WireMock.Matchers -{ - /// - /// ContentTypeMatcher which accepts also all charsets - /// - /// - public class ContentTypeMatcher : WildcardMatcher - { - private readonly string[] _patterns; - - /// - /// Initializes a new instance of the class. - /// - /// The pattern. - /// IgnoreCase (default false) - public ContentTypeMatcher([NotNull] string pattern, bool ignoreCase = false) : this(new[] { pattern }, ignoreCase) - { - } - - /// - /// Initializes a new instance of the class. - /// - /// The match behaviour. - /// The pattern. - /// IgnoreCase (default false) - public ContentTypeMatcher(MatchBehaviour matchBehaviour, [NotNull] string pattern, bool ignoreCase = false) : this(matchBehaviour, new[] { pattern }, ignoreCase) - { - } - - /// - /// Initializes a new instance of the class. - /// - /// The patterns. - /// IgnoreCase (default false) - public ContentTypeMatcher([NotNull] string[] patterns, bool ignoreCase = false) : this(MatchBehaviour.AcceptOnMatch, patterns, ignoreCase) - { - } - - /// - /// Initializes a new instance of the class. - /// - /// The match behaviour. - /// The patterns. - /// IgnoreCase (default false) - public ContentTypeMatcher(MatchBehaviour matchBehaviour, [NotNull] string[] patterns, bool ignoreCase = false) : base(matchBehaviour, patterns, ignoreCase) - { - _patterns = patterns; - } - - /// - public override double IsMatch(string input) - { - if (string.IsNullOrEmpty(input) || !MediaTypeHeaderValue.TryParse(input, out MediaTypeHeaderValue contentType)) - { - return MatchBehaviourHelper.Convert(MatchBehaviour, MatchScores.Mismatch); - } - - return base.IsMatch(contentType.MediaType); - } - - /// - public override string[] GetPatterns() - { - return _patterns; - } - - /// - public override string Name => "ContentTypeMatcher"; - } +using System.Net.Http.Headers; +using JetBrains.Annotations; + +namespace WireMock.Matchers +{ + /// + /// ContentTypeMatcher which accepts also all charsets + /// + /// + public class ContentTypeMatcher : WildcardMatcher + { + private readonly string[] _patterns; + + /// + /// Initializes a new instance of the class. + /// + /// The pattern. + /// IgnoreCase (default false) + public ContentTypeMatcher([NotNull] string pattern, bool ignoreCase = false) : this(new[] { pattern }, ignoreCase) + { + } + + /// + /// Initializes a new instance of the class. + /// + /// The match behaviour. + /// The pattern. + /// IgnoreCase (default false) + public ContentTypeMatcher(MatchBehaviour matchBehaviour, [NotNull] string pattern, bool ignoreCase = false) : this(matchBehaviour, new[] { pattern }, ignoreCase) + { + } + + /// + /// Initializes a new instance of the class. + /// + /// The patterns. + /// IgnoreCase (default false) + public ContentTypeMatcher([NotNull] string[] patterns, bool ignoreCase = false) : this(MatchBehaviour.AcceptOnMatch, patterns, ignoreCase) + { + } + + /// + /// Initializes a new instance of the class. + /// + /// The match behaviour. + /// The patterns. + /// IgnoreCase (default false) + /// Throw an exception when the internal matching fails because of invalid input. + public ContentTypeMatcher(MatchBehaviour matchBehaviour, [NotNull] string[] patterns, bool ignoreCase = false, bool throwException = false) : + base(matchBehaviour, patterns, ignoreCase, throwException) + { + _patterns = patterns; + } + + /// + public override double IsMatch(string input) + { + if (string.IsNullOrEmpty(input) || !MediaTypeHeaderValue.TryParse(input, out MediaTypeHeaderValue contentType)) + { + return MatchBehaviourHelper.Convert(MatchBehaviour, MatchScores.Mismatch); + } + + return base.IsMatch(contentType.MediaType); + } + + /// + public override string[] GetPatterns() + { + return _patterns; + } + + /// + public override string Name => "ContentTypeMatcher"; + } } \ No newline at end of file diff --git a/src/WireMock.Net/Matchers/ExactMatcher.cs b/src/WireMock.Net/Matchers/ExactMatcher.cs index ab2d3795..4ceee72f 100644 --- a/src/WireMock.Net/Matchers/ExactMatcher.cs +++ b/src/WireMock.Net/Matchers/ExactMatcher.cs @@ -1,59 +1,64 @@ -using System.Linq; -using JetBrains.Annotations; -using WireMock.Validation; - -namespace WireMock.Matchers -{ - /// - /// ExactMatcher - /// - /// - public class ExactMatcher : IStringMatcher - { - private readonly string[] _values; - - /// - public MatchBehaviour MatchBehaviour { get; } - - /// - /// Initializes a new instance of the class. - /// - /// The values. - public ExactMatcher([NotNull] params string[] values) : this(MatchBehaviour.AcceptOnMatch, values) - { - } - - /// - /// Initializes a new instance of the class. - /// - /// The match behaviour. - /// The values. - public ExactMatcher(MatchBehaviour matchBehaviour, [NotNull] params string[] values) - { - Check.HasNoNulls(values, nameof(values)); - - _values = values; - MatchBehaviour = matchBehaviour; - } - - /// - public double IsMatch(string input) - { - if (_values.Length == 1) - { - return MatchBehaviourHelper.Convert(MatchBehaviour, MatchScores.ToScore(_values[0] == input)); - } - - return MatchBehaviourHelper.Convert(MatchBehaviour, MatchScores.ToScore(_values.Contains(input))); - } - - /// - public string[] GetPatterns() - { - return _values; - } - - /// - public string Name => "ExactMatcher"; - } +using System.Linq; +using JetBrains.Annotations; +using WireMock.Validation; + +namespace WireMock.Matchers +{ + /// + /// ExactMatcher + /// + /// + public class ExactMatcher : IStringMatcher + { + private readonly string[] _values; + + /// + public MatchBehaviour MatchBehaviour { get; } + + /// + public bool ThrowException { get; } + + /// + /// Initializes a new instance of the class. + /// + /// The values. + public ExactMatcher([NotNull] params string[] values) : this(MatchBehaviour.AcceptOnMatch, false, values) + { + } + + /// + /// Initializes a new instance of the class. + /// + /// The match behaviour. + /// Throw an exception when the internal matching fails because of invalid input. + /// The values. + public ExactMatcher(MatchBehaviour matchBehaviour, bool throwException = false, [NotNull] params string[] values) + { + Check.HasNoNulls(values, nameof(values)); + + MatchBehaviour = matchBehaviour; + ThrowException = throwException; + _values = values; + } + + /// + public double IsMatch(string input) + { + if (_values.Length == 1) + { + return MatchBehaviourHelper.Convert(MatchBehaviour, MatchScores.ToScore(_values[0] == input)); + } + + return MatchBehaviourHelper.Convert(MatchBehaviour, MatchScores.ToScore(_values.Contains(input))); + } + + /// + public string[] GetPatterns() + { + return _values; + } + + /// + public string Name => "ExactMatcher"; + } } \ No newline at end of file diff --git a/src/WireMock.Net/Matchers/ExactObjectMatcher.cs b/src/WireMock.Net/Matchers/ExactObjectMatcher.cs index 5bd79429..ce8af29f 100644 --- a/src/WireMock.Net/Matchers/ExactObjectMatcher.cs +++ b/src/WireMock.Net/Matchers/ExactObjectMatcher.cs @@ -1,78 +1,83 @@ -using JetBrains.Annotations; -using System.Linq; -using WireMock.Validation; - -namespace WireMock.Matchers -{ - /// - /// ExactObjectMatcher - /// - /// - public class ExactObjectMatcher : IObjectMatcher - { - /// - /// Gets the value as object. - /// - public object ValueAsObject { get; } - - /// - /// Gets the value as byte[]. - /// - public byte[] ValueAsBytes { get; } - - /// - public MatchBehaviour MatchBehaviour { get; } - - /// - /// Initializes a new instance of the class. - /// - /// The value. - public ExactObjectMatcher([NotNull] object value) : this(MatchBehaviour.AcceptOnMatch, value) - { - } - - /// - /// Initializes a new instance of the class. - /// - /// The match behaviour. - /// The value. - public ExactObjectMatcher(MatchBehaviour matchBehaviour, [NotNull] object value) - { - Check.NotNull(value, nameof(value)); - - ValueAsObject = value; - MatchBehaviour = matchBehaviour; - } - - /// - /// Initializes a new instance of the class. - /// - /// The value. - public ExactObjectMatcher([NotNull] byte[] value) : this(MatchBehaviour.AcceptOnMatch, value) - { - } - - /// - /// Initializes a new instance of the class. - /// - /// The match behaviour. - /// The value. - public ExactObjectMatcher(MatchBehaviour matchBehaviour, [NotNull] byte[] value) - { - Check.NotNull(value, nameof(value)); - - ValueAsBytes = value; - MatchBehaviour = matchBehaviour; - } - - /// - public double IsMatch(object input) - { - bool equals = ValueAsObject != null ? Equals(ValueAsObject, input) : ValueAsBytes.SequenceEqual((byte[])input); - return MatchBehaviourHelper.Convert(MatchBehaviour, MatchScores.ToScore(equals)); - } - - /// - public string Name => "ExactObjectMatcher"; - } +using JetBrains.Annotations; +using System.Linq; +using WireMock.Validation; + +namespace WireMock.Matchers +{ + /// + /// ExactObjectMatcher + /// + /// + public class ExactObjectMatcher : IObjectMatcher + { + /// + /// Gets the value as object. + /// + public object ValueAsObject { get; } + + /// + /// Gets the value as byte[]. + /// + public byte[] ValueAsBytes { get; } + + /// + public MatchBehaviour MatchBehaviour { get; } + + /// + public bool ThrowException { get; } + + /// + /// Initializes a new instance of the class. + /// + /// The value. + public ExactObjectMatcher([NotNull] object value) : this(MatchBehaviour.AcceptOnMatch, value) + { + } + + /// + /// Initializes a new instance of the class. + /// + /// The match behaviour. + /// The value. + public ExactObjectMatcher(MatchBehaviour matchBehaviour, [NotNull] object value) + { + Check.NotNull(value, nameof(value)); + + ValueAsObject = value; + MatchBehaviour = matchBehaviour; + } + + /// + /// Initializes a new instance of the class. + /// + /// The value. + public ExactObjectMatcher([NotNull] byte[] value) : this(MatchBehaviour.AcceptOnMatch, value) + { + } + + /// + /// Initializes a new instance of the class. + /// + /// The match behaviour. + /// Throw an exception when the internal matching fails because of invalid input. + /// The value. + public ExactObjectMatcher(MatchBehaviour matchBehaviour, [NotNull] byte[] value, bool throwException = false) + { + Check.NotNull(value, nameof(value)); + + MatchBehaviour = matchBehaviour; + ThrowException = throwException; + ValueAsBytes = value; + } + + /// + public double IsMatch(object input) + { + bool equals = ValueAsObject != null ? Equals(ValueAsObject, input) : ValueAsBytes.SequenceEqual((byte[])input); + return MatchBehaviourHelper.Convert(MatchBehaviour, MatchScores.ToScore(equals)); + } + + /// + public string Name => "ExactObjectMatcher"; + } } \ No newline at end of file diff --git a/src/WireMock.Net/Matchers/IMatcher.cs b/src/WireMock.Net/Matchers/IMatcher.cs index 35650b4e..67dde261 100644 --- a/src/WireMock.Net/Matchers/IMatcher.cs +++ b/src/WireMock.Net/Matchers/IMatcher.cs @@ -1,18 +1,23 @@ -namespace WireMock.Matchers -{ - /// - /// IMatcher - /// - public interface IMatcher - { - /// - /// Gets the name. - /// - string Name { get; } - - /// - /// Gets the match behaviour. - /// - MatchBehaviour MatchBehaviour { get; } - } +namespace WireMock.Matchers +{ + /// + /// IMatcher + /// + public interface IMatcher + { + /// + /// Gets the name. + /// + string Name { get; } + + /// + /// Gets the match behaviour. + /// + MatchBehaviour MatchBehaviour { get; } + + /// + /// Should this matcher throw an exception? + /// + bool ThrowException { get; } + } } \ No newline at end of file diff --git a/src/WireMock.Net/Matchers/JSONPathMatcher.cs b/src/WireMock.Net/Matchers/JSONPathMatcher.cs index 5a672488..65937497 100644 --- a/src/WireMock.Net/Matchers/JSONPathMatcher.cs +++ b/src/WireMock.Net/Matchers/JSONPathMatcher.cs @@ -1,99 +1,110 @@ -using System.Linq; -using JetBrains.Annotations; -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; -using WireMock.Validation; - -namespace WireMock.Matchers -{ - /// - /// JsonPathMatcher - /// - /// - /// - public class JsonPathMatcher : IStringMatcher, IObjectMatcher - { - private readonly string[] _patterns; - - /// - public MatchBehaviour MatchBehaviour { get; } - - /// - /// Initializes a new instance of the class. - /// - /// The patterns. - public JsonPathMatcher([NotNull] params string[] patterns) : this(MatchBehaviour.AcceptOnMatch, patterns) - { - } - - /// - /// Initializes a new instance of the class. - /// - /// The match behaviour. - /// The patterns. - public JsonPathMatcher(MatchBehaviour matchBehaviour, [NotNull] params string[] patterns) - { - Check.NotNull(patterns, nameof(patterns)); - - MatchBehaviour = matchBehaviour; - _patterns = patterns; - } - - /// - public double IsMatch(string input) - { - double match = MatchScores.Mismatch; - if (input != null) - { - try - { - var jtoken = JToken.Parse(input); - match = IsMatch(jtoken); - } - catch (JsonException) - { - // just ignore JsonException - } - } - - return MatchBehaviourHelper.Convert(MatchBehaviour, match); - } - - /// - public double IsMatch(object input) - { - double match = MatchScores.Mismatch; - - // When input is null or byte[], return Mismatch. - if (input != null && !(input is byte[])) - { - try - { - // Check if JToken or object - JToken jtoken = input is JToken token ? token : JObject.FromObject(input); - match = IsMatch(jtoken); - } - catch (JsonException) - { - // just ignore JsonException - } - } - - return MatchBehaviourHelper.Convert(MatchBehaviour, match); - } - - /// - public string[] GetPatterns() - { - return _patterns; - } - - /// - public string Name => "JsonPathMatcher"; - - private double IsMatch(JToken jtoken) - { - return MatchScores.ToScore(_patterns.Select(pattern => jtoken.SelectToken(pattern) != null)); - } - } +using System.Linq; +using JetBrains.Annotations; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; +using WireMock.Validation; + +namespace WireMock.Matchers +{ + /// + /// JsonPathMatcher + /// + /// + /// + public class JsonPathMatcher : IStringMatcher, IObjectMatcher + { + private readonly string[] _patterns; + + /// + public MatchBehaviour MatchBehaviour { get; } + + /// + public bool ThrowException { get; } + + /// + /// Initializes a new instance of the class. + /// + /// The patterns. + public JsonPathMatcher([NotNull] params string[] patterns) : this(MatchBehaviour.AcceptOnMatch, false, patterns) + { + } + + /// + /// Initializes a new instance of the class. + /// + /// The match behaviour. + /// Throw an exception when the internal matching fails because of invalid input. + /// The patterns. + public JsonPathMatcher(MatchBehaviour matchBehaviour, bool throwException = false, [NotNull] params string[] patterns) + { + Check.NotNull(patterns, nameof(patterns)); + + MatchBehaviour = matchBehaviour; + ThrowException = throwException; + _patterns = patterns; + } + + /// + public double IsMatch(string input) + { + double match = MatchScores.Mismatch; + if (input != null) + { + try + { + var jtoken = JToken.Parse(input); + match = IsMatch(jtoken); + } + catch (JsonException) + { + if (ThrowException) + { + throw; + } + } + } + + return MatchBehaviourHelper.Convert(MatchBehaviour, match); + } + + /// + public double IsMatch(object input) + { + double match = MatchScores.Mismatch; + + // When input is null or byte[], return Mismatch. + if (input != null && !(input is byte[])) + { + try + { + // Check if JToken or object + JToken jtoken = input is JToken token ? token : JObject.FromObject(input); + match = IsMatch(jtoken); + } + catch (JsonException) + { + if (ThrowException) + { + throw; + } + } + } + + return MatchBehaviourHelper.Convert(MatchBehaviour, match); + } + + /// + public string[] GetPatterns() + { + return _patterns; + } + + /// + public string Name => "JsonPathMatcher"; + + private double IsMatch(JToken jtoken) + { + return MatchScores.ToScore(_patterns.Select(pattern => jtoken.SelectToken(pattern) != null)); + } + } } \ No newline at end of file diff --git a/src/WireMock.Net/Matchers/JmesPathMatcher.cs b/src/WireMock.Net/Matchers/JmesPathMatcher.cs index a01308f0..7f916746 100644 --- a/src/WireMock.Net/Matchers/JmesPathMatcher.cs +++ b/src/WireMock.Net/Matchers/JmesPathMatcher.cs @@ -1,83 +1,100 @@ -using DevLab.JmesPath; -using JetBrains.Annotations; -using Newtonsoft.Json; -using System.Linq; -using WireMock.Validation; - -namespace WireMock.Matchers -{ - /// - /// http://jmespath.org/ - /// - public class JmesPathMatcher : IStringMatcher, IObjectMatcher - { - private readonly string[] _patterns; - - /// - public MatchBehaviour MatchBehaviour { get; } - - /// - /// Initializes a new instance of the class. - /// - /// The patterns. - public JmesPathMatcher([NotNull] params string[] patterns) : this(MatchBehaviour.AcceptOnMatch, patterns) - { - } - - /// - /// Initializes a new instance of the class. - /// - /// The match behaviour. - /// The patterns. - public JmesPathMatcher(MatchBehaviour matchBehaviour, [NotNull] params string[] patterns) - { - Check.NotNull(patterns, nameof(patterns)); - - MatchBehaviour = matchBehaviour; - _patterns = patterns; - } - - /// - public double IsMatch(string input) - { - double match = MatchScores.Mismatch; - if (input != null) - { - try - { - match = MatchScores.ToScore(_patterns.Select(pattern => bool.Parse(new JmesPath().Transform(input, pattern)))); - } - catch (JsonException) - { - // just ignore JsonException - } - } - - return MatchBehaviourHelper.Convert(MatchBehaviour, match); - } - - /// - public double IsMatch(object input) - { - double match = MatchScores.Mismatch; - - // When input is null or byte[], return Mismatch. - if (input != null && !(input is byte[])) - { - string inputAsString = JsonConvert.SerializeObject(input); - return IsMatch(inputAsString); - } - - return MatchBehaviourHelper.Convert(MatchBehaviour, match); - } - - /// - public string[] GetPatterns() - { - return _patterns; - } - - /// - public string Name => "JmesPathMatcher"; - } +using DevLab.JmesPath; +using JetBrains.Annotations; +using Newtonsoft.Json; +using System.Linq; +using WireMock.Validation; + +namespace WireMock.Matchers +{ + /// + /// http://jmespath.org/ + /// + public class JmesPathMatcher : IStringMatcher, IObjectMatcher + { + private readonly string[] _patterns; + + /// + public MatchBehaviour MatchBehaviour { get; } + + /// + public bool ThrowException { get; } + + /// + /// Initializes a new instance of the class. + /// + /// The patterns. + public JmesPathMatcher([NotNull] params string[] patterns) : this(MatchBehaviour.AcceptOnMatch, false, patterns) + { + } + + /// + /// Initializes a new instance of the class. + /// + /// Throw an exception when the internal matching fails because of invalid input. + /// The patterns. + public JmesPathMatcher(bool throwException = false, [NotNull] params string[] patterns) : this(MatchBehaviour.AcceptOnMatch, throwException, patterns) + { + } + + /// + /// Initializes a new instance of the class. + /// + /// The match behaviour. + /// Throw an exception when the internal matching fails because of invalid input. + /// The patterns. + public JmesPathMatcher(MatchBehaviour matchBehaviour, bool throwException = false, [NotNull] params string[] patterns) + { + Check.NotNull(patterns, nameof(patterns)); + + MatchBehaviour = matchBehaviour; + ThrowException = throwException; + _patterns = patterns; + } + + /// + public double IsMatch(string input) + { + double match = MatchScores.Mismatch; + if (input != null) + { + try + { + match = MatchScores.ToScore(_patterns.Select(pattern => bool.Parse(new JmesPath().Transform(input, pattern)))); + } + catch (JsonException) + { + if (ThrowException) + { + throw; + } + } + } + + return MatchBehaviourHelper.Convert(MatchBehaviour, match); + } + + /// + public double IsMatch(object input) + { + double match = MatchScores.Mismatch; + + // When input is null or byte[], return Mismatch. + if (input != null && !(input is byte[])) + { + string inputAsString = JsonConvert.SerializeObject(input); + return IsMatch(inputAsString); + } + + return MatchBehaviourHelper.Convert(MatchBehaviour, match); + } + + /// + public string[] GetPatterns() + { + return _patterns; + } + + /// + public string Name => "JmesPathMatcher"; + } } \ No newline at end of file diff --git a/src/WireMock.Net/Matchers/JsonMatcher.cs b/src/WireMock.Net/Matchers/JsonMatcher.cs index d7d0f758..85cfe6c0 100644 --- a/src/WireMock.Net/Matchers/JsonMatcher.cs +++ b/src/WireMock.Net/Matchers/JsonMatcher.cs @@ -1,169 +1,165 @@ -using JetBrains.Annotations; -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; -using System.Collections; -using System.Linq; -using WireMock.Util; -using WireMock.Validation; - -namespace WireMock.Matchers -{ - /// - /// JsonMatcher - /// - public class JsonMatcher : IValueMatcher, IIgnoreCaseMatcher - { - /// - public object Value { get; } - - /// - public string Name => "JsonMatcher"; - - /// - public MatchBehaviour MatchBehaviour { get; } - - /// - public bool IgnoreCase { get; } - - /// - /// Initializes a new instance of the class. - /// - /// The string value to check for equality. - /// Ignore the case from the PropertyName and PropertyValue (string only). - public JsonMatcher([NotNull] string value, bool ignoreCase = false) : this(MatchBehaviour.AcceptOnMatch, value, ignoreCase) - { - } - - /// - /// Initializes a new instance of the class. - /// - /// The object value to check for equality. - /// Ignore the case from the PropertyName and PropertyValue (string only). - public JsonMatcher([NotNull] object value, bool ignoreCase = false) : this(MatchBehaviour.AcceptOnMatch, value, ignoreCase) - { - } - - /// - /// Initializes a new instance of the class. - /// - /// The match behaviour. - /// The string value to check for equality. - /// Ignore the case from the PropertyName and PropertyValue (string only). - public JsonMatcher(MatchBehaviour matchBehaviour, [NotNull] string value, bool ignoreCase = false) - { - Check.NotNull(value, nameof(value)); - - MatchBehaviour = matchBehaviour; - Value = value; - IgnoreCase = ignoreCase; - } - - /// - /// Initializes a new instance of the class. - /// - /// The match behaviour. - /// The object value to check for equality. - /// Ignore the case from the PropertyName and PropertyValue (string only). - public JsonMatcher(MatchBehaviour matchBehaviour, [NotNull] object value, bool ignoreCase = false) - { - Check.NotNull(value, nameof(value)); - - MatchBehaviour = matchBehaviour; - Value = value; - IgnoreCase = ignoreCase; - } - - /// - public double IsMatch(object input) - { - bool match = false; - - // When input is null or byte[], return Mismatch. - if (input != null && !(input is byte[])) - { - try - { - // Check if JToken or object - JToken jtokenInput = input is JToken tokenInput ? tokenInput : JObject.FromObject(input); - - // Check if JToken, string, IEnumerable or object - 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) - { - // just ignore JsonException - } - } - - return MatchBehaviourHelper.Convert(MatchBehaviour, MatchScores.ToScore(match)); - } - - private bool DeepEquals(JToken value, JToken input) - { - if (!IgnoreCase) - { - return JToken.DeepEquals(value, input); - } - - JToken renamedValue = Rename(value); - JToken renamedInput = Rename(input); - - return JToken.DeepEquals(renamedValue, renamedInput); - } - - private static string ToUpper(string input) - { - return input?.ToUpperInvariant(); - } - - // https://stackoverflow.com/questions/11679804/json-net-rename-properties - private static JToken Rename(JToken json) - { - if (json is JProperty property) - { - JToken propertyValue = property.Value; - if (propertyValue.Type == JTokenType.String) - { - string stringValue = propertyValue.Value(); - propertyValue = ToUpper(stringValue); - } - - return new JProperty(ToUpper(property.Name), Rename(propertyValue)); - } - - if (json is JArray array) - { - var renamedValues = array.Select(Rename); - return new JArray(renamedValues); - } - - if (json is JObject obj) - { - var renamedProperties = obj.Properties().Select(Rename); - return new JObject(renamedProperties); - } - - return json; - } - } +using System.Collections; +using System.Linq; +using JetBrains.Annotations; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; +using WireMock.Util; +using WireMock.Validation; + +namespace WireMock.Matchers +{ + /// + /// JsonMatcher + /// + public class JsonMatcher : IValueMatcher, IIgnoreCaseMatcher + { + /// + public object Value { get; } + + /// + public string Name => "JsonMatcher"; + + /// + public MatchBehaviour MatchBehaviour { get; } + + /// + public bool IgnoreCase { get; } + + /// + public bool ThrowException { get; } + + private readonly JToken _valueAsJToken; + + /// + /// Initializes a new instance of the class. + /// + /// The string value to check for equality. + /// Ignore the case from the PropertyName and PropertyValue (string only). + /// Throw an exception when the internal matching fails because of invalid input. + public JsonMatcher([NotNull] string value, bool ignoreCase = false, bool throwException = false) : this(MatchBehaviour.AcceptOnMatch, value, ignoreCase, throwException) + { + } + + /// + /// Initializes a new instance of the class. + /// + /// The object value to check for equality. + /// Ignore the case from the PropertyName and PropertyValue (string only). + /// Throw an exception when the internal matching fails because of invalid input. + public JsonMatcher([NotNull] object value, bool ignoreCase = false, bool throwException = false) : this(MatchBehaviour.AcceptOnMatch, value, ignoreCase, throwException) + { + } + + /// + /// Initializes a new instance of the class. + /// + /// The match behaviour. + /// The value to check for equality. + /// Ignore the case from the PropertyName and PropertyValue (string only). + /// Throw an exception when the internal matching fails because of invalid input. + public JsonMatcher(MatchBehaviour matchBehaviour, [NotNull] object value, bool ignoreCase = false, bool throwException = false) + { + Check.NotNull(value, nameof(value)); + + MatchBehaviour = matchBehaviour; + IgnoreCase = ignoreCase; + ThrowException = throwException; + + Value = value; + _valueAsJToken = ConvertValueToJToken(value); + } + + /// + public double IsMatch(object input) + { + bool match = false; + + // When input is null or byte[], return Mismatch. + if (input != null && !(input is byte[])) + { + try + { + var inputAsJToken = ConvertValueToJToken(input); + + match = DeepEquals(_valueAsJToken, inputAsJToken); + } + catch (JsonException) + { + if (ThrowException) + { + throw; + } + } + } + + 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) + { + if (!IgnoreCase) + { + return JToken.DeepEquals(value, input); + } + + JToken renamedValue = Rename(value); + JToken renamedInput = Rename(input); + + return JToken.DeepEquals(renamedValue, renamedInput); + } + + private static string ToUpper(string input) + { + return input?.ToUpperInvariant(); + } + + // https://stackoverflow.com/questions/11679804/json-net-rename-properties + private static JToken Rename(JToken json) + { + if (json is JProperty property) + { + JToken propertyValue = property.Value; + if (propertyValue.Type == JTokenType.String) + { + string stringValue = propertyValue.Value(); + propertyValue = ToUpper(stringValue); + } + + return new JProperty(ToUpper(property.Name), Rename(propertyValue)); + } + + if (json is JArray array) + { + var renamedValues = array.Select(Rename); + return new JArray(renamedValues); + } + + if (json is JObject obj) + { + var renamedProperties = obj.Properties().Select(Rename); + return new JObject(renamedProperties); + } + + return json; + } + } } \ No newline at end of file diff --git a/src/WireMock.Net/Matchers/LinqMatcher.cs b/src/WireMock.Net/Matchers/LinqMatcher.cs index 500cbe4e..b3134a03 100644 --- a/src/WireMock.Net/Matchers/LinqMatcher.cs +++ b/src/WireMock.Net/Matchers/LinqMatcher.cs @@ -1,132 +1,140 @@ -using System.Linq; -using System.Linq.Dynamic.Core; -using JetBrains.Annotations; -using Newtonsoft.Json.Linq; -using WireMock.Util; - -namespace WireMock.Matchers -{ - /// - /// System.Linq.Dynamic.Core Expression Matcher - /// - /// - /// - public class LinqMatcher : IObjectMatcher, IStringMatcher - { - private readonly string[] _patterns; - - /// - public MatchBehaviour MatchBehaviour { get; } - - /// - /// Initializes a new instance of the class. - /// - /// The pattern. - public LinqMatcher([NotNull] string pattern) : this(new[] { pattern }) - { - } - - /// - /// Initializes a new instance of the class. - /// - /// The patterns. - public LinqMatcher([NotNull] string[] patterns) : this(MatchBehaviour.AcceptOnMatch, patterns) - { - } - - /// - /// Initializes a new instance of the class. - /// - /// The match behaviour. - /// The pattern. - public LinqMatcher(MatchBehaviour matchBehaviour, [NotNull] string pattern) : this(matchBehaviour, new[] { pattern }) - { - } - - /// - /// Initializes a new instance of the class. - /// - /// The match behaviour. - /// The patterns. - public LinqMatcher(MatchBehaviour matchBehaviour, [NotNull] string[] patterns) - { - MatchBehaviour = matchBehaviour; - _patterns = patterns; - } - - /// - public double IsMatch(string input) - { - double match = MatchScores.Mismatch; - - // Convert a single input string to a Queryable string-list with 1 entry. - IQueryable queryable = new[] { input }.AsQueryable(); - - try - { - // Use the Any(...) method to check if the result matches - match = MatchScores.ToScore(_patterns.Select(pattern => queryable.Any(pattern))); - - return MatchBehaviourHelper.Convert(MatchBehaviour, match); - } - catch - { - // just ignore exception - // TODO add logging? - } - - return MatchBehaviourHelper.Convert(MatchBehaviour, match); - } - - /// - public double IsMatch(object input) - { - double match = MatchScores.Mismatch; - - JObject value; - switch (input) - { - case JObject valueAsJObject: - value = valueAsJObject; - break; - - default: - value = JObject.FromObject(input); - break; - } - - // Convert a single object to a Queryable JObject-list with 1 entry. - var queryable1 = new[] { value }.AsQueryable(); - - try - { - // Generate the DynamicLinq select statement. - string dynamicSelect = JsonUtils.GenerateDynamicLinqStatement(value); - - // Execute DynamicLinq Select statement. - var queryable2 = queryable1.Select(dynamicSelect); - - // Use the Any(...) method to check if the result matches. - match = MatchScores.ToScore(_patterns.Select(pattern => queryable2.Any(pattern))); - - return MatchBehaviourHelper.Convert(MatchBehaviour, match); - } - catch - { - // just ignore exception - // TODO add logging? - } - - return MatchBehaviourHelper.Convert(MatchBehaviour, match); - } - - /// - public string[] GetPatterns() - { - return _patterns; - } - - /// - public string Name => "LinqMatcher"; - } -} +using System.Linq; +using System.Linq.Dynamic.Core; +using JetBrains.Annotations; +using Newtonsoft.Json.Linq; +using WireMock.Util; + +namespace WireMock.Matchers +{ + /// + /// System.Linq.Dynamic.Core Expression Matcher + /// + /// + /// + public class LinqMatcher : IObjectMatcher, IStringMatcher + { + private readonly string[] _patterns; + + /// + public MatchBehaviour MatchBehaviour { get; } + /// + public bool ThrowException { get; } + + /// + /// Initializes a new instance of the class. + /// + /// The pattern. + public LinqMatcher([NotNull] string pattern) : this(new[] { pattern }) + { + } + + /// + /// Initializes a new instance of the class. + /// + /// The patterns. + public LinqMatcher([NotNull] params string[] patterns) : this(MatchBehaviour.AcceptOnMatch, false, patterns) + { + } + + /// + /// Initializes a new instance of the class. + /// + /// The match behaviour. + /// The pattern. + public LinqMatcher(MatchBehaviour matchBehaviour, [NotNull] string pattern) : this(matchBehaviour, false, pattern) + { + } + + /// + /// Initializes a new instance of the class. + /// + /// The match behaviour. + /// The patterns. + /// Throw an exception when the internal matching fails because of invalid input. + public LinqMatcher(MatchBehaviour matchBehaviour, bool throwException = false, [NotNull] params string[] patterns) + { + MatchBehaviour = matchBehaviour; + ThrowException = throwException; + _patterns = patterns; + } + + /// + public double IsMatch(string input) + { + double match = MatchScores.Mismatch; + + // Convert a single input string to a Queryable string-list with 1 entry. + IQueryable queryable = new[] { input }.AsQueryable(); + + try + { + // Use the Any(...) method to check if the result matches + match = MatchScores.ToScore(_patterns.Select(pattern => queryable.Any(pattern))); + + return MatchBehaviourHelper.Convert(MatchBehaviour, match); + } + catch + { + if (ThrowException) + { + throw; + } + } + + return MatchBehaviourHelper.Convert(MatchBehaviour, match); + } + + /// + public double IsMatch(object input) + { + double match = MatchScores.Mismatch; + + JObject value; + switch (input) + { + case JObject valueAsJObject: + value = valueAsJObject; + break; + + default: + value = JObject.FromObject(input); + break; + } + + // Convert a single object to a Queryable JObject-list with 1 entry. + var queryable1 = new[] { value }.AsQueryable(); + + try + { + // Generate the DynamicLinq select statement. + string dynamicSelect = JsonUtils.GenerateDynamicLinqStatement(value); + + // Execute DynamicLinq Select statement. + var queryable2 = queryable1.Select(dynamicSelect); + + // Use the Any(...) method to check if the result matches. + match = MatchScores.ToScore(_patterns.Select(pattern => queryable2.Any(pattern))); + + return MatchBehaviourHelper.Convert(MatchBehaviour, match); + } + catch + { + if (ThrowException) + { + throw; + } + } + + return MatchBehaviourHelper.Convert(MatchBehaviour, match); + } + + /// + public string[] GetPatterns() + { + return _patterns; + } + + /// + public string Name => "LinqMatcher"; + } +} diff --git a/src/WireMock.Net/Matchers/RegexMatcher.cs b/src/WireMock.Net/Matchers/RegexMatcher.cs index 4e83c9e7..a5b52b55 100644 --- a/src/WireMock.Net/Matchers/RegexMatcher.cs +++ b/src/WireMock.Net/Matchers/RegexMatcher.cs @@ -19,6 +19,9 @@ namespace WireMock.Matchers /// public MatchBehaviour MatchBehaviour { get; } + /// + public bool ThrowException { get; } + /// /// Initializes a new instance of the class. /// @@ -53,13 +56,15 @@ namespace WireMock.Matchers /// The match behaviour. /// The patterns. /// Ignore the case from the pattern. - public RegexMatcher(MatchBehaviour matchBehaviour, [NotNull, RegexPattern] string[] patterns, bool ignoreCase = false) + /// Throw an exception when the internal matching fails because of invalid input. + public RegexMatcher(MatchBehaviour matchBehaviour, [NotNull, RegexPattern] string[] patterns, bool ignoreCase = false, bool throwException = false) { Check.NotNull(patterns, nameof(patterns)); _patterns = patterns; IgnoreCase = ignoreCase; MatchBehaviour = matchBehaviour; + ThrowException = throwException; RegexOptions options = RegexOptions.Compiled | RegexOptions.Multiline; @@ -83,10 +88,13 @@ namespace WireMock.Matchers } catch (Exception) { - // just ignore exception + if (ThrowException) + { + throw; + } } - } - + } + return MatchBehaviourHelper.Convert(MatchBehaviour, match); } diff --git a/src/WireMock.Net/Matchers/Request/RequestMessageParamMatcher.cs b/src/WireMock.Net/Matchers/Request/RequestMessageParamMatcher.cs index 9b8d19f7..808d9001 100644 --- a/src/WireMock.Net/Matchers/Request/RequestMessageParamMatcher.cs +++ b/src/WireMock.Net/Matchers/Request/RequestMessageParamMatcher.cs @@ -51,7 +51,7 @@ namespace WireMock.Matchers.Request /// The key. /// Defines if the key should be matched using case-ignore. /// The values. - public RequestMessageParamMatcher(MatchBehaviour matchBehaviour, [NotNull] string key, bool ignoreCase, [CanBeNull] string[] values) : this(matchBehaviour, key, ignoreCase, values?.Select(value => new ExactMatcher(matchBehaviour, value)).Cast().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().ToArray()) { } diff --git a/src/WireMock.Net/Matchers/SimMetricsMatcher.cs b/src/WireMock.Net/Matchers/SimMetricsMatcher.cs index 4cf08b84..95125cda 100644 --- a/src/WireMock.Net/Matchers/SimMetricsMatcher.cs +++ b/src/WireMock.Net/Matchers/SimMetricsMatcher.cs @@ -1,125 +1,131 @@ -using System.Linq; -using JetBrains.Annotations; -using SimMetrics.Net; -using SimMetrics.Net.API; -using SimMetrics.Net.Metric; -using WireMock.Validation; - -namespace WireMock.Matchers -{ - /// - /// SimMetricsMatcher - /// - /// - public class SimMetricsMatcher : IStringMatcher - { - private readonly string[] _patterns; - private readonly SimMetricType _simMetricType; - - /// - public MatchBehaviour MatchBehaviour { get; } - - /// - /// Initializes a new instance of the class. - /// - /// The pattern. - /// The SimMetric Type - public SimMetricsMatcher([NotNull] string pattern, SimMetricType simMetricType = SimMetricType.Levenstein) : this(new[] { pattern }, simMetricType) - { - } - - /// - /// Initializes a new instance of the class. - /// - /// The match behaviour. - /// The pattern. - /// The SimMetric Type - public SimMetricsMatcher(MatchBehaviour matchBehaviour, [NotNull] string pattern, SimMetricType simMetricType = SimMetricType.Levenstein) : this(matchBehaviour, new[] { pattern }, simMetricType) - { - } - - /// - /// Initializes a new instance of the class. - /// - /// The patterns. - /// The SimMetric Type - public SimMetricsMatcher([NotNull] string[] patterns, SimMetricType simMetricType = SimMetricType.Levenstein) : this(MatchBehaviour.AcceptOnMatch, patterns, simMetricType) - { - } - - /// - /// Initializes a new instance of the class. - /// - /// The match behaviour. - /// The patterns. - /// The SimMetric Type - public SimMetricsMatcher(MatchBehaviour matchBehaviour, [NotNull] string[] patterns, SimMetricType simMetricType = SimMetricType.Levenstein) - { - Check.NotNullOrEmpty(patterns, nameof(patterns)); - - MatchBehaviour = matchBehaviour; - _patterns = patterns; - _simMetricType = simMetricType; - } - - /// - public double IsMatch(string input) - { - IStringMetric m = GetStringMetricType(); - - return MatchBehaviourHelper.Convert(MatchBehaviour, MatchScores.ToScore(_patterns.Select(p => m.GetSimilarity(p, input)))); - } - - private IStringMetric GetStringMetricType() - { - switch (_simMetricType) - { - case SimMetricType.BlockDistance: - return new BlockDistance(); - case SimMetricType.ChapmanLengthDeviation: - return new ChapmanLengthDeviation(); - case SimMetricType.CosineSimilarity: - return new CosineSimilarity(); - case SimMetricType.DiceSimilarity: - return new DiceSimilarity(); - case SimMetricType.EuclideanDistance: - return new EuclideanDistance(); - case SimMetricType.JaccardSimilarity: - return new JaccardSimilarity(); - case SimMetricType.Jaro: - return new Jaro(); - case SimMetricType.JaroWinkler: - return new JaroWinkler(); - case SimMetricType.MatchingCoefficient: - return new MatchingCoefficient(); - case SimMetricType.MongeElkan: - return new MongeElkan(); - case SimMetricType.NeedlemanWunch: - return new NeedlemanWunch(); - case SimMetricType.OverlapCoefficient: - return new OverlapCoefficient(); - case SimMetricType.QGramsDistance: - return new QGramsDistance(); - case SimMetricType.SmithWaterman: - return new SmithWaterman(); - case SimMetricType.SmithWatermanGotoh: - return new SmithWatermanGotoh(); - case SimMetricType.SmithWatermanGotohWindowedAffine: - return new SmithWatermanGotohWindowedAffine(); - case SimMetricType.ChapmanMeanLength: - return new ChapmanMeanLength(); - default: - return new Levenstein(); - } - } - - /// - public string[] GetPatterns() - { - return _patterns; - } - - /// - public string Name => $"SimMetricsMatcher.{_simMetricType}"; - } +using System.Linq; +using JetBrains.Annotations; +using SimMetrics.Net; +using SimMetrics.Net.API; +using SimMetrics.Net.Metric; +using WireMock.Validation; + +namespace WireMock.Matchers +{ + /// + /// SimMetricsMatcher + /// + /// + public class SimMetricsMatcher : IStringMatcher + { + private readonly string[] _patterns; + private readonly SimMetricType _simMetricType; + + /// + public MatchBehaviour MatchBehaviour { get; } + + /// + public bool ThrowException { get; } + + /// + /// Initializes a new instance of the class. + /// + /// The pattern. + /// The SimMetric Type + public SimMetricsMatcher([NotNull] string pattern, SimMetricType simMetricType = SimMetricType.Levenstein) : this(new[] { pattern }, simMetricType) + { + } + + /// + /// Initializes a new instance of the class. + /// + /// The match behaviour. + /// The pattern. + /// The SimMetric Type + public SimMetricsMatcher(MatchBehaviour matchBehaviour, [NotNull] string pattern, SimMetricType simMetricType = SimMetricType.Levenstein) : this(matchBehaviour, new[] { pattern }, simMetricType) + { + } + + /// + /// Initializes a new instance of the class. + /// + /// The patterns. + /// The SimMetric Type + public SimMetricsMatcher([NotNull] string[] patterns, SimMetricType simMetricType = SimMetricType.Levenstein) : this(MatchBehaviour.AcceptOnMatch, patterns, simMetricType) + { + } + + /// + /// Initializes a new instance of the class. + /// + /// The match behaviour. + /// The patterns. + /// The SimMetric Type + /// Throw an exception when the internal matching fails because of invalid input. + public SimMetricsMatcher(MatchBehaviour matchBehaviour, [NotNull] string[] patterns, SimMetricType simMetricType = SimMetricType.Levenstein, bool throwException = false) + { + Check.NotNullOrEmpty(patterns, nameof(patterns)); + + MatchBehaviour = matchBehaviour; + ThrowException = throwException; + + _patterns = patterns; + _simMetricType = simMetricType; + } + + /// + public double IsMatch(string input) + { + IStringMetric m = GetStringMetricType(); + + return MatchBehaviourHelper.Convert(MatchBehaviour, MatchScores.ToScore(_patterns.Select(p => m.GetSimilarity(p, input)))); + } + + private IStringMetric GetStringMetricType() + { + switch (_simMetricType) + { + case SimMetricType.BlockDistance: + return new BlockDistance(); + case SimMetricType.ChapmanLengthDeviation: + return new ChapmanLengthDeviation(); + case SimMetricType.CosineSimilarity: + return new CosineSimilarity(); + case SimMetricType.DiceSimilarity: + return new DiceSimilarity(); + case SimMetricType.EuclideanDistance: + return new EuclideanDistance(); + case SimMetricType.JaccardSimilarity: + return new JaccardSimilarity(); + case SimMetricType.Jaro: + return new Jaro(); + case SimMetricType.JaroWinkler: + return new JaroWinkler(); + case SimMetricType.MatchingCoefficient: + return new MatchingCoefficient(); + case SimMetricType.MongeElkan: + return new MongeElkan(); + case SimMetricType.NeedlemanWunch: + return new NeedlemanWunch(); + case SimMetricType.OverlapCoefficient: + return new OverlapCoefficient(); + case SimMetricType.QGramsDistance: + return new QGramsDistance(); + case SimMetricType.SmithWaterman: + return new SmithWaterman(); + case SimMetricType.SmithWatermanGotoh: + return new SmithWatermanGotoh(); + case SimMetricType.SmithWatermanGotohWindowedAffine: + return new SmithWatermanGotohWindowedAffine(); + case SimMetricType.ChapmanMeanLength: + return new ChapmanMeanLength(); + default: + return new Levenstein(); + } + } + + /// + public string[] GetPatterns() + { + return _patterns; + } + + /// + public string Name => $"SimMetricsMatcher.{_simMetricType}"; + } } \ No newline at end of file diff --git a/src/WireMock.Net/Matchers/WildcardMatcher.cs b/src/WireMock.Net/Matchers/WildcardMatcher.cs index 5b735f52..6e1b534b 100644 --- a/src/WireMock.Net/Matchers/WildcardMatcher.cs +++ b/src/WireMock.Net/Matchers/WildcardMatcher.cs @@ -1,63 +1,65 @@ -using System.Linq; -using System.Text.RegularExpressions; -using JetBrains.Annotations; - -namespace WireMock.Matchers -{ - /// - /// WildcardMatcher - /// - /// - public class WildcardMatcher : RegexMatcher - { - private readonly string[] _patterns; - - /// - /// Initializes a new instance of the class. - /// - /// The pattern. - /// IgnoreCase - public WildcardMatcher([NotNull] string pattern, bool ignoreCase = false) : this(new[] { pattern }, ignoreCase) - { - } - - /// - /// Initializes a new instance of the class. - /// - /// The match behaviour. - /// The pattern. - /// IgnoreCase - public WildcardMatcher(MatchBehaviour matchBehaviour, [NotNull] string pattern, bool ignoreCase = false) : this(matchBehaviour, new[] { pattern }, ignoreCase) - { - } - - /// - /// Initializes a new instance of the class. - /// - /// The patterns. - /// IgnoreCase - public WildcardMatcher([NotNull] string[] patterns, bool ignoreCase = false) : this(MatchBehaviour.AcceptOnMatch, patterns, ignoreCase) - { - } - - /// - /// Initializes a new instance of the class. - /// - /// The match behaviour. - /// The patterns. - /// IgnoreCase - public WildcardMatcher(MatchBehaviour matchBehaviour, [NotNull] string[] patterns, bool ignoreCase = false) : base(matchBehaviour, patterns.Select(pattern => "^" + Regex.Escape(pattern).Replace(@"\*", ".*").Replace(@"\?", ".") + "$").ToArray(), ignoreCase) - { - _patterns = patterns; - } - - /// - public override string[] GetPatterns() - { - return _patterns; - } - - /// - public override string Name => "WildcardMatcher"; - } +using System.Linq; +using System.Text.RegularExpressions; +using JetBrains.Annotations; + +namespace WireMock.Matchers +{ + /// + /// WildcardMatcher + /// + /// + public class WildcardMatcher : RegexMatcher + { + private readonly string[] _patterns; + + /// + /// Initializes a new instance of the class. + /// + /// The pattern. + /// IgnoreCase + public WildcardMatcher([NotNull] string pattern, bool ignoreCase = false) : this(new[] { pattern }, ignoreCase) + { + } + + /// + /// Initializes a new instance of the class. + /// + /// The match behaviour. + /// The pattern. + /// IgnoreCase + public WildcardMatcher(MatchBehaviour matchBehaviour, [NotNull] string pattern, bool ignoreCase = false) : this(matchBehaviour, new[] { pattern }, ignoreCase) + { + } + + /// + /// Initializes a new instance of the class. + /// + /// The patterns. + /// IgnoreCase + public WildcardMatcher([NotNull] string[] patterns, bool ignoreCase = false) : this(MatchBehaviour.AcceptOnMatch, patterns, ignoreCase) + { + } + + /// + /// Initializes a new instance of the class. + /// + /// The match behaviour. + /// The patterns. + /// IgnoreCase + /// Throw an exception when the internal matching fails because of invalid input. + 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; + } + + /// + public override string[] GetPatterns() + { + return _patterns; + } + + /// + public override string Name => "WildcardMatcher"; + } } \ No newline at end of file diff --git a/src/WireMock.Net/Matchers/XPathMatcher.cs b/src/WireMock.Net/Matchers/XPathMatcher.cs index 3be50236..ae8df174 100644 --- a/src/WireMock.Net/Matchers/XPathMatcher.cs +++ b/src/WireMock.Net/Matchers/XPathMatcher.cs @@ -1,78 +1,85 @@ -using System; -using System.Linq; -using System.Xml; -using JetBrains.Annotations; -using WireMock.Validation; -#if !NETSTANDARD1_3 -using Wmhelp.XPath2; -#endif - -namespace WireMock.Matchers -{ - /// - /// XPath2Matcher - /// - /// - public class XPathMatcher : IStringMatcher - { - private readonly string[] _patterns; - - /// - public MatchBehaviour MatchBehaviour { get; } - - /// - /// Initializes a new instance of the class. - /// - /// The patterns. - public XPathMatcher([NotNull] params string[] patterns) : this(MatchBehaviour.AcceptOnMatch, patterns) - { - } - - /// - /// Initializes a new instance of the class. - /// - /// The match behaviour. - /// The patterns. - public XPathMatcher(MatchBehaviour matchBehaviour, [NotNull] params string[] patterns) - { - Check.NotNull(patterns, nameof(patterns)); - - MatchBehaviour = matchBehaviour; - _patterns = patterns; - } - - /// - public double IsMatch(string input) - { - double match = MatchScores.Mismatch; - if (input != null) - { - try - { - var nav = new XmlDocument { InnerXml = input }.CreateNavigator(); -#if NETSTANDARD1_3 - match = MatchScores.ToScore(_patterns.Select(p => true.Equals(nav.Evaluate($"boolean({p})")))); -#else - match = MatchScores.ToScore(_patterns.Select(p => true.Equals(nav.XPath2Evaluate($"boolean({p})")))); -#endif - } - catch (Exception) - { - // just ignore exception - // TODO add logging? - } - } - - return MatchBehaviourHelper.Convert(MatchBehaviour, match); - } - - /// - public string[] GetPatterns() - { - return _patterns; - } - - /// - public string Name => "XPathMatcher"; - } +using System; +using System.Linq; +using System.Xml; +using JetBrains.Annotations; +using WireMock.Validation; +#if !NETSTANDARD1_3 +using Wmhelp.XPath2; +#endif + +namespace WireMock.Matchers +{ + /// + /// XPath2Matcher + /// + /// + public class XPathMatcher : IStringMatcher + { + private readonly string[] _patterns; + + /// + public MatchBehaviour MatchBehaviour { get; } + + /// + public bool ThrowException { get; } + + /// + /// Initializes a new instance of the class. + /// + /// The patterns. + public XPathMatcher([NotNull] params string[] patterns) : this(MatchBehaviour.AcceptOnMatch, false, patterns) + { + } + + /// + /// Initializes a new instance of the class. + /// + /// The match behaviour. + /// Throw an exception when the internal matching fails because of invalid input. + /// The patterns. + public XPathMatcher(MatchBehaviour matchBehaviour, bool throwException = false, [NotNull] params string[] patterns) + { + Check.NotNull(patterns, nameof(patterns)); + + MatchBehaviour = matchBehaviour; + ThrowException = throwException; + _patterns = patterns; + } + + /// + public double IsMatch(string input) + { + double match = MatchScores.Mismatch; + if (input != null) + { + try + { + var nav = new XmlDocument { InnerXml = input }.CreateNavigator(); +#if NETSTANDARD1_3 + match = MatchScores.ToScore(_patterns.Select(p => true.Equals(nav.Evaluate($"boolean({p})")))); +#else + match = MatchScores.ToScore(_patterns.Select(p => true.Equals(nav.XPath2Evaluate($"boolean({p})")))); +#endif + } + catch (Exception) + { + if (ThrowException) + { + throw; + } + } + } + + return MatchBehaviourHelper.Convert(MatchBehaviour, match); + } + + /// + public string[] GetPatterns() + { + return _patterns; + } + + /// + public string Name => "XPathMatcher"; + } } \ No newline at end of file diff --git a/src/WireMock.Net/Serialization/MatcherMapper.cs b/src/WireMock.Net/Serialization/MatcherMapper.cs index 45a86dce..50c4bc56 100644 --- a/src/WireMock.Net/Serialization/MatcherMapper.cs +++ b/src/WireMock.Net/Serialization/MatcherMapper.cs @@ -38,6 +38,8 @@ namespace WireMock.Serialization string[] stringPatterns = matcher.Patterns != null ? matcher.Patterns.OfType().ToArray() : new[] { matcher.Pattern as string }; MatchBehaviour matchBehaviour = matcher.RejectOnMatch == true ? MatchBehaviour.RejectOnMatch : MatchBehaviour.AcceptOnMatch; + bool ignoreCase = matcher.IgnoreCase == true; + bool throwExceptionWhenMatcherFails = _settings.ThrowExceptionWhenMatcherFails == true; 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'."); case "LinqMatcher": - return new LinqMatcher(matchBehaviour, stringPatterns); + return new LinqMatcher(matchBehaviour, throwExceptionWhenMatcherFails, stringPatterns); case "ExactMatcher": - return new ExactMatcher(matchBehaviour, stringPatterns); + return new ExactMatcher(matchBehaviour, throwExceptionWhenMatcherFails, stringPatterns); case "ExactObjectMatcher": - return CreateExactObjectMatcher(matchBehaviour, stringPatterns[0]); + return CreateExactObjectMatcher(matchBehaviour, stringPatterns[0], throwExceptionWhenMatcherFails); case "RegexMatcher": - return new RegexMatcher(matchBehaviour, stringPatterns, matcher.IgnoreCase == true); + return new RegexMatcher(matchBehaviour, stringPatterns, ignoreCase, throwExceptionWhenMatcherFails); case "JsonMatcher": - return new JsonMatcher(matchBehaviour, matcher.Pattern, matcher.IgnoreCase == true); + return new JsonMatcher(matchBehaviour, stringPatterns, ignoreCase, throwExceptionWhenMatcherFails); case "JsonPathMatcher": - return new JsonPathMatcher(matchBehaviour, stringPatterns); + return new JsonPathMatcher(matchBehaviour, throwExceptionWhenMatcherFails, stringPatterns); case "JmesPathMatcher": - return new JmesPathMatcher(matchBehaviour, stringPatterns); + return new JmesPathMatcher(matchBehaviour, throwExceptionWhenMatcherFails, stringPatterns); case "XPathMatcher": - return new XPathMatcher(matchBehaviour, stringPatterns); + return new XPathMatcher(matchBehaviour, throwExceptionWhenMatcherFails, stringPatterns); case "WildcardMatcher": - return new WildcardMatcher(matchBehaviour, stringPatterns, matcher.IgnoreCase == true); + return new WildcardMatcher(matchBehaviour, stringPatterns, ignoreCase, throwExceptionWhenMatcherFails); case "ContentTypeMatcher": - return new ContentTypeMatcher(matchBehaviour, stringPatterns, matcher.IgnoreCase == true); + return new ContentTypeMatcher(matchBehaviour, stringPatterns, ignoreCase, throwExceptionWhenMatcherFails); case "SimMetricsMatcher": SimMetricType type = SimMetricType.Levenstein; @@ -86,14 +88,14 @@ namespace WireMock.Serialization 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: 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; 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)); } - return new ExactObjectMatcher(matchBehaviour, bytePattern); + return new ExactObjectMatcher(matchBehaviour, bytePattern, throwException); } public MatcherModel[] Map([CanBeNull] IEnumerable matchers) diff --git a/src/WireMock.Net/Server/WireMockServer.Admin.cs b/src/WireMock.Net/Server/WireMockServer.Admin.cs index 3432da97..1a9d78ce 100644 --- a/src/WireMock.Net/Server/WireMockServer.Admin.cs +++ b/src/WireMock.Net/Server/WireMockServer.Admin.cs @@ -1,6 +1,3 @@ -using JetBrains.Annotations; -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; using System; using System.Collections.Generic; using System.IO; @@ -9,6 +6,9 @@ using System.Net; using System.Net.Http; using System.Text; using System.Threading.Tasks; +using JetBrains.Annotations; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; using WireMock.Admin.Mappings; using WireMock.Admin.Scenarios; using WireMock.Admin.Settings; @@ -274,7 +274,12 @@ namespace WireMock.Server if (HttpStatusRangeParser.IsMatch(settings.ProxyAndRecordSettings.SaveMappingForStatusCodePattern, responseMessage.StatusCode) && (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) { @@ -314,18 +319,19 @@ namespace WireMock.Server } }); + bool throwExceptionWhenMatcherFails = _settings.ThrowExceptionWhenMatcherFails == true; switch (requestMessage.BodyData?.DetectedBodyType) { case BodyType.Json: - request.WithBody(new JsonMatcher(MatchBehaviour.AcceptOnMatch, requestMessage.BodyData.BodyAsJson)); + request.WithBody(new JsonMatcher(MatchBehaviour.AcceptOnMatch, requestMessage.BodyData.BodyAsJson, true, throwExceptionWhenMatcherFails)); break; case BodyType.String: - request.WithBody(new ExactMatcher(MatchBehaviour.AcceptOnMatch, requestMessage.BodyData.BodyAsString)); + request.WithBody(new ExactMatcher(MatchBehaviour.AcceptOnMatch, throwExceptionWhenMatcherFails, requestMessage.BodyData.BodyAsString)); break; case BodyType.Bytes: - request.WithBody(new ExactObjectMatcher(MatchBehaviour.AcceptOnMatch, requestMessage.BodyData.BodyAsBytes)); + request.WithBody(new ExactObjectMatcher(MatchBehaviour.AcceptOnMatch, requestMessage.BodyData.BodyAsBytes, throwExceptionWhenMatcherFails)); break; } @@ -340,12 +346,13 @@ namespace WireMock.Server { var model = new SettingsModel { - AllowPartialMapping = _options.AllowPartialMapping, - MaxRequestLogCount = _options.MaxRequestLogCount, - RequestLogExpirationDuration = _options.RequestLogExpirationDuration, + AllowPartialMapping = _settings.AllowPartialMapping, + MaxRequestLogCount = _settings.MaxRequestLogCount, + RequestLogExpirationDuration = _settings.RequestLogExpirationDuration, GlobalProcessingDelay = (int?)_options.RequestProcessingDelay?.TotalMilliseconds, - AllowBodyForAllHttpMethods = _options.AllowBodyForAllHttpMethods, - HandleRequestsSynchronously = _options.HandleRequestsSynchronously + AllowBodyForAllHttpMethods = _settings.AllowBodyForAllHttpMethods, + HandleRequestsSynchronously = _settings.HandleRequestsSynchronously, + ThrowExceptionWhenMatcherFails = _settings.ThrowExceptionWhenMatcherFails }; return ToJson(model); @@ -377,6 +384,11 @@ namespace WireMock.Server _options.HandleRequestsSynchronously = settings.HandleRequestsSynchronously.Value; } + if (settings.ThrowExceptionWhenMatcherFails != null) + { + _settings.ThrowExceptionWhenMatcherFails = settings.ThrowExceptionWhenMatcherFails.Value; + } + return ResponseMessageBuilder.Create("Settings updated"); } #endregion Settings diff --git a/src/WireMock.Net/Settings/IWireMockServerSettings.cs b/src/WireMock.Net/Settings/IWireMockServerSettings.cs index 0d3ffd88..65ce9a30 100644 --- a/src/WireMock.Net/Settings/IWireMockServerSettings.cs +++ b/src/WireMock.Net/Settings/IWireMockServerSettings.cs @@ -3,6 +3,7 @@ using HandlebarsDotNet; using JetBrains.Annotations; using WireMock.Handlers; using WireMock.Logging; +using WireMock.Matchers; namespace WireMock.Settings { @@ -163,5 +164,11 @@ namespace WireMock.Settings /// [PublicAPI] bool? HandleRequestsSynchronously { get; set; } + + /// + /// Throw an exception when the fails because of invalid input. (default set to false). + /// + [PublicAPI] + bool? ThrowExceptionWhenMatcherFails { get; set; } } } \ No newline at end of file diff --git a/src/WireMock.Net/Settings/WireMockServerSettings.cs b/src/WireMock.Net/Settings/WireMockServerSettings.cs index 02a60d6a..ac1beb14 100644 --- a/src/WireMock.Net/Settings/WireMockServerSettings.cs +++ b/src/WireMock.Net/Settings/WireMockServerSettings.cs @@ -117,5 +117,9 @@ namespace WireMock.Settings /// [PublicAPI] public bool? HandleRequestsSynchronously { get; set; } + + /// + [PublicAPI] + public bool? ThrowExceptionWhenMatcherFails { get; set; } } } \ No newline at end of file diff --git a/src/WireMock.Net/Settings/WireMockServerSettingsParser.cs b/src/WireMock.Net/Settings/WireMockServerSettingsParser.cs index 366f1104..1c0236b0 100644 --- a/src/WireMock.Net/Settings/WireMockServerSettingsParser.cs +++ b/src/WireMock.Net/Settings/WireMockServerSettingsParser.cs @@ -37,7 +37,8 @@ namespace WireMock.Settings AllowBodyForAllHttpMethods = parser.GetBoolValue("AllowBodyForAllHttpMethods"), AllowOnlyDefinedHttpStatusCodeInResponse = parser.GetBoolValue("AllowOnlyDefinedHttpStatusCodeInResponse"), DisableJsonBodyParsing = parser.GetBoolValue("DisableJsonBodyParsing"), - HandleRequestsSynchronously = parser.GetBoolValue("HandleRequestsSynchronously") + HandleRequestsSynchronously = parser.GetBoolValue("HandleRequestsSynchronously"), + ThrowExceptionWhenMatcherFails = parser.GetBoolValue("ThrowExceptionWhenMatcherFails") }; if (logger != null) diff --git a/src/WireMock.Net/Transformers/HandlebarsContextFactory.cs b/src/WireMock.Net/Transformers/HandlebarsContextFactory.cs index b34b8c47..751c26ef 100644 --- a/src/WireMock.Net/Transformers/HandlebarsContextFactory.cs +++ b/src/WireMock.Net/Transformers/HandlebarsContextFactory.cs @@ -1,5 +1,5 @@ -using HandlebarsDotNet; -using System; +using System; +using HandlebarsDotNet; using WireMock.Handlers; namespace WireMock.Transformers diff --git a/src/WireMock.Net/Transformers/ResponseMessageTransformer.cs b/src/WireMock.Net/Transformers/ResponseMessageTransformer.cs index c11037b7..65aa277a 100644 --- a/src/WireMock.Net/Transformers/ResponseMessageTransformer.cs +++ b/src/WireMock.Net/Transformers/ResponseMessageTransformer.cs @@ -1,11 +1,10 @@ -using HandlebarsDotNet; +using System; +using System.Collections.Generic; +using System.Linq; +using HandlebarsDotNet; using JetBrains.Annotations; using Newtonsoft.Json; using Newtonsoft.Json.Linq; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; using WireMock.Types; using WireMock.Util; using WireMock.Validation; diff --git a/test/WireMock.Net.Tests/Matchers/CSharpCodeMatcherTests.cs b/test/WireMock.Net.Tests/Matchers/CSharpCodeMatcherTests.cs index 1519736f..fbc2c8fb 100644 --- a/test/WireMock.Net.Tests/Matchers/CSharpCodeMatcherTests.cs +++ b/test/WireMock.Net.Tests/Matchers/CSharpCodeMatcherTests.cs @@ -1,92 +1,92 @@ -using NFluent; -using WireMock.Matchers; -using Xunit; - -namespace WireMock.Net.Tests.Matchers -{ - public class CSharpCodeMatcherTests - { - [Fact] - public void CSharpCodeMatcher_For_String_SinglePattern_IsMatch_Positive() - { - // Assign - string input = "x"; - - // Act - var matcher = new CSharpCodeMatcher("return it == \"x\";"); - - // Assert - Check.That(matcher.IsMatch(input)).IsEqualTo(1.0d); - } - - [Fact] - public void CSharpCodeMatcher_For_String_IsMatch_Negative() - { - // Assign - string input = "y"; - - // Act - var matcher = new CSharpCodeMatcher("return it == \"x\";"); - - // Assert - Check.That(matcher.IsMatch(input)).IsEqualTo(0.0d); - } - - [Fact] - public void CSharpCodeMatcher_For_String_IsMatch_RejectOnMatch() - { - // Assign - string input = "x"; - - // Act - var matcher = new CSharpCodeMatcher(MatchBehaviour.RejectOnMatch, "return it == \"x\";"); - - // Assert - Check.That(matcher.IsMatch(input)).IsEqualTo(0.0d); - } - - [Fact] - public void CSharpCodeMatcher_For_Object_IsMatch() - { - // Assign - var input = new - { - Id = 9, - Name = "Test" - }; - - // Act - var matcher = new CSharpCodeMatcher("return it.Id > 1 && it.Name == \"Test\";"); - double match = matcher.IsMatch(input); - - // Assert - Assert.Equal(1.0, match); - } - - [Fact] - public void CSharpCodeMatcher_GetName() - { - // Assign - var matcher = new CSharpCodeMatcher("x"); - - // Act - string name = matcher.Name; - - // Assert - Check.That(name).Equals("CSharpCodeMatcher"); - } - - [Fact] - public void CSharpCodeMatcher_GetPatterns() - { - // Assign - var matcher = new CSharpCodeMatcher("x"); - - // Act - string[] patterns = matcher.GetPatterns(); - - // Assert - Check.That(patterns).ContainsExactly("x"); - } - } +using NFluent; +using WireMock.Matchers; +using Xunit; + +namespace WireMock.Net.Tests.Matchers +{ + public class CSharpCodeMatcherTests + { + [Fact] + public void CSharpCodeMatcher_For_String_SinglePattern_IsMatch_Positive() + { + // Assign + string input = "x"; + + // Act + var matcher = new CSharpCodeMatcher("return it == \"x\";"); + + // Assert + Check.That(matcher.IsMatch(input)).IsEqualTo(1.0d); + } + + [Fact] + public void CSharpCodeMatcher_For_String_IsMatch_Negative() + { + // Assign + string input = "y"; + + // Act + var matcher = new CSharpCodeMatcher("return it == \"x\";"); + + // Assert + Check.That(matcher.IsMatch(input)).IsEqualTo(0.0d); + } + + [Fact] + public void CSharpCodeMatcher_For_String_IsMatch_RejectOnMatch() + { + // Assign + string input = "x"; + + // Act + var matcher = new CSharpCodeMatcher(MatchBehaviour.RejectOnMatch, "return it == \"x\";"); + + // Assert + Check.That(matcher.IsMatch(input)).IsEqualTo(0.0d); + } + + [Fact] + public void CSharpCodeMatcher_For_Object_IsMatch() + { + // Assign + var input = new + { + Id = 9, + Name = "Test" + }; + + // Act + var matcher = new CSharpCodeMatcher("return it.Id > 1 && it.Name == \"Test\";"); + double match = matcher.IsMatch(input); + + // Assert + Assert.Equal(1.0, match); + } + + [Fact] + public void CSharpCodeMatcher_GetName() + { + // Assign + var matcher = new CSharpCodeMatcher("x"); + + // Act + string name = matcher.Name; + + // Assert + Check.That(name).Equals("CSharpCodeMatcher"); + } + + [Fact] + public void CSharpCodeMatcher_GetPatterns() + { + // Assign + var matcher = new CSharpCodeMatcher("x"); + + // Act + string[] patterns = matcher.GetPatterns(); + + // Assert + Check.That(patterns).ContainsExactly("x"); + } + } } \ No newline at end of file diff --git a/test/WireMock.Net.Tests/Matchers/ExactMatcherTests.cs b/test/WireMock.Net.Tests/Matchers/ExactMatcherTests.cs index bb91c329..1f58d1c8 100644 --- a/test/WireMock.Net.Tests/Matchers/ExactMatcherTests.cs +++ b/test/WireMock.Net.Tests/Matchers/ExactMatcherTests.cs @@ -1,113 +1,113 @@ -using NFluent; -using WireMock.Matchers; -using Xunit; - -namespace WireMock.Net.Tests.Matchers -{ - public class ExactMatcherTests - { - [Fact] - public void ExactMatcher_GetName() - { - // Assign - var matcher = new ExactMatcher("X"); - - // Act - string name = matcher.Name; - - // Assert - Check.That(name).Equals("ExactMatcher"); - } - - [Fact] - public void ExactMatcher_GetPatterns() - { - // Assign - var matcher = new ExactMatcher("X"); - - // Act - string[] patterns = matcher.GetPatterns(); - - // Assert - Check.That(patterns).ContainsExactly("X"); - } - - [Fact] - public void ExactMatcher_IsMatch_WithSinglePattern_ReturnsMatch1_0() - { - // Assign - var matcher = new ExactMatcher("x"); - - // Act - double result = matcher.IsMatch("x"); - - // Assert - Check.That(result).IsEqualTo(1.0); - } - - [Fact] - public void ExactMatcher_IsMatch_WithSinglePattern_ReturnsMatch0_0() - { - // Assign - var matcher = new ExactMatcher("x"); - - // Act - double result = matcher.IsMatch("y"); - - // Assert - Check.That(result).IsEqualTo(0.0); - } - - [Fact] - public void ExactMatcher_IsMatch_WithMultiplePatterns_ReturnsMatch0_5() - { - // Assign - var matcher = new ExactMatcher("x", "y"); - - // Act - double result = matcher.IsMatch("x"); - - // Assert - Check.That(result).IsEqualTo(1.0); - } - - [Fact] - public void ExactMatcher_IsMatch_SinglePattern() - { - // Assign - var matcher = new ExactMatcher("cat"); - - // Act - double result = matcher.IsMatch("caR"); - - // Assert - Check.That(result).IsEqualTo(0.0); - } - - [Fact] - public void ExactMatcher_IsMatch_SinglePattern_AcceptOnMatch() - { - // Assign - var matcher = new ExactMatcher(MatchBehaviour.AcceptOnMatch, "cat"); - - // Act - double result = matcher.IsMatch("cat"); - - // Assert - Check.That(result).IsEqualTo(1.0); - } - - [Fact] - public void ExactMatcher_IsMatch_SinglePattern_RejectOnMatch() - { - // Assign - var matcher = new ExactMatcher(MatchBehaviour.RejectOnMatch, "cat"); - - // Act - double result = matcher.IsMatch("cat"); - - // Assert - Check.That(result).IsEqualTo(0.0); - } - } +using NFluent; +using WireMock.Matchers; +using Xunit; + +namespace WireMock.Net.Tests.Matchers +{ + public class ExactMatcherTests + { + [Fact] + public void ExactMatcher_GetName() + { + // Assign + var matcher = new ExactMatcher("X"); + + // Act + string name = matcher.Name; + + // Assert + Check.That(name).Equals("ExactMatcher"); + } + + [Fact] + public void ExactMatcher_GetPatterns() + { + // Assign + var matcher = new ExactMatcher("X"); + + // Act + string[] patterns = matcher.GetPatterns(); + + // Assert + Check.That(patterns).ContainsExactly("X"); + } + + [Fact] + public void ExactMatcher_IsMatch_WithSinglePattern_ReturnsMatch1_0() + { + // Assign + var matcher = new ExactMatcher("x"); + + // Act + double result = matcher.IsMatch("x"); + + // Assert + Check.That(result).IsEqualTo(1.0); + } + + [Fact] + public void ExactMatcher_IsMatch_WithSinglePattern_ReturnsMatch0_0() + { + // Assign + var matcher = new ExactMatcher("x"); + + // Act + double result = matcher.IsMatch("y"); + + // Assert + Check.That(result).IsEqualTo(0.0); + } + + [Fact] + public void ExactMatcher_IsMatch_WithMultiplePatterns_ReturnsMatch0_5() + { + // Assign + var matcher = new ExactMatcher("x", "y"); + + // Act + double result = matcher.IsMatch("x"); + + // Assert + Check.That(result).IsEqualTo(1.0); + } + + [Fact] + public void ExactMatcher_IsMatch_SinglePattern() + { + // Assign + var matcher = new ExactMatcher("cat"); + + // Act + double result = matcher.IsMatch("caR"); + + // Assert + Check.That(result).IsEqualTo(0.0); + } + + [Fact] + public void ExactMatcher_IsMatch_SinglePattern_AcceptOnMatch() + { + // Assign + var matcher = new ExactMatcher(MatchBehaviour.AcceptOnMatch, false, "cat"); + + // Act + double result = matcher.IsMatch("cat"); + + // Assert + Check.That(result).IsEqualTo(1.0); + } + + [Fact] + public void ExactMatcher_IsMatch_SinglePattern_RejectOnMatch() + { + // Assign + var matcher = new ExactMatcher(MatchBehaviour.RejectOnMatch, false, "cat"); + + // Act + double result = matcher.IsMatch("cat"); + + // Assert + Check.That(result).IsEqualTo(0.0); + } + } } \ No newline at end of file diff --git a/test/WireMock.Net.Tests/Matchers/JmesPathMatcherTests.cs b/test/WireMock.Net.Tests/Matchers/JmesPathMatcherTests.cs index bef4724f..22f4d407 100644 --- a/test/WireMock.Net.Tests/Matchers/JmesPathMatcherTests.cs +++ b/test/WireMock.Net.Tests/Matchers/JmesPathMatcherTests.cs @@ -1,166 +1,166 @@ -using Newtonsoft.Json.Linq; -using NFluent; -using WireMock.Matchers; -using Xunit; - -namespace WireMock.Net.Tests.Matchers -{ - public class JmesPathMatcherTests - { - [Fact] - public void JmesPathMatcher_GetName() - { - // Assign - var matcher = new JmesPathMatcher("X"); - - // Act - string name = matcher.Name; - - // Assert - Check.That(name).Equals("JmesPathMatcher"); - } - - [Fact] - public void JmesPathMatcher_GetPatterns() - { - // Assign - var matcher = new JmesPathMatcher("X"); - - // Act - string[] patterns = matcher.GetPatterns(); - - // Assert - Check.That(patterns).ContainsExactly("X"); - } - - [Fact] - public void JmesPathMatcher_IsMatch_ByteArray() - { - // Assign - var bytes = new byte[0]; - var matcher = new JmesPathMatcher(""); - - // Act - double match = matcher.IsMatch(bytes); - - // Assert - Check.That(match).IsEqualTo(0); - } - - [Fact] - public void JmesPathMatcher_IsMatch_NullString() - { - // Assign - string s = null; - var matcher = new JmesPathMatcher(""); - - // Act - double match = matcher.IsMatch(s); - - // Assert - Check.That(match).IsEqualTo(0); - } - - [Fact] - public void JmesPathMatcher_IsMatch_NullObject() - { - // Assign - object o = null; - var matcher = new JmesPathMatcher(""); - - // Act - double match = matcher.IsMatch(o); - - // Assert - Check.That(match).IsEqualTo(0); - } - - [Fact] - public void JmesPathMatcher_IsMatch_String_Exception_Mismatch() - { - // Assign - var matcher = new JmesPathMatcher("xxx"); - - // Act - double match = matcher.IsMatch(""); - - // Assert - Check.That(match).IsEqualTo(0); - } - - [Fact] - public void JmesPathMatcher_IsMatch_Object_Exception_Mismatch() - { - // Assign - var matcher = new JmesPathMatcher(""); - - // Act - double match = matcher.IsMatch("x"); - - // Assert - Check.That(match).IsEqualTo(0); - } - - [Fact] - public void JmesPathMatcher_IsMatch_AnonymousObject() - { - // Assign - var matcher = new JmesPathMatcher("things.name == 'RequiredThing'"); - - // Act - double match = matcher.IsMatch(new { things = new { name = "RequiredThing" } }); - - // Assert - Check.That(match).IsEqualTo(1); - } - - [Fact] - public void JmesPathMatcher_IsMatch_JObject() - { - // Assign - string[] patterns = { "things.x == 'RequiredThing'" }; - var matcher = new JmesPathMatcher(patterns); - - // Act - var sub = new JObject - { - { "x", new JValue("RequiredThing") } - }; - var jobject = new JObject - { - { "Id", new JValue(1) }, - { "things", sub } - }; - double match = matcher.IsMatch(jobject); - - // Assert - Check.That(match).IsEqualTo(1); - } - - [Fact] - public void JmesPathMatcher_IsMatch_JObject_Parsed() - { - // Assign - var matcher = new JmesPathMatcher("things.x == 'RequiredThing'"); - - // Act - double match = matcher.IsMatch(JObject.Parse("{ \"things\": { \"x\": \"RequiredThing\" } }")); - - // Assert - Check.That(match).IsEqualTo(1); - } - - [Fact] - public void JmesPathMatcher_IsMatch_RejectOnMatch() - { - // Assign - var matcher = new JmesPathMatcher(MatchBehaviour.RejectOnMatch, "things.x == 'RequiredThing'"); - - // Act - double match = matcher.IsMatch(JObject.Parse("{ \"things\": { \"x\": \"RequiredThing\" } }")); - - // Assert - Check.That(match).IsEqualTo(0.0); - } - } +using Newtonsoft.Json.Linq; +using NFluent; +using WireMock.Matchers; +using Xunit; + +namespace WireMock.Net.Tests.Matchers +{ + public class JmesPathMatcherTests + { + [Fact] + public void JmesPathMatcher_GetName() + { + // Assign + var matcher = new JmesPathMatcher("X"); + + // Act + string name = matcher.Name; + + // Assert + Check.That(name).Equals("JmesPathMatcher"); + } + + [Fact] + public void JmesPathMatcher_GetPatterns() + { + // Assign + var matcher = new JmesPathMatcher("X"); + + // Act + string[] patterns = matcher.GetPatterns(); + + // Assert + Check.That(patterns).ContainsExactly("X"); + } + + [Fact] + public void JmesPathMatcher_IsMatch_ByteArray() + { + // Assign + var bytes = new byte[0]; + var matcher = new JmesPathMatcher(""); + + // Act + double match = matcher.IsMatch(bytes); + + // Assert + Check.That(match).IsEqualTo(0); + } + + [Fact] + public void JmesPathMatcher_IsMatch_NullString() + { + // Assign + string s = null; + var matcher = new JmesPathMatcher(""); + + // Act + double match = matcher.IsMatch(s); + + // Assert + Check.That(match).IsEqualTo(0); + } + + [Fact] + public void JmesPathMatcher_IsMatch_NullObject() + { + // Assign + object o = null; + var matcher = new JmesPathMatcher(""); + + // Act + double match = matcher.IsMatch(o); + + // Assert + Check.That(match).IsEqualTo(0); + } + + [Fact] + public void JmesPathMatcher_IsMatch_String_Exception_Mismatch() + { + // Assign + var matcher = new JmesPathMatcher("xxx"); + + // Act + double match = matcher.IsMatch(""); + + // Assert + Check.That(match).IsEqualTo(0); + } + + [Fact] + public void JmesPathMatcher_IsMatch_Object_Exception_Mismatch() + { + // Assign + var matcher = new JmesPathMatcher(""); + + // Act + double match = matcher.IsMatch("x"); + + // Assert + Check.That(match).IsEqualTo(0); + } + + [Fact] + public void JmesPathMatcher_IsMatch_AnonymousObject() + { + // Assign + var matcher = new JmesPathMatcher("things.name == 'RequiredThing'"); + + // Act + double match = matcher.IsMatch(new { things = new { name = "RequiredThing" } }); + + // Assert + Check.That(match).IsEqualTo(1); + } + + [Fact] + public void JmesPathMatcher_IsMatch_JObject() + { + // Assign + string[] patterns = { "things.x == 'RequiredThing'" }; + var matcher = new JmesPathMatcher(patterns); + + // Act + var sub = new JObject + { + { "x", new JValue("RequiredThing") } + }; + var jobject = new JObject + { + { "Id", new JValue(1) }, + { "things", sub } + }; + double match = matcher.IsMatch(jobject); + + // Assert + Check.That(match).IsEqualTo(1); + } + + [Fact] + public void JmesPathMatcher_IsMatch_JObject_Parsed() + { + // Assign + var matcher = new JmesPathMatcher("things.x == 'RequiredThing'"); + + // Act + double match = matcher.IsMatch(JObject.Parse("{ \"things\": { \"x\": \"RequiredThing\" } }")); + + // Assert + Check.That(match).IsEqualTo(1); + } + + [Fact] + public void JmesPathMatcher_IsMatch_RejectOnMatch() + { + // Assign + var matcher = new JmesPathMatcher(MatchBehaviour.RejectOnMatch, false, "things.x == 'RequiredThing'"); + + // Act + double match = matcher.IsMatch(JObject.Parse("{ \"things\": { \"x\": \"RequiredThing\" } }")); + + // Assert + Check.That(match).IsEqualTo(0.0); + } + } } \ No newline at end of file diff --git a/test/WireMock.Net.Tests/Matchers/JsonMatcherTests.cs b/test/WireMock.Net.Tests/Matchers/JsonMatcherTests.cs index 82f4163a..639994fa 100644 --- a/test/WireMock.Net.Tests/Matchers/JsonMatcherTests.cs +++ b/test/WireMock.Net.Tests/Matchers/JsonMatcherTests.cs @@ -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 WireMock.Matchers; using Xunit; @@ -33,6 +37,52 @@ namespace WireMock.Net.Tests.Matchers Check.That(value).Equals("{}"); } + [Fact] + public void JsonMatcher_WithInvalidStringValue_Should_ThrowException() + { + // Act + Action action = () => new JsonMatcher(MatchBehaviour.AcceptOnMatch, "{ \"Id\""); + + // Assert + action.Should().Throw(); + } + + [Fact] + public void JsonMatcher_WithInvalidObjectValue_Should_ThrowException() + { + // Act + Action action = () => new JsonMatcher(MatchBehaviour.AcceptOnMatch, new MemoryStream()); + + // Assert + action.Should().Throw(); + } + + [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(); + } + [Fact] public void JsonMatcher_IsMatch_ByteArray() { diff --git a/test/WireMock.Net.Tests/Matchers/JsonPathMatcherTests.cs b/test/WireMock.Net.Tests/Matchers/JsonPathMatcherTests.cs index a1ffe2ce..2eca285b 100644 --- a/test/WireMock.Net.Tests/Matchers/JsonPathMatcherTests.cs +++ b/test/WireMock.Net.Tests/Matchers/JsonPathMatcherTests.cs @@ -1,162 +1,162 @@ -using Newtonsoft.Json.Linq; -using NFluent; -using WireMock.Matchers; -using Xunit; - -namespace WireMock.Net.Tests.Matchers -{ - public class JsonPathMatcherTests - { - [Fact] - public void JsonPathMatcher_GetName() - { - // Assign - var matcher = new JsonPathMatcher("X"); - - // Act - string name = matcher.Name; - - // Assert - Check.That(name).Equals("JsonPathMatcher"); - } - - [Fact] - public void JsonPathMatcher_GetPatterns() - { - // Assign - var matcher = new JsonPathMatcher("X"); - - // Act - string[] patterns = matcher.GetPatterns(); - - // Assert - Check.That(patterns).ContainsExactly("X"); - } - - [Fact] - public void JsonPathMatcher_IsMatch_ByteArray() - { - // Assign - var bytes = new byte[0]; - var matcher = new JsonPathMatcher(""); - - // Act - double match = matcher.IsMatch(bytes); - - // Assert - Check.That(match).IsEqualTo(0); - } - - [Fact] - public void JsonPathMatcher_IsMatch_NullString() - { - // Assign - string s = null; - var matcher = new JsonPathMatcher(""); - - // Act - double match = matcher.IsMatch(s); - - // Assert - Check.That(match).IsEqualTo(0); - } - - [Fact] - public void JsonPathMatcher_IsMatch_NullObject() - { - // Assign - object o = null; - var matcher = new JsonPathMatcher(""); - - // Act - double match = matcher.IsMatch(o); - - // Assert - Check.That(match).IsEqualTo(0); - } - - [Fact] - public void JsonPathMatcher_IsMatch_String_Exception_Mismatch() - { - // Assign - var matcher = new JsonPathMatcher("xxx"); - - // Act - double match = matcher.IsMatch(""); - - // Assert - Check.That(match).IsEqualTo(0); - } - - [Fact] - public void JsonPathMatcher_IsMatch_Object_Exception_Mismatch() - { - // Assign - var matcher = new JsonPathMatcher(""); - - // Act - double match = matcher.IsMatch("x"); - - // Assert - Check.That(match).IsEqualTo(0); - } - - [Fact] - public void JsonPathMatcher_IsMatch_AnonymousObject() - { - // Assign - var matcher = new JsonPathMatcher("$..[?(@.Id == 1)]"); - - // Act - double match = matcher.IsMatch(new { Id = 1, Name = "Test" }); - - // Assert - Check.That(match).IsEqualTo(1); - } - - [Fact] - public void JsonPathMatcher_IsMatch_JObject() - { - // Assign - string[] patterns = { "$..[?(@.Id == 1)]" }; - var matcher = new JsonPathMatcher(patterns); - - // Act - var jobject = new JObject - { - { "Id", new JValue(1) }, - { "Name", new JValue("Test") } - }; - double match = matcher.IsMatch(jobject); - - // Assert - Check.That(match).IsEqualTo(1); - } - - [Fact] - public void JsonPathMatcher_IsMatch_JObject_Parsed() - { - // Assign - var matcher = new JsonPathMatcher("$..[?(@.Id == 1)]"); - - // Act - double match = matcher.IsMatch(JObject.Parse("{\"Id\":1,\"Name\":\"Test\"}")); - - // Assert - Check.That(match).IsEqualTo(1); - } - - [Fact] - public void JsonPathMatcher_IsMatch_RejectOnMatch() - { - // Assign - var matcher = new JsonPathMatcher(MatchBehaviour.RejectOnMatch, "$..[?(@.Id == 1)]"); - - // Act - double match = matcher.IsMatch(JObject.Parse("{\"Id\":1,\"Name\":\"Test\"}")); - - // Assert - Check.That(match).IsEqualTo(0.0); - } - } +using Newtonsoft.Json.Linq; +using NFluent; +using WireMock.Matchers; +using Xunit; + +namespace WireMock.Net.Tests.Matchers +{ + public class JsonPathMatcherTests + { + [Fact] + public void JsonPathMatcher_GetName() + { + // Assign + var matcher = new JsonPathMatcher("X"); + + // Act + string name = matcher.Name; + + // Assert + Check.That(name).Equals("JsonPathMatcher"); + } + + [Fact] + public void JsonPathMatcher_GetPatterns() + { + // Assign + var matcher = new JsonPathMatcher("X"); + + // Act + string[] patterns = matcher.GetPatterns(); + + // Assert + Check.That(patterns).ContainsExactly("X"); + } + + [Fact] + public void JsonPathMatcher_IsMatch_ByteArray() + { + // Assign + var bytes = new byte[0]; + var matcher = new JsonPathMatcher(""); + + // Act + double match = matcher.IsMatch(bytes); + + // Assert + Check.That(match).IsEqualTo(0); + } + + [Fact] + public void JsonPathMatcher_IsMatch_NullString() + { + // Assign + string s = null; + var matcher = new JsonPathMatcher(""); + + // Act + double match = matcher.IsMatch(s); + + // Assert + Check.That(match).IsEqualTo(0); + } + + [Fact] + public void JsonPathMatcher_IsMatch_NullObject() + { + // Assign + object o = null; + var matcher = new JsonPathMatcher(""); + + // Act + double match = matcher.IsMatch(o); + + // Assert + Check.That(match).IsEqualTo(0); + } + + [Fact] + public void JsonPathMatcher_IsMatch_String_Exception_Mismatch() + { + // Assign + var matcher = new JsonPathMatcher("xxx"); + + // Act + double match = matcher.IsMatch(""); + + // Assert + Check.That(match).IsEqualTo(0); + } + + [Fact] + public void JsonPathMatcher_IsMatch_Object_Exception_Mismatch() + { + // Assign + var matcher = new JsonPathMatcher(""); + + // Act + double match = matcher.IsMatch("x"); + + // Assert + Check.That(match).IsEqualTo(0); + } + + [Fact] + public void JsonPathMatcher_IsMatch_AnonymousObject() + { + // Assign + var matcher = new JsonPathMatcher("$..[?(@.Id == 1)]"); + + // Act + double match = matcher.IsMatch(new { Id = 1, Name = "Test" }); + + // Assert + Check.That(match).IsEqualTo(1); + } + + [Fact] + public void JsonPathMatcher_IsMatch_JObject() + { + // Assign + string[] patterns = { "$..[?(@.Id == 1)]" }; + var matcher = new JsonPathMatcher(patterns); + + // Act + var jobject = new JObject + { + { "Id", new JValue(1) }, + { "Name", new JValue("Test") } + }; + double match = matcher.IsMatch(jobject); + + // Assert + Check.That(match).IsEqualTo(1); + } + + [Fact] + public void JsonPathMatcher_IsMatch_JObject_Parsed() + { + // Assign + var matcher = new JsonPathMatcher("$..[?(@.Id == 1)]"); + + // Act + double match = matcher.IsMatch(JObject.Parse("{\"Id\":1,\"Name\":\"Test\"}")); + + // Assert + Check.That(match).IsEqualTo(1); + } + + [Fact] + public void JsonPathMatcher_IsMatch_RejectOnMatch() + { + // Assign + var matcher = new JsonPathMatcher(MatchBehaviour.RejectOnMatch, false, "$..[?(@.Id == 1)]"); + + // Act + double match = matcher.IsMatch(JObject.Parse("{\"Id\":1,\"Name\":\"Test\"}")); + + // Assert + Check.That(match).IsEqualTo(0.0); + } + } } \ No newline at end of file diff --git a/test/WireMock.Net.Tests/Matchers/XPathMatcherTests.cs b/test/WireMock.Net.Tests/Matchers/XPathMatcherTests.cs index 9102cf6f..ee4d6a03 100644 --- a/test/WireMock.Net.Tests/Matchers/XPathMatcherTests.cs +++ b/test/WireMock.Net.Tests/Matchers/XPathMatcherTests.cs @@ -1,69 +1,69 @@ -using NFluent; -using WireMock.Matchers; -using Xunit; - -namespace WireMock.Net.Tests.Matchers -{ - public class XPathMatcherTests - { - [Fact] - public void XPathMatcher_GetName() - { - // Assign - var matcher = new XPathMatcher("X"); - - // Act - string name = matcher.Name; - - // Assert - Check.That(name).Equals("XPathMatcher"); - } - - [Fact] - public void XPathMatcher_GetPatterns() - { - // Assign - var matcher = new XPathMatcher("X"); - - // Act - string[] patterns = matcher.GetPatterns(); - - // Assert - Check.That(patterns).ContainsExactly("X"); - } - - [Fact] - public void XPathMatcher_IsMatch_AcceptOnMatch() - { - // Assign - string xml = @" - - abc - "; - var matcher = new XPathMatcher("/todo-list[count(todo-item) = 1]"); - - // Act - double result = matcher.IsMatch(xml); - - // Assert - Check.That(result).IsEqualTo(1.0); - } - - [Fact] - public void XPathMatcher_IsMatch_RejectOnMatch() - { - // Assign - string xml = @" - - abc - "; - var matcher = new XPathMatcher(MatchBehaviour.RejectOnMatch, "/todo-list[count(todo-item) = 1]"); - - // Act - double result = matcher.IsMatch(xml); - - // Assert - Check.That(result).IsEqualTo(0.0); - } - } +using NFluent; +using WireMock.Matchers; +using Xunit; + +namespace WireMock.Net.Tests.Matchers +{ + public class XPathMatcherTests + { + [Fact] + public void XPathMatcher_GetName() + { + // Assign + var matcher = new XPathMatcher("X"); + + // Act + string name = matcher.Name; + + // Assert + Check.That(name).Equals("XPathMatcher"); + } + + [Fact] + public void XPathMatcher_GetPatterns() + { + // Assign + var matcher = new XPathMatcher("X"); + + // Act + string[] patterns = matcher.GetPatterns(); + + // Assert + Check.That(patterns).ContainsExactly("X"); + } + + [Fact] + public void XPathMatcher_IsMatch_AcceptOnMatch() + { + // Assign + string xml = @" + + abc + "; + var matcher = new XPathMatcher("/todo-list[count(todo-item) = 1]"); + + // Act + double result = matcher.IsMatch(xml); + + // Assert + Check.That(result).IsEqualTo(1.0); + } + + [Fact] + public void XPathMatcher_IsMatch_RejectOnMatch() + { + // Assign + string xml = @" + + abc + "; + var matcher = new XPathMatcher(MatchBehaviour.RejectOnMatch, false, "/todo-list[count(todo-item) = 1]"); + + // Act + double result = matcher.IsMatch(xml); + + // Assert + Check.That(result).IsEqualTo(0.0); + } + } } \ No newline at end of file diff --git a/test/WireMock.Net.Tests/Serialization/MatcherModelMapperTests.cs b/test/WireMock.Net.Tests/Serialization/MatcherModelMapperTests.cs index 5de718ac..9cecd32e 100644 --- a/test/WireMock.Net.Tests/Serialization/MatcherModelMapperTests.cs +++ b/test/WireMock.Net.Tests/Serialization/MatcherModelMapperTests.cs @@ -1,4 +1,5 @@ using System; +using FluentAssertions; using NFluent; using WireMock.Admin.Mappings; using WireMock.Matchers; @@ -43,7 +44,8 @@ namespace WireMock.Net.Tests.Serialization var matcher = (ExactMatcher)_sut.Map(model); // Assert - Check.That(matcher.GetPatterns()).ContainsExactly("x"); + matcher.GetPatterns().Should().ContainSingle("x"); + matcher.ThrowException.Should().BeFalse(); } [Fact] @@ -63,6 +65,39 @@ namespace WireMock.Net.Tests.Serialization 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] public void MatcherModelMapper_Map_ExactObjectMatcher_ValidBase64StringPattern() {