FunctionTester.java
/**
* 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 <http://www.gnu.org/licenses/>.
*/
package ch.powerunit.function;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.function.Function;
import java.util.function.Supplier;
import org.hamcrest.Matcher;
import ch.powerunit.TestInterface;
import ch.powerunit.function.impl.FunctionTesterImpl;
import ch.powerunit.function.impl.SupplierEqualsToMatcher;
import ch.powerunit.function.lang.FunctionTesterDefineDSL;
import ch.powerunit.function.lang.FunctionTesterEndDSL;
import ch.powerunit.function.lang.FunctionTesterNextDSL;
import ch.powerunit.function.lang.FunctionTesterStartDSL;
/**
* Tester for function.
*
* @author borettim
* @since 0.3.0
*/
@TestInterface(FunctionTesterImpl.class)
public final class FunctionTester<T, R> {
private final Function<T, R> underTest;
private final List<Supplier<T>> input;
private final List<Supplier<Matcher<? super R>>> result;
private final List<Supplier<String>> name;
private static class FunctionTesterDSL<T, R> implements
FunctionTesterDefineDSL<T, R>, FunctionTesterEndDSL<T, R>,
FunctionTesterNextDSL<T, R>, FunctionTesterStartDSL<T, R> {
private final Function<T, R> underTest;
private List<Supplier<T>> tmpInput = new ArrayList<>();
private List<Supplier<Matcher<? super R>>> tmpResult = new ArrayList<>();
private List<Supplier<String>> tmpName = new ArrayList<>();
private void finalizeCase() {
if (tmpName.size() < tmpInput.size()) {
tmpName.add(() -> "");
}
}
public FunctionTesterDSL(Function<T, R> underTest) {
this.underTest = underTest;
}
@Override
public FunctionTesterDefineDSL<T, R> passingAsParameter(T input) {
return passingAsParameter(() -> input);
}
@Override
public FunctionTesterDefineDSL<T, R> passingAsParameter(
Supplier<T> input) {
Objects.requireNonNull(input, "input can't be null");
finalizeCase();
tmpInput.add(input);
return this;
}
@Override
public FunctionTesterNextDSL<T, R> thenExpectingResult(R result) {
return thenExpectingResult(() -> result);
}
@Override
public FunctionTesterNextDSL<T, R> thenExpectingResult(
Supplier<R> result) {
Objects.requireNonNull(result, "matching can't be null");
return thenExpectingResultThat(new SupplierEqualsToMatcher<R>(
result));
}
@Override
public FunctionTesterNextDSL<T, R> thenExpectingResultThat(
Matcher<? super R> matching) {
Objects.requireNonNull(matching, "matching can't be null");
return thenExpectingResultThat(() -> matching);
}
@Override
public FunctionTesterNextDSL<T, R> thenExpectingResultThat(
Supplier<Matcher<? super R>> matching) {
Objects.requireNonNull(matching, "matching can't be null");
tmpResult.add(matching);
return this;
}
@Override
public FunctionTesterEndDSL<T, R> testNamed(String name) {
return testNamed(() -> name);
}
@Override
public FunctionTesterEndDSL<T, R> testNamed(Supplier<String> name) {
Objects.requireNonNull(name, "name can't be null");
tmpName.add(name);
return this;
}
@Override
public FunctionTester<T, R> build() {
finalizeCase();
return new FunctionTester<T, R>(underTest, tmpInput, tmpResult,
tmpName);
}
}
private FunctionTester(Function<T, R> underTest,
List<Supplier<T>> tmpInput,
List<Supplier<Matcher<? super R>>> tmpResult,
List<Supplier<String>> tmpName) {
this.underTest = underTest;
this.input = tmpInput;
this.result = tmpResult;
this.name = tmpName;
}
/**
* Start the creation of a tester of function.
*
* @param functionUnderTest
* the function to be tested
* @return {@link FunctionTesterStartDSL the DSL}
* @throws NullPointerException
* when functionUnderTest is null
* @param <T>
* the input argument type
* @param <R>
* the result type
* @see ch.powerunit.TestDelegate
*/
public static <T, R> FunctionTesterStartDSL<T, R> of(
Function<T, R> functionUnderTest) {
Objects.requireNonNull(functionUnderTest,
"functionUnderTest can't be null");
return new FunctionTesterDSL<T, R>(functionUnderTest);
}
/**
* Used by the framework.
*
* @return the underTest
*/
public Function<T, R> getUnderTest() {
return underTest;
}
/**
* Used by the framework.
*
* @return the input
*/
public List<Supplier<T>> getInput() {
return Collections.unmodifiableList(input);
}
/**
* Used by the framework.
*
* @return the result
*/
public List<Supplier<Matcher<? super R>>> getResult() {
return Collections.unmodifiableList(result);
}
/**
* Used by the framework.
*
* @return the name
*/
public List<Supplier<String>> getName() {
return Collections.unmodifiableList(name);
}
}