1 // Copyright 2022 The Chromium Authors 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 package org.chromium.base.test.util; 6 7 import static org.hamcrest.Matchers.equalTo; 8 import static org.hamcrest.Matchers.isIn; 9 10 import org.junit.Assert; 11 import org.junit.Rule; 12 import org.junit.Test; 13 import org.junit.runner.Description; 14 import org.junit.runner.RunWith; 15 import org.junit.runners.BlockJUnit4ClassRunner; 16 import org.junit.runners.model.FrameworkMethod; 17 import org.junit.runners.model.InitializationError; 18 import org.robolectric.annotation.Config; 19 20 import org.chromium.base.test.BaseRobolectricTestRunner; 21 22 /** Unit tests for {@link AndroidSdkLevelSkipCheck} */ 23 @RunWith(BaseRobolectricTestRunner.class) 24 @Config(manifest = Config.NONE, sdk = 29) 25 public class AndroidSdkLevelSkipCheckTest { 26 public static class UnannotatedBaseClass { 27 @Test 28 @MinAndroidSdkLevel(28) min28Method()29 public void min28Method() {} 30 31 @Test 32 @MinAndroidSdkLevel(29) min29Method()33 public void min29Method() {} 34 35 @Test 36 @MinAndroidSdkLevel(30) min30Method()37 public void min30Method() {} 38 39 @Test 40 @MaxAndroidSdkLevel(28) max28Method()41 public void max28Method() {} 42 43 @Test 44 @MaxAndroidSdkLevel(29) max29Method()45 public void max29Method() {} 46 47 @Test 48 @MaxAndroidSdkLevel(30) max30Method()49 public void max30Method() {} 50 51 @Test 52 @MinAndroidSdkLevel(28) 53 @MaxAndroidSdkLevel(30) min28max30Method()54 public void min28max30Method() {} 55 56 @Test 57 @MinAndroidSdkLevel(30) 58 @MaxAndroidSdkLevel(28) min30max28Method()59 public void min30max28Method() {} 60 } 61 62 @MinAndroidSdkLevel(28) 63 public static class Min28Class extends UnannotatedBaseClass { 64 @Test unannotatedMethod()65 public void unannotatedMethod() {} 66 } 67 68 @MinAndroidSdkLevel(30) 69 public static class Min30Class extends UnannotatedBaseClass { 70 @Test unannotatedMethod()71 public void unannotatedMethod() {} 72 } 73 74 public static class ExtendsMin28Class extends Min28Class { 75 @Override 76 @Test unannotatedMethod()77 public void unannotatedMethod() {} 78 } 79 80 public static class ExtendsMin30Class extends Min30Class { 81 @Override 82 @Test unannotatedMethod()83 public void unannotatedMethod() {} 84 } 85 86 private static final AndroidSdkLevelSkipCheck sSkipCheck = new AndroidSdkLevelSkipCheck(); 87 88 private static class InnerTestRunner extends BlockJUnit4ClassRunner { InnerTestRunner(Class<?> klass)89 public InnerTestRunner(Class<?> klass) throws InitializationError { 90 super(klass); 91 } 92 93 @Override isIgnored(FrameworkMethod method)94 protected boolean isIgnored(FrameworkMethod method) { 95 return super.isIgnored(method) || sSkipCheck.shouldSkip(method); 96 } 97 } 98 99 @Rule 100 public TestRunnerTestRule mTestRunnerTestRule = new TestRunnerTestRule(InnerTestRunner.class); 101 expectShouldSkip(Class<?> testClass, String methodName, boolean shouldSkip)102 private void expectShouldSkip(Class<?> testClass, String methodName, boolean shouldSkip) 103 throws Exception { 104 Assert.assertThat( 105 sSkipCheck.shouldSkip(new FrameworkMethod(testClass.getMethod(methodName))), 106 equalTo(shouldSkip)); 107 TestRunnerTestRule.TestLog runListener = mTestRunnerTestRule.runTest(testClass); 108 Assert.assertThat( 109 Description.createTestDescription(testClass, methodName), 110 isIn(shouldSkip ? runListener.skippedTests : runListener.runTests)); 111 } 112 113 // Test {@link MinAndroidSdkLevel} 114 115 @Test testAnnotatedMethodAboveMin_run()116 public void testAnnotatedMethodAboveMin_run() throws Exception { 117 expectShouldSkip(UnannotatedBaseClass.class, "min28Method", false); 118 } 119 120 @Test testAnnotatedMethodAtMin_run()121 public void testAnnotatedMethodAtMin_run() throws Exception { 122 expectShouldSkip(UnannotatedBaseClass.class, "min29Method", false); 123 } 124 125 @Test testAnnotatedMethodBelowMin_skip()126 public void testAnnotatedMethodBelowMin_skip() throws Exception { 127 expectShouldSkip(UnannotatedBaseClass.class, "min30Method", true); 128 } 129 130 @Test testAnnotatedClassAboveMin_run()131 public void testAnnotatedClassAboveMin_run() throws Exception { 132 expectShouldSkip(Min28Class.class, "unannotatedMethod", false); 133 } 134 135 @Test testAnnotatedClassBelowMin_skip()136 public void testAnnotatedClassBelowMin_skip() throws Exception { 137 expectShouldSkip(Min30Class.class, "unannotatedMethod", true); 138 } 139 140 @Test testAnnotatedSuperclassAboveMin_run()141 public void testAnnotatedSuperclassAboveMin_run() throws Exception { 142 expectShouldSkip(ExtendsMin28Class.class, "unannotatedMethod", false); 143 } 144 145 @Test testAnnotatedSuperclassBelowMin_skip()146 public void testAnnotatedSuperclassBelowMin_skip() throws Exception { 147 expectShouldSkip(ExtendsMin30Class.class, "unannotatedMethod", true); 148 } 149 150 // Test {@link MaxAndroidSdkLevel} 151 152 @Test testAnnotatedMethodAboveMax_skip()153 public void testAnnotatedMethodAboveMax_skip() throws Exception { 154 expectShouldSkip(UnannotatedBaseClass.class, "max28Method", true); 155 } 156 157 @Test testAnnotatedMethodAtMax_run()158 public void testAnnotatedMethodAtMax_run() throws Exception { 159 expectShouldSkip(UnannotatedBaseClass.class, "max29Method", false); 160 } 161 162 @Test testAnnotatedMethodBelowMax_run()163 public void testAnnotatedMethodBelowMax_run() throws Exception { 164 expectShouldSkip(UnannotatedBaseClass.class, "max30Method", false); 165 } 166 167 // Test combinations of {@link MinAndroidSdkLevel} and {@link MaxAndroidSdkLevel} 168 169 @Test testAnnotatedMethodAboveMinBelowMax_run()170 public void testAnnotatedMethodAboveMinBelowMax_run() throws Exception { 171 expectShouldSkip(UnannotatedBaseClass.class, "min28max30Method", false); 172 } 173 174 @Test testAnnotatedMethodBelowMinAboveMax_skip()175 public void testAnnotatedMethodBelowMinAboveMax_skip() throws Exception { 176 expectShouldSkip(UnannotatedBaseClass.class, "min30max28Method", true); 177 } 178 } 179