1// Copyright 2014 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5package org.chromium.testing.local;
6
7import org.junit.runner.Computer;
8import org.junit.runner.Description;
9import org.junit.runner.Runner;
10import org.junit.runner.manipulation.Filter;
11import org.junit.runner.manipulation.Filterable;
12import org.junit.runner.manipulation.NoTestsRemainException;
13import org.junit.runner.notification.RunNotifier;
14import org.junit.runners.model.InitializationError;
15import org.junit.runners.model.RunnerBuilder;
16
17/**
18 *  A Computer that logs the start and end of test cases googletest-style.
19 */
20public class GtestComputer extends Computer {
21
22    private final GtestLogger mLogger;
23
24    public GtestComputer(GtestLogger logger) {
25        mLogger = logger;
26    }
27
28    /**
29     *  A wrapping Runner that logs the start and end of each test case.
30     */
31    private class GtestSuiteRunner extends Runner implements Filterable {
32        private final Runner mRunner;
33
34        public GtestSuiteRunner(Runner contained) {
35            mRunner = contained;
36        }
37
38        public Description getDescription() {
39            return mRunner.getDescription();
40        }
41
42        public void run(RunNotifier notifier) {
43            long startTimeMillis = System.currentTimeMillis();
44            mLogger.testCaseStarted(mRunner.getDescription(),
45                    mRunner.getDescription().testCount());
46            mRunner.run(notifier);
47            mLogger.testCaseFinished(mRunner.getDescription(),
48                    mRunner.getDescription().testCount(),
49                    System.currentTimeMillis() - startTimeMillis);
50        }
51
52        public void filter(Filter filter) throws NoTestsRemainException {
53            if (mRunner instanceof Filterable) {
54                ((Filterable) mRunner).filter(filter);
55            }
56        }
57    }
58
59    /**
60     *  Returns a suite of unit tests with each class runner wrapped by a
61     *  GtestSuiteRunner.
62     */
63    @Override
64    public Runner getSuite(final RunnerBuilder builder, Class<?>[] classes)
65            throws InitializationError {
66        return super.getSuite(
67                new RunnerBuilder() {
68                    @Override
69                    public Runner runnerForClass(Class<?> testClass) throws Throwable {
70                        return new GtestSuiteRunner(builder.runnerForClass(testClass));
71                    }
72                }, classes);
73    }
74
75}
76
77