1 /*
   2  * Copyright (c) 2017, 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 8178339
  27  * @summary Tests indirect exports and opens in the module summary page
  28  * @modules jdk.javadoc/jdk.javadoc.internal.api
  29  *          jdk.javadoc/jdk.javadoc.internal.tool
  30  *          jdk.compiler/com.sun.tools.javac.api
  31  *          jdk.compiler/com.sun.tools.javac.main
  32  * @library ../lib /tools/lib
  33  * @build toolbox.ToolBox toolbox.ModuleBuilder JavadocTester
  34  * @run main TestIndirectExportsOpens
  35  */
  36 
  37 import java.nio.file.Path;
  38 import java.nio.file.Paths;
  39 
  40 import toolbox.*;
  41 
  42 public class TestIndirectExportsOpens extends JavadocTester {
  43 
  44     public final ToolBox tb;
  45     public static void main(String... args) throws Exception {
  46         TestIndirectExportsOpens tester = new TestIndirectExportsOpens();
  47         tester.runTests(m -> new Object[] { Paths.get(m.getName()) });
  48     }
  49 
  50     public TestIndirectExportsOpens() {
  51         tb = new ToolBox();
  52     }
  53 
  54     @Test
  55     public void checkNoIndirects(Path base) throws Exception {
  56 
  57         ModuleBuilder mb0 = new ModuleBuilder(tb, "m")
  58                 .classes("package pm; public class A {}");
  59         Path p0 = mb0.write(base);
  60 
  61         ModuleBuilder mb1 = new ModuleBuilder(tb, "a")
  62                 .requiresTransitive("m", p0)
  63                 .classes("package pa; public class NoOp {}")
  64                 .exports("pa");
  65         mb1.write(base);
  66 
  67         javadoc("-d", base.resolve("out-api").toString(),
  68                 "-quiet",
  69                 "--module-source-path", base.toString(),
  70                 "--expand-requires", "transitive",
  71                 "--module", "a");
  72         checkExit(Exit.OK);
  73         verifyIndirectExports(false);
  74         verifyIndirectOpens(false);
  75     }
  76 
  77     @Test
  78     public void checkExportsOpens(Path base) throws Exception {
  79 
  80         ModuleBuilder mb0 = new ModuleBuilder(tb, "m")
  81                 .classes("package pm; public class A {}")
  82                 .exports("pm")
  83                 .opens("pm");
  84 
  85         Path p0 = mb0.write(base);
  86 
  87         ModuleBuilder mb1 = new ModuleBuilder(tb, "a")
  88                 .requiresTransitive("m", p0)
  89                 .classes("package pa ; public class NoOp {}")
  90                 .exports("pa");
  91         mb1.write(base);
  92 
  93         javadoc("-d", base.resolve("out-api").toString(),
  94                 "-quiet",
  95                 "--module-source-path", base.toString(),
  96                 "--expand-requires", "transitive",
  97                 "--module", "a");
  98         checkExit(Exit.OK);
  99         verifyIndirectExports(true);
 100         verifyIndirectOpens(true);
 101     }
 102 
 103     @Test
 104     public void checkExportsToOpensTo(Path base) throws Exception {
 105 
 106         ModuleBuilder mb0 = new ModuleBuilder(tb, "m")
 107                 .classes("package pm; public class A {}")
 108                 .exportsTo("pm", "x")
 109                 .opensTo("pm", "x");
 110 
 111         Path p0 = mb0.write(base);
 112 
 113         ModuleBuilder mb1 = new ModuleBuilder(tb, "a")
 114                 .requiresTransitive("m", p0)
 115                 .classes("package pa ; public class NoOp {}")
 116                 .exports("pa");
 117         mb1.write(base);
 118 
 119         javadoc("-d", base.resolve("out-api").toString(),
 120                 "-quiet",
 121                 "--module-source-path", base.toString(),
 122                 "--expand-requires", "transitive",
 123                 "--module", "a");
 124 
 125         checkExit(Exit.OK);
 126         verifyIndirectExports(false);
 127         verifyIndirectOpens(false);
 128     }
 129 
 130     @Test
 131     public void checkExportsToOpensToDetailMode(Path base) throws Exception {
 132 
 133         ModuleBuilder mb0 = new ModuleBuilder(tb, "m")
 134                 .classes("package exportsto; public class A {}")
 135                 .classes("package opensto; public class A {}")
 136                 .exportsTo("exportsto", "x")
 137                 .opensTo("opensto", "x");
 138 
 139         Path p0 = mb0.write(base);
 140 
 141         ModuleBuilder mb1 = new ModuleBuilder(tb, "a")
 142                 .requiresTransitive("m", p0)
 143                 .classes("package pa ; public class NoOp {}")
 144                 .exports("pa");
 145         mb1.write(base);
 146 
 147         javadoc("-d", base.resolve("out-detail").toString(),
 148                 "-quiet",
 149                 "--module-source-path", base.toString(),
 150                 "--expand-requires", "transitive",
 151                 "--show-module-contents", "all",
 152                 "--module", "a");
 153 
 154         checkExit(Exit.OK);
 155 
 156         // In details mode all kinds of packages from java.base,
 157         // could be listed in the indirects section, so just
 158         // check for minimal expected strings.
 159         checkOutput("a/module-summary.html", true,
 160                 "Indirect Exports table",
 161                 "<th class=\"colFirst\" scope=\"row\"><a href=\"../m/module-summary.html\">m</a></th>\n"
 162                 + "<td class=\"colLast\"><a href=\"../m/exportsto/package-summary.html\">exportsto</a></td>\n"
 163                 + "</tr>\n");
 164 
 165         checkOutput("a/module-summary.html", true,
 166                 "Indirect Opens table",
 167                 "<th class=\"colFirst\" scope=\"row\"><a href=\"../m/module-summary.html\">m</a></th>\n"
 168                 + "<td class=\"colLast\">opensto</td>\n"
 169                 + "</tr>\n");
 170     }
 171 
 172     void verifyIndirectExports(boolean present) {
 173         verifyIndirects(present, false);
 174     }
 175 
 176     void verifyIndirectOpens(boolean present) {
 177         verifyIndirects(present, true);
 178     }
 179 
 180     void verifyIndirects(boolean present, boolean opens) {
 181 
 182         String typeString = opens ? "Indirect Opens" : "Indirect Exports";
 183 
 184         // Avoid false positives, just check for primary string absence.
 185         if (!present) {
 186             checkOutput("a/module-summary.html", false, typeString);
 187             return;
 188         }
 189 
 190         checkOutput("a/module-summary.html", present,
 191                 "<table class=\"packagesSummary\" summary=\"" + typeString + " table, listing modules, and packages\">\n"
 192                 + "<caption><span>" + typeString + "</span><span class=\"tabEnd\">&nbsp;</span></caption>\n"
 193                 + "<tr>\n"
 194                 + "<th class=\"colFirst\" scope=\"col\">From</th>\n"
 195                 + "<th class=\"colLast\" scope=\"col\">Packages</th>\n"
 196                 + "</tr>\n"
 197                 + "<tbody>\n"
 198                 + "<tr class=\"altColor\">\n"
 199                 + "<th class=\"colFirst\" scope=\"row\"><a href=\"../m/module-summary.html\">m</a></th>\n"
 200                 + "<td class=\"colLast\"><a href=\"../m/pm/package-summary.html\">pm</a></td>\n"
 201                 + "</tr>\n"
 202                 + "</tbody>\n"
 203                 + "</table>\n");
 204     }
 205 
 206 }
 207