package com.github.liblevenshtein.assertion;
import java.util.Set;
import org.assertj.core.api.AbstractAssert;
/**
* AssertJ-quality assertions for Set objects. AssertJ's provided assertions do
* not include an efficient implementation for Sets; instead, they are treated
* as Iterables and are iterated-over for determining element containment, etc.
* This behavior kills the performance of my tests against large dictionaries,
* so I wrote this custom class of assertions.
* @param <Type> Generic type of the set that is asserted-against.
*/
public class SetAssertions<Type>
extends AbstractAssert<SetAssertions<Type>, Set<Type>> {
/**
* Constructs a new {@link SetAssertions} for asserting-against {@link #actual}.
* @param actual Set to assert-against.
*/
public SetAssertions(final Set<Type> actual) {
super(actual, SetAssertions.class);
}
/**
* Constructs a new {@link SetAssertions} for asserting-against {@link #actual}.
* @param actual Set to assert-against.
* @param <Type> Generic type of the set that is asserted-against.
* @return New instance of {@link SetAssertions} to assert-against {@link #param}.
*/
public static <Type> SetAssertions<Type> assertThat(final Set<Type> actual) {
return new SetAssertions<Type>(actual);
}
/**
* Asserts that {@link #actual} contains each of the expected {@link #values}.
* @param values Expected elements of the {@link #actual} set.
* @return This {@link SetAssertions} for fluency.
* @throws AssertionError When the {@link #actual} set is null or does not
* contain any of the {@link #values}.
*/
public SetAssertions<Type> contains(final Object... values) {
isNotNull();
for (final Object value : values) {
if (!actual.contains(value)) {
failWithMessage("Expected value [%s] to be in the set", value);
}
}
return this;
}
/**
* Asserts that {@link #actual} does not contain any of the {@link #values}.
* @param values Elements expected not to be in the {@link #actual} set.
* @return This {@link SetAssertions} for fluency.
* @throws AssertionError When the {@link #actual} set is null or contains any
* of the {@link #values}.
*/
public SetAssertions<Type> doesNotContain(final Object... values) {
isNotNull();
for (final Object value : values) {
if (actual.contains(value)) {
failWithMessage("Did not expect value [%s] to be in the set", value);
}
}
return this;
}
/**
* Asserts that {@link #actual} has the expected size.
* @param size Expected size of the {@link #actual} set.
* @return This {@link SetAssertions} for fluency.
* @throws AssertionError When the {@link #actual} set is null or does not
* have the expected size.
*/
public SetAssertions<Type> hasSize(final int size) {
isNotNull();
if (size != actual.size()) {
failWithMessage("Expected size of the set to be [%d], but was [%d]",
size, actual.size());
}
return this;
}
/**
* Asserts that {@link #actual} is empty.
* @return This {@link SetAssertions} for fluency.
* @throws AssertionError When the {@link #actual} set is null, its size is
* not zero, or {@link Set#isEmpty()} returns false.
*/
public SetAssertions<Type> isEmpty() {
isNotNull();
if (0 != actual.size()) {
failWithMessage("Expected size of set to be [0], but was [%d]",
actual.size());
}
if (!actual.isEmpty()) {
failWithMessage("Expected set.isEmpty() to be [true]");
}
return this;
}
/**
* Asserts that {@link #actual} is not empty.
* @return This {@link SetAssertions} for fluency.
* @throws AssertionError When the {@link #actual} set is null, its size is
* non-positive, or {@link Set#isEmpty()} returns true.
*/
public SetAssertions<Type> isNotEmpty() {
isNotNull();
if (actual.size() < 1) {
failWithMessage("Expected size of set to be positive, but was [%d]",
actual.size());
}
if (actual.isEmpty()) {
failWithMessage("Expected set.isEmpty() to be [false]");
}
return this;
}
/**
* Verifies that the actual set is equivalent to the expected set, by
* checking {@link Set#equals(Object)} and {@link Set#hashCode()}.
* @param expected Equivalent set of the actual one.
* @return This {@link SetAssertions} for fluency.
* @throws AssertionError When the {@link #actual} set is null,
* {@link Set#equals(Object)} return false, or the values of
* {@link Set#hashCode()} differ.
*/
public SetAssertions<Type> isEqualTo(final Set<Type> expected) {
isNotNull();
if (!actual.equals(expected)) {
failWithMessage("Expected sets to be equivalent: [%s] != [%s]",
expected, actual);
}
if (actual.hashCode() != expected.hashCode()) {
failWithMessage("Expected hashCode to be [%d], but was [%d]",
actual.hashCode(), expected.hashCode());
}
return this;
}
}