1645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// Copyright 2014 The Chromium Authors. All rights reserved.
2645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// Use of this source code is governed by a BSD-style license that can be
3645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// found in the LICENSE file.
4645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
5645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#include <stddef.h>
6645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#include <stdint.h>
7645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#include <algorithm>
8645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#include <ostream>
9645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#include <string>
10645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#include <utility>
11645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
12645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#include "mojo/public/interfaces/bindings/tests/sample_service.mojom.h"
13645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#include "testing/gtest/include/gtest/gtest.h"
14645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
15645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chaveznamespace mojo {
16645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
17645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chaveztemplate <>
18645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavezstruct TypeConverter<int32_t, sample::BarPtr> {
19645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  static int32_t Convert(const sample::BarPtr& bar) {
20645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    return static_cast<int32_t>(bar->alpha) << 16 |
21645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez           static_cast<int32_t>(bar->beta) << 8 |
22645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez           static_cast<int32_t>(bar->gamma);
23645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  }
24645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez};
25645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
26645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez}  // namespace mojo
27645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
28645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chaveznamespace sample {
29645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chaveznamespace {
30645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
31645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// Set this variable to true to print the message in hex.
32645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavezbool g_dump_message_as_hex = false;
33645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
34645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// Set this variable to true to print the message in human readable form.
35645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavezbool g_dump_message_as_text = false;
36645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
37645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// Make a sample |Foo|.
38645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector ChavezFooPtr MakeFoo() {
39645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  std::string name("foopy");
40645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
41645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  BarPtr bar(Bar::New());
42645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  bar->alpha = 20;
43645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  bar->beta = 40;
44645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  bar->gamma = 60;
45645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  bar->type = Bar::Type::VERTICAL;
46645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
47645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  std::vector<BarPtr> extra_bars(3);
48645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  for (size_t i = 0; i < extra_bars.size(); ++i) {
49645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    Bar::Type type = i % 2 == 0 ? Bar::Type::VERTICAL : Bar::Type::HORIZONTAL;
50645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    BarPtr bar(Bar::New());
51645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    uint8_t base = static_cast<uint8_t>(i * 100);
52645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    bar->alpha = base;
53645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    bar->beta = base + 20;
54645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    bar->gamma = base + 40;
55645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    bar->type = type;
56645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    extra_bars[i] = std::move(bar);
57645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  }
58645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
59645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  std::vector<uint8_t> data(10);
60645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  for (size_t i = 0; i < data.size(); ++i)
61645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    data[i] = static_cast<uint8_t>(data.size() - i);
62645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
63645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  std::vector<mojo::ScopedDataPipeConsumerHandle> input_streams(2);
64645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  std::vector<mojo::ScopedDataPipeProducerHandle> output_streams(2);
65645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  for (size_t i = 0; i < input_streams.size(); ++i) {
66645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    MojoCreateDataPipeOptions options;
67645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    options.struct_size = sizeof(MojoCreateDataPipeOptions);
68645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    options.flags = MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_NONE;
69645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    options.element_num_bytes = 1;
70645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    options.capacity_num_bytes = 1024;
71645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    mojo::ScopedDataPipeProducerHandle producer;
72645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    mojo::ScopedDataPipeConsumerHandle consumer;
73645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    mojo::CreateDataPipe(&options, &producer, &consumer);
74645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    input_streams[i] = std::move(consumer);
75645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    output_streams[i] = std::move(producer);
76645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  }
77645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
78645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  std::vector<std::vector<bool>> array_of_array_of_bools(2);
79645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  for (size_t i = 0; i < 2; ++i) {
80645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    std::vector<bool> array_of_bools(2);
81645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    for (size_t j = 0; j < 2; ++j)
82645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez      array_of_bools[j] = j;
83645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    array_of_array_of_bools[i] = std::move(array_of_bools);
84645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  }
85645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
86645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  mojo::MessagePipe pipe;
87645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  FooPtr foo(Foo::New());
88645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  foo->name = name;
89645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  foo->x = 1;
90645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  foo->y = 2;
91645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  foo->a = false;
92645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  foo->b = true;
93645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  foo->c = false;
94645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  foo->bar = std::move(bar);
95645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  foo->extra_bars = std::move(extra_bars);
96645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  foo->data = std::move(data);
97645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  foo->source = std::move(pipe.handle1);
98645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  foo->input_streams = std::move(input_streams);
99645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  foo->output_streams = std::move(output_streams);
100645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  foo->array_of_array_of_bools = std::move(array_of_array_of_bools);
101645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
102645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  return foo;
103645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez}
104645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
105645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// Check that the given |Foo| is identical to the one made by |MakeFoo()|.
106645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavezvoid CheckFoo(const Foo& foo) {
107645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  const std::string kName("foopy");
108645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  EXPECT_EQ(kName.size(), foo.name.size());
109645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  for (size_t i = 0; i < std::min(kName.size(), foo.name.size()); i++) {
110645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    // Test both |operator[]| and |at|.
111645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    EXPECT_EQ(kName[i], foo.name.at(i)) << i;
112645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    EXPECT_EQ(kName[i], foo.name[i]) << i;
113645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  }
114645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  EXPECT_EQ(kName, foo.name);
115645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
116645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  EXPECT_EQ(1, foo.x);
117645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  EXPECT_EQ(2, foo.y);
118645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  EXPECT_FALSE(foo.a);
119645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  EXPECT_TRUE(foo.b);
120645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  EXPECT_FALSE(foo.c);
121645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
122645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  EXPECT_EQ(20, foo.bar->alpha);
123645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  EXPECT_EQ(40, foo.bar->beta);
124645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  EXPECT_EQ(60, foo.bar->gamma);
125645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  EXPECT_EQ(Bar::Type::VERTICAL, foo.bar->type);
126645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
127645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  EXPECT_EQ(3u, foo.extra_bars->size());
128645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  for (size_t i = 0; i < foo.extra_bars->size(); i++) {
129645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    uint8_t base = static_cast<uint8_t>(i * 100);
130645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    Bar::Type type = i % 2 == 0 ? Bar::Type::VERTICAL : Bar::Type::HORIZONTAL;
131645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    EXPECT_EQ(base, (*foo.extra_bars)[i]->alpha) << i;
132645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    EXPECT_EQ(base + 20, (*foo.extra_bars)[i]->beta) << i;
133645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    EXPECT_EQ(base + 40, (*foo.extra_bars)[i]->gamma) << i;
134645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    EXPECT_EQ(type, (*foo.extra_bars)[i]->type) << i;
135645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  }
136645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
137645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  EXPECT_EQ(10u, foo.data->size());
138645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  for (size_t i = 0; i < foo.data->size(); ++i) {
139645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    EXPECT_EQ(static_cast<uint8_t>(foo.data->size() - i), (*foo.data)[i]) << i;
140645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  }
141645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
142645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  EXPECT_TRUE(foo.input_streams);
143645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  EXPECT_EQ(2u, foo.input_streams->size());
144645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
145645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  EXPECT_TRUE(foo.output_streams);
146645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  EXPECT_EQ(2u, foo.output_streams->size());
147645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
148645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  EXPECT_EQ(2u, foo.array_of_array_of_bools->size());
149645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  for (size_t i = 0; i < foo.array_of_array_of_bools->size(); ++i) {
150645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    EXPECT_EQ(2u, (*foo.array_of_array_of_bools)[i].size());
151645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    for (size_t j = 0; j < (*foo.array_of_array_of_bools)[i].size(); ++j) {
152645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez      EXPECT_EQ(bool(j), (*foo.array_of_array_of_bools)[i][j]);
153645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    }
154645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  }
155645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez}
156645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
157645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavezvoid PrintSpacer(int depth) {
158645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  for (int i = 0; i < depth; ++i)
159645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    std::cout << "   ";
160645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez}
161645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
162645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavezvoid Print(int depth, const char* name, bool value) {
163645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  PrintSpacer(depth);
164645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  std::cout << name << ": " << (value ? "true" : "false") << std::endl;
165645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez}
166645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
167645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavezvoid Print(int depth, const char* name, int32_t value) {
168645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  PrintSpacer(depth);
169645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  std::cout << name << ": " << value << std::endl;
170645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez}
171645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
172645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavezvoid Print(int depth, const char* name, uint8_t value) {
173645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  PrintSpacer(depth);
174645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  std::cout << name << ": " << uint32_t(value) << std::endl;
175645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez}
176645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
177645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chaveztemplate <typename H>
178645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavezvoid Print(int depth,
179645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez           const char* name,
180645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez           const mojo::ScopedHandleBase<H>& value) {
181645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  PrintSpacer(depth);
182645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  std::cout << name << ": 0x" << std::hex << value.get().value() << std::endl;
183645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez}
184645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
185645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavezvoid Print(int depth, const char* name, const std::string& str) {
186645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  PrintSpacer(depth);
187645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  std::cout << name << ": \"" << str << "\"" << std::endl;
188645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez}
189645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
190645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavezvoid Print(int depth, const char* name, const BarPtr& bar) {
191645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  PrintSpacer(depth);
192645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  std::cout << name << ":" << std::endl;
193645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  if (!bar.is_null()) {
194645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    ++depth;
195645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    Print(depth, "alpha", bar->alpha);
196645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    Print(depth, "beta", bar->beta);
197645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    Print(depth, "gamma", bar->gamma);
198645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    Print(depth, "packed", bar.To<int32_t>());
199645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    --depth;
200645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  }
201645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez}
202645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
203645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chaveztemplate <typename T>
204645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavezvoid Print(int depth, const char* name, const std::vector<T>& array) {
205645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  PrintSpacer(depth);
206645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  std::cout << name << ":" << std::endl;
207645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ++depth;
208645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  for (size_t i = 0; i < array.size(); ++i) {
209645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    std::stringstream buf;
210645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    buf << i;
211645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    Print(depth, buf.str().data(), array.at(i));
212645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  }
213645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  --depth;
214645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez}
215645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
216645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chaveztemplate <typename T>
217645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavezvoid Print(int depth,
218645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez           const char* name,
219645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez           const base::Optional<std::vector<T>>& array) {
220645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  if (array)
221645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    Print(depth, name, *array);
222645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  else
223645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    Print(depth, name, std::vector<T>());
224645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez}
225645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
226645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavezvoid Print(int depth, const char* name, const FooPtr& foo) {
227645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  PrintSpacer(depth);
228645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  std::cout << name << ":" << std::endl;
229645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  if (!foo.is_null()) {
230645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    ++depth;
231645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    Print(depth, "name", foo->name);
232645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    Print(depth, "x", foo->x);
233645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    Print(depth, "y", foo->y);
234645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    Print(depth, "a", foo->a);
235645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    Print(depth, "b", foo->b);
236645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    Print(depth, "c", foo->c);
237645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    Print(depth, "bar", foo->bar);
238645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    Print(depth, "extra_bars", foo->extra_bars);
239645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    Print(depth, "data", foo->data);
240645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    Print(depth, "source", foo->source);
241645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    Print(depth, "input_streams", foo->input_streams);
242645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    Print(depth, "output_streams", foo->output_streams);
243645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    Print(depth, "array_of_array_of_bools", foo->array_of_array_of_bools);
244645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    --depth;
245645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  }
246645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez}
247645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
248645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavezvoid DumpHex(const uint8_t* bytes, uint32_t num_bytes) {
249645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  for (uint32_t i = 0; i < num_bytes; ++i) {
250645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    std::cout << std::setw(2) << std::setfill('0') << std::hex
251645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez              << uint32_t(bytes[i]);
252645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
253645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    if (i % 16 == 15) {
254645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez      std::cout << std::endl;
255645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez      continue;
256645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    }
257645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
258645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    if (i % 2 == 1)
259645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez      std::cout << " ";
260645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    if (i % 8 == 7)
261645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez      std::cout << " ";
262645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  }
263645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez}
264645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
265645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavezclass ServiceImpl : public Service {
266645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez public:
267645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  void Frobinate(FooPtr foo,
268645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                 BazOptions baz,
269645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                 PortPtr port,
270645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                 const Service::FrobinateCallback& callback) override {
271645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    // Users code goes here to handle the incoming Frobinate message.
272645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
273645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    // We mainly check that we're given the expected arguments.
274645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    EXPECT_FALSE(foo.is_null());
275645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    if (!foo.is_null())
276645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez      CheckFoo(*foo);
277645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    EXPECT_EQ(BazOptions::EXTRA, baz);
278645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
279645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    if (g_dump_message_as_text) {
280645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez      // Also dump the Foo structure and all of its members.
281645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez      std::cout << "Frobinate:" << std::endl;
282645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez      int depth = 1;
283645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez      Print(depth, "foo", foo);
284645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez      Print(depth, "baz", static_cast<int32_t>(baz));
285645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez      Print(depth, "port", port.get());
286645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    }
287645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    callback.Run(5);
288645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  }
289645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
290645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  void GetPort(mojo::InterfaceRequest<Port> port_request) override {}
291645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez};
292645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
293645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavezclass ServiceProxyImpl : public ServiceProxy {
294645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez public:
295645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  explicit ServiceProxyImpl(mojo::MessageReceiverWithResponder* receiver)
296645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez      : ServiceProxy(receiver) {}
297645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez};
298645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
299645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavezclass SimpleMessageReceiver : public mojo::MessageReceiverWithResponder {
300645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez public:
301645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  bool Accept(mojo::Message* message) override {
302645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    // Imagine some IPC happened here.
303645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
304645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    if (g_dump_message_as_hex) {
305645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez      DumpHex(reinterpret_cast<const uint8_t*>(message->data()),
306645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez              message->data_num_bytes());
307645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    }
308645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
309645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    // In the receiving process, an implementation of ServiceStub is known to
310645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    // the system. It receives the incoming message.
311645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    ServiceImpl impl;
312645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
313645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    ServiceStub stub;
314645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    stub.set_sink(&impl);
315645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    return stub.Accept(message);
316645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  }
317645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
318645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  bool AcceptWithResponder(mojo::Message* message,
319645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                           mojo::MessageReceiver* responder) override {
320645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    return false;
321645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  }
322645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez};
323645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
324645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavezusing BindingsSampleTest = testing::Test;
325645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
326645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector ChavezTEST_F(BindingsSampleTest, Basic) {
327645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  SimpleMessageReceiver receiver;
328645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
329645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // User has a proxy to a Service somehow.
330645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  Service* service = new ServiceProxyImpl(&receiver);
331645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
332645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // User constructs a message to send.
333645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
334645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // Notice that it doesn't matter in what order the structs / arrays are
335645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // allocated. Here, the various members of Foo are allocated before Foo is
336645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // allocated.
337645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
338645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  FooPtr foo = MakeFoo();
339645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  CheckFoo(*foo);
340645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
341645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  PortPtr port;
342645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  service->Frobinate(std::move(foo), Service::BazOptions::EXTRA,
343645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                     std::move(port), Service::FrobinateCallback());
344645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
345645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  delete service;
346645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez}
347645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
348645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector ChavezTEST_F(BindingsSampleTest, DefaultValues) {
349645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  DefaultsTestPtr defaults(DefaultsTest::New());
350645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  EXPECT_EQ(-12, defaults->a0);
351645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  EXPECT_EQ(kTwelve, defaults->a1);
352645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  EXPECT_EQ(1234, defaults->a2);
353645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  EXPECT_EQ(34567U, defaults->a3);
354645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  EXPECT_EQ(123456, defaults->a4);
355645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  EXPECT_EQ(3456789012U, defaults->a5);
356645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  EXPECT_EQ(-111111111111LL, defaults->a6);
357645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  EXPECT_EQ(9999999999999999999ULL, defaults->a7);
358645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  EXPECT_EQ(0x12345, defaults->a8);
359645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  EXPECT_EQ(-0x12345, defaults->a9);
360645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  EXPECT_EQ(1234, defaults->a10);
361645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  EXPECT_TRUE(defaults->a11);
362645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  EXPECT_FALSE(defaults->a12);
363645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  EXPECT_FLOAT_EQ(123.25f, defaults->a13);
364645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  EXPECT_DOUBLE_EQ(1234567890.123, defaults->a14);
365645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  EXPECT_DOUBLE_EQ(1E10, defaults->a15);
366645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  EXPECT_DOUBLE_EQ(-1.2E+20, defaults->a16);
367645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  EXPECT_DOUBLE_EQ(1.23E-20, defaults->a17);
368645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  EXPECT_TRUE(defaults->a18.empty());
369645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  EXPECT_TRUE(defaults->a19.empty());
370645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  EXPECT_EQ(Bar::Type::BOTH, defaults->a20);
371645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  EXPECT_TRUE(defaults->a21.is_null());
372645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_FALSE(defaults->a22.is_null());
373645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  EXPECT_EQ(imported::Shape::RECTANGLE, defaults->a22->shape);
374645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  EXPECT_EQ(imported::Color::BLACK, defaults->a22->color);
375645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  EXPECT_EQ(0xFFFFFFFFFFFFFFFFULL, defaults->a23);
376645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  EXPECT_EQ(0x123456789, defaults->a24);
377645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  EXPECT_EQ(-0x123456789, defaults->a25);
378645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez}
379645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
380645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez}  // namespace
381645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez}  // namespace sample
382