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; package es.uvigo.esei.xcs.rest;
import static es.uvigo.esei.xcs.domain.entities.IsEqualsToOwner.containsOwnersInAnyOrder; import static es.uvigo.esei.xcs.domain.entities.IsEqualToOwner.containsOwnersInAnyOrder;
import static es.uvigo.esei.xcs.domain.entities.IsEqualsToOwner.equalsToOwner; 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.EXISTENT_LOGIN;
import static es.uvigo.esei.xcs.domain.entities.OwnersDataset.NON_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; import static es.uvigo.esei.xcs.domain.entities.OwnersDataset.OWNER_WITHOUT_PETS_LOGIN;
...@@ -89,7 +89,7 @@ public class OwnerResourceRestTest { ...@@ -89,7 +89,7 @@ public class OwnerResourceRestTest {
final Owner owner = response.readEntity(Owner.class); final Owner owner = response.readEntity(Owner.class);
final Owner expected = existentOwner(); final Owner expected = existentOwner();
assertThat(owner, is(equalsToOwner(expected))); assertThat(owner, is(equalToOwner(expected)));
} }
@Test @InSequence(3) @Test @InSequence(3)
...@@ -202,7 +202,7 @@ public class OwnerResourceRestTest { ...@@ -202,7 +202,7 @@ public class OwnerResourceRestTest {
final Response responseGet = authorizedJsonRequestGet(location); final Response responseGet = authorizedJsonRequestGet(location);
final Owner owner = responseGet.readEntity(Owner.class); final Owner owner = responseGet.readEntity(Owner.class);
assertThat(owner, is(equalsToOwner(persistentOwner))); assertThat(owner, is(equalToOwner(persistentOwner)));
} }
......
package es.uvigo.esei.xcs.rest; package es.uvigo.esei.xcs.rest;
import static es.uvigo.esei.xcs.domain.entities.IsEqualsToOwner.containsOwnersInAnyOrder; import static es.uvigo.esei.xcs.domain.entities.IsEqualToOwner.containsOwnersInAnyOrder;
import static es.uvigo.esei.xcs.domain.entities.IsEqualsToOwner.equalsToOwner; 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.anyLogin;
import static es.uvigo.esei.xcs.domain.entities.OwnersDataset.anyOwner; import static es.uvigo.esei.xcs.domain.entities.OwnersDataset.anyOwner;
import static es.uvigo.esei.xcs.domain.entities.OwnersDataset.existentOwner; import static es.uvigo.esei.xcs.domain.entities.OwnersDataset.existentOwner;
...@@ -73,7 +73,7 @@ public class OwnerResourceUnitTest extends EasyMockSupport { ...@@ -73,7 +73,7 @@ public class OwnerResourceUnitTest extends EasyMockSupport {
assertThat(response, hasHttpStatus(OK)); assertThat(response, hasHttpStatus(OK));
assertThat(response.getEntity(), is(instanceOf(Owner.class))); 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) @Test(expected = IllegalArgumentException.class)
......
package es.uvigo.esei.xcs.service; package es.uvigo.esei.xcs.service;
import static es.uvigo.esei.xcs.domain.entities.IsEqualsToOwner.containsOwnersInAnyOrder; import static es.uvigo.esei.xcs.domain.entities.IsEqualToOwner.containsOwnersInAnyOrder;
import static es.uvigo.esei.xcs.domain.entities.IsEqualsToOwner.equalsToOwner; import static es.uvigo.esei.xcs.domain.entities.IsEqualToOwner.equalToOwner;
import static es.uvigo.esei.xcs.domain.entities.IsEqualsToPet.containsPetsInAnyOrder; 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.existentLogin;
import static es.uvigo.esei.xcs.domain.entities.OwnersDataset.existentOwner; import static es.uvigo.esei.xcs.domain.entities.OwnersDataset.existentOwner;
import static es.uvigo.esei.xcs.domain.entities.OwnersDataset.newOwnerWithFreshPets; import static es.uvigo.esei.xcs.domain.entities.OwnersDataset.newOwnerWithFreshPets;
...@@ -77,7 +77,7 @@ public class OwnerServiceIntegrationTest { ...@@ -77,7 +77,7 @@ public class OwnerServiceIntegrationTest {
final Owner actual = asAdmin.call(() -> facade.get(login)); final Owner actual = asAdmin.call(() -> facade.get(login));
assertThat(actual, is(equalsToOwner(ownerWithLogin(login)))); assertThat(actual, is(equalToOwner(ownerWithLogin(login))));
} }
@Test @Test
...@@ -113,7 +113,7 @@ public class OwnerServiceIntegrationTest { ...@@ -113,7 +113,7 @@ public class OwnerServiceIntegrationTest {
final List<Owner> owners = asAdmin.call(() -> facade.findByPetName(petName)); final List<Owner> owners = asAdmin.call(() -> facade.findByPetName(petName));
assertThat(owners, hasSize(1)); assertThat(owners, hasSize(1));
assertThat(owners.get(0), is(equalsToOwner(owner))); assertThat(owners.get(0), is(equalToOwner(owner)));
} }
@Test @Test
...@@ -151,7 +151,7 @@ public class OwnerServiceIntegrationTest { ...@@ -151,7 +151,7 @@ public class OwnerServiceIntegrationTest {
final Owner actual = asAdmin.call(() -> facade.create(newOwner)); final Owner actual = asAdmin.call(() -> facade.create(newOwner));
assertThat(actual, is(equalsToOwner(newOwner))); assertThat(actual, is(equalToOwner(newOwner)));
} }
@Test @Test
...@@ -159,7 +159,7 @@ public class OwnerServiceIntegrationTest { ...@@ -159,7 +159,7 @@ public class OwnerServiceIntegrationTest {
public void testCreateWithPets() { public void testCreateWithPets() {
final Owner actual = asAdmin.call(() -> facade.create(newOwnerWithFreshPets())); final Owner actual = asAdmin.call(() -> facade.create(newOwnerWithFreshPets()));
assertThat(actual, is(equalsToOwner(newOwnerWithPersistentPets()))); assertThat(actual, is(equalToOwner(newOwnerWithPersistentPets())));
} }
@Test(expected = EJBTransactionRolledbackException.class) @Test(expected = EJBTransactionRolledbackException.class)
...@@ -196,7 +196,7 @@ public class OwnerServiceIntegrationTest { ...@@ -196,7 +196,7 @@ public class OwnerServiceIntegrationTest {
final Owner actual = asAdmin.call(() -> facade.update(newOwner)); final Owner actual = asAdmin.call(() -> facade.update(newOwner));
assertThat(actual, is(equalsToOwner(newOwner))); assertThat(actual, is(equalToOwner(newOwner)));
} }
@Test @Test
...@@ -204,7 +204,7 @@ public class OwnerServiceIntegrationTest { ...@@ -204,7 +204,7 @@ public class OwnerServiceIntegrationTest {
public void testUpdateNewOwnerWithPets() { public void testUpdateNewOwnerWithPets() {
final Owner actual = asAdmin.call(() -> facade.update(newOwnerWithFreshPets())); final Owner actual = asAdmin.call(() -> facade.update(newOwnerWithFreshPets()));
assertThat(actual, is(equalsToOwner(newOwnerWithPersistentPets()))); assertThat(actual, is(equalToOwner(newOwnerWithPersistentPets())));
} }
@Test @Test
......
package es.uvigo.esei.xcs.service; package es.uvigo.esei.xcs.service;
import static es.uvigo.esei.xcs.domain.entities.IsEqualsToPet.containsPetsInAnyOrder; import static es.uvigo.esei.xcs.domain.entities.IsEqualToPet.containsPetsInAnyOrder;
import static es.uvigo.esei.xcs.domain.entities.IsEqualsToPet.equalsToPet; 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.existentPetId;
import static es.uvigo.esei.xcs.domain.entities.OwnersDataset.newPet; import static es.uvigo.esei.xcs.domain.entities.OwnersDataset.newPet;
import static es.uvigo.esei.xcs.domain.entities.OwnersDataset.newPetWithOwner; import static es.uvigo.esei.xcs.domain.entities.OwnersDataset.newPetWithOwner;
...@@ -75,7 +75,7 @@ public class PetServiceIntegrationTest { ...@@ -75,7 +75,7 @@ public class PetServiceIntegrationTest {
final Pet actual = asOwner.call(() -> facade.get(id)); final Pet actual = asOwner.call(() -> facade.get(id));
assertThat(actual, equalsToPet(pet)); assertThat(actual, equalToPet(pet));
} }
@Test @Test
......
package es.uvigo.esei.xcs.domain.entities; package es.uvigo.esei.xcs.domain.entities;
import static es.uvigo.esei.xcs.domain.entities.IsEqualsToPet.containsPetsWithoutRelationsInAnyOrder;
import org.hamcrest.Factory; import org.hamcrest.Factory;
import org.hamcrest.Matcher; import org.hamcrest.Matcher;
public class IsEqualsToOwner extends IsEqualsToEntity<Owner> { public class IsEqualToOwner extends IsEqualToEntity<Owner> {
private final boolean checkRelations; private final boolean checkRelations;
public IsEqualsToOwner(Owner owner, boolean checkRelations) { public IsEqualToOwner(Owner owner, boolean checkRelations) {
super(owner); super(owner);
this.checkRelations = checkRelations; this.checkRelations = checkRelations;
} }
...@@ -18,48 +16,42 @@ public class IsEqualsToOwner extends IsEqualsToEntity<Owner> { ...@@ -18,48 +16,42 @@ public class IsEqualsToOwner extends IsEqualsToEntity<Owner> {
this.clearDescribeTo(); this.clearDescribeTo();
if (actual == null) { if (actual == null) {
this.addTemplatedDescription("owner", expected.toString()); this.addTemplatedDescription("actual", 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());
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; return false;
}
} else { } else {
return true; return checkAttribute("login", Owner::getLogin, actual)
&& checkAttribute("password", Owner::getPassword, actual)
&& (!this.checkRelations || checkIterableAttribute("pets", Owner::getPets, actual, IsEqualToPet::containsPetsWithoutRelationsInAnyOrder));
} }
} }
@Factory @Factory
public static IsEqualsToOwner equalsToOwner(Owner owner) { public static IsEqualToOwner equalToOwner(Owner owner) {
return new IsEqualsToOwner(owner, true); return new IsEqualToOwner(owner, true);
} }
@Factory @Factory
public static IsEqualsToOwner equalsToOwnerWithoutRelations(Owner owner) { public static IsEqualToOwner equalToOwnerWithoutRelations(Owner owner) {
return new IsEqualsToOwner(owner, false); return new IsEqualToOwner(owner, false);
} }
@Factory @Factory
public static Matcher<Iterable<? extends Owner>> containsOwnersInAnyOrder(Owner ... owners) { public static Matcher<Iterable<? extends Owner>> containsOwnersInAnyOrder(Owner ... owners) {
return containsEntityInAnyOrder(IsEqualsToOwner::equalsToOwner, owners); return containsEntityInAnyOrder(IsEqualToOwner::equalToOwner, owners);
} }
@Factory @Factory
public static Matcher<Iterable<? extends Owner>> containsOwnersWithoutRelationsInAnyOrder(Owner ... owners) { 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