1 // Copyright 2014 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 <stdint.h>
6 #include <utility>
7 
8 #include "base/run_loop.h"
9 #include "mojo/public/cpp/bindings/binding.h"
10 #include "mojo/public/cpp/bindings/tests/bindings_test_base.h"
11 #include "mojo/public/cpp/test_support/test_utils.h"
12 #include "mojo/public/interfaces/bindings/tests/sample_import.mojom.h"
13 #include "mojo/public/interfaces/bindings/tests/sample_interfaces.mojom.h"
14 #include "testing/gtest/include/gtest/gtest.h"
15 
16 namespace mojo {
17 namespace test {
18 namespace {
19 
20 class ProviderImpl : public sample::Provider {
21  public:
ProviderImpl(InterfaceRequest<sample::Provider> request)22   explicit ProviderImpl(InterfaceRequest<sample::Provider> request)
23       : binding_(this, std::move(request)) {}
24 
EchoString(const std::string & a,const EchoStringCallback & callback)25   void EchoString(const std::string& a,
26                   const EchoStringCallback& callback) override {
27     EchoStringCallback callback_copy;
28     // Make sure operator= is used.
29     callback_copy = callback;
30     callback_copy.Run(a);
31   }
32 
EchoStrings(const std::string & a,const std::string & b,const EchoStringsCallback & callback)33   void EchoStrings(const std::string& a,
34                    const std::string& b,
35                    const EchoStringsCallback& callback) override {
36     callback.Run(a, b);
37   }
38 
EchoMessagePipeHandle(ScopedMessagePipeHandle a,const EchoMessagePipeHandleCallback & callback)39   void EchoMessagePipeHandle(
40       ScopedMessagePipeHandle a,
41       const EchoMessagePipeHandleCallback& callback) override {
42     callback.Run(std::move(a));
43   }
44 
EchoEnum(sample::Enum a,const EchoEnumCallback & callback)45   void EchoEnum(sample::Enum a, const EchoEnumCallback& callback) override {
46     callback.Run(a);
47   }
48 
EchoInt(int32_t a,const EchoIntCallback & callback)49   void EchoInt(int32_t a, const EchoIntCallback& callback) override {
50     callback.Run(a);
51   }
52 
53   Binding<sample::Provider> binding_;
54 };
55 
RecordString(std::string * storage,const base::Closure & closure,const std::string & str)56 void RecordString(std::string* storage,
57                   const base::Closure& closure,
58                   const std::string& str) {
59   *storage = str;
60   closure.Run();
61 }
62 
RecordStrings(std::string * storage,const base::Closure & closure,const std::string & a,const std::string & b)63 void RecordStrings(std::string* storage,
64                    const base::Closure& closure,
65                    const std::string& a,
66                    const std::string& b) {
67   *storage = a + b;
68   closure.Run();
69 }
70 
WriteToMessagePipe(const char * text,const base::Closure & closure,ScopedMessagePipeHandle handle)71 void WriteToMessagePipe(const char* text,
72                         const base::Closure& closure,
73                         ScopedMessagePipeHandle handle) {
74   WriteTextMessage(handle.get(), text);
75   closure.Run();
76 }
77 
RecordEnum(sample::Enum * storage,const base::Closure & closure,sample::Enum value)78 void RecordEnum(sample::Enum* storage,
79                 const base::Closure& closure,
80                 sample::Enum value) {
81   *storage = value;
82   closure.Run();
83 }
84 
85 class RequestResponseTest : public BindingsTestBase {
86  public:
RequestResponseTest()87   RequestResponseTest() {}
~RequestResponseTest()88   ~RequestResponseTest() override { base::RunLoop().RunUntilIdle(); }
89 
PumpMessages()90   void PumpMessages() { base::RunLoop().RunUntilIdle(); }
91 };
92 
TEST_P(RequestResponseTest,EchoString)93 TEST_P(RequestResponseTest, EchoString) {
94   sample::ProviderPtr provider;
95   ProviderImpl provider_impl(MakeRequest(&provider));
96 
97   std::string buf;
98   base::RunLoop run_loop;
99   provider->EchoString("hello",
100                        base::Bind(&RecordString, &buf, run_loop.QuitClosure()));
101 
102   run_loop.Run();
103 
104   EXPECT_EQ(std::string("hello"), buf);
105 }
106 
TEST_P(RequestResponseTest,EchoStrings)107 TEST_P(RequestResponseTest, EchoStrings) {
108   sample::ProviderPtr provider;
109   ProviderImpl provider_impl(MakeRequest(&provider));
110 
111   std::string buf;
112   base::RunLoop run_loop;
113   provider->EchoStrings("hello", " world", base::Bind(&RecordStrings, &buf,
114                                                       run_loop.QuitClosure()));
115 
116   run_loop.Run();
117 
118   EXPECT_EQ(std::string("hello world"), buf);
119 }
120 
TEST_P(RequestResponseTest,EchoMessagePipeHandle)121 TEST_P(RequestResponseTest, EchoMessagePipeHandle) {
122   sample::ProviderPtr provider;
123   ProviderImpl provider_impl(MakeRequest(&provider));
124 
125   MessagePipe pipe2;
126   base::RunLoop run_loop;
127   provider->EchoMessagePipeHandle(
128       std::move(pipe2.handle1),
129       base::Bind(&WriteToMessagePipe, "hello", run_loop.QuitClosure()));
130 
131   run_loop.Run();
132 
133   std::string value;
134   ReadTextMessage(pipe2.handle0.get(), &value);
135 
136   EXPECT_EQ(std::string("hello"), value);
137 }
138 
TEST_P(RequestResponseTest,EchoEnum)139 TEST_P(RequestResponseTest, EchoEnum) {
140   sample::ProviderPtr provider;
141   ProviderImpl provider_impl(MakeRequest(&provider));
142 
143   sample::Enum value;
144   base::RunLoop run_loop;
145   provider->EchoEnum(sample::Enum::VALUE,
146                      base::Bind(&RecordEnum, &value, run_loop.QuitClosure()));
147   run_loop.Run();
148 
149   EXPECT_EQ(sample::Enum::VALUE, value);
150 }
151 
152 INSTANTIATE_MOJO_BINDINGS_TEST_CASE_P(RequestResponseTest);
153 
154 }  // namespace
155 }  // namespace test
156 }  // namespace mojo
157