1/*
2 * Copyright (C) 2007 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
17package android.test;
18
19import java.util.ArrayList;
20import junit.framework.Test;
21import junit.framework.TestCase;
22import junit.framework.TestSuite;
23import junit.runner.BaseTestRunner;
24
25import java.lang.reflect.InvocationTargetException;
26import java.lang.reflect.Method;
27import java.lang.reflect.Modifier;
28import java.util.Enumeration;
29import java.util.HashSet;
30import java.util.List;
31import java.util.Set;
32
33/**
34 * @hide - This is part of a framework that is under development and should not be used for
35 * active development.
36 */
37@Deprecated
38public class TestCaseUtil {
39
40    private TestCaseUtil() {
41    }
42
43    public static List<? extends Test> getTests(Test test, boolean flatten) {
44        return getTests(test, flatten, new HashSet<Class<?>>());
45    }
46
47    private static List<? extends Test> getTests(Test test, boolean flatten,
48            Set<Class<?>> seen) {
49        List<Test> testCases = new ArrayList<>();
50        if (test != null) {
51
52            Test workingTest = null;
53            /*
54             * If we want to run a single TestCase method only, we must not
55             * invoke the suite() method, because we will run all test methods
56             * of the class then.
57             */
58            if (test instanceof TestCase &&
59                    ((TestCase)test).getName() == null) {
60                workingTest = invokeSuiteMethodIfPossible(test.getClass(),
61                        seen);
62            }
63            if (workingTest == null) {
64                workingTest = test;
65            }
66
67            if (workingTest instanceof TestSuite) {
68                TestSuite testSuite = (TestSuite) workingTest;
69                Enumeration enumeration = testSuite.tests();
70                while (enumeration.hasMoreElements()) {
71                    Test childTest = (Test) enumeration.nextElement();
72                    if (flatten) {
73                        testCases.addAll(getTests(childTest, flatten, seen));
74                    } else {
75                        testCases.add(childTest);
76                    }
77                }
78            } else {
79                testCases.add(workingTest);
80            }
81        }
82        return testCases;
83    }
84
85    static Test invokeSuiteMethodIfPossible(Class testClass,
86            Set<Class<?>> seen) {
87        try {
88            Method suiteMethod = testClass.getMethod(
89                    BaseTestRunner.SUITE_METHODNAME, new Class[0]);
90            /*
91             * Additional check necessary: If a TestCase contains a suite()
92             * method that returns a TestSuite including the TestCase itself,
93             * we need to stop the recursion. We use a set of classes to
94             * remember which classes' suite() methods were already invoked.
95             */
96            if (Modifier.isStatic(suiteMethod.getModifiers())
97                    && !seen.contains(testClass)) {
98                seen.add(testClass);
99                try {
100                    return (Test) suiteMethod.invoke(null, (Object[]) null);
101                } catch (InvocationTargetException e) {
102                    // do nothing
103                } catch (IllegalAccessException e) {
104                    // do nothing
105                }
106            }
107        } catch (NoSuchMethodException e) {
108            // do nothing
109        }
110        return null;
111    }
112
113    static String getTestName(Test test) {
114        if (test instanceof TestCase) {
115            TestCase testCase = (TestCase) test;
116            return testCase.getName();
117        } else if (test instanceof TestSuite) {
118            TestSuite testSuite = (TestSuite) test;
119            String name = testSuite.getName();
120            if (name != null) {
121                int index = name.lastIndexOf(".");
122                if (index > -1) {
123                    return name.substring(index + 1);
124                } else {
125                    return name;
126                }
127            }
128        }
129        return "";
130    }
131}
132