diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml new file mode 100644 index 00000000000..94673dce139 --- /dev/null +++ b/.github/workflows/codeql-analysis.yml @@ -0,0 +1,76 @@ +# For most projects, this workflow file will not need changing; you simply need +# to commit it to your repository. +# +# You may wish to alter this file to override the set of languages analyzed, +# or to provide custom queries or build logic. +name: "CodeQL" + +on: + push: + branches: [main] + pull_request: + # The branches below must be a subset of the branches above + branches: [main] + schedule: + - cron: '0 8 * * 0' + +jobs: + analyze: + name: Analyze + runs-on: ubuntu-latest + + strategy: + fail-fast: false + matrix: + # Override automatic language detection by changing the below list + # Supported options are ['csharp', 'cpp', 'go', 'java', 'javascript', 'python'] + language: ['java'] + # Learn more... + # https://docs.github.com/en/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#overriding-automatic-language-detection + + steps: + - name: Checkout repository + uses: actions/checkout@v2 + with: + # We must fetch at least the immediate parents so that if this is + # a pull request then we can checkout the head. + fetch-depth: 2 + + # If this run was triggered by a pull request event, then checkout + # the head of the pull request instead of the merge commit. + - run: git checkout HEAD^2 + if: ${{ github.event_name == 'pull_request' }} + + - name: Setup Java + uses: actions/setup-java@v1 + with: + java-version: 11 + + # Initializes the CodeQL tools for scanning. + - name: Initialize CodeQL + uses: github/codeql-action/init@v1 + with: + languages: ${{ matrix.language }} + # If you wish to specify custom queries, you can do so here or in a config file. + # By default, queries listed here will override any specified in a config file. + # Prefix the list here with "+" to use these queries and those in the config file. + # queries: ./path/to/local/query, your-org/your-repo/queries@main + + # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). + # If this step fails, then you should remove it and run the build manually (see below) + - name: Autobuild + uses: github/codeql-action/autobuild@v1 + + # ℹ️ Command-line programs to run using the OS shell. + # 📚 https://git.io/JvXDl + + # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines + # and modify them (or add more) to build your code if your project + # uses a compiled language + + #- run: | + # make bootstrap + # make release + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v1 diff --git a/.github/workflows/cross-version.yml b/.github/workflows/cross-version.yml index f83315bab99..da01957fd88 100644 --- a/.github/workflows/cross-version.yml +++ b/.github/workflows/cross-version.yml @@ -9,7 +9,7 @@ jobs: strategy: fail-fast: false matrix: - java: [14, 15-ea, 16-ea] + java: [14, 15, 16-ea, 17-ea] runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index f59e74e5b56..dcd10b03be1 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -29,7 +29,7 @@ jobs: sonar: name: Sonar code analysis runs-on: ubuntu-latest - if: github.repository == 'joel-costigliola/assertj-core' && github.event_name == 'push' + if: github.repository == 'assertj/assertj-core' && github.event_name == 'push' steps: - uses: actions/checkout@v2 with: diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 0f2d9fce376..12512a2e4ac 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -18,7 +18,7 @@ We appreciate your effort and to make sure that your pull request is easy to rev * Put GIVEN WHEN THEN steps in each test, favoring `BDDAssertions.then` instead of `Assertions.assertThat` for assertions in the THEN step. Steps can be combined or omitted if a separate step does not provide much benefit to test readability, just ensure that the WHEN step (either single or combined) contains the test target. * Use `AssertionUtil.expectAssertionError` for tests expecting to get an `AssertionError` - see `OptionalAssert_containsInstanceOf_Test` as an example.. * Use static import when it makes the code more readable. -* If possible, add a (fun) code example in [assertj-examples](https://github.com/joel-costigliola/assertj-examples) and use it in the javadoc. +* If possible, add a (fun) code example in [assertj-examples](https://github.com/assertj/assertj-examples) and use it in the javadoc. A good unit test to use as a reference is `OptionalAssert_containsInstanceOf_Test`. Here's a sample below: @@ -53,7 +53,7 @@ class OptionalAssert_containsInstanceOf_Test extends BaseTest { It's ok not to follow some of the rules described above if you have a good reason not to (use your best judgement) -[assertj-examples](https://github.com/joel-costigliola/assertj-examples) shows how to efficiently use AssertJ through fun unit test examples, it can be seen as AssertJs living documentation. +[assertj-examples](https://github.com/assertj/assertj-examples) shows how to efficiently use AssertJ through fun unit test examples, it can be seen as AssertJs living documentation. ## Rebase your PR on main (no merge!) diff --git a/README.md b/README.md index 4df225710f6..5987fa00850 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # AssertJ - Fluent assertions for java -[![Github CI status](https://github.com/joel-costigliola/assertj-core/workflows/CI/badge.svg)](https://github.com/joel-costigliola/assertj-core/actions?query=workflow%3ACI) -[![Github Cross-Version status](https://github.com/joel-costigliola/assertj-core/workflows/Cross-Version/badge.svg)](https://github.com/joel-costigliola/assertj-core/actions?query=workflow%3ACross-Version) +[![Github CI status](https://github.com/assertj/assertj-core/workflows/CI/badge.svg)](https://github.com/assertj/assertj-core/actions?query=workflow%3ACI) +[![Github Cross-Version status](https://github.com/assertj/assertj-core/workflows/Cross-Version/badge.svg)](https://github.com/assertj/assertj-core/actions?query=workflow%3ACross-Version) [![Maven Central](https://maven-badges.herokuapp.com/maven-central/org.assertj/assertj-core/badge.svg)](https://maven-badges.herokuapp.com/maven-central/org.assertj/assertj-core) [![Javadocs](http://www.javadoc.io/badge/org.assertj/assertj-core.svg)](http://www.javadoc.io/doc/org.assertj/assertj-core) [![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=joel-costigliola_assertj-core&metric=alert_status)](https://sonarcloud.io/dashboard?id=joel-costigliola_assertj-core) @@ -11,12 +11,11 @@ AssertJ provides a rich and intuitive set of strongly-typed assertions to use fo * [AssertJ's goals](#goals) * [Quick start](#quickstart) * [Latest News](#news) -* [Features highlight](http://joel-costigliola.github.io/assertj/assertj-core-features-highlight.html) (still in the old site but will soon be available in the [new site](https://assertj.github.io/doc/#overview)) +* AssertJ web site contains the [**AssertJ Core documentation**](https://assertj.github.io/doc/#assertj-core-assertions-guide). * [Assertions for custom types](http://joel-costigliola.github.io/assertj/assertj-core-custom-assertions.html) (still in the old site but will soon be available in the [new site](https://assertj.github.io/doc/#overview)) * [Replacing JUnit assertions with AssertJ Assertions](#junit-to-assertj-assertions) * [Contributing](#contributing) -The new AssertJ web site contains the [**AssertJ Core documentation**](https://assertj.github.io/doc/#assertj-core-assertions-guide). You can ask questions in [**stackoverflow (assertj tag)**](https://stackoverflow.com/questions/tagged/assertj?mixed=1) and make suggestions by simply creating an issue. @@ -29,13 +28,13 @@ a `Map`? Use Map-specific assertions to easily check the contents of the map. AssertJ is composed of several modules: * A core module (this one) to provide assertions for JDK types (`String`, `Iterable`, `Stream`, `Path`, `File`, `Map`...) - see [AssertJ Core documentation](https://assertj.github.io/doc/#assertj-core-assertions-guide) and [javadoc](https://www.javadoc.io/doc/org.assertj/assertj-core/latest/index.html). -* A **[Guava module](https://github.com/joel-costigliola/assertj-guava#readme)** to provide assertions for Guava types (`Multimap`, `Optional`...) - see [AssertJ Guava documentation](http://joel-costigliola.github.io/assertj/assertj-guava.html) and [javadoc](http://joel-costigliola.github.io/assertj/guava/api/index.html). -* A **[Joda Time module](https://github.com/joel-costigliola/assertj-joda-time#readme)** to provide assertions for Joda Time types (`DateTime`, `LocalDateTime`) - see [AssertJ Joda Time documentation](http://joel-costigliola.github.io/assertj/assertj-joda-time.html) and [javadoc](http://joel-costigliola.github.io/assertj/jodatime/api/index.html). -* A **[Neo4J module](https://github.com/joel-costigliola/assertj-neo4j#readme)** to provide assertions for Neo4J types (`Path`, `Node`, `Relationship`...) - see [AssertJ Neo4J documentation](http://joel-costigliola.github.io/assertj/assertj-neo4j.html) and [javadoc](http://joel-costigliola.github.io/assertj/neo4j/api/index.html). -* A **[DB module](https://github.com/joel-costigliola/assertj-db#readme)** to provide assertions for relational database types (`Table`, `Row`, `Column`...) - see [AssertJ DB documentation](http://joel-costigliola.github.io/assertj/assertj-db.html) and [javadoc](http://joel-costigliola.github.io/assertj/db/current/api/index.html). -* A **[Swing module](https://github.com/joel-costigliola/assertj-swing#readme)** provides a simple and intuitive API for functional testing of Swing user interfaces - see [AssertJ Swing documentation](http://joel-costigliola.github.io/assertj/assertj-swing.html) and [javadoc](http://joel-costigliola.github.io/assertj/swing/api/index.html). +* A **[Guava module](https://github.com/assertj/assertj-guava#readme)** to provide assertions for Guava types (`Multimap`, `Optional`...) - see [AssertJ Guava documentation](https://assertj.github.io/doc/#assertj-guava) and [javadoc](https://www.javadoc.io/doc/org.assertj/assertj-guava/latest/index.html). +* A **[Joda Time module](https://github.com/assertj/assertj-joda-time#readme)** to provide assertions for Joda Time types (`DateTime`, `LocalDateTime`) - see [AssertJ Joda Time documentation](http://joel-costigliola.github.io/assertj/assertj-joda-time.html) and [javadoc](https://www.javadoc.io/doc/org.assertj/assertj-joda-time/latest/index.html). +* A **[Neo4J module](https://github.com/assertj/assertj-neo4j#readme)** to provide assertions for Neo4J types (`Path`, `Node`, `Relationship`...) - see [AssertJ Neo4J documentation](http://joel-costigliola.github.io/assertj/assertj-neo4j.html) and [javadoc](https://www.javadoc.io/doc/org.assertj/assertj-neo4j/latest/index.html). +* A **[DB module](https://github.com/assertj/assertj-db#readme)** to provide assertions for relational database types (`Table`, `Row`, `Column`...) - see [AssertJ DB documentation](https://assertj.github.io/doc/#assertj-db) and [javadoc](https://www.javadoc.io/doc/org.assertj/assertj-db/latest/index.html). +* A **[Swing module](https://github.com/assertj/assertj-swing#readme)** provides a simple and intuitive API for functional testing of Swing user interfaces - see [AssertJ Swing documentation](http://joel-costigliola.github.io/assertj/assertj-swing.html) and [javadoc](https://www.javadoc.io/doc/org.assertj/assertj-swing/latest/index.html). -Assertion missing? Please [create an issue](https://github.com/joel-costigliola/assertj-core/issues)! +Assertion missing? Please [create an issue](https://github.com/assertj/assertj-core/issues)! AssertJ's assertions are super easy to use: just type **```assertThat```** followed by the actual value in parentheses and a dot, then any Java IDE will show you all assertions available for the type of the object. No more confusion about the @@ -65,8 +64,8 @@ Moreover, to ease your work, we provide assertions generator that can take a set ## Replacing JUnit assertions with AssertJ Assertions -To help you [**replace JUnit assertions**](http://joel-costigliola.github.io/assertj/assertj-core-converting-junit-assertions-to-assertj.html) with AssertJ ones, you can use a [**script**](http://joel-costigliola.github.io/assertj/assertj-core-converting-junit-assertions-to-assertj.html#automatic-conversion) or do regexp search and replace manually as described [**here**](http://joel-costigliola.github.io/assertj/assertj-core-converting-junit-assertions-to-assertj.html#manual-conversion). +To help you [**replace JUnit assertions**](https://assertj.github.io/doc/#assertj-migration) with AssertJ ones, you can use a [**script**](https://assertj.github.io/doc/#assertj-migration-using-scripts) or do regexp search and replace manually as described [**here**](https://assertj.github.io/doc/#assertj-migration-using-regexes). ## Want to contribute? -You are encouraged to contribute any missing, useful assertions. To do so, please read the [contributing section](https://github.com/joel-costigliola/assertj-core/blob/main/CONTRIBUTING.md). +You are encouraged to contribute any missing, useful assertions. To do so, please read the [contributing section](https://github.com/assertj/assertj-core/blob/main/CONTRIBUTING.md). diff --git a/pom.xml b/pom.xml index 45b7a31ec9e..447916d84ca 100644 --- a/pom.xml +++ b/pom.xml @@ -2,45 +2,38 @@ 4.0.0 assertj-core - 3.17.2 + 3.19.0 jar AssertJ fluent assertions Rich and fluent assertions for testing for Java org.assertj assertj-parent-pom - 2.2.7 + 2.2.10 - - - AssertJ Group - http://groups.google.com/group/assertj - http://groups.google.com/group/assertj - http://groups.google.com/group/assertj - - - scm:git:git@github.com:joel-costigliola/assertj-core.git - scm:git:git@github.com:joel-costigliola/assertj-core.git - git@github.com:joel-costigliola/assertj-core - assertj-core-3.17.2 + scm:git:git@github.com:assertj/assertj-core.git + scm:git:git@github.com:assertj/assertj-core.git + git@github.com:assertj/assertj-core + assertj-core-3.19.0 github - https://github.com/joel-costigliola/assertj-core/issues + https://github.com/assertj/assertj-core/issues -html5 --allow-script-in-comments --no-module-directories - 1.10.14 - 5.1.2 + 1.10.19 + 1.2.0 + 5.2.0 - 4.13 - 5.6.2 - 3.5.10 + 4.13.1 + 5.6.3 + 3.7.7 - 0.8.5 + 0.8.6 @@ -63,7 +56,7 @@ org.opentest4j opentest4j - 1.2.0 + ${opentest4j.version} @@ -75,10 +68,7 @@ provided true - + org.hamcrest hamcrest-core @@ -96,37 +86,6 @@ junit-jupiter test - - - org.junit.jupiter - junit-jupiter-engine - test - - - org.junit.platform - junit-platform-launcher - test - - - org.junit.platform - junit-platform-engine - test - - - org.junit.platform - junit-platform-commons - provided - org.junit.vintage @@ -170,6 +129,12 @@ mockito-junit-jupiter test + + com.fasterxml.jackson.core + jackson-databind + 2.12.1 + test + + 3.0.0 @@ -512,7 +478,7 @@ en_US - + 8 ${project.build.directory}/javadoc-stylesheet/assertj-javadoc-min.css @@ -522,7 +488,7 @@ private
- + ]]>
@@ -548,7 +514,7 @@ false false - false + true provided compile @@ -578,7 +544,7 @@ target/${project.build.finalName}-tests.jar false - false + true false provided @@ -590,13 +556,36 @@
+ + org.apache.maven.plugins + maven-invoker-plugin + 3.2.1 + + ${project.build.directory}/it + src/it/settings.xml + ${project.build.directory}/local-repo + + clean + test + + + + + integration-test + + install + run + + + + - net.alchim31.maven - yuicompressor-maven-plugin - 1.5.1 + net.alchim31.maven + yuicompressor-maven-plugin + 1.5.1 @@ -680,8 +669,7 @@ [16,) - -Dnl.jqno.equalsverifier.internal.lib.bytebuddy.experimental=true - true + -Dnet.bytebuddy.experimental=true --add-opens=java.base/java.lang=ALL-UNNAMED --add-opens=java.base/java.util=ALL-UNNAMED --add-opens=java.base/java.math=ALL-UNNAMED --add-opens=java.base/sun.nio.fs=ALL-UNNAMED diff --git a/src/it/junit4-with-opentest4j/pom.xml b/src/it/junit4-with-opentest4j/pom.xml new file mode 100644 index 00000000000..778367709b3 --- /dev/null +++ b/src/it/junit4-with-opentest4j/pom.xml @@ -0,0 +1,31 @@ + + + 4.0.0 + + + it + setup + 0 + + + junit4-with-opentest4j + + + + @project.groupId@ + @project.artifactId@ + test + + + junit + junit + test + + + org.opentest4j + opentest4j + test + + + + diff --git a/src/it/junit4-with-opentest4j/src/test/java/maven/invoker/it/assumptions/JUnit4_with_opentest4j_Test.java b/src/it/junit4-with-opentest4j/src/test/java/maven/invoker/it/assumptions/JUnit4_with_opentest4j_Test.java new file mode 100644 index 00000000000..f59c87fff4d --- /dev/null +++ b/src/it/junit4-with-opentest4j/src/test/java/maven/invoker/it/assumptions/JUnit4_with_opentest4j_Test.java @@ -0,0 +1,52 @@ +/* + * 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-2021 the original author or authors. + */ +package maven.invoker.it.assumptions; + +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; +import static org.assertj.core.api.Assertions.assertThatNoException; +import static org.assertj.core.api.Assertions.catchThrowable; +import static org.assertj.core.api.Assumptions.assumeThat; +import static org.assertj.core.api.BDDAssertions.then; + +import org.junit.AssumptionViolatedException; +import org.junit.Test; + +public class JUnit4_with_opentest4j_Test { + + @Test + public void should_throw_JUnit4_AssumptionViolatedException_when_assumption_fails() { + // WHEN + Throwable thrown = catchThrowable(() -> assumeThat(true).isFalse()); + // THEN + then(thrown).isInstanceOf(AssumptionViolatedException.class); + } + + @Test + public void should_not_have_TestNG_in_the_classpath() { + // WHEN/THEN + assertThatExceptionOfType(ClassNotFoundException.class).isThrownBy(() -> Class.forName("org.testng.SkipException")); + } + + @Test + public void should_have_JUnit_4_in_the_classpath() { + // WHEN/THEN + assertThatNoException().isThrownBy(() -> Class.forName("org.junit.AssumptionViolatedException")); + } + + @Test + public void should_have_opentest4j_in_the_classpath() { + // WHEN/THEN + assertThatNoException().isThrownBy(() -> Class.forName("org.opentest4j.TestAbortedException")); + } + +} diff --git a/src/it/settings.xml b/src/it/settings.xml new file mode 100644 index 00000000000..9675c2ec6bc --- /dev/null +++ b/src/it/settings.xml @@ -0,0 +1,35 @@ + + + + + it-repo + + true + + + + local.central + @localRepositoryUrl@ + + true + + + true + + + + + + local.central + @localRepositoryUrl@ + + true + + + true + + + + + + diff --git a/src/it/setup/invoker.properties b/src/it/setup/invoker.properties new file mode 100644 index 00000000000..e513b1137f7 --- /dev/null +++ b/src/it/setup/invoker.properties @@ -0,0 +1 @@ +invoker.goals = install diff --git a/src/it/setup/pom.xml b/src/it/setup/pom.xml new file mode 100644 index 00000000000..f07ec2d3736 --- /dev/null +++ b/src/it/setup/pom.xml @@ -0,0 +1,59 @@ + + + 4.0.0 + + it + setup + 0 + pom + + + UTF-8 + + + + + + @project.groupId@ + @project.artifactId@ + @project.version@ + + + junit + junit + @junit.version@ + + + org.opentest4j + opentest4j + @opentest4j.version@ + + + org.testng + testng + 7.3.0 + + + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + @maven-compiler-plugin.version@ + + 8 + + + + org.apache.maven.plugins + maven-surefire-plugin + @maven-surefire-plugin.version@ + + + + + + diff --git a/src/it/testng-with-junit4/pom.xml b/src/it/testng-with-junit4/pom.xml new file mode 100644 index 00000000000..3bad016f1ac --- /dev/null +++ b/src/it/testng-with-junit4/pom.xml @@ -0,0 +1,31 @@ + + + 4.0.0 + + + it + setup + 0 + + + testng-with-junit4 + + + + @project.groupId@ + @project.artifactId@ + test + + + junit + junit + test + + + org.testng + testng + test + + + + diff --git a/src/it/testng-with-junit4/src/test/java/maven/invoker/it/assumptions/TestNG_with_JUnit4_Test.java b/src/it/testng-with-junit4/src/test/java/maven/invoker/it/assumptions/TestNG_with_JUnit4_Test.java new file mode 100644 index 00000000000..e26878fd0ef --- /dev/null +++ b/src/it/testng-with-junit4/src/test/java/maven/invoker/it/assumptions/TestNG_with_JUnit4_Test.java @@ -0,0 +1,52 @@ +/* + * 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-2021 the original author or authors. + */ +package maven.invoker.it.assumptions; + +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; +import static org.assertj.core.api.Assertions.assertThatNoException; +import static org.assertj.core.api.Assertions.catchThrowable; +import static org.assertj.core.api.Assumptions.assumeThat; +import static org.assertj.core.api.BDDAssertions.then; + +import org.testng.SkipException; +import org.testng.annotations.Test; + +public class TestNG_with_JUnit4_Test { + + @Test + public void should_throw_TestNG_SkipException_when_assumption_fails() { + // WHEN + Throwable thrown = catchThrowable(() -> assumeThat(true).isFalse()); + // THEN + then(thrown).isInstanceOf(SkipException.class); + } + + @Test + public void should_have_TestNG_in_the_classpath() { + // WHEN/THEN + assertThatNoException().isThrownBy(() -> Class.forName("org.testng.SkipException")); + } + + @Test + public void should_have_JUnit_4_in_the_classpath() { + // WHEN/THEN + assertThatNoException().isThrownBy(() -> Class.forName("org.junit.AssumptionViolatedException")); + } + + @Test + public void should_not_have_opentest4j_in_the_classpath() { + // WHEN/THEN + assertThatExceptionOfType(ClassNotFoundException.class).isThrownBy(() -> Class.forName("org.opentest4j.TestAbortedException")); + } + +} diff --git a/src/main/java/org/assertj/core/annotations/Beta.java b/src/main/java/org/assertj/core/annotations/Beta.java index 893cf1590c5..757a4b583bb 100644 --- a/src/main/java/org/assertj/core/annotations/Beta.java +++ b/src/main/java/org/assertj/core/annotations/Beta.java @@ -8,7 +8,7 @@ * 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-2020 the original author or authors. + * Copyright 2012-2021 the original author or authors. */ package org.assertj.core.annotations; diff --git a/src/main/java/org/assertj/core/api/Abstract2DArrayAssert.java b/src/main/java/org/assertj/core/api/Abstract2DArrayAssert.java index 695879a14b9..95a73854300 100644 --- a/src/main/java/org/assertj/core/api/Abstract2DArrayAssert.java +++ b/src/main/java/org/assertj/core/api/Abstract2DArrayAssert.java @@ -8,7 +8,7 @@ * 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-2020 the original author or authors. + * Copyright 2012-2021 the original author or authors. */ package org.assertj.core.api; @@ -25,7 +25,7 @@ public abstract class Abstract2DArrayAssert, ACTUAL, ELEMENT> extends AbstractAssert implements Array2DAssert { - public Abstract2DArrayAssert(final ACTUAL actual, final Class selfType) { + protected Abstract2DArrayAssert(final ACTUAL actual, final Class selfType) { super(actual, selfType); } diff --git a/src/main/java/org/assertj/core/api/AbstractArrayAssert.java b/src/main/java/org/assertj/core/api/AbstractArrayAssert.java index 4c09883716c..c07d99d3a0f 100644 --- a/src/main/java/org/assertj/core/api/AbstractArrayAssert.java +++ b/src/main/java/org/assertj/core/api/AbstractArrayAssert.java @@ -8,10 +8,13 @@ * 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-2020 the original author or authors. + * Copyright 2012-2021 the original author or authors. */ package org.assertj.core.api; +import static java.util.Objects.requireNonNull; +import static org.assertj.core.error.ShouldNotBeNull.shouldNotBeNull; + /** * Base class for all array assertions. * @@ -21,10 +24,15 @@ * @author Joel Costigliola */ public abstract class AbstractArrayAssert, ACTUAL, ELEMENT> - extends AbstractEnumerableAssert - implements ArraySortedAssert, ELEMENT> { + extends AbstractEnumerableAssert + implements ArraySortedAssert, ELEMENT> { - public AbstractArrayAssert(final ACTUAL actual, final Class selfType) { + protected AbstractArrayAssert(final ACTUAL actual, final Class selfType) { super(actual, selfType); } + + static void requireNonNullParameter(Object parameter, String parameterName) { + requireNonNull(parameter, shouldNotBeNull(parameterName).create()); + } + } diff --git a/src/main/java/org/assertj/core/api/AbstractAssert.java b/src/main/java/org/assertj/core/api/AbstractAssert.java index 8026a0f6719..c133a6180f6 100644 --- a/src/main/java/org/assertj/core/api/AbstractAssert.java +++ b/src/main/java/org/assertj/core/api/AbstractAssert.java @@ -8,7 +8,7 @@ * 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-2020 the original author or authors. + * Copyright 2012-2021 the original author or authors. */ package org.assertj.core.api; @@ -65,7 +65,7 @@ */ public abstract class AbstractAssert, ACTUAL> implements Assert { - // https://github.com/joel-costigliola/assertj-core/issues/1128 + // https://github.com/assertj/assertj-core/issues/1128 public static boolean throwUnsupportedExceptionOnEquals = true; private static final String ORG_ASSERTJ = "org.assert"; @@ -79,7 +79,6 @@ public abstract class AbstractAssert, public WritableAssertionInfo info; // visibility is protected to allow us write custom assertions that need access to actual - @VisibleForTesting protected final ACTUAL actual; protected final SELF myself; @@ -97,7 +96,7 @@ public abstract class AbstractAssert, // constructor to cast with a compiler warning // let's keep compiler warning internal (when we can) and not expose them to our end users. @SuppressWarnings("unchecked") - public AbstractAssert(ACTUAL actual, Class selfType) { + protected AbstractAssert(ACTUAL actual, Class selfType) { myself = (SELF) selfType.cast(this); this.actual = actual; info = new WritableAssertionInfo(customRepresentation); @@ -116,13 +115,35 @@ public WritableAssertionInfo getWritableAssertionInfo() { } /** - * Utility method to ease writing custom assertions classes using {@link String#format(String, Object...)} specifiers + * Throw an assertion error based on information in this assertion. Equivalent to: + *
throw failure(errorMessage, arguments);
+ *

+ * This method is a thin wrapper around {@link #failure(String, Object...) failure()} - see that method for a more detailed + * description. + *

+ * Note that generally speaking, using {@link #failure(String, Object...) failure()} directly is preferable to using this + * wrapper method, as the compiler and other code analysis tools will be able to tell that the statement will never return + * normally and respond appropriately. + * + * @param errorMessage the error message to format + * @param arguments the arguments referenced by the format specifiers in the errorMessage string. + * @see #failWithActualExpectedAndMessage(Object, Object, String, Object...) + * @see #failure(String, Object...) + */ + protected void failWithMessage(String errorMessage, Object... arguments) { + throw failure(errorMessage, arguments); + } + + /** + * Generate a custom assertion error using the information in this assertion. + *

+ * This is a utility method to ease writing custom assertions classes using {@link String#format(String, Object...)} specifiers * in error message. *

* Moreover, this method honors any description set with {@link #as(String, Object...)} or overridden error message * defined by the user with {@link #overridingErrorMessage(String, Object...)}. *

- * Example : + * Example: *

 public TolkienCharacterAssert hasName(String name) {
    *   // check that actual TolkienCharacter we want to make assertions on is not null.
    *   isNotNull();
@@ -138,9 +159,11 @@ public WritableAssertionInfo getWritableAssertionInfo() {
    *
    * @param errorMessage the error message to format
    * @param arguments the arguments referenced by the format specifiers in the errorMessage string.
-   * @see #failWithActualExpectedAndMessage(Object, Object, String, Object...)
+   * @see #failureWithActualExpected(Object, Object, String, Object...)
+   * @see #failWithMessage(String, Object...)
+   * @return The generated assertion error.
    */
-  protected void failWithMessage(String errorMessage, Object... arguments) {
+  protected AssertionError failure(String errorMessage, Object... arguments) {
     AssertionError assertionError = Failures.instance().failureIfErrorMessageIsOverridden(info);
     if (assertionError == null) {
       // error message was not overridden, build it.
@@ -149,11 +172,35 @@ protected void failWithMessage(String errorMessage, Object... arguments) {
     }
     Failures.instance().removeAssertJRelatedElementsFromStackTraceIfNeeded(assertionError);
     removeCustomAssertRelatedElementsFromStackTraceIfNeeded(assertionError);
-    throw assertionError;
+    return assertionError;
+  }
+
+  /**
+   * Throw an assertion error based on information in this assertion. Equivalent to:
+   * 
throw failureWithActualExpected(actual, expected, errorMessageFormat, arguments);
+ *

+ * This method is a thin wrapper around {@link #failureWithActualExpected(Object, Object, String, Object...) failureWithActualExpected()} - + * see that method for a more detailed description. Note that generally speaking, using + * {@link #failureWithActualExpected(Object, Object, String, Object...) failureWithActualExpected()} directly is + * preferable to using this wrapper method, as the compiler and other code analysis tools will be able to tell that the + * statement will never return normally and respond appropriately. + * + * @param actual the actual object that was found during the test + * @param expected the object that was expected + * @param errorMessageFormat the error message to format + * @param arguments the arguments referenced by the format specifiers in the errorMessage string. + * @see #failWithMessage(String, Object...) + * @see #failureWithActualExpected(Object, Object, String, Object...) + */ + protected void failWithActualExpectedAndMessage(Object actual, Object expected, String errorMessageFormat, + Object... arguments) { + throw failureWithActualExpected(actual, expected, errorMessageFormat, arguments); } /** - * Utility method to ease writing custom assertions classes using {@link String#format(String, Object...)} specifiers + * Generate a custom assertion error using the information in this assertion, using the given actual and expected values. + *

+ * This is a utility method to ease writing custom assertions classes using {@link String#format(String, Object...)} specifiers * in error message with actual and expected values. *

* Moreover, this method honors any description set with {@link #as(String, Object...)} or overridden error message @@ -169,7 +216,7 @@ protected void failWithMessage(String errorMessage, Object... arguments) { * * // check condition * if (!actual.getName().equals(name)) { - * failWithActualExpectedAndMessage(actual.getName(), name, "Expected character's name to be <%s> but was <%s>", name, actual.getName()); + * throw failureWithActualExpected(actual.getName(), name, "Expected character's name to be <%s> but was <%s>", name, actual.getName()); * } * * // return the current assertion for method chaining @@ -180,17 +227,19 @@ protected void failWithMessage(String errorMessage, Object... arguments) { * @param expected the object that was expected * @param errorMessageFormat the error message to format * @param arguments the arguments referenced by the format specifiers in the errorMessage string. - * @see #failWithMessage(String, Object...) + * @return The generated assertion error. + * @see #failure(String, Object...) + * @see #failWithActualExpectedAndMessage(Object, Object, String, Object...) */ - protected void failWithActualExpectedAndMessage(Object actual, Object expected, String errorMessageFormat, - Object... arguments) { + protected AssertionError failureWithActualExpected(Object actual, Object expected, String errorMessageFormat, + Object... arguments) { String errorMessage = Optional.ofNullable(info.overridingErrorMessage()) .orElse(format(errorMessageFormat, arguments)); String description = MessageFormatter.instance().format(info.description(), info.representation(), errorMessage); - AssertionError assertionError = assertionErrorCreator.assertionError(description, actual, expected); + AssertionError assertionError = assertionErrorCreator.assertionError(description, actual, expected, info.representation()); Failures.instance().removeAssertJRelatedElementsFromStackTraceIfNeeded(assertionError); removeCustomAssertRelatedElementsFromStackTraceIfNeeded(assertionError); - throw assertionError; + return assertionError; } /** @@ -230,12 +279,10 @@ private boolean isAssertjAssertClass() { return getClass().getName().startsWith(ORG_ASSERTJ); } - private boolean isElementOfCustomAssert(StackTraceElement stackTraceElement) { + protected boolean isElementOfCustomAssert(StackTraceElement stackTraceElement) { Class currentAssertClass = getClass(); while (currentAssertClass != AbstractAssert.class) { - if (stackTraceElement.getClassName().equals(currentAssertClass.getName())) { - return true; - } + if (stackTraceElement.getClassName().equals(currentAssertClass.getName())) return true; currentAssertClass = currentAssertClass.getSuperclass(); } return false; @@ -472,6 +519,13 @@ public SELF hasToString(String expectedToString) { return myself; } + /** {@inheritDoc} */ + @Override + public SELF doesNotHaveToString(String otherToString) { + objects.assertDoesNotHaveToString(info, actual, otherToString); + return myself; + } + /** {@inheritDoc} */ @Override public SELF doesNotHaveSameClassAs(Object other) { @@ -938,6 +992,13 @@ public SELF hasSameHashCodeAs(Object other) { return myself; } + /** {@inheritDoc} */ + @Override + public SELF doesNotHaveSameHashCodeAs(Object other) { + objects.assertDoesNotHaveSameHashCodeAs(info, actual, other); + return myself; + } + /** * Create a {@link AbstractListAssert}. *

diff --git a/src/main/java/org/assertj/core/api/AbstractAtomicFieldUpdaterAssert.java b/src/main/java/org/assertj/core/api/AbstractAtomicFieldUpdaterAssert.java index e56b396ccb5..47f7580f6da 100644 --- a/src/main/java/org/assertj/core/api/AbstractAtomicFieldUpdaterAssert.java +++ b/src/main/java/org/assertj/core/api/AbstractAtomicFieldUpdaterAssert.java @@ -8,7 +8,7 @@ * 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-2020 the original author or authors. + * Copyright 2012-2021 the original author or authors. */ package org.assertj.core.api; @@ -30,7 +30,7 @@ public abstract class AbstractAtomicFieldUpdaterAssert selfType, boolean expectedNullAllowed) { + protected AbstractAtomicFieldUpdaterAssert(ATOMIC actual, Class selfType, boolean expectedNullAllowed) { super(actual, selfType); this.expectedNullAllowed = expectedNullAllowed; } diff --git a/src/main/java/org/assertj/core/api/AbstractAtomicReferenceAssert.java b/src/main/java/org/assertj/core/api/AbstractAtomicReferenceAssert.java index 99bcc30f991..11bf199d5b4 100644 --- a/src/main/java/org/assertj/core/api/AbstractAtomicReferenceAssert.java +++ b/src/main/java/org/assertj/core/api/AbstractAtomicReferenceAssert.java @@ -8,7 +8,7 @@ * 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-2020 the original author or authors. + * Copyright 2012-2021 the original author or authors. */ package org.assertj.core.api; @@ -26,7 +26,7 @@ public abstract class AbstractAtomicReferenceAssert, VALUE, ATOMIC> extends AbstractObjectAssert { - public AbstractAtomicReferenceAssert(ATOMIC actual, Class selfType) { + protected AbstractAtomicReferenceAssert(ATOMIC actual, Class selfType) { super(actual, selfType); } diff --git a/src/main/java/org/assertj/core/api/AbstractBigDecimalAssert.java b/src/main/java/org/assertj/core/api/AbstractBigDecimalAssert.java index 9ce5fb83814..a87d72853db 100644 --- a/src/main/java/org/assertj/core/api/AbstractBigDecimalAssert.java +++ b/src/main/java/org/assertj/core/api/AbstractBigDecimalAssert.java @@ -8,7 +8,7 @@ * 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-2020 the original author or authors. + * Copyright 2012-2021 the original author or authors. */ package org.assertj.core.api; @@ -24,11 +24,11 @@ /** * Base class for all implementations of assertions for {@link BigDecimal}s. - * + * * @param the "self" type of this assertion class. Please read "Emulating 'self types' using Java Generics to simplify fluent API implementation" * for more details. - * + * * @author Drummond Dawson * @author David DIDIER * @author Ted M. Young @@ -43,7 +43,7 @@ public abstract class AbstractBigDecimalAssert selfType) { + protected AbstractBigDecimalAssert(BigDecimal actual, Class selfType) { super(actual, selfType); } @@ -53,10 +53,10 @@ public AbstractBigDecimalAssert(BigDecimal actual, Class selfType) { * Example: *

 // assertion will pass
    * assertThat(BigDecimal.ZERO).isZero();
-   * 
+   *
    * // assertion will fail
    * assertThat(new BigDecimal("8.00")).isZero();
- * + * */ @Override public SELF isZero() { @@ -70,10 +70,10 @@ public SELF isZero() { * Example: *
 // assertion will pass
    * assertThat(new BigDecimal("8.00")).isNotZero();
-   * 
+   *
    * // assertion will fail
    * assertThat(BigDecimal.ZERO).isNotZero();
- * + * */ @Override public SELF isNotZero() { @@ -104,10 +104,10 @@ public SELF isOne() { * Example: *
 // assertion will pass
    * assertThat(new BigDecimal("8.0")).isPositive();
-   * 
+   *
    * // assertion will fail
    * assertThat(new BigDecimal("-8.0")).isPositive();
- * + * */ @Override public SELF isPositive() { @@ -121,10 +121,10 @@ public SELF isPositive() { * Example: *
 // assertion will pass
    * assertThat(new BigDecimal("-8.0")).isNegative();
-   * 
+   *
    * // assertion will fail
    * assertThat(new BigDecimal("8.0")).isNegative();
- * + * */ @Override public SELF isNegative() { @@ -138,10 +138,10 @@ public SELF isNegative() { * Example: *
 // assertion will pass
    * assertThat(new BigDecimal("-8.0")).isNotPositive();
-   * 
+   *
    * // assertion will fail
    * assertThat(new BigDecimal("8.0")).isNotPositive();
- * + * */ @Override public SELF isNotPositive() { @@ -155,10 +155,10 @@ public SELF isNotPositive() { * Example: *
 // assertion will pass
    * assertThat(new BigDecimal("8.0")).isNotNegative();
-   * 
+   *
    * // assertion will fail
    * assertThat(new BigDecimal("-8.0")).isNotNegative();
- * + * */ @Override public SELF isNotNegative() { @@ -177,10 +177,10 @@ public SELF isNotNegative() { * assertThat(new BigDecimal("8.0")).isBetween(new BigDecimal("7.0"), new BigDecimal("8.0")); * // comparison is performed without scale consideration: * assertThat(new BigDecimal("8.0")).isBetween(new BigDecimal("8.0"), new BigDecimal("8.00")); - * + * * // assertion will fail * assertThat(new BigDecimal("8.0")).isBetween(new BigDecimal("6.0"), new BigDecimal("7.0"));
- * + * * Note that comparison of {@link BigDecimal} is done by value without scale consideration, i.e 2.0 and 2.00 are * considered equal in value unlike {@link BigDecimal#equals(Object)}. */ @@ -197,11 +197,11 @@ public SELF isBetween(BigDecimal start, BigDecimal end) { * Example: *
 // assertion will pass
    * assertThat(new BigDecimal("8.0")).isStrictlyBetween(new BigDecimal("7.0"), new BigDecimal("9.0"));
-   * 
+   *
    * // assertions will fail
    * assertThat(new BigDecimal("8.0")).isStrictlyBetween(new BigDecimal("8.0"), new BigDecimal("9.0"));
    * assertThat(new BigDecimal("8.0")).isStrictlyBetween(new BigDecimal("7.0"), new BigDecimal("8.0"));
- * + * */ @Override public SELF isStrictlyBetween(BigDecimal start, BigDecimal end) { @@ -216,10 +216,10 @@ public SELF isStrictlyBetween(BigDecimal start, BigDecimal end) { * Example: *
 // assertion will pass
    * assertThat(new BigDecimal("8.0")).isEqualTo("8.0");
-   * 
+   *
    * // assertion will fail because 8.00 is not equals to 8.0
    * assertThat(new BigDecimal("8.00")).isEqualTo("8.0");
- * + * * @param expected the given number to compare the actual value to. * @return {@code this} assertion object. */ @@ -236,7 +236,7 @@ public SELF isEqualTo(String expected) { * assertThat(new BigDecimal("8.0")).isEqualByComparingTo("8.0"); * // assertion will pass because 8.0 is equals to 8.00 using {@link BigDecimal#compareTo(Object)} * assertThat(new BigDecimal("8.0")).isEqualByComparingTo("8.00"); - * + * * // assertion will fail * assertThat(new BigDecimal("8.0")).isEqualByComparingTo("2.0"); * @param expected the expected {@link BigDecimal} passed as a String @@ -286,28 +286,28 @@ public SELF usingDefaultComparator() { /** * Verifies that the actual number is close to the given one within the given offset value. *

- * When abs(actual - expected) == offset value, the assertion: + * When abs(actual - expected) == offset value, the assertion: *

*

- * Breaking change since 2.9.0/3.9.0: using {@link Assertions#byLessThan(BigDecimal)} implies a strict comparison, - * use {@link Assertions#within(BigDecimal)} to get the old behavior. + * Breaking change since 2.9.0/3.9.0: using {@link Assertions#byLessThan(BigDecimal)} implies a strict comparison, + * use {@link Assertions#within(BigDecimal)} to get the old behavior. *

* Examples: *

 final BigDecimal eightDotOne = new BigDecimal("8.1");
    * final BigDecimal eight =  new BigDecimal("8.0");
-   * 
+   *
    * // assertions succeed
    * assertThat(eightDotOne).isCloseTo(eight, within(new BigDecimal("0.2")));
    * assertThat(eightDotOne).isCloseTo(eight, byLessThan(new BigDecimal("0.2"))); // strict
    *
-   * // assertions succeed when the difference == offset value ...  
+   * // assertions succeed when the difference == offset value ...
    * assertThat(eightDotOne).isCloseTo(eight, within(new BigDecimal("0.1")));
    * // ... except when using byLessThan which implies a strict comparison
    * assertThat(eightDotOne).isCloseTo(eight, byLessThan(new BigDecimal("0.1"))); // strict => fail
-   * 
+   *
    * // this assertion also fails
    * assertThat(eightDotOne).isCloseTo(eight, within(new BigDecimal("0.001")));
* @@ -327,24 +327,24 @@ public SELF isCloseTo(final BigDecimal expected, final Offset offset /** * Verifies that the actual number is not close to the given one by less than the given offset.
*

- * When abs(actual - expected) == offset value, the assertion: + * When abs(actual - expected) == offset value, the assertion: *

*

- * Breaking change since 2.9.0/3.9.0: using {@link Assertions#byLessThan(BigDecimal)} implies a strict comparison, - * use {@link Assertions#within(BigDecimal)} to get the old behavior. + * Breaking change since 2.9.0/3.9.0: using {@link Assertions#byLessThan(BigDecimal)} implies a strict comparison, + * use {@link Assertions#within(BigDecimal)} to get the old behavior. *

* Example: *

 final BigDecimal eightDotOne = new BigDecimal("8.1");
    * final BigDecimal eight =  new BigDecimal("8.0");
-   * 
+   *
    * // assertions succeed
    * assertThat(eightDotOne).isNotCloseTo(eight, byLessThan(new BigDecimal("0.01")));
    * assertThat(eightDotOne).isNotCloseTo(eight, within(new BigDecimal("0.01")));
    * // diff == offset but isNotCloseTo succeeds as we use byLessThan
-   * assertThat(eightDotOne).isNotCloseTo(eight, byLessThan(new BigDecimal("0.1")));   
+   * assertThat(eightDotOne).isNotCloseTo(eight, byLessThan(new BigDecimal("0.1")));
    *
    * // assertions fail
    * assertThat(eightDotOne).isNotCloseTo(eight, within(new BigDecimal("0.1")));
@@ -399,11 +399,11 @@ public SELF isCloseTo(BigDecimal expected, Percentage percentage) {
    * 

* Example with BigDecimal: *

 BigDecimal eleven = BigDecimal.valueOf(11.0);
-   *  
+   *
    * // assertion will pass:
    * assertThat(eleven).isNotCloseTo(BigDecimal.TEN, withinPercentage(new BigDecimal("5")));
    *
-   * // assertion will fail as the difference is exactly equals to the computed offset (1.0) 
+   * // assertion will fail as the difference is exactly equals to the computed offset (1.0)
    * assertThat(eleven).isNotCloseTo(BigDecimal.TEN, withinPercentage(new BigDecimal("10")));
    *
    * // assertion will fail
@@ -431,13 +431,13 @@ public SELF isNotCloseTo(BigDecimal expected, Percentage percentage) {
    * assertThat(BigDecimal.ONE).isLessThanOrEqualTo(BigDecimal.ONE);
    * // comparison is performed without scale consideration:
    * assertThat(BigDecimal.ONE).isLessThanOrEqualTo(new BigDecimal("1.00"));
-   * 
+   *
    * // assertions will fail
    * assertThat(BigDecimal.ONE).isLessThanOrEqualTo(BigDecimal.ZERO);
- * + * * Note that comparison of {@link BigDecimal} is done by value without scale consideration, i.e 2.0 and 2.00 are * considered equal in value unlike {@link BigDecimal#equals(Object)}. - * + * * @param other the given value to compare the actual value to. * @return {@code this} assertion object. * @throws AssertionError if the actual value is {@code null}. @@ -457,13 +457,13 @@ public SELF isLessThanOrEqualTo(BigDecimal other) { * assertThat(BigDecimal.ONE).isGreaterThanOrEqualTo(BigDecimal.ONE); * // comparison is performed without scale consideration: * assertThat(BigDecimal.ONE).isGreaterThanOrEqualTo(new BigDecimal("1.00")); - * + * * // assertions will fail * assertThat(BigDecimal.ZERO).isGreaterThanOrEqualTo(BigDecimal.ONE);
- * + * * Note that comparison of {@link BigDecimal} is done by value without scale consideration, i.e 2.0 and 2.00 are * considered equal in value unlike {@link BigDecimal#equals(Object)}. - * + * * @param other the given value to compare the actual value to. * @return {@code this} assertion object. * @throws AssertionError if the actual value is {@code null}. diff --git a/src/main/java/org/assertj/core/api/AbstractBigIntegerAssert.java b/src/main/java/org/assertj/core/api/AbstractBigIntegerAssert.java index bc0ab85226d..4e82bbfdcf1 100644 --- a/src/main/java/org/assertj/core/api/AbstractBigIntegerAssert.java +++ b/src/main/java/org/assertj/core/api/AbstractBigIntegerAssert.java @@ -8,7 +8,7 @@ * 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-2020 the original author or authors. + * Copyright 2012-2021 the original author or authors. */ package org.assertj.core.api; @@ -33,7 +33,7 @@ public class AbstractBigIntegerAssert selfType) { + protected AbstractBigIntegerAssert(BigInteger actual, Class selfType) { super(actual, selfType); } @@ -57,7 +57,7 @@ public SELF isZero() { } /** - * Verifies that the actual value is not equal to zero. + * Verifies that the actual value is not equal to zero. *

* Example: *

 // assertion will pass
@@ -76,7 +76,7 @@ public SELF isNotZero() {
   }
 
   /**
-   * Verifies that the actual value is equal to one. 
+   * Verifies that the actual value is equal to one.
    * 

* Example: *

 // assertion will pass
@@ -95,7 +95,7 @@ public SELF isOne() {
   }
 
   /**
-   * Verifies that the actual value is positive. 
+   * Verifies that the actual value is positive.
    * 

* Example: *

 // assertion will pass
@@ -114,7 +114,7 @@ public SELF isPositive() {
   }
 
   /**
-   * Verifies that the actual value is negative. 
+   * Verifies that the actual value is negative.
    * 

* Example: *

 // assertion will pass
@@ -133,7 +133,7 @@ public SELF isNegative() {
   }
 
   /**
-   * Verifies that the actual value is non negative (positive or equal zero). 
+   * Verifies that the actual value is non negative (positive or equal zero).
    * 

* Example: *

 // assertion will pass
@@ -152,7 +152,7 @@ public SELF isNotNegative() {
   }
 
   /**
-   * Verifies that the actual value is non positive (negative or equal zero). 
+   * Verifies that the actual value is non positive (negative or equal zero).
    * 

* Example: *

 // assertion will pass
@@ -173,17 +173,17 @@ public SELF isNotPositive() {
   /**
    * Verifies that the actual number is close to the given one within the given offset.
*

- * When abs(actual - expected) == offset value, the assertion: + * When abs(actual - expected) == offset value, the assertion: *

    *
  • succeeds when using {@link Assertions#within(BigInteger)}
  • *
  • fails when using {@link Assertions#byLessThan(BigInteger)} or {@link Offset#strictOffset(Number)}
  • *
- * Breaking change since 2.9.0/3.9.0: using {@link Assertions#byLessThan(BigInteger)} implies a strict comparison, - * use {@link Assertions#within(BigInteger)} to get the old behavior. + * Breaking change since 2.9.0/3.9.0: using {@link Assertions#byLessThan(BigInteger)} implies a strict comparison, + * use {@link Assertions#within(BigInteger)} to get the old behavior. *

* Example: *

 import static org.assertj.core.api.Assertions.within;
-   *  
+   *
    * final BigInteger eight = new BigInteger("8");
    * final BigInteger ten =  BigInteger.TEN;
    *
@@ -218,18 +218,18 @@ public SELF isCloseTo(BigInteger expected, Offset offset) {
   /**
    * Verifies that the actual number is not close to the given one by less than the given offset.
*

- * When abs(actual - expected) == offset value, the assertion: + * When abs(actual - expected) == offset value, the assertion: *

    *
  • succeeds when using {@link Assertions#byLessThan(BigInteger)} or {@link Offset#strictOffset(Number)}
  • *
  • fails when using {@link Assertions#within(BigInteger)}
  • *
*

- * Breaking change since 2.9.0/3.9.0: using {@link Assertions#byLessThan(BigInteger)} implies a strict comparison, - * use {@link Assertions#within(BigInteger)} to get the old behavior. + * Breaking change since 2.9.0/3.9.0: using {@link Assertions#byLessThan(BigInteger)} implies a strict comparison, + * use {@link Assertions#within(BigInteger)} to get the old behavior. *

* Examples: *

 import static org.assertj.core.api.Assertions.byLessThan;
-   *  
+   *
    * final BigInteger eight = new BigInteger("8");
    * final BigInteger ten =  BigInteger.TEN;
    *
@@ -267,8 +267,8 @@ public SELF isNotCloseTo(BigInteger expected, Offset offset) {
    * If difference is equal to the percentage value, assertion is considered valid.
    * 

* Example with BigInteger: - *

 import static org.assertj.core.api.Assertions.withinPercentage; 
-   * 
+   * 
 import static org.assertj.core.api.Assertions.withinPercentage;
+   *
    * // assertions will pass:
    * assertThat(new BigInteger("11")).isCloseTo(BigInteger.TEN, withinPercentage(20));
    *
@@ -298,8 +298,8 @@ public SELF isCloseTo(BigInteger expected, Percentage percentage) {
    * If difference is equal to the percentage value, the assertion fails.
    * 

* Example with BigInteger: - *

 import static org.assertj.core.api.Assertions.withinPercentage; 
-   * 
+   * 
 import static org.assertj.core.api.Assertions.withinPercentage;
+   *
    * BigInteger eleven = new BigInteger("11");
    *
    * // assertion will pass:
diff --git a/src/main/java/org/assertj/core/api/AbstractBooleanArrayAssert.java b/src/main/java/org/assertj/core/api/AbstractBooleanArrayAssert.java
index 3d19a034381..f532ae33828 100644
--- a/src/main/java/org/assertj/core/api/AbstractBooleanArrayAssert.java
+++ b/src/main/java/org/assertj/core/api/AbstractBooleanArrayAssert.java
@@ -8,10 +8,12 @@
  * 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-2020 the original author or authors.
+ * Copyright 2012-2021 the original author or authors.
  */
 package org.assertj.core.api;
 
+import static java.util.stream.IntStream.range;
+
 import java.util.Comparator;
 
 import org.assertj.core.data.Index;
@@ -19,12 +21,12 @@
 import org.assertj.core.util.VisibleForTesting;
 
 public abstract class AbstractBooleanArrayAssert>
-  extends AbstractArrayAssert {
+    extends AbstractArrayAssert {
 
   @VisibleForTesting
   protected BooleanArrays arrays = BooleanArrays.instance();
 
-  public AbstractBooleanArrayAssert(boolean[] actual, Class selfType) {
+  protected AbstractBooleanArrayAssert(boolean[] actual, Class selfType) {
     super(actual, selfType);
   }
 
@@ -212,6 +214,32 @@ public SELF contains(boolean... values) {
     return myself;
   }
 
+  /**
+   * Verifies that the actual array contains the values of the given array, in any order.
+   * 

+ * Example: + *

 // assertion will pass
+   * assertThat(new boolean[] { true, false }).contains(new Boolean[] { true, false });
+   * assertThat(new boolean[] { false, true }).contains(new Boolean[] { true, false });
+   * assertThat(new boolean[] { true, false }).contains(new Boolean[] { true });
+   *
+   * // assertion will fail
+   * assertThat(new boolean[] { true, true }).contains(new Boolean[] { false });
+ * + * @param values the given values. + * @return {@code this} assertion object. + * @throws NullPointerException if the given argument is {@code null}. + * @throws IllegalArgumentException if the given argument is an empty array. + * @throws AssertionError if the actual array is {@code null}. + * @throws AssertionError if the actual array does not contain the given values. + * @since 3.19.0 + */ + public SELF contains(Boolean[] values) { + requireNonNullParameter(values, "values"); + arrays.assertContains(info, actual, toPrimitiveBooleanArray(values)); + return myself; + } + /** * Verifies that the actual array contains only the given values and nothing else, in any order. *

@@ -238,6 +266,33 @@ public SELF containsOnly(boolean... values) { return myself; } + /** + * Verifies that the actual array contains only the values of the given array and nothing else, in any order. + *

+ * Example: + *

 // assertions will pass
+   * assertThat(new boolean[] { true, false }).containsOnly(new Boolean[] { true, false });
+   * assertThat(new boolean[] { false, true }).containsOnly(new Boolean[] { true, false });
+   * assertThat(new boolean[] { true, true, false }).containsOnly(new Boolean[] { true, false });
+   *
+   * // assertions will fail
+   * assertThat(new boolean[] { true, false }).containsOnly(new Boolean[] { false });
+   * assertThat(new boolean[] { true }).containsOnly(new Boolean[] { true, false });
+ * + * @param values the given values. + * @return {@code this} assertion object. + * @throws NullPointerException if the given argument is {@code null}. + * @throws IllegalArgumentException if the given argument is an empty array. + * @throws AssertionError if the actual array is {@code null}. + * @throws AssertionError if the actual array does not contain the given values, i.e. the actual array contains some + * or none of the given values, or the actual array contains more values than the given ones. + */ + public SELF containsOnly(Boolean[] values) { + requireNonNullParameter(values, "values"); + arrays.assertContainsOnly(info, actual, toPrimitiveBooleanArray(values)); + return myself; + } + /** * Verifies that the actual array contains the given values only once. *

@@ -263,6 +318,32 @@ public SELF containsOnlyOnce(boolean... values) { return myself; } + /** + * Verifies that the actual array contains the values of the given array only once. + *

+ * Examples : + *

 // assertion will pass
+   * assertThat(new boolean[] { true, false }).containsOnlyOnce(new Boolean[] { true, false });
+   *
+   * // assertions will fail
+   * assertThat(new boolean[] { true, false, true }).containsOnlyOnce(new Boolean[] { true });
+   * assertThat(new boolean[] { true }).containsOnlyOnce(new Boolean[] { false });
+   * assertThat(new boolean[] { true }).containsOnlyOnce(new Boolean[] { true, false });
+ * + * @param values the given values. + * @return {@code this} assertion object. + * @throws NullPointerException if the given argument is {@code null}. + * @throws IllegalArgumentException if the given argument is an empty array. + * @throws AssertionError if the actual array is {@code null}. + * @throws AssertionError if the actual group does not contain the given values, i.e. the actual group contains some + * or none of the given values, or the actual group contains more than once these values. + */ + public SELF containsOnlyOnce(Boolean[] values) { + requireNonNullParameter(values, "values"); + arrays.assertContainsOnlyOnce(info, actual, toPrimitiveBooleanArray(values)); + return myself; + } + /** * Verifies that the actual array contains the given sequence, without any other values between them. *

@@ -285,6 +366,29 @@ public SELF containsSequence(boolean... sequence) { return myself; } + /** + * Verifies that the actual array contains the given sequence, without any other values between them. + *

+ * Example: + *

 // assertion will pass
+   * assertThat(new boolean[] { true, false }).containsSequence(new Boolean[] { true, false });
+   * assertThat(new boolean[] { true, false, false, true }).containsSequence(new Boolean[] { false, true });
+   *
+   * // assertion will fail
+   * assertThat(new boolean[] { true, true, false }).containsSequence(new Boolean[] { false, true });
+ * + * @param sequence the sequence of values to look for. + * @return myself assertion object. + * @throws AssertionError if the actual array is {@code null}. + * @throws AssertionError if the given array is {@code null}. + * @throws AssertionError if the actual array does not contain the given sequence. + */ + public SELF containsSequence(Boolean[] sequence) { + requireNonNullParameter(sequence, "sequence"); + arrays.assertContainsSequence(info, actual, toPrimitiveBooleanArray(sequence)); + return myself; + } + /** * Verifies that the actual array contains the given subsequence (possibly with other values between them). *

@@ -307,6 +411,29 @@ public SELF containsSubsequence(boolean... subsequence) { return myself; } + /** + * Verifies that the actual array contains the given subsequence (possibly with other values between them). + *

+ * Example: + *

 // assertion will pass
+   * assertThat(new boolean[] { true, false }).containsSubsequence(new Boolean[] { true, false });
+   * assertThat(new boolean[] { true, false, false, true }).containsSubsequence(new Boolean[] { true, true });
+   *
+   * // assertion will fail
+   * assertThat(new boolean[] { true, true, false }).containsSubsequence(new Boolean[] { false, true });
+ * + * @param subsequence the subsequence of values to look for. + * @return myself assertion object. + * @throws AssertionError if the actual array is {@code null}. + * @throws AssertionError if the given array is {@code null}. + * @throws AssertionError if the actual array does not contain the given subsequence. + */ + public SELF containsSubsequence(Boolean[] subsequence) { + requireNonNullParameter(subsequence, "subsequence"); + arrays.assertContainsSubsequence(info, actual, toPrimitiveBooleanArray(subsequence)); + return myself; + } + /** * Verifies that the actual array contains the given value at the given index. *

@@ -355,6 +482,29 @@ public SELF doesNotContain(boolean... values) { return myself; } + /** + * Verifies that the actual array does not contain the values of the given array. + *

+ * Example: + *

 // assertion will pass
+   * assertThat(new boolean[] { true, true }).doesNotContain(new Boolean[] { false });
+   *
+   * // assertion will fail
+   * assertThat(new boolean[] { true, true, false }).doesNotContain(new Boolean[] { false });
+ * + * @param values the given values. + * @return {@code this} assertion object. + * @throws NullPointerException if the given argument is {@code null}. + * @throws IllegalArgumentException if the given argument is an empty array. + * @throws AssertionError if the actual array is {@code null}. + * @throws AssertionError if the actual array contains any of the given values. + */ + public SELF doesNotContain(Boolean[] values) { + requireNonNullParameter(values, "values"); + arrays.assertDoesNotContain(info, actual, toPrimitiveBooleanArray(values)); + return myself; + } + /** * Verifies that the actual array does not contain the given value at the given index. *

@@ -422,6 +572,31 @@ public SELF startsWith(boolean... sequence) { return myself; } + /** + * Verifies that the actual array starts with the given sequence of values, without any other values between them. + * Similar to {@link #containsSequence(boolean...)}, but it also verifies that the first element in the + * sequence is also first element of the actual array. + *

+ * Example: + *

 // assertion will pass
+   * assertThat(new boolean[] { true, false, false, true }).startsWith(new Boolean[] { true, false });
+   *
+   * // assertion will fail
+   * assertThat(new boolean[] { true, false, false, true }).startsWith(new Boolean[] { false, false, true });
+ * + * @param sequence the sequence of values to look for. + * @return myself assertion object. + * @throws NullPointerException if the given argument is {@code null}. + * @throws IllegalArgumentException if the given argument is an empty array. + * @throws AssertionError if the actual array is {@code null}. + * @throws AssertionError if the actual array does not start with the given sequence. + */ + public SELF startsWith(Boolean[] sequence) { + requireNonNullParameter(sequence, "sequence"); + arrays.assertStartsWith(info, actual, toPrimitiveBooleanArray(sequence)); + return myself; + } + /** * Verifies that the actual array ends with the given sequence of values, without any other values between them. * Similar to {@link #containsSequence(boolean...)}, but it also verifies that the last element in the @@ -446,6 +621,31 @@ public SELF endsWith(boolean... sequence) { return myself; } + /** + * Verifies that the actual array ends with the given sequence of values, without any other values between them. + * Similar to {@link #containsSequence(boolean...)}, but it also verifies that the last element in the + * sequence is also last element of the actual array. + *

+ * Example: + *

 // assertion will pass
+   * assertThat(new boolean[] { true, false, false, true }).endsWith(new Boolean[] { false, false, true });
+   *
+   * // assertion will fail
+   * assertThat(new boolean[] { true, false, false, true }).endsWith(new Boolean[] { true, false });
+ * + * @param sequence the sequence of values to look for. + * @return myself assertion object. + * @throws NullPointerException if the given argument is {@code null}. + * @throws IllegalArgumentException if the given argument is an empty array. + * @throws AssertionError if the actual array is {@code null}. + * @throws AssertionError if the actual array does not end with the given sequence. + */ + public SELF endsWith(Boolean[] sequence) { + requireNonNullParameter(sequence, "sequence"); + arrays.assertEndsWith(info, actual, toPrimitiveBooleanArray(sequence)); + return myself; + } + /** {@inheritDoc} */ @Override public SELF isSorted() { @@ -507,6 +707,31 @@ public SELF containsExactly(boolean... values) { return myself; } + /** + * Verifies that the actual group contains only the values of the given array and nothing else, in order. + *

+ * Example : + *

 // assertion will pass
+   * assertThat(new boolean[] { true, false, true }).containsExactly(new Boolean[] { true, false, true });
+   *
+   * // assertion will fail as actual and expected order differ
+   * assertThat(new boolean[] { true, false, true }).containsExactly(new Boolean[] { false, true, true });
+ * + * @param values the given values. + * @return {@code this} assertion object. + * @throws NullPointerException if the given argument is {@code null}. + * @throws AssertionError if the actual group is {@code null}. + * @throws AssertionError if the actual group does not contain the given values with same order, i.e. the actual group + * contains some or none of the given values, or the actual group contains more values than the given ones + * or values are the same but the order is not. + * @since 3.19.0 + */ + public SELF containsExactly(Boolean[] values) { + requireNonNullParameter(values, "values"); + arrays.assertContainsExactly(info, actual, toPrimitiveBooleanArray(values)); + return myself; + } + /** * Verifies that the actual group contains exactly the given values and nothing else, in any order.
*

@@ -533,6 +758,33 @@ public SELF containsExactlyInAnyOrder(boolean... values) { return myself; } + /** + * Verifies that the actual group contains exactly the values of the given array and nothing else, in any order.
+ *

+ * Example : + *

 // assertions will pass
+   * assertThat(new boolean[] { true, false }).containsExactlyInAnyOrder(new Boolean[] { false, true });
+   * assertThat(new boolean[] { true, false, true }).containsExactlyInAnyOrder(new Boolean[] { true, true, false });
+   *
+   * // assertions will fail
+   * assertThat(new boolean[] { true, false }).containsExactlyInAnyOrder(new Boolean[] { true });
+   * assertThat(new boolean[] { true }).containsExactlyInAnyOrder(new Boolean[] { false, true });
+   * assertThat(new boolean[] { true, true, false }).containsExactlyInAnyOrder(new Boolean[] { false, true });
+ * + * @param values the given values. + * @return {@code this} assertion object. + * @throws NullPointerException if the given argument is {@code null}. + * @throws AssertionError if the actual group is {@code null}. + * @throws AssertionError if the actual group does not contain the given values, i.e. the actual group + * contains some or none of the given values, or the actual group contains more values than the given ones. + * @since 3.19.0 + */ + public SELF containsExactlyInAnyOrder(Boolean[] values) { + requireNonNullParameter(values, "values"); + arrays.assertContainsExactlyInAnyOrder(info, actual, toPrimitiveBooleanArray(values)); + return myself; + } + /** * Verifies that the actual array contains at least one of the given values. *

@@ -559,4 +811,39 @@ public SELF containsAnyOf(boolean... values) { arrays.assertContainsAnyOf(info, actual, values); return myself; } + + /** + * Verifies that the actual array contains at least one of the values of the given array. + *

+ * Example : + *

 boolean[] soTrue = { true, true, true };
+   *
+   * // assertions will pass
+   * assertThat(soTrue).containsAnyOf(new Boolean[] { true })
+   *                   .containsAnyOf(new Boolean[] { false, false, false, true });
+   *
+   * // assertions will fail
+   * assertThat(oneTwoThree).containsAnyOf(new Boolean[] { false });
+   * assertThat(oneTwoThree).containsAnyOf(new Boolean[] { false, false, false });
+ * + * @param values the values whose at least one which is expected to be in the array under test. + * @return {@code this} assertion object. + * @throws NullPointerException if the array of values is {@code null}. + * @throws IllegalArgumentException if the array of values is empty and the array under test is not empty. + * @throws AssertionError if the array under test is {@code null}. + * @throws AssertionError if the array under test does not contain any of the given {@code values}. + * @since 3.19.0 + */ + public SELF containsAnyOf(Boolean[] values) { + requireNonNullParameter(values, "values"); + arrays.assertContainsAnyOf(info, actual, toPrimitiveBooleanArray(values)); + return myself; + } + + private static boolean[] toPrimitiveBooleanArray(Boolean[] values) { + boolean[] booleans = new boolean[values.length]; + range(0, values.length).forEach(i -> booleans[i] = values[i]); + return booleans; + } + } diff --git a/src/main/java/org/assertj/core/api/AbstractBooleanAssert.java b/src/main/java/org/assertj/core/api/AbstractBooleanAssert.java index 79a623e8fde..4c54a6f467b 100644 --- a/src/main/java/org/assertj/core/api/AbstractBooleanAssert.java +++ b/src/main/java/org/assertj/core/api/AbstractBooleanAssert.java @@ -8,22 +8,26 @@ * 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-2020 the original author or authors. + * Copyright 2012-2021 the original author or authors. */ package org.assertj.core.api; +import static org.assertj.core.error.ShouldBeFalse.shouldBeFalse; +import static org.assertj.core.error.ShouldBeTrue.shouldBeTrue; + import java.util.Comparator; import org.assertj.core.internal.Booleans; +import org.assertj.core.internal.Failures; import org.assertj.core.util.VisibleForTesting; /** * Base class for all implementations of assertions for {@link Boolean}s. - * + * * @param the "self" type of this assertion class. Please read "Emulating 'self types' using Java Generics to simplify fluent API implementation" * for more details. - * + * * @author Alex Ruiz * @author Yvonne Wang * @author David DIDIER @@ -35,7 +39,7 @@ public abstract class AbstractBooleanAssert selfType) { + protected AbstractBooleanAssert(Boolean actual, Class selfType) { super(actual, selfType); } @@ -50,13 +54,15 @@ public AbstractBooleanAssert(Boolean actual, Class selfType) { * // assertions will fail * assertThat(false).isTrue(); * assertThat(Boolean.FALSE).isTrue();
- * + * * @return {@code this} assertion object. * @throws AssertionError if the actual value is {@code null}. * @throws AssertionError if the actual value is not {@code true}. */ public SELF isTrue() { - return isEqualTo(true); + objects.assertNotNull(info, actual); + if (actual) return myself; + throw Failures.instance().failure(info, shouldBeTrue(actual), actual, true); } /** @@ -70,13 +76,15 @@ public SELF isTrue() { * // assertions will fail * assertThat(true).isFalse(); * assertThat(Boolean.TRUE).isFalse();
- * + * * @return {@code this} assertion object. * @throws AssertionError if the actual value is {@code null}. * @throws AssertionError if the actual value is not {@code false}. */ public SELF isFalse() { - return isEqualTo(false); + objects.assertNotNull(info, actual); + if (actual == false) return myself; + throw Failures.instance().failure(info, shouldBeFalse(actual), actual, false); } /** @@ -86,11 +94,11 @@ public SELF isFalse() { *
 // assertions will pass
    * assertThat(true).isEqualTo(true);
    * assertThat(Boolean.FALSE).isEqualTo(false);
-   * 
+   *
    * // assertions will fail
    * assertThat(true).isEqualTo(false);
    * assertThat(Boolean.TRUE).isEqualTo(false);
- * + * * @param expected the given value to compare the actual value to. * @return {@code this} assertion object. * @throws AssertionError if the actual value is {@code null}. @@ -112,7 +120,7 @@ public SELF isEqualTo(boolean expected) { * // assertions will fail * assertThat(true).isNotEqualTo(true); * assertThat(Boolean.FALSE).isNotEqualTo(false);
- * + * * @param other the given value to compare the actual value to. * @return {@code this} assertion object. * @throws AssertionError if the actual value is {@code null}. @@ -137,7 +145,7 @@ public final SELF usingComparator(Comparator customComparator) /** * Do not use this method. - * + * * @deprecated Custom Comparator is not supported for Boolean comparison. * @throws UnsupportedOperationException if this method is called. */ diff --git a/src/main/java/org/assertj/core/api/AbstractByteArrayAssert.java b/src/main/java/org/assertj/core/api/AbstractByteArrayAssert.java index 55669317873..2d6d0216658 100644 --- a/src/main/java/org/assertj/core/api/AbstractByteArrayAssert.java +++ b/src/main/java/org/assertj/core/api/AbstractByteArrayAssert.java @@ -8,10 +8,11 @@ * 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-2020 the original author or authors. + * Copyright 2012-2021 the original author or authors. */ package org.assertj.core.api; +import static java.util.stream.IntStream.range; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.util.Hexadecimals.toHexString; @@ -31,7 +32,7 @@ public abstract class AbstractByteArrayAssert selfType) { + protected AbstractByteArrayAssert(byte[] actual, Class selfType) { super(actual, selfType); } @@ -220,6 +221,33 @@ public SELF contains(byte... values) { return myself; } + /** + * Verifies that the actual array contains the values of the given array, in any order. + *

+ * Example: + *

 // assertion will pass
+   * assertThat(new byte[] { 1, 2, 3 }).contains(new Byte[] { 1,  2 });
+   * assertThat(new byte[] { 1, 2, 3 }).contains(new Byte[] { 3,  1 });
+   * assertThat(new byte[] { 1, 2, 3 }).contains(new Byte[] { 1,  3,  2 });
+   *
+   * // assertion will fail
+   * assertThat(new byte[] { 1, 2, 3 }).contains(new Byte[] { 1,  4 });
+   * assertThat(new byte[] { 1, 2, 3 }).contains(new Byte[] { 4,  7 });
+ * + * @param values the given values. + * @return {@code this} assertion object. + * @throws NullPointerException if the given argument is {@code null}. + * @throws IllegalArgumentException if the given argument is an empty array. + * @throws AssertionError if the actual array is {@code null}. + * @throws AssertionError if the actual array does not contain the given values. + * @since 3.19.0 + */ + public SELF contains(Byte[] values) { + requireNonNullParameter(values, "values"); + arrays.assertContains(info, actual, toPrimitiveByteArray(values)); + return myself; + } + /** * Verifies that the actual array contains the given values, in any order. *

@@ -274,6 +302,36 @@ public SELF containsOnly(byte... values) { return myself; } + /** + * Verifies that the actual array contains only the values of the given array and nothing else, in any order. + *

+ * Example: + *

 // assertions will pass
+   * assertThat(new byte[] { 1, 2, 3 }).containsOnly(new Byte[] { 1,  2,  3 });
+   * assertThat(new byte[] { 1, 2, 3 }).containsOnly(new Byte[] { 2,  3,  1 });
+   * assertThat(new byte[] { 1, 1, 2 }).containsOnly(new Byte[] { 1,  2 });
+   *
+   * // assertions will fail
+   * assertThat(new byte[] { 1, 2, 3 }).containsOnly(new Byte[] { 1,  2,  3,  4 });
+   * assertThat(new byte[] { 1, 2, 3 }).containsOnly(new Byte[] { 4,  7 });
+ * + * @param values the given values. + * @return {@code this} assertion object. + * @throws NullPointerException if the given argument is {@code null}. + * @throws IllegalArgumentException if the given argument is an empty array. + * @throws AssertionError if the actual array is {@code null}. + * @throws AssertionError if the actual array does not contain the given values, i.e. the actual array + * contains some + * or none of the given values, or the actual array contains more values than the + * given ones. + * @since 3.19.0 + */ + public SELF containsOnly(Byte[] values) { + requireNonNullParameter(values, "values"); + arrays.assertContainsOnly(info, actual, toPrimitiveByteArray(values)); + return myself; + } + /** * Verifies that the actual array contains only the given values and nothing else, in any order. *

@@ -330,6 +388,35 @@ public SELF containsOnlyOnce(byte... values) { return myself; } + /** + * Verifies that the actual array contains the values of the given array only once. + *

+ * Examples : + *

 // assertion will pass
+   * assertThat(new byte[] { 1, 2, 3 }).containsOnlyOnce(new Byte[] { 1, 2 });
+   *
+   * // assertions will fail
+   * assertThat(new byte[] { 1, 2, 1 }).containsOnlyOnce(new Byte[] { 1 });
+   * assertThat(new byte[] { 1, 2, 3 }).containsOnlyOnce(new Byte[] { 4 });
+   * assertThat(new byte[] { 1, 2, 3, 3 }).containsOnlyOnce(new Byte[] { 0,  1,  2,  3,  4,  5 });
+ * + * @param values the given values. + * @return {@code this} assertion object. + * @throws NullPointerException if the given argument is {@code null}. + * @throws IllegalArgumentException if the given argument is an empty array. + * @throws AssertionError if the actual array is {@code null}. + * @throws AssertionError if the actual group does not contain the given values, i.e. the actual group + * contains some + * or none of the given values, or the actual group contains more than once these + * values. + * @since 3.19.0 + */ + public SELF containsOnlyOnce(Byte[] values) { + requireNonNullParameter(values, "values"); + arrays.assertContainsOnlyOnce(info, actual, toPrimitiveByteArray(values)); + return myself; + } + /** * Verifies that the actual array contains the given values only once. *

@@ -382,6 +469,32 @@ public SELF containsSequence(byte... sequence) { return myself; } + /** + * Verifies that the actual array contains the given sequence, without any other values between them. + *

+ * Example: + *

 // assertion will pass
+   * assertThat(new byte[] { 1, 2, 3 }).containsSequence(new Byte[] { 1,  2 });
+   * assertThat(new byte[] { 1, 2, 3 }).containsSequence(new Byte[] { 1,  2,  3 });
+   * assertThat(new byte[] { 1, 2, 3 }).containsSequence(new Byte[] { 2,  3 });
+   *
+   * // assertion will fail
+   * assertThat(new byte[] { 1, 2, 3 }).containsSequence(new Byte[] { 1,  3 });
+   * assertThat(new byte[] { 1, 2, 3 }).containsSequence(new Byte[] { 4,  7 });
+ * + * @param sequence the sequence of values to look for. + * @return myself assertion object. + * @throws AssertionError if the actual array is {@code null}. + * @throws AssertionError if the given array is {@code null}. + * @throws AssertionError if the actual array does not contain the given sequence. + * @since 3.19.0 + */ + public SELF containsSequence(Byte[] sequence) { + requireNonNullParameter(sequence, "sequence"); + arrays.assertContainsSequence(info, actual, toPrimitiveByteArray(sequence)); + return myself; + } + /** * Verifies that the actual array contains the given sequence, without any other values between them. *

@@ -432,6 +545,33 @@ public SELF containsSubsequence(byte... subsequence) { return myself; } + /** + * Verifies that the actual array contains the given subsequence (possibly with other values between them). + *

+ * Example: + *

 // assertion will pass
+   * assertThat(new byte[] { 1, 2, 3 }).containsSubsequence(new Byte[] { 1,  2,  3 });
+   * assertThat(new byte[] { 1, 2, 3 }).containsSubsequence(new Byte[] { 1,  2 });
+   * assertThat(new byte[] { 1, 2, 3 }).containsSubsequence(new Byte[] { 1,  3 });
+   * assertThat(new byte[] { 1, 2, 3 }).containsSubsequence(new Byte[] { 2,  3 });
+   *
+   * // assertion will fail
+   * assertThat(new byte[] { 1, 2, 3 }).containsSubsequence(new Byte[] { 2,  1 });
+   * assertThat(new byte[] { 1, 2, 3 }).containsSubsequence(new Byte[] { 4,  7 });
+ * + * @param subsequence the subsequence of values to look for. + * @return myself assertion object. + * @throws AssertionError if the actual array is {@code null}. + * @throws AssertionError if the given array is {@code null}. + * @throws AssertionError if the actual array does not contain the given subsequence. + * @since 3.19.0 + */ + public SELF containsSubsequence(Byte[] subsequence) { + requireNonNullParameter(subsequence, "subsequence"); + arrays.assertContainsSubsequence(info, actual, toPrimitiveByteArray(subsequence)); + return myself; + } + /** * Verifies that the actual array contains the given subsequence (possibly with other values between them). *

@@ -533,6 +673,30 @@ public SELF doesNotContain(byte... values) { return myself; } + /** + * Verifies that the actual array does not contain the values of the given array. + *

+ * Example: + *

 // assertion will pass
+   * assertThat(new byte[] { 1, 2, 3 }).doesNotContain(new Byte[] { 4 });
+   *
+   * // assertion will fail
+   * assertThat(new byte[] { 1, 2, 3 }).doesNotContain(new Byte[] { 2 });
+ * + * @param values the given values. + * @return {@code this} assertion object. + * @throws NullPointerException if the given argument is {@code null}. + * @throws IllegalArgumentException if the given argument is an empty array. + * @throws AssertionError if the actual array is {@code null}. + * @throws AssertionError if the actual array contains any of the given values. + * @since 3.19.0 + */ + public SELF doesNotContain(Byte[] values) { + requireNonNullParameter(values, "values"); + arrays.assertDoesNotContain(info, actual, toPrimitiveByteArray(values)); + return myself; + } + /** * Verifies that the actual array does not contain the given values. *

@@ -648,6 +812,32 @@ public SELF startsWith(byte... sequence) { return myself; } + /** + * Verifies that the actual array starts with the given sequence of values, without any other values between them. + * Similar to {@link #containsSequence(byte...)}, but it also verifies that the first element in the + * sequence is also first element of the actual array. + *

+ * Example: + *

 // assertion will pass
+   * assertThat(new byte[] { 1, 2, 3 }).startsWith(new Byte[] { 1,  2 });
+   *
+   * // assertion will fail
+   * assertThat(new byte[] { 1, 2, 3 }).startsWith(new Byte[] { 2,  3 });
+ * + * @param sequence the sequence of values to look for. + * @return myself assertion object. + * @throws NullPointerException if the given argument is {@code null}. + * @throws IllegalArgumentException if the given argument is an empty array. + * @throws AssertionError if the actual array is {@code null}. + * @throws AssertionError if the actual array does not start with the given sequence. + * @since 3.19.0 + */ + public SELF startsWith(Byte[] sequence) { + requireNonNullParameter(sequence, "sequence"); + arrays.assertStartsWith(info, actual, toPrimitiveByteArray(sequence)); + return myself; + } + /** * Verifies that the actual array starts with the given sequence of values, without any other values between them. * Similar to {@link #containsSequence(byte...)}, but it also verifies that the first element in the @@ -697,6 +887,32 @@ public SELF endsWith(byte... sequence) { return myself; } + /** + * Verifies that the actual array ends with the given sequence of values, without any other values between them. + * Similar to {@link #containsSequence(byte...)}, but it also verifies that the last element in the + * sequence is also last element of the actual array. + *

+ * Example: + *

 // assertion will pass
+   * assertThat(new byte[] { 1, 2, 3 }).endsWith(new Byte[] { 2,  3 });
+   *
+   * // assertion will fail
+   * assertThat(new byte[] { 1, 2, 3 }).endsWith(new Byte[] { 3,  4 });
+ * + * @param sequence the sequence of values to look for. + * @return myself assertion object. + * @throws NullPointerException if the given argument is {@code null}. + * @throws IllegalArgumentException if the given argument is an empty array. + * @throws AssertionError if the actual array is {@code null}. + * @throws AssertionError if the actual array does not end with the given sequence. + * @since 3.19.0 + */ + public SELF endsWith(Byte[] sequence) { + requireNonNullParameter(sequence, "sequence"); + arrays.assertEndsWith(info, actual, toPrimitiveByteArray(sequence)); + return myself; + } + /** * Verifies that the actual array ends with the given sequence of values, without any other values between them. * Similar to {@link #containsSequence(byte...)}, but it also verifies that the last element in the @@ -785,6 +1001,42 @@ public SELF containsExactly(byte... values) { return myself; } + /** + * Verifies that the actual group contains only the values of the given array and nothing else, in order. + *

+ * Warning: for performance reason, this assertion compares arrays directly meaning that it does not honor element + * comparator set with {@link #usingElementComparator(Comparator)}. + *

+ * Example : + *

 // assertion will pass
+   * assertThat(new byte[] { 1, 2, 3 }).containsExactly(new Byte[] { 1,  2,  3 });
+   *
+   * // assertion will fail as actual and expected order differ
+   * assertThat(new byte[] { 1, 2, 3 }).containsExactly(new Byte[] { 2,  1,  3 });
+ * + * @param values the given values. + * @return {@code this} assertion object. + * @throws NullPointerException if the given argument is {@code null}. + * @throws AssertionError if the actual group is {@code null}. + * @throws AssertionError if the actual group does not contain the given values with same order, i.e. the actual + * group + * contains some or none of the given values, or the actual group contains more values + * than the given ones + * or values are the same but the order is not. + * @since 3.19.0 + */ + public SELF containsExactly(Byte[] values) { + // In #1801 we changed objects.assertEqual to arrays.assertContainsExactly to get a better error message but it came with + // significant performance degradation as #1898 showed. + // We can't get the best of both approaches even if we call assertContainsExactly only when assertEqual, assertContainsExactly + // would take a long time to compute the diff between both arrays. + // We can at least solve the representation of byte[] arrays so that they show the bytes + + requireNonNullParameter(values, "values"); + objects.assertEqual(info, actual, toPrimitiveByteArray(values)); + return myself; + } + /** * Verifies that the actual group contains only the given values and nothing else, in order. *

@@ -837,6 +1089,33 @@ public SELF containsExactlyInAnyOrder(byte... values) { return myself; } + /** + * Verifies that the actual group contains exactly the values of the given array and nothing else, in any order.
+ *

+ * Example : + *

 // assertions will pass
+   * assertThat(new byte[] { 1, 2 }).containsExactlyInAnyOrder(new Byte[] { 1,  2 });
+   * assertThat(new byte[] { 1, 2, 1 }).containsExactlyInAnyOrder(new Byte[] { 1,  1,  2 });
+   *
+   * // assertions will fail
+   * assertThat(new byte[] { 1, 2 }).containsExactlyInAnyOrder(new Byte[] { 1 });
+   * assertThat(new byte[] { 1 }).containsExactlyInAnyOrder(new Byte[] { 1,  2 });
+   * assertThat(new byte[] { 1, 2, 1 }).containsExactlyInAnyOrder(new Byte[] { 1,  2 });
+ * + * @param values the given values. + * @return {@code this} assertion object. + * @throws NullPointerException if the given argument is {@code null}. + * @throws AssertionError if the actual group is {@code null}. + * @throws AssertionError if the actual group does not contain the given values, i.e. the actual group + * contains some or none of the given values, or the actual group contains more values than the given ones. + * @since 3.19.0 + */ + public SELF containsExactlyInAnyOrder(Byte[] values) { + requireNonNullParameter(values, "values"); + arrays.assertContainsExactlyInAnyOrder(info, actual, toPrimitiveByteArray(values)); + return myself; + } + /** * Verifies that the actual group contains exactly the given values and nothing else, in any order.
*

@@ -893,6 +1172,37 @@ public SELF containsAnyOf(byte... values) { return myself; } + /** + * Verifies that the actual array contains at least one of the values of the given array. + *

+ * Example : + *

 byte[] oneTwoThree = { 1, 2, 3 };
+   *
+   * // assertions will pass
+   * assertThat(oneTwoThree).containsAnyOf(new Byte[] { 2 })
+   *                        .containsAnyOf(new Byte[] { 2, 3 })
+   *                        .containsAnyOf(new Byte[] { 1, 2, 3 })
+   *                        .containsAnyOf(new Byte[] { 1, 2, 3, 4 })
+   *                        .containsAnyOf(new Byte[] { 5, 6, 7, 2 });
+   *
+   * // assertions will fail
+   * assertThat(oneTwoThree).containsAnyOf(new Byte[] { 4 });
+   * assertThat(oneTwoThree).containsAnyOf(new Byte[] { 4, 5, 6, 7 });
+ * + * @param values the values whose at least one which is expected to be in the array under test. + * @return {@code this} assertion object. + * @throws NullPointerException if the array of values is {@code null}. + * @throws IllegalArgumentException if the array of values is empty and the array under test is not empty. + * @throws AssertionError if the array under test is {@code null}. + * @throws AssertionError if the array under test does not contain any of the given {@code values}. + * @since 3.19.0 + */ + public SELF containsAnyOf(Byte[] values) { + requireNonNullParameter(values, "values"); + arrays.assertContainsAnyOf(info, actual, toPrimitiveByteArray(values)); + return myself; + } + /** * Verifies that the actual array contains at least one of the given values. *

@@ -1030,4 +1340,10 @@ public AbstractStringAssert encodedAsBase64() { return new StringAssert(Base64.getEncoder().encodeToString(actual)).withAssertionState(myself); } + private static byte[] toPrimitiveByteArray(Byte[] values) { + byte[] bytes = new byte[values.length]; + range(0, values.length).forEach(i -> bytes[i] = values[i]); + return bytes; + } + } diff --git a/src/main/java/org/assertj/core/api/AbstractByteAssert.java b/src/main/java/org/assertj/core/api/AbstractByteAssert.java index 9f2c3f05c8d..ba780d0b128 100644 --- a/src/main/java/org/assertj/core/api/AbstractByteAssert.java +++ b/src/main/java/org/assertj/core/api/AbstractByteAssert.java @@ -8,7 +8,7 @@ * 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-2020 the original author or authors. + * Copyright 2012-2021 the original author or authors. */ package org.assertj.core.api; @@ -43,7 +43,7 @@ public abstract class AbstractByteAssert> @VisibleForTesting Bytes bytes = Bytes.instance(); - public AbstractByteAssert(Byte actual, Class selfType) { + protected AbstractByteAssert(Byte actual, Class selfType) { super(actual, selfType); } diff --git a/src/main/java/org/assertj/core/api/AbstractCharArrayAssert.java b/src/main/java/org/assertj/core/api/AbstractCharArrayAssert.java index 88134f2200f..372259a6154 100644 --- a/src/main/java/org/assertj/core/api/AbstractCharArrayAssert.java +++ b/src/main/java/org/assertj/core/api/AbstractCharArrayAssert.java @@ -8,10 +8,12 @@ * 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-2020 the original author or authors. + * Copyright 2012-2021 the original author or authors. */ package org.assertj.core.api; +import static java.util.stream.IntStream.range; + import java.util.Comparator; import org.assertj.core.data.Index; @@ -21,12 +23,12 @@ import org.assertj.core.util.VisibleForTesting; public abstract class AbstractCharArrayAssert> - extends AbstractArrayAssert { + extends AbstractArrayAssert { @VisibleForTesting protected CharArrays arrays = CharArrays.instance(); - public AbstractCharArrayAssert(char[] actual, Class selfType) { + protected AbstractCharArrayAssert(char[] actual, Class selfType) { super(actual, selfType); } @@ -217,6 +219,33 @@ public SELF contains(char... values) { return myself; } + /** + * Verifies that the actual array contains the values of the given array, in any order. + *

+ * Example: + *

 // assertion will pass
+   * assertThat(new char[] { 'a', 'b', 'c' }).contains(new Character[] { 'a', 'b' });
+   * assertThat(new char[] { 'a', 'b', 'c' }).contains(new Character[] { 'c', 'a' });
+   * assertThat(new char[] { 'a', 'b', 'c' }).contains(new Character[] { 'a', 'c', 'b' });
+   *
+   * // assertion will fail
+   * assertThat(new char[] { 'a', 'b', 'c' }).contains(new Character[] { 'a', 'd' });
+   * assertThat(new char[] { 'a', 'b', 'c' }).contains(new Character[] { 'd', 'f' });
+ * + * @param values the given {@code Character} array of values. + * @return {@code this} assertion object. + * @throws NullPointerException if the given argument is {@code null}. + * @throws IllegalArgumentException if the given argument is an empty array. + * @throws AssertionError if the actual array is {@code null}. + * @throws AssertionError if the actual array does not contain the given values. + * @since 3.19.0 + */ + public SELF contains(Character[] values) { + requireNonNullParameter(values, "values"); + arrays.assertContains(info, actual, toPrimitiveCharacterArray(values)); + return myself; + } + /** * Verifies that the actual array contains only the given values and nothing else, in any order. *

@@ -243,6 +272,34 @@ public SELF containsOnly(char... values) { return myself; } + /** + * Verifies that the actual array contains only the values of the given array and nothing else, in any order. + *

+ * Example: + *

 // assertion will pass
+   * assertThat(new char[] { 'a', 'b', 'c' }).containsOnly(new Character[] { 'a', 'b', 'c' });
+   * assertThat(new char[] { 'a', 'b', 'c' }).containsOnly(new Character[] { 'b', 'c', 'a' });
+   * assertThat(new char[] { 'a', 'a', 'b' }).containsOnly(new Character[] { 'a', 'b' });
+   *
+   * // assertion will fail
+   * * assertThat(new char[] { 'a', 'b', 'c' }).containsOnly(new Character[] { 'a', 'b', 'c', 'd' });
+   * * assertThat(new char[] { 'a', 'b', 'c' }).containsOnly(new Character[] { 'd', 'f' });
+ * + * @param values the given values. + * @return {@code this} assertion object. + * @throws NullPointerException if the given argument is {@code null}. + * @throws IllegalArgumentException if the given argument is an empty array. + * @throws AssertionError if the actual array is {@code null}. + * @throws AssertionError if the actual array does not contain the given values, i.e. the actual array contains some + * or none of the given values, or the actual array contains more values than the given ones. + * @since 3.19.0 + */ + public SELF containsOnly(Character[] values) { + requireNonNullParameter(values, "values"); + arrays.assertContainsOnly(info, actual, toPrimitiveCharacterArray(values)); + return myself; + } + /** * Verifies that the actual array contains the given values only once. *

@@ -268,6 +325,33 @@ public SELF containsOnlyOnce(char... values) { return myself; } + /** + * Verifies that the actual array contains the values of the given array only once. + *

+ * Examples : + *

 // assertion will pass
+   * assertThat(new char[] { 'a', 'b', 'c' }).containsOnlyOnce(new Character[] { 'a', 'b' });
+   *
+   * // assertions will fail
+   * assertThat(new char[] { 'a', 'b', 'a' }).containsOnlyOnce(new Character[] { 'a' });
+   * assertThat(new char[] { 'a', 'b', 'c' }).containsOnlyOnce(new Character[] { 'd' });
+   * assertThat(new char[] { 'a', 'b', 'c', 'c' }).containsOnlyOnce(new Character[] { '0', 'a', 'b', 'c', 'd', 'e' });
+ * + * @param values the given values. + * @return {@code this} assertion object. + * @throws NullPointerException if the given argument is {@code null}. + * @throws IllegalArgumentException if the given argument is an empty array. + * @throws AssertionError if the actual array is {@code null}. + * @throws AssertionError if the actual group does not contain the given values, i.e. the actual group contains some + * or none of the given values, or the actual group contains more than once these values. + * @since 3.19.0 + */ + public SELF containsOnlyOnce(Character[] values) { + requireNonNullParameter(values, "values"); + arrays.assertContainsOnlyOnce(info, actual, toPrimitiveCharacterArray(values)); + return myself; + } + /** * Verifies that the actual array contains the given sequence, without any other values between them. *

@@ -292,6 +376,32 @@ public SELF containsSequence(char... sequence) { return myself; } + /** + * Verifies that the actual array contains the given sequence, without any other values between them. + *

+ * Example: + *

 // assertion will pass
+   * assertThat(new char[] { 'a', 'b', 'c' }).containsSequence(new Character[] { 'a', 'b' });
+   * assertThat(new char[] { 'a', 'b', 'c' }).containsSequence(new Character[] { 'a', 'b', 'c' });
+   * assertThat(new char[] { 'a', 'b', 'c' }).containsSequence(new Character[] { 'b', 'c' });
+   *
+   * // assertion will fail
+   * assertThat(new char[] { 'a', 'b', 'c' }).containsSequence(new Character[] { 'c', 'a' });
+   * assertThat(new char[] { 'a', 'b', 'c' }).containsSequence(new Character[] { 'd', 'f' });
+ * + * @param sequence the sequence of values to look for. + * @return myself assertion object. + * @throws AssertionError if the actual array is {@code null}. + * @throws AssertionError if the given array is {@code null}. + * @throws AssertionError if the actual array does not contain the given sequence. + * @since 3.19.0 + */ + public SELF containsSequence(Character[] sequence) { + requireNonNullParameter(sequence, "sequence"); + arrays.assertContainsSequence(info, actual, toPrimitiveCharacterArray(sequence)); + return myself; + } + /** * Verifies that the actual array contains the given subsequence (possibly with other values between them). *

@@ -317,6 +427,33 @@ public SELF containsSubsequence(char... subsequence) { return myself; } + /** + * Verifies that the actual array contains the given subsequence (possibly with other values between them). + *

+ * Example: + *

 // assertion will pass
+   * assertThat(new char[] { 'a', 'b', 'c' }).containsSubsequence(new Character[] { 'a', 'b' });
+   * assertThat(new char[] { 'a', 'b', 'c' }).containsSubsequence(new Character[] { 'a', 'c' });
+   * assertThat(new char[] { 'a', 'b', 'c' }).containsSubsequence(new Character[] { 'b', 'c' });
+   * assertThat(new char[] { 'a', 'b', 'c' }).containsSubsequence(new Character[] { 'a', 'b', 'c' });
+   *
+   * // assertion will fail
+   * assertThat(new char[] { 'a', 'b', 'c' }).containsSubsequence(new Character[] { 'c', 'a' });
+   * assertThat(new char[] { 'a', 'b', 'c' }).containsSubsequence(new Character[] { 'd', 'f' });
+ * + * @param subsequence the subsequence of values to look for. + * @return myself assertion object. + * @throws AssertionError if the actual array is {@code null}. + * @throws AssertionError if the given array is {@code null}. + * @throws AssertionError if the actual array does not contain the given subsequence. + * @since 3.19.0 + */ + public SELF containsSubsequence(Character[] subsequence) { + requireNonNullParameter(subsequence, "subsequence"); + arrays.assertContainsSubsequence(info, actual, toPrimitiveCharacterArray(subsequence)); + return myself; + } + /** * Verifies that the actual array contains the given value at the given index. *

@@ -365,6 +502,30 @@ public SELF doesNotContain(char... values) { return myself; } + /** + * Verifies that the actual array does not contain the given values. + *

+ * Example: + *

 // assertion will pass
+   * assertThat(new char[] { 'a', 'b', 'c' }).doesNotContain(new Character[] { 'd' });
+   *
+   * // assertion will fail
+   * assertThat(new char[] { 'a', 'b', 'c' }).doesNotContain(new Character[] { 'b' });
+ * + * @param values the given values. + * @return {@code this} assertion object. + * @throws NullPointerException if the given argument is {@code null}. + * @throws IllegalArgumentException if the given argument is an empty array. + * @throws AssertionError if the actual array is {@code null}. + * @throws AssertionError if the actual array contains any of the given values. + * @since 3.19.0 + */ + public SELF doesNotContain(Character[] values) { + requireNonNullParameter(values, "values"); + arrays.assertDoesNotContain(info, actual, toPrimitiveCharacterArray(values)); + return myself; + } + /** * Verifies that the actual array does not contain the given value at the given index. *

@@ -432,6 +593,32 @@ public SELF startsWith(char... sequence) { return myself; } + /** + * Verifies that the actual array starts with the given sequence of values, without any other values between them. + * Similar to {@link #containsSequence(char...)}, but it also verifies that the first element in the + * sequence is also first element of the actual array. + *

+ * Example: + *

 // assertion will pass
+   * assertThat(new char[] { 'a', 'b', 'c' }).startsWith(new Character[] { 'a', 'b' });
+   *
+   * // assertion will fail
+   * assertThat(new char[] { 'a', 'b', 'c' }).startsWith(new Character[] { 'b', 'c' });
+ * + * @param sequence the sequence of values to look for. + * @return myself assertion object. + * @throws NullPointerException if the given argument is {@code null}. + * @throws IllegalArgumentException if the given argument is an empty array. + * @throws AssertionError if the actual array is {@code null}. + * @throws AssertionError if the actual array does not start with the given sequence. + * @since 3.19.0 + */ + public SELF startsWith(Character[] sequence) { + requireNonNullParameter(sequence, "sequence"); + arrays.assertStartsWith(info, actual, toPrimitiveCharacterArray(sequence)); + return myself; + } + /** * Verifies that the actual array ends with the given sequence of values, without any other values between them. * Similar to {@link #containsSequence(char...)}, but it also verifies that the last element in the @@ -456,6 +643,32 @@ public SELF endsWith(char... sequence) { return myself; } + /** + * Verifies that the actual array ends with the given sequence of values, without any other values between them. + * Similar to {@link #containsSequence(char...)}, but it also verifies that the last element in the + * sequence is also last element of the actual array. + *

+ * Example: + *

 // assertion will pass
+   * assertThat(new char[] { 'a', 'b', 'c' }).endsWith(new Character[] { 'b', 'c' });
+   *
+   * // assertion will fail
+   * assertThat(new char[] { 'a', 'b', 'c' }).endsWith(new Character[] { 'c', 'd' });
+ * + * @param sequence the sequence of values to look for. + * @return myself assertion object. + * @throws NullPointerException if the given argument is {@code null}. + * @throws IllegalArgumentException if the given argument is an empty array. + * @throws AssertionError if the actual array is {@code null}. + * @throws AssertionError if the actual array does not end with the given sequence. + * @since 3.19.0 + */ + public SELF endsWith(Character[] sequence) { + requireNonNullParameter(sequence, "sequence"); + arrays.assertEndsWith(info, actual, toPrimitiveCharacterArray(sequence)); + return myself; + } + /** {@inheritDoc} */ @Override public SELF isSorted() { @@ -509,6 +722,31 @@ public SELF containsExactly(char... values) { return myself; } + /** + * Verifies that the actual group contains only the values of the given array and nothing else, in order. + *

+ * Example : + *

 // assertion will pass
+   * assertThat(new char[] { 'a', 'b', 'c' }).containsExactly(new Character[] { 'a', 'b', 'c' });
+   *
+   * // assertion will fail as actual and expected order differ
+   * assertThat(new char[] { 'a', 'b', 'c' }).containsExactly(new Character[] { 'b', 'a', 'c' });
+ * + * @param values the given values. + * @return {@code this} assertion object. + * @throws NullPointerException if the given argument is {@code null}. + * @throws AssertionError if the actual group is {@code null}. + * @throws AssertionError if the actual group does not contain the given values with same order, i.e. the actual group + * contains some or none of the given values, or the actual group contains more values than the given ones + * or values are the same but the order is not. + * @since 3.19.0 + */ + public SELF containsExactly(Character[] values) { + requireNonNullParameter(values, "values"); + arrays.assertContainsExactly(info, actual, toPrimitiveCharacterArray(values)); + return myself; + } + /** * Verifies that the actual group contains exactly the given values and nothing else, in any order.
*

@@ -535,6 +773,33 @@ public SELF containsExactlyInAnyOrder(char... values) { return myself; } + /** + * Verifies that the actual group contains exactly the values of the given array and nothing else, in any order.
+ *

+ * Example : + *

 // assertions will pass
+   * assertThat(new char[] { 'a', 'b' }).containsExactlyInAnyOrder(new Character[] { 'b', 'a' });
+   * assertThat(new char[] { 'a', 'b', 'a' }).containsExactlyInAnyOrder(new Character[] { 'a', 'a', 'b' });
+   *
+   * // assertions will fail
+   * assertThat(new char[] { 'a', 'b' }).containsExactlyInAnyOrder(new Character[] { 'a' });
+   * assertThat(new char[] { 'a' }).containsExactlyInAnyOrder(new Character[] { 'a', 'b' });
+   * assertThat(new char[] { 'a', 'b', 'a' }).containsExactlyInAnyOrder(new Character[] { 'a', 'b' });
+ * + * @param values the given values. + * @return {@code this} assertion object. + * @throws NullPointerException if the given argument is {@code null}. + * @throws AssertionError if the actual group is {@code null}. + * @throws AssertionError if the actual group does not contain the given values, i.e. the actual group + * contains some or none of the given values, or the actual group contains more values than the given ones. + * @since 3.19.0 + */ + public SELF containsExactlyInAnyOrder(Character[] values) { + requireNonNullParameter(values, "values"); + arrays.assertContainsExactlyInAnyOrder(info, actual, toPrimitiveCharacterArray(values)); + return myself; + } + /** * Use unicode character representation instead of standard representation in error messages. *

@@ -590,4 +855,41 @@ public SELF containsAnyOf(char... values) { return myself; } + /** + * Verifies that the actual array contains at least one of the given values. + *

+ * Example : + *

 char[] abc = { 'a', 'b', 'c' };
+   *
+   * // assertions will pass
+   * assertThat(abc).containsAnyOf(new Character[] { 'b' })
+   *                .containsAnyOf(new Character[] { 'b', 'c' })
+   *                .containsAnyOf(new Character[] { 'a', 'b', 'c' })
+   *                .containsAnyOf(new Character[] { 'a', 'b', 'c', 'd' })
+   *                .containsAnyOf(new Character[] { 'e', 'f', 'g', 'b' });
+   *
+   * // assertions will fail
+   * assertThat(abc).containsAnyOf(new Character[] { 'd' });
+   * assertThat(abc).containsAnyOf(new Character[] { 'd', 'e', 'f', 'g' });
+ * + * @param values the array of values whose at least one which is expected to be in the array under test. + * @return {@code this} assertion object. + * @throws NullPointerException if the array of values is {@code null}. + * @throws IllegalArgumentException if the array of values is empty and the array under test is not empty. + * @throws AssertionError if the array under test is {@code null}. + * @throws AssertionError if the array under test does not contain any of the given {@code values}. + * @since 3.19.0 + */ + public SELF containsAnyOf(Character[] values) { + requireNonNullParameter(values, "values"); + arrays.assertContainsAnyOf(info, actual, toPrimitiveCharacterArray(values)); + return myself; + } + + private static char[] toPrimitiveCharacterArray(Character[] values) { + char[] characters = new char[values.length]; + range(0, values.length).forEach(i -> characters[i] = values[i]); + return characters; + } + } diff --git a/src/main/java/org/assertj/core/api/AbstractCharSequenceAssert.java b/src/main/java/org/assertj/core/api/AbstractCharSequenceAssert.java index f8ee79e2448..d4da48b3f85 100644 --- a/src/main/java/org/assertj/core/api/AbstractCharSequenceAssert.java +++ b/src/main/java/org/assertj/core/api/AbstractCharSequenceAssert.java @@ -8,7 +8,7 @@ * 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-2020 the original author or authors. + * Copyright 2012-2021 the original author or authors. */ package org.assertj.core.api; @@ -17,6 +17,7 @@ import java.io.File; import java.io.LineNumberReader; +import java.text.Normalizer; import java.util.Comparator; import java.util.regex.Pattern; import java.util.regex.PatternSyntaxException; @@ -48,7 +49,7 @@ public abstract class AbstractCharSequenceAssert selfType) { + protected AbstractCharSequenceAssert(ACTUAL actual, Class selfType) { super(actual, selfType); } @@ -1114,6 +1115,15 @@ public SELF doesNotMatch(Pattern pattern) { } /** + * @deprecated + * + * This assertion has some limitations, for example it does not handle tab vs space and would fail if elements are the same but + * in a different order.
+ * The recommended approach is XML Unit which is able to deal with + * these limitations and provides many more features like XPath support and schema validation. + *

+ * Original javadoc: + *

* Verifies that the actual {@code CharSequence} is equal to the given XML {@code CharSequence} after both have been * formatted the same way. *

@@ -1156,7 +1166,10 @@ public SELF doesNotMatch(Pattern pattern) { * @throws NullPointerException if the given {@code CharSequence} is {@code null}. * @throws AssertionError if the actual {@code CharSequence} is {@code null} or is not the same XML as the given XML * {@code CharSequence}. + * @see XML Unit + * @see XML Unit XML source input */ + @Deprecated public SELF isXmlEqualTo(CharSequence expectedXml) { strings.assertXmlEqualsTo(info, actual, expectedXml); return myself; @@ -1178,6 +1191,7 @@ public SELF isXmlEqualTo(CharSequence expectedXml) { * @throws AssertionError if the actual {@code CharSequence} is {@code null} or is not the same XML as the content of * given {@code File}. */ + @Deprecated public SELF isXmlEqualToContentOf(File xmlFile) { isXmlEqualTo(contentOf(xmlFile)); return myself; @@ -1584,4 +1598,34 @@ public SELF isUpperCase() { strings.assertUpperCase(info, actual); return myself; } + + /** + * Verifies that the actual {@code CharSequence} is equal to the given one after they have been normalized + * according to the {@link Normalizer.Form#NFC} form, which is a canonical decomposition followed by canonical composition. + *

+ * Example: + *

 // assertions succeed:
+   *
+   * // Ä = \u00C4 - Ä = \u0041\u0308
+   * assertThat("Ä").isEqualToNormalizingUnicode("Ä");
+   * assertThat("\u00C4").isEqualToNormalizingUnicode("\u0041\u0308");
+   *
+   * // Amélie = u0041\u006d\u00e9\u006c\u0069\u0065 - Amélie = \u0041\u006d\u0065\u0301\u006c\u0069\u0065
+   * assertThat("Amélie").isEqualToNormalizingUnicode("Amélie");
+   *
+   * // assertions fail:
+   * assertThat("ñ").isEqualToNormalizingUnicode("n");
+   * assertThat("Ä").isEqualToNormalizingUnicode("b");
+ * + * @param expected the given {@code CharSequence} to compare the actual {@code CharSequence} to. + * @return {@code this} assertion object. + * @throws AssertionError if the actual {@code CharSequence} is not equal to the given one + * after both strings have been normalized to according to the {@link Normalizer.Form#NFC} form . + * @throws NullPointerException if the actual {@code CharSequence} is not null and the given is. + * @since 3.19.0 + */ + public SELF isEqualToNormalizingUnicode(CharSequence expected) { + strings.assertEqualsToNormalizingUnicode(info, actual, expected); + return myself; + } } diff --git a/src/main/java/org/assertj/core/api/AbstractCharacterAssert.java b/src/main/java/org/assertj/core/api/AbstractCharacterAssert.java index 34f5215a81c..f25090b32c8 100644 --- a/src/main/java/org/assertj/core/api/AbstractCharacterAssert.java +++ b/src/main/java/org/assertj/core/api/AbstractCharacterAssert.java @@ -8,7 +8,7 @@ * 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-2020 the original author or authors. + * Copyright 2012-2021 the original author or authors. */ package org.assertj.core.api; @@ -21,11 +21,11 @@ /** * Base class for all implementations of assertions for {@link Character}s. - * + * * @param the "self" type of this assertion class. Please read "Emulating 'self types' using Java Generics to simplify fluent API implementation" * for more details. - * + * * @author Yvonne Wang * @author David DIDIER * @author Ansgar Konermann @@ -39,7 +39,7 @@ public abstract class AbstractCharacterAssert selfType) { + protected AbstractCharacterAssert(Character actual, Class selfType) { super(actual, selfType); } @@ -97,7 +97,7 @@ public SELF isNotEqualTo(char other) { * assertThat('a').isLessThan('A'); * assertThat('b').isLessThan('a'); * assertThat('a').isLessThan('a');
- * + * * @param other the given value to compare the actual value to. * @return {@code this} assertion object. * @throws AssertionError if the actual value is {@code null}. @@ -118,7 +118,7 @@ public SELF isLessThan(char other) { * * // assertion will fail * assertThat('b').isLessThanOrEqualTo('a');
- * + * * @param other the given value to compare the actual value to. * @return {@code this} assertion object. * @throws AssertionError if the actual value is {@code null}. @@ -141,7 +141,7 @@ public SELF isLessThanOrEqualTo(char other) { * assertThat('A').isGreaterThan('a'); * assertThat('a').isGreaterThan('b'); * assertThat('a').isGreaterThan('a');
- * + * * @param other the given value to compare the actual value to. * @return {@code this} assertion object. * @throws AssertionError if the actual value is {@code null}. @@ -187,10 +187,10 @@ public SELF inUnicode() { *
 // assertions will pass
    * assertThat('A').isGreaterThanOrEqualTo('A');
    * assertThat('b').isGreaterThanOrEqualTo('a');
-   * 
+   *
    * // assertion will fail
    * assertThat('a').isGreaterThanOrEqualTo('b');
- * + * * @param other the given value to compare the actual value to. * @return {@code this} assertion object. * @throws AssertionError if the actual value is {@code null}. @@ -230,13 +230,13 @@ public SELF isLowerCase() { * Example: *
 // assertion will pass
    * assertThat('A').isUpperCase();
-   * 
+   *
    * // assertions will fail
    * assertThat('a').isUpperCase();
    * assertThat(' ').isUpperCase();
    * assertThat('.').isUpperCase();
    * assertThat('1').isUpperCase();
- * + * * @return {@code this} assertion object. * @throws AssertionError if the actual value is {@code null}. * @throws AssertionError if the actual value is not a uppercase character. diff --git a/src/main/java/org/assertj/core/api/AbstractClassAssert.java b/src/main/java/org/assertj/core/api/AbstractClassAssert.java index 33da1747ab0..5609d04df45 100644 --- a/src/main/java/org/assertj/core/api/AbstractClassAssert.java +++ b/src/main/java/org/assertj/core/api/AbstractClassAssert.java @@ -8,7 +8,7 @@ * 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-2020 the original author or authors. + * Copyright 2012-2021 the original author or authors. */ package org.assertj.core.api; @@ -31,7 +31,7 @@ public abstract class AbstractClassAssert Classes classes = Classes.instance(); - public AbstractClassAssert(Class actual, Class selfType) { + protected AbstractClassAssert(Class actual, Class selfType) { super(actual, selfType); } @@ -647,4 +647,64 @@ public SELF hasPublicMethods(String... methodNames) { classes.assertHasPublicMethods(info, actual, methodNames); return myself; } + + /** + * Verifies that the actual {@code Class} has the given package name (as in {@link Class#getPackage()}). + * + *

+ * Example: + *

 package one.two;
+   *
+   * class MyClass {}
+   *
+   * // this assertions succeeds:
+   * assertThat(MyClass.class).hasPackage("one.two");
+   *
+   * // these assertions fail:
+   * assertThat(MyClass.class).hasPackage("one");
+   * assertThat(MyClass.class).hasPackage("");
+   * assertThat(MyClass.class).hasPackage("java.lang");
+ * + * @param packageName the package name the class should have + * @return {@code this} assertions object + * @throws AssertionError if {@code actual} is {@code null}. + * @throws AssertionError if the actual {@code Class} does not have the given package. + * + * @since 3.18.0 + */ + public SELF hasPackage(String packageName) { + classes.assertHasPackage(info, actual, packageName); + return myself; + } + + /** + * Verifies that the actual {@code Class} has the given package (as in {@link Class#getPackage()}). + * + *

+ * Example: + *

 package one.two;
+   *
+   * class MyClass {}
+   **
+   * // these assertions succeed:
+   * assertThat(MyClass.class).hasPackage(Package.getPackage("one.two"));
+   * assertThat(MyClass.class).hasPackage(MyClass.class.getPackage());
+   *
+   * // these assertions fail:
+   * assertThat(MyClass.class).hasPackage(Package.getPackage("one"));
+   * assertThat(MyClass.class).hasPackage(Package.getPackage(""));
+   * assertThat(MyClass.class).hasPackage(Object.class.getPackage());
+ * + * @param aPackage the package the class should have + * @return {@code this} assertions object + * @throws AssertionError if {@code actual} is {@code null}. + * @throws AssertionError if the actual {@code Class} does not have the given package. + * + * @since 3.18.0 + */ + public SELF hasPackage(Package aPackage) { + classes.assertHasPackage(info, actual, aPackage); + return myself; + } + } diff --git a/src/main/java/org/assertj/core/api/AbstractComparableAssert.java b/src/main/java/org/assertj/core/api/AbstractComparableAssert.java index 64819a96d7e..455236b57d3 100644 --- a/src/main/java/org/assertj/core/api/AbstractComparableAssert.java +++ b/src/main/java/org/assertj/core/api/AbstractComparableAssert.java @@ -8,7 +8,7 @@ * 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-2020 the original author or authors. + * Copyright 2012-2021 the original author or authors. */ package org.assertj.core.api; @@ -21,12 +21,12 @@ /** * Base class for all implementations of {@link ComparableAssert}. - * + * * @param the "self" type of this assertion class. Please read "Emulating * 'self types' using Java Generics to simplify fluent API implementation" for more details. * @param the type of the "actual" value. - * + * * @author Alex Ruiz * @author Mikhail Mazursky */ @@ -36,7 +36,7 @@ public abstract class AbstractComparableAssert selfType) { + protected AbstractComparableAssert(ACTUAL actual, Class selfType) { super(actual, selfType); } diff --git a/src/main/java/org/assertj/core/api/AbstractCompletableFutureAssert.java b/src/main/java/org/assertj/core/api/AbstractCompletableFutureAssert.java index 0c7afb9842e..dc0b02c3f89 100644 --- a/src/main/java/org/assertj/core/api/AbstractCompletableFutureAssert.java +++ b/src/main/java/org/assertj/core/api/AbstractCompletableFutureAssert.java @@ -8,7 +8,7 @@ * 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-2020 the original author or authors. + * Copyright 2012-2021 the original author or authors. */ package org.assertj.core.api; @@ -28,9 +28,13 @@ import java.time.Duration; import java.util.Objects; +import java.util.concurrent.CancellationException; import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletionException; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; import java.util.function.Predicate; import org.assertj.core.internal.Failures; @@ -55,7 +59,7 @@ protected AbstractCompletableFutureAssert(CompletableFuture actual, Clas } /** - * Verifies that the {@link CompletableFuture} is done i.e. completed normally, exceptionally, or via cancellation. + * Verifies that the {@link CompletableFuture} is {@link CompletableFuture#isDone() done} i.e. completed normally, exceptionally, or via cancellation. *

* Assertion will pass : *

 assertThat(CompletableFuture.completedFuture("something")).isDone();
@@ -93,10 +97,9 @@ public SELF isNotDone() { } /** - * Verifies that the {@link CompletableFuture} is completed exceptionally. - * Possible causes include cancellation, explicit invocation of completeExceptionally, and abrupt termination of a CompletionStage action. + * Verifies that the {@link CompletableFuture} is {@link CompletableFuture#isCompletedExceptionally() completed exceptionally}. *

- * If you only want to check that actual future is completed exceptionally but not cancelled, use {@link #hasFailed()} or {@link #hasFailedWithThrowableThat()}. + * Possible causes include cancellation, explicit invocation of completeExceptionally, and abrupt termination of a CompletionStage action. *

* Assertion will pass : *

 CompletableFuture future = new CompletableFuture();
@@ -138,7 +141,7 @@ public SELF isNotCompletedExceptionally() {
   }
 
   /**
-   * Verifies that the {@link CompletableFuture} is cancelled.
+   * Verifies that the {@link CompletableFuture} is {@link CompletableFuture#isCancelled() cancelled}.
    * 

* Assertion will pass : *

 CompletableFuture future = new CompletableFuture();
@@ -181,7 +184,7 @@ public SELF isNotCancelled() {
 
   /**
    * Verifies that the {@link CompletableFuture} is completed normally (i.e.{@link CompletableFuture#isDone() done} but not
-   * {@link CompletableFuture#isCompletedExceptionally() completed exceptionally}) or {@link CompletableFuture#isCancelled() cancelled}).
+   * {@link CompletableFuture#isCompletedExceptionally() completed exceptionally}) or {@link CompletableFuture#isCancelled() cancelled}.
    * 

* Assertion will pass : *

 assertThat(CompletableFuture.completedFuture("something")).isCompleted();
@@ -292,6 +295,17 @@ private SELF isCompletedWithValueMatching(Predicate predicate, P } /** + * @deprecated + *

+ * Combine isCompletedExceptionally with isNotCancelled instead: + * + *

 assertThat(future).isCompletedExceptionally()
+   *                   .isNotCancelled();
+ * + * This assertion is deprecated to change the semantics of failed to correspond to {@link CompletableFuture#get()} failing. + *

+ * Original javadoc + *

* Verifies that the {@link CompletableFuture} has completed exceptionally but has not been cancelled, * this assertion is equivalent to: *

 assertThat(future).isCompletedExceptionally()
@@ -309,6 +323,7 @@ private SELF isCompletedWithValueMatching(Predicate predicate, P
    *
    * @return this assertion object.
    */
+  @Deprecated
   public SELF hasFailed() {
     isNotNull();
     if (!(actual.isCompletedExceptionally() && !actual.isCancelled())) throwAssertionError(shouldHaveFailed(actual));
@@ -316,6 +331,16 @@ public SELF hasFailed() {
   }
 
   /**
+   * @deprecated
+   * 

+ * Use matches with the following combination instead: + * + *

 assertThat(future).matches (f -> f.isNotCompletedExceptionally() {@literal ||} f.isCancelled());
+ * + * This assertion is deprecated because its semantic is not obvious. + *

+ * Original javadoc + *

* Verifies that the {@link CompletableFuture} has not failed i.e: incomplete, completed or cancelled.
* This is different from {@link #isNotCompletedExceptionally()} as a cancelled future has not failed but is completed exceptionally. *

@@ -331,6 +356,7 @@ public SELF hasFailed() { * * @return this assertion object. */ + @Deprecated public SELF hasNotFailed() { isNotNull(); if (actual.isCompletedExceptionally() && !actual.isCancelled()) throwAssertionError(shouldNotHaveFailed(actual)); @@ -476,6 +502,22 @@ private ObjectAssert internalSucceedsWithin(long timeout, TimeUnit unit) } /** + * @deprecated + *

+ * Although not 100% the same, consider using {@link #failsWithin(Duration)} or {@link #failsWithin(long, TimeUnit)} instead: + * + *

 CompletableFuture future = new CompletableFuture();
+   * future.completeExceptionally(new RuntimeException("boom!"));
+   *
+   * assertThat(future).failsWithin(1, TimeUnit.SECONDS)
+   *                   .withThrowableOfType(RuntimeException.class)
+   *                   .withMessage("boom!"); 
+ * + * This assertion is deprecated because it relies on {@link #hasFailed()} semantics which we want to move away from (they + * are not clear!) and to use failure semantics corresponding to {@link CompletableFuture#get()} failing. + *

+ * Original javadoc + *

* Verifies that the {@link CompletableFuture} has completed exceptionally and * returns a Throwable assertion object allowing to check the Throwable that has caused the future to fail. *

@@ -495,6 +537,7 @@ private ObjectAssert internalSucceedsWithin(long timeout, TimeUnit unit) * * @return an exception assertion object. */ + @Deprecated public AbstractThrowableAssert hasFailedWithThrowableThat() { hasFailed(); try { @@ -504,4 +547,84 @@ private ObjectAssert internalSucceedsWithin(long timeout, TimeUnit unit) return assertThat(e.getCause()); } } + + /** + * Checks that the future does not complete within the given time (by calling {@link Future#get(long, TimeUnit)}) and returns + * the exception that caused the failure for further (exception) assertions, the exception can be any of + * {@link InterruptedException}, {@link ExecutionException}, {@link TimeoutException} or {@link CancellationException}. + *

+ * WARNING + *

+ * {@code failsWithin} does not fully integrate with soft assertions, if the future completes the test will fail immediately (the + * error is not collected as a soft assertion error), if the assertion succeeds the chained assertions are executed and any + * errors will be collected as a soft assertion errors.
+ * The rationale is that if we collect {@code failsWithin} error as a soft assertion error, the chained assertions would be + * executed but that does not make sense since there is no exception to check as the future has completed. + *

+ * Examples: + *

 CompletableFuture<?> future = futureCompletingAfterMs(100);
+   *
+   * // assertion succeeds as the future is not completed after 50ms
+   * assertThat(future).failsWithin(Duration.ofMillis(50))
+   *                   .withThrowableOfType(TimeoutException.class)
+   *                   .withMessage(null);
+   *
+   * // fails as the future is completed after within 200ms
+   * assertThat(future).failsWithin(Duration.ofMillis(200));
+ * + * @param timeout the maximum time to wait + * @return a new assertion instance on the the future's exception. + * @throws AssertionError if the actual {@code CompletableFuture} is {@code null}. + * @throws AssertionError if the actual {@code CompletableFuture} succeeds within the given timeout. + * @since 3.18.0 + */ + public WithThrowable failsWithin(Duration timeout) { + return internalFailsWithin(timeout); + } + + /** + * Checks that the future does not complete within the given time (by calling {@link Future#get(long, TimeUnit)}) and returns + * the exception that caused the failure for further (exception) assertions, the exception can be any of + * {@link InterruptedException}, {@link ExecutionException}, {@link TimeoutException} or {@link CancellationException}. + *

+ * WARNING + *

+ * {@code failsWithin} does not fully integrate with soft assertions, if the future completes the test will fail immediately (the + * error is not collected as a soft assertion error), if the assertion succeeds the chained assertions are executed and any + * errors will be collected as a soft assertion errors.
+ * The rationale is that if we collect {@code failsWithin} error as a soft assertion error, the chained assertions would be + * executed but that does not make sense since there is no exception to check as the future has completed. + *

+ * Examples: + *

 CompletableFuture<?> future = futureCompletingAfterMs(100);
+   *
+   * // assertion succeeds as the future is not completed after 50ms
+   * assertThat(future).failsWithin(50, TimeUnit.MILLISECONDS)
+   *                   .withThrowableOfType(TimeoutException.class)
+   *                   .withMessage(null);
+   *
+   * // fails as the future is completed after within 200ms
+   * assertThat(future).failsWithin(200, TimeUnit.MILLISECONDS);
+ * + * @param timeout the maximum time to wait + * @param unit the time unit + * @return a new assertion instance on the the future's exception. + * @throws AssertionError if the actual {@code CompletableFuture} is {@code null}. + * @throws AssertionError if the actual {@code CompletableFuture} succeeds within the given timeout. + * @since 3.18.0 + */ + public WithThrowable failsWithin(long timeout, TimeUnit unit) { + return internalFailsWithin(timeout, unit); + } + + private WithThrowable internalFailsWithin(Duration timeout) { + Exception exception = futures.assertFailedWithin(info, actual, timeout); + return new WithThrowable(exception); + } + + private WithThrowable internalFailsWithin(long timeout, TimeUnit unit) { + Exception exception = futures.assertFailedWithin(info, actual, timeout, unit); + return new WithThrowable(exception); + } + } diff --git a/src/main/java/org/assertj/core/api/AbstractDateAssert.java b/src/main/java/org/assertj/core/api/AbstractDateAssert.java index b7f5096be07..88233e375b8 100644 --- a/src/main/java/org/assertj/core/api/AbstractDateAssert.java +++ b/src/main/java/org/assertj/core/api/AbstractDateAssert.java @@ -8,7 +8,7 @@ * 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-2020 the original author or authors. + * Copyright 2012-2021 the original author or authors. */ package org.assertj.core.api; @@ -30,6 +30,7 @@ import java.text.DateFormat; import java.text.ParseException; import java.text.SimpleDateFormat; +import java.time.Instant; import java.util.Calendar; import java.util.Collection; import java.util.Comparator; @@ -37,6 +38,7 @@ import java.util.LinkedHashSet; import java.util.List; import java.util.concurrent.TimeUnit; +import java.util.function.Function; import org.assertj.core.configuration.ConfigurationProvider; import org.assertj.core.internal.ComparatorBasedComparisonStrategy; @@ -91,7 +93,7 @@ public abstract class AbstractDateAssert> @VisibleForTesting Dates dates = Dates.instance(); - public AbstractDateAssert(Date actual, Class selfType) { + protected AbstractDateAssert(Date actual, Class selfType) { super(actual, selfType); } @@ -144,6 +146,23 @@ public SELF isEqualTo(String dateAsString) { return isEqualTo(parse(dateAsString)); } + /** + * Calls {@link AbstractAssert#isEqualTo(Object) isEqualTo(Date date)} after converting the given {@code Instant} to a + * {@code Date}. + *

+ * Example: + *

 // theTwoTowers release date : 2002-12-18
+   * assertThat(theTwoTowers.getReleaseDate()).isEqualTo(Instant.parse("2002-12-18T00:00:00.00Z"));
+ * + * @param instant the given {@code Instant} to compare to actual. + * @return this assertion object. + * @throws NullPointerException if given {@code Instant} is {@code null}. + * @throws AssertionError if actual {@code Date} and given {@link Instant} are not equal (after converting instant to a Date). + */ + public SELF isEqualTo(Instant instant) { + return isEqualTo(Date.from(instant)); + } + /** * Same assertion as {@link AbstractDateAssert#isEqualToIgnoringHours(Date)} but given Date is represented as String * either with one of the default supported date format or user custom date format (set with method @@ -194,13 +213,23 @@ public SELF isEqualToIgnoringHours(String dateAsString) { } /** - * Same assertion as {@link AbstractAssert#isEqualTo(Object)} but given Date is represented as String either with - * one of the default supported date format or user custom date format (set with method - * {@link #withDateFormat(DateFormat)}). - *

- * User custom date format take precedence over the default ones. + * Same assertion as {@link AbstractDateAssert#isEqualToIgnoringHours(Date)} but given Date is represented as + * an {@code java.time.Instant}. *

- * Unless specified otherwise, beware that the default formats are expressed in the current local timezone. + * Example: + *

 assertThat(new Date()).isEqualToIgnoringHours(Instant.now());
+ * + * @param instant the given {@code Instant}. + * @return this assertion object. + * @throws AssertionError if actual {@code Date} and given {@code Instant} are not equal ignoring hours, minutes, seconds and milliseconds. + * @since 3.19.0 + */ + public SELF isEqualToIgnoringHours(Instant instant) { + return isEqualToIgnoringHours(Date.from(instant)); + } + + /** + * Same assertion as {@link AbstractAssert#isEqualTo(Object)} but the comparison ignores hours, minutes, seconds and milliseconds. *

* Example: *

 Date date1 = parseDatetime("2003-04-26T13:01:35");
@@ -274,6 +303,22 @@ public SELF isEqualToIgnoringMinutes(String dateAsString) {
     return isEqualToIgnoringMinutes(parse(dateAsString));
   }
 
+  /**
+   * Same assertion as {@link AbstractDateAssert#isEqualToIgnoringMinutes(Date)} but given Date is represented as
+   * an {@code java.time.Instant}.
+   * 

+ * Example: + *

 assertThat(new Date()).isEqualToIgnoringMinutes(Instant.now());
+ * + * @param instant the given {@code Instant}. + * @return this assertion object. + * @throws AssertionError if actual {@code Date} and given {@code Instant} are not equal ignoring minutes, seconds and milliseconds. + * @since 3.19.0 + */ + public SELF isEqualToIgnoringMinutes(Instant instant) { + return isEqualToIgnoringMinutes(Date.from(instant)); + } + /** * Same assertion as {@link AbstractAssert#isEqualTo(Object)} but given Date should not take care of minutes, * seconds and milliseconds precision. @@ -352,6 +397,22 @@ public SELF isEqualToIgnoringSeconds(String dateAsString) { return isEqualToIgnoringSeconds(parse(dateAsString)); } + /** + * Same assertion as {@link AbstractDateAssert#isEqualToIgnoringSeconds(Date)} but given Date is represented as + * an {@code java.time.Instant}. + *

+ * Example: + *

 assertThat(new Date()).isEqualToIgnoringSeconds(Instant.now());
+ * + * @param instant the given {@code Instant}. + * @return this assertion object. + * @throws AssertionError if actual {@code Date} and given {@code Instant} are not equal ignoring seconds and milliseconds. + * @since 3.19.0 + */ + public SELF isEqualToIgnoringSeconds(Instant instant) { + return isEqualToIgnoringSeconds(Date.from(instant)); + } + /** * Same assertion as {@link AbstractAssert#isEqualTo(Object)} but given Date should not take care of seconds and * milliseconds precision. @@ -359,12 +420,12 @@ public SELF isEqualToIgnoringSeconds(String dateAsString) { * Example: *
 Date date1 = parseDatetime("2003-04-26T13:01:35");
    * Date date2 = parseDatetime("2003-04-26T13:01:36");
-   * Date date3 = parseDatetime("2003-04-26T14:02:00");
    *
    * // OK : all dates fields are the same up to seconds excluded
    * assertThat(date1).isEqualToIgnoringSeconds(date2);
    *
    * // KO : fail as minute fields differ
+   * Date date3 = parseDatetime("2003-04-26T13:02:00");
    * assertThat(date1).isEqualToIgnoringSeconds(date3);
* * @param date the given Date represented as String in default or custom date format. @@ -428,6 +489,22 @@ public SELF isEqualToIgnoringMillis(String dateAsString) { return isEqualToIgnoringMillis(parse(dateAsString)); } + /** + * Same assertion as {@link AbstractDateAssert#isEqualToIgnoringMillis(Date)} but given Date is represented as + * an {@code java.time.Instant}. + *

+ * Example: + *

 assertThat(new Date()).isEqualToIgnoringMillis(Instant.now());
+ * + * @param instant the given {@code Instant}. + * @return this assertion object. + * @throws AssertionError if actual {@code Date} and given {@code Instant} are not equal ignoring milliseconds. + * @since 3.19.0 + */ + public SELF isEqualToIgnoringMillis(Instant instant) { + return isEqualToIgnoringMillis(Date.from(instant)); + } + /** * Same assertion as {@link AbstractAssert#isEqualTo(Object)} but given Date should not take care of milliseconds * precision. @@ -503,7 +580,25 @@ public SELF isNotEqualTo(String dateAsString) { } /** - * Same assertion as {@link Assert#isIn(Object...)}but given date is represented as String either with one of the + * Same assertion as {@link AbstractAssert#isNotEqualTo(Object) isNotEqualTo(Date date)} but given date is + * represented as an {@code java.time.Instant}. + *

+ * Example: + *

 // assertion will pass
+   * // theTwoTowers release date : 2002-12-18
+   * assertThat(theTwoTowers.getReleaseDate()).isNotEqualTo(Instant.now());
+ * + * @param instant the given {@code Instant}. + * @return this assertion object. + * @throws AssertionError if actual {@code Date} and given {@code Instant} are equal. + * @since 3.19.0 + */ + public SELF isNotEqualTo(Instant instant) { + return isNotEqualTo(Date.from(instant)); + } + + /** + * Same assertion as {@link Assert#isIn(Object...)}but given dates are represented as String either with one of the * supported defaults date format or a user custom date format (set with method {@link #withDateFormat(DateFormat)}). *

* User custom date format take precedence over the default ones. @@ -547,15 +642,30 @@ public SELF isNotEqualTo(String dateAsString) { * @throws AssertionError if one of the given date as String could not be converted to a Date. */ public SELF isIn(String... datesAsString) { - Date[] dates = new Date[datesAsString.length]; - for (int i = 0; i < datesAsString.length; i++) { - dates[i] = parse(datesAsString[i]); - } + Date[] dates = toDateArray(datesAsString, this::parse); return isIn((Object[]) dates); } /** - * Same assertion as {@link Assert#isIn(Iterable)} but given date is represented as String either with one of the + * Same assertion as {@link Assert#isIn(Object...) }but given dates are represented as an {@code java.time.Instant}. + *

+ * Example: + *

 // assertion will fail
+   * // theTwoTowers release date : 2002-12-18
+   * Instant now = Instant.now()
+   * assertThat(theTwoTowers.getReleaseDate()).isIn(now, now.plusSeconds(5), now.minusSeconds(5));
+ * + * @param instants the given dates represented as {@code Instant}. + * @return this assertion object. + * @throws AssertionError if actual is not in given dates represented as {@code Instant}. + */ + public SELF isIn(Instant... instants) { + Date[] dates = toDateArray(instants, Date::from); + return isIn((Object[]) dates); + } + + /** + * Same assertion as {@link Assert#isIn(Iterable)} but given dates are represented as String either with one of the * supported defaults date format or a user custom date format (set with method {@link #withDateFormat(DateFormat)}). *

* User custom date format take precedence over the default ones. @@ -606,7 +716,7 @@ public SELF isInWithStringDateCollection(Collection datesAsString) { } /** - * Same assertion as {@link Assert#isNotIn(Object...)} but given date is represented as String either with one of the + * Same assertion as {@link Assert#isNotIn(Object...)} but given dates are represented as String either with one of the * supported defaults date format or a user custom date format (set with method {@link #withDateFormat(DateFormat)}). *

* User custom date format take precedence over the default ones. @@ -650,10 +760,26 @@ public SELF isInWithStringDateCollection(Collection datesAsString) { * @throws AssertionError if one of the given date as String could not be converted to a Date. */ public SELF isNotIn(String... datesAsString) { - Date[] dates = new Date[datesAsString.length]; - for (int i = 0; i < datesAsString.length; i++) { - dates[i] = parse(datesAsString[i]); - } + Date[] dates = toDateArray(datesAsString, this::parse); + return isNotIn((Object[]) dates); + } + + /** + * Same assertion as {@link Assert#isNotIn(Object...)} but given dates are represented as {@code java.time.Instant}. + *

+ * Example: + *

 // assertion will pass
+   * // theTwoTowers release date : 2002-12-18
+   * Instant now = Instant.now()
+   * assertThat(theTwoTowers.getReleaseDate()).isIn(now, now.plusSeconds(5), now.minusSeconds(5));
+ * + * @param instants the given dates represented as {@code Instant}. + * @return this assertion object. + * @throws AssertionError if actual is not in given dates represented as {@code Instant}. + * @since 3.19.0 + */ + public SELF isNotIn(Instant... instants) { + Date[] dates = toDateArray(instants, Date::from); return isNotIn((Object[]) dates); } @@ -729,6 +855,30 @@ public SELF isBefore(Date other) { return myself; } + /** + * Verifies that the actual {@code Date} is strictly before the given {@link Instant}. + *

+ * Example: + *

 // assertion succeeds
+   * // theTwoTowers release date : 2002-12-18
+   * assertThat(theTwoTowers.getReleaseDate()).isBefore(Instant.parse("2002-12-19T00:00:00.00Z"));
+   *
+   * // assertions fail
+   * assertThat(theTwoTowers.getReleaseDate()).isBefore(Instant.parse("2002-12-17T00:00:00.00Z"));
+   * assertThat(theTwoTowers.getReleaseDate()).isBefore(Instant.parse("2002-12-18T00:00:00.00Z"));
+ * + * @param other the given {@code Instant}. + * @return this assertion object. + * @throws AssertionError if the actual {@code Date} is {@code null}. + * @throws NullPointerException if other {@code Instant} is {@code null}. + * @throws AssertionError if the actual {@code Date} is not strictly before the given {@code Instant}. + * @since 3.19.0 + */ + public SELF isBefore(Instant other) { + dates.assertIsBefore(info, actual, Date.from(other)); + return myself; + } + /** * Same assertion as {@link #isBefore(Date)} but given date is represented as String either with one of the * supported defaults date format or a user custom date format (set with method {@link #withDateFormat(DateFormat)}). @@ -830,6 +980,30 @@ public SELF isBeforeOrEqualTo(Date other) { return myself; } + /** + * Verifies that the actual {@code Date} is before or equal to the given {@link Instant}. + *

+ * Example: + *

 // assertions succeed
+   * // theTwoTowers release date : 2002-12-18
+   * assertThat(theTwoTowers.getReleaseDate()).isBeforeOrEqualTo(Instant.parse("2002-12-19T00:00:00.00Z"));
+   * assertThat(theTwoTowers.getReleaseDate()).isBeforeOrEqualTo(Instant.parse("2002-12-18T00:00:00.00Z"));
+   *
+   * // assertion fails
+   * assertThat(theTwoTowers.getReleaseDate()).isBeforeOrEqualTo(Instant.parse("2002-12-17T00:00:00.00Z"));
+ * + * @param other the given {@code Instant}. + * @return this assertion object. + * @throws AssertionError if the actual {@code Date} is {@code null}. + * @throws NullPointerException if other {@code Instant} is {@code null}. + * @throws AssertionError if the actual {@code Date} is not before or equal to the given {@code Instant}. + * @since 3.19.0 + */ + public SELF isBeforeOrEqualTo(Instant other) { + dates.assertIsBeforeOrEqualTo(info, actual, Date.from(other)); + return myself; + } + /** * Same assertion as {@link #isBeforeOrEqualsTo(Date)} but given date is represented as String either with one of the * supported defaults date format or a user custom date format (set with method {@link #withDateFormat(DateFormat)}). @@ -958,6 +1132,30 @@ public SELF isAfter(Date other) { return myself; } + /** + * Verifies that the actual {@code Date} is strictly after the given {@link Instant}. + *

+ * Example: + *

 // assertion succeeds
+   * // theTwoTowers release date : 2002-12-18
+   * assertThat(theTwoTowers.getReleaseDate()).isAfter(Instant.parse("2002-12-17T00:00:00.00Z"));
+   *
+   * // assertions fail
+   * assertThat(theTwoTowers.getReleaseDate()).isAfter(Instant.parse("2002-12-18T00:00:00.00Z"));
+   * assertThat(theTwoTowers.getReleaseDate()).isAfter(Instant.parse("2002-12-19T00:00:00.00Z"));
+ * + * @param other the given {@code Instant}. + * @return this assertion object. + * @throws AssertionError if the actual {@code Date} is {@code null}. + * @throws NullPointerException if other {@code Instant} is {@code null}. + * @throws AssertionError if the actual {@code Date} is not strictly after the given {@code Instant}. + * @since 3.19.0 + */ + public SELF isAfter(Instant other) { + dates.assertIsAfter(info, actual, Date.from(other)); + return myself; + } + /** * Same assertion as {@link #isAfter(Date)} but given date is represented as String either with one of the * supported defaults date format or a user custom date format (set with method {@link #withDateFormat(DateFormat)}). @@ -1059,6 +1257,29 @@ public SELF isAfterOrEqualTo(Date other) { return myself; } + /** + * Verifies that the actual {@code Date} is after or equal to the given {@link Instant}. + *

+ * Example: + *

 // assertions succeed
+   * // theTwoTowers release date : 2002-12-18
+   * assertThat(theTwoTowers.getReleaseDate()).assertIsAfterOrEqualTo(Instant.parse("2002-12-17T00:00:00.00Z"))
+   *                                          .assertIsAfterOrEqualTo(Instant.parse("2002-12-18T00:00:00.00Z"));
+   * // assertion fails
+   * assertThat(theTwoTowers.getReleaseDate()).assertIsAfterOrEqualTo(Instant.parse("2002-12-19T00:00:00.00Z"));
+ * + * @param other the given {@code Instant}. + * @return this assertion object. + * @throws AssertionError if the actual {@code Date} is {@code null}. + * @throws NullPointerException if other {@code Instant} is {@code null}. + * @throws AssertionError if the actual {@code Date} is not after or equal to the given {@code Instant}. + * @since 3.19.0 + */ + public SELF isAfterOrEqualTo(Instant other) { + dates.assertIsAfterOrEqualTo(info, actual, Date.from(other)); + return myself; + } + /** * Same assertion as {@link #isAfterOrEqualsTo(Date)} but given date is represented as String either with one of the * supported defaults date format or a user custom date format (set with method {@link #withDateFormat(DateFormat)}). @@ -1240,6 +1461,25 @@ public SELF isBetween(String start, String end) { return isBetween(parse(start), parse(end)); } + /** + * Same assertion as {@link #isBetween(Date, Date)} but given period is represented with {@link java.time.Instant}. + *

+ * Example: + *

 assertThat(new Date()).isBetween(Instant.now().minusSeconds(5), Instant.now().plusSeconds(5));
+ * + * @param start the period start (inclusive), expected not to be null. + * @param end the period end (exclusive), expected not to be null. + * @return this assertion object. + * @throws AssertionError if the actual {@code Date} is {@code null}. + * @throws NullPointerException if start Instant as String is {@code null}. + * @throws NullPointerException if end Instant as String is {@code null}. + * @throws AssertionError if the actual {@code Date} is not in [start, end[ period. + * @since 3.19.0 + */ + public SELF isBetween(Instant start, Instant end) { + return isBetween(Date.from(start), Date.from(end)); + } + /** * Verifies that the actual {@code Date} is in the given period defined by start and end dates.
* To include start @@ -1274,7 +1514,7 @@ public SELF isBetween(Date start, Date end, boolean inclusiveStart, boolean incl } /** - * Same assertion as {@link #isBetween(Date, Date, boolean, boolean)}but given date is represented as String either + * Same assertion as {@link #isBetween(Date, Date, boolean, boolean)} but given date is represented as String either * with one of the supported defaults date format or a user custom date format (set with method * {@link #withDateFormat(DateFormat)}). *

@@ -1330,6 +1570,28 @@ public SELF isBetween(String start, String end, boolean inclusiveStart, boolean return myself; } + /** + * Same assertion as {@link #isBetween(Date, Date, boolean, boolean)} but given period is represented with {@link java.time.Instant}. + *

+ * Example: + *

 assertThat(new Date()).isBetween(Instant.now().minusSeconds(5), Instant.now().plusSeconds(5), true, true);
+ * + * @param start the period start, expected not to be null. + * @param end the period end, expected not to be null. + * @param inclusiveStart whether to include start date in period. + * @param inclusiveEnd whether to include end date in period. + * @return this assertion object. + * @throws AssertionError if {@code actual} is {@code null}. + * @throws NullPointerException if start Date as Instant is {@code null}. + * @throws NullPointerException if end Date as Instant is {@code null}. + * @throws AssertionError if the actual {@code Date} is not in (start, end) period. + * @since 3.19.0 + */ + public SELF isBetween(Instant start, Instant end, boolean inclusiveStart, boolean inclusiveEnd) { + dates.assertIsBetween(info, actual, Date.from(start), Date.from(end), inclusiveStart, inclusiveEnd); + return myself; + } + /** * Verifies that the actual {@code Date} is not in the given period defined by start and end dates.
* To include start in the period set inclusiveStart parameter to true.
@@ -1361,6 +1623,38 @@ public SELF isNotBetween(Date start, Date end, boolean inclusiveStart, boolean i return myself; } + /** + * Verifies that the actual {@code Date} is not in the given period defined by start and end dates.
+ * To include start in the period set inclusiveStart parameter to true.
+ * To include end in the period set inclusiveEnd parameter to true.
+ *

+ * Example: + *

 SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
+   * // assertions will pass
+   * assertThat(format.parse("2000-01-01")).isNotBetween(format.parse("2000-01-01T00:00:00Z"), format.parse("2100-12-01T00:00:00Z"), false, true);
+   * assertThat(format.parse("2000-01-01")).isNotBetween(format.parse("1900-01-01T00:00:00Z"), format.parse("2000-01-01T00:00:00Z"), true, false);
+   *
+   * // assertions will fail
+   * assertThat(format.parse("2000-01-01")).isNotBetween(format.parse("2000-01-01T00:00:00Z"), format.parse("2100-12-01T00:00:00Z"), true, true);
+   * assertThat(format.parse("2000-01-01")).isNotBetween(format.parse("1900-01-01T00:00:00Z"), format.parse("2000-01-01T00:00:00Z"), true, true);
+   * assertThat(format.parse("2000-01-01")).isNotBetween(format.parse("1900-01-01T00:00:00Z"), format.parse("2100-01-01T00:00:00Z"), false, false);
+ * + * @param start the period start (inclusive), expected not to be null. + * @param end the period end (exclusive), expected not to be null. + * @param inclusiveStart whether to include start date in period. + * @param inclusiveEnd whether to include end date in period. + * @return this assertion object. + * @throws AssertionError if {@code actual} is {@code null}. + * @throws NullPointerException if start {@code Instant} is {@code null}. + * @throws NullPointerException if end {@code Instant} is {@code null}. + * @throws AssertionError if the actual {@code Date} is not in (start, end) period. + * @since 3.19.0 + */ + public SELF isNotBetween(Instant start, Instant end, boolean inclusiveStart, boolean inclusiveEnd) { + dates.assertIsNotBetween(info, actual, Date.from(start), Date.from(end), inclusiveStart, inclusiveEnd); + return myself; + } + /** * Same assertion as {@link #isNotBetween(Date, Date, boolean, boolean)} but given date is represented as String * either with one of the supported defaults date format or a user custom date format (set with method @@ -1438,12 +1732,38 @@ public SELF isNotBetween(String start, String end, boolean inclusiveStart, boole * @throws NullPointerException if start {@code Date} is {@code null}. * @throws NullPointerException if end {@code Date} is {@code null}. * @throws AssertionError if the actual {@code Date} is in [start, end[ period. - * @throws AssertionError if one of the given date as String could not be converted to a Date. */ public SELF isNotBetween(Date start, Date end) { return isNotBetween(start, end, true, false); } + /** + * Verifies that the actual {@code Date} is not in [start, end[ period + *

+ * Example: + *

 SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
+   * // assertions will pass
+   * assertThat(format.parse("1900-01-01")).isNotBetween(Instant.parse("2000-01-01T00:00:00Z"), Instant.parse("2100-12-01T00:00:00Z"));
+   * assertThat(format.parse("2200-01-01")).isNotBetween(Instant.parse("2000-01-01T00:00:00Z"), Instant.parse("2100-12-01T00:00:00Z"));
+   * assertThat(format.parse("2000-01-01")).isNotBetween(Instant.parse("1900-01-01T00:00:00Z"), Instant.parse("2000-01-01T00:00:00Z"));
+   *
+   * // assertions will fail
+   * assertThat(format.parse("2001-12-24")).isNotBetween(Instant.parse("2000-01-01T00:00:00Z"), Instant.parse("2100-01-01T00:00:00Z"));
+   * assertThat(format.parse("1900-01-01")).isNotBetween(Instant.parse("1900-01-01T00:00:00Z"), Instant.parse("2000-01-01T00:00:00Z"));
+ * + * @param start the period start (inclusive), expected not to be null. + * @param end the period end (exclusive), expected not to be null. + * @return this assertion object. + * @throws AssertionError if the actual {@code Date} is {@code null}. + * @throws NullPointerException if start {@code Instant} is {@code null}. + * @throws NullPointerException if end {@code Instant} is {@code null}. + * @throws AssertionError if the actual {@code Date} is in [start, end[ period. + * @since 3.19.0 + */ + public SELF isNotBetween(Instant start, Instant end) { + return isNotBetween(Date.from(start), Date.from(end), true, false); + } + /** * Same assertion as {@link #isNotBetween(Date, Date)} but given date is represented as String either with one of the * supported defaults date format or a user custom date format (set with method {@link #withDateFormat(DateFormat)}). @@ -1594,7 +1914,7 @@ public SELF isAfterYear(int year) { /** * Verifies that the actual {@code Date} year is equal to the given year. *

- * Note that using a custom comparator has no effect on this assertion (see {@link #usingComparator(Comparator)}. + * Note that using a {@link #usingComparator(Comparator) custom comparator} has no effect on this assertion. *

* Example: *

 // assertion will pass
@@ -1628,7 +1948,7 @@ public SELF isWithinYear(int year) {
    * Verifies that the actual {@code Date} month is equal to the given month, month value starting at 1
    * (January=1, February=2, ...).
    * 

- * Note that using a custom comparator has no effect on this assertion (see {@link #usingComparator(Comparator)}. + * Note that using a {@link #usingComparator(Comparator) custom comparator} has no effect on this assertion. *

* Example: *

 // assertion will pass
@@ -1661,7 +1981,7 @@ public SELF isWithinMonth(int month) {
   /**
    * Verifies that the actual {@code Date} day of month is equal to the given day of month.
    * 

- * Note that using a custom comparator has no effect on this assertion (see {@link #usingComparator(Comparator)}. + * Note that using a {@link #usingComparator(Comparator) custom comparator} has no effect on this assertion. *

* Example: *

 // assertion will pass
@@ -1695,7 +2015,7 @@ public SELF isWithinDayOfMonth(int dayOfMonth) {
    * Verifies that the actual {@code Date} day of week is equal to the given day of week (see
    * {@link Calendar#DAY_OF_WEEK} for valid values).
    * 

- * Note that using a custom comparator has no effect on this assertion (see {@link #usingComparator(Comparator)}. + * Note that using a {@link #usingComparator(Comparator) custom comparator} has no effect on this assertion. *

* Example: *

 // assertion will pass
@@ -1729,7 +2049,7 @@ public SELF isWithinDayOfWeek(int dayOfWeek) {
   /**
    * Verifies that the actual {@code Date} hour of day is equal to the given hour of day (24-hour clock).
    * 

- * Note that using a custom comparator has no effect on this assertion (see {@link #usingComparator(Comparator)}. + * Note that using a {@link #usingComparator(Comparator) custom comparator} has no effect on this assertion. *

* Example: *

 // assertion will pass
@@ -1761,7 +2081,7 @@ public SELF isWithinHourOfDay(int hourOfDay) {
   /**
    * Verifies that the actual {@code Date} minute is equal to the given minute.
    * 

- * Note that using a custom comparator has no effect on this assertion (see {@link #usingComparator(Comparator)}. + * Note that using a {@link #usingComparator(Comparator) custom comparator} has no effect on this assertion. *

* Example: *

 // assertion will pass
@@ -1793,7 +2113,7 @@ public SELF isWithinMinute(int minute) {
   /**
    * Verifies that the actual {@code Date} second is equal to the given second.
    * 

- * Note that using a custom comparator has no effect on this assertion (see {@link #usingComparator(Comparator)}. + * Note that using a {@link #usingComparator(Comparator) custom comparator} has no effect on this assertion. *

* Example: *

 // assertion will pass
@@ -1832,7 +2152,7 @@ public SELF isWithinSecond(int second) {
    * // assertion will fail
    * assertThat(parseDatetimeWithMs("2003-04-26T13:20:35.017")).hasMillisecond(25);
* - * Note that using a custom comparator has no effect on this assertion (see {@link #usingComparator(Comparator)}. + * Note that using a {@link #usingComparator(Comparator) custom comparator} has no effect on this assertion. * * @param millisecond the millisecond to compare actual millisecond to * @return this assertion object. @@ -1863,7 +2183,7 @@ public SELF isWithinMillisecond(int millisecond) { * * assertThat(date1).isInSameYearAs(date2);
* - * Note that using a custom comparator has no effect on this assertion (see {@link #usingComparator(Comparator)}. + * Note that using a {@link #usingComparator(Comparator) custom comparator} has no effect on this assertion. * * @param other the given {@code Date} to compare actual {@code Date} to. * @return this assertion object. @@ -1876,6 +2196,29 @@ public SELF isInSameYearAs(Date other) { return myself; } + /** + * Verifies that actual {@code Date} and given {@code Instant} are in the same year. + *

+ * Example: + *

 Date date = parse("2003-04-26");
+   * Instant instant = Instant.parse("2003-04-26T12:30:00Z");
+   *
+   * assertThat(date).isInSameYearAs(instant);
+ * + * Note that using a {@link #usingComparator(Comparator) custom comparator} has no effect on this assertion. + * + * @param other the given {@code Instant} to compare actual {@code Date} to. + * @return this assertion object. + * @throws NullPointerException if {@code Instant} parameter is {@code null}. + * @throws AssertionError if the actual {@code Date} is {@code null}. + * @throws AssertionError if actual {@code Date} and given {@code Instant} are not in the same year. + * @since 3.19.0 + */ + public SELF isInSameYearAs(Instant other) { + dates.assertIsInSameYearAs(info, actual, Date.from(other)); + return myself; + } + /** * Same assertion as {@link #isInSameYearAs(Date)} but given date is represented as String either with one of the * supported defaults date format or a user custom date format (set with method {@link #withDateFormat(DateFormat)}). @@ -1931,19 +2274,42 @@ public SELF isInSameYearAs(String dateAsString) { * * assertThat(date1).isInSameMonthAs(date2);
* - * Note that using a custom comparator has no effect on this assertion (see {@link #usingComparator(Comparator)}. + * Note that using a {@link #usingComparator(Comparator) custom comparator} has no effect on this assertion. * * @param other the given {@code Date} to compare actual {@code Date} to. * @return this assertion object. * @throws NullPointerException if {@code Date} parameter is {@code null}. * @throws AssertionError if the actual {@code Date} is {@code null}. - * @throws AssertionError if actual and given {@code Date} are not in the same month. + * @throws AssertionError if actual and given {@code Date} are not in the same month and year. */ public SELF isInSameMonthAs(Date other) { dates.assertIsInSameMonthAs(info, actual, other); return myself; } + /** + * Verifies that actual {@code Date} and given {@code Instant} have same month and year fields. + *

+ * Example: + *

 Date date = parse("2003-04-26");
+   * Instant instant = Instant.parse("2003-04-27T12:30:00Z");
+   *
+   * assertThat(date).isInSameMonthAs(instant);
+ *

+ * Note that using a {@link #usingComparator(Comparator) custom comparator} has no effect on this assertion. + * + * @param other the given {@code Instant} to compare actual {@code Date} to. + * @return this assertion object. + * @throws NullPointerException if {@code Instant} parameter is {@code null}. + * @throws AssertionError if the actual {@code Date} is {@code null}. + * @throws AssertionError if actual {@code Date} and given {@code Instant} are not in the same month and year. + * @since 3.19.0 + */ + public SELF isInSameMonthAs(Instant other) { + dates.assertIsInSameMonthAs(info, actual, Date.from(other)); + return myself; + } + /** * Same assertion as {@link #isInSameMonthAs(Date)}but given date is represented as String either with one of the * supported defaults date format or a user custom date format (set with method {@link #withDateFormat(DateFormat)}). @@ -1997,20 +2363,47 @@ public SELF isInSameMonthAs(String dateAsString) { * Date date2 = parseDatetime("2003-04-26T12:30:00"); * * assertThat(date1).isInSameDayAs(date2);

- * - * Note that using a custom comparator has no effect on this assertion (see {@link #usingComparator(Comparator)}. + *

+ * Note that using a {@link #usingComparator(Comparator) custom comparator} has no effect on this assertion. + *

+ * This assertion is logically equivalent to {@link #isEqualToIgnoringHours(Date)}. * * @param other the given {@code Date} to compare actual {@code Date} to. * @return this assertion object. * @throws NullPointerException if {@code Date} parameter is {@code null}. * @throws AssertionError if the actual {@code Date} is {@code null}. - * @throws AssertionError if actual and given {@code Date} are not in the same day of month. + * @throws AssertionError if actual and given {@code Date} are not in the same day, month and year. */ public SELF isInSameDayAs(Date other) { dates.assertIsInSameDayAs(info, actual, other); return myself; } + /** + * Verifies that actual {@code Date} and given {@code Instant} have the same day of month, month and year fields values. + *

+ * Example: + *

 Date date = parseDatetime("2003-04-26T23:17:00");
+   * Instant instant = Instant.parse("2003-04-26T12:30:00Z");
+   *
+   * assertThat(date).isInSameDayAs(instant);
+ * + * Note that using a {@link #usingComparator(Comparator) custom comparator} has no effect on this assertion. + *

+ * This assertion is logically equivalent to {@link #isEqualToIgnoringHours(Instant)}. + * + * @param other the given {@code Date} to compare actual {@code Date} to. + * @return this assertion object. + * @throws NullPointerException if {@code Instant} parameter is {@code null}. + * @throws AssertionError if the actual {@code Date} is {@code null}. + * @throws AssertionError if actual {@code Date} and given {@code Instant} are not in the same day, month and year. + * @since 3.19.0 + */ + public SELF isInSameDayAs(Instant other) { + dates.assertIsInSameDayAs(info, actual, Date.from(other)); + return myself; + } + /** * Same assertion as {@link #isInSameDayAs(Date)} but given date is represented as String either with one of the * supported defaults date format or a user custom date format (set with method {@link #withDateFormat(DateFormat)}). @@ -2045,6 +2438,8 @@ public SELF isInSameDayAs(Date other) { *

* If you are getting an {@code IllegalArgumentException} with "Unknown pattern character 'X'" message (some Android versions don't support it), * you can explicitly specify the date format to use so that the default ones are bypassed. + *

+ * This assertion is logically equivalent to {@link #isEqualToIgnoringHours(String)}. * * @param dateAsString the given Date represented as String in default or custom date format. * @return this assertion object. @@ -2057,12 +2452,11 @@ public SELF isInSameDayAs(String dateAsString) { } /** - * Verifies that actual and given {@code Date} are chronologically in the same hour (i.e. their time difference <= 1 - * hour). + * Verifies that actual and given {@code Date} are chronologically in the same hour (i.e. their time difference < 1 hour). *

- * This assertion succeeds as time difference is exactly = 1h: + * This assertion succeeds as time difference is exactly < 1h: *

 Date date1 = parseDatetime("2003-04-26T13:00:00");
-   * Date date2 = parseDatetime("2003-04-26T14:00:00");
+   * Date date2 = parseDatetime("2003-04-26T13:30:00");
    * assertThat(date1).isInSameHourWindowAs(date2);
* * Two dates can have different hour fields and yet be in the same chronological hour, example: @@ -2071,17 +2465,14 @@ public SELF isInSameDayAs(String dateAsString) { * // succeeds as time difference == 1s * assertThat(date1).isInSameHourWindowAs(date2);
* - * This assertion fails as time difference is more than one hour: + * These assertions fail as time difference is equal to or greater than one hour: *
 Date date1 = parseDatetime("2003-04-26T13:00:00");
    * Date date2 = parseDatetime("2003-04-26T14:00:01");
-   * assertThat(date1).isInSameHourWindowAs(date2);
- * - * To compare date's hour fields only (without day, month and year), you can write : - *
 assertThat(myDate).isWithinHour(hourOfDayOf(otherDate));
- * - * see {@link org.assertj.core.util.DateUtil#hourOfDayOf(java.util.Date) hourOfDayOf} to get the hour of a given Date. + * Date date3 = parseDatetime("2003-04-26T14:00:00"); + * assertThat(date1).isInSameHourWindowAs(date2); + * assertThat(date1).isInSameHourWindowAs(date3);
*

- * Note that using a custom comparator has no effect on this assertion (see {@link #usingComparator(Comparator)}). + * Note that using a {@link #usingComparator(Comparator) custom comparator} has no effect on this assertion. * * @param other the given {@code Date} to compare actual {@code Date} to. * @return this assertion object. @@ -2094,6 +2485,42 @@ public SELF isInSameHourWindowAs(Date other) { return myself; } + /** + * Verifies that actual {@code Date} and given {@code Instant} are chronologically in the same hour (i.e. their time + * difference < 1 hour). + *

+ * This assertion succeeds as time difference is exactly = 1h: + *

 Date date = parseDatetime("2003-04-26T13:00:00Z");
+   * Instant instant = Instant.parse("2003-04-26T14:00:00Z");
+   * assertThat(date).isInSameHourWindowAs(instant);
+ * + * Two date/instant can have different hour fields and yet be in the same chronological hour, example: + *
 Date date = parseDatetime("2003-04-26T13:00:00Z");
+   * Instant instant = Instant.parse("2003-04-26T12:59:59Z");
+   * // succeeds as time difference == 1s
+   * assertThat(date).isInSameHourWindowAs(instant);
+ * + * These assertions fail as time difference is equal to or greater than one hour: + *
 Date date = parseDatetime("2003-04-26T13:00:00Z");
+   * Instant instant = Instant.parse("2003-04-26T14:00:01Z");
+   * Instant instant2 = Instant.parse("2003-04-26T14:00:00Z");
+   * assertThat(date).isInSameHourWindowAs(instant);
+   * assertThat(date).isInSameHourWindowAs(instant2);
+ *

+ * Note that using a {@link #usingComparator(Comparator) custom comparator} has no effect on this assertion. + * + * @param other the given {@code Instant} to compare actual {@code Date} to. + * @return this assertion object. + * @throws NullPointerException if {@code Instant} parameter is {@code null}. + * @throws AssertionError if the actual {@code Date} is {@code null}. + * @throws AssertionError if actual {@code Date} and given {@code Instant} are not in the same hour. + * @since 3.19.0 + */ + public SELF isInSameHourWindowAs(Instant other) { + dates.assertIsInSameHourWindowAs(info, actual, Date.from(other)); + return myself; + } + /** * Same assertion as {@link #isInSameHourWindowAs(java.util.Date)} but given date is represented as String either * with one of the supported defaults date format or a user custom date format (set with method @@ -2157,17 +2584,15 @@ public SELF isInSameHourWindowAs(String dateAsString) { * {@link #isInSameHourWindowAs(java.util.Date) isInSameHourWindowAs} assertion (note that if * isInSameHourAs succeeds then isInSameHourWindowAs will succeed too). *

- * If you want to compare hour only (without day, month and year), you could write : - * assertThat(myDate).isWithinHour(hourOfDayOf(otherDate))
- * see {@link org.assertj.core.util.DateUtil#hourOfDayOf(Date)} to get the hour of a given Date. + * Note that using a {@link #usingComparator(Comparator) custom comparator} has no effect on this assertion. *

- * Note that using a custom comparator has no effect on this assertion (see {@link #usingComparator(Comparator)}. + * This assertion is logically equivalent to {@link #isEqualToIgnoringMinutes(Date)}. * * @param other the given {@code Date} to compare actual {@code Date} to. * @return this assertion object. * @throws NullPointerException if {@code Date} parameter is {@code null}. * @throws AssertionError if the actual {@code Date} is {@code null}. - * @throws AssertionError if actual and given {@code Date} are not in the same hour. + * @throws AssertionError if actual and given {@code Date} are not in the same hour, day, month and year. */ public SELF isInSameHourAs(Date other) { dates.assertIsInSameHourAs(info, actual, other); @@ -2204,6 +2629,8 @@ public SELF isInSameHourAs(Date other) { *

* If you are getting an {@code IllegalArgumentException} with "Unknown pattern character 'X'" message (some Android versions don't support it), * you can explicitly specify the date format to use so that the default ones are bypassed. + *

+ * This assertion is logically equivalent to {@link #isEqualToIgnoringMinutes(String)}. * * @param dateAsString the given Date represented as String in default or custom date format. * @return this assertion object. @@ -2216,7 +2643,7 @@ public SELF isInSameHourAs(String dateAsString) { } /** - * Verifies that actual and given {@code Date} are chronologically in the same minute (i.e. their time difference <= 1 + * Verifies that actual and given {@code Date} are chronologically in the same minute (i.e. their time difference < 1 * minute). *

* Example: @@ -2230,17 +2657,15 @@ public SELF isInSameHourAs(String dateAsString) { *

 Date date1 = parseDatetime("2003-01-01T12:01:00");
    * Date date3 = parseDatetime("2003-01-01T12:00:59");
    *
-   * // succeeds as time difference == 1s even though minutes fields differ
+   * // succeeds as time difference == 1s even though minute fields differ
    * assertThat(date1).isInSameMinuteWindowAs(date3);
* - * This assertion fails as time difference is >= one minute: + * This assertion fails as time difference is ≥ 1 min: *
 Date date1 = parseDatetime("2003-01-01T12:01:00");
    * Date date2 = parseDatetime("2003-01-01T12:02:00");
+   * assertThat(date1).isInSameMinuteWindowAs(date2);
* - * // fails, time difference should hae been < 1 min - * assertThat(date1).isInSameMinuteWindowAs(date2); // ERROR
- * - * Note that using a custom comparator has no effect on this assertion (see {@link #usingComparator(Comparator)}). + * Note that using a {@link #usingComparator(Comparator) custom comparator} has no effect on this assertion. * * @param other the given {@code Date} to compare actual {@code Date} to. * @return this assertion object. @@ -2253,6 +2678,43 @@ public SELF isInSameMinuteWindowAs(Date other) { return myself; } + /** + * Verifies that actual {@code Date} and given {@code Instant} are chronologically in the same minute (i.e. their time difference < 1 + * minute). + *

+ * Example: + *

 Date date = parseDatetime("2003-01-01T12:01:00Z");
+   * Instant instant = Instant.parse("2003-01-01T12:01:30Z");
+   *
+   * // succeeds because date time difference < 1 min
+   * assertThat(date).isInSameMinuteWindowAs(instant);
+ * + * Two date/instant can have different minute fields and yet be in the same chronological minute, example: + *
 Date date = parseDatetime("2003-01-01T12:01:00Z");
+   * Instant instant = Instant.parse("2003-01-01T12:00:59Z");
+   *
+   * // succeeds as time difference == 1s even though minute fields differ
+   * assertThat(date).isInSameMinuteWindowAs(instant);
+ * + * This assertion fails as time difference is ≥ 1 min: + *
 Date date = parseDatetime("2003-01-01T12:01:00Z");
+   * Instant instant = Instant.parse("2003-01-01T12:02:00Z");
+   * assertThat(date).isInSameMinuteWindowAs(instant);
+ * + * Note that using a {@link #usingComparator(Comparator) custom comparator} has no effect on this assertion. + * + * @param other the given {@code Instant} to compare actual {@code Date} to. + * @return this assertion object. + * @throws NullPointerException if {@code Instant} parameter is {@code null}. + * @throws AssertionError if the actual {@code Date} is {@code null}. + * @throws AssertionError if actual {@code Date} and given {@code Instant} are not in the same minute. + * @since 3.19.0 + */ + public SELF isInSameMinuteWindowAs(Instant other) { + dates.assertIsInSameMinuteWindowAs(info, actual, Date.from(other)); + return myself; + } + /** * Same assertion as {@link #isInSameMinuteWindowAs(Date)} but given date is represented as String either with one of * the supported defaults date format or a user custom date format (set with method @@ -2318,11 +2780,9 @@ public SELF isInSameMinuteWindowAs(String dateAsString) { * {@link #isInSameMinuteWindowAs(java.util.Date) isInSameMinuteWindowAs} assertion (note that if * isInSameMinuteAs succeeds then isInSameMinuteWindowAs will succeed too). *

- * If you want to compare minute field only (without hour, day, month and year), you could write : - * assertThat(myDate).hasMinute(minuteOf(otherDate))
- * using {@link org.assertj.core.util.DateUtil#minuteOf(Date)} to get the minute of a given Date. + * Note that using a {@link #usingComparator(Comparator) custom comparator} has no effect on this assertion. *

- * Note that using a custom comparator has no effect on this assertion (see {@link #usingComparator(Comparator)}). + * This assertion is logically equivalent to {@link #isEqualToIgnoringSeconds(Date)}. * * @param other the given {@code Date} to compare actual {@code Date} to. * @return this assertion object. @@ -2365,6 +2825,8 @@ public SELF isInSameMinuteAs(Date other) { *

* If you are getting an {@code IllegalArgumentException} with "Unknown pattern character 'X'" message (some Android versions don't support it), * you can explicitly specify the date format to use so that the default ones are bypassed. + *

+ * This assertion is logically equivalent to {@link #isEqualToIgnoringSeconds(String)}. * * @param dateAsString the given Date represented as String in default or custom date format. * @return this assertion object. @@ -2399,13 +2861,13 @@ public SELF isInSameMinuteAs(String dateAsString) { * Date date2 = parseDatetimeWithMs("2003-04-26T13:01:02.000"); * * // fails as time difference = 1s - * assertThat(date1).isInSameSecondWindowAs(date2); // ERROR + * assertThat(date1).isInSameSecondWindowAs(date2); * * Date date3 = parseDatetimeWithMs("2003-04-26T13:01:02.001"); * // fails as time difference > 1s - * assertThat(date1).isInSameSecondWindowAs(date3); // ERROR

+ * assertThat(date1).isInSameSecondWindowAs(date3);
* - * Note that using a custom comparator has no effect on this assertion (see {@link #usingComparator(Comparator)}. + * Note that using a {@link #usingComparator(Comparator) custom comparator} has no effect on this assertion. * * @param other the given {@code Date} to compare actual {@code Date} to. * @return this assertion object. @@ -2418,6 +2880,49 @@ public SELF isInSameSecondWindowAs(Date other) { return myself; } + /** + * Verifies that actual {@code Date} and given {@code Instant} are chronologically strictly in the same second (i.e. their time + * difference < 1 second). + *

+ * Example: + *

 Date date = parseDatetimeWithMs("2003-04-26T13:01:02.123Z");
+   * Instant instant = Instant.parse("2003-04-26T13:01:02.456Z");
+   *
+   * // succeeds as time difference is < 1s
+   * assertThat(date).isInSameSecondWindowAs(instant);
+ * + * Two dates can have different second fields and yet be in the same chronological second, example: + *
 Date date = parseDatetimeWithMs("2003-04-26T13:01:02.999Z");
+   * Instant instant = Instant.parse("2003-04-26T13:01:03.000Z");
+   *
+   * // succeeds as time difference is 1ms < 1s
+   * assertThat(date).isInSameSecondWindowAs(instant);
+ * + * Those assertions fail as time difference is greater or equal to one second: + *
 Date date = parseDatetimeWithMs("2003-04-26T13:01:01.000Z");
+   * Instant instant = Instant.parse("2003-04-26T13:01:02.000Z");
+   *
+   * // fails as time difference = 1s
+   * assertThat(date).isInSameSecondWindowAs(instant);
+   *
+   * Instant instant2 = Instant.parse("2003-04-26T13:01:02.001Z");
+   * // fails as time difference > 1s
+   * assertThat(date).isInSameSecondWindowAs(instant2);
+ * + * Note that using a {@link #usingComparator(Comparator) custom comparator} has no effect on this assertion. + * + * @param other the given {@code Instant} to compare actual {@code Date} to. + * @return this assertion object. + * @throws NullPointerException if {@code Instant} parameter is {@code null}. + * @throws AssertionError if the actual {@code Date} is {@code null}. + * @throws AssertionError if actual {@code Date} and given {@code Instant} are not in the same second. + * @since 3.19.0 + */ + public SELF isInSameSecondWindowAs(Instant other) { + dates.assertIsInSameSecondWindowAs(info, actual, Date.from(other)); + return myself; + } + /** * Same assertion as {@link #isInSameSecondWindowAs(Date)} but given date is represented as String either with one of * the supported defaults date format or a user custom date format (set with method @@ -2485,7 +2990,9 @@ public SELF isInSameSecondWindowAs(String dateAsString) { * assertThat(myDate).hasSecond(secondOf(otherDate))
* using {@link org.assertj.core.util.DateUtil#secondOf(Date)} to get the second of a given Date. *

- * Note that using a custom comparator has no effect on this assertion (see {@link #usingComparator(Comparator)}). + * Note that using a {@link #usingComparator(Comparator) custom comparator} has no effect on this assertion. + *

+ * This assertion is logically equivalent to {@link #isEqualToIgnoringMillis(Date)}. * * @param other the given {@code Date} to compare actual {@code Date} to. * @return this assertion object. @@ -2528,6 +3035,9 @@ public SELF isInSameSecondAs(Date other) { *

* If you are getting an {@code IllegalArgumentException} with "Unknown pattern character 'X'" message (some Android versions don't support it), * you can explicitly specify the date format to use so that the default ones are bypassed. + *

+ * This assertion is logically equivalent to {@link #isEqualToIgnoringMillis(String)}. + * * @param dateAsString the given Date represented as String. * @return this assertion object. */ @@ -2538,22 +3048,22 @@ public SELF isInSameSecondAs(String dateAsString) { /** * Verifies that the actual {@code Date} is close to the other date by less than delta (expressed in milliseconds), * if - * difference is equals to delta it's ok. + * difference is equal to delta it's ok. *

* One can use handy {@link TimeUnit} to convert a duration in milliseconds, for example you can express a delta of 5 * seconds with TimeUnit.SECONDS.toMillis(5). *

- * Note that using a custom comparator has no effect on this assertion (see {@link #usingComparator(Comparator)}. + * Note that using a {@link #usingComparator(Comparator) custom comparator} has no effect on this assertion. *

* Example: *

 Date date1 = new Date();
    * Date date2 = new Date(date1.getTime() + 100);
    *
-   * // assertion will pass
-   * assertThat(date1).isCloseTo(date2, 80);
-   * assertThat(date1).isCloseTo(date2, 100);
+   * // assertion succeeds
+   * assertThat(date1).isCloseTo(date2, 80)
+   *                  .isCloseTo(date2, 100);
    *
-   * // assertion will fail
+   * // assertion fails
    * assertThat(date1).isCloseTo(date2, 101);
* * @param other the date to compare actual to @@ -2561,13 +3071,45 @@ public SELF isInSameSecondAs(String dateAsString) { * @return this assertion object. * @throws NullPointerException if {@code Date} parameter is {@code null}. * @throws AssertionError if the actual {@code Date} is {@code null}. - * @throws AssertionError if the actual {@code Date} week is not close to the given date by less than delta. + * @throws AssertionError if the actual {@code Date} is not close to the given date by less than delta. */ public SELF isCloseTo(Date other, long deltaInMilliseconds) { dates.assertIsCloseTo(info, actual, other, deltaInMilliseconds); return myself; } + /** + * Verifies that the actual {@code Date} is close to the given {@code Instant} by less than delta (expressed in milliseconds), + * if the difference is equal to delta the assertion succeeds. + *

+ * One can use handy {@link TimeUnit} to convert a duration in milliseconds, for example you can express a delta of 5 + * seconds with TimeUnit.SECONDS.toMillis(5). + *

+ * Note that using a {@link #usingComparator(Comparator) custom comparator} has no effect on this assertion. + *

+ * Example: + *

 Date date = new Date();
+   *
+   * // assertions succeed
+   * assertThat(date).isCloseTo(date.toInstant().plusMillis(80), 80)
+   *                 .isCloseTo(date.toInstant().plusMillis(80), 100);
+   *
+   * // assertions fails
+   * assertThat(date).isCloseTo(date.toInstant().minusMillis(101), 100);
+ * + * @param other the Instant to compare actual to + * @param deltaInMilliseconds the delta used for date comparison, expressed in milliseconds + * @return this assertion object. + * @throws NullPointerException if {@code Instant} parameter is {@code null}. + * @throws AssertionError if the actual {@code Date} is {@code null}. + * @throws AssertionError if the actual {@code Date} is not close to the given Instant by less than delta. + * @since 3.19.0 + */ + public SELF isCloseTo(Instant other, long deltaInMilliseconds) { + dates.assertIsCloseTo(info, actual, Date.from(other), deltaInMilliseconds); + return myself; + } + /** * Same assertion as {@link #isCloseTo(Date, long)} but given date is represented as String either with one of the * supported defaults date format or a user custom date format (set with method {@link #withDateFormat(DateFormat)}). @@ -2604,7 +3146,7 @@ public SELF isCloseTo(Date other, long deltaInMilliseconds) { * @return this assertion object. * @throws NullPointerException if dateAsString parameter is {@code null}. * @throws AssertionError if the actual {@code Date} is {@code null}. - * @throws AssertionError if the actual {@code Date} week is not close to the given date by less than delta. + * @throws AssertionError if the actual {@code Date} is not close to the given date by less than delta. */ public SELF isCloseTo(String dateAsString, long deltaInMilliseconds) { return isCloseTo(parse(dateAsString), deltaInMilliseconds); @@ -3011,6 +3553,14 @@ private Date parseDateWith(final String dateAsString, final Collection Date[] toDateArray(T[] values, Function converter) { + Date[] dates = new Date[values.length]; + for (int i = 0; i < values.length; i++) { + dates[i] = converter.apply(values[i]); + } + return dates; + } + @Override @CheckReturnValue public SELF usingComparator(Comparator customComparator) { diff --git a/src/main/java/org/assertj/core/api/AbstractDoubleArrayAssert.java b/src/main/java/org/assertj/core/api/AbstractDoubleArrayAssert.java index 365d6befdfa..2bd47914dd0 100755 --- a/src/main/java/org/assertj/core/api/AbstractDoubleArrayAssert.java +++ b/src/main/java/org/assertj/core/api/AbstractDoubleArrayAssert.java @@ -8,10 +8,11 @@ * 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-2020 the original author or authors. + * Copyright 2012-2021 the original author or authors. */ package org.assertj.core.api; +import java.util.Arrays; import java.util.Comparator; import org.assertj.core.data.Index; @@ -27,7 +28,7 @@ public abstract class AbstractDoubleArrayAssert selfType) { + protected AbstractDoubleArrayAssert(double[] actual, Class selfType) { super(actual, selfType); } @@ -224,6 +225,33 @@ public SELF contains(double... values) { return myself; } + /** + * Verifies that the actual array contains the values of the given array, in any order. + *

+ * Example: + *

 double[] values = new double[] { 1.0, 2.0, 3.0 };
+   *
+   * // assertion will pass
+   * assertThat(values).contains(new Double[] { 1.0, 3.0, 2.0 })
+   *
+   * // assertions will fail
+   * assertThat(values).contains(new Double[] { 1.0, 4.0 });
+   * assertThat(values).contains(new Double[] { 1.1, 2.1 });
+ * + * @param values the given values. + * @return {@code this} assertion object. + * @throws NullPointerException if the given argument is {@code null}. + * @throws IllegalArgumentException if the given argument is an empty array. + * @throws AssertionError if the actual array is {@code null}. + * @throws AssertionError if the actual array does not contain the given values. + * @since 3.19.0 + */ + public SELF contains(Double[] values) { + requireNonNullParameter(values, "values"); + arrays.assertContains(info, actual, toPrimitiveDoubleArray(values)); + return myself; + } + /** * Verifies that the actual array contains the given values, in any order, * the comparison is done at the given precision/offset set with {@link Assertions#withPrecision(Double)}. @@ -232,11 +260,11 @@ public SELF contains(double... values) { *
 double[] values = new double[] { 1.0, 2.0, 3.0 };
    *
    * // assertion will pass
-   * assertThat(values).contains(new double[] {1.01, 3.01, 2.0}, withPrecision(0.02));
+   * assertThat(values).contains(new double[] { 1.01, 3.01, 2.0 }, withPrecision(0.02));
    *
    * // assertions will fail
-   * assertThat(values).contains(new double[] {1.0, 4.0}, withPrecision(0.5));
-   * assertThat(values).contains(new double[] {4.0, 7.0}, withPrecision(2));
+ * assertThat(values).contains(new double[] { 1.0, 4.0 }, withPrecision(0.5)); + * assertThat(values).contains(new double[] { 4.0, 7.0 }, withPrecision(2));
* * @param values the given values. * @param precision the precision under which the value may vary @@ -250,6 +278,33 @@ public SELF contains(double[] values, Offset precision) { return usingComparatorWithPrecision(precision.value).contains(values); } + /** + * Verifies that the actual array contains the values of the given array, in any order, + * the comparison is done at the given precision/offset set with {@link Assertions#withPrecision(Double)}. + *

+ * Examples : + *

 double[] values = new double[] { 1.0, 2.0, 3.0 };
+   *
+   * // assertion will pass
+   * assertThat(values).contains(new Double[] { 1.01, 3.01, 2.0 }, withPrecision(0.02));
+   *
+   * // assertions will fail
+   * assertThat(values).contains(new Double[] { 1.0, 4.0 }, withPrecision(0.5));
+   * assertThat(values).contains(new Double[] { 4.0, 7.0 }, withPrecision(2));
+ * + * @param values the given values. + * @param precision the precision under which the value may vary + * @return {@code this} assertion object. + * @throws NullPointerException if the given argument is {@code null}. + * @throws IllegalArgumentException if the given argument is an empty array. + * @throws AssertionError if the actual array is {@code null}. + * @throws AssertionError if the actual array does not contain the given values. + * @since 3.19.0 + */ + public SELF contains(Double[] values, Offset precision) { + return usingComparatorWithPrecision(precision.value).contains(toPrimitiveDoubleArray(values)); + } + /** * Verifies that the actual array contains only the given values and nothing else, in any order. *

@@ -285,6 +340,34 @@ public SELF containsOnly(double... values) { return myself; } + /** + * Verifies that the actual array contains only the values of the given array and nothing else, in any order. + *

+ * Example: + *

 // assertions will pass
+   * assertThat(new double[] { 1.0 , 2.0 }).containsOnly(new Double[] { 1.0, 2.0 });
+   * assertThat(new double[] { 2.0, 1.0 }).containsOnly(new Double[] { 1.0, 2.0 });
+   * assertThat(new double[] { 1.0, 1.0, 2.0 }).containsOnly(new Double[] { 1.0, 2.0 });
+   *
+   * // assertions will fail
+   * assertThat(new double[] { 1.0, 2.0 }).containsOnly(new Double[] { 2.0 });
+   * assertThat(new double[] { 1.0 }).containsOnly(new Double[] { 1.0, 2.0 });
+ * + * @param values the given values. + * @return {@code this} assertion object. + * @throws NullPointerException if the given argument is {@code null}. + * @throws IllegalArgumentException if the given argument is an empty array. + * @throws AssertionError if the actual array is {@code null}. + * @throws AssertionError if the actual array does not contain the given values, i.e. the actual array contains some + * or none of the given values, or the actual array contains more values than the given ones. + * @since 3.19.0 + */ + public SELF containsOnly(Double[] values) { + requireNonNullParameter(values, "values"); + arrays.assertContainsOnly(info, actual, toPrimitiveDoubleArray(values)); + return myself; + } + /** * Verifies that the actual array contains only the given values and nothing else, in any order. * The comparison is done at the given precision/offset set with {@link Assertions#withPrecision(Double)}. @@ -293,12 +376,12 @@ public SELF containsOnly(double... values) { *
 double[] values = new double[] { 1.0, 2.0, 3.0 };
    *
    * // assertion will pass
-   * assertThat(values).containsOnly(new double[] {1.0, 2.0, 3.0}, withPrecision(0.00001))
-   *                   .containsOnly(new double[] {2.0, 3.0, 0.7}, withPrecision(0.5));
+   * assertThat(values).containsOnly(new double[] { 1.0, 2.0, 3.0 }, withPrecision(0.00001))
+   *                   .containsOnly(new double[] { 2.0, 3.0, 0.7 }, withPrecision(0.5));
    *
    * // assertions will fail
-   * assertThat(values).containsOnly(new double[] {1.0, 4.0, 2.0, 3.0}, withPrecision(0.5));
-   * assertThat(values).containsOnly(new double[] {4.0, 7.0}, withPrecision(0.2));
+ * assertThat(values).containsOnly(new double[] { 1.0, 4.0, 2.0, 3.0 }, withPrecision(0.5)); + * assertThat(values).containsOnly(new double[] { 4.0, 7.0 }, withPrecision(0.2));
* * @param values the given values. * @param precision the precision under which the value may vary @@ -313,6 +396,35 @@ public SELF containsOnly(double[] values, Offset precision) { return usingComparatorWithPrecision(precision.value).containsOnly(values); } + /** + * Verifies that the actual array contains only the values of the given array and nothing else, in any order. + * The comparison is done at the given precision/offset set with {@link Assertions#withPrecision(Double)}. + *

+ * Examples : + *

 double[] values = new double[] { 1.0, 2.0, 3.0 };
+   *
+   * // assertion will pass
+   * assertThat(values).containsOnly(new Double[] { 1.0, 2.0, 3.0 }, withPrecision(0.00001))
+   *                   .containsOnly(new Double[] { 2.0, 3.0, 0.7 }, withPrecision(0.5));
+   *
+   * // assertions will fail
+   * assertThat(values).containsOnly(new Double[] { 1.0, 4.0, 2.0, 3.0 }, withPrecision(0.5));
+   * assertThat(values).containsOnly(new Double[] { 4.0, 7.0 }, withPrecision(0.2));
+ * + * @param values the given values. + * @param precision the precision under which the value may vary + * @return {@code this} assertion object. + * @throws NullPointerException if the given argument is {@code null}. + * @throws IllegalArgumentException if the given argument is an empty array. + * @throws AssertionError if the actual array is {@code null}. + * @throws AssertionError if the actual array does not contain the given values, i.e. the actual array contains some + * or none of the given values, or the actual array contains more values than the given ones. + * @since 3.19.0 + */ + public SELF containsOnly(Double[] values, Offset precision) { + return usingComparatorWithPrecision(precision.value).containsOnly(toPrimitiveDoubleArray(values)); + } + /** * Verifies that the actual array contains the given values only once. *

@@ -345,6 +457,33 @@ public SELF containsOnlyOnce(double... values) { return myself; } + /** + * Verifies that the actual array contains the values of the given array only once. + *

+ * Examples : + *

 // assertion will pass
+   * assertThat(new double[] { 1.0, 2.0 }).containsOnlyOnce(new Double[] { 1.0, 2.0 });
+   *
+   * // assertions will fail
+   * assertThat(new double[] { 1.0, 2.0, 1.0 }).containsOnlyOnce(new Double[] { 1.0 });
+   * assertThat(new double[] { 1.0 }).containsOnlyOnce(new Double[] { 2.0 });
+   * assertThat(new double[] { 1.0 }).containsOnlyOnce(new Double[] { 1.0, 2.0 });
+ * + * @param values the given values. + * @return {@code this} assertion object. + * @throws NullPointerException if the given argument is {@code null}. + * @throws IllegalArgumentException if the given argument is an empty array. + * @throws AssertionError if the actual array is {@code null}. + * @throws AssertionError if the actual group does not contain the given values, i.e. the actual group contains some + * or none of the given values, or the actual group contains more than once these values. + * @since 3.19.0 + */ + public SELF containsOnlyOnce(Double[] values) { + requireNonNullParameter(values, "values"); + arrays.assertContainsOnlyOnce(info, actual, toPrimitiveDoubleArray(values)); + return myself; + } + /** * Verifies that the actual array contains the given values only once. * The comparison is done at the given precision/offset set with {@link Assertions#withPrecision(Double)}. @@ -371,6 +510,33 @@ public SELF containsOnlyOnce(double[] values, Offset precision) { return usingComparatorWithPrecision(precision.value).containsOnlyOnce(values); } + /** + * Verifies that the actual array contains the values of the given array only once. + * The comparison is done at the given precision/offset set with {@link Assertions#withPrecision(Double)}. + *

+ * Examples : + *

 // assertion will pass
+   * assertThat(new double[] { 1.0, 2.0, 3.0 }).containsOnlyOnce(new Double[] { 1.1, 2.0 }, withPrecision(0.2));
+   *
+   * // assertions will fail
+   * assertThat(new double[] { 1.0, 2.0, 1.0 }).containsOnlyOnce(new Double[] { 1.05 }, withPrecision(0.1));
+   * assertThat(new double[] { 1.0, 2.0, 3.0 }).containsOnlyOnce(new Double[] { 4.0 }, withPrecision(0.1));
+   * assertThat(new double[] { 1.0, 2.0, 3.0, 3.0 }).containsOnlyOnce(new Double[] { 0.1, 0.9, 2.0, 3.11, 4.0, 5.0 }, withPrecision(0.2));
+ * + * @param values the given values. + * @param precision the precision under which the value may vary + * @return {@code this} assertion object. + * @throws NullPointerException if the given argument is {@code null}. + * @throws IllegalArgumentException if the given argument is an empty array. + * @throws AssertionError if the actual array is {@code null}. + * @throws AssertionError if the actual group does not contain the given values, i.e. the actual group contains some + * or none of the given values, or the actual group contains more than once these values. + * @since 3.19.0 + */ + public SELF containsOnlyOnce(Double[] values, Offset precision) { + return usingComparatorWithPrecision(precision.value).containsOnlyOnce(toPrimitiveDoubleArray(values)); + } + /** * Verifies that the actual array contains the given sequence, without any other values between them. *

@@ -404,6 +570,30 @@ public SELF containsSequence(double... sequence) { return myself; } + /** + * Verifies that the actual array contains the given sequence, without any other values between them. + *

+ * Example: + *

 // assertion will pass
+   * assertThat(new double[] { 1.0, 2.0 }).containsSequence(new Double[] { 1.0, 2.0 });
+   * assertThat(new double[] { 1.0, 2.0, 2.0, 1.0 }).containsSequence(new Double[] { 2.0, 1.0 });
+   *
+   * // assertion will fail
+   * assertThat(new double[] { 1.0, 1.0, 2.0 }).containsSequence(new Double[] { 2.0, 1.0 });
+ * + * @param sequence the sequence of values to look for. + * @return myself assertion object. + * @throws AssertionError if the actual array is {@code null}. + * @throws AssertionError if the given array is {@code null}. + * @throws AssertionError if the actual array does not contain the given sequence. + * @since 3.19.0 + */ + public SELF containsSequence(Double[] sequence) { + requireNonNullParameter(sequence, "sequence"); + arrays.assertContainsSequence(info, actual, toPrimitiveDoubleArray(sequence)); + return myself; + } + /** * Verifies that the actual array contains the given sequence, without any other values between them. * The comparison is done at the given precision/offset set with {@link Assertions#withPrecision(Double)}. @@ -431,6 +621,34 @@ public SELF containsSequence(double[] sequence, Offset precision) { return usingComparatorWithPrecision(precision.value).containsSequence(sequence); } + /** + * Verifies that the actual array contains the given sequence, without any other values between them. + * The comparison is done at the given precision/offset set with {@link Assertions#withPrecision(Double)}. + *

+ * Examples : + *

 double[] values = new double[] { 1.0, 2.0, 3.0 };
+   *
+   * // assertion will pass
+   * assertThat(values).containsSequence(new Double[] { 1.07, 2.0 }, withPrecision(0.1))
+   *                   .containsSequence(new Double[] { 1.1, 2.1, 3.0 }, withPrecision(0.2))
+   *                   .containsSequence(new Double[] { 2.2, 3.0 }, withPrecision(0.3));
+   *
+   * // assertions will fail
+   * assertThat(values).containsSequence(new Double[] { 1.0, 3.0 }, withPrecision(0.2));
+   * assertThat(values).containsSequence(new Double[] { 4.0, 7.0 }, withPrecision(0.1));
+ * + * @param sequence the sequence of values to look for. + * @param precision the precision under which the value may vary + * @return {@code this} assertion object. + * @throws AssertionError if the actual array is {@code null}. + * @throws AssertionError if the given array is {@code null}. + * @throws AssertionError if the actual array does not contain the given sequence. + * @since 3.19.0 + */ + public SELF containsSequence(Double[] sequence, Offset precision) { + return usingComparatorWithPrecision(precision.value).containsSequence(toPrimitiveDoubleArray(sequence)); + } + /** * Verifies that the actual array contains the given subsequence (possibly with other values between them). *

@@ -464,6 +682,30 @@ public SELF containsSubsequence(double... subsequence) { return myself; } + /** + * Verifies that the actual array contains the given subsequence (possibly with other values between them). + *

+ * Example: + *

 // assertion will pass
+   * assertThat(new double[] { 1.0, 2.0 }).containsSubsequence(new Double[] { 1.0, 2.0 });
+   * assertThat(new double[] { 1.0, 2.0, 2.0, 1.0 }).containsSubsequence(new Double[] { 1.0, 1.0 });
+   *
+   * // assertion will fail
+   * assertThat(new double[] { 1.0, 1.0, 2.0 }).containsSubsequence(new Double[] { 2.0, 1.0 });
+ * + * @param subsequence the subsequence of values to look for. + * @return myself assertion object. + * @throws AssertionError if the actual array is {@code null}. + * @throws AssertionError if the given array is {@code null}. + * @throws AssertionError if the actual array does not contain the given subsequence. + * @since 3.19.0 + */ + public SELF containsSubsequence(Double[] subsequence) { + requireNonNullParameter(subsequence, "subsequence"); + arrays.assertContainsSubsequence(info, actual, toPrimitiveDoubleArray(subsequence)); + return myself; + } + /** * Verifies that the actual array contains the given subsequence (possibly with other values between them). * The comparison is done at the given precision/offset set with {@link Assertions#withPrecision(Double)}. @@ -491,6 +733,34 @@ public SELF containsSubsequence(double[] subsequence, Offset precision) return usingComparatorWithPrecision(precision.value).containsSubsequence(subsequence); } + /** + * Verifies that the actual array contains the given subsequence (possibly with other values between them). + * The comparison is done at the given precision/offset set with {@link Assertions#withPrecision(Double)}. + *

+ * Examples : + *

 double[] values = new double[] { 1.0, 2.0, 3.0 };
+   *
+   * // assertion will pass
+   * assertThat(values).containsSubsequence(new Double[] { 1.0, 2.0 }, withPrecision(0.1))
+   *                   .containsSubsequence(new Double[] { 1.0, 2.07, 3.0 }, withPrecision(0.1))
+   *                   .containsSubsequence(new Double[] { 2.1, 2.9 }, withPrecision(0.2));
+   *
+   * // assertions will fail
+   * assertThat(values).containsSubsequence(new Double[] { 1.0, 3.0 }, withPrecision(0.1));
+   * assertThat(values).containsSubsequence(new Double[] { 4.0, 7.0 }, withPrecision(0.1));
+ * + * @param subsequence the subsequence of values to look for. + * @param precision the precision under which the value may vary. + * @return {@code this} assertion object. + * @throws AssertionError if the actual array is {@code null}. + * @throws AssertionError if the given array is {@code null}. + * @throws AssertionError if the actual array does not contain the given subsequence. + * @since 3.19.0 + */ + public SELF containsSubsequence(Double[] subsequence, Offset precision) { + return usingComparatorWithPrecision(precision.value).containsSubsequence(toPrimitiveDoubleArray(subsequence)); + } + /** * Verifies that the actual array contains the given value at the given index. *

@@ -586,6 +856,30 @@ public SELF doesNotContain(double... values) { return myself; } + /** + * Verifies that the actual array does not contain the values of the given array. + *

+ * Example: + *

 // assertion will pass
+   * assertThat(new double[] { 1.0, 1.0 }).doesNotContain(new Double[] { 2.0 });
+   *
+   * // assertion will fail
+   * assertThat(new double[] { 1.0, 1.0, 2.0 }).doesNotContain(new Double[] { 2.0 });
+ * + * @param values the given values. + * @return {@code this} assertion object. + * @throws NullPointerException if the given argument is {@code null}. + * @throws IllegalArgumentException if the given argument is an empty array. + * @throws AssertionError if the actual array is {@code null}. + * @throws AssertionError if the actual array contains any of the given values. + * @since 3.19.0 + */ + public SELF doesNotContain(Double[] values) { + requireNonNullParameter(values, "values"); + arrays.assertDoesNotContain(info, actual, toPrimitiveDoubleArray(values)); + return myself; + } + /** * Verifies that the actual array does not contain the given values. * The comparison is done at the given precision/offset set with {@link Assertions#withPrecision(Double)}. @@ -611,6 +905,32 @@ public SELF doesNotContain(double[] values, Offset precision) { return usingComparatorWithPrecision(precision.value).doesNotContain(values); } + /** + * Verifies that the actual array does not contain the values of the given array. + * The comparison is done at the given precision/offset set with {@link Assertions#withPrecision(Double)}. + *

+ * Example: + *

 double[] values = new double[] { 1.0, 2.0, 3.0 };
+   *
+   * // assertion will pass
+   * assertThat(values).doesNotContain(new Double[] { 4.0, 8.0 }, withPrecision(0.5));
+   *
+   * // assertion will fail
+   * assertThat(values).doesNotContain(new Double[] { 1.05, 4.0, 8.0 }, withPrecision(0.1));
+ * + * @param values the given values. + * @param precision the precision under which the values may vary. + * @return {@code this} assertion object. + * @throws NullPointerException if the given argument is {@code null}. + * @throws IllegalArgumentException if the given argument is an empty array. + * @throws AssertionError if the actual array is {@code null}. + * @throws AssertionError if the actual array contains any of the given values. + * @since 3.19.0 + */ + public SELF doesNotContain(Double[] values, Offset precision) { + return usingComparatorWithPrecision(precision.value).doesNotContain(toPrimitiveDoubleArray(values)); + } + /** * Verifies that the actual array does not contain the given value at the given index. *

@@ -747,6 +1067,32 @@ public SELF startsWith(double... sequence) { return myself; } + /** + * Verifies that the actual array starts with the given sequence of values, without any other values between them. + * Similar to {@link #containsSequence(Double[])}, but it also verifies that the first element in the + * sequence is also first element of the actual array. + *

+ * Example: + *

 // assertion will pass
+   * assertThat(new double[] { 1.0, 2.0, 2.0, 1.0 }).startsWith(new Double[] { 1.0, 2.0 });
+   *
+   * // assertion will fail
+   * assertThat(new double[] { 1.0, 2.0, 2.0, 1.0 }).startsWith(new Double[] { 2.0, 2.0 });
+ * + * @param sequence the sequence of values to look for. + * @return myself assertion object. + * @throws NullPointerException if the given argument is {@code null}. + * @throws IllegalArgumentException if the given argument is an empty array. + * @throws AssertionError if the actual array is {@code null}. + * @throws AssertionError if the actual array does not start with the given sequence. + * @since 3.19.0 + */ + public SELF startsWith(Double[] sequence) { + requireNonNullParameter(sequence, "sequence"); + arrays.assertStartsWith(info, actual, toPrimitiveDoubleArray(sequence)); + return myself; + } + /** * Verifies that the actual array starts with the given sequence of values, without any other values between them. * Similar to {@link #containsSequence(double...)}, but it also verifies that the first element in the @@ -776,6 +1122,36 @@ public SELF startsWith(double[] values, Offset precision) { return usingComparatorWithPrecision(precision.value).startsWith(values); } + /** + * Verifies that the actual array starts with the given sequence of values, without any other values between them. + * Similar to {@link #containsSequence(double...)}, but it also verifies that the first element in the + * sequence is also first element of the actual array. + *

+ * The comparison is done at the given precision/offset set with {@link Assertions#withPrecision(Double)}. + *

+ * Example: + *

 double[] values = new double[] { 1.0, 2.0, 3.0 };
+   *
+   * // assertion will pass
+   * assertThat(values).startsWith(new Double[] { 1.01, 2.01 }, withPrecision(0.1));
+   *
+   * // assertions will fail
+   * assertThat(values).startsWith(new Double[] { 2.0, 1.0 }, withPrecision(0.1))
+   * assertThat(values).startsWith(new Double[] { 1.1, 2.1 }, withPrecision(0.5))
+ * + * @param values the sequence of values to look for. + * @param precision the precision under which the values may vary. + * @return {@code this} assertion object. + * @throws NullPointerException if the given argument is {@code null}. + * @throws IllegalArgumentException if the given argument is an empty array. + * @throws AssertionError if the actual array is {@code null}. + * @throws AssertionError if the actual array does not end with the given sequence. + * @since 3.19.0 + */ + public SELF startsWith(Double[] values, Offset precision) { + return usingComparatorWithPrecision(precision.value).startsWith(toPrimitiveDoubleArray(values)); + } + /** * Verifies that the actual array ends with the given sequence of values, without any other values between them. * Similar to {@link #containsSequence(double...)}, but it also verifies that the last element in the @@ -807,6 +1183,32 @@ public SELF endsWith(double... sequence) { return myself; } + /** + * Verifies that the actual array ends with the given sequence of values, without any other values between them. + * Similar to {@link #containsSequence(Double[])}, but it also verifies that the last element in the + * sequence is also last element of the actual array. + *

+ * Example: + *

 // assertion will pass
+   * assertThat(new double[] { 1.0, 2.0, 2.0, 1.0 }).endsWith(new Double[] { 2.0, 1.0 });
+   *
+   * // assertion will fail
+   * assertThat(new double[] { 1.0, 2.0, 2.0, 1.0 }).endsWith(new Double[] { 1.0, 2.0 });
+ * + * @param sequence the sequence of values to look for. + * @return myself assertion object. + * @throws NullPointerException if the given argument is {@code null}. + * @throws IllegalArgumentException if the given argument is an empty array. + * @throws AssertionError if the actual array is {@code null}. + * @throws AssertionError if the actual array does not end with the given sequence. + * @since 3.19.0 + */ + public SELF endsWith(Double[] sequence) { + requireNonNullParameter(sequence, "sequence"); + arrays.assertEndsWith(info, actual, toPrimitiveDoubleArray(sequence)); + return myself; + } + /** * Verifies that the actual array ends with the given sequence of values, without any other values between them. * Similar to {@link #containsSequence(double...)}, but it also verifies that the last element in the @@ -836,6 +1238,36 @@ public SELF endsWith(double[] values, Offset precision) { return usingComparatorWithPrecision(precision.value).endsWith(values); } + /** + * Verifies that the actual array ends with the given sequence of values, without any other values between them. + * Similar to {@link #containsSequence(double...)}, but it also verifies that the last element in the + * sequence is also last element of the actual array. + *

+ * The comparison is done at the given precision/offset set with {@link Assertions#withPrecision(Double)}. + *

+ * Example: + *

 double[] values = new double[] { 1.0, 2.0, 3.0 };
+   *
+   * // assertion will pass
+   * assertThat(values).endsWith(new Double[] { 2.01, 3.01 }, withPrecision(0.1));
+   *
+   * // assertion will fail
+   * assertThat(values).endsWith(new Double[] { 3.0, 2.0 }, withPrecision(0.1))
+   * assertThat(values).endsWith(new Double[] { 2.1, 3.1 }, withPrecision(0.5))
+ * + * @param values the sequence of values to look for. + * @param precision the precision under which the values may vary. + * @return {@code this} assertion object. + * @throws NullPointerException if the given argument is {@code null}. + * @throws IllegalArgumentException if the given argument is an empty array. + * @throws AssertionError if the actual array is {@code null}. + * @throws AssertionError if the actual array does not end with the given sequence. + * @since 3.19.0 + */ + public SELF endsWith(Double[] values, Offset precision) { + return usingComparatorWithPrecision(precision.value).endsWith(toPrimitiveDoubleArray(values)); + } + /** {@inheritDoc} */ @Override public SELF isSorted() { @@ -897,6 +1329,31 @@ public SELF containsExactly(double... values) { return myself; } + /** + * Verifies that the actual group contains only the values of the given array and nothing else, in order. + *

+ * Example : + *

 // assertion will pass
+   * assertThat(new double[] { 1.0, 2.0, 1.0 }).containsExactly(new Double[] { 1.0, 2.0, 1.0 });
+   *
+   * // assertion will fail as actual and expected order differ
+   * assertThat(new double[] { 1.0, 2.0, 1.0 }).containsExactly(new Double[] { 2.0, 1.0, 1.0 });
+ * + * @param values the given values. + * @return {@code this} assertion object. + * @throws NullPointerException if the given argument is {@code null}. + * @throws AssertionError if the actual group is {@code null}. + * @throws AssertionError if the actual group does not contain the given values with same order, i.e. the actual group + * contains some or none of the given values, or the actual group contains more values than the given ones + * or values are the same but the order is not. + * @since 3.19.0 + */ + public SELF containsExactly(Double[] values) { + requireNonNullParameter(values, "values"); + arrays.assertContainsExactly(info, actual, toPrimitiveDoubleArray(values)); + return myself; + } + /** * Verifies that the actual group contains exactly the given values and nothing else, in any order.
*

@@ -923,6 +1380,33 @@ public SELF containsExactlyInAnyOrder(double... values) { return myself; } + /** + * Verifies that the actual group contains exactly the values of the given array and nothing else, in any order.
+ *

+ * Example : + *

 // assertions will pass
+   * assertThat(new double[] { 1.0, 2.0 }).containsExactlyInAnyOrder(new Double[] { 2.0, 1.0 });
+   * assertThat(new double[] { 1.0, 2.0, 1.0 }).containsExactlyInAnyOrder(new Double[] { 1.0, 1.0, 2.0 });
+   *
+   * // assertions will fail
+   * assertThat(new double[] { 1.0, 2.0 }).containsExactlyInAnyOrder(new Double[] { 1.0 });
+   * assertThat(new double[] { 1.0 }).containsExactlyInAnyOrder(new Double[] { 2.0, 1.0 });
+   * assertThat(new double[] { 1.0, 1.0, 2.0 }).containsExactlyInAnyOrder(new Double[] { 2.0, 1.0 });
+ * + * @param values the given values. + * @return {@code this} assertion object. + * @throws NullPointerException if the given argument is {@code null}. + * @throws AssertionError if the actual group is {@code null}. + * @throws AssertionError if the actual group does not contain the given values, i.e. the actual group + * contains some or none of the given values, or the actual group contains more values than the given ones. + * @since 3.19.0 + */ + public SELF containsExactlyInAnyOrder(Double[] values) { + requireNonNullParameter(values, "values"); + arrays.assertContainsExactlyInAnyOrder(info, actual, toPrimitiveDoubleArray(values)); + return myself; + } + /** * Verifies that the actual group contains only the given values and nothing else, in order. * The values may vary with a specified precision. @@ -952,6 +1436,36 @@ public SELF containsExactly(double[] values, Offset precision) { return usingComparatorWithPrecision(precision.value).containsExactly(values); } + /** + * Verifies that the actual group contains only the values of the given array and nothing else, in order. + * The values may vary with a specified precision. + *

+ * Example : + *

 double[] values = new double[] { 1.0, 2.0, 3.0 };
+   *
+   * // assertion will pass
+   * assertThat(values).containsExactly(new Double[] { 1.0, 1.98, 3.01 }, withPrecision(0.05));
+   *
+   * // assertion fails because |1.0 -1.1| > 0.05 (precision).
+   * assertThat(values).containsExactly(new Double[] { 1.1, 2.0, 3.01 }, withPrecision(0.05));
+   *
+   * // assertion will fail as actual and expected order differ
+   * assertThat(values).containsExactly(new Double[] { 1.98, 1.0, 3.01 }, withPrecision(0.05));
+ * + * @param values the given values. + * @param precision the precision under which the values may vary. + * @return {@code this} assertion object. + * @throws NullPointerException if the given argument is {@code null}. + * @throws AssertionError if the actual group is {@code null}. + * @throws AssertionError if the actual group does not contain the given values within the specified precision + * with same order, i.e. the actual group contains some or none of the given values, or the actual group contains + * more values than the given ones or values are the same but the order is not. + * @since 3.19.0 + */ + public SELF containsExactly(Double[] values, Offset precision) { + return usingComparatorWithPrecision(precision.value).containsExactly(toPrimitiveDoubleArray(values)); + } + /** * Create a {@link Double} comparator which compares double at the given precision and pass it to {@link #usingElementComparator(Comparator)}. * All the following assertions will use this comparator to compare double[] elements. @@ -994,4 +1508,36 @@ public SELF containsAnyOf(double... values) { return myself; } + /** + * Verifies that the actual array contains at least one of the values of the given array. + *

+ * Example : + *


+   *
+   * // assertions will pass
+   * assertThat(new double[] { 1.0, 1.0, 1.0 }).containsAnyOf(new Double[] { 1.0 })
+   * assertThat(new double[] { 1.0, 1.0, 1.0 }).containsAnyOf(new Double[] { 2.0, 2.0, 2.0, 1.0 });
+   *
+   * // assertions will fail
+   * assertThat(new double[] { 1.0, 2.0, 3.0 }).containsAnyOf(new Double[] { 8.0 });
+   * assertThat(new double[] { 1.0, 2.0, 3.0 }).containsAnyOf(new Double[] { 12.0, 11.0, 15.0 };
+ * + * @param values the values whose at least one which is expected to be in the array under test. + * @return {@code this} assertion object. + * @throws NullPointerException if the array of values is {@code null}. + * @throws IllegalArgumentException if the array of values is empty and the array under test is not empty. + * @throws AssertionError if the array under test is {@code null}. + * @throws AssertionError if the array under test does not contain any of the given {@code values}. + * @since 3.19.0 + */ + public SELF containsAnyOf(Double[] values) { + requireNonNullParameter(values, "values"); + arrays.assertContainsAnyOf(info, actual, toPrimitiveDoubleArray(values)); + return myself; + } + + private static double[] toPrimitiveDoubleArray(Double[] values) { + return Arrays.stream(values).mapToDouble(Double::doubleValue).toArray(); + } + } diff --git a/src/main/java/org/assertj/core/api/AbstractDoubleAssert.java b/src/main/java/org/assertj/core/api/AbstractDoubleAssert.java index d298abfea48..8d705dbda51 100644 --- a/src/main/java/org/assertj/core/api/AbstractDoubleAssert.java +++ b/src/main/java/org/assertj/core/api/AbstractDoubleAssert.java @@ -8,7 +8,7 @@ * 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-2020 the original author or authors. + * Copyright 2012-2021 the original author or authors. */ package org.assertj.core.api; @@ -53,7 +53,7 @@ public abstract class AbstractDoubleAssert selfType) { + protected AbstractDoubleAssert(Double actual, Class selfType) { super(actual, selfType); this.isPrimitive = false; } @@ -855,4 +855,50 @@ private boolean noCustomComparatorSet() { return doubles.getComparator() == null; } + /** + * Verifies that the double value is a finite floating-point value. + *

+ * Examples: + *

 // assertion succeeds
+   * assertThat(1.0d).isFinite();
+   *
+   * // assertions fail
+   * assertThat(Double.NaN).isFinite();
+   * assertThat(Double.NEGATIVE_INFINITY).isFinite();
+   * assertThat(Double.POSITIVE_INFINITY).isFinite();
+ * + * @return this assertion object. + * @throws AssertionError if the actual value is not a finite floating-point value. + * @throws AssertionError if the actual value is null. + * @see #isInfinite() + * @since 3.19.0 + */ + @Override + public SELF isFinite() { + doubles.assertIsFinite(info, actual); + return myself; + } + + /** + * Verifies that the double value represents positive infinity or negative infinity. + *

+ * Examples: + *

 // assertions succeed
+   * assertThat(Double.NEGATIVE_INFINITY).isInfinite();
+   * assertThat(Double.POSITIVE_INFINITY).isInfinite();
+   *
+   * // assertions fail
+   * assertThat(1.0d).isInfinite();
+   * assertThat(Double.NaN).isInfinite();
+ * + * @return this assertion object. + * @throws AssertionError if the actual value doesn't represent the positive infinity nor negative infinity. + * @throws AssertionError if the actual value is null. + * @since 3.19.0 + */ + @Override + public SELF isInfinite() { + doubles.assertIsInfinite(info, actual); + return myself; + } } diff --git a/src/main/java/org/assertj/core/api/AbstractDurationAssert.java b/src/main/java/org/assertj/core/api/AbstractDurationAssert.java index dea9c9b811c..2be87f72dbe 100644 --- a/src/main/java/org/assertj/core/api/AbstractDurationAssert.java +++ b/src/main/java/org/assertj/core/api/AbstractDurationAssert.java @@ -8,20 +8,23 @@ * 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-2020 the original author or authors. + * Copyright 2012-2021 the original author or authors. */ package org.assertj.core.api; +import static org.assertj.core.error.ShouldBeCloseTo.shouldBeCloseTo; import static org.assertj.core.error.ShouldHaveDuration.shouldHaveDays; import static org.assertj.core.error.ShouldHaveDuration.shouldHaveHours; import static org.assertj.core.error.ShouldHaveDuration.shouldHaveMillis; import static org.assertj.core.error.ShouldHaveDuration.shouldHaveMinutes; import static org.assertj.core.error.ShouldHaveDuration.shouldHaveNanos; import static org.assertj.core.error.ShouldHaveDuration.shouldHaveSeconds; +import static org.assertj.core.util.Preconditions.checkArgument; import java.time.Duration; import org.assertj.core.internal.Failures; +import org.assertj.core.internal.Objects; /** * Assertions for {@link Duration} type. @@ -36,7 +39,7 @@ public abstract class AbstractDurationAssert selfType) { + protected AbstractDurationAssert(Duration duration, Class selfType) { super(duration, selfType); } @@ -248,4 +251,53 @@ public SELF hasDays(long otherDays) { } return myself; } + + /** + * Verifies that the actual {@link Duration} is close to the given one within the given allowed difference (assertion succeeds if difference = allowed difference). + *

+ * This is equivalent of: {@code abs(actual - expected) <= allowed difference}. + *

+ * For readability you can use {@link Assertions#withMarginOf(Duration)} to express the allowed difference. + *

+ * Examples: + *

 Duration twoMinutes = Duration.ofMinutes(2);
+   * // assertions succeed:
+   * assertThat(twoMinutes).isCloseTo(Duration.ofMinutes(3), Duration.ofMinutes(5));
+   * assertThat(twoMinutes).isCloseTo(Duration.ofMinutes(-3), Duration.ofMinutes(10));
+   *
+   * // assertion succeeds when difference is exactly equals to the allowed difference
+   * assertThat(twoMinutes).isCloseTo(Duration.ofMinutes(3), Duration.ofMinutes(1));
+   * assertThat(twoMinutes).isCloseTo(Duration.ofMinutes(-3), Duration.ofMinutes(5));
+   *
+   * // assertions using within syntactic sugar
+   * assertThat(twoMinutes).isCloseTo(Duration.ofMinutes(3), withMarginOf(Duration.ofMinutes(5)));
+   * assertThat(twoMinutes).isCloseTo(Duration.ofMinutes(3), withMarginOf(Duration.ofMinutes(1)));
+   *
+   * // assertions fail
+   * assertThat(twoMinutes).isCloseTo(Duration.ofMinutes(5), withMarginOf(Duration.ofMinutes(1)));
+   * assertThat(twoMinutes).isCloseTo(Duration.ofMinutes(-3), withMarginOf(Duration.ofMinutes(4)));
+ * + * @param expected the given {@link Duration} to compare to actual. + * @param allowedDifference a positive {@link Duration} to express the maximum allowed difference. + * @return {@code this} assertion object. + * @throws IllegalArgumentException if the expected Duration is {@code null}. + * @throws IllegalArgumentException if the allowed difference Duration is {@code null} or negative. + * @throws AssertionError if the actual value is not close enough to the given one. + * @since 3.18.0 + */ + public SELF isCloseTo(Duration expected, Duration allowedDifference) { + Objects.instance().assertNotNull(info, actual); + checkArgument(expected != null, "expected duration should not be null"); + checkArgument(allowedDifference != null, "allowed difference duration should not be null"); + checkArgument(!allowedDifference.isNegative(), "allowed difference duration should be >= 0"); + if (absDiff(actual, expected).compareTo(allowedDifference) > 0) { + throw Failures.instance().failure(info, shouldBeCloseTo(actual, expected, allowedDifference, absDiff(actual, expected))); + } + return myself; + } + + private static Duration absDiff(Duration actual, Duration expected) { + return actual.minus(expected).abs(); + } + } diff --git a/src/main/java/org/assertj/core/api/AbstractEnumerableAssert.java b/src/main/java/org/assertj/core/api/AbstractEnumerableAssert.java index 2fe35159733..0803224bdb6 100644 --- a/src/main/java/org/assertj/core/api/AbstractEnumerableAssert.java +++ b/src/main/java/org/assertj/core/api/AbstractEnumerableAssert.java @@ -8,7 +8,7 @@ * 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-2020 the original author or authors. + * Copyright 2012-2021 the original author or authors. */ package org.assertj.core.api; @@ -26,8 +26,12 @@ * @author Joel Costigliola */ public abstract class AbstractEnumerableAssert, ACTUAL, ELEMENT> - extends AbstractAssert - implements EnumerableAssert, ELEMENT> { + extends AbstractAssert + implements EnumerableAssert, ELEMENT> { + + protected AbstractEnumerableAssert(final ACTUAL actual, final Class selfType) { + super(actual, selfType); + } /** * {@inheritDoc} @@ -49,10 +53,6 @@ public SELF hasSameSizeAs(Object other) { return myself; } - public AbstractEnumerableAssert(final ACTUAL actual, final Class selfType) { - super(actual, selfType); - } - /** * Enable hexadecimal object representation of Iterable elements instead of standard java representation in error messages. *

diff --git a/src/main/java/org/assertj/core/api/AbstractFileAssert.java b/src/main/java/org/assertj/core/api/AbstractFileAssert.java index 3beee2b3e92..762bcbec05b 100644 --- a/src/main/java/org/assertj/core/api/AbstractFileAssert.java +++ b/src/main/java/org/assertj/core/api/AbstractFileAssert.java @@ -8,7 +8,7 @@ * 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-2020 the original author or authors. + * Copyright 2012-2021 the original author or authors. */ package org.assertj.core.api; @@ -51,7 +51,7 @@ public abstract class AbstractFileAssert> @VisibleForTesting Charset charset = Charset.defaultCharset(); - public AbstractFileAssert(File actual, Class selfType) { + protected AbstractFileAssert(File actual, Class selfType) { super(actual, selfType); } diff --git a/src/main/java/org/assertj/core/api/AbstractFloatArrayAssert.java b/src/main/java/org/assertj/core/api/AbstractFloatArrayAssert.java index c5dac9adf36..91b04eec419 100644 --- a/src/main/java/org/assertj/core/api/AbstractFloatArrayAssert.java +++ b/src/main/java/org/assertj/core/api/AbstractFloatArrayAssert.java @@ -8,10 +8,12 @@ * 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-2020 the original author or authors. + * Copyright 2012-2021 the original author or authors. */ package org.assertj.core.api; +import static java.util.stream.IntStream.range; + import java.util.Comparator; import org.assertj.core.data.Index; @@ -27,7 +29,7 @@ public abstract class AbstractFloatArrayAssert selfType) { + protected AbstractFloatArrayAssert(float[] actual, Class selfType) { super(actual, selfType); } @@ -223,6 +225,32 @@ public SELF contains(float... values) { return myself; } + /** + * Verifies that the actual array contains the values of the given array, in any order. + *

+ * Example: + *

 // assertion will pass
+   * assertThat(new float[] { 1.0f, 2.0f }).contains(new Float[] { 1.0f, 2.0f });
+   * assertThat(new float[] { 1.0f, 2.0f }).contains(new Float[] { 1.0f, 2.0f });
+   * assertThat(new float[] { 1.0f, 2.0f }).contains(new Float[] { 1.0f });
+   *
+   * // assertion will fail
+   * assertThat(new float[] { 1.0f, 2.0f }).contains(new Float[] { 3.0f });
+ * + * @param values the given values. + * @return {@code this} assertion object. + * @throws NullPointerException if the given argument is {@code null}. + * @throws IllegalArgumentException if the given argument is an empty array. + * @throws AssertionError if the actual array is {@code null}. + * @throws AssertionError if the actual array does not contain the given values. + * @since 3.19.0 + */ + public SELF contains(Float[] values) { + requireNonNullParameter(values, "values"); + arrays.assertContains(info, actual, toPrimitiveFloatArray(values)); + return myself; + } + /** * Verifies that the actual array contains the given values, in any order, * the comparison is done at the given precision/offset set with {@link Assertions#withPrecision(Float)}. @@ -231,11 +259,11 @@ public SELF contains(float... values) { *
 float[] values = new float[] {1.0f, 2.0f, 3.0f};
    *
    * // assertion will pass
-   * assertThat(values).contains(new float[] {1.01f, 3.01f, 2.0f}, withPrecision(0.02f));
+   * assertThat(values).contains(new float[] { 1.01f, 3.01f, 2.0f }, withPrecision(0.02f));
    *
    * // assertions will fail
-   * assertThat(values).contains(new float[] {1.0f, 4.0f}, withPrecision(0.5f));
-   * assertThat(values).contains(new float[] {4.0f, 7.0f}, withPrecision(2f));
+ * assertThat(values).contains(new float[] { 1.0f, 4.0f }, withPrecision(0.5f)); + * assertThat(values).contains(new float[] { 4.0f, 7.0f }, withPrecision(2f));
* * @param values the given values. * @param precision the precision under which the values may vary. @@ -249,6 +277,33 @@ public SELF contains(float[] values, Offset precision) { return usingComparatorWithPrecision(precision.value).contains(values); } + /** + * Verifies that the actual array contains the values of the given array, in any order, + * the comparison is done at the given precision/offset set with {@link Assertions#withPrecision(Float)}. + *

+ * Examples : + *

 float[] values = new float[] { 1.0f, 2.0f, 3.0f };
+   *
+   * // assertion will pass
+   * assertThat(values).contains(new Float[] { 1.01f, 3.01f, 2.0f }, withPrecision(0.02f));
+   *
+   * // assertions will fail
+   * assertThat(values).contains(new Float[] { 1.0f, 4.0f }, withPrecision(0.5f));
+   * assertThat(values).contains(new Float[] { 4.0f, 7.0f }, withPrecision(2f));
+ * + * @param values the given values. + * @param precision the precision under which the values may vary. + * @return {@code this} assertion object. + * @throws NullPointerException if the given argument is {@code null}. + * @throws IllegalArgumentException if the given argument is an empty array. + * @throws AssertionError if the actual array is {@code null}. + * @throws AssertionError if the actual array does not contain the given values. + * @since 3.19.0 + */ + public SELF contains(Float[] values, Offset precision) { + return usingComparatorWithPrecision(precision.value).contains(toPrimitiveFloatArray(values)); + } + /** * Verifies that the actual array contains only the given values and nothing else, in any order. *

@@ -284,6 +339,34 @@ public SELF containsOnly(float... values) { return myself; } + /** + * Verifies that the actual array contains only the values of the given array and nothing else, in any order. + *

+ * Example: + *

 // assertions will pass
+   * assertThat(new float[] { 1.0f, 2.0f }).containsOnly(new Float[] { 1.0f, 2.0f });
+   * assertThat(new float[] { 2.0f, 1.0f }).containsOnly(new Float[] { 1.0f, 2.0f });
+   * assertThat(new float[] { 1.0f, 1.0f, 2.0f }).containsOnly(new Float[] { 1.0f, 2.0f });
+   *
+   * // assertions will fail
+   * assertThat(new float[] { 1.0f, 2.0f }).containsOnly(new Float[] { 2.0f });
+   * assertThat(new float[] { 1.0f }).containsOnly(new Float[] { 1.0f, 2.0f });
+ * + * @param values the given values. + * @return {@code this} assertion object. + * @throws NullPointerException if the given argument is {@code null}. + * @throws IllegalArgumentException if the given argument is an empty array. + * @throws AssertionError if the actual array is {@code null}. + * @throws AssertionError if the actual array does not contain the given values, i.e. the actual array contains some + * or none of the given values, or the actual array contains more values than the given ones. + * @since 3.19.0 + */ + public SELF containsOnly(Float[] values) { + requireNonNullParameter(values, "values"); + arrays.assertContainsOnly(info, actual, toPrimitiveFloatArray(values)); + return myself; + } + /** * Verifies that the actual array contains only the given values and nothing else, in any order. * The comparison is done at the given precision/offset set with {@link Assertions#withPrecision(Float)}. @@ -312,6 +395,35 @@ public SELF containsOnly(float[] values, Offset precision) { return usingComparatorWithPrecision(precision.value).containsOnly(values); } + /** + * Verifies that the actual array contains only the values of the given array and nothing else, in any order. + * The comparison is done at the given precision/offset set with {@link Assertions#withPrecision(Float)}. + *

+ * Examples : + *

 float[] values = new float[] { 1.0f, 2.0f, 3.0f };
+   *
+   * // assertion will pass
+   * assertThat(values).containsOnly(new Float[] { 1.0f, 2.0f, 3.0f }, withPrecision(0.00001f))
+   *                   .containsOnly(new Float[] { 2.0,f 3.0f, 0.7f }, withPrecision(0.5f));
+   *
+   * // assertions will fail
+   * assertThat(values).containsOnly(new Float[] { 1.0f, 4.0f, 2.0f, 3.0f }, withPrecision(0.5f));
+   * assertThat(values).containsOnly(new Float[] { 4.0f, 7.0f }, withPrecision(0.2f));
+ * + * @param values the given values. + * @param precision the precision under which the values may vary. + * @return {@code this} assertion object. + * @throws NullPointerException if the given argument is {@code null}. + * @throws IllegalArgumentException if the given argument is an empty array. + * @throws AssertionError if the actual array is {@code null}. + * @throws AssertionError if the actual array does not contain the given values, i.e. the actual array contains some + * or none of the given values, or the actual array contains more values than the given ones. + * @since 3.19.0 + */ + public SELF containsOnly(Float[] values, Offset precision) { + return usingComparatorWithPrecision(precision.value).containsOnly(toPrimitiveFloatArray(values)); + } + /** * Verifies that the actual array contains the given values only once. *

@@ -344,6 +456,33 @@ public SELF containsOnlyOnce(float... values) { return myself; } + /** + * Verifies that the actual array contains the values of the given array only once. + *

+ * Examples : + *

 // assertion will pass
+   * assertThat(new float[] { 1.0f, 2.0f }).containsOnlyOnce(new Float[] { 1.0f, 2.0f });
+   *
+   * // assertions will fail
+   * assertThat(new float[] { 1.0f, 2.0f, 1.0f }).containsOnlyOnce(new Float[] { 1.0f });
+   * assertThat(new float[] { 1.0f }).containsOnlyOnce(new Float[] { 2.0f });
+   * assertThat(new float[] { 1.0f }).containsOnlyOnce(new Float[] { 1.0f, 2.0f });
+ * + * @param values the given values. + * @return {@code this} assertion object. + * @throws NullPointerException if the given argument is {@code null}. + * @throws IllegalArgumentException if the given argument is an empty array. + * @throws AssertionError if the actual array is {@code null}. + * @throws AssertionError if the actual group does not contain the given values, i.e. the actual group contains some + * or none of the given values, or the actual group contains more than once these values. + * @since 3.19.0 + */ + public SELF containsOnlyOnce(Float[] values) { + requireNonNullParameter(values, "values"); + arrays.assertContainsOnlyOnce(info, actual, toPrimitiveFloatArray(values)); + return myself; + } + /** * Verifies that the actual array contains the given values only once. * The comparison is done at the given precision/offset set with {@link Assertions#withPrecision(Float)}. @@ -370,6 +509,33 @@ public SELF containsOnlyOnce(float[] values, Offset precision) { return usingComparatorWithPrecision(precision.value).containsOnlyOnce(values); } + /** + * Verifies that the actual array contains the values of the given array only once. + * The comparison is done at the given precision/offset set with {@link Assertions#withPrecision(Float)}. + *

+ * Examples : + *

 // assertion will pass
+   * assertThat(new float[] { 1.0f, 2.0f, 3.0f }).containsOnlyOnce(new Float[] { 1.1f, 2.0f }, withPrecision(0.2f));
+   *
+   * // assertions will fail
+   * assertThat(new float[] { 1.0f, 2.0f, 1.0f }).containsOnlyOnce(new Float[] { 1.05f }, withPrecision(0.1f));
+   * assertThat(new float[] { 1.0f, 2.0f, 3.0f }).containsOnlyOnce(new Float[] { 4.0f }, withPrecision(0.1f));
+   * assertThat(new float[] { 1.0f, 2.0f, 3.0f, 3.0f }).containsOnlyOnce(new Float[] { 0.1f, 0.9f, 2.0f, 3.11f, 4.0f, 5.0f }, withPrecision(0.2f));
+ * + * @param values the given values. + * @param precision the precision under which the values may vary. + * @return {@code this} assertion object. + * @throws NullPointerException if the given argument is {@code null}. + * @throws IllegalArgumentException if the given argument is an empty array. + * @throws AssertionError if the actual array is {@code null}. + * @throws AssertionError if the actual group does not contain the given values, i.e. the actual group contains some + * or none of the given values, or the actual group contains more than once these values. + * @since 3.19.0 + */ + public SELF containsOnlyOnce(Float[] values, Offset precision) { + return usingComparatorWithPrecision(precision.value).containsOnlyOnce(toPrimitiveFloatArray(values)); + } + /** * Verifies that the actual array contains the given sequence, without any other values between them. *

@@ -403,6 +569,30 @@ public SELF containsSequence(float... sequence) { return myself; } + /** + * Verifies that the actual array contains the given sequence, without any other values between them. + *

+ * Example: + *

 // assertion will pass
+   * assertThat(new float[] { 1.0f, 2.0f }).containsSequence(new Float[] { 1.0f, 2.0f });
+   * assertThat(new float[] { 1.0f, 2.0f, 2.0f, 1.0f }).containsSequence(new Float[] { 2.0f, 1.0f });
+   *
+   * // assertion will fail
+   * assertThat(new float[] { 1.0f, 2.0f, 3.0f }).containsSequence(new Float[] { 3.0f, 1.0f });
+ * + * @param sequence the sequence of values to look for. + * @return myself assertion object. + * @throws AssertionError if the actual array is {@code null}. + * @throws AssertionError if the given array is {@code null}. + * @throws AssertionError if the actual array does not contain the given sequence. + * @since 3.19.0 + */ + public SELF containsSequence(Float[] sequence) { + requireNonNullParameter(sequence, "sequence"); + arrays.assertContainsSequence(info, actual, toPrimitiveFloatArray(sequence)); + return myself; + } + /** * Verifies that the actual array contains the given sequence, without any other values between them. * The comparison is done at the given precision/offset set with {@link Assertions#withPrecision(Float)}. @@ -430,6 +620,34 @@ public SELF containsSequence(float[] sequence, Offset precision) { return usingComparatorWithPrecision(precision.value).containsSequence(sequence); } + /** + * Verifies that the actual array contains the given sequence, without any other values between them. + * The comparison is done at the given precision/offset set with {@link Assertions#withPrecision(Float)}. + *

+ * Examples : + *

 float[] values = new float[] { 1.0f, 2.0f, 3.0f };
+   *
+   * // assertions will pass
+   * assertThat(values).containsSequence(new Float[] { 1.07f, 2.0f }, withPrecision(0.1f))
+   *                   .containsSequence(new Float[] { 1.1f, 2.1f, 3.0f }, withPrecision(0.2f))
+   *                   .containsSequence(new Float[] { 2.2f, 3.0f }, withPrecision(0.3f));
+   *
+   * // assertions will fail
+   * assertThat(values).containsSequence(new Float[] { 1.0f, 3.0f }, withPrecision(0.2f));
+   * assertThat(values).containsSequence(new Float[] { 4.0f, 7.0f }, withPrecision(0.1f));
+ * + * @param sequence the sequence of values to look for. + * @param precision the precision under which the values may vary. + * @return {@code this} assertion object. + * @throws AssertionError if the actual array is {@code null}. + * @throws AssertionError if the given array is {@code null}. + * @throws AssertionError if the actual array does not contain the given sequence. + * @since 3.19.0 + */ + public SELF containsSequence(Float[] sequence, Offset precision) { + return usingComparatorWithPrecision(precision.value).containsSequence(toPrimitiveFloatArray(sequence)); + } + /** * Verifies that the actual array contains the given subsequence (possibly with other values between them). *

@@ -463,6 +681,30 @@ public SELF containsSubsequence(float... subsequence) { return myself; } + /** + * Verifies that the actual array contains the given subsequence (possibly with other values between them). + *

+ * Example: + *

 // assertion will pass
+   * assertThat(new float[] { 1.0f, 2.0f }).containsSubsequence(new Float[] { 1.0f, 2.0f });
+   * assertThat(new float[] { 1.0f, 2.0f, 3.0f, 4.0f }).containsSubsequence(new Float[] { 1.0f, 4.0f });
+   *
+   * // assertion will fail
+   * assertThat(new float[] { 1.0f, 2.0f, 3.0f }).containsSubsequence(new Float[] { 3.0f, 1.0f });
+ * + * @param subsequence the subsequence of values to look for. + * @return myself assertion object. + * @throws AssertionError if the actual array is {@code null}. + * @throws AssertionError if the given array is {@code null}. + * @throws AssertionError if the actual array does not contain the given subsequence. + * @since 3.19.0 + */ + public SELF containsSubsequence(Float[] subsequence) { + requireNonNullParameter(subsequence, "subsequence"); + arrays.assertContainsSubsequence(info, actual, toPrimitiveFloatArray(subsequence)); + return myself; + } + /** * Verifies that the actual array contains the given subsequence (possibly with other values between them). * The comparison is done at the given precision/offset set with {@link Assertions#withPrecision(Float)}. @@ -490,6 +732,34 @@ public SELF containsSubsequence(float[] subsequence, Offset precision) { return usingComparatorWithPrecision(precision.value).containsSubsequence(subsequence); } + /** + * Verifies that the actual array contains the given subsequence (possibly with other values between them). + * The comparison is done at the given precision/offset set with {@link Assertions#withPrecision(Float)}. + *

+ * Examples : + *

 float[] values = new float[] { 1.0f, 2.0f, 3.0f };
+   *
+   * // assertions will pass
+   * assertThat(values).containsSubsequence(new Float[] { 1.0f, 2.0f }, withPrecision(0.1f))
+   *                   .containsSubsequence(new Float[] { 1.0f, 2.07f, 3.0f }, withPrecision(0.1f))
+   *                   .containsSubsequence(new Float[] { 2.1f, 2.9f }, withPrecision(0.2f));
+   *
+   * // assertions will fail
+   * assertThat(values).containsSubsequence(new Float[] { 1.0f, 3.0f }, withPrecision(0.1f));
+   * assertThat(values).containsSubsequence(new Float[] { 4.0f, 7.0f }, withPrecision(0.1f));
+ * + * @param subsequence the subsequence of values to look for. + * @param precision the precision under which the values may vary. + * @return {@code this} assertion object. + * @throws AssertionError if the actual array is {@code null}. + * @throws AssertionError if the given array is {@code null}. + * @throws AssertionError if the actual array does not contain the given subsequence. + * @since 3.19.0 + */ + public SELF containsSubsequence(Float[] subsequence, Offset precision) { + return usingComparatorWithPrecision(precision.value).containsSubsequence(toPrimitiveFloatArray(subsequence)); + } + /** * Verifies that the actual array contains the given value at the given index. *

@@ -585,6 +855,30 @@ public SELF doesNotContain(float... values) { return myself; } + /** + * Verifies that the actual array does not contain the values of the given array. + *

+ * Example: + *

 // assertion will pass
+   * assertThat(new float[] { 1.0f, 2.0f }).doesNotContain(new Float[] { 3.0f });
+   *
+   * // assertion will fail
+   * assertThat(new float[] { 1.0f, 2.0f, 3.0f }).doesNotContain(new Float[] { 1.0f });
+ * + * @param values the given values. + * @return {@code this} assertion object. + * @throws NullPointerException if the given argument is {@code null}. + * @throws IllegalArgumentException if the given argument is an empty array. + * @throws AssertionError if the actual array is {@code null}. + * @throws AssertionError if the actual array contains any of the given values. + * @since 3.19.0 + */ + public SELF doesNotContain(Float[] values) { + requireNonNullParameter(values, "values"); + arrays.assertDoesNotContain(info, actual, toPrimitiveFloatArray(values)); + return myself; + } + /** * Verifies that the actual array does not contain the given values. * The comparison is done at the given precision/offset set with {@link Assertions#withPrecision(Float)}. @@ -610,6 +904,32 @@ public SELF doesNotContain(float[] values, Offset precision) { return usingComparatorWithPrecision(precision.value).doesNotContain(values); } + /** + * Verifies that the actual array does not contain the values of the given array. + * The comparison is done at the given precision/offset set with {@link Assertions#withPrecision(Float)}. + *

+ * Example: + *

 float[] values = new float[] { 1.0f, 2.0f, 3.0f };
+   *
+   * // assertion will pass
+   * assertThat(values).doesNotContain(new Float[] { 4.0f, 8.0f }, withPrecision(0.5f));
+   *
+   * // assertion will fail
+   * assertThat(values).doesNotContain(new Float[] { 1.05f, 4.0f, 8.0f }, withPrecision(0.1f));
+ * + * @param values the given values. + * @param precision the precision under which the values may vary. + * @return {@code this} assertion object. + * @throws NullPointerException if the given argument is {@code null}. + * @throws IllegalArgumentException if the given argument is an empty array. + * @throws AssertionError if the actual array is {@code null}. + * @throws AssertionError if the actual array contains any of the given values. + * @since 3.19.0 + */ + public SELF doesNotContain(Float[] values, Offset precision) { + return usingComparatorWithPrecision(precision.value).doesNotContain(toPrimitiveFloatArray(values)); + } + /** * Verifies that the actual array does not contain the given value at the given index. *

@@ -746,6 +1066,32 @@ public SELF startsWith(float... sequence) { return myself; } + /** + * Verifies that the actual array starts with the given sequence of values, without any other values between them. + * Similar to {@link #containsSequence(Float[])}, but it also verifies that the first element in the + * sequence is also first element of the actual array. + *

+ * Example: + *

 // assertion will pass
+   * assertThat(new float[] { 1.0f, 2.0f, 3.0f, 4.0f }).startsWith(new Float[] { 1.0f, 2.0f });
+   *
+   * // assertion will fail
+   * assertThat(new float[] { 1.0f, 2.0f, 3.0f, 4.0f }).startsWith(new Float[] { 2.0f, 3.0f, 4.0f });
+ * + * @param sequence the sequence of values to look for. + * @return myself assertion object. + * @throws NullPointerException if the given argument is {@code null}. + * @throws IllegalArgumentException if the given argument is an empty array. + * @throws AssertionError if the actual array is {@code null}. + * @throws AssertionError if the actual array does not start with the given sequence. + * @since 3.19.0 + */ + public SELF startsWith(Float[] sequence) { + requireNonNullParameter(sequence, "sequence"); + arrays.assertStartsWith(info, actual, toPrimitiveFloatArray(sequence)); + return myself; + } + /** * Verifies that the actual array starts with the given sequence of values, without any other values between them. * Similar to {@link #containsSequence(float...)}, but it also verifies that the first element in the @@ -775,6 +1121,36 @@ public SELF startsWith(float[] values, Offset precision) { return usingComparatorWithPrecision(precision.value).startsWith(values); } + /** + * Verifies that the actual array starts with the given sequence of values, without any other values between them. + * Similar to {@link #containsSequence(float...)}, but it also verifies that the first element in the + * sequence is also first element of the actual array. + *

+ * The comparison is done at the given precision/offset set with {@link Assertions#withPrecision(Float)}. + *

+ * Example: + *

 float[] values = new float[] { 1.0f, 2.0f, 3.0f };
+   *
+   * // assertion will pass
+   * assertThat(values).startsWith(new Float[] { 1.01f, 2.01f }, withPrecision(0.1f));
+   *
+   * // assertions will fail
+   * assertThat(values).startsWith(new Float[] { 2.0f, 1.0f }, withPrecision(0.1f))
+   * assertThat(values).startsWith(new Float[] { 1.1f, 2.1f }, withPrecision(0.5f))
+ * + * @param values the sequence of values to look for. + * @param precision the precision under which the values may vary. + * @return {@code this} assertion object. + * @throws NullPointerException if the given argument is {@code null}. + * @throws IllegalArgumentException if the given argument is an empty array. + * @throws AssertionError if the actual array is {@code null}. + * @throws AssertionError if the actual array does not end with the given sequence. + * @since 3.19.0 + */ + public SELF startsWith(Float[] values, Offset precision) { + return usingComparatorWithPrecision(precision.value).startsWith(toPrimitiveFloatArray(values)); + } + /** * Verifies that the actual array ends with the given sequence of values, without any other values between them. * Similar to {@link #containsSequence(float...)}, but it also verifies that the last element in the @@ -806,6 +1182,32 @@ public SELF endsWith(float... sequence) { return myself; } + /** + * Verifies that the actual array ends with the given sequence of values, without any other values between them. + * Similar to {@link #containsSequence(Float[])}, but it also verifies that the last element in the + * sequence is also last element of the actual array. + *

+ * Example: + *

 // assertion will pass
+   * assertThat(new boolean[] { 1.0f, 2.0f, 3.0f, 4.0f }).endsWith(new Float[] { 3.0f, 4.0f });
+   *
+   * // assertion will fail
+   * assertThat(new boolean[] { 1.0f, 2.0f, 3.0f, 4.0f }).endsWith(new Float[] { 2.0f, 3.0f });
+ * + * @param sequence the sequence of values to look for. + * @return myself assertion object. + * @throws NullPointerException if the given argument is {@code null}. + * @throws IllegalArgumentException if the given argument is an empty array. + * @throws AssertionError if the actual array is {@code null}. + * @throws AssertionError if the actual array does not end with the given sequence. + * @since 3.19.0 + */ + public SELF endsWith(Float[] sequence) { + requireNonNullParameter(sequence, "sequence"); + arrays.assertEndsWith(info, actual, toPrimitiveFloatArray(sequence)); + return myself; + } + /** * Verifies that the actual array ends with the given sequence of values, without any other values between them. * Similar to {@link #containsSequence(float...)}, but it also verifies that the last element in the @@ -835,6 +1237,36 @@ public SELF endsWith(float[] values, Offset precision) { return usingComparatorWithPrecision(precision.value).endsWith(values); } + /** + * Verifies that the actual array ends with the given sequence of values, without any other values between them. + * Similar to {@link #containsSequence(float...)}, but it also verifies that the last element in the + * sequence is also last element of the actual array. + *

+ * The comparison is done at the given precision/offset set with {@link Assertions#withPrecision(Float)}. + *

+ * Example: + *

 float[] values = new float[] { 1.0f, 2.0f, 3.0f };
+   *
+   * // assertion will pass
+   * assertThat(values).endsWith(new Float[] { 2.01f, 3.01f }, withPrecision(0.1f));
+   *
+   * // assertions will fail
+   * assertThat(values).endsWith(new Float[] { 3.0f, 2.0f }, withPrecision(0.1f))
+   * assertThat(values).endsWith(new Float[] { 2.1f, 3.1f }, withPrecision(0.5f))
+ * + * @param values the sequence of values to look for. + * @param precision the precision under which the values may vary. + * @return {@code this} assertion object. + * @throws NullPointerException if the given argument is {@code null}. + * @throws IllegalArgumentException if the given argument is an empty array. + * @throws AssertionError if the actual array is {@code null}. + * @throws AssertionError if the actual array does not end with the given sequence. + * @since 3.19.0 + */ + public SELF endsWith(Float[] values, Offset precision) { + return usingComparatorWithPrecision(precision.value).endsWith(toPrimitiveFloatArray(values)); + } + /** {@inheritDoc} */ @Override public SELF isSorted() { @@ -895,6 +1327,31 @@ public SELF containsExactly(float... values) { return myself; } + /** + * Verifies that the actual group contains only the values of the given array and nothing else, in order. + *

+ * Example : + *

 // assertion will pass
+   * assertThat(new float[] { 1.0f, 2.0f, 3.0f, 4.0f }).containsExactly(new Float[] { 1.0f, 2.0f, 3.0f, 4.0f });
+   *
+   * // assertion will fail as actual and expected order differ
+   * assertThat(new float[] { 1.0f, 2.0f, 3.0f, 4.0f }).containsExactly(new Float[] { 1.0f, 5.0f });
+ * + * @param values the given values. + * @return {@code this} assertion object. + * @throws NullPointerException if the given argument is {@code null}. + * @throws AssertionError if the actual group is {@code null}. + * @throws AssertionError if the actual group does not contain the given values with same order, i.e. the actual group + * contains some or none of the given values, or the actual group contains more values than the given ones + * or values are the same but the order is not. + * @since 3.19.0 + */ + public SELF containsExactly(Float[] values) { + requireNonNullParameter(values, "values"); + arrays.assertContainsExactly(info, actual, toPrimitiveFloatArray(values)); + return myself; + } + /** * Verifies that the actual group contains only the given values and nothing else, in order. * The values may vary with a specified precision. @@ -924,6 +1381,36 @@ public SELF containsExactly(float[] values, Offset precision) { return usingComparatorWithPrecision(precision.value).containsExactly(values); } + /** + * Verifies that the actual group contains only the values of the given array and nothing else, in order. + * The values may vary with a specified precision. + *

+ * Example : + *

 float[] values = new float[] { 1.0f, 2.0f, 3.0f };
+   *
+   * // assertion will pass
+   * assertThat(values).containsExactly(new Float[] { 1.0f, 1.98f, 3.01f }, withPrecision(0.05f));
+   *
+   * // assertion fails because |1.0 - 1.1| > 0.05 (precision)
+   * assertThat(values).containsExactly(new Float[] { 1.1f, 2.0f, 3.01f }, withPrecision(0.05f));
+   *
+   * // assertion will fail as actual and expected order differ
+   * assertThat(values).containsExactly(new Float[] { 1.98f, 1.0f, 3.01f }, withPrecision(0.05f));
+ * + * @param values the given values. + * @param precision the precision under which the values may vary. + * @return {@code this} assertion object. + * @throws NullPointerException if the given argument is {@code null}. + * @throws AssertionError if the actual group is {@code null}. + * @throws AssertionError if the actual group does not contain the given values within the specified precision + * with same order, i.e. the actual group contains some or none of the given values, or the actual group contains + * more values than the given ones or values are the same but the order is not. + * @since 3.19.0 + */ + public SELF containsExactly(Float[] values, Offset precision) { + return usingComparatorWithPrecision(precision.value).containsExactly(toPrimitiveFloatArray(values)); + } + /** * Verifies that the actual group contains exactly the given values and nothing else, in any order.
*

@@ -950,6 +1437,33 @@ public SELF containsExactlyInAnyOrder(float... values) { return myself; } + /** + * Verifies that the actual group contains exactly the values of the given array and nothing else, in any order.
+ *

+ * Example : + *

 // assertions will pass
+   * assertThat(new float[] { 1.0f, 2.0f }).containsExactlyInAnyOrder(new Float[] { 2.0f, 1.0f });
+   * assertThat(new float[] { 1.0f, 2.0f, 3.0f }).containsExactlyInAnyOrder(new Float[] { 3.0f, 1.0f, 2.0f });
+   *
+   * // assertions will fail
+   * assertThat(new float[] { 1.0f, 2.0f }).containsExactlyInAnyOrder(new Float[] { 1.0f });
+   * assertThat(new float[] { 1.0f}).containsExactlyInAnyOrder(new Float[] { 2.0f, 1.0f });
+   * assertThat(new float[] { 1.0f, 2.0f, 3.0f }).containsExactlyInAnyOrder(new Float[] { 2.0f, 1.0f });
+ * + * @param values the given values. + * @return {@code this} assertion object. + * @throws NullPointerException if the given argument is {@code null}. + * @throws AssertionError if the actual group is {@code null}. + * @throws AssertionError if the actual group does not contain the given values, i.e. the actual group + * contains some or none of the given values, or the actual group contains more values than the given ones. + * @since 3.19.0 + */ + public SELF containsExactlyInAnyOrder(Float[] values) { + requireNonNullParameter(values, "values"); + arrays.assertContainsExactlyInAnyOrder(info, actual, toPrimitiveFloatArray(values)); + return myself; + } + /** * Create a {@link Float} comparator which compares floats at the given precision and pass it to {@link #usingElementComparator(Comparator)}. * All the following assertions will use this comparator to compare float[] elements. @@ -992,4 +1506,38 @@ public SELF containsAnyOf(float... values) { return myself; } + /** + * Verifies that the actual array contains at least one of the values of the given array. + *

+ * Example : + *

 float[] soFloats = { 1.0f, 2.0f, 3.0f };
+   *
+   * // assertions will pass
+   * assertThat(soFloats).containsAnyOf(new Float[] { 1.0f })
+   *                   .containsAnyOf(new Float[] { 3.0f, 4.0f, 5.0f, 6.0f });
+   *
+   * // assertions will fail
+   * assertThat(soFloats).containsAnyOf(new Float[] { 8.0f });
+   * assertThat(soFloats).containsAnyOf(new Float[] { 11.0f, 15.0f, 420.0f });
+ * + * @param values the values whose at least one which is expected to be in the array under test. + * @return {@code this} assertion object. + * @throws NullPointerException if the array of values is {@code null}. + * @throws IllegalArgumentException if the array of values is empty and the array under test is not empty. + * @throws AssertionError if the array under test is {@code null}. + * @throws AssertionError if the array under test does not contain any of the given {@code values}. + * @since 3.19.0 + */ + public SELF containsAnyOf(Float[] values) { + requireNonNullParameter(values, "values"); + arrays.assertContainsAnyOf(info, actual, toPrimitiveFloatArray(values)); + return myself; + } + + private static float[] toPrimitiveFloatArray(Float[] values) { + float[] floats = new float[values.length]; + range(0, values.length).forEach(i -> floats[i] = values[i]); + return floats; + } + } diff --git a/src/main/java/org/assertj/core/api/AbstractFloatAssert.java b/src/main/java/org/assertj/core/api/AbstractFloatAssert.java index b13a2d61529..7d2745d7c62 100644 --- a/src/main/java/org/assertj/core/api/AbstractFloatAssert.java +++ b/src/main/java/org/assertj/core/api/AbstractFloatAssert.java @@ -8,7 +8,7 @@ * 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-2020 the original author or authors. + * Copyright 2012-2021 the original author or authors. */ package org.assertj.core.api; @@ -40,6 +40,7 @@ * @author Ansgar Konermann * @author Mikhail Mazursky * @author Nicolas François + * @author Jin Kwon */ public abstract class AbstractFloatAssert> extends AbstractComparableAssert implements FloatingPointNumberAssert { @@ -51,7 +52,7 @@ public abstract class AbstractFloatAssert private final boolean isPrimitive; - public AbstractFloatAssert(Float actual, Class selfType) { + protected AbstractFloatAssert(Float actual, Class selfType) { super(actual, selfType); this.isPrimitive = false; } @@ -871,4 +872,51 @@ public SELF usingDefaultComparator() { private boolean noCustomComparatorSet() { return floats.getComparator() == null; } + + /** + * Verifies that the float value is a finite floating-point value. + *

+ * Example: + *

 // assertion succeeds
+   * assertThat(1.0f).isFinite();
+   *
+   * // assertions fail
+   * assertThat(Float.NaN).isFinite();
+   * assertThat(Float.NEGATIVE_INFINITY).isFinite();
+   * assertThat(Float.POSITIVE_INFINITY).isFinite();
+ * + * @return this assertion object. + * @throws AssertionError if the actual value is not a finite floating-point value. + * @throws AssertionError if the actual value is null. + * @see #isInfinite() + * @since 3.19.0 + */ + @Override + public SELF isFinite() { + floats.assertIsFinite(info, actual); + return myself; + } + + /** + * Verifies that the float value represents positive infinity or negative infinity. + *

+ * Examples: + *

 // assertions succeed
+   * assertThat(Float.NEGATIVE_INFINITY).isInfinite();
+   * assertThat(Float.POSITIVE_INFINITY).isInfinite();
+   *
+   * // assertions fail
+   * assertThat(1.0f).isInfinite();
+   * assertThat(Float.NaN).isInfinite();
+ * + * @return this assertion object. + * @throws AssertionError if the actual value doesn't represent the positive infinity nor negative infinity. + * @throws AssertionError if the actual value is null. + * @since 3.19.0 + */ + @Override + public SELF isInfinite() { + floats.assertIsInfinite(info, actual); + return myself; + } } diff --git a/src/main/java/org/assertj/core/api/AbstractFutureAssert.java b/src/main/java/org/assertj/core/api/AbstractFutureAssert.java index 7f6437e4ea4..0d88717c1f1 100644 --- a/src/main/java/org/assertj/core/api/AbstractFutureAssert.java +++ b/src/main/java/org/assertj/core/api/AbstractFutureAssert.java @@ -8,15 +8,18 @@ * 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-2020 the original author or authors. + * Copyright 2012-2021 the original author or authors. */ package org.assertj.core.api; import static org.assertj.core.api.AssertionsForClassTypes.assertThat; import java.time.Duration; +import java.util.concurrent.CancellationException; +import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; import org.assertj.core.internal.Futures; import org.assertj.core.util.VisibleForTesting; @@ -171,6 +174,14 @@ public SELF isNotDone() { *

* If the future's result is not available for any reason an assertion error is thrown. *

+ * WARNING + *

+ * {@code succeedsWithin} does not fully integrate with soft assertions, if it fails the test will fail immediately (the error + * is not collected as a soft assertion error), if it succeeds the chained assertions are executed and any error will be + * collected as a soft assertion error.
+ * The rationale is that if we collected {@code succeedsWithin} error as a soft assertion error, the chained assertions would be + * executed against a future value that is actually not available. + *

* To get assertions for the future result's type use {@link #succeedsWithin(Duration, InstanceOfAssertFactory)} instead. *

* Examples: @@ -210,6 +221,14 @@ public ObjectAssert succeedsWithin(Duration timeout) { *

* If the future's result is not available for any reason an assertion error is thrown. *

+ * WARNING + *

+ * {@code succeedsWithin} does not fully integrate with soft assertions, if it fails the test will fail immediately (the error + * is not collected as a soft assertion error), if it succeeds the chained assertions are executed and any error will be + * collected as a soft assertion error.
+ * The rationale is that if we collected {@code succeedsWithin} error as a soft assertion error, the chained assertions would be + * executed against a future value that is actually not available. + *

* To get assertions for the future result's type use {@link #succeedsWithin(long, TimeUnit, InstanceOfAssertFactory)} instead. *

* Examples: @@ -249,6 +268,14 @@ public ObjectAssert succeedsWithin(long timeout, TimeUnit unit) { *

* If the future's result is not available for any reason an assertion error is thrown. *

+ * WARNING + *

+ * {@code succeedsWithin} does not fully integrate with soft assertions, if it fails the test will fail immediately (the error + * is not collected as a soft assertion error), if it succeeds the chained assertions are executed and any error will be + * collected as a soft assertion error.
+ * The rationale is that if we collected {@code succeedsWithin} error as a soft assertion error, the chained assertions would be + * executed against a future value that is actually not available. + *

* Examples: *

 ExecutorService executorService = Executors.newSingleThreadExecutor();
    *
@@ -292,6 +319,14 @@ public ObjectAssert succeedsWithin(long timeout, TimeUnit unit) {
    * 

* If the future's result is not available for any reason an assertion error is thrown. *

+ * WARNING + *

+ * {@code succeedsWithin} does not fully integrate with soft assertions, if it fails the test will fail immediately (the error + * is not collected as a soft assertion error), if it succeeds the chained assertions are executed and any error will be + * collected as a soft assertion error.
+ * The rationale is that if we collected {@code succeedsWithin} error as a soft assertion error, the chained assertions would be + * executed against a future value that is actually not available. + *

* Examples: *

 ExecutorService executorService = Executors.newSingleThreadExecutor();
    *
@@ -328,6 +363,95 @@ public ObjectAssert succeedsWithin(long timeout, TimeUnit unit) {
     return internalSucceedsWithin(timeout, unit).asInstanceOf(assertFactory);
   }
 
+  /**
+   * Checks that the future does not complete within the given time and returns the exception that caused the failure for
+   * further (exception) assertions, the exception can be any of {@link InterruptedException}, {@link ExecutionException},
+   * {@link TimeoutException} or {@link CancellationException} as per {@link Future#get(long, TimeUnit)}.
+   * 

+ * WARNING + *

+ * {@code failsWithin} does not fully integrate with soft assertions, if the future completes the test will fail immediately (the + * error is not collected as a soft assertion error), if the assertion succeeds the chained assertions are executed and any + * errors will be collected as a soft assertion errors.
+ * The rationale is that if we collect {@code failsWithin} error as a soft assertion error, the chained assertions would be + * executed but that does not make sense since there is no exception to check as the future has completed. + *

+ * Examples: + *

 ExecutorService executorService = Executors.newSingleThreadExecutor();
+   *
+   * Future<String> future = executorService.submit(() -> {
+   *   Thread.sleep(100);
+   *   return "ook!";
+   * });
+   *
+   * // assertion succeeds as the future is not completed after 50ms
+   * assertThat(future).failsWithin(Duration.ofMillis(50))
+   *                   .withThrowableOfType(TimeoutException.class)
+   *                   .withMessage(null);
+   *
+   * // fails as the future is completed after within 200ms
+   * assertThat(future).failsWithin(Duration.ofMillis(200));
+ * + * @param timeout the maximum time to wait + * @return a new assertion instance on the the future's exception. + * @throws AssertionError if the actual {@code CompletableFuture} is {@code null}. + * @throws AssertionError if the actual {@code CompletableFuture} succeeds within the given timeout. + * @since 3.18.0 + */ + public WithThrowable failsWithin(Duration timeout) { + return internalFailsWithin(timeout); + } + + /** + * Checks that the future does not complete within the given time and returns the exception that caused the failure for + * further (exception) assertions, the exception can be any of {@link InterruptedException}, {@link ExecutionException}, + * {@link TimeoutException} or {@link CancellationException} as per {@link Future#get(long, TimeUnit)}. + *

+ * WARNING + *

+ * {@code failsWithin} does not fully integrate with soft assertions, if the future completes the test will fail immediately (the + * error is not collected as a soft assertion error), if the assertion succeeds the chained assertions are executed and any + * errors will be collected as a soft assertion errors.
+ * The rationale is that if we collect {@code failsWithin} error as a soft assertion error, the chained assertions would be + * executed but that does not make sense since there is no exception to check as the future has completed. + *

+ * Examples: + *

 ExecutorService executorService = Executors.newSingleThreadExecutor();
+   *
+   * Future<String> future = executorService.submit(() -> {
+   *   Thread.sleep(100);
+   *   return "ook!";
+   * });
+   *
+   * // assertion succeeds as the future is not completed after 50ms
+   * assertThat(future).failsWithin(50, TimeUnit.MILLISECONDS)
+   *                   .withThrowableOfType(TimeoutException.class)
+   *                   .withMessage(null);
+   *
+   * // fails as the future is completed after the given timeout duration
+   * assertThat(future).failsWithin(200, TimeUnit.MILLISECONDS);
+ * + * @param timeout the maximum time to wait + * @param unit the time unit + * @return a new assertion instance on the the future's exception. + * @throws AssertionError if the actual {@code CompletableFuture} is {@code null}. + * @throws AssertionError if the actual {@code CompletableFuture} succeeds within the given timeout. + * @since 3.18.0 + */ + public WithThrowable failsWithin(long timeout, TimeUnit unit) { + return internalFailsWithin(timeout, unit); + } + + private WithThrowable internalFailsWithin(Duration timeout) { + Exception exception = futures.assertFailedWithin(info, actual, timeout); + return new WithThrowable(exception); + } + + private WithThrowable internalFailsWithin(long timeout, TimeUnit unit) { + Exception exception = futures.assertFailedWithin(info, actual, timeout, unit); + return new WithThrowable(exception); + } + private ObjectAssert internalSucceedsWithin(Duration timeout) { RESULT result = futures.assertSucceededWithin(info, actual, timeout); return assertThat(result); diff --git a/src/main/java/org/assertj/core/api/AbstractInputStreamAssert.java b/src/main/java/org/assertj/core/api/AbstractInputStreamAssert.java index 6c7b776ff2e..207eb715532 100644 --- a/src/main/java/org/assertj/core/api/AbstractInputStreamAssert.java +++ b/src/main/java/org/assertj/core/api/AbstractInputStreamAssert.java @@ -8,7 +8,7 @@ * 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-2020 the original author or authors. + * Copyright 2012-2021 the original author or authors. */ package org.assertj.core.api; @@ -35,7 +35,7 @@ public abstract class AbstractInputStreamAssert selfType) { + protected AbstractInputStreamAssert(ACTUAL actual, Class selfType) { super(actual, selfType); } diff --git a/src/main/java/org/assertj/core/api/AbstractInstantAssert.java b/src/main/java/org/assertj/core/api/AbstractInstantAssert.java index b909c00bb8b..f6e3163d70a 100644 --- a/src/main/java/org/assertj/core/api/AbstractInstantAssert.java +++ b/src/main/java/org/assertj/core/api/AbstractInstantAssert.java @@ -8,7 +8,7 @@ * 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-2020 the original author or authors. + * Copyright 2012-2021 the original author or authors. */ package org.assertj.core.api; diff --git a/src/main/java/org/assertj/core/api/AbstractIntArrayAssert.java b/src/main/java/org/assertj/core/api/AbstractIntArrayAssert.java index 5b2ff83ed5c..c13aaa5126f 100644 --- a/src/main/java/org/assertj/core/api/AbstractIntArrayAssert.java +++ b/src/main/java/org/assertj/core/api/AbstractIntArrayAssert.java @@ -8,10 +8,11 @@ * 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-2020 the original author or authors. + * Copyright 2012-2021 the original author or authors. */ package org.assertj.core.api; +import java.util.Arrays; import java.util.Comparator; import org.assertj.core.data.Index; @@ -21,12 +22,12 @@ import org.assertj.core.util.VisibleForTesting; public abstract class AbstractIntArrayAssert> - extends AbstractArrayAssert { + extends AbstractArrayAssert { @VisibleForTesting protected IntArrays arrays = IntArrays.instance(); - public AbstractIntArrayAssert(int[] actual, Class selfType) { + protected AbstractIntArrayAssert(int[] actual, Class selfType) { super(actual, selfType); } @@ -198,6 +199,33 @@ public SELF contains(int... values) { return myself; } + /** + * Verifies that the actual array contains the values of the given array, in any order. + *

+ * Example: + *

 // assertion will pass
+   * assertThat(new int[] { 1, 2, 3 }).contains(new Integer[] { 1, 2 });
+   * assertThat(new int[] { 1, 2, 3 }).contains(new Integer[] { 3, 1 });
+   * assertThat(new int[] { 1, 2, 3 }).contains(new Integer[] { 1, 3, 2 });
+   *
+   * // assertion will fail
+   * assertThat(new int[] { 1, 2, 3 }).contains(new Integer[] { 1, 4 });
+   * assertThat(new int[] { 1, 2, 3 }).contains(new Integer[] { 4, 7 });
+ * + * @param values the given values. + * @return {@code this} assertion object. + * @throws NullPointerException if the given argument is {@code null}. + * @throws IllegalArgumentException if the given argument is an empty array. + * @throws AssertionError if the actual array is {@code null}. + * @throws AssertionError if the actual array does not contain the given values. + * @since 3.19.0 + */ + public SELF contains(Integer[] values) { + requireNonNullParameter(values, "values"); + arrays.assertContains(info, actual, toPrimitiveIntArray(values)); + return myself; + } + /** * Verifies that the actual array contains only the given values and nothing else, in any order. *

@@ -224,6 +252,34 @@ public SELF containsOnly(int... values) { return myself; } + /** + * Verifies that the actual array contains only the values of the given array and nothing else, in any order. + *

+ * Example: + *

 // assertions will pass
+   * assertThat(new int[] { 1, 2, 3 }).containsOnly(new Integer[] { 1, 2, 3 });
+   * assertThat(new int[] { 1, 2, 3 }).containsOnly(new Integer[] { 2, 3, 1 });
+   * assertThat(new int[] { 1, 1, 2 }).containsOnly(new Integer[] { 1, 2 });
+   *
+   * // assertions will fail
+   * assertThat(new int[] { 1, 2, 3 }).containsOnly(new Integer[] { 1, 2, 3, 4 });
+   * assertThat(new int[] { 1, 2, 3 }).containsOnly(new Integer[] { 4, 7 });
+ * + * @param values the given values. + * @return {@code this} assertion object. + * @throws NullPointerException if the given argument is {@code null}. + * @throws IllegalArgumentException if the given argument is an empty array. + * @throws AssertionError if the actual array is {@code null}. + * @throws AssertionError if the actual array does not contain the given values, i.e. the actual array contains some + * or none of the given values, or the actual array contains more values than the given ones. + * @since 3.19.0 + */ + public SELF containsOnly(Integer[] values) { + requireNonNullParameter(values, "values"); + arrays.assertContainsOnly(info, actual, toPrimitiveIntArray(values)); + return myself; + } + /** * Verifies that the actual array contains the given values only once. *

@@ -249,6 +305,33 @@ public SELF containsOnlyOnce(int... values) { return myself; } + /** + * Verifies that the actual array contains the values of the given array only once. + *

+ * Examples : + *

 // assertion will pass
+   * assertThat(new int[] { 1, 2, 3 }).containsOnlyOnce(new Integer[] { 1, 2 });
+   *
+   * // assertions will fail
+   * assertThat(new int[] { 1, 2, 1 }).containsOnlyOnce(new Integer[] { 1 });
+   * assertThat(new int[] { 1, 2, 3 }).containsOnlyOnce(new Integer[] { 4 });
+   * assertThat(new int[] { 1, 2, 3, 3 }).containsOnlyOnce(new Integer[] { 0, 1, 2, 3, 4, 5 });
+ * + * @param values the given values. + * @return {@code this} assertion object. + * @throws NullPointerException if the given argument is {@code null}. + * @throws IllegalArgumentException if the given argument is an empty array. + * @throws AssertionError if the actual array is {@code null}. + * @throws AssertionError if the actual group does not contain the given values, i.e. the actual group contains some + * or none of the given values, or the actual group contains more than once these values. + * @since 3.19.0 + */ + public SELF containsOnlyOnce(Integer[] values) { + requireNonNullParameter(values, "values"); + arrays.assertContainsOnlyOnce(info, actual, toPrimitiveIntArray(values)); + return myself; + } + /** * Verifies that the actual array contains the given sequence, without any other values between them. *

@@ -271,6 +354,30 @@ public SELF containsSequence(int... sequence) { return myself; } + /** + * Verifies that the actual array contains the given sequence, without any other values between them. + *

+ * Example: + *

 // assertion will pass
+   * assertThat(new int[] { 1, 2, 3 }).containsSequence(new Integer[] { 1, 2 });
+   *
+   * // assertion will fail
+   * assertThat(new int[] { 1, 2, 3 }).containsSequence(new Integer[] { 1, 3 });
+   * assertThat(new int[] { 1, 2, 3 }).containsSequence(new Integer[] { 2, 1 });
+ * + * @param sequence the sequence of values to look for. + * @return myself assertion object. + * @throws AssertionError if the actual array is {@code null}. + * @throws AssertionError if the given array is {@code null}. + * @throws AssertionError if the actual array does not contain the given sequence. + * @since 3.19.0 + */ + public SELF containsSequence(Integer[] sequence) { + requireNonNullParameter(sequence, "sequence"); + arrays.assertContainsSequence(info, actual, toPrimitiveIntArray(sequence)); + return myself; + } + /** * Verifies that the actual array contains the given subsequence (possibly with other values between them). *

@@ -293,6 +400,30 @@ public SELF containsSubsequence(int... subsequence) { return myself; } + /** + * Verifies that the actual array contains the given subsequence (possibly with other values between them). + *

+ * Example: + *

 // assertion will pass
+   * assertThat(new int[] { 1, 2, 3 }).containsSubsequence(new Integer[] { 1, 2 });
+   * assertThat(new int[] { 1, 2, 3 }).containsSubsequence(new Integer[] { 1, 3 });
+   *
+   * // assertion will fail
+   * assertThat(new int[] { 1, 2, 3 }).containsSubsequence(new Integer[] { 2, 1 });
+ * + * @param subsequence the subsequence of values to look for. + * @return myself assertion object. + * @throws AssertionError if the actual array is {@code null}. + * @throws AssertionError if the given array is {@code null}. + * @throws AssertionError if the actual array does not contain the given subsequence. + * @since 3.19.0 + */ + public SELF containsSubsequence(Integer[] subsequence) { + requireNonNullParameter(subsequence, "subsequence"); + arrays.assertContainsSubsequence(info, actual, toPrimitiveIntArray(subsequence)); + return myself; + } + /** * Verifies that the actual array contains the given value at the given index. *

@@ -341,6 +472,30 @@ public SELF doesNotContain(int... values) { return myself; } + /** + * Verifies that the actual array does not contain the values of the given array. + *

+ * Example: + *

 // assertion will pass
+   * assertThat(new int[] { 1, 2, 3 }).doesNotContain(new Integer[] { 4 });
+   *
+   * // assertion will fail
+   * assertThat(new int[] { 1, 2, 3 }).doesNotContain(new Integer[] { 2 });
+ * + * @param values the given values. + * @return {@code this} assertion object. + * @throws NullPointerException if the given argument is {@code null}. + * @throws IllegalArgumentException if the given argument is an empty array. + * @throws AssertionError if the actual array is {@code null}. + * @throws AssertionError if the actual array contains any of the given values. + * @since 3.19.0 + */ + public SELF doesNotContain(Integer[] values) { + requireNonNullParameter(values, "values"); + arrays.assertDoesNotContain(info, actual, toPrimitiveIntArray(values)); + return myself; + } + /** * Verifies that the actual array does not contain the given value at the given index. *

@@ -408,6 +563,32 @@ public SELF startsWith(int... sequence) { return myself; } + /** + * Verifies that the actual array starts with the given sequence of values, without any other values between them. + * Similar to {@link #containsSequence(int...)}, but it also verifies that the first element in the + * sequence is also first element of the actual array. + *

+ * Example: + *

 // assertion will pass
+   * assertThat(new int[] { 1, 2, 3 }).startsWith(new Integer[] { 1, 2 });
+   *
+   * // assertion will fail
+   * assertThat(new int[] { 1, 2, 3 }).startsWith(new Integer[] { 2, 3 });
+ * + * @param sequence the sequence of values to look for. + * @return myself assertion object. + * @throws NullPointerException if the given argument is {@code null}. + * @throws IllegalArgumentException if the given argument is an empty array. + * @throws AssertionError if the actual array is {@code null}. + * @throws AssertionError if the actual array does not start with the given sequence. + * @since 3.19.0 + */ + public SELF startsWith(Integer[] sequence) { + requireNonNullParameter(sequence, "sequence"); + arrays.assertStartsWith(info, actual, toPrimitiveIntArray(sequence)); + return myself; + } + /** * Verifies that the actual array ends with the given sequence of values, without any other values between them. * Similar to {@link #containsSequence(int...)}, but it also verifies that the last element in the @@ -432,6 +613,32 @@ public SELF endsWith(int... sequence) { return myself; } + /** + * Verifies that the actual array ends with the given sequence of values, without any other values between them. + * Similar to {@link #containsSequence(int...)}, but it also verifies that the last element in the + * sequence is also last element of the actual array. + *

+ * Example: + *

 // assertion will pass
+   * assertThat(new int[] { 1, 2, 3 }).endsWith(new Integer[] { 2, 3 });
+   *
+   * // assertion will fail
+   * assertThat(new int[] { 1, 2, 3 }).endsWith(new Integer[] { 3, 4 });
+ * + * @param sequence the sequence of values to look for. + * @return myself assertion object. + * @throws NullPointerException if the given argument is {@code null}. + * @throws IllegalArgumentException if the given argument is an empty array. + * @throws AssertionError if the actual array is {@code null}. + * @throws AssertionError if the actual array does not end with the given sequence. + * @since 3.19.0 + */ + public SELF endsWith(Integer[] sequence) { + requireNonNullParameter(sequence, "sequence"); + arrays.assertEndsWith(info, actual, toPrimitiveIntArray(sequence)); + return myself; + } + /** {@inheritDoc} */ @Override public SELF isSorted() { @@ -487,6 +694,31 @@ public SELF containsExactly(int... values) { return myself; } + /** + * Verifies that the actual group contains only the values of the given array and nothing else, in order. + *

+ * Example : + *

 // assertion will pass
+   * assertThat(new int[] { 1, 2, 3 }).containsExactly(new Integer[] { 1, 2, 3 });
+   *
+   * // assertion will fail as actual and expected order differ
+   * assertThat(new int[] { 1, 2, 3 }).containsExactly(new Integer[] { 1, 3, 2 });
+ * + * @param values the given values. + * @return {@code this} assertion object. + * @throws NullPointerException if the given argument is {@code null}. + * @throws AssertionError if the actual group is {@code null}. + * @throws AssertionError if the actual group does not contain the given values with same order, i.e. the actual group + * contains some or none of the given values, or the actual group contains more values than the given ones + * or values are the same but the order is not. + * @since 3.19.0 + */ + public SELF containsExactly(Integer[] values) { + requireNonNullParameter(values, "values"); + arrays.assertContainsExactly(info, actual, toPrimitiveIntArray(values)); + return myself; + } + /** * Verifies that the actual array contains exactly the given values and nothing else, in any order.
*

@@ -513,6 +745,33 @@ public SELF containsExactlyInAnyOrder(int... values) { return myself; } + /** + * Verifies that the actual group contains exactly the values of the given array and nothing else, in any order.
+ *

+ * Example : + *

 // assertions will pass
+   * assertThat(new int[] { 1, 2 }).containsExactlyInAnyOrder(new Integer[] { 2, 1 });
+   * assertThat(new int[] { 1, 2, 3 }).containsExactlyInAnyOrder(new Integer[] { 3, 2, 1 });
+   *
+   * // assertions will fail
+   * assertThat(new int[] { 1, 2 }).containsExactlyInAnyOrder(new Integer[] { 1, 4 });
+   * assertThat(new int[] { 1 }).containsExactlyInAnyOrder(new Integer[] { 4, 1 });
+   * assertThat(new int[] { 1, 2, 3 }).containsExactlyInAnyOrder(new Integer[] { 1, 2 });
+ * + * @param values the given values. + * @return {@code this} assertion object. + * @throws NullPointerException if the given argument is {@code null}. + * @throws AssertionError if the actual group is {@code null}. + * @throws AssertionError if the actual group does not contain the given values, i.e. the actual group + * contains some or none of the given values, or the actual group contains more values than the given ones. + * @since 3.19.0 + */ + public SELF containsExactlyInAnyOrder(Integer[] values) { + requireNonNullParameter(values, "values"); + arrays.assertContainsExactlyInAnyOrder(info, actual, toPrimitiveIntArray(values)); + return myself; + } + /** * Verifies that the actual array contains at least one of the given values. *

@@ -543,4 +802,39 @@ public SELF containsAnyOf(int... values) { return myself; } + /** + * Verifies that the actual array contains at least one of the values of the given array. + *

+ * Example : + *

 int[] oneTwoThree = { 1, 2, 3 };
+   *
+   * // assertions will pass
+   * assertThat(oneTwoThree).containsAnyOf(new Integer[] { 2 })
+   *                        .containsAnyOf(new Integer[] { 2, 3 })
+   *                        .containsAnyOf(new Integer[] { 1, 2, 3 })
+   *                        .containsAnyOf(new Integer[] { 1, 2, 3, 4 })
+   *                        .containsAnyOf(new Integer[] { 5, 6, 7, 2 });
+   *
+   * // assertions will fail
+   * assertThat(oneTwoThree).containsAnyOf(new Integer[] { 4 });
+   * assertThat(oneTwoThree).containsAnyOf(new Integer[] { 4, 5, 6, 7 });
+ * + * @param values the values whose at least one which is expected to be in the array under test. + * @return {@code this} assertion object. + * @throws NullPointerException if the array of values is {@code null}. + * @throws IllegalArgumentException if the array of values is empty and the array under test is not empty. + * @throws AssertionError if the array under test is {@code null}. + * @throws AssertionError if the array under test does not contain any of the given {@code values}. + * @since 3.19.0 + */ + public SELF containsAnyOf(Integer[] values) { + requireNonNullParameter(values, "values"); + arrays.assertContainsAnyOf(info, actual, toPrimitiveIntArray(values)); + return myself; + } + + private static int[] toPrimitiveIntArray(Integer[] values) { + return Arrays.stream(values).mapToInt(Integer::intValue).toArray(); + } + } diff --git a/src/main/java/org/assertj/core/api/AbstractIntegerAssert.java b/src/main/java/org/assertj/core/api/AbstractIntegerAssert.java index a9dcf04502d..b56283272ab 100644 --- a/src/main/java/org/assertj/core/api/AbstractIntegerAssert.java +++ b/src/main/java/org/assertj/core/api/AbstractIntegerAssert.java @@ -8,7 +8,7 @@ * 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-2020 the original author or authors. + * Copyright 2012-2021 the original author or authors. */ package org.assertj.core.api; @@ -44,7 +44,7 @@ public abstract class AbstractIntegerAssert selfType) { + protected AbstractIntegerAssert(Integer actual, Class selfType) { super(actual, selfType); } diff --git a/src/main/java/org/assertj/core/api/AbstractIterableAssert.java b/src/main/java/org/assertj/core/api/AbstractIterableAssert.java index aa865175e49..61851834e7e 100644 --- a/src/main/java/org/assertj/core/api/AbstractIterableAssert.java +++ b/src/main/java/org/assertj/core/api/AbstractIterableAssert.java @@ -8,7 +8,7 @@ * 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-2020 the original author or authors. + * Copyright 2012-2021 the original author or authors. */ package org.assertj.core.api; @@ -116,7 +116,7 @@ public abstract class AbstractIterableAssert selfType) { + protected AbstractIterableAssert(ACTUAL actual, Class selfType) { super(actual, selfType); } @@ -798,7 +798,7 @@ public SELF usingDefaultElementComparator() { /** * Verifies that the actual {@link Iterable} contains at least one of the given values. *

- * Example : + * Example: *

 Iterable<String> abc = Arrays.asList("a", "b", "c");
    *
    * // assertions will pass
@@ -829,7 +829,7 @@ public SELF containsAnyOf(@SuppressWarnings("unchecked") ELEMENT... values) {
   /**
    * Verifies that the {@link Iterable} under test contains at least one of the given {@link Iterable} elements.
    * 

- * Example : + * Example: *

 Iterable<String> abc = Arrays.asList("a", "b", "c");
    *
    * // assertions will pass
@@ -861,9 +861,9 @@ public SELF containsAnyElementsOf(Iterable iterable) {
    * Iterable becoming the Iterable under test.
    * 

* It allows you to test a property/field of the Iterable's elements instead of testing the elements themselves, which - * can be be much less work ! + * can be be much less work! *

- * Let's take a look at an example to make things clearer : + * Let's take a look at an example to make things clearer: *

 // build a list of TolkienCharacters: a TolkienCharacter has a name, and age and a Race (a specific class)
    * // they can be public field or properties, both can be extracted.
    * List<TolkienCharacter> fellowshipOfTheRing = new ArrayList<TolkienCharacter>();
@@ -877,13 +877,13 @@ public SELF containsAnyElementsOf(Iterable iterable) {
    * fellowshipOfTheRing.add(new TolkienCharacter("Aragorn", 87, MAN);
    * fellowshipOfTheRing.add(new TolkienCharacter("Boromir", 37, MAN));
    *
-   * // let's verify the names of the TolkienCharacters in fellowshipOfTheRing :
+   * // let's verify the names of the TolkienCharacters in fellowshipOfTheRing:
    *
    * assertThat(fellowshipOfTheRing).extracting("name")
    *           .contains("Boromir", "Gandalf", "Frodo")
    *           .doesNotContain("Sauron", "Elrond");
    *
-   * // you can extract nested properties/fields like the name of the race :
+   * // you can extract nested properties/fields like the name of the race:
    *
    * assertThat(fellowshipOfTheRing).extracting("race.name")
    *                                .contains("Hobbit", "Elf")
@@ -953,8 +953,8 @@ public AbstractListAssert, Object, ObjectAssert
-   * Let's take a look at an example to make things clearer :
-   * 
 // Build a array of WesterosHouse, a WesterosHouse has a method: public String sayTheWords()
+   * Let's take a look at an example to make things clearer:
+   * 
 // Build an array of WesterosHouse, a WesterosHouse has a method: public String sayTheWords()
    *
    * List<WesterosHouse> greatHouses = new ArrayList<WesterosHouse>();
    * greatHouses.add(new WesterosHouse("Stark", "Winter is Coming"));
@@ -1001,8 +1001,8 @@ public AbstractListAssert, Object, ObjectAssert
-   * Let's take an example to make things clearer :
-   * 
 // Build a array of WesterosHouse, a WesterosHouse has a method: public String sayTheWords()
+   * Let's take an example to make things clearer:
+   * 
 // Build an array of WesterosHouse, a WesterosHouse has a method: public String sayTheWords()
    * List<WesterosHouse> greatHouses = new ArrayList<WesterosHouse>();
    * greatHouses.add(new WesterosHouse("Stark", "Winter is Coming"));
    * greatHouses.add(new WesterosHouse("Lannister", "Hear Me Roar!"));
@@ -1049,9 +1049,9 @@ public 

AbstractListAssert, P, ObjectAssert

> extracti * Iterable becoming the Iterable under test. *

* It allows you to test a property/field of the Iterable's elements instead of testing the elements themselves, - * which can be much less work ! + * which can be much less work! *

- * Let's take an example to make things clearer : + * Let's take an example to make things clearer: *

 // Build a list of TolkienCharacter, a TolkienCharacter has a name, and age and a Race (a specific class)
    * // they can be public field or properties, both can be extracted.
    * List<TolkienCharacter> fellowshipOfTheRing = new ArrayList<TolkienCharacter>();
@@ -1065,12 +1065,12 @@ public 

AbstractListAssert, P, ObjectAssert

> extracti * fellowshipOfTheRing.add(new TolkienCharacter("Aragorn", 87, MAN); * fellowshipOfTheRing.add(new TolkienCharacter("Boromir", 37, MAN)); * - * // let's verify the names of TolkienCharacter in fellowshipOfTheRing : + * // let's verify the names of TolkienCharacter in fellowshipOfTheRing: * assertThat(fellowshipOfTheRing).extracting("name", String.class) * .contains("Boromir", "Gandalf", "Frodo") * .doesNotContain("Sauron", "Elrond"); * - * // you can extract nested property/field like the name of Race : + * // you can extract nested property/field like the name of Race: * assertThat(fellowshipOfTheRing).extracting("race.name", String.class) * .contains("Hobbit", "Elf") * .doesNotContain("Orc");

@@ -1146,7 +1146,7 @@ public

AbstractListAssert, P, ObjectAssert

> extracti * extract "id", "name" and "email" then each Tuple data will be composed of id, name and email extracted from the * element of the initial Iterable (the Tuple's data order is the same as the given fields/properties order). *

- * Let's take an example to make things clearer : + * Let's take an example to make things clearer: *

 // Build a list of TolkienCharacter, a TolkienCharacter has a name, and age and a Race (a specific class)
    * // they can be public field or properties, both can be extracted.
    * List<TolkienCharacter> fellowshipOfTheRing = new ArrayList<TolkienCharacter>();
@@ -1160,14 +1160,14 @@ public 

AbstractListAssert, P, ObjectAssert

> extracti * fellowshipOfTheRing.add(new TolkienCharacter("Aragorn", 87, MAN); * fellowshipOfTheRing.add(new TolkienCharacter("Boromir", 37, MAN)); * - * // let's verify 'name' and 'age' of some TolkienCharacter in fellowshipOfTheRing : + * // let's verify 'name' and 'age' of some TolkienCharacter in fellowshipOfTheRing: * assertThat(fellowshipOfTheRing).extracting("name", "age") * .contains(tuple("Boromir", 37), * tuple("Sam", 38), * tuple("Legolas", 1000)); * * - * // extract 'name', 'age' and Race name values : + * // extract 'name', 'age' and Race name values: * assertThat(fellowshipOfTheRing).extracting("name", "age", "race.name") * .contains(tuple("Boromir", 37, "Man"), * tuple("Sam", 38, "Hobbit"), @@ -1229,12 +1229,12 @@ public AbstractListAssert, Tuple, ObjectAssert> /** * Extract the values from Iterable's elements under test by applying an extracting function on them. The returned - * iterable becomes a new object under test. + * iterable becomes the instance under test. *

* It allows to test values from the elements more safely than by using {@link #extracting(String)}, as it * doesn't utilize introspection. *

- * Let's have a look at an example : + * Let's have a look at an example: *

 // Build a list of TolkienCharacter, a TolkienCharacter has a name, and age and a Race (a specific class)
    * // they can be public field or properties, both can be extracted.
    * List<TolkienCharacter> fellowshipOfTheRing = new ArrayList<TolkienCharacter>();
@@ -1252,8 +1252,7 @@ public AbstractListAssert, Tuple, ObjectAssert>
    * assertThat(fellowshipOfTheRing).extracting(TolkienCharacter::getRace).contains(HOBBIT);
* * Note that the order of extracted property/field values is consistent with the iteration order of the Iterable under - * test, for example if it's a {@link HashSet}, you won't be able to make any assumptions on the extracted values - * order. + * test, for example if it's a {@link HashSet}, you won't be able to make any assumptions on the extracted values order. * * @param the type of elements extracted. * @param extractor the object transforming input object to desired one @@ -1261,20 +1260,58 @@ public AbstractListAssert, Tuple, ObjectAssert> */ @CheckReturnValue public AbstractListAssert, V, ObjectAssert> extracting(Function extractor) { + return internalExtracting(extractor); + } + + private AbstractListAssert, V, ObjectAssert> internalExtracting(Function extractor) { List values = FieldsOrPropertiesExtractor.extract(actual, extractor); return newListAssertInstanceForMethodsChangingElementType(values); } + /** + * Maps the Iterable's elements under test by applying a mapping function, the resulting list becomes the instance under test. + *

+ * This allows to test values from the elements more safely than by using {@link #extracting(String)}. + *

+ * Let's have a look at an example: + *

 // Build a list of TolkienCharacter, a TolkienCharacter has a name, and age and a Race (a specific class)
+   * List<TolkienCharacter> fellowshipOfTheRing = new ArrayList<TolkienCharacter>();
+   *
+   * fellowshipOfTheRing.add(new TolkienCharacter("Frodo", 33, HOBBIT));
+   * fellowshipOfTheRing.add(new TolkienCharacter("Sam", 38, HOBBIT));
+   * fellowshipOfTheRing.add(new TolkienCharacter("Gandalf", 2020, MAIA));
+   * fellowshipOfTheRing.add(new TolkienCharacter("Legolas", 1000, ELF));
+   * fellowshipOfTheRing.add(new TolkienCharacter("Pippin", 28, HOBBIT));
+   * fellowshipOfTheRing.add(new TolkienCharacter("Gimli", 139, DWARF));
+   * fellowshipOfTheRing.add(new TolkienCharacter("Aragorn", 87, MAN);
+   * fellowshipOfTheRing.add(new TolkienCharacter("Boromir", 37, MAN));
+   *
+   * // fellowship has hobbitses, right, my precioussss?
+   * assertThat(fellowshipOfTheRing).map(TolkienCharacter::getRace)
+   *                                .contains(HOBBIT);
+ * + * Note that the order of mapped values is consistent with the order of the Iterable under test, for example if + * it's a {@link HashSet}, you won't be able to make any assumptions on the extracted values order. + * + * @param the type of elements resulting of the map operation. + * @param mapper the {@link Function} transforming input object to desired one + * @return a new assertion object whose object under test is the list of values extracted + * @since 3.19.0 + */ + public AbstractListAssert, V, ObjectAssert> map(Function mapper) { + return internalExtracting(mapper); + } + /** * Extract the values from Iterable's elements under test by applying an extracting function (which might throw an - * exception) on them. The returned iterable becomes a new object under test. + * exception) on them. The returned iterable becomes the instance under test. *

* Any checked exception raised in the extractor is rethrown wrapped in a {@link RuntimeException}. *

* It allows to test values from the elements more safely than by using {@link #extracting(String)}, as it * doesn't utilize introspection. *

- * Let's have a look at an example : + * Let's have a look at an example: *

 // Build a list of TolkienCharacter, a TolkienCharacter has a name, and age and a Race (a specific class)
    * // they can be public field or properties, both can be extracted.
    * List<TolkienCharacter> fellowshipOfTheRing = new ArrayList<TolkienCharacter>();
@@ -1307,8 +1344,49 @@ public  AbstractListAssert, V, ObjectAssert> extracti
    */
   @CheckReturnValue
   public  AbstractListAssert, V, ObjectAssert> extracting(ThrowingExtractor extractor) {
-    List values = FieldsOrPropertiesExtractor.extract(actual, extractor);
-    return newListAssertInstanceForMethodsChangingElementType(values);
+    return internalExtracting(extractor);
+  }
+
+  /**
+   * Maps the Iterable's elements by applying the given mapping function (which might throw an exception), the returned list
+   * becomes the instance under test.
+   * 

+ * Any checked exception raised in the function is rethrown wrapped in a {@link RuntimeException}. + *

+ * This allows to test values from the elements more safely than by using {@link #extracting(String)}. + *

+ * Let's have a look at an example: + *

 // Build a list of TolkienCharacter, a TolkienCharacter has a name, and age and a Race (a specific class)
+   * List<TolkienCharacter> fellowshipOfTheRing = new ArrayList<TolkienCharacter>();
+   *
+   * fellowshipOfTheRing.add(new TolkienCharacter("Frodo", 33, HOBBIT));
+   * fellowshipOfTheRing.add(new TolkienCharacter("Sam", 38, HOBBIT));
+   * fellowshipOfTheRing.add(new TolkienCharacter("Gandalf", 2020, MAIA));
+   * fellowshipOfTheRing.add(new TolkienCharacter("Legolas", 1000, ELF));
+   * fellowshipOfTheRing.add(new TolkienCharacter("Pippin", 28, HOBBIT));
+   * fellowshipOfTheRing.add(new TolkienCharacter("Gimli", 139, DWARF));
+   * fellowshipOfTheRing.add(new TolkienCharacter("Aragorn", 87, MAN);
+   * fellowshipOfTheRing.add(new TolkienCharacter("Boromir", 37, MAN));
+   *
+   * assertThat(fellowshipOfTheRing).map(input -> {
+   *   if (input.getAge() < 20) {
+   *     throw new Exception("age < 20");
+   *   }
+   *   return input.getName();
+   * }).contains("Frodo");
+ * + * Note that the order of mapped values is consistent with the order of the Iterable under test, for example if it's a + * {@link HashSet}, you won't be able to make any assumptions on the extracted values order. + * + * @param the exception type of {@link ThrowingExtractor} + * @param the type of elements extracted. + * @param mapper the function transforming input object to desired one + * @return a new assertion object whose object under test is the list of values extracted + * @since 3.19.0 + */ + @CheckReturnValue + public AbstractListAssert, V, ObjectAssert> map(ThrowingExtractor mapper) { + return internalExtracting(mapper); } /* @@ -1327,15 +1405,14 @@ private AbstractListAssert, V, ObjectAssert> newList } /** - * Extract the Iterable values from Iterable's elements under test by applying an Iterable extracting function on them - * and concatenating the result lists. The returned iterable becomes a new object under test. - *

- * It allows testing the results of extracting values that are represented by Iterables. + * Extracts Iterable elements values by applying a function and concatenates the result into a list that becomes the instance + * under test. *

- * For example: + * Example: *

 CartoonCharacter bart = new CartoonCharacter("Bart Simpson");
    * CartoonCharacter lisa = new CartoonCharacter("Lisa Simpson");
    * CartoonCharacter maggie = new CartoonCharacter("Maggie Simpson");
+   *
    * CartoonCharacter homer = new CartoonCharacter("Homer Simpson");
    * homer.getChildren().add(bart);
    * homer.getChildren().add(lisa);
@@ -1351,13 +1428,11 @@ private  AbstractListAssert, V, ObjectAssert> newList
    * assertThat(parents).flatExtracting(CartoonCharacter::getChildren)
    *                    .containsOnly(bart, lisa, maggie, pebbles);
* - * The order of extracted values is consistent with both the order of the collection itself, as well as the extracted - * collections. + * The extracted values order is consistent with both the order of the iterable itself as well as the extracted collections. * - * @param the type of elements extracted. - * @param extractor the object transforming input object to an {@code Iterable} of desired ones + * @param the type of extracted elements. + * @param extractor the {@link Function} transforming input object to an {@code Iterable} of desired ones * @return a new assertion object whose object under test is the list of values extracted - * @throws NullPointerException if one of the {@code Iterable}'s element is null. */ @CheckReturnValue public AbstractListAssert, V, ObjectAssert> flatExtracting(Function> extractor) { @@ -1365,16 +1440,50 @@ public AbstractListAssert, V, ObjectAssert> flatExtr } /** - * Extract the Iterable values from Iterable's elements under test by applying an Iterable extracting function (which - * might throw a checked exception) on them and concatenating the result lists. The returned iterable becomes a new object - * under test. + * Maps the Iterable's elements under test by applying the given {@link Function} and flattens the resulting collections in a + * list becoming the object under test. *

- * It allows testing the results of extracting values that are represented by Iterables. + * Example: + *

 CartoonCharacter bart = new CartoonCharacter("Bart Simpson");
+   * CartoonCharacter lisa = new CartoonCharacter("Lisa Simpson");
+   * CartoonCharacter maggie = new CartoonCharacter("Maggie Simpson");
+   *
+   * CartoonCharacter homer = new CartoonCharacter("Homer Simpson");
+   * homer.getChildren().add(bart);
+   * homer.getChildren().add(lisa);
+   * homer.getChildren().add(maggie);
+   *
+   * CartoonCharacter pebbles = new CartoonCharacter("Pebbles Flintstone");
+   * CartoonCharacter fred = new CartoonCharacter("Fred Flintstone");
+   * fred.getChildren().add(pebbles);
+   *
+   * List<CartoonCharacter> parents = list(homer, fred);
+   *
+   * // check children property which is a List<CartoonCharacter>
+   * assertThat(parents).flatMap(CartoonCharacter::getChildren)
+   *                    .containsOnly(bart, lisa, maggie, pebbles);
+ * + * The mapped values order is consistent with both the order of the iterable itself as well as the mapped collections. + * + * @param the type of mapped elements. + * @param mapper the {@link Function} transforming input object to an {@code Iterable} of desired ones + * @return a new assertion object whose object under test is the list of values extracted + * @since 3.19.0 + */ + @CheckReturnValue + public AbstractListAssert, V, ObjectAssert> flatMap(Function> mapper) { + return doFlatExtracting(mapper); + } + + /** + * Extracts Iterable elements values by applying a function (which might throw a checked exception) on them and + * concatenates/flattens the result into a single list that becomes the instance under test. *

- * For example: + * Example: *

 CartoonCharacter bart = new CartoonCharacter("Bart Simpson");
    * CartoonCharacter lisa = new CartoonCharacter("Lisa Simpson");
    * CartoonCharacter maggie = new CartoonCharacter("Maggie Simpson");
+   *
    * CartoonCharacter homer = new CartoonCharacter("Homer Simpson");
    * homer.getChildren().add(bart);
    * homer.getChildren().add(lisa);
@@ -1390,14 +1499,12 @@ public  AbstractListAssert, V, ObjectAssert> flatExtr
    * assertThat(parents).flatExtracting(CartoonCharacter::getChildren)
    *                    .containsOnly(bart, lisa, maggie, pebbles);
* - * The order of extracted values is consistent with both the order of the collection itself, as well as the extracted - * collections. + * The extracted values order is consistent with both the order of the iterable itself as well as the extracted collections. * - * @param the type of elements extracted. + * @param the type of extracted values. * @param the exception type of {@link ThrowingExtractor} * @param extractor the object transforming input object to an {@code Iterable} of desired ones * @return a new assertion object whose object under test is the list of values extracted - * @throws NullPointerException if one of the {@code Iterable}'s element is null. * @since 3.7.0 */ @CheckReturnValue @@ -1405,6 +1512,43 @@ public AbstractListAssert, return doFlatExtracting(extractor); } + /** + * Maps the Iterable's elements under test by applying a mapping function (which might throw a checked exception) and + * concatenates/flattens the result into a single list that becomes the instance under test. + *

+ * Example: + *

 CartoonCharacter bart = new CartoonCharacter("Bart Simpson");
+   * CartoonCharacter lisa = new CartoonCharacter("Lisa Simpson");
+   * CartoonCharacter maggie = new CartoonCharacter("Maggie Simpson");
+   *
+   * CartoonCharacter homer = new CartoonCharacter("Homer Simpson");
+   * homer.getChildren().add(bart);
+   * homer.getChildren().add(lisa);
+   * homer.getChildren().add(maggie);
+   *
+   * CartoonCharacter pebbles = new CartoonCharacter("Pebbles Flintstone");
+   * CartoonCharacter fred = new CartoonCharacter("Fred Flintstone");
+   * fred.getChildren().add(pebbles);
+   *
+   * List<CartoonCharacter> parents = list(homer, fred);
+   *
+   * // check children property where getChildren() can throw an Exception!
+   * assertThat(parents).flatMap(CartoonCharacter::getChildren)
+   *                    .containsOnly(bart, lisa, maggie, pebbles);
+ * + * The mapped values order is consistent with both the order of the iterable itself as well as the mapped collections. + * + * @param the type of mapped values. + * @param the exception type of {@link ThrowingExtractor} + * @param mapper the object transforming input object to an {@code Iterable} of desired ones + * @return a new assertion object whose object under test is the list of values extracted + * @since 3.19.0 + */ + @CheckReturnValue + public AbstractListAssert, V, ObjectAssert> flatMap(ThrowingExtractor, EXCEPTION> mapper) { + return doFlatExtracting(mapper); + } + private AbstractListAssert, V, ObjectAssert> doFlatExtracting(Function> extractor) { List result = FieldsOrPropertiesExtractor.extract(actual, extractor).stream() .flatMap(Collection::stream) @@ -1413,18 +1557,18 @@ private AbstractListAssert, V, ObjectAssert> doFlatE } /** - * Extract multiple values from each {@code Iterable}'s element according to the given {@code Function}s - * and concatenate/flatten the extracted values in a list that is used as the new object under test. + * Extracts multiple values from each {@code Iterable}'s element according to the given {@code Function}s and + * concatenates/flattens them in a list that becomes the instance under test. *

- * If extracted values were not flattened, instead of a simple list like (given 2 extractors) : - *

element1.value1, element1.value2, element2.value1, element2.value2, ...  
- * we would get a list of list like : - *
list(element1.value1, element1.value2), list(element2.value1, element2.value2), ...  
+ * If extracted values were not flattened, instead of a simple list like (given 2 extractors): + *
  element1.value1, element1.value2, element2.value1, element2.value2, ...  
+ * we would get a list of list like: + *
  list(element1.value1, element1.value2), list(element2.value1, element2.value2), ...  
*

- * Code example: + * Example: *

 // fellowshipOfTheRing is a List<TolkienCharacter>
    *
-   * // values are extracted in order and flattened : age1, name1, age2, name2, age3 ...
+   * // values are extracted in order and flattened: age1, name1, age2, name2, age3 ...
    * assertThat(fellowshipOfTheRing).flatExtracting(TolkienCharacter::getAge,
    *                                                TolkienCharacter::getName)
    *                                .contains(33 ,"Frodo",
@@ -1432,33 +1576,68 @@ private  AbstractListAssert, V, ObjectAssert> doFlatE
    *                                          87, "Aragorn");
* * The resulting extracted values list is ordered by {@code Iterable}'s element first and then extracted values, - * this is why is in the example that age values come before names. + * this is why is in the example age values come before names. * * @param extractors all the extractors to apply on each actual {@code Iterable}'s elements * @return a new assertion object whose object under test is a flattened list of all extracted values. */ @CheckReturnValue public AbstractListAssert, Object, ObjectAssert> flatExtracting(@SuppressWarnings("unchecked") Function... extractors) { + return doFlaExtracting(extractors); + } + + /** + * Maps multiple values from each {@code Iterable}'s element according to the given {@code Function}s + * and concatenates/flattens them in a list that becomes the instance under test. + *

+ * If mapped values were not flattened, instead of a simple list like (given 2 extractors): + *

  element1.value1, element1.value2, element2.value1, element2.value2, ...  
+ * we would get a list of list like: + *
  list(element1.value1, element1.value2), list(element2.value1, element2.value2), ...  
+ *

+ * Example: + *

 // fellowshipOfTheRing is a List<TolkienCharacter>
+   *
+   * // values are extracted in order and flattened: age1, name1, age2, name2, age3 ...
+   * assertThat(fellowshipOfTheRing).flatMap(TolkienCharacter::getAge,
+   *                                         TolkienCharacter::getName)
+   *                                .contains(33 ,"Frodo",
+   *                                          1000, "Legolas",
+   *                                          87, "Aragorn");
+ * + * The resulting mapped values list is ordered by {@code Iterable}'s element first and then mapped values, this is why is + * in the example age values come before names. + * + * @param mappers all the mappers to apply on each actual {@code Iterable}'s elements + * @return a new assertion object whose object under test is a flattened list of all mapped values. + * @since 3.19.0 + */ + @CheckReturnValue + public AbstractListAssert, Object, ObjectAssert> flatMap(@SuppressWarnings("unchecked") Function... mappers) { + return doFlaExtracting(mappers); + } + + @SafeVarargs + private final AbstractListAssert, Object, ObjectAssert> doFlaExtracting(Function... extractors) { Stream actualStream = stream(actual.spliterator(), false); - List result = actualStream.flatMap(element -> Stream.of(extractors) - .map(extractor -> extractor.apply(element))) + List result = actualStream.flatMap(element -> Stream.of(extractors).map(extractor -> extractor.apply(element))) .collect(toList()); return newListAssertInstanceForMethodsChangingElementType(result); } /** - * Extract multiple values from each {@code Iterable}'s element according to the given {@link ThrowingExtractor}s - * and concatenate/flatten the extracted values in a list that is used as the new object under test. + * Extracts multiple values from each {@code Iterable}'s element according to the given {@link ThrowingExtractor}s + * and concatenates/flattens them in a list that becomes the object under test. *

- * If extracted values were not flattened, instead of a simple list like (given 2 extractors) : - *

element1.value1, element1.value2, element2.value1, element2.value2, ...  
- * we would get a list of list like : - *
list(element1.value1, element1.value2), list(element2.value1, element2.value2), ...  
+ * If extracted values were not flattened, instead of a simple list like (given 2 extractors): + *
  element1.value1, element1.value2, element2.value1, element2.value2, ...  
+ * we would get a list of list like: + *
  list(element1.value1, element1.value2), list(element2.value1, element2.value2), ...  
*

- * Code example: + * Example: *

 // fellowshipOfTheRing is a List<TolkienCharacter>
    *
-   * // values are extracted in order and flattened : age1, name1, age2, name2, age3 ...
+   * // values are extracted in order and flattened: age1, name1, age2, name2, age3 ...
    * assertThat(fellowshipOfTheRing).flatExtracting(input -> {
    *   if (input.getAge() < 20) {
    *     throw new Exception("age < 20");
@@ -1474,7 +1653,7 @@ public AbstractListAssert, Object, ObjectAssert
    *
    * The resulting extracted values list is ordered by {@code Iterable}'s element first and then extracted values,
-   * this is why is in the example that age values come before names.
+   * this is why is in the example age values come before names.
    *
    * @param  the exception type of {@link ThrowingExtractor}
    * @param extractors all the extractors to apply on each actual {@code Iterable}'s elements
@@ -1483,18 +1662,62 @@ public AbstractListAssert, Object, ObjectAssert AbstractListAssert, Object, ObjectAssert> flatExtracting(@SuppressWarnings("unchecked") ThrowingExtractor... extractors) {
+    return doFlatExtracting(extractors);
+  }
+
+  /**
+   * Maps multiple values from each {@code Iterable}'s element according to the given {@link ThrowingExtractor}s and
+   * concatenates/flattens them in a list that becomes the object under test.
+   * 

+ * If mapped values were not flattened, instead of a simple list like (given 2 mappers): + *

  element1.value1, element1.value2, element2.value1, element2.value2, ...  
+ * we would get a list of list like: + *
  list(element1.value1, element1.value2), list(element2.value1, element2.value2), ...  
+ *

+ * Example: + *

 // fellowshipOfTheRing is a List<TolkienCharacter>
+   *
+   * // values are extracted in order and flattened: age1, name1, age2, name2, age3 ...
+   * assertThat(fellowshipOfTheRing).flatMap(input -> {
+   *   if (input.getAge() < 20) {
+   *     throw new Exception("age < 20");
+   *   }
+   *   return input.getName();
+   * }, input2 -> {
+   *   if (input2.getAge() < 20) {
+   *     throw new Exception("age < 20");
+   *   }
+   *   return input2.getAge();
+   * }).contains(33 ,"Frodo",
+   *     1000, "Legolas",
+   *     87, "Aragorn");
+ * + * The resulting mapped values list is ordered by {@code Iterable}'s element first and then mapped values, this is why is in + * the example age values come before names. + * + * @param the exception type of {@link ThrowingExtractor} + * @param mappers all the mappers to apply on each actual {@code Iterable}'s elements + * @return a new assertion object whose object under test is a flattened list of all extracted values. + * @since 3.19.0 + */ + @CheckReturnValue + public AbstractListAssert, Object, ObjectAssert> flatMap(@SuppressWarnings("unchecked") ThrowingExtractor... mappers) { + return doFlatExtracting(mappers); + } + + @SafeVarargs + private final AbstractListAssert, Object, ObjectAssert> doFlatExtracting(ThrowingExtractor... mappers) { Stream actualStream = stream(actual.spliterator(), false); - List result = actualStream.flatMap(element -> Stream.of(extractors) - .map(extractor -> extractor.apply(element))) + List result = actualStream.flatMap(element -> Stream.of(mappers).map(extractor -> extractor.apply(element))) .collect(toList()); return newListAssertInstanceForMethodsChangingElementType(result); } /** - * Extract from Iterable's elements the Iterable/Array values corresponding to the given property/field name and - * concatenate them into a single list becoming the new object under test. + * Extract Iterable's elements values corresponding to the given property/field name and concatenates them into a list becoming + * the new instance under test. *

- * It allows testing the elements of extracting values that are represented by iterables or arrays. + * This allows testing the elements extracted values that are iterables or arrays. *

* For example: *

 CartoonCharacter bart = new CartoonCharacter("Bart Simpson");
@@ -1515,8 +1738,7 @@ public  AbstractListAssert
* - * The order of extracted values is consisted with both the order of the collection itself, as well as the extracted - * collections. + * The order of extracted values is consisted with both the order of the iterable itself as well as the extracted collections. * * @param fieldOrPropertyName the object transforming input object to an Iterable of desired ones * @return a new assertion object whose object under test is the list of values extracted @@ -1553,12 +1775,11 @@ public AbstractListAssert, Object, ObjectAssert - * The Tuple data corresponds to the extracted values from the Iterable's elements, for instance if you pass functions + * The {@link Tuple} data correspond to the extracted values from the Iterable's elements, for instance if you pass functions * extracting "id", "name" and "email" values then each Tuple data will be composed of an id, a name and an email - * extracted from the element of the initial Iterable (the Tuple's data order is the same as the given functions - * order). + * extracted from the element of the initial Iterable (the Tuple's data order is the same as the given functions order). *

- * Let's take a look at an example to make things clearer : + * Let's take a look at an example to make things clearer: *

 // Build a list of TolkienCharacter, a TolkienCharacter has a name, and age and a Race (a specific class)
    * // they can be public field or properties, both can be extracted.
    * List<TolkienCharacter> fellowshipOfTheRing = new ArrayList<TolkienCharacter>();
@@ -1572,7 +1793,7 @@ public AbstractListAssert, Object, ObjectAssert, Object, ObjectAssert, Tuple, ObjectAssert> extracting(@SuppressWarnings("unchecked") Function... extractors) {
+    return doExtracting(extractors);
+  }
+
+  @SafeVarargs
+  private final AbstractListAssert, Tuple, ObjectAssert> doExtracting(Function... extractors) {
     // combine all extractors into one function
     Function tupleExtractor = objectToExtractValueFrom -> new Tuple(Stream.of(extractors)
                                                                                           .map(extractor -> extractor.apply(objectToExtractValueFrom))
@@ -1605,19 +1831,72 @@ public AbstractListAssert, Tuple, ObjectAssert>
     return newListAssertInstanceForMethodsChangingElementType(tuples);
   }
 
+  /**
+   * Use the given {@link Function}s to map the {@link Iterable}'s elements into a {@link List} of {@link Tuple}s
+   * (a simple data structure containing the mapped values), this new list becoming the object under test.
+   * 

+ * This allows you to test values from the {@link Iterable}'s elements instead of testing the elements themselves, which + * sometimes can be much less work! + *

+ * The {@link Tuple} data correspond to the extracted values from the Iterable's elements, for instance if you pass functions + * mapping "id", "name" and "email" values then each {@code Tuple} data will be composed of an id, a name and an email + * mapped from the element of the initial Iterable (the Tuple's data order is the same as the given functions order). + *

+ * Let's take a look at an example to make things clearer: + *

 // Build a list of TolkienCharacter, a TolkienCharacter has a name, and age and a Race (a specific class)
+   * // they can be public field or properties, both can be extracted.
+   * List<TolkienCharacter> fellowshipOfTheRing = new ArrayList<TolkienCharacter>();
+   *
+   * fellowshipOfTheRing.add(new TolkienCharacter("Frodo", 33, HOBBIT));
+   * fellowshipOfTheRing.add(new TolkienCharacter("Sam", 38, HOBBIT));
+   * fellowshipOfTheRing.add(new TolkienCharacter("Gandalf", 2020, MAIA));
+   * fellowshipOfTheRing.add(new TolkienCharacter("Legolas", 1000, ELF));
+   * fellowshipOfTheRing.add(new TolkienCharacter("Pippin", 28, HOBBIT));
+   * fellowshipOfTheRing.add(new TolkienCharacter("Gimli", 139, DWARF));
+   * fellowshipOfTheRing.add(new TolkienCharacter("Aragorn", 87, MAN);
+   * fellowshipOfTheRing.add(new TolkienCharacter("Boromir", 37, MAN));
+   *
+   * // let's verify 'name', 'age' and Race of some TolkienCharacter in fellowshipOfTheRing:
+   * assertThat(fellowshipOfTheRing).map(TolkienCharacter::getName,
+   *                                     character -> character.getAge(),
+   *                                     TolkienCharacter::getRace)
+   *                                .containsOnly(tuple("Frodo", 33, HOBBIT),
+   *                                              tuple("Sam", 38, HOBBIT),
+   *                                              tuple("Gandalf", 2020, MAIA),
+   *                                              tuple("Legolas", 1000, ELF),
+   *                                              tuple("Pippin", 28, HOBBIT),
+   *                                              tuple("Gimli", 139, DWARF),
+   *                                              tuple("Aragorn", 87, MAN),
+   *                                              tuple("Boromir", 37, MAN));
+ * You can use lambda expression or a method reference to extract the expected values. + *

+ * Use {@link Tuple#tuple(Object...)} to initialize the expected values. + *

+ * Note that the order of the extracted tuples list is consistent with the iteration order of the Iterable under test, + * for example if it's a {@link HashSet}, you won't be able to make any assumptions on the extracted tuples order. + * + * @param mappers the mapper functions to extract a value from an element of the Iterable under test. + * @return a new assertion object whose object under test is the list of Tuples containing the extracted values. + * @since 3.19.0 + */ + @CheckReturnValue + public AbstractListAssert, Tuple, ObjectAssert> map(@SuppressWarnings("unchecked") Function... mappers) { + return doExtracting(mappers); + } + /** * Extract the given property/field values from each {@code Iterable}'s element and * flatten the extracted values in a list that is used as the new object under test. *

- * Given 2 properties, if the extracted values were not flattened, instead having a simple list like : - *

element1.value1, element1.value2, element2.value1, element2.value2, ...  
- * ... we would get a list of list : - *
list(element1.value1, element1.value2), list(element2.value1, element2.value2), ...  
+ * Given 2 properties, if the extracted values were not flattened, instead having a simple list like: + *
  element1.value1, element1.value2, element2.value1, element2.value2, ...  
+ * ... we would get a list of list: + *
  list(element1.value1, element1.value2), list(element2.value1, element2.value2), ...  
*

- * Code example: + * Example: *

 // fellowshipOfTheRing is a List<TolkienCharacter>
    *
-   * // values are extracted in order and flattened : age1, name1, age2, name2, age3 ...
+   * // values are extracted in order and flattened: age1, name1, age2, name2, age3 ...
    * assertThat(fellowshipOfTheRing).flatExtracting("age", "name")
    *                                .contains(33 ,"Frodo",
    *                                          1000, "Legolas",
@@ -2386,7 +2665,7 @@ public SELF filteredOnNull(String propertyOrFieldName) {
    * Filters the iterable under test keeping only elements having a property or field matching the filter expressed with
    * the {@link FilterOperator}, the property/field is specified by {@code propertyOrFieldName} parameter.
    * 

- * The existing filters are : + * The existing filters are: *