/* * Copyright (C) 2016 Google, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.google.testing.compile; import static com.google.common.truth.Truth.assertThat; import static com.google.testing.compile.CompilationSubject.assertThat; import static com.google.testing.compile.Compiler.javac; import static java.nio.charset.StandardCharsets.UTF_8; import static org.junit.Assume.assumeTrue; import com.google.common.collect.ImmutableList; import java.io.File; import java.io.IOException; import java.net.URL; import java.net.URLClassLoader; import java.util.Arrays; import java.util.Locale; import javax.annotation.processing.Processor; import javax.lang.model.SourceVersion; import javax.tools.JavaCompiler; import javax.tools.JavaCompiler.CompilationTask; import javax.tools.JavaFileObject; import javax.tools.StandardJavaFileManager; import javax.tools.StandardLocation; import javax.tools.ToolProvider; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TemporaryFolder; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; /** Tests for {@link Compiler}. */ @RunWith(JUnit4.class) public final class CompilerTest { @Rule public final TemporaryFolder temporaryFolder = new TemporaryFolder(); private static final JavaFileObject HELLO_WORLD = JavaFileObjects.forResource("HelloWorld.java"); @Test public void options() { NoOpProcessor processor = new NoOpProcessor(); Object[] options1 = {"-Agone=nowhere"}; JavaFileObject[] files = {HELLO_WORLD}; Compilation unused = javac() .withOptions(options1) .withOptions(ImmutableList.of("-Ab=2", "-Ac=3")) .withProcessors(processor) .compile(files); assertThat(processor.options) .containsExactly( "b", "2", "c", "3") .inOrder(); } @Test public void multipleProcesors() { NoOpProcessor noopProcessor1 = new NoOpProcessor(); NoOpProcessor noopProcessor2 = new NoOpProcessor(); NoOpProcessor noopProcessor3 = new NoOpProcessor(); assertThat(noopProcessor1.invoked).isFalse(); assertThat(noopProcessor2.invoked).isFalse(); assertThat(noopProcessor3.invoked).isFalse(); Processor[] processors = {noopProcessor1, noopProcessor3}; JavaFileObject[] files = {HELLO_WORLD}; Compilation unused = javac() .withProcessors(processors) .withProcessors(noopProcessor1, noopProcessor2) .compile(files); assertThat(noopProcessor1.invoked).isTrue(); assertThat(noopProcessor2.invoked).isTrue(); assertThat(noopProcessor3.invoked).isFalse(); } @Test public void multipleProcesors_asIterable() { NoOpProcessor noopProcessor1 = new NoOpProcessor(); NoOpProcessor noopProcessor2 = new NoOpProcessor(); NoOpProcessor noopProcessor3 = new NoOpProcessor(); assertThat(noopProcessor1.invoked).isFalse(); assertThat(noopProcessor2.invoked).isFalse(); assertThat(noopProcessor3.invoked).isFalse(); JavaFileObject[] files = {HELLO_WORLD}; Compilation unused = javac() .withProcessors(Arrays.asList(noopProcessor1, noopProcessor3)) .withProcessors(Arrays.asList(noopProcessor1, noopProcessor2)) .compile(files); assertThat(noopProcessor1.invoked).isTrue(); assertThat(noopProcessor2.invoked).isTrue(); assertThat(noopProcessor3.invoked).isFalse(); } @Test public void classPath_default() { Compilation compilation = javac() .compile( JavaFileObjects.forSourceLines( "Test", "import com.google.testing.compile.CompilerTest;", "class Test {", " CompilerTest t;", "}")); assertThat(compilation).succeeded(); } @Test public void classPath_empty() { Compilation compilation = javac() .withClasspath(ImmutableList.of()) .compile( JavaFileObjects.forSourceLines( "Test", "import com.google.testing.compile.CompilerTest;", "class Test {", " CompilerTest t;", "}")); assertThat(compilation).hadErrorContaining("com.google.testing.compile does not exist"); } /** Sets up a jar containing a single class 'Lib', for use in classpath tests. */ private File compileTestLib() throws IOException { File lib = temporaryFolder.newFolder("tmp"); JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); StandardJavaFileManager fileManager = compiler.getStandardFileManager(/* diagnosticListener= */ null, Locale.getDefault(), UTF_8); fileManager.setLocation(StandardLocation.CLASS_OUTPUT, ImmutableList.of(lib)); CompilationTask task = compiler.getTask( /* out= */ null, fileManager, /* diagnosticListener= */ null, /* options= */ ImmutableList.of(), /* classes= */ null, ImmutableList.of(JavaFileObjects.forSourceLines("Lib", "class Lib {}"))); assertThat(task.call()).isTrue(); return lib; } @Test public void classPath_customFiles() throws Exception { File lib = compileTestLib(); // compile with only 'Lib' on the classpath Compilation compilation = javac() .withClasspath(ImmutableList.of(lib)) .withOptions("-verbose") .compile( JavaFileObjects.forSourceLines( "Test", // "class Test {", " Lib lib;", "}")); assertThat(compilation).succeeded(); } @Test public void classPath_empty_urlClassLoader() { Compilation compilation = javac() .withClasspathFrom(new URLClassLoader(new URL[0], Compiler.platformClassLoader)) .compile( JavaFileObjects.forSourceLines( "Test", "import com.google.testing.compile.CompilerTest;", "class Test {", " CompilerTest t;", "}")); assertThat(compilation).hadErrorContaining("com.google.testing.compile does not exist"); } @Test public void classPath_customFiles_urlClassLoader() throws Exception { File lib = compileTestLib(); Compilation compilation = javac() .withClasspathFrom(new URLClassLoader(new URL[] {lib.toURI().toURL()})) .withOptions("-verbose") .compile(JavaFileObjects.forSourceLines("Test", "class Test {", " Lib lib;", "}")); assertThat(compilation).succeeded(); } @Test public void releaseFlag() { assumeTrue(isJdk9OrLater()); Compilation compilation = javac() .withOptions("--release", "8") .compile(JavaFileObjects.forSourceString("HelloWorld", "final class HelloWorld {}")); assertThat(compilation).succeeded(); } static boolean isJdk9OrLater() { return SourceVersion.latestSupported().compareTo(SourceVersion.RELEASE_8) > 0; } }