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.CollectionUtils.*; 021import static org.apache.juneau.commons.utils.StringUtils.*; 022import static org.apache.juneau.commons.utils.Utils.*; 023 024import java.io.*; 025import java.util.*; 026import java.util.function.*; 027import java.util.regex.*; 028 029import org.apache.juneau.commons.utils.*; 030import org.apache.juneau.cp.*; 031import org.apache.juneau.serializer.*; 032 033/** 034 * Used for fluent assertion calls against strings. 035 * 036 * <h5 class='section'>Example:</h5> 037 * <p class='bjava'> 038 * <jc>// Validates the response body of an HTTP call is the text "OK".</jc> 039 * <jv>client</jv> 040 * .get(<jsf>URL</jsf>) 041 * .run() 042 * .assertContent().is(<js>"OK"</js>); 043 * </p> 044 * 045 * 046 * <h5 class='section'>Test Methods:</h5> 047 * <p> 048 * <ul class='javatree'> 049 * <li class='jc'>{@link FluentStringAssertion} 050 * <ul class='javatreec'> 051 * <li class='jm'>{@link FluentStringAssertion#is(String) is(String)} 052 * <li class='jm'>{@link FluentStringAssertion#isNot(String) isNot(String)} 053 * <li class='jm'>{@link FluentStringAssertion#isLines(String...) isLines(String...)} 054 * <li class='jm'>{@link FluentStringAssertion#isSortedLines(String...) isSortedLines(String...)} 055 * <li class='jm'>{@link FluentStringAssertion#isIc(String) isIc(String)} 056 * <li class='jm'>{@link FluentStringAssertion#isNotIc(String) isNotIc(String)} 057 * <li class='jm'>{@link FluentStringAssertion#isContains(String...) isContains(String...)} 058 * <li class='jm'>{@link FluentStringAssertion#isNotContains(String...) isNotContains(String...)} 059 * <li class='jm'>{@link FluentStringAssertion#isEmpty() isEmpty()} 060 * <li class='jm'>{@link FluentStringAssertion#isNotEmpty() isNotEmpty()} 061 * <li class='jm'>{@link FluentStringAssertion#isString(Object) isString(Object)} 062 * <li class='jm'>{@link FluentStringAssertion#isMatches(String) isMatches(String)} 063 * <li class='jm'>{@link FluentStringAssertion#isPattern(String) isPattern(String)} 064 * <li class='jm'>{@link FluentStringAssertion#isPattern(String,int) isPattern(String,int)} 065 * <li class='jm'>{@link FluentStringAssertion#isPattern(Pattern) isPattern(Pattern)} 066 * <li class='jm'>{@link FluentStringAssertion#isStartsWith(String) isStartsWith(String)} 067 * <li class='jm'>{@link FluentStringAssertion#isEndsWith(String) isEndsWith(String)} 068 * </ul> 069 * <li class='jc'>{@link FluentObjectAssertion} 070 * <ul class='javatreec'> 071 * <li class='jm'>{@link FluentObjectAssertion#isExists() isExists()} 072 * <li class='jm'>{@link FluentObjectAssertion#is(Object) is(Object)} 073 * <li class='jm'>{@link FluentObjectAssertion#is(Predicate) is(Predicate)} 074 * <li class='jm'>{@link FluentObjectAssertion#isNot(Object) isNot(Object)} 075 * <li class='jm'>{@link FluentObjectAssertion#isAny(Object...) isAny(Object...)} 076 * <li class='jm'>{@link FluentObjectAssertion#isNotAny(Object...) isNotAny(Object...)} 077 * <li class='jm'>{@link FluentObjectAssertion#isNull() isNull()} 078 * <li class='jm'>{@link FluentObjectAssertion#isNotNull() isNotNull()} 079 * <li class='jm'>{@link FluentObjectAssertion#isString(String) isString(String)} 080 * <li class='jm'>{@link FluentObjectAssertion#isJson(String) isJson(String)} 081 * <li class='jm'>{@link FluentObjectAssertion#isSame(Object) isSame(Object)} 082 * <li class='jm'>{@link FluentObjectAssertion#isSameJsonAs(Object) isSameJsonAs(Object)} 083 * <li class='jm'>{@link FluentObjectAssertion#isSameSortedJsonAs(Object) isSameSortedJsonAs(Object)} 084 * <li class='jm'>{@link FluentObjectAssertion#isSameSerializedAs(Object, WriterSerializer) isSameSerializedAs(Object, WriterSerializer)} 085 * <li class='jm'>{@link FluentObjectAssertion#isType(Class) isType(Class)} 086 * <li class='jm'>{@link FluentObjectAssertion#isExactType(Class) isExactType(Class)} 087 * </ul> 088 * </ul> 089 * 090 * <h5 class='section'>Transform Methods:</h5> 091 * <p> 092 * <ul class='javatree'> 093 * <li class='jc'>{@link FluentStringAssertion} 094 * <ul class='javatreec'> 095 * <li class='jm'>{@link FluentStringAssertion#asReplaceAll(String,String) asReplaceAll(String,String)} 096 * <li class='jm'>{@link FluentStringAssertion#asReplace(String,String) asReplace(String,String)} 097 * <li class='jm'>{@link FluentStringAssertion#asUrlDecode() asUrlDecode()} 098 * <li class='jm'>{@link FluentStringAssertion#asLc() asLc()} 099 * <li class='jm'>{@link FluentStringAssertion#asUc() asUc()} 100 * <li class='jm'>{@link FluentStringAssertion#asLines() asLines()} 101 * <li class='jm'>{@link FluentStringAssertion#asSplit(String) asSplit(String)} 102 * <li class='jm'>{@link FluentStringAssertion#asLength() asLength()} 103 * <li class='jm'>{@link FluentStringAssertion#asOneLine() asOneLine()} 104 * </ul> 105 * <li class='jc'>{@link FluentObjectAssertion} 106 * <ul class='javatreec'> 107 * <li class='jm'>{@link FluentObjectAssertion#asString() asString()} 108 * <li class='jm'>{@link FluentObjectAssertion#asString(WriterSerializer) asString(WriterSerializer)} 109 * <li class='jm'>{@link FluentObjectAssertion#asString(Function) asString(Function)} 110 * <li class='jm'>{@link FluentObjectAssertion#asJson() asJson()} 111 * <li class='jm'>{@link FluentObjectAssertion#asJsonSorted() asJsonSorted()} 112 * <li class='jm'>{@link FluentObjectAssertion#asTransformed(Function) asApplied(Function)} 113 * <li class='jm'>{@link FluentObjectAssertion#asAny() asAny()} 114 * </ul> 115 * </ul> 116 * 117 * <h5 class='section'>Configuration Methods:</h5> 118 * <p> 119 * <ul class='javatree'> 120 * <li class='jc'>{@link Assertion} 121 * <ul class='javatreec'> 122 * <li class='jm'>{@link Assertion#setMsg(String, Object...) setMsg(String, Object...)} 123 * <li class='jm'>{@link Assertion#setOut(PrintStream) setOut(PrintStream)} 124 * <li class='jm'>{@link Assertion#setSilent() setSilent()} 125 * <li class='jm'>{@link Assertion#setStdOut() setStdOut()} 126 * <li class='jm'>{@link Assertion#setThrowable(Class) setThrowable(Class)} 127 * </ul> 128 * </ul> 129 * 130 * <h5 class='section'>See Also:</h5><ul> 131 * <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/JuneauEcosystemOverview">Juneau Ecosystem Overview</a> 132 * </ul> 133 * 134 * @param <R> The return type. 135 */ 136public class FluentStringAssertion<R> extends FluentObjectAssertion<String,R> { 137 138 // @formatter:off 139 private static final Messages MESSAGES = Messages.of(FluentStringAssertion.class, "Messages"); 140 private static final String 141 MSG_stringDifferedAtPosition = MESSAGES.getString("stringDifferedAtPosition"), 142 MSG_expectedStringHadDifferentNumbersOfLines = MESSAGES.getString("expectedStringHadDifferentNumbersOfLines"), 143 MSG_expectedStringHadDifferentValuesAtLine = MESSAGES.getString("expectedStringHadDifferentValuesAtLine"), 144 MSG_stringEqualedUnexpected = MESSAGES.getString("stringEqualedUnexpected"), 145 MSG_stringDidNotContainExpectedSubstring = MESSAGES.getString("stringDidNotContainExpectedSubstring"), 146 MSG_stringContainedUnexpectedSubstring = MESSAGES.getString("stringContainedUnexpectedSubstring"), 147 MSG_stringWasNotEmpty = MESSAGES.getString("stringWasNotEmpty"), 148 MSG_stringWasNull = MESSAGES.getString("stringWasNull"), 149 MSG_stringWasEmpty = MESSAGES.getString("stringWasEmpty"), 150 MSG_stringDidNotMatchExpectedPattern = MESSAGES.getString("stringDidNotMatchExpectedPattern"), 151 MSG_stringDidNotStartWithExpected = MESSAGES.getString("stringDidNotStartWithExpected"), 152 MSG_stringDidNotEndWithExpected = MESSAGES.getString("stringDidNotEndWithExpected"); 153 // @formatter:on 154 155 private boolean javaStrings; 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 FluentStringAssertion(Assertion creator, String value, R returns) { 175 super(creator, value, returns); 176 } 177 178 /** 179 * Constructor. 180 * 181 * @param value 182 * The object being tested. 183 * <br>Can be <jk>null</jk>. 184 * @param returns 185 * The object to return after a test method is called. 186 * <br>If <jk>null</jk>, the test method returns this object allowing multiple test method calls to be 187 * used on the same assertion. 188 */ 189 public FluentStringAssertion(String value, R returns) { 190 this(null, value, returns); 191 } 192 193 /** 194 * When enabled, text in the message is converted to valid Java strings. 195 * 196 * <p class='bjava'> 197 * <jv>value</jv>.replaceAll(<js>"\\\\"</js>, <js>"\\\\\\\\"</js>).replaceAll(<js>"\n"</js>, <js>"\\\\n"</js>).replaceAll(<js>"\t"</js>, <js>"\\\\t"</js>); 198 * </p> 199 * 200 * @return This object. 201 */ 202 public FluentStringAssertion<R> asJavaStrings() { 203 this.javaStrings = true; 204 return this; 205 } 206 207 /** 208 * Converts the text to lowercase. 209 * 210 * @return This object. 211 */ 212 public FluentStringAssertion<R> asLc() { 213 return asTransformed(x -> x == null ? null : x.toLowerCase()); 214 } 215 216 /** 217 * Returns the length of this string as an integer assertion. 218 * 219 * @return This object. 220 */ 221 public FluentIntegerAssertion<R> asLength() { 222 return new FluentIntegerAssertion<>(this, valueIsNull() ? null : value().length(), returns()); 223 } 224 225 /** 226 * Splits the string into lines. 227 * 228 * @return This object. 229 */ 230 public FluentListAssertion<String,R> asLines() { 231 return asSplit("[\r\n]+"); 232 } 233 234 /** 235 * Removes any newlines from the string. 236 * 237 * @return This object. 238 */ 239 public FluentStringAssertion<R> asOneLine() { 240 return asTransformed(x -> x == null ? null : x.replaceAll("\\s*[\r\n]+\\s*", " ")); 241 } 242 243 /** 244 * Performs the specified substring replacement on the underlying string. 245 * 246 * @param target The sequence of char values to be replaced. 247 * @param replacement The replacement sequence of char values. 248 * @return This object. 249 */ 250 public FluentStringAssertion<R> asReplace(String target, String replacement) { 251 assertArgNotNull("target", target); 252 assertArgNotNull("replacement", replacement); 253 return asTransformed(x -> x == null ? null : x.replace(target, replacement)); 254 } 255 256 /** 257 * Performs the specified regular expression replacement on the underlying string. 258 * 259 * @param regex The regular expression to which this string is to be matched. 260 * @param replacement The string to be substituted for each match. 261 * @return This object. 262 */ 263 public FluentStringAssertion<R> asReplaceAll(String regex, String replacement) { 264 assertArgNotNull("regex", regex); 265 assertArgNotNull("replacement", replacement); 266 return asTransformed(x -> x == null ? null : x.replaceAll(regex, replacement)); 267 } 268 269 /** 270 * Splits the string into lines using the specified regular expression. 271 * 272 * @param regex The delimiting regular expression 273 * @return This object. 274 */ 275 public FluentListAssertion<String,R> asSplit(String regex) { 276 assertArgNotNull("regex", regex); 277 return new FluentListAssertion<>(this, valueIsNull() ? null : l(value().trim().split(regex)), returns()); 278 } 279 280 @Override /* Overridden from FluentObjectAssertion */ 281 public FluentStringAssertion<R> asTransformed(Function<String,String> function) { // NOSONAR - Intentional. 282 return new FluentStringAssertion<>(this, function.apply(orElse(null)), returns()); 283 } 284 285 /** 286 * Removes any leading/trailing whitespace from the string. 287 * 288 * @return This object. 289 */ 290 public FluentStringAssertion<R> asTrimmed() { 291 return new FluentStringAssertion<>(this, valueIsNull() ? null : value().trim(), returns()); 292 } 293 294 /** 295 * Converts the text to uppercase. 296 * 297 * @return This object. 298 */ 299 public FluentStringAssertion<R> asUc() { 300 return asTransformed(x -> x == null ? null : x.toUpperCase()); 301 } 302 303 /** 304 * URL-decodes the text in this assertion. 305 * 306 * @return This object. 307 */ 308 public FluentStringAssertion<R> asUrlDecode() { 309 return asTransformed(StringUtils::urlDecode); 310 } 311 312 /** 313 * Asserts that the text equals the specified value. 314 * 315 * <p> 316 * Similar to {@link #is(String)} except error message states diff position. 317 * 318 * <h5 class='section'>Example:</h5> 319 * <p class='bjava'> 320 * <jc>// Validates the response body of an HTTP call is the text "OK".</jc> 321 * <jv>client</jv> 322 * .get(<jsf>URL</jsf>) 323 * .run() 324 * .assertContent().is(<js>"OK"</js>); 325 * </p> 326 * 327 * @param value 328 * The value to check against. 329 * <br>If multiple values are specified, they are concatenated with newlines. 330 * @return The fluent return object. 331 * @throws AssertionError If assertion failed. 332 */ 333 @Override 334 public R is(String value) throws AssertionError { 335 var s = orElse(null); 336 if (neq(value, s)) 337 throw error(MSG_stringDifferedAtPosition, diffPosition(value, s), fix(value), fix(s)); 338 return returns(); 339 } 340 341 /** 342 * Asserts that the text contains all of the specified substrings. 343 * 344 * @param values The values to check against. 345 * @return The fluent return object. 346 * @throws AssertionError If assertion failed. 347 */ 348 public R isContains(String...values) throws AssertionError { 349 assertArgNotNull("values", values); 350 var s = orElse(null); 351 for (var substring : values) 352 if (nn(substring) && ! contains(s, substring)) 353 throw error(MSG_stringDidNotContainExpectedSubstring, fix(substring), fix(s)); 354 return returns(); 355 } 356 357 /** 358 * Asserts that the text is empty. 359 * 360 * @return The fluent return object. 361 * @throws AssertionError If assertion failed. 362 */ 363 public R isEmpty() throws AssertionError { 364 var s = orElse(null); 365 if (nn(s) && ! s.isEmpty()) 366 throw error(MSG_stringWasNotEmpty, fix(s)); 367 return returns(); 368 } 369 370 /** 371 * Asserts that the text ends with the specified string. 372 * 373 * @param string The string to test for. 374 * @return The fluent return object. 375 * @throws AssertionError If assertion failed. 376 */ 377 public R isEndsWith(String string) { 378 assertArgNotNull("string", string); 379 var s = value(); 380 if (! s.endsWith(string)) 381 throw error(MSG_stringDidNotEndWithExpected, fix(string), fix(s)); 382 return returns(); 383 } 384 385 /** 386 * Asserts that the text equals the specified value ignoring case. 387 * 388 * @param value The value to check against. 389 * @return The fluent return object. 390 * @throws AssertionError If assertion failed. 391 */ 392 public R isIc(String value) throws AssertionError { 393 var s = orElse(null); 394 if (neqic(value, s)) 395 throw error(MSG_stringDifferedAtPosition, diffPositionIc(value, s), fix(value), fix(s)); 396 return returns(); 397 } 398 399 /** 400 * Asserts that the lines of text equals the specified value. 401 * 402 * <h5 class='section'>Example:</h5> 403 * <p class='bjava'> 404 * <jc>// Validates the response body of an HTTP call is the text "OK".</jc> 405 * <jv>client</jv> 406 * .get(<jsf>URL</jsf>) 407 * .run() 408 * .assertContent().isLines( 409 * <js>"Line 1"</js>, 410 * <js>"Line 2"</js>, 411 * <js>"Line 3"</js> 412 * ); 413 * </p> 414 * 415 * @param lines 416 * The value to check against. 417 * <br>If multiple values are specified, they are concatenated with newlines. 418 * @return The fluent return object. 419 * @throws AssertionError If assertion failed. 420 */ 421 public R isLines(String...lines) throws AssertionError { 422 assertArgNotNull("lines", lines); 423 var v = join(lines, '\n'); 424 var s = value(); 425 if (neq(v, s)) 426 throw error(MSG_stringDifferedAtPosition, diffPosition(v, s), fix(v), fix(s)); 427 return returns(); 428 } 429 430 /** 431 * Asserts that the text matches the specified pattern containing <js>"*"</js> meta characters. 432 * 433 * <p> 434 * The <js>"*"</js> meta character can be used to represent zero or more characters.. 435 * 436 * @param searchPattern The search pattern. 437 * @return The fluent return object. 438 * @throws AssertionError If assertion failed. 439 */ 440 public R isMatches(String searchPattern) throws AssertionError { 441 assertArgNotNull("searchPattern", searchPattern); 442 return isPattern(getMatchPattern(searchPattern)); 443 } 444 445 /** 446 * Asserts that the text equals the specified value. 447 * 448 * @param value The value to check against. 449 * @return The fluent return object. 450 * @throws AssertionError If assertion failed. 451 */ 452 @Override 453 public R isNot(String value) throws AssertionError { 454 var s = orElse(null); 455 if (eq(value, s)) 456 throw error(MSG_stringEqualedUnexpected, fix(s)); 457 return returns(); 458 } 459 460 /** 461 * Asserts that the text doesn't contain any of the specified substrings. 462 * 463 * @param values The values to check against. 464 * @return The fluent return object. 465 * @throws AssertionError If assertion failed. 466 */ 467 public R isNotContains(String...values) throws AssertionError { 468 assertArgNotNull("values", values); 469 var s = orElse(null); 470 for (var substring : values) 471 if (nn(substring) && contains(s, substring)) 472 throw error(MSG_stringContainedUnexpectedSubstring, fix(substring), fix(s)); 473 return returns(); 474 } 475 476 /** 477 * Asserts that the text is not null or empty. 478 * 479 * @return The fluent return object. 480 * @throws AssertionError If assertion failed. 481 */ 482 public R isNotEmpty() throws AssertionError { 483 var s = orElse(null); 484 if (s == null) 485 throw error(MSG_stringWasNull); 486 if (s.isEmpty()) 487 throw error(MSG_stringWasEmpty); 488 return returns(); 489 } 490 491 /** 492 * Asserts that the text does not equal the specified value ignoring case. 493 * 494 * @param value The value to check against. 495 * @return The fluent return object. 496 * @throws AssertionError If assertion failed. 497 */ 498 public R isNotIc(String value) throws AssertionError { 499 var s = orElse(null); 500 if (eqic(value, s)) 501 throw error(MSG_stringEqualedUnexpected, fix(s)); 502 return returns(); 503 } 504 505 /** 506 * Asserts that the text matches the specified regular expression pattern. 507 * 508 * @param pattern The pattern to test for. 509 * @return The fluent return object. 510 * @throws AssertionError If assertion failed. 511 */ 512 public R isPattern(Pattern pattern) throws AssertionError { 513 assertArgNotNull("pattern", pattern); 514 var s = value(); 515 if (! pattern.matcher(s).matches()) 516 throw error(MSG_stringDidNotMatchExpectedPattern, fix(pattern.pattern()), fix(s)); 517 return returns(); 518 } 519 520 /** 521 * Asserts that the text matches the specified regular expression. 522 * 523 * @param regex The pattern to test for. 524 * @return The fluent return object. 525 * @throws AssertionError If assertion failed. 526 */ 527 public R isPattern(String regex) throws AssertionError { 528 return isPattern(regex, 0); 529 } 530 531 /** 532 * Asserts that the text matches the specified regular expression. 533 * 534 * @param regex The pattern to test for. 535 * @param flags Pattern match flags. See {@link Pattern#compile(String, int)}. 536 * @return The fluent return object. 537 * @throws AssertionError If assertion failed. 538 */ 539 public R isPattern(String regex, int flags) throws AssertionError { 540 assertArgNotNull("regex", regex); 541 var p = Pattern.compile(regex, flags); 542 var s = value(); 543 if (! p.matcher(s).matches()) 544 throw error(MSG_stringDidNotMatchExpectedPattern, fix(regex), fix(s)); 545 return returns(); 546 } 547 548 /** 549 * Asserts that the text equals the specified value after splitting both by newlines and sorting the rows. 550 * 551 * <h5 class='section'>Example:</h5> 552 * <p class='bjava'> 553 * <jc>// Validates the response body of an HTTP call is the text "OK".</jc> 554 * <jv>client</jv> 555 * .get(<jsf>URL</jsf>) 556 * .run() 557 * .assertContent().isSortedLines( 558 * <js>"Line 1"</js>, 559 * <js>"Line 2"</js>, 560 * <js>"Line 3"</js> 561 * ); 562 * </p> 563 * 564 * @param lines 565 * The value to check against. 566 * <br>If multiple values are specified, they are concatenated with newlines. 567 * @return The fluent return object. 568 * @throws AssertionError If assertion failed. 569 */ 570 public R isSortedLines(String...lines) { 571 assertArgNotNull("lines", lines); 572 573 // Must work for windows too. 574 var e = join(lines, '\n').trim().split("[\r\n]+"); 575 var a = value().trim().split("[\r\n]+"); 576 577 if (e.length != a.length) 578 throw error(MSG_expectedStringHadDifferentNumbersOfLines, e.length, a.length); 579 580 Arrays.sort(e); 581 Arrays.sort(a); 582 583 for (var i = 0; i < e.length; i++) 584 if (! e[i].equals(a[i])) 585 throw error(MSG_expectedStringHadDifferentValuesAtLine, i + 1, e[i], a[i]); 586 587 return returns(); 588 } 589 590 /** 591 * Asserts that the text starts with the specified string. 592 * 593 * @param string The string to test for. 594 * @return The fluent return object. 595 * @throws AssertionError If assertion failed. 596 */ 597 public R isStartsWith(String string) { 598 assertArgNotNull("string", string); 599 var s = value(); 600 if (! s.startsWith(string)) 601 throw error(MSG_stringDidNotStartWithExpected, fix(string), fix(s)); 602 return returns(); 603 } 604 605 /** 606 * Asserts that the text equals the specified object after calling {@link #toString()} on the object. 607 * 608 * @param value The value to check against. 609 * @return The fluent return object. 610 */ 611 public R isString(Object value) { 612 return is(value == null ? null : toString()); 613 } 614 615 @Override /* Overridden from Assertion */ 616 public FluentStringAssertion<R> setMsg(String msg, Object...args) { 617 super.setMsg(msg, args); 618 return this; 619 } 620 621 @Override /* Overridden from Assertion */ 622 public FluentStringAssertion<R> setOut(PrintStream value) { 623 super.setOut(value); 624 return this; 625 } 626 627 @Override /* Overridden from Assertion */ 628 public FluentStringAssertion<R> setSilent() { 629 super.setSilent(); 630 return this; 631 } 632 633 @Override /* Overridden from Assertion */ 634 public FluentStringAssertion<R> setStdOut() { 635 super.setStdOut(); 636 return this; 637 } 638 639 @Override /* Overridden from Assertion */ 640 public FluentStringAssertion<R> setThrowable(Class<? extends java.lang.RuntimeException> value) { 641 super.setThrowable(value); 642 return this; 643 } 644 645 private String fix(String text) { 646 if (javaStrings) 647 text = text.replace("\\", "\\\\").replace("\n", "\\n").replace("\t", "\\t"); 648 return text; 649 } 650}