Home | History | Annotate | Download | only in features
      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 
     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 {
     40     void behave();
     41   }
     42 
     43   interface ExampleDerivedInterface extends ExampleBaseInterface {
     44     void misbehave();
     45   }
     46 
     47   enum ExampleBaseFeature implements Feature<ExampleBaseInterface> {
     48     BASE_FEATURE_1,
     49     BASE_FEATURE_2;
     50 
     51     @Override
     52     public Set<Feature<? super ExampleBaseInterface>> getImpliedFeatures() {
     53       return Collections.emptySet();
     54     }
     55 
     56     @Retention(RetentionPolicy.RUNTIME)
     57     @Inherited
     58     @TesterAnnotation
     59     @interface Require {
     60       ExampleBaseFeature[] value() default {};
     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 
     77     ExampleDerivedFeature(
     78         Feature<? super ExampleDerivedInterface> ... implied) {
     79       this.implied = ImmutableSet.copyOf(implied);
     80     }
     81 
     82     @Override
     83     public Set<Feature<? super ExampleDerivedInterface>> getImpliedFeatures() {
     84       return implied;
     85     }
     86 
     87     @Retention(RetentionPolicy.RUNTIME)
     88     @Inherited
     89     @TesterAnnotation
     90     @interface Require {
     91       ExampleDerivedFeature[] value() default {};
     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 {
    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})
    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})
    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})
    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 
    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 
    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 
    157   public void testAddImpliedFeatures_addsImpliedFeatures() throws Exception {
    158     Set<Feature<?>> features;
    159 
    160     features = Sets.<Feature<?>>newHashSet(
    161         ExampleDerivedFeature.DERIVED_FEATURE_1);
    162     assertThat(FeatureUtil.addImpliedFeatures(features)).has().item(
    163         ExampleDerivedFeature.DERIVED_FEATURE_1);
    164 
    165     features = Sets.<Feature<?>>newHashSet(
    166         ExampleDerivedFeature.DERIVED_FEATURE_2);
    167     assertThat(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     assertThat(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 
    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 
    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     assertThat(FeatureUtil.impliedFeatures(features)).has().item(
    197         ExampleBaseFeature.BASE_FEATURE_1);
    198 
    199     features = Sets.<Feature<?>>newHashSet(
    200         ExampleDerivedFeature.COMPOUND_DERIVED_FEATURE);
    201     assertThat(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 
    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 
    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 
    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       assertThat(e.getConflicts()).has().item(
    254           ExampleBaseFeature.BASE_FEATURE_1);
    255       assertEquals(ExampleDerivedInterfaceTester_Conflict.class, e.getSource());
    256     }
    257   }
    258 
    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       assertThat(e.getConflicts()).has().item(
    268           ExampleBaseFeature.BASE_FEATURE_1);
    269       assertEquals(method, e.getSource());
    270     }
    271   }
    272 
    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