BiFunctionTester.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.bifunction;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.function.BiFunction;
import java.util.function.Supplier;
import org.hamcrest.Matcher;
import ch.powerunit.TestInterface;
import ch.powerunit.bifunction.impl.BiFunctionTesterImpl;
import ch.powerunit.bifunction.lang.BiFunctionTesterDefineDSL;
import ch.powerunit.bifunction.lang.BiFunctionTesterEndDSL;
import ch.powerunit.bifunction.lang.BiFunctionTesterNextDSL;
import ch.powerunit.bifunction.lang.BiFunctionTesterStartDSL;
import ch.powerunit.function.impl.SupplierEqualsToMatcher;
/**
* Tester for bifunction.
*
* @author borettim
* @since 0.3.0
*/
@TestInterface(BiFunctionTesterImpl.class)
public final class BiFunctionTester<T, U, R> {
private final BiFunction<T, U, R> underTest;
private final List<Supplier<T>> input1;
private final List<Supplier<U>> input2;
private final List<Supplier<Matcher<? super R>>> result;
private final List<Supplier<String>> name;
private static class BiFunctionTesterDSL<T, U, R> implements
BiFunctionTesterDefineDSL<T, U, R>,
BiFunctionTesterEndDSL<T, U, R>, BiFunctionTesterNextDSL<T, U, R>,
BiFunctionTesterStartDSL<T, U, R> {
private final BiFunction<T, U, R> underTest;
private List<Supplier<T>> tmpInput1 = new ArrayList<>();
private List<Supplier<U>> tmpInput2 = new ArrayList<>();
private List<Supplier<Matcher<? super R>>> tmpResult = new ArrayList<>();
private List<Supplier<String>> tmpName = new ArrayList<>();
private void finalizeCase() {
if (tmpName.size() < tmpInput1.size()) {
tmpName.add(() -> "");
}
}
public BiFunctionTesterDSL(BiFunction<T, U, R> underTest) {
this.underTest = underTest;
}
@Override
public BiFunctionTesterDefineDSL<T, U, R> passingAsParameter(T input1,
U input2) {
return passingAsParameter(() -> input1, () -> input2);
}
@Override
public BiFunctionTesterDefineDSL<T, U, R> passingAsParameter(
Supplier<T> input1, Supplier<U> input2) {
Objects.requireNonNull(input1, "input1 can't be null");
Objects.requireNonNull(input2, "input2 can't be null");
finalizeCase();
tmpInput1.add(input1);
tmpInput2.add(input2);
return this;
}
@Override
public BiFunctionTesterNextDSL<T, U, R> thenExpectingResult(R result) {
return thenExpectingResult(() -> result);
}
@Override
public BiFunctionTesterNextDSL<T, U, R> thenExpectingResult(
Supplier<R> result) {
Objects.requireNonNull(result, "matching can't be null");
return thenExpectingResultThat(new SupplierEqualsToMatcher<R>(
result));
}
@Override
public BiFunctionTesterNextDSL<T, U, R> thenExpectingResultThat(
Matcher<? super R> matching) {
Objects.requireNonNull(matching, "matching can't be null");
return thenExpectingResultThat(() -> matching);
}
@Override
public BiFunctionTesterNextDSL<T, U, R> thenExpectingResultThat(
Supplier<Matcher<? super R>> matching) {
Objects.requireNonNull(matching, "matching can't be null");
tmpResult.add(matching);
return this;
}
@Override
public BiFunctionTesterEndDSL<T, U, R> testNamed(String name) {
return testNamed(() -> name);
}
@Override
public BiFunctionTesterEndDSL<T, U, R> testNamed(Supplier<String> name) {
Objects.requireNonNull(name, "name can't be null");
tmpName.add(name);
return this;
}
@Override
public BiFunctionTester<T, U, R> build() {
finalizeCase();
return new BiFunctionTester<T, U, R>(underTest, tmpInput1,
tmpInput2, tmpResult, tmpName);
}
}
private BiFunctionTester(BiFunction<T, U, R> underTest,
List<Supplier<T>> tmpInput1, List<Supplier<U>> tmpInput2,
List<Supplier<Matcher<? super R>>> tmpResult,
List<Supplier<String>> tmpName) {
this.underTest = underTest;
this.input1 = tmpInput1;
this.input2 = tmpInput2;
this.result = tmpResult;
this.name = tmpName;
}
/**
* Start the creation of a tester of function.
* <p>
* For example :
*
* <pre>
* @TestDelegate
* public final BiFunctionTester<Short, Integer, Long> tester1 = BiFunctionTester
* .of(this::bifunctionToBeTested).passingAsParameter((short) 1, 2)
* .thenExpectingResult(3l).testNamed("tested")
* .passingAsParameter((short) 2, 4).thenExpectingResult(6l).build();
* </pre>
*
* @param bifunctionUnderTest
* the function to be tested
* @return {@link BiFunctionTesterStartDSL the DSL}
* @throws NullPointerException
* when bifunctionUnderTest is null
* @param <T>
* the first input argument type
* @param <U>
* the second input argument type
* @param <R>
* the result type
* @see ch.powerunit.TestDelegate
*/
public static <T, U, R> BiFunctionTesterStartDSL<T, U, R> of(
BiFunction<T, U, R> bifunctionUnderTest) {
Objects.requireNonNull(bifunctionUnderTest,
"bifunctionUnderTest can't be null");
return new BiFunctionTesterDSL<T, U, R>(bifunctionUnderTest);
}
/**
* Used by the framework.
*
* @return the underTest
*/
public BiFunction<T, U, R> getUnderTest() {
return underTest;
}
/**
* Used by the framework.
*
* @return the first input
*/
public List<Supplier<T>> getInput1() {
return Collections.unmodifiableList(input1);
}
/**
* Used by the framework.
*
* @return the first input
*/
public List<Supplier<U>> getInput2() {
return Collections.unmodifiableList(input2);
}
/**
* 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);
}
}