/* * Copyright (C) 2016 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 dagger.internal.codegen.DaggerModuleMethodSubject.Factory.assertThatMethodInUnannotatedClass; import static dagger.internal.codegen.DaggerModuleMethodSubject.Factory.assertThatModuleMethod; import com.google.common.collect.ImmutableList; import dagger.Module; import dagger.producers.ProducerModule; import java.lang.annotation.Annotation; import java.util.Collection; import javax.inject.Qualifier; 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 MultibindsValidationTest { @Parameters(name = "{0}") public static Collection parameters() { return ImmutableList.copyOf(new Object[][] {{Module.class}, {ProducerModule.class}}); } private final String moduleDeclaration; public MultibindsValidationTest(Class moduleAnnotation) { moduleDeclaration = "@" + moduleAnnotation.getCanonicalName() + " abstract class %s { %s }"; } @Test public void notWithinModule() { assertThatMethodInUnannotatedClass("@Multibinds abstract Set emptySet();") .hasError("@Multibinds methods can only be present within a @Module or @ProducerModule"); } @Test public void voidMethod() { assertThatModuleMethod("@Multibinds abstract void voidMethod();") .withDeclaration(moduleDeclaration) .hasError("@Multibinds methods must return Map or Set"); } @Test public void primitiveMethod() { assertThatModuleMethod("@Multibinds abstract int primitive();") .withDeclaration(moduleDeclaration) .hasError("@Multibinds methods must return Map or Set"); } @Test public void rawMap() { assertThatModuleMethod("@Multibinds abstract Map rawMap();") .withDeclaration(moduleDeclaration) .hasError("@Multibinds methods must return Map or Set"); } @Test public void wildcardMap() { assertThatModuleMethod("@Multibinds abstract Map wildcardMap();") .withDeclaration(moduleDeclaration) .hasError("@Multibinds methods must return Map or Set"); } @Test public void providerMap() { assertThatModuleMethod("@Multibinds abstract Map> providerMap();") .withDeclaration(moduleDeclaration) .hasError("@Multibinds methods must return Map or Set"); } @Test public void producerMap() { assertThatModuleMethod("@Multibinds abstract Map> producerMap();") .withDeclaration(moduleDeclaration) .hasError("@Multibinds methods must return Map or Set"); } @Test public void producedMap() { assertThatModuleMethod("@Multibinds abstract Map> producedMap();") .withDeclaration(moduleDeclaration) .hasError("@Multibinds methods must return Map or Set"); } @Test public void rawSet() { assertThatModuleMethod("@Multibinds abstract Set rawSet();") .withDeclaration(moduleDeclaration) .hasError("@Multibinds methods must return Map or Set"); } @Test public void wildcardSet() { assertThatModuleMethod("@Multibinds abstract Set wildcardSet();") .withDeclaration(moduleDeclaration) .hasError("@Multibinds methods must return Map or Set"); } @Test public void providerSet() { assertThatModuleMethod("@Multibinds abstract Set> providerSet();") .withDeclaration(moduleDeclaration) .hasError("@Multibinds methods must return Map or Set"); } @Test public void producerSet() { assertThatModuleMethod("@Multibinds abstract Set> producerSet();") .withDeclaration(moduleDeclaration) .hasError("@Multibinds methods must return Map or Set"); } @Test public void producedSet() { assertThatModuleMethod("@Multibinds abstract Set> producedSet();") .withDeclaration(moduleDeclaration) .hasError("@Multibinds methods must return Map or Set"); } @Test public void overqualifiedSet() { assertThatModuleMethod( "@Multibinds @SomeQualifier @OtherQualifier " + "abstract Set tooManyQualifiersSet();") .withDeclaration(moduleDeclaration) .importing(SomeQualifier.class, OtherQualifier.class) .hasError("may not use more than one @Qualifier"); } @Test public void overqualifiedMap() { assertThatModuleMethod( "@Multibinds @SomeQualifier @OtherQualifier " + "abstract Map tooManyQualifiersMap();") .withDeclaration(moduleDeclaration) .importing(SomeQualifier.class, OtherQualifier.class) .hasError("may not use more than one @Qualifier"); } @Test public void hasParameters() { assertThatModuleMethod("@Multibinds abstract Set parameters(Object param);") .hasError("@Multibinds methods cannot have parameters"); } @Qualifier public @interface SomeQualifier {} @Qualifier public @interface OtherQualifier {} }