| /* |
| * Copyright (C) 2021 The Dagger Authors. |
| * |
| * 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 buildtests; |
| |
| import static com.google.common.truth.Truth.assertThat; |
| import static org.gradle.testkit.runner.TaskOutcome.SUCCESS; |
| |
| import java.io.File; |
| import java.io.IOException; |
| import org.gradle.testkit.runner.BuildResult; |
| import org.gradle.testkit.runner.GradleRunner; |
| import org.junit.Rule; |
| import org.junit.Test; |
| import org.junit.rules.TemporaryFolder; |
| import org.junit.runner.RunWith; |
| import org.junit.runners.JUnit4; |
| |
| // This is a regression test for https://github.com/google/dagger/issues/3136 |
| @RunWith(JUnit4.class) |
| public class TransitiveScopeTest { |
| @Rule public TemporaryFolder folder = new TemporaryFolder(); |
| |
| @Test |
| public void testTransitiveScope_WithImplementation() throws IOException { |
| BuildResult result = setupRunnerWith("implementation").buildAndFail(); |
| assertThat(result.getOutput()).contains("Task :app:compileJava FAILED"); |
| // TODO(bcorso): Give more context about what couldn't be resolved once we've fixed the issue |
| // described in https://github.com/google/dagger/issues/2208. |
| assertThat(result.getOutput()) |
| .contains( |
| "error: dagger.internal.codegen.ComponentProcessor was unable to process " |
| + "'app.MyComponent' because not all of its dependencies could be resolved."); |
| } |
| |
| @Test |
| public void testTransitiveScope_WithApi() throws IOException { |
| BuildResult result = setupRunnerWith("api").build(); |
| assertThat(result.task(":app:assemble").getOutcome()).isEqualTo(SUCCESS); |
| assertThat(result.getOutput()).contains("@Inject library1.Foo(): SCOPED"); |
| } |
| |
| private GradleRunner setupRunnerWith(String dependencyType) throws IOException { |
| File projectDir = folder.getRoot(); |
| GradleModule.create(projectDir) |
| .addSettingsFile( |
| "include 'app'", |
| "include 'library1'", |
| "include 'library2'", |
| "include 'spi-plugin'") |
| .addBuildFile( |
| "buildscript {", |
| " ext {", |
| String.format("dagger_version = \"%s\"", System.getProperty("dagger_version")), |
| " }", |
| "}", |
| "", |
| "allprojects {", |
| " repositories {", |
| " mavenCentral()", |
| " mavenLocal()", |
| " }", |
| "}"); |
| |
| GradleModule.create(projectDir, "app") |
| .addBuildFile( |
| "plugins {", |
| " id 'java'", |
| " id 'application'", |
| "}", |
| "dependencies {", |
| " implementation project(':library1')", |
| " annotationProcessor project(':spi-plugin')", |
| " implementation \"com.google.dagger:dagger:$dagger_version\"", |
| " annotationProcessor \"com.google.dagger:dagger-compiler:$dagger_version\"", |
| "}") |
| .addSrcFile( |
| "MyComponent.java", |
| "package app;", |
| "", |
| "import dagger.Component;", |
| "import library1.MySubcomponent;", |
| "", |
| "@Component", |
| "public interface MyComponent {", |
| " MySubcomponent subcomponent();", |
| "}"); |
| |
| GradleModule.create(projectDir, "library1") |
| .addBuildFile( |
| "plugins {", |
| " id 'java'", |
| " id 'java-library'", |
| "}", |
| "dependencies {", |
| dependencyType + " project(':library2')", |
| " implementation \"com.google.dagger:dagger:$dagger_version\"", |
| " annotationProcessor \"com.google.dagger:dagger-compiler:$dagger_version\"", |
| "}") |
| .addSrcFile( |
| "Foo.java", |
| "package library1;", |
| "", |
| "import javax.inject.Inject;", |
| "import library2.MyScope;", |
| "", |
| "@MyScope", |
| "public class Foo {", |
| " @Inject Foo() {}", |
| "}") |
| // Note: In order to repro the issue we place MyScope on a subcomponent so that it can be a |
| // transitive dependency of the component. If MyScope was placed on directly on the |
| // component, it would need to be a direct dependency of the component. |
| .addSrcFile( |
| "MySubcomponent.java", |
| "package library1;", |
| "", |
| "import dagger.Subcomponent;", |
| "import library2.MyScope;", |
| "", |
| "@MyScope", |
| "@Subcomponent", |
| "public interface MySubcomponent {", |
| " Foo foo();", |
| "}"); |
| |
| GradleModule.create(projectDir, "library2") |
| .addBuildFile( |
| "plugins {", |
| " id 'java'", |
| " id 'java-library'", |
| "}", |
| "dependencies {", |
| " implementation 'javax.inject:javax.inject:1'", |
| "}") |
| .addSrcFile( |
| "MyScope.java", |
| "package library2;", |
| "", |
| "import javax.inject.Scope;", |
| "", |
| "@Scope", |
| "public @interface MyScope {}"); |
| |
| // This plugin is used to print output about bindings that we can assert on in tests. |
| GradleModule.create(projectDir, "spi-plugin") |
| .addBuildFile( |
| "plugins {", |
| " id 'java'", |
| "}", |
| "dependencies {", |
| " implementation \"com.google.dagger:dagger-spi:$dagger_version\"", |
| " implementation 'com.google.auto.service:auto-service-annotations:1.0.1'", |
| " annotationProcessor 'com.google.auto.service:auto-service:1.0.1'", |
| "}") |
| .addSrcFile( |
| "TestBindingGraphPlugin.java", |
| "package spiplugin;", |
| "", |
| "import com.google.auto.service.AutoService;", |
| "import dagger.model.BindingGraph;", |
| "import dagger.spi.BindingGraphPlugin;", |
| "import dagger.spi.DiagnosticReporter;", |
| "", |
| "@AutoService(BindingGraphPlugin.class)", |
| "public class TestBindingGraphPlugin implements BindingGraphPlugin {", |
| " @Override", |
| " public void visitGraph(BindingGraph bindingGraph, DiagnosticReporter" |
| + " diagnosticReporter) {", |
| " bindingGraph.bindings().stream()", |
| " .filter(binding -> binding.scope().isPresent())", |
| " .forEach(binding -> System.out.println(binding + \": SCOPED\"));", |
| " bindingGraph.bindings().stream()", |
| " .filter(binding -> !binding.scope().isPresent())", |
| " .forEach(binding -> System.out.println(binding + \": UNSCOPED\"));", |
| " }", |
| "}"); |
| |
| return GradleRunner.create() |
| .withArguments("--stacktrace", "build") |
| .withProjectDir(projectDir); |
| } |
| } |