// Copyright (c) 2011 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "base/basictypes.h" #include "base/memory/scoped_ptr.h" #include "base/task.h" #include "base/task_queue.h" #include "testing/gtest/include/gtest/gtest.h" namespace { // Sets bools according to whether Run or the destructor were called. class TrackCallsTask : public Task { public: TrackCallsTask(bool* ran, bool* deleted) : ran_(ran), deleted_(deleted) { *ran_ = false; *deleted_ = false; } virtual ~TrackCallsTask() { *deleted_ = true; } virtual void Run() { *ran_ = true; } private: bool* ran_; bool* deleted_; DISALLOW_COPY_AND_ASSIGN(TrackCallsTask); }; // Adds a given task to the queue when run. class TaskQueuerTask : public Task { public: TaskQueuerTask(TaskQueue* queue, Task* task_to_queue) : queue_(queue), task_to_queue_(task_to_queue) { } virtual void Run() { queue_->Push(task_to_queue_); } private: TaskQueue* queue_; Task* task_to_queue_; DISALLOW_COPY_AND_ASSIGN(TaskQueuerTask); }; } // namespace TEST(TaskQueueTest, RunNoTasks) { TaskQueue queue; EXPECT_TRUE(queue.IsEmpty()); queue.Run(); EXPECT_TRUE(queue.IsEmpty()); } TEST(TaskQueueTest, RunTasks) { TaskQueue queue; bool ran_task1 = false; bool deleted_task1 = false; queue.Push(new TrackCallsTask(&ran_task1, &deleted_task1)); bool ran_task2 = false; bool deleted_task2 = false; queue.Push(new TrackCallsTask(&ran_task2, &deleted_task2)); queue.Run(); EXPECT_TRUE(ran_task1); EXPECT_TRUE(deleted_task1); EXPECT_TRUE(ran_task2); EXPECT_TRUE(deleted_task2); EXPECT_TRUE(queue.IsEmpty()); } TEST(TaskQueueTest, ClearTasks) { TaskQueue queue; bool ran_task1 = false; bool deleted_task1 = false; queue.Push(new TrackCallsTask(&ran_task1, &deleted_task1)); bool ran_task2 = false; bool deleted_task2 = false; queue.Push(new TrackCallsTask(&ran_task2, &deleted_task2)); queue.Clear(); EXPECT_TRUE(queue.IsEmpty()); queue.Run(); EXPECT_FALSE(ran_task1); EXPECT_TRUE(deleted_task1); EXPECT_FALSE(ran_task2); EXPECT_TRUE(deleted_task2); EXPECT_TRUE(queue.IsEmpty()); } TEST(TaskQueueTest, OneTaskQueuesMore) { TaskQueue main_queue; // Build a task which will queue two more when run. scoped_ptr<TaskQueue> nested_queue(new TaskQueue()); bool ran_task1 = false; bool deleted_task1 = false; nested_queue->Push( new TaskQueuerTask(&main_queue, new TrackCallsTask(&ran_task1, &deleted_task1))); bool ran_task2 = false; bool deleted_task2 = false; nested_queue->Push( new TaskQueuerTask(&main_queue, new TrackCallsTask(&ran_task2, &deleted_task2))); main_queue.Push(nested_queue.release()); // Run the task which pushes two more tasks. main_queue.Run(); // None of the pushed tasks shoudl have run yet. EXPECT_FALSE(ran_task1); EXPECT_FALSE(deleted_task1); EXPECT_FALSE(ran_task2); EXPECT_FALSE(deleted_task2); EXPECT_FALSE(main_queue.IsEmpty()); // Now run the nested tasks. main_queue.Run(); EXPECT_TRUE(ran_task1); EXPECT_TRUE(deleted_task1); EXPECT_TRUE(ran_task2); EXPECT_TRUE(deleted_task2); EXPECT_TRUE(main_queue.IsEmpty()); }