From be906bc137c0ea3f83a7711492f5f54ebf043c37 Mon Sep 17 00:00:00 2001 From: Marten Gajda Date: Sat, 30 Dec 2023 18:53:13 +0100 Subject: [PATCH] Add ordered Quality of Iterables ordered by a given Comparator, closes #157 (#158) --- .../confidence/quality/iterable/Ordered.java | 85 +++++++++++++++++++ .../quality/iterable/OrderedTest.java | 67 +++++++++++++++ 2 files changed, 152 insertions(+) create mode 100644 confidence-core/src/main/java/org/saynotobugs/confidence/quality/iterable/Ordered.java create mode 100644 confidence-core/src/test/java/org/saynotobugs/confidence/quality/iterable/OrderedTest.java diff --git a/confidence-core/src/main/java/org/saynotobugs/confidence/quality/iterable/Ordered.java b/confidence-core/src/main/java/org/saynotobugs/confidence/quality/iterable/Ordered.java new file mode 100644 index 00000000..b8817c46 --- /dev/null +++ b/confidence-core/src/main/java/org/saynotobugs/confidence/quality/iterable/Ordered.java @@ -0,0 +1,85 @@ +/* + * Copyright 2023 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.quality.iterable; + +import org.dmfs.srcless.annotations.staticfactory.StaticFactories; +import org.saynotobugs.confidence.Assessment; +import org.saynotobugs.confidence.Quality; +import org.saynotobugs.confidence.assessment.AllPassed; +import org.saynotobugs.confidence.assessment.PassIf; +import org.saynotobugs.confidence.description.Spaced; +import org.saynotobugs.confidence.description.Text; +import org.saynotobugs.confidence.description.Value; +import org.saynotobugs.confidence.quality.composite.QualityComposition; + +import java.util.Comparator; +import java.util.Iterator; + +import static org.saynotobugs.confidence.description.LiteralDescription.NEW_LINE; + +@StaticFactories(value = "Core", packageName = "org.saynotobugs.confidence.quality") +public final class Ordered extends QualityComposition> +{ + /** + * A {@link Quality} that describes an {@link Iterable} that iterates elements in the + * order imposed by the given {@link Comparator}. + */ + public Ordered(Comparator comparator) + { + this("", comparator); + } + + /** + * A {@link Quality} that describes an {@link Iterable} that iterates elements in the + * order imposed by the given {@link Comparator}. + *

+ * This constructor also takes a description of the {@link Comparator}. + */ + public Ordered(String description, Comparator comparator) + { + super(actual -> new AllPassed(new Text("["), NEW_LINE, new Text("]"), () -> new Iterator() + { + private final Iterator mDelegate = actual.iterator(); + private T mCurrent = mDelegate.hasNext() ? mDelegate.next() : null; + private int mIndex = 0; + + @Override + public boolean hasNext() + { + return mDelegate.hasNext(); + } + + @Override + public Assessment next() + { + T next = mDelegate.next(); + Assessment result = new PassIf(comparator.compare(mCurrent, next) <= 0, + new Spaced( + new Text(mIndex + ":"), + new Value(mCurrent), + new Text(">"), + new Text(++mIndex + ":"), + new Value(next))); + mCurrent = next; + return result; + } + }), + new Text("ordered" + (description.isEmpty() ? "" : " " + description))); + } +} diff --git a/confidence-core/src/test/java/org/saynotobugs/confidence/quality/iterable/OrderedTest.java b/confidence-core/src/test/java/org/saynotobugs/confidence/quality/iterable/OrderedTest.java new file mode 100644 index 00000000..909d2b96 --- /dev/null +++ b/confidence-core/src/test/java/org/saynotobugs/confidence/quality/iterable/OrderedTest.java @@ -0,0 +1,67 @@ +/* + * Copyright 2023 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.quality.iterable; + +import org.dmfs.jems2.comparator.By; +import org.dmfs.jems2.iterable.EmptyIterable; +import org.dmfs.jems2.iterable.Seq; +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 OrderedTest +{ + @Test + void test() + { + assertThat(new Ordered<>(new By<>(String::length)), + new AllOf<>( + new Passes<>(new Seq<>("1", "2", "3"), + new Seq<>("1", "12", "123"), + new Seq<>("1", "12"), + new Seq<>("1"), + new EmptyIterable<>()), + new Fails<>(new Seq<>("123", "12", "1"), "[0: \"123\" > 1: \"12\"\n 1: \"12\" > 2: \"1\"]"), + new Fails<>(new Seq<>("1", "2", "12", "1"), "[...\n 2: \"12\" > 3: \"1\"]"), + new HasDescription("ordered") + ) + ); + } + + @Test + void testWithDescription() + { + assertThat(new Ordered<>("by length", new By<>(String::length)), + new AllOf<>( + new Passes<>(new Seq<>("1", "2", "3"), + new Seq<>("1", "12", "123"), + new Seq<>("1", "12"), + new Seq<>("1"), + new EmptyIterable<>()), + new Fails<>(new Seq<>("123", "12", "1"), "[0: \"123\" > 1: \"12\"\n 1: \"12\" > 2: \"1\"]"), + new Fails<>(new Seq<>("1", "2", "12", "1"), "[...\n 2: \"12\" > 3: \"1\"]"), + new HasDescription("ordered by length") + ) + ); + } +} \ No newline at end of file