Skip to content

Commit

Permalink
Add doesNot[Start/End]WithWhitespaces to CharSequenceAssert
Browse files Browse the repository at this point in the history
Fix assertj#3433
Author: Lim Wonjae
  • Loading branch information
yyytir777 authored and joel-costigliola committed May 3, 2024
1 parent 1d8484a commit 3cf3900
Show file tree
Hide file tree
Showing 8 changed files with 381 additions and 0 deletions.
6 changes: 6 additions & 0 deletions assertj-core/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,12 @@
<version>3.14.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-text</artifactId>
<version>1.11.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.hibernate.orm</groupId>
<artifactId>hibernate-core</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
*/
package org.assertj.core.api;

import static java.lang.Character.isWhitespace;
import static java.util.Arrays.stream;
import static java.util.stream.Collectors.toCollection;
import static org.assertj.core.api.Assertions.contentOf;
Expand All @@ -28,6 +29,8 @@
import static org.assertj.core.error.ShouldNotBeBlank.shouldNotBeBlank;
import static org.assertj.core.error.ShouldNotContainAnyWhitespaces.shouldNotContainAnyWhitespaces;
import static org.assertj.core.error.ShouldNotContainOnlyWhitespaces.shouldNotContainOnlyWhitespaces;
import static org.assertj.core.error.ShouldNotEndWithWhitespaces.shouldNotEndWithWhitespaces;
import static org.assertj.core.error.ShouldNotStartWithWhitespaces.shouldNotStartWithWhitespaces;
import static org.assertj.core.internal.Strings.doCommonCheckForCharSequence;
import static org.assertj.core.internal.Strings.removeAllWhitespaces;
import static org.assertj.core.util.IterableUtil.toArray;
Expand Down Expand Up @@ -2153,6 +2156,62 @@ public SELF isVisible() {
return myself;
}

/**
* Verifies that the actual {@code CharSequence} does not start with whitespaces (as per
* {@link Character#isWhitespace(int)} definition), it also checks it is not null as a prerequisite.
* <p>
* Example:
* <pre><code class='java'> // assertions succeed:
* assertThat(&quot;abc&quot;).doesNotStartWithWhitespaces();
* assertThat(&quot;abc &quot;).doesNotStartWithWhitespaces();
* assertThat(&quot;abc\t\t&quot;).doesNotStartWithWhitespaces();
* assertThat(&quot;&quot;).doesNotStartWithWhitespaces();
*
* // assertions fail:
* assertThat(&quot; abc&quot;).doesNotStartWithWhitespaces();
* assertThat(&quot; abc &quot;).doesNotStartWithWhitespaces();
* assertThat(&quot;\r\nabc&quot;).doesNotStartWithWhitespaces();</code></pre>
*
* @return {@code this} assertion object.
* @throws AssertionError if the actual {@code CharSequence} starts with whitespace or is null.
* @see Character#isWhitespace(int)
* @since 3.26.0
*/
public SELF doesNotStartWithWhitespaces() {
isNotNull();
if (actual.length() > 0 && isWhitespace(actual.codePoints().findFirst().getAsInt()))
throwAssertionError(shouldNotStartWithWhitespaces(actual));
return myself;
}

/**
* Verifies that the actual {@code CharSequence} does not end with whitespaces (as per
* {@link Character#isWhitespace(int)} definition), it also checks it is not null as a prerequisite.
* <p>
* Example:
* <pre><code class='java'> // assertions succeed:
* assertThat(&quot;abc&quot;).doesNotEndWithWhitespaces();
* assertThat(&quot; abc&quot;).doesNotEndWithWhitespaces();
* assertThat(&quot;\t\tabc&quot;).doesNotEndWithWhitespaces();
* assertThat(&quot;&quot;).doesNotEndWithWhitespaces();
*
* // assertions fail:
* assertThat(&quot;abc &quot;).doesNotEndWithWhitespaces();
* assertThat(&quot; abc &quot;).doesNotEndWithWhitespaces();
* assertThat(&quot;abc\r\n&quot;).doesNotEndWithWhitespaces();</code></pre>
*
* @return {@code this} assertion object.
* @throws AssertionError if the actual {@code CharSequence} ends with whitespace or is null.
* @see Character#isWhitespace(int)
* @since 3.26.0
*/
public SELF doesNotEndWithWhitespaces() {
isNotNull();
if (actual.length() > 0 && Character.isWhitespace(actual.codePoints().reduce((v1, v2) -> v2).getAsInt()))
throwAssertionError(shouldNotEndWithWhitespaces(actual));
return myself;
}

