| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include <algorithm> | 5 #include <algorithm> |
| 6 #include <ostream> | 6 #include <ostream> |
| 7 #include <string> | 7 #include <string> |
| 8 | 8 |
| 9 #include "mojo/public/tests/simple_bindings_support.h" | 9 #include "mojo/public/tests/bindings/simple_bindings_support.h" |
| 10 #include "mojom/sample_service.h" | 10 #include "mojom/sample_service.h" |
| 11 #include "testing/gtest/include/gtest/gtest.h" | 11 #include "testing/gtest/include/gtest/gtest.h" |
| 12 | 12 |
| 13 namespace mojo { | 13 namespace mojo { |
| 14 | 14 |
| 15 template <> | 15 template <> |
| 16 class TypeConverter<sample::Bar, int32_t> { | 16 class TypeConverter<sample::Bar, int32_t> { |
| 17 public: | 17 public: |
| 18 static int32_t ConvertTo(const sample::Bar& bar) { | 18 static int32_t ConvertTo(const sample::Bar& bar) { |
| 19 return static_cast<int32_t>(bar.alpha()) << 16 | | 19 return static_cast<int32_t>(bar.alpha()) << 16 | |
| 20 static_cast<int32_t>(bar.beta()) << 8 | | 20 static_cast<int32_t>(bar.beta()) << 8 | |
| 21 static_cast<int32_t>(bar.gamma()); | 21 static_cast<int32_t>(bar.gamma()); |
| 22 } | 22 } |
| 23 }; | 23 }; |
| 24 | 24 |
| 25 } // namespace mojo | 25 } // namespace mojo |
| 26 | 26 |
| 27 namespace sample { | 27 namespace sample { |
| 28 namespace { |
| 28 | 29 |
| 29 // Set this variable to true to print the binary message in hex. | 30 // Set this variable to true to print the message in hex. |
| 30 bool g_dump_message_as_hex = true; | 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; |
| 31 | 35 |
| 32 // Make a sample |Foo|. | 36 // Make a sample |Foo|. |
| 33 Foo MakeFoo() { | 37 Foo MakeFoo() { |
| 34 mojo::String name("foopy"); | 38 mojo::String name("foopy"); |
| 35 | 39 |
| 36 Bar::Builder bar; | 40 Bar::Builder bar; |
| 37 bar.set_alpha(20); | 41 bar.set_alpha(20); |
| 38 bar.set_beta(40); | 42 bar.set_beta(40); |
| 39 bar.set_gamma(60); | 43 bar.set_gamma(60); |
| 40 bar.set_type(BAR_VERTICAL); | 44 bar.set_type(BAR_VERTICAL); |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 128 EXPECT_EQ(static_cast<uint8_t>(foo.data().size() - i), foo.data()[i]) << i; | 132 EXPECT_EQ(static_cast<uint8_t>(foo.data().size() - i), foo.data()[i]) << i; |
| 129 } | 133 } |
| 130 | 134 |
| 131 EXPECT_FALSE(foo.input_streams().is_null()); | 135 EXPECT_FALSE(foo.input_streams().is_null()); |
| 132 EXPECT_EQ(2u, foo.input_streams().size()); | 136 EXPECT_EQ(2u, foo.input_streams().size()); |
| 133 | 137 |
| 134 EXPECT_FALSE(foo.output_streams().is_null()); | 138 EXPECT_FALSE(foo.output_streams().is_null()); |
| 135 EXPECT_EQ(2u, foo.output_streams().size()); | 139 EXPECT_EQ(2u, foo.output_streams().size()); |
| 136 } | 140 } |
| 137 | 141 |
| 138 static void PrintSpacer(int depth) { | 142 void PrintSpacer(int depth) { |
| 139 for (int i = 0; i < depth; ++i) | 143 for (int i = 0; i < depth; ++i) |
| 140 std::cout << " "; | 144 std::cout << " "; |
| 141 } | 145 } |
| 142 | 146 |
| 143 static void Print(int depth, const char* name, bool value) { | 147 void Print(int depth, const char* name, bool value) { |
| 144 PrintSpacer(depth); | 148 PrintSpacer(depth); |
| 145 std::cout << name << ": " << (value ? "true" : "false") << std::endl; | 149 std::cout << name << ": " << (value ? "true" : "false") << std::endl; |
| 146 } | 150 } |
| 147 | 151 |
| 148 static void Print(int depth, const char* name, int32_t value) { | 152 void Print(int depth, const char* name, int32_t value) { |
| 149 PrintSpacer(depth); | 153 PrintSpacer(depth); |
| 150 std::cout << name << ": " << value << std::endl; | 154 std::cout << name << ": " << value << std::endl; |
| 151 } | 155 } |
| 152 | 156 |
| 153 static void Print(int depth, const char* name, uint8_t value) { | 157 void Print(int depth, const char* name, uint8_t value) { |
| 154 PrintSpacer(depth); | 158 PrintSpacer(depth); |
| 155 std::cout << name << ": " << uint32_t(value) << std::endl; | 159 std::cout << name << ": " << uint32_t(value) << std::endl; |
| 156 } | 160 } |
| 157 | 161 |
| 158 static void Print(int depth, const char* name, mojo::Handle value) { | 162 void Print(int depth, const char* name, mojo::Handle value) { |
| 159 PrintSpacer(depth); | 163 PrintSpacer(depth); |
| 160 std::cout << name << ": 0x" << std::hex << value.value() << std::endl; | 164 std::cout << name << ": 0x" << std::hex << value.value() << std::endl; |
| 161 } | 165 } |
| 162 | 166 |
| 163 static void Print(int depth, const char* name, const mojo::String& str) { | 167 void Print(int depth, const char* name, const mojo::String& str) { |
| 164 std::string s = str.To<std::string>(); | 168 std::string s = str.To<std::string>(); |
| 165 PrintSpacer(depth); | 169 PrintSpacer(depth); |
| 166 std::cout << name << ": \"" << str.To<std::string>() << "\"" << std::endl; | 170 std::cout << name << ": \"" << str.To<std::string>() << "\"" << std::endl; |
| 167 } | 171 } |
| 168 | 172 |
| 169 static void Print(int depth, const char* name, const Bar& bar) { | 173 void Print(int depth, const char* name, const Bar& bar) { |
| 170 PrintSpacer(depth); | 174 PrintSpacer(depth); |
| 171 std::cout << name << ":" << std::endl; | 175 std::cout << name << ":" << std::endl; |
| 172 if (!bar.is_null()) { | 176 if (!bar.is_null()) { |
| 173 ++depth; | 177 ++depth; |
| 174 Print(depth, "alpha", bar.alpha()); | 178 Print(depth, "alpha", bar.alpha()); |
| 175 Print(depth, "beta", bar.beta()); | 179 Print(depth, "beta", bar.beta()); |
| 176 Print(depth, "gamma", bar.gamma()); | 180 Print(depth, "gamma", bar.gamma()); |
| 177 Print(depth, "packed", bar.To<int32_t>()); | 181 Print(depth, "packed", bar.To<int32_t>()); |
| 178 --depth; | 182 --depth; |
| 179 } | 183 } |
| 180 } | 184 } |
| 181 | 185 |
| 182 template <typename T> | 186 template <typename T> |
| 183 static void Print(int depth, const char* name, | 187 void Print(int depth, const char* name, |
| 184 const mojo::Passable<T>& passable) { | 188 const mojo::Passable<T>& passable) { |
| 185 Print(depth, name, passable.get()); | 189 Print(depth, name, passable.get()); |
| 186 } | 190 } |
| 187 | 191 |
| 188 template <typename T> | 192 template <typename T> |
| 189 static void Print(int depth, const char* name, const mojo::Array<T>& array) { | 193 void Print(int depth, const char* name, const mojo::Array<T>& array) { |
| 190 PrintSpacer(depth); | 194 PrintSpacer(depth); |
| 191 std::cout << name << ":" << std::endl; | 195 std::cout << name << ":" << std::endl; |
| 192 if (!array.is_null()) { | 196 if (!array.is_null()) { |
| 193 ++depth; | 197 ++depth; |
| 194 for (size_t i = 0; i < array.size(); ++i) { | 198 for (size_t i = 0; i < array.size(); ++i) { |
| 195 std::stringstream buf; | 199 std::stringstream buf; |
| 196 buf << i; | 200 buf << i; |
| 197 Print(depth, buf.str().data(), array.at(i)); | 201 Print(depth, buf.str().data(), array.at(i)); |
| 198 } | 202 } |
| 199 --depth; | 203 --depth; |
| 200 } | 204 } |
| 201 } | 205 } |
| 202 | 206 |
| 203 static void Print(int depth, const char* name, const Foo& foo) { | 207 void Print(int depth, const char* name, const Foo& foo) { |
| 204 PrintSpacer(depth); | 208 PrintSpacer(depth); |
| 205 std::cout << name << ":" << std::endl; | 209 std::cout << name << ":" << std::endl; |
| 206 if (!foo.is_null()) { | 210 if (!foo.is_null()) { |
| 207 ++depth; | 211 ++depth; |
| 208 Print(depth, "name", foo.name()); | 212 Print(depth, "name", foo.name()); |
| 209 Print(depth, "x", foo.x()); | 213 Print(depth, "x", foo.x()); |
| 210 Print(depth, "y", foo.y()); | 214 Print(depth, "y", foo.y()); |
| 211 Print(depth, "a", foo.a()); | 215 Print(depth, "a", foo.a()); |
| 212 Print(depth, "b", foo.b()); | 216 Print(depth, "b", foo.b()); |
| 213 Print(depth, "c", foo.c()); | 217 Print(depth, "c", foo.c()); |
| 214 Print(depth, "bar", foo.bar()); | 218 Print(depth, "bar", foo.bar()); |
| 215 Print(depth, "extra_bars", foo.extra_bars()); | 219 Print(depth, "extra_bars", foo.extra_bars()); |
| 216 Print(depth, "data", foo.data()); | 220 Print(depth, "data", foo.data()); |
| 217 Print(depth, "source", foo.source().get()); | 221 Print(depth, "source", foo.source().get()); |
| 218 Print(depth, "input_streams", foo.input_streams()); | 222 Print(depth, "input_streams", foo.input_streams()); |
| 219 Print(depth, "output_streams", foo.output_streams()); | 223 Print(depth, "output_streams", foo.output_streams()); |
| 220 --depth; | 224 --depth; |
| 221 } | 225 } |
| 222 } | 226 } |
| 223 | 227 |
| 224 static void DumpHex(const uint8_t* bytes, uint32_t num_bytes) { | 228 void DumpHex(const uint8_t* bytes, uint32_t num_bytes) { |
| 225 for (uint32_t i = 0; i < num_bytes; ++i) { | 229 for (uint32_t i = 0; i < num_bytes; ++i) { |
| 226 std::cout << std::setw(2) << std::setfill('0') << std::hex << | 230 std::cout << std::setw(2) << std::setfill('0') << std::hex << |
| 227 uint32_t(bytes[i]); | 231 uint32_t(bytes[i]); |
| 228 | 232 |
| 229 if (i % 16 == 15) { | 233 if (i % 16 == 15) { |
| 230 std::cout << std::endl; | 234 std::cout << std::endl; |
| 231 continue; | 235 continue; |
| 232 } | 236 } |
| 233 | 237 |
| 234 if (i % 2 == 1) | 238 if (i % 2 == 1) |
| 235 std::cout << " "; | 239 std::cout << " "; |
| 236 if (i % 8 == 7) | 240 if (i % 8 == 7) |
| 237 std::cout << " "; | 241 std::cout << " "; |
| 238 } | 242 } |
| 239 } | 243 } |
| 240 | 244 |
| 241 class ServiceImpl : public Service { | 245 class ServiceImpl : public Service { |
| 242 public: | 246 public: |
| 243 virtual void Frobinate(const Foo& foo, int32_t baz, | 247 virtual void Frobinate(const Foo& foo, int32_t baz, |
| 244 mojo::ScopedMessagePipeHandle port) | 248 mojo::ScopedMessagePipeHandle port) |
| 245 MOJO_OVERRIDE { | 249 MOJO_OVERRIDE { |
| 246 // Users code goes here to handle the incoming Frobinate message. | 250 // Users code goes here to handle the incoming Frobinate message. |
| 247 | 251 |
| 248 // We mainly check that we're given the expected arguments. | 252 // We mainly check that we're given the expected arguments. |
| 249 CheckFoo(foo); | 253 CheckFoo(foo); |
| 250 EXPECT_EQ(BAZ_EXTRA, baz); | 254 EXPECT_EQ(BAZ_EXTRA, baz); |
| 251 | 255 |
| 252 // Also dump the Foo structure and all of its members. | 256 if (g_dump_message_as_text) { |
| 253 // TODO(vtl): Make it optional, so that the test spews less? | 257 // Also dump the Foo structure and all of its members. |
| 254 std::cout << "Frobinate:" << std::endl; | 258 std::cout << "Frobinate:" << std::endl; |
| 255 int depth = 1; | 259 int depth = 1; |
| 256 Print(depth, "foo", foo); | 260 Print(depth, "foo", foo); |
| 257 Print(depth, "baz", baz); | 261 Print(depth, "baz", baz); |
| 258 Print(depth, "port", port.get()); | 262 Print(depth, "port", port.get()); |
| 263 } |
| 259 } | 264 } |
| 260 }; | 265 }; |
| 261 | 266 |
| 262 class SimpleMessageReceiver : public mojo::MessageReceiver { | 267 class SimpleMessageReceiver : public mojo::MessageReceiver { |
| 263 public: | 268 public: |
| 264 virtual bool Accept(mojo::Message* message) MOJO_OVERRIDE { | 269 virtual bool Accept(mojo::Message* message) MOJO_OVERRIDE { |
| 265 // Imagine some IPC happened here. | 270 // Imagine some IPC happened here. |
| 266 | 271 |
| 267 if (g_dump_message_as_hex) { | 272 if (g_dump_message_as_hex) { |
| 268 DumpHex(reinterpret_cast<const uint8_t*>(message->data), | 273 DumpHex(reinterpret_cast<const uint8_t*>(message->data), |
| 269 message->data->header.num_bytes); | 274 message->data->header.num_bytes); |
| 270 } | 275 } |
| 271 | 276 |
| 272 // In the receiving process, an implementation of ServiceStub is known to | 277 // In the receiving process, an implementation of ServiceStub is known to |
| 273 // the system. It receives the incoming message. | 278 // the system. It receives the incoming message. |
| 274 ServiceImpl impl; | 279 ServiceImpl impl; |
| 275 | 280 |
| 276 ServiceStub stub(&impl); | 281 ServiceStub stub(&impl); |
| 277 return stub.Accept(message); | 282 return stub.Accept(message); |
| 278 } | 283 } |
| 279 }; | 284 }; |
| 280 | 285 |
| 286 } // namespace |
| 287 |
| 281 TEST(BindingsSampleTest, Basic) { | 288 TEST(BindingsSampleTest, Basic) { |
| 282 mojo::test::SimpleBindingsSupport bindings_support; | 289 mojo::test::SimpleBindingsSupport bindings_support; |
| 283 SimpleMessageReceiver receiver; | 290 SimpleMessageReceiver receiver; |
| 284 | 291 |
| 285 // User has a proxy to a Service somehow. | 292 // User has a proxy to a Service somehow. |
| 286 Service* service = new ServiceProxy(&receiver); | 293 Service* service = new ServiceProxy(&receiver); |
| 287 | 294 |
| 288 // User constructs a message to send. | 295 // User constructs a message to send. |
| 289 | 296 |
| 290 // Notice that it doesn't matter in what order the structs / arrays are | 297 // Notice that it doesn't matter in what order the structs / arrays are |
| 291 // allocated. Here, the various members of Foo are allocated before Foo is | 298 // allocated. Here, the various members of Foo are allocated before Foo is |
| 292 // allocated. | 299 // allocated. |
| 293 | 300 |
| 294 mojo::AllocationScope scope; | 301 mojo::AllocationScope scope; |
| 295 | 302 |
| 296 Foo foo = MakeFoo(); | 303 Foo foo = MakeFoo(); |
| 297 CheckFoo(foo); | 304 CheckFoo(foo); |
| 298 | 305 |
| 299 mojo::ScopedMessagePipeHandle port0, port1; | 306 mojo::ScopedMessagePipeHandle port0, port1; |
| 300 mojo::CreateMessagePipe(&port0, &port1); | 307 mojo::CreateMessagePipe(&port0, &port1); |
| 301 | 308 |
| 302 service->Frobinate(foo, Service::BAZ_EXTRA, port0.Pass()); | 309 service->Frobinate(foo, Service::BAZ_EXTRA, port0.Pass()); |
| 303 } | 310 } |
| 304 | 311 |
| 305 } // namespace sample | 312 } // namespace sample |
| OLD | NEW |