Chromium Code Reviews| 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 "base/bind.h" | |
| 6 #include "base/callback.h" | |
| 5 #include "mojo/public/cpp/bindings/binding.h" | 7 #include "mojo/public/cpp/bindings/binding.h" |
| 6 #include "mojo/public/cpp/bindings/error_handler.h" | 8 #include "mojo/public/cpp/bindings/error_handler.h" |
| 7 #include "mojo/public/cpp/bindings/strong_binding.h" | 9 #include "mojo/public/cpp/bindings/strong_binding.h" |
| 8 #include "mojo/public/cpp/environment/environment.h" | 10 #include "mojo/public/cpp/environment/environment.h" |
| 9 #include "mojo/public/cpp/utility/run_loop.h" | 11 #include "mojo/public/cpp/utility/run_loop.h" |
| 10 #include "mojo/public/interfaces/bindings/tests/math_calculator.mojom.h" | 12 #include "mojo/public/interfaces/bindings/tests/math_calculator.mojom.h" |
| 11 #include "mojo/public/interfaces/bindings/tests/sample_service.mojom.h" | 13 #include "mojo/public/interfaces/bindings/tests/sample_service.mojom.h" |
| 12 #include "testing/gtest/include/gtest/gtest.h" | 14 #include "testing/gtest/include/gtest/gtest.h" |
| 13 | 15 |
| 14 namespace mojo { | 16 namespace mojo { |
| 15 namespace test { | 17 namespace test { |
| 16 namespace { | 18 namespace { |
| 17 | 19 |
| 18 class ErrorObserver : public ErrorHandler { | 20 class ErrorObserver : public ErrorHandler { |
| 19 public: | 21 public: |
| 20 ErrorObserver() : encountered_error_(false) {} | 22 ErrorObserver() : encountered_error_(false) {} |
| 21 | 23 |
| 22 bool encountered_error() const { return encountered_error_; } | 24 bool encountered_error() const { return encountered_error_; } |
| 23 | 25 |
| 24 void OnConnectionError() override { encountered_error_ = true; } | 26 void OnConnectionError() override { encountered_error_ = true; } |
| 25 | 27 |
| 26 private: | 28 private: |
| 27 bool encountered_error_; | 29 bool encountered_error_; |
| 28 }; | 30 }; |
| 29 | 31 |
| 32 typedef mojo::Callback<void(double)> CalcCallback; | |
| 33 | |
| 30 class MathCalculatorImpl : public InterfaceImpl<math::Calculator> { | 34 class MathCalculatorImpl : public InterfaceImpl<math::Calculator> { |
|
jamesr
2015/01/22 00:30:04
if you're rewriting these anyway might as well swi
Aaron Boodman
2015/01/22 22:27:29
It seems to work fine as InterfaceImpl. I'd rather
| |
| 31 public: | 35 public: |
| 32 ~MathCalculatorImpl() override {} | 36 ~MathCalculatorImpl() override {} |
| 33 | 37 |
| 34 MathCalculatorImpl() : total_(0.0) {} | 38 MathCalculatorImpl() : total_(0.0) {} |
| 35 | 39 |
| 36 void Clear() override { client()->Output(total_); } | 40 void Clear(const CalcCallback& callback) override { |
| 37 | 41 // TODO(aa): Shouldn't it actually reset total_? |
|
jamesr
2015/01/22 00:30:04
instead of a TODO can you just do it? do the tests
Aaron Boodman
2015/01/22 22:27:29
Done.
| |
| 38 void Add(double value) override { | 42 callback.Run(total_); |
| 39 total_ += value; | |
| 40 client()->Output(total_); | |
| 41 } | 43 } |
| 42 | 44 |
| 43 void Multiply(double value) override { | 45 void Add(double value, const CalcCallback& callback) override { |
| 46 total_ += value; | |
| 47 callback.Run(total_); | |
| 48 } | |
| 49 | |
| 50 void Multiply(double value, const CalcCallback& callback) override { | |
| 44 total_ *= value; | 51 total_ *= value; |
| 45 client()->Output(total_); | 52 callback.Run(total_); |
| 46 } | 53 } |
| 47 | 54 |
| 48 private: | 55 private: |
| 49 double total_; | 56 double total_; |
| 50 }; | 57 }; |
| 51 | 58 |
| 52 class MathCalculatorUIImpl : public math::CalculatorUI { | 59 class MathCalculatorUI { |
| 53 public: | 60 public: |
| 54 explicit MathCalculatorUIImpl(math::CalculatorPtr calculator) | 61 explicit MathCalculatorUI(math::CalculatorPtr calculator) |
| 55 : calculator_(calculator.Pass()), output_(0.0) { | 62 : calculator_(calculator.Pass()), |
| 56 calculator_.set_client(this); | 63 callback_( |
| 57 } | 64 base::Bind(&MathCalculatorUI::Output, base::Unretained(this))), |
|
jamesr
2015/01/22 00:30:04
since there's only one type of Output it should be
Aaron Boodman
2015/01/22 22:27:29
You keep using that word 'functor'. I don't think
| |
| 65 output_(0.0) {} | |
| 58 | 66 |
| 59 bool WaitForIncomingMethodCall() { | 67 bool WaitForIncomingMethodCall() { |
| 60 return calculator_.WaitForIncomingMethodCall(); | 68 return calculator_.WaitForIncomingMethodCall(); |
| 61 } | 69 } |
| 62 | 70 |
| 63 bool encountered_error() const { return calculator_.encountered_error(); } | 71 bool encountered_error() const { return calculator_.encountered_error(); } |
| 64 | 72 |
| 65 void Add(double value) { calculator_->Add(value); } | 73 void Add(double value) { calculator_->Add(value, callback_); } |
| 66 | 74 |
| 67 void Subtract(double value) { calculator_->Add(-value); } | 75 void Subtract(double value) { calculator_->Add(-value, callback_); } |
| 68 | 76 |
| 69 void Multiply(double value) { calculator_->Multiply(value); } | 77 void Multiply(double value) { calculator_->Multiply(value, callback_); } |
| 70 | 78 |
| 71 void Divide(double value) { calculator_->Multiply(1.0 / value); } | 79 void Divide(double value) { calculator_->Multiply(1.0 / value, callback_); } |
| 72 | 80 |
| 73 double GetOutput() const { return output_; } | 81 double GetOutput() const { return output_; } |
| 74 | 82 |
| 75 private: | 83 private: |
| 76 // math::CalculatorUI implementation: | 84 void Output(double value) { output_ = value; } |
| 77 void Output(double value) override { output_ = value; } | |
| 78 | 85 |
| 79 math::CalculatorPtr calculator_; | 86 math::CalculatorPtr calculator_; |
| 87 mojo::Callback<void(double)> callback_; | |
| 80 double output_; | 88 double output_; |
| 81 }; | 89 }; |
| 82 | 90 |
| 83 class SelfDestructingMathCalculatorUIImpl : public math::CalculatorUI { | 91 class SelfDestructingMathCalculatorUI { |
| 84 public: | 92 public: |
| 85 explicit SelfDestructingMathCalculatorUIImpl(math::CalculatorPtr calculator) | 93 explicit SelfDestructingMathCalculatorUI(math::CalculatorPtr calculator) |
| 86 : calculator_(calculator.Pass()), nesting_level_(0) { | 94 : calculator_(calculator.Pass()), |
| 95 callback_(base::Bind(&SelfDestructingMathCalculatorUI::Output, | |
| 96 base::Unretained(this))), | |
| 97 nesting_level_(0) { | |
| 87 ++num_instances_; | 98 ++num_instances_; |
| 88 calculator_.set_client(this); | |
| 89 } | 99 } |
| 90 | 100 |
| 91 void BeginTest(bool nested) { | 101 void BeginTest(bool nested) { |
| 92 nesting_level_ = nested ? 2 : 1; | 102 nesting_level_ = nested ? 2 : 1; |
| 93 calculator_->Add(1.0); | 103 calculator_->Add(1.0, callback_); |
| 94 } | 104 } |
| 95 | 105 |
| 96 static int num_instances() { return num_instances_; } | 106 static int num_instances() { return num_instances_; } |
| 97 | 107 |
| 98 private: | 108 private: |
| 99 ~SelfDestructingMathCalculatorUIImpl() override { --num_instances_; } | 109 ~SelfDestructingMathCalculatorUI() { --num_instances_; } |
| 100 | 110 |
| 101 void Output(double value) override { | 111 void Output(double value) { |
| 102 if (--nesting_level_ > 0) { | 112 if (--nesting_level_ > 0) { |
| 103 // Add some more and wait for re-entrant call to Output! | 113 // Add some more and wait for re-entrant call to Output! |
| 104 calculator_->Add(1.0); | 114 calculator_->Add(1.0, callback_); |
| 105 RunLoop::current()->RunUntilIdle(); | 115 RunLoop::current()->RunUntilIdle(); |
| 106 } else { | 116 } else { |
| 107 delete this; | 117 delete this; |
| 108 } | 118 } |
| 109 } | 119 } |
| 110 | 120 |
| 111 math::CalculatorPtr calculator_; | 121 math::CalculatorPtr calculator_; |
| 122 mojo::Callback<void(double)> callback_; | |
| 112 int nesting_level_; | 123 int nesting_level_; |
| 113 static int num_instances_; | 124 static int num_instances_; |
| 114 }; | 125 }; |
| 115 | 126 |
| 116 // static | 127 // static |
| 117 int SelfDestructingMathCalculatorUIImpl::num_instances_ = 0; | 128 int SelfDestructingMathCalculatorUI::num_instances_ = 0; |
| 118 | 129 |
| 119 class ReentrantServiceImpl : public InterfaceImpl<sample::Service> { | 130 class ReentrantServiceImpl : public InterfaceImpl<sample::Service> { |
| 120 public: | 131 public: |
| 121 ~ReentrantServiceImpl() override {} | 132 ~ReentrantServiceImpl() override {} |
| 122 | 133 |
| 123 ReentrantServiceImpl() : call_depth_(0), max_call_depth_(0) {} | 134 ReentrantServiceImpl() : call_depth_(0), max_call_depth_(0) {} |
| 124 | 135 |
| 125 int max_call_depth() { return max_call_depth_; } | 136 int max_call_depth() { return max_call_depth_; } |
| 126 | 137 |
| 127 void Frobinate(sample::FooPtr foo, | 138 void Frobinate(sample::FooPtr foo, |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 150 private: | 161 private: |
| 151 Environment env_; | 162 Environment env_; |
| 152 RunLoop loop_; | 163 RunLoop loop_; |
| 153 }; | 164 }; |
| 154 | 165 |
| 155 TEST_F(InterfacePtrTest, EndToEnd) { | 166 TEST_F(InterfacePtrTest, EndToEnd) { |
| 156 math::CalculatorPtr calc; | 167 math::CalculatorPtr calc; |
| 157 BindToProxy(new MathCalculatorImpl(), &calc); | 168 BindToProxy(new MathCalculatorImpl(), &calc); |
| 158 | 169 |
| 159 // Suppose this is instantiated in a process that has pipe1_. | 170 // Suppose this is instantiated in a process that has pipe1_. |
| 160 MathCalculatorUIImpl calculator_ui(calc.Pass()); | 171 MathCalculatorUI calculator_ui(calc.Pass()); |
| 161 | 172 |
| 162 calculator_ui.Add(2.0); | 173 calculator_ui.Add(2.0); |
| 163 calculator_ui.Multiply(5.0); | 174 calculator_ui.Multiply(5.0); |
| 164 | 175 |
| 165 PumpMessages(); | 176 PumpMessages(); |
| 166 | 177 |
| 167 EXPECT_EQ(10.0, calculator_ui.GetOutput()); | 178 EXPECT_EQ(10.0, calculator_ui.GetOutput()); |
| 168 } | 179 } |
| 169 | 180 |
| 170 TEST_F(InterfacePtrTest, EndToEnd_Synchronous) { | 181 TEST_F(InterfacePtrTest, EndToEnd_Synchronous) { |
| 171 math::CalculatorPtr calc; | 182 math::CalculatorPtr calc; |
| 172 MathCalculatorImpl* impl = BindToProxy(new MathCalculatorImpl(), &calc); | 183 MathCalculatorImpl* impl = BindToProxy(new MathCalculatorImpl(), &calc); |
| 173 | 184 |
| 174 // Suppose this is instantiated in a process that has pipe1_. | 185 // Suppose this is instantiated in a process that has pipe1_. |
| 175 MathCalculatorUIImpl calculator_ui(calc.Pass()); | 186 MathCalculatorUI calculator_ui(calc.Pass()); |
| 176 | 187 |
| 177 EXPECT_EQ(0.0, calculator_ui.GetOutput()); | 188 EXPECT_EQ(0.0, calculator_ui.GetOutput()); |
| 178 | 189 |
| 179 calculator_ui.Add(2.0); | 190 calculator_ui.Add(2.0); |
| 180 EXPECT_EQ(0.0, calculator_ui.GetOutput()); | 191 EXPECT_EQ(0.0, calculator_ui.GetOutput()); |
| 181 impl->WaitForIncomingMethodCall(); | 192 impl->WaitForIncomingMethodCall(); |
| 182 calculator_ui.WaitForIncomingMethodCall(); | 193 calculator_ui.WaitForIncomingMethodCall(); |
| 183 EXPECT_EQ(2.0, calculator_ui.GetOutput()); | 194 EXPECT_EQ(2.0, calculator_ui.GetOutput()); |
| 184 | 195 |
| 185 calculator_ui.Multiply(5.0); | 196 calculator_ui.Multiply(5.0); |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 223 EXPECT_FALSE(a.internal_state()->router_for_testing()); | 234 EXPECT_FALSE(a.internal_state()->router_for_testing()); |
| 224 | 235 |
| 225 // Test that handle was closed. | 236 // Test that handle was closed. |
| 226 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, CloseRaw(handle)); | 237 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, CloseRaw(handle)); |
| 227 } | 238 } |
| 228 | 239 |
| 229 TEST_F(InterfacePtrTest, EncounteredError) { | 240 TEST_F(InterfacePtrTest, EncounteredError) { |
| 230 math::CalculatorPtr proxy; | 241 math::CalculatorPtr proxy; |
| 231 MathCalculatorImpl* server = BindToProxy(new MathCalculatorImpl(), &proxy); | 242 MathCalculatorImpl* server = BindToProxy(new MathCalculatorImpl(), &proxy); |
| 232 | 243 |
| 233 MathCalculatorUIImpl calculator_ui(proxy.Pass()); | 244 MathCalculatorUI calculator_ui(proxy.Pass()); |
| 234 | 245 |
| 235 calculator_ui.Add(2.0); | 246 calculator_ui.Add(2.0); |
| 236 PumpMessages(); | 247 PumpMessages(); |
| 237 EXPECT_EQ(2.0, calculator_ui.GetOutput()); | 248 EXPECT_EQ(2.0, calculator_ui.GetOutput()); |
| 238 EXPECT_FALSE(calculator_ui.encountered_error()); | 249 EXPECT_FALSE(calculator_ui.encountered_error()); |
| 239 | 250 |
| 240 calculator_ui.Multiply(5.0); | 251 calculator_ui.Multiply(5.0); |
| 241 EXPECT_FALSE(calculator_ui.encountered_error()); | 252 EXPECT_FALSE(calculator_ui.encountered_error()); |
| 242 | 253 |
| 243 // Close the server. | 254 // Close the server. |
| 244 server->internal_router()->CloseMessagePipe(); | 255 server->internal_router()->CloseMessagePipe(); |
| 245 | 256 |
| 246 // The state change isn't picked up locally yet. | 257 // The state change isn't picked up locally yet. |
| 247 EXPECT_FALSE(calculator_ui.encountered_error()); | 258 EXPECT_FALSE(calculator_ui.encountered_error()); |
| 248 | 259 |
| 249 PumpMessages(); | 260 PumpMessages(); |
| 250 | 261 |
| 251 // OK, now we see the error. | 262 // OK, now we see the error. |
| 252 EXPECT_TRUE(calculator_ui.encountered_error()); | 263 EXPECT_TRUE(calculator_ui.encountered_error()); |
| 253 } | 264 } |
| 254 | 265 |
| 255 TEST_F(InterfacePtrTest, EncounteredErrorCallback) { | 266 TEST_F(InterfacePtrTest, EncounteredErrorCallback) { |
| 256 math::CalculatorPtr proxy; | 267 math::CalculatorPtr proxy; |
| 257 MathCalculatorImpl* server = BindToProxy(new MathCalculatorImpl(), &proxy); | 268 MathCalculatorImpl* server = BindToProxy(new MathCalculatorImpl(), &proxy); |
| 258 | 269 |
| 259 ErrorObserver error_observer; | 270 ErrorObserver error_observer; |
| 260 proxy.set_error_handler(&error_observer); | 271 proxy.set_error_handler(&error_observer); |
| 261 | 272 |
| 262 MathCalculatorUIImpl calculator_ui(proxy.Pass()); | 273 MathCalculatorUI calculator_ui(proxy.Pass()); |
| 263 | 274 |
| 264 calculator_ui.Add(2.0); | 275 calculator_ui.Add(2.0); |
| 265 PumpMessages(); | 276 PumpMessages(); |
| 266 EXPECT_EQ(2.0, calculator_ui.GetOutput()); | 277 EXPECT_EQ(2.0, calculator_ui.GetOutput()); |
| 267 EXPECT_FALSE(calculator_ui.encountered_error()); | 278 EXPECT_FALSE(calculator_ui.encountered_error()); |
| 268 | 279 |
| 269 calculator_ui.Multiply(5.0); | 280 calculator_ui.Multiply(5.0); |
| 270 EXPECT_FALSE(calculator_ui.encountered_error()); | 281 EXPECT_FALSE(calculator_ui.encountered_error()); |
| 271 | 282 |
| 272 // Close the server. | 283 // Close the server. |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 290 // does not have an explicit Client attribute. | 301 // does not have an explicit Client attribute. |
| 291 sample::PortPtr port; | 302 sample::PortPtr port; |
| 292 MessagePipe pipe; | 303 MessagePipe pipe; |
| 293 port.Bind(pipe.handle0.Pass()); | 304 port.Bind(pipe.handle0.Pass()); |
| 294 } | 305 } |
| 295 | 306 |
| 296 TEST_F(InterfacePtrTest, DestroyInterfacePtrOnClientMethod) { | 307 TEST_F(InterfacePtrTest, DestroyInterfacePtrOnClientMethod) { |
| 297 math::CalculatorPtr proxy; | 308 math::CalculatorPtr proxy; |
| 298 BindToProxy(new MathCalculatorImpl(), &proxy); | 309 BindToProxy(new MathCalculatorImpl(), &proxy); |
| 299 | 310 |
| 300 EXPECT_EQ(0, SelfDestructingMathCalculatorUIImpl::num_instances()); | 311 EXPECT_EQ(0, SelfDestructingMathCalculatorUI::num_instances()); |
| 301 | 312 |
| 302 SelfDestructingMathCalculatorUIImpl* impl = | 313 SelfDestructingMathCalculatorUI* impl = |
| 303 new SelfDestructingMathCalculatorUIImpl(proxy.Pass()); | 314 new SelfDestructingMathCalculatorUI(proxy.Pass()); |
| 304 impl->BeginTest(false); | 315 impl->BeginTest(false); |
| 305 | 316 |
| 306 PumpMessages(); | 317 PumpMessages(); |
| 307 | 318 |
| 308 EXPECT_EQ(0, SelfDestructingMathCalculatorUIImpl::num_instances()); | 319 EXPECT_EQ(0, SelfDestructingMathCalculatorUI::num_instances()); |
| 309 } | 320 } |
| 310 | 321 |
| 311 TEST_F(InterfacePtrTest, NestedDestroyInterfacePtrOnClientMethod) { | 322 TEST_F(InterfacePtrTest, NestedDestroyInterfacePtrOnClientMethod) { |
| 312 math::CalculatorPtr proxy; | 323 math::CalculatorPtr proxy; |
| 313 BindToProxy(new MathCalculatorImpl(), &proxy); | 324 BindToProxy(new MathCalculatorImpl(), &proxy); |
| 314 | 325 |
| 315 EXPECT_EQ(0, SelfDestructingMathCalculatorUIImpl::num_instances()); | 326 EXPECT_EQ(0, SelfDestructingMathCalculatorUI::num_instances()); |
| 316 | 327 |
| 317 SelfDestructingMathCalculatorUIImpl* impl = | 328 SelfDestructingMathCalculatorUI* impl = |
| 318 new SelfDestructingMathCalculatorUIImpl(proxy.Pass()); | 329 new SelfDestructingMathCalculatorUI(proxy.Pass()); |
| 319 impl->BeginTest(true); | 330 impl->BeginTest(true); |
| 320 | 331 |
| 321 PumpMessages(); | 332 PumpMessages(); |
| 322 | 333 |
| 323 EXPECT_EQ(0, SelfDestructingMathCalculatorUIImpl::num_instances()); | 334 EXPECT_EQ(0, SelfDestructingMathCalculatorUI::num_instances()); |
| 324 } | 335 } |
| 325 | 336 |
| 326 TEST_F(InterfacePtrTest, ReentrantWaitForIncomingMethodCall) { | 337 TEST_F(InterfacePtrTest, ReentrantWaitForIncomingMethodCall) { |
| 327 sample::ServicePtr proxy; | 338 sample::ServicePtr proxy; |
| 328 ReentrantServiceImpl* impl = BindToProxy(new ReentrantServiceImpl(), &proxy); | 339 ReentrantServiceImpl* impl = BindToProxy(new ReentrantServiceImpl(), &proxy); |
| 329 | 340 |
| 330 proxy->Frobinate(nullptr, sample::Service::BAZ_OPTIONS_REGULAR, nullptr); | 341 proxy->Frobinate(nullptr, sample::Service::BAZ_OPTIONS_REGULAR, nullptr); |
| 331 proxy->Frobinate(nullptr, sample::Service::BAZ_OPTIONS_REGULAR, nullptr); | 342 proxy->Frobinate(nullptr, sample::Service::BAZ_OPTIONS_REGULAR, nullptr); |
| 332 | 343 |
| 333 PumpMessages(); | 344 PumpMessages(); |
| 334 | 345 |
| 335 EXPECT_EQ(2, impl->max_call_depth()); | 346 EXPECT_EQ(2, impl->max_call_depth()); |
| 336 } | 347 } |
| 337 | 348 |
| 338 class StrongMathCalculatorImpl : public math::Calculator, public ErrorHandler { | 349 class StrongMathCalculatorImpl : public math::Calculator, public ErrorHandler { |
| 339 public: | 350 public: |
| 351 typedef mojo::Callback<void(double)> Callback; | |
|
jamesr
2015/01/22 00:30:04
I think we already have this typedef
Aaron Boodman
2015/01/22 22:27:29
Done.
| |
| 352 | |
| 340 StrongMathCalculatorImpl(ScopedMessagePipeHandle handle, | 353 StrongMathCalculatorImpl(ScopedMessagePipeHandle handle, |
| 341 bool* error_received, | 354 bool* error_received, |
| 342 bool* destroyed) | 355 bool* destroyed) |
| 343 : error_received_(error_received), | 356 : error_received_(error_received), |
| 344 destroyed_(destroyed), | 357 destroyed_(destroyed), |
| 345 binding_(this, handle.Pass()) { | 358 binding_(this, handle.Pass()) { |
| 346 binding_.set_error_handler(this); | 359 binding_.set_error_handler(this); |
| 347 } | 360 } |
| 348 ~StrongMathCalculatorImpl() override { *destroyed_ = true; } | 361 ~StrongMathCalculatorImpl() override { *destroyed_ = true; } |
| 349 | 362 |
| 350 // math::Calculator implementation. | 363 // math::Calculator implementation. |
| 351 void Clear() override { binding_.client()->Output(total_); } | 364 void Clear(const CalcCallback& callback) override { callback.Run(total_); } |
| 352 | 365 |
| 353 void Add(double value) override { | 366 void Add(double value, const CalcCallback& callback) override { |
| 354 total_ += value; | 367 total_ += value; |
| 355 binding_.client()->Output(total_); | 368 callback.Run(total_); |
| 356 } | 369 } |
| 357 | 370 |
| 358 void Multiply(double value) override { | 371 void Multiply(double value, const CalcCallback& callback) override { |
| 359 total_ *= value; | 372 total_ *= value; |
| 360 binding_.client()->Output(total_); | 373 callback.Run(total_); |
| 361 } | 374 } |
| 362 | 375 |
| 363 // ErrorHandler implementation. | 376 // ErrorHandler implementation. |
| 364 void OnConnectionError() override { *error_received_ = true; } | 377 void OnConnectionError() override { *error_received_ = true; } |
| 365 | 378 |
| 366 private: | 379 private: |
| 367 double total_ = 0.0; | 380 double total_ = 0.0; |
| 368 bool* error_received_; | 381 bool* error_received_; |
| 369 bool* destroyed_; | 382 bool* destroyed_; |
| 370 | 383 |
| 371 StrongBinding<math::Calculator> binding_; | 384 StrongBinding<math::Calculator> binding_; |
| 372 }; | 385 }; |
| 373 | 386 |
| 374 TEST(StrongConnectorTest, Math) { | 387 TEST(StrongConnectorTest, Math) { |
| 375 Environment env; | 388 Environment env; |
| 376 RunLoop loop; | 389 RunLoop loop; |
| 377 | 390 |
| 378 bool error_received = false; | 391 bool error_received = false; |
| 379 bool destroyed = false; | 392 bool destroyed = false; |
| 380 MessagePipe pipe; | 393 MessagePipe pipe; |
| 381 new StrongMathCalculatorImpl(pipe.handle0.Pass(), &error_received, | 394 new StrongMathCalculatorImpl(pipe.handle0.Pass(), &error_received, |
| 382 &destroyed); | 395 &destroyed); |
| 383 | 396 |
| 384 math::CalculatorPtr calc; | 397 math::CalculatorPtr calc; |
| 385 calc.Bind(pipe.handle1.Pass()); | 398 calc.Bind(pipe.handle1.Pass()); |
| 386 | 399 |
| 387 { | 400 { |
| 388 // Suppose this is instantiated in a process that has the other end of the | 401 // Suppose this is instantiated in a process that has the other end of the |
| 389 // message pipe. | 402 // message pipe. |
| 390 MathCalculatorUIImpl calculator_ui(calc.Pass()); | 403 MathCalculatorUI calculator_ui(calc.Pass()); |
| 391 | 404 |
| 392 calculator_ui.Add(2.0); | 405 calculator_ui.Add(2.0); |
| 393 calculator_ui.Multiply(5.0); | 406 calculator_ui.Multiply(5.0); |
| 394 | 407 |
| 395 loop.RunUntilIdle(); | 408 loop.RunUntilIdle(); |
| 396 | 409 |
| 397 EXPECT_EQ(10.0, calculator_ui.GetOutput()); | 410 EXPECT_EQ(10.0, calculator_ui.GetOutput()); |
| 398 EXPECT_FALSE(error_received); | 411 EXPECT_FALSE(error_received); |
| 399 EXPECT_FALSE(destroyed); | 412 EXPECT_FALSE(destroyed); |
| 400 } | 413 } |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 412 WeakMathCalculatorImpl(ScopedMessagePipeHandle handle, | 425 WeakMathCalculatorImpl(ScopedMessagePipeHandle handle, |
| 413 bool* error_received, | 426 bool* error_received, |
| 414 bool* destroyed) | 427 bool* destroyed) |
| 415 : error_received_(error_received), | 428 : error_received_(error_received), |
| 416 destroyed_(destroyed), | 429 destroyed_(destroyed), |
| 417 binding_(this, handle.Pass()) { | 430 binding_(this, handle.Pass()) { |
| 418 binding_.set_error_handler(this); | 431 binding_.set_error_handler(this); |
| 419 } | 432 } |
| 420 ~WeakMathCalculatorImpl() override { *destroyed_ = true; } | 433 ~WeakMathCalculatorImpl() override { *destroyed_ = true; } |
| 421 | 434 |
| 422 void Clear() override { binding_.client()->Output(total_); } | 435 void Clear(const CalcCallback& callback) override { callback.Run(total_); } |
| 423 | 436 |
| 424 void Add(double value) override { | 437 void Add(double value, const CalcCallback& callback) override { |
| 425 total_ += value; | 438 total_ += value; |
| 426 binding_.client()->Output(total_); | 439 callback.Run(total_); |
| 427 } | 440 } |
| 428 | 441 |
| 429 void Multiply(double value) override { | 442 void Multiply(double value, const CalcCallback& callback) override { |
| 430 total_ *= value; | 443 total_ *= value; |
| 431 binding_.client()->Output(total_); | 444 callback.Run(total_); |
| 432 } | 445 } |
| 433 | 446 |
| 434 // ErrorHandler implementation. | 447 // ErrorHandler implementation. |
| 435 void OnConnectionError() override { *error_received_ = true; } | 448 void OnConnectionError() override { *error_received_ = true; } |
| 436 | 449 |
| 437 private: | 450 private: |
| 438 double total_ = 0.0; | 451 double total_ = 0.0; |
| 439 bool* error_received_; | 452 bool* error_received_; |
| 440 bool* destroyed_; | 453 bool* destroyed_; |
| 441 | 454 |
| 442 Binding<math::Calculator> binding_; | 455 Binding<math::Calculator> binding_; |
| 443 }; | 456 }; |
| 444 | 457 |
| 445 TEST(WeakConnectorTest, Math) { | 458 TEST(WeakConnectorTest, Math) { |
| 446 Environment env; | 459 Environment env; |
| 447 RunLoop loop; | 460 RunLoop loop; |
| 448 | 461 |
| 449 bool error_received = false; | 462 bool error_received = false; |
| 450 bool destroyed = false; | 463 bool destroyed = false; |
| 451 MessagePipe pipe; | 464 MessagePipe pipe; |
| 452 WeakMathCalculatorImpl impl(pipe.handle0.Pass(), &error_received, &destroyed); | 465 WeakMathCalculatorImpl impl(pipe.handle0.Pass(), &error_received, &destroyed); |
| 453 | 466 |
| 454 math::CalculatorPtr calc; | 467 math::CalculatorPtr calc; |
| 455 calc.Bind(pipe.handle1.Pass()); | 468 calc.Bind(pipe.handle1.Pass()); |
| 456 | 469 |
| 457 { | 470 { |
| 458 // Suppose this is instantiated in a process that has the other end of the | 471 // Suppose this is instantiated in a process that has the other end of the |
| 459 // message pipe. | 472 // message pipe. |
| 460 MathCalculatorUIImpl calculator_ui(calc.Pass()); | 473 MathCalculatorUI calculator_ui(calc.Pass()); |
| 461 | 474 |
| 462 calculator_ui.Add(2.0); | 475 calculator_ui.Add(2.0); |
| 463 calculator_ui.Multiply(5.0); | 476 calculator_ui.Multiply(5.0); |
| 464 | 477 |
| 465 loop.RunUntilIdle(); | 478 loop.RunUntilIdle(); |
| 466 | 479 |
| 467 EXPECT_EQ(10.0, calculator_ui.GetOutput()); | 480 EXPECT_EQ(10.0, calculator_ui.GetOutput()); |
| 468 EXPECT_FALSE(error_received); | 481 EXPECT_FALSE(error_received); |
| 469 EXPECT_FALSE(destroyed); | 482 EXPECT_FALSE(destroyed); |
| 470 // Destroying calculator_ui should close the pipe and generate an error on | 483 // Destroying calculator_ui should close the pipe and generate an error on |
| 471 // the other | 484 // the other |
| 472 // end which will destroy the instance since it is strongly bound. | 485 // end which will destroy the instance since it is strongly bound. |
| 473 } | 486 } |
| 474 | 487 |
| 475 loop.RunUntilIdle(); | 488 loop.RunUntilIdle(); |
| 476 EXPECT_TRUE(error_received); | 489 EXPECT_TRUE(error_received); |
| 477 EXPECT_FALSE(destroyed); | 490 EXPECT_FALSE(destroyed); |
| 478 } | 491 } |
| 479 | 492 |
| 480 } // namespace | 493 } // namespace |
| 481 } // namespace test | 494 } // namespace test |
| 482 } // namespace mojo | 495 } // namespace mojo |
| OLD | NEW |