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.rest.client.assertion; 018 019import java.io.*; 020import java.lang.reflect.*; 021import java.util.*; 022import java.util.function.*; 023import java.util.regex.*; 024 025import org.apache.juneau.assertions.*; 026import org.apache.juneau.http.response.*; 027import org.apache.juneau.internal.*; 028import org.apache.juneau.rest.client.*; 029import org.apache.juneau.serializer.*; 030 031/** 032 * Used for fluent assertion calls against {@link ResponseHeader} objects. 033 * 034 * <h5 class='topic'>Test Methods</h5> 035 * <p> 036 * <ul class='javatree'> 037 * <li class='jc'>{@link FluentStringAssertion} 038 * <ul class='javatreec'> 039 * <li class='jm'>{@link FluentStringAssertion#is(String) is(String)} 040 * <li class='jm'>{@link FluentStringAssertion#isNot(String) isNot(String)} 041 * <li class='jm'>{@link FluentStringAssertion#isLines(String...) isLines(String...)} 042 * <li class='jm'>{@link FluentStringAssertion#isSortedLines(String...) isSortedLines(String...)} 043 * <li class='jm'>{@link FluentStringAssertion#isIc(String) isIc(String)} 044 * <li class='jm'>{@link FluentStringAssertion#isNotIc(String) isNotIc(String)} 045 * <li class='jm'>{@link FluentStringAssertion#isContains(String...) isContains(String...)} 046 * <li class='jm'>{@link FluentStringAssertion#isNotContains(String...) isNotContains(String...)} 047 * <li class='jm'>{@link FluentStringAssertion#isEmpty() isEmpty()} 048 * <li class='jm'>{@link FluentStringAssertion#isNotEmpty() isNotEmpty()} 049 * <li class='jm'>{@link FluentStringAssertion#isString(Object) isString(Object)} 050 * <li class='jm'>{@link FluentStringAssertion#isMatches(String) isMatches(String)} 051 * <li class='jm'>{@link FluentStringAssertion#isPattern(String) isPattern(String)} 052 * <li class='jm'>{@link FluentStringAssertion#isPattern(String,int) isPattern(String,int)} 053 * <li class='jm'>{@link FluentStringAssertion#isPattern(Pattern) isPattern(Pattern)} 054 * <li class='jm'>{@link FluentStringAssertion#isStartsWith(String) isStartsWith(String)} 055 * <li class='jm'>{@link FluentStringAssertion#isEndsWith(String) isEndsWith(String)} 056 * </ul> 057 * <li class='jc'>{@link FluentObjectAssertion} 058 * <ul class='javatreec'> 059 * <li class='jm'>{@link FluentObjectAssertion#isExists() isExists()} 060 * <li class='jm'>{@link FluentObjectAssertion#is(Object) is(Object)} 061 * <li class='jm'>{@link FluentObjectAssertion#is(Predicate) is(Predicate)} 062 * <li class='jm'>{@link FluentObjectAssertion#isNot(Object) isNot(Object)} 063 * <li class='jm'>{@link FluentObjectAssertion#isAny(Object...) isAny(Object...)} 064 * <li class='jm'>{@link FluentObjectAssertion#isNotAny(Object...) isNotAny(Object...)} 065 * <li class='jm'>{@link FluentObjectAssertion#isNull() isNull()} 066 * <li class='jm'>{@link FluentObjectAssertion#isNotNull() isNotNull()} 067 * <li class='jm'>{@link FluentObjectAssertion#isString(String) isString(String)} 068 * <li class='jm'>{@link FluentObjectAssertion#isJson(String) isJson(String)} 069 * <li class='jm'>{@link FluentObjectAssertion#isSame(Object) isSame(Object)} 070 * <li class='jm'>{@link FluentObjectAssertion#isSameJsonAs(Object) isSameJsonAs(Object)} 071 * <li class='jm'>{@link FluentObjectAssertion#isSameSortedJsonAs(Object) isSameSortedJsonAs(Object)} 072 * <li class='jm'>{@link FluentObjectAssertion#isSameSerializedAs(Object, WriterSerializer) isSameSerializedAs(Object, WriterSerializer)} 073 * <li class='jm'>{@link FluentObjectAssertion#isType(Class) isType(Class)} 074 * <li class='jm'>{@link FluentObjectAssertion#isExactType(Class) isExactType(Class)} 075 * </ul> 076 * </ul> 077 * 078 * <h5 class='topic'>Transform Methods</h5> 079 * <p> 080 * <ul class='javatree'> 081 * <li class='jc'>{@link FluentResponseHeaderAssertion} 082 * <ul class='javatreec'> 083 * <li class='jm'>{@link FluentResponseHeaderAssertion#asBoolean() asBoolean()} 084 * <li class='jm'>{@link FluentResponseHeaderAssertion#asInteger() asInteger()} 085 * <li class='jm'>{@link FluentResponseHeaderAssertion#asLong() asLong()} 086 * <li class='jm'>{@link FluentResponseHeaderAssertion#asZonedDateTime() asZonedDateTime()} 087 * <li class='jm'>{@link FluentResponseHeaderAssertion#as(Class) as(Class)} 088 * <li class='jm'>{@link FluentResponseHeaderAssertion#as(Type,Type...) as(Type,Type...)} 089 * </ul> 090 * <li class='jc'>{@link FluentStringAssertion} 091 * <ul class='javatreec'> 092 * <li class='jm'>{@link FluentStringAssertion#asReplaceAll(String,String) asReplaceAll(String,String)} 093 * <li class='jm'>{@link FluentStringAssertion#asReplace(String,String) asReplace(String,String)} 094 * <li class='jm'>{@link FluentStringAssertion#asUrlDecode() asUrlDecode()} 095 * <li class='jm'>{@link FluentStringAssertion#asLc() asLc()} 096 * <li class='jm'>{@link FluentStringAssertion#asUc() asUc()} 097 * <li class='jm'>{@link FluentStringAssertion#asLines() asLines()} 098 * <li class='jm'>{@link FluentStringAssertion#asSplit(String) asSplit(String)} 099 * <li class='jm'>{@link FluentStringAssertion#asLength() asLength()} 100 * <li class='jm'>{@link FluentStringAssertion#asOneLine() asOneLine()} 101 * </ul> 102 * <li class='jc'>{@link FluentObjectAssertion} 103 * <ul class='javatreec'> 104 * <li class='jm'>{@link FluentObjectAssertion#asString() asString()} 105 * <li class='jm'>{@link FluentObjectAssertion#asString(WriterSerializer) asString(WriterSerializer)} 106 * <li class='jm'>{@link FluentObjectAssertion#asString(Function) asString(Function)} 107 * <li class='jm'>{@link FluentObjectAssertion#asJson() asJson()} 108 * <li class='jm'>{@link FluentObjectAssertion#asJsonSorted() asJsonSorted()} 109 * <li class='jm'>{@link FluentObjectAssertion#asTransformed(Function) asApplied(Function)} 110 * <li class='jm'>{@link FluentObjectAssertion#asAny() asAny()} 111 * </ul> 112 * </ul> 113 * 114 * <h5 class='topic'>Configuration Methods</h5> 115 * <p> 116 * <ul class='javatree'> 117 * <li class='jc'>{@link Assertion} 118 * <ul class='javatreec'> 119 * <li class='jm'>{@link Assertion#setMsg(String, Object...) setMsg(String, Object...)} 120 * <li class='jm'>{@link Assertion#setOut(PrintStream) setOut(PrintStream)} 121 * <li class='jm'>{@link Assertion#setSilent() setSilent()} 122 * <li class='jm'>{@link Assertion#setStdOut() setStdOut()} 123 * <li class='jm'>{@link Assertion#setThrowable(Class) setThrowable(Class)} 124 * </ul> 125 * </ul> 126 * 127 * <h5 class='section'>See Also:</h5><ul> 128 * <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/JuneauEcosystemOverview">Juneau Ecosystem Overview</a> 129 * <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/JuneauRestClientBasics">juneau-rest-client Basics</a> 130 * </ul> 131 * 132 * @param <R> The return type. 133 */ 134public class FluentResponseHeaderAssertion<R> extends FluentStringAssertion<R> { 135 136 private final ResponseHeader value; 137 138 //----------------------------------------------------------------------------------------------------------------- 139 // Constructors 140 //----------------------------------------------------------------------------------------------------------------- 141 142 /** 143 * Constructor. 144 * 145 * @param value 146 * The object being tested. 147 * <br>Can be <jk>null</jk>. 148 * @param returns 149 * The object to return after a test method is called. 150 * <br>If <jk>null</jk>, the test method returns this object allowing multiple test method calls to be 151 * used on the same assertion. 152 */ 153 public FluentResponseHeaderAssertion(ResponseHeader value, R returns) { 154 this(null, value, returns); 155 } 156 157 /** 158 * Chained constructor. 159 * 160 * <p> 161 * Used when transforming one assertion into another so that the assertion config can be used by the new assertion. 162 * 163 * @param creator 164 * The assertion that created this assertion. 165 * <br>Should be <jk>null</jk> if this is the top-level assertion. 166 * @param value 167 * The object being tested. 168 * <br>Can be <jk>null</jk>. 169 * @param returns 170 * The object to return after a test method is called. 171 * <br>If <jk>null</jk>, the test method returns this object allowing multiple test method calls to be 172 * used on the same assertion. 173 */ 174 public FluentResponseHeaderAssertion(Assertion creator, ResponseHeader value, R returns) { 175 super(creator, value.asString().orElse(null), returns); 176 this.value = value; 177 setThrowable(BadRequest.class); 178 } 179 180 //----------------------------------------------------------------------------------------------------------------- 181 // Transform methods 182 //----------------------------------------------------------------------------------------------------------------- 183 184 /** 185 * Converts this object assertion into a boolean assertion. 186 * 187 * @return A new assertion. 188 * @throws AssertionError If object is not a boolean. 189 */ 190 public FluentBooleanAssertion<R> asBoolean() { 191 return new FluentBooleanAssertion<>(this, value.asBoolean().orElse(null), returns()); 192 } 193 194 /** 195 * Converts this object assertion into an integer assertion. 196 * 197 * @return A new assertion. 198 * @throws AssertionError If object is not an integer. 199 */ 200 public FluentIntegerAssertion<R> asInteger() { 201 return new FluentIntegerAssertion<>(this, value.asInteger().orElse(null), returns()); 202 } 203 204 /** 205 * Converts this object assertion into a long assertion. 206 * 207 * @return A new assertion. 208 * @throws AssertionError If object is not a long. 209 */ 210 public FluentLongAssertion<R> asLong() { 211 return new FluentLongAssertion<>(this, value.asLong().orElse(null), returns()); 212 } 213 214 /** 215 * Converts this object assertion into a zoned-datetime assertion. 216 * 217 * @return A new assertion. 218 * @throws AssertionError If object is not a zoned-datetime. 219 */ 220 public FluentZonedDateTimeAssertion<R> asZonedDateTime() { 221 return new FluentZonedDateTimeAssertion<>(this, value.asDateHeader().asZonedDateTime().orElse(null), returns()); 222 } 223 224 /** 225 * Converts the parameter value to a type using {@link ResponseHeader#as(Class)} and then returns the value as an any-object assertion. 226 * 227 * @param <T> The object type to create. 228 * @param type The object type to create. 229 * @return A new fluent assertion object. 230 * @throws RestCallException If value could not be parsed. 231 */ 232 public <T> FluentAnyAssertion<T,R> as(Class<T> type) throws RestCallException { 233 return new FluentAnyAssertion<>(value.as(type).orElse(null), returns()); 234 } 235 236 /** 237 * Converts the parameter value to a type using {@link ResponseHeader#as(Type,Type...)} and then returns the value as an any-object assertion. 238 * 239 * <p> 240 * See <a class="doclink" href="https://juneau.apache.org/docs/topics/ComplexDataTypes">Complex Data Types</a> for information on defining complex generic types of {@link Map Maps} and {@link Collection Collections}. 241 * 242 * @param type The object type to create. 243 * @param args Optional type arguments. 244 * @return A new fluent assertion object. 245 * @throws RestCallException If value could not be parsed. 246 */ 247 public FluentAnyAssertion<Object,R> as(Type type, Type...args) throws RestCallException { 248 return new FluentAnyAssertion<>(value.as(type, args).orElse(null), returns()); 249 } 250 251 //----------------------------------------------------------------------------------------------------------------- 252 // Fluent setters 253 //----------------------------------------------------------------------------------------------------------------- 254 @Override /* Overridden from Assertion */ 255 public FluentResponseHeaderAssertion<R> setMsg(String msg, Object...args) { 256 super.setMsg(msg, args); 257 return this; 258 } 259 260 @Override /* Overridden from Assertion */ 261 public FluentResponseHeaderAssertion<R> setOut(PrintStream value) { 262 super.setOut(value); 263 return this; 264 } 265 266 @Override /* Overridden from Assertion */ 267 public FluentResponseHeaderAssertion<R> setSilent() { 268 super.setSilent(); 269 return this; 270 } 271 272 @Override /* Overridden from Assertion */ 273 public FluentResponseHeaderAssertion<R> setStdOut() { 274 super.setStdOut(); 275 return this; 276 } 277 278 @Override /* Overridden from Assertion */ 279 public FluentResponseHeaderAssertion<R> setThrowable(Class<? extends java.lang.RuntimeException> value) { 280 super.setThrowable(value); 281 return this; 282 } 283 284 @Override /* Overridden from FluentStringAssertion */ 285 public FluentResponseHeaderAssertion<R> asJavaStrings() { 286 super.asJavaStrings(); 287 return this; 288 } 289}