Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(709)

Side by Side Diff: chrome/browser/accessibility/browser_accessibility_win_unittest.cc

Issue 8804001: Move a bunch of accessibility tests in chrome that have no chrome dependencies to content. We wan... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 9 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2011 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.
4
5 #include "base/memory/scoped_ptr.h"
6 #include "base/win/scoped_comptr.h"
7 #include "content/browser/accessibility/browser_accessibility_manager.h"
8 #include "content/browser/accessibility/browser_accessibility_win.h"
9 #include "content/common/view_messages.h"
10 #include "testing/gtest/include/gtest/gtest.h"
11 #include "ui/base/win/atl_module.h"
12
13 using webkit_glue::WebAccessibility;
14
15 namespace {
16
17 // Subclass of BrowserAccessibilityWin that counts the number of instances.
18 class CountedBrowserAccessibility : public BrowserAccessibilityWin {
19 public:
20 CountedBrowserAccessibility() { global_obj_count_++; }
21 virtual ~CountedBrowserAccessibility() { global_obj_count_--; }
22 static int global_obj_count_;
23 };
24
25 int CountedBrowserAccessibility::global_obj_count_ = 0;
26
27 // Factory that creates a CountedBrowserAccessibility.
28 class CountedBrowserAccessibilityFactory
29 : public BrowserAccessibilityFactory {
30 public:
31 virtual ~CountedBrowserAccessibilityFactory() {}
32 virtual BrowserAccessibility* Create() {
33 CComObject<CountedBrowserAccessibility>* instance;
34 HRESULT hr = CComObject<CountedBrowserAccessibility>::CreateInstance(
35 &instance);
36 DCHECK(SUCCEEDED(hr));
37 instance->AddRef();
38 return instance;
39 }
40 };
41
42 } // anonymous namespace
43
44 VARIANT CreateI4Variant(LONG value) {
45 VARIANT variant = {0};
46
47 V_VT(&variant) = VT_I4;
48 V_I4(&variant) = value;
49
50 return variant;
51 }
52
53 class BrowserAccessibilityTest : public testing::Test {
54 protected:
55 virtual void SetUp() {
56 ui::win::CreateATLModuleIfNeeded();
57 ::CoInitialize(NULL);
58 }
59
60 virtual void TearDown() {
61 ::CoUninitialize();
62 }
63 };
64
65 // Test that BrowserAccessibilityManager correctly releases the tree of
66 // BrowserAccessibility instances upon delete.
67 TEST_F(BrowserAccessibilityTest, TestNoLeaks) {
68 // Create WebAccessibility objects for a simple document tree,
69 // representing the accessibility information used to initialize
70 // BrowserAccessibilityManager.
71 WebAccessibility button;
72 button.id = 2;
73 button.name = L"Button";
74 button.role = WebAccessibility::ROLE_BUTTON;
75 button.state = 0;
76
77 WebAccessibility checkbox;
78 checkbox.id = 3;
79 checkbox.name = L"Checkbox";
80 checkbox.role = WebAccessibility::ROLE_CHECKBOX;
81 checkbox.state = 0;
82
83 WebAccessibility root;
84 root.id = 1;
85 root.name = L"Document";
86 root.role = WebAccessibility::ROLE_DOCUMENT;
87 root.state = 0;
88 root.children.push_back(button);
89 root.children.push_back(checkbox);
90
91 // Construct a BrowserAccessibilityManager with this WebAccessibility tree
92 // and a factory for an instance-counting BrowserAccessibility, and ensure
93 // that exactly 3 instances were created. Note that the manager takes
94 // ownership of the factory.
95 CountedBrowserAccessibility::global_obj_count_ = 0;
96 BrowserAccessibilityManager* manager =
97 BrowserAccessibilityManager::Create(
98 GetDesktopWindow(),
99 root,
100 NULL,
101 new CountedBrowserAccessibilityFactory());
102 ASSERT_EQ(3, CountedBrowserAccessibility::global_obj_count_);
103
104 // Delete the manager and test that all 3 instances are deleted.
105 delete manager;
106 ASSERT_EQ(0, CountedBrowserAccessibility::global_obj_count_);
107
108 // Construct a manager again, and this time use the IAccessible interface
109 // to get new references to two of the three nodes in the tree.
110 manager =
111 BrowserAccessibilityManager::Create(
112 GetDesktopWindow(),
113 root,
114 NULL,
115 new CountedBrowserAccessibilityFactory());
116 ASSERT_EQ(3, CountedBrowserAccessibility::global_obj_count_);
117 IAccessible* root_accessible =
118 manager->GetRoot()->toBrowserAccessibilityWin();
119 IDispatch* root_iaccessible = NULL;
120 IDispatch* child1_iaccessible = NULL;
121 VARIANT var_child;
122 var_child.vt = VT_I4;
123 var_child.lVal = CHILDID_SELF;
124 HRESULT hr = root_accessible->get_accChild(var_child, &root_iaccessible);
125 ASSERT_EQ(S_OK, hr);
126 var_child.lVal = 1;
127 hr = root_accessible->get_accChild(var_child, &child1_iaccessible);
128 ASSERT_EQ(S_OK, hr);
129
130 // Now delete the manager, and only one of the three nodes in the tree
131 // should be released.
132 delete manager;
133 ASSERT_EQ(2, CountedBrowserAccessibility::global_obj_count_);
134
135 // Release each of our references and make sure that each one results in
136 // the instance being deleted as its reference count hits zero.
137 root_iaccessible->Release();
138 ASSERT_EQ(1, CountedBrowserAccessibility::global_obj_count_);
139 child1_iaccessible->Release();
140 ASSERT_EQ(0, CountedBrowserAccessibility::global_obj_count_);
141 }
142
143 TEST_F(BrowserAccessibilityTest, TestChildrenChange) {
144 // Create WebAccessibility objects for a simple document tree,
145 // representing the accessibility information used to initialize
146 // BrowserAccessibilityManager.
147 WebAccessibility text;
148 text.id = 2;
149 text.role = WebAccessibility::ROLE_STATIC_TEXT;
150 text.name = L"old text";
151 text.state = 0;
152
153 WebAccessibility root;
154 root.id = 1;
155 root.name = L"Document";
156 root.role = WebAccessibility::ROLE_DOCUMENT;
157 root.state = 0;
158 root.children.push_back(text);
159
160 // Construct a BrowserAccessibilityManager with this WebAccessibility tree
161 // and a factory for an instance-counting BrowserAccessibility.
162 CountedBrowserAccessibility::global_obj_count_ = 0;
163 BrowserAccessibilityManager* manager =
164 BrowserAccessibilityManager::Create(
165 GetDesktopWindow(),
166 root,
167 NULL,
168 new CountedBrowserAccessibilityFactory());
169
170 // Query for the text IAccessible and verify that it returns "old text" as its
171 // value.
172 base::win::ScopedComPtr<IDispatch> text_dispatch;
173 HRESULT hr = manager->GetRoot()->toBrowserAccessibilityWin()->get_accChild(
174 CreateI4Variant(1), text_dispatch.Receive());
175 ASSERT_EQ(S_OK, hr);
176
177 base::win::ScopedComPtr<IAccessible> text_accessible;
178 hr = text_dispatch.QueryInterface(text_accessible.Receive());
179 ASSERT_EQ(S_OK, hr);
180
181 CComBSTR name;
182 hr = text_accessible->get_accName(CreateI4Variant(CHILDID_SELF), &name);
183 ASSERT_EQ(S_OK, hr);
184 EXPECT_STREQ(L"old text", name.m_str);
185
186 text_dispatch.Release();
187 text_accessible.Release();
188
189 // Notify the BrowserAccessibilityManager that the text child has changed.
190 text.name = L"new text";
191 ViewHostMsg_AccessibilityNotification_Params param;
192 param.notification_type = ViewHostMsg_AccEvent::CHILDREN_CHANGED;
193 param.acc_tree = text;
194 param.includes_children = true;
195 param.id = text.id;
196 std::vector<ViewHostMsg_AccessibilityNotification_Params> notifications;
197 notifications.push_back(param);
198 manager->OnAccessibilityNotifications(notifications);
199
200 // Query for the text IAccessible and verify that it now returns "new text"
201 // as its value.
202 hr = manager->GetRoot()->toBrowserAccessibilityWin()->get_accChild(
203 CreateI4Variant(1),
204 text_dispatch.Receive());
205 ASSERT_EQ(S_OK, hr);
206
207 hr = text_dispatch.QueryInterface(text_accessible.Receive());
208 ASSERT_EQ(S_OK, hr);
209
210 hr = text_accessible->get_accName(CreateI4Variant(CHILDID_SELF), &name);
211 ASSERT_EQ(S_OK, hr);
212 EXPECT_STREQ(L"new text", name.m_str);
213
214 text_dispatch.Release();
215 text_accessible.Release();
216
217 // Delete the manager and test that all BrowserAccessibility instances are
218 // deleted.
219 delete manager;
220 ASSERT_EQ(0, CountedBrowserAccessibility::global_obj_count_);
221 }
222
223 TEST_F(BrowserAccessibilityTest, TestChildrenChangeNoLeaks) {
224 // Create WebAccessibility objects for a simple document tree,
225 // representing the accessibility information used to initialize
226 // BrowserAccessibilityManager.
227 WebAccessibility text;
228 text.id = 3;
229 text.role = WebAccessibility::ROLE_STATIC_TEXT;
230 text.state = 0;
231
232 WebAccessibility div;
233 div.id = 2;
234 div.role = WebAccessibility::ROLE_GROUP;
235 div.state = 0;
236
237 div.children.push_back(text);
238 text.id = 4;
239 div.children.push_back(text);
240
241 WebAccessibility root;
242 root.id = 1;
243 root.role = WebAccessibility::ROLE_DOCUMENT;
244 root.state = 0;
245 root.children.push_back(div);
246
247 // Construct a BrowserAccessibilityManager with this WebAccessibility tree
248 // and a factory for an instance-counting BrowserAccessibility and ensure
249 // that exactly 4 instances were created. Note that the manager takes
250 // ownership of the factory.
251 CountedBrowserAccessibility::global_obj_count_ = 0;
252 BrowserAccessibilityManager* manager =
253 BrowserAccessibilityManager::Create(
254 GetDesktopWindow(),
255 root,
256 NULL,
257 new CountedBrowserAccessibilityFactory());
258 ASSERT_EQ(4, CountedBrowserAccessibility::global_obj_count_);
259
260 // Notify the BrowserAccessibilityManager that the div node and its children
261 // were removed and ensure that only one BrowserAccessibility instance exists.
262 root.children.clear();
263 ViewHostMsg_AccessibilityNotification_Params param;
264 param.notification_type = ViewHostMsg_AccEvent::CHILDREN_CHANGED;
265 param.acc_tree = root;
266 param.includes_children = true;
267 param.id = root.id;
268 std::vector<ViewHostMsg_AccessibilityNotification_Params> notifications;
269 notifications.push_back(param);
270 manager->OnAccessibilityNotifications(notifications);
271 ASSERT_EQ(1, CountedBrowserAccessibility::global_obj_count_);
272
273 // Delete the manager and test that all BrowserAccessibility instances are
274 // deleted.
275 delete manager;
276 ASSERT_EQ(0, CountedBrowserAccessibility::global_obj_count_);
277 }
278
279 TEST_F(BrowserAccessibilityTest, TestTextBoundaries) {
280 WebAccessibility text1;
281 text1.id = 11;
282 text1.role = WebAccessibility::ROLE_TEXT_FIELD;
283 text1.state = 0;
284 text1.value = L"One two three.\nFour five six.";
285 text1.line_breaks.push_back(15);
286
287 WebAccessibility root;
288 root.id = 1;
289 root.role = WebAccessibility::ROLE_DOCUMENT;
290 root.state = 0;
291 root.children.push_back(text1);
292
293 CountedBrowserAccessibility::global_obj_count_ = 0;
294 BrowserAccessibilityManager* manager = BrowserAccessibilityManager::Create(
295 GetDesktopWindow(), root, NULL,
296 new CountedBrowserAccessibilityFactory());
297 ASSERT_EQ(2, CountedBrowserAccessibility::global_obj_count_);
298
299 BrowserAccessibilityWin* root_obj =
300 manager->GetRoot()->toBrowserAccessibilityWin();
301 BrowserAccessibilityWin* text1_obj =
302 root_obj->GetChild(0)->toBrowserAccessibilityWin();
303
304 BSTR text;
305 long start;
306 long end;
307
308 long text1_len;
309 ASSERT_EQ(S_OK, text1_obj->get_nCharacters(&text1_len));
310
311 ASSERT_EQ(S_OK, text1_obj->get_text(0, text1_len, &text));
312 ASSERT_EQ(text, text1.value);
313 SysFreeString(text);
314
315 ASSERT_EQ(S_OK, text1_obj->get_text(0, 4, &text));
316 ASSERT_EQ(text, string16(L"One "));
317 SysFreeString(text);
318
319 ASSERT_EQ(S_OK, text1_obj->get_textAtOffset(
320 1, IA2_TEXT_BOUNDARY_CHAR, &start, &end, &text));
321 ASSERT_EQ(start, 1);
322 ASSERT_EQ(end, 2);
323 ASSERT_EQ(text, string16(L"n"));
324 SysFreeString(text);
325
326 ASSERT_EQ(S_FALSE, text1_obj->get_textAtOffset(
327 text1_len, IA2_TEXT_BOUNDARY_CHAR, &start, &end, &text));
328 ASSERT_EQ(start, text1_len);
329 ASSERT_EQ(end, text1_len);
330
331 ASSERT_EQ(S_OK, text1_obj->get_textAtOffset(
332 1, IA2_TEXT_BOUNDARY_WORD, &start, &end, &text));
333 ASSERT_EQ(start, 0);
334 ASSERT_EQ(end, 3);
335 ASSERT_EQ(text, string16(L"One"));
336 SysFreeString(text);
337
338 ASSERT_EQ(S_OK, text1_obj->get_textAtOffset(
339 6, IA2_TEXT_BOUNDARY_WORD, &start, &end, &text));
340 ASSERT_EQ(start, 4);
341 ASSERT_EQ(end, 7);
342 ASSERT_EQ(text, string16(L"two"));
343 SysFreeString(text);
344
345 ASSERT_EQ(S_OK, text1_obj->get_textAtOffset(
346 text1_len, IA2_TEXT_BOUNDARY_WORD, &start, &end, &text));
347 ASSERT_EQ(start, 25);
348 ASSERT_EQ(end, 29);
349 ASSERT_EQ(text, string16(L"six."));
350 SysFreeString(text);
351
352 ASSERT_EQ(S_OK, text1_obj->get_textAtOffset(
353 1, IA2_TEXT_BOUNDARY_LINE, &start, &end, &text));
354 ASSERT_EQ(start, 0);
355 ASSERT_EQ(end, 15);
356 ASSERT_EQ(text, string16(L"One two three.\n"));
357 SysFreeString(text);
358
359 ASSERT_EQ(S_OK, text1_obj->get_text(0, IA2_TEXT_OFFSET_LENGTH, &text));
360 ASSERT_EQ(text, string16(L"One two three.\nFour five six."));
361 SysFreeString(text);
362
363 // Delete the manager and test that all BrowserAccessibility instances are
364 // deleted.
365 delete manager;
366 ASSERT_EQ(0, CountedBrowserAccessibility::global_obj_count_);
367 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698