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.commons.utils.AssertionUtils.*;
020import static org.apache.juneau.commons.utils.Utils.*;
021
022import java.io.*;
023import java.util.function.*;
024
025import org.apache.juneau.cp.*;
026import org.apache.juneau.serializer.*;
027
028/**
029 * Used for fluent assertion calls against comparable objects.
030 *
031 * <h5 class='section'>Test Methods:</h5>
032 * <p>
033 * <ul class='javatree'>
034 *    <li class='jc'>{@link FluentComparableAssertion}
035 *    <ul class='javatreec'>
036 *       <li class='jm'>{@link FluentComparableAssertion#isGt(Comparable) isGt(Comparable)}
037 *       <li class='jm'>{@link FluentComparableAssertion#isGte(Comparable) isGte(Comparable)}
038 *       <li class='jm'>{@link FluentComparableAssertion#isLt(Comparable) isLt(Comparable)}
039 *       <li class='jm'>{@link FluentComparableAssertion#isLte(Comparable) isLte(Comparable)}
040 *       <li class='jm'>{@link FluentComparableAssertion#isBetween(Comparable,Comparable) isBetween(Comparable,Comparable)}
041 *    </ul>
042 *    <li class='jc'>{@link FluentObjectAssertion}
043 *    <ul class='javatreec'>
044 *       <li class='jm'>{@link FluentObjectAssertion#isExists() isExists()}
045 *       <li class='jm'>{@link FluentObjectAssertion#is(Object) is(Object)}
046 *       <li class='jm'>{@link FluentObjectAssertion#is(Predicate) is(Predicate)}
047 *       <li class='jm'>{@link FluentObjectAssertion#isNot(Object) isNot(Object)}
048 *       <li class='jm'>{@link FluentObjectAssertion#isAny(Object...) isAny(Object...)}
049 *       <li class='jm'>{@link FluentObjectAssertion#isNotAny(Object...) isNotAny(Object...)}
050 *       <li class='jm'>{@link FluentObjectAssertion#isNull() isNull()}
051 *       <li class='jm'>{@link FluentObjectAssertion#isNotNull() isNotNull()}
052 *       <li class='jm'>{@link FluentObjectAssertion#isString(String) isString(String)}
053 *       <li class='jm'>{@link FluentObjectAssertion#isJson(String) isJson(String)}
054 *       <li class='jm'>{@link FluentObjectAssertion#isSame(Object) isSame(Object)}
055 *       <li class='jm'>{@link FluentObjectAssertion#isSameJsonAs(Object) isSameJsonAs(Object)}
056 *       <li class='jm'>{@link FluentObjectAssertion#isSameSortedJsonAs(Object) isSameSortedJsonAs(Object)}
057 *       <li class='jm'>{@link FluentObjectAssertion#isSameSerializedAs(Object, WriterSerializer) isSameSerializedAs(Object, WriterSerializer)}
058 *       <li class='jm'>{@link FluentObjectAssertion#isType(Class) isType(Class)}
059 *       <li class='jm'>{@link FluentObjectAssertion#isExactType(Class) isExactType(Class)}
060 *    </ul>
061 * </ul>
062 *
063 * <h5 class='section'>Transform Methods:</h5>
064 * <p>
065 * <ul class='javatree'>
066 *    <li class='jc'>{@link FluentObjectAssertion}
067 *    <ul class='javatreec'>
068 *       <li class='jm'>{@link FluentObjectAssertion#asString() asString()}
069 *       <li class='jm'>{@link FluentObjectAssertion#asString(WriterSerializer) asString(WriterSerializer)}
070 *       <li class='jm'>{@link FluentObjectAssertion#asString(Function) asString(Function)}
071 *       <li class='jm'>{@link FluentObjectAssertion#asJson() asJson()}
072 *       <li class='jm'>{@link FluentObjectAssertion#asJsonSorted() asJsonSorted()}
073 *       <li class='jm'>{@link FluentObjectAssertion#asTransformed(Function) asApplied(Function)}
074 *       <li class='jm'>{@link FluentObjectAssertion#asAny() asAny()}
075 * </ul>
076 * </ul>
077 *
078 * <h5 class='section'>Configuration Methods:</h5>
079 * <p>
080 * <ul class='javatree'>
081 *    <li class='jc'>{@link Assertion}
082 *    <ul class='javatreec'>
083 *       <li class='jm'>{@link Assertion#setMsg(String, Object...) setMsg(String, Object...)}
084 *       <li class='jm'>{@link Assertion#setOut(PrintStream) setOut(PrintStream)}
085 *       <li class='jm'>{@link Assertion#setSilent() setSilent()}
086 *       <li class='jm'>{@link Assertion#setStdOut() setStdOut()}
087 *       <li class='jm'>{@link Assertion#setThrowable(Class) setThrowable(Class)}
088 *    </ul>
089 * </ul>
090 *
091 * <h5 class='section'>See Also:</h5><ul>
092 *    <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/JuneauEcosystemOverview">Juneau Ecosystem Overview</a>
093 * </ul>
094 *
095 * @param <T> The value type
096 * @param <R> The return type.
097 */
098@SuppressWarnings("rawtypes")
099public class FluentComparableAssertion<T extends Comparable,R> extends FluentObjectAssertion<T,R> {
100
101   // @formatter:off
102   private static final Messages MESSAGES = Messages.of(FluentComparableAssertion.class, "Messages");
103   private static final String
104      MSG_valueWasNotGreaterThanExpected = MESSAGES.getString("valueWasNotGreaterThanExpected"),
105      MSG_valueWasNotGreaterOrEqualsToExpected = MESSAGES.getString("valueWasNotGreaterOrEqualsToExpected"),
106      MSG_valueWasNotLessThanExpected = MESSAGES.getString("valueWasNotLessThanExpected"),
107      MSG_valueWasNotLessOrEqualsToExpected = MESSAGES.getString("valueWasNotLessOrEqualsToExpected");
108   // @formatter:on
109
110   /**
111    * Chained constructor.
112    *
113    * <p>
114    * Used when transforming one assertion into another so that the assertion config can be used by the new assertion.
115    *
116    * @param creator
117    *    The assertion that created this assertion.
118    *    <br>Should be <jk>null</jk> if this is the top-level assertion.
119    * @param value
120    *    The object being tested.
121    *    <br>Can be <jk>null</jk>.
122    * @param returns
123    *    The object to return after a test method is called.
124    *    <br>If <jk>null</jk>, the test method returns this object allowing multiple test method calls to be
125    * used on the same assertion.
126    */
127   public FluentComparableAssertion(Assertion creator, T value, R returns) {
128      super(creator, value, returns);
129   }
130
131   /**
132    * Constructor.
133    *
134    * @param value
135    *    The object being tested.
136    *    <br>Can be <jk>null</jk>.
137    * @param returns
138    *    The object to return after a test method is called.
139    *    <br>If <jk>null</jk>, the test method returns this object allowing multiple test method calls to be
140    * used on the same assertion.
141    */
142   public FluentComparableAssertion(T value, R returns) {
143      this(null, value, returns);
144   }
145
146   @Override /* Overridden from FluentObjectAssertion */
147   public FluentComparableAssertion<T,R> asTransformed(Function<T,T> function) { // NOSONAR - Intentional.
148      return new FluentComparableAssertion<>(this, function.apply(orElse(null)), returns());
149   }
150
151   /**
152    * Asserts that the value is between (inclusive) the specified upper and lower values.
153    *
154    * @param lower The lower value to check against.
155    * @param upper The upper value to check against.
156    * @return The fluent return object.
157    * @throws AssertionError If assertion failed.
158    */
159   public R isBetween(Comparable lower, Comparable upper) throws AssertionError {
160      isExists();
161      assertArgNotNull("lower", lower);
162      assertArgNotNull("upper", upper);
163      isLte(upper);
164      isGte(lower);
165      return returns();
166   }
167
168   /**
169    * Asserts that the value is greater than the specified value.
170    *
171    * @param value The values to check against.
172    * @return The fluent return object.
173    * @throws AssertionError If assertion failed.
174    */
175   @SuppressWarnings("unchecked")
176   public R isGt(Comparable value) throws AssertionError {
177      assertArgNotNull("value", value);
178      if (value().compareTo(value) <= 0)
179         throw error(MSG_valueWasNotGreaterThanExpected, r(value), r(value()));
180      return returns();
181   }
182
183   /**
184    * Asserts that the value is greater than or equal to the specified value.
185    *
186    * @param value The values to check against.
187    * @return The fluent return object.
188    * @throws AssertionError If assertion failed.
189    */
190   @SuppressWarnings("unchecked")
191   public R isGte(Comparable value) throws AssertionError {
192      assertArgNotNull("value", value);
193      if (value().compareTo(value) < 0)
194         throw error(MSG_valueWasNotGreaterOrEqualsToExpected, r(value), r(value()));
195      return returns();
196   }
197
198   /**
199    * Asserts that the value is less than the specified value.
200    *
201    * @param value The values to check against.
202    * @return The fluent return object.
203    * @throws AssertionError If assertion failed.
204    */
205   @SuppressWarnings("unchecked")
206   public R isLt(Comparable value) throws AssertionError {
207      assertArgNotNull("value", value);
208      if (value().compareTo(value) >= 0)
209         throw error(MSG_valueWasNotLessThanExpected, r(value), r(value()));
210      return returns();
211   }
212
213   /**
214    * Asserts that the value is less than or equals to the specified value.
215    *
216    * @param value The values to check against.
217    * @return The fluent return object.
218    * @throws AssertionError If assertion failed.
219    */
220   @SuppressWarnings("unchecked")
221   public R isLte(Comparable value) throws AssertionError {
222      assertArgNotNull("value", value);
223      if (value().compareTo(value) > 0)
224         throw error(MSG_valueWasNotLessOrEqualsToExpected, r(value), r(value()));
225      return returns();
226   }
227
228   @Override /* Overridden from Assertion */
229   public FluentComparableAssertion<T,R> setMsg(String msg, Object...args) {
230      super.setMsg(msg, args);
231      return this;
232   }
233
234   @Override /* Overridden from Assertion */
235   public FluentComparableAssertion<T,R> setOut(PrintStream value) {
236      super.setOut(value);
237      return this;
238   }
239
240   @Override /* Overridden from Assertion */
241   public FluentComparableAssertion<T,R> setSilent() {
242      super.setSilent();
243      return this;
244   }
245
246   @Override /* Overridden from Assertion */
247   public FluentComparableAssertion<T,R> setStdOut() {
248      super.setStdOut();
249      return this;
250   }
251
252   @Override /* Overridden from Assertion */
253   public FluentComparableAssertion<T,R> setThrowable(Class<? extends java.lang.RuntimeException> value) {
254      super.setThrowable(value);
255      return this;
256   }
257}