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 3 // found in the LICENSE file. 4 5 #include "mojo/public/bindings/lib/remote_ptr.h" 6 #include "mojo/public/tests/simple_bindings_support.h" 7 #include "mojom/math_calculator.h" 8 #include "testing/gtest/include/gtest/gtest.h" 9 10 namespace mojo { 11 namespace test { 12 13 class MathCalculatorImpl : public math::CalculatorStub { 14 public: 15 virtual ~MathCalculatorImpl() {} 16 17 explicit MathCalculatorImpl(ScopedMessagePipeHandle pipe) 18 : ui_(pipe.Pass()), 19 total_(0.0) { 20 ui_.SetPeer(this); 21 } 22 23 virtual void Clear() MOJO_OVERRIDE { 24 ui_->Output(total_); 25 } 26 27 virtual void Add(double value) MOJO_OVERRIDE { 28 total_ += value; 29 ui_->Output(total_); 30 } 31 32 virtual void Multiply(double value) MOJO_OVERRIDE { 33 total_ *= value; 34 ui_->Output(total_); 35 } 36 37 private: 38 RemotePtr<math::CalculatorUI> ui_; 39 double total_; 40 }; 41 42 class MathCalculatorUIImpl : public math::CalculatorUIStub { 43 public: 44 explicit MathCalculatorUIImpl(ScopedMessagePipeHandle pipe) 45 : calculator_(pipe.Pass()), 46 output_(0.0) { 47 calculator_.SetPeer(this); 48 } 49 50 bool encountered_error() const { 51 return calculator_.encountered_error(); 52 } 53 54 void Add(double value) { 55 calculator_->Add(value); 56 } 57 58 void Subtract(double value) { 59 calculator_->Add(-value); 60 } 61 62 void Multiply(double value) { 63 calculator_->Multiply(value); 64 } 65 66 void Divide(double value) { 67 calculator_->Multiply(1.0 / value); 68 } 69 70 double GetOutput() const { 71 return output_; 72 } 73 74 private: 75 // math::CalculatorUI implementation: 76 virtual void Output(double value) MOJO_OVERRIDE { 77 output_ = value; 78 } 79 80 RemotePtr<math::Calculator> calculator_; 81 double output_; 82 }; 83 84 class BindingsRemotePtrTest : public testing::Test { 85 public: 86 BindingsRemotePtrTest() { 87 CreateMessagePipe(&pipe0_, &pipe1_); 88 } 89 90 virtual ~BindingsRemotePtrTest() { 91 } 92 93 void PumpMessages() { 94 bindings_support_.Process(); 95 } 96 97 protected: 98 ScopedMessagePipeHandle pipe0_; 99 ScopedMessagePipeHandle pipe1_; 100 101 private: 102 SimpleBindingsSupport bindings_support_; 103 }; 104 105 TEST_F(BindingsRemotePtrTest, EndToEnd) { 106 // Suppose this is instantiated in a process that has pipe0_. 107 MathCalculatorImpl calculator(pipe0_.Pass()); 108 109 // Suppose this is instantiated in a process that has pipe1_. 110 MathCalculatorUIImpl calculator_ui(pipe1_.Pass()); 111 112 calculator_ui.Add(2.0); 113 calculator_ui.Multiply(5.0); 114 115 PumpMessages(); 116 117 EXPECT_EQ(10.0, calculator_ui.GetOutput()); 118 } 119 120 TEST_F(BindingsRemotePtrTest, Movable) { 121 RemotePtr<math::Calculator> a; 122 RemotePtr<math::Calculator> b(pipe0_.Pass()); 123 124 EXPECT_TRUE(a.is_null()); 125 EXPECT_FALSE(b.is_null()); 126 127 a = b.Pass(); 128 129 EXPECT_FALSE(a.is_null()); 130 EXPECT_TRUE(b.is_null()); 131 } 132 133 TEST_F(BindingsRemotePtrTest, Resettable) { 134 RemotePtr<math::Calculator> a; 135 136 EXPECT_TRUE(a.is_null()); 137 138 MessagePipeHandle handle = pipe0_.get(); 139 140 a.reset(pipe0_.Pass()); 141 142 EXPECT_FALSE(a.is_null()); 143 144 a.reset(); 145 146 EXPECT_TRUE(a.is_null()); 147 148 // Test that handle was closed. 149 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, CloseRaw(handle)); 150 } 151 152 TEST_F(BindingsRemotePtrTest, EncounteredError) { 153 MathCalculatorImpl* calculator = new MathCalculatorImpl(pipe0_.Pass()); 154 155 MathCalculatorUIImpl calculator_ui(pipe1_.Pass()); 156 157 calculator_ui.Add(2.0); 158 PumpMessages(); 159 EXPECT_EQ(2.0, calculator_ui.GetOutput()); 160 EXPECT_FALSE(calculator_ui.encountered_error()); 161 162 calculator_ui.Multiply(5.0); 163 EXPECT_FALSE(calculator_ui.encountered_error()); 164 165 // Close the other side of the pipe. 166 delete calculator; 167 168 // The state change isn't picked up locally yet. 169 EXPECT_FALSE(calculator_ui.encountered_error()); 170 171 PumpMessages(); 172 173 // OK, now we see the error. 174 EXPECT_TRUE(calculator_ui.encountered_error()); 175 } 176 177 } // namespace test 178 } // namespace mojo 179