
io.activej.test.ActiveJRunner Maven / Gradle / Ivy
/*
* Copyright (C) 2020 ActiveJ LLC.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.activej.test;
import io.activej.inject.Injector;
import io.activej.inject.InstanceInjector;
import io.activej.inject.Key;
import io.activej.inject.binding.Binding;
import io.activej.inject.module.Module;
import io.activej.inject.module.ModuleBuilder;
import io.activej.inject.module.Modules;
import io.activej.inject.util.ReflectionUtils;
import io.activej.test.rules.LambdaStatement;
import org.junit.After;
import org.junit.Before;
import org.junit.runner.Description;
import org.junit.runner.notification.Failure;
import org.junit.runner.notification.RunNotifier;
import org.junit.runners.BlockJUnit4ClassRunner;
import org.junit.runners.model.FrameworkMethod;
import org.junit.runners.model.InitializationError;
import org.junit.runners.model.MultipleFailureException;
import org.junit.runners.model.Statement;
import java.lang.annotation.Annotation;
import java.util.*;
import static io.activej.common.collection.CollectionUtils.union;
import static io.activej.types.Types.parameterizedType;
import static java.util.stream.Collectors.toSet;
public class ActiveJRunner extends BlockJUnit4ClassRunner {
private final Set surroundings = new HashSet<>();
private final Set> staticDependencies;
private Module currentModule;
private Set> currentDependencies;
protected Injector currentInjector;
public ActiveJRunner(Class> cls) throws InitializationError {
super(cls);
surroundings.addAll(getTestClass().getAnnotatedMethods(Before.class));
surroundings.addAll(getTestClass().getAnnotatedMethods(After.class));
staticDependencies = surroundings.stream()
.flatMap(m -> Arrays.stream(ReflectionUtils.toDependencies(cls, m.getMethod())))
.collect(toSet());
}
// runChild is always called before createTest
@Override
protected void runChild(FrameworkMethod method, RunNotifier notifier) {
Description description = describeChild(method);
if (isIgnored(method)) {
notifier.fireTestIgnored(description);
return;
}
try {
Class> cls = getTestClass().getJavaClass();
Set modules = new HashSet<>();
addClassModules(modules, cls); // add modules from class annotation
addMethodModules(modules, method); // add modules from current test method
for (FrameworkMethod m : surroundings) { // add modules from befores and afters
addMethodModules(modules, m);
}
currentModule = Modules.combine(modules);
currentDependencies =
Arrays.stream(ReflectionUtils.toDependencies(cls, method.getMethod()))
.collect(toSet());
} catch (ExceptionInInitializerError e) {
Throwable cause = e.getCause();
notifier.fireTestFailure(new Failure(description, cause != null ? cause : e));
return;
} catch (Exception e) {
notifier.fireTestFailure(new Failure(description, e));
return;
}
runLeaf(methodBlock(method), description, notifier);
}
private static void addClassModules(Set modules, Class> cls) throws ExceptionInInitializerError, ReflectiveOperationException {
while (cls != null) {
UseModules useModules = cls.getAnnotation(UseModules.class);
if (useModules != null) {
for (Class extends Module> moduleClass : useModules.value()) {
modules.add(moduleClass.getDeclaredConstructor().newInstance());
}
}
cls = cls.getSuperclass();
}
}
private static void addMethodModules(Set modules, FrameworkMethod method) throws ExceptionInInitializerError, ReflectiveOperationException {
UseModules useModules = method.getMethod().getAnnotation(UseModules.class);
if (useModules == null) {
return;
}
for (Class extends Module> moduleClass : useModules.value()) {
modules.add(moduleClass.getDeclaredConstructor().newInstance());
}
}
public static final class DependencyToken {}
// createTest is always called after runChild
@Override
protected Object createTest() throws Exception {
Object instance = super.createTest();
Key
© 2015 - 2025 Weber Informatics LLC | Privacy Policy