/* * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package build.tools.module; import java.io.BufferedWriter; import java.io.IOException; import java.io.PrintWriter; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.Arrays; import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Set; import build.tools.module.GenModuleInfoSource.Statement; /** * Sanity test for GenModuleInfoSource tool */ public class ModuleInfoExtraTest { private static final Path DIR = Paths.get("test"); public static void main(String... args) throws Exception { if (args.length != 0) GenModuleInfoSource.verbose = true; ModuleInfoExtraTest test = new ModuleInfoExtraTest("m", "m1", "m2", "m3"); test.run(); } String[] moduleInfo = new String[] { "exports p", "to", " // comment", " /* comment */ m1", ",", "m2,m3", " ;", "exports q to m1;", "provides s with /* ", " comment */ impl ; // comment", "provides s1", " with ", " impl1, impl2;" }; String[] moduleInfoExtra = new String[] { "exports q", "to", " m2 // comment", " /* comment */;", " ;", "opens p.q ", " to /* comment */ m3", " , // m1", " /* comment */, m4;", "provides s1 with impl3;" }; String[] test1 = new String[] { "exports p1 to m1;", "exports p2" }; String[] test2 = new String[] { "exports to m1;" }; String[] test3 = new String[]{ "exports p3 to m1;", " m2, m3;" }; String[] test4 = new String[]{ "provides s with impl1;", // typo ; should be , " impl2, impl3;" }; String[] test5 = new String[]{ "uses s3", "provides s3 with impl1,", " impl2, impl3;" }; final Builder builder; ModuleInfoExtraTest(String name, String... modules) { this.builder = new Builder(name).modules(modules); } void run() throws IOException { testModuleInfo(); errorCases(); } void testModuleInfo() throws IOException { GenModuleInfoSource source = builder.sourceFile(moduleInfo).build(); Set<String> targetsP = new HashSet<>(); targetsP.add("m1"); targetsP.add("m2"); targetsP.add("m3"); Set<String> targetsQ = new HashSet<>(); targetsQ.add("m1"); Set<String> providerS = new HashSet<>(); providerS.add("impl"); Set<String> providerS1 = new HashSet<>(); providerS1.add("impl1"); providerS1.add("impl2"); Set<String> opensPQ = new HashSet<>(); check(source, targetsP, targetsQ, opensPQ, providerS, providerS1); // augment with extra Path file = DIR.resolve("extra"); Files.write(file, Arrays.asList(moduleInfoExtra)); source = builder.build(file); targetsQ.add("m2"); providerS1.add("impl3"); opensPQ.add("m3"); check(source, targetsP, targetsQ, opensPQ, providerS, providerS1); } void check(GenModuleInfoSource source, Set<String> targetsP, Set<String> targetsQ, Set<String> opensPQ, Set<String> providerS, Set<String> providerS1) { source.moduleInfo.print(new PrintWriter(System.out, true)); Statement export = source.moduleInfo.exports.get("p"); if (!export.targets.equals(targetsP)) { throw new Error("unexpected: " + export); } export = source.moduleInfo.exports.get("q"); if (!export.targets.equals(targetsQ)) { throw new Error("unexpected: " + export); } Statement provides = source.moduleInfo.provides.get("s"); if (!provides.targets.equals(providerS)) { throw new Error("unexpected: " + provides); } provides = source.moduleInfo.provides.get("s1"); if (!provides.targets.equals(providerS1)) { throw new Error("unexpected: " + provides); } } void errorCases() throws IOException { fail(test1); fail(test2); fail(test3); fail(test4); fail(test5); } void fail(String... extras) throws IOException { Path file = DIR.resolve("test1"); Files.write(file, Arrays.asList(extras)); try { builder.build(file); } catch (RuntimeException e) { if (!e.getMessage().matches("test/test1, line .* is malformed.*") && !e.getMessage().matches("test/test1, line .* missing keyword.*")) { throw e; } } } static class Builder { final String moduleName; final Path sourceFile; final Set<String> modules = new HashSet<>(); public Builder(String name) { this.moduleName = name; this.sourceFile = DIR.resolve(name).resolve("module-info.java"); } public Builder modules(String... names) { Arrays.stream(names).forEach(modules::add); return this; } public Builder sourceFile(String... lines) throws IOException { Files.createDirectories(sourceFile.getParent()); try (BufferedWriter bw = Files.newBufferedWriter(sourceFile); PrintWriter writer = new PrintWriter(bw)) { writer.format("module %s {%n", moduleName); for (String l : lines) { writer.println(l); } writer.println("}"); } return this; } public GenModuleInfoSource build() throws IOException { return build(Collections.emptyList()); } public GenModuleInfoSource build(Path extraFile) throws IOException { return build(Collections.singletonList(extraFile)); } public GenModuleInfoSource build(List<Path> extraFiles) throws IOException { return new GenModuleInfoSource(sourceFile, extraFiles, modules); } } }