1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package org.htmlunit.libraries.jquery;
16
17 import static java.nio.charset.StandardCharsets.ISO_8859_1;
18
19 import java.io.BufferedReader;
20 import java.io.BufferedWriter;
21 import java.io.File;
22 import java.io.FileReader;
23 import java.io.FileWriter;
24 import java.io.IOException;
25 import java.util.ArrayList;
26 import java.util.Collection;
27 import java.util.Collections;
28 import java.util.HashMap;
29 import java.util.HashSet;
30 import java.util.Iterator;
31 import java.util.List;
32 import java.util.Map;
33 import java.util.TreeMap;
34 import java.util.TreeSet;
35 import java.util.regex.Matcher;
36 import java.util.regex.Pattern;
37
38 import org.apache.commons.io.FileUtils;
39 import org.apache.commons.lang3.reflect.MethodUtils;
40 import org.htmlunit.WebDriverTestCase;
41 import org.htmlunit.junit.annotation.TestedBrowser;
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59 public final class JQueryExtractor {
60 private static final String RERUN_ID = "Rerun [";
61
62 private JQueryExtractor() {
63 }
64
65
66
67
68
69
70 public static void main(final String[] args) throws Exception {
71
72
73
74 final Class<? extends WebDriverTestCase> testClass = JQuery3x3x1Test.class;
75
76 final String version = (String) MethodUtils.invokeExactMethod(testClass.newInstance(), "getVersion");
77 final File baseDir = new File("src/test/resources/libraries/jQuery/" + version + "/expectations");
78
79 for (final String browser : new String[] {"CHROME", "EDGE", "FF", "FF-ESR"}) {
80 final File out = new File(baseDir, browser + ".out");
81 final File results = new File(baseDir, "results." + browser + ".txt");
82 extractExpectations(out, results);
83 }
84
85 generateTestCases(testClass, baseDir);
86 }
87
88
89
90
91
92
93
94
95
96 public static void extractExpectations(final File input, final File output) throws IOException {
97 try (BufferedReader reader = new BufferedReader(new FileReader(input))) {
98 try (BufferedWriter writer = new BufferedWriter(new FileWriter(output))) {
99 int testNumber = 1;
100 String line;
101 while ((line = reader.readLine()) != null) {
102 line = line.trim();
103
104
105
106 if (line.contains(RERUN_ID)) {
107 final int start = line.indexOf(RERUN_ID) + RERUN_ID.length();
108 final int end = line.indexOf(']', start);
109 final String testId = line.substring(start, end);
110
111 line = line.substring(0, line.indexOf(RERUN_ID)).trim();
112 final String prefix = "" + testNumber + ".";
113 if (line.startsWith(prefix)) {
114 line = line.substring(prefix.length());
115 }
116 line = "" + testNumber + '.' + ' ' + line + " [" + testId + ']';
117 writer.write(line + System.lineSeparator());
118 testNumber++;
119 }
120
121
122
123
124 else if (line.indexOf("Rerun") > -1) {
125 line = line.substring(0, line.indexOf("Rerun"))
126 + " [" + testNumber + ']';
127 writer.write(line + System.lineSeparator());
128 testNumber++;
129 }
130 else if (line.endsWith("Rerun")) {
131 if (line.indexOf("" + testNumber + '.', 4) != -1) {
132 System.out.println("Incorrect line for test# " + testNumber
133 + ", please correct it manually");
134 break;
135 }
136 line = "" + testNumber + '.'
137 + ' ' + line.substring(0, line.length() - 5)
138 + " [" + testNumber + ']';
139 writer.write(line + System.lineSeparator());
140 testNumber++;
141 }
142 }
143 System.out.println("Last output #" + (testNumber - 1));
144 }
145 }
146 }
147
148
149
150
151
152
153
154 public static void generateTestCases(final Class<? extends WebDriverTestCase> testClass,
155 final File dir) throws Exception {
156 final TestedBrowser[] browsers = TestedBrowser.values();
157
158 final List<String> mainNames = new ArrayList<>();
159 for (final TestedBrowser b : browsers) {
160 String name = b.name();
161 if ("FF_ESR".equals(name)) {
162 name = "FF-ESR";
163 }
164 mainNames.add(name);
165 }
166
167 final Map<String, Expectations> browserExpectations = new HashMap<>();
168 final File[] files = dir.listFiles();
169 if (files != null) {
170 for (final File file : files) {
171 if (file.isFile() && file.getName().endsWith(".txt")) {
172 for (final String browserName : mainNames) {
173 if (file.getName().equalsIgnoreCase("results." + browserName + ".txt")) {
174 browserExpectations.put(browserName, Expectations.readExpectations(file));
175 }
176 }
177 }
178 }
179 }
180
181
182 final List<Test> allTests = computeTestsList(browserExpectations);
183
184 final Collection<String> availableBrowserNames = new TreeSet<>(browserExpectations.keySet());
185 for (final Test test : allTests) {
186 final Map<String, String> testExpectation = new TreeMap<>();
187 final Map<Integer, List<String>> lineToBrowser = new TreeMap<>();
188 for (final String browserName : availableBrowserNames) {
189 final Expectation expectation = browserExpectations.get(browserName).getExpectation(test);
190 if (expectation != null) {
191 List<String> browsersForLine = lineToBrowser.get(expectation.getLine());
192 if (browsersForLine == null) {
193 browsersForLine = new ArrayList<>();
194 lineToBrowser.put(expectation.getLine(), browsersForLine);
195 }
196 browsersForLine.add(browserName);
197 final String str = expectation.getTestResult();
198 testExpectation.put(browserName,
199 str.replaceAll("\\\\", "\\\\\\\\").replaceAll("\\\"", "\\\\\""));
200 }
201 }
202 System.out.println(" /**");
203 System.out.println(" * Test " + lineToBrowser + ".");
204 System.out.println(" * @throws Exception if an error occurs");
205 System.out.println(" */");
206 System.out.println(" @Test");
207 System.out.print(" @Alerts(");
208
209 final boolean allSame = testExpectation.size() == availableBrowserNames.size()
210 && new HashSet<>(testExpectation.values()).size() == 1;
211 if (allSame) {
212 final String first = testExpectation.keySet().iterator().next();
213 String expectation = testExpectation.get(first);
214 if (expectation.length() > 100) {
215 expectation = expectation.substring(0, 50) + "\"\n + \"" + expectation.substring(50);
216 }
217 System.out.print("\"" + expectation + '"');
218 }
219 else {
220 final List<String> cleanedBrowserNames = new ArrayList<>(testExpectation.keySet());
221 Collections.sort(cleanedBrowserNames);
222
223 if (testExpectation.size() == availableBrowserNames.size()) {
224
225
226 int matches = 0;
227 ArrayList<String> defaultBrowsers = null;
228
229 for (final String browser : cleanedBrowserNames) {
230 final String expectation = testExpectation.get(browser);
231
232 final ArrayList<String> matchBrowsers = new ArrayList<>();
233 int matchCount = 0;
234 for (final String otherBrowser : cleanedBrowserNames) {
235 if (!browser.equals(otherBrowser)
236 && expectation.equals(testExpectation.get(otherBrowser))) {
237 matchCount++;
238 matchBrowsers.add(otherBrowser);
239 }
240 }
241 if (matches < matchCount) {
242 matches = matchCount;
243 matchBrowsers.add(browser);
244 defaultBrowsers = matchBrowsers;
245 }
246 }
247
248 if (matches > 1) {
249 testExpectation.put("DEFAULT", testExpectation.get(defaultBrowsers.get(0)));
250 cleanedBrowserNames.add(0, "DEFAULT");
251 for (final String browser : defaultBrowsers) {
252 testExpectation.remove(browser);
253 cleanedBrowserNames.remove(browser);
254 }
255 }
256 }
257
258 boolean first = true;
259 if (cleanedBrowserNames.size() == 1 && "DEFAULT".equals(cleanedBrowserNames.get(0))) {
260 System.out.print("\"" + testExpectation.get("DEFAULT") + '"');
261 }
262 else {
263 for (final String browserName : cleanedBrowserNames) {
264 final String expectation = testExpectation.get(browserName);
265 if (expectation == null) {
266 continue;
267 }
268 if (!first) {
269 System.out.println(",");
270 System.out.print(" ");
271 }
272 System.out.print(browserName + " = \"" + expectation + '"');
273 first = false;
274 }
275 }
276 }
277 System.out.println(")");
278
279 final String methodName = test.getName().replaceAll("\\W", "_");
280
281 System.out.println(" public void " + methodName + "() throws Exception {");
282 System.out.println(" runTest(\"" + test.getName().replace("\"", "\\\"") + "\");");
283 System.out.println(" }");
284 System.out.println();
285 }
286 }
287
288 private static List<Test> computeTestsList(final Map<String, Expectations> browserExpectations) {
289 final Map<String, Test> map = new HashMap<>();
290 for (final Expectations expectations : browserExpectations.values()) {
291 for (final Expectation expectation : expectations) {
292 final String testName = expectation.getTestName();
293 if (!testName.startsWith("skipped")) {
294 Test test = map.get(testName);
295 if (test == null) {
296 test = new Test(testName);
297 map.put(testName, test);
298 }
299 test.addLine(expectation.getLine());
300 }
301 }
302 }
303
304 final List<Test> tests = new ArrayList<>(map.values());
305 Collections.sort(tests);
306
307 return tests;
308 }
309
310 static class Expectations implements Iterable<Expectation> {
311 static Expectations readExpectations(final File file) throws IOException {
312 final Expectations expectations = new Expectations();
313 final List<String> lines = FileUtils.readLines(file, ISO_8859_1);
314 for (int i = 0; i < lines.size(); i++) {
315 expectations.add(new Expectation(file, i + 1, lines.get(i)));
316 }
317
318 return expectations;
319 }
320
321 private final Map<String, Expectation> expectations_ = new HashMap<>();
322
323 public Expectation getExpectation(final Test test) {
324 return expectations_.get(test.getName());
325 }
326
327 private void add(final Expectation expectation) {
328 expectations_.put(expectation.getTestName(), expectation);
329 }
330
331 @Override
332 public Iterator<Expectation> iterator() {
333 return expectations_.values().iterator();
334 }
335 }
336
337 static class Expectation {
338
339 private static final Pattern PATTERN =
340 Pattern.compile("(\\d+\\. ?)?(.+)\\((\\d+(, \\d+, \\d+)?)\\) \\[([0-9a-f]{1,8})\\]");
341
342 private final int line_;
343 private final String testId_;
344 private final String testName_;
345 private final String testResult_;
346
347 Expectation(final File file, final int line, final String string) {
348 line_ = line;
349 final Matcher matcher = PATTERN.matcher(string);
350 if (!matcher.matches()) {
351 throw new RuntimeException("Invalid line " + line + ": '" + string
352 + "' in file: " + file.getAbsolutePath());
353 }
354 final String testNumber = matcher.group(1);
355 if (testNumber != null && !testNumber.trim().equals(line + ".")) {
356 throw new RuntimeException("Invalid test number for line " + line + ": " + string
357 + " in file: " + file.getAbsolutePath());
358 }
359
360 testName_ = matcher.group(2).trim();
361 testResult_ = matcher.group(3);
362 testId_ = matcher.group(4);
363 }
364
365 public int getLine() {
366 return line_;
367 }
368
369 public String getTestId() {
370 return testId_;
371 }
372
373 public String getTestName() {
374 return testName_;
375 }
376
377 public String getTestResult() {
378 return testResult_;
379 }
380 }
381
382 static class Test implements Comparable<Test> {
383 private final List<Integer> lines_ = new ArrayList<>();
384 private final String name_;
385
386 Test(final String name) {
387 name_ = name;
388 }
389
390 public String getName() {
391 return name_;
392 }
393
394 void addLine(final int line) {
395 if (!lines_.contains(line)) {
396 lines_.add(line);
397 Collections.sort(lines_);
398 }
399 }
400
401 @Override
402 public int compareTo(final Test o) {
403 int diff = lines_.get(0) - o.lines_.get(0);
404 if (diff == 0) {
405 diff = lines_.size() - o.lines_.size();
406 if (diff == 0) {
407 diff = name_.compareTo(o.name_);
408 }
409 }
410 return diff;
411 }
412
413 @Override
414 public int hashCode() {
415 return name_.hashCode();
416 }
417
418 @Override
419 public boolean equals(final Object obj) {
420 return (obj instanceof Test) && name_.equals(((Test) obj).name_);
421 }
422 }
423 }