-
-
Notifications
You must be signed in to change notification settings - Fork 208
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Support for partial JSON matching (#539)
* support Json partial match with JsonPartialMatcher * fix erroneous filenames * add newline * newlines fix * add JsonPartialMatcher to mapper * curly braces for ifs * fix JToken type comparison * more test cases * rename AreEqual -> IsMatch + more test cases * separate tests for JPath matcher values Co-authored-by: Gleb Osokin <[email protected]>
- Loading branch information
1 parent
2d95167
commit 548fc2c
Showing
5 changed files
with
578 additions
and
17 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using JetBrains.Annotations; | ||
using Newtonsoft.Json.Linq; | ||
|
||
namespace WireMock.Matchers | ||
{ | ||
/// <summary> | ||
/// JsonPartialMatcher | ||
/// </summary> | ||
public class JsonPartialMatcher : JsonMatcher | ||
{ | ||
/// <inheritdoc cref="IMatcher.Name"/> | ||
public override string Name => "JsonPartialMatcher"; | ||
|
||
/// <summary> | ||
/// Initializes a new instance of the <see cref="JsonPartialMatcher"/> class. | ||
/// </summary> | ||
/// <param name="value">The string value to check for equality.</param> | ||
/// <param name="ignoreCase">Ignore the case from the PropertyName and PropertyValue (string only).</param> | ||
/// <param name="throwException">Throw an exception when the internal matching fails because of invalid input.</param> | ||
public JsonPartialMatcher([NotNull] string value, bool ignoreCase = false, bool throwException = false) | ||
: base(value, ignoreCase, throwException) | ||
{ | ||
} | ||
|
||
/// <summary> | ||
/// Initializes a new instance of the <see cref="JsonPartialMatcher"/> class. | ||
/// </summary> | ||
/// <param name="value">The object value to check for equality.</param> | ||
/// <param name="ignoreCase">Ignore the case from the PropertyName and PropertyValue (string only).</param> | ||
/// <param name="throwException">Throw an exception when the internal matching fails because of invalid input.</param> | ||
public JsonPartialMatcher([NotNull] object value, bool ignoreCase = false, bool throwException = false) | ||
: base(value, ignoreCase, throwException) | ||
{ | ||
} | ||
|
||
/// <summary> | ||
/// Initializes a new instance of the <see cref="JsonPartialMatcher"/> class. | ||
/// </summary> | ||
/// <param name="matchBehaviour">The match behaviour.</param> | ||
/// <param name="value">The value to check for equality.</param> | ||
/// <param name="ignoreCase">Ignore the case from the PropertyName and PropertyValue (string only).</param> | ||
/// <param name="throwException">Throw an exception when the internal matching fails because of invalid input.</param> | ||
public JsonPartialMatcher(MatchBehaviour matchBehaviour, [NotNull] object value, bool ignoreCase = false, bool throwException = false) | ||
: base(matchBehaviour, value, ignoreCase, throwException) | ||
{ | ||
} | ||
|
||
/// <inheritdoc /> | ||
protected override bool IsMatch(JToken value, JToken input) | ||
{ | ||
if (value == null || value == input) | ||
{ | ||
return true; | ||
} | ||
|
||
if (input == null || value.Type != input.Type) | ||
{ | ||
return false; | ||
} | ||
|
||
switch (value.Type) | ||
{ | ||
case JTokenType.Object: | ||
var nestedValues = value.ToObject<Dictionary<string, JToken>>(); | ||
return nestedValues?.Any() != true || | ||
nestedValues.All(pair => IsMatch(pair.Value, input.SelectToken(pair.Key))); | ||
|
||
case JTokenType.Array: | ||
var valuesArray = value.ToObject<JToken[]>(); | ||
var tokenArray = input.ToObject<JToken[]>(); | ||
|
||
if (valuesArray?.Any() != true) | ||
{ | ||
return true; | ||
} | ||
|
||
return tokenArray?.Any() == true && | ||
valuesArray.All(subFilter => tokenArray.Any(subToken => IsMatch(subFilter, subToken))); | ||
|
||
default: | ||
return value.ToString() == input.ToString(); | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.