#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "base/strings/stringprintf.h"
+#include "mojo/application_manager/application_manager.h"
#include "mojo/common/common_type_converters.h"
-#include "mojo/public/cpp/application/application.h"
+#include "mojo/public/cpp/application/application_connection.h"
+#include "mojo/public/cpp/application/application_delegate.h"
+#include "mojo/public/cpp/application/application_impl.h"
#include "mojo/public/cpp/application/connect.h"
#include "mojo/public/cpp/bindings/lib/router.h"
-#include "mojo/service_manager/service_manager.h"
+#include "mojo/public/interfaces/application/service_provider.mojom.h"
#include "mojo/services/public/cpp/geometry/geometry_type_converters.h"
#include "mojo/services/public/cpp/view_manager/types.h"
#include "mojo/services/public/cpp/view_manager/util.h"
#include "ui/gfx/geometry/rect.h"
namespace mojo {
-namespace view_manager {
namespace service {
namespace {
const char kTestServiceURL[] = "mojo:test_url";
+const char kTestServiceURL2[] = "mojo:test_url2";
// ViewManagerProxy is a proxy to an ViewManagerService. It handles invoking
// ViewManagerService functions on the right thread in a synchronous manner
public:
explicit ViewManagerProxy(TestChangeTracker* tracker)
: tracker_(tracker),
+ main_loop_(NULL),
view_manager_(NULL),
quit_count_(0),
router_(NULL) {
SetInstance(this);
}
- virtual ~ViewManagerProxy() {}
+ virtual ~ViewManagerProxy() {
+ }
// Runs a message loop until the single instance has been created.
static ViewManagerProxy* WaitForInstance() {
router_->CloseMessagePipe();
}
+ void ClearChanges() {
+ changes_.clear();
+ tracker_->changes()->clear();
+ }
+
+ void CopyChangesFromTracker() {
+ std::vector<Change> changes;
+ tracker_->changes()->swap(changes);
+ changes_.swap(changes);
+ }
+
// The following functions are cover methods for ViewManagerService. They
// block until the result is received.
bool CreateNode(Id node_id) {
changes_.clear();
- bool result = false;
- view_manager_->CreateNode(node_id,
- base::Bind(&ViewManagerProxy::GotResult,
- base::Unretained(this), &result));
+ ErrorCode result = ERROR_CODE_NONE;
+ view_manager_->CreateView(
+ node_id,
+ base::Bind(&ViewManagerProxy::GotResultWithErrorCode,
+ base::Unretained(this), &result));
+ RunMainLoop();
+ return result == ERROR_CODE_NONE;
+ }
+ ErrorCode CreateNodeWithErrorCode(Id node_id) {
+ changes_.clear();
+ ErrorCode result = ERROR_CODE_NONE;
+ view_manager_->CreateView(
+ node_id,
+ base::Bind(&ViewManagerProxy::GotResultWithErrorCode,
+ base::Unretained(this), &result));
RunMainLoop();
return result;
}
- bool AddNode(Id parent, Id child, Id server_change_id) {
+ bool AddNode(Id parent, Id child) {
changes_.clear();
bool result = false;
- view_manager_->AddNode(parent, child, server_change_id,
+ view_manager_->AddView(parent, child,
base::Bind(&ViewManagerProxy::GotResult,
base::Unretained(this), &result));
RunMainLoop();
return result;
}
- bool RemoveNodeFromParent(Id node_id, Id server_change_id) {
+ bool RemoveNodeFromParent(Id node_id) {
changes_.clear();
bool result = false;
- view_manager_->RemoveNodeFromParent(node_id, server_change_id,
+ view_manager_->RemoveViewFromParent(node_id,
base::Bind(&ViewManagerProxy::GotResult,
base::Unretained(this), &result));
RunMainLoop();
}
bool ReorderNode(Id node_id,
Id relative_node_id,
- OrderDirection direction,
- Id server_change_id) {
+ OrderDirection direction) {
changes_.clear();
bool result = false;
- view_manager_->ReorderNode(node_id, relative_node_id, direction,
- server_change_id,
+ view_manager_->ReorderView(node_id, relative_node_id, direction,
base::Bind(&ViewManagerProxy::GotResult,
base::Unretained(this), &result));
RunMainLoop();
return result;
}
- bool SetView(Id node_id, Id view_id) {
- changes_.clear();
- bool result = false;
- view_manager_->SetView(node_id, view_id,
- base::Bind(&ViewManagerProxy::GotResult,
- base::Unretained(this), &result));
- RunMainLoop();
- return result;
- }
- bool CreateView(Id view_id) {
- changes_.clear();
- bool result = false;
- view_manager_->CreateView(view_id,
- base::Bind(&ViewManagerProxy::GotResult,
- base::Unretained(this), &result));
- RunMainLoop();
- return result;
- }
void GetNodeTree(Id node_id, std::vector<TestNode>* nodes) {
changes_.clear();
- view_manager_->GetNodeTree(node_id,
+ view_manager_->GetViewTree(node_id,
base::Bind(&ViewManagerProxy::GotNodeTree,
base::Unretained(this), nodes));
RunMainLoop();
}
- bool Embed(const std::vector<Id>& nodes) {
+ bool Embed(const Id node_id, const char* url) {
changes_.clear();
base::AutoReset<bool> auto_reset(&in_embed_, true);
bool result = false;
- view_manager_->Embed(kTestServiceURL, Array<Id>::From(nodes),
+ ServiceProviderPtr services;
+ view_manager_->Embed(url, node_id, services.Pass(),
base::Bind(&ViewManagerProxy::GotResult,
base::Unretained(this), &result));
RunMainLoop();
return result;
}
- bool DeleteNode(Id node_id, Id server_change_id) {
- changes_.clear();
- bool result = false;
- view_manager_->DeleteNode(node_id,
- server_change_id,
- base::Bind(&ViewManagerProxy::GotResult,
- base::Unretained(this), &result));
- RunMainLoop();
- return result;
- }
- bool DeleteView(Id view_id) {
+ bool DeleteNode(Id node_id) {
changes_.clear();
bool result = false;
- view_manager_->DeleteView(view_id,
+ view_manager_->DeleteView(node_id,
base::Bind(&ViewManagerProxy::GotResult,
base::Unretained(this), &result));
RunMainLoop();
bool SetNodeBounds(Id node_id, const gfx::Rect& bounds) {
changes_.clear();
bool result = false;
- view_manager_->SetNodeBounds(node_id, Rect::From(bounds),
+ view_manager_->SetViewBounds(node_id, Rect::From(bounds),
base::Bind(&ViewManagerProxy::GotResult,
base::Unretained(this), &result));
RunMainLoop();
main_run_loop_->Quit();
}
- void CopyChangesFromTracker() {
- std::vector<Change> changes;
- tracker_->changes()->swap(changes);
- changes_.swap(changes);
- }
-
static void SetInstance(ViewManagerProxy* instance) {
DCHECK(!instance_);
instance_ = instance;
main_run_loop_->Quit();
}
- void GotNodeTree(std::vector<TestNode>* nodes, Array<NodeDataPtr> results) {
- NodeDatasToTestNodes(results, nodes);
+ void GotResultWithErrorCode(ErrorCode* error_code_cache,
+ ErrorCode error_code) {
+ *error_code_cache = error_code;
+ DCHECK(main_run_loop_);
+ main_run_loop_->Quit();
+ }
+
+ void GotNodeTree(std::vector<TestNode>* nodes, Array<ViewDataPtr> results) {
+ ViewDatasToTestNodes(results, nodes);
DCHECK(main_run_loop_);
main_run_loop_->Quit();
}
tracker_.set_delegate(&connection_);
}
- // InterfaceImp:
+ // InterfaceImpl:
virtual void OnConnectionEstablished() OVERRIDE {
connection_.set_router(internal_state()->router());
connection_.set_view_manager(client());
}
- // ViewMangerClient:
- virtual void OnViewManagerConnectionEstablished(
+ // ViewManagerClient:
+ virtual void OnEmbed(
ConnectionSpecificId connection_id,
const String& creator_url,
- Id next_server_change_id,
- Array<NodeDataPtr> nodes) OVERRIDE {
- tracker_.OnViewManagerConnectionEstablished(
- connection_id, creator_url, next_server_change_id, nodes.Pass());
- }
- virtual void OnRootsAdded(Array<NodeDataPtr> nodes) OVERRIDE {
- tracker_.OnRootsAdded(nodes.Pass());
+ ViewDataPtr root,
+ InterfaceRequest<ServiceProvider> services) OVERRIDE {
+ tracker_.OnEmbed(connection_id, creator_url, root.Pass());
}
- virtual void OnServerChangeIdAdvanced(
- Id next_server_change_id) OVERRIDE {
- tracker_.OnServerChangeIdAdvanced(next_server_change_id);
- }
- virtual void OnNodeBoundsChanged(Id node_id,
+ virtual void OnViewBoundsChanged(Id node_id,
RectPtr old_bounds,
RectPtr new_bounds) OVERRIDE {
tracker_.OnNodeBoundsChanged(node_id, old_bounds.Pass(), new_bounds.Pass());
}
- virtual void OnNodeHierarchyChanged(Id node,
+ virtual void OnViewHierarchyChanged(Id node,
Id new_parent,
Id old_parent,
- Id server_change_id,
- Array<NodeDataPtr> nodes) OVERRIDE {
- tracker_.OnNodeHierarchyChanged(node, new_parent, old_parent,
- server_change_id, nodes.Pass());
+ Array<ViewDataPtr> nodes) OVERRIDE {
+ tracker_.OnNodeHierarchyChanged(node, new_parent, old_parent, nodes.Pass());
}
- virtual void OnNodeReordered(Id node_id,
+ virtual void OnViewReordered(Id node_id,
Id relative_node_id,
- OrderDirection direction,
- Id server_change_id) OVERRIDE {
- tracker_.OnNodeReordered(node_id, relative_node_id, direction,
- server_change_id);
- }
- virtual void OnNodeDeleted(Id node, Id server_change_id) OVERRIDE {
- tracker_.OnNodeDeleted(node, server_change_id);
+ OrderDirection direction) OVERRIDE {
+ tracker_.OnNodeReordered(node_id, relative_node_id, direction);
}
- virtual void OnViewDeleted(Id view) OVERRIDE {
- tracker_.OnViewDeleted(view);
+ virtual void OnViewDeleted(Id node) OVERRIDE {
+ tracker_.OnNodeDeleted(node);
}
- virtual void OnNodeViewReplaced(Id node,
- Id new_view_id,
- Id old_view_id) OVERRIDE {
- tracker_.OnNodeViewReplaced(node, new_view_id, old_view_id);
- }
- virtual void OnViewInputEvent(Id view_id,
+ virtual void OnViewInputEvent(Id node_id,
EventPtr event,
const Callback<void()>& callback) OVERRIDE {
- tracker_.OnViewInputEvent(view_id, event.Pass());
+ tracker_.OnNodeInputEvent(node_id, event.Pass());
+ }
+ virtual void Embed(
+ const String& url,
+ InterfaceRequest<ServiceProvider> service_provider) OVERRIDE {
+ tracker_.DelegateEmbed(url);
}
- virtual void DispatchOnViewInputEvent(Id view_id,
- mojo::EventPtr event) OVERRIDE {
+ virtual void DispatchOnViewInputEvent(mojo::EventPtr event) OVERRIDE {
}
private:
// Used with ViewManagerService::Embed(). Creates a
// TestViewManagerClientConnection, which creates and owns the ViewManagerProxy.
-class EmbedServiceLoader : public ServiceLoader {
+class EmbedApplicationLoader : public ApplicationLoader,
+ ApplicationDelegate,
+ public InterfaceFactory<ViewManagerClient> {
public:
- EmbedServiceLoader() {}
- virtual ~EmbedServiceLoader() {}
-
- // ServiceLoader:
- virtual void LoadService(ServiceManager* manager,
- const GURL& url,
- ScopedMessagePipeHandle shell_handle) OVERRIDE {
- scoped_ptr<Application> app(new Application(shell_handle.Pass()));
- app->AddService<TestViewManagerClientConnection>();
+ EmbedApplicationLoader() {}
+ virtual ~EmbedApplicationLoader() {}
+
+ // ApplicationLoader implementation:
+ virtual void Load(ApplicationManager* manager,
+ const GURL& url,
+ scoped_refptr<LoadCallbacks> callbacks) OVERRIDE {
+ ScopedMessagePipeHandle shell_handle = callbacks->RegisterApplication();
+ if (!shell_handle.is_valid())
+ return;
+ scoped_ptr<ApplicationImpl> app(new ApplicationImpl(this,
+ shell_handle.Pass()));
apps_.push_back(app.release());
}
- virtual void OnServiceError(ServiceManager* manager,
- const GURL& url) OVERRIDE {
+ virtual void OnServiceError(ApplicationManager* manager,
+ const GURL& url) OVERRIDE {}
+
+ // ApplicationDelegate implementation:
+ virtual bool ConfigureIncomingConnection(ApplicationConnection* connection)
+ OVERRIDE {
+ connection->AddService(this);
+ return true;
+ }
+
+ // InterfaceFactory<ViewManagerClient> implementation:
+ virtual void Create(ApplicationConnection* connection,
+ InterfaceRequest<ViewManagerClient> request) OVERRIDE {
+ BindToRequest(new TestViewManagerClientConnection, &request);
}
private:
- ScopedVector<Application> apps_;
+ ScopedVector<ApplicationImpl> apps_;
- DISALLOW_COPY_AND_ASSIGN(EmbedServiceLoader);
+ DISALLOW_COPY_AND_ASSIGN(EmbedApplicationLoader);
};
// Creates an id used for transport from the specified parameters.
return (connection_id << 16) | node_id;
}
-// Creates an id used for transport from the specified parameters.
-Id BuildViewId(ConnectionSpecificId connection_id,
- ConnectionSpecificId view_id) {
- return (connection_id << 16) | view_id;
-}
-
-// Callback from EmbedRoot(). |result| is the result of the
+// Callback from Embed(). |result| is the result of the
// Embed() call and |run_loop| the nested RunLoop.
-void EmbedRootCallback(bool* result_cache,
- base::RunLoop* run_loop,
- bool result) {
+void EmbedCallback(bool* result_cache, base::RunLoop* run_loop, bool result) {
*result_cache = result;
run_loop->Quit();
}
-// Resposible for establishing the initial ViewManagerService connection. Blocks
-// until result is determined.
-bool EmbedRoot(ViewManagerInitService* view_manager_init,
- const std::string& url) {
+// Embed from an application that does not yet have a view manager connection.
+// Blocks until result is determined.
+bool InitEmbed(ViewManagerInitService* view_manager_init,
+ const std::string& url,
+ size_t number_of_calls) {
bool result = false;
base::RunLoop run_loop;
- view_manager_init->EmbedRoot(url, base::Bind(&EmbedRootCallback,
- &result, &run_loop));
+ for (size_t i = 0; i < number_of_calls; ++i) {
+ ServiceProviderPtr sp;
+ view_manager_init->Embed(url, sp.Pass(),
+ base::Bind(&EmbedCallback, &result, &run_loop));
+ }
run_loop.Run();
return result;
}
class ViewManagerTest : public testing::Test {
public:
- ViewManagerTest() : connection_(NULL), connection2_(NULL) {}
+ ViewManagerTest()
+ : connection_(NULL),
+ connection2_(NULL),
+ connection3_(NULL) {}
virtual void SetUp() OVERRIDE {
test_helper_.Init();
test_helper_.SetLoaderForURL(
- scoped_ptr<ServiceLoader>(new EmbedServiceLoader()),
+ scoped_ptr<ApplicationLoader>(new EmbedApplicationLoader()),
GURL(kTestServiceURL));
- ConnectToService(test_helper_.service_provider(),
- "mojo:mojo_view_manager",
- &view_manager_init_);
- ASSERT_TRUE(EmbedRoot(view_manager_init_.get(), kTestServiceURL));
+ test_helper_.SetLoaderForURL(
+ scoped_ptr<ApplicationLoader>(new EmbedApplicationLoader()),
+ GURL(kTestServiceURL2));
+
+ test_helper_.application_manager()->ConnectToService(
+ GURL("mojo:mojo_view_manager"), &view_manager_init_);
+ ASSERT_TRUE(InitEmbed(view_manager_init_.get(), kTestServiceURL, 1));
connection_ = ViewManagerProxy::WaitForInstance();
ASSERT_TRUE(connection_ != NULL);
}
virtual void TearDown() OVERRIDE {
+ if (connection3_)
+ connection3_->Destroy();
if (connection2_)
connection2_->Destroy();
if (connection_)
}
protected:
- void EstablishSecondConnectionWithRoots(Id id1, Id id2) {
- std::vector<Id> node_ids;
- node_ids.push_back(id1);
- if (id2 != 0)
- node_ids.push_back(id2);
- ASSERT_TRUE(connection_->Embed(node_ids));
+ void EstablishSecondConnectionWithRoot(Id root_id) {
+ ASSERT_TRUE(connection_->Embed(root_id, kTestServiceURL));
connection2_ = ViewManagerProxy::WaitForInstance();
ASSERT_TRUE(connection2_ != NULL);
connection2_->DoRunLoopUntilChangesCount(1);
if (create_initial_node)
ASSERT_TRUE(connection_->CreateNode(BuildNodeId(1, 1)));
ASSERT_NO_FATAL_FAILURE(
- EstablishSecondConnectionWithRoots(BuildNodeId(1, 1), 0));
+ EstablishSecondConnectionWithRoot(BuildNodeId(1, 1)));
const std::vector<Change>& changes(connection2_->changes());
ASSERT_EQ(1u, changes.size());
- EXPECT_EQ("OnConnectionEstablished creator=mojo:test_url",
+ EXPECT_EQ("OnEmbed creator=mojo:test_url",
ChangesToDescription1(changes)[0]);
if (create_initial_node) {
- EXPECT_EQ("[node=1,1 parent=null view=null]",
+ EXPECT_EQ("[node=1,1 parent=null]",
ChangeNodeDescription(changes));
}
}
+ void EstablishThirdConnection(ViewManagerProxy* owner, Id root_id) {
+ ASSERT_TRUE(connection3_ == NULL);
+ ASSERT_TRUE(owner->Embed(root_id, kTestServiceURL2));
+ connection3_ = ViewManagerProxy::WaitForInstance();
+ ASSERT_TRUE(connection3_ != NULL);
+ connection3_->DoRunLoopUntilChangesCount(1);
+ ASSERT_EQ(1u, connection3_->changes().size());
+ EXPECT_EQ("OnEmbed creator=mojo:test_url",
+ ChangesToDescription1(connection3_->changes())[0]);
+ }
+
void DestroySecondConnection() {
connection2_->Destroy();
connection2_ = NULL;
}
base::ShadowingAtExitManager at_exit_;
- base::MessageLoop loop_;
shell::ShellTestHelper test_helper_;
ViewManagerInitServicePtr view_manager_init_;
+ // NOTE: this connection is the root. As such, it has special permissions.
ViewManagerProxy* connection_;
ViewManagerProxy* connection2_;
+ ViewManagerProxy* connection3_;
DISALLOW_COPY_AND_ASSIGN(ViewManagerTest);
};
-// TODO(sky): reenable tests: http://crbug.com/385475
+TEST_F(ViewManagerTest, SecondEmbedRoot_InitService) {
+ ASSERT_TRUE(InitEmbed(view_manager_init_.get(), kTestServiceURL, 1));
+ connection_->DoRunLoopUntilChangesCount(1);
+ EXPECT_EQ(kTestServiceURL, connection_->changes()[0].embed_url);
+}
+
+TEST_F(ViewManagerTest, SecondEmbedRoot_Service) {
+ ASSERT_TRUE(connection_->Embed(BuildNodeId(0, 0), kTestServiceURL));
+ connection_->DoRunLoopUntilChangesCount(1);
+ EXPECT_EQ(kTestServiceURL, connection_->changes()[0].embed_url);
+}
+
+TEST_F(ViewManagerTest, MultipleEmbedRootsBeforeWTHReady) {
+ ASSERT_TRUE(InitEmbed(view_manager_init_.get(), kTestServiceURL, 2));
+ connection_->DoRunLoopUntilChangesCount(2);
+ EXPECT_EQ(kTestServiceURL, connection_->changes()[0].embed_url);
+ EXPECT_EQ(kTestServiceURL, connection_->changes()[1].embed_url);
+}
// Verifies client gets a valid id.
-TEST_F(ViewManagerTest, DISABLED_ValidId) {
+#if defined(OS_LINUX)
+// http://crbug.com/396492
+#define MAYBE_ValidId DISABLED_ValidId
+#else
+#define MAYBE_ValidId ValidId
+#endif
+TEST_F(ViewManagerTest, MAYBE_ValidId) {
// TODO(beng): this should really have the URL of the application that
// connected to ViewManagerInit.
- EXPECT_EQ("OnConnectionEstablished creator=",
+ EXPECT_EQ("OnEmbed creator=",
ChangesToDescription1(connection_->changes())[0]);
// All these tests assume 1 for the client id. The only real assertion here is
// the client id is not zero, but adding this as rest of code here assumes 1.
EXPECT_EQ(1, connection_->changes()[0].connection_id);
-
- // Change ids start at 1 as well.
- EXPECT_EQ(static_cast<Id>(1), connection_->changes()[0].change_id);
}
// Verifies two clients/connections get different ids.
-TEST_F(ViewManagerTest, DISABLED_TwoClientsGetDifferentConnectionIds) {
+TEST_F(ViewManagerTest, TwoClientsGetDifferentConnectionIds) {
ASSERT_NO_FATAL_FAILURE(EstablishSecondConnection(true));
- EXPECT_EQ("OnConnectionEstablished creator=mojo:test_url",
+ EXPECT_EQ("OnEmbed creator=mojo:test_url",
ChangesToDescription1(connection2_->changes())[0]);
- // It isn't strickly necessary that the second connection gets 2, but these
+ // It isn't strictly necessary that the second connection gets 2, but these
// tests are written assuming that is the case. The key thing is the
// connection ids of |connection_| and |connection2_| differ.
EXPECT_EQ(2, connection2_->changes()[0].connection_id);
-
- // Change ids start at 1 as well.
- EXPECT_EQ(static_cast<Id>(1), connection2_->changes()[0].change_id);
}
-// Verifies client gets a valid id.
-TEST_F(ViewManagerTest, DISABLED_CreateNode) {
+// Verifies when Embed() is invoked any child nodes are removed.
+TEST_F(ViewManagerTest, NodesRemovedWhenEmbedding) {
+ // Two nodes 1 and 2. 2 is parented to 1.
ASSERT_TRUE(connection_->CreateNode(BuildNodeId(1, 1)));
- EXPECT_TRUE(connection_->changes().empty());
+ ASSERT_TRUE(connection_->CreateNode(BuildNodeId(1, 2)));
+ ASSERT_TRUE(connection_->AddNode(BuildNodeId(1, 1), BuildNodeId(1, 2)));
- // Can't create a node with the same id.
- ASSERT_FALSE(connection_->CreateNode(BuildNodeId(1, 1)));
- EXPECT_TRUE(connection_->changes().empty());
+ ASSERT_NO_FATAL_FAILURE(EstablishSecondConnection(false));
+ EXPECT_EQ("[node=1,1 parent=null]",
+ ChangeNodeDescription(connection2_->changes()));
- // Can't create a node with a bogus connection id.
- EXPECT_FALSE(connection_->CreateNode(BuildNodeId(2, 1)));
- EXPECT_TRUE(connection_->changes().empty());
-}
+ // Embed() removed node 2.
+ {
+ std::vector<TestNode> nodes;
+ connection_->GetNodeTree(BuildNodeId(1, 2), &nodes);
+ ASSERT_EQ(1u, nodes.size());
+ EXPECT_EQ("node=1,2 parent=null", nodes[0].ToString());
+ }
-TEST_F(ViewManagerTest, DISABLED_CreateViewFailsWithBogusConnectionId) {
- EXPECT_FALSE(connection_->CreateView(BuildViewId(2, 1)));
- EXPECT_TRUE(connection_->changes().empty());
-}
+ // |connection2_| should not see node 2.
+ {
+ std::vector<TestNode> nodes;
+ connection2_->GetNodeTree(BuildNodeId(1, 1), &nodes);
+ ASSERT_EQ(1u, nodes.size());
+ EXPECT_EQ("node=1,1 parent=null", nodes[0].ToString());
+ }
+ {
+ std::vector<TestNode> nodes;
+ connection2_->GetNodeTree(BuildNodeId(1, 2), &nodes);
+ EXPECT_TRUE(nodes.empty());
+ }
-// Verifies hierarchy changes.
-TEST_F(ViewManagerTest, DISABLED_AddRemoveNotify) {
- ASSERT_TRUE(connection_->CreateNode(BuildNodeId(1, 2)));
- ASSERT_TRUE(connection_->CreateNode(BuildNodeId(1, 3)));
+ // Nodes 3 and 4 in connection 2.
+ ASSERT_TRUE(connection2_->CreateNode(BuildNodeId(2, 3)));
+ ASSERT_TRUE(connection2_->CreateNode(BuildNodeId(2, 4)));
+ ASSERT_TRUE(connection2_->AddNode(BuildNodeId(2, 3), BuildNodeId(2, 4)));
- ASSERT_NO_FATAL_FAILURE(EstablishSecondConnection(true));
+ // Connection 3 rooted at 2.
+ ASSERT_NO_FATAL_FAILURE(EstablishThirdConnection(connection2_,
+ BuildNodeId(2, 3)));
- // Make 3 a child of 2.
+ // Node 4 should no longer have a parent.
{
- ASSERT_TRUE(connection_->AddNode(BuildNodeId(1, 2), BuildNodeId(1, 3), 1));
- EXPECT_TRUE(connection_->changes().empty());
+ std::vector<TestNode> nodes;
+ connection2_->GetNodeTree(BuildNodeId(2, 3), &nodes);
+ ASSERT_EQ(1u, nodes.size());
+ EXPECT_EQ("node=2,3 parent=null", nodes[0].ToString());
- connection2_->DoRunLoopUntilChangesCount(1);
- const Changes changes(ChangesToDescription1(connection2_->changes()));
- ASSERT_EQ(1u, changes.size());
- EXPECT_EQ("ServerChangeIdAdvanced 2", changes[0]);
+ nodes.clear();
+ connection2_->GetNodeTree(BuildNodeId(2, 4), &nodes);
+ ASSERT_EQ(1u, nodes.size());
+ EXPECT_EQ("node=2,4 parent=null", nodes[0].ToString());
}
- // Remove 3 from its parent.
+ // And node 4 should not be visible to connection 3.
{
- ASSERT_TRUE(connection_->RemoveNodeFromParent(BuildNodeId(1, 3), 2));
- EXPECT_TRUE(connection_->changes().empty());
-
- connection2_->DoRunLoopUntilChangesCount(1);
- const Changes changes(ChangesToDescription1(connection2_->changes()));
- ASSERT_EQ(1u, changes.size());
- EXPECT_EQ("ServerChangeIdAdvanced 3", changes[0]);
+ std::vector<TestNode> nodes;
+ connection3_->GetNodeTree(BuildNodeId(2, 3), &nodes);
+ ASSERT_EQ(1u, nodes.size());
+ EXPECT_EQ("node=2,3 parent=null", nodes[0].ToString());
}
}
-// Verifies AddNode fails when node is already in position.
-TEST_F(ViewManagerTest, DISABLED_AddNodeWithNoChange) {
- ASSERT_TRUE(connection_->CreateNode(BuildNodeId(1, 2)));
- ASSERT_TRUE(connection_->CreateNode(BuildNodeId(1, 3)));
-
+// Verifies once Embed() has been invoked the parent connection can't see any
+// children.
+TEST_F(ViewManagerTest, CantAccessChildrenOfEmbeddedNode) {
ASSERT_NO_FATAL_FAILURE(EstablishSecondConnection(true));
- // Make 3 a child of 2.
+ ASSERT_TRUE(connection2_->CreateNode(BuildNodeId(2, 2)));
+ ASSERT_TRUE(connection2_->AddNode(BuildNodeId(1, 1), BuildNodeId(2, 2)));
+
+ ASSERT_NO_FATAL_FAILURE(EstablishThirdConnection(connection2_,
+ BuildNodeId(2, 2)));
+
+ ASSERT_TRUE(connection3_->CreateNode(BuildNodeId(3, 3)));
+ ASSERT_TRUE(connection3_->AddNode(BuildNodeId(2, 2), BuildNodeId(3, 3)));
+
+ // Even though 3 is a child of 2 connection 2 can't see 3 as it's from a
+ // different connection.
{
- ASSERT_TRUE(connection_->AddNode(BuildNodeId(1, 2), BuildNodeId(1, 3), 1));
+ std::vector<TestNode> nodes;
+ connection2_->GetNodeTree(BuildNodeId(2, 2), &nodes);
+ ASSERT_EQ(1u, nodes.size());
+ EXPECT_EQ("node=2,2 parent=1,1", nodes[0].ToString());
+ }
- connection2_->DoRunLoopUntilChangesCount(1);
- const Changes changes(ChangesToDescription1(connection2_->changes()));
- ASSERT_EQ(1u, changes.size());
- EXPECT_EQ("ServerChangeIdAdvanced 2", changes[0]);
+ {
+ std::vector<TestNode> nodes;
+ connection2_->GetNodeTree(BuildNodeId(3, 3), &nodes);
+ EXPECT_TRUE(nodes.empty());
}
- // Try again, this should fail.
+ // Connection 2 shouldn't be able to get node 3 at all.
{
- EXPECT_FALSE(connection_->AddNode(BuildNodeId(1, 2), BuildNodeId(1, 3), 2));
+ std::vector<TestNode> nodes;
+ connection2_->GetNodeTree(BuildNodeId(3, 3), &nodes);
+ EXPECT_TRUE(nodes.empty());
}
+
+ // Connection 1 should be able to see it all (its the root).
+ {
+ std::vector<TestNode> nodes;
+ connection_->GetNodeTree(BuildNodeId(1, 1), &nodes);
+ ASSERT_EQ(3u, nodes.size());
+ EXPECT_EQ("node=1,1 parent=null", nodes[0].ToString());
+ EXPECT_EQ("node=2,2 parent=1,1", nodes[1].ToString());
+ EXPECT_EQ("node=3,3 parent=2,2", nodes[2].ToString());
+ }
+}
+
+// Verifies once Embed() has been invoked the parent can't mutate the children.
+TEST_F(ViewManagerTest, CantModifyChildrenOfEmbeddedNode) {
+ ASSERT_NO_FATAL_FAILURE(EstablishSecondConnection(true));
+
+ ASSERT_TRUE(connection2_->CreateNode(BuildNodeId(2, 2)));
+ ASSERT_TRUE(connection2_->AddNode(BuildNodeId(1, 1), BuildNodeId(2, 2)));
+
+ ASSERT_NO_FATAL_FAILURE(EstablishThirdConnection(connection2_,
+ BuildNodeId(2, 2)));
+
+ ASSERT_TRUE(connection2_->CreateNode(BuildNodeId(2, 3)));
+ // Connection 2 shouldn't be able to add anything to the node anymore.
+ ASSERT_FALSE(connection2_->AddNode(BuildNodeId(2, 2), BuildNodeId(2, 3)));
+
+ // Create node 3 in connection 3 and add it to node 3.
+ ASSERT_TRUE(connection3_->CreateNode(BuildNodeId(3, 3)));
+ ASSERT_TRUE(connection3_->AddNode(BuildNodeId(2, 2), BuildNodeId(3, 3)));
+
+ // Connection 2 shouldn't be able to remove node 3.
+ ASSERT_FALSE(connection2_->RemoveNodeFromParent(BuildNodeId(3, 3)));
+}
+
+// Verifies client gets a valid id.
+TEST_F(ViewManagerTest, CreateNode) {
+ ASSERT_TRUE(connection_->CreateNode(BuildNodeId(1, 1)));
+ EXPECT_TRUE(connection_->changes().empty());
+
+ // Can't create a node with the same id.
+ ASSERT_EQ(ERROR_CODE_VALUE_IN_USE,
+ connection_->CreateNodeWithErrorCode(BuildNodeId(1, 1)));
+ EXPECT_TRUE(connection_->changes().empty());
+
+ // Can't create a node with a bogus connection id.
+ EXPECT_EQ(ERROR_CODE_ILLEGAL_ARGUMENT,
+ connection_->CreateNodeWithErrorCode(BuildNodeId(2, 1)));
+ EXPECT_TRUE(connection_->changes().empty());
}
// Verifies AddNode fails when node is already in position.
-TEST_F(ViewManagerTest, DISABLED_AddAncestorFails) {
+TEST_F(ViewManagerTest, AddNodeWithNoChange) {
ASSERT_TRUE(connection_->CreateNode(BuildNodeId(1, 2)));
ASSERT_TRUE(connection_->CreateNode(BuildNodeId(1, 3)));
ASSERT_NO_FATAL_FAILURE(EstablishSecondConnection(true));
// Make 3 a child of 2.
- {
- ASSERT_TRUE(connection_->AddNode(BuildNodeId(1, 2), BuildNodeId(1, 3), 1));
- connection2_->DoRunLoopUntilChangesCount(1);
- const Changes changes(ChangesToDescription1(connection2_->changes()));
- ASSERT_EQ(1u, changes.size());
- EXPECT_EQ("ServerChangeIdAdvanced 2", changes[0]);
- }
+ ASSERT_TRUE(connection_->AddNode(BuildNodeId(1, 2), BuildNodeId(1, 3)));
- // Try to make 2 a child of 3, this should fail since 2 is an ancestor of 3.
- {
- EXPECT_FALSE(connection_->AddNode(BuildNodeId(1, 3), BuildNodeId(1, 2), 2));
- }
+ // Try again, this should fail.
+ EXPECT_FALSE(connection_->AddNode(BuildNodeId(1, 2), BuildNodeId(1, 3)));
}
-// Verifies adding with an invalid id fails.
-TEST_F(ViewManagerTest, DISABLED_AddWithInvalidServerId) {
- // Create two nodes.
- ASSERT_TRUE(connection_->CreateNode(BuildNodeId(1, 1)));
+// Verifies AddNode fails when node is already in position.
+TEST_F(ViewManagerTest, AddAncestorFails) {
ASSERT_TRUE(connection_->CreateNode(BuildNodeId(1, 2)));
+ ASSERT_TRUE(connection_->CreateNode(BuildNodeId(1, 3)));
+
+ ASSERT_NO_FATAL_FAILURE(EstablishSecondConnection(true));
- // Make 2 a child of 1. Supply an invalid change id, which should fail.
- ASSERT_FALSE(connection_->AddNode(BuildNodeId(1, 1), BuildNodeId(1, 2), 0));
+ // Make 3 a child of 2.
+ ASSERT_TRUE(connection_->AddNode(BuildNodeId(1, 2), BuildNodeId(1, 3)));
+
+ // Try to make 2 a child of 3, this should fail since 2 is an ancestor of 3.
+ EXPECT_FALSE(connection_->AddNode(BuildNodeId(1, 3), BuildNodeId(1, 2)));
}
// Verifies adding to root sends right notifications.
-TEST_F(ViewManagerTest, DISABLED_AddToRoot) {
+TEST_F(ViewManagerTest, AddToRoot) {
ASSERT_TRUE(connection_->CreateNode(BuildNodeId(1, 21)));
ASSERT_TRUE(connection_->CreateNode(BuildNodeId(1, 3)));
ASSERT_NO_FATAL_FAILURE(EstablishSecondConnection(true));
// Make 3 a child of 21.
- {
- ASSERT_TRUE(connection_->AddNode(BuildNodeId(1, 21), BuildNodeId(1, 3), 1));
-
- connection2_->DoRunLoopUntilChangesCount(1);
- const Changes changes(ChangesToDescription1(connection2_->changes()));
- ASSERT_EQ(1u, changes.size());
- EXPECT_EQ("ServerChangeIdAdvanced 2", changes[0]);
- }
+ ASSERT_TRUE(connection_->AddNode(BuildNodeId(1, 21), BuildNodeId(1, 3)));
// Make 21 a child of 1.
- {
- ASSERT_TRUE(connection_->AddNode(BuildNodeId(1, 1), BuildNodeId(1, 21), 2));
-
- connection2_->DoRunLoopUntilChangesCount(1);
- const Changes changes(ChangesToDescription1(connection2_->changes()));
- ASSERT_EQ(1u, changes.size());
- EXPECT_EQ(
- "HierarchyChanged change_id=2 node=1,21 new_parent=1,1 old_parent=null",
- changes[0]);
- }
+ ASSERT_TRUE(connection_->AddNode(BuildNodeId(1, 1), BuildNodeId(1, 21)));
+
+ // Connection 2 should not be told anything (because the node is from a
+ // different connection). Create a node to ensure we got a response from
+ // the server.
+ ASSERT_TRUE(connection2_->CreateNode(BuildNodeId(2, 100)));
+ connection2_->CopyChangesFromTracker();
+ EXPECT_TRUE(connection2_->changes().empty());
}
// Verifies HierarchyChanged is correctly sent for various adds/removes.
-TEST_F(ViewManagerTest, DISABLED_NodeHierarchyChangedNodes) {
+TEST_F(ViewManagerTest, NodeHierarchyChangedNodes) {
+ // 1,2->1,11.
ASSERT_TRUE(connection_->CreateNode(BuildNodeId(1, 2)));
ASSERT_TRUE(connection_->CreateNode(BuildNodeId(1, 11)));
- // Make 11 a child of 2.
- ASSERT_TRUE(connection_->AddNode(BuildNodeId(1, 2), BuildNodeId(1, 11), 1));
+ ASSERT_TRUE(connection_->AddNode(BuildNodeId(1, 2), BuildNodeId(1, 11)));
ASSERT_NO_FATAL_FAILURE(EstablishSecondConnection(true));
- // Make 2 a child of 1.
+ // 1,1->1,2->1,11
{
- ASSERT_TRUE(connection_->AddNode(BuildNodeId(1, 1), BuildNodeId(1, 2), 2));
-
- // Client 2 should get a hierarchy change that includes the new nodes as it
- // has not yet seen them.
- connection2_->DoRunLoopUntilChangesCount(1);
- const Changes changes(ChangesToDescription1(connection2_->changes()));
- ASSERT_EQ(1u, changes.size());
- EXPECT_EQ(
- "HierarchyChanged change_id=2 node=1,2 new_parent=1,1 old_parent=null",
- changes[0]);
- EXPECT_EQ("[node=1,2 parent=1,1 view=null],"
- "[node=1,11 parent=1,2 view=null]",
- ChangeNodeDescription(connection2_->changes()));
+ // Client 2 should not get anything (1,2 is from another connection).
+ connection2_->ClearChanges();
+ ASSERT_TRUE(connection_->AddNode(BuildNodeId(1, 1), BuildNodeId(1, 2)));
+ ASSERT_TRUE(connection2_->CreateNode(BuildNodeId(2, 100)));
+ connection2_->CopyChangesFromTracker();
+ EXPECT_TRUE(connection2_->changes().empty());
}
- // Add 1 to the root.
+ // 0,1->1,1->1,2->1,11.
{
- ASSERT_TRUE(connection_->AddNode(BuildNodeId(0, 1), BuildNodeId(1, 1), 3));
-
- // Client 2 should get a hierarchy change that includes the new nodes as it
- // has not yet seen them.
- connection2_->DoRunLoopUntilChangesCount(1);
- const Changes changes(ChangesToDescription1(connection2_->changes()));
- ASSERT_EQ(1u, changes.size());
- EXPECT_EQ(
- "HierarchyChanged change_id=3 node=1,1 new_parent=null old_parent=null",
- changes[0]);
- EXPECT_EQ(std::string(), ChangeNodeDescription(connection2_->changes()));
+ // Again, client 2 should not get anything.
+ connection2_->ClearChanges();
+ ASSERT_TRUE(connection_->AddNode(BuildNodeId(0, 1), BuildNodeId(1, 1)));
+ ASSERT_TRUE(connection2_->CreateNode(BuildNodeId(2, 101)));
+ connection2_->CopyChangesFromTracker();
+ EXPECT_TRUE(connection2_->changes().empty());
}
- // Remove 1 from its parent.
+ // 1,1->1,2->1,11.
{
- ASSERT_TRUE(connection_->RemoveNodeFromParent(BuildNodeId(1, 1), 4));
+ connection2_->ClearChanges();
+ ASSERT_TRUE(connection_->RemoveNodeFromParent(BuildNodeId(1, 1)));
EXPECT_TRUE(connection_->changes().empty());
-
- connection2_->DoRunLoopUntilChangesCount(1);
- const Changes changes(ChangesToDescription1(connection2_->changes()));
- ASSERT_EQ(1u, changes.size());
- EXPECT_EQ(
- "HierarchyChanged change_id=4 node=1,1 new_parent=null old_parent=null",
- changes[0]);
+ ASSERT_TRUE(connection2_->CreateNode(BuildNodeId(2, 102)));
+ connection2_->CopyChangesFromTracker();
+ EXPECT_TRUE(connection2_->changes().empty());
}
- // Create another node, 111, parent it to 11.
+ // 1,1->1,2->1,11->1,111.
ASSERT_TRUE(connection_->CreateNode(BuildNodeId(1, 111)));
{
- ASSERT_TRUE(connection_->AddNode(BuildNodeId(1, 11), BuildNodeId(1, 111),
- 5));
-
- connection2_->DoRunLoopUntilChangesCount(1);
- const Changes changes(ChangesToDescription1(connection2_->changes()));
- ASSERT_EQ(1u, changes.size());
- EXPECT_EQ(
- "HierarchyChanged change_id=5 node=1,111 new_parent=1,11 "
- "old_parent=null", changes[0]);
- EXPECT_EQ("[node=1,111 parent=1,11 view=null]",
- ChangeNodeDescription(connection2_->changes()));
+ connection2_->ClearChanges();
+ ASSERT_TRUE(connection_->AddNode(BuildNodeId(1, 11), BuildNodeId(1, 111)));
+ ASSERT_TRUE(connection2_->CreateNode(BuildNodeId(2, 103)));
+ connection2_->CopyChangesFromTracker();
+ EXPECT_TRUE(connection2_->changes().empty());
}
- // Reattach 1 to the root.
+ // 0,1->1,1->1,2->1,11->1,111
{
- ASSERT_TRUE(connection_->AddNode(BuildNodeId(0, 1), BuildNodeId(1, 1), 6));
-
- connection2_->DoRunLoopUntilChangesCount(1);
- const Changes changes(ChangesToDescription1(connection2_->changes()));
- ASSERT_EQ(1u, changes.size());
- EXPECT_EQ(
- "HierarchyChanged change_id=6 node=1,1 new_parent=null old_parent=null",
- changes[0]);
- EXPECT_EQ(std::string(), ChangeNodeDescription(connection2_->changes()));
+ connection2_->ClearChanges();
+ ASSERT_TRUE(connection_->AddNode(BuildNodeId(0, 1), BuildNodeId(1, 1)));
+ ASSERT_TRUE(connection2_->CreateNode(BuildNodeId(2, 104)));
+ connection2_->CopyChangesFromTracker();
+ EXPECT_TRUE(connection2_->changes().empty());
}
}
-TEST_F(ViewManagerTest, DISABLED_NodeHierarchyChangedAddingKnownToUnknown) {
+TEST_F(ViewManagerTest, NodeHierarchyChangedAddingKnownToUnknown) {
// Create the following structure: root -> 1 -> 11 and 2->21 (2 has no
// parent).
- ASSERT_TRUE(connection_->CreateNode(BuildNodeId(1, 1)));
- ASSERT_TRUE(connection_->CreateNode(BuildNodeId(1, 11)));
- ASSERT_TRUE(connection_->CreateNode(BuildNodeId(1, 2)));
- ASSERT_TRUE(connection_->CreateNode(BuildNodeId(1, 21)));
+ ASSERT_NO_FATAL_FAILURE(EstablishSecondConnection(true));
- // Set up the hierarchy.
- ASSERT_TRUE(connection_->AddNode(BuildNodeId(0, 1), BuildNodeId(1, 1), 1));
- ASSERT_TRUE(connection_->AddNode(BuildNodeId(1, 1), BuildNodeId(1, 11), 2));
- ASSERT_TRUE(connection_->AddNode(BuildNodeId(1, 2), BuildNodeId(1, 21), 3));
+ ASSERT_TRUE(connection2_->CreateNode(BuildNodeId(2, 11)));
+ ASSERT_TRUE(connection2_->CreateNode(BuildNodeId(2, 2)));
+ ASSERT_TRUE(connection2_->CreateNode(BuildNodeId(2, 21)));
- ASSERT_NO_FATAL_FAILURE(EstablishSecondConnection(false));
- {
- EXPECT_EQ("[node=1,1 parent=null view=null],"
- "[node=1,11 parent=1,1 view=null]",
- ChangeNodeDescription(connection2_->changes()));
- }
+ // Set up the hierarchy.
+ ASSERT_TRUE(connection_->AddNode(BuildNodeId(0, 1), BuildNodeId(1, 1)));
+ ASSERT_TRUE(connection2_->AddNode(BuildNodeId(1, 1), BuildNodeId(2, 11)));
+ ASSERT_TRUE(connection2_->AddNode(BuildNodeId(2, 2), BuildNodeId(2, 21)));
- // Remove 11, should result in a delete (since 11 is no longer in connection
- // 2's root).
+ // Remove 11, should result in a hierarchy change for the root.
{
- ASSERT_TRUE(connection_->RemoveNodeFromParent(BuildNodeId(1, 11), 4));
+ connection_->ClearChanges();
+ ASSERT_TRUE(connection2_->RemoveNodeFromParent(BuildNodeId(2, 11)));
- connection2_->DoRunLoopUntilChangesCount(1);
- const Changes changes(ChangesToDescription1(connection2_->changes()));
+ connection_->DoRunLoopUntilChangesCount(1);
+ const Changes changes(ChangesToDescription1(connection_->changes()));
ASSERT_EQ(1u, changes.size());
- EXPECT_EQ("NodeDeleted change_id=4 node=1,11", changes[0]);
+ EXPECT_EQ("HierarchyChanged node=2,11 new_parent=null old_parent=1,1",
+ changes[0]);
}
// Add 2 to 1.
{
- ASSERT_TRUE(connection_->AddNode(BuildNodeId(1, 1), BuildNodeId(1, 2), 5));
+ ASSERT_TRUE(connection2_->AddNode(BuildNodeId(1, 1), BuildNodeId(2, 2)));
- connection2_->DoRunLoopUntilChangesCount(1);
- const Changes changes(ChangesToDescription1(connection2_->changes()));
+ connection_->DoRunLoopUntilChangesCount(1);
+ const Changes changes(ChangesToDescription1(connection_->changes()));
ASSERT_EQ(1u, changes.size());
- EXPECT_EQ(
- "HierarchyChanged change_id=5 node=1,2 new_parent=1,1 old_parent=null",
- changes[0]);
- EXPECT_EQ("[node=1,2 parent=1,1 view=null],"
- "[node=1,21 parent=1,2 view=null]",
- ChangeNodeDescription(connection2_->changes()));
+ EXPECT_EQ("HierarchyChanged node=2,2 new_parent=1,1 old_parent=null",
+ changes[0]);
+ EXPECT_EQ("[node=2,2 parent=1,1],"
+ "[node=2,21 parent=2,2]",
+ ChangeNodeDescription(connection_->changes()));
}
}
-TEST_F(ViewManagerTest, DISABLED_ReorderNode) {
- Id node1_id = BuildNodeId(1, 1);
- Id node2_id = BuildNodeId(1, 2);
- Id node3_id = BuildNodeId(1, 3);
+TEST_F(ViewManagerTest, ReorderNode) {
+ ASSERT_NO_FATAL_FAILURE(EstablishSecondConnection(true));
+
+ Id node1_id = BuildNodeId(2, 1);
+ Id node2_id = BuildNodeId(2, 2);
+ Id node3_id = BuildNodeId(2, 3);
Id node4_id = BuildNodeId(1, 4); // Peer to 1,1
Id node5_id = BuildNodeId(1, 5); // Peer to 1,1
- Id node6_id = BuildNodeId(1, 6); // Child of 1,2.
- Id node7_id = BuildNodeId(1, 7); // Unparented.
- Id node8_id = BuildNodeId(1, 8); // Unparented.
- ASSERT_TRUE(connection_->CreateNode(node1_id));
- ASSERT_TRUE(connection_->CreateNode(node2_id));
- ASSERT_TRUE(connection_->CreateNode(node3_id));
+ Id node6_id = BuildNodeId(2, 6); // Child of 1,2.
+ Id node7_id = BuildNodeId(2, 7); // Unparented.
+ Id node8_id = BuildNodeId(2, 8); // Unparented.
+ ASSERT_TRUE(connection2_->CreateNode(node1_id));
+ ASSERT_TRUE(connection2_->CreateNode(node2_id));
+ ASSERT_TRUE(connection2_->CreateNode(node3_id));
ASSERT_TRUE(connection_->CreateNode(node4_id));
ASSERT_TRUE(connection_->CreateNode(node5_id));
- ASSERT_TRUE(connection_->CreateNode(node6_id));
- ASSERT_TRUE(connection_->CreateNode(node7_id));
- ASSERT_TRUE(connection_->CreateNode(node8_id));
- ASSERT_TRUE(connection_->AddNode(node1_id, node2_id, 1));
- ASSERT_TRUE(connection_->AddNode(node2_id, node6_id, 2));
- ASSERT_TRUE(connection_->AddNode(node1_id, node3_id, 3));
+ ASSERT_TRUE(connection2_->CreateNode(node6_id));
+ ASSERT_TRUE(connection2_->CreateNode(node7_id));
+ ASSERT_TRUE(connection2_->CreateNode(node8_id));
+ ASSERT_TRUE(connection2_->AddNode(node1_id, node2_id));
+ ASSERT_TRUE(connection2_->AddNode(node2_id, node6_id));
+ ASSERT_TRUE(connection2_->AddNode(node1_id, node3_id));
ASSERT_TRUE(connection_->AddNode(
- NodeIdToTransportId(RootNodeId()), node4_id, 4));
+ NodeIdToTransportId(RootNodeId()), node4_id));
ASSERT_TRUE(connection_->AddNode(
- NodeIdToTransportId(RootNodeId()), node5_id, 5));
+ NodeIdToTransportId(RootNodeId()), node5_id));
- ASSERT_NO_FATAL_FAILURE(EstablishSecondConnection(false));
+ ASSERT_TRUE(connection_->AddNode(
+ NodeIdToTransportId(RootNodeId()), node1_id));
{
- connection_->ReorderNode(node2_id, node3_id, ORDER_ABOVE, 6);
+ ASSERT_TRUE(
+ connection2_->ReorderNode(node2_id, node3_id, ORDER_DIRECTION_ABOVE));
- connection2_->DoRunLoopUntilChangesCount(1);
- const Changes changes(ChangesToDescription1(connection2_->changes()));
+ connection_->DoRunLoopUntilChangesCount(1);
+ const Changes changes(ChangesToDescription1(connection_->changes()));
ASSERT_EQ(1u, changes.size());
- EXPECT_EQ(
- "Reordered change_id=6 node=1,2 relative=1,3 direction=above",
- changes[0]);
+ EXPECT_EQ("Reordered node=2,2 relative=2,3 direction=above",
+ changes[0]);
}
{
- connection_->ReorderNode(node2_id, node3_id, ORDER_BELOW, 7);
+ ASSERT_TRUE(connection2_->ReorderNode(
+ node2_id, node3_id, ORDER_DIRECTION_BELOW));
- connection2_->DoRunLoopUntilChangesCount(1);
- const Changes changes(ChangesToDescription1(connection2_->changes()));
+ connection_->DoRunLoopUntilChangesCount(1);
+ const Changes changes(ChangesToDescription1(connection_->changes()));
ASSERT_EQ(1u, changes.size());
- EXPECT_EQ(
- "Reordered change_id=7 node=1,2 relative=1,3 direction=below",
- changes[0]);
+ EXPECT_EQ("Reordered node=2,2 relative=2,3 direction=below",
+ changes[0]);
}
- {
- // node2 is already below node3.
- EXPECT_FALSE(connection_->ReorderNode(node2_id, node3_id, ORDER_BELOW, 8));
- }
+ // node2 is already below node3.
+ EXPECT_FALSE(
+ connection2_->ReorderNode(node2_id, node3_id, ORDER_DIRECTION_BELOW));
- {
- // node4 & 5 are unknown to connection2_.
- EXPECT_FALSE(connection2_->ReorderNode(node4_id, node5_id, ORDER_ABOVE, 8));
- }
+ // node4 & 5 are unknown to connection2_.
+ EXPECT_FALSE(connection2_->ReorderNode(
+ node4_id, node5_id, ORDER_DIRECTION_ABOVE));
- {
- // node6 & node3 have different parents.
- EXPECT_FALSE(connection_->ReorderNode(node3_id, node6_id, ORDER_ABOVE, 8));
- }
+ // node6 & node3 have different parents.
+ EXPECT_FALSE(
+ connection_->ReorderNode(node3_id, node6_id, ORDER_DIRECTION_ABOVE));
- {
- // Non-existent node-ids
- EXPECT_FALSE(connection_->ReorderNode(BuildNodeId(1, 27),
- BuildNodeId(1, 28),
- ORDER_ABOVE,
- 8));
- }
+ // Non-existent node-ids
+ EXPECT_FALSE(connection_->ReorderNode(
+ BuildNodeId(1, 27), BuildNodeId(1, 28), ORDER_DIRECTION_ABOVE));
- {
- // node7 & node8 are un-parented.
- EXPECT_FALSE(connection_->ReorderNode(node7_id, node8_id, ORDER_ABOVE, 8));
- }
+ // node7 & node8 are un-parented.
+ EXPECT_FALSE(
+ connection_->ReorderNode(node7_id, node8_id, ORDER_DIRECTION_ABOVE));
}
// Verifies DeleteNode works.
-TEST_F(ViewManagerTest, DISABLED_DeleteNode) {
- ASSERT_TRUE(connection_->CreateNode(BuildNodeId(1, 2)));
-
+TEST_F(ViewManagerTest, DeleteNode) {
ASSERT_NO_FATAL_FAILURE(EstablishSecondConnection(true));
+ ASSERT_TRUE(connection2_->CreateNode(BuildNodeId(2, 2)));
// Make 2 a child of 1.
{
- ASSERT_TRUE(connection_->AddNode(BuildNodeId(1, 1), BuildNodeId(1, 2), 1));
- connection2_->DoRunLoopUntilChangesCount(1);
- const Changes changes(ChangesToDescription1(connection2_->changes()));
+ ASSERT_TRUE(connection2_->AddNode(BuildNodeId(1, 1), BuildNodeId(2, 2)));
+ connection_->DoRunLoopUntilChangesCount(1);
+ const Changes changes(ChangesToDescription1(connection_->changes()));
ASSERT_EQ(1u, changes.size());
- EXPECT_EQ("HierarchyChanged change_id=1 node=1,2 new_parent=1,1 "
- "old_parent=null", changes[0]);
+ EXPECT_EQ("HierarchyChanged node=2,2 new_parent=1,1 old_parent=null",
+ changes[0]);
}
// Delete 2.
{
- ASSERT_TRUE(connection_->DeleteNode(BuildNodeId(1, 2), 2));
- EXPECT_TRUE(connection_->changes().empty());
+ ASSERT_TRUE(connection2_->DeleteNode(BuildNodeId(2, 2)));
+ EXPECT_TRUE(connection2_->changes().empty());
- connection2_->DoRunLoopUntilChangesCount(1);
- const Changes changes(ChangesToDescription1(connection2_->changes()));
+ connection_->DoRunLoopUntilChangesCount(1);
+ const Changes changes(ChangesToDescription1(connection_->changes()));
ASSERT_EQ(1u, changes.size());
- EXPECT_EQ("NodeDeleted change_id=2 node=1,2", changes[0]);
+ EXPECT_EQ("NodeDeleted node=2,2", changes[0]);
}
}
// Verifies DeleteNode isn't allowed from a separate connection.
-TEST_F(ViewManagerTest, DISABLED_DeleteNodeFromAnotherConnectionDisallowed) {
+TEST_F(ViewManagerTest, DeleteNodeFromAnotherConnectionDisallowed) {
ASSERT_NO_FATAL_FAILURE(EstablishSecondConnection(true));
- EXPECT_FALSE(connection2_->DeleteNode(BuildNodeId(1, 1), 1));
-}
-
-// Verifies DeleteView isn't allowed from a separate connection.
-TEST_F(ViewManagerTest, DISABLED_DeleteViewFromAnotherConnectionDisallowed) {
- ASSERT_TRUE(connection_->CreateView(BuildViewId(1, 1)));
- ASSERT_NO_FATAL_FAILURE(EstablishSecondConnection(true));
- EXPECT_FALSE(connection2_->DeleteView(BuildViewId(1, 1)));
+ EXPECT_FALSE(connection2_->DeleteNode(BuildNodeId(1, 1)));
}
// Verifies if a node was deleted and then reused that other clients are
// properly notified.
-TEST_F(ViewManagerTest, DISABLED_ReuseDeletedNodeId) {
+TEST_F(ViewManagerTest, ReuseDeletedNodeId) {
ASSERT_NO_FATAL_FAILURE(EstablishSecondConnection(true));
- ASSERT_TRUE(connection_->CreateNode(BuildNodeId(1, 2)));
+ ASSERT_TRUE(connection2_->CreateNode(BuildNodeId(2, 2)));
// Add 2 to 1.
{
- ASSERT_TRUE(connection_->AddNode(BuildNodeId(1, 1), BuildNodeId(1, 2), 1));
+ ASSERT_TRUE(connection2_->AddNode(BuildNodeId(1, 1), BuildNodeId(2, 2)));
- connection2_->DoRunLoopUntilChangesCount(1);
- const Changes changes(ChangesToDescription1(connection2_->changes()));
- EXPECT_EQ(
- "HierarchyChanged change_id=1 node=1,2 new_parent=1,1 old_parent=null",
- changes[0]);
- EXPECT_EQ("[node=1,2 parent=1,1 view=null]",
- ChangeNodeDescription(connection2_->changes()));
+ connection_->DoRunLoopUntilChangesCount(1);
+ const Changes changes(ChangesToDescription1(connection_->changes()));
+ EXPECT_EQ("HierarchyChanged node=2,2 new_parent=1,1 old_parent=null",
+ changes[0]);
+ EXPECT_EQ("[node=2,2 parent=1,1]",
+ ChangeNodeDescription(connection_->changes()));
}
// Delete 2.
{
- ASSERT_TRUE(connection_->DeleteNode(BuildNodeId(1, 2), 2));
+ ASSERT_TRUE(connection2_->DeleteNode(BuildNodeId(2, 2)));
- connection2_->DoRunLoopUntilChangesCount(1);
- const Changes changes(ChangesToDescription1(connection2_->changes()));
+ connection_->DoRunLoopUntilChangesCount(1);
+ const Changes changes(ChangesToDescription1(connection_->changes()));
ASSERT_EQ(1u, changes.size());
- EXPECT_EQ("NodeDeleted change_id=2 node=1,2", changes[0]);
+ EXPECT_EQ("NodeDeleted node=2,2", changes[0]);
}
// Create 2 again, and add it back to 1. Should get the same notification.
- ASSERT_TRUE(connection_->CreateNode(BuildNodeId(1, 2)));
- {
- ASSERT_TRUE(connection_->AddNode(BuildNodeId(1, 1), BuildNodeId(1, 2), 3));
-
- connection2_->DoRunLoopUntilChangesCount(1);
- const Changes changes(ChangesToDescription1(connection2_->changes()));
- EXPECT_EQ(
- "HierarchyChanged change_id=3 node=1,2 new_parent=1,1 old_parent=null",
- changes[0]);
- EXPECT_EQ("[node=1,2 parent=1,1 view=null]",
- ChangeNodeDescription(connection2_->changes()));
- }
-}
-
-// Assertions around setting a view.
-TEST_F(ViewManagerTest, DISABLED_SetView) {
- // Create nodes 1, 2 and 3 and the view 11. Nodes 2 and 3 are parented to 1.
- ASSERT_TRUE(connection_->CreateNode(BuildNodeId(1, 1)));
- ASSERT_TRUE(connection_->CreateNode(BuildNodeId(1, 2)));
- ASSERT_TRUE(connection_->CreateNode(BuildNodeId(1, 3)));
- ASSERT_TRUE(connection_->CreateView(BuildViewId(1, 11)));
- ASSERT_TRUE(connection_->AddNode(BuildNodeId(1, 1), BuildNodeId(1, 2), 1));
- ASSERT_TRUE(connection_->AddNode(BuildNodeId(1, 1), BuildNodeId(1, 3), 2));
-
- ASSERT_NO_FATAL_FAILURE(EstablishSecondConnection(false));
-
- // Set view 11 on node 1.
- {
- ASSERT_TRUE(connection_->SetView(BuildNodeId(1, 1),
- BuildViewId(1, 11)));
-
- connection2_->DoRunLoopUntilChangesCount(1);
- const Changes changes(ChangesToDescription1(connection2_->changes()));
- ASSERT_EQ(1u, changes.size());
- EXPECT_EQ("ViewReplaced node=1,1 new_view=1,11 old_view=null",
- changes[0]);
- }
-
- // Set view 11 on node 2.
- {
- ASSERT_TRUE(connection_->SetView(BuildNodeId(1, 2), BuildViewId(1, 11)));
-
- connection2_->DoRunLoopUntilChangesCount(2);
- const Changes changes(ChangesToDescription1(connection2_->changes()));
- ASSERT_EQ(2u, changes.size());
- EXPECT_EQ("ViewReplaced node=1,1 new_view=null old_view=1,11",
- changes[0]);
- EXPECT_EQ("ViewReplaced node=1,2 new_view=1,11 old_view=null",
- changes[1]);
- }
-}
-
-// Verifies deleting a node with a view sends correct notifications.
-TEST_F(ViewManagerTest, DISABLED_DeleteNodeWithView) {
- ASSERT_TRUE(connection_->CreateNode(BuildNodeId(1, 1)));
- ASSERT_TRUE(connection_->CreateNode(BuildNodeId(1, 2)));
- ASSERT_TRUE(connection_->CreateNode(BuildNodeId(1, 3)));
- ASSERT_TRUE(connection_->CreateView(BuildViewId(1, 11)));
-
- // Set view 11 on node 2.
- ASSERT_TRUE(connection_->SetView(BuildNodeId(1, 2), BuildViewId(1, 11)));
-
- ASSERT_NO_FATAL_FAILURE(EstablishSecondConnection(false));
-
- // Delete node 2. The second connection should not see this because the node
- // was not known to it.
- {
- ASSERT_TRUE(connection_->DeleteNode(BuildNodeId(1, 2), 1));
-
- connection2_->DoRunLoopUntilChangesCount(1);
- const Changes changes(ChangesToDescription1(connection2_->changes()));
- ASSERT_EQ(1u, changes.size());
- EXPECT_EQ("ServerChangeIdAdvanced 2", changes[0]);
- }
-
- // Parent 3 to 1.
- ASSERT_TRUE(connection_->AddNode(BuildNodeId(1, 1), BuildNodeId(1, 3), 2));
- connection2_->DoRunLoopUntilChangesCount(1);
-
- // Set view 11 on node 3.
- {
- ASSERT_TRUE(connection_->SetView(BuildNodeId(1, 3), BuildViewId(1, 11)));
-
- connection2_->DoRunLoopUntilChangesCount(1);
- const Changes changes(ChangesToDescription1(connection2_->changes()));
- ASSERT_EQ(1u, changes.size());
- EXPECT_EQ("ViewReplaced node=1,3 new_view=1,11 old_view=null", changes[0]);
- }
-
- // Delete 3.
+ ASSERT_TRUE(connection2_->CreateNode(BuildNodeId(2, 2)));
{
- ASSERT_TRUE(connection_->DeleteNode(BuildNodeId(1, 3), 3));
+ ASSERT_TRUE(connection2_->AddNode(BuildNodeId(1, 1), BuildNodeId(2, 2)));
- connection2_->DoRunLoopUntilChangesCount(1);
- const Changes changes(ChangesToDescription1(connection2_->changes()));
- ASSERT_EQ(1u, changes.size());
- EXPECT_EQ("NodeDeleted change_id=3 node=1,3", changes[0]);
- }
-}
-
-// Sets view from one connection on another.
-TEST_F(ViewManagerTest, DISABLED_SetViewFromSecondConnection) {
- ASSERT_NO_FATAL_FAILURE(EstablishSecondConnection(true));
-
- ASSERT_TRUE(connection_->CreateNode(BuildNodeId(1, 2)));
-
- // Create a view in the second connection.
- ASSERT_TRUE(connection2_->CreateView(BuildViewId(2, 51)));
-
- // Attach view to node 1 in the first connection.
- {
- ASSERT_TRUE(connection2_->SetView(BuildNodeId(1, 1), BuildViewId(2, 51)));
connection_->DoRunLoopUntilChangesCount(1);
const Changes changes(ChangesToDescription1(connection_->changes()));
- ASSERT_EQ(1u, changes.size());
- EXPECT_EQ("ViewReplaced node=1,1 new_view=2,51 old_view=null", changes[0]);
- }
-
- // Shutdown the second connection and verify view is removed.
- {
- DestroySecondConnection();
- connection_->DoRunLoopUntilChangesCount(2);
- const Changes changes(ChangesToDescription1(connection_->changes()));
- ASSERT_EQ(2u, changes.size());
- EXPECT_EQ("ViewReplaced node=1,1 new_view=null old_view=2,51", changes[0]);
- EXPECT_EQ("ViewDeleted view=2,51", changes[1]);
+ EXPECT_EQ("HierarchyChanged node=2,2 new_parent=1,1 old_parent=null",
+ changes[0]);
+ EXPECT_EQ("[node=2,2 parent=1,1]",
+ ChangeNodeDescription(connection_->changes()));
}
}
// Assertions for GetNodeTree.
-TEST_F(ViewManagerTest, DISABLED_GetNodeTree) {
+TEST_F(ViewManagerTest, GetNodeTree) {
ASSERT_NO_FATAL_FAILURE(EstablishSecondConnection(true));
// Create 11 in first connection and make it a child of 1.
ASSERT_TRUE(connection_->CreateNode(BuildNodeId(1, 11)));
- ASSERT_TRUE(connection_->AddNode(BuildNodeId(0, 1), BuildNodeId(1, 1), 1));
- ASSERT_TRUE(connection_->AddNode(BuildNodeId(1, 1), BuildNodeId(1, 11), 2));
+ ASSERT_TRUE(connection_->AddNode(BuildNodeId(0, 1), BuildNodeId(1, 1)));
+ ASSERT_TRUE(connection_->AddNode(BuildNodeId(1, 1), BuildNodeId(1, 11)));
// Create two nodes in second connection, 2 and 3, both children of 1.
ASSERT_TRUE(connection2_->CreateNode(BuildNodeId(2, 2)));
ASSERT_TRUE(connection2_->CreateNode(BuildNodeId(2, 3)));
- ASSERT_TRUE(connection2_->AddNode(BuildNodeId(1, 1), BuildNodeId(2, 2), 3));
- ASSERT_TRUE(connection2_->AddNode(BuildNodeId(1, 1), BuildNodeId(2, 3), 4));
-
- // Attach view to node 11 in the first connection.
- ASSERT_TRUE(connection_->CreateView(BuildViewId(1, 51)));
- ASSERT_TRUE(connection_->SetView(BuildNodeId(1, 11), BuildViewId(1, 51)));
+ ASSERT_TRUE(connection2_->AddNode(BuildNodeId(1, 1), BuildNodeId(2, 2)));
+ ASSERT_TRUE(connection2_->AddNode(BuildNodeId(1, 1), BuildNodeId(2, 3)));
- // Verifies GetNodeTree() on the root.
+ // Verifies GetNodeTree() on the root. The root connection sees all.
{
std::vector<TestNode> nodes;
connection_->GetNodeTree(BuildNodeId(0, 1), &nodes);
ASSERT_EQ(5u, nodes.size());
- EXPECT_EQ("node=0,1 parent=null view=null", nodes[0].ToString());
- EXPECT_EQ("node=1,1 parent=0,1 view=null", nodes[1].ToString());
- EXPECT_EQ("node=1,11 parent=1,1 view=1,51", nodes[2].ToString());
- EXPECT_EQ("node=2,2 parent=1,1 view=null", nodes[3].ToString());
- EXPECT_EQ("node=2,3 parent=1,1 view=null", nodes[4].ToString());
+ EXPECT_EQ("node=0,1 parent=null", nodes[0].ToString());
+ EXPECT_EQ("node=1,1 parent=0,1", nodes[1].ToString());
+ EXPECT_EQ("node=1,11 parent=1,1", nodes[2].ToString());
+ EXPECT_EQ("node=2,2 parent=1,1", nodes[3].ToString());
+ EXPECT_EQ("node=2,3 parent=1,1", nodes[4].ToString());
}
- // Verifies GetNodeTree() on the node 1,1.
+ // Verifies GetNodeTree() on the node 1,1. This does not include any children
+ // as they are not from this connection.
{
std::vector<TestNode> nodes;
connection2_->GetNodeTree(BuildNodeId(1, 1), &nodes);
- ASSERT_EQ(4u, nodes.size());
- EXPECT_EQ("node=1,1 parent=null view=null", nodes[0].ToString());
- EXPECT_EQ("node=1,11 parent=1,1 view=1,51", nodes[1].ToString());
- EXPECT_EQ("node=2,2 parent=1,1 view=null", nodes[2].ToString());
- EXPECT_EQ("node=2,3 parent=1,1 view=null", nodes[3].ToString());
+ ASSERT_EQ(1u, nodes.size());
+ EXPECT_EQ("node=1,1 parent=null", nodes[0].ToString());
}
// Connection 2 shouldn't be able to get the root tree.
}
}
-TEST_F(ViewManagerTest, DISABLED_SetNodeBounds) {
+TEST_F(ViewManagerTest, SetNodeBounds) {
ASSERT_TRUE(connection_->CreateNode(BuildNodeId(1, 1)));
- ASSERT_TRUE(connection_->AddNode(BuildNodeId(0, 1), BuildNodeId(1, 1), 1));
+ ASSERT_TRUE(connection_->AddNode(BuildNodeId(0, 1), BuildNodeId(1, 1)));
ASSERT_NO_FATAL_FAILURE(EstablishSecondConnection(false));
gfx::Rect(0, 0, 0, 0)));
}
-// Various assertions around SetRoots.
-TEST_F(ViewManagerTest, DISABLED_SetRoots) {
- // Create 1, 2, and 3 in the first connection.
- ASSERT_TRUE(connection_->CreateNode(BuildNodeId(1, 1)));
- ASSERT_TRUE(connection_->CreateNode(BuildNodeId(1, 2)));
- ASSERT_TRUE(connection_->CreateNode(BuildNodeId(1, 3)));
-
- // Parent 1 to the root.
- ASSERT_TRUE(connection_->AddNode(BuildNodeId(0, 1), BuildNodeId(1, 1), 1));
-
- // Establish the second connection and give it the roots 1 and 3.
- {
- ASSERT_NO_FATAL_FAILURE(EstablishSecondConnectionWithRoots(
- BuildNodeId(1, 1), BuildNodeId(1, 3)));
- const Changes changes(ChangesToDescription1(connection2_->changes()));
- ASSERT_EQ(1u, changes.size());
- EXPECT_EQ("OnConnectionEstablished creator=mojo:test_url", changes[0]);
- EXPECT_EQ("[node=1,1 parent=null view=null],"
- "[node=1,3 parent=null view=null]",
- ChangeNodeDescription(connection2_->changes()));
- }
-
- // Create 4 and add it to the root, connection 2 should only get id advanced.
- {
- ASSERT_TRUE(connection_->CreateNode(BuildNodeId(1, 4)));
- ASSERT_TRUE(connection_->AddNode(BuildNodeId(0, 1), BuildNodeId(1, 4), 2));
-
- connection2_->DoRunLoopUntilChangesCount(1);
- const Changes changes(ChangesToDescription1(connection2_->changes()));
- ASSERT_EQ(1u, changes.size());
- EXPECT_EQ("ServerChangeIdAdvanced 3", changes[0]);
- }
-
- // Move 4 under 3, this should expose 4 to the client.
- {
- ASSERT_TRUE(connection_->AddNode(BuildNodeId(1, 3), BuildNodeId(1, 4), 3));
- connection2_->DoRunLoopUntilChangesCount(1);
- const Changes changes(ChangesToDescription1(connection2_->changes()));
- ASSERT_EQ(1u, changes.size());
- EXPECT_EQ(
- "HierarchyChanged change_id=3 node=1,4 new_parent=1,3 "
- "old_parent=null", changes[0]);
- EXPECT_EQ("[node=1,4 parent=1,3 view=null]",
- ChangeNodeDescription(connection2_->changes()));
- }
-
- // Move 4 under 2, since 2 isn't a root client should get a delete.
- {
- ASSERT_TRUE(connection_->AddNode(BuildNodeId(1, 2), BuildNodeId(1, 4), 4));
- connection2_->DoRunLoopUntilChangesCount(1);
- const Changes changes(ChangesToDescription1(connection2_->changes()));
- ASSERT_EQ(1u, changes.size());
- EXPECT_EQ("NodeDeleted change_id=4 node=1,4", changes[0]);
- }
-
- // Delete 4, client shouldn't receive a delete since it should no longer know
- // about 4.
- {
- ASSERT_TRUE(connection_->DeleteNode(BuildNodeId(1, 4), 5));
-
- connection2_->DoRunLoopUntilChangesCount(1);
- const Changes changes(ChangesToDescription1(connection2_->changes()));
- ASSERT_EQ(1u, changes.size());
- EXPECT_EQ("ServerChangeIdAdvanced 6", changes[0]);
- }
-}
-
// Verify AddNode fails when trying to manipulate nodes in other roots.
-TEST_F(ViewManagerTest, DISABLED_CantMoveNodesFromOtherRoot) {
+TEST_F(ViewManagerTest, CantMoveNodesFromOtherRoot) {
// Create 1 and 2 in the first connection.
ASSERT_TRUE(connection_->CreateNode(BuildNodeId(1, 1)));
ASSERT_TRUE(connection_->CreateNode(BuildNodeId(1, 2)));
// Try to move 2 to be a child of 1 from connection 2. This should fail as 2
// should not be able to access 1.
- ASSERT_FALSE(connection2_->AddNode(BuildNodeId(1, 1), BuildNodeId(1, 2), 1));
+ ASSERT_FALSE(connection2_->AddNode(BuildNodeId(1, 1), BuildNodeId(1, 2)));
// Try to reparent 1 to the root. A connection is not allowed to reparent its
// roots.
- ASSERT_FALSE(connection2_->AddNode(BuildNodeId(0, 1), BuildNodeId(1, 1), 1));
+ ASSERT_FALSE(connection2_->AddNode(BuildNodeId(0, 1), BuildNodeId(1, 1)));
}
// Verify RemoveNodeFromParent fails for nodes that are descendants of the
// roots.
-TEST_F(ViewManagerTest, DISABLED_CantRemoveNodesInOtherRoots) {
+TEST_F(ViewManagerTest, CantRemoveNodesInOtherRoots) {
// Create 1 and 2 in the first connection and parent both to the root.
ASSERT_TRUE(connection_->CreateNode(BuildNodeId(1, 1)));
ASSERT_TRUE(connection_->CreateNode(BuildNodeId(1, 2)));
- ASSERT_TRUE(connection_->AddNode(BuildNodeId(0, 1), BuildNodeId(1, 1), 1));
- ASSERT_TRUE(connection_->AddNode(BuildNodeId(0, 1), BuildNodeId(1, 2), 2));
+ ASSERT_TRUE(connection_->AddNode(BuildNodeId(0, 1), BuildNodeId(1, 1)));
+ ASSERT_TRUE(connection_->AddNode(BuildNodeId(0, 1), BuildNodeId(1, 2)));
// Establish the second connection and give it the root 1.
ASSERT_NO_FATAL_FAILURE(EstablishSecondConnection(false));
// Connection 2 should not be able to remove node 2 or 1 from its parent.
- ASSERT_FALSE(connection2_->RemoveNodeFromParent(BuildNodeId(1, 2), 3));
- ASSERT_FALSE(connection2_->RemoveNodeFromParent(BuildNodeId(1, 1), 3));
+ ASSERT_FALSE(connection2_->RemoveNodeFromParent(BuildNodeId(1, 2)));
+ ASSERT_FALSE(connection2_->RemoveNodeFromParent(BuildNodeId(1, 1)));
// Create nodes 10 and 11 in 2.
ASSERT_TRUE(connection2_->CreateNode(BuildNodeId(2, 10)));
ASSERT_TRUE(connection2_->CreateNode(BuildNodeId(2, 11)));
// Parent 11 to 10.
- ASSERT_TRUE(connection2_->AddNode(BuildNodeId(2, 10), BuildNodeId(2, 11), 3));
+ ASSERT_TRUE(connection2_->AddNode(BuildNodeId(2, 10), BuildNodeId(2, 11)));
// Remove 11 from 10.
- ASSERT_TRUE(connection2_->RemoveNodeFromParent( BuildNodeId(2, 11), 4));
+ ASSERT_TRUE(connection2_->RemoveNodeFromParent( BuildNodeId(2, 11)));
// Verify nothing was actually removed.
{
std::vector<TestNode> nodes;
connection_->GetNodeTree(BuildNodeId(0, 1), &nodes);
ASSERT_EQ(3u, nodes.size());
- EXPECT_EQ("node=0,1 parent=null view=null", nodes[0].ToString());
- EXPECT_EQ("node=1,1 parent=0,1 view=null", nodes[1].ToString());
- EXPECT_EQ("node=1,2 parent=0,1 view=null", nodes[2].ToString());
+ EXPECT_EQ("node=0,1 parent=null", nodes[0].ToString());
+ EXPECT_EQ("node=1,1 parent=0,1", nodes[1].ToString());
+ EXPECT_EQ("node=1,2 parent=0,1", nodes[2].ToString());
}
}
-// Verify SetView fails for nodes that are not descendants of the roots.
-TEST_F(ViewManagerTest, DISABLED_CantRemoveSetViewInOtherRoots) {
- // Create 1 and 2 in the first connection and parent both to the root.
- ASSERT_TRUE(connection_->CreateNode(BuildNodeId(1, 1)));
- ASSERT_TRUE(connection_->CreateNode(BuildNodeId(1, 2)));
-
- ASSERT_TRUE(connection_->AddNode(BuildNodeId(0, 1), BuildNodeId(1, 1), 1));
- ASSERT_TRUE(connection_->AddNode(BuildNodeId(0, 1), BuildNodeId(1, 2), 2));
-
- ASSERT_NO_FATAL_FAILURE(EstablishSecondConnection(false));
-
- // Create a view in the second connection.
- ASSERT_TRUE(connection2_->CreateView(BuildViewId(2, 51)));
-
- // Connection 2 should be able to set the view on node 1 (it's root), but not
- // on 2.
- ASSERT_TRUE(connection2_->SetView(BuildNodeId(1, 1), BuildViewId(2, 51)));
- ASSERT_FALSE(connection2_->SetView(BuildNodeId(1, 2), BuildViewId(2, 51)));
-}
-
// Verify GetNodeTree fails for nodes that are not descendants of the roots.
-TEST_F(ViewManagerTest, DISABLED_CantGetNodeTreeOfOtherRoots) {
+TEST_F(ViewManagerTest, CantGetNodeTreeOfOtherRoots) {
// Create 1 and 2 in the first connection and parent both to the root.
ASSERT_TRUE(connection_->CreateNode(BuildNodeId(1, 1)));
ASSERT_TRUE(connection_->CreateNode(BuildNodeId(1, 2)));
- ASSERT_TRUE(connection_->AddNode(BuildNodeId(0, 1), BuildNodeId(1, 1), 1));
- ASSERT_TRUE(connection_->AddNode(BuildNodeId(0, 1), BuildNodeId(1, 2), 2));
+ ASSERT_TRUE(connection_->AddNode(BuildNodeId(0, 1), BuildNodeId(1, 1)));
+ ASSERT_TRUE(connection_->AddNode(BuildNodeId(0, 1), BuildNodeId(1, 2)));
ASSERT_NO_FATAL_FAILURE(EstablishSecondConnection(false));
// Should get node 1 if asked for.
connection2_->GetNodeTree(BuildNodeId(1, 1), &nodes);
ASSERT_EQ(1u, nodes.size());
- EXPECT_EQ("node=1,1 parent=null view=null", nodes[0].ToString());
+ EXPECT_EQ("node=1,1 parent=null", nodes[0].ToString());
}
-TEST_F(ViewManagerTest, DISABLED_ConnectTwice) {
+TEST_F(ViewManagerTest, ConnectTwice) {
ASSERT_TRUE(connection_->CreateNode(BuildNodeId(1, 1)));
ASSERT_TRUE(connection_->CreateNode(BuildNodeId(1, 2)));
- ASSERT_TRUE(connection_->AddNode(BuildNodeId(1, 1), BuildNodeId(1, 2), 1));
-
ASSERT_NO_FATAL_FAILURE(EstablishSecondConnection(false));
// Try to connect again to 1,1, this should fail as already connected to that
// root.
- {
- std::vector<Id> node_ids;
- node_ids.push_back(BuildNodeId(1, 1));
- ASSERT_FALSE(connection_->Embed(node_ids));
- }
+ ASSERT_FALSE(connection_->Embed(BuildNodeId(1, 1), kTestServiceURL));
// Connecting to 1,2 should succeed and end up in connection2.
{
- std::vector<Id> node_ids;
- node_ids.push_back(BuildNodeId(1, 2));
- ASSERT_TRUE(connection_->Embed(node_ids));
+ ASSERT_TRUE(connection_->Embed(BuildNodeId(1, 2), kTestServiceURL));
connection2_->DoRunLoopUntilChangesCount(1);
const Changes changes(ChangesToDescription1(connection2_->changes()));
ASSERT_EQ(1u, changes.size());
- EXPECT_EQ("OnRootsAdded", changes[0]);
- EXPECT_EQ("[node=1,2 parent=1,1 view=null]",
+ EXPECT_EQ("OnEmbed creator=mojo:test_url", changes[0]);
+ EXPECT_EQ("[node=1,2 parent=null]",
ChangeNodeDescription(connection2_->changes()));
}
}
-TEST_F(ViewManagerTest, DISABLED_OnViewInput) {
- // Create node 1 and assign a view from connection 2 to it.
+TEST_F(ViewManagerTest, OnNodeInput) {
ASSERT_TRUE(connection_->CreateNode(BuildNodeId(1, 1)));
ASSERT_NO_FATAL_FAILURE(EstablishSecondConnection(false));
- ASSERT_TRUE(connection2_->CreateView(BuildViewId(2, 11)));
- ASSERT_TRUE(connection2_->SetView(BuildNodeId(1, 1), BuildViewId(2, 11)));
- // Dispatch an event to the view and verify its received.
+ // Dispatch an event to the node and verify its received.
{
EventPtr event(Event::New());
- event->action = 1;
+ event->action = static_cast<EventType>(1);
connection_->view_manager()->DispatchOnViewInputEvent(
- BuildViewId(2, 11),
+ BuildNodeId(1, 1),
event.Pass());
connection2_->DoRunLoopUntilChangesCount(1);
const Changes changes(ChangesToDescription1(connection2_->changes()));
ASSERT_EQ(1u, changes.size());
- EXPECT_EQ("InputEvent view=2,11 event_action=1", changes[0]);
+ EXPECT_EQ("InputEvent node=1,1 event_action=1", changes[0]);
+ }
+}
+
+TEST_F(ViewManagerTest, EmbedWithSameNodeId) {
+ ASSERT_NO_FATAL_FAILURE(EstablishSecondConnection(true));
+
+ ASSERT_NO_FATAL_FAILURE(EstablishThirdConnection(connection_,
+ BuildNodeId(1, 1)));
+
+ // Connection2 should have been told the node was deleted.
+ {
+ connection2_->DoRunLoopUntilChangesCount(1);
+ const Changes changes(ChangesToDescription1(connection2_->changes()));
+ ASSERT_EQ(1u, changes.size());
+ EXPECT_EQ("NodeDeleted node=1,1", changes[0]);
+ }
+
+ // Connection2 has no root. Verify it can't see node 1,1 anymore.
+ {
+ std::vector<TestNode> nodes;
+ connection2_->GetNodeTree(BuildNodeId(1, 1), &nodes);
+ EXPECT_TRUE(nodes.empty());
+ }
+}
+
+TEST_F(ViewManagerTest, EmbedWithSameNodeId2) {
+ ASSERT_NO_FATAL_FAILURE(EstablishSecondConnection(true));
+
+ ASSERT_NO_FATAL_FAILURE(EstablishThirdConnection(connection_,
+ BuildNodeId(1, 1)));
+
+ // Connection2 should have been told the node was deleted.
+ connection2_->DoRunLoopUntilChangesCount(1);
+ connection2_->ClearChanges();
+
+ // Create a node in the third connection and parent it to the root.
+ ASSERT_TRUE(connection3_->CreateNode(BuildNodeId(3, 1)));
+ ASSERT_TRUE(connection3_->AddNode(BuildNodeId(1, 1), BuildNodeId(3, 1)));
+
+ // Connection 1 should have been told about the add (it owns the node).
+ {
+ connection_->DoRunLoopUntilChangesCount(1);
+ const Changes changes(ChangesToDescription1(connection_->changes()));
+ ASSERT_EQ(1u, changes.size());
+ EXPECT_EQ("HierarchyChanged node=3,1 new_parent=1,1 old_parent=null",
+ changes[0]);
+ }
+
+ // Embed 1,1 back in connection 2.
+ {
+ // 2 should be told about the new embed.
+ ASSERT_TRUE(connection_->Embed(BuildNodeId(1, 1), kTestServiceURL));
+ connection2_->DoRunLoopUntilChangesCount(1);
+ const std::vector<Change>& changes(connection2_->changes());
+ ASSERT_EQ(1u, changes.size());
+ EXPECT_EQ("OnEmbed creator=mojo:test_url",
+ ChangesToDescription1(changes)[0]);
+ EXPECT_EQ("[node=1,1 parent=null]",
+ ChangeNodeDescription(changes));
+
+ // And 3 should get a delete.
+ connection3_->DoRunLoopUntilChangesCount(1);
+ ASSERT_EQ(1u, connection3_->changes().size());
+ EXPECT_EQ("NodeDeleted node=1,1",
+ ChangesToDescription1(connection3_->changes())[0]);
+ }
+
+ // Connection3_ has no root. Verify it can't see node 1,1 anymore.
+ {
+ std::vector<TestNode> nodes;
+ connection3_->GetNodeTree(BuildNodeId(1, 1), &nodes);
+ EXPECT_TRUE(nodes.empty());
+ }
+
+ // Verify 3,1 is no longer parented to 1,1. We have to do this from 1,1 as
+ // connection3_ can no longer see 1,1.
+ {
+ std::vector<TestNode> nodes;
+ connection_->GetNodeTree(BuildNodeId(1, 1), &nodes);
+ ASSERT_EQ(1u, nodes.size());
+ EXPECT_EQ("node=1,1 parent=null", nodes[0].ToString());
+ }
+
+ // Verify connection3_ can still see the node it created 3,1.
+ {
+ std::vector<TestNode> nodes;
+ connection3_->GetNodeTree(BuildNodeId(3, 1), &nodes);
+ ASSERT_EQ(1u, nodes.size());
+ EXPECT_EQ("node=3,1 parent=null", nodes[0].ToString());
}
}
// TODO(sky): add coverage of test that destroys connections and ensures other
-// connections get deletion notification (or advanced server id).
+// connections get deletion notification.
// TODO(sky): need to better track changes to initial connection. For example,
// that SetBounsdNodes/AddNode and the like don't result in messages to the
// originating connection.
} // namespace service
-} // namespace view_manager
} // namespace mojo