unplugged-system/external/dagger2/javatests/dagger/internal/codegen/ComponentShardTest.java

323 lines
14 KiB
Java

/*
* Copyright (C) 2020 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 dagger.internal.codegen;
import static com.google.testing.compile.CompilationSubject.assertThat;
import static dagger.internal.codegen.CompilerMode.DEFAULT_MODE;
import static dagger.internal.codegen.CompilerMode.FAST_INIT_MODE;
import static dagger.internal.codegen.Compilers.compilerWithOptions;
import static java.util.stream.Collectors.joining;
import com.google.common.collect.ImmutableCollection;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.testing.compile.Compilation;
import com.google.testing.compile.Compiler;
import com.google.testing.compile.JavaFileObjects;
import java.util.Arrays;
import javax.tools.JavaFileObject;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;
@RunWith(Parameterized.class)
public class ComponentShardTest {
private static final int BINDINGS_PER_SHARD = 2;
@Parameters(name = "{0}")
public static ImmutableCollection<Object[]> parameters() {
return CompilerMode.TEST_PARAMETERS;
}
private final CompilerMode compilerMode;
public ComponentShardTest(CompilerMode compilerMode) {
this.compilerMode = compilerMode;
}
@Test
public void testNewShardCreated() {
// Add all bindings.
//
// 1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7
// ^--------/
//
ImmutableList.Builder<JavaFileObject> javaFileObjects = ImmutableList.builder();
javaFileObjects
// Shard 2: Bindings (1)
.add(createBinding("Binding1", "Binding2 binding2"))
// Shard 1: Bindings (2, 3, 4, 5). Contains more than 2 bindings due to cycle.
.add(createBinding("Binding2", "Binding3 binding3"))
.add(createBinding("Binding3", "Binding4 binding4"))
.add(createBinding("Binding4", "Binding5 binding5, Provider<Binding2> binding2Provider"))
.add(createBinding("Binding5", "Binding6 binding6"))
// Component shard: Bindings (6, 7)
.add(createBinding("Binding6", "Binding7 binding7"))
.add(createBinding("Binding7"));
// Add the component with entry points for each binding and its provider.
javaFileObjects.add(
JavaFileObjects.forSourceLines(
"dagger.internal.codegen.TestComponent",
"package dagger.internal.codegen;",
"",
"import dagger.Component;",
"import javax.inject.Provider;",
"import javax.inject.Singleton;",
"",
"@Singleton",
"@Component",
"interface TestComponent {",
" Binding1 binding1();",
" Binding2 binding2();",
" Binding3 binding3();",
" Binding4 binding4();",
" Binding5 binding5();",
" Binding6 binding6();",
" Binding7 binding7();",
" Provider<Binding1> providerBinding1();",
" Provider<Binding2> providerBinding2();",
" Provider<Binding3> providerBinding3();",
" Provider<Binding4> providerBinding4();",
" Provider<Binding5> providerBinding5();",
" Provider<Binding6> providerBinding6();",
" Provider<Binding7> providerBinding7();",
"}"));
Compilation compilation = compiler().compile(javaFileObjects.build());
assertThat(compilation).succeededWithoutWarnings();
assertThat(compilation)
.generatedSourceFile("dagger.internal.codegen.DaggerTestComponent")
.containsElementsIn(
compilerMode
.javaFileBuilder("dagger.internal.codegen.DaggerTestComponent")
.addLines(
"package dagger.internal.codegen;",
"",
GeneratedLines.generatedAnnotations(),
"final class DaggerTestComponent implements TestComponent {",
" private Shard1 shard1;",
" private Shard2 shard2;",
" private final DaggerTestComponent testComponent = this;",
" private Provider<Binding7> binding7Provider;",
" private Provider<Binding6> binding6Provider;",
"",
" private DaggerTestComponent() {",
" initialize();",
" shard1 = new Shard1();",
" shard2 = new Shard2();",
" }")
.addLinesIn(
DEFAULT_MODE,
" @SuppressWarnings(\"unchecked\")",
" private void initialize() {",
" this.binding7Provider =",
" DoubleCheck.provider(Binding7_Factory.create());",
" this.binding6Provider =",
" DoubleCheck.provider(Binding6_Factory.create(binding7Provider));",
" }")
.addLinesIn(
FAST_INIT_MODE,
" @SuppressWarnings(\"unchecked\")",
" private void initialize() {",
" this.binding7Provider = DoubleCheck.provider(",
" new SwitchingProvider<Binding7>(testComponent, 6));",
" this.binding6Provider = DoubleCheck.provider(",
" new SwitchingProvider<Binding6>(testComponent, 5));",
" }")
.addLines(
" @Override",
" public Binding1 binding1() {",
" return testComponent.shard2.binding1Provider.get();",
" }",
"",
" @Override",
" public Binding2 binding2() {",
" return testComponent.shard1.binding2Provider.get();",
" }",
"",
" @Override",
" public Binding3 binding3() {",
" return testComponent.shard1.binding3Provider.get();",
" }",
"",
" @Override",
" public Binding4 binding4() {",
" return testComponent.shard1.binding4Provider.get();",
" }",
"",
" @Override",
" public Binding5 binding5() {",
" return testComponent.shard1.binding5Provider.get();",
" }",
"",
" @Override",
" public Binding6 binding6() {",
" return binding6Provider.get();",
" }",
"",
" @Override",
" public Binding7 binding7() {",
" return binding7Provider.get();",
" }",
"",
" @Override",
" public Provider<Binding1> providerBinding1() {",
" return testComponent.shard2.binding1Provider;",
" }",
"",
" @Override",
" public Provider<Binding2> providerBinding2() {",
" return testComponent.shard1.binding2Provider;",
" }",
"",
" @Override",
" public Provider<Binding3> providerBinding3() {",
" return testComponent.shard1.binding3Provider;",
" }",
"",
" @Override",
" public Provider<Binding4> providerBinding4() {",
" return testComponent.shard1.binding4Provider;",
" }",
"",
" @Override",
" public Provider<Binding5> providerBinding5() {",
" return testComponent.shard1.binding5Provider;",
" }",
"",
" @Override",
" public Provider<Binding6> providerBinding6() {",
" return binding6Provider;",
" }",
"",
" @Override",
" public Provider<Binding7> providerBinding7() {",
" return binding7Provider;",
" }",
"",
" private final class Shard1 {",
" private Provider<Binding5> binding5Provider;",
" private Provider<Binding2> binding2Provider;",
" private Provider<Binding4> binding4Provider;",
" private Provider<Binding3> binding3Provider;")
.addLinesIn(
DEFAULT_MODE,
" @SuppressWarnings(\"unchecked\")",
" private void initialize() {",
" this.binding5Provider =",
" DoubleCheck.provider(",
" Binding5_Factory.create(testComponent.binding6Provider));",
" this.binding2Provider = new DelegateFactory<>();",
" this.binding4Provider =",
" DoubleCheck.provider(",
" Binding4_Factory.create(binding5Provider, binding2Provider));",
" this.binding3Provider =",
" DoubleCheck.provider(Binding3_Factory.create(binding4Provider));",
" DelegateFactory.setDelegate(",
" binding2Provider,",
" DoubleCheck.provider(Binding2_Factory.create(binding3Provider)));",
" }",
" }")
.addLinesIn(
FAST_INIT_MODE,
" @SuppressWarnings(\"unchecked\")",
" private void initialize() {",
" this.binding5Provider = DoubleCheck.provider(",
" new SwitchingProvider<Binding5>(testComponent, 4));",
" this.binding4Provider = DoubleCheck.provider(",
" new SwitchingProvider<Binding4>(testComponent, 3));",
" this.binding3Provider = DoubleCheck.provider(",
" new SwitchingProvider<Binding3>(testComponent, 2));",
" this.binding2Provider = DoubleCheck.provider(",
" new SwitchingProvider<Binding2>(testComponent, 1));",
" }",
" }")
.addLines(
" private final class Shard2 {",
" private Provider<Binding1> binding1Provider;")
.addLinesIn(
DEFAULT_MODE,
" @SuppressWarnings(\"unchecked\")",
" private void initialize() {",
" this.binding1Provider =",
" DoubleCheck.provider(",
" Binding1_Factory.create(",
" testComponent.shard1.binding2Provider));",
" }",
" }")
.addLinesIn(
FAST_INIT_MODE,
" @SuppressWarnings(\"unchecked\")",
" private void initialize() {",
" this.binding1Provider = DoubleCheck.provider(",
" new SwitchingProvider<Binding1>(testComponent, 0));",
" }",
" }",
"",
" private static final class SwitchingProvider<T> implements Provider<T> {",
" @SuppressWarnings(\"unchecked\")",
" @Override",
" public T get() {",
" switch (id) {",
" case 0: return (T) new Binding1(",
" testComponent.shard1.binding2Provider.get());",
" case 1: return (T) new Binding2(",
" testComponent.shard1.binding3Provider.get());",
" case 2: return (T) new Binding3(",
" testComponent.shard1.binding4Provider.get());",
" case 3: return (T) new Binding4(",
" testComponent.shard1.binding5Provider.get(),",
" testComponent.shard1.binding2Provider);",
" case 4: return (T) new Binding5(",
" testComponent.binding6Provider.get());",
" case 5: return (T) new Binding6(",
" testComponent.binding7Provider.get());",
" case 6: return (T) new Binding7();",
" default: throw new AssertionError(id);",
" }",
" }",
" }")
.build());
}
private static JavaFileObject createBinding(String bindingName, String... deps) {
return JavaFileObjects.forSourceLines(
"dagger.internal.codegen." + bindingName,
"package dagger.internal.codegen;",
"",
"import javax.inject.Inject;",
"import javax.inject.Provider;",
"import javax.inject.Singleton;",
"",
"@Singleton",
"final class " + bindingName + " {",
" @Inject",
" " + bindingName + "(" + Arrays.stream(deps).collect(joining(", ")) + ") {}",
"}");
}
private Compiler compiler() {
return compilerWithOptions(
ImmutableSet.<String>builder()
.add("-Adagger.keysPerComponentShard=" + BINDINGS_PER_SHARD)
.addAll(compilerMode.javacopts())
.build());
}
}