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 "base/bind.h"
8#include "base/message_loop/message_loop.h"
9#include "base/run_loop.h"
10#include "testing/gtest/include/gtest/gtest.h"
11
12namespace base {
13
14namespace {
15
16int ReturnFourtyTwo() {
17  return 42;
18}
19
20void StoreValue(int* destination, int value) {
21  *destination = value;
22}
23
24void StoreDoubleValue(double* destination, double value) {
25  *destination = value;
26}
27
28int g_foo_destruct_count = 0;
29int g_foo_free_count = 0;
30
31struct Foo {
32  ~Foo() {
33    ++g_foo_destruct_count;
34  }
35};
36
37scoped_ptr<Foo> CreateFoo() {
38  return scoped_ptr<Foo>(new Foo);
39}
40
41void ExpectFoo(scoped_ptr<Foo> foo) {
42  EXPECT_TRUE(foo.get());
43  scoped_ptr<Foo> local_foo(foo.Pass());
44  EXPECT_TRUE(local_foo.get());
45  EXPECT_FALSE(foo.get());
46}
47
48struct FooDeleter {
49  void operator()(Foo* foo) const {
50    ++g_foo_free_count;
51    delete foo;
52  };
53};
54
55scoped_ptr<Foo, FooDeleter> CreateScopedFoo() {
56  return scoped_ptr<Foo, FooDeleter>(new Foo);
57}
58
59void ExpectScopedFoo(scoped_ptr<Foo, FooDeleter> foo) {
60  EXPECT_TRUE(foo.get());
61  scoped_ptr<Foo, FooDeleter> local_foo(foo.Pass());
62  EXPECT_TRUE(local_foo.get());
63  EXPECT_FALSE(foo.get());
64}
65
66}  // namespace
67
68TEST(TaskRunnerHelpersTest, PostTaskAndReplyWithResult) {
69  int result = 0;
70
71  MessageLoop message_loop;
72  PostTaskAndReplyWithResult(message_loop.message_loop_proxy().get(),
73                             FROM_HERE,
74                             Bind(&ReturnFourtyTwo),
75                             Bind(&StoreValue, &result));
76
77  RunLoop().RunUntilIdle();
78
79  EXPECT_EQ(42, result);
80}
81
82TEST(TaskRunnerHelpersTest, PostTaskAndReplyWithResultImplicitConvert) {
83  double result = 0;
84
85  MessageLoop message_loop;
86  PostTaskAndReplyWithResult(message_loop.message_loop_proxy().get(),
87                             FROM_HERE,
88                             Bind(&ReturnFourtyTwo),
89                             Bind(&StoreDoubleValue, &result));
90
91  RunLoop().RunUntilIdle();
92
93  EXPECT_DOUBLE_EQ(42.0, result);
94}
95
96TEST(TaskRunnerHelpersTest, PostTaskAndReplyWithResultPassed) {
97  g_foo_destruct_count = 0;
98  g_foo_free_count = 0;
99
100  MessageLoop message_loop;
101  PostTaskAndReplyWithResult(message_loop.message_loop_proxy().get(),
102                             FROM_HERE,
103                             Bind(&CreateFoo),
104                             Bind(&ExpectFoo));
105
106  RunLoop().RunUntilIdle();
107
108  EXPECT_EQ(1, g_foo_destruct_count);
109  EXPECT_EQ(0, g_foo_free_count);
110}
111
112TEST(TaskRunnerHelpersTest, PostTaskAndReplyWithResultPassedFreeProc) {
113  g_foo_destruct_count = 0;
114  g_foo_free_count = 0;
115
116  MessageLoop message_loop;
117  PostTaskAndReplyWithResult(message_loop.message_loop_proxy().get(),
118                             FROM_HERE,
119                             Bind(&CreateScopedFoo),
120                             Bind(&ExpectScopedFoo));
121
122  RunLoop().RunUntilIdle();
123
124  EXPECT_EQ(1, g_foo_destruct_count);
125  EXPECT_EQ(1, g_foo_free_count);
126}
127
128}  // namespace base
129