19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*
29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2008 The Android Open Source Project
39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License.
69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at
79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and
149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License.
159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage android.test.suitebuilder;
189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.Context;
209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.test.AndroidTestRunner;
219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.test.TestCaseUtil;
229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.Log;
239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport com.android.internal.util.Predicate;
249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport static android.test.suitebuilder.TestGrouping.SORT_BY_FULLY_QUALIFIED_NAME;
259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport static android.test.suitebuilder.TestPredicates.REJECT_SUPPRESSED;
269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport junit.framework.Test;
289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport junit.framework.TestCase;
299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport junit.framework.TestSuite;
309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.List;
329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.Set;
339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.HashSet;
349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.ArrayList;
359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.Collections;
369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/**
389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Build suites based on a combination of included packages, excluded packages,
399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * and predicates that must be satisfied.
40253ad40649242edae625d95e2ae415a1bf27b9fcPaul Duffin *
41253ad40649242edae625d95e2ae415a1bf27b9fcPaul Duffin * @deprecated New tests should be written using the
42253ad40649242edae625d95e2ae415a1bf27b9fcPaul Duffin * <a href="{@docRoot}tools/testing-support-library/index.html">Android Testing Support Library</a>.
439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
44253ad40649242edae625d95e2ae415a1bf27b9fcPaul Duffin@Deprecated
459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic class TestSuiteBuilder {
469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
47e2e557976f1d68bf4d6a147ec484e5455f15eeefPaul Duffin    private final TestGrouping testGrouping;
489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private final Set<Predicate<TestMethod>> predicates = new HashSet<Predicate<TestMethod>>();
499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private List<TestCase> testCases;
509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private TestSuite rootSuite;
519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private TestSuite suiteForCurrentClass;
529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private String currentClassname;
539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private String suiteName;
549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * The given name is automatically prefixed with the package containing the tests to be run.
579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * If more than one package is specified, the first is used.
589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param clazz Use the class from your .apk. Use the class name for the test suite name.
609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *              Use the class' classloader in order to load classes for testing.
619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *              This is needed when running in the emulator.
629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public TestSuiteBuilder(Class clazz) {
649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        this(clazz.getName(), clazz.getClassLoader());
659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public TestSuiteBuilder(String name, ClassLoader classLoader) {
689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        this.suiteName = name;
69e2e557976f1d68bf4d6a147ec484e5455f15eeefPaul Duffin        this.testGrouping = new TestGrouping(SORT_BY_FULLY_QUALIFIED_NAME, classLoader);
708c5a24d16926fb14f407ba51026f9a5b973b2e01Paul Duffin        this.testCases = new ArrayList<>();
719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        addRequirements(REJECT_SUPPRESSED);
729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
73bd1c5da28dab9c3fb7e19bdadb22d7ad960fa3c3Jesse Wilson
749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /** @hide pending API Council approval */
75bd1c5da28dab9c3fb7e19bdadb22d7ad960fa3c3Jesse Wilson    public TestSuiteBuilder addTestClassByName(String testClassName, String testMethodName,
769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            Context context) {
779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        AndroidTestRunner atr = new AndroidTestRunner();
799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        atr.setContext(context);
809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        atr.setTestClassName(testClassName, testMethodName);
819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        this.testCases.addAll(atr.getTestCases());
839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return this;
849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
85bd1c5da28dab9c3fb7e19bdadb22d7ad960fa3c3Jesse Wilson
869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /** @hide pending API Council approval */
879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public TestSuiteBuilder addTestSuite(TestSuite testSuite) {
889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (TestCase testCase : (List<TestCase>) TestCaseUtil.getTests(testSuite, true)) {
899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            this.testCases.add(testCase);
909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return this;
929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Include all tests that satisfy the requirements in the given packages and all sub-packages,
969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * unless otherwise specified.
979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param packageNames Names of packages to add.
999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return The builder for method chaining.
1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public TestSuiteBuilder includePackages(String... packageNames) {
1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        testGrouping.addPackagesRecursive(packageNames);
1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return this;
1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Exclude all tests in the given packages and all sub-packages, unless otherwise specified.
1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param packageNames Names of packages to remove.
1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return The builder for method chaining.
1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public TestSuiteBuilder excludePackages(String... packageNames) {
1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        testGrouping.removePackagesRecursive(packageNames);
1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return this;
1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Exclude tests that fail to satisfy all of the given predicates.
1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param predicates Predicates to add to the list of requirements.
1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return The builder for method chaining.
1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public TestSuiteBuilder addRequirements(List<Predicate<TestMethod>> predicates) {
1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        this.predicates.addAll(predicates);
1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return this;
1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Include all junit tests that satisfy the requirements in the calling class' package and all
1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * sub-packages.
1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return The builder for method chaining.
1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public final TestSuiteBuilder includeAllPackagesUnderHere() {
1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        StackTraceElement[] stackTraceElements = Thread.currentThread().getStackTrace();
1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        String callingClassName = null;
1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        String thisClassName = TestSuiteBuilder.class.getName();
1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // We want to get the package of this method's calling class. This method's calling class
1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // should be one level below this class in the stack trace.
1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (int i = 0; i < stackTraceElements.length; i++) {
1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            StackTraceElement element = stackTraceElements[i];
1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (thisClassName.equals(element.getClassName())
1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    && "includeAllPackagesUnderHere".equals(element.getMethodName())) {
1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // We've found this class in the call stack. The calling class must be the
1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // next class in the stack.
1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                callingClassName = stackTraceElements[i + 1].getClassName();
1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                break;
1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        String packageName = parsePackageNameFromClassName(callingClassName);
1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return includePackages(packageName);
1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Override the default name for the suite being built. This should generally be called if you
1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * call {@link #addRequirements(com.android.internal.util.Predicate[])} to make it clear which
1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * tests will be included. The name you specify is automatically prefixed with the package
1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * containing the tests to be run. If more than one package is specified, the first is used.
1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param newSuiteName Prefix of name to give the suite being built.
1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return The builder for method chaining.
1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public TestSuiteBuilder named(String newSuiteName) {
1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        suiteName = newSuiteName;
1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return this;
1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Call this method once you've configured your builder as desired.
1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return The suite containing the requested tests.
1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public final TestSuite build() {
1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        rootSuite = new TestSuite(getSuiteName());
1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Keep track of current class so we know when to create a new sub-suite.
1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        currentClassname = null;
1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        try {
1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            for (TestMethod test : testGrouping.getTests()) {
1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (satisfiesAllPredicates(test)) {
1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    addTest(test);
1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (testCases.size() > 0) {
1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                for (TestCase testCase : testCases) {
1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (satisfiesAllPredicates(new TestMethod(testCase))) {
1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        addTest(testCase);
1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } catch (Exception exception) {
1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            Log.i("TestSuiteBuilder", "Failed to create test.", exception);
1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            TestSuite suite = new TestSuite(getSuiteName());
1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            suite.addTest(new FailedToCreateTests(exception));
1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return suite;
1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return rootSuite;
2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Subclasses use this method to determine the name of the suite.
2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return The package and suite name combined.
2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected String getSuiteName() {
2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return suiteName;
2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Exclude tests that fail to satisfy all of the given predicates. If you call this method, you
2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * probably also want to call {@link #named(String)} to override the default suite name.
2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param predicates Predicates to add to the list of requirements.
2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return The builder for method chaining.
2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public final TestSuiteBuilder addRequirements(Predicate<TestMethod>... predicates) {
2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        ArrayList<Predicate<TestMethod>> list = new ArrayList<Predicate<TestMethod>>();
2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Collections.addAll(list, predicates);
2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return addRequirements(list);
2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * A special {@link junit.framework.TestCase} used to indicate a failure during the build()
2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * step.
228253ad40649242edae625d95e2ae415a1bf27b9fcPaul Duffin     *
229253ad40649242edae625d95e2ae415a1bf27b9fcPaul Duffin     * @deprecated New tests should be written using the
230253ad40649242edae625d95e2ae415a1bf27b9fcPaul Duffin     * <a href="{@docRoot}tools/testing-support-library/index.html">Android Testing Support Library</a>.
2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
232253ad40649242edae625d95e2ae415a1bf27b9fcPaul Duffin    @Deprecated
2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static class FailedToCreateTests extends TestCase {
2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        private final Exception exception;
2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public FailedToCreateTests(Exception exception) {
2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            super("testSuiteConstructionFailed");
2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            this.exception = exception;
2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void testSuiteConstructionFailed() {
2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new RuntimeException("Exception during suite construction", exception);
2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private boolean satisfiesAllPredicates(TestMethod test) {
2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (Predicate<TestMethod> predicate : predicates) {
2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (!predicate.apply(test)) {
2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return false;
2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return true;
2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private void addTest(TestMethod testMethod) throws Exception {
2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        addSuiteIfNecessary(testMethod.getEnclosingClassname());
2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        suiteForCurrentClass.addTest(testMethod.createTest());
2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
259bd1c5da28dab9c3fb7e19bdadb22d7ad960fa3c3Jesse Wilson
2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private void addTest(Test test) {
2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        addSuiteIfNecessary(test.getClass().getName());
2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        suiteForCurrentClass.addTest(test);
2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private void addSuiteIfNecessary(String parentClassname) {
2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!parentClassname.equals(currentClassname)) {
2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            currentClassname = parentClassname;
2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            suiteForCurrentClass = new TestSuite(parentClassname);
2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            rootSuite.addTest(suiteForCurrentClass);
2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static String parsePackageNameFromClassName(String className) {
2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return className.substring(0, className.lastIndexOf('.'));
2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
277