diff --git a/Directory.Build.props b/Directory.Build.props
index 2e22d82ff..36db2bfbe 100644
--- a/Directory.Build.props
+++ b/Directory.Build.props
@@ -4,7 +4,7 @@
- 1.0.13
+ 1.0.14
diff --git a/WireMock.Net Solution.sln.DotSettings b/WireMock.Net Solution.sln.DotSettings
index 4556d123c..8f9aa5d2d 100644
--- a/WireMock.Net Solution.sln.DotSettings
+++ b/WireMock.Net Solution.sln.DotSettings
@@ -10,6 +10,7 @@
XUA
True
True
+ True
True
True
\ No newline at end of file
diff --git a/examples/WireMock.Net.StandAlone.Net461/App.config b/examples/WireMock.Net.StandAlone.Net461/App.config
index 4be9c6eff..0b11f8d0b 100644
--- a/examples/WireMock.Net.StandAlone.Net461/App.config
+++ b/examples/WireMock.Net.StandAlone.Net461/App.config
@@ -44,7 +44,7 @@
-
+
diff --git a/examples/WireMock.Net.StandAlone.Net461/WireMock.Net.StandAlone.Net461.csproj b/examples/WireMock.Net.StandAlone.Net461/WireMock.Net.StandAlone.Net461.csproj
index cc1988ce5..4a9309c97 100644
--- a/examples/WireMock.Net.StandAlone.Net461/WireMock.Net.StandAlone.Net461.csproj
+++ b/examples/WireMock.Net.StandAlone.Net461/WireMock.Net.StandAlone.Net461.csproj
@@ -225,8 +225,8 @@
..\..\packages\System.IO.Pipelines.4.5.2\lib\netstandard2.0\System.IO.Pipelines.dll
-
- ..\..\packages\System.Linq.Dynamic.Core.1.0.11\lib\net46\System.Linq.Dynamic.Core.dll
+
+ ..\..\packages\System.Linq.Dynamic.Core.1.0.12\lib\net46\System.Linq.Dynamic.Core.dll
..\..\packages\System.Memory.4.5.1\lib\netstandard2.0\System.Memory.dll
diff --git a/examples/WireMock.Net.StandAlone.Net461/packages.config b/examples/WireMock.Net.StandAlone.Net461/packages.config
index 9ff4575ad..679c143cd 100644
--- a/examples/WireMock.Net.StandAlone.Net461/packages.config
+++ b/examples/WireMock.Net.StandAlone.Net461/packages.config
@@ -65,7 +65,7 @@
-
+
diff --git a/src/WireMock.Net/Matchers/JmesPathMatcher.cs b/src/WireMock.Net/Matchers/JmesPathMatcher.cs
new file mode 100644
index 000000000..a01308f0c
--- /dev/null
+++ b/src/WireMock.Net/Matchers/JmesPathMatcher.cs
@@ -0,0 +1,83 @@
+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";
+ }
+}
\ No newline at end of file
diff --git a/src/WireMock.Net/Serialization/MatcherMapper.cs b/src/WireMock.Net/Serialization/MatcherMapper.cs
index 57b128e5f..14154c7f2 100644
--- a/src/WireMock.Net/Serialization/MatcherMapper.cs
+++ b/src/WireMock.Net/Serialization/MatcherMapper.cs
@@ -45,6 +45,9 @@ public static IMatcher Map([CanBeNull] MatcherModel matcher)
case "JsonPathMatcher":
return new JsonPathMatcher(matchBehaviour, stringPatterns);
+ case "JmesPathMatcher":
+ return new JmesPathMatcher(matchBehaviour, stringPatterns);
+
case "XPathMatcher":
return new XPathMatcher(matchBehaviour, (string)matcher.Pattern);
diff --git a/src/WireMock.Net/WireMock.Net.csproj b/src/WireMock.Net/WireMock.Net.csproj
index 6b4054811..f8e012e41 100644
--- a/src/WireMock.Net/WireMock.Net.csproj
+++ b/src/WireMock.Net/WireMock.Net.csproj
@@ -57,8 +57,9 @@
all
runtime; build; native; contentfiles; analyzers
-
+
+
diff --git a/test/WireMock.Net.Tests/Matchers/JmesPathMatcherTests.cs b/test/WireMock.Net.Tests/Matchers/JmesPathMatcherTests.cs
new file mode 100644
index 000000000..bef4724fc
--- /dev/null
+++ b/test/WireMock.Net.Tests/Matchers/JmesPathMatcherTests.cs
@@ -0,0 +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);
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/WireMock.Net.Tests/WireMock.Net.Tests.csproj b/test/WireMock.Net.Tests/WireMock.Net.Tests.csproj
index d8e5e9ea9..16306f97d 100644
--- a/test/WireMock.Net.Tests/WireMock.Net.Tests.csproj
+++ b/test/WireMock.Net.Tests/WireMock.Net.Tests.csproj
@@ -36,7 +36,7 @@
-
+
all