Home | History | Annotate | Download | only in tests
      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