[go: nahoru, domu]

blob: 4e5ea52d1fe316a11538c3d2726e84d97be6a6f9 [file] [log] [blame]
Avi Drissman3e1a26c2022-09-15 20:26:031// Copyright 2018 The Chromium Authors
Nektarios Paisiosbe87bc42018-10-12 23:47:032// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "ui/accessibility/ax_node_data.h"
6
Nektarios Paisios31e51882020-05-05 22:17:127#include <set>
Lei Zhang998100f2021-06-25 17:58:198#include <string>
9#include <unordered_set>
10#include <utility>
Nektarios Paisios31e51882020-05-05 22:17:1211
Jan Wilken Dörrie721926d2020-12-09 23:57:4712#include "base/containers/contains.h"
Joanmarie Diggs762303d2022-08-09 10:56:5713#include "base/test/gtest_util.h"
Nektarios Paisiosbe87bc42018-10-12 23:47:0314#include "testing/gtest/include/gtest/gtest.h"
Ian Preste1c32992019-12-04 19:53:1315#include "ui/accessibility/ax_enum_util.h"
Nektarios Paisiosbe87bc42018-10-12 23:47:0316#include "ui/accessibility/ax_enums.mojom.h"
Ian Preste1c32992019-12-04 19:53:1317#include "ui/accessibility/ax_role_properties.h"
Nektarios Paisios70b6a5e2021-08-03 05:32:3618#include "ui/accessibility/ax_text_attributes.h"
Nektarios Paisiosbe87bc42018-10-12 23:47:0319
20namespace ui {
21
22TEST(AXNodeDataTest, GetAndSetCheckedState) {
23 AXNodeData root;
24 EXPECT_EQ(ax::mojom::CheckedState::kNone, root.GetCheckedState());
25 EXPECT_FALSE(root.HasIntAttribute(ax::mojom::IntAttribute::kCheckedState));
26
27 root.SetCheckedState(ax::mojom::CheckedState::kMixed);
28 EXPECT_EQ(ax::mojom::CheckedState::kMixed, root.GetCheckedState());
29 EXPECT_TRUE(root.HasIntAttribute(ax::mojom::IntAttribute::kCheckedState));
30
31 root.SetCheckedState(ax::mojom::CheckedState::kFalse);
32 EXPECT_EQ(ax::mojom::CheckedState::kFalse, root.GetCheckedState());
33 EXPECT_TRUE(root.HasIntAttribute(ax::mojom::IntAttribute::kCheckedState));
34
35 root.SetCheckedState(ax::mojom::CheckedState::kNone);
36 EXPECT_EQ(ax::mojom::CheckedState::kNone, root.GetCheckedState());
37 EXPECT_FALSE(root.HasIntAttribute(ax::mojom::IntAttribute::kCheckedState));
38}
39
Kurt Catti-Schmidtf738bce2019-05-08 01:06:5640TEST(AXNodeDataTest, TextAttributes) {
41 AXNodeData node_1;
42 node_1.AddFloatAttribute(ax::mojom::FloatAttribute::kFontSize, 1.5);
43
44 AXNodeData node_2;
45 node_2.AddFloatAttribute(ax::mojom::FloatAttribute::kFontSize, 1.5);
Nektarios Paisios70b6a5e2021-08-03 05:32:3646 EXPECT_TRUE(node_1.GetTextAttributes() == node_2.GetTextAttributes());
Kurt Catti-Schmidtf738bce2019-05-08 01:06:5647
48 node_2.AddIntAttribute(ax::mojom::IntAttribute::kColor, 100);
Nektarios Paisios70b6a5e2021-08-03 05:32:3649 EXPECT_TRUE(node_1.GetTextAttributes() != node_2.GetTextAttributes());
Kurt Catti-Schmidtf738bce2019-05-08 01:06:5650
51 node_1.AddIntAttribute(ax::mojom::IntAttribute::kColor, 100);
Nektarios Paisios70b6a5e2021-08-03 05:32:3652 EXPECT_TRUE(node_1.GetTextAttributes() == node_2.GetTextAttributes());
Kurt Catti-Schmidtf738bce2019-05-08 01:06:5653
54 node_2.RemoveIntAttribute(ax::mojom::IntAttribute::kColor);
Nektarios Paisios70b6a5e2021-08-03 05:32:3655 EXPECT_TRUE(node_1.GetTextAttributes() != node_2.GetTextAttributes());
Kurt Catti-Schmidtf738bce2019-05-08 01:06:5656
57 node_2.AddIntAttribute(ax::mojom::IntAttribute::kColor, 100);
Nektarios Paisios70b6a5e2021-08-03 05:32:3658 EXPECT_TRUE(node_1.GetTextAttributes() == node_2.GetTextAttributes());
Kurt Catti-Schmidtf738bce2019-05-08 01:06:5659
60 node_1.AddStringAttribute(ax::mojom::StringAttribute::kFontFamily,
61 "test font");
Nektarios Paisios70b6a5e2021-08-03 05:32:3662 EXPECT_TRUE(node_1.GetTextAttributes() != node_2.GetTextAttributes());
Kurt Catti-Schmidtf738bce2019-05-08 01:06:5663
64 node_2.AddStringAttribute(ax::mojom::StringAttribute::kFontFamily,
65 "test font");
Nektarios Paisios70b6a5e2021-08-03 05:32:3666 EXPECT_TRUE(node_1.GetTextAttributes() == node_2.GetTextAttributes());
Kurt Catti-Schmidtf738bce2019-05-08 01:06:5667
68 node_2.RemoveStringAttribute(ax::mojom::StringAttribute::kFontFamily);
Nektarios Paisios70b6a5e2021-08-03 05:32:3669 EXPECT_TRUE(node_1.GetTextAttributes() != node_2.GetTextAttributes());
Kurt Catti-Schmidtf738bce2019-05-08 01:06:5670
71 node_2.AddStringAttribute(ax::mojom::StringAttribute::kFontFamily,
72 "test font");
Nektarios Paisios70b6a5e2021-08-03 05:32:3673 EXPECT_TRUE(node_1.GetTextAttributes() == node_2.GetTextAttributes());
Kurt Catti-Schmidtf738bce2019-05-08 01:06:5674
75 node_2.AddStringAttribute(ax::mojom::StringAttribute::kFontFamily,
76 "different font");
Nektarios Paisios70b6a5e2021-08-03 05:32:3677 EXPECT_TRUE(node_1.GetTextAttributes() != node_2.GetTextAttributes());
Kurt Catti-Schmidtf738bce2019-05-08 01:06:5678
Sara Katoe38f905a2019-10-17 01:25:0079 std::string tooltip;
80 node_2.AddStringAttribute(ax::mojom::StringAttribute::kTooltip,
81 "test tooltip");
82 EXPECT_TRUE(node_2.GetStringAttribute(ax::mojom::StringAttribute::kTooltip,
83 &tooltip));
84 EXPECT_EQ(tooltip, "test tooltip");
85
Nektarios Paisios70b6a5e2021-08-03 05:32:3686 AXTextAttributes node1_attributes = node_1.GetTextAttributes();
87 AXTextAttributes moved_attributes = std::move(node1_attributes);
88 EXPECT_TRUE(node1_attributes != moved_attributes);
89 EXPECT_TRUE(moved_attributes == node_1.GetTextAttributes());
Kurt Catti-Schmidtf738bce2019-05-08 01:06:5690}
91
Victor Fei4f5aa7d2020-04-09 03:15:5092TEST(AXNodeDataTest, IsButtonPressed) {
93 // A non-button element with CheckedState::kTrue should not return true for
94 // IsButtonPressed.
95 AXNodeData non_button_pressed;
96 non_button_pressed.role = ax::mojom::Role::kGenericContainer;
97 non_button_pressed.SetCheckedState(ax::mojom::CheckedState::kTrue);
98 EXPECT_FALSE(IsButton(non_button_pressed.role));
99 EXPECT_FALSE(non_button_pressed.IsButtonPressed());
100
101 // A button element with CheckedState::kTrue should return true for
102 // IsButtonPressed.
103 AXNodeData button_pressed;
104 button_pressed.role = ax::mojom::Role::kButton;
105 button_pressed.SetCheckedState(ax::mojom::CheckedState::kTrue);
106 EXPECT_TRUE(IsButton(button_pressed.role));
107 EXPECT_TRUE(button_pressed.IsButtonPressed());
108
109 button_pressed.role = ax::mojom::Role::kPopUpButton;
110 EXPECT_TRUE(IsButton(button_pressed.role));
111 EXPECT_TRUE(button_pressed.IsButtonPressed());
112
113 button_pressed.role = ax::mojom::Role::kToggleButton;
114 EXPECT_TRUE(IsButton(button_pressed.role));
115 EXPECT_TRUE(button_pressed.IsButtonPressed());
116
117 // A button element does not have CheckedState::kTrue should return false for
118 // IsButtonPressed.
119 AXNodeData button_not_pressed;
120 button_not_pressed.role = ax::mojom::Role::kButton;
121 button_not_pressed.SetCheckedState(ax::mojom::CheckedState::kNone);
122 EXPECT_TRUE(IsButton(button_not_pressed.role));
123 EXPECT_FALSE(button_not_pressed.IsButtonPressed());
124
125 button_not_pressed.role = ax::mojom::Role::kPopUpButton;
126 button_not_pressed.SetCheckedState(ax::mojom::CheckedState::kFalse);
127 EXPECT_TRUE(IsButton(button_not_pressed.role));
128 EXPECT_FALSE(button_not_pressed.IsButtonPressed());
129
130 button_not_pressed.role = ax::mojom::Role::kToggleButton;
131 button_not_pressed.SetCheckedState(ax::mojom::CheckedState::kMixed);
132 EXPECT_TRUE(IsButton(button_not_pressed.role));
133 EXPECT_FALSE(button_not_pressed.IsButtonPressed());
134}
135
136TEST(AXNodeDataTest, IsClickable) {
Ian Preste1c32992019-12-04 19:53:13137 // Test for ax node data attribute with a custom default action verb.
138 AXNodeData data_default_action_verb;
139
140 for (int action_verb_idx =
141 static_cast<int>(ax::mojom::DefaultActionVerb::kMinValue);
142 action_verb_idx <=
143 static_cast<int>(ax::mojom::DefaultActionVerb::kMaxValue);
144 action_verb_idx++) {
145 data_default_action_verb.SetDefaultActionVerb(
146 static_cast<ax::mojom::DefaultActionVerb>(action_verb_idx));
147 bool is_clickable = data_default_action_verb.IsClickable();
148
149 SCOPED_TRACE(testing::Message()
150 << "ax::mojom::DefaultActionVerb="
151 << ToString(data_default_action_verb.GetDefaultActionVerb())
152 << ", Actual: isClickable=" << is_clickable
153 << ", Expected: isClickable=" << !is_clickable);
154
155 if (data_default_action_verb.GetDefaultActionVerb() ==
156 ax::mojom::DefaultActionVerb::kClickAncestor ||
157 data_default_action_verb.GetDefaultActionVerb() ==
158 ax::mojom::DefaultActionVerb::kNone)
159 EXPECT_FALSE(is_clickable);
160 else
161 EXPECT_TRUE(is_clickable);
162 }
163
164 // Test for iterating through all roles and validate if a role is clickable.
Nektarios Paisios31e51882020-05-05 22:17:12165 std::set<ax::mojom::Role> roles_expected_is_clickable = {
Ian Preste1c32992019-12-04 19:53:13166 ax::mojom::Role::kButton,
167 ax::mojom::Role::kCheckBox,
168 ax::mojom::Role::kColorWell,
Nektarios Paisios31e51882020-05-05 22:17:12169 ax::mojom::Role::kComboBoxMenuButton,
Daniel Libbya620cff2022-09-15 22:46:22170 ax::mojom::Role::kComboBoxSelect,
Nektarios Paisios31e51882020-05-05 22:17:12171 ax::mojom::Role::kDate,
172 ax::mojom::Role::kDateTime,
Ian Preste1c32992019-12-04 19:53:13173 ax::mojom::Role::kDisclosureTriangle,
L. David Barona4af9ba62023-12-01 23:18:57174 ax::mojom::Role::kDisclosureTriangleGrouped,
Ian Preste1c32992019-12-04 19:53:13175 ax::mojom::Role::kDocBackLink,
176 ax::mojom::Role::kDocBiblioRef,
177 ax::mojom::Role::kDocGlossRef,
178 ax::mojom::Role::kDocNoteRef,
Nektarios Paisios31e51882020-05-05 22:17:12179 ax::mojom::Role::kImeCandidate,
180 ax::mojom::Role::kInputTime,
Ian Preste1c32992019-12-04 19:53:13181 ax::mojom::Role::kLink,
Nektarios Paisios31e51882020-05-05 22:17:12182 ax::mojom::Role::kListBox,
Ian Preste1c32992019-12-04 19:53:13183 ax::mojom::Role::kListBoxOption,
Ian Preste1c32992019-12-04 19:53:13184 ax::mojom::Role::kMenuItem,
185 ax::mojom::Role::kMenuItemCheckBox,
186 ax::mojom::Role::kMenuItemRadio,
187 ax::mojom::Role::kMenuListOption,
Ankit Kumar 🌪️4d5bf202020-01-28 05:30:47188 ax::mojom::Role::kPdfActionableHighlight,
Ian Preste1c32992019-12-04 19:53:13189 ax::mojom::Role::kPopUpButton,
Nektarios Paisios31e51882020-05-05 22:17:12190 ax::mojom::Role::kPortal,
Ian Preste1c32992019-12-04 19:53:13191 ax::mojom::Role::kRadioButton,
Nektarios Paisios31e51882020-05-05 22:17:12192 ax::mojom::Role::kSearchBox,
193 ax::mojom::Role::kSpinButton,
Ian Preste1c32992019-12-04 19:53:13194 ax::mojom::Role::kSwitch,
195 ax::mojom::Role::kTab,
Nektarios Paisios31e51882020-05-05 22:17:12196 ax::mojom::Role::kTextField,
197 ax::mojom::Role::kTextFieldWithComboBox,
Ian Preste1c32992019-12-04 19:53:13198 ax::mojom::Role::kToggleButton};
199
200 AXNodeData data;
201
202 for (int role_idx = static_cast<int>(ax::mojom::Role::kMinValue);
203 role_idx <= static_cast<int>(ax::mojom::Role::kMaxValue); role_idx++) {
204 data.role = static_cast<ax::mojom::Role>(role_idx);
205 bool is_clickable = data.IsClickable();
206
207 SCOPED_TRACE(testing::Message()
208 << "ax::mojom::Role=" << ToString(data.role)
209 << ", Actual: isClickable=" << is_clickable
210 << ", Expected: isClickable=" << !is_clickable);
211
Nektarios Paisios31e51882020-05-05 22:17:12212 EXPECT_EQ(base::Contains(roles_expected_is_clickable, data.role),
213 is_clickable);
Ian Preste1c32992019-12-04 19:53:13214 }
215}
216
Victor Fei4f5aa7d2020-04-09 03:15:50217TEST(AXNodeDataTest, IsInvocable) {
Ian Preste1c32992019-12-04 19:53:13218 // Test for iterating through all roles and validate if a role is invocable.
Benjamin Beaudry412260d72022-01-14 02:52:36219 // A role is invocable if it is clickable and supports neither expand collapse
220 // nor toggle. A link should always be invocable, regardless of whether it is
221 // clickable or supports expand/collapse or toggle.
Ian Preste1c32992019-12-04 19:53:13222 AXNodeData data;
223 for (int role_idx = static_cast<int>(ax::mojom::Role::kMinValue);
224 role_idx <= static_cast<int>(ax::mojom::Role::kMaxValue); role_idx++) {
225 data.role = static_cast<ax::mojom::Role>(role_idx);
Nektarios Paisios31e51882020-05-05 22:17:12226 bool is_activatable = data.IsActivatable();
227 const bool supports_expand_collapse = data.SupportsExpandCollapse();
228 const bool supports_toggle = ui::SupportsToggle(data.role);
229 const bool is_clickable = data.IsClickable();
230 const bool is_invocable = data.IsInvocable();
Ian Preste1c32992019-12-04 19:53:13231
232 SCOPED_TRACE(testing::Message()
233 << "ax::mojom::Role=" << ToString(data.role)
Nektarios Paisios31e51882020-05-05 22:17:12234 << ", isClickable=" << is_clickable << ", isActivatable="
235 << is_activatable << ", supportsToggle=" << supports_toggle
Ian Preste1c32992019-12-04 19:53:13236 << ", supportsExpandCollapse=" << supports_expand_collapse
237 << ", Actual: isInvocable=" << is_invocable
238 << ", Expected: isInvocable=" << !is_invocable);
239
Benjamin Beaudry412260d72022-01-14 02:52:36240 if (ui::IsLink(data.role) ||
241 (is_clickable && !is_activatable && !supports_toggle &&
242 !supports_expand_collapse)) {
Ian Preste1c32992019-12-04 19:53:13243 EXPECT_TRUE(is_invocable);
Benjamin Beaudry412260d72022-01-14 02:52:36244 } else {
Ian Preste1c32992019-12-04 19:53:13245 EXPECT_FALSE(is_invocable);
Benjamin Beaudry412260d72022-01-14 02:52:36246 }
Ian Preste1c32992019-12-04 19:53:13247 }
248}
249
Victor Fei4f5aa7d2020-04-09 03:15:50250TEST(AXNodeDataTest, IsMenuButton) {
251 // A non button element should return false for IsMenuButton.
252 AXNodeData non_button;
253 non_button.role = ax::mojom::Role::kGenericContainer;
254 EXPECT_FALSE(IsButton(non_button.role));
255 EXPECT_FALSE(non_button.IsMenuButton());
256
257 // Only button element with HasPopup::kMenu should return true for
258 // IsMenuButton. All other ax::mojom::HasPopup types should return false.
259 AXNodeData button_with_popup;
260
261 button_with_popup.role = ax::mojom::Role::kButton;
262
263 for (int has_popup_idx = static_cast<int>(ax::mojom::HasPopup::kMinValue);
264 has_popup_idx <= static_cast<int>(ax::mojom::HasPopup::kMaxValue);
265 has_popup_idx++) {
266 button_with_popup.SetHasPopup(
267 static_cast<ax::mojom::HasPopup>(has_popup_idx));
268 bool is_menu_button = button_with_popup.IsMenuButton();
269
270 SCOPED_TRACE(testing::Message()
271 << "ax::mojom::Role=" << ToString(button_with_popup.role)
272 << ", hasPopup=" << button_with_popup.GetHasPopup()
273 << ", Actual: isMenuButton=" << is_menu_button
274 << ", Expected: isMenuButton=" << !is_menu_button);
275
276 if (IsButton(button_with_popup.role) &&
277 button_with_popup.GetHasPopup() == ax::mojom::HasPopup::kMenu)
278 EXPECT_TRUE(is_menu_button);
279 else
280 EXPECT_FALSE(is_menu_button);
281 }
282}
283
284TEST(AXNodeDataTest, SupportsExpandCollapse) {
Ian Preste1c32992019-12-04 19:53:13285 // Test for iterating through all hasPopup attributes and validate if a
286 // hasPopup attribute supports expand collapse.
287 AXNodeData data_has_popup;
288
289 for (int has_popup_idx = static_cast<int>(ax::mojom::HasPopup::kMinValue);
290 has_popup_idx <= static_cast<int>(ax::mojom::HasPopup::kMaxValue);
291 has_popup_idx++) {
292 data_has_popup.SetHasPopup(static_cast<ax::mojom::HasPopup>(has_popup_idx));
293 bool supports_expand_collapse = data_has_popup.SupportsExpandCollapse();
294
295 SCOPED_TRACE(testing::Message() << "ax::mojom::HasPopup="
296 << ToString(data_has_popup.GetHasPopup())
297 << ", Actual: supportsExpandCollapse="
298 << supports_expand_collapse
299 << ", Expected: supportsExpandCollapse="
300 << !supports_expand_collapse);
301
302 if (data_has_popup.GetHasPopup() == ax::mojom::HasPopup::kFalse)
303 EXPECT_FALSE(supports_expand_collapse);
304 else
305 EXPECT_TRUE(supports_expand_collapse);
306 }
307
308 // Test for iterating through all states and validate if a state supports
309 // expand collapse.
310 AXNodeData data_state;
311
312 for (int state_idx = static_cast<int>(ax::mojom::State::kMinValue);
313 state_idx <= static_cast<int>(ax::mojom::State::kMaxValue);
314 state_idx++) {
315 ax::mojom::State state = static_cast<ax::mojom::State>(state_idx);
316
317 // skipping kNone here because AXNodeData::AddState, RemoveState forbids
318 // kNone to be added/removed and would fail DCHECK.
319 if (state == ax::mojom::State::kNone)
320 continue;
321
322 data_state.AddState(state);
323
324 bool supports_expand_collapse = data_state.SupportsExpandCollapse();
325
326 SCOPED_TRACE(testing::Message() << "ax::mojom::State=" << ToString(state)
327 << ", Actual: supportsExpandCollapse="
328 << supports_expand_collapse
329 << ", Expected: supportsExpandCollapse="
330 << !supports_expand_collapse);
331
332 if (data_state.HasState(ax::mojom::State::kExpanded) ||
333 data_state.HasState(ax::mojom::State::kCollapsed))
334 EXPECT_TRUE(supports_expand_collapse);
335 else
336 EXPECT_FALSE(supports_expand_collapse);
337
338 data_state.RemoveState(state);
339 }
340
341 // Test for iterating through all roles and validate if a role supports expand
342 // collapse.
343 AXNodeData data;
344
345 std::unordered_set<ax::mojom::Role> roles_expected_supports_expand_collapse =
Daniel Libbya620cff2022-09-15 22:46:22346 {ax::mojom::Role::kComboBoxGrouping,
347 ax::mojom::Role::kComboBoxMenuButton,
348 ax::mojom::Role::kComboBoxSelect,
Ian Preste1c32992019-12-04 19:53:13349 ax::mojom::Role::kDisclosureTriangle,
L. David Barona4af9ba62023-12-01 23:18:57350 ax::mojom::Role::kDisclosureTriangleGrouped,
Daniel Libbya620cff2022-09-15 22:46:22351 ax::mojom::Role::kTextFieldWithComboBox,
352 ax::mojom::Role::kTreeItem};
Ian Preste1c32992019-12-04 19:53:13353
354 for (int role_idx = static_cast<int>(ax::mojom::Role::kMinValue);
355 role_idx <= static_cast<int>(ax::mojom::Role::kMaxValue); role_idx++) {
356 data.role = static_cast<ax::mojom::Role>(role_idx);
357 bool supports_expand_collapse = data.SupportsExpandCollapse();
358
359 SCOPED_TRACE(testing::Message() << "ax::mojom::Role=" << ToString(data.role)
360 << ", Actual: supportsExpandCollapse="
361 << supports_expand_collapse
362 << ", Expected: supportsExpandCollapse="
363 << !supports_expand_collapse);
364
365 if (roles_expected_supports_expand_collapse.find(data.role) !=
366 roles_expected_supports_expand_collapse.end())
367 EXPECT_TRUE(supports_expand_collapse);
368 else
369 EXPECT_FALSE(supports_expand_collapse);
370 }
371}
372
Joanmarie Diggs762303d2022-08-09 10:56:57373TEST(AXNodeDataTest, SetName) {
374 AXNodeData data;
Joanmarie Diggs008ea7c2022-09-12 20:22:34375 // SetName should not be called on a role of kUnknown. That role means the
376 // role has not yet been set, and we need a role to identify the NameFrom on
377 // objects where it has not been set. This is enforced by a DCHECK.
378 EXPECT_DCHECK_DEATH(data.SetName("no role yet"));
379
Joanmarie Diggs762303d2022-08-09 10:56:57380 // SetName should not be called on a role of kNone. That role is used for
381 // presentational objects which should not be included in the accessibility
382 // tree. This is enforced by a DCHECK.
383 data.role = ax::mojom::Role::kNone;
384 EXPECT_DCHECK_DEATH(data.SetName("role is presentational"));
385
386 // For roles other than text, setting the name should result in the NameFrom
387 // source being kAttribute.
388 data.role = ax::mojom::Role::kButton;
389 data.SetName("foo");
390 EXPECT_EQ("foo", data.GetStringAttribute(ax::mojom::StringAttribute::kName));
391 EXPECT_EQ(data.GetNameFrom(), ax::mojom::NameFrom::kAttribute);
392
393 // TODO(accessibility): The static text role should have a NameFrom source of
394 // kContents. But nothing clears the NameFrom if the role of an existing
395 // object changes because currently there is no AXNodeData::SetRole method.
396 data.role = ax::mojom::Role::kStaticText;
397 data.SetName("bar");
398 EXPECT_EQ("bar", data.GetStringAttribute(ax::mojom::StringAttribute::kName));
399 EXPECT_EQ(data.GetNameFrom(), ax::mojom::NameFrom::kAttribute);
400
401 data.RemoveIntAttribute(ax::mojom::IntAttribute::kNameFrom);
402 data.SetName("baz");
403 EXPECT_EQ("baz", data.GetStringAttribute(ax::mojom::StringAttribute::kName));
404 EXPECT_EQ(data.GetNameFrom(), ax::mojom::NameFrom::kContents);
405
Joanmarie Diggs8ca948392022-09-29 17:11:00406 // Setting the name to the empty string should not be done by
407 // `SetNameChecked`, which enforces that expectation with a DCHECK.
408 EXPECT_DCHECK_DEATH(data.SetNameChecked(""));
409
Joanmarie Diggs762303d2022-08-09 10:56:57410 data.SetNameExplicitlyEmpty();
411 EXPECT_EQ("", data.GetStringAttribute(ax::mojom::StringAttribute::kName));
412 EXPECT_EQ(data.GetNameFrom(), ax::mojom::NameFrom::kAttributeExplicitlyEmpty);
413
414 data.SetName("foo");
415 EXPECT_EQ("foo", data.GetStringAttribute(ax::mojom::StringAttribute::kName));
416 EXPECT_EQ(data.GetNameFrom(), ax::mojom::NameFrom::kContents);
417}
418
Joanmarie Diggsca2b5ce2022-10-07 20:57:09419TEST(AXNodeDataTest, SetDescription) {
420 AXNodeData data;
421 data.role = ax::mojom::Role::kButton;
422
423 // Initially there is no description and no DescriptionFrom.
424 EXPECT_EQ("",
425 data.GetStringAttribute(ax::mojom::StringAttribute::kDescription));
426 EXPECT_EQ(data.GetDescriptionFrom(), ax::mojom::DescriptionFrom::kNone);
427
428 // When the DescriptionFrom is not specified it defaults to kAriaDescription.
429 data.SetDescription("foo");
430 EXPECT_EQ("foo",
431 data.GetStringAttribute(ax::mojom::StringAttribute::kDescription));
432 EXPECT_EQ(data.GetDescriptionFrom(),
433 ax::mojom::DescriptionFrom::kAriaDescription);
434
435 // Setting the description explicitly empty should both clear the string
436 // and update the DescriptionFrom.
437 data.SetDescriptionExplicitlyEmpty();
438 EXPECT_EQ("",
439 data.GetStringAttribute(ax::mojom::StringAttribute::kDescription));
440 EXPECT_EQ(data.GetDescriptionFrom(),
441 ax::mojom::DescriptionFrom::kAttributeExplicitlyEmpty);
442
443 // We currently do not enforce that the description gets set prior to the
444 // DescriptionFrom. As a result it is possible to have a DescriptionFrom
445 // value other than kNone and kAttributeExplicitlyEmpty while the description
446 // is an empty string.
447 data.SetDescriptionFrom(ax::mojom::DescriptionFrom::kTitle);
448 EXPECT_EQ("",
449 data.GetStringAttribute(ax::mojom::StringAttribute::kDescription));
450 EXPECT_EQ(data.GetDescriptionFrom(), ax::mojom::DescriptionFrom::kTitle);
451
452 // Setting the description to the empty string should not be done by
453 // SetDescription, which enforces that expectation with a DCHECK.
454 EXPECT_DCHECK_DEATH(data.SetDescription(""));
455}
456
Mark Schillaci47159f62023-04-10 17:10:28457TEST(AXNodeDataTest, BitFieldsConfidenceCheck) {
Hiroki Satofdb71f412020-02-27 01:18:37458 EXPECT_LT(static_cast<size_t>(ax::mojom::State::kMaxValue),
459 sizeof(AXNodeData::state) * 8);
460 EXPECT_LT(static_cast<size_t>(ax::mojom::Action::kMaxValue),
461 sizeof(AXNodeData::actions) * 8);
462}
463
Nektarios Paisiosbe87bc42018-10-12 23:47:03464} // namespace ui