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

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

Issue 3591003: Make BrowserAccessibilityManager cross platform. Step 1.... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Some cleanup. Created 10 years, 2 months 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) 2010 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/scoped_ptr.h"
6 #include "base/scoped_comptr_win.h"
7 #include "chrome/browser/browser_accessibility_manager_win.h"
8 #include "chrome/browser/browser_accessibility_win.h"
9 #include "chrome/common/render_messages_params.h"
10 #include "testing/gtest/include/gtest/gtest.h"
11
12 using webkit_glue::WebAccessibility;
13
14 // Subclass of BrowserAccessibility that counts the number of instances.
15 class CountedBrowserAccessibility : public BrowserAccessibility {
16 public:
17 CountedBrowserAccessibility() { global_obj_count_++; }
18 virtual ~CountedBrowserAccessibility() { global_obj_count_--; }
19 static int global_obj_count_;
20 };
21
22 int CountedBrowserAccessibility::global_obj_count_ = 0;
23
24 // Factory that creates a CountedBrowserAccessibility.
25 class CountedBrowserAccessibilityFactory : public BrowserAccessibilityFactory {
26 public:
27 virtual ~CountedBrowserAccessibilityFactory() {}
28 virtual BrowserAccessibility* Create() {
29 CComObject<CountedBrowserAccessibility>* instance;
30 HRESULT hr = CComObject<CountedBrowserAccessibility>::CreateInstance(
31 &instance);
32 DCHECK(SUCCEEDED(hr));
33 return instance->NewReference();
34 }
35 };
36
37 VARIANT CreateI4Variant(LONG value) {
38 VARIANT variant = {0};
39
40 V_VT(&variant) = VT_I4;
41 V_I4(&variant) = value;
42
43 return variant;
44 }
45
46 class BrowserAccessibilityTest : public testing::Test {
47 protected:
48 virtual void SetUp() {
49 // ATL needs a pointer to a COM module.
50 static CComModule module;
51 _pAtlModule = &module;
52
53 // Make sure COM is initialized for this thread; it's safe to call twice.
54 ::CoInitialize(NULL);
55 }
56
57 virtual void TearDown()
58 {
59 ::CoUninitialize();
60 }
61 };
62
63 // Test that BrowserAccessibilityManager correctly releases the tree of
64 // BrowserAccessibility instances upon delete.
65 TEST_F(BrowserAccessibilityTest, TestNoLeaks) {
66 // Create WebAccessibility objects for a simple document tree,
67 // representing the accessibility information used to initialize
68 // BrowserAccessibilityManager.
69 WebAccessibility button;
70 button.id = 2;
71 button.name = L"Button";
72 button.role = WebAccessibility::ROLE_BUTTON;
73 button.state = 0;
74
75 WebAccessibility checkbox;
76 checkbox.id = 3;
77 checkbox.name = L"Checkbox";
78 checkbox.role = WebAccessibility::ROLE_CHECKBOX;
79 checkbox.state = 0;
80
81 WebAccessibility root;
82 root.id = 1;
83 root.name = L"Document";
84 root.role = WebAccessibility::ROLE_DOCUMENT;
85 root.state = 0;
86 root.children.push_back(button);
87 root.children.push_back(checkbox);
88
89 // Construct a BrowserAccessibilityManager with this WebAccessibility tree
90 // and a factory for an instance-counting BrowserAccessibility, and ensure
91 // that exactly 3 instances were created. Note that the manager takes
92 // ownership of the factory.
93 CountedBrowserAccessibility::global_obj_count_ = 0;
94 BrowserAccessibilityManager* manager =
95 new BrowserAccessibilityManager(
96 GetDesktopWindow(), root, NULL,
97 new CountedBrowserAccessibilityFactory());
98 ASSERT_EQ(3, CountedBrowserAccessibility::global_obj_count_);
99
100 // Delete the manager and test that all 3 instances are deleted.
101 delete manager;
102 ASSERT_EQ(0, CountedBrowserAccessibility::global_obj_count_);
103
104 // Construct a manager again, and this time use the IAccessible interface
105 // to get new references to two of the three nodes in the tree.
106 manager = new BrowserAccessibilityManager(
107 GetDesktopWindow(), root, NULL,
108 new CountedBrowserAccessibilityFactory());
109 ASSERT_EQ(3, CountedBrowserAccessibility::global_obj_count_);
110 BrowserAccessibility* root_accessible = manager->GetRoot();
111 IDispatch* root_iaccessible = NULL;
112 IDispatch* child1_iaccessible = NULL;
113 VARIANT var_child;
114 var_child.vt = VT_I4;
115 var_child.lVal = CHILDID_SELF;
116 HRESULT hr = root_accessible->get_accChild(var_child, &root_iaccessible);
117 ASSERT_EQ(S_OK, hr);
118 var_child.lVal = 1;
119 hr = root_accessible->get_accChild(var_child, &child1_iaccessible);
120 ASSERT_EQ(S_OK, hr);
121
122 // Now delete the manager, and only one of the three nodes in the tree
123 // should be released.
124 delete manager;
125 ASSERT_EQ(2, CountedBrowserAccessibility::global_obj_count_);
126
127 // Release each of our references and make sure that each one results in
128 // the instance being deleted as its reference count hits zero.
129 root_iaccessible->Release();
130 ASSERT_EQ(1, CountedBrowserAccessibility::global_obj_count_);
131 child1_iaccessible->Release();
132 ASSERT_EQ(0, CountedBrowserAccessibility::global_obj_count_);
133 }
134
135 TEST_F(BrowserAccessibilityTest, TestChildrenChange) {
136 // Create WebAccessibility objects for a simple document tree,
137 // representing the accessibility information used to initialize
138 // BrowserAccessibilityManager.
139 WebAccessibility text;
140 text.id = 2;
141 text.role = WebAccessibility::ROLE_STATIC_TEXT;
142 text.value = L"old text";
143 text.state = 0;
144
145 WebAccessibility root;
146 root.id = 1;
147 root.name = L"Document";
148 root.role = WebAccessibility::ROLE_DOCUMENT;
149 root.state = 0;
150 root.children.push_back(text);
151
152 // Construct a BrowserAccessibilityManager with this WebAccessibility tree
153 // and a factory for an instance-counting BrowserAccessibility.
154 CountedBrowserAccessibility::global_obj_count_ = 0;
155 BrowserAccessibilityManager* manager =
156 new BrowserAccessibilityManager(
157 GetDesktopWindow(), root, NULL,
158 new CountedBrowserAccessibilityFactory());
159
160 // Query for the text IAccessible and verify that it returns "old text" as its
161 // value.
162 ScopedComPtr<IDispatch> text_dispatch;
163 HRESULT hr = manager->GetRoot()->get_accChild(CreateI4Variant(1),
164 text_dispatch.Receive());
165 ASSERT_EQ(S_OK, hr);
166
167 ScopedComPtr<IAccessible> text_accessible;
168 hr = text_dispatch.QueryInterface(text_accessible.Receive());
169 ASSERT_EQ(S_OK, hr);
170
171 CComBSTR value;
172 hr = text_accessible->get_accValue(CreateI4Variant(CHILDID_SELF), &value);
173 ASSERT_EQ(S_OK, hr);
174 EXPECT_STREQ(L"old text", value.m_str);
175
176 text_dispatch.Release();
177 text_accessible.Release();
178
179 // Notify the BrowserAccessibilityManager that the text child has changed.
180 text.value = L"new text";
181 ViewHostMsg_AccessibilityNotification_Params param;
182 param.notification_type =
183 ViewHostMsg_AccessibilityNotification_Params::
184 NOTIFICATION_TYPE_CHILDREN_CHANGED;
185 param.acc_obj = text;
186 std::vector<ViewHostMsg_AccessibilityNotification_Params> notifications;
187 notifications.push_back(param);
188 manager->OnAccessibilityNotifications(notifications);
189
190 // Query for the text IAccessible and verify that it now returns "new text"
191 // as its value.
192 hr = manager->GetRoot()->get_accChild(
193 CreateI4Variant(1),
194 text_dispatch.Receive());
195 ASSERT_EQ(S_OK, hr);
196
197 hr = text_dispatch.QueryInterface(text_accessible.Receive());
198 ASSERT_EQ(S_OK, hr);
199
200 hr = text_accessible->get_accValue(CreateI4Variant(CHILDID_SELF), &value);
201 ASSERT_EQ(S_OK, hr);
202 EXPECT_STREQ(L"new text", value.m_str);
203
204 text_dispatch.Release();
205 text_accessible.Release();
206
207 // Delete the manager and test that all BrowserAccessibility instances are
208 // deleted.
209 delete manager;
210 ASSERT_EQ(0, CountedBrowserAccessibility::global_obj_count_);
211 }
212
213 TEST_F(BrowserAccessibilityTest, TestChildrenChangeNoLeaks) {
214 // Create WebAccessibility objects for a simple document tree,
215 // representing the accessibility information used to initialize
216 // BrowserAccessibilityManager.
217 WebAccessibility text;
218 text.id = 3;
219 text.role = WebAccessibility::ROLE_STATIC_TEXT;
220 text.state = 0;
221
222 WebAccessibility div;
223 div.id = 2;
224 div.role = WebAccessibility::ROLE_GROUP;
225 div.state = 0;
226
227 div.children.push_back(text);
228 text.id = 4;
229 div.children.push_back(text);
230
231 WebAccessibility root;
232 root.id = 1;
233 root.role = WebAccessibility::ROLE_DOCUMENT;
234 root.state = 0;
235 root.children.push_back(div);
236
237 // Construct a BrowserAccessibilityManager with this WebAccessibility tree
238 // and a factory for an instance-counting BrowserAccessibility and ensure
239 // that exactly 4 instances were created. Note that the manager takes
240 // ownership of the factory.
241 CountedBrowserAccessibility::global_obj_count_ = 0;
242 BrowserAccessibilityManager* manager =
243 new BrowserAccessibilityManager(
244 GetDesktopWindow(), root, NULL,
245 new CountedBrowserAccessibilityFactory());
246 ASSERT_EQ(4, CountedBrowserAccessibility::global_obj_count_);
247
248 // Notify the BrowserAccessibilityManager that the div node and its children
249 // were removed and ensure that only one BrowserAccessibility instance exists.
250 root.children.clear();
251 ViewHostMsg_AccessibilityNotification_Params param;
252 param.notification_type =
253 ViewHostMsg_AccessibilityNotification_Params::
254 NOTIFICATION_TYPE_CHILDREN_CHANGED;
255 param.acc_obj = root;
256 std::vector<ViewHostMsg_AccessibilityNotification_Params> notifications;
257 notifications.push_back(param);
258 manager->OnAccessibilityNotifications(notifications);
259 ASSERT_EQ(1, CountedBrowserAccessibility::global_obj_count_);
260
261 // Delete the manager and test that all BrowserAccessibility instances are
262 // deleted.
263 delete manager;
264 ASSERT_EQ(0, CountedBrowserAccessibility::global_obj_count_);
265 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698