DATAGEODE-83 - Override generated OQL from Repository query methods.
This commit is contained in:
@@ -0,0 +1,142 @@
|
||||
/*
|
||||
* Copyright 2017 the original author or authors.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package org.springframework.data.gemfire.repository.config;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import org.apache.geode.cache.GemFireCache;
|
||||
import org.apache.geode.cache.Region;
|
||||
import org.apache.geode.cache.RegionAttributes;
|
||||
import org.apache.geode.cache.client.ClientRegionShortcut;
|
||||
import org.junit.Test;
|
||||
import org.springframework.beans.factory.BeanCreationException;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
import org.springframework.context.annotation.FilterType;
|
||||
import org.springframework.data.gemfire.client.ClientRegionFactoryBean;
|
||||
import org.springframework.data.gemfire.config.annotation.ClientCacheApplication;
|
||||
import org.springframework.data.gemfire.repository.sample.Animal;
|
||||
import org.springframework.data.gemfire.repository.sample.Plant;
|
||||
import org.springframework.data.gemfire.repository.sample.PlantRepository;
|
||||
import org.springframework.data.gemfire.repository.sample.RabbitRepository;
|
||||
import org.springframework.data.gemfire.test.mock.annotation.EnableGemFireMockObjects;
|
||||
import org.springframework.data.mapping.PersistentEntity;
|
||||
import org.springframework.data.repository.Repository;
|
||||
|
||||
/**
|
||||
* Integration tests for Spring Data [GemFire] Repositories testing compatibility of {@link Region}
|
||||
* {@link RegionAttributes#getKeyConstraint() key type}, {@link Repository} {@link Class ID type}
|
||||
* and {@link PersistentEntity entity} {@link Class ID type}.
|
||||
*
|
||||
* @author John Blum
|
||||
* @see org.junit.Test
|
||||
* @see org.springframework.context.ConfigurableApplicationContext
|
||||
* @since 1.4.0
|
||||
* @link https://github.com/spring-projects/spring-data-gemfire/pull/55
|
||||
*/
|
||||
public class IncompatibleRegionKeyRepositoryIdAndEntityIdRepositoryIntegrationTests {
|
||||
|
||||
private static ConfigurableApplicationContext newApplicationContext(Class<?> testConfiguration) {
|
||||
return new AnnotationConfigApplicationContext(testConfiguration);
|
||||
}
|
||||
|
||||
private void withTestConfigurationExpectIllegalArgumentExceptionWithMessage(Class<?> testConfiguration,
|
||||
Class<? extends Repository> repositoryType, Supplier<String> exceptionMessage) {
|
||||
|
||||
try {
|
||||
|
||||
ConfigurableApplicationContext applicationContext = newApplicationContext(testConfiguration);
|
||||
|
||||
assertThat(applicationContext.getBean(repositoryType)).isNotNull();
|
||||
}
|
||||
catch (BeanCreationException expected) {
|
||||
|
||||
assertThat(expected).hasCauseInstanceOf(IllegalArgumentException.class);
|
||||
assertThat(expected.getCause()).hasMessage(exceptionMessage.get());
|
||||
|
||||
throw (IllegalArgumentException) expected.getCause();
|
||||
}
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void withRegionUsingStringKeyAndRepositoryUsingLongId() {
|
||||
|
||||
withTestConfigurationExpectIllegalArgumentExceptionWithMessage(
|
||||
TestIncompatibleRegionKeyRepositoryIdTypeConfiguration.class,
|
||||
RabbitRepository.class,
|
||||
() -> String.format("Region [/Rabbits] requires keys of type [%1$s], but Repository [%2$s] declared an id of type [%3$s]",
|
||||
String.class.getName(), RabbitRepository.class.getName(), Long.class.getName()));
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void withRepositoryUsingStringIdAndEntityUsingLongId() {
|
||||
|
||||
withTestConfigurationExpectIllegalArgumentExceptionWithMessage(
|
||||
TestIncompatibleRepositoryIdEntityIdTypeConfiguration.class,
|
||||
PlantRepository.class,
|
||||
() -> String.format("Repository [%1$s] declared an id of type [%2$s], but entity [%3$s] has an id of type [%4$s]",
|
||||
PlantRepository.class.getName(), String.class.getName(), Plant.class.getName(), Long.class.getName()));
|
||||
}
|
||||
|
||||
@ClientCacheApplication
|
||||
@EnableGemFireMockObjects
|
||||
@EnableGemfireRepositories(basePackageClasses = RabbitRepository.class,
|
||||
includeFilters = @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = RabbitRepository.class)
|
||||
)
|
||||
@SuppressWarnings("unused")
|
||||
static class TestIncompatibleRegionKeyRepositoryIdTypeConfiguration {
|
||||
|
||||
@Bean("Rabbits")
|
||||
public ClientRegionFactoryBean<String, Animal> clientRegion(GemFireCache gemfireCache) {
|
||||
|
||||
ClientRegionFactoryBean<String, Animal> clientRegion = new ClientRegionFactoryBean<>();
|
||||
|
||||
clientRegion.setCache(gemfireCache);
|
||||
clientRegion.setClose(false);
|
||||
clientRegion.setKeyConstraint(String.class);
|
||||
clientRegion.setShortcut(ClientRegionShortcut.LOCAL);
|
||||
clientRegion.setValueConstraint(Animal.class);
|
||||
|
||||
return clientRegion;
|
||||
}
|
||||
}
|
||||
|
||||
@ClientCacheApplication
|
||||
@EnableGemFireMockObjects
|
||||
@EnableGemfireRepositories(basePackageClasses = PlantRepository.class,
|
||||
includeFilters = @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = PlantRepository.class)
|
||||
)
|
||||
@SuppressWarnings("unused")
|
||||
static class TestIncompatibleRepositoryIdEntityIdTypeConfiguration {
|
||||
|
||||
@Bean("Plants")
|
||||
public ClientRegionFactoryBean<Object, Object> clientRegion(GemFireCache gemfireCache) {
|
||||
|
||||
ClientRegionFactoryBean<Object, Object> clientRegion = new ClientRegionFactoryBean<>();
|
||||
|
||||
clientRegion.setCache(gemfireCache);
|
||||
clientRegion.setClose(false);
|
||||
clientRegion.setShortcut(ClientRegionShortcut.PROXY);
|
||||
|
||||
return clientRegion;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -17,23 +17,18 @@
|
||||
package org.springframework.data.gemfire.repository.query;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.hamcrest.Matchers.nullValue;
|
||||
import static org.mockito.Matchers.eq;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.ExpectedException;
|
||||
import org.springframework.data.gemfire.mapping.GemfirePersistentEntity;
|
||||
import org.springframework.data.repository.query.parser.PartTree;
|
||||
|
||||
/**
|
||||
* Test suite of test cases testing the contract and functionality of the {@link QueryBuilder} class.
|
||||
* Unit tests for {@link QueryBuilder} class.
|
||||
*
|
||||
* @author John Blum
|
||||
* @see org.junit.Test
|
||||
@@ -43,12 +38,11 @@ import org.springframework.data.repository.query.parser.PartTree;
|
||||
*/
|
||||
public class QueryBuilderUnitTests {
|
||||
|
||||
@Rule
|
||||
public ExpectedException exception = ExpectedException.none();
|
||||
|
||||
@Test
|
||||
public void createQueryBuilderWithDistinctQuery() {
|
||||
|
||||
GemfirePersistentEntity<?> mockPersistentEntity = mock(GemfirePersistentEntity.class);
|
||||
|
||||
PartTree mockPartTree = mock(PartTree.class);
|
||||
|
||||
when(mockPersistentEntity.getRegionName()).thenReturn("Example");
|
||||
@@ -64,7 +58,9 @@ public class QueryBuilderUnitTests {
|
||||
|
||||
@Test
|
||||
public void createQueryBuilderWithNonDistinctQuery() {
|
||||
|
||||
GemfirePersistentEntity<?> mockPersistentEntity = mock(GemfirePersistentEntity.class);
|
||||
|
||||
PartTree mockPartTree = mock(PartTree.class);
|
||||
|
||||
when(mockPersistentEntity.getRegionName()).thenReturn("Example");
|
||||
@@ -78,24 +74,31 @@ public class QueryBuilderUnitTests {
|
||||
verify(mockPartTree, times(1)).isDistinct();
|
||||
}
|
||||
|
||||
@Test
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void createQueryBuilderWithNullQueryString() {
|
||||
exception.expect(IllegalArgumentException.class);
|
||||
exception.expectCause(is(nullValue(Throwable.class)));
|
||||
exception.expectMessage(is(equalTo("An OQL Query must be specified")));
|
||||
|
||||
new QueryBuilder(null);
|
||||
try {
|
||||
new QueryBuilder(null);
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
|
||||
assertThat(expected).hasMessage("Query is required");
|
||||
assertThat(expected).hasNoCause();
|
||||
|
||||
throw expected;
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("all")
|
||||
public void createWithPredicate() {
|
||||
|
||||
Predicate mockPredicate = mock(Predicate.class);
|
||||
|
||||
when(mockPredicate.toString(eq(QueryBuilder.DEFAULT_ALIAS))).thenReturn("x.id = 1");
|
||||
|
||||
QueryBuilder queryBuilder = new QueryBuilder(
|
||||
String.format("SELECT * FROM /Example %s", QueryBuilder.DEFAULT_ALIAS));
|
||||
QueryBuilder queryBuilder =
|
||||
new QueryBuilder(String.format("SELECT * FROM /Example %s", QueryBuilder.DEFAULT_ALIAS));
|
||||
|
||||
QueryString queryString = queryBuilder.create(mockPredicate);
|
||||
|
||||
@@ -107,6 +110,7 @@ public class QueryBuilderUnitTests {
|
||||
|
||||
@Test
|
||||
public void createWithNullPredicate() {
|
||||
|
||||
QueryBuilder queryBuilder = new QueryBuilder("SELECT * FROM /Example");
|
||||
|
||||
QueryString queryString = queryBuilder.create(null);
|
||||
|
||||
@@ -0,0 +1,227 @@
|
||||
/*
|
||||
* Copyright 2017 the original author or authors.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package org.springframework.data.gemfire.repository.query;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
import org.apache.geode.cache.GemFireCache;
|
||||
import org.apache.geode.cache.client.ClientRegionShortcut;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.data.gemfire.client.ClientRegionFactoryBean;
|
||||
import org.springframework.data.gemfire.config.annotation.ClientCacheApplication;
|
||||
import org.springframework.data.gemfire.mapping.GemfireMappingContext;
|
||||
import org.springframework.data.gemfire.repository.sample.Person;
|
||||
import org.springframework.data.gemfire.repository.sample.PersonRepository;
|
||||
import org.springframework.data.gemfire.repository.sample.User;
|
||||
import org.springframework.data.gemfire.repository.sample.UserRepository;
|
||||
import org.springframework.data.gemfire.repository.support.GemfireRepositoryFactoryBean;
|
||||
import org.springframework.data.repository.Repository;
|
||||
import org.springframework.data.repository.query.QueryMethod;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
/**
|
||||
* The QueryPostProcessorIntegrationTests class...
|
||||
*
|
||||
* @author John Blum
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@RunWith(SpringRunner.class)
|
||||
@ContextConfiguration
|
||||
public class QueryPostProcessorIntegrationTests {
|
||||
|
||||
private static final AtomicLong idSequence = new AtomicLong(0L);
|
||||
|
||||
@Autowired
|
||||
private FindOrderedLimitedPeopleByFirstNameQueryPostProcessor peopleQueryPostProcessor;
|
||||
|
||||
@Autowired
|
||||
private PersonRepository personRepository;
|
||||
|
||||
@Autowired
|
||||
private RecordingQueryPostProcessor recordingQueryPostProcessor;
|
||||
|
||||
@Autowired
|
||||
private UserRepository userRepository;
|
||||
|
||||
private static Person newPerson(String firstName, String lastName) {
|
||||
|
||||
Person person = new Person(firstName, lastName);
|
||||
|
||||
person.id = idSequence.incrementAndGet();
|
||||
|
||||
return person;
|
||||
}
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
|
||||
this.personRepository.save(newPerson("Jon", "Doe"));
|
||||
this.personRepository.save(newPerson("Cookie", "Doe"));
|
||||
this.personRepository.save(newPerson("Pie", "Doe"));
|
||||
this.personRepository.save(newPerson("Sour", "Doe"));
|
||||
this.personRepository.save(newPerson("Jack", "BeNimble"));
|
||||
this.personRepository.save(newPerson("Jack", "BeQuick"));
|
||||
this.personRepository.save(newPerson("Jack", "Black"));
|
||||
this.personRepository.save(newPerson("Jack", "JumpedOverTheCandleStick"));
|
||||
this.personRepository.save(newPerson("Jack", "Handy"));
|
||||
this.personRepository.save(newPerson("Jack", "Sparrow"));
|
||||
this.personRepository.save(newPerson("Agent", "Smith"));
|
||||
|
||||
this.userRepository.save(new User("abuser"));
|
||||
this.userRepository.save(new User("jdoe"));
|
||||
this.userRepository.save(new User("root"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void queryPostProcessingProcessesGeneratedOqlQueries() {
|
||||
|
||||
assertThat(this.personRepository.count()).isEqualTo(11);
|
||||
assertThat(this.userRepository.count()).isEqualTo(3);
|
||||
assertThat(this.recordingQueryPostProcessor.queries).isEmpty();
|
||||
|
||||
List<User> users = this.userRepository.findDistinctByUsernameLike("%doe");
|
||||
|
||||
assertThat(users).hasSize(1);
|
||||
assertThat(this.recordingQueryPostProcessor.queries).hasSize(1);
|
||||
assertThat(this.recordingQueryPostProcessor.queries)
|
||||
.containsExactly("SELECT DISTINCT * FROM /Users x WHERE x.username LIKE $1");
|
||||
|
||||
Collection<Person> bakingDoes = this.personRepository.findByFirstnameIn("Cookie", "Pie", "Sour");
|
||||
|
||||
assertThat(bakingDoes).hasSize(3);
|
||||
assertThat(this.recordingQueryPostProcessor.queries).hasSize(2);
|
||||
assertThat(this.recordingQueryPostProcessor.queries).containsExactly(
|
||||
"SELECT DISTINCT * FROM /Users x WHERE x.username LIKE $1",
|
||||
"SELECT * FROM /simple x WHERE x.firstname IN SET ('Cookie', 'Pie', 'Sour')"
|
||||
);
|
||||
|
||||
Collection<Person> jacks = this.personRepository.findByFirstname("Jack");
|
||||
|
||||
assertThat(jacks).hasSize(1);
|
||||
assertThat(jacks.stream().findFirst().map(Person::getName).orElse(null)).isEqualTo("Jack Sparrow");
|
||||
|
||||
assertThat(this.recordingQueryPostProcessor.queries).hasSize(3);
|
||||
assertThat(this.recordingQueryPostProcessor.queries).containsExactly(
|
||||
"SELECT DISTINCT * FROM /Users x WHERE x.username LIKE $1",
|
||||
"SELECT * FROM /simple x WHERE x.firstname IN SET ('Cookie', 'Pie', 'Sour')",
|
||||
"SELECT DISTINCT * FROM /simple x WHERE x.firstname = $1 ORDER BY lastname DESC LIMIT 1"
|
||||
);
|
||||
}
|
||||
|
||||
@ClientCacheApplication
|
||||
@SuppressWarnings("unused")
|
||||
static class TestConfiguration {
|
||||
|
||||
@Bean("simple")
|
||||
public ClientRegionFactoryBean<Object, Object> peopleRegion(GemFireCache gemfireCache) {
|
||||
|
||||
ClientRegionFactoryBean<Object, Object> clientRegion = new ClientRegionFactoryBean<>();
|
||||
|
||||
clientRegion.setCache(gemfireCache);
|
||||
clientRegion.setClose(false);
|
||||
clientRegion.setShortcut(ClientRegionShortcut.LOCAL);
|
||||
|
||||
return clientRegion;
|
||||
}
|
||||
|
||||
@Bean("Users")
|
||||
public ClientRegionFactoryBean<Object, Object> usersRegion(GemFireCache gemfireCache) {
|
||||
|
||||
ClientRegionFactoryBean<Object, Object> clientRegion = new ClientRegionFactoryBean<>();
|
||||
|
||||
clientRegion.setCache(gemfireCache);
|
||||
clientRegion.setClose(false);
|
||||
clientRegion.setShortcut(ClientRegionShortcut.LOCAL);
|
||||
|
||||
return clientRegion;
|
||||
}
|
||||
|
||||
@Bean
|
||||
GemfireMappingContext mappingContext() {
|
||||
return new GemfireMappingContext();
|
||||
}
|
||||
|
||||
@Bean
|
||||
GemfireRepositoryFactoryBean<PersonRepository, Person, Long> personRepository() {
|
||||
return new GemfireRepositoryFactoryBean<>(PersonRepository.class);
|
||||
}
|
||||
|
||||
@Bean
|
||||
GemfireRepositoryFactoryBean<UserRepository, User, String> userRepository() {
|
||||
return new GemfireRepositoryFactoryBean<>(UserRepository.class);
|
||||
}
|
||||
|
||||
@Bean
|
||||
FindOrderedLimitedPeopleByFirstNameQueryPostProcessor personQueryPostProcess() {
|
||||
return new FindOrderedLimitedPeopleByFirstNameQueryPostProcessor(1);
|
||||
}
|
||||
|
||||
@Bean
|
||||
RecordingQueryPostProcessor recordingQueryPostProcessor() {
|
||||
return new RecordingQueryPostProcessor();
|
||||
}
|
||||
}
|
||||
|
||||
static class FindOrderedLimitedPeopleByFirstNameQueryPostProcessor implements QueryPostProcessor<PersonRepository, String> {
|
||||
|
||||
private final int limit;
|
||||
|
||||
FindOrderedLimitedPeopleByFirstNameQueryPostProcessor(int limit) {
|
||||
this.limit = limit;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOrder() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String postProcess(QueryMethod queryMethod, String query, Object... arguments) {
|
||||
|
||||
return "findByFirstname".equals(queryMethod.getName())
|
||||
? query.trim().replace("SELECT", "SELECT DISTINCT")
|
||||
.concat(" ORDER BY lastname DESC").concat(String.format(" LIMIT %d", this.limit))
|
||||
: query;
|
||||
}
|
||||
}
|
||||
|
||||
static class RecordingQueryPostProcessor implements QueryPostProcessor<Repository, String> {
|
||||
|
||||
List<String> queries = new CopyOnWriteArrayList<>();
|
||||
|
||||
@Override
|
||||
public int getOrder() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String postProcess(QueryMethod queryMethod, String query, Object... arguments) {
|
||||
this.queries.add(query);
|
||||
return query;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,123 @@
|
||||
/*
|
||||
* Copyright 2017 the original author or authors.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package org.springframework.data.gemfire.repository.query;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.inOrder;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.mockito.InOrder;
|
||||
import org.springframework.data.repository.query.QueryMethod;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link QueryPostProcessor}.
|
||||
*
|
||||
* @author John Blum
|
||||
* @see org.junit.Test
|
||||
* @see org.mockito.Mockito
|
||||
* @see org.springframework.data.gemfire.repository.query.QueryPostProcessor
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public class QueryPostProcessorUnitTests {
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
public void processAfterReturnsCompositeQueryPostProcessorAndPostProcessesInOrder() {
|
||||
|
||||
QueryMethod mockQueryMethod = mock(QueryMethod.class);
|
||||
|
||||
String query = "SELECT * FROM /Test";
|
||||
|
||||
QueryPostProcessor<?, String> mockQueryPostProcessorOne = mock(QueryPostProcessor.class);
|
||||
QueryPostProcessor<?, String> mockQueryPostProcessorTwo = mock(QueryPostProcessor.class);
|
||||
|
||||
when(mockQueryPostProcessorOne.processAfter(any())).thenCallRealMethod();
|
||||
when(mockQueryPostProcessorOne.postProcess(any(QueryMethod.class), anyString(), any())).thenReturn(query);
|
||||
when(mockQueryPostProcessorTwo.postProcess(any(QueryMethod.class), anyString(), any())).thenReturn(query);
|
||||
|
||||
QueryPostProcessor<?, String> composite = mockQueryPostProcessorOne.processAfter(mockQueryPostProcessorTwo);
|
||||
|
||||
assertThat(composite).isNotNull();
|
||||
assertThat(composite).isNotSameAs(mockQueryPostProcessorOne);
|
||||
assertThat(composite).isNotSameAs(mockQueryPostProcessorTwo);
|
||||
assertThat(composite.postProcess(mockQueryMethod, query)).isEqualTo(query);
|
||||
|
||||
InOrder inOrder = inOrder(mockQueryPostProcessorOne, mockQueryPostProcessorTwo);
|
||||
|
||||
inOrder.verify(mockQueryPostProcessorTwo, times(1))
|
||||
.postProcess(eq(mockQueryMethod), eq(query), any());
|
||||
|
||||
inOrder.verify(mockQueryPostProcessorOne, times(1))
|
||||
.postProcess(eq(mockQueryMethod), eq(query), any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void processAfterReturnsThis() {
|
||||
|
||||
QueryPostProcessor<?, ?> mockQueryPostProcessor = mock(QueryPostProcessor.class);
|
||||
|
||||
when(mockQueryPostProcessor.processAfter(any())).thenCallRealMethod();
|
||||
|
||||
assertThat(mockQueryPostProcessor.processAfter(null)).isSameAs(mockQueryPostProcessor);
|
||||
}
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
public void processBeforeReturnsCompositeQueryPostProcessorAndPostProcessesInOrder() {
|
||||
|
||||
QueryMethod mockQueryMethod = mock(QueryMethod.class);
|
||||
|
||||
String query = "SELECT * FROM /Test";
|
||||
|
||||
QueryPostProcessor<?, String> mockQueryPostProcessorOne = mock(QueryPostProcessor.class);
|
||||
QueryPostProcessor<?, String> mockQueryPostProcessorTwo = mock(QueryPostProcessor.class);
|
||||
|
||||
when(mockQueryPostProcessorOne.processBefore(any())).thenCallRealMethod();
|
||||
when(mockQueryPostProcessorOne.postProcess(any(QueryMethod.class), anyString(), any())).thenReturn(query);
|
||||
when(mockQueryPostProcessorTwo.postProcess(any(QueryMethod.class), anyString(), any())).thenReturn(query);
|
||||
|
||||
QueryPostProcessor<?, String> composite = mockQueryPostProcessorOne.processBefore(mockQueryPostProcessorTwo);
|
||||
|
||||
assertThat(composite).isNotNull();
|
||||
assertThat(composite).isNotSameAs(mockQueryPostProcessorOne);
|
||||
assertThat(composite).isNotSameAs(mockQueryPostProcessorTwo);
|
||||
assertThat(composite.postProcess(mockQueryMethod, query)).isEqualTo(query);
|
||||
|
||||
InOrder inOrder = inOrder(mockQueryPostProcessorOne, mockQueryPostProcessorTwo);
|
||||
|
||||
inOrder.verify(mockQueryPostProcessorOne, times(1))
|
||||
.postProcess(eq(mockQueryMethod), eq(query), any());
|
||||
|
||||
inOrder.verify(mockQueryPostProcessorTwo, times(1))
|
||||
.postProcess(eq(mockQueryMethod), eq(query), any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void processBeforeReturnsThis() {
|
||||
|
||||
QueryPostProcessor<?, ?> mockQueryPostProcessor = mock(QueryPostProcessor.class);
|
||||
|
||||
when(mockQueryPostProcessor.processBefore(any())).thenCallRealMethod();
|
||||
|
||||
assertThat(mockQueryPostProcessor.processBefore(null)).isSameAs(mockQueryPostProcessor);
|
||||
}
|
||||
}
|
||||
@@ -17,9 +17,6 @@
|
||||
package org.springframework.data.gemfire.repository.query;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.hamcrest.Matchers.nullValue;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
@@ -61,61 +58,110 @@ public class QueryStringUnitTests {
|
||||
@SuppressWarnings("rawtypes")
|
||||
Region region;
|
||||
|
||||
protected Sort.Order newSortOrder(String property) {
|
||||
private Sort.Order newSortOrder(String property) {
|
||||
return newSortOrder(property, Sort.Direction.ASC);
|
||||
}
|
||||
|
||||
protected Sort.Order newSortOrder(String property, Sort.Direction direction) {
|
||||
private Sort.Order newSortOrder(String property, Sort.Direction direction) {
|
||||
return new Sort.Order(direction, property);
|
||||
}
|
||||
|
||||
protected Sort newSort(Sort.Order... orders) {
|
||||
return new Sort(orders);
|
||||
private Sort newSort(Sort.Order... orders) {
|
||||
return Sort.by(orders);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createQueryStringWithDomainType() {
|
||||
public void constructQueryStringWithDomainType() {
|
||||
assertThat(new QueryString(Person.class).toString()).isEqualTo("SELECT * FROM /Person");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createQueryStringWithDomainTypeHavingCount() {
|
||||
public void constructQueryStringWithDomainTypeAsCount() {
|
||||
assertThat(new QueryString(Person.class, true).toString()).isEqualTo("SELECT count(*) FROM /Person");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createQueryStringWithNullDomainType() {
|
||||
exception.expect(IllegalArgumentException.class);
|
||||
exception.expectCause(is(nullValue(Throwable.class)));
|
||||
exception.expectMessage(is(equalTo("domainType must not be null")));
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void constructQueryStringWithNullDomainType() {
|
||||
|
||||
new QueryString((Class<?>) null);
|
||||
try {
|
||||
new QueryString((Class<?>) null);
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
|
||||
assertThat(expected).hasMessage("Domain type is required");
|
||||
assertThat(expected).hasNoCause();
|
||||
|
||||
throw expected;
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createQueryStringWithQuery() {
|
||||
public void constructQueryStringWithQuery() {
|
||||
|
||||
String query = "SELECT * FROM /Example";
|
||||
|
||||
assertThat(new QueryString(query).toString()).isEqualTo(query);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createQueryStringWithUnspecifiedQueryThrowsIllegalArgumentException() {
|
||||
assertUnspecifiedQueryThrowsIllegalArgumentException("");
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void constructQueryStringWithBlankQueryThrowsIllegalArgumentException() {
|
||||
assertUnspecifiedQueryThrowsIllegalArgumentException(" ");
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void constructQueryStringWithEmptyQueryThrowsIllegalArgumentException() {
|
||||
assertUnspecifiedQueryThrowsIllegalArgumentException("");
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void constructQueryStringWithNullQueryThrowsIllegalArgumentException() {
|
||||
assertUnspecifiedQueryThrowsIllegalArgumentException(null);
|
||||
}
|
||||
|
||||
protected void assertUnspecifiedQueryThrowsIllegalArgumentException(String query) {
|
||||
exception.expect(IllegalArgumentException.class);
|
||||
exception.expectCause(is(nullValue(Throwable.class)));
|
||||
exception.expectMessage(is(equalTo("An OQL Query must be specified")));
|
||||
private void assertUnspecifiedQueryThrowsIllegalArgumentException(String query) {
|
||||
|
||||
new QueryString(query);
|
||||
try {
|
||||
new QueryString(query);
|
||||
}
|
||||
catch (Exception expected) {
|
||||
|
||||
assertThat(expected).hasMessage("Query [%s] is required", query);
|
||||
assertThat(expected).hasNoCause();
|
||||
|
||||
throw expected;
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void queryStringOfQuery() {
|
||||
|
||||
QueryString query = QueryString.of("SELECT * FROM /Test");
|
||||
|
||||
assertThat(query).isNotNull();
|
||||
assertThat(query.toString()).isEqualTo("SELECT * FROM /Test");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void queryStringFromDomainType() {
|
||||
|
||||
QueryString query = QueryString.from(Person.class);
|
||||
|
||||
assertThat(query).isNotNull();
|
||||
assertThat(query.toString()).isEqualTo("SELECT * FROM /Person");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void queryStringCountingObjectsOfDomainType() {
|
||||
|
||||
QueryString query = QueryString.count(Person.class);
|
||||
|
||||
assertThat(query).isNotNull();
|
||||
assertThat(query.toString()).isEqualTo("SELECT count(*) FROM /Person");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void hintPatternMatches() {
|
||||
|
||||
assertThat(matches(HINT_PATTERN, "<HINT 'ExampleIndex'>")).isTrue();
|
||||
assertThat(matches(HINT_PATTERN, "<HINT 'IdIdx'> SELECT * FROM /Example WHERE id = $1")).isTrue();
|
||||
assertThat(matches(HINT_PATTERN, "<HINT 'LastNameIdx', 'BirthDateIdx'> SELECT * FROM /Person WHERE lastName = $1 AND birthDate = $2")).isTrue();
|
||||
@@ -123,6 +169,7 @@ public class QueryStringUnitTests {
|
||||
|
||||
@Test
|
||||
public void hintPatternNoMatches() {
|
||||
|
||||
assertThat(matches(HINT_PATTERN, "HINT")).isFalse();
|
||||
assertThat(matches(HINT_PATTERN, "<HINT>")).isFalse();
|
||||
assertThat(matches(HINT_PATTERN, "<HINT ''>")).isFalse();
|
||||
@@ -136,6 +183,7 @@ public class QueryStringUnitTests {
|
||||
|
||||
@Test
|
||||
public void importPatternMatches() {
|
||||
|
||||
assertThat(matches(IMPORT_PATTERN, "IMPORT *;")).isTrue();
|
||||
assertThat(matches(IMPORT_PATTERN, "IMPORT org.example.*;")).isTrue();
|
||||
assertThat(matches(IMPORT_PATTERN, "IMPORT org.example.Type;")).isTrue();
|
||||
@@ -144,6 +192,7 @@ public class QueryStringUnitTests {
|
||||
|
||||
@Test
|
||||
public void importPatternNoMatches() {
|
||||
|
||||
assertThat(matches(IMPORT_PATTERN, "IMPORT")).isFalse();
|
||||
assertThat(matches(IMPORT_PATTERN, "IMPORT ;")).isFalse();
|
||||
assertThat(matches(IMPORT_PATTERN, "IMPORT *")).isFalse();
|
||||
@@ -153,6 +202,7 @@ public class QueryStringUnitTests {
|
||||
|
||||
@Test
|
||||
public void limitPatternMatches() {
|
||||
|
||||
assertThat(matches(LIMIT_PATTERN, "LIMIT 0")).isTrue();
|
||||
assertThat(matches(LIMIT_PATTERN, "LIMIT 1")).isTrue();
|
||||
assertThat(matches(LIMIT_PATTERN, "LIMIT 10")).isTrue();
|
||||
@@ -162,6 +212,7 @@ public class QueryStringUnitTests {
|
||||
|
||||
@Test
|
||||
public void limitPatternNoMatches() {
|
||||
|
||||
assertThat(matches(LIMIT_PATTERN, "LIMIT")).isFalse();
|
||||
assertThat(matches(LIMIT_PATTERN, "LIMIT lO")).isFalse();
|
||||
assertThat(matches(LIMIT_PATTERN, "LIMIT AF")).isFalse();
|
||||
@@ -172,6 +223,7 @@ public class QueryStringUnitTests {
|
||||
|
||||
@Test
|
||||
public void tracePatternMatches() {
|
||||
|
||||
assertThat(matches(TRACE_PATTERN, "<TRACE>")).isTrue();
|
||||
assertThat(matches(TRACE_PATTERN, "<TRACE> SELECT * FROM /Example")).isTrue();
|
||||
assertThat(matches(TRACE_PATTERN, "<TRACE>SELECT * FROM /Example")).isTrue();
|
||||
@@ -180,56 +232,78 @@ public class QueryStringUnitTests {
|
||||
|
||||
@Test
|
||||
public void tracePatternNoMatches() {
|
||||
|
||||
assertThat(matches(TRACE_PATTERN, "TRACE")).isFalse();
|
||||
assertThat(matches(TRACE_PATTERN, "TRACE SELECT * FROM /Example")).isFalse();
|
||||
assertThat(matches(TRACE_PATTERN, "<TRACE SELECT * FROM /Example>")).isFalse();
|
||||
}
|
||||
|
||||
protected boolean matches(Pattern pattern, String value) {
|
||||
private boolean matches(Pattern pattern, String value) {
|
||||
return pattern.matcher(value).find();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void asDistinctQuery() {
|
||||
|
||||
QueryString query = QueryString.of("SELECT * FROM /Test");
|
||||
|
||||
assertThat(query.asDistinct().toString()).isEqualTo("SELECT DISTINCT * FROM /Test");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void asDistinctWithDistinctQuery() {
|
||||
|
||||
QueryString query = QueryString.of("SELECT DISTINCT * FROM /Test");
|
||||
|
||||
assertThat(query.asDistinct().toString()).isEqualTo("SELECT DISTINCT * FROM /Test");
|
||||
}
|
||||
|
||||
// SGF-251
|
||||
@Test
|
||||
public void replacesDomainTypeSimpleNameWithRegionPathCorrectly() {
|
||||
QueryString query = new QueryString(Person.class);
|
||||
|
||||
when(region.getFullPath()).thenReturn("/foo/bar");
|
||||
QueryString query = QueryString.from(Person.class);
|
||||
|
||||
assertThat(query.forRegion(Person.class, region).toString()).isEqualTo("SELECT * FROM /foo/bar");
|
||||
when(this.region.getFullPath()).thenReturn("/foo/bar");
|
||||
|
||||
verify(region, times(1)).getFullPath();
|
||||
assertThat(query.toString()).isEqualTo("SELECT * FROM /Person");
|
||||
assertThat(query.fromRegion(Person.class, this.region).toString()).isEqualTo("SELECT * FROM /foo/bar");
|
||||
|
||||
verify(this.region, times(1)).getFullPath();
|
||||
}
|
||||
|
||||
// SGF-156, SGF-251
|
||||
@Test
|
||||
public void replacesFromClauseWithRegionPathCorrectly() {
|
||||
QueryString query = new QueryString("SELECT * FROM /Persons p WHERE p.lastname = $1");
|
||||
|
||||
when(region.getFullPath()).thenReturn("/People");
|
||||
QueryString query = QueryString.of("SELECT * FROM /Persons p WHERE p.lastname = $1");
|
||||
|
||||
assertThat(query.forRegion(Person.class, region).toString())
|
||||
when(this.region.getFullPath()).thenReturn("/People");
|
||||
|
||||
assertThat(query.fromRegion(Person.class, this.region).toString())
|
||||
.isEqualTo("SELECT * FROM /People p WHERE p.lastname = $1");
|
||||
|
||||
verify(region, times(1)).getFullPath();
|
||||
verify(this.region, times(1)).getFullPath();
|
||||
}
|
||||
|
||||
// SGF-252
|
||||
@Test
|
||||
public void replacesFullyQualifiedSubRegionPathWithRegionPathCorrectly() {
|
||||
QueryString query = new QueryString("SELECT * FROM //Local/Root/Users u WHERE u.username = $1");
|
||||
|
||||
when(region.getFullPath()).thenReturn("/Remote/Root/Users");
|
||||
QueryString query = QueryString.of("SELECT * FROM //Local/Root/Users u WHERE u.username = $1");
|
||||
|
||||
assertThat(query.forRegion(RootUser.class, region).toString())
|
||||
when(this.region.getFullPath()).thenReturn("/Remote/Root/Users");
|
||||
|
||||
assertThat(query.fromRegion(RootUser.class, this.region).toString())
|
||||
.isEqualTo("SELECT * FROM /Remote/Root/Users u WHERE u.username = $1");
|
||||
|
||||
verify(region, times(1)).getFullPath();
|
||||
verify(this.region, times(1)).getFullPath();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void bindsInValuesCorrectly() {
|
||||
QueryString query = new QueryString("SELECT * FROM /Collection WHERE elements IN SET $1");
|
||||
|
||||
QueryString query = QueryString.of("SELECT * FROM /Collection WHERE elements IN SET $1");
|
||||
|
||||
assertThat(query.bindIn(Arrays.asList(1, 2, 3)).toString())
|
||||
.isEqualTo("SELECT * FROM /Collection WHERE elements IN SET ('1', '2', '3')");
|
||||
@@ -237,22 +311,26 @@ public class QueryStringUnitTests {
|
||||
|
||||
@Test
|
||||
public void detectsInParameterIndexesCorrectly() {
|
||||
QueryString query = new QueryString("SELECT * FROM /Example WHERE values IN SET $1 OR IN SET $2");
|
||||
|
||||
QueryString query = QueryString.of("SELECT * FROM /Example WHERE values IN SET $1 OR IN SET $2");
|
||||
|
||||
assertThat(query.getInParameterIndexes()).isEqualTo(Arrays.asList(1, 2));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void addsNoOrderByClauseCorrectly() {
|
||||
QueryString query = new QueryString("SELECT * FROM /People p").orderBy(null);
|
||||
|
||||
QueryString query = QueryString.of("SELECT * FROM /People p").orderBy(null);
|
||||
|
||||
assertThat(query.toString()).isEqualTo("SELECT * FROM /People p");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void addsOrderByClauseCorrectly() {
|
||||
QueryString query = new QueryString("SELECT * FROM /People p WHERE p.lastName = $1")
|
||||
.orderBy(newSort(newSortOrder("lastName", Sort.Direction.DESC), newSortOrder("firstName")));
|
||||
|
||||
QueryString query = QueryString.of("SELECT * FROM /People p WHERE p.lastName = $1")
|
||||
.orderBy(newSort(newSortOrder("lastName", Sort.Direction.DESC),
|
||||
newSortOrder("firstName")));
|
||||
|
||||
assertThat(query.toString())
|
||||
.isEqualTo("SELECT DISTINCT * FROM /People p WHERE p.lastName = $1 ORDER BY lastName DESC, firstName ASC");
|
||||
@@ -260,7 +338,8 @@ public class QueryStringUnitTests {
|
||||
|
||||
@Test
|
||||
public void addsSingleOrderByClauseCorrectly() {
|
||||
QueryString query = new QueryString("SELECT DISTINCT p.lastName FROM /People p WHERE p.firstName = $1")
|
||||
|
||||
QueryString query = QueryString.of("SELECT DISTINCT p.lastName FROM /People p WHERE p.firstName = $1")
|
||||
.orderBy(newSort(newSortOrder("lastName")));
|
||||
|
||||
assertThat(query.toString())
|
||||
@@ -269,16 +348,18 @@ public class QueryStringUnitTests {
|
||||
|
||||
@Test
|
||||
public void withHints() {
|
||||
assertThat(new QueryString("SELECT * FROM /Example").withHints("IdIdx").toString())
|
||||
|
||||
assertThat(QueryString.of("SELECT * FROM /Example").withHints("IdIdx").toString())
|
||||
.isEqualTo("<HINT 'IdIdx'> SELECT * FROM /Example");
|
||||
|
||||
assertThat(new QueryString("SELECT * FROM /Example").withHints("IdIdx", "SpatialIdx", "TxDateIdx").toString())
|
||||
assertThat(QueryString.of("SELECT * FROM /Example").withHints("IdIdx", "SpatialIdx", "TxDateIdx").toString())
|
||||
.isEqualTo("<HINT 'IdIdx', 'SpatialIdx', 'TxDateIdx'> SELECT * FROM /Example");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void withoutHints() {
|
||||
QueryString expectedQueryString = new QueryString("SELECT * FROM /Example");
|
||||
|
||||
QueryString expectedQueryString = QueryString.of("SELECT * FROM /Example");
|
||||
|
||||
assertThat(expectedQueryString.withHints()).isSameAs(expectedQueryString);
|
||||
assertThat(expectedQueryString.withHints((String[]) null)).isSameAs(expectedQueryString);
|
||||
@@ -286,13 +367,14 @@ public class QueryStringUnitTests {
|
||||
|
||||
@Test
|
||||
public void withImport() {
|
||||
assertThat(new QueryString("SELECT * FROM /People").withImport("org.example.app.domain.Person").toString())
|
||||
assertThat(QueryString.of("SELECT * FROM /People").withImport("org.example.app.domain.Person").toString())
|
||||
.isEqualTo("IMPORT org.example.app.domain.Person; SELECT * FROM /People");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void withoutImport() {
|
||||
QueryString expectedQueryString = new QueryString("SELECT * FROM /Example");
|
||||
|
||||
QueryString expectedQueryString = QueryString.of("SELECT * FROM /Example");
|
||||
|
||||
assertThat(expectedQueryString.withImport(null)).isSameAs(expectedQueryString);
|
||||
assertThat(expectedQueryString.withImport("")).isSameAs(expectedQueryString);
|
||||
@@ -301,40 +383,47 @@ public class QueryStringUnitTests {
|
||||
|
||||
@Test
|
||||
public void withLimit() {
|
||||
assertThat(new QueryString("SELECT * FROM /Example").withLimit(10).toString())
|
||||
|
||||
assertThat(QueryString.of("SELECT * FROM /Example").withLimit(10).toString())
|
||||
.isEqualTo("SELECT * FROM /Example LIMIT 10");
|
||||
|
||||
assertThat(new QueryString("SELECT * FROM /Example").withLimit(0).toString())
|
||||
assertThat(QueryString.of("SELECT * FROM /Example").withLimit(0).toString())
|
||||
.isEqualTo("SELECT * FROM /Example LIMIT 0");
|
||||
|
||||
assertThat(new QueryString("SELECT * FROM /Example").withLimit(-5).toString())
|
||||
assertThat(QueryString.of("SELECT * FROM /Example").withLimit(-5).toString())
|
||||
.isEqualTo("SELECT * FROM /Example LIMIT -5");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void withoutLimit() {
|
||||
QueryString expectedQueryString = new QueryString("SELECT * FROM /Example");
|
||||
|
||||
QueryString expectedQueryString = QueryString.of("SELECT * FROM /Example");
|
||||
|
||||
assertThat(expectedQueryString.withLimit(null)).isSameAs(expectedQueryString);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void withTrace() {
|
||||
assertThat(new QueryString("SELECT * FROM /Example").withTrace().toString())
|
||||
assertThat(QueryString.of("SELECT * FROM /Example").withTrace().toString())
|
||||
.isEqualTo("<TRACE> SELECT * FROM /Example");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void withHintAndTrace() {
|
||||
assertThat(new QueryString("SELECT * FROM /Example").withHints("IdIdx").withTrace().toString())
|
||||
assertThat(QueryString.of("SELECT * FROM /Example").withHints("IdIdx").withTrace().toString())
|
||||
.isEqualTo("<TRACE> <HINT 'IdIdx'> SELECT * FROM /Example");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void withHintImportLimitAndTrace() {
|
||||
QueryString query = new QueryString("SELECT * FROM /Example");
|
||||
|
||||
assertThat(query.withImport("org.example.domain.Type").withHints("IdIdx", "NameIdx").withLimit(20).withTrace().toString())
|
||||
QueryString query = QueryString.of("SELECT * FROM /Example")
|
||||
.withImport("org.example.domain.Type")
|
||||
.withHints("IdIdx", "NameIdx")
|
||||
.withLimit(20)
|
||||
.withTrace();
|
||||
|
||||
assertThat(query.toString())
|
||||
.isEqualTo("<TRACE> <HINT 'IdIdx', 'NameIdx'> IMPORT org.example.domain.Type; SELECT * FROM /Example LIMIT 20");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,9 +18,7 @@ package org.springframework.data.gemfire.repository.query;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.equalTo;
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.hamcrest.CoreMatchers.not;
|
||||
import static org.hamcrest.CoreMatchers.notNullValue;
|
||||
import static org.hamcrest.CoreMatchers.sameInstance;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
@@ -59,7 +57,9 @@ public class StringBasedGemfireRepositoryQueryTest {
|
||||
|
||||
@Test
|
||||
public void testToCollectionWithSelectResults() {
|
||||
|
||||
SelectResults mockSelectResults = mock(SelectResults.class, "testToCollectionWithSelectResults.SelectResults");
|
||||
|
||||
List<String> expectedList = Arrays.asList("one", "two", "three");
|
||||
|
||||
when(mockSelectResults.asList()).thenReturn(expectedList);
|
||||
@@ -71,7 +71,9 @@ public class StringBasedGemfireRepositoryQueryTest {
|
||||
|
||||
@Test
|
||||
public void testToCollectionWithResultsBag() {
|
||||
|
||||
ResultsBag mockResultsBag = mock(ResultsBag.class, "testToCollectionWithResultsBag.ResultsBag");
|
||||
|
||||
List<String> expectedList = Arrays.asList("a", "b", "c");
|
||||
|
||||
when(mockResultsBag.asList()).thenReturn(expectedList);
|
||||
@@ -83,7 +85,9 @@ public class StringBasedGemfireRepositoryQueryTest {
|
||||
|
||||
@Test
|
||||
public void testToCollectionWithCollection() {
|
||||
|
||||
List<String> expectedList = Arrays.asList("x", "y", "z");
|
||||
|
||||
Collection<?> actualList = repositoryQuery.toCollection(expectedList);
|
||||
|
||||
assertSame(expectedList, actualList);
|
||||
@@ -91,7 +95,9 @@ public class StringBasedGemfireRepositoryQueryTest {
|
||||
|
||||
@Test
|
||||
public void testToCollectionWithArray() {
|
||||
|
||||
Object[] array = { 1, 2, 3 };
|
||||
|
||||
Collection<?> list = repositoryQuery.toCollection(array);
|
||||
|
||||
assertNotNull(list);
|
||||
@@ -103,6 +109,7 @@ public class StringBasedGemfireRepositoryQueryTest {
|
||||
|
||||
@Test
|
||||
public void testToCollectionWithSingleObject() {
|
||||
|
||||
Collection<?> list = repositoryQuery.toCollection("test");
|
||||
|
||||
assertTrue(list instanceof List);
|
||||
@@ -113,6 +120,7 @@ public class StringBasedGemfireRepositoryQueryTest {
|
||||
|
||||
@Test
|
||||
public void testToCollectionWithNull() {
|
||||
|
||||
Collection<?> list = repositoryQuery.toCollection(null);
|
||||
|
||||
assertNotNull(list);
|
||||
@@ -121,6 +129,7 @@ public class StringBasedGemfireRepositoryQueryTest {
|
||||
|
||||
@Test
|
||||
public void applyAllQueryAnnotationExtensions() {
|
||||
|
||||
GemfireQueryMethod mockQueryMethod = mock(GemfireQueryMethod.class, "MockGemfireQueryMethod");
|
||||
|
||||
when(mockQueryMethod.hasHint()).thenReturn(true);
|
||||
@@ -131,18 +140,18 @@ public class StringBasedGemfireRepositoryQueryTest {
|
||||
when(mockQueryMethod.getLimit()).thenReturn(10);
|
||||
when(mockQueryMethod.hasTrace()).thenReturn(true);
|
||||
|
||||
QueryString queryString = new QueryString("SELECT * FROM /Example");
|
||||
QueryString queryString = QueryString.of("SELECT * FROM /Example");
|
||||
|
||||
assertThat(queryString.toString(), is(equalTo("SELECT * FROM /Example")));
|
||||
|
||||
StringBasedGemfireRepositoryQuery repositoryQuery = new StringBasedGemfireRepositoryQuery();
|
||||
|
||||
QueryString actualQueryString = repositoryQuery.applyQueryAnnotationExtensions(mockQueryMethod, queryString);
|
||||
String postProcessedQueryString = repositoryQuery.getQueryPostProcessor()
|
||||
.postProcess(mockQueryMethod, queryString.toString());
|
||||
|
||||
assertThat(actualQueryString, is(notNullValue()));
|
||||
assertThat(actualQueryString, is(not(sameInstance(queryString))));
|
||||
assertThat(actualQueryString.toString(), is(equalTo(
|
||||
"<TRACE> <HINT 'IdIdx', 'NameIdx'> IMPORT org.example.domain.Type; SELECT * FROM /Example LIMIT 10")));
|
||||
assertThat(postProcessedQueryString, is(notNullValue()));
|
||||
assertThat(postProcessedQueryString,
|
||||
is(equalTo("<TRACE> <HINT 'IdIdx', 'NameIdx'> IMPORT org.example.domain.Type; SELECT * FROM /Example LIMIT 10")));
|
||||
|
||||
verify(mockQueryMethod, times(1)).hasHint();
|
||||
verify(mockQueryMethod, times(1)).getHints();
|
||||
@@ -155,6 +164,7 @@ public class StringBasedGemfireRepositoryQueryTest {
|
||||
|
||||
@Test
|
||||
public void applyHintLimitAndTraceQueryAnnotationExtensionsWithExistingHintAndLimit() {
|
||||
|
||||
GemfireQueryMethod mockQueryMethod = mock(GemfireQueryMethod.class, "MockGemfireQueryMethod");
|
||||
|
||||
when(mockQueryMethod.hasHint()).thenReturn(true);
|
||||
@@ -170,12 +180,11 @@ public class StringBasedGemfireRepositoryQueryTest {
|
||||
|
||||
StringBasedGemfireRepositoryQuery repositoryQuery = new StringBasedGemfireRepositoryQuery();
|
||||
|
||||
QueryString actualQueryString = repositoryQuery.applyQueryAnnotationExtensions(mockQueryMethod, queryString);
|
||||
String postProcessedQueryString = repositoryQuery.getQueryPostProcessor().postProcess(mockQueryMethod, queryString.toString());
|
||||
|
||||
assertThat(actualQueryString, is(notNullValue()));
|
||||
assertThat(actualQueryString, is(not(sameInstance(queryString))));
|
||||
assertThat(actualQueryString.toString(), is(equalTo(
|
||||
"<TRACE> <HINT 'LastNameIdx'> SELECT * FROM /Example LIMIT 25")));
|
||||
assertThat(postProcessedQueryString, is(notNullValue()));
|
||||
assertThat(postProcessedQueryString,
|
||||
is(equalTo("<TRACE> <HINT 'LastNameIdx'> SELECT * FROM /Example LIMIT 25")));
|
||||
|
||||
verify(mockQueryMethod, times(1)).hasHint();
|
||||
verify(mockQueryMethod, never()).getHints();
|
||||
@@ -188,6 +197,7 @@ public class StringBasedGemfireRepositoryQueryTest {
|
||||
|
||||
@Test
|
||||
public void applyImportAndTraceQueryAnnotationExtensionsWithExistingTrace() {
|
||||
|
||||
GemfireQueryMethod mockQueryMethod = mock(GemfireQueryMethod.class, "MockGemfireQueryMethod");
|
||||
|
||||
when(mockQueryMethod.hasHint()).thenReturn(false);
|
||||
@@ -202,12 +212,11 @@ public class StringBasedGemfireRepositoryQueryTest {
|
||||
|
||||
StringBasedGemfireRepositoryQuery repositoryQuery = new StringBasedGemfireRepositoryQuery();
|
||||
|
||||
QueryString actualQueryString = repositoryQuery.applyQueryAnnotationExtensions(mockQueryMethod, queryString);
|
||||
String postProcessedQueryString = repositoryQuery.getQueryPostProcessor().postProcess(mockQueryMethod, queryString.toString());
|
||||
|
||||
assertThat(actualQueryString, is(notNullValue()));
|
||||
assertThat(actualQueryString, is(not(sameInstance(queryString))));
|
||||
assertThat(actualQueryString.toString(), is(equalTo(
|
||||
"IMPORT org.example.domain.Type; <TRACE> SELECT * FROM /Example")));
|
||||
assertThat(postProcessedQueryString, is(notNullValue()));
|
||||
assertThat(postProcessedQueryString,
|
||||
is(equalTo("IMPORT org.example.domain.Type; <TRACE> SELECT * FROM /Example")));
|
||||
|
||||
verify(mockQueryMethod, times(1)).hasHint();
|
||||
verify(mockQueryMethod, never()).getHints();
|
||||
@@ -217,5 +226,4 @@ public class StringBasedGemfireRepositoryQueryTest {
|
||||
verify(mockQueryMethod, never()).getLimit();
|
||||
verify(mockQueryMethod, times(1)).hasTrace();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -21,6 +21,8 @@ import org.springframework.data.gemfire.mapping.annotation.Region;
|
||||
import org.springframework.data.gemfire.mapping.annotation.ReplicateRegion;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* The Customer class is a class abstraction modeling a Customer.
|
||||
*
|
||||
@@ -29,6 +31,7 @@ import org.springframework.util.ObjectUtils;
|
||||
* @see Region
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@Data
|
||||
@ReplicateRegion("Customers")
|
||||
@SuppressWarnings("unused")
|
||||
public class Customer {
|
||||
@@ -42,39 +45,15 @@ public class Customer {
|
||||
public Customer() {
|
||||
}
|
||||
|
||||
public Customer(final Long id) {
|
||||
public Customer(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public Customer(final String firstName, final String lastName) {
|
||||
public Customer(String firstName, String lastName) {
|
||||
this.firstName = firstName;
|
||||
this.lastName = lastName;
|
||||
}
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(final Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getFirstName() {
|
||||
return firstName;
|
||||
}
|
||||
|
||||
public void setFirstName(final String firstName) {
|
||||
this.firstName = firstName;
|
||||
}
|
||||
|
||||
public String getLastName() {
|
||||
return lastName;
|
||||
}
|
||||
|
||||
public void setLastName(final String lastName) {
|
||||
this.lastName = lastName;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return String.format("%1$s %2$s", getFirstName(), getLastName());
|
||||
}
|
||||
@@ -85,7 +64,8 @@ public class Customer {
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object obj) {
|
||||
if (obj == this) {
|
||||
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -100,7 +80,7 @@ public class Customer {
|
||||
&& ObjectUtils.nullSafeEquals(this.getLastName(), that.getLastName());
|
||||
}
|
||||
|
||||
protected static int hashCodeIgnoreNull(final Object obj) {
|
||||
protected static int hashCodeIgnoreNull(Object obj) {
|
||||
return (obj != null ? obj.hashCode() : 0);
|
||||
}
|
||||
|
||||
@@ -115,7 +95,6 @@ public class Customer {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("%1$s %2$s", getFirstName(), getLastName());
|
||||
return getName();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,72 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2018 the original author or authors.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package org.springframework.data.gemfire.repository.sample;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.beans.factory.BeanCreationException;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||
|
||||
/**
|
||||
* The IncompatibleRegionKeyEntityIdAnimalRepositoryTest class is a test suite of test cases testing the functionality
|
||||
* behind PR #55 involving persisting application domain object/entities to multiple Regions in GemFire's Cache.
|
||||
*
|
||||
* @author John Blum
|
||||
* @see org.junit.Test
|
||||
* @see org.springframework.context.ConfigurableApplicationContext
|
||||
* @since 1.4.0
|
||||
* @link https://github.com/spring-projects/spring-data-gemfire/pull/55
|
||||
*/
|
||||
public class IncompatibleRegionKeyEntityIdAnimalRepositoryTest {
|
||||
|
||||
private static final String APPLICATION_CONTEXT_CONFIG_LOCATION = String.format("%1$s%2$s%1$s%3$s",
|
||||
File.separator, AnimalRepositoryTest.class.getPackage().getName().replace('.', File.separatorChar),
|
||||
String.format("%s-context.xml", IncompatibleRegionKeyEntityIdAnimalRepositoryTest.class.getSimpleName()));
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void storeAnimalHavingLongIdInRabbitsRegionWithStringKey() {
|
||||
try {
|
||||
ConfigurableApplicationContext applicationContext =
|
||||
new ClassPathXmlApplicationContext(APPLICATION_CONTEXT_CONFIG_LOCATION);
|
||||
|
||||
applicationContext.getBean(RabbitRepository.class);
|
||||
}
|
||||
// NOTE the ClassCastException thrown from GemFire is unexpected; this is not correct and the identifying type
|
||||
// mismatch should be caught and handled by GemfireRepositoryFactory.getTemplate(..) method on line 129
|
||||
// (appropriately throwing an IllegalArgumentException) after satisfying the condition on line 128,
|
||||
// which always occurs with the @Region annotation set on the domain class/entity!
|
||||
catch (ClassCastException unexpected) {
|
||||
//unexpected.printStackTrace(System.err);
|
||||
//assertTrue(unexpected.getMessage().contains("key ( java.lang.Long ) does not satisfy keyConstraint ( java.lang.String )"));
|
||||
fail(unexpected.getMessage());
|
||||
}
|
||||
catch (BeanCreationException expected) {
|
||||
//expected.printStackTrace(System.err);
|
||||
assertTrue(expected.getCause() instanceof IllegalArgumentException);
|
||||
assertEquals(String.format("The Region referenced only supports keys of type [%1$s], but the entity to be stored has an id of type [%2$s]",
|
||||
String.class.getName(), Long.class.getName()), expected.getCause().getMessage());
|
||||
|
||||
throw (IllegalArgumentException) expected.getCause();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -33,20 +33,20 @@ import org.springframework.util.ObjectUtils;
|
||||
public class Plant {
|
||||
|
||||
@Id
|
||||
private String id;
|
||||
private Long id;
|
||||
|
||||
private String name;
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
public Long getId() {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
public void setId(String id) {
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
return this.name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
@@ -55,7 +55,8 @@ public class Plant {
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object obj) {
|
||||
if (obj == this) {
|
||||
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -71,9 +72,12 @@ public class Plant {
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
|
||||
int hashValue = 17;
|
||||
|
||||
hashValue = 37 * hashValue + ObjectUtils.nullSafeHashCode(getId());
|
||||
hashValue = 37 * hashValue + ObjectUtils.nullSafeHashCode(getName());
|
||||
|
||||
return hashValue;
|
||||
}
|
||||
|
||||
@@ -81,5 +85,4 @@ public class Plant {
|
||||
public String toString() {
|
||||
return String.format("{ @type = %1$s, id = %2$s, name = %3$s }", getClass().getSimpleName(), getId(), getName());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,64 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2018 the original author or authors.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package org.springframework.data.gemfire.repository.sample;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.beans.factory.BeanCreationException;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||
|
||||
/**
|
||||
* The PlantRepositoryTest class is a test suite of test cases testing the functionality behind PR #55 involving
|
||||
* persisting application domain object/entities to multiple Regions in GemFire's Cache.
|
||||
*
|
||||
* @author John Blum
|
||||
* @see org.junit.Test
|
||||
* @see org.springframework.context.ConfigurableApplicationContext
|
||||
* @since 1.4.0
|
||||
* @link https://github.com/spring-projects/spring-data-gemfire/pull/55
|
||||
*/
|
||||
public class PlantRepositoryTest {
|
||||
|
||||
private static final String APPLICATION_CONTEXT_CONFIG_LOCATION = String.format("%1$s%2$s%1$s%3$s",
|
||||
File.separator, PlantRepositoryTest.class.getPackage().getName().replace('.', File.separatorChar),
|
||||
"PlantRepositoryTest-context.xml");
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void storePlantHavingStringIdInPlantsRegionWithLongKey() {
|
||||
try {
|
||||
ConfigurableApplicationContext context =
|
||||
new ClassPathXmlApplicationContext(APPLICATION_CONTEXT_CONFIG_LOCATION);
|
||||
|
||||
context.getBean(PlantRepository.class);
|
||||
}
|
||||
// NOTE technically, the IllegalArgumentException for incompatible Region 'Key' and Entity ID is thrown
|
||||
// when the Spring container starts up and the Repository beans are created.
|
||||
catch (BeanCreationException expected) {
|
||||
//expected.printStackTrace(System.err);
|
||||
assertTrue(expected.getCause() instanceof IllegalArgumentException);
|
||||
assertEquals(String.format("The Region referenced only supports keys of type [%1$s], but the entity to be stored has an id of type [%2$s]",
|
||||
Long.class.getName(), String.class.getName()), expected.getCause().getMessage());
|
||||
|
||||
throw (IllegalArgumentException) expected.getCause();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -93,7 +93,8 @@ public class User implements Comparable<User> {
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object obj) {
|
||||
if (obj == this) {
|
||||
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -113,9 +114,12 @@ public class User implements Comparable<User> {
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
|
||||
int hashValue = 17;
|
||||
|
||||
hashValue = 37 * hashValue + ObjectUtils.nullSafeHashCode(getEmail());
|
||||
hashValue = 37 * hashValue + ObjectUtils.nullSafeHashCode(getUsername());
|
||||
|
||||
return hashValue;
|
||||
}
|
||||
|
||||
@@ -123,5 +127,4 @@ public class User implements Comparable<User> {
|
||||
public String toString() {
|
||||
return getUsername();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -16,18 +16,16 @@
|
||||
|
||||
package org.springframework.data.gemfire.repository.support;
|
||||
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.hamcrest.Matchers.notNullValue;
|
||||
import static org.hamcrest.Matchers.nullValue;
|
||||
import static org.hamcrest.Matchers.startsWith;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.Mockito.atLeastOnce;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.verifyNoMoreInteractions;
|
||||
import static org.mockito.Mockito.verifyZeroInteractions;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.springframework.data.gemfire.util.RuntimeExceptionFactory.newUnsupportedOperationException;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Arrays;
|
||||
@@ -36,285 +34,509 @@ import java.util.Collections;
|
||||
import org.apache.geode.cache.Region;
|
||||
import org.apache.geode.cache.RegionAttributes;
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.ExpectedException;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.invocation.InvocationOnMock;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
import org.mockito.stubbing.Answer;
|
||||
import org.springframework.aop.framework.Advised;
|
||||
import org.springframework.data.gemfire.GemfireTemplate;
|
||||
import org.springframework.data.gemfire.mapping.GemfireMappingContext;
|
||||
import org.springframework.data.gemfire.mapping.GemfirePersistentEntity;
|
||||
import org.springframework.data.gemfire.repository.GemfireRepository;
|
||||
import org.springframework.data.gemfire.repository.sample.Person;
|
||||
import org.springframework.data.gemfire.util.RegionUtils;
|
||||
import org.springframework.data.repository.PagingAndSortingRepository;
|
||||
import org.springframework.data.repository.core.EntityInformation;
|
||||
import org.springframework.data.repository.core.RepositoryMetadata;
|
||||
import org.springframework.data.repository.core.support.RepositoryComposition;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link GemfireRepositoryFactory}.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
* @author John Blum
|
||||
* @see org.junit.Test
|
||||
* @see org.mockito.Mockito
|
||||
* @see org.springframework.data.gemfire.repository.support.GemfireRepositoryFactory
|
||||
*/
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
@SuppressWarnings("unused")
|
||||
@SuppressWarnings("rawtypes")
|
||||
public class GemfireRepositoryFactoryUnitTests {
|
||||
|
||||
@Rule
|
||||
public ExpectedException exception = ExpectedException.none();
|
||||
|
||||
private GemfireMappingContext gemfireMappingContext = new GemfireMappingContext();
|
||||
private GemfireMappingContext mappingContext;
|
||||
|
||||
@Mock
|
||||
private Region<Object, Object> mockRegion;
|
||||
private Region mockRegion;
|
||||
|
||||
@Mock
|
||||
@SuppressWarnings("rawtypes")
|
||||
private RegionAttributes mockRegionAttributes;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
protected <K, V> Region<K, V> configureMockRegion(Region<K, V> mockRegion, String name,
|
||||
Class<K> keyType, Class<V> valueType) {
|
||||
|
||||
when(mockRegion.getAttributes()).thenReturn(mockRegionAttributes);
|
||||
when(mockRegion.getFullPath()).thenReturn(String.format("%1$s%2$s", Region.SEPARATOR, name));
|
||||
when(mockRegion.getName()).thenReturn(name);
|
||||
when(mockRegionAttributes.getKeyConstraint()).thenReturn(keyType);
|
||||
when(mockRegionAttributes.getValueConstraint()).thenReturn(valueType);
|
||||
|
||||
return mockRegion;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
protected <K, V> Region<K, V> mockRegion(String name, Class<K> keyType, Class<V> valueType) {
|
||||
return configureMockRegion(mock(Region.class, name), name, keyType, valueType);
|
||||
}
|
||||
|
||||
protected RepositoryMetadata mockRepositoryMetadata(final Class<?> domainType, final Class<?> idType,
|
||||
final Class<?> repositoryInterface) {
|
||||
|
||||
RepositoryMetadata mockRepositoryMetadata = mock(RepositoryMetadata.class);
|
||||
|
||||
when(mockRepositoryMetadata.getDomainType()).then(new Answer<Class<?>>() {
|
||||
@Override public Class<?> answer(InvocationOnMock invocation) throws Throwable {
|
||||
return domainType;
|
||||
}
|
||||
});
|
||||
|
||||
when(mockRepositoryMetadata.getIdType()).then(new Answer<Class<?>>() {
|
||||
@Override public Class<?> answer(InvocationOnMock invocation) throws Throwable {
|
||||
return idType;
|
||||
}
|
||||
});
|
||||
|
||||
when(mockRepositoryMetadata.getRepositoryInterface()).then(new Answer<Class<?>>() {
|
||||
@Override public Class<?> answer(InvocationOnMock invocation) throws Throwable {
|
||||
return repositoryInterface;
|
||||
}
|
||||
});
|
||||
|
||||
return mockRepositoryMetadata;
|
||||
}
|
||||
|
||||
@Before
|
||||
@SuppressWarnings("unchecked")
|
||||
public void setup() {
|
||||
configureMockRegion(mockRegion, "simple", Object.class, Object.class);
|
||||
this.mappingContext = new GemfireMappingContext();
|
||||
configureMockRegion(this.mockRegion, "simple", Object.class, Object.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void constructGemfireRepositoryFactoryWithNullMappingContextThrowsIllegalArgumentException() {
|
||||
exception.expect(IllegalArgumentException.class);
|
||||
exception.expectCause(is(nullValue(Throwable.class)));
|
||||
exception.expectMessage("MappingContext must not be null");
|
||||
|
||||
new GemfireRepositoryFactory(Collections.<Region<?, ?>>emptyList(), null);
|
||||
@SuppressWarnings("unchecked")
|
||||
private <K, V> Region<K, V> mockRegion(String name, Class<K> keyType, Class<V> valueType) {
|
||||
return configureMockRegion(this.mockRegion, name, keyType, valueType);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void constructGemfireRepositoryFactoryWithNullRegionsThrowsIllegalArgumentException() {
|
||||
exception.expect(IllegalArgumentException.class);
|
||||
exception.expectCause(is(nullValue(Throwable.class)));
|
||||
exception.expectMessage("Regions must not be null");
|
||||
@SuppressWarnings("unchecked")
|
||||
private <K, V> Region<K, V> configureMockRegion(Region<K, V> mockRegion, String name,
|
||||
Class<K> keyType, Class<V> valueType) {
|
||||
|
||||
new GemfireRepositoryFactory(null, gemfireMappingContext);
|
||||
when(mockRegion.getAttributes()).thenReturn(this.mockRegionAttributes);
|
||||
when(mockRegion.getFullPath()).thenReturn(RegionUtils.toRegionPath(name));
|
||||
when(mockRegion.getName()).thenReturn(name);
|
||||
when(this.mockRegionAttributes.getKeyConstraint()).thenReturn(keyType);
|
||||
when(this.mockRegionAttributes.getValueConstraint()).thenReturn(valueType);
|
||||
|
||||
return mockRegion;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getRepositoryRegionNameFromRepositoryInterfaceWithRegionAnnotation() {
|
||||
GemfireRepositoryFactory gemfireRepositoryFactory = new GemfireRepositoryFactory(
|
||||
Collections.<Region<?, ?>>emptyList(), gemfireMappingContext);
|
||||
private RepositoryMetadata mockRepositoryMetadata(Class<?> domainType, Class<?> idType,
|
||||
Class<?> repositoryInterface) {
|
||||
|
||||
assertThat(gemfireRepositoryFactory.getRepositoryRegionName(PersonRepository.class),
|
||||
is(equalTo("People")));
|
||||
}
|
||||
RepositoryMetadata mockRepositoryMetadata = mock(RepositoryMetadata.class);
|
||||
|
||||
@Test
|
||||
public void getRepositoryRegionNameFromRepositoryInterfaceWithoutRegionAnnotation() {
|
||||
GemfireRepositoryFactory gemfireRepositoryFactory = new GemfireRepositoryFactory(
|
||||
Collections.<Region<?, ?>>emptyList(), gemfireMappingContext);
|
||||
when(mockRepositoryMetadata.getDomainType()).thenAnswer(invocation -> domainType);
|
||||
when(mockRepositoryMetadata.getIdType()).thenAnswer(invocation -> idType);
|
||||
when(mockRepositoryMetadata.getRepositoryInterface()).thenAnswer(invocation -> repositoryInterface);
|
||||
|
||||
assertThat(gemfireRepositoryFactory.getRepositoryRegionName(SampleCustomGemfireRepository.class),
|
||||
is(nullValue(String.class)));
|
||||
return mockRepositoryMetadata;
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
public void getTemplateReturnsGemfireTemplateForPeopleRegion() {
|
||||
RepositoryMetadata mockRepositoryMetadata = mockRepositoryMetadata(Person.class, Long.class,
|
||||
PersonRepository.class);
|
||||
public void constructGemfireRepositoryFactorySuccessfully() {
|
||||
|
||||
GemfireRepositoryFactory repositoryFactory =
|
||||
new GemfireRepositoryFactory(Collections.singletonList(this.mockRegion), this.mappingContext);
|
||||
|
||||
assertThat(repositoryFactory).isNotNull();
|
||||
assertThat(repositoryFactory.getMappingContext()).isEqualTo(this.mappingContext);
|
||||
assertThat(repositoryFactory.getRegions()).contains(this.mockRegion);
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void constructGemfireRepositoryFactoryWithNullMappingContextThrowsIllegalArgumentException() {
|
||||
|
||||
try {
|
||||
new GemfireRepositoryFactory(Collections.emptyList(), null);
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
|
||||
assertThat(expected).hasMessage("MappingContext is required");
|
||||
assertThat(expected).hasNoCause();
|
||||
|
||||
throw expected;
|
||||
}
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void constructGemfireRepositoryFactoryWithNullRegionsThrowsIllegalArgumentException() {
|
||||
|
||||
try {
|
||||
new GemfireRepositoryFactory(null, this.mappingContext);
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
|
||||
assertThat(expected).hasMessage("Regions are required");
|
||||
assertThat(expected).hasNoCause();
|
||||
|
||||
throw expected;
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getEntityRegionNameFromEntityRegionName() {
|
||||
|
||||
GemfireRepositoryFactory repositoryFactory =
|
||||
new GemfireRepositoryFactory(Collections.emptyList(), this.mappingContext);
|
||||
|
||||
GemfirePersistentEntity<?> mockPersistentEntity = mock(GemfirePersistentEntity.class);
|
||||
|
||||
when(mockPersistentEntity.getRegionName()).thenReturn("MockRegionName");
|
||||
|
||||
RepositoryMetadata mockRepositoryMetadata = mock(RepositoryMetadata.class);
|
||||
|
||||
assertThat(repositoryFactory.getEntityRegionName(mockRepositoryMetadata, mockPersistentEntity))
|
||||
.isEqualTo("MockRegionName");
|
||||
|
||||
verify(mockPersistentEntity, times(1)).getRegionName();
|
||||
verify(mockPersistentEntity, never()).getType();
|
||||
verifyZeroInteractions(mockRepositoryMetadata);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getEntityRegionNameFromEntityDomainType() {
|
||||
|
||||
GemfireRepositoryFactory repositoryFactory =
|
||||
new GemfireRepositoryFactory(Collections.emptyList(), this.mappingContext);
|
||||
|
||||
GemfirePersistentEntity<?> mockPersistentEntity = mock(GemfirePersistentEntity.class);
|
||||
|
||||
RepositoryMetadata mockRepositoryMetadata = mock(RepositoryMetadata.class);
|
||||
|
||||
when(mockPersistentEntity.getRegionName()).thenReturn(" ");
|
||||
when(mockPersistentEntity.getType()).thenAnswer(invocation -> Person.class);
|
||||
|
||||
assertThat(repositoryFactory.getEntityRegionName(mockRepositoryMetadata, mockPersistentEntity))
|
||||
.isEqualTo(Person.class.getSimpleName());
|
||||
|
||||
verify(mockPersistentEntity, times(1)).getRegionName();
|
||||
verify(mockPersistentEntity, times(1)).getType();
|
||||
verifyZeroInteractions(mockRepositoryMetadata);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getEntityRegionNameFromRepositoryMetadata() {
|
||||
|
||||
GemfireRepositoryFactory repositoryFactory =
|
||||
new GemfireRepositoryFactory(Collections.emptyList(), this.mappingContext);
|
||||
|
||||
GemfirePersistentEntity<?> mockPersistentEntity = mock(GemfirePersistentEntity.class);
|
||||
|
||||
RepositoryMetadata mockRepositoryMetadata = mock(RepositoryMetadata.class);
|
||||
|
||||
when(mockPersistentEntity.getRegionName()).thenReturn(" ");
|
||||
when(mockPersistentEntity.getType()).thenReturn(null);
|
||||
when(mockRepositoryMetadata.getDomainType()).thenAnswer(invocation -> Person.class);
|
||||
|
||||
assertThat(repositoryFactory.getEntityRegionName(mockRepositoryMetadata, mockPersistentEntity))
|
||||
.isEqualTo(Person.class.getSimpleName());
|
||||
|
||||
verify(mockPersistentEntity, times(1)).getRegionName();
|
||||
verify(mockPersistentEntity, times(1)).getType();
|
||||
verify(mockRepositoryMetadata, times(1)).getDomainType();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getEntityRegionNameFromRepositoryMetadataWhenEntityIsNull() {
|
||||
|
||||
GemfireRepositoryFactory repositoryFactory =
|
||||
new GemfireRepositoryFactory(Collections.emptyList(), this.mappingContext);
|
||||
|
||||
RepositoryMetadata mockRepositoryMetadata = mock(RepositoryMetadata.class);
|
||||
|
||||
when(mockRepositoryMetadata.getDomainType()).thenAnswer(invocation -> Person.class);
|
||||
|
||||
assertThat(repositoryFactory.getEntityRegionName(mockRepositoryMetadata, null))
|
||||
.isEqualTo(Person.class.getSimpleName());
|
||||
|
||||
verify(mockRepositoryMetadata, times(1)).getDomainType();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getRepositoryRegionNameFromRegionAnnotatedRepositoryInterface() {
|
||||
|
||||
GemfireRepositoryFactory gemfireRepositoryFactory =
|
||||
new GemfireRepositoryFactory(Collections.emptyList(), this.mappingContext);
|
||||
|
||||
RepositoryMetadata mockRepositoryMetadata = mock(RepositoryMetadata.class);
|
||||
|
||||
when(mockRepositoryMetadata.getRepositoryInterface()).thenAnswer(invocation -> PeopleRepository.class);
|
||||
|
||||
assertThat(gemfireRepositoryFactory.getRepositoryRegionName(mockRepositoryMetadata).orElse(null))
|
||||
.isEqualTo("People");
|
||||
|
||||
verify(mockRepositoryMetadata, times(1)).getRepositoryInterface();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getRepositoryRegionNameFromRegionAnnotatedRepositoryInterfaceHavingNoValue() {
|
||||
|
||||
GemfireRepositoryFactory gemfireRepositoryFactory =
|
||||
new GemfireRepositoryFactory(Collections.emptyList(), this.mappingContext);
|
||||
|
||||
RepositoryMetadata mockRepositoryMetadata = mock(RepositoryMetadata.class);
|
||||
|
||||
when(mockRepositoryMetadata.getRepositoryInterface()).thenAnswer(invocation -> NonQualifiedRegionAnnotatedRepository.class);
|
||||
|
||||
assertThat(gemfireRepositoryFactory.getRepositoryRegionName(mockRepositoryMetadata).isPresent()).isFalse();
|
||||
|
||||
verify(mockRepositoryMetadata, times(1)).getRepositoryInterface();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getRepositoryRegionNameFromNonRegionAnnotatedRepositoryInterface() {
|
||||
|
||||
GemfireRepositoryFactory gemfireRepositoryFactory =
|
||||
new GemfireRepositoryFactory(Collections.emptyList(), this.mappingContext);
|
||||
|
||||
RepositoryMetadata mockRepositoryMetadata = mock(RepositoryMetadata.class);
|
||||
|
||||
when(mockRepositoryMetadata.getRepositoryInterface())
|
||||
.thenAnswer(invocation -> TestGemfireRepository.class);
|
||||
|
||||
assertThat(gemfireRepositoryFactory.getRepositoryRegionName(mockRepositoryMetadata).isPresent()).isFalse();
|
||||
|
||||
verify(mockRepositoryMetadata, times(1)).getRepositoryInterface();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void resolveRegionWithRepositoryMetadataAndRegionNamePath() {
|
||||
|
||||
RepositoryMetadata mockRepositoryMetadata =
|
||||
mockRepositoryMetadata(Person.class, Long.class, PeopleRepository.class);
|
||||
|
||||
Region<?, ?> mockRegionOne = mockRegion("RegionOne", Person.class, Long.class);
|
||||
Region<?, ?> mockRegionTwo = mockRegion("RegionTwo", Object.class, Long.class);
|
||||
|
||||
GemfireRepositoryFactory repositoryFactory =
|
||||
new GemfireRepositoryFactory(Arrays.asList(mockRegionOne, mockRegionTwo), this.mappingContext);
|
||||
|
||||
assertThat(repositoryFactory.resolveRegion(mockRepositoryMetadata, mockRegionTwo.getName()))
|
||||
.isEqualTo(mockRegionTwo);
|
||||
|
||||
assertThat(repositoryFactory.resolveRegion(mockRepositoryMetadata, mockRegionOne.getFullPath()))
|
||||
.isEqualTo(mockRegionOne);
|
||||
|
||||
verifyZeroInteractions(mockRepositoryMetadata);
|
||||
}
|
||||
|
||||
@Test(expected = IllegalStateException.class)
|
||||
public void resolveRegionWithRepositoryMetadataAndNonExistingRegionNamePath() {
|
||||
|
||||
try {
|
||||
RepositoryMetadata mockRepositoryMetadata =
|
||||
mockRepositoryMetadata(Person.class, Long.class, PeopleRepository.class);
|
||||
|
||||
GemfireRepositoryFactory repositoryFactory =
|
||||
new GemfireRepositoryFactory(Collections.emptyList(), this.mappingContext);
|
||||
|
||||
repositoryFactory.resolveRegion(mockRepositoryMetadata, "Test");
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
|
||||
assertThat(expected).hasMessage(GemfireRepositoryFactory.REGION_NOT_FOUND,
|
||||
"Test", Person.class.getName());
|
||||
|
||||
assertThat(expected).hasNoCause();
|
||||
|
||||
throw expected;
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
public void newTemplateReturnsGemfireTemplateForPeopleRegion() {
|
||||
|
||||
RepositoryMetadata mockRepositoryMetadata =
|
||||
mockRepositoryMetadata(Person.class, Long.class, PeopleRepository.class);
|
||||
|
||||
Region<Long, Person> mockPeopleRegion = mockRegion("People", Long.class, Person.class);
|
||||
|
||||
Iterable<Region<?, ?>> regions = Arrays.asList(mockRegion, mockPeopleRegion);
|
||||
GemfireRepositoryFactory repositoryFactory =
|
||||
new GemfireRepositoryFactory(Arrays.asList(this.mockRegion, mockPeopleRegion), mappingContext);
|
||||
|
||||
GemfireRepositoryFactory gemfireRepositoryFactory = new GemfireRepositoryFactory(
|
||||
regions, gemfireMappingContext);
|
||||
GemfireTemplate gemfireTemplate = repositoryFactory.newTemplate(mockRepositoryMetadata);
|
||||
|
||||
GemfireTemplate gemfireTemplate = gemfireRepositoryFactory.getTemplate(mockRepositoryMetadata);
|
||||
|
||||
assertThat(gemfireTemplate, is(notNullValue(GemfireTemplate.class)));
|
||||
assertThat(gemfireTemplate.<Long, Person>getRegion(), is(equalTo(mockPeopleRegion)));
|
||||
assertThat(gemfireTemplate).isNotNull();
|
||||
assertThat(gemfireTemplate.getRegion()).isEqualTo(mockPeopleRegion);
|
||||
|
||||
verify(mockPeopleRegion, times(1)).getAttributes();
|
||||
verify(mockPeopleRegion, times(1)).getFullPath();
|
||||
verify(mockPeopleRegion, times(1)).getName();
|
||||
verify(mockRegionAttributes, times(1)).getKeyConstraint();
|
||||
verify(this.mockRegionAttributes, times(1)).getKeyConstraint();
|
||||
verify(mockRepositoryMetadata, times(1)).getDomainType();
|
||||
verify(mockRepositoryMetadata, times(1)).getIdType();
|
||||
verify(mockRepositoryMetadata, times(1)).getRepositoryInterface();
|
||||
verifyNoMoreInteractions(mockRepositoryMetadata);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getTemplateReturnsGemfireTemplateForSimpleRegion() {
|
||||
RepositoryMetadata mockRepositoryMetadata = mockRepositoryMetadata(Person.class, Long.class,
|
||||
SampleCustomGemfireRepository.class);
|
||||
@SuppressWarnings("unchecked")
|
||||
public void newTemplateReturnsGemfireTemplateForSimpleRegion() {
|
||||
|
||||
Iterable<Region<?, ?>> regions = Collections.<Region<?, ?>>singleton(mockRegion);
|
||||
RepositoryMetadata mockRepositoryMetadata =
|
||||
mockRepositoryMetadata(Person.class, Long.class, TestGemfireRepository.class);
|
||||
|
||||
GemfireRepositoryFactory gemfireRepositoryFactory = new GemfireRepositoryFactory(
|
||||
regions, gemfireMappingContext);
|
||||
GemfireRepositoryFactory gemfireRepositoryFactory =
|
||||
new GemfireRepositoryFactory(Collections.singleton(this.mockRegion), this.mappingContext);
|
||||
|
||||
GemfireTemplate gemfireTemplate = gemfireRepositoryFactory.getTemplate(mockRepositoryMetadata);
|
||||
GemfireTemplate gemfireTemplate = gemfireRepositoryFactory.newTemplate(mockRepositoryMetadata);
|
||||
|
||||
assertThat(gemfireTemplate, is(notNullValue(GemfireTemplate.class)));
|
||||
assertThat(gemfireTemplate.getRegion(), is(equalTo(mockRegion)));
|
||||
assertThat(gemfireTemplate).isNotNull();
|
||||
assertThat(gemfireTemplate.getRegion()).isEqualTo(this.mockRegion);
|
||||
|
||||
verify(this.mockRegion, times(1)).getAttributes();
|
||||
verify(this.mockRegionAttributes, times(1)).getKeyConstraint();
|
||||
verify(mockRepositoryMetadata, times(1)).getDomainType();
|
||||
verify(mockRepositoryMetadata, times(1)).getIdType();
|
||||
verify(mockRepositoryMetadata, times(1)).getRepositoryInterface();
|
||||
verifyNoMoreInteractions(mockRepositoryMetadata);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getTemplateThrowsIllegalArgumentExceptionForIncompatibleRegionKeyTypeAndRepositoryIdType() {
|
||||
RepositoryMetadata mockRepositoryMetadata = mockRepositoryMetadata(Person.class, Long.class,
|
||||
PersonRepository.class);
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void newTemplateWithIncompatibleRegionKeyTypeAndRepositoryIdTypeThrowsIllegalArgumentException() {
|
||||
|
||||
Region<String, Person> mockPeopleRegion = mockRegion("People", String.class, Person.class);
|
||||
RepositoryMetadata mockRepositoryMetadata =
|
||||
mockRepositoryMetadata(Person.class, Long.class, PeopleRepository.class);
|
||||
|
||||
GemfireRepositoryFactory gemfireRepositoryFactory = new GemfireRepositoryFactory(
|
||||
Collections.<Region<?, ?>>singleton(mockPeopleRegion), gemfireMappingContext);
|
||||
Region<Integer, Person> mockPeopleRegion = mockRegion("People", Integer.class, Person.class);
|
||||
|
||||
GemfireRepositoryFactory gemfireRepositoryFactory =
|
||||
new GemfireRepositoryFactory(Collections.singleton(mockPeopleRegion), this.mappingContext);
|
||||
|
||||
try {
|
||||
exception.expect(IllegalArgumentException.class);
|
||||
exception.expectCause(is(nullValue(Throwable.class)));
|
||||
exception.expectMessage(String.format(
|
||||
"The Region referenced only supports keys of type [%1$s], but the entity to be stored has an id of type [%2$s]",
|
||||
String.class.getName(), Long.class.getName()));
|
||||
gemfireRepositoryFactory.newTemplate(mockRepositoryMetadata);
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
|
||||
gemfireRepositoryFactory.getTemplate(mockRepositoryMetadata);
|
||||
assertThat(expected).hasMessage(GemfireRepositoryFactory.REGION_REPOSITORY_ID_TYPE_MISMATCH,
|
||||
"/People", Integer.class.getName(), PeopleRepository.class.getName(), Long.class.getName());
|
||||
|
||||
assertThat(expected).hasNoCause();
|
||||
|
||||
throw expected;
|
||||
}
|
||||
finally {
|
||||
verify(mockPeopleRegion, times(1)).getAttributes();
|
||||
verify(mockPeopleRegion, atLeastOnce()).getFullPath();
|
||||
verify(this.mockRegionAttributes, times(1)).getKeyConstraint();
|
||||
verify(mockRepositoryMetadata, times(1)).getDomainType();
|
||||
verify(mockRepositoryMetadata, times(1)).getIdType();
|
||||
verify(mockPeopleRegion, times(1)).getAttributes();
|
||||
verify(mockPeopleRegion, times(1)).getFullPath();
|
||||
verify(mockPeopleRegion, times(1)).getName();
|
||||
verify(mockRegionAttributes, times(1)).getKeyConstraint();
|
||||
verify(mockRepositoryMetadata, times(2)).getRepositoryInterface();
|
||||
verifyNoMoreInteractions(mockRepositoryMetadata);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getTemplateThrowsIllegalStateExceptionForRegionNotFound() {
|
||||
RepositoryMetadata mockRepositoryMetadata = mockRepositoryMetadata(Person.class, Long.class,
|
||||
PersonRepository.class);
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void newTemplateWithIncompatibleRepositoryIdTypeAndEntityIdTypeThrowsIllegalArgumentException() {
|
||||
|
||||
GemfireRepositoryFactory gemfireRepositoryFactory = new GemfireRepositoryFactory(
|
||||
Collections.<Region<?, ?>>singleton(mockRegion), gemfireMappingContext);
|
||||
RepositoryMetadata mockRepositoryMetadata =
|
||||
mockRepositoryMetadata(Person.class, Integer.class, PeopleIntegerRepository.class);
|
||||
|
||||
Region<String, Person> mockPeopleRegion = mockRegion("People", null, null);
|
||||
|
||||
GemfireRepositoryFactory gemfireRepositoryFactory =
|
||||
new GemfireRepositoryFactory(Collections.singleton(mockPeopleRegion), this.mappingContext);
|
||||
|
||||
try {
|
||||
exception.expect(IllegalStateException.class);
|
||||
exception.expectCause(is(nullValue(Throwable.class)));
|
||||
exception.expectMessage(String.format(
|
||||
"No Region [People] was found for domain class [%s]; Make sure you have configured a GemFire Region of that name in your application context",
|
||||
Person.class.getName()));
|
||||
gemfireRepositoryFactory.newTemplate(mockRepositoryMetadata);
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
|
||||
gemfireRepositoryFactory.getTemplate(mockRepositoryMetadata);
|
||||
assertThat(expected).hasMessage(GemfireRepositoryFactory.REPOSITORY_ENTITY_ID_TYPE_MISMATCH,
|
||||
PeopleIntegerRepository.class.getName(), Integer.class.getName(), Person.class.getName(),
|
||||
Long.class.getName());
|
||||
|
||||
assertThat(expected).hasNoCause();
|
||||
|
||||
throw expected;
|
||||
}
|
||||
finally {
|
||||
verify(mockPeopleRegion, times(1)).getAttributes();
|
||||
verify(this.mockRegionAttributes, times(1)).getKeyConstraint();
|
||||
verify(mockRepositoryMetadata, times(1)).getDomainType();
|
||||
verify(mockRepositoryMetadata, times(1)).getIdType();
|
||||
verify(mockRepositoryMetadata, times(2)).getRepositoryInterface();
|
||||
verifyNoMoreInteractions(mockRepositoryMetadata);
|
||||
}
|
||||
}
|
||||
|
||||
@Test(expected = IllegalStateException.class)
|
||||
@SuppressWarnings("unchecked")
|
||||
public void newTemplateWithNonExistingRegionThrowsIllegalStateException() {
|
||||
|
||||
RepositoryMetadata mockRepositoryMetadata =
|
||||
mockRepositoryMetadata(Person.class, Long.class, PeopleRepository.class);
|
||||
|
||||
GemfireRepositoryFactory gemfireRepositoryFactory =
|
||||
new GemfireRepositoryFactory(Collections.singleton(this.mockRegion), this.mappingContext);
|
||||
|
||||
try {
|
||||
gemfireRepositoryFactory.newTemplate(mockRepositoryMetadata);
|
||||
}
|
||||
catch (IllegalStateException expected) {
|
||||
|
||||
assertThat(expected).hasMessage(GemfireRepositoryFactory.REGION_NOT_FOUND,
|
||||
"People", Person.class.getName(), PeopleRepository.class.getName());
|
||||
|
||||
assertThat(expected).hasNoCause();
|
||||
|
||||
throw expected;
|
||||
}
|
||||
finally {
|
||||
verify(mockRepositoryMetadata, times(2)).getDomainType();
|
||||
verify(mockRepositoryMetadata, never()).getIdType();
|
||||
verify(mockRegion, times(1)).getFullPath();
|
||||
verify(mockRegion, times(1)).getName();
|
||||
verifyZeroInteractions(mockRegionAttributes);
|
||||
verify(mockRepositoryMetadata, times(2)).getRepositoryInterface();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @link https://jira.spring.io/browse/SGF-112
|
||||
* @link <a href="https://jira.spring.io/browse/SGF-112">Repositories should reject PagingAndSortingRepository and Pageable parameters</a>
|
||||
*/
|
||||
@Test
|
||||
@Test(expected = IllegalStateException.class)
|
||||
@SuppressWarnings("unchecked")
|
||||
public void rejectsInterfacesExtendingPagingAndSortingRepository() {
|
||||
exception.expect(IllegalStateException.class);
|
||||
exception.expectCause(is(nullValue(Throwable.class)));
|
||||
exception.expectMessage(startsWith("Pagination is not supported by GemFire Repositories"));
|
||||
|
||||
GemfireRepositoryFactory repositoryFactory = new GemfireRepositoryFactory(
|
||||
Collections.<Region<?, ?>>singletonList(mockRegion), new GemfireMappingContext());
|
||||
GemfireRepositoryFactory repositoryFactory =
|
||||
new GemfireRepositoryFactory(Collections.singletonList(this.mockRegion), new GemfireMappingContext());
|
||||
|
||||
repositoryFactory.getRepository(SamplePagingAndSortingRepository.class);
|
||||
try {
|
||||
repositoryFactory.getRepository(SamplePagingAndSortingRepository.class);
|
||||
}
|
||||
catch (IllegalStateException expected) {
|
||||
|
||||
assertThat(expected).hasMessageStartingWith("Pagination is not supported by GemFire Repositories");
|
||||
assertThat(expected).hasNoCause();
|
||||
|
||||
throw expected;
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
public void usesConfiguredRepositoryBaseClass() {
|
||||
GemfireRepositoryFactory repositoryFactory = new GemfireRepositoryFactory(
|
||||
Collections.<Region<?, ?>>singletonList(mockRegion), new GemfireMappingContext());
|
||||
|
||||
repositoryFactory.setRepositoryBaseClass(CustomBaseRepository.class);
|
||||
GemfireRepositoryFactory repositoryFactory =
|
||||
new GemfireRepositoryFactory(Collections.singletonList(this.mockRegion), this.mappingContext);
|
||||
|
||||
GemfireRepository<?, ?> gemfireRepository = repositoryFactory.getRepository(SampleCustomGemfireRepository.class,
|
||||
new SampleCustomRepositoryImpl());
|
||||
repositoryFactory.setRepositoryBaseClass(TestCustomBaseRepository.class);
|
||||
|
||||
assertThat(((Advised) gemfireRepository).getTargetClass(), is(equalTo((Class) CustomBaseRepository.class)));
|
||||
GemfireRepository<?, ?> gemfireRepository =
|
||||
repositoryFactory.getRepository(TestGemfireRepository.class,
|
||||
RepositoryComposition.RepositoryFragments.just(new TestCustomRepositoryImpl()));
|
||||
|
||||
assertThat(((Advised) gemfireRepository).getTargetClass()).isEqualTo(TestCustomBaseRepository.class);
|
||||
}
|
||||
|
||||
interface SamplePagingAndSortingRepository extends PagingAndSortingRepository<Person, Long> {
|
||||
}
|
||||
|
||||
static class CustomBaseRepository<T, ID extends Serializable> extends SimpleGemfireRepository<T, ID> {
|
||||
static class TestCustomBaseRepository<T, ID extends Serializable> extends SimpleGemfireRepository<T, ID> {
|
||||
|
||||
public CustomBaseRepository(GemfireTemplate template, EntityInformation<T, ID> entityInformation) {
|
||||
public TestCustomBaseRepository(GemfireTemplate template, EntityInformation<T, ID> entityInformation) {
|
||||
super(template, entityInformation);
|
||||
}
|
||||
}
|
||||
|
||||
interface SampleCustomRepository<T> {
|
||||
interface TestCustomRepository<T> {
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
void doCustomUpdate(T entity);
|
||||
|
||||
}
|
||||
|
||||
class SampleCustomRepositoryImpl<T> implements SampleCustomRepository<T> {
|
||||
class TestCustomRepositoryImpl<T> implements TestCustomRepository<T> {
|
||||
|
||||
@Override
|
||||
public void doCustomUpdate(final T entity) {
|
||||
throw new UnsupportedOperationException("Not Implemented");
|
||||
public void doCustomUpdate(T entity) {
|
||||
throw newUnsupportedOperationException("Not Implemented");
|
||||
}
|
||||
}
|
||||
|
||||
interface SampleCustomGemfireRepository extends GemfireRepository<Person, Long>, SampleCustomRepository<Person> {
|
||||
}
|
||||
interface TestGemfireRepository extends GemfireRepository<Person, Long>, TestCustomRepository<Person> { }
|
||||
|
||||
@org.springframework.data.gemfire.mapping.annotation.Region("People")
|
||||
interface PersonRepository extends GemfireRepository<Person, Long> {
|
||||
}
|
||||
interface PeopleRepository extends GemfireRepository<Person, Long> { }
|
||||
|
||||
@org.springframework.data.gemfire.mapping.annotation.Region("People")
|
||||
interface PeopleIntegerRepository extends GemfireRepository<Person, Integer> { }
|
||||
|
||||
@org.springframework.data.gemfire.mapping.annotation.Region
|
||||
interface NonQualifiedRegionAnnotatedRepository extends GemfireRepository<Person, Long> { }
|
||||
|
||||
}
|
||||
|
||||
@@ -17,8 +17,6 @@
|
||||
package org.springframework.data.gemfire.util;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.hamcrest.Matchers.nullValue;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
@@ -35,10 +33,11 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.StreamSupport;
|
||||
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.ExpectedException;
|
||||
import org.springframework.data.gemfire.test.support.MapBuilder;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link CollectionUtils}.
|
||||
@@ -59,9 +58,6 @@ import org.junit.rules.ExpectedException;
|
||||
*/
|
||||
public class CollectionUtilsUnitTests {
|
||||
|
||||
@Rule
|
||||
public ExpectedException exception = ExpectedException.none();
|
||||
|
||||
@Test
|
||||
public void addAllIterableElementsToList() {
|
||||
|
||||
@@ -88,14 +84,19 @@ public class CollectionUtilsUnitTests {
|
||||
assertThat(target).contains(1, 2, 3, 4, 5);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void addIterableToNullCollection() {
|
||||
|
||||
exception.expect(IllegalArgumentException.class);
|
||||
exception.expectCause(is(nullValue(Throwable.class)));
|
||||
exception.expectMessage("Collection is required");
|
||||
try {
|
||||
CollectionUtils.addAll(null, Collections.emptySet());
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
|
||||
CollectionUtils.addAll(null, Collections.emptySet());
|
||||
assertThat(expected).hasMessage("Collection is required");
|
||||
assertThat(expected).hasNoCause();
|
||||
|
||||
throw expected;
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -185,6 +186,11 @@ public class CollectionUtilsUnitTests {
|
||||
assertThat(CollectionUtils.containsAny(null, 1)).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void containsAnyWithNullCollectionAndNullArrayIsFalse() {
|
||||
assertThat(CollectionUtils.containsAny(null, (Object[]) null)).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void emptyIterableReturnsEmptyIterable() {
|
||||
|
||||
@@ -197,25 +203,20 @@ public class CollectionUtilsUnitTests {
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
public void iterableEnumeration() {
|
||||
public void iterableOfEnumeration() {
|
||||
|
||||
Enumeration<String> mockEnumeration = mock(Enumeration.class, "MockEnumeration");
|
||||
Enumeration<Object> mockEnumeration = mock(Enumeration.class, "MockEnumeration");
|
||||
|
||||
when(mockEnumeration.hasMoreElements()).thenReturn(true).thenReturn(true).thenReturn(true).thenReturn(false);
|
||||
when(mockEnumeration.nextElement()).thenReturn("zero").thenReturn("one").thenReturn("two")
|
||||
when(mockEnumeration.nextElement()).thenReturn(1).thenReturn(2).thenReturn(3)
|
||||
.thenThrow(new NoSuchElementException("Enumeration exhausted"));
|
||||
|
||||
Iterable<String> iterable = CollectionUtils.iterable(mockEnumeration);
|
||||
Iterable<Object> iterable = CollectionUtils.iterable(mockEnumeration);
|
||||
|
||||
assertThat(iterable).isNotNull();
|
||||
|
||||
List<String> actualList = new ArrayList<String>(3);
|
||||
|
||||
for (String element : iterable) {
|
||||
actualList.add(element);
|
||||
}
|
||||
|
||||
assertThat(actualList).isEqualTo(Arrays.asList("zero", "one", "two"));
|
||||
//assertThat(iterable).containsExactly(1, 2, 3);
|
||||
assertThat(StreamSupport.stream(iterable.spliterator(), false).collect(Collectors.toSet()))
|
||||
.containsExactly(1, 2, 3);
|
||||
|
||||
verify(mockEnumeration, times(4)).hasMoreElements();
|
||||
verify(mockEnumeration, times(3)).nextElement();
|
||||
@@ -223,30 +224,93 @@ public class CollectionUtilsUnitTests {
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
public void iterableIterator() {
|
||||
public void iterableOfSingleEnumeration() {
|
||||
|
||||
Iterator<String> mockIterator = mock(Iterator.class, "MockIterator");
|
||||
Enumeration<Object> mockEnumeration = mock(Enumeration.class);
|
||||
|
||||
when(mockEnumeration.hasMoreElements()).thenReturn(true).thenReturn(false);
|
||||
when(mockEnumeration.nextElement()).thenReturn(1)
|
||||
.thenThrow(new NoSuchElementException("Enumeration exhausted"));
|
||||
|
||||
Iterable<Object> iterable = CollectionUtils.iterable(mockEnumeration);
|
||||
|
||||
assertThat(iterable).isNotNull();
|
||||
//assertThat(iterable).containsExactly(1);
|
||||
assertThat(StreamSupport.stream(iterable.spliterator(), false).collect(Collectors.toSet()))
|
||||
.containsExactly(1);
|
||||
|
||||
verify(mockEnumeration, times(2)).hasMoreElements();
|
||||
verify(mockEnumeration, times(1)).nextElement();
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
public void iterableOfNullEnumeration() {
|
||||
|
||||
Iterable<?> iterable = CollectionUtils.iterable((Enumeration<?>) null);
|
||||
|
||||
assertThat(iterable).isNotNull();
|
||||
assertThat(iterable).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
public void iterableOfIterator() {
|
||||
|
||||
Iterator<Object> mockIterator = mock(Iterator.class, "MockIterator");
|
||||
|
||||
when(mockIterator.hasNext()).thenReturn(true).thenReturn(true).thenReturn(true).thenReturn(false);
|
||||
when(mockIterator.next()).thenReturn("zero").thenReturn("one").thenReturn("two")
|
||||
when(mockIterator.next()).thenReturn(1).thenReturn(2).thenReturn(3)
|
||||
.thenThrow(new NoSuchElementException("Iterator exhausted"));
|
||||
|
||||
Iterable<String> iterable = CollectionUtils.iterable(mockIterator);
|
||||
Iterable<Object> iterable = CollectionUtils.iterable(mockIterator);
|
||||
|
||||
assertThat(iterable).isNotNull();
|
||||
|
||||
List<String> actualList = new ArrayList<String>(3);
|
||||
Set<Object> set = new HashSet<>();
|
||||
|
||||
for (String element : iterable) {
|
||||
actualList.add(element);
|
||||
}
|
||||
iterable.forEach(set::add);
|
||||
|
||||
assertThat(actualList).containsAll(Arrays.asList("zero", "one", "two"));
|
||||
assertThat(set).hasSize(3);
|
||||
assertThat(set).containsExactly(1, 2, 3);
|
||||
|
||||
verify(mockIterator, times(4)).hasNext();
|
||||
verify(mockIterator, times(3)).next();
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
public void iterableOfSingleIterator() {
|
||||
|
||||
Iterator<Object> mockIterator = mock(Iterator.class, "MockIterator");
|
||||
|
||||
when(mockIterator.hasNext()).thenReturn(true).thenReturn(false);
|
||||
when(mockIterator.next()).thenReturn(1).thenThrow(new NoSuchElementException("Iterator exhausted"));
|
||||
|
||||
Iterable<Object> iterable = CollectionUtils.iterable(mockIterator);
|
||||
|
||||
assertThat(iterable).isNotNull();
|
||||
|
||||
Set<Object> set = new HashSet<>();
|
||||
|
||||
iterable.forEach(set::add);
|
||||
|
||||
assertThat(set).hasSize(1);
|
||||
assertThat(set).containsExactly(1);
|
||||
|
||||
verify(mockIterator, times(2)).hasNext();
|
||||
verify(mockIterator, times(1)).next();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void iterableOfNullIterator() {
|
||||
|
||||
Iterable<?> iterable = CollectionUtils.iterable((Iterator<?>) null);
|
||||
|
||||
assertThat(iterable).isNotNull();
|
||||
assertThat(iterable).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void nullSafeCollectionWithNonNullCollection() {
|
||||
|
||||
@@ -264,6 +328,23 @@ public class CollectionUtilsUnitTests {
|
||||
assertThat(collection.isEmpty()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void nullSafeEnumerationWithNonNullEnumeration() {
|
||||
|
||||
Enumeration<?> mockEnumeration = mock(Enumeration.class);
|
||||
|
||||
assertThat(CollectionUtils.nullSafeEnumeration(mockEnumeration)).isSameAs(mockEnumeration);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void nullSafeEnumerationWithNullEnumeration() {
|
||||
|
||||
Enumeration<?> enumeration = CollectionUtils.nullSafeEnumeration(null);
|
||||
|
||||
assertThat(enumeration).isNotNull();
|
||||
assertThat(enumeration.hasMoreElements()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
public void nullSafeIterableWithNonNullIterable() {
|
||||
@@ -340,6 +421,23 @@ public class CollectionUtilsUnitTests {
|
||||
assertThat(CollectionUtils.nullSafeIterable((Iterable<?>) null, null)).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void nullSafeIteratorWithNonNullIterator() {
|
||||
|
||||
Iterator<?> mockIterator = mock(Iterator.class);
|
||||
|
||||
assertThat(CollectionUtils.nullSafeIterator(mockIterator)).isSameAs(mockIterator);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void nullSafeIteratorWithNullIterator() {
|
||||
|
||||
Iterator<?> iterator = CollectionUtils.nullSafeIterator(null);
|
||||
|
||||
assertThat(iterator).isNotNull();
|
||||
assertThat(iterator).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void nullSafeListWithNonNullList() {
|
||||
|
||||
@@ -391,18 +489,97 @@ public class CollectionUtilsUnitTests {
|
||||
assertThat(set.isEmpty()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void nullSafeIsEmptyCollectionWithNonNulNonEmptyCollectionReturnsFalse() {
|
||||
assertThat(CollectionUtils.nullSafeIsEmpty(Collections.singleton(1))).isFalse();
|
||||
assertThat(CollectionUtils.nullSafeIsEmpty(Collections.singletonList(1))).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void nullSafeIsEmptyCollectionWithEmptyCollectionReturnsTrue() {
|
||||
assertThat(CollectionUtils.isEmpty(Collections.emptyList())).isTrue();
|
||||
assertThat(CollectionUtils.isEmpty(Collections.emptySet())).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void nullSafeIsEmptyCollectionWithNullCollectionReturnsTrue() {
|
||||
assertThat(CollectionUtils.isEmpty((Collection<?>) null)).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void nullSafeIsEmptyMapWithNonNullNonEmptyMapReturnsFalse() {
|
||||
assertThat(CollectionUtils.isEmpty(Collections.singletonMap("key", "value"))).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void nullSafeIsEmptyMapWithEmptyMapReturnsTrue() {
|
||||
assertThat(CollectionUtils.isEmpty(Collections.emptyMap())).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void nullSafeIsEmptyMapWithNullMapReturnsTrue() {
|
||||
assertThat(CollectionUtils.isEmpty((Map<?, ?>) null)).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void nullSafeCollectionSizeWithNonNullNonEmptyCollectionReturnsSize() {
|
||||
assertThat(CollectionUtils.nullSafeSize(Collections.singleton(1))).isEqualTo(1);
|
||||
assertThat(CollectionUtils.nullSafeSize(Collections.singletonList(1))).isEqualTo(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void nullSafeCollectionSizeWithEmptyCollectionReturnsZero() {
|
||||
assertThat(CollectionUtils.nullSafeSize(Collections.emptyList())).isZero();
|
||||
assertThat(CollectionUtils.nullSafeSize(Collections.emptySet())).isZero();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void nullSafeCollectionSizeWithNullCollectionReturnsZero() {
|
||||
assertThat(CollectionUtils.nullSafeSize((Collection<?>) null)).isZero();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void nullSafeMapSizeWithNonNullNonEmptyMapReturnsSize() {
|
||||
assertThat(CollectionUtils.nullSafeSize(Collections.singletonMap("key", "value"))).isEqualTo(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void nullSafeMapSizeWithEmptyMapReturnsZero() {
|
||||
assertThat(CollectionUtils.nullSafeSize(Collections.emptyMap())).isZero();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void nullSafeMapSizeWithNullMapReturnsZero() {
|
||||
assertThat(CollectionUtils.nullSafeSize((Map<?, ?>) null)).isZero();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void sortIsSuccessful() {
|
||||
|
||||
List<Integer> list = new ArrayList<Integer>(Arrays.asList(2, 3, 1));
|
||||
List<Integer> list = new ArrayList<>(Arrays.asList(2, 3, 1));
|
||||
List<Integer> sortedList = CollectionUtils.sort(list);
|
||||
|
||||
assertThat(sortedList).isSameAs(list);
|
||||
assertThat(sortedList).isEqualTo(Arrays.asList(1, 2, 3));
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void sortWithNullListThrowsIllegalArgumentException() {
|
||||
|
||||
try {
|
||||
CollectionUtils.sort(null);
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
|
||||
assertThat(expected).hasMessage("List is required");
|
||||
assertThat(expected).hasNoCause();
|
||||
|
||||
throw expected;
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void subListFromListWithIndexesReturnsSubList() {
|
||||
public void subListOfListWithIndexesReturnsSubList() {
|
||||
|
||||
List<Integer> list = Arrays.asList(0, 1, 2, 3);
|
||||
List<Integer> subList = CollectionUtils.subList(list, 1, 3);
|
||||
@@ -413,8 +590,13 @@ public class CollectionUtilsUnitTests {
|
||||
assertThat(subList).containsAll(Arrays.asList(1, 3));
|
||||
}
|
||||
|
||||
@Test(expected = IndexOutOfBoundsException.class)
|
||||
public void subListOfListWithInvalidIndexThrowsIndexOutOfBoundsException() {
|
||||
CollectionUtils.subList(Arrays.asList(0, 1, 2), 1, 3);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void subListFromListWithNoIndexesReturnsEmptyList() {
|
||||
public void subListOfListWithNoIndexesReturnsEmptyList() {
|
||||
|
||||
List<Integer> subList = CollectionUtils.subList(Arrays.asList(0, 1, 2));
|
||||
|
||||
@@ -422,18 +604,59 @@ public class CollectionUtilsUnitTests {
|
||||
assertThat(subList.isEmpty()).isTrue();
|
||||
}
|
||||
|
||||
@Test(expected = IndexOutOfBoundsException.class)
|
||||
public void subListFromListWithInvalidIndexThrowsIndexOutOfBoundsException() {
|
||||
CollectionUtils.subList(Arrays.asList(0, 1, 2), 1, 3);
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void subListOfNullListThrowsIllegalArgumentException() {
|
||||
|
||||
try {
|
||||
CollectionUtils.subList(null, 1, 2, 3);
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
|
||||
assertThat(expected).hasMessage("List is required");
|
||||
assertThat(expected).hasNoCause();
|
||||
|
||||
throw expected;
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void subListWithNullSourceListThrowsIllegalArgumentException() {
|
||||
public void toStringOfMultiEntryMap() {
|
||||
|
||||
exception.expect(IllegalArgumentException.class);
|
||||
exception.expectCause(is(nullValue(Throwable.class)));
|
||||
exception.expectMessage("List is required");
|
||||
Map<String, String> map = MapBuilder.<String, String>newMapBuilder()
|
||||
.put("keyOne", "valueOne")
|
||||
.put("keyTwo", "valueTwo")
|
||||
.build();
|
||||
|
||||
CollectionUtils.subList(null, 1, 2, 3);
|
||||
String mapString = CollectionUtils.toString(map);
|
||||
|
||||
assertThat(mapString).isNotNull();
|
||||
assertThat(mapString).isEqualTo("{\n\tkeyOne = valueOne,\n\tkeyTwo = valueTwo\n}");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void toStringOfSingleEntryMap() {
|
||||
|
||||
String mapString = CollectionUtils.toString(Collections.singletonMap("key", "value"));
|
||||
|
||||
assertThat(mapString).isNotNull();
|
||||
assertThat(mapString).isEqualTo("{\n\tkey = value\n}");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void toStringOfEmptyMap() {
|
||||
|
||||
String mapString = CollectionUtils.toString(Collections.emptyMap());
|
||||
|
||||
assertThat(mapString).isNotNull();
|
||||
assertThat(mapString).isEqualTo("{\n\n}");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void toStringOfNullMap() {
|
||||
|
||||
String mapString = CollectionUtils.toString(null);
|
||||
|
||||
assertThat(mapString).isNotNull();
|
||||
assertThat(mapString).isEqualTo("{\n\n}");
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user