ComparatorTester.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.comparator;
import java.util.Comparator;
import java.util.Objects;
import java.util.function.Supplier;
import ch.powerunit.TestInterface;
import ch.powerunit.comparator.impl.ComparatorTesterImpl;
import ch.powerunit.comparator.impl.SampleProvider;
import ch.powerunit.comparator.lang.ComparatorTesterDSLEnd;
import ch.powerunit.comparator.lang.ComparatorTesterDSLEquals;
import ch.powerunit.comparator.lang.ComparatorTesterDSLGreater;
import ch.powerunit.comparator.lang.ComparatorTesterDSLLess;
import ch.powerunit.comparator.lang.ComparatorTesterDSLStart;
/**
* This is a framework to simplify the testing of {@link Comparator}.
*
* @author borettim
* @since 0.3.0
* @param <O>
* The object of the comparator
* @param <C>
* The comparator undertest
*/
@TestInterface(ComparatorTesterImpl.class)
public final class ComparatorTester<O, C extends Comparator<O>> {
private static class ComparatorTesterDSL<O, C extends Comparator<O>>
implements ComparatorTesterDSLStart<O, C>,
ComparatorTesterDSLLess<O, C>, ComparatorTesterDSLEquals<O, C>,
ComparatorTesterDSLGreater<O, C>, ComparatorTesterDSLEnd<O, C> {
private final Class<C> clazzUnderTest;
private O lessSamples[];
private O equalSamples[];
private O greaterSamples[];
private C underTest;
public ComparatorTesterDSL(Class<C> clazzUnderTest) {
this.clazzUnderTest = clazzUnderTest;
}
@Override
public ComparatorTesterDSLEquals<O, C> withLessSamples(O... lessSamples) {
this.lessSamples = lessSamples;
return this;
}
@SuppressWarnings("unchecked")
@Override
public ComparatorTesterDSLEquals<O, C> withLessSamples(O first) {
return withLessSamples((O[]) new Object[] { first });
}
@SuppressWarnings("unchecked")
@Override
public ComparatorTesterDSLEquals<O, C> withLessSamples(O first, O second) {
return withLessSamples((O[]) new Object[] { first, second });
}
@SuppressWarnings("unchecked")
@Override
public ComparatorTesterDSLEquals<O, C> withLessSamples(O first,
O second, O third) {
return withLessSamples((O[]) new Object[] { first, second, third });
}
@SuppressWarnings("unchecked")
@Override
public ComparatorTesterDSLEquals<O, C> withLessSamples(O first,
O second, O third, O fourth) {
return withLessSamples((O[]) new Object[] { first, second, third,
fourth });
}
@Override
public ComparatorTesterDSLGreater<O, C> withEqualSamples(
O... equalSamples) {
this.equalSamples = equalSamples;
return this;
}
@SuppressWarnings("unchecked")
@Override
public ComparatorTesterDSLGreater<O, C> withEqualSamples(O first) {
return withEqualSamples((O[]) new Object[] { first });
}
@SuppressWarnings("unchecked")
@Override
public ComparatorTesterDSLGreater<O, C> withEqualSamples(O first,
O second) {
return withEqualSamples((O[]) new Object[] { first, second });
}
@SuppressWarnings("unchecked")
@Override
public ComparatorTesterDSLGreater<O, C> withEqualSamples(O first,
O second, O third) {
return withEqualSamples((O[]) new Object[] { first, second, third });
}
@SuppressWarnings("unchecked")
@Override
public ComparatorTesterDSLGreater<O, C> withEqualSamples(O first,
O second, O third, O fourth) {
return withEqualSamples((O[]) new Object[] { first, second, third,
fourth });
}
@Override
public ComparatorTesterDSLEnd<O, C> withGreaterSamples(
O... greaterSamples) {
this.greaterSamples = greaterSamples;
return this;
}
@SuppressWarnings("unchecked")
@Override
public ComparatorTesterDSLEnd<O, C> withGreaterSamples(O first) {
return withGreaterSamples((O[]) new Object[] { first });
}
@SuppressWarnings("unchecked")
@Override
public ComparatorTesterDSLEnd<O, C> withGreaterSamples(O first, O second) {
return withGreaterSamples((O[]) new Object[] { first, second });
}
@SuppressWarnings("unchecked")
@Override
public ComparatorTesterDSLEnd<O, C> withGreaterSamples(O first,
O second, O third) {
return withGreaterSamples((O[]) new Object[] { first, second, third });
}
@SuppressWarnings("unchecked")
@Override
public ComparatorTesterDSLEnd<O, C> withGreaterSamples(O first,
O second, O third, O fourth) {
return withGreaterSamples((O[]) new Object[] { first, second,
third, fourth });
}
@Override
public ComparatorTesterDSLLess<O, C> usingInstance(C instance) {
Objects.requireNonNull(instance, "instance can't be null");
this.underTest = instance;
return this;
}
@Override
public ComparatorTester<O, C> build() {
Supplier<C> comparatorSupplier;
if (underTest == null) {
comparatorSupplier = () -> {
try {
return clazzUnderTest.newInstance();
} catch (InstantiationException | IllegalAccessException e) {
throw new IllegalArgumentException(
"Unable to instanciate the class underTest using the default constructor. Use the usingInstance method to provide an instance",
e);
}
};
} else {
comparatorSupplier = () -> underTest;
}
Supplier<O[]> lessSupplier;
Supplier<O[]> equalsSupplier;
Supplier<O[]> greatSupplier;
if (lessSamples == null) {
SampleProvider<O, C> providers = new SampleProvider<O, C>(
clazzUnderTest, comparatorSupplier);
lessSupplier = providers::getLessSamples;
equalsSupplier = providers::getEqualSamples;
greatSupplier = providers::getGreaterSamples;
} else {
lessSupplier = () -> lessSamples;
equalsSupplier = () -> equalSamples;
greatSupplier = () -> greaterSamples;
}
return new ComparatorTester<O, C>(clazzUnderTest, lessSupplier,
equalsSupplier, greatSupplier, comparatorSupplier);
}
}
private final Class<C> comparatorClass;
private final Supplier<O[]> lessSamples;
private final Supplier<O[]> equalSamples;
private final Supplier<O[]> greaterSamples;
private final Supplier<C> underTest;
private ComparatorTester(Class<C> comparatorClass,
Supplier<O[]> lessSamples, Supplier<O[]> equalSamples,
Supplier<O[]> greaterSamples, Supplier<C> underTest) {
this.comparatorClass = comparatorClass;
this.lessSamples = lessSamples;
this.equalSamples = equalSamples;
this.greaterSamples = greaterSamples;
this.underTest = underTest;
}
/**
* Use this method to start the DSL to test a comparator.
* <p>
* For example :
*
* <pre>
* @TestDelegate
* public final ComparatorTester<Integer, MyComparator> direct = ComparatorTester.of(
* MyComparator.class).withLessSamples(-6).withEqualSamples(12)
* .withGreaterSamples(16).build();
* </pre>
*
* @param clazzUnderTest
* The class of the comparator to be tested.
* @return {@link ComparatorTesterDSLStart the following of the DSL}
* @throws NullPointerException
* when clazzUnderTest is null
* @param <O>
* The object of the comparator
* @param <C>
* The comparator undertest
* @see ch.powerunit.TestDelegate
*/
public static <O, C extends Comparator<O>> ComparatorTesterDSLStart<O, C> of(
final Class<C> clazzUnderTest) {
Objects.requireNonNull(clazzUnderTest, "clazzUnderTest can't be null");
return new ComparatorTesterDSL<O, C>(clazzUnderTest);
}
/**
* Used by the framework.
*
* @return the comparatorClass
*/
public Class<C> getComparatorClass() {
return comparatorClass;
}
/**
* Used by the framework.
*
* @return the lessSamples
*/
public Supplier<O[]> getLessSamples() {
return lessSamples;
}
/**
* Used by the framework.
*
* @return the equalSamples
*/
public Supplier<O[]> getEqualSamples() {
return equalSamples;
}
/**
* Used by the framework.
*
* @return the greaterSamples
*/
public Supplier<O[]> getGreaterSamples() {
return greaterSamples;
}
/**
* Used by the framework.
*
* @return the underTest
*/
public Supplier<C> getUnderTest() {
return underTest;
}
}