1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
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/task_runner_util.h"
6 
7 #include <utility>
8 
9 #include "base/bind.h"
10 #include "base/location.h"
11 #include "base/run_loop.h"
12 #include "base/test/task_environment.h"
13 #include "base/threading/thread_task_runner_handle.h"
14 #include "testing/gtest/include/gtest/gtest.h"
15 
16 namespace base {
17 
18 namespace {
19 
ReturnFourtyTwo()20 int ReturnFourtyTwo() {
21   return 42;
22 }
23 
StoreValue(int * destination,int value)24 void StoreValue(int* destination, int value) {
25   *destination = value;
26 }
27 
StoreDoubleValue(double * destination,double value)28 void StoreDoubleValue(double* destination, double value) {
29   *destination = value;
30 }
31 
32 int g_foo_destruct_count = 0;
33 int g_foo_free_count = 0;
34 
35 struct Foo {
~Foobase::__anone011e54b0111::Foo36   ~Foo() {
37     ++g_foo_destruct_count;
38   }
39 };
40 
CreateFoo()41 std::unique_ptr<Foo> CreateFoo() {
42   return std::unique_ptr<Foo>(new Foo);
43 }
44 
ExpectFoo(std::unique_ptr<Foo> foo)45 void ExpectFoo(std::unique_ptr<Foo> foo) {
46   EXPECT_TRUE(foo.get());
47   std::unique_ptr<Foo> local_foo(std::move(foo));
48   EXPECT_TRUE(local_foo.get());
49   EXPECT_FALSE(foo.get());
50 }
51 
52 struct FooDeleter {
operator ()base::__anone011e54b0111::FooDeleter53   void operator()(Foo* foo) const {
54     ++g_foo_free_count;
55     delete foo;
56   }
57 };
58 
CreateScopedFoo()59 std::unique_ptr<Foo, FooDeleter> CreateScopedFoo() {
60   return std::unique_ptr<Foo, FooDeleter>(new Foo);
61 }
62 
ExpectScopedFoo(std::unique_ptr<Foo,FooDeleter> foo)63 void ExpectScopedFoo(std::unique_ptr<Foo, FooDeleter> foo) {
64   EXPECT_TRUE(foo.get());
65   std::unique_ptr<Foo, FooDeleter> local_foo(std::move(foo));
66   EXPECT_TRUE(local_foo.get());
67   EXPECT_FALSE(foo.get());
68 }
69 
70 struct FooWithoutDefaultConstructor {
FooWithoutDefaultConstructorbase::__anone011e54b0111::FooWithoutDefaultConstructor71   explicit FooWithoutDefaultConstructor(int value) : value(value) {}
72   int value;
73 };
74 
CreateFooWithoutDefaultConstructor(int value)75 FooWithoutDefaultConstructor CreateFooWithoutDefaultConstructor(int value) {
76   return FooWithoutDefaultConstructor(value);
77 }
78 
SaveFooWithoutDefaultConstructor(int * output_value,FooWithoutDefaultConstructor input)79 void SaveFooWithoutDefaultConstructor(int* output_value,
80                                       FooWithoutDefaultConstructor input) {
81   *output_value = input.value;
82 }
83 
84 }  // namespace
85 
TEST(TaskRunnerHelpersTest,PostTaskAndReplyWithResult)86 TEST(TaskRunnerHelpersTest, PostTaskAndReplyWithResult) {
87   int result = 0;
88 
89   test::TaskEnvironment task_environment;
90   PostTaskAndReplyWithResult(ThreadTaskRunnerHandle::Get().get(), FROM_HERE,
91                              BindOnce(&ReturnFourtyTwo),
92                              BindOnce(&StoreValue, &result));
93 
94   RunLoop().RunUntilIdle();
95 
96   EXPECT_EQ(42, result);
97 }
98 
TEST(TaskRunnerHelpersTest,PostTaskAndReplyWithResultImplicitConvert)99 TEST(TaskRunnerHelpersTest, PostTaskAndReplyWithResultImplicitConvert) {
100   double result = 0;
101 
102   test::TaskEnvironment task_environment;
103   PostTaskAndReplyWithResult(ThreadTaskRunnerHandle::Get().get(), FROM_HERE,
104                              BindOnce(&ReturnFourtyTwo),
105                              BindOnce(&StoreDoubleValue, &result));
106 
107   RunLoop().RunUntilIdle();
108 
109   EXPECT_DOUBLE_EQ(42.0, result);
110 }
111 
TEST(TaskRunnerHelpersTest,PostTaskAndReplyWithResultPassed)112 TEST(TaskRunnerHelpersTest, PostTaskAndReplyWithResultPassed) {
113   g_foo_destruct_count = 0;
114   g_foo_free_count = 0;
115 
116   test::TaskEnvironment task_environment;
117   PostTaskAndReplyWithResult(ThreadTaskRunnerHandle::Get().get(), FROM_HERE,
118                              BindOnce(&CreateFoo), BindOnce(&ExpectFoo));
119 
120   RunLoop().RunUntilIdle();
121 
122   EXPECT_EQ(1, g_foo_destruct_count);
123   EXPECT_EQ(0, g_foo_free_count);
124 }
125 
TEST(TaskRunnerHelpersTest,PostTaskAndReplyWithResultPassedFreeProc)126 TEST(TaskRunnerHelpersTest, PostTaskAndReplyWithResultPassedFreeProc) {
127   g_foo_destruct_count = 0;
128   g_foo_free_count = 0;
129 
130   test::TaskEnvironment task_environment;
131   PostTaskAndReplyWithResult(ThreadTaskRunnerHandle::Get().get(), FROM_HERE,
132                              BindOnce(&CreateScopedFoo),
133                              BindOnce(&ExpectScopedFoo));
134 
135   RunLoop().RunUntilIdle();
136 
137   EXPECT_EQ(1, g_foo_destruct_count);
138   EXPECT_EQ(1, g_foo_free_count);
139 }
140 
TEST(TaskRunnerHelpersTest,PostTaskAndReplyWithResultWithoutDefaultConstructor)141 TEST(TaskRunnerHelpersTest,
142      PostTaskAndReplyWithResultWithoutDefaultConstructor) {
143   const int kSomeVal = 17;
144 
145   test::TaskEnvironment task_environment;
146   int actual = 0;
147   PostTaskAndReplyWithResult(
148       ThreadTaskRunnerHandle::Get().get(), FROM_HERE,
149       BindOnce(&CreateFooWithoutDefaultConstructor, kSomeVal),
150       BindOnce(&SaveFooWithoutDefaultConstructor, &actual));
151 
152   RunLoop().RunUntilIdle();
153 
154   EXPECT_EQ(kSomeVal, actual);
155 }
156 
157 }  // namespace base
158