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.Utils.*;
020
021import java.io.*;
022
023/**
024 * Parent class of all fluent assertion calls.
025 *
026 * <p>
027 * Defines a {@link #returns()} method that returns an original object.
028 * Assertion test methods that pass use this method to return to the origin of the call.
029 *
030 * <h5 class='figure'>Example:</h5>
031 * <p class='bjava'>
032 *    <jc>// Create a basic REST client with JSON support and download a bean.</jc>
033 *    MyPojo <jv>myPojo</jv> = ...;
034 *    MyTestedBean <jv>myTestedBean</jv> = ...;
035 *
036 *    Assertion <jv>assertion</jv> = <jk>new</jk> FluentBeanAssertion&lt;MyPojo,MyTestedBean&gt;(<jv>myPojo</jv>, <jv>myTestedBean</jv>);
037 *    <jv>myPojo</jv> = <jv>assertion</jv>.test(<jv>x</jv> -&gt; <jv>x</jv>.getMyProperty().equals(<js>"foo"</js>));  <jc>// Returns myPojo after test.</jc>
038 * </p>
039 * <p>
040 * For subclasses such as {@link IntegerAssertion}, the return object is simply itself so that multiple tests
041 * can be performed using the same assertion.
042 * <h5 class='figure'>Example:</h5>
043 * <p class='bjava'>
044 *    <jk>public class</jk> IntegerAssertion <jk>extends</jk> FluentIntegerAssertion&lt;IntegerAssertion&gt; {
045 *    ...
046 *    }
047 *
048 *    Assertion <jv>assertion</jv> = <jk>new</jk> IntegerAssertion(123);
049 *    <jv>assertion</jv>
050 *       .isNotNull()
051 *       .isGt(100)
052 *  ;
053 * </p>
054 *
055 *
056 * <h5 class='section'>Test Methods:</h5>
057 * <p>
058 * <ul class='javatree'>
059 *    <li>None
060 * </ul>
061  *
062 * <h5 class='section'>Transform Methods:</h5>
063 * <p>
064 * <ul class='javatree'>
065 *    <li>None
066 * </ul>
067 *
068 * <h5 class='section'>Configuration Methods:</h5>
069 * <p>
070 * <ul class='javatree'>
071 *    <li class='jc'>{@link Assertion}
072 *    <ul class='javatreec'>
073 *       <li class='jm'>{@link Assertion#setMsg(String, Object...) setMsg(String, Object...)}
074 *       <li class='jm'>{@link Assertion#setOut(PrintStream) setOut(PrintStream)}
075 *       <li class='jm'>{@link Assertion#setSilent() setSilent()}
076 *       <li class='jm'>{@link Assertion#setStdOut() setStdOut()}
077 *       <li class='jm'>{@link Assertion#setThrowable(Class) setThrowable(Class)}
078 *    </ul>
079 * </ul>
080 *
081 * <h5 class='section'>See Also:</h5><ul>
082 *    <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/JuneauEcosystemOverview">Juneau Ecosystem Overview</a>
083 * </ul>
084 *
085 * @param <R> The return type.
086 */
087public abstract class FluentAssertion<R> extends Assertion {
088
089   private final R returns;
090
091   /**
092    * Constructor.
093    *
094    * @param creator
095    *    The assertion that created this assertion.
096    *    <br>Should be <jk>null</jk> if this is the top-level assertion.
097    * @param returns
098    *    The object to return after a test method is called.
099    *    <br>If <jk>null</jk>, the test method returns this object allowing multiple test method calls to be
100    * used on the same assertion.
101    */
102   protected FluentAssertion(Assertion creator, R returns) {
103      super(creator);
104      this.returns = returns;
105   }
106
107   @Override /* Overridden from Assertion */
108   public FluentAssertion<R> setMsg(String msg, Object...args) {
109      super.setMsg(msg, args);
110      return this;
111   }
112
113   @Override /* Overridden from Assertion */
114   public FluentAssertion<R> setOut(PrintStream value) {
115      super.setOut(value);
116      return this;
117   }
118
119   @Override /* Overridden from Assertion */
120   public FluentAssertion<R> setSilent() {
121      super.setSilent();
122      return this;
123   }
124
125   @Override /* Overridden from Assertion */
126   public FluentAssertion<R> setStdOut() {
127      super.setStdOut();
128      return this;
129   }
130
131   @Override /* Overridden from Assertion */
132   public FluentAssertion<R> setThrowable(Class<? extends java.lang.RuntimeException> value) {
133      super.setThrowable(value);
134      return this;
135   }
136
137   /**
138    * Returns the object that the fluent methods on this class should return.
139    *
140    * @return The response object.
141    */
142   @SuppressWarnings("unchecked")
143   protected R returns() {
144      return nn(returns) ? returns : (R)this;
145   }
146}