1 package host.exp.exponent.utils
2 
3 import androidx.test.internal.runner.junit4.AndroidJUnit4ClassRunner
4 import host.exp.exponent.annotations.ExpoAlwaysPassThroughFilter
5 import host.exp.exponent.annotations.ExpoDevModeTest
6 import host.exp.exponent.annotations.ExpoSdkVersionTest
7 import host.exp.exponent.annotations.ExpoTestSuiteTest
8 import org.json.JSONObject
9 import org.junit.runner.Description
10 import org.junit.runner.manipulation.Filter
11 import org.junit.runner.manipulation.NoTestsRemainException
12 
13 class ExpoTestRunner(klass: Class<*>?) : AndroidJUnit4ClassRunner(klass) {
14   class ExpoTestFilter : Filter() {
15     private val testConfig: JSONObject = TestConfig.get()
16 
shouldRunnull17     override fun shouldRun(description: Description): Boolean {
18       if (description.getAnnotation(ExpoAlwaysPassThroughFilter::class.java) != null) {
19         return true
20       }
21       val testTypes = testConfig.optJSONArray(TEST_TYPES_KEY)
22       if (testTypes != null) {
23         var foundTestType = false
24         for (i in 0 until testTypes.length()) {
25           if (testTypes.optString(i) == TEST_SUITE_TEST_TYPE && description.getAnnotation(
26               ExpoTestSuiteTest::class.java
27             ) != null
28           ) {
29             foundTestType = true
30           } else if (testTypes.optString(i) == DEV_MODE_TEST_TYPE && description.getAnnotation(
31               ExpoDevModeTest::class.java
32             ) != null
33           ) {
34             foundTestType = true
35           }
36         }
37         if (!foundTestType) {
38           return false
39         }
40       }
41       val sdkVersions = testConfig.optJSONArray(SDK_VERSIONS_KEY)
42       val sdkVersionAnnotation = description.getAnnotation(
43         ExpoSdkVersionTest::class.java
44       )
45       if (sdkVersions != null && sdkVersionAnnotation != null) {
46         var foundSdkVersion = false
47         for (i in 0 until sdkVersions.length()) {
48           if (sdkVersionAnnotation.value == sdkVersions.optString(i)) {
49             foundSdkVersion = true
50           }
51         }
52         if (!foundSdkVersion) {
53           return false
54         }
55       }
56       return true
57     }
58 
describenull59     override fun describe(): String {
60       return "Filters tests based on TEST_CONFIG env var"
61     }
62   }
63 
64   companion object {
65     const val TEST_TYPES_KEY = "includeTestTypes"
66     const val TEST_SUITE_TEST_TYPE = "test-suite"
67     const val DEV_MODE_TEST_TYPE = "dev-mode"
68     const val SDK_VERSIONS_KEY = "includeSdkVersions"
69   }
70 
71   init {
72     val filter = ExpoTestFilter()
73     try {
74       filter.apply(this)
75     } catch (e: NoTestsRemainException) {
76       throw RuntimeException(e)
77     }
78   }
79 }
80