Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / mojo / public / cpp / bindings / tests / sample_service_unittest.cc
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 <algorithm>
6 #include <ostream>
7 #include <string>
8
9 #include "mojo/public/cpp/environment/environment.h"
10 #include "mojo/public/cpp/system/macros.h"
11 #include "mojo/public/interfaces/bindings/tests/sample_service.mojom.h"
12 #include "testing/gtest/include/gtest/gtest.h"
13
14 namespace mojo {
15
16 template <>
17 struct TypeConverter<int32_t, sample::BarPtr> {
18   static int32_t Convert(const sample::BarPtr& bar) {
19     return static_cast<int32_t>(bar->alpha) << 16 |
20            static_cast<int32_t>(bar->beta) << 8 |
21            static_cast<int32_t>(bar->gamma);
22   }
23 };
24
25 }  // namespace mojo
26
27 namespace sample {
28 namespace {
29
30 // Set this variable to true to print the message in hex.
31 bool g_dump_message_as_hex = false;
32
33 // Set this variable to true to print the message in human readable form.
34 bool g_dump_message_as_text = false;
35
36 // Make a sample |Foo|.
37 FooPtr MakeFoo() {
38   mojo::String name("foopy");
39
40   BarPtr bar(Bar::New());
41   bar->alpha = 20;
42   bar->beta = 40;
43   bar->gamma = 60;
44   bar->type = Bar::TYPE_VERTICAL;
45
46   mojo::Array<BarPtr> extra_bars(3);
47   for (size_t i = 0; i < extra_bars.size(); ++i) {
48     Bar::Type type = i % 2 == 0 ? Bar::TYPE_VERTICAL : Bar::TYPE_HORIZONTAL;
49     BarPtr bar(Bar::New());
50     uint8_t base = static_cast<uint8_t>(i * 100);
51     bar->alpha = base;
52     bar->beta = base + 20;
53     bar->gamma = base + 40;
54     bar->type = type;
55     extra_bars[i] = bar.Pass();
56   }
57
58   mojo::Array<uint8_t> data(10);
59   for (size_t i = 0; i < data.size(); ++i)
60     data[i] = static_cast<uint8_t>(data.size() - i);
61
62   mojo::Array<mojo::ScopedDataPipeConsumerHandle> input_streams(2);
63   mojo::Array<mojo::ScopedDataPipeProducerHandle> output_streams(2);
64   for (size_t i = 0; i < input_streams.size(); ++i) {
65     MojoCreateDataPipeOptions options;
66     options.struct_size = sizeof(MojoCreateDataPipeOptions);
67     options.flags = MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_NONE;
68     options.element_num_bytes = 1;
69     options.capacity_num_bytes = 1024;
70     mojo::ScopedDataPipeProducerHandle producer;
71     mojo::ScopedDataPipeConsumerHandle consumer;
72     mojo::CreateDataPipe(&options, &producer, &consumer);
73     input_streams[i] = consumer.Pass();
74     output_streams[i] = producer.Pass();
75   }
76
77   mojo::Array<mojo::Array<bool>> array_of_array_of_bools(2);
78   for (size_t i = 0; i < 2; ++i) {
79     mojo::Array<bool> array_of_bools(2);
80     for (size_t j = 0; j < 2; ++j)
81       array_of_bools[j] = j;
82     array_of_array_of_bools[i] = array_of_bools.Pass();
83   }
84
85   mojo::MessagePipe pipe;
86   FooPtr foo(Foo::New());
87   foo->name = name;
88   foo->x = 1;
89   foo->y = 2;
90   foo->a = false;
91   foo->b = true;
92   foo->c = false;
93   foo->bar = bar.Pass();
94   foo->extra_bars = extra_bars.Pass();
95   foo->data = data.Pass();
96   foo->source = pipe.handle1.Pass();
97   foo->input_streams = input_streams.Pass();
98   foo->output_streams = output_streams.Pass();
99   foo->array_of_array_of_bools = array_of_array_of_bools.Pass();
100
101   return foo.Pass();
102 }
103
104 // Check that the given |Foo| is identical to the one made by |MakeFoo()|.
105 void CheckFoo(const Foo& foo) {
106   const std::string kName("foopy");
107   ASSERT_FALSE(foo.name.is_null());
108   EXPECT_EQ(kName.size(), foo.name.size());
109   for (size_t i = 0; i < std::min(kName.size(), foo.name.size()); i++) {
110     // Test both |operator[]| and |at|.
111     EXPECT_EQ(kName[i], foo.name.at(i)) << i;
112     EXPECT_EQ(kName[i], foo.name[i]) << i;
113   }
114   EXPECT_EQ(kName, foo.name.get());
115
116   EXPECT_EQ(1, foo.x);
117   EXPECT_EQ(2, foo.y);
118   EXPECT_FALSE(foo.a);
119   EXPECT_TRUE(foo.b);
120   EXPECT_FALSE(foo.c);
121
122   EXPECT_EQ(20, foo.bar->alpha);
123   EXPECT_EQ(40, foo.bar->beta);
124   EXPECT_EQ(60, foo.bar->gamma);
125   EXPECT_EQ(Bar::TYPE_VERTICAL, foo.bar->type);
126
127   EXPECT_EQ(3u, foo.extra_bars.size());
128   for (size_t i = 0; i < foo.extra_bars.size(); i++) {
129     uint8_t base = static_cast<uint8_t>(i * 100);
130     Bar::Type type = i % 2 == 0 ? Bar::TYPE_VERTICAL : Bar::TYPE_HORIZONTAL;
131     EXPECT_EQ(base, foo.extra_bars[i]->alpha) << i;
132     EXPECT_EQ(base + 20, foo.extra_bars[i]->beta) << i;
133     EXPECT_EQ(base + 40, foo.extra_bars[i]->gamma) << i;
134     EXPECT_EQ(type, foo.extra_bars[i]->type) << i;
135   }
136
137   EXPECT_EQ(10u, foo.data.size());
138   for (size_t i = 0; i < foo.data.size(); ++i) {
139     EXPECT_EQ(static_cast<uint8_t>(foo.data.size() - i), foo.data[i]) << i;
140   }
141
142   EXPECT_FALSE(foo.input_streams.is_null());
143   EXPECT_EQ(2u, foo.input_streams.size());
144
145   EXPECT_FALSE(foo.output_streams.is_null());
146   EXPECT_EQ(2u, foo.output_streams.size());
147
148   EXPECT_EQ(2u, foo.array_of_array_of_bools.size());
149   for (size_t i = 0; i < foo.array_of_array_of_bools.size(); ++i) {
150     EXPECT_EQ(2u, foo.array_of_array_of_bools[i].size());
151     for (size_t j = 0; j < foo.array_of_array_of_bools[i].size(); ++j) {
152       EXPECT_EQ(bool(j), foo.array_of_array_of_bools[i][j]);
153     }
154   }
155 }
156
157 void PrintSpacer(int depth) {
158   for (int i = 0; i < depth; ++i)
159     std::cout << "   ";
160 }
161
162 void Print(int depth, const char* name, bool value) {
163   PrintSpacer(depth);
164   std::cout << name << ": " << (value ? "true" : "false") << std::endl;
165 }
166
167 void Print(int depth, const char* name, int32_t value) {
168   PrintSpacer(depth);
169   std::cout << name << ": " << value << std::endl;
170 }
171
172 void Print(int depth, const char* name, uint8_t value) {
173   PrintSpacer(depth);
174   std::cout << name << ": " << uint32_t(value) << std::endl;
175 }
176
177 template <typename H>
178 void Print(int depth,
179            const char* name,
180            const mojo::ScopedHandleBase<H>& value) {
181   PrintSpacer(depth);
182   std::cout << name << ": 0x" << std::hex << value.get().value() << std::endl;
183 }
184
185 void Print(int depth, const char* name, const mojo::String& str) {
186   PrintSpacer(depth);
187   std::cout << name << ": \"" << str.get() << "\"" << std::endl;
188 }
189
190 void Print(int depth, const char* name, const BarPtr& bar) {
191   PrintSpacer(depth);
192   std::cout << name << ":" << std::endl;
193   if (!bar.is_null()) {
194     ++depth;
195     Print(depth, "alpha", bar->alpha);
196     Print(depth, "beta", bar->beta);
197     Print(depth, "gamma", bar->gamma);
198     Print(depth, "packed", bar.To<int32_t>());
199     --depth;
200   }
201 }
202
203 template <typename T>
204 void Print(int depth, const char* name, const mojo::Array<T>& array) {
205   PrintSpacer(depth);
206   std::cout << name << ":" << std::endl;
207   if (!array.is_null()) {
208     ++depth;
209     for (size_t i = 0; i < array.size(); ++i) {
210       std::stringstream buf;
211       buf << i;
212       Print(depth, buf.str().data(), array.at(i));
213     }
214     --depth;
215   }
216 }
217
218 void Print(int depth, const char* name, const FooPtr& foo) {
219   PrintSpacer(depth);
220   std::cout << name << ":" << std::endl;
221   if (!foo.is_null()) {
222     ++depth;
223     Print(depth, "name", foo->name);
224     Print(depth, "x", foo->x);
225     Print(depth, "y", foo->y);
226     Print(depth, "a", foo->a);
227     Print(depth, "b", foo->b);
228     Print(depth, "c", foo->c);
229     Print(depth, "bar", foo->bar);
230     Print(depth, "extra_bars", foo->extra_bars);
231     Print(depth, "data", foo->data);
232     Print(depth, "source", foo->source);
233     Print(depth, "input_streams", foo->input_streams);
234     Print(depth, "output_streams", foo->output_streams);
235     Print(depth, "array_of_array_of_bools", foo->array_of_array_of_bools);
236     --depth;
237   }
238 }
239
240 void DumpHex(const uint8_t* bytes, uint32_t num_bytes) {
241   for (uint32_t i = 0; i < num_bytes; ++i) {
242     std::cout << std::setw(2) << std::setfill('0') << std::hex
243               << uint32_t(bytes[i]);
244
245     if (i % 16 == 15) {
246       std::cout << std::endl;
247       continue;
248     }
249
250     if (i % 2 == 1)
251       std::cout << " ";
252     if (i % 8 == 7)
253       std::cout << " ";
254   }
255 }
256
257 class ServiceImpl : public Service {
258  public:
259   void Frobinate(FooPtr foo, BazOptions baz, PortPtr port) override {
260     // Users code goes here to handle the incoming Frobinate message.
261
262     // We mainly check that we're given the expected arguments.
263     EXPECT_FALSE(foo.is_null());
264     if (!foo.is_null())
265       CheckFoo(*foo);
266     EXPECT_EQ(BAZ_OPTIONS_EXTRA, baz);
267
268     if (g_dump_message_as_text) {
269       // Also dump the Foo structure and all of its members.
270       std::cout << "Frobinate:" << std::endl;
271       int depth = 1;
272       Print(depth, "foo", foo);
273       Print(depth, "baz", baz);
274       Print(depth, "port", port.get());
275     }
276   }
277
278   void GetPort(mojo::InterfaceRequest<Port> port_request) override {}
279 };
280
281 class ServiceProxyImpl : public ServiceProxy {
282  public:
283   explicit ServiceProxyImpl(mojo::MessageReceiverWithResponder* receiver)
284       : ServiceProxy(receiver) {}
285 };
286
287 class SimpleMessageReceiver : public mojo::MessageReceiverWithResponder {
288  public:
289   bool Accept(mojo::Message* message) override {
290     // Imagine some IPC happened here.
291
292     if (g_dump_message_as_hex) {
293       DumpHex(reinterpret_cast<const uint8_t*>(message->data()),
294               message->data_num_bytes());
295     }
296
297     // In the receiving process, an implementation of ServiceStub is known to
298     // the system. It receives the incoming message.
299     ServiceImpl impl;
300
301     ServiceStub stub;
302     stub.set_sink(&impl);
303     return stub.Accept(message);
304   }
305
306   bool AcceptWithResponder(mojo::Message* message,
307                            mojo::MessageReceiver* responder) override {
308     return false;
309   }
310 };
311
312 class BindingsSampleTest : public testing::Test {
313  public:
314   BindingsSampleTest() {}
315   ~BindingsSampleTest() override {}
316
317  private:
318   mojo::Environment env_;
319
320   MOJO_DISALLOW_COPY_AND_ASSIGN(BindingsSampleTest);
321 };
322
323 TEST_F(BindingsSampleTest, Basic) {
324   SimpleMessageReceiver receiver;
325
326   // User has a proxy to a Service somehow.
327   Service* service = new ServiceProxyImpl(&receiver);
328
329   // User constructs a message to send.
330
331   // Notice that it doesn't matter in what order the structs / arrays are
332   // allocated. Here, the various members of Foo are allocated before Foo is
333   // allocated.
334
335   FooPtr foo = MakeFoo();
336   CheckFoo(*foo);
337
338   PortPtr port;
339   service->Frobinate(foo.Pass(), Service::BAZ_OPTIONS_EXTRA, port.Pass());
340
341   delete service;
342 }
343
344 TEST_F(BindingsSampleTest, DefaultValues) {
345   DefaultsTestPtr defaults(DefaultsTest::New());
346   EXPECT_EQ(-12, defaults->a0);
347   EXPECT_EQ(kTwelve, defaults->a1);
348   EXPECT_EQ(1234, defaults->a2);
349   EXPECT_EQ(34567U, defaults->a3);
350   EXPECT_EQ(123456, defaults->a4);
351   EXPECT_EQ(3456789012U, defaults->a5);
352   EXPECT_EQ(-111111111111LL, defaults->a6);
353   EXPECT_EQ(9999999999999999999ULL, defaults->a7);
354   EXPECT_EQ(0x12345, defaults->a8);
355   EXPECT_EQ(-0x12345, defaults->a9);
356   EXPECT_EQ(1234, defaults->a10);
357   EXPECT_TRUE(defaults->a11);
358   EXPECT_FALSE(defaults->a12);
359   EXPECT_FLOAT_EQ(123.25f, defaults->a13);
360   EXPECT_DOUBLE_EQ(1234567890.123, defaults->a14);
361   EXPECT_DOUBLE_EQ(1E10, defaults->a15);
362   EXPECT_DOUBLE_EQ(-1.2E+20, defaults->a16);
363   EXPECT_DOUBLE_EQ(1.23E-20, defaults->a17);
364   EXPECT_TRUE(defaults->a18.is_null());
365   EXPECT_TRUE(defaults->a19.is_null());
366   EXPECT_EQ(Bar::TYPE_BOTH, defaults->a20);
367   EXPECT_TRUE(defaults->a21.is_null());
368   ASSERT_FALSE(defaults->a22.is_null());
369   EXPECT_EQ(imported::SHAPE_RECTANGLE, defaults->a22->shape);
370   EXPECT_EQ(imported::COLOR_BLACK, defaults->a22->color);
371   EXPECT_EQ(0xFFFFFFFFFFFFFFFFULL, defaults->a23);
372   EXPECT_EQ(0x123456789, defaults->a24);
373   EXPECT_EQ(-0x123456789, defaults->a25);
374 }
375
376 }  // namespace
377 }  // namespace sample