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.bifunction; 021 022import java.util.ArrayList; 023import java.util.Collections; 024import java.util.List; 025import java.util.Objects; 026import java.util.function.BiFunction; 027import java.util.function.Function; 028import java.util.function.Supplier; 029 030import org.hamcrest.Matcher; 031 032import ch.powerunit.TestInterface; 033import ch.powerunit.bifunction.impl.BiFunctionTesterImpl; 034import ch.powerunit.function.impl.SupplierEqualsToMatcher; 035import ch.powerunit.bifunction.lang.BiFunctionTesterDefineDSL; 036import ch.powerunit.bifunction.lang.BiFunctionTesterEndDSL; 037import ch.powerunit.bifunction.lang.BiFunctionTesterNextDSL; 038import ch.powerunit.bifunction.lang.BiFunctionTesterStartDSL; 039 040/** 041 * Tester for function. 042 * 043 * @author borettim 044 * @since 0.3.0 045 */ 046@TestInterface(BiFunctionTesterImpl.class) 047public final class BiFunctionTester<T, U, R> { 048 private final BiFunction<T, U, R> underTest; 049 private final List<Supplier<T>> input1; 050 private final List<Supplier<U>> input2; 051 private final List<Supplier<Matcher<? super R>>> result; 052 private final List<Supplier<String>> name; 053 054 private static class BiFunctionTesterDSL<T, U, R> implements 055 BiFunctionTesterDefineDSL<T, U, R>, 056 BiFunctionTesterEndDSL<T, U, R>, BiFunctionTesterNextDSL<T, U, R>, 057 BiFunctionTesterStartDSL<T, U, R> { 058 059 private final BiFunction<T, U, R> underTest; 060 061 private List<Supplier<T>> tmpInput1 = new ArrayList<>(); 062 063 private List<Supplier<U>> tmpInput2 = new ArrayList<>(); 064 065 private List<Supplier<Matcher<? super R>>> tmpResult = new ArrayList<>(); 066 067 private List<Supplier<String>> tmpName = new ArrayList<>(); 068 069 private void finalizeCase() { 070 if (tmpName.size() < tmpInput1.size()) { 071 tmpName.add(() -> ""); 072 } 073 } 074 075 public BiFunctionTesterDSL(BiFunction<T, U, R> underTest) { 076 this.underTest = underTest; 077 } 078 079 @Override 080 public BiFunctionTesterDefineDSL<T, U, R> passingAsParameter(T input1, 081 U input2) { 082 return passingAsParameter(() -> input1, () -> input2); 083 } 084 085 @Override 086 public BiFunctionTesterDefineDSL<T, U, R> passingAsParameter( 087 Supplier<T> input1, Supplier<U> input2) { 088 Objects.requireNonNull(input1, "input1 can't be null"); 089 Objects.requireNonNull(input2, "input2 can't be null"); 090 finalizeCase(); 091 tmpInput1.add(input1); 092 tmpInput2.add(input2); 093 return this; 094 } 095 096 @Override 097 public BiFunctionTesterNextDSL<T, U, R> thenExpectingResult(R result) { 098 return thenExpectingResult(() -> result); 099 } 100 101 @Override 102 public BiFunctionTesterNextDSL<T, U, R> thenExpectingResult( 103 Supplier<R> result) { 104 Objects.requireNonNull(result, "matching can't be null"); 105 return thenExpectingResultThat(new SupplierEqualsToMatcher<R>( 106 result)); 107 } 108 109 @Override 110 public BiFunctionTesterNextDSL<T, U, R> thenExpectingResultThat( 111 Matcher<? super R> matching) { 112 Objects.requireNonNull(matching, "matching can't be null"); 113 return thenExpectingResultThat(() -> matching); 114 } 115 116 @Override 117 public BiFunctionTesterNextDSL<T, U, R> thenExpectingResultThat( 118 Supplier<Matcher<? super R>> matching) { 119 Objects.requireNonNull(matching, "matching can't be null"); 120 tmpResult.add(matching); 121 return this; 122 } 123 124 @Override 125 public BiFunctionTesterEndDSL<T, U, R> testNamed(String name) { 126 return testNamed(() -> name); 127 } 128 129 @Override 130 public BiFunctionTesterEndDSL<T, U, R> testNamed(Supplier<String> name) { 131 Objects.requireNonNull(name, "name can't be null"); 132 tmpName.add(name); 133 return this; 134 } 135 136 @Override 137 public BiFunctionTester<T, U, R> build() { 138 finalizeCase(); 139 return new BiFunctionTester<T, U, R>(underTest, tmpInput1, 140 tmpInput2, tmpResult, tmpName); 141 } 142 } 143 144 private BiFunctionTester(BiFunction<T, U, R> underTest, 145 List<Supplier<T>> tmpInput1, List<Supplier<U>> tmpInput2, 146 List<Supplier<Matcher<? super R>>> tmpResult, 147 List<Supplier<String>> tmpName) { 148 this.underTest = underTest; 149 this.input1 = tmpInput1; 150 this.input2 = tmpInput2; 151 this.result = tmpResult; 152 this.name = tmpName; 153 } 154 155 /** 156 * Start the creation of a tester of function. 157 * 158 * @param bifunctionUnderTest 159 * the function to be tested 160 * @return {@link BiFunctionTesterStartDSL the DSL} 161 * @throws NullPointerException 162 * when bifunctionUnderTest is null 163 * @param <T> 164 * the first input argument type 165 * @param <U> 166 * the second input argument type 167 * @param <R> 168 * the result type 169 * @see ch.powerunit.TestDelegate 170 */ 171 public static <T, U, R> BiFunctionTesterStartDSL<T, U, R> of( 172 BiFunction<T, U, R> bifunctionUnderTest) { 173 Objects.requireNonNull(bifunctionUnderTest, 174 "bifunctionUnderTest can't be null"); 175 return new BiFunctionTesterDSL<T, U, R>(bifunctionUnderTest); 176 } 177 178 /** 179 * Used by the framework. 180 * 181 * @return the underTest 182 */ 183 public BiFunction<T, U, R> getUnderTest() { 184 return underTest; 185 } 186 187 /** 188 * Used by the framework. 189 * 190 * @return the first input 191 */ 192 public List<Supplier<T>> getInput1() { 193 return Collections.unmodifiableList(input1); 194 } 195 196 /** 197 * Used by the framework. 198 * 199 * @return the first input 200 */ 201 public List<Supplier<U>> getInput2() { 202 return Collections.unmodifiableList(input2); 203 } 204 205 /** 206 * Used by the framework. 207 * 208 * @return the result 209 */ 210 public List<Supplier<Matcher<? super R>>> getResult() { 211 return Collections.unmodifiableList(result); 212 } 213 214 /** 215 * Used by the framework. 216 * 217 * @return the name 218 */ 219 public List<Supplier<String>> getName() { 220 return Collections.unmodifiableList(name); 221 } 222 223}