diff --git a/pom.xml b/pom.xml
index 9af879b..1748dfb 100644
--- a/pom.xml
+++ b/pom.xml
@@ -77,6 +77,12 @@
org.hamcrest
hamcrest
+
+ org.junit.jupiter
+ junit-jupiter-api
+ 5.6.2
+ test
+
org.junit.jupiter
junit-jupiter-params
diff --git a/src/main/java/org/llorllale/cactoos/matchers/Assert.java b/src/main/java/org/llorllale/cactoos/matchers/Assert.java
new file mode 100644
index 0000000..7928a25
--- /dev/null
+++ b/src/main/java/org/llorllale/cactoos/matchers/Assert.java
@@ -0,0 +1,48 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) for portions of project cactoos-matchers are held by
+ * Yegor Bugayenko, 2017-2018, as part of project cactoos.
+ * All other copyright for project cactoos-matchers are held by
+ * George Aristy, 2018-2020.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+package org.llorllale.cactoos.matchers;
+
+import org.cactoos.Text;
+
+/**
+ * Assertion with textual description.
+ *
+ * @since 1.0.0
+ */
+public interface Assert {
+ /**
+ * Description.
+ * @return Message of assert.
+ */
+ Text description();
+
+ /**
+ * Affirm this assertion.
+ * @throws AssertionError if this assertion is refuted
+ */
+ void affirm() throws AssertionError;
+}
diff --git a/src/main/java/org/llorllale/cactoos/matchers/AssertAll.java b/src/main/java/org/llorllale/cactoos/matchers/AssertAll.java
new file mode 100644
index 0000000..4fb162e
--- /dev/null
+++ b/src/main/java/org/llorllale/cactoos/matchers/AssertAll.java
@@ -0,0 +1,138 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) for portions of project cactoos-matchers are held by
+ * Yegor Bugayenko, 2017-2018, as part of project cactoos.
+ * All other copyright for project cactoos-matchers are held by
+ * George Aristy, 2018-2020.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+package org.llorllale.cactoos.matchers;
+
+import org.cactoos.Text;
+import org.cactoos.iterable.IterableOf;
+import org.cactoos.iterable.MappedWithIndex;
+import org.cactoos.scalar.Folded;
+import org.cactoos.scalar.Mapped;
+import org.cactoos.scalar.Unchecked;
+import org.cactoos.text.FormattedText;
+import org.cactoos.text.Joined;
+import org.cactoos.text.TextOf;
+import org.cactoos.text.UncheckedText;
+
+/**
+ * Group assert.
+ * Fails if one of assertions fails.
+ *
+ * @since 1.0.0
+ * @checkstyle ClassDataAbstractionCoupling (100 lines)
+ */
+public final class AssertAll implements Assert {
+
+ /**
+ * Assertions.
+ */
+ private final Iterable extends Assert> assertions;
+
+ /**
+ * Description.
+ */
+ private final Text desc;
+
+ /**
+ * Ctor.
+ * @param description Description.
+ * @param assertions Assertions.
+ */
+ public AssertAll(
+ final String description,
+ final Assert... assertions
+ ) {
+ this(
+ description,
+ new IterableOf<>(assertions)
+ );
+ }
+
+ /**
+ * Ctor.
+ * @param description Description.
+ * @param assertions Assertions.
+ */
+ public AssertAll(
+ final String description,
+ final Iterable extends Assert> assertions
+ ) {
+ this.desc = new FormattedText(
+ "%s: %s",
+ new TextOf(description),
+ new Joined(
+ new TextOf(", "),
+ new MappedWithIndex<>(
+ (check, num) -> new FormattedText(
+ "%d) %s",
+ num + 1,
+ check.description().asString()
+ ),
+ assertions
+ )
+ )
+ );
+ this.assertions = assertions;
+ }
+
+ @Override
+ public Text description() {
+ return this.desc;
+ }
+
+ @SuppressWarnings(
+ { "PMD.AvoidCatchingGenericException", "PMD.AvoidCatchingThrowable" }
+ )
+ @Override
+ public void affirm() throws AssertionError {
+ new Unchecked<>(
+ new Mapped(
+ res -> {
+ if (res.getSuppressed().length > 0) {
+ throw res;
+ }
+ return null;
+ },
+ new Folded<>(
+ new AssertionError(
+ new UncheckedText(this.desc).asString()
+ ),
+ (res, check) -> {
+ // @checkstyle IllegalCatchCheck (5 lines)
+ try {
+ check.affirm();
+ } catch (final Throwable ex) {
+ res.addSuppressed(ex);
+ }
+ return res;
+ },
+ this.assertions
+ )
+ )
+ ).value();
+ }
+
+}
diff --git a/src/main/java/org/llorllale/cactoos/matchers/AssertWith.java b/src/main/java/org/llorllale/cactoos/matchers/AssertWith.java
new file mode 100644
index 0000000..d1309ba
--- /dev/null
+++ b/src/main/java/org/llorllale/cactoos/matchers/AssertWith.java
@@ -0,0 +1,74 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) for portions of project cactoos-matchers are held by
+ * Yegor Bugayenko, 2017-2018, as part of project cactoos.
+ * All other copyright for project cactoos-matchers are held by
+ * George Aristy, 2018-2020.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+package org.llorllale.cactoos.matchers;
+
+import org.cactoos.Func;
+import org.cactoos.Text;
+import org.cactoos.func.UncheckedFunc;
+
+/**
+ * Assert with value.
+ * @param Type of value
+ *
+ * @since 1.0.0
+ */
+public final class AssertWith implements Assert {
+ /**
+ * Value.
+ */
+ private final T value;
+
+ /**
+ * Assertion.
+ */
+ private final Func super T, ? extends Assert> func;
+
+ /**
+ * Ctor.
+ * @param value Value.
+ * @param func Function to produce assertion.
+ */
+ public AssertWith(
+ final T value,
+ final Func super T, ? extends Assert> func
+ ) {
+ this.value = value;
+ this.func = func;
+ }
+
+ @Override
+ public Text description() {
+ return new UncheckedFunc<>(this.func)
+ .apply(this.value)
+ .description();
+ }
+
+ @Override
+ public void affirm() throws AssertionError {
+ new UncheckedFunc<>(this.func).apply(this.value).affirm();
+ }
+}
diff --git a/src/main/java/org/llorllale/cactoos/matchers/Assertion.java b/src/main/java/org/llorllale/cactoos/matchers/Assertion.java
index 0d3df7b..5f5354b 100644
--- a/src/main/java/org/llorllale/cactoos/matchers/Assertion.java
+++ b/src/main/java/org/llorllale/cactoos/matchers/Assertion.java
@@ -26,6 +26,8 @@
*/
package org.llorllale.cactoos.matchers;
+import org.cactoos.Text;
+import org.cactoos.text.TextOf;
import org.hamcrest.Description;
import org.hamcrest.Matcher;
import org.hamcrest.StringDescription;
@@ -42,7 +44,7 @@
* new Assertion<>(
* "must match the string",
* new TextOf("string"),
- * new TextIs("string")
+ * new IsText("string")
* ).affirm(); // value is affirmed
* }
* }
@@ -67,7 +69,7 @@
* Assertion, and ban all overloads of the former in forbidden-apis.txt.
* We should also look into banning common matchers like Matchers.is(), etc.
*/
-public final class Assertion {
+public final class Assertion implements Assert {
/**
* Message.
@@ -98,10 +100,7 @@ public Assertion(
this.matcher = matcher;
}
- /**
- * Affirm this assertion.
- * @throws AssertionError if this assertion is refuted
- */
+ @Override
public void affirm() throws AssertionError {
if (!this.matcher.matches(this.test)) {
final Description text = new StringDescription();
@@ -116,4 +115,9 @@ public void affirm() throws AssertionError {
throw new AssertionError(text.toString());
}
}
+
+ @Override
+ public Text description() {
+ return new TextOf(this.msg);
+ }
}
diff --git a/src/main/java/org/llorllale/cactoos/matchers/FailsWith.java b/src/main/java/org/llorllale/cactoos/matchers/FailsWith.java
new file mode 100644
index 0000000..a557c55
--- /dev/null
+++ b/src/main/java/org/llorllale/cactoos/matchers/FailsWith.java
@@ -0,0 +1,86 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) for portions of project cactoos-matchers are held by
+ * Yegor Bugayenko, 2017-2018, as part of project cactoos.
+ * All other copyright for project cactoos-matchers are held by
+ * George Aristy, 2018-2020.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+package org.llorllale.cactoos.matchers;
+
+import org.cactoos.scalar.ScalarOf;
+import org.hamcrest.Matcher;
+import org.hamcrest.core.IsAnything;
+import org.hamcrest.core.IsEqual;
+
+/**
+ * Matcher for Assert that fails.
+ *
+ * @since 1.0.0
+ */
+public final class FailsWith extends MatcherEnvelope {
+ /**
+ * Ctor.
+ * @param type Expected error type.
+ * @param msg Expected message.
+ */
+ public FailsWith(
+ final Class extends Throwable> type,
+ final Matcher msg
+ ) {
+ super(
+ new Satisfies<>(
+ new Throws<>(msg, type),
+ check -> new ScalarOf<>(
+ check::affirm, true
+ )
+ )
+ );
+ }
+
+ /**
+ * Ctor.
+ * @param message Expected message.
+ */
+ public FailsWith(final Matcher message) {
+ this(
+ AssertionError.class, message
+ );
+ }
+
+ /**
+ * Ctor.
+ * @param message Expected message.
+ */
+ public FailsWith(final String message) {
+ this(
+ new IsEqual<>(message)
+ );
+ }
+
+ /**
+ * Ctor.
+ * @param error Expected error type.
+ */
+ public FailsWith(final Class extends Throwable> error) {
+ this(error, new IsAnything<>());
+ }
+}
diff --git a/src/main/java/org/llorllale/cactoos/matchers/Passes.java b/src/main/java/org/llorllale/cactoos/matchers/Passes.java
new file mode 100644
index 0000000..dfe4e6b
--- /dev/null
+++ b/src/main/java/org/llorllale/cactoos/matchers/Passes.java
@@ -0,0 +1,53 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) for portions of project cactoos-matchers are held by
+ * Yegor Bugayenko, 2017-2018, as part of project cactoos.
+ * All other copyright for project cactoos-matchers are held by
+ * George Aristy, 2018-2020.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+package org.llorllale.cactoos.matchers;
+
+import org.cactoos.scalar.ScalarOf;
+import org.hamcrest.core.IsNot;
+
+/**
+ * Matcher for Assert that passes.
+ *
+ * @since 1.0.0
+ */
+public final class Passes extends MatcherEnvelope {
+ /**
+ * Ctor.
+ */
+ public Passes() {
+ super(
+ new Satisfies<>(
+ new IsNot<>(
+ new Throws<>(AssertionError.class)
+ ),
+ check -> new ScalarOf<>(
+ check::affirm, true
+ )
+ )
+ );
+ }
+}
diff --git a/src/test/java/org/llorllale/cactoos/matchers/AssertAllTest.java b/src/test/java/org/llorllale/cactoos/matchers/AssertAllTest.java
new file mode 100644
index 0000000..9bae3ed
--- /dev/null
+++ b/src/test/java/org/llorllale/cactoos/matchers/AssertAllTest.java
@@ -0,0 +1,61 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) for portions of project cactoos-matchers are held by
+ * Yegor Bugayenko, 2017-2018, as part of project cactoos.
+ * All other copyright for project cactoos-matchers are held by
+ * George Aristy, 2018-2020.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+package org.llorllale.cactoos.matchers;
+
+import org.cactoos.iterable.IterableOf;
+import org.hamcrest.core.IsEqual;
+
+/**
+ * Test for {@link AssertAll}.
+ *
+ * @since 1.0.0
+ */
+@SuppressWarnings({"unchecked", "PMD.TestClassWithoutTestCases"})
+final class AssertAllTest extends TestEnvelope {
+ AssertAllTest() {
+ super(
+ new Assertion<>(
+ "assertion must fail if one of assertion fails",
+ new AssertAll(
+ "must fail on second",
+ new Assertion<>("must pass", 1, new IsEqual<>(1)),
+ new Assertion<>("must fail", 1, new IsEqual<>(2))
+ ),
+ new FailsWith("must fail on second: 1) must pass, 2) must fail")
+ ),
+ new Assertion<>(
+ "empty group must pass",
+ new AssertAll(
+ "must pass for empty iterable",
+ new IterableOf<>()
+ ),
+ new Passes()
+ )
+ );
+ }
+
+}
diff --git a/src/test/java/org/llorllale/cactoos/matchers/AssertionTest.java b/src/test/java/org/llorllale/cactoos/matchers/AssertionTest.java
index 2660257..d9ccb9d 100644
--- a/src/test/java/org/llorllale/cactoos/matchers/AssertionTest.java
+++ b/src/test/java/org/llorllale/cactoos/matchers/AssertionTest.java
@@ -28,107 +28,82 @@
import java.util.concurrent.atomic.AtomicInteger;
import org.cactoos.Scalar;
-import org.cactoos.text.Joined;
import org.cactoos.text.TextOf;
-import org.hamcrest.core.IsEqual;
-import org.junit.jupiter.api.Assertions;
-import org.junit.jupiter.api.Test;
/**
* Tests for {@link Assertion}.
* @since 1.0.0
* @checkstyle ClassDataAbstractionCouplingCheck (500 lines)
*/
-@SuppressWarnings("PMD.AvoidDuplicateLiterals")
-final class AssertionTest {
- /**
- * Assertion can be affirmed if the operation being tested matches.
- */
- @Test
- void affirmIfResultMatches() {
- final String expected = "abc123";
- new Assertion<>(
- "must affirm the assertion if the test's result is as expected",
- new TextOf(expected),
- new IsText(expected)
- ).affirm();
- }
-
- /**
- * Assertion must be refuted if the operation being tested does not
- * match.
- *
- * @throws Exception if something goes wrong.
- */
- @Test
- void refuteIfResultDoesNotMatch() throws Exception {
- Assertions.assertThrows(
- AssertionError.class,
- () -> new Assertion<>(
- "must refute the assertion if the test's result is not as expected",
- new TextOf("test"),
- new IsText("no match")
- ).affirm(),
- new Joined(
- System.lineSeparator(),
- "must refute the assertion if the test's result is not as expected",
- "Expected: Text with value \"no match\"",
- " but was: Text is \"test\""
- ).asString()
- );
- }
+@SuppressWarnings({"unchecked", "PMD.AvoidDuplicateLiterals",
+ "PMD.TestClassWithoutTestCases"})
+final class AssertionTest extends TestEnvelope {
- /**
- * Assertion cannot be affirmed if the operation being tested throws an
- * unexpected error.
- */
- @Test
- void refuteIfErrorDoesNotMatch() {
- Assertions.assertThrows(
- IllegalStateException.class,
- () -> new Assertion>(
- "must fail if the test throws an unexpected error",
- () -> {
- throw new IllegalStateException();
- },
- new HasValue<>("no match")
- ).affirm()
+ AssertionTest() {
+ super(
+ new Assertion<>(
+ "Assertion can be affirmed if the operation being tested matches.",
+ new Assertion<>(
+ "must affirm the assertion if the test's result is as expected",
+ new TextOf("abc123"),
+ new IsText("abc123")
+ ),
+ new Passes()
+ ),
+ new Assertion<>(
+ "Assertion must be refuted if the operation being tested does not match.",
+ new Assertion<>(
+ "must refute the assertion if the test's result is not as expected",
+ new TextOf("test"),
+ new IsText("no match")
+ ),
+ new FailsWith(
+ AssertionError.class
+ )
+ ),
+ new Assertion<>(
+ "Must not be affirmed if the operation being tested throws an unexpected error",
+ new Assertion>(
+ "must fail if the test throws an unexpected error",
+ () -> {
+ throw new IllegalStateException();
+ },
+ new HasValue<>("no match")
+ ),
+ new FailsWith(
+ IllegalStateException.class
+ )
+ ),
+ new Assertion<>(
+ "Assertion can be affirmed if the operation being tested throws an expected error.",
+ new Assertion<>(
+ "must affirm the assertion if the test throws the expected error",
+ () -> {
+ throw new IllegalStateException("this is a test");
+ },
+ new Throws<>("this is a test", IllegalStateException.class)
+ ),
+ new Passes()
+ ),
+ new AssertWith<>(
+ new AtomicInteger(0),
+ quantity -> new AssertAll(
+ "The scalar within Assertion executed is only once",
+ new Assertion<>(
+ "must match the exception",
+ () -> {
+ quantity.incrementAndGet();
+ throw new IllegalStateException("this is a test");
+ },
+ new Throws<>("this is a test", IllegalStateException.class)
+ ),
+ new Assertion<>(
+ "must execute scalar only once",
+ quantity::get,
+ new HasValue<>(1)
+ )
+ )
+ )
);
}
-
- /**
- * Assertion can be affirmed if the operation being tested throws an
- * expected error.
- */
- @Test
- void affirmIfErrorMatches() {
- new Assertion<>(
- "must affirm the assertion if the test throws the expected error",
- () -> {
- throw new IllegalStateException("this is a test");
- },
- new Throws<>("this is a test", IllegalStateException.class)
- ).affirm();
- }
-
- /**
- * The scalar within Assertion executed is only once.
- */
- @Test
- void scalarIsExecutedOnce() {
- final AtomicInteger quantity = new AtomicInteger(0);
- new Assertion<>(
- "must match the exception",
- () -> {
- quantity.incrementAndGet();
- throw new IllegalStateException("this is a test");
- },
- new Throws<>("this is a test", IllegalStateException.class)
- ).affirm();
- new Assertion<>(
- "must execute scalar only once",
- quantity.get(),
- new IsEqual<>(1)
- ).affirm();
- }
}
diff --git a/src/test/java/org/llorllale/cactoos/matchers/TestEnvelope.java b/src/test/java/org/llorllale/cactoos/matchers/TestEnvelope.java
new file mode 100644
index 0000000..60ef18a
--- /dev/null
+++ b/src/test/java/org/llorllale/cactoos/matchers/TestEnvelope.java
@@ -0,0 +1,86 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) for portions of project cactoos-matchers are held by
+ * Yegor Bugayenko, 2017-2018, as part of project cactoos.
+ * All other copyright for project cactoos-matchers are held by
+ * George Aristy, 2018-2020.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+package org.llorllale.cactoos.matchers;
+
+import org.cactoos.iterable.IterableOf;
+import org.cactoos.iterable.Mapped;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.DynamicNode;
+import org.junit.jupiter.api.DynamicTest;
+import org.junit.jupiter.api.TestFactory;
+
+/**
+ * Template for tests.
+ *
+ * @see Assert
+ *
+ * @since 1.0.0
+ */
+@SuppressWarnings({"PMD.TestClassWithoutTestCases",
+ "PMD.AbstractClassWithoutAbstractMethod"})
+public abstract class TestEnvelope {
+ /**
+ * Assertions.
+ */
+ private final Iterable extends Assert> checks;
+
+ /**
+ * Ctor.
+ * @param checks Assertions.
+ */
+ protected TestEnvelope(
+ final Assert... checks
+ ) {
+ this(new IterableOf<>(checks));
+ }
+
+ /**
+ * Ctor.
+ * @param checks Assertions.
+ */
+ protected TestEnvelope(
+ final Iterable extends Assert> checks
+ ) {
+ this.checks = checks;
+ }
+
+ /**
+ * Test factory.
+ * @return Tests as DynamicNode.
+ */
+ @TestFactory
+ @DisplayName("Tests: ")
+ public final Iterable tests() {
+ return new Mapped<>(
+ check -> DynamicTest.dynamicTest(
+ check.description().asString(),
+ check::affirm
+ ),
+ this.checks
+ );
+ }
+}