org.assertj.vavr.api.AbstractSeqAssert Maven / Gradle / Ivy
Show all versions of assertj-vavr Show documentation
/*
* 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 2017-2020 the original author or authors.
*/
package org.assertj.vavr.api;
/*
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-2019 the original author or authors.
*/
import io.vavr.collection.Seq;
import org.assertj.core.api.AbstractAssert;
import org.assertj.core.api.Condition;
import org.assertj.core.api.IndexedObjectEnumerableAssert;
import org.assertj.core.data.Index;
import org.assertj.core.internal.ComparatorBasedComparisonStrategy;
import org.assertj.core.internal.ComparisonStrategy;
import org.assertj.core.internal.StandardComparisonStrategy;
import org.assertj.core.util.CheckReturnValue;
import java.util.Comparator;
import java.util.function.Consumer;
import static java.lang.String.format;
import static org.assertj.core.error.ShouldBeSorted.shouldHaveComparableElementsAccordingToGivenComparator;
import static org.assertj.core.error.ShouldContainAtIndex.shouldContainAtIndex;
import static org.assertj.core.error.ShouldNotBeEmpty.shouldNotBeEmpty;
import static org.assertj.core.error.ShouldNotContainAtIndex.shouldNotContainAtIndex;
import static org.assertj.core.util.Preconditions.checkNotNull;
import static org.assertj.vavr.api.SeqShouldBeAtIndex.shouldBeAtIndex;
import static org.assertj.vavr.api.SeqShouldBeSorted.*;
import static org.assertj.vavr.api.SeqShouldHaveAtIndex.shouldHaveAtIndex;
/**
* Assertions for {@link Seq}.
*
* @param the "self" type of this assertion class.
* @param type of elements contained in the {@link Seq}.
* @author Michał Chmielarz
*/
abstract class AbstractSeqAssert,
ACTUAL extends Seq extends ELEMENT>,
ELEMENT,
ELEMENT_ASSERT extends AbstractAssert>
extends AbstractTraversableAssert
implements IndexedObjectEnumerableAssert {
private ComparisonStrategy seqElementComparisonStrategy;
AbstractSeqAssert(ACTUAL elements, Class> selfType) {
super(elements, selfType);
this.seqElementComparisonStrategy = StandardComparisonStrategy.instance();
}
/**
* Use given custom comparator instead of relying on actual type A equals
method to compare the
* {@link Seq} element's object for incoming assertion checks.
*
* @param customComparator the comparator to use for incoming assertion checks.
* @return {@code this} assertion object.
* @throws NullPointerException if the given comparator is {@code null}.
*/
@CheckReturnValue
public SELF usingElementComparator(Comparator super ELEMENT> customComparator) {
seqElementComparisonStrategy = new ComparatorBasedComparisonStrategy(customComparator);
return myself;
}
/**
* Verifies that the actual {@link Seq} contains the given object at the given index.
*
* Example:
*
Seq<Ring> elvesRings = List.of(vilya, nenya, narya);
*
* // assertions will pass
* assertThat(elvesRings).contains(vilya, atIndex(0));
* assertThat(elvesRings).contains(nenya, atIndex(1));
* assertThat(elvesRings).contains(narya, atIndex(2));
*
* // assertions will fail
* assertThat(elvesRings).contains(vilya, atIndex(1));
* assertThat(elvesRings).contains(nenya, atIndex(2));
* assertThat(elvesRings).contains(narya, atIndex(0));
*
* @param value the object to look for.
* @param index the index where the object should be stored in the actual group.
* @return this assertion object.
* @throws AssertionError if the actual group is {@code null} or empty.
* @throws NullPointerException if the given {@code Index} is {@code null}.
* @throws IndexOutOfBoundsException if the value of the given {@code Index} is equal to or greater than the size of the actual
* group.
* @throws AssertionError if the actual group does not contain the given object at the given index.
*/
public SELF contains(ELEMENT value, Index index) {
isNotNull();
assertNotEmpty();
assertIndexIsValid(index);
Object actualElement = actual.get(index.value);
if (!seqElementComparisonStrategy.areEqual(actualElement, value)) {
throwAssertionError(shouldContainAtIndex(actual, value, index, actual.get(index.value)));
}
return myself;
}
/**
* Verifies that the actual group does not contain the given object at the given index.
*
* Example:
*
Seq<Ring> elvesRings = List.of(vilya, nenya, narya);
*
* // assertions will pass
* assertThat(elvesRings).contains(vilya, atIndex(1));
* assertThat(elvesRings).contains(nenya, atIndex(2));
* assertThat(elvesRings).contains(narya, atIndex(0));
*
* // assertions will fail
* assertThat(elvesRings).contains(vilya, atIndex(0));
* assertThat(elvesRings).contains(nenya, atIndex(1));
* assertThat(elvesRings).contains(narya, atIndex(2));
*
* @param value the object to look for.
* @param index the index where the object should not be stored in the actual group.
* @return this assertion object.
* @throws AssertionError if the actual group is {@code null}.
* @throws NullPointerException if the given {@code Index} is {@code null}.
* @throws AssertionError if the actual group contains the given object at the given index.
*/
public SELF doesNotContain(ELEMENT value, Index index) {
isNotNull();
assertNotEmpty();
assertIndexIsValid(index);
Object actualElement = actual.get(index.value);
if (seqElementComparisonStrategy.areEqual(actualElement, value)) {
throwAssertionError(shouldNotContainAtIndex(actual, value, index));
}
return myself;
}
/**
* Verifies that the actual object at the given index in the actual group satisfies the given condition.
*
* @param condition the given condition.
* @param index the index where the object should be stored in the actual group.
* @return this assertion object.
* @throws AssertionError if the given {@link Seq} is {@code null} or empty.
* @throws NullPointerException if the given {@code Index} is {@code null}.
* @throws IndexOutOfBoundsException if the value of the given {@code Index} is equal to or greater than the size of
* the given {@link Seq}.
* @throws NullPointerException if the given {@code Condition} is {@code null}.
* @throws AssertionError if the value in the given {@link Seq} at the given index does not satisfy the given
* {@code Condition} .
*/
public SELF has(Condition super ELEMENT> condition, Index index) {
assertConditionIsMetAtIndex(
condition,
index,
() -> throwAssertionError(shouldHaveAtIndex(actual, condition, index, actual.get(index.value)))
);
return myself;
}
/**
* Verifies that the actual object at the given index in the actual group satisfies the given condition (alias of {@link #has(Condition, Index)}).
*
* @param condition the given condition.
* @param index the index where the object should be stored in the actual group.
* @return this assertion object.
* @throws AssertionError if the given {@link Seq} is {@code null} or empty.
* @throws NullPointerException if the given {@code Index} is {@code null}.
* @throws IndexOutOfBoundsException if the value of the given {@code Index} is equal to or greater than the size of
* the given {@link Seq}.
* @throws NullPointerException if the given {@code Condition} is {@code null}.
* @throws AssertionError if the value in the given {@link Seq} at the given index does not satisfy the given
* {@code Condition} .
*/
public SELF is(Condition super ELEMENT> condition, Index index) {
assertConditionIsMetAtIndex(
condition,
index,
() -> throwAssertionError(shouldBeAtIndex(actual, condition, index, actual.get(index.value)))
);
return myself;
}
/**
* Verifies that the actual sequence is sorted in ascending order according to the natural ordering of its elements.
*
* All sequence elements must implement the {@link Comparable} interface and must be mutually comparable (that is,
* e1.compareTo(e2) must not throw a ClassCastException for any elements e1 and e2 in the sequence), examples :
*
* - a sequence composed of {"a1", "a2", "a3"} is ok because the element type (String) is Comparable
* - a sequence composed of Rectangle {r1, r2, r3} is NOT ok because Rectangle is not Comparable
* - a sequence composed of {True, "abc", False} is NOT ok because elements are not mutually comparable
*
* Empty sequences are considered sorted.
Unique element sequences are considered sorted unless the element type is not Comparable.
*
* @return {@code this} assertion object.
* @throws AssertionError if the actual sequence is not sorted in ascending order according to the natural ordering of its
* elements.
* @throws AssertionError if the actual sequence is null
.
* @throws AssertionError if the actual sequence element type does not implement {@link Comparable}.
* @throws AssertionError if the actual sequence elements are not mutually {@link Comparable}.
*/
public SELF isSorted() {
isNotNull();
if (seqElementComparisonStrategy instanceof ComparatorBasedComparisonStrategy) {
// instead of comparing elements with their natural comparator, use the one set by client.
Comparator> comparator = ((ComparatorBasedComparisonStrategy) seqElementComparisonStrategy).getComparator();
assertIsSortedAccordingToComparator(comparator);
return myself;
}
try {
// sorted assertion is only relevant if elements are Comparable, we assume they are
Seq> comparableSequence = actual.map(e -> (Comparable