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