| OLD | NEW |
| (Empty) |
| 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/tests/math_calculator.mojom.h" | |
| 6 #include "mojo/public/bindings/tests/sample_service.mojom.h" | |
| 7 #include "mojo/public/cpp/bindings/error_handler.h" | |
| 8 #include "mojo/public/cpp/bindings/remote_ptr.h" | |
| 9 #include "mojo/public/cpp/environment/environment.h" | |
| 10 #include "mojo/public/cpp/utility/run_loop.h" | |
| 11 #include "testing/gtest/include/gtest/gtest.h" | |
| 12 | |
| 13 namespace mojo { | |
| 14 namespace test { | |
| 15 namespace { | |
| 16 | |
| 17 class ErrorObserver : public ErrorHandler { | |
| 18 public: | |
| 19 ErrorObserver() : encountered_error_(false) { | |
| 20 } | |
| 21 | |
| 22 bool encountered_error() const { return encountered_error_; } | |
| 23 | |
| 24 virtual void OnError() MOJO_OVERRIDE { | |
| 25 encountered_error_ = true; | |
| 26 } | |
| 27 | |
| 28 private: | |
| 29 bool encountered_error_; | |
| 30 }; | |
| 31 | |
| 32 class MathCalculatorImpl : public math::Calculator { | |
| 33 public: | |
| 34 virtual ~MathCalculatorImpl() {} | |
| 35 | |
| 36 explicit MathCalculatorImpl(math::ScopedCalculatorUIHandle ui_handle) | |
| 37 : ui_(ui_handle.Pass(), this), | |
| 38 total_(0.0) { | |
| 39 } | |
| 40 | |
| 41 virtual void Clear() MOJO_OVERRIDE { | |
| 42 ui_->Output(total_); | |
| 43 } | |
| 44 | |
| 45 virtual void Add(double value) MOJO_OVERRIDE { | |
| 46 total_ += value; | |
| 47 ui_->Output(total_); | |
| 48 } | |
| 49 | |
| 50 virtual void Multiply(double value) MOJO_OVERRIDE { | |
| 51 total_ *= value; | |
| 52 ui_->Output(total_); | |
| 53 } | |
| 54 | |
| 55 private: | |
| 56 RemotePtr<math::CalculatorUI> ui_; | |
| 57 double total_; | |
| 58 }; | |
| 59 | |
| 60 class MathCalculatorUIImpl : public math::CalculatorUI { | |
| 61 public: | |
| 62 explicit MathCalculatorUIImpl(math::ScopedCalculatorHandle calculator_handle, | |
| 63 ErrorHandler* error_handler = NULL) | |
| 64 : calculator_(calculator_handle.Pass(), this, error_handler), | |
| 65 output_(0.0) { | |
| 66 } | |
| 67 | |
| 68 bool encountered_error() const { | |
| 69 return calculator_.encountered_error(); | |
| 70 } | |
| 71 | |
| 72 void Add(double value) { | |
| 73 calculator_->Add(value); | |
| 74 } | |
| 75 | |
| 76 void Subtract(double value) { | |
| 77 calculator_->Add(-value); | |
| 78 } | |
| 79 | |
| 80 void Multiply(double value) { | |
| 81 calculator_->Multiply(value); | |
| 82 } | |
| 83 | |
| 84 void Divide(double value) { | |
| 85 calculator_->Multiply(1.0 / value); | |
| 86 } | |
| 87 | |
| 88 double GetOutput() const { | |
| 89 return output_; | |
| 90 } | |
| 91 | |
| 92 private: | |
| 93 // math::CalculatorUI implementation: | |
| 94 virtual void Output(double value) MOJO_OVERRIDE { | |
| 95 output_ = value; | |
| 96 } | |
| 97 | |
| 98 RemotePtr<math::Calculator> calculator_; | |
| 99 double output_; | |
| 100 }; | |
| 101 | |
| 102 class RemotePtrTest : public testing::Test { | |
| 103 public: | |
| 104 void PumpMessages() { | |
| 105 loop_.RunUntilIdle(); | |
| 106 } | |
| 107 | |
| 108 protected: | |
| 109 InterfacePipe<math::CalculatorUI> pipe_; | |
| 110 | |
| 111 private: | |
| 112 Environment env_; | |
| 113 RunLoop loop_; | |
| 114 }; | |
| 115 | |
| 116 TEST_F(RemotePtrTest, EndToEnd) { | |
| 117 // Suppose this is instantiated in a process that has pipe0_. | |
| 118 MathCalculatorImpl calculator(pipe_.handle_to_self.Pass()); | |
| 119 | |
| 120 // Suppose this is instantiated in a process that has pipe1_. | |
| 121 MathCalculatorUIImpl calculator_ui(pipe_.handle_to_peer.Pass()); | |
| 122 | |
| 123 calculator_ui.Add(2.0); | |
| 124 calculator_ui.Multiply(5.0); | |
| 125 | |
| 126 PumpMessages(); | |
| 127 | |
| 128 EXPECT_EQ(10.0, calculator_ui.GetOutput()); | |
| 129 } | |
| 130 | |
| 131 TEST_F(RemotePtrTest, Movable) { | |
| 132 RemotePtr<math::Calculator> a; | |
| 133 RemotePtr<math::Calculator> b(pipe_.handle_to_peer.Pass(), NULL); | |
| 134 | |
| 135 EXPECT_TRUE(a.is_null()); | |
| 136 EXPECT_FALSE(b.is_null()); | |
| 137 | |
| 138 a = b.Pass(); | |
| 139 | |
| 140 EXPECT_FALSE(a.is_null()); | |
| 141 EXPECT_TRUE(b.is_null()); | |
| 142 } | |
| 143 | |
| 144 TEST_F(RemotePtrTest, Resettable) { | |
| 145 RemotePtr<math::Calculator> a; | |
| 146 | |
| 147 EXPECT_TRUE(a.is_null()); | |
| 148 | |
| 149 math::CalculatorHandle handle = pipe_.handle_to_peer.get(); | |
| 150 | |
| 151 a.reset(pipe_.handle_to_peer.Pass(), NULL); | |
| 152 | |
| 153 EXPECT_FALSE(a.is_null()); | |
| 154 | |
| 155 a.reset(); | |
| 156 | |
| 157 EXPECT_TRUE(a.is_null()); | |
| 158 | |
| 159 // Test that handle was closed. | |
| 160 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, CloseRaw(handle)); | |
| 161 } | |
| 162 | |
| 163 TEST_F(RemotePtrTest, EncounteredError) { | |
| 164 MathCalculatorImpl* calculator = | |
| 165 new MathCalculatorImpl(pipe_.handle_to_self.Pass()); | |
| 166 | |
| 167 MathCalculatorUIImpl calculator_ui(pipe_.handle_to_peer.Pass()); | |
| 168 | |
| 169 calculator_ui.Add(2.0); | |
| 170 PumpMessages(); | |
| 171 EXPECT_EQ(2.0, calculator_ui.GetOutput()); | |
| 172 EXPECT_FALSE(calculator_ui.encountered_error()); | |
| 173 | |
| 174 calculator_ui.Multiply(5.0); | |
| 175 EXPECT_FALSE(calculator_ui.encountered_error()); | |
| 176 | |
| 177 // Close the other side of the pipe. | |
| 178 delete calculator; | |
| 179 | |
| 180 // The state change isn't picked up locally yet. | |
| 181 EXPECT_FALSE(calculator_ui.encountered_error()); | |
| 182 | |
| 183 PumpMessages(); | |
| 184 | |
| 185 // OK, now we see the error. | |
| 186 EXPECT_TRUE(calculator_ui.encountered_error()); | |
| 187 } | |
| 188 | |
| 189 TEST_F(RemotePtrTest, EncounteredErrorCallback) { | |
| 190 MathCalculatorImpl* calculator = | |
| 191 new MathCalculatorImpl(pipe_.handle_to_self.Pass()); | |
| 192 | |
| 193 ErrorObserver error_observer; | |
| 194 MathCalculatorUIImpl calculator_ui(pipe_.handle_to_peer.Pass(), | |
| 195 &error_observer); | |
| 196 | |
| 197 calculator_ui.Add(2.0); | |
| 198 PumpMessages(); | |
| 199 EXPECT_EQ(2.0, calculator_ui.GetOutput()); | |
| 200 EXPECT_FALSE(calculator_ui.encountered_error()); | |
| 201 | |
| 202 calculator_ui.Multiply(5.0); | |
| 203 EXPECT_FALSE(calculator_ui.encountered_error()); | |
| 204 | |
| 205 // Close the other side of the pipe. | |
| 206 delete calculator; | |
| 207 | |
| 208 // The state change isn't picked up locally yet. | |
| 209 EXPECT_FALSE(calculator_ui.encountered_error()); | |
| 210 | |
| 211 PumpMessages(); | |
| 212 | |
| 213 // OK, now we see the error. | |
| 214 EXPECT_TRUE(calculator_ui.encountered_error()); | |
| 215 | |
| 216 // We should have also been able to observe the error through the | |
| 217 // ErrorHandler interface. | |
| 218 EXPECT_TRUE(error_observer.encountered_error()); | |
| 219 } | |
| 220 | |
| 221 TEST_F(RemotePtrTest, NoPeerAttribute) { | |
| 222 // This is a test to ensure the following compiles. The sample::Port interface | |
| 223 // does not have an explicit Peer attribute. | |
| 224 InterfacePipe<sample::Port, NoInterface> pipe; | |
| 225 RemotePtr<sample::Port> port(pipe.handle_to_self.Pass(), NULL); | |
| 226 } | |
| 227 | |
| 228 } // namespace | |
| 229 } // namespace test | |
| 230 } // namespace mojo | |
| OLD | NEW |