Commit 259a6760 authored by Administrator's avatar Administrator

Improves the IsEqualToEntity abstract matcher

The IsEqualToEntity matcher (previously, IsEqualsToEntity) has been
improved to allow property comparison by functional reference to the
getter methods of the properties to compare. Specifically, the
"checkAttribute" methods added allow providing a Function<T, R> as a
getter, where T is the type of the entity to compare and R is the type
returned by the getter method.
parent 342bf501
package es.uvigo.esei.xcs.rest;
import static es.uvigo.esei.xcs.domain.entities.IsEqualsToOwner.containsOwnersInAnyOrder;
import static es.uvigo.esei.xcs.domain.entities.IsEqualsToOwner.equalsToOwner;
import static es.uvigo.esei.xcs.domain.entities.IsEqualToOwner.containsOwnersInAnyOrder;
import static es.uvigo.esei.xcs.domain.entities.IsEqualToOwner.equalToOwner;
import static es.uvigo.esei.xcs.domain.entities.OwnersDataset.EXISTENT_LOGIN;
import static es.uvigo.esei.xcs.domain.entities.OwnersDataset.NON_EXISTENT_LOGIN;
import static es.uvigo.esei.xcs.domain.entities.OwnersDataset.OWNER_WITHOUT_PETS_LOGIN;
......@@ -89,7 +89,7 @@ public class OwnerResourceRestTest {
final Owner owner = response.readEntity(Owner.class);
final Owner expected = existentOwner();
assertThat(owner, is(equalsToOwner(expected)));
assertThat(owner, is(equalToOwner(expected)));
}
@Test @InSequence(3)
......@@ -202,7 +202,7 @@ public class OwnerResourceRestTest {
final Response responseGet = authorizedJsonRequestGet(location);
final Owner owner = responseGet.readEntity(Owner.class);
assertThat(owner, is(equalsToOwner(persistentOwner)));
assertThat(owner, is(equalToOwner(persistentOwner)));
}
......
package es.uvigo.esei.xcs.rest;
import static es.uvigo.esei.xcs.domain.entities.IsEqualsToOwner.containsOwnersInAnyOrder;
import static es.uvigo.esei.xcs.domain.entities.IsEqualsToOwner.equalsToOwner;
import static es.uvigo.esei.xcs.domain.entities.IsEqualToOwner.containsOwnersInAnyOrder;
import static es.uvigo.esei.xcs.domain.entities.IsEqualToOwner.equalToOwner;
import static es.uvigo.esei.xcs.domain.entities.OwnersDataset.anyLogin;
import static es.uvigo.esei.xcs.domain.entities.OwnersDataset.anyOwner;
import static es.uvigo.esei.xcs.domain.entities.OwnersDataset.existentOwner;
......@@ -73,7 +73,7 @@ public class OwnerResourceUnitTest extends EasyMockSupport {
assertThat(response, hasHttpStatus(OK));
assertThat(response.getEntity(), is(instanceOf(Owner.class)));
assertThat((Owner) response.getEntity(), is(equalsToOwner(owner)));
assertThat((Owner) response.getEntity(), is(equalToOwner(owner)));
}
@Test(expected = IllegalArgumentException.class)
......
package es.uvigo.esei.xcs.service;
import static es.uvigo.esei.xcs.domain.entities.IsEqualsToOwner.containsOwnersInAnyOrder;
import static es.uvigo.esei.xcs.domain.entities.IsEqualsToOwner.equalsToOwner;
import static es.uvigo.esei.xcs.domain.entities.IsEqualsToPet.containsPetsInAnyOrder;
import static es.uvigo.esei.xcs.domain.entities.IsEqualToOwner.containsOwnersInAnyOrder;
import static es.uvigo.esei.xcs.domain.entities.IsEqualToOwner.equalToOwner;
import static es.uvigo.esei.xcs.domain.entities.IsEqualToPet.containsPetsInAnyOrder;
import static es.uvigo.esei.xcs.domain.entities.OwnersDataset.existentLogin;
import static es.uvigo.esei.xcs.domain.entities.OwnersDataset.existentOwner;
import static es.uvigo.esei.xcs.domain.entities.OwnersDataset.newOwnerWithFreshPets;
......@@ -77,7 +77,7 @@ public class OwnerServiceIntegrationTest {
final Owner actual = asAdmin.call(() -> facade.get(login));
assertThat(actual, is(equalsToOwner(ownerWithLogin(login))));
assertThat(actual, is(equalToOwner(ownerWithLogin(login))));
}
@Test
......@@ -113,7 +113,7 @@ public class OwnerServiceIntegrationTest {
final List<Owner> owners = asAdmin.call(() -> facade.findByPetName(petName));
assertThat(owners, hasSize(1));
assertThat(owners.get(0), is(equalsToOwner(owner)));
assertThat(owners.get(0), is(equalToOwner(owner)));
}
@Test
......@@ -151,7 +151,7 @@ public class OwnerServiceIntegrationTest {
final Owner actual = asAdmin.call(() -> facade.create(newOwner));
assertThat(actual, is(equalsToOwner(newOwner)));
assertThat(actual, is(equalToOwner(newOwner)));
}
@Test
......@@ -159,7 +159,7 @@ public class OwnerServiceIntegrationTest {
public void testCreateWithPets() {
final Owner actual = asAdmin.call(() -> facade.create(newOwnerWithFreshPets()));
assertThat(actual, is(equalsToOwner(newOwnerWithPersistentPets())));
assertThat(actual, is(equalToOwner(newOwnerWithPersistentPets())));
}
@Test(expected = EJBTransactionRolledbackException.class)
......@@ -196,7 +196,7 @@ public class OwnerServiceIntegrationTest {
final Owner actual = asAdmin.call(() -> facade.update(newOwner));
assertThat(actual, is(equalsToOwner(newOwner)));
assertThat(actual, is(equalToOwner(newOwner)));
}
@Test
......@@ -204,7 +204,7 @@ public class OwnerServiceIntegrationTest {
public void testUpdateNewOwnerWithPets() {
final Owner actual = asAdmin.call(() -> facade.update(newOwnerWithFreshPets()));
assertThat(actual, is(equalsToOwner(newOwnerWithPersistentPets())));
assertThat(actual, is(equalToOwner(newOwnerWithPersistentPets())));
}
@Test
......
package es.uvigo.esei.xcs.service;
import static es.uvigo.esei.xcs.domain.entities.IsEqualsToPet.containsPetsInAnyOrder;
import static es.uvigo.esei.xcs.domain.entities.IsEqualsToPet.equalsToPet;
import static es.uvigo.esei.xcs.domain.entities.IsEqualToPet.containsPetsInAnyOrder;
import static es.uvigo.esei.xcs.domain.entities.IsEqualToPet.equalToPet;
import static es.uvigo.esei.xcs.domain.entities.OwnersDataset.existentPetId;
import static es.uvigo.esei.xcs.domain.entities.OwnersDataset.newPet;
import static es.uvigo.esei.xcs.domain.entities.OwnersDataset.newPetWithOwner;
......@@ -75,7 +75,7 @@ public class PetServiceIntegrationTest {
final Pet actual = asOwner.call(() -> facade.get(id));
assertThat(actual, equalsToPet(pet));
assertThat(actual, equalToPet(pet));
}
@Test
......
package es.uvigo.esei.xcs.domain.entities;
import static es.uvigo.esei.xcs.domain.entities.IsEqualsToPet.containsPetsWithoutRelationsInAnyOrder;
import org.hamcrest.Factory;
import org.hamcrest.Matcher;
public class IsEqualsToOwner extends IsEqualsToEntity<Owner> {
public class IsEqualToOwner extends IsEqualToEntity<Owner> {
private final boolean checkRelations;
public IsEqualsToOwner(Owner owner, boolean checkRelations) {
public IsEqualToOwner(Owner owner, boolean checkRelations) {
super(owner);
this.checkRelations = checkRelations;
}
......@@ -18,48 +16,42 @@ public class IsEqualsToOwner extends IsEqualsToEntity<Owner> {
this.clearDescribeTo();
if (actual == null) {
this.addTemplatedDescription("owner", expected.toString());
return false;
} else if (!expected.getLogin().equals(actual.getLogin())) {
this.addTemplatedDescription("login", expected.getLogin());
return false;
} else if (!expected.getPassword().equals(actual.getPassword())) {
this.addTemplatedDescription("password", expected.getPassword());
this.addTemplatedDescription("actual", expected.toString());
return false;
} else if (this.checkRelations) {
final Matcher<Iterable<? extends Pet>> petsMatcher =
containsPetsWithoutRelationsInAnyOrder(
expected.getPets().toArray(new Pet[0]));
if (petsMatcher.matches(actual.getPets())) {
this.addMatcherDescription(petsMatcher);
return true;
} else {
return false;
}
} else {
return true;
return checkAttribute("login", Owner::getLogin, actual)
&& checkAttribute("password", Owner::getPassword, actual)
&& (!this.checkRelations || checkIterableAttribute("pets", Owner::getPets, actual, IsEqualToPet::containsPetsWithoutRelationsInAnyOrder));
}
}
@Factory
public static IsEqualsToOwner equalsToOwner(Owner owner) {
return new IsEqualsToOwner(owner, true);
public static IsEqualToOwner equalToOwner(Owner owner) {
return new IsEqualToOwner(owner, true);
}
@Factory
public static IsEqualsToOwner equalsToOwnerWithoutRelations(Owner owner) {
return new IsEqualsToOwner(owner, false);
public static IsEqualToOwner equalToOwnerWithoutRelations(Owner owner) {
return new IsEqualToOwner(owner, false);
}
@Factory
public static Matcher<Iterable<? extends Owner>> containsOwnersInAnyOrder(Owner ... owners) {
return containsEntityInAnyOrder(IsEqualsToOwner::equalsToOwner, owners);
return containsEntityInAnyOrder(IsEqualToOwner::equalToOwner, owners);
}
@Factory
public static Matcher<Iterable<? extends Owner>> containsOwnersWithoutRelationsInAnyOrder(Owner ... owners) {
return containsEntityInAnyOrder(IsEqualsToOwner::equalsToOwnerWithoutRelations, owners);
return containsEntityInAnyOrder(IsEqualToOwner::equalToOwnerWithoutRelations, owners);
}
@Factory
public static Matcher<Iterable<? extends Owner>> containsOwnersInAnyOrder(Iterable<Owner> owners) {
return containsEntityInAnyOrder(IsEqualToOwner::equalToOwner, owners);
}
@Factory
public static Matcher<Iterable<? extends Owner>> containsOwnersWithoutRelationsInAnyOrder(Iterable<Owner> owners) {
return containsEntityInAnyOrder(IsEqualToOwner::equalToOwnerWithoutRelations, owners);
}
}
package es.uvigo.esei.xcs.domain.entities;
import org.hamcrest.Factory;
import org.hamcrest.Matcher;
public class IsEqualToPet extends IsEqualToEntity<Pet> {
private final boolean checkRelations;
public IsEqualToPet(Pet pet, boolean checkRelations) {
super(pet);
this.checkRelations = checkRelations;
}
@Override
protected boolean matchesSafely(Pet actual) {
this.clearDescribeTo();
if (actual == null) {
this.addTemplatedDescription("actual", expected.toString());
return false;
} else {
return checkAttribute("id", Pet::getId, actual)
&& checkAttribute("name", Pet::getName, actual)
&& checkAttribute("animal", Pet::getAnimal, actual)
&& checkAttribute("birth", Pet::getBirth, actual)
&& (!this.checkRelations || checkAttribute("owner", Pet::getOwner, actual, IsEqualToOwner::equalToOwnerWithoutRelations));
}
}
@Factory
public static IsEqualToPet equalToPet(Pet pet) {
return new IsEqualToPet(pet, true);
}
@Factory
public static IsEqualToPet equalToPetWithoutRelations(Pet pet) {
return new IsEqualToPet(pet, false);
}
@Factory
public static Matcher<Iterable<? extends Pet>> containsPetsInAnyOrder(Pet ... pets) {
return containsEntityInAnyOrder(IsEqualToPet::equalToPet, pets);
}
@Factory
public static Matcher<Iterable<? extends Pet>> containsPetsWithoutRelationsInAnyOrder(Pet ... pets) {
return containsEntityInAnyOrder(IsEqualToPet::equalToPetWithoutRelations, pets);
}
@Factory
public static Matcher<Iterable<? extends Pet>> containsPetsInAnyOrder(Iterable<Pet> pets) {
return containsEntityInAnyOrder(IsEqualToPet::equalToPet, pets);
}
@Factory
public static Matcher<Iterable<? extends Pet>> containsPetsWithoutRelationsInAnyOrder(Iterable<Pet> pets) {
return containsEntityInAnyOrder(IsEqualToPet::equalToPetWithoutRelations, pets);
}
}
package es.uvigo.esei.xcs.domain.entities;
import static java.util.Arrays.stream;
import static java.util.stream.Collectors.toList;
import static org.hamcrest.collection.IsIterableContainingInAnyOrder.containsInAnyOrder;
import java.util.Collection;
import java.util.function.Consumer;
import java.util.function.Function;
import org.hamcrest.Description;
import org.hamcrest.Matcher;
import org.hamcrest.TypeSafeMatcher;
public abstract class IsEqualsToEntity<T> extends TypeSafeMatcher<T> {
protected final T expected;
private Consumer<Description> describeTo;
public IsEqualsToEntity(T entity) {
this.expected = entity;
}
@Override
public void describeTo(Description description) {
if (this.describeTo != null) {
this.describeTo.accept(description);
}
}
protected void addTemplatedDescription(String attribute, Object expected) {
this.describeTo = d -> d.appendText(String.format(
"%s entity with value '%s' for %s",
this.expected.getClass().getSimpleName(),
expected, attribute
));
}
protected void addMatcherDescription(Matcher<?> matcher) {
this.describeTo = matcher::describeTo;
}
protected void clearDescribeTo() {
this.describeTo = null;
}
@SafeVarargs
protected static <T> Matcher<Iterable<? extends T>> containsEntityInAnyOrder(
Function<T, Matcher<? super T>> converter, T ... entities
) {
final Collection<Matcher<? super T>> ownerMatchers = stream(entities)
.map(converter)
.collect(toList());
return containsInAnyOrder(ownerMatchers);
}
}
package es.uvigo.esei.xcs.domain.entities;
import static es.uvigo.esei.xcs.domain.entities.IsEqualsToOwner.equalsToOwnerWithoutRelations;
import org.hamcrest.Factory;
import org.hamcrest.Matcher;
public class IsEqualsToPet extends IsEqualsToEntity<Pet> {
private final boolean checkRelations;
public IsEqualsToPet(Pet pet, boolean checkRelations) {
super(pet);
this.checkRelations = checkRelations;
}
@Override
protected boolean matchesSafely(Pet actual) {
this.clearDescribeTo();
if (actual == null) {
this.addTemplatedDescription("pet", expected.toString());
return false;
} else if (this.expected.getId() != actual.getId()) {
this.addTemplatedDescription("id", expected.getId());
return false;
} else if (!this.expected.getName().equals(actual.getName())) {
this.addTemplatedDescription("name", expected.getName());
return false;
} else if (!this.expected.getAnimal().equals(actual.getAnimal())) {
this.addTemplatedDescription("animal", expected.getAnimal());
return false;
} else if (this.expected.getBirth().getTime() != actual.getBirth().getTime()) {
this.addTemplatedDescription("birth", expected.getBirth());
return false;
} else if (this.checkRelations) {
final IsEqualsToOwner equalsToOwner = equalsToOwnerWithoutRelations(this.expected.getOwner());
if (equalsToOwner.matchesSafely(actual.getOwner())) {
return true;
} else {
this.addMatcherDescription(equalsToOwner);
return false;
}
} else {
return true;
}
}
@Factory
public static IsEqualsToPet equalsToPet(Pet pet) {
return new IsEqualsToPet(pet, true);
}
@Factory
public static IsEqualsToPet equalsToPetWithoutRelations(Pet pet) {
return new IsEqualsToPet(pet, false);
}
@Factory
public static Matcher<Iterable<? extends Pet>> containsPetsInAnyOrder(Pet ... pets) {
return containsEntityInAnyOrder(IsEqualsToPet::equalsToPet, pets);
}
@Factory
public static Matcher<Iterable<? extends Pet>> containsPetsWithoutRelationsInAnyOrder(Pet ... pets) {
return containsEntityInAnyOrder(IsEqualsToPet::equalsToPetWithoutRelations, pets);
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment