JsonMatcher support IgnoreCase (#333)

* JsonMatcher - IgnoreCase - #332

* also rename property name

* Remove example project
This commit is contained in:
Stef Heyenrath
2019-08-23 19:49:15 +00:00
committed by GitHub
parent 2e33bcc464
commit ccb2c51a39
8 changed files with 118 additions and 139 deletions

View File

@@ -1,4 +1,5 @@
using JetBrains.Annotations;
using System.Linq;
using JetBrains.Annotations;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using WireMock.Validation;
@@ -8,7 +9,7 @@ namespace WireMock.Matchers
/// <summary>
/// JsonMatcher
/// </summary>
public class JsonMatcher : IValueMatcher
public class JsonMatcher : IValueMatcher, IIgnoreCaseMatcher
{
/// <inheritdoc cref="IValueMatcher.Value"/>
public object Value { get; }
@@ -19,11 +20,15 @@ namespace WireMock.Matchers
/// <inheritdoc cref="IMatcher.MatchBehaviour"/>
public MatchBehaviour MatchBehaviour { get; }
/// <inheritdoc cref="IIgnoreCaseMatcher.IgnoreCase"/>
public bool IgnoreCase { get; }
/// <summary>
/// Initializes a new instance of the <see cref="JsonMatcher"/> class.
/// </summary>
/// <param name="value">The string value to check for equality.</param>
public JsonMatcher([NotNull] string value) : this(MatchBehaviour.AcceptOnMatch, value)
/// <param name="ignoreCase">Ignore the case from the PropertyName and PropertyValue (string only).</param>
public JsonMatcher([NotNull] string value, bool ignoreCase = false) : this(MatchBehaviour.AcceptOnMatch, value, ignoreCase)
{
}
@@ -31,7 +36,8 @@ namespace WireMock.Matchers
/// Initializes a new instance of the <see cref="JsonMatcher"/> class.
/// </summary>
/// <param name="value">The object value to check for equality.</param>
public JsonMatcher([NotNull] object value) : this(MatchBehaviour.AcceptOnMatch, value)
/// <param name="ignoreCase">Ignore the case from the PropertyName and PropertyValue (string only).</param>
public JsonMatcher([NotNull] object value, bool ignoreCase = false) : this(MatchBehaviour.AcceptOnMatch, value, ignoreCase)
{
}
@@ -40,12 +46,14 @@ namespace WireMock.Matchers
/// </summary>
/// <param name="matchBehaviour">The match behaviour.</param>
/// <param name="value">The string value to check for equality.</param>
public JsonMatcher(MatchBehaviour matchBehaviour, [NotNull] string value)
/// <param name="ignoreCase">Ignore the case from the PropertyName and PropertyValue (string only).</param>
public JsonMatcher(MatchBehaviour matchBehaviour, [NotNull] string value, bool ignoreCase = false)
{
Check.NotNull(value, nameof(value));
MatchBehaviour = matchBehaviour;
Value = value;
IgnoreCase = ignoreCase;
}
/// <summary>
@@ -53,12 +61,14 @@ namespace WireMock.Matchers
/// </summary>
/// <param name="matchBehaviour">The match behaviour.</param>
/// <param name="value">The object value to check for equality.</param>
public JsonMatcher(MatchBehaviour matchBehaviour, [NotNull] object value)
/// <param name="ignoreCase">Ignore the case from the PropertyName and PropertyValue (string only).</param>
public JsonMatcher(MatchBehaviour matchBehaviour, [NotNull] object value, bool ignoreCase = false)
{
Check.NotNull(value, nameof(value));
MatchBehaviour = matchBehaviour;
Value = value;
IgnoreCase = ignoreCase;
}
/// <inheritdoc cref="IObjectMatcher.IsMatch"/>
@@ -91,7 +101,7 @@ namespace WireMock.Matchers
break;
}
match = JToken.DeepEquals(jtokenValue, jtokenInput);
match = DeepEquals(jtokenValue, jtokenInput);
}
catch (JsonException)
{
@@ -101,5 +111,53 @@ namespace WireMock.Matchers
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<string>();
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;
}
}
}

View File

@@ -55,7 +55,7 @@ namespace WireMock.Serialization
return new RegexMatcher(matchBehaviour, stringPatterns, matcher.IgnoreCase == true);
case "JsonMatcher":
return new JsonMatcher(matchBehaviour, matcher.Pattern);
return new JsonMatcher(matchBehaviour, matcher.Pattern, matcher.IgnoreCase == true);
case "JsonPathMatcher":
return new JsonPathMatcher(matchBehaviour, stringPatterns);