1 // Copyright 2023 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef PARTITION_ALLOC_POINTERS_RAW_PTR_TEST_SUPPORT_H_
6 #define PARTITION_ALLOC_POINTERS_RAW_PTR_TEST_SUPPORT_H_
7 
8 #include <optional>
9 
10 #include "testing/gmock/include/gmock/gmock.h"
11 
12 // Struct intended to be used with designated initializers and passed
13 // to the `CountersMatch()` matcher.
14 //
15 // TODO(tsepez): Although we only want one kind of these, the class is still
16 // a template to circumvent the chromium-style out-of-line constructor rule.
17 // Adding such a constructor would make this no longer be an aggregate and
18 // that would prohibit designated initiaizers.
19 template <int IGNORE>
20 struct CountingRawPtrExpectationTemplate {
21   std::optional<int> wrap_raw_ptr_cnt;
22   std::optional<int> release_wrapped_ptr_cnt;
23   std::optional<int> get_for_dereference_cnt;
24   std::optional<int> get_for_extraction_cnt;
25   std::optional<int> get_for_comparison_cnt;
26   std::optional<int> wrapped_ptr_swap_cnt;
27   std::optional<int> wrapped_ptr_less_cnt;
28   std::optional<int> pointer_to_member_operator_cnt;
29   std::optional<int> wrap_raw_ptr_for_dup_cnt;
30   std::optional<int> get_for_duplication_cnt;
31 };
32 using CountingRawPtrExpectations = CountingRawPtrExpectationTemplate<0>;
33 
34 #define REPORT_UNEQUAL_RAW_PTR_COUNTER(member_name)                          \
35   {                                                                          \
36     if (arg.member_name.has_value() &&                                       \
37         arg.member_name.value() !=                                           \
38             base::test::RawPtrCountingImplForTest::member_name) {            \
39       *result_listener << "Expected `" #member_name "` to be "               \
40                        << arg.member_name.value() << " but got "             \
41                        << base::test::RawPtrCountingImplForTest::member_name \
42                        << "; ";                                              \
43       result = false;                                                        \
44     }                                                                        \
45   }
46 
47 #define REPORT_UNEQUAL_RAW_PTR_COUNTERS(result)                    \
48   {                                                                \
49     result = true;                                                 \
50     REPORT_UNEQUAL_RAW_PTR_COUNTER(wrap_raw_ptr_cnt)               \
51     REPORT_UNEQUAL_RAW_PTR_COUNTER(release_wrapped_ptr_cnt)        \
52     REPORT_UNEQUAL_RAW_PTR_COUNTER(get_for_dereference_cnt)        \
53     REPORT_UNEQUAL_RAW_PTR_COUNTER(get_for_extraction_cnt)         \
54     REPORT_UNEQUAL_RAW_PTR_COUNTER(get_for_comparison_cnt)         \
55     REPORT_UNEQUAL_RAW_PTR_COUNTER(wrapped_ptr_swap_cnt)           \
56     REPORT_UNEQUAL_RAW_PTR_COUNTER(wrapped_ptr_less_cnt)           \
57     REPORT_UNEQUAL_RAW_PTR_COUNTER(pointer_to_member_operator_cnt) \
58     REPORT_UNEQUAL_RAW_PTR_COUNTER(wrap_raw_ptr_for_dup_cnt)       \
59     REPORT_UNEQUAL_RAW_PTR_COUNTER(get_for_duplication_cnt)        \
60   }
61 
62 // Matcher used with `CountingRawPtr`. Provides slightly shorter
63 // boilerplate for verifying counts. This inner function is detached
64 // from the `MATCHER`.
CountersMatchImpl(const CountingRawPtrExpectations & arg,testing::MatchResultListener * result_listener)65 inline bool CountersMatchImpl(const CountingRawPtrExpectations& arg,
66                               testing::MatchResultListener* result_listener) {
67   bool result = true;
68   REPORT_UNEQUAL_RAW_PTR_COUNTERS(result);
69   return result;
70 }
71 
72 // Implicit `arg` has type `CountingRawPtrExpectations`, specialized for
73 // the specific counting impl.
74 MATCHER(CountersMatch, "counting impl has specified counters") {
75   return CountersMatchImpl(arg, result_listener);
76 }
77 
78 #undef REPORT_UNEQUAL_RAW_PTR_COUNTERS
79 #undef REPORT_UNEQUAL_RAW_PTR_COUNTER
80 
81 #endif  // PARTITION_ALLOC_POINTERS_RAW_PTR_TEST_SUPPORT_H_
82