1 // Copyright 2019 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 "ui/accessibility/ax_enum_util.h"
6
7 #include "testing/gtest/include/gtest/gtest.h"
8 #include "ui/accessibility/ax_enums.mojom.h"
9 #include "ui/accessibility/ax_node_data.h"
10
11 namespace ui {
12
13 // Templatized function that tests that for a mojom enum
14 // such as ax::mojom::Role, ax::mojom::Event, etc. we can
15 // call ToString() on the enum to get a string, and then
16 // ParseEnumName() on the string to get back the original
17 // value. Also tests what happens when we call ToString
18 // or ParseEnumName on a bogus value.
19 template <typename T>
TestEnumStringConversion(T (ParseFunction)(const char *),int32_t (step)(int32_t)=[](int32_t val){})20 void TestEnumStringConversion(
21 T(ParseFunction)(const char*),
22 int32_t(step)(int32_t) = [](int32_t val) { return val + 1; }) {
23 // Check every valid enum value.
24 for (int i = static_cast<int>(T::kMinValue);
25 i <= static_cast<int>(T::kMaxValue); i = step(i)) {
26 T src = static_cast<T>(i);
27 std::string str = ToString(src);
28 auto dst = ParseFunction(str.c_str());
29 EXPECT_EQ(src, dst);
30 }
31
32 // Parse a bogus string.
33 EXPECT_EQ(T::kNone, ParseFunction("bogus"));
34
35 // Convert a bogus value to a string.
36 int out_of_range_value = static_cast<int>(T::kMaxValue) + 1;
37 EXPECT_STREQ("", ToString(static_cast<T>(out_of_range_value)));
38 }
39
40 // Templatized function that tries calling a setter on AXNodeData
41 // such as AddIntAttribute, AddFloatAttribute - with each possible
42 // enum value.
43 //
44 // This variant is for cases where the value type is an object.
45 template <typename T, typename U>
TestAXNodeDataSetter(void (AXNodeData::* Setter)(T,const U &),const U & value)46 void TestAXNodeDataSetter(void (AXNodeData::*Setter)(T, const U&),
47 const U& value) {
48 AXNodeData node_data;
49 for (int i = static_cast<int>(T::kMinValue) + 1;
50 i <= static_cast<int>(T::kMaxValue); ++i) {
51 T attr = static_cast<T>(i);
52 ((node_data).*(Setter))(attr, value);
53 }
54 EXPECT_TRUE(!node_data.ToString().empty());
55 }
56
57 // Same as TextAXNodeData, above, but This variant is for
58 // cases where the value type is POD.
59 template <typename T, typename U>
TestAXNodeDataSetter(void (AXNodeData::* Setter)(T,U),U value)60 void TestAXNodeDataSetter(void (AXNodeData::*Setter)(T, U), U value) {
61 AXNodeData node_data;
62 for (int i = static_cast<int>(T::kMinValue) + 1;
63 i <= static_cast<int>(T::kMaxValue); ++i) {
64 T attr = static_cast<T>(i);
65 ((node_data).*(Setter))(attr, value);
66 }
67 EXPECT_TRUE(!node_data.ToString().empty());
68 }
69
TEST(AXEnumUtilTest,Event)70 TEST(AXEnumUtilTest, Event) {
71 TestEnumStringConversion<ax::mojom::Event>(ParseEvent);
72 }
73
TEST(AXEnumUtilTest,Role)74 TEST(AXEnumUtilTest, Role) {
75 TestEnumStringConversion<ax::mojom::Role>(ParseRole);
76 }
77
TEST(AXEnumUtilTest,State)78 TEST(AXEnumUtilTest, State) {
79 TestEnumStringConversion<ax::mojom::State>(ParseState);
80 }
81
TEST(AXEnumUtilTest,Action)82 TEST(AXEnumUtilTest, Action) {
83 TestEnumStringConversion<ax::mojom::Action>(ParseAction);
84 }
85
TEST(AXEnumUtilTest,ActionFlags)86 TEST(AXEnumUtilTest, ActionFlags) {
87 TestEnumStringConversion<ax::mojom::ActionFlags>(ParseActionFlags);
88 }
89
TEST(AXEnumUtilTest,DefaultActionVerb)90 TEST(AXEnumUtilTest, DefaultActionVerb) {
91 TestEnumStringConversion<ax::mojom::DefaultActionVerb>(
92 ParseDefaultActionVerb);
93 }
94
TEST(AXEnumUtilTest,Mutation)95 TEST(AXEnumUtilTest, Mutation) {
96 TestEnumStringConversion<ax::mojom::Mutation>(ParseMutation);
97 }
98
TEST(AXEnumUtilTest,StringAttribute)99 TEST(AXEnumUtilTest, StringAttribute) {
100 TestEnumStringConversion<ax::mojom::StringAttribute>(ParseStringAttribute);
101 TestAXNodeDataSetter<ax::mojom::StringAttribute>(
102 &AXNodeData::AddStringAttribute, std::string());
103 }
104
TEST(AXEnumUtilTest,IntAttribute)105 TEST(AXEnumUtilTest, IntAttribute) {
106 TestEnumStringConversion<ax::mojom::IntAttribute>(ParseIntAttribute);
107 TestAXNodeDataSetter<ax::mojom::IntAttribute>(&AXNodeData::AddIntAttribute,
108 0);
109 }
110
TEST(AXEnumUtilTest,FloatAttribute)111 TEST(AXEnumUtilTest, FloatAttribute) {
112 TestEnumStringConversion<ax::mojom::FloatAttribute>(ParseFloatAttribute);
113 TestAXNodeDataSetter<ax::mojom::FloatAttribute>(
114 &AXNodeData::AddFloatAttribute, 0.0f);
115 }
116
TEST(AXEnumUtilTest,BoolAttribute)117 TEST(AXEnumUtilTest, BoolAttribute) {
118 TestEnumStringConversion<ax::mojom::BoolAttribute>(ParseBoolAttribute);
119 TestAXNodeDataSetter<ax::mojom::BoolAttribute>(&AXNodeData::AddBoolAttribute,
120 false);
121 }
122
TEST(AXEnumUtilTest,IntListAttribute)123 TEST(AXEnumUtilTest, IntListAttribute) {
124 TestEnumStringConversion<ax::mojom::IntListAttribute>(ParseIntListAttribute);
125 TestAXNodeDataSetter<ax::mojom::IntListAttribute>(
126 &AXNodeData::AddIntListAttribute, std::vector<int32_t>());
127 }
128
TEST(AXEnumUtilTest,StringListAttribute)129 TEST(AXEnumUtilTest, StringListAttribute) {
130 TestEnumStringConversion<ax::mojom::StringListAttribute>(
131 ParseStringListAttribute);
132 TestAXNodeDataSetter<ax::mojom::StringListAttribute>(
133 &AXNodeData::AddStringListAttribute, std::vector<std::string>());
134 }
135
TEST(AXEnumUtilTest,MarkerType)136 TEST(AXEnumUtilTest, MarkerType) {
137 TestEnumStringConversion<ax::mojom::MarkerType>(
138 ParseMarkerType, [](int32_t val) {
139 return val == 0 ? 1 :
140 // 8 (Composition) is
141 // explicitly skipped in
142 // ax_enums.mojom.
143 val == 4 ? 16 : val * 2;
144 });
145 }
146
TEST(AXEnumUtilTest,Text_Decoration_Style)147 TEST(AXEnumUtilTest, Text_Decoration_Style) {
148 TestEnumStringConversion<ax::mojom::TextDecorationStyle>(
149 ParseTextDecorationStyle);
150 }
151
TEST(AXEnumUtilTest,ListStyle)152 TEST(AXEnumUtilTest, ListStyle) {
153 TestEnumStringConversion<ax::mojom::ListStyle>(ParseListStyle);
154 }
155
TEST(AXEnumUtilTest,MoveDirection)156 TEST(AXEnumUtilTest, MoveDirection) {
157 TestEnumStringConversion<ax::mojom::MoveDirection>(ParseMoveDirection);
158 }
159
TEST(AXEnumUtilTest,EditCommand)160 TEST(AXEnumUtilTest, EditCommand) {
161 TestEnumStringConversion<ax::mojom::EditCommand>(ParseEditCommand);
162 }
163
TEST(AXEnumUtilTest,SelectionCommand)164 TEST(AXEnumUtilTest, SelectionCommand) {
165 TestEnumStringConversion<ax::mojom::SelectionCommand>(ParseSelectionCommand);
166 }
167
TEST(AXEnumUtilTest,TextBoundary)168 TEST(AXEnumUtilTest, TextBoundary) {
169 TestEnumStringConversion<ax::mojom::TextBoundary>(ParseTextBoundary);
170 }
171
TEST(AXEnumUtilTest,TextDirection)172 TEST(AXEnumUtilTest, TextDirection) {
173 TestEnumStringConversion<ax::mojom::TextDirection>(ParseTextDirection);
174 }
175
TEST(AXEnumUtilTest,TextPosition)176 TEST(AXEnumUtilTest, TextPosition) {
177 TestEnumStringConversion<ax::mojom::TextPosition>(ParseTextPosition);
178 }
179
TEST(AXEnumUtilTest,TextStyle)180 TEST(AXEnumUtilTest, TextStyle) {
181 TestEnumStringConversion<ax::mojom::TextStyle>(ParseTextStyle);
182 }
183
TEST(AXEnumUtilTest,AriaCurrentState)184 TEST(AXEnumUtilTest, AriaCurrentState) {
185 TestEnumStringConversion<ax::mojom::AriaCurrentState>(ParseAriaCurrentState);
186 }
187
TEST(AXEnumUtilTest,HasPopup)188 TEST(AXEnumUtilTest, HasPopup) {
189 TestEnumStringConversion<ax::mojom::HasPopup>(ParseHasPopup);
190 }
191
TEST(AXEnumUtilTest,InvalidState)192 TEST(AXEnumUtilTest, InvalidState) {
193 TestEnumStringConversion<ax::mojom::InvalidState>(ParseInvalidState);
194 }
195
TEST(AXEnumUtilTest,Restriction)196 TEST(AXEnumUtilTest, Restriction) {
197 TestEnumStringConversion<ax::mojom::Restriction>(ParseRestriction);
198 }
199
TEST(AXEnumUtilTest,CheckedState)200 TEST(AXEnumUtilTest, CheckedState) {
201 TestEnumStringConversion<ax::mojom::CheckedState>(ParseCheckedState);
202 }
203
TEST(AXEnumUtilTest,SortDirection)204 TEST(AXEnumUtilTest, SortDirection) {
205 TestEnumStringConversion<ax::mojom::SortDirection>(ParseSortDirection);
206 }
207
TEST(AXEnumUtilTest,NameFrom)208 TEST(AXEnumUtilTest, NameFrom) {
209 TestEnumStringConversion<ax::mojom::NameFrom>(ParseNameFrom);
210 }
211
TEST(AXEnumUtilTest,DescriptionFrom)212 TEST(AXEnumUtilTest, DescriptionFrom) {
213 TestEnumStringConversion<ax::mojom::DescriptionFrom>(ParseDescriptionFrom);
214 }
215
TEST(AXEnumUtilTest,EventFrom)216 TEST(AXEnumUtilTest, EventFrom) {
217 TestEnumStringConversion<ax::mojom::EventFrom>(ParseEventFrom);
218 }
219
TEST(AXEnumUtilTest,Gesture)220 TEST(AXEnumUtilTest, Gesture) {
221 TestEnumStringConversion<ax::mojom::Gesture>(ParseGesture);
222 }
223
TEST(AXEnumUtilTest,TextAffinity)224 TEST(AXEnumUtilTest, TextAffinity) {
225 TestEnumStringConversion<ax::mojom::TextAffinity>(ParseTextAffinity);
226 }
227
TEST(AXEnumUtilTest,TreeOrder)228 TEST(AXEnumUtilTest, TreeOrder) {
229 TestEnumStringConversion<ax::mojom::TreeOrder>(ParseTreeOrder);
230 }
231
TEST(AXEnumUtilTest,ImageAnnotationStatus)232 TEST(AXEnumUtilTest, ImageAnnotationStatus) {
233 TestEnumStringConversion<ax::mojom::ImageAnnotationStatus>(
234 ParseImageAnnotationStatus);
235 }
236
TEST(AXEnumUtilTest,Dropeffect)237 TEST(AXEnumUtilTest, Dropeffect) {
238 TestEnumStringConversion<ax::mojom::Dropeffect>(ParseDropeffect);
239 }
240
241 } // namespace ui
242