1 /* 2 * Copyright (C) 2024 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 android.tools.flicker.junit 18 19 import android.tools.Scenario 20 import android.tools.flicker.datastore.DataStore 21 import android.tools.flicker.legacy.FlickerBuilder 22 import android.tools.flicker.legacy.LegacyFlickerTest 23 import java.lang.reflect.Modifier 24 import org.junit.runner.Description 25 import org.junit.runners.model.FrameworkMethod 26 import org.junit.runners.model.Statement 27 import org.junit.runners.model.TestClass 28 29 class LegacyFlickerDecorator( 30 testClass: TestClass, 31 val scenario: Scenario?, 32 val transitionRunner: ITransitionRunner, 33 inner: IFlickerJUnitDecorator? = null 34 ) : AbstractFlickerRunnerDecorator(testClass, inner) { getChildDescriptionnull35 override fun getChildDescription(method: FrameworkMethod): Description { 36 return inner?.getChildDescription(method) 37 ?: error("Need inner to provide child description") 38 } 39 getTestMethodsnull40 override fun getTestMethods(test: Any): List<FrameworkMethod> { 41 return inner?.getTestMethods(test) ?: error("Need inner to provide test methods") 42 } 43 getMethodInvokernull44 override fun getMethodInvoker(method: FrameworkMethod, test: Any): Statement { 45 return object : Statement() { 46 override fun evaluate() { 47 requireNotNull(scenario) { "Expected to have a scenario to run" } 48 val description = getChildDescription(method) 49 if (!android.tools.flicker.datastore.DataStore.containsResult(scenario)) { 50 transitionRunner.runTransition(scenario, test, description) 51 } 52 inner?.getMethodInvoker(method, test)?.evaluate() 53 } 54 } 55 } 56 doValidateConstructornull57 override fun doValidateConstructor(): List<Throwable> { 58 val errors = super.doValidateConstructor().toMutableList() 59 val ctor = testClass.javaClass.constructors.firstOrNull() 60 if (ctor?.parameterTypes?.none { it == LegacyFlickerTest::class.java } != false) { 61 errors.add( 62 IllegalStateException( 63 "Constructor should have a parameter of type " + 64 LegacyFlickerTest::class.java.simpleName 65 ) 66 ) 67 } 68 return errors 69 } 70 doValidateInstanceMethodsnull71 override fun doValidateInstanceMethods(): List<Throwable> { 72 val errors = super.doValidateInstanceMethods().toMutableList() 73 74 val methods = getCandidateProviderMethods(testClass) 75 76 if (methods.isEmpty() || methods.size > 1) { 77 val prefix = if (methods.isEmpty()) "One" else "Only one" 78 errors.add( 79 IllegalArgumentException( 80 "$prefix object should be annotated with @FlickerBuilderProvider" 81 ) 82 ) 83 } else { 84 val method = methods.first() 85 86 if (Modifier.isStatic(method.method.modifiers)) { 87 errors.add(IllegalArgumentException("Method ${method.name}() should not be static")) 88 } 89 if (!Modifier.isPublic(method.method.modifiers)) { 90 errors.add(IllegalArgumentException("Method ${method.name}() should be public")) 91 } 92 if (method.returnType != FlickerBuilder::class.java) { 93 errors.add( 94 IllegalArgumentException( 95 "Method ${method.name}() should return a " + 96 "${FlickerBuilder::class.java.simpleName} object" 97 ) 98 ) 99 } 100 if (method.method.parameterTypes.isNotEmpty()) { 101 errors.add( 102 IllegalArgumentException("Method ${method.name} should have no parameters") 103 ) 104 } 105 } 106 107 return errors 108 } 109 110 private val providerMethod: FrameworkMethod 111 get() = 112 getCandidateProviderMethods(testClass).firstOrNull() 113 ?: error("Provider method not found") 114 115 companion object { getCandidateProviderMethodsnull116 private fun getCandidateProviderMethods(testClass: TestClass): List<FrameworkMethod> = 117 testClass.getAnnotatedMethods(FlickerBuilderProvider::class.java) ?: emptyList() 118 } 119 } 120