fixup! [M120 Migration] Notify media device state to webbrowser
[platform/framework/web/chromium-efl.git] / base / one_shot_event_unittest.cc
1 // Copyright 2013 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 #include "base/one_shot_event.h"
6
7 #include "base/functional/bind.h"
8 #include "base/memory/raw_ptr.h"
9 #include "base/run_loop.h"
10 #include "base/task/single_thread_task_runner.h"
11 #include "base/test/task_environment.h"
12 #include "base/test/test_simple_task_runner.h"
13 #include "testing/gtest/include/gtest/gtest.h"
14
15 namespace base {
16
17 void Increment(int* i) {
18   ++*i;
19 }
20
21 // |*did_delete_instance| will be set to true upon its destruction.
22 class RefCountedClass : public base::RefCounted<RefCountedClass> {
23  public:
24   explicit RefCountedClass(bool* did_delete_instance)
25       : did_delete_instance_(did_delete_instance) {
26     DCHECK(!*did_delete_instance_);
27   }
28   RefCountedClass(const RefCountedClass&) = delete;
29   RefCountedClass& operator=(const RefCountedClass&) = delete;
30
31   void PerformTask() { did_perform_task_ = true; }
32   bool did_perform_task() const { return did_perform_task_; }
33
34  private:
35   friend class base::RefCounted<RefCountedClass>;
36
37   ~RefCountedClass() { *did_delete_instance_ = true; }
38
39   const raw_ptr<bool> did_delete_instance_;  // Not owned.
40
41   bool did_perform_task_ = false;
42 };
43
44 TEST(OneShotEventTest, RecordsSignal) {
45   OneShotEvent event;
46   EXPECT_FALSE(event.is_signaled());
47   event.Signal();
48   EXPECT_TRUE(event.is_signaled());
49 }
50
51 TEST(OneShotEventTest, CallsQueueAsDistinctTask) {
52   OneShotEvent event;
53   scoped_refptr<base::TestSimpleTaskRunner> runner(
54       new base::TestSimpleTaskRunner);
55   int i = 0;
56   event.Post(FROM_HERE, base::BindOnce(&Increment, &i), runner);
57   event.Post(FROM_HERE, base::BindOnce(&Increment, &i), runner);
58   EXPECT_EQ(0U, runner->NumPendingTasks());
59   event.Signal();
60
61   auto pending_tasks = runner->TakePendingTasks();
62   ASSERT_EQ(2U, pending_tasks.size());
63   EXPECT_NE(pending_tasks[0].location.line_number(),
64             pending_tasks[1].location.line_number())
65       << "Make sure FROM_HERE is propagated.";
66 }
67
68 TEST(OneShotEventTest, CallsQueue) {
69   OneShotEvent event;
70   scoped_refptr<base::TestSimpleTaskRunner> runner(
71       new base::TestSimpleTaskRunner);
72   int i = 0;
73   event.Post(FROM_HERE, base::BindOnce(&Increment, &i), runner);
74   event.Post(FROM_HERE, base::BindOnce(&Increment, &i), runner);
75   EXPECT_EQ(0U, runner->NumPendingTasks());
76   event.Signal();
77   ASSERT_EQ(2U, runner->NumPendingTasks());
78
79   EXPECT_EQ(0, i);
80   runner->RunPendingTasks();
81   EXPECT_EQ(2, i);
82 }
83
84 TEST(OneShotEventTest, CallsAfterSignalDontRunInline) {
85   OneShotEvent event;
86   scoped_refptr<base::TestSimpleTaskRunner> runner(
87       new base::TestSimpleTaskRunner);
88   int i = 0;
89
90   event.Signal();
91   event.Post(FROM_HERE, base::BindOnce(&Increment, &i), runner);
92   EXPECT_EQ(1U, runner->NumPendingTasks());
93   EXPECT_EQ(0, i);
94   runner->RunPendingTasks();
95   EXPECT_EQ(1, i);
96 }
97
98 TEST(OneShotEventTest, PostDefaultsToCurrentMessageLoop) {
99   OneShotEvent event;
100   scoped_refptr<base::TestSimpleTaskRunner> runner(
101       new base::TestSimpleTaskRunner);
102   base::test::SingleThreadTaskEnvironment task_environment;
103   int runner_i = 0;
104   int loop_i = 0;
105
106   event.Post(FROM_HERE, base::BindOnce(&Increment, &runner_i), runner);
107   event.Post(FROM_HERE, base::BindOnce(&Increment, &loop_i));
108   event.Signal();
109   EXPECT_EQ(1U, runner->NumPendingTasks());
110   EXPECT_EQ(0, runner_i);
111   runner->RunPendingTasks();
112   EXPECT_EQ(1, runner_i);
113   EXPECT_EQ(0, loop_i);
114   base::RunLoop().RunUntilIdle();
115   EXPECT_EQ(1, loop_i);
116 }
117
118 void CheckSignaledAndPostIncrement(
119     OneShotEvent* event,
120     const scoped_refptr<base::SingleThreadTaskRunner>& runner,
121     int* i) {
122   EXPECT_TRUE(event->is_signaled());
123   event->Post(FROM_HERE, base::BindOnce(&Increment, i), runner);
124 }
125
126 TEST(OneShotEventTest, IsSignaledAndPostsFromCallbackWork) {
127   OneShotEvent event;
128   scoped_refptr<base::TestSimpleTaskRunner> runner(
129       new base::TestSimpleTaskRunner);
130   int i = 0;
131
132   event.Post(FROM_HERE,
133              base::BindOnce(&CheckSignaledAndPostIncrement, &event, runner, &i),
134              runner);
135   EXPECT_EQ(0, i);
136   event.Signal();
137
138   // CheckSignaledAndPostIncrement is queued on |runner|.
139   EXPECT_EQ(1U, runner->NumPendingTasks());
140   EXPECT_EQ(0, i);
141   runner->RunPendingTasks();
142   // Increment is queued on |runner|.
143   EXPECT_EQ(1U, runner->NumPendingTasks());
144   EXPECT_EQ(0, i);
145   runner->RunPendingTasks();
146   // Increment has run.
147   EXPECT_EQ(0U, runner->NumPendingTasks());
148   EXPECT_EQ(1, i);
149 }
150
151 // Tests that OneShotEvent does not keep references to tasks once OneShotEvent
152 // Signal()s.
153 TEST(OneShotEventTest, DropsCallbackRefUponSignalled) {
154   auto runner = base::MakeRefCounted<base::TestSimpleTaskRunner>();
155   bool did_delete_instance = false;
156   OneShotEvent event;
157
158   {
159     auto ref_counted_class =
160         base::MakeRefCounted<RefCountedClass>(&did_delete_instance);
161     event.Post(FROM_HERE,
162                base::BindOnce(&RefCountedClass::PerformTask, ref_counted_class),
163                runner);
164     event.Signal();
165     runner->RunPendingTasks();
166     EXPECT_TRUE(ref_counted_class->did_perform_task());
167   }
168
169   // Once OneShotEvent doesn't have any queued events, it should have dropped
170   // all the references to the callbacks it received through Post().
171   EXPECT_TRUE(did_delete_instance);
172 }
173
174 }  // namespace base