Home | History | Annotate | Download | only in instant
      1 // Copyright (c) 2011 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 "base/memory/scoped_ptr.h"
      6 #include "chrome/browser/instant/instant_loader.h"
      7 #include "chrome/browser/instant/instant_loader_delegate.h"
      8 #include "chrome/browser/instant/instant_loader_manager.h"
      9 #include "testing/gtest/include/gtest/gtest.h"
     10 
     11 namespace {
     12 
     13 class InstantLoaderDelegateImpl : public InstantLoaderDelegate {
     14  public:
     15   InstantLoaderDelegateImpl() {}
     16 
     17   virtual void InstantStatusChanged(InstantLoader* loader) OVERRIDE {}
     18 
     19   virtual void SetSuggestedTextFor(InstantLoader* loader,
     20                                    const string16& text,
     21                                    InstantCompleteBehavior behavior) OVERRIDE {}
     22 
     23   virtual gfx::Rect GetInstantBounds() OVERRIDE {
     24     return gfx::Rect();
     25   }
     26 
     27   virtual bool ShouldCommitInstantOnMouseUp() OVERRIDE {
     28     return false;
     29   }
     30 
     31   virtual void CommitInstantLoader(InstantLoader* loader) OVERRIDE {
     32   }
     33 
     34   virtual void InstantLoaderDoesntSupportInstant(
     35       InstantLoader* loader) OVERRIDE {
     36   }
     37 
     38   virtual void AddToBlacklist(InstantLoader* loader,
     39                               const GURL& url) OVERRIDE {
     40   }
     41 
     42  private:
     43   DISALLOW_COPY_AND_ASSIGN(InstantLoaderDelegateImpl);
     44 };
     45 
     46 }
     47 
     48 class InstantLoaderManagerTest : public testing::Test {
     49  public:
     50   InstantLoaderManagerTest() {}
     51 
     52   void MarkReady(InstantLoader* loader) {
     53     loader->ready_ = true;
     54   }
     55 
     56  private:
     57   DISALLOW_COPY_AND_ASSIGN(InstantLoaderManagerTest);
     58 };
     59 
     60 // Makes sure UpdateLoader works when invoked once.
     61 TEST_F(InstantLoaderManagerTest, Basic) {
     62   InstantLoaderDelegateImpl delegate;
     63   InstantLoaderManager manager(&delegate);
     64   scoped_ptr<InstantLoader> loader;
     65   manager.UpdateLoader(0, &loader);
     66   EXPECT_EQ(NULL, loader.get());
     67   EXPECT_TRUE(manager.current_loader());
     68   EXPECT_EQ(NULL, manager.pending_loader());
     69   EXPECT_EQ(0, manager.current_loader()->template_url_id());
     70 }
     71 
     72 // Make sure invoking update twice for non-instant results keeps the same
     73 // loader.
     74 TEST_F(InstantLoaderManagerTest, UpdateTwice) {
     75   InstantLoaderDelegateImpl delegate;
     76   InstantLoaderManager manager(&delegate);
     77   scoped_ptr<InstantLoader> loader;
     78   manager.UpdateLoader(0, &loader);
     79   InstantLoader* current_loader = manager.current_loader();
     80   manager.UpdateLoader(0, &loader);
     81   EXPECT_EQ(NULL, loader.get());
     82   EXPECT_EQ(current_loader, manager.current_loader());
     83   EXPECT_EQ(NULL, manager.pending_loader());
     84 }
     85 
     86 // Make sure invoking update twice for instant results keeps the same loader.
     87 TEST_F(InstantLoaderManagerTest, UpdateInstantTwice) {
     88   InstantLoaderDelegateImpl delegate;
     89   InstantLoaderManager manager(&delegate);
     90   scoped_ptr<InstantLoader> loader;
     91   manager.UpdateLoader(1, &loader);
     92   InstantLoader* current_loader = manager.current_loader();
     93   manager.UpdateLoader(1, &loader);
     94   EXPECT_EQ(NULL, loader.get());
     95   EXPECT_EQ(current_loader, manager.current_loader());
     96   EXPECT_EQ(NULL, manager.pending_loader());
     97   EXPECT_EQ(1u, manager.num_instant_loaders());
     98 }
     99 
    100 // Makes sure transitioning from non-instant to instant works.
    101 TEST_F(InstantLoaderManagerTest, NonInstantToInstant) {
    102   InstantLoaderDelegateImpl delegate;
    103   InstantLoaderManager manager(&delegate);
    104   scoped_ptr<InstantLoader> loader;
    105   manager.UpdateLoader(0, &loader);
    106   InstantLoader* current_loader = manager.current_loader();
    107   manager.UpdateLoader(1, &loader);
    108   EXPECT_TRUE(loader.get() != NULL);
    109   EXPECT_NE(current_loader, manager.current_loader());
    110   EXPECT_EQ(NULL, manager.pending_loader());
    111   EXPECT_EQ(1u, manager.num_instant_loaders());
    112 }
    113 
    114 // Makes sure instant loaders aren't deleted when invoking update with different
    115 // ids.
    116 TEST_F(InstantLoaderManagerTest, DontDeleteInstantLoaders) {
    117   InstantLoaderDelegateImpl delegate;
    118   InstantLoaderManager manager(&delegate);
    119   scoped_ptr<InstantLoader> loader;
    120   manager.UpdateLoader(1, &loader);
    121   InstantLoader* current_loader = manager.current_loader();
    122   manager.UpdateLoader(2, &loader);
    123   EXPECT_EQ(NULL, loader.get());
    124   EXPECT_NE(current_loader, manager.current_loader());
    125   EXPECT_EQ(NULL, manager.pending_loader());
    126   EXPECT_EQ(2u, manager.num_instant_loaders());
    127 }
    128 
    129 // Makes sure a new loader is created and assigned to secondary when
    130 // transitioning from a ready non-instant to instant.
    131 TEST_F(InstantLoaderManagerTest, CreateSecondaryWhenReady) {
    132   InstantLoaderDelegateImpl delegate;
    133   InstantLoaderManager manager(&delegate);
    134   scoped_ptr<InstantLoader> loader;
    135   manager.UpdateLoader(0, &loader);
    136   InstantLoader* current_loader = manager.current_loader();
    137   ASSERT_TRUE(current_loader);
    138   MarkReady(current_loader);
    139 
    140   manager.UpdateLoader(1, &loader);
    141   EXPECT_EQ(NULL, loader.get());
    142   EXPECT_EQ(current_loader, manager.current_loader());
    143   EXPECT_TRUE(manager.pending_loader());
    144   EXPECT_NE(current_loader, manager.pending_loader());
    145   EXPECT_EQ(1u, manager.num_instant_loaders());
    146 
    147   // Make the pending loader current.
    148   InstantLoader* pending_loader = manager.pending_loader();
    149   manager.MakePendingCurrent(&loader);
    150   EXPECT_TRUE(loader.get());
    151   EXPECT_EQ(pending_loader, manager.current_loader());
    152   EXPECT_EQ(NULL, manager.pending_loader());
    153   EXPECT_EQ(1u, manager.num_instant_loaders());
    154 }
    155 
    156 // Makes sure releasing an instant updates maps currectly.
    157 TEST_F(InstantLoaderManagerTest, ReleaseInstant) {
    158   InstantLoaderDelegateImpl delegate;
    159   InstantLoaderManager manager(&delegate);
    160   scoped_ptr<InstantLoader> loader;
    161   manager.UpdateLoader(1, &loader);
    162   scoped_ptr<InstantLoader> current_loader(manager.ReleaseCurrentLoader());
    163   EXPECT_TRUE(current_loader.get());
    164   EXPECT_EQ(NULL, manager.current_loader());
    165   EXPECT_EQ(0u, manager.num_instant_loaders());
    166 }
    167 
    168 // Tests transitioning from a non-instant ready loader to an instant ready
    169 // loader is immediate.
    170 TEST_F(InstantLoaderManagerTest, NonInstantToInstantWhenReady) {
    171   InstantLoaderDelegateImpl delegate;
    172   InstantLoaderManager manager(&delegate);
    173   scoped_ptr<InstantLoader> loader;
    174   manager.UpdateLoader(1, &loader);
    175   ASSERT_TRUE(manager.current_loader());
    176   EXPECT_EQ(1, manager.current_loader()->template_url_id());
    177   InstantLoader* instant_loader = manager.current_loader();
    178 
    179   manager.UpdateLoader(0, &loader);
    180   InstantLoader* non_instant_loader = manager.current_loader();
    181   ASSERT_TRUE(non_instant_loader);
    182   MarkReady(non_instant_loader);
    183   EXPECT_NE(non_instant_loader, instant_loader);
    184 
    185   MarkReady(instant_loader);
    186   manager.UpdateLoader(1, &loader);
    187   EXPECT_EQ(non_instant_loader, loader.get());
    188   EXPECT_EQ(instant_loader, manager.current_loader());
    189   EXPECT_EQ(NULL, manager.pending_loader());
    190   EXPECT_EQ(1u, manager.num_instant_loaders());
    191 }
    192 
    193 // Tests transitioning between 3 instant loaders, all ready.
    194 TEST_F(InstantLoaderManagerTest, ThreeInstant) {
    195   InstantLoaderDelegateImpl delegate;
    196   InstantLoaderManager manager(&delegate);
    197   scoped_ptr<InstantLoader> loader;
    198   manager.UpdateLoader(1, &loader);
    199   ASSERT_TRUE(manager.current_loader());
    200   EXPECT_EQ(1, manager.current_loader()->template_url_id());
    201   InstantLoader* instant_loader1 = manager.current_loader();
    202   MarkReady(instant_loader1);
    203 
    204   manager.UpdateLoader(2, &loader);
    205   InstantLoader* instant_loader2 = manager.pending_loader();
    206   ASSERT_TRUE(instant_loader2);
    207   EXPECT_EQ(2, instant_loader2->template_url_id());
    208   EXPECT_NE(instant_loader1, instant_loader2);
    209   EXPECT_EQ(instant_loader1, manager.current_loader());
    210 
    211   manager.UpdateLoader(3, &loader);
    212   InstantLoader* instant_loader3 = manager.pending_loader();
    213   ASSERT_TRUE(instant_loader3);
    214   EXPECT_EQ(3, instant_loader3->template_url_id());
    215   EXPECT_NE(instant_loader1, instant_loader3);
    216   EXPECT_NE(instant_loader2, instant_loader3);
    217   EXPECT_EQ(instant_loader1, manager.current_loader());
    218 }
    219 
    220 // Tests DestroyLoader with an instant loader.
    221 TEST_F(InstantLoaderManagerTest, DestroyInstantLoader) {
    222   InstantLoaderDelegateImpl delegate;
    223   InstantLoaderManager manager(&delegate);
    224   scoped_ptr<InstantLoader> loader;
    225   manager.UpdateLoader(1, &loader);
    226   ASSERT_TRUE(manager.current_loader());
    227   EXPECT_EQ(1, manager.current_loader()->template_url_id());
    228   // Now destroy it.
    229   manager.DestroyLoader(manager.current_loader());
    230 
    231   // There should be no current, pending and 0 instant loaders.
    232   ASSERT_EQ(NULL, manager.current_loader());
    233   ASSERT_EQ(NULL, manager.pending_loader());
    234   EXPECT_EQ(0u, manager.num_instant_loaders());
    235 }
    236 
    237 // Tests DestroyLoader when the loader is pending.
    238 TEST_F(InstantLoaderManagerTest, DestroyPendingLoader) {
    239   InstantLoaderDelegateImpl delegate;
    240   InstantLoaderManager manager(&delegate);
    241   scoped_ptr<InstantLoader> loader;
    242   manager.UpdateLoader(1, &loader);
    243   InstantLoader* first_loader = manager.active_loader();
    244   MarkReady(first_loader);
    245 
    246   // Create another loader.
    247   manager.UpdateLoader(0, &loader);
    248   InstantLoader* second_loader = manager.pending_loader();
    249   ASSERT_TRUE(second_loader);
    250   ASSERT_NE(second_loader, first_loader);
    251 
    252   // Destroy it.
    253   manager.DestroyLoader(second_loader);
    254   EXPECT_EQ(NULL, manager.pending_loader());
    255   EXPECT_EQ(first_loader, manager.current_loader());
    256 }
    257 
    258 // Makes sure WillUpateChangeActiveLoader works.
    259 TEST_F(InstantLoaderManagerTest, WillUpateChangeActiveLoader) {
    260   InstantLoaderDelegateImpl delegate;
    261   InstantLoaderManager manager(&delegate);
    262   scoped_ptr<InstantLoader> loader;
    263 
    264   // When there is no loader WillUpateChangeActiveLoader should return true.
    265   EXPECT_TRUE(manager.WillUpateChangeActiveLoader(0));
    266   EXPECT_TRUE(manager.WillUpateChangeActiveLoader(1));
    267 
    268   // Add a loder with id 0 and test again.
    269   manager.UpdateLoader(0, &loader);
    270   EXPECT_FALSE(manager.WillUpateChangeActiveLoader(0));
    271   EXPECT_TRUE(manager.WillUpateChangeActiveLoader(1));
    272   ASSERT_TRUE(manager.active_loader());
    273   MarkReady(manager.active_loader());
    274 
    275   // Add a loader with id 1 and test again.
    276   manager.UpdateLoader(1, &loader);
    277   EXPECT_TRUE(manager.WillUpateChangeActiveLoader(0));
    278   EXPECT_FALSE(manager.WillUpateChangeActiveLoader(1));
    279 }
    280 
    281 // Makes sure UpdateLoader doesn't schedule a loader for deletion when asked
    282 // to update and the pending loader is ready.
    283 TEST_F(InstantLoaderManagerTest, UpdateWithReadyPending) {
    284   InstantLoaderDelegateImpl delegate;
    285   InstantLoaderManager manager(&delegate);
    286 
    287   {
    288     scoped_ptr<InstantLoader> loader;
    289     manager.UpdateLoader(1, &loader);
    290   }
    291   InstantLoader* instant_loader = manager.current_loader();
    292   ASSERT_TRUE(instant_loader);
    293   MarkReady(instant_loader);
    294 
    295   {
    296     scoped_ptr<InstantLoader> loader;
    297     manager.UpdateLoader(0, &loader);
    298   }
    299   InstantLoader* non_instant_loader = manager.active_loader();
    300   ASSERT_TRUE(non_instant_loader);
    301   ASSERT_NE(instant_loader, non_instant_loader);
    302   MarkReady(non_instant_loader);
    303 
    304   // This makes the non_instant_loader the current loader since it was ready.
    305   scoped_ptr<InstantLoader> loader;
    306   manager.UpdateLoader(0, &loader);
    307   ASSERT_NE(loader.get(), non_instant_loader);
    308 }
    309