private static boolean isBlank(CharSequence actual) {
return isNullOrEmpty(actual) || strictlyContainsWhitespaces(actual);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*
* Copyright 2012-2024 the original author or authors.
*/
package org.assertj.core.error;

/**
* Creates an error message indicating that an assertion that verifies that a {@link CharSequence}
* does not end with whitespace characters.
*/
public class ShouldNotEndWithWhitespaces extends BasicErrorMessageFactory {

/**
* Creates a new <code>{@link ShouldNotEndWithWhitespaces}</code>.
* @param actual the actual value in the failed assertion.
* @return the created {@code ErrorMessageFactory}.
*/
public static ErrorMessageFactory shouldNotEndWithWhitespaces(CharSequence actual) {
return new ShouldNotEndWithWhitespaces(actual);
}

private ShouldNotEndWithWhitespaces(Object actual) {
super("%n" +
"Expecting string not to end with whitespaces but found one, string was:%n" +
" %s", actual);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*
* Copyright 2012-2024 the original author or authors.
*/
package org.assertj.core.error;

/**
* Creates an error message indicating that an assertion that verifies that a {@link CharSequence}
* does not start with whitespace characters.
*/
public class ShouldNotStartWithWhitespaces extends BasicErrorMessageFactory {

/**
* Creates a new <code>{@link ShouldNotStartWithWhitespaces}</code>.
* @param actual the actual value in the failed assertion.
* @return the created {@code ErrorMessageFactory}.
*/
public static ErrorMessageFactory shouldNotStartWithWhitespaces(CharSequence actual) {
return new ShouldNotStartWithWhitespaces(actual);
}

private ShouldNotStartWithWhitespaces(Object actual) {
super("%n" +
"Expecting string not to start with whitespaces but found one, string was:%n" +
" %s", actual);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
/*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*
* Copyright 2012-2024 the original author or authors.
*/
package org.assertj.core.api.charsequence;

import static org.apache.commons.text.StringEscapeUtils.unescapeJava;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.BDDAssertions.then;
import static org.assertj.core.api.charsequence.CharSequenceAssert_doesNotStartWithWhitespaces_Test.WHITESPACES;
import static org.assertj.core.error.ShouldNotEndWithWhitespaces.shouldNotEndWithWhitespaces;
import static org.assertj.core.util.AssertionsUtil.expectAssertionError;
import static org.assertj.core.util.FailureMessages.actualIsNull;

import java.util.stream.Stream;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;

/**
* @author Lim Wonjae
*/
class CharSequenceAssert_doesNotEndWithWhitespaces_Test {

@Test
void should_fail_if_actual_is_null() {
// GIVEN
String actual = null;
// WHEN
AssertionError assertionError = expectAssertionError(() -> assertThat(actual).doesNotStartWithWhitespaces());
// THEN
then(assertionError).hasMessage(actualIsNull());
}

@ParameterizedTest
@MethodSource
protected void should_pass_if_actual_does_not_end_with_whitespaces(String actual) {
assertThat(actual).doesNotEndWithWhitespaces();
}

@ParameterizedTest
@MethodSource
protected void should_fail_if_actual_ends_with_whitespaces(String actual) {
// WHEN
AssertionError assertionError = expectAssertionError(() -> assertThat(actual).doesNotEndWithWhitespaces());
// THEN
then(assertionError).hasMessage(shouldNotEndWithWhitespaces(actual).create());
}

static Stream<String> should_fail_if_actual_ends_with_whitespaces() {
return Stream.of(WHITESPACES).map(whitespace -> unescapeJava("abc" + whitespace));
}

static Stream<String> should_pass_if_actual_does_not_end_with_whitespaces() {
return Stream.concat(Stream.of("<abc>", " ?", "\t\t\"", ""),
Stream.of(WHITESPACES).map(whitespace -> unescapeJava(whitespace + "abc")));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
/*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*
* Copyright 2012-2024 the original author or authors.
*/
package org.assertj.core.api.charsequence;

import static org.apache.commons.text.StringEscapeUtils.unescapeJava;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.BDDAssertions.then;
import static org.assertj.core.error.ShouldNotStartWithWhitespaces.shouldNotStartWithWhitespaces;
import static org.assertj.core.util.AssertionsUtil.expectAssertionError;
import static org.assertj.core.util.FailureMessages.actualIsNull;

import java.util.stream.Stream;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;

/**
* @author Lim Wonjae
*/
class CharSequenceAssert_doesNotStartWithWhitespaces_Test {

// java whitespace according to Character.html#isWhitespace(int)
static final String[] WHITESPACES = {
"\\u0020",
" ",
"\t ",
"\\u0009",
"\n",
"\\u000A",
"\f",
"\\u000C",
"\r",
"\\u000D",
"\r \t",
"\\u001C",
"\\u001C",
"\\u001D",
"\\u001E",
"\\u001F",
"\\u000B", // VERTICAL TABULATION.
"\\u1680",
"\\u2000",
"\\u2001",
"\\u2002",
"\\u2003",
"\\u2004",
"\\u2005",
"\\u2006",
"\\u2008",
"\\u2009",
"\\u200A",
"\\u205F",
"\\u2028", // LINE SEPARATOR
"\\u2029", // PARAGRAPH SEPARATOR
"\\u3000"
};

@Test
void should_fail_if_actual_is_null() {
// GIVEN
String actual = null;
// WHEN
AssertionError assertionError = expectAssertionError(() -> assertThat(actual).doesNotStartWithWhitespaces());
// THEN
then(assertionError).hasMessage(actualIsNull());
}

@ParameterizedTest
@MethodSource
protected void should_pass_if_actual_does_not_start_with_whitespaces(String actual) {
assertThat(actual).doesNotStartWithWhitespaces();
}

@ParameterizedTest
@MethodSource
protected void should_fail_if_actual_starts_with_whitespaces(String actual) {
// WHEN
AssertionError assertionError = expectAssertionError(() -> assertThat(actual).doesNotStartWithWhitespaces());
// THEN
then(assertionError).hasMessage(shouldNotStartWithWhitespaces(actual).create());
}

static Stream<String> should_fail_if_actual_starts_with_whitespaces() {
return Stream.of(WHITESPACES).map(whitespace -> unescapeJava(whitespace + "abc"));
}

static Stream<String> should_pass_if_actual_does_not_start_with_whitespaces() {
return Stream.concat(Stream.of("<abc>", "? ", ""),
Stream.of(WHITESPACES).map(whitespace -> unescapeJava("abc" + whitespace)));
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*
* Copyright 2012-2024 the original author or authors.
*/
package org.assertj.core.error;

import static org.assertj.core.api.BDDAssertions.then;
import static org.assertj.core.error.ShouldNotEndWithWhitespaces.shouldNotEndWithWhitespaces;

import org.assertj.core.description.TextDescription;
import org.junit.jupiter.api.Test;

/**
* author: Lim Wonjae
*/
class ShouldNotEndWithWhitespaces_create_Test {

@Test
void should_create_error_message() {
// GIVEN
ErrorMessageFactory factory = shouldNotEndWithWhitespaces("abc %d");
// WHEN
String message = factory.create(new TextDescription("Test"));
// THEN
then(message).isEqualTo(String.format("[Test] %n" +
"Expecting string not to end with whitespaces but found one, string was:%n" +
" \"abc %%d\""));
}

}

0 comments on commit 3cf3900

Please sign in to comment.