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