• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2019 The Android Open Source Project
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 libcore.junit.util.compat;
18 
19 import android.compat.Compatibility;
20 import android.compat.Compatibility.ChangeConfig;
21 
22 import org.junit.rules.TestRule;
23 import org.junit.runner.Description;
24 import org.junit.runners.model.Statement;
25 
26 import java.lang.annotation.ElementType;
27 import java.lang.annotation.Retention;
28 import java.lang.annotation.RetentionPolicy;
29 import java.lang.annotation.Target;
30 import java.util.HashSet;
31 import java.util.Set;
32 import com.google.common.primitives.Longs;
33 
34 /**
35  * Allows tests to specify the which change to disable.
36  *
37  * <p>To use add the following to the test class. It will only change the behavior of a test method
38  * if it is annotated with {@link EnableCompatChanges} and/or {@link DisableCompatChanges}.
39  *
40  * <pre>
41  * &#64;Rule
42  * public TestRule compatChangeRule = new CoreCompatChangeRule();
43  * </pre>
44  *
45  * <p>Each test method that needs to disable a specific change needs to be annotated
46  * with {@link EnableCompatChanges} and/or {@link DisableCompatChanges} specifying the change id.
47  * e.g.:
48  *
49  * <pre>
50  *   &#64;Test
51  *   &#64;DisableCompatChanges({42})
52  *   public void testAsIfChange42Disabled() {
53  *     // check behavior
54  *   }
55  *
56  *   &#64;Test
57  *   &#64;EnableCompatChanges({42})
58  *   public void testAsIfChange42Enabled() {
59  *     // check behavior
60  *
61  * </pre>
62  */
63 public class CoreCompatChangeRule implements TestRule {
64 
65     @Override
apply(final Statement statement, Description description)66     public Statement apply(final Statement statement, Description description) {
67         Set<Long> enabled = new HashSet<>();
68         Set<Long> disabled = new HashSet<>();
69         EnableCompatChanges enableCompatChanges = description.getAnnotation(
70                 EnableCompatChanges.class);
71         DisableCompatChanges disableCompatChanges = description.getAnnotation(
72                 DisableCompatChanges.class);
73         if (enableCompatChanges != null) {
74             enabled.addAll(Longs.asList(enableCompatChanges.value()));
75         }
76         if (disableCompatChanges != null) {
77             disabled.addAll(Longs.asList(disableCompatChanges.value()));
78         }
79         ChangeConfig config = new ChangeConfig(enabled, disabled);
80         if (config.isEmpty()) {
81             return statement;
82         } else {
83             return createStatementForConfig(statement, config);
84         }
85     }
86 
createStatementForConfig(final Statement statement, ChangeConfig config)87     protected Statement createStatementForConfig(final Statement statement, ChangeConfig config) {
88             return new CompatChangeStatement(statement, config);
89     }
90 
91     private static class CompatChangeStatement extends Statement {
92         private final Statement testStatement;
93         private final ChangeConfig config;
94 
CompatChangeStatement(Statement testStatement, ChangeConfig config)95         private CompatChangeStatement(Statement testStatement, ChangeConfig config) {
96             this.testStatement = testStatement;
97             this.config = config;
98         }
99 
100         @Override
evaluate()101         public void evaluate() throws Throwable {
102             Compatibility.setOverrides(config);
103             try {
104                 testStatement.evaluate();
105             } finally {
106                 Compatibility.clearOverrides();
107             }
108         }
109     }
110 
111     @Retention(RetentionPolicy.RUNTIME)
112     @Target(ElementType.METHOD)
113     public @interface EnableCompatChanges {
value()114         long[] value();
115     }
116 
117     @Retention(RetentionPolicy.RUNTIME)
118     @Target(ElementType.METHOD)
119     public @interface DisableCompatChanges {
value()120         long[] value();
121     }
122 }
123