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.IOUtils.*;
016
017import java.io.*;
018import java.time.*;
019import java.util.*;
020import java.util.stream.*;
021
022import org.apache.juneau.*;
023import org.apache.juneau.common.utils.*;
024
025/**
026 * Main class for creation of assertions for stand-alone testing.
027 *
028 * <p>
029 * Provides assertions for various common POJO types.
030 *
031 * <h5 class='section'>Example:</h5>
032 * <p class='bjava'>
033 *    <jk>import static</jk> org.apache.juneau.assertions.Assertions.*;
034 *
035 * <jc>// Assert string is greater than 100 characters and contains "foo".</jc>
036 *    <jsm>assertString</jsm>(<jv>myString</jv>)
037 *       .length().isGt(100)
038 *       .contains(<js>"foo"</js>);
039 * </p>
040 *
041 * <p>
042 * Provides simple testing that {@link Throwable Throwables} are being thrown correctly.
043 *
044 * <h5 class='section'>Example:</h5>
045 * <p class='bjava'>
046 *    <jk>import static</jk> org.apache.juneau.assertions.Assertions.*;
047 *
048 * <jc>// Assert that calling doBadCall() causes a RuntimeException.</jc>
049 *    <jsm>assertThrown</jsm>(() -&gt; <jv>myPojo</jv>.doBadCall())
050 *       .isType(RuntimeException.<jk>class</jk>)
051 *       .message().contains(<js>"Bad thing happened."</js>);
052 * </p>
053 *
054 * <p>
055 * Provides other assertion convenience methods such as asserting non-null method arguments.
056 *
057 * <h5 class='section'>Example:</h5>
058 * <p class='bjava'>
059 *    <jk>import static</jk> org.apache.juneau.assertions.Assertions.*;
060 *
061 * <jk>public</jk> String getFoo(String <jv>bar</jv>) {
062 *    <jsm>assertArgNotNull</jsm>(<js>"bar"</js>, <jv>bar</jv>);
063 *    ...
064 * }
065 * </p>
066 *
067 * <h5 class='section'>See Also:</h5>
068 * <ul>
069 *    <li class='link'><a class="doclink" href="../../../../index.html#ja.Overview">Fluent Assertions</a>
070 * </ul>
071 */
072public class Assertions {
073
074   //-----------------------------------------------------------------------------------------------------------------
075   // Fluent assertions
076   //-----------------------------------------------------------------------------------------------------------------
077
078   /**
079    * Performs an assertion on an arbitrary POJO.
080    *
081    * <p>
082    * The distinction between {@link ObjectAssertion} and {@link AnyAssertion} is that the latter supports all
083    * the operations of the former, but adds various transform methods for conversion to specific assertion types.
084    *
085    * <p>
086    * Various transform methods such as {@link FluentListAssertion#asItem(int)} and {@link FluentBeanAssertion#asProperty(String)}
087    * return generic any-assertions so that they can be easily transformed into other assertion types.
088    *
089    * <h5 class='section'>Example:</h5>
090    * <p class='bjava'>
091    *    <jk>import static</jk> org.apache.juneau.assertions.Assertions.*;
092    *
093    *    <jc>// Asserts that the property 'foo' of a bean is 'bar'.</jc>
094    *    <jsm>assertAny</jsm>(<jv>myPojo</jv>)  <jc>// Start with AnyAssertion.</jc>
095    *       .asBean(MyBean.<jk>class</jk>)  <jc>// Transform to BeanAssertion.</jc>
096    *          .property(<js>"foo"</js>).is(<js>"bar"</js>);
097    * </p>
098    *
099    * <p>
100    * See <a class="doclink" href="../../../../index.html#ja.Overview">Fluent Assertions</a> for general assertion usage and {@link AnyAssertion} for supported operations on this type.
101    *
102    * @param <T> The value type.
103    * @param value
104    *    The object being tested.
105    *    <br>Can be <jk>null</jk>.
106    * @return
107    *    A new assertion object.
108    *    <br>Never <jk>null</jk>.
109    */
110   public static final <T> AnyAssertion<T> assertAny(T value) {
111      return AnyAssertion.create(value);
112   }
113
114   /**
115    * Performs an assertion on an array of POJOs.
116    *
117    * <h5 class='section'>Example:</h5>
118    * <p class='bjava'>
119    *    <jk>import static</jk> org.apache.juneau.assertions.Assertions.*;
120    *
121    * <jc>// Asserts that an Integer array contains [1,2,3].</jc>
122    *    Integer[] <jv>array</jv> = {...};
123    *    <jsm>assertArray</jsm>(<jv>array</jv>)
124    *       .asJson().is(<js>"[1,2,3]"</js>);
125    * </p>
126    *
127    * <p>
128    * See <a class="doclink" href="../../../../index.html#ja.Overview">Fluent Assertions</a> for general assertion usage and {@link ArrayAssertion} for supported operations on this type.
129    *
130    * @param <E> The value element type.
131    * @param value
132    *    The object being tested.
133    *    <br>Can be <jk>null</jk>.
134    * @return
135    *    A new assertion object.
136    *    <br>Never <jk>null</jk>.
137    */
138   public static final <E> ArrayAssertion<E> assertArray(E[] value) {
139      return ArrayAssertion.create(value);
140   }
141
142   /**
143    * Performs an assertion on a Java bean.
144    *
145    * <h5 class='section'>Example:</h5>
146    * <p class='bjava'>
147    *    <jk>import static</jk> org.apache.juneau.assertions.Assertions.*;
148    *
149    * <jc>// Asserts that the 'foo' and 'bar' properties of a bean are 1 and 2 respectively.</jc>
150    *    <jsm>assertBean</jsm>(<jv>myBean</jv>)
151    *       .isType(MyBean.<jk>class</jk>)
152    *       .extract(<js>"foo,bar"</js>)
153    *          .asJson().is(<js>"{foo:1,bar:2}"</js>);
154    * </p>
155    *
156    * <p>
157    * See <a class="doclink" href="../../../../index.html#ja.Overview">Fluent Assertions</a> for general assertion usage and {@link BeanAssertion} for supported operations on this type.
158    *
159    * @param <T> The value type.
160    * @param value
161    *    The object being tested.
162    *    <br>Can be <jk>null</jk>.
163    * @return
164    *    A new assertion object.
165    *    <br>Never <jk>null</jk>.
166    */
167   public static final <T> BeanAssertion<T> assertBean(T value) {
168      return BeanAssertion.create(value);
169   }
170
171   /**
172    * Performs an assertion on a list of Java beans.
173    *
174    * <h5 class='section'>Example:</h5>
175    * <p class='bjava'>
176    *    <jk>import static</jk> org.apache.juneau.assertions.Assertions.*;
177    *
178    * <jc>// Asserts that a bean list has 3 entries with 'foo' property values of 'bar','baz','qux'.</jc>
179    *    <jsm>assertBeanList</jsm>(<jv>myListOfBeans</jv>)
180    *       .isSize(3)
181    *       .property(<js>"foo"</js>)
182    *          .is(<js>"bar"</js>,<js>"baz"</js>,<js>"qux"</js>);
183    * </p>
184    *
185    * <p>
186    * See <a class="doclink" href="../../../../index.html#ja.Overview">Fluent Assertions</a> for general assertion usage and {@link BeanListAssertion} for supported operations on this type.
187    *
188    * @param <E> The element type.
189    * @param value
190    *    The object being tested.
191    *    <br>Can be <jk>null</jk>.
192    * @return
193    *    A new assertion object.
194    *    <br>Never <jk>null</jk>.
195    */
196   public static final <E> BeanListAssertion<E> assertBeanList(List<E> value) {
197      return BeanListAssertion.create(value);
198   }
199
200   /**
201    * Performs an assertion on a Boolean.
202    *
203    * <h5 class='section'>Example:</h5>
204    * <p class='bjava'>
205    *    <jk>import static</jk> org.apache.juneau.assertions.Assertions.*;
206    *
207    * <jc>// Asserts that a Boolean is not null and TRUE.</jc>
208    *    <jsm>assertBoolean</jsm>(<jv>myBoolean</jv>)
209    *       .isTrue();
210    * </p>
211    *
212    * <p>
213    * See <a class="doclink" href="../../../../index.html#ja.Overview">Fluent Assertions</a> for general assertion usage and {@link BooleanAssertion} for supported operations on this type.
214    *
215    * @param value
216    *    The object being tested.
217    *    <br>Can be <jk>null</jk>.
218    * @return
219    *    A new assertion object.
220    *    <br>Never <jk>null</jk>.
221    */
222   public static final BooleanAssertion assertBoolean(Boolean value) {
223      return BooleanAssertion.create(value);
224   }
225
226   /**
227    * Performs an assertion on a boolean array.
228    *
229    * <h5 class='section'>Example:</h5>
230    * <p class='bjava'>
231    *    <jk>import static</jk> org.apache.juneau.assertions.Assertions.*;
232    *
233    * <jc>// Asserts that a Boolean array has size of 3 and all entries are TRUE.</jc>
234    *    <jsm>assertBooleanArray</jsm>(<jv>myBooleanArray</jv>)
235    *       .isSize(3)
236    *       .all(<jv>x</jv> -&gt; <jv>x</jv> == <jk>true</jk>);
237    * </p>
238    *
239    * <p>
240    * See <a class="doclink" href="../../../../index.html#ja.Overview">Fluent Assertions</a> for general assertion usage and {@link PrimitiveArrayAssertion} for supported operations on this type.
241    *
242    * @param value
243    *    The object being tested.
244    *    <br>Can be <jk>null</jk>.
245    * @return
246    *    A new assertion object.
247    *    <br>Never <jk>null</jk>.
248    */
249   public static final PrimitiveArrayAssertion<Boolean,boolean[]> assertBooleanArray(boolean[] value) {
250      return PrimitiveArrayAssertion.create(value);
251   }
252
253   /**
254    * Performs an assertion on a byte array.
255    *
256    * <p>
257    * The distinction between {@link #assertByteArray} and {@link #assertBytes} is that the former returns an assertion
258    * more tied to general byte arrays and the latter returns an assertion more tied to dealing with binary streams
259    * that can be decoded or transformed into a string.
260    *
261    * <h5 class='section'>Example:</h5>
262    * <p class='bjava'>
263    *    <jk>import static</jk> org.apache.juneau.assertions.Assertions.*;
264    *
265    * <jc>// Asserts that a byte array has size of 3 and all bytes are larger than 10.</jc>
266    *    <jsm>assertByteArray</jsm>(<jv>myByteArray</jv>)
267    *       .isSize(3)
268    *       .all(<jv>x</jv> -&gt; <jv>x</jv> &gt; 10);
269    * </p>
270    *
271    * <p>
272    * See <a class="doclink" href="../../../../index.html#ja.Overview">Fluent Assertions</a> for general assertion usage and {@link PrimitiveArrayAssertion} for supported operations on this type.
273    *
274    * @param value
275    *    The object being tested.
276    *    <br>Can be <jk>null</jk>.
277    * @return
278    *    A new assertion object.
279    *    <br>Never <jk>null</jk>.
280    */
281   public static final PrimitiveArrayAssertion<Byte,byte[]> assertByteArray(byte[] value) {
282      return PrimitiveArrayAssertion.create(value);
283   }
284
285   /**
286    * Performs an assertion on a byte array.
287    *
288    * <p>
289    * The distinction between {@link #assertByteArray} and {@link #assertBytes} is that the former returns an assertion
290    * more tied to general byte arrays and the latter returns an assertion more tied to dealing with binary streams
291    * that can be decoded or transformed into a string.
292    *
293    * <h5 class='section'>Example:</h5>
294    * <p class='bjava'>
295    *    <jk>import static</jk> org.apache.juneau.assertions.Assertions.*;
296    *
297    *    <jc>// Asserts that the byte array contains the string "foo".</jc>
298    *    <jsm>assertBytes</jsm>(<jv>myBytes</jv>)
299    *       .asHex().is(<js>"666F6F"</js>);
300    * </p>
301    *
302    * <p>
303    * See <a class="doclink" href="../../../../index.html#ja.Overview">Fluent Assertions</a> for general assertion usage and {@link ByteArrayAssertion} for supported operations on this type.
304    *
305    * @param value
306    *    The object being tested.
307    *    <br>Can be <jk>null</jk>.
308    * @return
309    *    A new assertion object.
310    *    <br>Never <jk>null</jk>.
311    */
312   public static final ByteArrayAssertion assertBytes(byte[] value) {
313      return ByteArrayAssertion.create(value);
314   }
315
316   /**
317    * Performs an assertion on the contents of an input stream.
318    *
319    * <h5 class='section'>Example:</h5>
320    * <p class='bjava'>
321    *    <jk>import static</jk> org.apache.juneau.assertions.Assertions.*;
322    *
323    *    <jc>// Asserts that the stream contains the string "foo".</jc>
324    *    <jsm>assertBytes</jsm>(<jv>myStream</jv>)
325    *       .asHex().is(<js>"666F6F"</js>);
326    * </p>
327    *
328    * <p>
329    * See <a class="doclink" href="../../../../index.html#ja.Overview">Fluent Assertions</a> for general assertion usage and {@link ByteArrayAssertion} for supported operations on this type.
330    *
331    * @param value
332    *    The object being tested.
333    *    <br>Can be <jk>null</jk>.
334    *    <br>Stream is automatically closed.
335    * @return
336    *    A new assertion object.
337    *    <br>Never <jk>null</jk>.
338    * @throws IOException If thrown while reading contents from stream.
339    */
340   public static final ByteArrayAssertion assertBytes(InputStream value) throws IOException {
341      return assertBytes(value == null ? null : readBytes(value));
342   }
343
344   /**
345    * Performs an assertion on a char array.
346    *
347    * <h5 class='section'>Example:</h5>
348    * <p class='bjava'>
349    *    <jk>import static</jk> org.apache.juneau.assertions.Assertions.*;
350    *
351    *    <jc>// Asserts that the char array contains the string "foo".</jc>
352    *    <jsm>assertCharArray</jsm>(<jv>myCharArray</jv>)
353    *       .asString().is(<js>"foo"</js>);
354    * </p>
355    *
356    * <p>
357    * See <a class="doclink" href="../../../../index.html#ja.Overview">Fluent Assertions</a> for general assertion usage and {@link PrimitiveArrayAssertion} for supported operations on this type.
358    *
359    * @param value
360    *    The object being tested.
361    *    <br>Can be <jk>null</jk>.
362    * @return
363    *    A new assertion object.
364    *    <br>Never <jk>null</jk>.
365    */
366   public static final PrimitiveArrayAssertion<Character,char[]> assertCharArray(char[] value) {
367      return PrimitiveArrayAssertion.create(value);
368   }
369
370   /**
371    * Performs an assertion on a collection of POJOs.
372    *
373    * <h5 class='section'>Example:</h5>
374    * <p class='bjava'>
375    *    <jk>import static</jk> org.apache.juneau.assertions.Assertions.*;
376    *
377    *    <jc>// Asserts that a collection of strings has only one entry of 'foo'.</jc>
378    *    <jsm>assertCollection</jsm>(<jv>myCollectionOfStrings</jv>)
379    *       .isSize(1)
380    *       .contains(<js>"foo"</js>);
381    * </p>
382    *
383    * <p>
384    * In general, use {@link #assertList(List)} if you're performing an assertion on a list since {@link ListAssertion}
385    * provides more functionality than {@link CollectionAssertion}.
386    *
387    * <p>
388    * See <a class="doclink" href="../../../../index.html#ja.Overview">Fluent Assertions</a> for general assertion usage and {@link CollectionAssertion} for supported operations on this type.
389    *
390    * @param <E> The element type.
391    * @param value
392    *    The object being tested.
393    *    <br>Can be <jk>null</jk>.
394    * @return
395    *    A new assertion object.
396    *    <br>Never <jk>null</jk>.
397    */
398   public static final <E> CollectionAssertion<E> assertCollection(Collection<E> value) {
399      return CollectionAssertion.create(value);
400   }
401
402   /**
403    * Performs an assertion on a Comparable.
404    *
405    * <h5 class='section'>Example:</h5>
406    * <p class='bjava'>
407    *    <jk>import static</jk> org.apache.juneau.assertions.Assertions.*;
408    *
409    *    <jc>// Asserts a comparable is less than another comparable.</jc>
410    *    <jsm>assertComparable</jsm>(<jv>myComparable</jv>)
411    *       .isLt(<jv>anotherComparable</jv>);
412    * </p>
413    *
414    * <p>
415    * See <a class="doclink" href="../../../../index.html#ja.Overview">Fluent Assertions</a> for general assertion usage and {@link ComparableAssertion} for supported operations on this type.
416    *
417    * @param <T> The value type.
418    * @param value
419    *    The object being tested.
420    *    <br>Can be <jk>null</jk>.
421    * @return
422    *    A new assertion object.
423    *    <br>Never <jk>null</jk>.
424    */
425   public static final <T extends Comparable<T>> ComparableAssertion<T> assertComparable(T value) {
426      return ComparableAssertion.create(value);
427   }
428
429   /**
430    * Performs an assertion on a Date.
431    *
432    * <h5 class='section'>Example:</h5>
433    * <p class='bjava'>
434    *    <jk>import static</jk> org.apache.juneau.assertions.Assertions.*;
435    *
436    *    <jc>// Asserts the specified date is after the current date.</jc>
437    *    <jsm>assertDate</jsm>(<jv>myDate</jv>)
438    *       .isAfterNow();
439    * </p>
440    *
441    * <p>
442    * See <a class="doclink" href="../../../../index.html#ja.Overview">Fluent Assertions</a> for general assertion usage and {@link DateAssertion} for supported operations on this type.
443    *
444    * @param value
445    *    The object being tested.
446    *    <br>Can be <jk>null</jk>.
447    * @return
448    *    A new assertion object.
449    *    <br>Never <jk>null</jk>.
450    */
451   public static final DateAssertion assertDate(Date value) {
452      return DateAssertion.create(value);
453   }
454
455   /**
456    * Performs an assertion on a double array.
457    *
458    * <h5 class='section'>Example:</h5>
459    * <p class='bjava'>
460    *    <jk>import static</jk> org.apache.juneau.assertions.Assertions.*;
461    *
462    *    <jc>// Asserts that a double array is at least size 100 and all values are greater than 1000.</jc>
463    *    <jsm>assertDoubleArray</jsm>(<jv>myDoubleArray</jv>)
464    *       .size().isGte(100f)
465    *       .all(<jv>x</jv> -&gt; <jv>x</jv> &gt; 1000f);
466    * </p>
467    *
468    * <p>
469    * See <a class="doclink" href="../../../../index.html#ja.Overview">Fluent Assertions</a> for general assertion usage and {@link PrimitiveArrayAssertion} for supported operations on this type.
470    *
471    * @param value
472    *    The object being tested.
473    *    <br>Can be <jk>null</jk>.
474    * @return
475    *    A new assertion object.
476    *    <br>Never <jk>null</jk>.
477    */
478   public static final PrimitiveArrayAssertion<Double,double[]> assertDoubleArray(double[] value) {
479      return PrimitiveArrayAssertion.create(value);
480   }
481
482   /**
483    * Performs an assertion on a float array.
484    *
485    * <h5 class='section'>Example:</h5>
486    * <p class='bjava'>
487    *    <jk>import static</jk> org.apache.juneau.assertions.Assertions.*;
488    *
489    *    <jc>// Asserts that a float array is at least size 100 and all values are greater than 1000.</jc>
490    *    <jsm>assertFloatArray</jsm>(<jv>myFloatArray</jv>)
491    *       .size().isGte(100f)
492    *       .all(<jv>x</jv> -&gt; <jv>x</jv> &gt; 1000f);
493    * </p>
494    *
495    * <p>
496    * See <a class="doclink" href="../../../../index.html#ja.Overview">Fluent Assertions</a> for general assertion usage and {@link PrimitiveArrayAssertion} for supported operations on this type.
497    *
498    * @param value
499    *    The object being tested.
500    *    <br>Can be <jk>null</jk>.
501    * @return
502    *    A new assertion object.
503    *    <br>Never <jk>null</jk>.
504    */
505   public static final PrimitiveArrayAssertion<Float,float[]> assertFloatArray(float[] value) {
506      return PrimitiveArrayAssertion.create(value);
507   }
508
509   /**
510    * Performs an assertion on an int array.
511    *
512    * <h5 class='section'>Example:</h5>
513    * <p class='bjava'>
514    *    <jk>import static</jk> org.apache.juneau.assertions.Assertions.*;
515    *
516    *    <jc>// Asserts that a double array is at least size 100 and all values are greater than 1000.</jc>
517    *    <jsm>assertIntArray</jsm>(<jv>myIntArray</jv>)
518    *       .size().isGte(100)
519    *       .all(<jv>x</jv> -&gt; <jv>x</jv> &gt; 1000);
520    * </p>
521    *
522    * <p>
523    * See <a class="doclink" href="../../../../index.html#ja.Overview">Fluent Assertions</a> for general assertion usage and {@link PrimitiveArrayAssertion} for supported operations on this type.
524    *
525    * @param value
526    *    The object being tested.
527    *    <br>Can be <jk>null</jk>.
528    * @return
529    *    A new assertion object.
530    *    <br>Never <jk>null</jk>.
531    */
532   public static final PrimitiveArrayAssertion<Integer,int[]> assertIntArray(int[] value) {
533      return PrimitiveArrayAssertion.create(value);
534   }
535
536   /**
537    * Performs an assertion on an Integer.
538    *
539    * <h5 class='section'>Example:</h5>
540    * <p class='bjava'>
541    *    <jk>import static</jk> org.apache.juneau.assertions.Assertions.*;
542    *
543    *    <jc>// Assert that an HTTP response status code is 200 or 404.</jc>
544    *    <jsm>assertInteger</jsm>(<jv>httpReponse</jv>)
545    *       .isAny(200,404);
546    * </p>
547    *
548    * <p>
549    * See <a class="doclink" href="../../../../index.html#ja.Overview">Fluent Assertions</a> for general assertion usage and {@link IntegerAssertion} for supported operations on this type.
550    *
551    * @param value
552    *    The object being tested.
553    *    <br>Can be <jk>null</jk>.
554    * @return
555    *    A new assertion object.
556    *    <br>Never <jk>null</jk>.
557    */
558   public static final IntegerAssertion assertInteger(Integer value) {
559      return IntegerAssertion.create(value);
560   }
561
562   /**
563    * Performs an assertion on a list of POJOs.
564    *
565    * <h5 class='section'>Example:</h5>
566    * <p class='bjava'>
567    *    <jk>import static</jk> org.apache.juneau.assertions.Assertions.*;
568    *
569    *    <jc>// Assert that the first entry in a list is "{foo:'bar'}" when serialized to simplified JSON.</jc>
570    *    <jsm>assertList</jsm>(<jv>myList</jv>)
571    *       .item(0)
572    *          .asJson().is(<js>"{foo:'bar'}"</js>);
573    * </p>
574    *
575    * <p>
576    * See <a class="doclink" href="../../../../index.html#ja.Overview">Fluent Assertions</a> for general assertion usage and {@link ListAssertion} for supported operations on this type.
577    *
578    * @param <E> The element type.
579    * @param value
580    *    The object being tested.
581    *    <br>Can be <jk>null</jk>.
582    * @return
583    *    A new assertion object.
584    *    <br>Never <jk>null</jk>.
585    */
586   public static final <E> ListAssertion<E> assertList(List<E> value) {
587      return ListAssertion.create(value);
588   }
589
590   /**
591    * Performs an assertion on a stream of POJOs.
592    *
593    * <h5 class='section'>Example:</h5>
594    * <p class='bjava'>
595    *    <jk>import static</jk> org.apache.juneau.assertions.Assertions.*;
596    *
597    *    <jc>// Assert that the first entry in a list is "{foo:'bar'}" when serialized to simplified JSON.</jc>
598    *    <jsm>assertList</jsm>(<jv>myStream</jv>)
599    *       .item(0)
600    *          .asJson().is(<js>"{foo:'bar'}"</js>);
601    * </p>
602    *
603    * <p>
604    * See <a class="doclink" href="../../../../index.html#ja.Overview">Fluent Assertions</a> for general assertion usage and {@link ListAssertion} for supported operations on this type.
605    *
606    * @param <E> The element type.
607    * @param value
608    *    The object being tested.
609    *    <br>Can be <jk>null</jk>.
610    * @return
611    *    A new assertion object.
612    *    <br>Never <jk>null</jk>.
613    */
614   public static final <E> ListAssertion<E> assertList(Stream<E> value) {
615      return ListAssertion.create(value);
616   }
617
618   /**
619    * Performs an assertion on a Long.
620    *
621    * <h5 class='section'>Example:</h5>
622    * <p class='bjava'>
623    *    <jk>import static</jk> org.apache.juneau.assertions.Assertions.*;
624    *
625    *    <jc>// Throw a BadReqest if an HTTP response length is greater than 100k.</jc>
626    *    <jsm>assertLong</jsm>(<jv>responseLength</jv>)
627    *       .throwable(BadRequest.<jk>class</jk>)
628    *       .msg(<js>"Request is too large"</js>)
629    *       .isLt(100000);
630    * </p>
631    *
632    * <p>
633    * See <a class="doclink" href="../../../../index.html#ja.Overview">Fluent Assertions</a> for general assertion usage and {@link LongAssertion} for supported operations on this type.
634    *
635    * @param value
636    *    The object being tested.
637    *    <br>Can be <jk>null</jk>.
638    * @return
639    *    A new assertion object.
640    *    <br>Never <jk>null</jk>.
641    */
642   public static final LongAssertion assertLong(Long value) {
643      return LongAssertion.create(value);
644   }
645
646   /**
647    * Performs an assertion on a long array.
648    *
649    * <h5 class='section'>Example:</h5>
650    * <p class='bjava'>
651    *    <jk>import static</jk> org.apache.juneau.assertions.Assertions.*;
652    *
653    *    <jc>// Asserts that a long array is at least size 100 and all values are greater than 1000.</jc>
654    *    <jsm>assertLongArray</jsm>(<jv>myLongArray</jv>)
655    *       .size().isGte(100)
656    *       .all(<jv>x</jv> -&gt; <jv>x</jv> &gt; 1000);
657    * </p>
658    *
659    * <p>
660    * See <a class="doclink" href="../../../../index.html#ja.Overview">Fluent Assertions</a> for general assertion usage and {@link PrimitiveArrayAssertion} for supported operations on this type.
661    *
662    * @param value
663    *    The object being tested.
664    *    <br>Can be <jk>null</jk>.
665    * @return
666    *    A new assertion object.
667    *    <br>Never <jk>null</jk>.
668    */
669   public static final PrimitiveArrayAssertion<Long,long[]> assertLongArray(long[] value) {
670      return PrimitiveArrayAssertion.create(value);
671   }
672
673   /**
674    * Performs an assertion on a map.
675    *
676    * <h5 class='section'>Example:</h5>
677    * <p class='bjava'>
678    *    <jk>import static</jk> org.apache.juneau.assertions.Assertions.*;
679    *
680    *    <jc>// Assert the specified map is a HashMap and contains the key "foo".</jc>
681    *    <jsm>assertMap</jsm>(<jv>myMap</jv>)
682    *       .isType(HashMap.<jk>class</jk>)
683    *       .containsKey(<js>"foo"</js>);
684    * </p>
685    *
686    * <p>
687    * See <a class="doclink" href="../../../../index.html#ja.Overview">Fluent Assertions</a> for general assertion usage and {@link MapAssertion} for supported operations on this type.
688    *
689    * @param <K> The key type.
690    * @param <V> The value type.
691    * @param value
692    *    The object being tested.
693    *    <br>Can be <jk>null</jk>.
694    * @return
695    *    A new assertion object.
696    *    <br>Never <jk>null</jk>.
697    */
698   public static final <K,V> MapAssertion<K,V> assertMap(Map<K,V> value) {
699      return MapAssertion.create(value);
700   }
701
702   /**
703    * Performs an assertion on a Java Object.
704    *
705    * <h5 class='section'>Example:</h5>
706    * <p class='bjava'>
707    *    <jk>import static</jk> org.apache.juneau.assertions.Assertions.*;
708    *
709    *    <jc>// Asserts the specified POJO is of type MyBean and is "{foo:'bar'}" </jc>
710    *    <jc>// when serialized to Simplified JSON.</jc>
711    *    <jsm>assertObject</jsm>(<jv>myPojo</jv>)
712    *       .isType(MyBean.<jk>class</jk>)
713    *       .asJson().is(<js>"{foo:'bar'}"</js>);
714    * </p>
715    *
716    * <p>
717    * See <a class="doclink" href="../../../../index.html#ja.Overview">Fluent Assertions</a> for general assertion usage and {@link ObjectAssertion} for supported operations on this type.
718    *
719    * @param <T> The value type.
720    * @param value
721    *    The object being tested.
722    *    <br>Can be <jk>null</jk>.
723    * @return
724    *    A new assertion object.
725    *    <br>Never <jk>null</jk>.
726    */
727   public static final <T> ObjectAssertion<T> assertObject(T value) {
728      return ObjectAssertion.create(value);
729   }
730
731   /**
732    * Performs an assertion on a Java Object wrapped in an Optional.
733    *
734    * <h5 class='section'>Example:</h5>
735    * <p class='bjava'>
736    *    <jk>import static</jk> org.apache.juneau.assertions.Assertions.*;
737    *
738    *    <jc>// Asserts the specified POJO is of type MyBean and is "{foo:'bar'}" </jc>
739    *    <jc>// when serialized to Simplified JSON.</jc>
740    *    <jsm>assertOptional</jsm>(<jv>opt</jv>)
741    *       .isType(MyBean.<jk>class</jk>)
742    *       .asJson().is(<js>"{foo:'bar'}"</js>);
743    * </p>
744    *
745    * <p>
746    * See <a class="doclink" href="../../../../index.html#ja.Overview">Fluent Assertions</a> for general assertion usage and {@link AnyAssertion} for supported operations on this type.
747    *
748    * @param <T> The value type.
749    * @param value
750    *    The object being tested.
751    *    <br>Can be <jk>null</jk>.
752    * @return
753    *    A new assertion object.
754    *    <br>Never <jk>null</jk>.
755    */
756   public static final <T> AnyAssertion<T> assertOptional(Optional<T> value) {
757      return AnyAssertion.create(value.orElse(null));
758   }
759
760   /**
761    * Performs an assertion on the contents of a Reader.
762    *
763    * <h5 class='section'>Example:</h5>
764    * <p class='bjava'>
765    *    <jk>import static</jk> org.apache.juneau.assertions.Assertions.*;
766    *
767    *    <jc>// Asserts the contents of the Reader contains "foo".</jc>
768    *    <jsm>assertReader</jsm>(<jv>myReader</jv>)
769    *       .contains(<js>"foo"</js>);
770    * </p>
771    *
772    * <p>
773    * See <a class="doclink" href="../../../../index.html#ja.Overview">Fluent Assertions</a> for general assertion usage and {@link StringAssertion} for supported operations on this type.
774    *
775    * @param value
776    *    The object being tested.
777    *    <br>Can be <jk>null</jk>.
778    *    <br>Reader is automatically closed.
779    * @return
780    *    A new assertion object.
781    *    <br>Never <jk>null</jk>.
782    * @throws IOException If thrown while reading contents from reader.
783    */
784   public static final StringAssertion assertReader(Reader value) throws IOException {
785      return assertString(read(value));
786   }
787
788   /**
789    * Performs an assertion on a short array.
790    *
791    * <h5 class='section'>Example:</h5>
792    * <p class='bjava'>
793    *    <jk>import static</jk> org.apache.juneau.assertions.Assertions.*;
794    *
795    *    <jc>// Asserts that a float array is at least size 10 and all values are greater than 100.</jc>
796    *    <jsm>assertShortArray</jsm>(<jv>myShortArray</jv>)
797    *       .size().isGte(10)
798    *       .all(<jv>x</jv> -&gt; <jv>x</jv> &gt; 100);
799    * </p>
800    *
801    * <p>
802    * See <a class="doclink" href="../../../../index.html#ja.Overview">Fluent Assertions</a> for general assertion usage and {@link PrimitiveArrayAssertion} for supported operations on this type.
803    *
804    * @param value
805    *    The object being tested.
806    *    <br>Can be <jk>null</jk>.
807    * @return
808    *    A new assertion object.
809    *    <br>Never <jk>null</jk>.
810    */
811   public static final PrimitiveArrayAssertion<Short,short[]> assertShortArray(short[] value) {
812      return PrimitiveArrayAssertion.create(value);
813   }
814
815   /**
816    * Performs an assertion on a String.
817    *
818    * <h5 class='section'>Example:</h5>
819    * <p class='bjava'>
820    *    <jk>import static</jk> org.apache.juneau.assertions.Assertions.*;
821    *
822    * <jc>// Asserts a string is at least 100 characters long and contains "foo".</jc>
823    *    <jsm>assertString</jsm>(<jv>myString</jv>)
824    *       .size().isGte(100)
825    *       .contains(<js>"foo"</js>);
826    * </p>
827    *
828    * <p>
829    * See <a class="doclink" href="../../../../index.html#ja.Overview">Fluent Assertions</a> for general assertion usage and {@link StringAssertion} for supported operations on this type.
830    *
831    * @param value
832    *    The object being tested.
833    *    <br>Can be <jk>null</jk>.
834    * @return
835    *    A new assertion object.
836    *    <br>Never <jk>null</jk>.
837    */
838   public static final StringAssertion assertString(Object value) {
839      if (value instanceof Optional)
840         value = ((Optional<?>)value).orElse(null);
841      return StringAssertion.create(value);
842   }
843
844   /**
845    * Performs an assertion on a list of Strings.
846    *
847    * <h5 class='section'>Example:</h5>
848    * <p class='bjava'>
849    *    <jk>import static</jk> org.apache.juneau.assertions.Assertions.*;
850    *
851    * <jc>// Asserts a list of strings contain "foo,bar,baz" after trimming all and joining.</jc>
852    *    <jsm>assertStringList</jsm>(<jv>myListOfStrings</jv>)
853    *       .isSize(3)
854    *       .trim()
855    *       .join(<js>","</js>)
856    *       .is(<js>"foo,bar,baz"</js>);
857    * </p>
858    *
859    * <p>
860    * See <a class="doclink" href="../../../../index.html#ja.Overview">Fluent Assertions</a> for general assertion usage and {@link StringListAssertion} for supported operations on this type.
861    *
862    * @param value
863    *    The object being tested.
864    *    <br>Can be <jk>null</jk>.
865    * @return
866    *    A new assertion object.
867    *    <br>Never <jk>null</jk>.
868    */
869   public static final StringListAssertion assertStringList(List<String> value) {
870      return StringListAssertion.create(value);
871   }
872
873   /**
874    * Performs an assertion on a Throwable.
875    *
876    * <h5 class='section'>Example:</h5>
877    * <p class='bjava'>
878    *    <jk>import static</jk> org.apache.juneau.assertions.Assertions.*;
879    *
880    *    <jc>// Asserts a throwable is a RuntimeException containing 'foobar' in the message.</jc>
881    *    <jsm>assertThrowable</jsm>(<jv>throwable</jv>)
882    *       .isExactType(RuntimeException.<jk>class</jk>)
883    *       .message().contains(<js>"foobar"</js>);
884    * </p>
885    *
886    * <p>
887    * See <a class="doclink" href="../../../../index.html#ja.Overview">Fluent Assertions</a> for general assertion usage and {@link ThrowableAssertion} for supported operations on this type.
888    *
889    * @param <T> The value type.
890    * @param value
891    *    The object being tested.
892    *    <br>Can be <jk>null</jk>.
893    * @return
894    *    A new assertion object.
895    *    <br>Never <jk>null</jk>.
896    */
897   public static final <T extends Throwable> ThrowableAssertion<T> assertThrowable(T value) {
898      return ThrowableAssertion.create(value);
899   }
900
901   /**
902    * Performs an assertion on a Version.
903    *
904    * <h5 class='section'>Example:</h5>
905    * <p class='bjava'>
906    *    <jk>import static</jk> org.apache.juneau.assertions.Assertions.*;
907    *
908    *    <jc>// Asserts the specified major version is at least 2.</jc>
909    *    <jsm>assertVersion</jsm>(<jv>version</jv>)
910    *       .major().isGte(2);
911    * </p>
912    *
913    * <p>
914    * See <a class="doclink" href="../../../../index.html#ja.Overview">Fluent Assertions</a> for general assertion usage and {@link VersionAssertion} for supported operations on this type.
915    *
916    * @param value
917    *    The object being tested.
918    *    <br>Can be <jk>null</jk>.
919    * @return
920    *    A new assertion object.
921    *    <br>Never <jk>null</jk>.
922    */
923   public static final VersionAssertion assertVersion(Version value) {
924      return VersionAssertion.create(value);
925   }
926
927   /**
928    * Performs an assertion on a ZonedDateTime.
929    *
930    * <h5 class='section'>Example:</h5>
931    * <p class='bjava'>
932    *    <jk>import static</jk> org.apache.juneau.assertions.Assertions.*;
933    *
934    *    <jc>// Asserts the specified date is after the current date.</jc>
935    *    <jsm>assertZonedDateTime</jsm>(<jv>myZonedDateTime</jv>)
936    *       .isAfterNow();
937    * </p>
938    *
939    * <p>
940    * See <a class="doclink" href="../../../../index.html#ja.Overview">Fluent Assertions</a> for general assertion usage and {@link ZonedDateTimeAssertion} for supported operations on this type.
941    *
942    * @param value
943    *    The object being tested.
944    *    <br>Can be <jk>null</jk>.
945    * @return
946    *    A new assertion object.
947    *    <br>Never <jk>null</jk>.
948    */
949   public static final ZonedDateTimeAssertion assertZonedDateTime(ZonedDateTime value) {
950      return ZonedDateTimeAssertion.create(value);
951   }
952
953   //-----------------------------------------------------------------------------------------------------------------
954   // Snippet assertions
955   //-----------------------------------------------------------------------------------------------------------------
956
957   /**
958    * Executes an arbitrary snippet of code and captures anything thrown from it as a Throwable assertion.
959    *
960    * <h5 class='section'>Example:</h5>
961    * <p class='bjava'>
962    *    <jk>import static</jk> org.apache.juneau.assertions.Assertions.*;
963    *
964    *    <jc>// Asserts that the specified method throws a RuntimeException containing "foobar" in the message. </jc>
965    *    <jsm>assertThrown</jsm>(()-&gt;<jv>foo</jv>.getBar())
966    *       .isType(RuntimeException.<jk>class</jk>)
967    *       .message().contains(<js>"foobar"</js>);
968    * </p>
969    *
970    * @param snippet The snippet of code to execute.
971    * @return A new assertion object.  Never <jk>null</jk>.
972    */
973   public static final ThrowableAssertion<Throwable> assertThrown(Snippet snippet) {
974      try {
975         snippet.run();
976      } catch (Throwable e) {
977         return assertThrowable(e);
978      }
979      return assertThrowable(null);
980   }
981}