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 java.io.*;
020
021import org.apache.juneau.internal.*;
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   //-----------------------------------------------------------------------------------------------------------------
090   // Instance
091   //-----------------------------------------------------------------------------------------------------------------
092
093   private final R returns;
094
095   /**
096    * Constructor.
097    *
098    * @param creator
099    *    The assertion that created this assertion.
100    *    <br>Should be <jk>null</jk> if this is the top-level assertion.
101    * @param returns
102    *    The object to return after a test method is called.
103    *    <br>If <jk>null</jk>, the test method returns this object allowing multiple test method calls to be
104    * used on the same assertion.
105    */
106   protected FluentAssertion(Assertion creator, R returns) {
107      super(creator);
108      this.returns = returns;
109   }
110
111   //-----------------------------------------------------------------------------------------------------------------
112   // Fluent setters
113   //-----------------------------------------------------------------------------------------------------------------
114   @Override /* Overridden from Assertion */
115   public FluentAssertion<R> setMsg(String msg, Object...args) {
116      super.setMsg(msg, args);
117      return this;
118   }
119
120   @Override /* Overridden from Assertion */
121   public FluentAssertion<R> setOut(PrintStream value) {
122      super.setOut(value);
123      return this;
124   }
125
126   @Override /* Overridden from Assertion */
127   public FluentAssertion<R> setSilent() {
128      super.setSilent();
129      return this;
130   }
131
132   @Override /* Overridden from Assertion */
133   public FluentAssertion<R> setStdOut() {
134      super.setStdOut();
135      return this;
136   }
137
138   @Override /* Overridden from Assertion */
139   public FluentAssertion<R> setThrowable(Class<? extends java.lang.RuntimeException> value) {
140      super.setThrowable(value);
141      return this;
142   }
143   //-----------------------------------------------------------------------------------------------------------------
144   // Utility methods
145   //-----------------------------------------------------------------------------------------------------------------
146
147   /**
148    * Returns the object that the fluent methods on this class should return.
149    *
150    * @return The response object.
151    */
152   protected R returns() {
153      return returns != null ? returns : (R)this;
154   }
155}