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 BASE_ALLOCATOR_PARTITION_ALLOCATOR_POINTERS_RAW_PTR_TEST_SUPPORT_H_
6 #define BASE_ALLOCATOR_PARTITION_ALLOCATOR_POINTERS_RAW_PTR_TEST_SUPPORT_H_
7
8 #include "testing/gmock/include/gmock/gmock.h"
9 #include "third_party/abseil-cpp/absl/types/optional.h"
10
11 // Struct intended to be used with designated initializers and passed
12 // to the `CountersMatch()` matcher.
13 //
14 // `CountingImplType` isn't used directly; it tells the `CountersMatch`
15 // matcher which impl's static members should be checked.
16 template <typename CountingImplType>
17 struct CountingRawPtrExpectations {
18 absl::optional<int> wrap_raw_ptr_cnt;
19 absl::optional<int> release_wrapped_ptr_cnt;
20 absl::optional<int> get_for_dereference_cnt;
21 absl::optional<int> get_for_extraction_cnt;
22 absl::optional<int> get_for_comparison_cnt;
23 absl::optional<int> wrapped_ptr_swap_cnt;
24 absl::optional<int> wrapped_ptr_less_cnt;
25 absl::optional<int> pointer_to_member_operator_cnt;
26 absl::optional<int> wrap_raw_ptr_for_dup_cnt;
27 absl::optional<int> get_for_duplication_cnt;
28 };
29
30 #define REPORT_UNEQUAL_RAW_PTR_COUNTER(member_name, CounterClassImpl) \
31 { \
32 if (arg.member_name.has_value() && \
33 arg.member_name.value() != CounterClassImpl::member_name) { \
34 *result_listener << "Expected `" #member_name "` to be " \
35 << arg.member_name.value() << " but got " \
36 << CounterClassImpl::member_name << "; "; \
37 result = false; \
38 } \
39 }
40 #define REPORT_UNEQUAL_RAW_PTR_COUNTERS(result, CounterClassImpl) \
41 { \
42 result = true; \
43 REPORT_UNEQUAL_RAW_PTR_COUNTER(wrap_raw_ptr_cnt, CounterClassImpl) \
44 REPORT_UNEQUAL_RAW_PTR_COUNTER(release_wrapped_ptr_cnt, CounterClassImpl) \
45 REPORT_UNEQUAL_RAW_PTR_COUNTER(get_for_dereference_cnt, CounterClassImpl) \
46 REPORT_UNEQUAL_RAW_PTR_COUNTER(get_for_extraction_cnt, CounterClassImpl) \
47 REPORT_UNEQUAL_RAW_PTR_COUNTER(get_for_comparison_cnt, CounterClassImpl) \
48 REPORT_UNEQUAL_RAW_PTR_COUNTER(wrapped_ptr_swap_cnt, CounterClassImpl) \
49 REPORT_UNEQUAL_RAW_PTR_COUNTER(wrapped_ptr_less_cnt, CounterClassImpl) \
50 REPORT_UNEQUAL_RAW_PTR_COUNTER(pointer_to_member_operator_cnt, \
51 CounterClassImpl) \
52 REPORT_UNEQUAL_RAW_PTR_COUNTER(wrap_raw_ptr_for_dup_cnt, CounterClassImpl) \
53 REPORT_UNEQUAL_RAW_PTR_COUNTER(get_for_duplication_cnt, CounterClassImpl) \
54 }
55
56 // Matcher used with `CountingRawPtr`. Provides slightly shorter
57 // boilerplate for verifying counts. This inner function is detached
58 // from the `MATCHER` to isolate the templating.
59 template <typename CountingImplType>
CountersMatchImpl(const CountingRawPtrExpectations<CountingImplType> & arg,testing::MatchResultListener * result_listener)60 bool CountersMatchImpl(const CountingRawPtrExpectations<CountingImplType>& arg,
61 testing::MatchResultListener* result_listener) {
62 bool result = true;
63 REPORT_UNEQUAL_RAW_PTR_COUNTERS(result, CountingImplType);
64 return result;
65 }
66
67 // Implicit `arg` has type `CountingRawPtrExpectations`, specialized for
68 // the specific counting impl.
69 MATCHER(CountersMatch, "counting impl has specified counters") {
70 return CountersMatchImpl(arg, result_listener);
71 }
72
73 #undef REPORT_UNEQUAL_RAW_PTR_COUNTERS
74 #undef REPORT_UNEQUAL_RAW_PTR_COUNTER
75
76 #endif // BASE_ALLOCATOR_PARTITION_ALLOCATOR_POINTERS_RAW_PTR_TEST_SUPPORT_H_
77