9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 /* 25 * @test 26 * @bug 4494033 7028815 7052425 8007338 8023608 8008164 8016549 8072461 8154261 8162363 8160196 8151743 8177417 27 * 8175218 8176452 8181215 8182263 8183511 8169819 8183037 8185369 8182765 8196201 8184205 8223378 28 * @summary Run tests on doclet stylesheet. 29 * @library ../../lib 30 * @modules jdk.javadoc/jdk.javadoc.internal.tool 31 * @build javadoc.tester.* 32 * @run main TestStylesheet 33 */ 34 35 import javadoc.tester.JavadocTester; 36 37 public class TestStylesheet extends JavadocTester { 38 39 public static void main(String... args) throws Exception { 40 TestStylesheet tester = new TestStylesheet(); 41 tester.runTests(); 42 } 43 44 @Test 45 public void test() { 46 javadoc("-d", "out", 47 "-sourcepath", testSrc, 48 "pkg"); 49 checkExit(Exit.ERROR); 50 51 checkOutput(Output.OUT, true, 52 "attribute not supported in HTML5: name"); 53 54 // TODO: most of this test seems a bit silly, since javadoc is simply 55 // copying in the stylesheet from the source directory 56 checkOutput("stylesheet.css", true, 57 "body {\n" 58 + " background-color:#ffffff;\n" 59 + " color:#353833;\n" 60 + " font-family:'DejaVu Sans', Arial, Helvetica, sans-serif;\n" 61 + " font-size:14px;\n" 62 + " margin:0;\n" 63 + " padding:0;\n" 64 + " height:100%;\n" 65 + " width:100%;\n" 66 + "}", 216 + " padding:0;\n" 217 + "}", 218 "a:active {\n" 219 + " text-decoration:none;\n" 220 + " color:#4A6782;\n" 221 + "}", 222 "a[name]:hover {\n" 223 + " text-decoration:none;\n" 224 + " color:#353833;\n" 225 + "}", 226 "td.col-first a:link, td.col-first a:visited,\n" 227 + "td.col-second a:link, td.col-second a:visited,\n" 228 + "th.col-first a:link, th.col-first a:visited,\n" 229 + "th.col-second a:link, th.col-second a:visited,\n" 230 + "th.col-constructor-name a:link, th.col-constructor-name a:visited,\n" 231 + "td.col-last a:link, td.col-last a:visited,\n" 232 + ".constant-values-container td a:link, .constant-values-container td a:visited {\n" 233 + " font-weight:bold;\n" 234 + "}"); 235 } 236 } | 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 /* 25 * @test 26 * @bug 4494033 7028815 7052425 8007338 8023608 8008164 8016549 8072461 8154261 8162363 8160196 8151743 8177417 27 * 8175218 8176452 8181215 8182263 8183511 8169819 8183037 8185369 8182765 8196201 8184205 8223378 28 * @summary Run tests on doclet stylesheet. 29 * @library /tools/lib ../../lib 30 * @modules jdk.javadoc/jdk.javadoc.internal.tool 31 * @build toolbox.ToolBox javadoc.tester.* 32 * @run main TestStylesheet 33 */ 34 35 import java.io.IOException; 36 import java.io.PrintStream; 37 import java.nio.file.Path; 38 import java.util.List; 39 import java.util.Map; 40 import java.util.Set; 41 import java.util.TreeSet; 42 import java.util.function.Function; 43 44 import javadoc.tester.HtmlChecker; 45 import javadoc.tester.JavadocTester; 46 import toolbox.ToolBox; 47 48 public class TestStylesheet extends JavadocTester { 49 50 public static void main(String... args) throws Exception { 51 TestStylesheet tester = new TestStylesheet(); 52 tester.runTests(m -> new Object[] { Path.of(m.getName())}); 53 } 54 55 @Test 56 public void test(Path base) { 57 javadoc("-d", base.resolve("out").toString(), 58 "-sourcepath", testSrc, 59 "pkg"); 60 checkExit(Exit.ERROR); 61 62 checkOutput(Output.OUT, true, 63 "attribute not supported in HTML5: name"); 64 65 // TODO: most of this test seems a bit silly, since javadoc is simply 66 // copying in the stylesheet from the source directory 67 checkOutput("stylesheet.css", true, 68 "body {\n" 69 + " background-color:#ffffff;\n" 70 + " color:#353833;\n" 71 + " font-family:'DejaVu Sans', Arial, Helvetica, sans-serif;\n" 72 + " font-size:14px;\n" 73 + " margin:0;\n" 74 + " padding:0;\n" 75 + " height:100%;\n" 76 + " width:100%;\n" 77 + "}", 227 + " padding:0;\n" 228 + "}", 229 "a:active {\n" 230 + " text-decoration:none;\n" 231 + " color:#4A6782;\n" 232 + "}", 233 "a[name]:hover {\n" 234 + " text-decoration:none;\n" 235 + " color:#353833;\n" 236 + "}", 237 "td.col-first a:link, td.col-first a:visited,\n" 238 + "td.col-second a:link, td.col-second a:visited,\n" 239 + "th.col-first a:link, th.col-first a:visited,\n" 240 + "th.col-second a:link, th.col-second a:visited,\n" 241 + "th.col-constructor-name a:link, th.col-constructor-name a:visited,\n" 242 + "td.col-last a:link, td.col-last a:visited,\n" 243 + ".constant-values-container td a:link, .constant-values-container td a:visited {\n" 244 + " font-weight:bold;\n" 245 + "}"); 246 } 247 248 ToolBox tb = new ToolBox(); 249 250 @Test 251 public void testStyles(Path base) throws Exception { 252 Path src = base.resolve("src"); 253 tb.writeJavaFiles(src, 254 "module mA { exports p; }", 255 "package p; public class C {\n" 256 + "public C() { }\n" 257 + "public C(int i) { }\n" 258 + "public int f1;\n" 259 + "public int f2;\n" 260 + "public int m1() { }\n" 261 + "public int m2(int i) { }\n" 262 + "}\n", 263 "package p; public @interface Anno {\n" 264 + "public int value();\n" 265 + "}\n" 266 ); 267 268 javadoc("-d", base.resolve("out").toString(), 269 "-sourcepath", src.toString(), 270 "--module", "mA"); 271 checkExit(Exit.OK); 272 checkStyles(addExtraCSSClassNames(readStylesheet())); 273 } 274 275 Set<String> readStylesheet() { 276 // scan for class selectors, skipping '{' ... '}' 277 Set<String> styles = new TreeSet<>(); 278 String stylesheet = readFile("stylesheet.css"); 279 for (int i = 0; i < stylesheet.length(); i++) { 280 char ch = stylesheet.charAt(i); 281 switch (ch) { 282 case '.': 283 i++; 284 int start = i; 285 while (i < stylesheet.length()) { 286 ch = stylesheet.charAt(i); 287 if (!(Character.isLetterOrDigit(ch) || ch == '-')) { 288 break; 289 } 290 i++; 291 } 292 styles.add(stylesheet.substring(start, i)); 293 break; 294 295 case '{': 296 i++; 297 while (i < stylesheet.length()) { 298 ch = stylesheet.charAt(i); 299 if (ch == '}') { 300 break; 301 } 302 i++; 303 } 304 break; 305 306 case '@': 307 i++; 308 while (i < stylesheet.length()) { 309 ch = stylesheet.charAt(i); 310 if (ch == '{') { 311 break; 312 } 313 i++; 314 } 315 break; 316 } 317 } 318 out.println("found styles: " + styles); 319 return styles; 320 } 321 322 Set<String> addExtraCSSClassNames(Set<String> styles) throws Exception { 323 // The following names are used in the generated HTML, 324 // but have no corresponding definitions in the stylesheet file. 325 // They are mostly optional, in the "use if you want to" category. 326 // They are included here so that we do not get errors when these 327 // names are used in the generated HTML. 328 List<String> extra = List.of( 329 // entries for <body> elements 330 "all-classes-index-page", 331 "all-packages-index-page", 332 "constants-summary-page", 333 "deprecated-list-page", 334 "help-page", 335 "index-redirect-page", 336 "package-declaration-page", 337 "package-tree-page", 338 "single-index-page", 339 "tree-page", 340 // the following names are matched by [class$='...'] in the stylesheet 341 "constructor-details", 342 "constructor-summary", 343 "field-details", 344 "field-summary", 345 "member-details", 346 "method-details", 347 "method-summary", 348 // the following provide the ability to optionally override components of the 349 // memberSignature structure 350 "member-name", 351 "modifiers", 352 "packages", 353 "return-type", 354 // and others... 355 "help-section", // part of the help page 356 "hierarchy", // for the hierarchy on a tree page 357 "index" // on the index page 358 ); 359 for (String e : extra) { 360 if (styles.contains(e)) { 361 throw new Exception("extra CSS class name found in style sheet: " + e); 362 } 363 styles.add(e); 364 } 365 return styles; 366 } 367 368 /** 369 * Checks that all the CSS names found in {@code class} attributes in HTML files in the 370 * output directory are present in a given set of styles. 371 * 372 * @param styles the styles 373 */ 374 void checkStyles(Set<String> styles) { 375 checking("Check CSS class names"); 376 CSSClassChecker c = new CSSClassChecker(out, this::readFile, styles); 377 try { 378 c.checkDirectory(outputDir.toPath()); 379 c.report(); 380 int errors = c.getErrorCount(); 381 if (errors == 0) { 382 passed("No CSS class name errors found"); 383 } else { 384 failed(errors + " errors found when checking CSS class names"); 385 } 386 } catch (IOException e) { 387 failed("exception thrown when reading files: " + e); 388 } 389 390 } 391 392 class CSSClassChecker extends HtmlChecker { 393 Set<String> styles; 394 int errors; 395 396 protected CSSClassChecker(PrintStream out, 397 Function<Path, String> fileReader, 398 Set<String> styles) { 399 super(out, fileReader); 400 this.styles = styles; 401 } 402 403 protected int getErrorCount() { 404 return errors; 405 } 406 407 @Override 408 protected void report() { 409 if (getErrorCount() == 0) { 410 out.println("All CSS class names found"); 411 } else { 412 out.println(getErrorCount() + " CSS class names not found"); 413 } 414 415 } 416 417 @Override 418 public void startElement(String name, Map<String,String> attrs, boolean selfClosing) { 419 String style = attrs.get("class"); 420 if (style != null && !styles.contains(style)) { 421 error(currFile, getLineNumber(), "CSS class name not found: " + style); 422 } 423 } 424 } 425 } |