1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package org.htmlunit.html;
16
17 import java.lang.reflect.Method;
18 import java.util.ArrayList;
19 import java.util.HashSet;
20 import java.util.List;
21 import java.util.Locale;
22
23 import org.htmlunit.BrowserVersion;
24 import org.htmlunit.MockWebConnection;
25 import org.htmlunit.WebClient;
26 import org.htmlunit.WebTestCase;
27 import org.htmlunit.html.parser.HTMLParser;
28
29 import junit.framework.Test;
30 import junit.framework.TestCase;
31 import junit.framework.TestSuite;
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49 public class AttributesTest extends TestCase {
50
51 private final Class<?> classUnderTest_;
52 private final Method method_;
53 private final String attributeName_;
54
55 private static final List<String> EXCLUDED_METHODS = new ArrayList<>();
56 static {
57 EXCLUDED_METHODS.add("getHtmlElementsByAttribute");
58 EXCLUDED_METHODS.add("getOneHtmlElementByAttribute");
59 EXCLUDED_METHODS.add("getAttribute");
60 EXCLUDED_METHODS.add("getElementsByAttribute");
61 }
62
63
64
65
66
67
68
69 public static Test suite() throws Exception {
70 final TestSuite suite = new TestSuite();
71 final String[] classesToTest = {
72 "HtmlAbbreviated", "HtmlAcronym",
73 "HtmlAnchor", "HtmlAddress", "HtmlArea",
74 "HtmlArticle", "HtmlAside", "HtmlAudio",
75 "HtmlBackgroundSound", "HtmlBase", "HtmlBaseFont",
76 "HtmlBidirectionalIsolation",
77 "HtmlBidirectionalOverride", "HtmlBig",
78 "HtmlBlockQuote", "HtmlBody", "HtmlBold",
79 "HtmlBreak", "HtmlButton", "HtmlCanvas", "HtmlCaption",
80 "HtmlCenter", "HtmlCitation", "HtmlCode", "DomComment",
81 "HtmlData", "HtmlDataList",
82 "HtmlDefinition", "HtmlDefinitionDescription",
83 "HtmlDeletedText", "HtmlDetails", "HtmlDialog", "HtmlDirectory",
84 "HtmlDivision", "HtmlDefinitionList",
85 "HtmlDefinitionTerm", "HtmlEmbed",
86 "HtmlEmphasis",
87 "HtmlFieldSet", "HtmlFigureCaption", "HtmlFigure",
88 "HtmlFont", "HtmlForm", "HtmlFooter",
89 "HtmlFrame", "HtmlFrameSet",
90 "HtmlHead", "HtmlHeader",
91 "HtmlHeading1", "HtmlHeading2", "HtmlHeading3",
92 "HtmlHeading4", "HtmlHeading5", "HtmlHeading6",
93 "HtmlHorizontalRule", "HtmlHtml", "HtmlInlineFrame",
94 "HtmlInlineQuotation",
95 "HtmlImage", "HtmlImage", "HtmlInsertedText",
96 "HtmlItalic", "HtmlKeyboard", "HtmlLabel", "HtmlLayer",
97 "HtmlLegend", "HtmlListing", "HtmlListItem",
98 "HtmlLink",
99 "HtmlMap", "HtmlMain", "HtmlMark", "HtmlMarquee",
100 "HtmlMenu", "HtmlMeta", "HtmlMeter",
101 "HtmlNav",
102 "HtmlNoBreak", "HtmlNoEmbed", "HtmlNoFrames", "HtmlNoLayer",
103 "HtmlNoScript", "HtmlObject", "HtmlOrderedList",
104 "HtmlOptionGroup", "HtmlOption", "HtmlOutput",
105 "HtmlParagraph",
106 "HtmlParameter", "HtmlPicture", "HtmlPlainText", "HtmlPreformattedText",
107 "HtmlProgress",
108 "HtmlRb", "HtmlRp", "HtmlRt", "HtmlRtc", "HtmlRuby",
109 "HtmlS", "HtmlSample",
110 "HtmlScript", "HtmlSection", "HtmlSelect", "HtmlSlot", "HtmlSmall",
111 "HtmlSource", "HtmlSpan",
112 "HtmlStrike", "HtmlStrong", "HtmlStyle",
113 "HtmlSubscript", "HtmlSummary", "HtmlSuperscript",
114 "HtmlSvg",
115 "HtmlTable", "HtmlTableColumn", "HtmlTableColumnGroup",
116 "HtmlTableBody", "HtmlTableDataCell", "HtmlTableHeaderCell",
117 "HtmlTableRow", "HtmlTextArea", "HtmlTableFooter",
118 "HtmlTableHeader", "HtmlTeletype", "HtmlTemplate", "HtmlTrack",
119 "HtmlTime", "HtmlTitle",
120 "HtmlUnderlined", "HtmlUnorderedList",
121 "HtmlVariable", "HtmlVideo",
122 "HtmlWordBreak", "HtmlExample"
123 };
124
125 final HashSet<String> supportedTags = new HashSet<>(DefaultElementFactory.SUPPORTED_TAGS_);
126
127 for (final String testClass : classesToTest) {
128 final Class<?> clazz = Class.forName("org.htmlunit.html." + testClass);
129 addTestsForClass(clazz, suite);
130
131 String tag;
132 if (DomComment.class == clazz) {
133 tag = "comment";
134 }
135 else {
136 tag = (String) clazz.getField("TAG_NAME").get(null);
137 }
138 supportedTags.remove(tag);
139 try {
140 tag = (String) clazz.getField("TAG_NAME2").get(null);
141 supportedTags.remove(tag);
142 }
143 catch (final NoSuchFieldException ignored) {
144
145 }
146 }
147
148 supportedTags.remove("input");
149
150 if (!supportedTags.isEmpty()) {
151 throw new RuntimeException("Missing tag class(es) " + supportedTags);
152 }
153 return suite;
154 }
155
156
157
158
159
160
161
162
163
164 private static void addTestsForClass(final Class<?> clazz, final TestSuite suite)
165 throws Exception {
166
167 final Method[] methods = clazz.getMethods();
168 for (final Method method : methods) {
169 final String methodName = method.getName();
170 if (methodName.startsWith("get")
171 && methodName.endsWith("Attribute")
172 && !EXCLUDED_METHODS.contains(methodName)) {
173
174 String attributeName = methodName.substring(3, methodName.length() - 9).toLowerCase(Locale.ROOT);
175 if ("xmllang".equals(attributeName)) {
176 attributeName = "xml:lang";
177 }
178 else if ("columns".equals(attributeName)) {
179 attributeName = "cols";
180 }
181 else if ("columnspan".equals(attributeName)) {
182 attributeName = "colspan";
183 }
184 else if ("textdirection".equals(attributeName)) {
185 attributeName = "dir";
186 }
187 else if ("httpequiv".equals(attributeName)) {
188 attributeName = "http-equiv";
189 }
190 else if ("acceptcharset".equals(attributeName)) {
191 attributeName = "accept-charset";
192 }
193 else if ("htmlfor".equals(attributeName)) {
194 attributeName = "for";
195 }
196 suite.addTest(new AttributesTest(attributeName, clazz, method));
197 }
198 }
199 }
200
201
202
203
204
205
206
207
208 public AttributesTest(
209 final String attributeName,
210 final Class<?> classUnderTest,
211 final Method method) {
212
213 super(createTestName(classUnderTest, method));
214 classUnderTest_ = classUnderTest;
215 method_ = method;
216 attributeName_ = attributeName;
217 }
218
219
220
221
222
223
224
225 private static String createTestName(final Class<?> clazz, final Method method) {
226 String className = clazz.getName();
227 final int index = className.lastIndexOf('.');
228 className = className.substring(index + 1);
229
230 return "testAttributes_" + className + '_' + method.getName();
231 }
232
233
234
235
236
237 @Override
238 protected void runTest() throws Exception {
239 try (WebClient webClient = new WebClient(BrowserVersion.BEST_SUPPORTED)) {
240 final MockWebConnection connection = new MockWebConnection();
241 connection.setDefaultResponse("<html><head><title>foo</title></head><body></body></html>");
242 webClient.setWebConnection(connection);
243 final HtmlPage page = webClient.getPage(WebTestCase.URL_FIRST);
244
245 final String value = "value";
246
247 final DomElement objectToTest = getNewInstanceForClassUnderTest(page);
248 objectToTest.setAttribute(attributeName_, value);
249
250 final Object[] noObjects = new Object[0];
251 final Object result = method_.invoke(objectToTest, noObjects);
252 assertSame(value, result);
253 }
254 }
255
256
257
258
259
260
261 private DomElement getNewInstanceForClassUnderTest(final HtmlPage page) throws Exception {
262 final HTMLParser htmlParser = page.getWebClient().getPageCreator().getHtmlParser();
263 final DomElement newInstance;
264 if (classUnderTest_ == HtmlTableRow.class) {
265 newInstance = htmlParser.getFactory(HtmlTableRow.TAG_NAME)
266 .createElement(page, HtmlTableRow.TAG_NAME, null);
267 }
268 else if (classUnderTest_ == HtmlTableHeaderCell.class) {
269 newInstance = htmlParser.getFactory(HtmlTableHeaderCell.TAG_NAME)
270 .createElement(page, HtmlTableHeaderCell.TAG_NAME, null);
271 }
272 else if (classUnderTest_ == HtmlTableDataCell.class) {
273 newInstance = htmlParser.getFactory(HtmlTableDataCell.TAG_NAME)
274 .createElement(page, HtmlTableDataCell.TAG_NAME, null);
275 }
276 else {
277 final String tagName = (String) classUnderTest_.getField("TAG_NAME").get(null);
278 newInstance = htmlParser.getFactory(tagName).createElement(page, tagName, null);
279 }
280
281 return newInstance;
282 }
283 }