blob: ccd1978b3ca6f7246ccbf42e08c2e5c2ce800f30 [file] [log] [blame]
#include "quiche/common/quiche_callbacks.h"
#include <memory>
#include <utility>
#include <vector>
#include "quiche/common/platform/api/quiche_test.h"
namespace quiche {
namespace {
void Apply(const std::vector<int>& container,
UnretainedCallback<void(int)> function) {
for (int n : container) {
function(n);
}
}
TEST(QuicheCallbacksTest, UnretainedCallback) {
std::vector<int> nums = {1, 2, 3, 4};
int sum = 0;
Apply(nums, [&sum](int n) { sum += n; });
EXPECT_EQ(sum, 10);
}
TEST(QuicheCallbacksTest, SingleUseCallback) {
int called = 0;
SingleUseCallback<void()> callback = [&called]() { called++; };
EXPECT_EQ(called, 0);
SingleUseCallback<void()> new_callback = std::move(callback);
EXPECT_EQ(called, 0);
std::move(new_callback)();
EXPECT_EQ(called, 1);
EXPECT_QUICHE_DEBUG_DEATH(
std::move(new_callback)(), // NOLINT(bugprone-use-after-move)
"AnyInvocable");
}
class SetFlagOnDestruction {
public:
SetFlagOnDestruction(bool* flag) : flag_(flag) {}
~SetFlagOnDestruction() { *flag_ = true; }
private:
bool* flag_;
};
TEST(QuicheCallbacksTest, SingleUseCallbackOwnership) {
bool deleted = false;
auto flag_setter = std::make_unique<SetFlagOnDestruction>(&deleted);
{
SingleUseCallback<void()> callback = [setter = std::move(flag_setter)]() {};
EXPECT_FALSE(deleted);
}
EXPECT_TRUE(deleted);
}
TEST(QuicheCallbacksTest, MultiUseCallback) {
int called = 0;
MultiUseCallback<void()> callback = [&called]() { called++; };
EXPECT_EQ(called, 0);
callback();
EXPECT_EQ(called, 1);
callback();
callback();
EXPECT_EQ(called, 3);
}
TEST(QuicheCallbacksTest, MultiUseCallbackOwnership) {
bool deleted = false;
auto flag_setter = std::make_unique<SetFlagOnDestruction>(&deleted);
{
MultiUseCallback<void()> callback = [setter = std::move(flag_setter)]() {};
EXPECT_FALSE(deleted);
}
EXPECT_TRUE(deleted);
}
} // namespace
} // namespace quiche