1/* 2 * Copyright (C) 2014 Google, Inc. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16package dagger.internal.codegen; 17 18import com.google.testing.compile.JavaFileObjects; 19import javax.tools.JavaFileObject; 20import org.junit.Test; 21import org.junit.runner.RunWith; 22import org.junit.runners.JUnit4; 23 24import static com.google.common.truth.Truth.assertAbout; 25import static com.google.testing.compile.JavaSourceSubjectFactory.javaSource; 26 27@RunWith(JUnit4.class) 28public class ProductionComponentProcessorTest { 29 @Test public void componentOnConcreteClass() { 30 JavaFileObject componentFile = JavaFileObjects.forSourceLines("test.NotAComponent", 31 "package test;", 32 "", 33 "import dagger.producers.ProductionComponent;", 34 "", 35 "@ProductionComponent", 36 "final class NotAComponent {}"); 37 assertAbout(javaSource()).that(componentFile) 38 .processedWith(new ComponentProcessor()) 39 .failsToCompile() 40 .withErrorContaining("interface"); 41 } 42 43 @Test public void componentOnEnum() { 44 JavaFileObject componentFile = JavaFileObjects.forSourceLines("test.NotAComponent", 45 "package test;", 46 "", 47 "import dagger.producers.ProductionComponent;", 48 "", 49 "@ProductionComponent", 50 "enum NotAComponent {", 51 " INSTANCE", 52 "}"); 53 assertAbout(javaSource()).that(componentFile) 54 .processedWith(new ComponentProcessor()) 55 .failsToCompile() 56 .withErrorContaining("interface"); 57 } 58 59 @Test public void componentOnAnnotation() { 60 JavaFileObject componentFile = JavaFileObjects.forSourceLines("test.NotAComponent", 61 "package test;", 62 "", 63 "import dagger.producers.ProductionComponent;", 64 "", 65 "@ProductionComponent", 66 "@interface NotAComponent {}"); 67 assertAbout(javaSource()).that(componentFile) 68 .processedWith(new ComponentProcessor()) 69 .failsToCompile() 70 .withErrorContaining("interface"); 71 } 72 73 @Test public void nonModuleModule() { 74 JavaFileObject componentFile = JavaFileObjects.forSourceLines("test.NotAComponent", 75 "package test;", 76 "", 77 "import dagger.producers.ProductionComponent;", 78 "", 79 "@ProductionComponent(modules = Object.class)", 80 "interface NotAComponent {}"); 81 assertAbout(javaSource()).that(componentFile) 82 .processedWith(new ComponentProcessor()) 83 .failsToCompile() 84 .withErrorContaining("is not annotated with @Module or @ProducerModule"); 85 } 86 87 @Test public void simpleComponent() { 88 JavaFileObject component = JavaFileObjects.forSourceLines("test.TestClass", 89 "package test;", 90 "", 91 "import com.google.common.util.concurrent.ListenableFuture;", 92 "import dagger.Module;", 93 "import dagger.Provides;", 94 "import dagger.producers.ProducerModule;", 95 "import dagger.producers.Produces;", 96 "import dagger.producers.ProductionComponent;", 97 "import javax.inject.Inject;", 98 "", 99 "final class TestClass {", 100 " static final class C {", 101 " @Inject C() {}", 102 " }", 103 "", 104 " interface A {}", 105 " interface B {}", 106 "", 107 " @Module", 108 " static final class BModule {", 109 " @Provides B b(C c) {", 110 " return null;", 111 " }", 112 " }", 113 "", 114 " @ProducerModule", 115 " static final class AModule {", 116 " @Produces ListenableFuture<A> a(B b) {", 117 " return null;", 118 " }", 119 " }", 120 "", 121 " @ProductionComponent(modules = {AModule.class, BModule.class})", 122 " interface SimpleComponent {", 123 " ListenableFuture<A> a();", 124 " }", 125 "}"); 126 JavaFileObject generatedComponent = 127 JavaFileObjects.forSourceLines( 128 "test.DaggerTestClass_SimpleComponent", 129 "package test;", 130 "", 131 "import com.google.common.util.concurrent.ListenableFuture;", 132 "import dagger.internal.InstanceFactory;", 133 "import dagger.internal.SetFactory;", 134 "import dagger.producers.Producer;", 135 "import dagger.producers.internal.Producers;", 136 "import dagger.producers.monitoring.ProductionComponentMonitor;", 137 "import dagger.producers.monitoring.ProductionComponentMonitor.Factory;", 138 "import java.util.Set;", 139 "import java.util.concurrent.Executor;", 140 "import javax.annotation.Generated;", 141 "import javax.inject.Provider;", 142 "import test.TestClass.A;", 143 "import test.TestClass.AModule;", 144 "import test.TestClass.B;", 145 "import test.TestClass.BModule;", 146 "import test.TestClass.SimpleComponent;", 147 "", 148 "@Generated(\"dagger.internal.codegen.ComponentProcessor\")", 149 "public final class DaggerTestClass_SimpleComponent implements SimpleComponent {", 150 " private Provider<SimpleComponent> simpleComponentProvider;", 151 " private Provider<Set<Factory>> setOfFactoryContribution1Provider;", 152 " private Provider<Set<Factory>> setOfFactoryProvider;", 153 " private Provider<ProductionComponentMonitor> monitorProvider;", 154 " private Provider<B> bProvider;", 155 " private Producer<A> aProducer;", 156 "", 157 " private DaggerTestClass_SimpleComponent(Builder builder) {", 158 " assert builder != null;", 159 " initialize(builder);", 160 " }", 161 "", 162 " public static Builder builder() {", 163 " return new Builder();", 164 " }", 165 "", 166 " @SuppressWarnings(\"unchecked\")", 167 " private void initialize(final Builder builder) {", 168 " this.simpleComponentProvider = InstanceFactory.<SimpleComponent>create(this);", 169 " this.setOfFactoryContribution1Provider =", 170 " TestClass$SimpleComponent_MonitoringModule_DefaultSetOfFactoriesFactory", 171 " .create();", 172 " this.setOfFactoryProvider = SetFactory.create(setOfFactoryContribution1Provider);", 173 " this.monitorProvider =", 174 " TestClass$SimpleComponent_MonitoringModule_MonitorFactory.create(", 175 " builder.testClass$SimpleComponent_MonitoringModule,", 176 " simpleComponentProvider,", 177 " setOfFactoryProvider);", 178 " this.bProvider = TestClass$BModule_BFactory.create(", 179 " builder.bModule, TestClass$C_Factory.create());", 180 " this.aProducer = new TestClass$AModule_AFactory(", 181 " builder.aModule,", 182 " builder.executor,", 183 " monitorProvider,", 184 " Producers.producerFromProvider(bProvider));", 185 " }", 186 "", 187 " @Override", 188 " public ListenableFuture<A> a() {", 189 " return aProducer.get();", 190 " }", 191 "", 192 " public static final class Builder {", 193 " private TestClass$SimpleComponent_MonitoringModule", 194 " testClass$SimpleComponent_MonitoringModule;", 195 " private BModule bModule;", 196 " private AModule aModule;", 197 " private Executor executor;", 198 "", 199 " private Builder() {", 200 " }", 201 "", 202 " public SimpleComponent build() {", 203 " if (testClass$SimpleComponent_MonitoringModule == null) {", 204 " this.testClass$SimpleComponent_MonitoringModule =", 205 " new TestClass$SimpleComponent_MonitoringModule();", 206 " }", 207 " if (bModule == null) {", 208 " this.bModule = new BModule();", 209 " }", 210 " if (aModule == null) {", 211 " this.aModule = new AModule();", 212 " }", 213 " if (executor == null) {", 214 " throw new IllegalStateException(Executor.class.getCanonicalName()", 215 " + \" must be set\");", 216 " }", 217 " return new DaggerTestClass_SimpleComponent(this);", 218 " }", 219 "", 220 " public Builder aModule(AModule aModule) {", 221 " if (aModule == null) {", 222 " throw new NullPointerException();", 223 " }", 224 " this.aModule = aModule;", 225 " return this;", 226 " }", 227 "", 228 " public Builder bModule(BModule bModule) {", 229 " if (bModule == null) {", 230 " throw new NullPointerException();", 231 " }", 232 " this.bModule = bModule;", 233 " return this;", 234 " }", 235 "", 236 " public Builder testClass$SimpleComponent_MonitoringModule(", 237 " TestClass$SimpleComponent_MonitoringModule", 238 " testClass$SimpleComponent_MonitoringModule) {", 239 " if (testClass$SimpleComponent_MonitoringModule == null) {", 240 " throw new NullPointerException();", 241 " }", 242 " this.testClass$SimpleComponent_MonitoringModule =", 243 " testClass$SimpleComponent_MonitoringModule;", 244 " return this;", 245 " }", 246 "", 247 " public Builder executor(Executor executor) {", 248 " if (executor == null) {", 249 " throw new NullPointerException();", 250 " }", 251 " this.executor = executor;", 252 " return this;", 253 " }", 254 " }", 255 "}"); 256 assertAbout(javaSource()).that(component) 257 .processedWith(new ComponentProcessor()) 258 .compilesWithoutError() 259 .and().generatesSources(generatedComponent); 260 } 261} 262