[Mojo] Load V8's external snapshot before initializing Blink.
[chromium-blink-merge.git] / mojo / services / html_viewer / ax_provider_impl_unittest.cc
blob3aa95c7d8dcf069a8407304b4740519dc4a86bf4
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "mojo/services/html_viewer/ax_provider_impl.h"
7 #include "base/bind.h"
8 #include "base/message_loop/message_loop.h"
9 #include "base/metrics/stats_counters.h"
10 #include "gin/public/isolate_holder.h"
11 #include "mojo/services/html_viewer/blink_platform_impl.h"
12 #include "testing/gtest/include/gtest/gtest.h"
13 #include "third_party/WebKit/public/platform/WebData.h"
14 #include "third_party/WebKit/public/platform/WebURL.h"
15 #include "third_party/WebKit/public/web/WebFrameClient.h"
16 #include "third_party/WebKit/public/web/WebKit.h"
17 #include "third_party/WebKit/public/web/WebLocalFrame.h"
18 #include "third_party/WebKit/public/web/WebView.h"
19 #include "third_party/WebKit/public/web/WebViewClient.h"
20 #include "url/gurl.h"
22 using blink::WebData;
23 using blink::WebLocalFrame;
24 using blink::WebFrameClient;
25 using blink::WebURL;
26 using blink::WebView;
27 using blink::WebViewClient;
29 namespace mojo {
31 namespace {
33 class TestWebFrameClient : public WebFrameClient {
34 public:
35 virtual ~TestWebFrameClient() {}
36 virtual void didStopLoading() { base::MessageLoop::current()->Quit(); }
39 class TestWebViewClient : public WebViewClient {
40 public:
41 virtual bool allowsBrokenNullLayerTreeView() const { return true; }
42 virtual ~TestWebViewClient() {}
45 class AxProviderImplTest : public testing::Test {
46 public:
47 AxProviderImplTest() {
48 #if defined(V8_USE_EXTERNAL_STARTUP_DATA)
49 gin::IsolateHolder::LoadV8Snapshot();
50 #endif
51 blink::initialize(new BlinkPlatformImpl());
54 virtual ~AxProviderImplTest() override { blink::shutdown(); }
56 private:
57 base::MessageLoopForUI message_loop;
60 struct NodeCatcher {
61 void OnNodes(Array<AxNodePtr> nodes) { this->nodes = nodes.Pass(); }
62 Array<AxNodePtr> nodes;
65 AxNodePtr CreateNode(int id,
66 int parent_id,
67 int next_sibling_id,
68 const RectPtr& bounds,
69 const std::string& url,
70 const std::string& text) {
71 AxNodePtr node(AxNode::New());
72 node->id = id;
73 node->parent_id = parent_id;
74 node->next_sibling_id = next_sibling_id;
75 node->bounds = bounds.Clone();
77 if (!url.empty()) {
78 node->link = AxLink::New();
79 node->link->url = url;
81 if (!text.empty()) {
82 node->text = AxText::New();
83 node->text->content = text;
85 return node.Pass();
88 } // namespace
90 TEST_F(AxProviderImplTest, Basic) {
91 TestWebViewClient web_view_client;
92 TestWebFrameClient web_frame_client;
93 WebView* view = WebView::create(&web_view_client);
94 view->setMainFrame(WebLocalFrame::create(&web_frame_client));
95 view->mainFrame()->loadHTMLString(
96 WebData(
97 "<html><body>foo<a "
98 "href='http://monkey.net'>bar</a>baz</body></html>"),
99 WebURL(GURL("http://someplace.net")));
100 base::MessageLoop::current()->Run();
102 AxProviderImpl ax_provider_impl(view);
103 NodeCatcher catcher;
104 ax_provider_impl.GetTree(
105 base::Bind(&NodeCatcher::OnNodes, base::Unretained(&catcher)));
107 std::map<uint32, AxNode*> lookup;
108 for (size_t i = 0; i < catcher.nodes.size(); ++i) {
109 auto& node = catcher.nodes[i];
110 lookup[node->id] = node.get();
113 typedef decltype(lookup)::value_type MapEntry;
114 auto is_link = [](MapEntry pair) { return pair.second->link.get(); };
115 auto is_text = [](MapEntry pair, const char* content) {
116 return pair.second->text.get() &&
117 pair.second->text->content.To<std::string>() == content;
119 auto is_foo = [&is_text](MapEntry pair) { return is_text(pair, "foo"); };
120 auto is_bar = [&is_text](MapEntry pair) { return is_text(pair, "bar"); };
121 auto is_baz = [&is_text](MapEntry pair) { return is_text(pair, "baz"); };
123 EXPECT_EQ(1, std::count_if(lookup.begin(), lookup.end(), is_link));
124 EXPECT_EQ(1, std::count_if(lookup.begin(), lookup.end(), is_foo));
125 EXPECT_EQ(1, std::count_if(lookup.begin(), lookup.end(), is_bar));
126 EXPECT_EQ(1, std::count_if(lookup.begin(), lookup.end(), is_baz));
128 auto root = lookup[1u];
129 auto link = std::find_if(lookup.begin(), lookup.end(), is_link)->second;
130 auto foo = std::find_if(lookup.begin(), lookup.end(), is_foo)->second;
131 auto bar = std::find_if(lookup.begin(), lookup.end(), is_bar)->second;
132 auto baz = std::find_if(lookup.begin(), lookup.end(), is_baz)->second;
134 // Test basic content of each node. The properties we copy (like parent_id)
135 // here are tested differently below.
136 EXPECT_TRUE(CreateNode(root->id, 0, 0, root->bounds, "", "")->Equals(*root));
137 EXPECT_TRUE(CreateNode(foo->id, foo->parent_id, 0, foo->bounds, "", "foo")
138 ->Equals(*foo));
139 EXPECT_TRUE(CreateNode(bar->id, bar->parent_id, 0, bar->bounds, "", "bar")
140 ->Equals(*bar));
141 EXPECT_TRUE(CreateNode(baz->id, baz->parent_id, 0, baz->bounds, "", "baz")
142 ->Equals(*baz));
143 EXPECT_TRUE(CreateNode(link->id,
144 link->parent_id,
145 link->next_sibling_id,
146 link->bounds,
147 "http://monkey.net/",
148 "")->Equals(*link));
150 auto is_descendant_of = [&lookup](uint32 id, uint32 ancestor) {
151 for (; (id = lookup[id]->parent_id) != 0;) {
152 if (id == ancestor)
153 return true;
155 return false;
158 EXPECT_TRUE(is_descendant_of(bar->id, link->id));
159 for (auto pair : lookup) {
160 AxNode* node = pair.second;
161 if (node != root)
162 EXPECT_TRUE(is_descendant_of(node->id, 1u));
163 if (node != link && node != foo && node != bar && node != baz) {
164 EXPECT_TRUE(CreateNode(node->id,
165 node->parent_id,
166 node->next_sibling_id,
167 node->bounds,
169 ""));
173 // TODO(aa): Test bounds.
174 // TODO(aa): Test sibling ordering of foo/bar/baz.
176 view->close();
179 } // namespace mojo