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 java.io.*;
016import java.time.*;
017import java.util.*;
018
019import org.apache.juneau.internal.*;
020
021/**
022 * Main class for creation of assertions for testing.
023 */
024public class Assertions {
025
026   /**
027    * Used for assertion calls against {@link Date} objects.
028    *
029    * <h5 class='section'>Example:</h5>
030    * <p class='bcode w800'>
031    *    <jc>// Validates the specified date is after the current date.</jc>
032    *    <jsm>assertDate</jsm>(<jv>myDate</jv>).isAfterNow();
033    * </p>
034    *
035    * @param value The date being wrapped.
036    * @return A new {@link DateAssertion} object.  Never <jk>null</jk>.
037    */
038   public static DateAssertion assertDate(Date value) {
039      return new DateAssertion(value);
040   }
041
042   /**
043    * Used for assertion calls against {@link ZonedDateTime} objects.
044    *
045    * <h5 class='section'>Example:</h5>
046    * <p class='bcode w800'>
047    *    <jc>// Validates the specified date is after the current date.</jc>
048    *    <jsm>assertZonedDateTime</jsm>(<jv>byZdt</jv>).isAfterNow();
049    * </p>
050    *
051    * @param value The date being wrapped.
052    * @return A new {@link ZonedDateTimeAssertion} object.  Never <jk>null</jk>.
053    */
054   public static ZonedDateTimeAssertion assertZonedDateTimeAssertion(ZonedDateTime value) {
055      return new ZonedDateTimeAssertion(value);
056   }
057
058   /**
059    * Used for assertion calls against integers.
060    *
061    * <h5 class='section'>Example:</h5>
062    * <p class='bcode w800'>
063    *    <jc>// Validates the response status code is 200 or 404.</jc>
064    *    <jsm>assertInteger</jsm>(<jv>httpReponse<jv>).isAny(200,404);
065    * </p>
066    *
067    * @param value The object being wrapped.
068    * @return A new {@link IntegerAssertion} object.  Never <jk>null</jk>.
069    */
070   public static IntegerAssertion assertInteger(Integer value) {
071      return new IntegerAssertion(value);
072   }
073
074   /**
075    * Used for assertion calls against longs.
076    *
077    * <h5 class='section'>Example:</h5>
078    * <p class='bcode w800'>
079    *    <jc>// Validates the response length isn't too long.</jc>
080    *    <jsm>assertLong</jsm>(<jv>responseLength</jv>).isLessThan(100000);
081    * </p>
082    *
083    * @param value The object being wrapped.
084    * @return A new {@link LongAssertion} object.  Never <jk>null</jk>.
085    */
086   public static LongAssertion assertLong(Long value) {
087      return new LongAssertion(value);
088   }
089
090   /**
091    * Used for assertion calls against longs.
092    *
093    * <h5 class='section'>Example:</h5>
094    * <p class='bcode w800'>
095    *    <jc>// Validates the response length isn't too long.</jc>
096    *    <jsm>assertLong</jsm>(<jv>responseLength</jv>).isLessThan(100000);
097    * </p>
098    *
099    * @param value The object being wrapped.
100    * @return A new {@link LongAssertion} object.  Never <jk>null</jk>.
101    */
102   public static ComparableAssertion assertComparable(Comparable<?> value) {
103      return new ComparableAssertion(value);
104   }
105
106   /**
107    * Used for assertion calls against arbitrary POJOs.
108    *
109    * <h5 class='section'>Example:</h5>
110    * <p class='bcode w800'>
111    *    <jc>// Validates the specified POJO is the specified type and serializes to the specified value.</jc>
112    *    <jsm>assertObject</jsm>(<jv>myPojo</jv>).instanceOf(MyBean.<jk>class</jk>).json().is(<js>"{foo:'bar'}"</js>);
113    * </p>
114    *
115    * @param value The object being wrapped.
116    * @return A new {@link ObjectAssertion} object.  Never <jk>null</jk>.
117    */
118   public static ObjectAssertion assertObject(Object value) {
119      return new ObjectAssertion(value);
120   }
121
122   /**
123    * Used for assertion calls against string objects.
124    *
125    * <h5 class='section'>Example:</h5>
126    * <p class='bcode w800'>
127    *    <jc>// Validates the response body of an HTTP call is the text "OK".</jc>
128    *    <jsm>assertString</jsm>(<jv>httpBody</jv>).is(<js>"OK"</js>);
129    * </p>
130    *
131    * @param value The string being wrapped.
132    * @return A new {@link StringAssertion} object.  Never <jk>null</jk>.
133    */
134   public static StringAssertion assertString(Object value) {
135      return new StringAssertion(value);
136   }
137
138   /**
139    * Used for assertion calls against boolean objects.
140    *
141    * <h5 class='section'>Example:</h5>
142    * <p class='bcode w800'>
143    *    <jc>// Validates that the specified boolean object exists and is true.</jc>
144    *    <jsm>assertBoolean</jsm>(<jv>myBoolean</jv>).exists().isTrue();
145    * </p>
146    *
147    * @param value The boolean being wrapped.
148    * @return A new {@link BooleanAssertion} object.  Never <jk>null</jk>.
149    */
150   public static BooleanAssertion assertBoolean(Boolean value) {
151      return new BooleanAssertion(value);
152   }
153
154   /**
155    * Used for assertion calls against throwable objects.
156    *
157    * <h5 class='section'>Example:</h5>
158    * <p class='bcode w800'>
159    *    <jc>// Validates the throwable message or one of the parent messages contain 'Foobar'.</jc>
160    *    <jsm>assertThrowable</jsm>(<jv>throwable</jv>).contains(<js>"Foobar"</js>);
161    * </p>
162    *
163    * @param value The throwable being wrapped.
164    * @return A new {@link ThrowableAssertion} object.  Never <jk>null</jk>.
165    */
166   public static ThrowableAssertion assertThrowable(Throwable value) {
167      return new ThrowableAssertion(value);
168   }
169
170   /**
171    * Used for assertion calls against arrays.
172    *
173    * <h5 class='section'>Example:</h5>
174    * <p class='bcode w800'>
175    *    String[] <jv>array</jv> = <jk>new</jk> String[]{<js>"foo"</js>};
176    *    <jsm>assertArray</jsm>(<jv>array</jv>).isSize(1);
177    * </p>
178    *
179    * @param value The object being wrapped.
180    * @return A new {@link ArrayAssertion} object.  Never <jk>null</jk>.
181    */
182   public static ArrayAssertion assertArray(Object value) {
183      return new ArrayAssertion(value);
184   }
185
186   /**
187    * Used for assertion calls against {@link Collection} objects.
188    *
189    * <h5 class='section'>Example:</h5>
190    * <p class='bcode w800'>
191    *    List=&lt;String&gt; <jv>list</jv> = AList.<jsm>of</jsm>(<js>"foo"</js>);
192    *    <jsm>assertCollection</jsm>(<jv>list</jv>).isNotEmpty();
193    * </p>
194    *
195    * @param value The object being wrapped.
196    * @return A new {@link CollectionAssertion} object.  Never <jk>null</jk>.
197    */
198   public static CollectionAssertion assertCollection(Collection<?> value) {
199      return new CollectionAssertion(value);
200   }
201
202   /**
203    * Used for assertion calls against {@link Collection} objects.
204    *
205    * <h5 class='section'>Example:</h5>
206    * <p class='bcode w800'>
207    *    List=&lt;String&gt; <jv>list</jv> = AList.<jsm>of</jsm>(<js>"foo"</js>);
208    *    <jsm>assertList</jsm>(<jv>list</jv>).item(0).isEqual(<js>"foo"</js>);
209    * </p>
210    *
211    * @param value The object being wrapped.
212    * @return A new {@link ListAssertion} object.  Never <jk>null</jk>.
213    */
214   public static ListAssertion assertList(List<?> value) {
215      return new ListAssertion(value);
216   }
217
218   /**
219    * Executes an arbitrary snippet of code and captures anything thrown from it.
220    *
221    * <h5 class='section'>Example:</h5>
222    * <p class='bcode w800'>
223    *    <jc>// Asserts that the specified method throws a RuntimeException containing "Foobar" in the message. </jc>
224    *    <jsm>assertThrown</jsm>(()-&gt;<jv>foo</jv>.getBar())
225    *       .exists()
226    *       .isType(RuntimeException.<jk>class</jk>)
227    *       .contains(<js>"Foobar"</js>);
228    * </p>
229    *
230    * @param snippet The snippet of code to execute.
231    * @return A new assertion object.  Never <jk>null</jk>.
232    */
233   public static ThrowableAssertion assertThrown(Snippet snippet) {
234      try {
235         snippet.run();
236      } catch (Throwable e) {
237         return assertThrowable(e);
238      }
239      return assertThrowable(null);
240   }
241
242   /**
243    * Used for assertion calls against the contents of input streams.
244    *
245    * <h5 class='section'>Example:</h5>
246    * <p class='bcode w800'>
247    *    <jc>// Validates that the stream contains the string "foo".</jc>
248    *    <jsm>assertStream</jsm>(<jv>myStream</jv>).hex().is(<js>"666F6F"</js>);
249    * </p>
250    *
251    * @param is The input stream being wrapped.
252    * @return A new {@link ByteArrayAssertion} object.  Never <jk>null</jk>.
253    * @throws IOException If thrown while reading contents from stream.
254    */
255   public static ByteArrayAssertion assertStream(InputStream is) throws IOException {
256      return new ByteArrayAssertion(is == null ? null : IOUtils.readBytes(is));
257   }
258
259   /**
260    * Used for assertion calls against byte arrays.
261    *
262    * <h5 class='section'>Example:</h5>
263    * <p class='bcode w800'>
264    *    <jc>// Validates that the byte array contains the string "foo".</jc>
265    *    <jsm>assertBytes</jsm>(<jv>myBytes</jv>).hex().is(<js>"666F6F"</js>);
266    * </p>
267    *
268    * @param bytes The byte array being wrapped.
269    * @return A new {@link ByteArrayAssertion} object.  Never <jk>null</jk>.
270    */
271   public static ByteArrayAssertion assertBytes(byte[] bytes) {
272      return new ByteArrayAssertion(bytes);
273   }
274
275   /**
276    * Used for assertion calls against the contents of readers.
277    *
278    * <h5 class='section'>Example:</h5>
279    * <p class='bcode w800'>
280    *    <jc>// Validates the throwable message or one of the parent messages contain 'Foobar'.</jc>
281    *    <jsm>assertReader</jsm>(<jv>myReader</jv>).is(<js>"foo"</js>);
282    * </p>
283    *
284    * @param r The reader being wrapped.
285    * @return A new {@link StringAssertion} object.  Never <jk>null</jk>.
286    * @throws IOException If thrown while reading contents from reader.
287    */
288   public static StringAssertion assertReader(Reader r) throws IOException {
289      return new StringAssertion(r == null ? null : IOUtils.read(r));
290   }
291}