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