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