From e16fcaf420a88873d0c2ce1dfec1c39015a3ca40 Mon Sep 17 00:00:00 2001 From: Marten Gajda Date: Fri, 9 Feb 2024 23:14:44 +0100 Subject: [PATCH] Dedicated Hamcrest Adapter module, closes #109 (#173) Provide a separate module containing adapters between Hamcrest and Confidence. This deprecates the Hamcrest `Quality` in confidence-core. --- README.md | 18 ++++- confidence-core/build.gradle | 2 +- .../confidence/quality/compat/Hamcrest.java | 5 +- confidence-hamcrest/build.gradle | 26 +++++++ .../hamcrest/matcher/QualifiesAs.java | 59 ++++++++++++++++ .../confidence/hamcrest/quality/Matches.java | 67 +++++++++++++++++++ .../hamcrest/matcher/QualifiesAsTest.java | 41 ++++++++++++ .../hamcrest/quality/MatchesTest.java | 42 ++++++++++++ settings.gradle | 1 + 9 files changed, 256 insertions(+), 5 deletions(-) create mode 100644 confidence-hamcrest/build.gradle create mode 100644 confidence-hamcrest/src/main/java/org/saynotobugs/confidence/hamcrest/matcher/QualifiesAs.java create mode 100644 confidence-hamcrest/src/main/java/org/saynotobugs/confidence/hamcrest/quality/Matches.java create mode 100644 confidence-hamcrest/src/test/java/org/saynotobugs/confidence/hamcrest/matcher/QualifiesAsTest.java create mode 100644 confidence-hamcrest/src/test/java/org/saynotobugs/confidence/hamcrest/quality/MatchesTest.java diff --git a/README.md b/README.md index c64a77d5..4a6a2eef 100644 --- a/README.md +++ b/README.md @@ -153,11 +153,23 @@ General note on matching arrays: arrays (including ones of primitive types) can *works with arrays of primitive types -Confidence provides an adapter to use Hamcrest `Matcher`s in Confidence assertions. -The adapter `Quality` is called `hamcrest` and you just pass a `Matcher` to it like in: +## confidence-hamcrest + +Confidence provides adapters to use Hamcrest `Matcher`s in Confidence assertions and Confidence `Quality`s where +Hamcrest `Matchers` are required (for instance when working with rest-assured, mockito or awaitlity). + +You can use Hamcrest `Matcher`s with Confidence by including the `confidence-hamcrest` artifact and adapting it with +the `matches` adapter `Quality`. + +```java +assertThat(List.of(1,2,5,10,11), matches(hasItem(2))); +``` + +The same module also provides a Hamcrest `Matcher` called `qualifiesAs` to use Confidence `Quality`s in a test +that requires a `Matcher`: ```java -assertThat(List.of(1,2,5,10,11), hamcrest(hasItem(2))); +response.then().body("id", qualifiesAs(jsonStringOf(object(with("foo", equalTo("bar")))))) ``` # JUnit Confidence TestEngine diff --git a/confidence-core/build.gradle b/confidence-core/build.gradle index 68dedff2..b8cacd6b 100644 --- a/confidence-core/build.gradle +++ b/confidence-core/build.gradle @@ -12,7 +12,7 @@ dependencies { compileOnly libs.srcless.annotations annotationProcessor libs.bundles.srcless.processors compileOnly libs.hamcrest - implementation libs.jems2 + api libs.jems2 testImplementation project(':confidence-test') testImplementation libs.jems2.testing diff --git a/confidence-core/src/main/java/org/saynotobugs/confidence/quality/compat/Hamcrest.java b/confidence-core/src/main/java/org/saynotobugs/confidence/quality/compat/Hamcrest.java index cba59b1b..677109c0 100644 --- a/confidence-core/src/main/java/org/saynotobugs/confidence/quality/compat/Hamcrest.java +++ b/confidence-core/src/main/java/org/saynotobugs/confidence/quality/compat/Hamcrest.java @@ -27,7 +27,10 @@ import org.saynotobugs.confidence.assessment.Pass; import org.saynotobugs.confidence.description.Text; - +/** + * @deprecated in favour of the Matches Quality in the confidence-hamcrest module + */ +@Deprecated @StaticFactories(value = "Core", packageName = "org.saynotobugs.confidence.quality") public final class Hamcrest implements Quality { diff --git a/confidence-hamcrest/build.gradle b/confidence-hamcrest/build.gradle new file mode 100644 index 00000000..628e6cf4 --- /dev/null +++ b/confidence-hamcrest/build.gradle @@ -0,0 +1,26 @@ +plugins { + id 'java-library' +} +apply from: '../jacoco.gradle' +apply from: '../publish.gradle' + +sourceCompatibility = JavaVersion.VERSION_1_8 +targetCompatibility = JavaVersion.VERSION_1_8 + +dependencies { + compileOnly libs.eclipse.jdt.anntation + compileOnly libs.srcless.annotations + annotationProcessor libs.bundles.srcless.processors + + api libs.hamcrest + api project(':confidence-core') + + testImplementation project(':confidence-test') + testImplementation libs.jems2.testing + testImplementation libs.junit.jupiter.api + testRuntimeOnly libs.junit.jupiter.engine +} + +test { + useJUnitPlatform() +} \ No newline at end of file diff --git a/confidence-hamcrest/src/main/java/org/saynotobugs/confidence/hamcrest/matcher/QualifiesAs.java b/confidence-hamcrest/src/main/java/org/saynotobugs/confidence/hamcrest/matcher/QualifiesAs.java new file mode 100644 index 00000000..15e23dbb --- /dev/null +++ b/confidence-hamcrest/src/main/java/org/saynotobugs/confidence/hamcrest/matcher/QualifiesAs.java @@ -0,0 +1,59 @@ +/* + * Copyright 2024 dmfs GmbH + * + * + * 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. + * + */ + +package org.saynotobugs.confidence.hamcrest.matcher; + +import org.dmfs.srcless.annotations.staticfactory.StaticFactories; +import org.hamcrest.Description; +import org.hamcrest.TypeSafeDiagnosingMatcher; +import org.saynotobugs.confidence.Assessment; +import org.saynotobugs.confidence.Quality; +import org.saynotobugs.confidence.Scribe; +import org.saynotobugs.confidence.scribe.StringBuilderScribe; + +/** + * A Hamcrest {@link org.hamcrest.Matcher} of {@code T} that delegates to a {@link Quality}. + */ +@StaticFactories(value = "Hamcrest", packageName = "org.saynotobugs.confidence.hamcrest") +public final class QualifiesAs extends TypeSafeDiagnosingMatcher +{ + private final Quality mQuality; + + public QualifiesAs(Quality quality) + { + mQuality = quality; + } + + @Override + protected boolean matchesSafely(T item, Description mismatchDescription) + { + Scribe scribe = new StringBuilderScribe(""); + Assessment assessment = mQuality.assessmentOf(item); + assessment.description().describeTo(scribe); + mismatchDescription.appendText(scribe.toString()); + return assessment.isSuccess(); + } + + @Override + public void describeTo(Description description) + { + Scribe scribe = new StringBuilderScribe(""); + mQuality.description().describeTo(scribe); + description.appendText(scribe.toString()); + } +} diff --git a/confidence-hamcrest/src/main/java/org/saynotobugs/confidence/hamcrest/quality/Matches.java b/confidence-hamcrest/src/main/java/org/saynotobugs/confidence/hamcrest/quality/Matches.java new file mode 100644 index 00000000..0d793aae --- /dev/null +++ b/confidence-hamcrest/src/main/java/org/saynotobugs/confidence/hamcrest/quality/Matches.java @@ -0,0 +1,67 @@ +/* + * Copyright 2024 dmfs GmbH + * + * + * 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. + * + */ + +package org.saynotobugs.confidence.hamcrest.quality; + +import org.dmfs.srcless.annotations.staticfactory.StaticFactories; +import org.hamcrest.StringDescription; +import org.saynotobugs.confidence.Assessment; +import org.saynotobugs.confidence.Description; +import org.saynotobugs.confidence.Quality; +import org.saynotobugs.confidence.assessment.Fail; +import org.saynotobugs.confidence.assessment.Pass; +import org.saynotobugs.confidence.description.Text; + + +/** + * A {@link Quality} of {@code T} that delegates to a Hamcrest {@link org.hamcrest.Matcher}. + */ +@StaticFactories(value = "Hamcrest", packageName = "org.saynotobugs.confidence.hamcrest") +public final class Matches implements Quality +{ + private final org.hamcrest.Matcher mDelegate; + + + public Matches(org.hamcrest.Matcher delegate) + { + mDelegate = delegate; + } + + + @Override + public Assessment assessmentOf(T candidate) + { + if (mDelegate.matches(candidate)) + { + return new Pass(); + } + org.hamcrest.Description mismatch = new StringDescription(); + mDelegate.describeMismatch(candidate, mismatch); + return new Fail(new Text(mismatch.toString())); + } + + + @Override + public Description description() + { + org.hamcrest.Description expected = new StringDescription(); + mDelegate.describeTo(expected); + return new Text(expected.toString()); + } + +} diff --git a/confidence-hamcrest/src/test/java/org/saynotobugs/confidence/hamcrest/matcher/QualifiesAsTest.java b/confidence-hamcrest/src/test/java/org/saynotobugs/confidence/hamcrest/matcher/QualifiesAsTest.java new file mode 100644 index 00000000..fbee08ad --- /dev/null +++ b/confidence-hamcrest/src/test/java/org/saynotobugs/confidence/hamcrest/matcher/QualifiesAsTest.java @@ -0,0 +1,41 @@ +/* + * Copyright 2024 dmfs GmbH + * + * + * 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. + * + */ + +package org.saynotobugs.confidence.hamcrest.matcher; + +import org.junit.jupiter.api.Test; +import org.saynotobugs.confidence.quality.object.EqualTo; + +import static org.dmfs.jems2.hamcrest.matchers.matcher.MatcherMatcher.*; +import static org.hamcrest.CoreMatchers.allOf; +import static org.hamcrest.MatcherAssert.assertThat; + +class QualifiesAsTest +{ + @Test + void test() + { + assertThat(new QualifiesAs<>(new EqualTo<>("123")), + allOf( + matches("123"), + mismatches("12", "\"12\""), + describesAs("\"123\"") + )); + } + +} \ No newline at end of file diff --git a/confidence-hamcrest/src/test/java/org/saynotobugs/confidence/hamcrest/quality/MatchesTest.java b/confidence-hamcrest/src/test/java/org/saynotobugs/confidence/hamcrest/quality/MatchesTest.java new file mode 100644 index 00000000..47666fe2 --- /dev/null +++ b/confidence-hamcrest/src/test/java/org/saynotobugs/confidence/hamcrest/quality/MatchesTest.java @@ -0,0 +1,42 @@ +/* + * Copyright 2024 dmfs GmbH + * + * + * 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. + * + */ + +package org.saynotobugs.confidence.hamcrest.quality; + +import org.hamcrest.Matchers; +import org.junit.jupiter.api.Test; +import org.saynotobugs.confidence.quality.composite.AllOf; +import org.saynotobugs.confidence.test.quality.Fails; +import org.saynotobugs.confidence.test.quality.HasDescription; +import org.saynotobugs.confidence.test.quality.Passes; + +import static org.saynotobugs.confidence.Assertion.assertThat; + +class MatchesTest +{ + @Test + void test() + { + assertThat(new Matches<>(Matchers.equalTo(123)), + new AllOf<>( + new Passes<>(123), + new Fails<>(12, "was <12>"), + new HasDescription("<123>") + )); + } +} \ No newline at end of file diff --git a/settings.gradle b/settings.gradle index b3382fca..758eace7 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,5 +1,6 @@ rootProject.name = 'confidence' include 'confidence-core' +include 'confidence-hamcrest' include 'confidence-asm' include 'confidence-json' include 'confidence-mockito4'