Home | History | Annotate | Download | only in src
      1 // Copyright (c) 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 "ui/v2/public/view.h"
      6 
      7 #include "base/logging.h"
      8 #include "testing/gtest/include/gtest/gtest.h"
      9 #include "ui/compositor/layer.h"
     10 #include "ui/compositor/layer_type.h"
     11 
     12 namespace v2 {
     13 
     14 // View ------------------------------------------------------------------------
     15 
     16 typedef testing::Test ViewTest;
     17 
     18 TEST_F(ViewTest, AddChild) {
     19   View v1;
     20   View* v11 = new View;
     21   v1.AddChild(v11);
     22   EXPECT_EQ(1U, v1.children().size());
     23 }
     24 
     25 TEST_F(ViewTest, RemoveChild) {
     26   View v1;
     27   View* v11 = new View;
     28   v1.AddChild(v11);
     29   EXPECT_EQ(1U, v1.children().size());
     30   v1.RemoveChild(v11);
     31   EXPECT_EQ(0U, v1.children().size());
     32 }
     33 
     34 TEST_F(ViewTest, Reparent) {
     35   View v1;
     36   View v2;
     37   View* v11 = new View;
     38   v1.AddChild(v11);
     39   EXPECT_EQ(1U, v1.children().size());
     40   v2.AddChild(v11);
     41   EXPECT_EQ(1U, v2.children().size());
     42   EXPECT_EQ(0U, v1.children().size());
     43 }
     44 
     45 TEST_F(ViewTest, Contains) {
     46   View v1;
     47 
     48   // Direct descendant.
     49   View* v11 = new View;
     50   v1.AddChild(v11);
     51   EXPECT_TRUE(v1.Contains(v11));
     52 
     53   // Indirect descendant.
     54   View* v111 = new View;
     55   v11->AddChild(v111);
     56   EXPECT_TRUE(v1.Contains(v111));
     57 }
     58 
     59 TEST_F(ViewTest, Stacking) {
     60   View v1;
     61   View* v11 = new View;
     62   View* v12 = new View;
     63   View* v13 = new View;
     64   v1.AddChild(v11);
     65   v1.AddChild(v12);
     66   v1.AddChild(v13);
     67 
     68   // Order: v11, v12, v13
     69   EXPECT_EQ(3U, v1.children().size());
     70   EXPECT_EQ(v11, v1.children().front());
     71   EXPECT_EQ(v13, v1.children().back());
     72 
     73   // Move v11 to front.
     74   // Resulting order: v12, v13, v11
     75   v1.StackChildAtTop(v11);
     76   EXPECT_EQ(v12, v1.children().front());
     77   EXPECT_EQ(v11, v1.children().back());
     78 
     79   // Move v11 to back.
     80   // Resulting order: v11, v12, v13
     81   v1.StackChildAtBottom(v11);
     82   EXPECT_EQ(v11, v1.children().front());
     83   EXPECT_EQ(v13, v1.children().back());
     84 
     85   // Move v11 above v12.
     86   // Resulting order: v12. v11, v13
     87   v1.StackChildAbove(v11, v12);
     88   EXPECT_EQ(v12, v1.children().front());
     89   EXPECT_EQ(v13, v1.children().back());
     90 
     91   // Move v11 below v12.
     92   // Resulting order: v11, v12, v13
     93   v1.StackChildBelow(v11, v12);
     94   EXPECT_EQ(v11, v1.children().front());
     95   EXPECT_EQ(v13, v1.children().back());
     96 }
     97 
     98 TEST_F(ViewTest, Layer) {
     99   View v1;
    100   v1.CreateLayer(ui::LAYER_NOT_DRAWN);
    101   EXPECT_TRUE(v1.HasLayer());
    102   v1.DestroyLayer();
    103   EXPECT_FALSE(v1.HasLayer());
    104 
    105   v1.CreateLayer(ui::LAYER_NOT_DRAWN);
    106   scoped_ptr<ui::Layer>(v1.AcquireLayer());
    107   // Acquiring the layer transfers ownership to the scoped_ptr above, so this
    108   // test passes if it doesn't crash.
    109 }
    110 
    111 // ViewObserver ----------------------------------------------------------------
    112 
    113 typedef testing::Test ViewObserverTest;
    114 
    115 bool TreeChangeParamsMatch(const ViewObserver::TreeChangeParams& lhs,
    116                            const ViewObserver::TreeChangeParams& rhs) {
    117   return lhs.target == rhs.target &&  lhs.old_parent == rhs.old_parent &&
    118       lhs.new_parent == rhs.new_parent && lhs.receiver == rhs.receiver &&
    119       lhs.phase == rhs.phase;
    120 }
    121 
    122 class TreeChangeObserver : public ViewObserver {
    123  public:
    124   explicit TreeChangeObserver(View* observee) : observee_(observee) {
    125     observee_->AddObserver(this);
    126   }
    127   virtual ~TreeChangeObserver() {
    128     observee_->RemoveObserver(this);
    129   }
    130 
    131   void Reset() {
    132       received_params_.clear();
    133   }
    134 
    135   const std::vector<TreeChangeParams>& received_params() {
    136     return received_params_;
    137   }
    138 
    139  private:
    140   // Overridden from ViewObserver:
    141   virtual void OnViewTreeChange(const TreeChangeParams& params) OVERRIDE {
    142     received_params_.push_back(params);
    143   }
    144 
    145   View* observee_;
    146   std::vector<TreeChangeParams> received_params_;
    147 
    148   DISALLOW_COPY_AND_ASSIGN(TreeChangeObserver);
    149 };
    150 
    151 // Adds/Removes v11 to v1.
    152 TEST_F(ViewObserverTest, TreeChange_SimpleAddRemove) {
    153   View v1;
    154   TreeChangeObserver o1(&v1);
    155   EXPECT_TRUE(o1.received_params().empty());
    156 
    157   View v11;
    158   v11.set_owned_by_parent(false);
    159   TreeChangeObserver o11(&v11);
    160   EXPECT_TRUE(o11.received_params().empty());
    161 
    162   // Add.
    163 
    164   v1.AddChild(&v11);
    165 
    166   EXPECT_EQ(1U, o1.received_params().size());
    167   ViewObserver::TreeChangeParams p1;
    168   p1.target = &v11;
    169   p1.receiver = &v1;
    170   p1.old_parent = NULL;
    171   p1.new_parent = &v1;
    172   p1.phase = ViewObserver::DISPOSITION_CHANGED;
    173   EXPECT_TRUE(TreeChangeParamsMatch(p1, o1.received_params().back()));
    174 
    175   EXPECT_EQ(2U, o11.received_params().size());
    176   ViewObserver::TreeChangeParams p11 = p1;
    177   p11.receiver = &v11;
    178   p11.phase = ViewObserver::DISPOSITION_CHANGING;
    179   EXPECT_TRUE(TreeChangeParamsMatch(p11, o11.received_params().front()));
    180   p11.phase = ViewObserver::DISPOSITION_CHANGED;
    181   EXPECT_TRUE(TreeChangeParamsMatch(p11, o11.received_params().back()));
    182 
    183   o1.Reset();
    184   o11.Reset();
    185   EXPECT_TRUE(o1.received_params().empty());
    186   EXPECT_TRUE(o11.received_params().empty());
    187 
    188   // Remove.
    189 
    190   v1.RemoveChild(&v11);
    191 
    192   EXPECT_EQ(1U, o1.received_params().size());
    193   p1.target = &v11;
    194   p1.receiver = &v1;
    195   p1.old_parent = &v1;
    196   p1.new_parent = NULL;
    197   p1.phase = ViewObserver::DISPOSITION_CHANGING;
    198   EXPECT_TRUE(TreeChangeParamsMatch(p1, o1.received_params().back()));
    199 
    200   EXPECT_EQ(2U, o11.received_params().size());
    201   p11 = p1;
    202   p11.receiver = &v11;
    203   EXPECT_TRUE(TreeChangeParamsMatch(p11, o11.received_params().front()));
    204   p11.phase = ViewObserver::DISPOSITION_CHANGED;
    205   EXPECT_TRUE(TreeChangeParamsMatch(p11, o11.received_params().back()));
    206 }
    207 
    208 // Creates these two trees:
    209 // v1
    210 //  +- v11
    211 // v111
    212 //  +- v1111
    213 //  +- v1112
    214 // Then adds/removes v111 from v11.
    215 TEST_F(ViewObserverTest, TreeChange_NestedAddRemove) {
    216   View v1, v11, v111, v1111, v1112;
    217 
    218   // Root tree.
    219   v11.set_owned_by_parent(false);
    220   v1.AddChild(&v11);
    221 
    222   // Tree to be attached.
    223   v111.set_owned_by_parent(false);
    224   v1111.set_owned_by_parent(false);
    225   v111.AddChild(&v1111);
    226   v1112.set_owned_by_parent(false);
    227   v111.AddChild(&v1112);
    228 
    229   TreeChangeObserver o1(&v1), o11(&v11), o111(&v111), o1111(&v1111),
    230       o1112(&v1112);
    231   ViewObserver::TreeChangeParams p1, p11, p111, p1111, p1112;
    232 
    233   // Add.
    234 
    235   v11.AddChild(&v111);
    236 
    237   EXPECT_EQ(1U, o1.received_params().size());
    238   p1.target = &v111;
    239   p1.receiver = &v1;
    240   p1.old_parent = NULL;
    241   p1.new_parent = &v11;
    242   p1.phase = ViewObserver::DISPOSITION_CHANGED;
    243   EXPECT_TRUE(TreeChangeParamsMatch(p1, o1.received_params().back()));
    244 
    245   EXPECT_EQ(1U, o11.received_params().size());
    246   p11 = p1;
    247   p11.receiver = &v11;
    248   EXPECT_TRUE(TreeChangeParamsMatch(p11, o11.received_params().back()));
    249 
    250   EXPECT_EQ(2U, o111.received_params().size());
    251   p111 = p11;
    252   p111.receiver = &v111;
    253   p111.phase = ViewObserver::DISPOSITION_CHANGING;
    254   EXPECT_TRUE(TreeChangeParamsMatch(p111, o111.received_params().front()));
    255   p111.phase = ViewObserver::DISPOSITION_CHANGED;
    256   EXPECT_TRUE(TreeChangeParamsMatch(p111, o111.received_params().back()));
    257 
    258   EXPECT_EQ(2U, o1111.received_params().size());
    259   p1111 = p111;
    260   p1111.receiver = &v1111;
    261   p1111.phase = ViewObserver::DISPOSITION_CHANGING;
    262   EXPECT_TRUE(TreeChangeParamsMatch(p1111, o1111.received_params().front()));
    263   p1111.phase = ViewObserver::DISPOSITION_CHANGED;
    264   EXPECT_TRUE(TreeChangeParamsMatch(p1111, o1111.received_params().back()));
    265 
    266   EXPECT_EQ(2U, o1112.received_params().size());
    267   p1112 = p111;
    268   p1112.receiver = &v1112;
    269   p1112.phase = ViewObserver::DISPOSITION_CHANGING;
    270   EXPECT_TRUE(TreeChangeParamsMatch(p1112, o1112.received_params().front()));
    271   p1112.phase = ViewObserver::DISPOSITION_CHANGED;
    272   EXPECT_TRUE(TreeChangeParamsMatch(p1112, o1112.received_params().back()));
    273 
    274   // Remove.
    275   o1.Reset();
    276   o11.Reset();
    277   o111.Reset();
    278   o1111.Reset();
    279   o1112.Reset();
    280   EXPECT_TRUE(o1.received_params().empty());
    281   EXPECT_TRUE(o11.received_params().empty());
    282   EXPECT_TRUE(o111.received_params().empty());
    283   EXPECT_TRUE(o1111.received_params().empty());
    284   EXPECT_TRUE(o1112.received_params().empty());
    285 
    286   v11.RemoveChild(&v111);
    287 
    288   EXPECT_EQ(1U, o1.received_params().size());
    289   p1.target = &v111;
    290   p1.receiver = &v1;
    291   p1.old_parent = &v11;
    292   p1.new_parent = NULL;
    293   p1.phase = ViewObserver::DISPOSITION_CHANGING;
    294   EXPECT_TRUE(TreeChangeParamsMatch(p1, o1.received_params().back()));
    295 
    296   EXPECT_EQ(1U, o11.received_params().size());
    297   p11 = p1;
    298   p11.receiver = &v11;
    299   EXPECT_TRUE(TreeChangeParamsMatch(p11, o11.received_params().back()));
    300 
    301   EXPECT_EQ(2U, o111.received_params().size());
    302   p111 = p11;
    303   p111.receiver = &v111;
    304   p111.phase = ViewObserver::DISPOSITION_CHANGING;
    305   EXPECT_TRUE(TreeChangeParamsMatch(p111, o111.received_params().front()));
    306   p111.phase = ViewObserver::DISPOSITION_CHANGED;
    307   EXPECT_TRUE(TreeChangeParamsMatch(p111, o111.received_params().back()));
    308 
    309   EXPECT_EQ(2U, o1111.received_params().size());
    310   p1111 = p111;
    311   p1111.receiver = &v1111;
    312   p1111.phase = ViewObserver::DISPOSITION_CHANGING;
    313   EXPECT_TRUE(TreeChangeParamsMatch(p1111, o1111.received_params().front()));
    314   p1111.phase = ViewObserver::DISPOSITION_CHANGED;
    315   EXPECT_TRUE(TreeChangeParamsMatch(p1111, o1111.received_params().back()));
    316 
    317   EXPECT_EQ(2U, o1112.received_params().size());
    318   p1112 = p111;
    319   p1112.receiver = &v1112;
    320   p1112.phase = ViewObserver::DISPOSITION_CHANGING;
    321   EXPECT_TRUE(TreeChangeParamsMatch(p1112, o1112.received_params().front()));
    322   p1112.phase = ViewObserver::DISPOSITION_CHANGED;
    323   EXPECT_TRUE(TreeChangeParamsMatch(p1112, o1112.received_params().back()));
    324 }
    325 
    326 TEST_F(ViewObserverTest, TreeChange_Reparent) {
    327   View v1, v11, v12, v111;
    328   v11.set_owned_by_parent(false);
    329   v111.set_owned_by_parent(false);
    330   v12.set_owned_by_parent(false);
    331   v1.AddChild(&v11);
    332   v1.AddChild(&v12);
    333   v11.AddChild(&v111);
    334 
    335   TreeChangeObserver o1(&v1), o11(&v11), o12(&v12), o111(&v111);
    336 
    337   // Reparent.
    338   v12.AddChild(&v111);
    339 
    340   // v1 (root) should see both changing and changed notifications.
    341   EXPECT_EQ(2U, o1.received_params().size());
    342   ViewObserver::TreeChangeParams p1;
    343   p1.target = &v111;
    344   p1.receiver = &v1;
    345   p1.old_parent = &v11;
    346   p1.new_parent = &v12;
    347   p1.phase = ViewObserver::DISPOSITION_CHANGING;
    348   EXPECT_TRUE(TreeChangeParamsMatch(p1, o1.received_params().front()));
    349   p1.phase = ViewObserver::DISPOSITION_CHANGED;
    350   EXPECT_TRUE(TreeChangeParamsMatch(p1, o1.received_params().back()));
    351 
    352   // v11 should see changing notifications.
    353   EXPECT_EQ(1U, o11.received_params().size());
    354   ViewObserver::TreeChangeParams p11;
    355   p11 = p1;
    356   p11.receiver = &v11;
    357   p11.phase = ViewObserver::DISPOSITION_CHANGING;
    358   EXPECT_TRUE(TreeChangeParamsMatch(p11, o11.received_params().back()));
    359 
    360   // v12 should see changed notifications.
    361   EXPECT_EQ(1U, o12.received_params().size());
    362   ViewObserver::TreeChangeParams p12;
    363   p12 = p1;
    364   p12.receiver = &v12;
    365   p12.phase = ViewObserver::DISPOSITION_CHANGED;
    366   EXPECT_TRUE(TreeChangeParamsMatch(p12, o12.received_params().back()));
    367 
    368   // v111 should see both changing and changed notifications.
    369   EXPECT_EQ(2U, o111.received_params().size());
    370   ViewObserver::TreeChangeParams p111;
    371   p111 = p1;
    372   p111.receiver = &v111;
    373   p111.phase = ViewObserver::DISPOSITION_CHANGING;
    374   EXPECT_TRUE(TreeChangeParamsMatch(p111, o111.received_params().front()));
    375   p111.phase = ViewObserver::DISPOSITION_CHANGED;
    376   EXPECT_TRUE(TreeChangeParamsMatch(p111, o111.received_params().back()));
    377 }
    378 
    379 class VisibilityObserver : public ViewObserver {
    380  public:
    381   typedef std::pair<ViewObserver::DispositionChangePhase, bool> LogEntry;
    382   typedef std::vector<LogEntry> LogEntries;
    383 
    384   VisibilityObserver(View* view) : view_(view) {
    385     view_->AddObserver(this);
    386   }
    387   virtual ~VisibilityObserver() {
    388     view_->RemoveObserver(this);
    389   }
    390 
    391   const LogEntries& log_entries() const { return log_entries_; }
    392 
    393  private:
    394   // Overridden from ViewObserver:
    395   virtual void OnViewVisibilityChange(
    396       View* view,
    397       ViewObserver::DispositionChangePhase phase) OVERRIDE {
    398     DCHECK_EQ(view_, view);
    399     log_entries_.push_back(std::make_pair(phase, view->visible()));
    400   }
    401 
    402   View* view_;
    403   LogEntries log_entries_;
    404 
    405   DISALLOW_COPY_AND_ASSIGN(VisibilityObserver);
    406 };
    407 
    408 TEST_F(ViewObserverTest, VisibilityChange) {
    409   View v1;  // Starts out visible.
    410 
    411   VisibilityObserver o1(&v1);
    412 
    413   v1.SetVisible(false);
    414 
    415   EXPECT_EQ(2U, o1.log_entries().size());
    416   EXPECT_EQ(ViewObserver::DISPOSITION_CHANGING, o1.log_entries().front().first);
    417   EXPECT_EQ(o1.log_entries().front().second, true);
    418   EXPECT_EQ(ViewObserver::DISPOSITION_CHANGED, o1.log_entries().back().first);
    419   EXPECT_EQ(o1.log_entries().back().second, false);
    420 }
    421 
    422 class BoundsObserver : public ViewObserver {
    423  public:
    424   typedef std::pair<gfx::Rect, gfx::Rect> BoundsChange;
    425   typedef std::vector<BoundsChange> BoundsChanges;
    426 
    427   explicit BoundsObserver(View* view) : view_(view) {
    428     view_->AddObserver(this);
    429   }
    430   virtual ~BoundsObserver() {
    431     view_->RemoveObserver(this);
    432   }
    433 
    434   const BoundsChanges& bounds_changes() const { return bounds_changes_; }
    435 
    436  private:
    437   virtual void OnViewBoundsChanged(View* view,
    438                                   const gfx::Rect& old_bounds,
    439                                   const gfx::Rect& new_bounds) OVERRIDE {
    440     DCHECK_EQ(view_, view);
    441     bounds_changes_.push_back(std::make_pair(old_bounds, new_bounds));
    442   }
    443 
    444   View* view_;
    445   BoundsChanges bounds_changes_;
    446 
    447   DISALLOW_COPY_AND_ASSIGN(BoundsObserver);
    448 };
    449 
    450 TEST_F(ViewObserverTest, BoundsChanged) {
    451   View v1;
    452   BoundsObserver o1(&v1);
    453 
    454   gfx::Rect new_bounds(0, 0, 10, 10);
    455 
    456   v1.SetBounds(new_bounds);
    457   EXPECT_EQ(1U, o1.bounds_changes().size());
    458   EXPECT_EQ(gfx::Rect(), o1.bounds_changes().front().first);
    459   EXPECT_EQ(new_bounds, o1.bounds_changes().front().second);
    460 }
    461 
    462 }  // namespace v2
    463