• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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