ch.powerunit.Statement Maven / Gradle / Ivy
Show all versions of powerunit Show documentation
/**
* Powerunit - A JDK1.8 test framework
* Copyright (C) 2014 Mathieu Boretti.
*
* This file is part of Powerunit
*
* Powerunit is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Powerunit is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Powerunit. If not, see .
*/
package ch.powerunit;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Objects;
import java.util.function.Consumer;
import ch.powerunit.exception.InternalError;
/**
* Definition of a statement (piece of code that can thrown Throwable).
*
* A statement can be used inside test (to isolate a code that must thrown an
* exception) and are used internally by the framework to compose and execute
* test sequence element.
*
* @author borettim
* @param
* The type of the parameter
* @param
* the exception type
*/
@FunctionalInterface
public interface Statement {
/**
* Executable code.
*
* @param parameter
* A parameter for the statement
* @throws Throwable
* in case of error.
*/
void run(P parameter) throws Throwable;// should be T, but T seem to produce
// a bug in the compiler
/**
* Used to provide a name (for internal use purpose).
*
* @return the string, by default null.
* @since 0.1.0
*/
default String getName() {
return null;
}
/**
* Aggregate this statement and then the following. The second statement is
* done, even in case of exception in the first one.
*
* @param after
* the next statement
* @return the new statement
*/
default Statement
andThenAlways(Statement
after) {
Objects.requireNonNull(after);
return (p) -> {
try {
run(p);
} finally {
after.run(p);
}
};
}
/**
* Aggregate this statement and then the following. The second statement is
* done except in case of exception in the first one.
*
* @param after
* the next statement
* @return the new statement
*/
default Statement
andThenOnlySuccess(Statement
after) {
Objects.requireNonNull(after);
return (p) -> {
run(p);
after.run(p);
};
}
/**
* Build a around statement (do something, then something others, and after
* one a third statement, event in case of exception.
*
* @param internal
* the internal part
* @param before
* the first statement
* @param after
* the last statement, done event in case of exception.
* @return the new statement.
* @param
* The type of the parameter
* @param
* the exception type
*/
static Statement
around(
Statement
internal, Statement
before,
Statement
after) {
Objects.requireNonNull(internal);
Objects.requireNonNull(before);
Objects.requireNonNull(after);
return before.andThenOnlySuccess(internal).andThenAlways(after);
}
/**
* Build a statement based on a method-
*
* @param target
* the target object
* @param method
* the method
* @return the new statement.
* @param
* The type of the parameter
* @param
* the exception type
*/
static Statement
reflectionMethod(
Object target, Method method) {
Objects.requireNonNull(target);
Objects.requireNonNull(method);
return new Statement
() {
@Override
public void run(P parameter) throws Throwable {
try {
method.invoke(target);
} catch (InvocationTargetException e) {
throw e.getCause();
} catch (IllegalAccessException | IllegalArgumentException e) {
throw new InternalError("Unexpected error "
+ e.getMessage(), e);
}
}
@Override
public String getName() {
return method.getName();
}
};
}
/**
* Build a statement based on a method-
*
* @param method
* the method
* @param param
* the param
* @return the new statement.
* @param
* The type of the parameter
* @param
* the exception type
* @since 0.2.0
*/
static Statement
reflectionMethod(
Consumer