1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package org.htmlunit;
16
17 import static java.nio.charset.StandardCharsets.ISO_8859_1;
18
19 import java.io.File;
20 import java.io.IOException;
21 import java.util.List;
22 import java.util.Set;
23 import java.util.TreeSet;
24
25 import org.apache.commons.io.FileUtils;
26 import org.htmlunit.general.ElementPropertiesTest;
27 import org.junit.Test;
28
29
30
31
32
33
34
35 public class NotYetImplementedTest {
36
37 private Set<String> entries_ = new TreeSet<>();
38
39
40
41
42 @Test
43 public void test() throws Exception {
44 process(new File("src/test/java"));
45 save();
46 }
47
48 private void process(final File dir) throws IOException {
49 final File[] files = dir.listFiles();
50 if (files != null) {
51 for (final File file : files) {
52 final String fileName = file.getName();
53 if (file.isDirectory()
54 && !"huge".equals(fileName)
55 && !".git".equals(fileName)) {
56 process(file);
57 }
58 else {
59 if (fileName.endsWith(".java")
60 && !"SimpleWebTestCase.java".equals(fileName)
61 && !"AnnotationUtilsTest.java".equals(fileName)
62 && !"NotYetImplementedTest.java".equals(fileName)
63 && !"CodeStyleTest.java".equals(fileName)) {
64 final List<String> lines = FileUtils.readLines(file, ISO_8859_1);
65 final String relativePath = file.getAbsolutePath().substring(
66 new File(".").getAbsolutePath().length() - 1).replace('\\', '/');
67 process(lines, relativePath);
68 }
69 }
70 }
71 }
72 }
73
74 private void process(final List<String> lines, final String path) {
75 int index = 1;
76 for (final String line : lines) {
77 if (line.startsWith(" @NotYetImplemented")) {
78 String browser = "All";
79 if (line.contains("(")) {
80 browser = line.replaceAll(".*\\((.*)\\).*", "$1");
81 browser = browser.replaceAll("Browser\\.", "");
82 browser = browser.replaceAll("[{}]", "");
83 browser = browser.trim();
84 }
85 String methodName = null;
86 for (int i = index; i < lines.size(); i++) {
87 final String l = lines.get(i);
88 if (l.startsWith(" public ")) {
89 methodName = l.split(" ")[6];
90 break;
91 }
92 }
93 final int lineNumber = getLineNumber(lines, index);
94 final String description = getDescription(lines, index);
95 entries_.add(path + ';' + methodName + ';' + lineNumber + ";" + browser
96 + ';' + description);
97 }
98 else if (line.startsWith(" @HtmlUnitNYI")) {
99 String browser = "All";
100 final StringBuilder nyi = new StringBuilder(line);
101
102 String methodName = null;
103 for (int i = index; i < lines.size(); i++) {
104 final String l = lines.get(i);
105 if (l.startsWith(" public ")) {
106 methodName = l.split(" ")[6];
107 break;
108 }
109 nyi.append(l);
110 }
111 final int lineNumber = getLineNumber(lines, index);
112 final String description = getDescription(lines, index);
113
114 final String nyiString = nyi.toString();
115 if (nyiString.startsWith(" @HtmlUnitNYI(")) {
116 browser = "";
117 if (nyiString.contains("CHROME = ")) {
118 browser += "CHROME";
119 }
120 if (nyiString.contains("EDGE = ")) {
121 browser += "EDGE";
122 }
123 if (nyiString.contains("FF_ESR = ")) {
124 if (browser.length() > 0) {
125 browser += ", ";
126 }
127 browser += "FF_ESR";
128 }
129 if (nyiString.contains("FF = ")) {
130 if (browser.length() > 0) {
131 browser += ", ";
132 }
133 browser += "FF";
134 }
135 }
136 if (browser.length() < 2) {
137 throw new IllegalArgumentException("'" + nyiString + "' seems to be not supported by @HtmlUnitNYI");
138 }
139 entries_.add(path + ';' + methodName + ';' + lineNumber + ";" + browser
140 + ';' + description);
141 }
142 index++;
143 }
144 }
145
146 private static int getLineNumber(final List<String> lines, final int index) {
147 for (int i = index; i >= 0; i--) {
148 final String l = lines.get(i);
149 if (l.startsWith(" /**")) {
150 return i;
151 }
152 }
153 return 0;
154 }
155
156 private static String getDescription(final List<String> lines, final int index) {
157 final StringBuilder builder = new StringBuilder();
158 for (int i = getLineNumber(lines, index); i < lines.size(); i++) {
159 final String line = lines.get(i).trim();
160 final int start = line.indexOf(' ') != -1 ? line.indexOf(' ') + 1 : -1;
161 final boolean end = line.endsWith("*/");
162 if (line.contains("* @throws ") || line.contains("* @exception")) {
163 break;
164 }
165 if (start != -1) {
166 if (builder.length() != 0) {
167 builder.append(' ');
168 }
169 builder.append(line, start, line.length() - (end ? 2 : 0));
170 }
171 if (end) {
172 break;
173 }
174 }
175 return builder.toString().replace(";", "__semicolon__");
176 }
177
178 private void save() throws Exception {
179 final StringBuilder builder = new StringBuilder();
180 builder.append("<html><head>\n");
181 builder.append("<style type=\"text/css\">\n");
182 builder.append("table.bottomBorder { border-collapse:collapse; }\n");
183 builder.append("table.bottomBorder td, table.bottomBorder th { "
184 + "border-bottom:1px dotted black;padding:5px; }\n");
185 builder.append("table.bottomBorder td.numeric { text-align:right; }\n");
186 builder.append("</style>\n");
187 builder.append("</head><body>\n");
188 builder.append("<p>NotYetImplemented is a condition in which a test is known to fail with HtmlUnit.</p>");
189
190 builder.append("<h3>Overview</h3>");
191 final int overviewPos = builder.length();
192
193
194
195 builder.append("<h3>Details</h3>");
196 builder.append("<table class='bottomBorder'>\n");
197 builder.append(" <tr><th>File</th><th>#</th><th>Method</th><th>Line</th><th>Description</th></tr>\n");
198 String lastFile = null;
199
200 int count = 0;
201 int countFFESR = 0;
202 int countFF = 0;
203 int countChrome = 0;
204 for (final String entry : entries_) {
205 final String[] values = entry.split(";");
206 final String file = values[0];
207 final String fileName = file.substring(file.lastIndexOf('/') + 1, file.length() - 5);
208 final String method = values[1];
209 final String line = values[2];
210 String browser = values[3];
211 final String description = entry.endsWith(";") ? " "
212 : values[values.length - 1].replace("__semicolon__", ";");
213 builder.append(" <tr>\n");
214 if (!file.equals(lastFile)) {
215 int totalCount = 0;
216 for (final String e : entries_) {
217 if (e.startsWith(file)) {
218 totalCount++;
219 }
220 }
221 if (totalCount != 1) {
222 builder.append(" <td rowspan='" + totalCount + "'>");
223 }
224 else {
225 builder.append(" <td>");
226 }
227 builder.append("<a target='_blank' href='https://github.com/HtmlUnit/htmlunit/blob/master/")
228 .append(file)
229 .append("'>")
230 .append(fileName)
231 .append("</a>");
232 builder.append("</td>\n");
233 lastFile = file;
234 }
235 builder.append(" <td>").append(Integer.toString(count++)).append("</td>\n");
236
237 builder.append(" <td><a target='_blank' href='https://github.com/HtmlUnit/htmlunit/blob/master/")
238 .append(file)
239 .append("#L")
240 .append(line)
241 .append("'>")
242 .append(method)
243 .append("</a> ")
244 .append(browser)
245 .append("</td>\n");
246 builder.append(" <td class='numeric'>").append(line).append("</td>\n");
247 builder.append(" <td>").append(description).append("</td>\n");
248 builder.append(" </tr>\n");
249
250 if (browser.contains("FF_ESR")) {
251 browser = browser.replace("FF_ESR", "");
252 countFFESR++;
253 }
254 if (browser.contains("FF")) {
255 countFF++;
256 }
257 if (browser.contains("CHROME")) {
258 countChrome++;
259 }
260 if (browser.contains("All")) {
261 countFFESR++;
262 countFF++;
263 countChrome++;
264 }
265 }
266 builder.append("</table>\n").append("</body></html>");
267
268 final StringBuilder overview = new StringBuilder();
269 overview.append("<table class='bottomBorder'>\n");
270 overview.append(" <tr>\n");
271 overview.append(" <td class='numeric'>").append(Integer.toString(count)).append("</td>\n");
272 overview.append(" <td>methods marked as NotYetImplemented</td>\n");
273 overview.append(" </tr>\n");
274
275 overview.append(" <tr>\n");
276 overview.append(" <td class='numeric'>").append(countFFESR).append("</td>\n");
277 overview.append(" <td>for FF_ESR</td>\n");
278 overview.append(" </tr>\n");
279
280 overview.append(" <tr>\n");
281 overview.append(" <td class='numeric'>").append(countFF).append("</td>\n");
282 overview.append(" <td>for FF</td>\n");
283 overview.append(" </tr>\n");
284
285 overview.append(" <tr>\n");
286 overview.append(" <td class='numeric'>").append(Integer.toString(countChrome)).append("</td>\n");
287 overview.append(" <td>for Chrome</td>\n");
288 overview.append(" </tr>\n");
289
290 overview.append("</table>\n");
291
292 builder.insert(overviewPos, overview);
293
294 FileUtils.writeStringToFile(new File(ElementPropertiesTest.getTargetDirectory(), "notYetImplemented.html"),
295 builder.toString(), ISO_8859_1);
296 }
297
298 }