1 /*
   2  * Copyright (c) 2019, 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      8227047
  27  * @summary  Sealed types
  28  * @library  /tools/lib ../../lib
  29  * @modules jdk.javadoc/jdk.javadoc.internal.tool
  30  * @build    toolbox.ToolBox javadoc.tester.*
  31  * @run main TestSealedTypes
  32  */
  33 
  34 
  35 import java.io.IOException;
  36 import java.nio.file.Path;
  37 
  38 import javadoc.tester.JavadocTester;
  39 import toolbox.ToolBox;
  40 
  41 public class TestSealedTypes extends JavadocTester {
  42 
  43     public static void main(String... args) throws Exception {
  44         TestSealedTypes tester = new TestSealedTypes();
  45         tester.runTests(m -> new Object[] { Path.of(m.getName()) });
  46     }
  47 
  48     private final ToolBox tb = new ToolBox();
  49 
  50     @Test
  51     public void testSealedModifierClass(Path base) throws IOException {
  52         Path src = base.resolve("src");
  53         tb.writeJavaFiles(src,
  54                 "package p; public sealed class A { }");
  55 
  56         javadoc("-d", base.resolve("out").toString(),
  57                 "-sourcepath", src.toString(),
  58                 "p");
  59         checkExit(Exit.OK);
  60 
  61         checkOutput("p/A.html", true,
  62                 "public sealed class <span class=\"typeNameLabel\">A</span>");
  63     }
  64 
  65     @Test
  66     public void testSealedModifierInterface(Path base) throws IOException {
  67         Path src = base.resolve("src");
  68         tb.writeJavaFiles(src,
  69                 "package p; public sealed interface A { }");
  70 
  71         javadoc("-d", base.resolve("out").toString(),
  72                 "-sourcepath", src.toString(),
  73                 "p");
  74         checkExit(Exit.OK);
  75 
  76         checkOutput("p/A.html", true,
  77                 "public sealed interface <span class=\"typeNameLabel\">A</span>");
  78     }
  79 
  80     @Test
  81     public void testNonSealedModifierClass(Path base) throws IOException {
  82         Path src = base.resolve("src");
  83         tb.writeJavaFiles(src,
  84                 "package p; public sealed class A permits B { }",
  85                 "package p; public non-sealed class B extends A { }");
  86 
  87         javadoc("-d", base.resolve("out").toString(),
  88                 "--source-path", src.toString(),
  89                 "p");
  90         checkExit(Exit.OK);
  91 
  92         checkOutput("p/A.html", true,
  93                 "public sealed class <span class=\"typeNameLabel\">A</span>");
  94 
  95         checkOutput("p/B.html", true,
  96                 "public non-sealed class <span class=\"typeNameLabel\">B</span>");
  97     }
  98 
  99     @Test
 100     public void testNonSealedModifierInterface(Path base) throws IOException {
 101         Path src = base.resolve("src");
 102         tb.writeJavaFiles(src,
 103                 "package p; public sealed interface A permits B { }",
 104                 "package p; public non-sealed interface B extends A { }");
 105 
 106         javadoc("-d", base.resolve("out").toString(),
 107                 "--source-path", src.toString(),
 108                 "p");
 109         checkExit(Exit.OK);
 110 
 111         checkOutput("p/A.html", true,
 112                 "public sealed interface <span class=\"typeNameLabel\">A</span>");
 113 
 114         checkOutput("p/B.html", true,
 115                 "public non-sealed interface <span class=\"typeNameLabel\">B</span>");
 116     }
 117 
 118     @Test
 119     public void testImplicitSealedModifierClass(Path base) throws IOException {
 120         Path src = base.resolve("src");
 121         tb.writeJavaFiles(src,
 122                 "package p; public sealed class A permits B { }",
 123                 "package p; public abstract class B extends A { }");
 124 
 125         javadoc("-d", base.resolve("out").toString(),
 126                 "--source-path", src.toString(),
 127                 "p");
 128         checkExit(Exit.OK);
 129 
 130         checkOutput("p/A.html", true,
 131                 "public sealed class <span class=\"typeNameLabel\">A</span>");
 132 
 133         checkOutput("p/B.html", true,
 134                 "public abstract sealed class <span class=\"typeNameLabel\">B</span>");
 135     }
 136 
 137     @Test
 138     public void testImplicitSealedModifierInterface(Path base) throws IOException {
 139         Path src = base.resolve("src");
 140         tb.writeJavaFiles(src,
 141                 "package p; public sealed interface A permits B { }",
 142                 "package p; public interface B extends A { }");
 143 
 144         javadoc("-d", base.resolve("out").toString(),
 145                 "--source-path", src.toString(),
 146                 "p");
 147         checkExit(Exit.OK);
 148 
 149         checkOutput("p/A.html", true,
 150                 "public sealed interface <span class=\"typeNameLabel\">A</span>");
 151 
 152         checkOutput("p/B.html", true,
 153                 "public sealed interface <span class=\"typeNameLabel\">B</span>");
 154     }
 155 
 156     @Test
 157     public void testSinglePermits(Path base) throws IOException {
 158         Path src = base.resolve("src");
 159         tb.writeJavaFiles(src,
 160                 "package p; public sealed class A permits B { }",
 161                 "package p; public class B extends A { }");
 162 
 163         javadoc("-d", base.resolve("out").toString(),
 164                 "--source-path", src.toString(),
 165                 "p");
 166         checkExit(Exit.OK);
 167 
 168         checkOutput("p/A.html", true,
 169                 "<pre>public sealed class <span class=\"typeNameLabel\">A</span>\n"
 170                 + "extends java.lang.Object\n"
 171                 + "permits <a href=\"B.html\" title=\"class in p\">B</a></pre>");
 172     }
 173 
 174     @Test
 175     public void testMultiplePermits(Path base) throws IOException {
 176         Path src = base.resolve("src");
 177         tb.writeJavaFiles(src,
 178                 "package p; public sealed class A permits B,C,D { }",
 179                 "package p; public class B extends A { }",
 180                 "package p; public class C extends A { }",
 181                 "package p; public class D extends A { }");
 182 
 183         javadoc("-d", base.resolve("out").toString(),
 184                 "--source-path", src.toString(),
 185                 "p");
 186         checkExit(Exit.OK);
 187 
 188         checkOutput("p/A.html", true,
 189                 "<pre>public sealed class <span class=\"typeNameLabel\">A</span>\n"
 190                 + "extends java.lang.Object\n"
 191                 + "permits <a href=\"B.html\" title=\"class in p\">B</a>, "
 192                 + "<a href=\"C.html\" title=\"class in p\">C</a>, "
 193                 + "<a href=\"D.html\" title=\"class in p\">D</a></pre>");
 194     }
 195 
 196     @Test
 197     public void testPartialMultiplePermits(Path base) throws IOException {
 198         Path src = base.resolve("src");
 199         tb.writeJavaFiles(src,
 200                 "package p; public sealed class A permits B,C,D { }",
 201                 "package p; public class B extends A { }",
 202                 "package p; public class C extends A { }",
 203                 "package p;        class D extends A { }");
 204 
 205         javadoc("-d", base.resolve("out").toString(),
 206                 "--source-path", src.toString(),
 207                 "p");
 208         checkExit(Exit.OK);
 209 
 210         checkOutput("p/A.html", true,
 211                 "<pre>public sealed class <span class=\"typeNameLabel\">A</span>\n"
 212                 + "extends java.lang.Object\n"
 213                 + "permits <a href=\"B.html\" title=\"class in p\">B</a>, "
 214                 + "<a href=\"C.html\" title=\"class in p\">C</a>, p.D</pre>");
 215     }
 216 
 217     @Test
 218     public void testPartialMultiplePermitsWithSubtypes1(Path base) throws IOException {
 219         Path src = base.resolve("src");
 220         tb.writeJavaFiles(src,
 221                 "package p; public sealed class A permits B,C,D { }",
 222                 "package p; public class B extends A { }",
 223                 "package p; public class C extends A { }",
 224                 "package p;        sealed class D extends A permits D1, D2 { }",
 225                 "package p; public class D1 extends D { }",
 226                 "package p; public class D2 extends D { }");
 227 
 228         javadoc("-d", base.resolve("out").toString(),
 229                 "--source-path", src.toString(),
 230                 "p");
 231         checkExit(Exit.OK);
 232 
 233         checkOutput("p/A.html", true,
 234                 "<pre>public sealed class <span class=\"typeNameLabel\">A</span>\n"
 235                 + "extends java.lang.Object\n"
 236                 + "permits <a href=\"B.html\" title=\"class in p\">B</a>, "
 237                 + "<a href=\"C.html\" title=\"class in p\">C</a>, p.D</pre>");
 238     }
 239 
 240     @Test
 241     public void testPartialMultiplePermitsWithSubtypes2(Path base) throws IOException {
 242         Path src = base.resolve("src");
 243         tb.writeJavaFiles(src,
 244                 "package p; public sealed class A permits B,C,D { }",
 245                 "package p; public class B extends A { }",
 246                 "package p; public class C extends A { }",
 247                 "package p;        non-sealed class D extends A { }",
 248                 "package p; public class D1 extends D { }",
 249                 "package p; public class D2 extends D { }");
 250 
 251         javadoc("-d", base.resolve("out").toString(),
 252                 "--source-path", src.toString(),
 253                 "p");
 254         checkExit(Exit.OK);
 255 
 256         checkOutput("p/A.html", true,
 257                 "<pre>public sealed class <span class=\"typeNameLabel\">A</span>\n"
 258                 + "extends java.lang.Object\n"
 259                 + "permits <a href=\"B.html\" title=\"class in p\">B</a>, "
 260                 + "<a href=\"C.html\" title=\"class in p\">C</a>, p.D</pre>");
 261     }
 262 
 263     @Test
 264     public void testImplicitPermitsAuxiliary(Path base) throws IOException {
 265         Path src = base.resolve("src");
 266         tb.writeJavaFiles(src,
 267                 "package p; public sealed class A { }\n"
 268                 + "class B extends A { }\n"
 269                 + "class C extends A { }\n"
 270                 + "class D extends A { }\n");
 271 
 272         javadoc("-d", base.resolve("out").toString(),
 273                 "--source-path", src.toString(),
 274                 "-package",
 275                 "p");
 276         checkExit(Exit.OK);
 277 
 278         checkOutput("p/A.html", true,
 279                 "<pre>public sealed class <span class=\"typeNameLabel\">A</span>\n"
 280                 + "extends java.lang.Object\n"
 281                 + "permits <a href=\"B.html\" title=\"class in p\">B</a>, "
 282                 + "<a href=\"C.html\" title=\"class in p\">C</a>, "
 283                 + "<a href=\"D.html\" title=\"class in p\">D</a></pre>");
 284     }
 285 
 286     @Test
 287     public void testImplicitPermitsNested(Path base) throws IOException {
 288         Path src = base.resolve("src");
 289         tb.writeJavaFiles(src,
 290                 "package p; public sealed class A {\n"
 291                 + "  public static class B extends A { }\n"
 292                 + "  public static class C extends A { }\n"
 293                 + "  public static class D extends A { }\n"
 294                 + "}");
 295 
 296         javadoc("-d", base.resolve("out").toString(),
 297                 "--source-path", src.toString(),
 298                 "p");
 299         checkExit(Exit.OK);
 300 
 301         checkOutput("p/A.html", true,
 302                 "<pre>public sealed class <span class=\"typeNameLabel\">A</span>\n"
 303                 + "extends java.lang.Object\n"
 304                 + "permits <a href=\"A.B.html\" title=\"class in p\">A.B</a>, "
 305                 + "<a href=\"A.C.html\" title=\"class in p\">A.C</a>, "
 306                 + "<a href=\"A.D.html\" title=\"class in p\">A.D</a></pre>");
 307     }
 308 }