001// *************************************************************************************************************************** 002// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file * 003// * distributed with this work for additional information regarding copyright ownership. The ASF licenses this file * 004// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance * 005// * with the License. You may obtain a copy of the License at * 006// * * 007// * http://www.apache.org/licenses/LICENSE-2.0 * 008// * * 009// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an * 010// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the * 011// * specific language governing permissions and limitations under the License. * 012// *************************************************************************************************************************** 013package org.apache.juneau.assertions; 014 015import static org.apache.juneau.common.internal.ArgUtils.*; 016 017import java.io.*; 018import java.time.*; 019import java.util.*; 020import java.util.function.*; 021 022import org.apache.juneau.*; 023import org.apache.juneau.cp.*; 024import org.apache.juneau.internal.*; 025import org.apache.juneau.reflect.*; 026import org.apache.juneau.serializer.*; 027 028/** 029 * Used for assertion calls against generic POJOs. 030 * 031 * <p> 032 * Extends from {@link FluentObjectAssertion} allowing you to perform basic assertions, but adds several transform 033 * methods to convert to more-specific assertion types. 034 * 035 * <h5 class='section'>Example:</h5> 036 * <p class='bjava'> 037 * <jk>import static</jk> org.apache.juneau.assertions.Assertions.*; 038 * 039 * List<MyBean> <jv>listOfBeans</jv> = ...; 040 * <jsm>assertList</jsm>(<jv>listOfBeans</jv>) 041 * .asItem(1) <jc>// Returns an AnyAssertion.</jc> 042 * .asBean() <jc>// Transforms to BeanAssertion.</jc> 043 * .asProperty(<js>"foo"</js>) <jc>// Returns an AnyAssertion.</jc> 044 * .asString() <jc>// Transforms to StringAssertion.</jc> 045 * .is(<js>"bar"</js>); <jc>// Performs test.</jc> 046 * </p> 047 * 048 * <h5 class='section'>Test Methods:</h5> 049 * <p> 050 * <ul class='javatree'> 051 * <li class='jc'>{@link FluentObjectAssertion} 052 * <ul class='javatreec'> 053 * <li class='jm'>{@link FluentObjectAssertion#isExists() isExists()} 054 * <li class='jm'>{@link FluentObjectAssertion#is(Object) is(Object)} 055 * <li class='jm'>{@link FluentObjectAssertion#is(Predicate) is(Predicate)} 056 * <li class='jm'>{@link FluentObjectAssertion#isNot(Object) isNot(Object)} 057 * <li class='jm'>{@link FluentObjectAssertion#isAny(Object...) isAny(Object...)} 058 * <li class='jm'>{@link FluentObjectAssertion#isNotAny(Object...) isNotAny(Object...)} 059 * <li class='jm'>{@link FluentObjectAssertion#isNull() isNull()} 060 * <li class='jm'>{@link FluentObjectAssertion#isNotNull() isNotNull()} 061 * <li class='jm'>{@link FluentObjectAssertion#isString(String) isString(String)} 062 * <li class='jm'>{@link FluentObjectAssertion#isJson(String) isJson(String)} 063 * <li class='jm'>{@link FluentObjectAssertion#isSame(Object) isSame(Object)} 064 * <li class='jm'>{@link FluentObjectAssertion#isSameJsonAs(Object) isSameJsonAs(Object)} 065 * <li class='jm'>{@link FluentObjectAssertion#isSameSortedJsonAs(Object) isSameSortedJsonAs(Object)} 066 * <li class='jm'>{@link FluentObjectAssertion#isSameSerializedAs(Object, WriterSerializer) isSameSerializedAs(Object, WriterSerializer)} 067 * <li class='jm'>{@link FluentObjectAssertion#isType(Class) isType(Class)} 068 * <li class='jm'>{@link FluentObjectAssertion#isExactType(Class) isExactType(Class)} 069 * </ul> 070 * </ul> 071 * 072 * <h5 class='section'>Transform Methods:</h5> 073 * <p> 074 * <ul class='javatree'> 075 * <li class='jc'>{@link FluentAnyAssertion} 076 * <ul class='javatreec'> 077 * <li class='jm'>{@link FluentAnyAssertion#asArray(Class) asArray(Class)} 078 * <li class='jm'>{@link FluentAnyAssertion#asIntArray() asIntArray()} 079 * <li class='jm'>{@link FluentAnyAssertion#asLongArray() asLongArray()} 080 * <li class='jm'>{@link FluentAnyAssertion#asShortArray() asShortArray()} 081 * <li class='jm'>{@link FluentAnyAssertion#asFloatArray() asFloatArray()} 082 * <li class='jm'>{@link FluentAnyAssertion#asDoubleArray() asDoubleArray()} 083 * <li class='jm'>{@link FluentAnyAssertion#asCharArray() asCharArray()} 084 * <li class='jm'>{@link FluentAnyAssertion#asByteArray() asByteArray()} 085 * <li class='jm'>{@link FluentAnyAssertion#asBooleanArray() asBooleanArray()} 086 * <li class='jm'>{@link FluentAnyAssertion#asBoolean() asBoolean()} 087 * <li class='jm'>{@link FluentAnyAssertion#asBytes() asBytes()} 088 * <li class='jm'>{@link FluentAnyAssertion#asCollection() asCollection()} 089 * <li class='jm'>{@link FluentAnyAssertion#asCollection(Class) asCollection(Class)} 090 * <li class='jm'>{@link FluentAnyAssertion#asStringList() asStringList()} 091 * <li class='jm'>{@link FluentAnyAssertion#asComparable() asComparable()} 092 * <li class='jm'>{@link FluentAnyAssertion#asDate() asDate()} 093 * <li class='jm'>{@link FluentAnyAssertion#asInteger() asInteger()} 094 * <li class='jm'>{@link FluentAnyAssertion#asLong() asLong()} 095 * <li class='jm'>{@link FluentAnyAssertion#asList() asList()} 096 * <li class='jm'>{@link FluentAnyAssertion#asList(Class) asList(Class)} 097 * <li class='jm'>{@link FluentAnyAssertion#asMap() asMap()} 098 * <li class='jm'>{@link FluentAnyAssertion#asMap(Class,Class) asMap(Class,Class)} 099 * <li class='jm'>{@link FluentAnyAssertion#asBean() asBean()} 100 * <li class='jm'>{@link FluentAnyAssertion#asBean(Class) asBean(Class)} 101 * <li class='jm'>{@link FluentAnyAssertion#asBeanList(Class) asBeanList(Class)} 102 * <li class='jm'>{@link FluentAnyAssertion#asZonedDateTime() asZonedDateTime()} 103 * </ul> 104 * <li class='jc'>{@link FluentObjectAssertion} 105 * <ul class='javatreec'> 106 * <li class='jm'>{@link FluentObjectAssertion#asString() asString()} 107 * <li class='jm'>{@link FluentObjectAssertion#asString(WriterSerializer) asString(WriterSerializer)} 108 * <li class='jm'>{@link FluentObjectAssertion#asString(Function) asString(Function)} 109 * <li class='jm'>{@link FluentObjectAssertion#asJson() asJson()} 110 * <li class='jm'>{@link FluentObjectAssertion#asJsonSorted() asJsonSorted()} 111 * <li class='jm'>{@link FluentObjectAssertion#asTransformed(Function) asApplied(Function)} 112 * <li class='jm'>{@link FluentObjectAssertion#asAny() asAny()} 113 * </ul> 114 * </ul> 115 * 116 * <h5 class='section'>Configuration Methods:</h5> 117 * <p> 118 * <ul class='javatree'> 119 * <li class='jc'>{@link Assertion} 120 * <ul class='javatreec'> 121 * <li class='jm'>{@link Assertion#setMsg(String, Object...) setMsg(String, Object...)} 122 * <li class='jm'>{@link Assertion#setOut(PrintStream) setOut(PrintStream)} 123 * <li class='jm'>{@link Assertion#setSilent() setSilent()} 124 * <li class='jm'>{@link Assertion#setStdOut() setStdOut()} 125 * <li class='jm'>{@link Assertion#setThrowable(Class) setThrowable(Class)} 126 * </ul> 127 * </ul> 128 * 129 * <h5 class='section'>See Also:</h5><ul> 130 * <li class='link'><a class="doclink" href="../../../../index.html#ja.Overview">Overview > juneau-assertions > Overview</a> 131 * </ul> 132 * 133 * @param <T> The object type. 134 * @param <R> The return type. 135 */ 136@FluentSetters(returns="FluentAnyAssertion<T,R>") 137public class FluentAnyAssertion<T,R> extends FluentObjectAssertion<T,R> { 138 139 //----------------------------------------------------------------------------------------------------------------- 140 // Static 141 //----------------------------------------------------------------------------------------------------------------- 142 143 private static final Messages MESSAGES = Messages.of(FluentAnyAssertion.class, "Messages"); 144 private static final String 145 MSG_objectWasNotType = MESSAGES.getString("objectWasNotType"); 146 147 //----------------------------------------------------------------------------------------------------------------- 148 // Instance 149 //----------------------------------------------------------------------------------------------------------------- 150 151 /** 152 * Constructor. 153 * 154 * @param value 155 * The object being tested. 156 * <br>Can be <jk>null</jk>. 157 * @param returns 158 * The object to return after a test method is called. 159 * <br>If <jk>null</jk>, the test method returns this object allowing multiple test method calls to be 160 * used on the same assertion. 161 */ 162 public FluentAnyAssertion(T value, R returns) { 163 this(null, value, returns); 164 } 165 166 /** 167 * Chained constructor. 168 * 169 * <p> 170 * Used when transforming one assertion into another so that the assertion config can be used by the new assertion. 171 * 172 * @param creator 173 * The assertion that created this assertion. 174 * <br>Should be <jk>null</jk> if this is the top-level assertion. 175 * @param value 176 * The object being tested. 177 * <br>Can be <jk>null</jk>. 178 * @param returns 179 * The object to return after a test method is called. 180 * <br>If <jk>null</jk>, the test method returns this object allowing multiple test method calls to be 181 * used on the same assertion. 182 */ 183 public FluentAnyAssertion(Assertion creator, T value, R returns) { 184 super(creator, value, returns); 185 } 186 187 //----------------------------------------------------------------------------------------------------------------- 188 // Transform methods 189 //----------------------------------------------------------------------------------------------------------------- 190 191 /** 192 * Converts this object assertion into an array assertion. 193 * 194 * @param <E> The element type of the array. 195 * @param elementType The element type of the array. 196 * @return A new assertion. 197 * @throws AssertionError If object is not an array. 198 */ 199 public <E> FluentArrayAssertion<E,R> asArray(Class<E> elementType) throws AssertionError { 200 assertArgNotNull("elementType", elementType); 201 return new FluentArrayAssertion<>(this, cast(arrayClass(elementType)), returns()); 202 } 203 204 /** 205 * Converts this object assertion into a primitive int array assertion. 206 * 207 * @return A new assertion. 208 * @throws AssertionError If object is not an int array. 209 */ 210 public FluentPrimitiveArrayAssertion<Integer,int[],R> asIntArray() throws AssertionError { 211 return new FluentPrimitiveArrayAssertion<>(this, cast(int[].class), returns()); 212 } 213 214 /** 215 * Converts this object assertion into a primitive long array assertion. 216 * 217 * @return A new assertion. 218 * @throws AssertionError If object is not an long array. 219 */ 220 public FluentPrimitiveArrayAssertion<Long,long[],R> asLongArray() throws AssertionError { 221 return new FluentPrimitiveArrayAssertion<>(this, cast(long[].class), returns()); 222 } 223 224 /** 225 * Converts this object assertion into a primitive short array assertion. 226 * 227 * @return A new assertion. 228 * @throws AssertionError If object is not an short array. 229 */ 230 public FluentPrimitiveArrayAssertion<Short,short[],R> asShortArray() throws AssertionError { 231 return new FluentPrimitiveArrayAssertion<>(this, cast(short[].class), returns()); 232 } 233 234 /** 235 * Converts this object assertion into a primitive float array assertion. 236 * 237 * @return A new assertion. 238 * @throws AssertionError If object is not an float array. 239 */ 240 public FluentPrimitiveArrayAssertion<Float,float[],R> asFloatArray() throws AssertionError { 241 return new FluentPrimitiveArrayAssertion<>(this, cast(float[].class), returns()); 242 } 243 244 /** 245 * Converts this object assertion into a primitive double array assertion. 246 * 247 * @return A new assertion. 248 * @throws AssertionError If object is not an double array. 249 */ 250 public FluentPrimitiveArrayAssertion<Double,double[],R> asDoubleArray() throws AssertionError { 251 return new FluentPrimitiveArrayAssertion<>(this, cast(double[].class), returns()); 252 } 253 254 /** 255 * Converts this object assertion into a primitive char array assertion. 256 * 257 * @return A new assertion. 258 * @throws AssertionError If object is not an char array. 259 */ 260 public FluentPrimitiveArrayAssertion<Character,char[],R> asCharArray() throws AssertionError { 261 return new FluentPrimitiveArrayAssertion<>(this, cast(char[].class), returns()); 262 } 263 264 /** 265 * Converts this object assertion into a primitive byte array assertion. 266 * 267 * @return A new assertion. 268 * @throws AssertionError If object is not an byte array. 269 */ 270 public FluentPrimitiveArrayAssertion<Byte,byte[],R> asByteArray() throws AssertionError { 271 return new FluentPrimitiveArrayAssertion<>(this, cast(byte[].class), returns()); 272 } 273 274 /** 275 * Converts this object assertion into a primitive boolean array assertion. 276 * 277 * @return A new assertion. 278 * @throws AssertionError If object is not an boolean array. 279 */ 280 public FluentPrimitiveArrayAssertion<Boolean,boolean[],R> asBooleanArray() throws AssertionError { 281 return new FluentPrimitiveArrayAssertion<>(this, cast(boolean[].class), returns()); 282 } 283 284 /** 285 * Converts this object assertion into a boolean assertion. 286 * 287 * @return A new assertion. 288 * @throws AssertionError If object is not a boolean. 289 */ 290 public FluentBooleanAssertion<R> asBoolean() { 291 return new FluentBooleanAssertion<>(this, cast(Boolean.class), returns()); 292 } 293 294 /** 295 * Converts this object assertion into a byte array assertion. 296 * 297 * @return A new assertion. 298 * @throws AssertionError If object is not a byte array. 299 */ 300 public FluentByteArrayAssertion<R> asBytes() { 301 return new FluentByteArrayAssertion<>(this, cast(byte[].class), returns()); 302 } 303 304 /** 305 * Converts this object assertion into a collection assertion. 306 * 307 * @return A new assertion. 308 * @throws AssertionError If object is not a collection. 309 */ 310 public FluentCollectionAssertion<Object,R> asCollection() { 311 return asCollection(Object.class); 312 } 313 314 /** 315 * Converts this object assertion into a collection assertion. 316 * 317 * @param <E> The element type of the collection. 318 * @param elementType The element type of the collection. 319 * @return A new assertion. 320 * @throws AssertionError If object is not a collection. 321 */ 322 @SuppressWarnings("unchecked") 323 public <E> FluentCollectionAssertion<E,R> asCollection(Class<E> elementType) { 324 assertArgNotNull("elementType", elementType); 325 return new FluentCollectionAssertion<>(this, cast(Collection.class), returns()); 326 } 327 328 /** 329 * Converts this object assertion into a collection assertion. 330 * 331 * @return A new assertion. 332 * @throws AssertionError If object is not a collection. 333 */ 334 @SuppressWarnings("unchecked") 335 public FluentStringListAssertion<R> asStringList() { 336 return new FluentStringListAssertion<>(this, cast(List.class), returns()); 337 } 338 339 /** 340 * Converts this object assertion into a comparable object assertion. 341 * 342 * @param <T2> The comparable type. 343 * @return A new assertion. 344 * @throws AssertionError If object is not an instance of {@link Comparable}. 345 */ 346 @SuppressWarnings("unchecked") 347 public <T2 extends Comparable<T2>> FluentComparableAssertion<T2,R> asComparable() { 348 return new FluentComparableAssertion<>(this, (T2)cast(Comparable.class), returns()); 349 } 350 351 /** 352 * Converts this object assertion into a date assertion. 353 * 354 * @return A new assertion. 355 * @throws AssertionError If object is not a date. 356 */ 357 public FluentDateAssertion<R> asDate() { 358 return new FluentDateAssertion<>(this, cast(Date.class), returns()); 359 } 360 361 /** 362 * Converts this object assertion into an integer assertion. 363 * 364 * @return A new assertion. 365 * @throws AssertionError If object is not an integer. 366 */ 367 public FluentIntegerAssertion<R> asInteger() { 368 return new FluentIntegerAssertion<>(this, cast(Integer.class), returns()); 369 } 370 371 /** 372 * Converts this object assertion into a long assertion. 373 * 374 * @return A new assertion. 375 * @throws AssertionError If object is not a long. 376 */ 377 public FluentLongAssertion<R> asLong() { 378 return new FluentLongAssertion<>(this, cast(Long.class), returns()); 379 } 380 381 /** 382 * Converts this object assertion into a list assertion. 383 * 384 * @return A new assertion. 385 * @throws AssertionError If object is not a list. 386 */ 387 public FluentListAssertion<Object,R> asList() { 388 return asList(Object.class); 389 } 390 391 /** 392 * Converts this object assertion into a list assertion. 393 * 394 * @param <E> The element type. 395 * @param elementType The element type. 396 * @return A new assertion. 397 * @throws AssertionError If object is not a list. 398 */ 399 @SuppressWarnings("unchecked") 400 public <E> FluentListAssertion<E,R> asList(Class<E> elementType) { 401 assertArgNotNull("elementType", elementType); 402 return new FluentListAssertion<>(this, cast(List.class), returns()); 403 } 404 405 /** 406 * Converts this object assertion into a map assertion. 407 * 408 * @return A new assertion. 409 * @throws AssertionError If object is not a map. 410 */ 411 public FluentMapAssertion<String,Object,R> asMap() { 412 return asMap(String.class,Object.class); 413 } 414 415 /** 416 * Converts this object assertion into a map assertion with the specified key and value types. 417 * 418 * @param <K> The key type. 419 * @param <V> The value type. 420 * @param keyType The key type. 421 * @param valueType The value type. 422 * @return A new assertion. 423 * @throws AssertionError If object is not a map. 424 */ 425 @SuppressWarnings("unchecked") 426 public <K,V> FluentMapAssertion<K,V,R> asMap(Class<K> keyType, Class<V> valueType) { 427 assertArgNotNull("keyType", keyType); 428 assertArgNotNull("valueType", valueType); 429 return new FluentMapAssertion<>(this, cast(Map.class), returns()); 430 } 431 432 /** 433 * Converts this object assertion into a bean assertion. 434 * 435 * @param <T2> The bean type. 436 * @param beanType The bean type. 437 * @return A new assertion. 438 * @throws AssertionError If object is not a bean. 439 */ 440 public <T2> FluentBeanAssertion<T2,R> asBean(Class<T2> beanType) { 441 assertArgNotNull("beanType", beanType); 442 return new FluentBeanAssertion<>(this, cast(beanType), returns()); 443 } 444 445 /** 446 * Converts this object assertion into a bean assertion. 447 * 448 * @return A new assertion. 449 * @throws AssertionError If object is not a bean. 450 */ 451 public FluentBeanAssertion<T,R> asBean() { 452 return new FluentBeanAssertion<>(this, orElse(null), returns()); 453 } 454 455 /** 456 * Converts this object assertion into a list-of-beans assertion. 457 * 458 * @param <T2> The bean type. 459 * @param beanType The bean type. 460 * @return A new assertion. 461 * @throws AssertionError If object is not a bean. 462 */ 463 @SuppressWarnings("unchecked") 464 public <T2> FluentBeanListAssertion<T2,R> asBeanList(Class<T2> beanType) { 465 assertArgNotNull("beanType", beanType); 466 return new FluentBeanListAssertion<>(this, cast(List.class), returns()); 467 } 468 469 /** 470 * Converts this object assertion into a zoned-datetime assertion. 471 * 472 * @return A new assertion. 473 * @throws AssertionError If object is not a zoned-datetime. 474 */ 475 public FluentZonedDateTimeAssertion<R> asZonedDateTime() { 476 return new FluentZonedDateTimeAssertion<>(this, cast(ZonedDateTime.class), returns()); 477 } 478 479 //----------------------------------------------------------------------------------------------------------------- 480 // Fluent setters 481 //----------------------------------------------------------------------------------------------------------------- 482 483 // <FluentSetters> 484 485 @Override /* GENERATED - org.apache.juneau.assertions.Assertion */ 486 public FluentAnyAssertion<T,R> setMsg(String msg, Object...args) { 487 super.setMsg(msg, args); 488 return this; 489 } 490 491 @Override /* GENERATED - org.apache.juneau.assertions.Assertion */ 492 public FluentAnyAssertion<T,R> setOut(PrintStream value) { 493 super.setOut(value); 494 return this; 495 } 496 497 @Override /* GENERATED - org.apache.juneau.assertions.Assertion */ 498 public FluentAnyAssertion<T,R> setSilent() { 499 super.setSilent(); 500 return this; 501 } 502 503 @Override /* GENERATED - org.apache.juneau.assertions.Assertion */ 504 public FluentAnyAssertion<T,R> setStdOut() { 505 super.setStdOut(); 506 return this; 507 } 508 509 @Override /* GENERATED - org.apache.juneau.assertions.Assertion */ 510 public FluentAnyAssertion<T,R> setThrowable(Class<? extends java.lang.RuntimeException> value) { 511 super.setThrowable(value); 512 return this; 513 } 514 515 // </FluentSetters> 516 517 //----------------------------------------------------------------------------------------------------------------- 518 // Utility methods 519 //----------------------------------------------------------------------------------------------------------------- 520 521 private <T2> T2 cast(Class<T2> c) throws AssertionError { 522 Object o = orElse(null); 523 if (o == null || c.isInstance(o)) 524 return c.cast(o); 525 throw new BasicAssertionError(MSG_objectWasNotType, ClassInfo.of(c).getFullName(), o.getClass()); 526 } 527}