1 /* 2 * Copyright 2008 Google LLC 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 package com.google.auto.service.processor; 17 18 import static com.google.auto.service.processor.AutoServiceProcessor.MISSING_SERVICES_ERROR; 19 import static com.google.common.truth.Truth.assertThat; 20 import static com.google.testing.compile.CompilationSubject.assertThat; 21 22 import com.google.common.io.Resources; 23 import com.google.testing.compile.Compilation; 24 import com.google.testing.compile.Compiler; 25 import com.google.testing.compile.JavaFileObjects; 26 import javax.tools.JavaFileObject; 27 import javax.tools.StandardLocation; 28 import org.junit.Test; 29 import org.junit.runner.RunWith; 30 import org.junit.runners.JUnit4; 31 32 /** Tests the {@link AutoServiceProcessor}. */ 33 @RunWith(JUnit4.class) 34 public class AutoServiceProcessorTest { 35 private final Compiler compiler = Compiler.javac().withProcessors(new AutoServiceProcessor()); 36 37 @Test autoService()38 public void autoService() { 39 Compilation compilation = 40 compiler.compile( 41 JavaFileObjects.forResource("test/SomeService.java"), 42 JavaFileObjects.forResource("test/SomeServiceProvider1.java"), 43 JavaFileObjects.forResource("test/SomeServiceProvider2.java"), 44 JavaFileObjects.forResource("test/Enclosing.java"), 45 JavaFileObjects.forResource("test/AnotherService.java"), 46 JavaFileObjects.forResource("test/AnotherServiceProvider.java")); 47 assertThat(compilation).succeededWithoutWarnings(); 48 assertThat(compilation) 49 .generatedFile(StandardLocation.CLASS_OUTPUT, "META-INF/services/test.SomeService") 50 .hasContents( 51 Resources.asByteSource(Resources.getResource("META-INF/services/test.SomeService"))); 52 assertThat(compilation) 53 .generatedFile(StandardLocation.CLASS_OUTPUT, "META-INF/services/test.AnotherService") 54 .hasContents( 55 Resources.asByteSource(Resources.getResource("META-INF/services/test.AnotherService"))); 56 } 57 58 @Test multiService()59 public void multiService() { 60 Compilation compilation = 61 compiler.compile( 62 JavaFileObjects.forResource("test/SomeService.java"), 63 JavaFileObjects.forResource("test/AnotherService.java"), 64 JavaFileObjects.forResource("test/MultiServiceProvider.java")); 65 assertThat(compilation).succeededWithoutWarnings(); 66 // We have @AutoService({SomeService.class, AnotherService.class}) class MultiServiceProvider. 67 // So we expect META-INF/services/test.SomeService with contents that name MultiServiceProvider 68 // and likewise META-INF/services/test.AnotherService. 69 assertThat(compilation) 70 .generatedFile(StandardLocation.CLASS_OUTPUT, "META-INF/services/test.SomeService") 71 .contentsAsUtf8String() 72 .isEqualTo("test.MultiServiceProvider\n"); 73 assertThat(compilation) 74 .generatedFile(StandardLocation.CLASS_OUTPUT, "META-INF/services/test.AnotherService") 75 .contentsAsUtf8String() 76 .isEqualTo("test.MultiServiceProvider\n"); 77 } 78 79 @Test badMultiService()80 public void badMultiService() { 81 Compilation compilation = compiler.compile(JavaFileObjects.forResource("test/NoServices.java")); 82 assertThat(compilation).failed(); 83 assertThat(compilation).hadErrorContaining(MISSING_SERVICES_ERROR); 84 } 85 86 @Test doesNotImplement_failsByDefault()87 public void doesNotImplement_failsByDefault() { 88 Compilation compilation = 89 compiler.compile(JavaFileObjects.forResource("test/DoesNotImplement.java")); 90 assertThat(compilation).failed(); 91 assertThat(compilation) 92 .hadErrorContaining("test.DoesNotImplement does not implement test.SomeService"); 93 } 94 95 @Test doesNotImplement_succeedsWithVerifyFalse()96 public void doesNotImplement_succeedsWithVerifyFalse() { 97 Compilation compilation = 98 compiler 99 .withOptions("-Averify=false") 100 .compile( 101 JavaFileObjects.forResource("test/DoesNotImplement.java"), 102 JavaFileObjects.forResource("test/SomeService.java")); 103 assertThat(compilation).succeededWithoutWarnings(); 104 assertThat(compilation) 105 .generatedFile(StandardLocation.CLASS_OUTPUT, "META-INF/services/test.SomeService") 106 .contentsAsUtf8String() 107 .isEqualTo("test.DoesNotImplement\n"); 108 } 109 110 @Test doesNotImplement_suppressed()111 public void doesNotImplement_suppressed() { 112 Compilation compilation = 113 compiler.compile( 114 JavaFileObjects.forResource("test/DoesNotImplementSuppressed.java"), 115 JavaFileObjects.forResource("test/SomeService.java")); 116 assertThat(compilation).succeededWithoutWarnings(); 117 assertThat(compilation) 118 .generatedFile(StandardLocation.CLASS_OUTPUT, "META-INF/services/test.SomeService") 119 .contentsAsUtf8String() 120 .isEqualTo("test.DoesNotImplementSuppressed\n"); 121 } 122 123 @Test generic()124 public void generic() { 125 Compilation compilation = 126 compiler 127 .withOptions("-Averify=false") 128 .compile( 129 JavaFileObjects.forResource("test/GenericService.java"), 130 JavaFileObjects.forResource("test/GenericServiceProvider.java")); 131 assertThat(compilation).succeededWithoutWarnings(); 132 assertThat(compilation) 133 .generatedFile(StandardLocation.CLASS_OUTPUT, "META-INF/services/test.GenericService") 134 .contentsAsUtf8String() 135 .isEqualTo("test.GenericServiceProvider\n"); 136 } 137 138 @Test genericWithNoVerifyOption()139 public void genericWithNoVerifyOption() { 140 Compilation compilation = 141 compiler.compile( 142 JavaFileObjects.forResource("test/GenericService.java"), 143 JavaFileObjects.forResource("test/GenericServiceProvider.java")); 144 assertThat(compilation).succeeded(); 145 assertThat(compilation) 146 .hadWarningContaining( 147 "Service provider test.GenericService is generic, so it can't be named exactly by" 148 + " @AutoService. If this is OK, add @SuppressWarnings(\"rawtypes\")."); 149 } 150 151 @Test genericWithExplicitVerify()152 public void genericWithExplicitVerify() { 153 Compilation compilation = 154 compiler 155 .withOptions("-Averify=true") 156 .compile( 157 JavaFileObjects.forResource("test/GenericService.java"), 158 JavaFileObjects.forResource("test/GenericServiceProvider.java")); 159 assertThat(compilation).succeeded(); 160 assertThat(compilation) 161 .hadWarningContaining( 162 "Service provider test.GenericService is generic, so it can't be named exactly by" 163 + " @AutoService. If this is OK, add @SuppressWarnings(\"rawtypes\")."); 164 } 165 166 @Test genericWithVerifyOptionAndSuppressWarings()167 public void genericWithVerifyOptionAndSuppressWarings() { 168 Compilation compilation = 169 compiler 170 .withOptions("-Averify=true") 171 .compile( 172 JavaFileObjects.forResource("test/GenericService.java"), 173 JavaFileObjects.forResource("test/GenericServiceProviderSuppressWarnings.java")); 174 assertThat(compilation).succeededWithoutWarnings(); 175 } 176 177 @Test nestedGenericWithVerifyOptionAndSuppressWarnings()178 public void nestedGenericWithVerifyOptionAndSuppressWarnings() { 179 Compilation compilation = 180 compiler 181 .withOptions("-Averify=true") 182 .compile( 183 JavaFileObjects.forResource("test/GenericService.java"), 184 JavaFileObjects.forResource("test/EnclosingGeneric.java")); 185 assertThat(compilation).succeededWithoutWarnings(); 186 assertThat(compilation) 187 .generatedFile(StandardLocation.CLASS_OUTPUT, "META-INF/services/test.GenericService") 188 .contentsAsUtf8String() 189 .isEqualTo("test.EnclosingGeneric$GenericServiceProvider\n"); 190 } 191 192 @Test missing()193 public void missing() { 194 AutoServiceProcessor processor = new AutoServiceProcessor(); 195 Compilation compilation = 196 compiler 197 .withOptions("-Averify=true") 198 .compile( 199 JavaFileObjects.forResource( 200 "test/GenericServiceProviderWithMissingServiceClass.java")); 201 assertThat(compilation).failed(); 202 assertThat(processor.exceptionStacks()).isEmpty(); 203 } 204 205 @Test autoServiceOnInterface()206 public void autoServiceOnInterface() { 207 AutoServiceProcessor processor = new AutoServiceProcessor(); 208 JavaFileObject autoServiceOnInterface = 209 JavaFileObjects.forResource("test/AutoServiceOnInterface.java"); 210 Compilation compilation = 211 Compiler.javac() 212 .withProcessors(processor) 213 .withOptions("-Averify=true") 214 .compile(autoServiceOnInterface); 215 assertThat(compilation) 216 .hadErrorContaining("@AutoService cannot be applied to an abstract class or an interface") 217 .inFile(autoServiceOnInterface) 218 .onLineContaining("@AutoService"); 219 assertThat(processor.exceptionStacks()).isEmpty(); 220 } 221 222 @Test autoServiceOnAbstractClass()223 public void autoServiceOnAbstractClass() { 224 AutoServiceProcessor processor = new AutoServiceProcessor(); 225 JavaFileObject autoServiceOnAbstractClass = 226 JavaFileObjects.forResource("test/AutoServiceOnAbstractClass.java"); 227 Compilation compilation = 228 Compiler.javac() 229 .withProcessors(processor) 230 .withOptions("-Averify=true") 231 .compile(autoServiceOnAbstractClass); 232 assertThat(compilation) 233 .hadErrorContaining("@AutoService cannot be applied to an abstract class or an interface") 234 .inFile(autoServiceOnAbstractClass) 235 .onLineContaining("@AutoService"); 236 assertThat(processor.exceptionStacks()).isEmpty(); 237 } 238 } 239