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