001/** 002 * Powerunit - A JDK1.8 test framework 003 * Copyright (C) 2014 Mathieu Boretti. 004 * 005 * This file is part of Powerunit 006 * 007 * Powerunit is free software: you can redistribute it and/or modify 008 * it under the terms of the GNU General Public License as published by 009 * the Free Software Foundation, either version 3 of the License, or 010 * (at your option) any later version. 011 * 012 * Powerunit is distributed in the hope that it will be useful, 013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 015 * GNU General Public License for more details. 016 * 017 * You should have received a copy of the GNU General Public License 018 * along with Powerunit. If not, see <http://www.gnu.org/licenses/>. 019 */ 020package ch.powerunit.comparator; 021 022import java.util.Comparator; 023import java.util.Objects; 024import java.util.function.Supplier; 025 026import ch.powerunit.TestInterface; 027import ch.powerunit.comparator.impl.ComparatorTesterImpl; 028import ch.powerunit.comparator.impl.SampleProvider; 029import ch.powerunit.comparator.lang.ComparatorTesterDSLEnd; 030import ch.powerunit.comparator.lang.ComparatorTesterDSLEquals; 031import ch.powerunit.comparator.lang.ComparatorTesterDSLGreater; 032import ch.powerunit.comparator.lang.ComparatorTesterDSLLess; 033import ch.powerunit.comparator.lang.ComparatorTesterDSLStart; 034 035/** 036 * This is a framework to simplify the testing of {@link Comparator}. 037 * 038 * @author borettim 039 * @since 0.3.0 040 * @param <O> 041 * The object of the comparator 042 * @param <C> 043 * The comparator undertest 044 */ 045@TestInterface(ComparatorTesterImpl.class) 046public final class ComparatorTester<O, C extends Comparator<O>> { 047 private static class ComparatorTesterDSL<O, C extends Comparator<O>> 048 implements ComparatorTesterDSLStart<O, C>, 049 ComparatorTesterDSLLess<O, C>, ComparatorTesterDSLEquals<O, C>, 050 ComparatorTesterDSLGreater<O, C>, ComparatorTesterDSLEnd<O, C> { 051 private final Class<C> clazzUnderTest; 052 private O lessSamples[]; 053 private O equalSamples[]; 054 private O greaterSamples[]; 055 private C underTest; 056 057 public ComparatorTesterDSL(Class<C> clazzUnderTest) { 058 this.clazzUnderTest = clazzUnderTest; 059 } 060 061 @Override 062 public ComparatorTesterDSLEquals<O, C> withLessSamples(O... lessSamples) { 063 this.lessSamples = lessSamples; 064 return this; 065 } 066 067 @SuppressWarnings("unchecked") 068 @Override 069 public ComparatorTesterDSLEquals<O, C> withLessSamples(O first) { 070 return withLessSamples((O[]) new Object[] { first }); 071 } 072 073 @SuppressWarnings("unchecked") 074 @Override 075 public ComparatorTesterDSLEquals<O, C> withLessSamples(O first, O second) { 076 return withLessSamples((O[]) new Object[] { first, second }); 077 } 078 079 @SuppressWarnings("unchecked") 080 @Override 081 public ComparatorTesterDSLEquals<O, C> withLessSamples(O first, 082 O second, O third) { 083 return withLessSamples((O[]) new Object[] { first, second, third }); 084 } 085 086 @SuppressWarnings("unchecked") 087 @Override 088 public ComparatorTesterDSLEquals<O, C> withLessSamples(O first, 089 O second, O third, O fourth) { 090 return withLessSamples((O[]) new Object[] { first, second, third, 091 fourth }); 092 } 093 094 @Override 095 public ComparatorTesterDSLGreater<O, C> withEqualSamples( 096 O... equalSamples) { 097 this.equalSamples = equalSamples; 098 return this; 099 } 100 101 @SuppressWarnings("unchecked") 102 @Override 103 public ComparatorTesterDSLGreater<O, C> withEqualSamples(O first) { 104 return withEqualSamples((O[]) new Object[] { first }); 105 } 106 107 @SuppressWarnings("unchecked") 108 @Override 109 public ComparatorTesterDSLGreater<O, C> withEqualSamples(O first, 110 O second) { 111 return withEqualSamples((O[]) new Object[] { first, second }); 112 } 113 114 @SuppressWarnings("unchecked") 115 @Override 116 public ComparatorTesterDSLGreater<O, C> withEqualSamples(O first, 117 O second, O third) { 118 return withEqualSamples((O[]) new Object[] { first, second, third }); 119 } 120 121 @SuppressWarnings("unchecked") 122 @Override 123 public ComparatorTesterDSLGreater<O, C> withEqualSamples(O first, 124 O second, O third, O fourth) { 125 return withEqualSamples((O[]) new Object[] { first, second, third, 126 fourth }); 127 } 128 129 @Override 130 public ComparatorTesterDSLEnd<O, C> withGreaterSamples( 131 O... greaterSamples) { 132 this.greaterSamples = greaterSamples; 133 return this; 134 } 135 136 @SuppressWarnings("unchecked") 137 @Override 138 public ComparatorTesterDSLEnd<O, C> withGreaterSamples(O first) { 139 return withGreaterSamples((O[]) new Object[] { first }); 140 } 141 142 @SuppressWarnings("unchecked") 143 @Override 144 public ComparatorTesterDSLEnd<O, C> withGreaterSamples(O first, O second) { 145 return withGreaterSamples((O[]) new Object[] { first, second }); 146 } 147 148 @SuppressWarnings("unchecked") 149 @Override 150 public ComparatorTesterDSLEnd<O, C> withGreaterSamples(O first, 151 O second, O third) { 152 return withGreaterSamples((O[]) new Object[] { first, second, third }); 153 } 154 155 @SuppressWarnings("unchecked") 156 @Override 157 public ComparatorTesterDSLEnd<O, C> withGreaterSamples(O first, 158 O second, O third, O fourth) { 159 return withGreaterSamples((O[]) new Object[] { first, second, 160 third, fourth }); 161 } 162 163 @Override 164 public ComparatorTesterDSLLess<O, C> usingInstance(C instance) { 165 Objects.requireNonNull(instance, "instance can't be null"); 166 this.underTest = instance; 167 return this; 168 } 169 170 @Override 171 public ComparatorTester<O, C> build() { 172 Supplier<C> comparatorSupplier; 173 if (underTest == null) { 174 comparatorSupplier = () -> { 175 try { 176 return clazzUnderTest.newInstance(); 177 } catch (InstantiationException | IllegalAccessException e) { 178 throw new IllegalArgumentException( 179 "Unable to instanciate the class underTest using the default constructor. Use the usingInstance method to provide an instance", 180 e); 181 } 182 }; 183 } else { 184 comparatorSupplier = () -> underTest; 185 } 186 Supplier<O[]> lessSupplier; 187 Supplier<O[]> equalsSupplier; 188 Supplier<O[]> greatSupplier; 189 if (lessSamples == null) { 190 SampleProvider<O, C> providers = new SampleProvider<O, C>( 191 clazzUnderTest, comparatorSupplier); 192 lessSupplier = providers::getLessSamples; 193 equalsSupplier = providers::getEqualSamples; 194 greatSupplier = providers::getGreaterSamples; 195 } else { 196 lessSupplier = () -> lessSamples; 197 equalsSupplier = () -> equalSamples; 198 greatSupplier = () -> greaterSamples; 199 } 200 return new ComparatorTester<O, C>(clazzUnderTest, lessSupplier, 201 equalsSupplier, greatSupplier, comparatorSupplier); 202 } 203 } 204 205 private final Class<C> comparatorClass; 206 207 private final Supplier<O[]> lessSamples; 208 209 private final Supplier<O[]> equalSamples; 210 211 private final Supplier<O[]> greaterSamples; 212 213 private final Supplier<C> underTest; 214 215 private ComparatorTester(Class<C> comparatorClass, 216 Supplier<O[]> lessSamples, Supplier<O[]> equalSamples, 217 Supplier<O[]> greaterSamples, Supplier<C> underTest) { 218 this.comparatorClass = comparatorClass; 219 this.lessSamples = lessSamples; 220 this.equalSamples = equalSamples; 221 this.greaterSamples = greaterSamples; 222 this.underTest = underTest; 223 } 224 225 /** 226 * Use this method to start the DSL to test a comparator. 227 * <p> 228 * For example : 229 * 230 * <pre> 231 * @TestDelegate 232 * public final ComparatorTester<Integer, MyComparator> direct = ComparatorTester.of( 233 * MyComparator.class).withLessSamples(-6).withEqualSamples(12) 234 * .withGreaterSamples(16).build(); 235 * </pre> 236 * 237 * @param clazzUnderTest 238 * The class of the comparator to be tested. 239 * @return {@link ComparatorTesterDSLStart the following of the DSL} 240 * @throws NullPointerException 241 * when clazzUnderTest is null 242 * @param <O> 243 * The object of the comparator 244 * @param <C> 245 * The comparator undertest 246 * @see ch.powerunit.TestDelegate 247 */ 248 public static <O, C extends Comparator<O>> ComparatorTesterDSLStart<O, C> of( 249 final Class<C> clazzUnderTest) { 250 Objects.requireNonNull(clazzUnderTest, "clazzUnderTest can't be null"); 251 return new ComparatorTesterDSL<O, C>(clazzUnderTest); 252 } 253 254 /** 255 * Used by the framework. 256 * 257 * @return the comparatorClass 258 */ 259 public Class<C> getComparatorClass() { 260 return comparatorClass; 261 } 262 263 /** 264 * Used by the framework. 265 * 266 * @return the lessSamples 267 */ 268 public Supplier<O[]> getLessSamples() { 269 return lessSamples; 270 } 271 272 /** 273 * Used by the framework. 274 * 275 * @return the equalSamples 276 */ 277 public Supplier<O[]> getEqualSamples() { 278 return equalSamples; 279 } 280 281 /** 282 * Used by the framework. 283 * 284 * @return the greaterSamples 285 */ 286 public Supplier<O[]> getGreaterSamples() { 287 return greaterSamples; 288 } 289 290 /** 291 * Used by the framework. 292 * 293 * @return the underTest 294 */ 295 public Supplier<C> getUnderTest() { 296 return underTest; 297 } 298}