• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2015 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.common.truth.Truth.assertThat;
20 
21 import androidx.room.compiler.processing.XElement;
22 import androidx.room.compiler.processing.XProcessingEnv;
23 import androidx.room.compiler.processing.XProcessingStep;
24 import androidx.room.compiler.processing.XTypeElement;
25 import androidx.room.compiler.processing.util.Source;
26 import com.google.common.collect.ImmutableSet;
27 import dagger.internal.codegen.validation.ValidationReport;
28 import dagger.testing.compile.CompilerTests;
29 import java.util.Map;
30 import java.util.Set;
31 import org.junit.Test;
32 import org.junit.runner.RunWith;
33 import org.junit.runners.JUnit4;
34 
35 @RunWith(JUnit4.class)
36 public class ValidationReportTest {
37   private static final Source TEST_CLASS_FILE =
38       CompilerTests.javaSource(
39           "test.TestClass",
40           "package test;",
41           "",
42           "import javax.inject.Singleton;",
43           "",
44           "@Singleton",
45           "final class TestClass {}");
46 
47   @Test
basicReport()48   public void basicReport() {
49     CompilerTests.daggerCompiler(TEST_CLASS_FILE)
50         .withProcessingSteps(
51             () -> new SimpleTestStep() {
52               @Override
53               void test() {
54                 ValidationReport.about(getTypeElement("test.TestClass"))
55                     .addError("simple error")
56                     .build()
57                     .printMessagesTo(processingEnv.getMessager());
58               }
59             })
60         .compile(
61           subject -> {
62             subject.hasErrorCount(1);
63             subject.hasErrorContaining("simple error")
64                 .onSource(TEST_CLASS_FILE)
65                 .onLine(6);
66           });
67   }
68 
69   @Test
messageOnDifferentElement()70   public void messageOnDifferentElement() {
71     CompilerTests.daggerCompiler(TEST_CLASS_FILE)
72         .withProcessingSteps(
73             () -> new SimpleTestStep() {
74               @Override
75               void test() {
76                 ValidationReport.about(getTypeElement("test.TestClass"))
77                     .addError("simple error", getTypeElement(String.class))
78                     .build()
79                     .printMessagesTo(processingEnv.getMessager());
80               }
81             })
82         .compile(
83           subject -> {
84             subject.hasErrorCount(1);
85             // TODO(b/249298461): The String types should match between javac and ksp.
86             switch (CompilerTests.backend(subject)) {
87               case JAVAC:
88                 subject.hasErrorContaining("[java.lang.String] simple error")
89                     .onSource(TEST_CLASS_FILE)
90                     .onLine(6);
91                 break;
92               case KSP:
93                 subject.hasErrorContaining("[kotlin.String] simple error")
94                     .onSource(TEST_CLASS_FILE)
95                     .onLine(6);
96             }
97           });
98   }
99 
100   @Test
subreport()101   public void subreport() {
102     CompilerTests.daggerCompiler(TEST_CLASS_FILE)
103         .withProcessingSteps(
104             () -> new SimpleTestStep() {
105               @Override
106               void test() {
107                 ValidationReport parentReport =
108                     ValidationReport.about(getTypeElement(String.class))
109                         .addSubreport(
110                             ValidationReport.about(getTypeElement("test.TestClass"))
111                                 .addError("simple error")
112                                 .build())
113                         .build();
114                 assertThat(parentReport.isClean()).isFalse();
115                 parentReport.printMessagesTo(processingEnv.getMessager());
116               }
117             })
118         .compile(
119           subject -> {
120             subject.hasErrorCount(1);
121             subject.hasErrorContaining("simple error")
122                 .onSource(TEST_CLASS_FILE)
123                 .onLine(6);
124           });
125   }
126 
127   private abstract static class SimpleTestStep implements XProcessingStep {
128     protected XProcessingEnv processingEnv;
129 
130     @Override
annotations()131     public final ImmutableSet<String> annotations() {
132       // TODO(b/249322175): Replace this with "*" after this bug is fixed.
133       // For now, we just trigger off of annotations in the other sources in the test, but ideally
134       // this should support "*" similar to javac's Processor.
135       return ImmutableSet.of("javax.inject.Singleton");
136     }
137 
138     @Override
process( XProcessingEnv env, Map<String, ? extends Set<? extends XElement>> elementsByAnnotation)139     public ImmutableSet<XElement> process(
140         XProcessingEnv env, Map<String, ? extends Set<? extends XElement>> elementsByAnnotation) {
141       this.processingEnv = env;
142       test();
143       return ImmutableSet.of();
144     }
145 
146     @Override
processOver( XProcessingEnv env, Map<String, ? extends Set<? extends XElement>> elementsByAnnotation)147     public void processOver(
148         XProcessingEnv env, Map<String, ? extends Set<? extends XElement>> elementsByAnnotation) {}
149 
getTypeElement(Class<?> clazz)150     protected final XTypeElement getTypeElement(Class<?> clazz) {
151       return getTypeElement(clazz.getCanonicalName());
152     }
153 
getTypeElement(String canonicalName)154     protected final XTypeElement getTypeElement(String canonicalName) {
155       return processingEnv.requireTypeElement(canonicalName);
156     }
157 
test()158     abstract void test();
159   }
160 }
161