1 /* 2 * Copyright (C) 2020 The Dagger Authors. 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 */ 16 17 package dagger.internal.codegen; 18 19 import static com.google.testing.compile.CompilationSubject.assertThat; 20 import static dagger.internal.codegen.CompilerMode.DEFAULT_MODE; 21 import static dagger.internal.codegen.CompilerMode.FAST_INIT_MODE; 22 import static dagger.internal.codegen.Compilers.compilerWithOptions; 23 24 import com.google.common.collect.ImmutableCollection; 25 import com.google.testing.compile.Compilation; 26 import com.google.testing.compile.JavaFileObjects; 27 import javax.tools.JavaFileObject; 28 import org.junit.Test; 29 import org.junit.runner.RunWith; 30 import org.junit.runners.Parameterized; 31 import org.junit.runners.Parameterized.Parameters; 32 33 @RunWith(Parameterized.class) 34 public class AssistedFactoryTest { 35 @Parameters(name = "{0}") parameters()36 public static ImmutableCollection<Object[]> parameters() { 37 return CompilerMode.TEST_PARAMETERS; 38 } 39 40 private final CompilerMode compilerMode; 41 AssistedFactoryTest(CompilerMode compilerMode)42 public AssistedFactoryTest(CompilerMode compilerMode) { 43 this.compilerMode = compilerMode; 44 } 45 46 @Test testAssistedFactory()47 public void testAssistedFactory() { 48 JavaFileObject foo = 49 JavaFileObjects.forSourceLines( 50 "test.Foo", 51 "package test;", 52 "", 53 "import dagger.assisted.Assisted;", 54 "import dagger.assisted.AssistedInject;", 55 "", 56 "class Foo {", 57 " @AssistedInject", 58 " Foo(@Assisted String str, Bar bar) {}", 59 "}"); 60 JavaFileObject fooFactory = 61 JavaFileObjects.forSourceLines( 62 "test.FooFactory", 63 "package test;", 64 "", 65 "import dagger.assisted.AssistedFactory;", 66 "", 67 "@AssistedFactory", 68 "interface FooFactory {", 69 " Foo create(String factoryStr);", 70 "}"); 71 JavaFileObject bar = 72 JavaFileObjects.forSourceLines( 73 "test.Bar", 74 "package test;", 75 "", 76 "import javax.inject.Inject;", 77 "", 78 "class Bar {", 79 " @Inject Bar() {}", 80 "}"); 81 JavaFileObject component = 82 JavaFileObjects.forSourceLines( 83 "test.TestComponent", 84 "package test;", 85 "", 86 "import dagger.Component;", 87 "", 88 "@Component", 89 "interface TestComponent {", 90 " FooFactory fooFactory();", 91 "}"); 92 Compilation compilation = 93 compilerWithOptions(compilerMode.javacopts()).compile(foo, bar, fooFactory, component); 94 assertThat(compilation).succeeded(); 95 JavaFileObject generatedComponent = 96 compilerMode 97 .javaFileBuilder("test.DaggerTestComponent") 98 .addLines("package test;", "", GeneratedLines.generatedAnnotations()) 99 .addLinesIn( 100 FAST_INIT_MODE, 101 "final class DaggerTestComponent implements TestComponent {", 102 "", 103 " private Foo foo(String str) {", 104 " return new Foo(str, new Bar());", 105 " }", 106 "", 107 " @Override", 108 " public FooFactory fooFactory() {", 109 " return new FooFactory() {", 110 " @Override", 111 " public Foo create(String str) {", 112 " return DaggerTestComponent.this.foo(str);", 113 " }", 114 " };", 115 " }", 116 "}") 117 .addLinesIn( 118 DEFAULT_MODE, 119 "final class DaggerTestComponent implements TestComponent {", 120 "", 121 " private Foo_Factory fooProvider;", 122 "", 123 " private Provider<FooFactory> fooFactoryProvider;", 124 "", 125 " @SuppressWarnings(\"unchecked\")", 126 " private void initialize() {", 127 " this.fooProvider = Foo_Factory.create(Bar_Factory.create());", 128 " this.fooFactoryProvider = FooFactory_Impl.create(fooProvider);", 129 " }", 130 "", 131 " @Override", 132 " public FooFactory fooFactory() {", 133 " return fooFactoryProvider.get();", 134 " }", 135 "}") 136 .build(); 137 assertThat(compilation) 138 .generatedSourceFile("test.DaggerTestComponent") 139 .containsElementsIn(generatedComponent); 140 } 141 142 @Test testAssistedFactoryCycle()143 public void testAssistedFactoryCycle() { 144 JavaFileObject foo = 145 JavaFileObjects.forSourceLines( 146 "test.Foo", 147 "package test;", 148 "", 149 "import dagger.assisted.Assisted;", 150 "import dagger.assisted.AssistedInject;", 151 "", 152 "class Foo {", 153 " @AssistedInject", 154 " Foo(@Assisted String str, Bar bar) {}", 155 "}"); 156 JavaFileObject fooFactory = 157 JavaFileObjects.forSourceLines( 158 "test.FooFactory", 159 "package test;", 160 "", 161 "import dagger.assisted.AssistedFactory;", 162 "", 163 "@AssistedFactory", 164 "interface FooFactory {", 165 " Foo create(String factoryStr);", 166 "}"); 167 JavaFileObject bar = 168 JavaFileObjects.forSourceLines( 169 "test.Bar", 170 "package test;", 171 "", 172 "import javax.inject.Inject;", 173 "", 174 "class Bar {", 175 " @Inject Bar(FooFactory fooFactory) {}", 176 "}"); 177 JavaFileObject component = 178 JavaFileObjects.forSourceLines( 179 "test.TestComponent", 180 "package test;", 181 "", 182 "import dagger.Component;", 183 "", 184 "@Component", 185 "interface TestComponent {", 186 " FooFactory fooFactory();", 187 "}"); 188 Compilation compilation = 189 compilerWithOptions(compilerMode.javacopts()).compile(foo, bar, fooFactory, component); 190 assertThat(compilation).succeeded(); 191 JavaFileObject generatedComponent = 192 compilerMode 193 .javaFileBuilder("test.DaggerTestComponent") 194 .addLines("package test;", "", GeneratedLines.generatedAnnotations()) 195 .addLinesIn( 196 FAST_INIT_MODE, 197 "final class DaggerTestComponent implements TestComponent {", 198 "", 199 " private Bar bar() {", 200 " return new Bar(fooFactory());", 201 " }", 202 "", 203 " private Foo foo(String str) {", 204 " return new Foo(str, bar());", 205 " }", 206 "", 207 " @Override", 208 " public FooFactory fooFactory() {", 209 " return new FooFactory() {", 210 " @Override", 211 " public Foo create(String str) {", 212 " return DaggerTestComponent.this.foo(str);", 213 " }", 214 " };", 215 " }", 216 "}") 217 .addLinesIn( 218 DEFAULT_MODE, 219 "final class DaggerTestComponent implements TestComponent {", 220 "", 221 " private Provider<FooFactory> fooFactoryProvider;", 222 "", 223 " private Provider<Bar> barProvider;", 224 "", 225 " private Foo_Factory fooProvider;", 226 "", 227 " @SuppressWarnings(\"unchecked\")", 228 " private void initialize() {", 229 " this.fooFactoryProvider = new DelegateFactory<>();", 230 " this.barProvider = Bar_Factory.create(fooFactoryProvider);", 231 " this.fooProvider = Foo_Factory.create(barProvider);", 232 " DelegateFactory.setDelegate(", 233 " fooFactoryProvider, FooFactory_Impl.create(fooProvider));", 234 " }", 235 "", 236 " @Override", 237 " public FooFactory fooFactory() {", 238 " return fooFactoryProvider.get();", 239 " }", 240 "}") 241 .build(); 242 assertThat(compilation) 243 .generatedSourceFile("test.DaggerTestComponent") 244 .containsElementsIn(generatedComponent); 245 } 246 } 247