Index: mojo/services/view_manager/view_manager_connection_unittest.cc |
diff --git a/mojo/services/view_manager/view_manager_connection_unittest.cc b/mojo/services/view_manager/view_manager_connection_unittest.cc |
index a2d0ab589069fd9915d5b7a3726113dd25b38cbc..063a740e2eb07da72c487f8f552939bc3d86d8a6 100644 |
--- a/mojo/services/view_manager/view_manager_connection_unittest.cc |
+++ b/mojo/services/view_manager/view_manager_connection_unittest.cc |
@@ -10,6 +10,7 @@ |
#include "base/message_loop/message_loop.h" |
#include "base/run_loop.h" |
#include "base/strings/stringprintf.h" |
+#include "mojo/common/common_type_converters.h" |
#include "mojo/public/cpp/bindings/allocation_scope.h" |
#include "mojo/public/cpp/environment/environment.h" |
#include "mojo/public/cpp/shell/connect.h" |
@@ -20,6 +21,21 @@ |
#include "testing/gtest/include/gtest/gtest.h" |
namespace mojo { |
+ |
+// TODO(sky): remove this when Darin is done with cleanup. |
+template <typename T> |
+class MOJO_COMMON_EXPORT TypeConverter<T, T> { |
+ public: |
+ static T ConvertFrom(T input, Buffer* buf) { |
+ return input; |
+ } |
+ static T ConvertTo(T input) { |
+ return input; |
+ } |
+ |
+ MOJO_ALLOW_IMPLICIT_TYPE_CONVERSION(); |
+}; |
+ |
namespace view_manager { |
namespace service { |
@@ -30,6 +46,8 @@ base::RunLoop* current_run_loop = NULL; |
// Sets |current_run_loop| and runs it. It is expected that someone else quits |
// the loop. |
void DoRunLoop() { |
+ DCHECK(!current_run_loop); |
+ |
base::RunLoop run_loop; |
current_run_loop = &run_loop; |
current_run_loop->Run(); |
@@ -175,6 +193,17 @@ bool SetView(IViewManager* view_manager, |
return result; |
} |
+bool SetRoots(IViewManager* view_manager, |
+ TransportConnectionId connection_id, |
+ const std::vector<uint32_t>& node_ids) { |
+ bool result = false; |
+ view_manager->SetRoots(connection_id, |
+ Array<uint32_t>::From(node_ids), |
+ base::Bind(&BooleanCallback, &result)); |
+ DoRunLoop(); |
+ return result; |
+} |
+ |
} // namespace |
typedef std::vector<std::string> Changes; |
@@ -204,9 +233,13 @@ class ViewManagerClientImpl : public IViewManagerClient { |
return changes; |
} |
+ void ClearId() { |
+ id_ = 0; |
+ } |
+ |
void WaitForId() { |
- if (id_ == 0) |
- DoRunLoop(); |
+ DCHECK_EQ(0, id_); |
+ DoRunLoopUntilChangesCount(1); |
} |
void DoRunLoopUntilChangesCount(size_t count) { |
@@ -224,9 +257,10 @@ class ViewManagerClientImpl : public IViewManagerClient { |
const mojo::Array<INode>& nodes) OVERRIDE { |
id_ = connection_id; |
next_server_change_id_ = next_server_change_id; |
+ initial_nodes_.clear(); |
INodesToTestNodes(nodes, &initial_nodes_); |
- if (current_run_loop) |
- current_run_loop->Quit(); |
+ changes_.push_back("OnConnectionEstablished"); |
+ QuitIfNecessary(); |
} |
virtual void OnServerChangeIdAdvanced( |
uint32_t next_server_change_id) OVERRIDE { |
@@ -314,6 +348,7 @@ class ViewManagerConnectionTest : public testing::Test { |
view_manager_->SetClient(&client_); |
client_.WaitForId(); |
+ client_.GetAndClearChanges(); |
} |
protected: |
@@ -323,6 +358,7 @@ class ViewManagerConnectionTest : public testing::Test { |
view_manager2_->SetClient(&client2_); |
client2_.WaitForId(); |
+ client2_.GetAndClearChanges(); |
} |
void DestroySecondConnection() { |
@@ -1092,6 +1128,95 @@ TEST_F(ViewManagerConnectionTest, GetNodeTree) { |
} |
} |
+TEST_F(ViewManagerConnectionTest, SetRoots) { |
+ // Create 1, 2, and 3 in the first connection. |
+ ASSERT_TRUE(CreateNode(view_manager_.get(), 1, 1)); |
+ ASSERT_TRUE(CreateNode(view_manager_.get(), 1, 2)); |
+ ASSERT_TRUE(CreateNode(view_manager_.get(), 1, 3)); |
+ |
+ // Parent 1 to the root. |
+ ASSERT_TRUE(AddNode(view_manager_.get(), |
+ CreateNodeId(0, 1), |
+ CreateNodeId(client_.id(), 1), |
+ 1)); |
+ |
+ // Establish the second connection and give it the roots 1 and 3. |
+ EstablishSecondConnection(); |
+ client2_.ClearId(); |
+ { |
+ AllocationScope scope; |
+ std::vector<uint32_t> roots; |
+ roots.push_back(CreateNodeId(1, 1)); |
+ roots.push_back(CreateNodeId(1, 3)); |
+ ASSERT_TRUE(SetRoots(view_manager_.get(), 2, roots)); |
+ client2_.DoRunLoopUntilChangesCount(1); |
+ Changes changes(client2_.GetAndClearChanges()); |
+ ASSERT_EQ(1u, changes.size()); |
+ EXPECT_EQ("OnConnectionEstablished", changes[0]); |
+ ASSERT_NE(0u, client2_.id()); |
+ const std::vector<TestNode>& nodes(client2_.initial_nodes()); |
+ ASSERT_EQ(2u, nodes.size()); |
+ EXPECT_EQ("node=1,1 parent=null view=null", nodes[0].ToString()); |
+ EXPECT_EQ("node=1,3 parent=null view=null", nodes[1].ToString()); |
+ } |
+ |
+ // Create 4 and add it to the root, connection 2 should only get id advanced. |
+ { |
+ ASSERT_TRUE(CreateNode(view_manager_.get(), 1, 4)); |
+ ASSERT_TRUE(AddNode(view_manager_.get(), |
+ CreateNodeId(0, 1), |
+ CreateNodeId(client_.id(), 4), |
+ 2)); |
+ client2_.DoRunLoopUntilChangesCount(1); |
+ Changes changes(client2_.GetAndClearChanges()); |
+ ASSERT_EQ(1u, changes.size()); |
+ EXPECT_EQ("ServerChangeIdAdvanced 3", changes[0]); |
+ } |
+ |
+ // Move 4 under 3, this should expose 4 to the client. |
+ { |
+ ASSERT_TRUE(AddNode(view_manager_.get(), |
+ CreateNodeId(1, 3), |
+ CreateNodeId(1, 4), |
+ 3)); |
+ client2_.DoRunLoopUntilChangesCount(1); |
+ Changes changes(client2_.GetAndClearChanges()); |
+ ASSERT_EQ(1u, changes.size()); |
+ EXPECT_EQ( |
+ "HierarchyChanged change_id=3 node=1,4 new_parent=1,3 " |
+ "old_parent=null", changes[0]); |
+ const std::vector<TestNode>& nodes(client2_.hierarchy_changed_nodes()); |
+ ASSERT_EQ(1u, nodes.size()); |
+ EXPECT_EQ("node=1,4 parent=1,3 view=null", nodes[0].ToString()); |
+ } |
+ |
+ // Move 4 under 2, since 2 isn't a root client should get a delete. |
+ { |
+ ASSERT_TRUE(AddNode(view_manager_.get(), |
+ CreateNodeId(1, 2), |
+ CreateNodeId(1, 4), |
+ 4)); |
+ client2_.DoRunLoopUntilChangesCount(1); |
+ Changes changes(client2_.GetAndClearChanges()); |
+ 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(DeleteNode(view_manager_.get(), CreateNodeId(client_.id(), 4))); |
+ ASSERT_TRUE(client_.GetAndClearChanges().empty()); |
+ |
+ client2_.DoRunLoopUntilChangesCount(1); |
+ Changes changes(client2_.GetAndClearChanges()); |
+ ASSERT_EQ(1u, changes.size()); |
+ EXPECT_EQ("ServerChangeIdAdvanced 6", changes[0]); |
+ } |
+} |
+ |
+// TODO: add tests that verify can't manipulate trees of uknown nodes. |
+ |
} // namespace service |
} // namespace view_manager |
} // namespace mojo |