From 686144e57c377aca08a395df7be50ff71f4dbd90 Mon Sep 17 00:00:00 2001 From: Milad Naseri Date: Sat, 11 Jun 2016 02:40:26 -0700 Subject: [PATCH 1/7] chore(travis): enable container infrastructure --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index a69d9b15..e5f5b785 100644 --- a/.travis.yml +++ b/.travis.yml @@ -11,7 +11,7 @@ after_success: - '[[ $TRAVIS_BRANCH == "master" && ( "x${TRAVIS_PULL_REQUEST}" == "xfalse" || "x${TRAVIS_PULL_REQUEST}" == "x" ) && ( "x$(echo $JAVA_HOME | grep -o 8)" == "x8" ) ]] && sudo apt-get install gnupg2' - '[[ $TRAVIS_BRANCH == "master" && ( "x${TRAVIS_PULL_REQUEST}" == "xfalse" || "x${TRAVIS_PULL_REQUEST}" == "x" ) && ( "x$(echo $JAVA_HOME | grep -o 8)" == "x8" ) ]] && bash ../deployment/deploy.sh eb1a6f34f056 ../deployment/key.asc.enc ../deployment/settings.xml' # SUDO should be set to `false` except when deploying to OSSRH to trigger container infrastructure -sudo: true +sudo: false env: global: - secure: DPkao3yJ4hhEsUOfs2VQJ8WCV3VdR3ToFiGB1l461PUstjaytTeXYK3bW2PmZqYJs6Hxxwyl8UHFvgBvWLb/yQV/dqyyJAV8XRb9UC37e4ddLoi8HE7NSGQIiXq0tySiMaOTyd2NtRTepfNAMEMDP746Nrox1giPEq1FPv+K98o= From 6ff57f7a1f2e66b65c51bea43822e596d6da7d8d Mon Sep 17 00:00:00 2001 From: Paul Verest Date: Sun, 12 Jun 2016 14:37:40 +0800 Subject: [PATCH 2/7] README #67 History section --- README.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/README.md b/README.md index 2d68c39e..1439356b 100644 --- a/README.md +++ b/README.md @@ -100,6 +100,13 @@ There you can get more information on how to download the framework, as well as incorporate it in your project to have hassle-free data store mocking capabilities added to your shiny applications. +## History + +- 1.1 Add QueryDSL and findByExample support + +see [site changelog](https://mmnaseri.github.io/spring-data-mock/site/#/changelog) + + FAQ ------------- From 490292cc7e4a734c3d2b0ee6865c47191d683df2 Mon Sep 17 00:00:00 2001 From: Milad Naseri Date: Sun, 12 Jun 2016 14:01:54 -0700 Subject: [PATCH 3/7] feat(sample): add basic use cases for the JPA sample module --- spring-data-mock-build/pom.xml | 3 +- spring-data-mock-sample-jpa/pom.xml | 59 +++++++++++++++++++ .../spring/data/jpa/model/Customer.java | 55 +++++++++++++++++ .../jpa/repository/CustomerRepository.java | 17 ++++++ .../data/jpa/service/CustomerService.java | 22 +++++++ .../service/impl/DefaultCustomerService.java | 53 +++++++++++++++++ 6 files changed, 208 insertions(+), 1 deletion(-) create mode 100644 spring-data-mock-sample-jpa/pom.xml create mode 100644 spring-data-mock-sample-jpa/src/main/java/com/mmnaseri/utils/samples/spring/data/jpa/model/Customer.java create mode 100644 spring-data-mock-sample-jpa/src/main/java/com/mmnaseri/utils/samples/spring/data/jpa/repository/CustomerRepository.java create mode 100644 spring-data-mock-sample-jpa/src/main/java/com/mmnaseri/utils/samples/spring/data/jpa/service/CustomerService.java create mode 100644 spring-data-mock-sample-jpa/src/main/java/com/mmnaseri/utils/samples/spring/data/jpa/service/impl/DefaultCustomerService.java diff --git a/spring-data-mock-build/pom.xml b/spring-data-mock-build/pom.xml index 930ff369..98ef0602 100644 --- a/spring-data-mock-build/pom.xml +++ b/spring-data-mock-build/pom.xml @@ -73,7 +73,8 @@ ../spring-data-mock/ - + ../spring-data-mock-sample-jpa + UTF-8 diff --git a/spring-data-mock-sample-jpa/pom.xml b/spring-data-mock-sample-jpa/pom.xml new file mode 100644 index 00000000..723bfbbb --- /dev/null +++ b/spring-data-mock-sample-jpa/pom.xml @@ -0,0 +1,59 @@ + + + 4.0.0 + + com.mmnaseri.utils.sample + spring-data-mock-sample-jpa + 1.0 + + This module tries to demonstrate how Spring Data Mock could be used to test an application that + is using Spring Data JPA. + + + + org.springframework.data + spring-data-commons + ${spring-data-commons.version} + + + org.springframework.data + spring-data-jpa + ${spring-data-jpa.version} + + + javax.persistence + persistence-api + ${persistence-api.version} + + + org.testng + testng + ${testng.version} + test + + + org.hamcrest + hamcrest-all + ${hamcrest.version} + test + + + com.mmnaseri.utils + spring-data-mock + ${spring-data-mock.version} + test + + + + + 1.12.1.RELEASE + 1.10.1.RELEASE + 1.0.2 + 1.1.1 + 6.9.6 + 1.3 + + + \ No newline at end of file diff --git a/spring-data-mock-sample-jpa/src/main/java/com/mmnaseri/utils/samples/spring/data/jpa/model/Customer.java b/spring-data-mock-sample-jpa/src/main/java/com/mmnaseri/utils/samples/spring/data/jpa/model/Customer.java new file mode 100644 index 00000000..1378ddaf --- /dev/null +++ b/spring-data-mock-sample-jpa/src/main/java/com/mmnaseri/utils/samples/spring/data/jpa/model/Customer.java @@ -0,0 +1,55 @@ +package com.mmnaseri.utils.samples.spring.data.jpa.model; + +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Temporal; +import javax.persistence.TemporalType; +import java.util.Date; + +/** + * @author Mohammad Milad Naseri (m.m.naseri@gmail.com) + * @since 1.0 (6/12/16, 1:50 PM) + */ +@Entity +public class Customer { + + @Id + private long id; + @Temporal(TemporalType.DATE) + private Date birthday; + private String firstName; + private String lastName; + + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } + + public Date getBirthday() { + return birthday; + } + + public void setBirthday(Date birthday) { + this.birthday = birthday; + } + + public String getFirstName() { + return firstName; + } + + public void setFirstName(String firstName) { + this.firstName = firstName; + } + + public String getLastName() { + return lastName; + } + + public void setLastName(String lastName) { + this.lastName = lastName; + } + +} diff --git a/spring-data-mock-sample-jpa/src/main/java/com/mmnaseri/utils/samples/spring/data/jpa/repository/CustomerRepository.java b/spring-data-mock-sample-jpa/src/main/java/com/mmnaseri/utils/samples/spring/data/jpa/repository/CustomerRepository.java new file mode 100644 index 00000000..4d24ac72 --- /dev/null +++ b/spring-data-mock-sample-jpa/src/main/java/com/mmnaseri/utils/samples/spring/data/jpa/repository/CustomerRepository.java @@ -0,0 +1,17 @@ +package com.mmnaseri.utils.samples.spring.data.jpa.repository; + +import com.mmnaseri.utils.samples.spring.data.jpa.model.Customer; +import org.springframework.data.jpa.repository.JpaRepository; + +import java.util.Date; +import java.util.List; + +/** + * @author Mohammad Milad Naseri (m.m.naseri@gmail.com) + * @since 1.0 (6/12/16, 1:53 PM) + */ +public interface CustomerRepository extends JpaRepository { + + List findByBirthdayBetween(Date from, Date to); + +} diff --git a/spring-data-mock-sample-jpa/src/main/java/com/mmnaseri/utils/samples/spring/data/jpa/service/CustomerService.java b/spring-data-mock-sample-jpa/src/main/java/com/mmnaseri/utils/samples/spring/data/jpa/service/CustomerService.java new file mode 100644 index 00000000..1df1555c --- /dev/null +++ b/spring-data-mock-sample-jpa/src/main/java/com/mmnaseri/utils/samples/spring/data/jpa/service/CustomerService.java @@ -0,0 +1,22 @@ +package com.mmnaseri.utils.samples.spring.data.jpa.service; + +import com.mmnaseri.utils.samples.spring.data.jpa.model.Customer; + +import java.util.Date; +import java.util.List; + +/** + * @author Mohammad Milad Naseri (m.m.naseri@gmail.com) + * @since 1.0 (6/12/16, 1:51 PM) + */ +public interface CustomerService { + + long register(String firstName, String lastName, Date birthday); + + Customer findCustomer(long id); + + List findCustomersByBirthday(Date from, Date to); + + List findCustomersByName(String firstName, String lastName); + +} diff --git a/spring-data-mock-sample-jpa/src/main/java/com/mmnaseri/utils/samples/spring/data/jpa/service/impl/DefaultCustomerService.java b/spring-data-mock-sample-jpa/src/main/java/com/mmnaseri/utils/samples/spring/data/jpa/service/impl/DefaultCustomerService.java new file mode 100644 index 00000000..c54a8fd4 --- /dev/null +++ b/spring-data-mock-sample-jpa/src/main/java/com/mmnaseri/utils/samples/spring/data/jpa/service/impl/DefaultCustomerService.java @@ -0,0 +1,53 @@ +package com.mmnaseri.utils.samples.spring.data.jpa.service.impl; + +import com.mmnaseri.utils.samples.spring.data.jpa.model.Customer; +import com.mmnaseri.utils.samples.spring.data.jpa.repository.CustomerRepository; +import com.mmnaseri.utils.samples.spring.data.jpa.service.CustomerService; +import org.springframework.data.domain.Example; +import org.springframework.data.domain.ExampleMatcher; + +import java.util.Date; +import java.util.List; + +import static org.springframework.data.domain.ExampleMatcher.GenericPropertyMatchers.ignoreCase; + +/** + * @author Mohammad Milad Naseri (m.m.naseri@gmail.com) + * @since 1.0 (6/12/16, 1:55 PM) + */ +public class DefaultCustomerService implements CustomerService { + + private final CustomerRepository repository; + + public DefaultCustomerService(CustomerRepository repository) { + this.repository = repository; + } + + public long register(String firstName, String lastName, Date birthday) { + final Customer customer = new Customer(); + customer.setFirstName(firstName); + customer.setLastName(lastName); + customer.setBirthday(birthday); + return repository.save(customer).getId(); + } + + public Customer findCustomer(long id) { + return repository.findOne(id); + } + + public List findCustomersByBirthday(Date from, Date to) { + return repository.findByBirthdayBetween(from, to); + } + + public List findCustomersByName(String firstName, String lastName) { + final Customer probe = new Customer(); + probe.setFirstName(firstName); + probe.setLastName(lastName); + final ExampleMatcher matcher = ExampleMatcher.matching() + .withMatcher("firstName", ignoreCase()) + .withMatcher("lastName", ignoreCase()); + final Example example = Example.of(probe, matcher); + return repository.findAll(example); + } + +} From c2f8ee1ae306e96d9b2f6e9ec37dd575283d2c9c Mon Sep 17 00:00:00 2001 From: Milad Naseri Date: Sun, 12 Jun 2016 15:41:56 -0700 Subject: [PATCH 4/7] fix(com.mmnaseri.utils.spring.data.domain.impl.id): fix mapping between primitive and non-primitive types when resolving IDs --- .../data/domain/impl/id/AnnotatedFieldIdPropertyResolver.java | 3 ++- .../spring/data/domain/impl/id/IdPropertyResolverUtils.java | 2 +- .../data/domain/impl/id/NamedFieldIdPropertyResolver.java | 3 ++- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/spring-data-mock/src/main/java/com/mmnaseri/utils/spring/data/domain/impl/id/AnnotatedFieldIdPropertyResolver.java b/spring-data-mock/src/main/java/com/mmnaseri/utils/spring/data/domain/impl/id/AnnotatedFieldIdPropertyResolver.java index a7ae7599..86de9a9a 100644 --- a/spring-data-mock/src/main/java/com/mmnaseri/utils/spring/data/domain/impl/id/AnnotatedFieldIdPropertyResolver.java +++ b/spring-data-mock/src/main/java/com/mmnaseri/utils/spring/data/domain/impl/id/AnnotatedFieldIdPropertyResolver.java @@ -3,6 +3,7 @@ import com.mmnaseri.utils.spring.data.domain.IdPropertyResolver; import com.mmnaseri.utils.spring.data.error.MultipleIdPropertiesException; import com.mmnaseri.utils.spring.data.error.PropertyTypeMismatchException; +import com.mmnaseri.utils.spring.data.tools.PropertyUtils; import org.springframework.data.annotation.Id; import org.springframework.util.ReflectionUtils; @@ -41,7 +42,7 @@ public void doWith(Field field) throws IllegalArgumentException, IllegalAccessEx final Field idAnnotatedField = found.get(); //if a field was found, try to get the ID property name if (idAnnotatedField != null) { - if (!idType.isAssignableFrom(idAnnotatedField.getType())) { + if (!PropertyUtils.getTypeOf(idType).isAssignableFrom(PropertyUtils.getTypeOf(idAnnotatedField.getType()))) { throw new PropertyTypeMismatchException(entityType, idAnnotatedField.getName(), idType, idAnnotatedField.getType()); } else { return idAnnotatedField.getName(); diff --git a/spring-data-mock/src/main/java/com/mmnaseri/utils/spring/data/domain/impl/id/IdPropertyResolverUtils.java b/spring-data-mock/src/main/java/com/mmnaseri/utils/spring/data/domain/impl/id/IdPropertyResolverUtils.java index f29410cd..c72b3849 100644 --- a/spring-data-mock/src/main/java/com/mmnaseri/utils/spring/data/domain/impl/id/IdPropertyResolverUtils.java +++ b/spring-data-mock/src/main/java/com/mmnaseri/utils/spring/data/domain/impl/id/IdPropertyResolverUtils.java @@ -45,7 +45,7 @@ private IdPropertyResolverUtils() { public static String getPropertyNameFromAnnotatedMethod(Class entityType, Class idType, Method idAnnotatedMethod) { if (idAnnotatedMethod != null) { final String name = PropertyUtils.getPropertyName(idAnnotatedMethod); - if (!idType.isAssignableFrom(idAnnotatedMethod.getReturnType())) { + if (!PropertyUtils.getTypeOf(idType).isAssignableFrom(PropertyUtils.getTypeOf(idAnnotatedMethod.getReturnType()))) { throw new PropertyTypeMismatchException(entityType, name, idType, idAnnotatedMethod.getReturnType()); } else { return name; diff --git a/spring-data-mock/src/main/java/com/mmnaseri/utils/spring/data/domain/impl/id/NamedFieldIdPropertyResolver.java b/spring-data-mock/src/main/java/com/mmnaseri/utils/spring/data/domain/impl/id/NamedFieldIdPropertyResolver.java index 6051fff4..4e4702fc 100644 --- a/spring-data-mock/src/main/java/com/mmnaseri/utils/spring/data/domain/impl/id/NamedFieldIdPropertyResolver.java +++ b/spring-data-mock/src/main/java/com/mmnaseri/utils/spring/data/domain/impl/id/NamedFieldIdPropertyResolver.java @@ -2,6 +2,7 @@ import com.mmnaseri.utils.spring.data.domain.IdPropertyResolver; import com.mmnaseri.utils.spring.data.error.PropertyTypeMismatchException; +import com.mmnaseri.utils.spring.data.tools.PropertyUtils; import org.springframework.util.ReflectionUtils; import java.io.Serializable; @@ -20,7 +21,7 @@ public class NamedFieldIdPropertyResolver implements IdPropertyResolver { public String resolve(Class entityType, Class idType) { final Field field = ReflectionUtils.findField(entityType, "id"); if (field != null) { - if (idType.isAssignableFrom(field.getType())) { + if (PropertyUtils.getTypeOf(idType).isAssignableFrom(PropertyUtils.getTypeOf(field.getType()))) { return field.getName(); } else { throw new PropertyTypeMismatchException(entityType, field.getName(), idType, field.getType()); From e67d33eba8cb17508caa8b7a7f2b35ed7bd047ae Mon Sep 17 00:00:00 2001 From: Milad Naseri Date: Sun, 12 Jun 2016 15:42:21 -0700 Subject: [PATCH 5/7] test(sample-jpa): add tests for entity creation --- .../impl/DefaultCustomerServiceTest.java | 55 +++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 spring-data-mock-sample-jpa/src/test/java/com/mmnaseri/utils/samples/spring/data/jpa/service/impl/DefaultCustomerServiceTest.java diff --git a/spring-data-mock-sample-jpa/src/test/java/com/mmnaseri/utils/samples/spring/data/jpa/service/impl/DefaultCustomerServiceTest.java b/spring-data-mock-sample-jpa/src/test/java/com/mmnaseri/utils/samples/spring/data/jpa/service/impl/DefaultCustomerServiceTest.java new file mode 100644 index 00000000..0cc37705 --- /dev/null +++ b/spring-data-mock-sample-jpa/src/test/java/com/mmnaseri/utils/samples/spring/data/jpa/service/impl/DefaultCustomerServiceTest.java @@ -0,0 +1,55 @@ +package com.mmnaseri.utils.samples.spring.data.jpa.service.impl; + +import com.mmnaseri.utils.samples.spring.data.jpa.model.Customer; +import com.mmnaseri.utils.samples.spring.data.jpa.repository.CustomerRepository; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; + +import java.util.Calendar; +import java.util.Date; +import java.util.GregorianCalendar; + +import static com.mmnaseri.utils.spring.data.dsl.factory.RepositoryFactoryBuilder.builder; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.*; + +/** + * @author Mohammad Milad Naseri (m.m.naseri@gmail.com) + * @since 1.0 (6/12/16, 2:03 PM) + */ +public class DefaultCustomerServiceTest { + + private DefaultCustomerService service; + private CustomerRepository repository; + + @BeforeMethod + public void setUp() throws Exception { + repository = builder().mock(CustomerRepository.class); + service = new DefaultCustomerService(repository); + } + + @Test + public void testCustomerRegistration() throws Exception { + final Date date = getDate(1988, 0, 1); + assertThat(repository.count(), is(0L)); + final String firstName = "Milad"; + final String lastName = "Naseri"; + final long id = service.register(firstName, lastName, date); + assertThat(repository.count(), is(1L)); + final Customer customer = repository.findOne(id); + assertThat(customer, is(notNullValue())); + assertThat(customer.getId(), is(id)); + assertThat(customer.getFirstName(), is(firstName)); + assertThat(customer.getLastName(), is(lastName)); + assertThat(customer.getBirthday(), is(date)); + } + + private Date getDate(int year, int month, int day) { + final Calendar calendar = new GregorianCalendar(); + calendar.set(Calendar.YEAR, year); + calendar.set(Calendar.MONTH, month + 1); + calendar.set(Calendar.DATE, day); + return calendar.getTime(); + } + +} \ No newline at end of file From 0c2f07146b96c0e43327523f38c3820d9c67bf5f Mon Sep 17 00:00:00 2001 From: Milad Naseri Date: Sun, 12 Jun 2016 18:18:52 -0700 Subject: [PATCH 6/7] feat(sample-jpa): add test cases and remedy arising issues --- .travis.yml | 2 +- spring-data-mock-sample-jpa/pom.xml | 45 ++++++++++-- .../spring/data/jpa/model/Customer.java | 6 +- .../jpa/repository/CustomerRepository.java | 3 + .../service/impl/DefaultCustomerService.java | 2 +- .../CustomerRepositoryExampleSupport.java | 26 +++++++ .../impl/DefaultCustomerServiceTest.java | 69 +++++++++++++++++-- spring-data-mock/pom.xml | 13 +++- .../impl/id/EntityIdPropertyResolver.java | 8 +++ .../data/error/PrimitiveIdTypeException.java | 13 ++++ .../impl/id/EntityIdPropertyResolverTest.java | 23 +++++-- .../models/EntityWithPrimitiveIdProperty.java | 14 ++++ 12 files changed, 200 insertions(+), 24 deletions(-) create mode 100644 spring-data-mock-sample-jpa/src/test/java/com/mmnaseri/utils/samples/spring/data/jpa/repository/CustomerRepositoryExampleSupport.java create mode 100644 spring-data-mock/src/main/java/com/mmnaseri/utils/spring/data/error/PrimitiveIdTypeException.java create mode 100644 spring-data-mock/src/test/java/com/mmnaseri/utils/spring/data/sample/models/EntityWithPrimitiveIdProperty.java diff --git a/.travis.yml b/.travis.yml index e5f5b785..907ad5d9 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,7 +6,7 @@ script: - cd spring-data-mock - mvn test -B after_success: - - cd spring-data-mock-parent + - cd spring-data-mock-build - mvn -P coverage clean cobertura:cobertura coveralls:report - '[[ $TRAVIS_BRANCH == "master" && ( "x${TRAVIS_PULL_REQUEST}" == "xfalse" || "x${TRAVIS_PULL_REQUEST}" == "x" ) && ( "x$(echo $JAVA_HOME | grep -o 8)" == "x8" ) ]] && sudo apt-get install gnupg2' - '[[ $TRAVIS_BRANCH == "master" && ( "x${TRAVIS_PULL_REQUEST}" == "xfalse" || "x${TRAVIS_PULL_REQUEST}" == "x" ) && ( "x$(echo $JAVA_HOME | grep -o 8)" == "x8" ) ]] && bash ../deployment/deploy.sh eb1a6f34f056 ../deployment/key.asc.enc ../deployment/settings.xml' diff --git a/spring-data-mock-sample-jpa/pom.xml b/spring-data-mock-sample-jpa/pom.xml index 723bfbbb..02ff4acf 100644 --- a/spring-data-mock-sample-jpa/pom.xml +++ b/spring-data-mock-sample-jpa/pom.xml @@ -7,10 +7,37 @@ com.mmnaseri.utils.sample spring-data-mock-sample-jpa 1.0 - + Spring Data Mock: Samples (JPA) This module tries to demonstrate how Spring Data Mock could be used to test an application that is using Spring Data JPA. + + + + org.apache.maven.plugins + maven-compiler-plugin + ${maven-compiler-plugin.version} + + ${target-jdk.version} + ${target-jdk.version} + + + + org.codehaus.mojo + cobertura-maven-plugin + ${cobertura-maven-plugin.version} + + xml + 256m + + true + + target/reports + + + + + org.springframework.data @@ -27,18 +54,18 @@ persistence-api ${persistence-api.version} - - org.testng - testng - ${testng.version} - test - org.hamcrest hamcrest-all ${hamcrest.version} test + + org.testng + testng + ${testng.version} + test + com.mmnaseri.utils spring-data-mock @@ -54,6 +81,10 @@ 1.1.1 6.9.6 1.3 + UTF-8 + 3.5.1 + 1.7 + 2.7 \ No newline at end of file diff --git a/spring-data-mock-sample-jpa/src/main/java/com/mmnaseri/utils/samples/spring/data/jpa/model/Customer.java b/spring-data-mock-sample-jpa/src/main/java/com/mmnaseri/utils/samples/spring/data/jpa/model/Customer.java index 1378ddaf..59887583 100644 --- a/spring-data-mock-sample-jpa/src/main/java/com/mmnaseri/utils/samples/spring/data/jpa/model/Customer.java +++ b/spring-data-mock-sample-jpa/src/main/java/com/mmnaseri/utils/samples/spring/data/jpa/model/Customer.java @@ -14,17 +14,17 @@ public class Customer { @Id - private long id; + private Long id; @Temporal(TemporalType.DATE) private Date birthday; private String firstName; private String lastName; - public long getId() { + public Long getId() { return id; } - public void setId(long id) { + public void setId(Long id) { this.id = id; } diff --git a/spring-data-mock-sample-jpa/src/main/java/com/mmnaseri/utils/samples/spring/data/jpa/repository/CustomerRepository.java b/spring-data-mock-sample-jpa/src/main/java/com/mmnaseri/utils/samples/spring/data/jpa/repository/CustomerRepository.java index 4d24ac72..5486722d 100644 --- a/spring-data-mock-sample-jpa/src/main/java/com/mmnaseri/utils/samples/spring/data/jpa/repository/CustomerRepository.java +++ b/spring-data-mock-sample-jpa/src/main/java/com/mmnaseri/utils/samples/spring/data/jpa/repository/CustomerRepository.java @@ -1,6 +1,7 @@ package com.mmnaseri.utils.samples.spring.data.jpa.repository; import com.mmnaseri.utils.samples.spring.data.jpa.model.Customer; +import org.springframework.data.domain.Example; import org.springframework.data.jpa.repository.JpaRepository; import java.util.Date; @@ -14,4 +15,6 @@ public interface CustomerRepository extends JpaRepository { List findByBirthdayBetween(Date from, Date to); + List findByExample(Example probe); + } diff --git a/spring-data-mock-sample-jpa/src/main/java/com/mmnaseri/utils/samples/spring/data/jpa/service/impl/DefaultCustomerService.java b/spring-data-mock-sample-jpa/src/main/java/com/mmnaseri/utils/samples/spring/data/jpa/service/impl/DefaultCustomerService.java index c54a8fd4..50b55cf0 100644 --- a/spring-data-mock-sample-jpa/src/main/java/com/mmnaseri/utils/samples/spring/data/jpa/service/impl/DefaultCustomerService.java +++ b/spring-data-mock-sample-jpa/src/main/java/com/mmnaseri/utils/samples/spring/data/jpa/service/impl/DefaultCustomerService.java @@ -47,7 +47,7 @@ public List findCustomersByName(String firstName, String lastName) { .withMatcher("firstName", ignoreCase()) .withMatcher("lastName", ignoreCase()); final Example example = Example.of(probe, matcher); - return repository.findAll(example); + return repository.findByExample(example); } } diff --git a/spring-data-mock-sample-jpa/src/test/java/com/mmnaseri/utils/samples/spring/data/jpa/repository/CustomerRepositoryExampleSupport.java b/spring-data-mock-sample-jpa/src/test/java/com/mmnaseri/utils/samples/spring/data/jpa/repository/CustomerRepositoryExampleSupport.java new file mode 100644 index 00000000..24e6f5de --- /dev/null +++ b/spring-data-mock-sample-jpa/src/test/java/com/mmnaseri/utils/samples/spring/data/jpa/repository/CustomerRepositoryExampleSupport.java @@ -0,0 +1,26 @@ +package com.mmnaseri.utils.samples.spring.data.jpa.repository; + +import com.mmnaseri.utils.samples.spring.data.jpa.model.Customer; +import com.mmnaseri.utils.spring.data.domain.RepositoryAware; +import org.springframework.data.domain.Example; + +import java.util.List; + +/** + * @author Mohammad Milad Naseri (m.m.naseri@gmail.com) + * @since 1.0 (6/12/16, 5:30 PM) + */ +public class CustomerRepositoryExampleSupport implements RepositoryAware { + + private CustomerRepository repository; + + public List findByExample(Example example) { + return repository.findAll(example); + } + + @Override + public void setRepository(CustomerRepository repository) { + this.repository = repository; + } + +} diff --git a/spring-data-mock-sample-jpa/src/test/java/com/mmnaseri/utils/samples/spring/data/jpa/service/impl/DefaultCustomerServiceTest.java b/spring-data-mock-sample-jpa/src/test/java/com/mmnaseri/utils/samples/spring/data/jpa/service/impl/DefaultCustomerServiceTest.java index 0cc37705..5591845d 100644 --- a/spring-data-mock-sample-jpa/src/test/java/com/mmnaseri/utils/samples/spring/data/jpa/service/impl/DefaultCustomerServiceTest.java +++ b/spring-data-mock-sample-jpa/src/test/java/com/mmnaseri/utils/samples/spring/data/jpa/service/impl/DefaultCustomerServiceTest.java @@ -2,12 +2,14 @@ import com.mmnaseri.utils.samples.spring.data.jpa.model.Customer; import com.mmnaseri.utils.samples.spring.data.jpa.repository.CustomerRepository; +import com.mmnaseri.utils.samples.spring.data.jpa.repository.CustomerRepositoryExampleSupport; import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; import java.util.Calendar; import java.util.Date; import java.util.GregorianCalendar; +import java.util.List; import static com.mmnaseri.utils.spring.data.dsl.factory.RepositoryFactoryBuilder.builder; import static org.hamcrest.MatcherAssert.assertThat; @@ -24,19 +26,26 @@ public class DefaultCustomerServiceTest { @BeforeMethod public void setUp() throws Exception { - repository = builder().mock(CustomerRepository.class); + repository = builder() + .usingImplementation(CustomerRepositoryExampleSupport.class) + .mock(CustomerRepository.class); service = new DefaultCustomerService(repository); } @Test public void testCustomerRegistration() throws Exception { - final Date date = getDate(1988, 0, 1); + final Date date = date(1988, 0, 1); + //let's make sure that the database is empty assertThat(repository.count(), is(0L)); final String firstName = "Milad"; final String lastName = "Naseri"; + //and then register a customer final long id = service.register(firstName, lastName, date); + //after registration, we should have exactly one record assertThat(repository.count(), is(1L)); + //and we should be able to load the cutomer by it's ID final Customer customer = repository.findOne(id); + //and that customer should be the one we registered assertThat(customer, is(notNullValue())); assertThat(customer.getId(), is(id)); assertThat(customer.getFirstName(), is(firstName)); @@ -44,11 +53,63 @@ public void testCustomerRegistration() throws Exception { assertThat(customer.getBirthday(), is(date)); } - private Date getDate(int year, int month, int day) { + @Test + public void testLoadingCustomerById() throws Exception { + //let's save a customer to the database first + final Customer customer = createCustomer("Milad", "Naseri", date(1988, 1, 1)); + //we should be able to locate that via the service + final Customer loaded = service.findCustomer(customer.getId()); + assertThat(loaded, is(notNullValue())); + assertThat(loaded.getId(), is(customer.getId())); + assertThat(loaded.getBirthday(), is(customer.getBirthday())); + assertThat(loaded.getFirstName(), is(customer.getFirstName())); + assertThat(loaded.getLastName(), is(customer.getLastName())); + } + + @Test + public void testLoadingCustomersByBirthday() throws Exception { + //let's register three customers, two of which are born within [88/1/1 .. 89/12/28] + final Customer first = createCustomer("Milad", "Naseri", date(1988, 1, 1)); + final Customer second = createCustomer("Zohreh", "Sadeghi", date(1989, 9, 22)); + createCustomer("Hassan", "Naseri", date(1962, 4, 15)); + //we should be able to look up these customers using the service + final List list = service.findCustomersByBirthday(date(1988, 1, 1), date(1989, 12, 28)); + //and the customers should be the ones indicated above + assertThat(list, is(notNullValue())); + assertThat(list, hasSize(2)); + assertThat(list, containsInAnyOrder(first, second)); + } + + @Test + public void testLoadingCustomersByFirstNameAndLastName() throws Exception { + //let's save three customers ... + final Customer customer = createCustomer("Milad", "Naseri", date(1988, 1, 1)); + createCustomer("Zohreh", "Sadeghi", date(1989, 9, 22)); + createCustomer("Hassan", "Naseri", date(1962, 4, 15)); + //... and have the service look up one of them + final List list = service.findCustomersByName("Milad", "Naseri"); + assertThat(list, is(notNullValue())); + assertThat(list, hasSize(1)); + assertThat(list.get(0), is(customer)); + } + + private Customer createCustomer(String firstName, String lastName, Date birthday) { + final Customer customer = new Customer(); + customer.setFirstName(firstName); + customer.setLastName(lastName); + customer.setBirthday(birthday); + return repository.save(customer); + } + + private Date date(int year, int month, int day) { final Calendar calendar = new GregorianCalendar(); calendar.set(Calendar.YEAR, year); - calendar.set(Calendar.MONTH, month + 1); + calendar.set(Calendar.MONTH, month - 1); calendar.set(Calendar.DATE, day); + calendar.set(Calendar.HOUR, 0); + calendar.set(Calendar.MINUTE, 0); + calendar.set(Calendar.SECOND, 0); + calendar.set(Calendar.MILLISECOND, 0); return calendar.getTime(); } diff --git a/spring-data-mock/pom.xml b/spring-data-mock/pom.xml index f8814195..85b594f3 100644 --- a/spring-data-mock/pom.xml +++ b/spring-data-mock/pom.xml @@ -45,6 +45,12 @@ Gemfire Repository http://dist.gemstone.com/maven/release + + + gradle-repository + Gradle Repository + http://gradle.artifactoryonline.com/gradle/libs/ + @@ -265,7 +271,7 @@ org.eluder.coveralls coveralls-maven-plugin - 4.1.0 + ${coveralls-maven-plugin.version} @@ -301,7 +307,7 @@ 1.2 2.9.4 - 6.9.10 + 6.9.11 1.3 1.6 @@ -310,11 +316,12 @@ 2.8.2 1.6.7 2.7 + 4.2.0 1.12.1.RELEASE 1.8.1.RELEASE 1.10.1.RELEASE - 4.1.0 + 4.1.2 3.2.2 1.0.2 diff --git a/spring-data-mock/src/main/java/com/mmnaseri/utils/spring/data/domain/impl/id/EntityIdPropertyResolver.java b/spring-data-mock/src/main/java/com/mmnaseri/utils/spring/data/domain/impl/id/EntityIdPropertyResolver.java index a65a885a..b2d2f4f8 100644 --- a/spring-data-mock/src/main/java/com/mmnaseri/utils/spring/data/domain/impl/id/EntityIdPropertyResolver.java +++ b/spring-data-mock/src/main/java/com/mmnaseri/utils/spring/data/domain/impl/id/EntityIdPropertyResolver.java @@ -2,6 +2,10 @@ import com.mmnaseri.utils.spring.data.domain.IdPropertyResolver; import com.mmnaseri.utils.spring.data.error.NoIdPropertyException; +import com.mmnaseri.utils.spring.data.error.PrimitiveIdTypeException; +import com.mmnaseri.utils.spring.data.query.PropertyDescriptor; +import com.mmnaseri.utils.spring.data.tools.PropertyUtils; +import com.mmnaseri.utils.spring.data.tools.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -54,6 +58,10 @@ public String resolve(Class entityType, Class idType) log.error("No ID property was found for entity " + entityType); throw new NoIdPropertyException(entityType); } + final PropertyDescriptor descriptor = PropertyUtils.getPropertyDescriptor(entityType, StringUtils.capitalize(idProperty)); + if (descriptor.getType().isPrimitive()) { + throw new PrimitiveIdTypeException(entityType, idProperty); + } return idProperty; } diff --git a/spring-data-mock/src/main/java/com/mmnaseri/utils/spring/data/error/PrimitiveIdTypeException.java b/spring-data-mock/src/main/java/com/mmnaseri/utils/spring/data/error/PrimitiveIdTypeException.java new file mode 100644 index 00000000..659d0b4c --- /dev/null +++ b/spring-data-mock/src/main/java/com/mmnaseri/utils/spring/data/error/PrimitiveIdTypeException.java @@ -0,0 +1,13 @@ +package com.mmnaseri.utils.spring.data.error; + +/** + * @author Mohammad Milad Naseri (m.m.naseri@gmail.com) + * @since 1.0 (6/12/16, 5:58 PM) + */ +public class PrimitiveIdTypeException extends EntityDefinitionException { + + public PrimitiveIdTypeException(Class entityType, String idProperty) { + super("The ID property (" + idProperty + ") found on entity <" + entityType + "> is of a primitive type. Primitive types are not supported by this framework."); + } + +} diff --git a/spring-data-mock/src/test/java/com/mmnaseri/utils/spring/data/domain/impl/id/EntityIdPropertyResolverTest.java b/spring-data-mock/src/test/java/com/mmnaseri/utils/spring/data/domain/impl/id/EntityIdPropertyResolverTest.java index 0de73865..79c580e1 100644 --- a/spring-data-mock/src/test/java/com/mmnaseri/utils/spring/data/domain/impl/id/EntityIdPropertyResolverTest.java +++ b/spring-data-mock/src/test/java/com/mmnaseri/utils/spring/data/domain/impl/id/EntityIdPropertyResolverTest.java @@ -2,7 +2,9 @@ import com.mmnaseri.utils.spring.data.domain.IdPropertyResolver; import com.mmnaseri.utils.spring.data.error.NoIdPropertyException; +import com.mmnaseri.utils.spring.data.error.PrimitiveIdTypeException; import com.mmnaseri.utils.spring.data.sample.models.*; +import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; import java.io.Serializable; @@ -17,9 +19,15 @@ */ public class EntityIdPropertyResolverTest { + private EntityIdPropertyResolver resolver; + + @BeforeMethod + public void setUp() throws Exception { + resolver = new EntityIdPropertyResolver(); + } + @Test public void testThatAnnotatedGetterHasPrecedence() throws Exception { - final IdPropertyResolver resolver = new EntityIdPropertyResolver(); final String resolved = resolver.resolve(EntityWithAnnotationOnIdFieldAndGetterAndAnIdField.class, Serializable.class); assertThat(resolved, is(notNullValue())); assertThat(resolved, is("unannotatedId")); @@ -27,7 +35,6 @@ public void testThatAnnotatedGetterHasPrecedence() throws Exception { @Test public void testThatAnnotatedPropertyIsSecond() throws Exception { - final IdPropertyResolver resolver = new EntityIdPropertyResolver(); final String resolved = resolver.resolve(EntityWithIdFieldAndAnAnnotatedIdField.class, Serializable.class); assertThat(resolved, is(notNullValue())); assertThat(resolved, is("annotatedId")); @@ -35,7 +42,6 @@ public void testThatAnnotatedPropertyIsSecond() throws Exception { @Test public void testThatNamedGetterIsThird() throws Exception { - final IdPropertyResolver resolver = new EntityIdPropertyResolver(); final String resolved = resolver.resolve(EntityWithUnderscorePrecedingIdField.class, Serializable.class); assertThat(resolved, is(notNullValue())); assertThat(resolved, is("id")); @@ -43,7 +49,6 @@ public void testThatNamedGetterIsThird() throws Exception { @Test public void testThatNamedFieldIsFourth() throws Exception { - final IdPropertyResolver resolver = new EntityIdPropertyResolver(); final String resolved = resolver.resolve(EntityWithIdFieldHiddenBehindDifferentlyNamedAccessors.class, Serializable.class); assertThat(resolved, is(notNullValue())); assertThat(resolved, is("id")); @@ -51,8 +56,16 @@ public void testThatNamedFieldIsFourth() throws Exception { @Test(expectedExceptions = NoIdPropertyException.class) public void testThatNoOtherValueIsHonored() throws Exception { - final IdPropertyResolver resolver = new EntityIdPropertyResolver(); resolver.resolve(EntityWithNoImmediatelyResolvableIdProperty.class, Serializable.class); } + /** + * see https://github.com/mmnaseri/spring-data-mock/issues/83 + * @throws Exception + */ + @Test(expectedExceptions = PrimitiveIdTypeException.class) + public void testPrimitiveIdTypeDoesNotWork() throws Exception { + resolver.resolve(EntityWithPrimitiveIdProperty.class, Long.class); + } + } \ No newline at end of file diff --git a/spring-data-mock/src/test/java/com/mmnaseri/utils/spring/data/sample/models/EntityWithPrimitiveIdProperty.java b/spring-data-mock/src/test/java/com/mmnaseri/utils/spring/data/sample/models/EntityWithPrimitiveIdProperty.java new file mode 100644 index 00000000..3d3054ff --- /dev/null +++ b/spring-data-mock/src/test/java/com/mmnaseri/utils/spring/data/sample/models/EntityWithPrimitiveIdProperty.java @@ -0,0 +1,14 @@ +package com.mmnaseri.utils.spring.data.sample.models; + +import javax.persistence.Id; + +/** + * @author Mohammad Milad Naseri (m.m.naseri@gmail.com) + * @since 1.0 (6/12/16, 6:14 PM) + */ +public class EntityWithPrimitiveIdProperty { + + @Id + private long id; + +} From 033c9b1686ebac4dd19fe976b30977bcdffaacee Mon Sep 17 00:00:00 2001 From: Milad Naseri Date: Sun, 12 Jun 2016 18:28:15 -0700 Subject: [PATCH 7/7] chore(all): prepare for release v1.1.2 --- .travis.yml | 2 +- spring-data-mock-build/pom.xml | 2 +- spring-data-mock-sample-jpa/pom.xml | 2 +- spring-data-mock/pom.xml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index 907ad5d9..3f81f435 100644 --- a/.travis.yml +++ b/.travis.yml @@ -11,7 +11,7 @@ after_success: - '[[ $TRAVIS_BRANCH == "master" && ( "x${TRAVIS_PULL_REQUEST}" == "xfalse" || "x${TRAVIS_PULL_REQUEST}" == "x" ) && ( "x$(echo $JAVA_HOME | grep -o 8)" == "x8" ) ]] && sudo apt-get install gnupg2' - '[[ $TRAVIS_BRANCH == "master" && ( "x${TRAVIS_PULL_REQUEST}" == "xfalse" || "x${TRAVIS_PULL_REQUEST}" == "x" ) && ( "x$(echo $JAVA_HOME | grep -o 8)" == "x8" ) ]] && bash ../deployment/deploy.sh eb1a6f34f056 ../deployment/key.asc.enc ../deployment/settings.xml' # SUDO should be set to `false` except when deploying to OSSRH to trigger container infrastructure -sudo: false +sudo: true env: global: - secure: DPkao3yJ4hhEsUOfs2VQJ8WCV3VdR3ToFiGB1l461PUstjaytTeXYK3bW2PmZqYJs6Hxxwyl8UHFvgBvWLb/yQV/dqyyJAV8XRb9UC37e4ddLoi8HE7NSGQIiXq0tySiMaOTyd2NtRTepfNAMEMDP746Nrox1giPEq1FPv+K98o= diff --git a/spring-data-mock-build/pom.xml b/spring-data-mock-build/pom.xml index 98ef0602..281fdff3 100644 --- a/spring-data-mock-build/pom.xml +++ b/spring-data-mock-build/pom.xml @@ -26,7 +26,7 @@ com.mmnaseri.utils spring-data-mock-build - 1.1.1 + 1.1.0 Spring Data Mock: Build Aggregator This is the build module that will aggregate all reactors for the spring-data-mock project https://mmnaseri.github.io/spring-data-mock diff --git a/spring-data-mock-sample-jpa/pom.xml b/spring-data-mock-sample-jpa/pom.xml index 02ff4acf..c8273cd3 100644 --- a/spring-data-mock-sample-jpa/pom.xml +++ b/spring-data-mock-sample-jpa/pom.xml @@ -78,7 +78,7 @@ 1.12.1.RELEASE 1.10.1.RELEASE 1.0.2 - 1.1.1 + 1.1.2 6.9.6 1.3 UTF-8 diff --git a/spring-data-mock/pom.xml b/spring-data-mock/pom.xml index 85b594f3..85092a57 100644 --- a/spring-data-mock/pom.xml +++ b/spring-data-mock/pom.xml @@ -26,7 +26,7 @@ com.mmnaseri.utils spring-data-mock - 1.1.1 + 1.1.2 Spring Data Mock A framework for mocking Spring Data repositories https://mmnaseri.github.io/spring-data-mock