Commit cc11e7bf authored by Rohit Rao's avatar Rohit Rao Committed by Commit Bot

[ios] Adds helper classes for observing WebStates in a WebStateList.

AllWebStateObservationForwarder forwards observer methods for all the
WebStates in a WebStateList, keeping track of WebStates as they are
added, removed, and replaced.

ActiveWebStateObservationForwarder forwards observer methods for just
the currently-active WebState, even as the active WebState in the
WebStateList changes.

These classes are intended to remove some of the boilerplate bookkeeping
that is necessary when trying to perform either of these common tasks.

Change-Id: I8320f1d1c6aef180a79adf9cbe614cd2066b84fb
Reviewed-on: https://chromium-review.googlesource.com/c/1393531Reviewed-by: default avatarMark Cogan <marq@chromium.org>
Reviewed-by: default avataredchin <edchin@chromium.org>
Commit-Queue: Rohit Rao <rohitrao@chromium.org>
Cr-Commit-Position: refs/heads/master@{#619650}
parent e44b7cc0
......@@ -4,6 +4,10 @@
source_set("web_state_list") {
sources = [
"active_web_state_observation_forwarder.h",
"active_web_state_observation_forwarder.mm",
"all_web_state_observation_forwarder.h",
"all_web_state_observation_forwarder.mm",
"web_state_list.h",
"web_state_list.mm",
"web_state_list_delegate.h",
......@@ -45,6 +49,8 @@ source_set("test_support") {
source_set("unit_tests") {
testonly = true
sources = [
"active_web_state_observation_forwarder_unittest.mm",
"all_web_state_observation_forwarder_unittest.mm",
"web_state_list_order_controller_unittest.mm",
"web_state_list_serialization_unittest.mm",
"web_state_list_unittest.mm",
......
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef IOS_CHROME_BROWSER_WEB_STATE_LIST_ACTIVE_WEB_STATE_OBSERVATION_FORWARDER_H_
#define IOS_CHROME_BROWSER_WEB_STATE_LIST_ACTIVE_WEB_STATE_OBSERVATION_FORWARDER_H_
#include "base/scoped_observer.h"
#include "ios/chrome/browser/web_state_list/web_state_list_observer.h"
class WebStateList;
namespace web {
class WebState;
class WebStateObserver;
} // namespace web
// ActiveWebStateObservationForwarder forwards WebStateObserver methods for the
// active WebState in a WebStateList, handling cases where the active WebState
// changes.
class ActiveWebStateObservationForwarder : public WebStateListObserver {
public:
// Creates an object which forwards observation methods to |observer| and
// tracks |web_state_list| to keep track of the currently-active WebState.
// |web_state_list| and |observer| must both outlive this object.
ActiveWebStateObservationForwarder(WebStateList* web_state_list,
web::WebStateObserver* observer);
~ActiveWebStateObservationForwarder() override;
// WebStateListObserver.
void WebStateActivatedAt(WebStateList* web_state_list,
web::WebState* old_web_state,
web::WebState* new_web_state,
int active_index,
int reason) override;
private:
ScopedObserver<WebStateList, WebStateListObserver> web_state_list_observer_;
ScopedObserver<web::WebState, web::WebStateObserver> web_state_observer_;
};
#endif // IOS_CHROME_BROWSER_WEB_STATE_LIST_ACTIVE_WEB_STATE_OBSERVATION_FORWARDER_H_
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#import "ios/chrome/browser/web_state_list/active_web_state_observation_forwarder.h"
#include "base/logging.h"
#include "ios/chrome/browser/web_state_list/web_state_list.h"
#include "ios/web/public/web_state/web_state.h"
#if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support."
#endif
ActiveWebStateObservationForwarder::ActiveWebStateObservationForwarder(
WebStateList* web_state_list,
web::WebStateObserver* observer)
: web_state_list_observer_(this), web_state_observer_(observer) {
DCHECK(observer);
DCHECK(web_state_list);
web_state_list_observer_.Add(web_state_list);
web::WebState* active_web_state = web_state_list->GetActiveWebState();
if (active_web_state) {
web_state_observer_.Add(active_web_state);
}
}
ActiveWebStateObservationForwarder::~ActiveWebStateObservationForwarder() {}
void ActiveWebStateObservationForwarder::WebStateActivatedAt(
WebStateList* web_state_list,
web::WebState* old_web_state,
web::WebState* new_web_state,
int active_index,
int reason) {
if (old_web_state) {
web_state_observer_.Remove(old_web_state);
}
if (new_web_state) {
web_state_observer_.Add(new_web_state);
}
}
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#import "ios/chrome/browser/web_state_list/active_web_state_observation_forwarder.h"
#include <algorithm>
#include <memory>
#include <vector>
#include "ios/chrome/browser/web_state_list/web_state_list.h"
#include "ios/chrome/browser/web_state_list/web_state_list_delegate.h"
#include "ios/chrome/browser/web_state_list/web_state_opener.h"
#include "ios/web/public/test/fakes/test_web_state.h"
#include "ios/web/public/web_state/web_state.h"
#include "ios/web/public/web_state/web_state_observer.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "testing/gtest_mac.h"
#include "testing/platform_test.h"
#if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support."
#endif
namespace {
class TestObserver : public web::WebStateObserver {
public:
TestObserver() {}
~TestObserver() override {}
bool WasInvokedFor(web::WebState* web_state) {
return std::find(invoker_web_states_.begin(), invoker_web_states_.end(),
web_state) != invoker_web_states_.end();
}
void Reset() { invoker_web_states_.clear(); }
// web::WebStateObserver.
void RenderProcessGone(web::WebState* web_state) override {
invoker_web_states_.push_back(web_state);
}
private:
std::vector<web::WebState*> invoker_web_states_;
};
class ActiveWebStateObservationForwarderTest : public PlatformTest,
public WebStateListDelegate {
public:
ActiveWebStateObservationForwarderTest() : web_state_list_(this) {
forwarder_ = std::make_unique<ActiveWebStateObservationForwarder>(
&web_state_list_, &observer_);
}
web::TestWebState* AddWebStateToList(bool activate) {
std::unique_ptr<web::TestWebState> web_state(
std::make_unique<web::TestWebState>());
web::TestWebState* web_state_ptr = web_state.get();
web_state_list_.InsertWebState(0, std::move(web_state),
activate ? WebStateList::INSERT_ACTIVATE
: WebStateList::INSERT_NO_FLAGS,
WebStateOpener());
return web_state_ptr;
}
// WebStateListDelegate.
void WillAddWebState(web::WebState* web_state) override {}
void WebStateDetached(web::WebState* web_state) override {}
protected:
WebStateList web_state_list_;
TestObserver observer_;
std::unique_ptr<ActiveWebStateObservationForwarder> forwarder_;
};
} // namespace
TEST_F(ActiveWebStateObservationForwarderTest, TestInsertActiveWebState) {
// Insert two webstates into the list and mark the second one active. Send
// observer notifications for both and verify the result.
web::TestWebState* web_state_a = AddWebStateToList(true);
web::TestWebState* web_state_b = AddWebStateToList(true);
ASSERT_EQ(web_state_b, web_state_list_.GetActiveWebState());
web_state_a->OnRenderProcessGone();
web_state_b->OnRenderProcessGone();
// The observer should only be notified for the active web state B.
EXPECT_TRUE(observer_.WasInvokedFor(web_state_b));
EXPECT_FALSE(observer_.WasInvokedFor(web_state_a));
}
TEST_F(ActiveWebStateObservationForwarderTest, TestInsertNonActiveWebState) {
// Insert two webstates into the list, but do not mark the second one active.
// Send observer notifications for both and verify the result.
web::TestWebState* web_state_a = AddWebStateToList(true);
web::TestWebState* web_state_b = AddWebStateToList(false);
ASSERT_EQ(web_state_a, web_state_list_.GetActiveWebState());
web_state_a->OnRenderProcessGone();
web_state_b->OnRenderProcessGone();
// The observer should only be notified for the active web state A.
EXPECT_TRUE(observer_.WasInvokedFor(web_state_a));
EXPECT_FALSE(observer_.WasInvokedFor(web_state_b));
}
TEST_F(ActiveWebStateObservationForwarderTest, TestDetachActiveWebState) {
// Insert three webstates into the list.
web::TestWebState* web_state_a = AddWebStateToList(true);
web::TestWebState* web_state_b = AddWebStateToList(true);
web::TestWebState* web_state_c = AddWebStateToList(true);
ASSERT_EQ(web_state_c, web_state_list_.GetActiveWebState());
// Remove the active web state and send observer notifications.
std::unique_ptr<web::WebState> detached_web_state =
web_state_list_.DetachWebStateAt(web_state_list_.active_index());
web::WebState* active_web_state = web_state_list_.GetActiveWebState();
web::WebState* non_active_web_state =
(active_web_state == web_state_a ? web_state_b : web_state_a);
web_state_a->OnRenderProcessGone();
web_state_b->OnRenderProcessGone();
web_state_c->OnRenderProcessGone();
// The observer should only be notified for the new active web state.
EXPECT_TRUE(observer_.WasInvokedFor(active_web_state));
EXPECT_FALSE(observer_.WasInvokedFor(non_active_web_state));
EXPECT_FALSE(observer_.WasInvokedFor(web_state_c));
}
TEST_F(ActiveWebStateObservationForwarderTest, TestDetachNonActiveWebState) {
// Insert three webstates into the list.
web::TestWebState* web_state_a = AddWebStateToList(true);
web::TestWebState* web_state_b = AddWebStateToList(true);
web::TestWebState* web_state_c = AddWebStateToList(true);
ASSERT_EQ(web_state_c, web_state_list_.GetActiveWebState());
// Remove a non-active web state and send observer notifications.
std::unique_ptr<web::WebState> detached_web_state =
web_state_list_.DetachWebStateAt(
web_state_list_.GetIndexOfWebState(web_state_a));
ASSERT_EQ(web_state_c, web_state_list_.GetActiveWebState());
web_state_a->OnRenderProcessGone();
web_state_b->OnRenderProcessGone();
web_state_c->OnRenderProcessGone();
// The observer should only be notified for the active web state.
EXPECT_TRUE(observer_.WasInvokedFor(web_state_c));
EXPECT_FALSE(observer_.WasInvokedFor(web_state_a));
EXPECT_FALSE(observer_.WasInvokedFor(web_state_b));
}
TEST_F(ActiveWebStateObservationForwarderTest, TestReplaceActiveWebState) {
// Insert two webstates into the list and mark the second one active.
web::TestWebState* web_state_a = AddWebStateToList(true);
web::TestWebState* web_state_b = AddWebStateToList(true);
ASSERT_EQ(web_state_b, web_state_list_.GetActiveWebState());
// Replace the active web state. Send notifications and verify the result.
std::unique_ptr<web::TestWebState> replacement_web_state(
std::make_unique<web::TestWebState>());
web::TestWebState* web_state_c = replacement_web_state.get();
std::unique_ptr<web::WebState> detached_web_state =
web_state_list_.ReplaceWebStateAt(
web_state_list_.GetIndexOfWebState(web_state_b),
std::move(replacement_web_state));
web_state_a->OnRenderProcessGone();
web_state_b->OnRenderProcessGone();
web_state_c->OnRenderProcessGone();
// The observer should only be notified for the new active web state C.
EXPECT_TRUE(observer_.WasInvokedFor(web_state_c));
EXPECT_FALSE(observer_.WasInvokedFor(web_state_a));
EXPECT_FALSE(observer_.WasInvokedFor(web_state_b));
}
TEST_F(ActiveWebStateObservationForwarderTest, TestChangeActiveWebState) {
// Insert two webstates into the list and mark the second one active.
web::TestWebState* web_state_a = AddWebStateToList(true);
web::TestWebState* web_state_b = AddWebStateToList(true);
ASSERT_EQ(web_state_b, web_state_list_.GetActiveWebState());
// Make web state A active and send notifications.
web_state_list_.ActivateWebStateAt(
web_state_list_.GetIndexOfWebState(web_state_a));
web_state_a->OnRenderProcessGone();
web_state_b->OnRenderProcessGone();
// The observer should only be notified for the active web state A.
EXPECT_TRUE(observer_.WasInvokedFor(web_state_a));
EXPECT_FALSE(observer_.WasInvokedFor(web_state_b));
// Make web state B active and send notifications.
observer_.Reset();
web_state_list_.ActivateWebStateAt(
web_state_list_.GetIndexOfWebState(web_state_b));
web_state_a->OnRenderProcessGone();
web_state_b->OnRenderProcessGone();
// The observer should only be notified for the active web state B.
EXPECT_TRUE(observer_.WasInvokedFor(web_state_b));
EXPECT_FALSE(observer_.WasInvokedFor(web_state_a));
}
TEST_F(ActiveWebStateObservationForwarderTest,
TestNonEmptyInitialWebStateList) {
// Insert two webstates into the list.
web::TestWebState* web_state_a = AddWebStateToList(true);
web::TestWebState* web_state_b = AddWebStateToList(true);
ASSERT_EQ(web_state_b, web_state_list_.GetActiveWebState());
// Recreate the multi observer to simulate creation with an already-populated
// WebStateList.
forwarder_.reset();
forwarder_ = std::make_unique<ActiveWebStateObservationForwarder>(
&web_state_list_, &observer_);
// Send notifications and verify the result.
web_state_a->OnRenderProcessGone();
web_state_b->OnRenderProcessGone();
// The observer should only be notified for the active web state B.
EXPECT_TRUE(observer_.WasInvokedFor(web_state_b));
EXPECT_FALSE(observer_.WasInvokedFor(web_state_a));
}
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef IOS_CHROME_BROWSER_WEB_STATE_LIST_ALL_WEB_STATE_OBSERVATION_FORWARDER_H_
#define IOS_CHROME_BROWSER_WEB_STATE_LIST_ALL_WEB_STATE_OBSERVATION_FORWARDER_H_
#include "base/scoped_observer.h"
#include "ios/chrome/browser/web_state_list/web_state_list_observer.h"
class WebStateList;
namespace web {
class WebState;
class WebStateObserver;
} // namespace web
// AllWebStateObservationForwarder forwards WebStateObserver methods for all
// WebStates in a WebStateList, handling cases where WebStates are added,
// removed, or replaced.
class AllWebStateObservationForwarder : public WebStateListObserver {
public:
// Creates an object which forwards observation methods to |observer| and
// tracks the set of WebStates in |web_state_list|. |web_state_list| and
// |observer| must both outlive this object.
AllWebStateObservationForwarder(WebStateList* web_state_list,
web::WebStateObserver* observer);
~AllWebStateObservationForwarder() override;
// WebStateListObserver.
void WebStateInsertedAt(WebStateList* web_state_list,
web::WebState* web_state,
int index,
bool activating) override;
void WebStateReplacedAt(WebStateList* web_state_list,
web::WebState* old_web_state,
web::WebState* new_web_state,
int index) override;
void WebStateDetachedAt(WebStateList* web_state_list,
web::WebState* web_state,
int index) override;
private:
ScopedObserver<WebStateList, WebStateListObserver> web_state_list_observer_;
ScopedObserver<web::WebState, web::WebStateObserver> web_state_observer_;
};
#endif // IOS_CHROME_BROWSER_WEB_STATE_LIST_ALL_WEB_STATE_OBSERVATION_FORWARDER_H_
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#import "ios/chrome/browser/web_state_list/all_web_state_observation_forwarder.h"
#include "base/logging.h"
#include "ios/chrome/browser/web_state_list/web_state_list.h"
#include "ios/web/public/web_state/web_state.h"
#if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support."
#endif
AllWebStateObservationForwarder::AllWebStateObservationForwarder(
WebStateList* web_state_list,
web::WebStateObserver* observer)
: web_state_list_observer_(this), web_state_observer_(observer) {
DCHECK(observer);
DCHECK(web_state_list);
web_state_list_observer_.Add(web_state_list);
for (int ii = 0; ii < web_state_list->count(); ++ii) {
web::WebState* web_state = web_state_list->GetWebStateAt(ii);
web_state_observer_.Add(web_state);
}
}
AllWebStateObservationForwarder::~AllWebStateObservationForwarder() {}
void AllWebStateObservationForwarder::WebStateInsertedAt(
WebStateList* web_state_list,
web::WebState* web_state,
int index,
bool activating) {
web_state_observer_.Add(web_state);
}
void AllWebStateObservationForwarder::WebStateReplacedAt(
WebStateList* web_state_list,
web::WebState* old_web_state,
web::WebState* new_web_state,
int index) {
web_state_observer_.Remove(old_web_state);
web_state_observer_.Add(new_web_state);
}
void AllWebStateObservationForwarder::WebStateDetachedAt(
WebStateList* web_state_list,
web::WebState* web_state,
int index) {
web_state_observer_.Remove(web_state);
}
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#import "ios/chrome/browser/web_state_list/all_web_state_observation_forwarder.h"
#include <algorithm>
#include <memory>
#include <vector>
#include "ios/chrome/browser/web_state_list/web_state_list.h"
#include "ios/chrome/browser/web_state_list/web_state_list_delegate.h"
#include "ios/chrome/browser/web_state_list/web_state_opener.h"
#include "ios/web/public/test/fakes/test_web_state.h"
#include "ios/web/public/web_state/web_state.h"
#include "ios/web/public/web_state/web_state_observer.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "testing/gtest_mac.h"
#include "testing/platform_test.h"
#if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support."
#endif
namespace {
class TestObserver : public web::WebStateObserver {
public:
TestObserver() {}
~TestObserver() override {}
bool WasInvokedFor(web::WebState* web_state) {
return std::find(invoker_web_states_.begin(), invoker_web_states_.end(),
web_state) != invoker_web_states_.end();
}
void Reset() { invoker_web_states_.clear(); }
// web::WebStateObserver.
void RenderProcessGone(web::WebState* web_state) override {
invoker_web_states_.push_back(web_state);
}
private:
std::vector<web::WebState*> invoker_web_states_;
};
class AllWebStateObservationForwarderTest : public PlatformTest,
public WebStateListDelegate {
public:
AllWebStateObservationForwarderTest() : web_state_list_(this) {
forwarder_ = std::make_unique<AllWebStateObservationForwarder>(
&web_state_list_, &observer_);
}
web::TestWebState* AddWebStateToList(bool activate) {
std::unique_ptr<web::TestWebState> web_state(
std::make_unique<web::TestWebState>());
web::TestWebState* web_state_ptr = web_state.get();
web_state_list_.InsertWebState(0, std::move(web_state),
activate ? WebStateList::INSERT_ACTIVATE
: WebStateList::INSERT_NO_FLAGS,
WebStateOpener());
return web_state_ptr;
}
// WebStateListDelegate.
void WillAddWebState(web::WebState* web_state) override {}
void WebStateDetached(web::WebState* web_state) override {}
protected:
WebStateList web_state_list_;
TestObserver observer_;
std::unique_ptr<AllWebStateObservationForwarder> forwarder_;
};
} // namespace
TEST_F(AllWebStateObservationForwarderTest, TestInsertActiveWebState) {
// Insert two webstates into the list and mark the second one active. Send
// observer notifications for both and verify the result.
web::TestWebState* web_state_a = AddWebStateToList(true);
web::TestWebState* web_state_b = AddWebStateToList(true);
ASSERT_EQ(web_state_b, web_state_list_.GetActiveWebState());
web_state_a->OnRenderProcessGone();
web_state_b->OnRenderProcessGone();
// The observer should get notifications for both web states.
EXPECT_TRUE(observer_.WasInvokedFor(web_state_a));
EXPECT_TRUE(observer_.WasInvokedFor(web_state_b));
}
TEST_F(AllWebStateObservationForwarderTest, TestInsertNonActiveWebState) {
// Insert two webstates into the list, but do not mark the second one active.
// Send observer notifications for both and verify the result.
web::TestWebState* web_state_a = AddWebStateToList(true);
web::TestWebState* web_state_b = AddWebStateToList(false);
ASSERT_EQ(web_state_a, web_state_list_.GetActiveWebState());
web_state_a->OnRenderProcessGone();
web_state_b->OnRenderProcessGone();
// The observer should get notifications for both web states.
EXPECT_TRUE(observer_.WasInvokedFor(web_state_a));
EXPECT_TRUE(observer_.WasInvokedFor(web_state_b));
}
TEST_F(AllWebStateObservationForwarderTest, TestDetachActiveWebState) {
// Insert three webstates into the list.
web::TestWebState* web_state_a = AddWebStateToList(true);
web::TestWebState* web_state_b = AddWebStateToList(true);
web::TestWebState* web_state_c = AddWebStateToList(true);
ASSERT_EQ(web_state_c, web_state_list_.GetActiveWebState());
// Remove the active web state and send observer notifications.
std::unique_ptr<web::WebState> detached_web_state =
web_state_list_.DetachWebStateAt(web_state_list_.active_index());
web_state_a->OnRenderProcessGone();
web_state_b->OnRenderProcessGone();
web_state_c->OnRenderProcessGone();
// The observer should get notifications for the two remaining web states.
EXPECT_TRUE(observer_.WasInvokedFor(web_state_a));
EXPECT_TRUE(observer_.WasInvokedFor(web_state_b));
EXPECT_FALSE(observer_.WasInvokedFor(web_state_c));
}
TEST_F(AllWebStateObservationForwarderTest, TestDetachNonActiveWebState) {
// Insert three webstates into the list.
web::TestWebState* web_state_a = AddWebStateToList(true);
web::TestWebState* web_state_b = AddWebStateToList(true);
web::TestWebState* web_state_c = AddWebStateToList(true);
ASSERT_EQ(web_state_c, web_state_list_.GetActiveWebState());
// Remove a non-active web state and send observer notifications.
std::unique_ptr<web::WebState> detached_web_state =
web_state_list_.DetachWebStateAt(
web_state_list_.GetIndexOfWebState(web_state_a));
ASSERT_EQ(web_state_c, web_state_list_.GetActiveWebState());
web_state_a->OnRenderProcessGone();
web_state_b->OnRenderProcessGone();
web_state_c->OnRenderProcessGone();
// The observer should get notifications for the two remaining web states.
EXPECT_TRUE(observer_.WasInvokedFor(web_state_b));
EXPECT_TRUE(observer_.WasInvokedFor(web_state_c));
EXPECT_FALSE(observer_.WasInvokedFor(web_state_a));
}
TEST_F(AllWebStateObservationForwarderTest, TestReplaceActiveWebState) {
// Insert two webstates into the list and mark the second one active.
web::TestWebState* web_state_a = AddWebStateToList(true);
web::TestWebState* web_state_b = AddWebStateToList(true);
ASSERT_EQ(web_state_b, web_state_list_.GetActiveWebState());
// Replace the active web state. Send notifications and verify the result.
std::unique_ptr<web::TestWebState> replacement_web_state(
std::make_unique<web::TestWebState>());
web::TestWebState* web_state_c = replacement_web_state.get();
std::unique_ptr<web::WebState> detached_web_state =
web_state_list_.ReplaceWebStateAt(
web_state_list_.GetIndexOfWebState(web_state_b),
std::move(replacement_web_state));
web_state_a->OnRenderProcessGone();
web_state_b->OnRenderProcessGone();
web_state_c->OnRenderProcessGone();
// The observer should get notifications for the two remaining web states.
EXPECT_TRUE(observer_.WasInvokedFor(web_state_a));
EXPECT_TRUE(observer_.WasInvokedFor(web_state_c));
EXPECT_FALSE(observer_.WasInvokedFor(web_state_b));
}
TEST_F(AllWebStateObservationForwarderTest, TestChangeActiveWebState) {
// Insert two webstates into the list and mark the second one active.
web::TestWebState* web_state_a = AddWebStateToList(true);
web::TestWebState* web_state_b = AddWebStateToList(true);
ASSERT_EQ(web_state_b, web_state_list_.GetActiveWebState());
// Make web state A active and send notifications.
web_state_list_.ActivateWebStateAt(
web_state_list_.GetIndexOfWebState(web_state_a));
web_state_a->OnRenderProcessGone();
web_state_b->OnRenderProcessGone();
// The observer should get notifications for both web states.
EXPECT_TRUE(observer_.WasInvokedFor(web_state_a));
EXPECT_TRUE(observer_.WasInvokedFor(web_state_b));
// Make web state B active and send notifications.
observer_.Reset();
web_state_list_.ActivateWebStateAt(
web_state_list_.GetIndexOfWebState(web_state_b));
web_state_a->OnRenderProcessGone();
web_state_b->OnRenderProcessGone();
// The observer should get notifications for both web states.
EXPECT_TRUE(observer_.WasInvokedFor(web_state_a));
EXPECT_TRUE(observer_.WasInvokedFor(web_state_b));
}
TEST_F(AllWebStateObservationForwarderTest, TestNonEmptyInitialWebStateList) {
// Insert two webstates into the list.
web::TestWebState* web_state_a = AddWebStateToList(true);
web::TestWebState* web_state_b = AddWebStateToList(true);
ASSERT_EQ(web_state_b, web_state_list_.GetActiveWebState());
// Recreate the multi observer to simulate creation with an already-populated
// WebStateList.
forwarder_.reset();
forwarder_ = std::make_unique<AllWebStateObservationForwarder>(
&web_state_list_, &observer_);
// Send notifications and verify the result.
web_state_a->OnRenderProcessGone();
web_state_b->OnRenderProcessGone();
// The observer should get notifications for both web states.
EXPECT_TRUE(observer_.WasInvokedFor(web_state_a));
EXPECT_TRUE(observer_.WasInvokedFor(web_state_b));
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment