View Javadoc
1   /*
2    * Copyright (c) 2002-2025 Gargoyle Software Inc.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    * https://www.apache.org/licenses/LICENSE-2.0
8    *
9    * Unless required by applicable law or agreed to in writing, software
10   * distributed under the License is distributed on an "AS IS" BASIS,
11   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12   * See the License for the specific language governing permissions and
13   * limitations under the License.
14   */
15  package org.htmlunit.javascript.regexp.mozilla;
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  
23  import org.apache.commons.io.FileUtils;
24  
25  /**
26   * Utility for automatically transforming Mozilla JavaScript tests to WebDriver test cases.
27   *
28   * @author Ahmed Ashour
29   */
30  public final class MozillaTestGenerator {
31  
32      private MozillaTestGenerator() {
33      }
34  
35      /**
36       * Outputs java test case for the specified JavaScript source.
37       * @param author the author name
38       * @param htmlunitRoot HtmlUnit root path
39       * @param mozillaRoot Mozilla root path
40       * @param jsPath relative JavaScript source path, e.g. "/js/src/tests/js1_2/regexp/everything.js"
41       * @param initialScript whether another initial script is needed or not
42       * @throws IOException if a reading error occurs
43       */
44      public static void printMozillaTest(final String author, final String htmlunitRoot,
45              final String mozillaRoot, final String jsPath, final boolean initialScript) throws IOException {
46          for (final Object o : FileUtils.readLines(new File(htmlunitRoot, "LICENSE.txt"), ISO_8859_1)) {
47              System.out.println(o);
48          }
49          final String[] jsPathTokens = jsPath.split("/");
50          System.out.println("package org.htmlunit.javascript.regexp.mozilla."
51                  + jsPathTokens[4] + ";");
52          System.out.println();
53          System.out.println("import org.junit.Test;");
54          System.out.println("import org.junit.runner.RunWith;");
55          System.out.println();
56          System.out.println("import org.htmlunit.BrowserRunner;");
57          System.out.println("import org.htmlunit.WebDriverTestCase;");
58          System.out.println("import org.htmlunit.BrowserRunner.Alerts;");
59          System.out.println();
60          System.out.println("/**");
61          System.out.println(" * Tests originally in '" + jsPath + "'.");
62          System.out.println(" *");
63          System.out.println(" * @author " + author);
64          System.out.println(" */");
65          System.out.println("@RunWith(BrowserRunner.class)");
66          String className = jsPathTokens[jsPathTokens.length - 1];
67          className = Character.toUpperCase(className.charAt(0)) + className.substring(1, className.length() - 3);
68          System.out.println("public class " + className + "Test extends WebDriverTestCase {");
69          final List<String> lines = FileUtils.readLines(new File(mozillaRoot, jsPath), ISO_8859_1);
70          int testNumber = 1;
71          for (int i = 0; i < lines.size(); i++) {
72              final String line = lines.get(i);
73              if (line.startsWith("new TestCase")) {
74                  if (line.endsWith(";")) {
75                      System.out.println("ERROR...... test case ends with ; in " + (i + 1));
76                      continue;
77                  }
78                  int x = i + 1;
79                  String next = lines.get(x++).trim();
80                  while (!next.endsWith(";")) {
81                      next = lines.get(x++).trim();
82                  }
83                  final String expected = getExpected(next);
84                  final String script;
85                  if (next.startsWith("String(")) {
86                      final int p0 = next.indexOf("String(", 1) + "String(".length();
87                      script = next.substring(p0, next.length() - 3);
88                  }
89                  else if (next.startsWith("\"")) {
90                      script = next.substring(expected.length() + 3, next.length() - 2).trim();
91                  }
92                  else {
93                      script = next.substring(next.indexOf(',') + 1, next.length() - 2).trim();
94                  }
95                  System.out.println();
96                  System.out.println("    /**");
97                  System.out.println("     * Tests " + script + ".");
98                  System.out.println("     * @throws Exception if the test fails");
99                  System.out.println("     */");
100                 System.out.println("    @Test");
101                 System.out.println("    @Alerts(\"" + expected + "\")");
102                 System.out.println("    public void test" + testNumber++ + "() throws Exception {");
103                 if (initialScript) {
104                     System.out.print("        test(initialScript, ");
105                 }
106                 else {
107                     System.out.print("        test(");
108                 }
109                 System.out.println("\"" + script.replace("\\", "\\\\").replace("\"", "\\\"") + "\");");
110                 System.out.println("    }");
111             }
112         }
113         System.out.println();
114         if (initialScript) {
115             System.out.println("    private void test(final String script) throws Exception {");
116             System.out.println("        test(null, script);");
117             System.out.println("    }");
118             System.out.println("");
119             System.out.println(
120                     "    private void test(final String initialScript, final String script) throws Exception {");
121             System.out.println("        String html = \"<html><head><title>foo</title><script>\\n\";");
122             System.out.println("        if (initialScript != null) {");
123             System.out.println("            html += initialScript + \";\\n\";");
124             System.out.println("        }");
125             System.out.println("        html += \"  alert(\" + script + \");\\n\"");
126             System.out.println("            + \"</script></head><body>\\n\"");
127             System.out.println("            + \"</body></html>\";");
128             System.out.println("        loadPageWithAlerts2(html);");
129             System.out.println("    }");
130         }
131         else {
132             System.out.println("    private void test(final String script) throws Exception {");
133             System.out.println("        final String html = \"<html><head><title>foo</title><script>\\n\"");
134             System.out.println("            + \"  alert(\" + script + \");\\n\"");
135             System.out.println("            + \"</script></head><body>\\n\"");
136             System.out.println("            + \"</body></html>\";");
137             System.out.println("        loadPageWithAlerts2(html);");
138             System.out.println("    }");
139         }
140         System.out.println("}");
141     }
142 
143     private static String getExpected(final String line) {
144         if (line.startsWith("\"")) {
145             final int p0 = 1;
146             int p1 = p0 + 1;
147             for (int i = p1; i < line.length() - 1; i++) {
148                 if (line.charAt(i) == '"' && line.charAt(i - 1) != '\\') {
149                     p1 = i;
150                     break;
151                 }
152             }
153             return line.substring(p0, p1);
154         }
155         else if (line.startsWith("'")) {
156             final int p0 = 1;
157             int p1 = p0 + 1;
158             for (int i = p1; i < line.length() - 1; i++) {
159                 if (line.charAt(i) == '\'' && line.charAt(i - 1) != '\\') {
160                     p1 = i;
161                     break;
162                 }
163             }
164             return line.substring(p0, p1);
165         }
166         else if (line.startsWith("String([")) {
167             final StringBuilder builder = new StringBuilder();
168             char terminator = line.charAt("String([".length());
169             int p0 = "String([\"".length();
170             if (terminator != '"' && terminator != '\'') {
171                 p0--;
172                 terminator = ']';
173             }
174             while (true) {
175                 int p1 = p0 + 1;
176                 int i = p1;
177                 if (line.charAt(p0) != terminator) {
178                     for (i = p1; i < line.length() - 1; i++) {
179                         if (line.charAt(i) == terminator && line.charAt(i - 1) != '\\') {
180                             p1 = i;
181                             break;
182                         }
183                     }
184                 }
185                 else {
186                     i = p1 - 1;
187                     p1 = p0;
188                 }
189                 if (builder.length() != 0) {
190                     builder.append(',');
191                 }
192                 builder.append(line, p0, p1);
193                 if (terminator != '"' && terminator != '\'') {
194                     break;
195                 }
196                 if (line.charAt(i + 1) == ']') {
197                     break;
198                 }
199                 terminator = line.charAt(i + 2);
200                 p0 = i + 3;
201             }
202             return builder.toString();
203         }
204         else {
205             return line.substring(0, line.indexOf(','));
206         }
207     }
208 
209 }