package io.vertx.ext.unit.impl;
import io.vertx.core.Handler;
import io.vertx.core.Vertx;
import io.vertx.ext.unit.TestCompletion;
import io.vertx.ext.unit.TestOptions;
import io.vertx.ext.unit.TestSuite;
import io.vertx.ext.unit.TestContext;
import io.vertx.ext.unit.report.Reporter;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class TestSuiteImpl implements TestSuite {
private static volatile Handler<TestSuiteRunner> defaultRunner;
static void setDefaultRunner(Handler<TestSuiteRunner> runner) {
defaultRunner = runner;
}
private final String name;
private volatile Handler<TestContext> before;
private volatile Handler<TestContext> beforeEach;
private volatile Handler<TestContext> after;
private volatile Handler<TestContext> afterEach;
private final List<TestCaseImpl> testCases = new ArrayList<>();
public TestSuiteImpl(String name) {
this.name = name;
}
public TestSuiteImpl(Object testSuiteObject) {
Class<?> suiteClass = testSuiteObject.getClass();
name = suiteClass.getName();
for (Method method : suiteClass.getMethods()) {
int modifiers = method.getModifiers();
String methodName = method.getName();
if (Modifier.isPublic(modifiers) && !Modifier.isStatic(modifiers) &&
Arrays.equals(method.getParameterTypes(), new Class[]{TestContext.class})) {
Handler<TestContext> handler = context -> {
try {
method.invoke(testSuiteObject, context);
} catch (IllegalAccessException e) {
Helper.uncheckedThrow(e);
} catch (InvocationTargetException e) {
Helper.uncheckedThrow(e.getCause());
}
};
switch (methodName) {
case "before":
before(handler);
break;
case "after":
after(handler);
break;
case "beforeEach":
beforeEach(handler);
break;
case "afterEach":
afterEach(handler);
break;
default:
if (methodName.startsWith("test") && methodName.length() > 4) {
test(methodName, handler);
}
break;
}
}
}
}
public List<TestCaseImpl> testCases() {
return testCases;
}
@Override
public TestSuite before(Handler<TestContext> callback) {
this.before = callback;
return this;
}
@Override
public TestSuite beforeEach(Handler<TestContext> callback) {
beforeEach = callback;
return this;
}
@Override
public TestSuite after(Handler<TestContext> handler) {
this.after = handler;
return this;
}
@Override
public TestSuite afterEach(Handler<TestContext> handler) {
afterEach = handler;
return this;
}
@Override
public TestSuite test(String name, Handler<TestContext> testCase) {
return test(name, 1, testCase);
}
@Override
public TestSuite test(String name, int repeat, Handler<TestContext> testCase) {
testCases.add(new TestCaseImpl(name, repeat, testCase));
return this;
}
@Override
public TestCompletion run() {
return run(null, new TestOptions());
}
@Override
public TestCompletion run(Vertx vertx) {
return run(vertx, new TestOptions());
}
@Override
public TestCompletion run(TestOptions options) {
return run(null, options);
}
@Override
public TestCompletion run(Vertx vertx, TestOptions options) {
Reporter[] reporters = options.getReporters().stream().map(reportOptions -> Reporter.reporter(vertx, reportOptions)).toArray(Reporter[]::new);
TestCompletionImpl completion = new TestCompletionImpl(reporters);
TestSuiteRunner runner = runner().
setVertx(vertx).
setTimeout(options.getTimeout()).
setUseEventLoop(options.isUseEventLoop()).
setReporter(completion);
if (defaultRunner != null) {
defaultRunner.handle(runner);
} else {
runner.run();
}
return completion;
}
public TestSuiteRunner runner() {
return new TestSuiteRunner(name, before, after, beforeEach, afterEach, new ArrayList<>(testCases));
}
}