Browse Source

Add support for matching a predicate.

Sam Jaffe 6 years ago
parent
commit
08e14adb9f
2 changed files with 47 additions and 1 deletions
  1. 17 0
      include/match/match.hpp
  2. 30 1
      test/match_test.cxx

+ 17 - 0
include/match/match.hpp

@@ -52,6 +52,23 @@ namespace matcher {
   }
 }
 
+namespace matcher {
+  template <typename Pred>
+  struct predicate_t {
+    Pred predicate;
+  };
+  
+  template <typename T, typename Pred>
+  bool operator==(T const & t, predicate_t<Pred> const & of) {
+    return of.predicate(t);
+  }
+  
+  template <typename Pred>
+  predicate_t<Pred> matches(Pred && args) {
+    return {args};
+  }
+}
+
 namespace matcher {
   template <typename... Args>
   struct matcher {

+ 30 - 1
test/match_test.cxx

@@ -17,6 +17,9 @@ struct example {
 bool operator==(example const & a, example const & b) {
   return a.i == b.i;
 }
+bool operator<(example const & a, example const & b) {
+  return a.i < b.i;
+}
 
 struct CaseMatcherTest : public testing::Test {
   example const ex{1};
@@ -103,12 +106,13 @@ TEST_F(CaseMatcherTest, CanMatchMultipleUnlinkedClauses) {
   EXPECT_THAT(hits, Eq(2));
 }
 
-TEST_F(CaseMatcherTest, CanMatchCompoundList) {
+TEST_F(CaseMatcherTest, CanMatchAnyOf) {
   match(ex, b) {
     with(matcher::any_of(example{1}, example{0xDEADBEEF}), true) {
     } nomatch() {
       FAIL() << "Unable to match with choice";
     }
+    EXPECT_THAT(_matcher_local, Not(IsUnmatched()));
   } else {
     FAIL() << "Unable to construct matcher";
   }
@@ -124,3 +128,28 @@ TEST_F(CaseMatcherTest, WillNotMatchAnyIfNoSubMatches) {
     FAIL() << "Unable to construct matcher";
   }
 }
+
+TEST_F(CaseMatcherTest, CanMatchPredicate) {
+  auto lt_5 = [](example e) { return e.i < 5; };
+  match(ex, b) {
+    with(matcher::matches(lt_5), true) {
+    } nomatch() {
+      FAIL() << "Unable to match with choice";
+    }
+    EXPECT_THAT(_matcher_local, Not(IsUnmatched()));
+  } else {
+    FAIL() << "Unable to construct matcher";
+  }
+}
+
+TEST_F(CaseMatcherTest, WillNotMatchIfPredicateFails) {
+  auto lt_1 = [](example e) { return e.i < 1; };
+  match(ex, b) {
+    with(matcher::matches(lt_1), true) {
+      FAIL() << "Incorrect match!";
+    }
+    EXPECT_THAT(_matcher_local, IsUnmatched());
+  } else {
+    FAIL() << "Unable to construct matcher";
+  }
+}