summaryrefslogtreecommitdiffstats
path: root/vespalib
diff options
context:
space:
mode:
authorTor Brede Vekterli <vekterli@yahooinc.com>2023-04-20 11:53:36 +0000
committerTor Brede Vekterli <vekterli@yahooinc.com>2023-04-20 12:04:12 +0000
commit53dc081d48be4f5850f4b609e6a031c014ae6425 (patch)
treee32eb4e17709beef33acdccbb2b912b8a15aa365 /vespalib
parentb78746c2f8cac3e87b79ca362acb57c0a5d9f4df (diff)
Add NewestReplica equality tests and gmock matcher for distinct elements in a range
Add a new `matchers` directory in vespalib which can be used as a repository for generic, reusable GMock matchers. Move distributor tests from using an explicit gtest runner to using `GTest::gmock_main` which serves the same purpose. Need to depend on a gmock target (not just gtest) to be able to link with stuff required for matchers.
Diffstat (limited to 'vespalib')
-rw-r--r--vespalib/src/vespa/vespalib/gtest/matchers/elements_are_distinct.h35
1 files changed, 35 insertions, 0 deletions
diff --git a/vespalib/src/vespa/vespalib/gtest/matchers/elements_are_distinct.h b/vespalib/src/vespa/vespalib/gtest/matchers/elements_are_distinct.h
new file mode 100644
index 00000000000..374dafbf893
--- /dev/null
+++ b/vespalib/src/vespa/vespalib/gtest/matchers/elements_are_distinct.h
@@ -0,0 +1,35 @@
+// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+#include <gtest/gtest.h>
+#include <gmock/gmock.h>
+#include <ranges>
+
+/**
+ * Checks that all elements of a forward iterable range are distinct, i.e. the following must hold:
+ * - for any single element `foo`, foo == foo is true
+ * - for any two separate elements `foo` and `bar`, foo == bar is false
+ */
+MATCHER(ElementsAreDistinct, "") {
+ const auto& range = arg;
+ static_assert(std::ranges::forward_range<decltype(range)>);
+ const auto end = std::ranges::cend(range);
+ // Explicitly count element positions instead of comparing iterators to avoid depending
+ // on iterators being comparable with each other.
+ size_t i = 0;
+ for (auto lhs = std::ranges::cbegin(range); lhs != end; ++lhs, ++i) {
+ size_t j = 0;
+ for (auto rhs = std::ranges::cbegin(range); rhs != end; ++rhs, ++j) {
+ if (i != j) {
+ if (*lhs == *rhs) {
+ *result_listener << "Expected elements to be distinct, but element at position "
+ << i << " (" << *lhs << ") is equal to element at position "
+ << j << " (" << *rhs << ")";
+ return false;
+ }
+ } else if (!(*lhs == *rhs)) {
+ *result_listener << "Element at position " << i << " (" << *lhs << ") does not equal itself";
+ return false;
+ }
+ }
+ }
+ return true;
+}