1 #include "quiche/common/quiche_callbacks.h"
2
3 #include <memory>
4
5 #include "quiche/common/platform/api/quiche_test.h"
6
7 namespace quiche {
8 namespace {
9
Apply(const std::vector<int> & container,UnretainedCallback<void (int)> function)10 void Apply(const std::vector<int>& container,
11 UnretainedCallback<void(int)> function) {
12 for (int n : container) {
13 function(n);
14 }
15 }
16
TEST(QuicheCallbacksTest,UnretainedCallback)17 TEST(QuicheCallbacksTest, UnretainedCallback) {
18 std::vector<int> nums = {1, 2, 3, 4};
19 int sum = 0;
20 Apply(nums, [&sum](int n) { sum += n; });
21 EXPECT_EQ(sum, 10);
22 }
23
TEST(QuicheCallbacksTest,SingleUseCallback)24 TEST(QuicheCallbacksTest, SingleUseCallback) {
25 int called = 0;
26 SingleUseCallback<void()> callback = [&called]() { called++; };
27 EXPECT_EQ(called, 0);
28
29 SingleUseCallback<void()> new_callback = std::move(callback);
30 EXPECT_EQ(called, 0);
31
32 std::move(new_callback)();
33 EXPECT_EQ(called, 1);
34 EXPECT_QUICHE_DEBUG_DEATH(
35 std::move(new_callback)(), // NOLINT(bugprone-use-after-move)
36 "AnyInvocable");
37 }
38
39 class SetFlagOnDestruction {
40 public:
SetFlagOnDestruction(bool * flag)41 SetFlagOnDestruction(bool* flag) : flag_(flag) {}
~SetFlagOnDestruction()42 ~SetFlagOnDestruction() { *flag_ = true; }
43
44 private:
45 bool* flag_;
46 };
47
TEST(QuicheCallbacksTest,SingleUseCallbackOwnership)48 TEST(QuicheCallbacksTest, SingleUseCallbackOwnership) {
49 bool deleted = false;
50 auto flag_setter = std::make_unique<SetFlagOnDestruction>(&deleted);
51 {
52 SingleUseCallback<void()> callback = [setter = std::move(flag_setter)]() {};
53 EXPECT_FALSE(deleted);
54 }
55 EXPECT_TRUE(deleted);
56 }
57
TEST(QuicheCallbacksTest,MultiUseCallback)58 TEST(QuicheCallbacksTest, MultiUseCallback) {
59 int called = 0;
60 MultiUseCallback<void()> callback = [&called]() { called++; };
61 EXPECT_EQ(called, 0);
62
63 callback();
64 EXPECT_EQ(called, 1);
65
66 callback();
67 callback();
68 EXPECT_EQ(called, 3);
69 }
70
TEST(QuicheCallbacksTest,MultiUseCallbackOwnership)71 TEST(QuicheCallbacksTest, MultiUseCallbackOwnership) {
72 bool deleted = false;
73 auto flag_setter = std::make_unique<SetFlagOnDestruction>(&deleted);
74 {
75 MultiUseCallback<void()> callback = [setter = std::move(flag_setter)]() {};
76 EXPECT_FALSE(deleted);
77 }
78 EXPECT_TRUE(deleted);
79 }
80
81 } // namespace
82 } // namespace quiche
83