Flutter Engine
The Flutter Engine
ax_node_data_unittest.cc
Go to the documentation of this file.
1// Copyright 2018 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 "ax_node_data.h"
6
7#include <set>
8#include <unordered_set>
9
10#include "gtest/gtest.h"
11
12#include "ax_enum_util.h"
13#include "ax_enums.h"
14#include "ax_role_properties.h"
16
17namespace ui {
18
19TEST(AXNodeDataTest, GetAndSetCheckedState) {
21 EXPECT_EQ(ax::mojom::CheckedState::kNone, root.GetCheckedState());
22 EXPECT_FALSE(root.HasIntAttribute(ax::mojom::IntAttribute::kCheckedState));
23
25 EXPECT_EQ(ax::mojom::CheckedState::kMixed, root.GetCheckedState());
27
29 EXPECT_EQ(ax::mojom::CheckedState::kFalse, root.GetCheckedState());
31
32 root.SetCheckedState(ax::mojom::CheckedState::kNone);
33 EXPECT_EQ(ax::mojom::CheckedState::kNone, root.GetCheckedState());
34 EXPECT_FALSE(root.HasIntAttribute(ax::mojom::IntAttribute::kCheckedState));
35}
36
37TEST(AXNodeDataTest, TextAttributes) {
38 AXNodeData node_1;
40
41 AXNodeData node_2;
43 EXPECT_TRUE(node_1.GetTextStyles() == node_2.GetTextStyles());
44
46 EXPECT_TRUE(node_1.GetTextStyles() != node_2.GetTextStyles());
47
49 EXPECT_TRUE(node_1.GetTextStyles() == node_2.GetTextStyles());
50
52 EXPECT_TRUE(node_1.GetTextStyles() != node_2.GetTextStyles());
53
55 EXPECT_TRUE(node_1.GetTextStyles() == node_2.GetTextStyles());
56
58 "test font");
59 EXPECT_TRUE(node_1.GetTextStyles() != node_2.GetTextStyles());
60
62 "test font");
63 EXPECT_TRUE(node_1.GetTextStyles() == node_2.GetTextStyles());
64
66 EXPECT_TRUE(node_1.GetTextStyles() != node_2.GetTextStyles());
67
69 "test font");
70 EXPECT_TRUE(node_1.GetTextStyles() == node_2.GetTextStyles());
71
73 "different font");
74 EXPECT_TRUE(node_1.GetTextStyles() != node_2.GetTextStyles());
75
76 std::string tooltip;
78 "test tooltip");
80 &tooltip));
81 EXPECT_EQ(tooltip, "test tooltip");
82
83 AXNodeTextStyles node1_styles = node_1.GetTextStyles();
84 AXNodeTextStyles moved_styles = std::move(node1_styles);
85 EXPECT_TRUE(node1_styles != moved_styles);
86 EXPECT_TRUE(moved_styles == node_1.GetTextStyles());
87}
88
89TEST(AXNodeDataTest, IsButtonPressed) {
90 // A non-button element with CheckedState::kTrue should not return true for
91 // IsButtonPressed.
92 AXNodeData non_button_pressed;
93 non_button_pressed.role = ax::mojom::Role::kGenericContainer;
95 EXPECT_FALSE(IsButton(non_button_pressed.role));
96 EXPECT_FALSE(non_button_pressed.IsButtonPressed());
97
98 // A button element with CheckedState::kTrue should return true for
99 // IsButtonPressed.
100 AXNodeData button_pressed;
101 button_pressed.role = ax::mojom::Role::kButton;
103 EXPECT_TRUE(IsButton(button_pressed.role));
104 EXPECT_TRUE(button_pressed.IsButtonPressed());
105
106 button_pressed.role = ax::mojom::Role::kPopUpButton;
107 EXPECT_TRUE(IsButton(button_pressed.role));
108 EXPECT_TRUE(button_pressed.IsButtonPressed());
109
110 button_pressed.role = ax::mojom::Role::kToggleButton;
111 EXPECT_TRUE(IsButton(button_pressed.role));
112 EXPECT_TRUE(button_pressed.IsButtonPressed());
113
114 // A button element does not have CheckedState::kTrue should return false for
115 // IsButtonPressed.
116 AXNodeData button_not_pressed;
117 button_not_pressed.role = ax::mojom::Role::kButton;
119 EXPECT_TRUE(IsButton(button_not_pressed.role));
120 EXPECT_FALSE(button_not_pressed.IsButtonPressed());
121
122 button_not_pressed.role = ax::mojom::Role::kPopUpButton;
124 EXPECT_TRUE(IsButton(button_not_pressed.role));
125 EXPECT_FALSE(button_not_pressed.IsButtonPressed());
126
127 button_not_pressed.role = ax::mojom::Role::kToggleButton;
129 EXPECT_TRUE(IsButton(button_not_pressed.role));
130 EXPECT_FALSE(button_not_pressed.IsButtonPressed());
131}
132
133TEST(AXNodeDataTest, IsClickable) {
134 // Test for ax node data attribute with a custom default action verb.
135 AXNodeData data_default_action_verb;
136
137 for (int action_verb_idx =
139 action_verb_idx <=
141 action_verb_idx++) {
142 data_default_action_verb.SetDefaultActionVerb(
143 static_cast<ax::mojom::DefaultActionVerb>(action_verb_idx));
144 bool is_clickable = data_default_action_verb.IsClickable();
145
146 SCOPED_TRACE(testing::Message()
147 << "ax::mojom::DefaultActionVerb="
148 << ToString(data_default_action_verb.GetDefaultActionVerb())
149 << ", Actual: isClickable=" << is_clickable
150 << ", Expected: isClickable=" << !is_clickable);
151
152 if (data_default_action_verb.GetDefaultActionVerb() ==
154 data_default_action_verb.GetDefaultActionVerb() ==
156 EXPECT_FALSE(is_clickable);
157 else
158 EXPECT_TRUE(is_clickable);
159 }
160
161 // Test for iterating through all roles and validate if a role is clickable.
162 std::set<ax::mojom::Role> roles_expected_is_clickable = {
194
196
197 for (int role_idx = static_cast<int>(ax::mojom::Role::kMinValue);
198 role_idx <= static_cast<int>(ax::mojom::Role::kMaxValue); role_idx++) {
199 data.role = static_cast<ax::mojom::Role>(role_idx);
200 bool is_clickable = data.IsClickable();
201
202 SCOPED_TRACE(testing::Message()
203 << "ax::mojom::Role=" << ToString(data.role)
204 << ", Actual: isClickable=" << is_clickable
205 << ", Expected: isClickable=" << !is_clickable);
206
207 EXPECT_EQ(base::Contains(roles_expected_is_clickable, data.role),
208 is_clickable);
209 }
210}
211
212TEST(AXNodeDataTest, IsInvocable) {
213 // Test for iterating through all roles and validate if a role is invocable.
214 // A role is invocable if it is clickable and supports neither expand collapse
215 // nor toggle.
217 for (int role_idx = static_cast<int>(ax::mojom::Role::kMinValue);
218 role_idx <= static_cast<int>(ax::mojom::Role::kMaxValue); role_idx++) {
219 data.role = static_cast<ax::mojom::Role>(role_idx);
220 bool is_activatable = data.IsActivatable();
221 const bool supports_expand_collapse = data.SupportsExpandCollapse();
222 const bool supports_toggle = ui::SupportsToggle(data.role);
223 const bool is_clickable = data.IsClickable();
224 const bool is_invocable = data.IsInvocable();
225
226 SCOPED_TRACE(testing::Message()
227 << "ax::mojom::Role=" << ToString(data.role)
228 << ", isClickable=" << is_clickable << ", isActivatable="
229 << is_activatable << ", supportsToggle=" << supports_toggle
230 << ", supportsExpandCollapse=" << supports_expand_collapse
231 << ", Actual: isInvocable=" << is_invocable
232 << ", Expected: isInvocable=" << !is_invocable);
233
234 if (is_clickable && !is_activatable && !supports_toggle &&
235 !supports_expand_collapse)
236 EXPECT_TRUE(is_invocable);
237 else
238 EXPECT_FALSE(is_invocable);
239 }
240}
241
242TEST(AXNodeDataTest, IsMenuButton) {
243 // A non button element should return false for IsMenuButton.
244 AXNodeData non_button;
246 EXPECT_FALSE(IsButton(non_button.role));
247 EXPECT_FALSE(non_button.IsMenuButton());
248
249 // Only button element with HasPopup::kMenu should return true for
250 // IsMenuButton. All other ax::mojom::HasPopup types should return false.
251 AXNodeData button_with_popup;
252
253 button_with_popup.role = ax::mojom::Role::kButton;
254
255 for (int has_popup_idx = static_cast<int>(ax::mojom::HasPopup::kMinValue);
256 has_popup_idx <= static_cast<int>(ax::mojom::HasPopup::kMaxValue);
257 has_popup_idx++) {
258 button_with_popup.SetHasPopup(
259 static_cast<ax::mojom::HasPopup>(has_popup_idx));
260 bool is_menu_button = button_with_popup.IsMenuButton();
261
262 SCOPED_TRACE(testing::Message()
263 << "ax::mojom::Role=" << ToString(button_with_popup.role)
264 << ", hasPopup=" << ToString(button_with_popup.GetHasPopup())
265 << ", Actual: isMenuButton=" << is_menu_button
266 << ", Expected: isMenuButton=" << !is_menu_button);
267
268 if (IsButton(button_with_popup.role) &&
269 button_with_popup.GetHasPopup() == ax::mojom::HasPopup::kMenu)
270 EXPECT_TRUE(is_menu_button);
271 else
272 EXPECT_FALSE(is_menu_button);
273 }
274}
275
276TEST(AXNodeDataTest, SupportsExpandCollapse) {
277 // Test for iterating through all hasPopup attributes and validate if a
278 // hasPopup attribute supports expand collapse.
279 AXNodeData data_has_popup;
280
281 for (int has_popup_idx = static_cast<int>(ax::mojom::HasPopup::kMinValue);
282 has_popup_idx <= static_cast<int>(ax::mojom::HasPopup::kMaxValue);
283 has_popup_idx++) {
284 data_has_popup.SetHasPopup(static_cast<ax::mojom::HasPopup>(has_popup_idx));
285 bool supports_expand_collapse = data_has_popup.SupportsExpandCollapse();
286
287 SCOPED_TRACE(testing::Message() << "ax::mojom::HasPopup="
288 << ToString(data_has_popup.GetHasPopup())
289 << ", Actual: supportsExpandCollapse="
290 << supports_expand_collapse
291 << ", Expected: supportsExpandCollapse="
292 << !supports_expand_collapse);
293
294 if (data_has_popup.GetHasPopup() == ax::mojom::HasPopup::kFalse)
295 EXPECT_FALSE(supports_expand_collapse);
296 else
297 EXPECT_TRUE(supports_expand_collapse);
298 }
299
300 // Test for iterating through all states and validate if a state supports
301 // expand collapse.
302 AXNodeData data_state;
303
304 for (int state_idx = static_cast<int>(ax::mojom::State::kMinValue);
305 state_idx <= static_cast<int>(ax::mojom::State::kMaxValue);
306 state_idx++) {
307 ax::mojom::State state = static_cast<ax::mojom::State>(state_idx);
308
309 // skipping kNone here because AXNodeData::AddState, RemoveState forbids
310 // kNone to be added/removed and would fail DCHECK.
312 continue;
313
314 data_state.AddState(state);
315
316 bool supports_expand_collapse = data_state.SupportsExpandCollapse();
317
318 SCOPED_TRACE(testing::Message() << "ax::mojom::State=" << ToString(state)
319 << ", Actual: supportsExpandCollapse="
320 << supports_expand_collapse
321 << ", Expected: supportsExpandCollapse="
322 << !supports_expand_collapse);
323
324 if (data_state.HasState(ax::mojom::State::kExpanded) ||
326 EXPECT_TRUE(supports_expand_collapse);
327 else
328 EXPECT_FALSE(supports_expand_collapse);
329
330 data_state.RemoveState(state);
331 }
332
333 // Test for iterating through all roles and validate if a role supports expand
334 // collapse.
336
337 std::unordered_set<ax::mojom::Role> roles_expected_supports_expand_collapse =
341
342 for (int role_idx = static_cast<int>(ax::mojom::Role::kMinValue);
343 role_idx <= static_cast<int>(ax::mojom::Role::kMaxValue); role_idx++) {
344 data.role = static_cast<ax::mojom::Role>(role_idx);
345 bool supports_expand_collapse = data.SupportsExpandCollapse();
346
347 SCOPED_TRACE(testing::Message() << "ax::mojom::Role=" << ToString(data.role)
348 << ", Actual: supportsExpandCollapse="
349 << supports_expand_collapse
350 << ", Expected: supportsExpandCollapse="
351 << !supports_expand_collapse);
352
353 if (roles_expected_supports_expand_collapse.find(data.role) !=
354 roles_expected_supports_expand_collapse.end())
355 EXPECT_TRUE(supports_expand_collapse);
356 else
357 EXPECT_FALSE(supports_expand_collapse);
358 }
359}
360
361TEST(AXNodeDataTest, BitFieldsSanityCheck) {
362 EXPECT_LT(static_cast<size_t>(ax::mojom::State::kMaxValue),
363 sizeof(AXNodeData::state) * 8);
364 EXPECT_LT(static_cast<size_t>(ax::mojom::Action::kMaxValue),
365 sizeof(AXNodeData::actions) * 8);
366}
367
368} // namespace ui
AtkStateType state
DefaultActionVerb
Definition: ax_enums.h:489
bool Contains(const Container &container, const Value &value)
string root
Definition: scale_cpu.py:20
TEST(AXEnumUtilTest, Event)
const char * ToString(ax::mojom::Event event)
Definition: ax_enum_util.cc:9
bool SupportsExpandCollapse(const ax::mojom::Role role)
bool SupportsToggle(const ax::mojom::Role role)
bool IsClickable(const ax::mojom::Role role)
bool IsButton(const ax::mojom::Role role)
void AddFloatAttribute(ax::mojom::FloatAttribute attribute, float value)
bool HasState(ax::mojom::State state) const
ax::mojom::HasPopup GetHasPopup() const
bool IsClickable() const
void AddState(ax::mojom::State state)
void SetDefaultActionVerb(ax::mojom::DefaultActionVerb default_action_verb)
void RemoveIntAttribute(ax::mojom::IntAttribute attribute)
void AddIntAttribute(ax::mojom::IntAttribute attribute, int32_t value)
uint32_t state
Definition: ax_node_data.h:278
uint64_t actions
Definition: ax_node_data.h:279
void SetHasPopup(ax::mojom::HasPopup has_popup)
ax::mojom::DefaultActionVerb GetDefaultActionVerb() const
AXNodeTextStyles GetTextStyles() const
bool IsButtonPressed() const
void RemoveState(ax::mojom::State state)
void AddStringAttribute(ax::mojom::StringAttribute attribute, const std::string &value)
ax::mojom::Role role
Definition: ax_node_data.h:277
const std::string & GetStringAttribute(ax::mojom::StringAttribute attribute) const
void RemoveStringAttribute(ax::mojom::StringAttribute attribute)
bool SupportsExpandCollapse() const
void SetCheckedState(ax::mojom::CheckedState checked_state)
bool IsMenuButton() const
std::shared_ptr< const fml::Mapping > data
Definition: texture_gles.cc:63
#define EXPECT_TRUE(handle)
Definition: unit_test.h:678