1 /* 2 * Copyright (C) 2008 The Guava 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 com.google.common.collect.testing.features; 18 19 import static com.google.common.truth.Truth.assertThat; 20 21 import com.google.common.collect.ImmutableSet; 22 import com.google.common.collect.Sets; 23 import java.lang.annotation.Inherited; 24 import java.lang.annotation.Retention; 25 import java.lang.annotation.RetentionPolicy; 26 import java.lang.reflect.Method; 27 import java.util.Collections; 28 import java.util.Set; 29 import junit.framework.TestCase; 30 31 /** @author George van den Driessche */ 32 // Enum values use constructors with generic varargs. 33 @SuppressWarnings("unchecked") 34 public class FeatureUtilTest extends TestCase { 35 interface ExampleBaseInterface { behave()36 void behave(); 37 } 38 39 interface ExampleDerivedInterface extends ExampleBaseInterface { misbehave()40 void misbehave(); 41 } 42 43 enum ExampleBaseFeature implements Feature<ExampleBaseInterface> { 44 BASE_FEATURE_1, 45 BASE_FEATURE_2; 46 47 @Override getImpliedFeatures()48 public Set<Feature<? super ExampleBaseInterface>> getImpliedFeatures() { 49 return Collections.emptySet(); 50 } 51 52 @Retention(RetentionPolicy.RUNTIME) 53 @Inherited 54 @TesterAnnotation 55 @interface Require { value()56 ExampleBaseFeature[] value() default {}; 57 absent()58 ExampleBaseFeature[] absent() default {}; 59 } 60 } 61 62 enum ExampleDerivedFeature implements Feature<ExampleDerivedInterface> { 63 DERIVED_FEATURE_1, 64 DERIVED_FEATURE_2(ExampleBaseFeature.BASE_FEATURE_1), 65 DERIVED_FEATURE_3, 66 67 COMPOUND_DERIVED_FEATURE( 68 DERIVED_FEATURE_1, DERIVED_FEATURE_2, ExampleBaseFeature.BASE_FEATURE_2); 69 70 private Set<Feature<? super ExampleDerivedInterface>> implied; 71 ExampleDerivedFeature(Feature<? super ExampleDerivedInterface>.... implied)72 ExampleDerivedFeature(Feature<? super ExampleDerivedInterface>... implied) { 73 this.implied = ImmutableSet.copyOf(implied); 74 } 75 76 @Override getImpliedFeatures()77 public Set<Feature<? super ExampleDerivedInterface>> getImpliedFeatures() { 78 return implied; 79 } 80 81 @Retention(RetentionPolicy.RUNTIME) 82 @Inherited 83 @TesterAnnotation 84 @interface Require { value()85 ExampleDerivedFeature[] value() default {}; 86 absent()87 ExampleDerivedFeature[] absent() default {}; 88 } 89 } 90 91 @Retention(RetentionPolicy.RUNTIME) 92 @interface NonTesterAnnotation {} 93 94 @ExampleBaseFeature.Require({ExampleBaseFeature.BASE_FEATURE_1}) 95 private abstract static class ExampleBaseInterfaceTester extends TestCase { doNotActuallyRunThis()96 protected final void doNotActuallyRunThis() { 97 fail("Nobody's meant to actually run this!"); 98 } 99 } 100 101 @AndroidIncompatible // Android attempts to run directly 102 @NonTesterAnnotation 103 @ExampleDerivedFeature.Require({ExampleDerivedFeature.DERIVED_FEATURE_2}) 104 private static class ExampleDerivedInterfaceTester extends ExampleBaseInterfaceTester { 105 // Exists to test that our framework doesn't run it: 106 @SuppressWarnings("unused") 107 @ExampleDerivedFeature.Require({ 108 ExampleDerivedFeature.DERIVED_FEATURE_1, 109 ExampleDerivedFeature.DERIVED_FEATURE_2 110 }) testRequiringTwoExplicitDerivedFeatures()111 public void testRequiringTwoExplicitDerivedFeatures() throws Exception { 112 doNotActuallyRunThis(); 113 } 114 115 // Exists to test that our framework doesn't run it: 116 @SuppressWarnings("unused") 117 @ExampleDerivedFeature.Require({ 118 ExampleDerivedFeature.DERIVED_FEATURE_1, 119 ExampleDerivedFeature.DERIVED_FEATURE_3 120 }) testRequiringAllThreeDerivedFeatures()121 public void testRequiringAllThreeDerivedFeatures() { 122 doNotActuallyRunThis(); 123 } 124 125 // Exists to test that our framework doesn't run it: 126 @SuppressWarnings("unused") 127 @ExampleBaseFeature.Require(absent = {ExampleBaseFeature.BASE_FEATURE_1}) testRequiringConflictingFeatures()128 public void testRequiringConflictingFeatures() throws Exception { 129 doNotActuallyRunThis(); 130 } 131 } 132 133 @ExampleDerivedFeature.Require(absent = {ExampleDerivedFeature.DERIVED_FEATURE_2}) 134 private static class ConflictingRequirementsExampleDerivedInterfaceTester 135 extends ExampleBaseInterfaceTester {} 136 testTestFeatureEnums()137 public void testTestFeatureEnums() throws Exception { 138 // Haha! Let's test our own test rig! 139 FeatureEnumTest.assertGoodFeatureEnum(FeatureUtilTest.ExampleBaseFeature.class); 140 FeatureEnumTest.assertGoodFeatureEnum(FeatureUtilTest.ExampleDerivedFeature.class); 141 } 142 testAddImpliedFeatures_returnsSameSetInstance()143 public void testAddImpliedFeatures_returnsSameSetInstance() throws Exception { 144 Set<Feature<?>> features = Sets.<Feature<?>>newHashSet(ExampleBaseFeature.BASE_FEATURE_1); 145 assertSame(features, FeatureUtil.addImpliedFeatures(features)); 146 } 147 testAddImpliedFeatures_addsImpliedFeatures()148 public void testAddImpliedFeatures_addsImpliedFeatures() throws Exception { 149 Set<Feature<?>> features; 150 151 features = Sets.<Feature<?>>newHashSet(ExampleDerivedFeature.DERIVED_FEATURE_1); 152 assertThat(FeatureUtil.addImpliedFeatures(features)) 153 .contains(ExampleDerivedFeature.DERIVED_FEATURE_1); 154 155 features = Sets.<Feature<?>>newHashSet(ExampleDerivedFeature.DERIVED_FEATURE_2); 156 assertThat(FeatureUtil.addImpliedFeatures(features)) 157 .containsExactly( 158 ExampleDerivedFeature.DERIVED_FEATURE_2, ExampleBaseFeature.BASE_FEATURE_1); 159 160 features = Sets.<Feature<?>>newHashSet(ExampleDerivedFeature.COMPOUND_DERIVED_FEATURE); 161 assertThat(FeatureUtil.addImpliedFeatures(features)) 162 .containsExactly( 163 ExampleDerivedFeature.COMPOUND_DERIVED_FEATURE, 164 ExampleDerivedFeature.DERIVED_FEATURE_1, 165 ExampleDerivedFeature.DERIVED_FEATURE_2, 166 ExampleBaseFeature.BASE_FEATURE_1, 167 ExampleBaseFeature.BASE_FEATURE_2); 168 } 169 testImpliedFeatures_returnsNewSetInstance()170 public void testImpliedFeatures_returnsNewSetInstance() throws Exception { 171 Set<Feature<?>> features = Sets.<Feature<?>>newHashSet(ExampleBaseFeature.BASE_FEATURE_1); 172 assertNotSame(features, FeatureUtil.impliedFeatures(features)); 173 } 174 testImpliedFeatures_returnsImpliedFeatures()175 public void testImpliedFeatures_returnsImpliedFeatures() throws Exception { 176 Set<Feature<?>> features; 177 178 features = Sets.<Feature<?>>newHashSet(ExampleDerivedFeature.DERIVED_FEATURE_1); 179 assertTrue(FeatureUtil.impliedFeatures(features).isEmpty()); 180 181 features = Sets.<Feature<?>>newHashSet(ExampleDerivedFeature.DERIVED_FEATURE_2); 182 assertThat(FeatureUtil.impliedFeatures(features)).contains(ExampleBaseFeature.BASE_FEATURE_1); 183 184 features = Sets.<Feature<?>>newHashSet(ExampleDerivedFeature.COMPOUND_DERIVED_FEATURE); 185 assertThat(FeatureUtil.impliedFeatures(features)) 186 .containsExactly( 187 ExampleDerivedFeature.DERIVED_FEATURE_1, 188 ExampleDerivedFeature.DERIVED_FEATURE_2, 189 ExampleBaseFeature.BASE_FEATURE_1, 190 ExampleBaseFeature.BASE_FEATURE_2); 191 } 192 193 @AndroidIncompatible // Android runs ExampleDerivedInterfaceTester directly if it exists testBuildTesterRequirements_class()194 public void testBuildTesterRequirements_class() throws Exception { 195 assertEquals( 196 FeatureUtil.buildTesterRequirements(ExampleBaseInterfaceTester.class), 197 new TesterRequirements( 198 Sets.<Feature<?>>newHashSet(ExampleBaseFeature.BASE_FEATURE_1), 199 Collections.<Feature<?>>emptySet())); 200 201 assertEquals( 202 FeatureUtil.buildTesterRequirements(ExampleDerivedInterfaceTester.class), 203 new TesterRequirements( 204 Sets.<Feature<?>>newHashSet( 205 ExampleBaseFeature.BASE_FEATURE_1, ExampleDerivedFeature.DERIVED_FEATURE_2), 206 Collections.<Feature<?>>emptySet())); 207 } 208 209 @AndroidIncompatible // Android runs ExampleDerivedInterfaceTester directly if it exists testBuildTesterRequirements_method()210 public void testBuildTesterRequirements_method() throws Exception { 211 assertEquals( 212 FeatureUtil.buildTesterRequirements( 213 ExampleDerivedInterfaceTester.class.getMethod( 214 "testRequiringTwoExplicitDerivedFeatures")), 215 new TesterRequirements( 216 Sets.<Feature<?>>newHashSet( 217 ExampleBaseFeature.BASE_FEATURE_1, 218 ExampleDerivedFeature.DERIVED_FEATURE_1, 219 ExampleDerivedFeature.DERIVED_FEATURE_2), 220 Collections.<Feature<?>>emptySet())); 221 assertEquals( 222 FeatureUtil.buildTesterRequirements( 223 ExampleDerivedInterfaceTester.class.getMethod("testRequiringAllThreeDerivedFeatures")), 224 new TesterRequirements( 225 Sets.<Feature<?>>newHashSet( 226 ExampleBaseFeature.BASE_FEATURE_1, 227 ExampleDerivedFeature.DERIVED_FEATURE_1, 228 ExampleDerivedFeature.DERIVED_FEATURE_2, 229 ExampleDerivedFeature.DERIVED_FEATURE_3), 230 Collections.<Feature<?>>emptySet())); 231 } 232 233 @AndroidIncompatible // Android runs ExampleDerivedInterfaceTester directly if it exists testBuildTesterRequirements_classClassConflict()234 public void testBuildTesterRequirements_classClassConflict() throws Exception { 235 try { 236 FeatureUtil.buildTesterRequirements( 237 ConflictingRequirementsExampleDerivedInterfaceTester.class); 238 fail("Expected ConflictingRequirementsException"); 239 } catch (ConflictingRequirementsException e) { 240 assertThat(e.getConflicts()).contains(ExampleBaseFeature.BASE_FEATURE_1); 241 assertEquals(ConflictingRequirementsExampleDerivedInterfaceTester.class, e.getSource()); 242 } 243 } 244 245 @AndroidIncompatible // Android runs ExampleDerivedInterfaceTester directly if it exists testBuildTesterRequirements_methodClassConflict()246 public void testBuildTesterRequirements_methodClassConflict() throws Exception { 247 final Method method = 248 ExampleDerivedInterfaceTester.class.getMethod("testRequiringConflictingFeatures"); 249 try { 250 FeatureUtil.buildTesterRequirements(method); 251 fail("Expected ConflictingRequirementsException"); 252 } catch (ConflictingRequirementsException e) { 253 assertThat(e.getConflicts()).contains(ExampleBaseFeature.BASE_FEATURE_1); 254 assertEquals(method, e.getSource()); 255 } 256 } 257 258 @AndroidIncompatible // Android runs ExampleDerivedInterfaceTester directly if it exists testBuildDeclaredTesterRequirements()259 public void testBuildDeclaredTesterRequirements() throws Exception { 260 assertEquals( 261 FeatureUtil.buildDeclaredTesterRequirements( 262 ExampleDerivedInterfaceTester.class.getMethod( 263 "testRequiringTwoExplicitDerivedFeatures")), 264 new TesterRequirements( 265 FeatureUtil.addImpliedFeatures( 266 Sets.<Feature<?>>newHashSet( 267 ExampleDerivedFeature.DERIVED_FEATURE_1, 268 ExampleDerivedFeature.DERIVED_FEATURE_2)), 269 Collections.<Feature<?>>emptySet())); 270 } 271 } 272