1 /* 2 * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 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 8025633 8025524 8081854 8187521 8182765 27 * @summary Test for valid name attribute in HTML anchors. 28 * @author Bhavesh Patel 29 * @library /tools/lib ../lib 30 * @modules jdk.javadoc/jdk.javadoc.internal.tool 31 * @build toolbox.ToolBox JavadocTester 32 * @run main TestAnchorNames 33 */ 34 35 import java.io.IOException; 36 import java.nio.file.Path; 37 import java.nio.file.Paths; 38 39 import toolbox.*; 40 41 public class TestAnchorNames extends JavadocTester { 42 43 public final ToolBox tb; main(String... args)44 public static void main(String... args) throws Exception { 45 TestAnchorNames tester = new TestAnchorNames(); 46 tester.runTests(m -> new Object[] { Paths.get(m.getName()) }); 47 } 48 TestAnchorNames()49 public TestAnchorNames() { 50 tb = new ToolBox(); 51 } 52 53 @Test testHtml4(Path ignore)54 void testHtml4(Path ignore) { 55 setAutomaticCheckLinks(false); // @ignore JDK-8202622 56 javadoc("-d", "out-html4", 57 "-html4", 58 "-sourcepath", testSrc, 59 "-source", "8", //so that '_' can be used as an identifier 60 "-use", 61 "pkg1"); 62 setAutomaticCheckLinks(true); // @ignore JDK-8202622 63 checkExit(Exit.OK); 64 65 // Test some section markers and links to these markers 66 checkOutput("pkg1/RegClass.html", true, 67 "<a name=\"skip.navbar.top\">", 68 "<a href=\"#skip.navbar.top\" title=\"Skip navigation links\">", 69 "<a name=\"nested.class.summary\">", 70 "<a href=\"#nested.class.summary\">", 71 "<a name=\"method.summary\">", 72 "<a href=\"#method.summary\">", 73 "<a name=\"field.detail\">", 74 "<a href=\"#field.detail\">", 75 "<a name=\"constructor.detail\">", 76 "<a href=\"#constructor.detail\">"); 77 78 // Test some members and link to these members 79 checkOutput("pkg1/RegClass.html", true, 80 //The marker for this appears in the serialized-form.html which we will 81 //test below 82 "<a href=\"../serialized-form.html#pkg1.RegClass\">"); 83 84 // Test some fields 85 checkOutput("pkg1/RegClass.html", true, 86 "<a name=\"Z:Z_\">", 87 "<a href=\"#Z:Z_\">", 88 "<a name=\"Z:Z_:D\">", 89 "<a href=\"#Z:Z_:D\">", 90 "<a name=\"Z:Z:D_\">", 91 "<a href=\"#Z:Z:D_\">", 92 "<a name=\"Z:Z:Dfield\">", 93 "<a href=\"#Z:Z:Dfield\">", 94 "<a name=\"fieldInCla:D:D\">", 95 "<a href=\"#fieldInCla:D:D\">", 96 "<a name=\"S_:D:D:D:D:DINT\">", 97 "<a href=\"#S_:D:D:D:D:DINT\">", 98 "<a name=\"method:D:D\">", 99 "<a href=\"#method:D:D\">"); 100 101 checkOutput("pkg1/DeprMemClass.html", true, 102 "<a name=\"Z:Z_field_In_Class\">", 103 "<a href=\"#Z:Z_field_In_Class\">"); 104 105 // Test constructor 106 checkOutput("pkg1/RegClass.html", true, 107 "<a name=\"RegClass-java.lang.String-int-\">", 108 "<a href=\"#RegClass-java.lang.String-int-\">"); 109 110 // Test some methods 111 checkOutput("pkg1/RegClass.html", true, 112 "<a name=\"Z:Z_methodInClass-java.lang.String-\">", 113 "<a href=\"#Z:Z_methodInClass-java.lang.String-\">", 114 "<a name=\"method--\">", 115 "<a href=\"#method--\">", 116 "<a name=\"foo-java.util.Map-\">", 117 "<a href=\"#foo-java.util.Map-\">", 118 "<a name=\"methodInCla:Ds-java.lang.String:A-\">", 119 "<a href=\"#methodInCla:Ds-java.lang.String:A-\">", 120 "<a name=\"Z:Z_methodInClas:D-java.lang.String-int-\">", 121 "<a href=\"#Z:Z_methodInClas:D-java.lang.String-int-\">", 122 "<a name=\"methodD-pkg1.RegClass.:DA-\">", 123 "<a href=\"#methodD-pkg1.RegClass.:DA-\">", 124 "<a name=\"methodD-pkg1.RegClass.D:A-\">", 125 "<a href=\"#methodD-pkg1.RegClass.D:A-\">"); 126 127 checkOutput("pkg1/DeprMemClass.html", true, 128 "<a name=\"Z:Z:Dmethod_In_Class--\">", 129 "<a href=\"#Z:Z:Dmethod_In_Class--\">"); 130 131 // Test enum 132 checkOutput("pkg1/RegClass.Te$t_Enum.html", true, 133 "<a name=\"Z:Z:DFLD2\">", 134 "<a href=\"#Z:Z:DFLD2\">"); 135 136 // Test nested class 137 checkOutput("pkg1/RegClass._NestedClas$.html", true, 138 "<a name=\"Z:Z_NestedClas:D--\">", 139 "<a href=\"#Z:Z_NestedClas:D--\">"); 140 141 // Test class use page 142 checkOutput("pkg1/class-use/DeprMemClass.html", true, 143 "<a href=\"../RegClass.html#d____mc\">"); 144 145 // Test deprecated list page 146 checkOutput("deprecated-list.html", true, 147 "<a href=\"pkg1/DeprMemClass.html#Z:Z_field_In_Class\">", 148 "<a href=\"pkg1/DeprMemClass.html#Z:Z:Dmethod_In_Class--\">"); 149 150 // Test constant values page 151 checkOutput("constant-values.html", true, 152 "<a href=\"pkg1/RegClass.html#S_:D:D:D:D:DINT\">"); 153 154 // Test serialized form page 155 checkOutput("serialized-form.html", true, 156 //This is the marker for the link that appears in the pkg1.RegClass.html page 157 "<a name=\"pkg1.RegClass\">"); 158 159 // Test member name index page 160 checkOutput("index-all.html", true, 161 "<a name=\"I:Z:Z:D\">", 162 "<a href=\"#I:Z:Z:D\">$", 163 "<a href=\"#I:Z:Z_\">_"); 164 165 // The marker name conversion should only affect HTML anchors. It should not 166 // affect the labels. 167 checkOutput("pkg1/RegClass.html", false, 168 " Z:Z_", 169 " Z:Z:Dfield", 170 " Z:Z_field_In_Class", 171 " S_:D:D:D:D:DINT"); 172 } 173 174 @Test testHtml5(Path ignore)175 void testHtml5(Path ignore) { 176 javadoc("-d", "out-html5", 177 "-sourcepath", testSrc, 178 "-source", "8", //so that '_' can be used as an identifier 179 "-use", 180 "pkg1"); 181 checkExit(Exit.OK); 182 183 // Test some section markers and links to these markers 184 checkOutput("pkg1/RegClass.html", true, 185 "<a id=\"skip.navbar.top\">", 186 "<a href=\"#skip.navbar.top\" title=\"Skip navigation links\">", 187 "<a id=\"nested.class.summary\">", 188 "<a href=\"#nested.class.summary\">", 189 "<a id=\"method.summary\">", 190 "<a href=\"#method.summary\">", 191 "<a id=\"field.detail\">", 192 "<a href=\"#field.detail\">", 193 "<a id=\"constructor.detail\">", 194 "<a href=\"#constructor.detail\">"); 195 196 // Test some members and link to these members 197 checkOutput("pkg1/RegClass.html", true, 198 //The marker for this appears in the serialized-form.html which we will 199 //test below 200 "<a href=\"../serialized-form.html#pkg1.RegClass\">"); 201 202 // Test some fields 203 checkOutput("pkg1/RegClass.html", true, 204 "<a id=\"_\">", 205 "<a href=\"#_\">", 206 "<a id=\"_$\">", 207 "<a href=\"#_$\">", 208 "<a id=\"$_\">", 209 "<a href=\"#$_\">", 210 "<a id=\"$field\">", 211 "<a href=\"#$field\">", 212 "<a id=\"fieldInCla$$\">", 213 "<a href=\"#fieldInCla$$\">", 214 "<a id=\"S_$$$$$INT\">", 215 "<a href=\"#S_$$$$$INT\">", 216 "<a id=\"method$$\">", 217 "<a href=\"#method$$\">"); 218 219 checkOutput("pkg1/DeprMemClass.html", true, 220 "<a id=\"_field_In_Class\">", 221 "<a href=\"#_field_In_Class\">"); 222 223 // Test constructor 224 checkOutput("pkg1/RegClass.html", true, 225 "<a id=\"<init>(java.lang.String,int)\">", 226 "<a href=\"#%3Cinit%3E(java.lang.String,int)\">"); 227 228 // Test some methods 229 checkOutput("pkg1/RegClass.html", true, 230 "<a id=\"_methodInClass(java.lang.String)\">", 231 "<a href=\"#_methodInClass(java.lang.String)\">", 232 "<a id=\"method()\">", 233 "<a href=\"#method()\">", 234 "<a id=\"foo(java.util.Map)\">", 235 "<a href=\"#foo(java.util.Map)\">", 236 "<a id=\"methodInCla$s(java.lang.String[])\">", 237 "<a href=\"#methodInCla$s(java.lang.String%5B%5D)\">", 238 "<a id=\"_methodInClas$(java.lang.String,int)\">", 239 "<a href=\"#_methodInClas$(java.lang.String,int)\">", 240 "<a id=\"methodD(pkg1.RegClass.$A)\">", 241 "<a href=\"#methodD(pkg1.RegClass.$A)\">", 242 "<a id=\"methodD(pkg1.RegClass.D[])\">", 243 "<a href=\"#methodD(pkg1.RegClass.D%5B%5D)\">"); 244 245 checkOutput("pkg1/DeprMemClass.html", true, 246 "<a id=\"$method_In_Class()\">", 247 "<a href=\"#$method_In_Class()\">"); 248 249 // Test enum 250 checkOutput("pkg1/RegClass.Te$t_Enum.html", true, 251 "<a id=\"$FLD2\">", 252 "<a href=\"#$FLD2\">"); 253 254 // Test nested class 255 checkOutput("pkg1/RegClass._NestedClas$.html", true, 256 "<a id=\"<init>()\">", 257 "<a href=\"#%3Cinit%3E()\">"); 258 259 // Test class use page 260 checkOutput("pkg1/class-use/DeprMemClass.html", true, 261 "<a href=\"../RegClass.html#d____mc\">"); 262 263 // Test deprecated list page 264 checkOutput("deprecated-list.html", true, 265 "<a href=\"pkg1/DeprMemClass.html#_field_In_Class\">", 266 "<a href=\"pkg1/DeprMemClass.html#$method_In_Class()\">"); 267 268 // Test constant values page 269 checkOutput("constant-values.html", true, 270 "<a href=\"pkg1/RegClass.html#S_$$$$$INT\">"); 271 272 // Test serialized form page 273 checkOutput("serialized-form.html", true, 274 //This is the marker for the link that appears in the pkg1.RegClass.html page 275 "<a id=\"pkg1.RegClass\">"); 276 277 // Test member name index page 278 checkOutput("index-all.html", true, 279 "<a id=\"I:$\">", 280 "<a href=\"#I:$\">$", 281 "<a href=\"#I:_\">_"); 282 } 283 284 /** 285 * The following test is somewhat simplistic, but it is useful 286 * in conjunction with the W3C Validation Service at https://validator.w3.org/nu/#file 287 * @param base A working directory for this method, in which some UTF-8 source files 288 * will be generated 289 * @throws IOException if there is a problem generating the source files 290 */ 291 @Test testNonAscii(Path base)292 void testNonAscii(Path base) throws IOException { 293 Path src = base.resolve("src"); 294 tb.writeJavaFiles(src, 295 "package p; public class Def {\n" 296 + " public int \u00e0\u00e9;\n" // a`e' 297 + " public void \u00c0\u00c9() { }\n" // A`E' 298 + " public int \u03b1\u03b2\u03b3;\n" // alpha beta gamma 299 + " public void \u0391\u0392\u0393() { }\n" // ALPHA BETA GAMMA 300 + "}", 301 "package p; \n" 302 + "/**\n" 303 + " * {@link Def#\u00e0\u00e9 àé}<br>\n" 304 + " * {@link Def#\u00c0\u00c9() ÀÉ}<br>\n" 305 + " * {@link Def#\u03b1\u03b2\u03b3 αβγ}<br>\n" 306 + " * {@link Def#\u0391\u0392\u0393() ΑΒΓ}<br>\n" 307 + " */\n" 308 + "public class Ref { }"); 309 310 javadoc("-d", "out-nonAscii", 311 "-sourcepath", src.toString(), 312 "-html5", 313 "-encoding", "utf-8", 314 "p"); 315 checkExit(Exit.OK); 316 317 checkOutput("p/Def.html", true, 318 "<a id=\"\u00e0\u00e9\">", 319 "<a id=\"\u00c0\u00c9()\">", 320 "<a id=\"\u03b1\u03b2\u03b3\">", 321 "<a id=\"\u0391\u0392\u0393()\">"); 322 323 checkOutput("p/Ref.html", true, 324 "<a href=\"Def.html#%C3%A0%C3%A9\"><code>àé</code></a>", 325 "<a href=\"Def.html#%C3%80%C3%89()\"><code>ÀÉ</code></a>", 326 "<a href=\"Def.html#%CE%B1%CE%B2%CE%B3\"><code>αβγ</code></a>", 327 "<a href=\"Def.html#%CE%91%CE%92%CE%93()\"><code>ΑΒΓ</code></a>"); 328 329 } 330 } 331