001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.apache.juneau.bct.assertions; 018 019import static org.apache.juneau.commons.utils.Shorts.*; 020 021import java.io.*; 022import java.util.function.*; 023 024import org.apache.juneau.commons.function.*; 025 026 027/** 028 * Used for fluent assertion calls against comparable objects. 029 * 030 * <h5 class='section'>Test Methods:</h5> 031 * <p> 032 * <ul class='javatree'> 033 * <li class='jc'>{@link FluentComparableAssertion} 034 * <ul class='javatreec'> 035 * <li class='jm'>{@link FluentComparableAssertion#isGt(Comparable) isGt(Comparable)} 036 * <li class='jm'>{@link FluentComparableAssertion#isGte(Comparable) isGte(Comparable)} 037 * <li class='jm'>{@link FluentComparableAssertion#isLt(Comparable) isLt(Comparable)} 038 * <li class='jm'>{@link FluentComparableAssertion#isLte(Comparable) isLte(Comparable)} 039 * <li class='jm'>{@link FluentComparableAssertion#isBetween(Comparable,Comparable) isBetween(Comparable,Comparable)} 040 * </ul> 041 * <li class='jc'>{@link FluentObjectAssertion} 042 * <ul class='javatreec'> 043 * <li class='jm'>{@link FluentObjectAssertion#isExists() isExists()} 044 * <li class='jm'>{@link FluentObjectAssertion#is(Object) is(Object)} 045 * <li class='jm'>{@link FluentObjectAssertion#is(Predicate) is(Predicate)} 046 * <li class='jm'>{@link FluentObjectAssertion#isNot(Object) isNot(Object)} 047 * <li class='jm'>{@link FluentObjectAssertion#isAny(Object...) isAny(Object...)} 048 * <li class='jm'>{@link FluentObjectAssertion#isNotAny(Object...) isNotAny(Object...)} 049 * <li class='jm'>{@link FluentObjectAssertion#isNull() isNull()} 050 * <li class='jm'>{@link FluentObjectAssertion#isNotNull() isNotNull()} 051 * <li class='jm'>{@link FluentObjectAssertion#isString(String) isString(String)} 052 * <li class='jm'>{@link FluentObjectAssertion#isSame(Object) isSame(Object)} 053 * <li class='jm'>{@link FluentObjectAssertion#isType(Class) isType(Class)} 054 * <li class='jm'>{@link FluentObjectAssertion#isExactType(Class) isExactType(Class)} 055 * </ul> 056 * </ul> 057 * 058 * <h5 class='section'>Transform Methods:</h5> 059 * <p> 060 * <ul class='javatree'> 061 * <li class='jc'>{@link FluentObjectAssertion} 062 * <ul class='javatreec'> 063 * <li class='jm'>{@link FluentObjectAssertion#asString() asString()} 064 * <li class='jm'>{@link FluentObjectAssertion#asString(ThrowingFunction) asString(ThrowingFunction)} 065 * <li class='jm'>{@link FluentObjectAssertion#asTransformed(UnaryOperator) asTransformed(UnaryOperator)} 066 * <li class='jm'>{@link FluentObjectAssertion#asAny() asAny()} 067 * </ul> 068 * </ul> 069 * 070 * <h5 class='section'>Configuration Methods:</h5> 071 * <p> 072 * <ul class='javatree'> 073 * <li class='jc'>{@link Assertion} 074 * <ul class='javatreec'> 075 * <li class='jm'>{@link Assertion#setMsg(String, Object...) setMsg(String, Object...)} 076 * <li class='jm'>{@link Assertion#setOut(PrintStream) setOut(PrintStream)} 077 * <li class='jm'>{@link Assertion#setSilent() setSilent()} 078 * <li class='jm'>{@link Assertion#setStdOut() setStdOut()} 079 * <li class='jm'>{@link Assertion#setThrowable(Class) setThrowable(Class)} 080 * </ul> 081 * </ul> 082 * 083 * <h5 class='section'>See Also:</h5><ul> 084 * <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/JuneauEcosystemOverview">Juneau Ecosystem</a> 085 * </ul> 086 * 087 * @param <T> The value type 088 * @param <R> The return type. 089 */ 090@SuppressWarnings({ 091 "java:S115", // Constants use UPPER_snakeCase naming convention 092 "java:S1192", // Duplicated literals (argument/property names) read more clearly inline than as constants 093 "rawtypes", // Raw Comparable type necessary for flexible comparison API without self-referencing type constraints 094 "unchecked" // Type erasure requires cast for comparable comparison 095}) 096public class FluentComparableAssertion<T extends Comparable,R> extends FluentObjectAssertion<T,R> { 097 098 private static final Messages MESSAGES = Messages.of(FluentComparableAssertion.class, "Messages"); 099 private static final String MSG_valueWasNotGreaterThanExpected = MESSAGES.getString("valueWasNotGreaterThanExpected"); 100 private static final String MSG_valueWasNotGreaterOrEqualsToExpected = MESSAGES.getString("valueWasNotGreaterOrEqualsToExpected"); 101 private static final String MSG_valueWasNotLessThanExpected = MESSAGES.getString("valueWasNotLessThanExpected"); 102 private static final String MSG_valueWasNotLessOrEqualsToExpected = MESSAGES.getString("valueWasNotLessOrEqualsToExpected"); 103 104 /** 105 * Chained constructor. 106 * 107 * <p> 108 * Used when transforming one assertion into another so that the assertion config can be used by the new assertion. 109 * 110 * @param creator 111 * The assertion that created this assertion. 112 * <br>Should be <jk>null</jk> if this is the top-level assertion. 113 * @param value 114 * The object being tested. 115 * <br>Can be <jk>null</jk> (assertions such as {@code isNull()} then operate on the absence of a value). 116 * @param returns 117 * The object to return after a test method is called. 118 * <br>If <jk>null</jk>, the test method returns this object allowing multiple test method calls to be 119 * used on the same assertion. 120 */ 121 public FluentComparableAssertion(Assertion creator, T value, R returns) { 122 super(creator, value, returns); 123 } 124 125 /** 126 * Constructor. 127 * 128 * @param value 129 * The object being tested. 130 * <br>Can be <jk>null</jk> (assertions such as {@code isNull()} then operate on the absence of a value). 131 * @param returns 132 * The object to return after a test method is called. 133 * <br>If <jk>null</jk>, the test method returns this object allowing multiple test method calls to be 134 * used on the same assertion. 135 */ 136 public FluentComparableAssertion(T value, R returns) { 137 this(null, value, returns); 138 } 139 140 @Override /* Overridden from FluentObjectAssertion */ 141 public FluentComparableAssertion<T,R> asTransformed(UnaryOperator<T> function) { 142 return new FluentComparableAssertion<>(this, function.apply(orElse(null)), returns()); 143 } 144 145 /** 146 * Asserts that the value is between (inclusive) the specified upper and lower values. 147 * 148 * @param lower The lower value to check against. 149 * @param upper The upper value to check against. 150 * @return The fluent return object. 151 * @throws AssertionError If assertion failed. 152 */ 153 public R isBetween(Comparable lower, Comparable upper) throws AssertionError { 154 isExists(); 155 reqnn("lower", lower); 156 reqnn("upper", upper); 157 isLte(upper); 158 isGte(lower); 159 return returns(); 160 } 161 162 /** 163 * Asserts that the value is greater than the specified value. 164 * 165 * @param value The values to check against. 166 * @return The fluent return object. 167 * @throws AssertionError If assertion failed. 168 */ 169 public R isGt(Comparable value) throws AssertionError { 170 reqnn("value", value); 171 if (value().compareTo(value) <= 0) 172 throw error(MSG_valueWasNotGreaterThanExpected, r(value), r(value())); 173 return returns(); 174 } 175 176 /** 177 * Asserts that the value is greater than or equal to the specified value. 178 * 179 * @param value The values to check against. 180 * @return The fluent return object. 181 * @throws AssertionError If assertion failed. 182 */ 183 public R isGte(Comparable value) throws AssertionError { 184 reqnn("value", value); 185 if (value().compareTo(value) < 0) 186 throw error(MSG_valueWasNotGreaterOrEqualsToExpected, r(value), r(value())); 187 return returns(); 188 } 189 190 /** 191 * Asserts that the value is less than the specified value. 192 * 193 * @param value The values to check against. 194 * @return The fluent return object. 195 * @throws AssertionError If assertion failed. 196 */ 197 public R isLt(Comparable value) throws AssertionError { 198 reqnn("value", value); 199 if (value().compareTo(value) >= 0) 200 throw error(MSG_valueWasNotLessThanExpected, r(value), r(value())); 201 return returns(); 202 } 203 204 /** 205 * Asserts that the value is less than or equals to the specified value. 206 * 207 * @param value The values to check against. 208 * @return The fluent return object. 209 * @throws AssertionError If assertion failed. 210 */ 211 public R isLte(Comparable value) throws AssertionError { 212 reqnn("value", value); 213 if (value().compareTo(value) > 0) 214 throw error(MSG_valueWasNotLessOrEqualsToExpected, r(value), r(value())); 215 return returns(); 216 } 217 218 @Override /* Overridden from Assertion */ 219 public FluentComparableAssertion<T,R> setMsg(String msg, Object...args) { 220 super.setMsg(msg, args); 221 return this; 222 } 223 224 @Override /* Overridden from Assertion */ 225 public FluentComparableAssertion<T,R> setOut(PrintStream value) { 226 super.setOut(value); 227 return this; 228 } 229 230 @Override /* Overridden from Assertion */ 231 public FluentComparableAssertion<T,R> setSilent() { 232 super.setSilent(); 233 return this; 234 } 235 236 @Override /* Overridden from Assertion */ 237 public FluentComparableAssertion<T,R> setStdOut() { 238 super.setStdOut(); 239 return this; 240 } 241 242 @Override /* Overridden from Assertion */ 243 public FluentComparableAssertion<T,R> setThrowable(Class<? extends RuntimeException> value) { 244 super.setThrowable(value); 245 return this; 246 } 247}