Index: chrome/browser/ui/tabs/tab_strip_model_unittest.cc |
diff --git a/chrome/browser/ui/tabs/tab_strip_model_unittest.cc b/chrome/browser/ui/tabs/tab_strip_model_unittest.cc |
index c767a8b51673a5156d10848aba50cab6322ce07b..d6befc4d952b7396e445de1123d1c117d246ee75 100644 |
--- a/chrome/browser/ui/tabs/tab_strip_model_unittest.cc |
+++ b/chrome/browser/ui/tabs/tab_strip_model_unittest.cc |
@@ -46,14 +46,19 @@ using extensions::Extension; |
namespace { |
-// Class used to delete a WebContents when another WebContents is destroyed. |
+// Class used to delete a WebContents and TabStripModel when another WebContents |
+// is destroyed. |
class DeleteWebContentsOnDestroyedObserver |
: public content::NotificationObserver { |
public: |
+ // When |source| is deleted both |tab_to_delete| and |tab_strip| are deleted. |
+ // |tab_to_delete| and |tab_strip| may be NULL. |
DeleteWebContentsOnDestroyedObserver(WebContents* source, |
- WebContents* tab_to_delete) |
+ WebContents* tab_to_delete, |
+ TabStripModel* tab_strip) |
: source_(source), |
- tab_to_delete_(tab_to_delete) { |
+ tab_to_delete_(tab_to_delete), |
+ tab_strip_(tab_strip) { |
registrar_.Add(this, content::NOTIFICATION_WEB_CONTENTS_DESTROYED, |
content::Source<WebContents>(source)); |
} |
@@ -63,12 +68,16 @@ class DeleteWebContentsOnDestroyedObserver |
const content::NotificationDetails& details) OVERRIDE { |
WebContents* tab_to_delete = tab_to_delete_; |
tab_to_delete_ = NULL; |
+ TabStripModel* tab_strip_to_delete = tab_strip_; |
+ tab_strip_ = NULL; |
delete tab_to_delete; |
+ delete tab_strip_to_delete; |
} |
private: |
WebContents* source_; |
WebContents* tab_to_delete_; |
+ TabStripModel* tab_strip_; |
content::NotificationRegistrar registrar_; |
DISALLOW_COPY_AND_ASSIGN(DeleteWebContentsOnDestroyedObserver); |
@@ -206,6 +215,7 @@ class MockTabStripModelObserver : public TabStripModelObserver { |
public: |
explicit MockTabStripModelObserver(TabStripModel* model) |
: empty_(true), |
+ deleted_(false), |
model_(model) {} |
virtual ~MockTabStripModelObserver() {} |
@@ -329,18 +339,23 @@ class MockTabStripModelObserver : public TabStripModelObserver { |
virtual void TabStripEmpty() OVERRIDE { |
empty_ = true; |
} |
+ virtual void TabStripModelDeleted() OVERRIDE { |
+ deleted_ = true; |
+ } |
void ClearStates() { |
states_.clear(); |
} |
bool empty() const { return empty_; } |
+ bool deleted() const { return deleted_; } |
TabStripModel* model() { return model_; } |
private: |
std::vector<State> states_; |
bool empty_; |
+ bool deleted_; |
TabStripModel* model_; |
DISALLOW_COPY_AND_ASSIGN(MockTabStripModelObserver); |
@@ -2116,10 +2131,29 @@ TEST_F(TabStripModelTest, DeleteFromDestroy) { |
strip.AppendWebContents(contents2, true); |
// DeleteWebContentsOnDestroyedObserver deletes contents1 when contents2 sends |
// out notification that it is being destroyed. |
- DeleteWebContentsOnDestroyedObserver observer(contents2, contents1); |
+ DeleteWebContentsOnDestroyedObserver observer(contents2, contents1, NULL); |
strip.CloseAllTabs(); |
} |
+// Makes sure TabStripModel handles the case of deleting another tab and the |
+// TabStrip while removing another tab. |
+TEST_F(TabStripModelTest, DeleteTabStripFromDestroy) { |
+ TabStripDummyDelegate delegate; |
+ TabStripModel* strip = new TabStripModel(&delegate, profile()); |
+ MockTabStripModelObserver tab_strip_model_observer(strip); |
+ strip->AddObserver(&tab_strip_model_observer); |
+ WebContents* contents1 = CreateWebContents(); |
+ WebContents* contents2 = CreateWebContents(); |
+ strip->AppendWebContents(contents1, true); |
+ strip->AppendWebContents(contents2, true); |
+ // DeleteWebContentsOnDestroyedObserver deletes |contents1| and |strip| when |
+ // |contents2| sends out notification that it is being destroyed. |
+ DeleteWebContentsOnDestroyedObserver observer(contents2, contents1, strip); |
+ strip->CloseAllTabs(); |
+ EXPECT_TRUE(tab_strip_model_observer.empty()); |
+ EXPECT_TRUE(tab_strip_model_observer.deleted()); |
+} |
+ |
TEST_F(TabStripModelTest, MoveSelectedTabsTo) { |
struct TestData { |
// Number of tabs the tab strip should have. |