#include "base/task/delayed_task_handle.h"
#include "base/memory/raw_ptr.h"
#include "base/test/gtest_util.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace base {
namespace {
class TestDelegate : public DelayedTaskHandle::Delegate {
public:
explicit TestDelegate(bool* was_cancel_task_called = nullptr)
: was_cancel_task_called_(was_cancel_task_called) {
DCHECK(!was_cancel_task_called_ || !*was_cancel_task_called_);
}
~TestDelegate() override = default;
bool IsValid() const override { return is_valid_; }
void CancelTask() override {
is_valid_ = false;
if (was_cancel_task_called_) {
*was_cancel_task_called_ = true;
}
}
private:
bool is_valid_ = true;
raw_ptr<bool> was_cancel_task_called_;
};
}
TEST(DelayedTaskHandleTest, DefaultConstructor) {
DelayedTaskHandle delayed_task_handle;
EXPECT_FALSE(delayed_task_handle.IsValid());
}
TEST(DelayedTaskHandleTest, RequiresValidDelegateOnConstruction) {
auto delegate = std::make_unique<TestDelegate>();
EXPECT_TRUE(delegate->IsValid());
delegate->CancelTask();
EXPECT_FALSE(delegate->IsValid());
EXPECT_DCHECK_DEATH(
{ DelayedTaskHandle delayed_task_handle(std::move(delegate)); });
}
TEST(DelayedTaskHandleTest, CancelTask) {
bool was_cancel_task_called = false;
auto delegate = std::make_unique<TestDelegate>(&was_cancel_task_called);
EXPECT_FALSE(was_cancel_task_called);
EXPECT_TRUE(delegate->IsValid());
auto* delegate_ptr = delegate.get();
DelayedTaskHandle delayed_task_handle(std::move(delegate));
EXPECT_FALSE(was_cancel_task_called);
EXPECT_TRUE(delegate_ptr->IsValid());
EXPECT_TRUE(delayed_task_handle.IsValid());
delayed_task_handle.CancelTask();
EXPECT_TRUE(was_cancel_task_called);
EXPECT_FALSE(delayed_task_handle.IsValid());
}
TEST(DelayedTaskHandleTest, CancelTaskNoDelegate) {
DelayedTaskHandle delayed_task_handle;
EXPECT_FALSE(delayed_task_handle.IsValid());
delayed_task_handle.CancelTask();
EXPECT_FALSE(delayed_task_handle.IsValid());
}
TEST(DelayedTaskHandleTest, CancelTaskInvalidDelegate) {
bool was_cancel_task_called = false;
auto delegate = std::make_unique<TestDelegate>(&was_cancel_task_called);
EXPECT_FALSE(was_cancel_task_called);
EXPECT_TRUE(delegate->IsValid());
auto* delegate_ptr = delegate.get();
DelayedTaskHandle delayed_task_handle(std::move(delegate));
EXPECT_FALSE(was_cancel_task_called);
EXPECT_TRUE(delegate_ptr->IsValid());
EXPECT_TRUE(delayed_task_handle.IsValid());
delegate_ptr->CancelTask();
EXPECT_TRUE(was_cancel_task_called);
EXPECT_FALSE(delegate_ptr->IsValid());
EXPECT_FALSE(delayed_task_handle.IsValid());
was_cancel_task_called = false;
delayed_task_handle.CancelTask();
EXPECT_TRUE(was_cancel_task_called);
EXPECT_FALSE(delayed_task_handle.IsValid());
}
TEST(DelayedTaskHandleTest, InvalidateDelegate) {
auto delegate = std::make_unique<TestDelegate>();
EXPECT_TRUE(delegate->IsValid());
auto* delegate_ptr = delegate.get();
DelayedTaskHandle delayed_task_handle(std::move(delegate));
EXPECT_TRUE(delegate_ptr->IsValid());
EXPECT_TRUE(delayed_task_handle.IsValid());
delegate_ptr->CancelTask();
EXPECT_FALSE(delegate_ptr->IsValid());
EXPECT_FALSE(delayed_task_handle.IsValid());
}
TEST(DelayedTaskHandleTest, InvalidOnDestuction) {
auto delegate = std::make_unique<TestDelegate>();
EXPECT_TRUE(delegate->IsValid());
auto* delegate_ptr = delegate.get();
EXPECT_DCHECK_DEATH({
DelayedTaskHandle delayed_task_handle(std::move(delegate));
EXPECT_TRUE(delegate_ptr->IsValid());
EXPECT_TRUE(delayed_task_handle.IsValid());
});
}
TEST(DelayedTaskHandleTest, MoveConstructor) {
auto delegate = std::make_unique<TestDelegate>();
EXPECT_TRUE(delegate->IsValid());
auto* delegate_ptr = delegate.get();
DelayedTaskHandle delayed_task_handle(std::move(delegate));
EXPECT_TRUE(delegate_ptr->IsValid());
EXPECT_TRUE(delayed_task_handle.IsValid());
DelayedTaskHandle other_delayed_task_handle(std::move(delayed_task_handle));
EXPECT_TRUE(delegate_ptr->IsValid());
EXPECT_TRUE(other_delayed_task_handle.IsValid());
other_delayed_task_handle.CancelTask();
}
TEST(DelayedTaskHandleTest, MoveAssignment) {
auto delegate = std::make_unique<TestDelegate>();
EXPECT_TRUE(delegate->IsValid());
auto* delegate_ptr = delegate.get();
DelayedTaskHandle delayed_task_handle(std::move(delegate));
EXPECT_TRUE(delegate_ptr->IsValid());
EXPECT_TRUE(delayed_task_handle.IsValid());
DelayedTaskHandle other_delayed_task_handle;
EXPECT_FALSE(other_delayed_task_handle.IsValid());
other_delayed_task_handle = std::move(delayed_task_handle);
EXPECT_TRUE(delegate_ptr->IsValid());
EXPECT_TRUE(other_delayed_task_handle.IsValid());
other_delayed_task_handle.CancelTask();
}
TEST(DelayedTaskHandleTest, AssignToValidHandle) {
auto delegate = std::make_unique<TestDelegate>();
EXPECT_TRUE(delegate->IsValid());
auto* delegate_ptr = delegate.get();
DelayedTaskHandle delayed_task_handle(std::move(delegate));
EXPECT_TRUE(delegate_ptr->IsValid());
EXPECT_TRUE(delayed_task_handle.IsValid());
EXPECT_DCHECK_DEATH({ delayed_task_handle = DelayedTaskHandle(); });
delayed_task_handle.CancelTask();
}
}