DATACMNS-810 - Polishing.
Renamed ExampleSpecification to ExampleMatcher and introduced a matching() factory method, dropping the dedicated override mechanism for types for now. Updated documentation accordingly. Used Lombok for constructor creation, field defaults, toString() as well as equals(…) and hashCode() implementations. Tweaked imports in unit tests. Renamed methods to express expected behavior. Original pull request: #153.
This commit is contained in:
@@ -0,0 +1,183 @@
|
||||
/*
|
||||
* Copyright 2016 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.domain;
|
||||
|
||||
import static org.hamcrest.Matchers.*;
|
||||
import static org.hamcrest.core.Is.is;
|
||||
import static org.junit.Assert.*;
|
||||
import static org.springframework.data.domain.ExampleMatcher.*;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.data.domain.ExampleMatcher.NullHandler;
|
||||
import org.springframework.data.domain.ExampleMatcher.StringMatcher;
|
||||
|
||||
/**
|
||||
* Unit test for {@link ExampleMatcher}.
|
||||
*
|
||||
* @author Mark Paluch
|
||||
* @soundtrack K2 - Der Berg Ruft (Club Mix)
|
||||
*/
|
||||
public class ExampleMatcherUnitTests {
|
||||
|
||||
ExampleMatcher matcher;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
matcher = matching();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATACMNS-810
|
||||
*/
|
||||
@Test
|
||||
public void defaultStringMatcherShouldReturnDefault() throws Exception {
|
||||
assertThat(matcher.getDefaultStringMatcher(), is(StringMatcher.DEFAULT));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATACMNS-810
|
||||
*/
|
||||
@Test
|
||||
public void ignoreCaseShouldReturnFalseByDefault() throws Exception {
|
||||
assertThat(matcher.isIgnoreCaseEnabled(), is(false));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATACMNS-810
|
||||
*/
|
||||
@Test
|
||||
public void ignoredPathsIsEmptyByDefault() throws Exception {
|
||||
assertThat(matcher.getIgnoredPaths(), is(empty()));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATACMNS-810
|
||||
*/
|
||||
@Test
|
||||
public void nullHandlerShouldReturnIgnoreByDefault() throws Exception {
|
||||
assertThat(matcher.getNullHandler(), is(NullHandler.IGNORE));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATACMNS-810
|
||||
*/
|
||||
@Test(expected = UnsupportedOperationException.class)
|
||||
public void ignoredPathsIsNotModifiable() throws Exception {
|
||||
matcher.getIgnoredPaths().add("¯\\_(ツ)_/¯");
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATACMNS-810
|
||||
*/
|
||||
@Test
|
||||
public void ignoreCaseShouldReturnTrueWhenIgnoreCaseEnabled() throws Exception {
|
||||
|
||||
matcher = matching().withIgnoreCase();
|
||||
|
||||
assertThat(matcher.isIgnoreCaseEnabled(), is(true));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATACMNS-810
|
||||
*/
|
||||
@Test
|
||||
public void ignoreCaseShouldReturnTrueWhenIgnoreCaseSet() throws Exception {
|
||||
|
||||
matcher = matching().withIgnoreCase(true);
|
||||
|
||||
assertThat(matcher.isIgnoreCaseEnabled(), is(true));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATACMNS-810
|
||||
*/
|
||||
@Test
|
||||
public void nullHandlerShouldReturnInclude() throws Exception {
|
||||
|
||||
matcher = matching().withIncludeNullValues();
|
||||
|
||||
assertThat(matcher.getNullHandler(), is(NullHandler.INCLUDE));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATACMNS-810
|
||||
*/
|
||||
@Test
|
||||
public void nullHandlerShouldReturnIgnore() throws Exception {
|
||||
|
||||
matcher = matching().withIgnoreNullValues();
|
||||
|
||||
assertThat(matcher.getNullHandler(), is(NullHandler.IGNORE));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATACMNS-810
|
||||
*/
|
||||
@Test
|
||||
public void nullHandlerShouldReturnConfiguredValue() throws Exception {
|
||||
|
||||
matcher = matching().withNullHandler(NullHandler.INCLUDE);
|
||||
|
||||
assertThat(matcher.getNullHandler(), is(NullHandler.INCLUDE));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATACMNS-810
|
||||
*/
|
||||
@Test
|
||||
public void ignoredPathsShouldReturnCorrectProperties() throws Exception {
|
||||
|
||||
matcher = matching().withIgnorePaths("foo", "bar", "baz");
|
||||
|
||||
assertThat(matcher.getIgnoredPaths(), contains("foo", "bar", "baz"));
|
||||
assertThat(matcher.getIgnoredPaths(), hasSize(3));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATACMNS-810
|
||||
*/
|
||||
@Test
|
||||
public void ignoredPathsShouldReturnUniqueProperties() throws Exception {
|
||||
|
||||
matcher = matching().withIgnorePaths("foo", "bar", "foo");
|
||||
|
||||
assertThat(matcher.getIgnoredPaths(), contains("foo", "bar"));
|
||||
assertThat(matcher.getIgnoredPaths(), hasSize(2));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATACMNS-810
|
||||
*/
|
||||
@Test
|
||||
public void withCreatesNewInstance() throws Exception {
|
||||
|
||||
matcher = matching().withIgnorePaths("foo", "bar", "foo");
|
||||
ExampleMatcher configuredExampleSpec = matcher.withIgnoreCase();
|
||||
|
||||
assertThat(matcher, is(not(sameInstance(configuredExampleSpec))));
|
||||
assertThat(matcher.getIgnoredPaths(), hasSize(2));
|
||||
assertThat(matcher.isIgnoreCaseEnabled(), is(false));
|
||||
|
||||
assertThat(configuredExampleSpec.getIgnoredPaths(), hasSize(2));
|
||||
assertThat(configuredExampleSpec.isIgnoreCaseEnabled(), is(true));
|
||||
}
|
||||
|
||||
static class Person {
|
||||
|
||||
String firstname;
|
||||
}
|
||||
}
|
||||
@@ -1,220 +0,0 @@
|
||||
/*
|
||||
* Copyright 2016 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.domain;
|
||||
|
||||
import static org.hamcrest.Matchers.*;
|
||||
import static org.hamcrest.core.Is.is;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.data.domain.ExampleSpec.NullHandler;
|
||||
import org.springframework.data.domain.ExampleSpec.StringMatcher;
|
||||
|
||||
/**
|
||||
* Unit test for {@link ExampleSpec}.
|
||||
*
|
||||
* @author Mark Paluch
|
||||
* @soundtrack K2 - Der Berg Ruft (Club Mix)
|
||||
*/
|
||||
public class ExampleSpecUnitTests {
|
||||
|
||||
ExampleSpec exampleSpec;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
exampleSpec = ExampleSpec.untyped();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATACMNS-810
|
||||
*/
|
||||
@Test
|
||||
public void defaultStringMatcherShouldReturnDefault() throws Exception {
|
||||
assertThat(exampleSpec.getDefaultStringMatcher(), is(StringMatcher.DEFAULT));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATACMNS-810
|
||||
*/
|
||||
@Test
|
||||
public void defaultStringMatcherShouldReturnContainingWhenConfigured() throws Exception {
|
||||
|
||||
exampleSpec = ExampleSpec.untyped().withStringMatcherContaining();
|
||||
assertThat(exampleSpec.getDefaultStringMatcher(), is(StringMatcher.CONTAINING));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATACMNS-810
|
||||
*/
|
||||
@Test
|
||||
public void defaultStringMatcherShouldReturnStartingWhenConfigured() throws Exception {
|
||||
|
||||
exampleSpec = ExampleSpec.untyped().withStringMatcherStarting();
|
||||
assertThat(exampleSpec.getDefaultStringMatcher(), is(StringMatcher.STARTING));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATACMNS-810
|
||||
*/
|
||||
@Test
|
||||
public void defaultStringMatcherShouldReturnEndingWhenConfigured() throws Exception {
|
||||
|
||||
exampleSpec = ExampleSpec.untyped().withStringMatcherEnding();
|
||||
assertThat(exampleSpec.getDefaultStringMatcher(), is(StringMatcher.ENDING));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATACMNS-810
|
||||
*/
|
||||
@Test
|
||||
public void ignoreCaseShouldReturnFalseByDefault() throws Exception {
|
||||
assertThat(exampleSpec.isIgnoreCaseEnabled(), is(false));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATACMNS-810
|
||||
*/
|
||||
@Test
|
||||
public void ignoredPathsIsEmptyByDefault() throws Exception {
|
||||
assertThat(exampleSpec.getIgnoredPaths(), is(empty()));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATACMNS-810
|
||||
*/
|
||||
@Test
|
||||
public void nullHandlerShouldReturnIgnoreByDefault() throws Exception {
|
||||
assertThat(exampleSpec.getNullHandler(), is(NullHandler.IGNORE));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATACMNS-810
|
||||
*/
|
||||
@Test(expected = UnsupportedOperationException.class)
|
||||
public void ignoredPathsIsNotModifiable() throws Exception {
|
||||
exampleSpec.getIgnoredPaths().add("¯\\_(ツ)_/¯");
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATACMNS-810
|
||||
*/
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void defaultExampleSpecWithoutTypeFails() throws Exception {
|
||||
ExampleSpec.typed(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATACMNS-810
|
||||
*/
|
||||
@Test
|
||||
public void ignoreCaseShouldReturnTrueWhenIgnoreCaseEnabled() throws Exception {
|
||||
|
||||
exampleSpec = ExampleSpec.untyped().withIgnoreCase();
|
||||
|
||||
assertThat(exampleSpec.isIgnoreCaseEnabled(), is(true));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATACMNS-810
|
||||
*/
|
||||
@Test
|
||||
public void ignoreCaseShouldReturnTrueWhenIgnoreCaseSet() throws Exception {
|
||||
|
||||
exampleSpec = ExampleSpec.untyped().withIgnoreCase(true);
|
||||
|
||||
assertThat(exampleSpec.isIgnoreCaseEnabled(), is(true));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATACMNS-810
|
||||
*/
|
||||
@Test
|
||||
public void nullHandlerShouldReturnInclude() throws Exception {
|
||||
|
||||
exampleSpec = ExampleSpec.untyped().withIncludeNullValues();
|
||||
|
||||
assertThat(exampleSpec.getNullHandler(), is(NullHandler.INCLUDE));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATACMNS-810
|
||||
*/
|
||||
@Test
|
||||
public void nullHandlerShouldReturnIgnore() throws Exception {
|
||||
|
||||
exampleSpec = ExampleSpec.untyped().withIgnoreNullValues();
|
||||
|
||||
assertThat(exampleSpec.getNullHandler(), is(NullHandler.IGNORE));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATACMNS-810
|
||||
*/
|
||||
@Test
|
||||
public void nullHandlerShouldReturnConfiguredValue() throws Exception {
|
||||
|
||||
exampleSpec = ExampleSpec.untyped().withNullHandler(NullHandler.INCLUDE);
|
||||
|
||||
assertThat(exampleSpec.getNullHandler(), is(NullHandler.INCLUDE));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATACMNS-810
|
||||
*/
|
||||
@Test
|
||||
public void ignoredPathsShouldReturnCorrectProperties() throws Exception {
|
||||
|
||||
exampleSpec = ExampleSpec.untyped().withIgnorePaths("foo", "bar", "baz");
|
||||
|
||||
assertThat(exampleSpec.getIgnoredPaths(), contains("foo", "bar", "baz"));
|
||||
assertThat(exampleSpec.getIgnoredPaths(), hasSize(3));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATACMNS-810
|
||||
*/
|
||||
@Test
|
||||
public void ignoredPathsShouldReturnUniqueProperties() throws Exception {
|
||||
|
||||
exampleSpec = ExampleSpec.untyped().withIgnorePaths("foo", "bar", "foo");
|
||||
|
||||
assertThat(exampleSpec.getIgnoredPaths(), contains("foo", "bar"));
|
||||
assertThat(exampleSpec.getIgnoredPaths(), hasSize(2));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATACMNS-810
|
||||
*/
|
||||
@Test
|
||||
public void withCreatesNewInstance() throws Exception {
|
||||
|
||||
exampleSpec = ExampleSpec.untyped().withIgnorePaths("foo", "bar", "foo");
|
||||
ExampleSpec configuredExampleSpec = exampleSpec.withIgnoreCase();
|
||||
|
||||
assertThat(exampleSpec, is(not(sameInstance(configuredExampleSpec))));
|
||||
assertThat(exampleSpec.getIgnoredPaths(), hasSize(2));
|
||||
assertThat(exampleSpec.isIgnoreCaseEnabled(), is(false));
|
||||
|
||||
assertThat(configuredExampleSpec.getIgnoredPaths(), hasSize(2));
|
||||
assertThat(configuredExampleSpec.isIgnoreCaseEnabled(), is(true));
|
||||
}
|
||||
|
||||
static class Person {
|
||||
|
||||
String firstname;
|
||||
}
|
||||
}
|
||||
@@ -15,9 +15,8 @@
|
||||
*/
|
||||
package org.springframework.data.domain;
|
||||
|
||||
import static org.hamcrest.core.IsEqual.*;
|
||||
import static org.hamcrest.CoreMatchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
import static org.springframework.data.domain.Example.*;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
@@ -27,11 +26,12 @@ import org.junit.Test;
|
||||
*
|
||||
* @author Christoph Strobl
|
||||
* @author Mark Paluch
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public class ExampleUnitTests {
|
||||
|
||||
private Person person;
|
||||
private Example<Person> example;
|
||||
Person person;
|
||||
Example<Person> example;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
@@ -39,14 +39,14 @@ public class ExampleUnitTests {
|
||||
person = new Person();
|
||||
person.firstname = "rand";
|
||||
|
||||
example = of(person);
|
||||
example = Example.of(person);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATACMNS-810
|
||||
*/
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void exampleOfNullThrowsException() {
|
||||
public void rejectsNullProbe() {
|
||||
Example.of(null);
|
||||
}
|
||||
|
||||
@@ -54,44 +54,11 @@ public class ExampleUnitTests {
|
||||
* @see DATACMNS-810
|
||||
*/
|
||||
@Test
|
||||
public void getSampleTypeRetunsSampleObjectsClass() {
|
||||
assertThat(example.getProbeType(), equalTo(Person.class));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATACMNS-810
|
||||
*/
|
||||
@Test
|
||||
public void createTypedExample() {
|
||||
|
||||
Example<Person> example = of(new Person(), ExampleSpec.typed(Contact.class));
|
||||
|
||||
assertThat(example.getProbeType(), equalTo(Person.class));
|
||||
assertThat(example.getResultType(), equalTo((Class) Contact.class));
|
||||
assertThat(example.getProbeType(), equalTo(Person.class));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATACMNS-810
|
||||
*/
|
||||
@Test
|
||||
public void createUntypedExample() {
|
||||
|
||||
Example<Person> example = of(new Person(), ExampleSpec.untyped());
|
||||
|
||||
assertThat(example.getProbeType(), equalTo(Person.class));
|
||||
assertThat(example.getResultType(), equalTo((Class) Person.class));
|
||||
assertThat(example.getProbeType(), equalTo(Person.class));
|
||||
}
|
||||
|
||||
static class Contact {
|
||||
|
||||
String label;
|
||||
public void retunsSampleObjectsClassAsProbeType() {
|
||||
assertThat(example.getProbeType(), is(equalTo(Person.class)));
|
||||
}
|
||||
|
||||
static class Person {
|
||||
|
||||
String firstname;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,231 +0,0 @@
|
||||
/*
|
||||
* Copyright 2016 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.domain;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.hamcrest.MatcherAssert.*;
|
||||
import static org.hamcrest.Matchers.*;
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
import static org.hamcrest.Matchers.not;
|
||||
import static org.hamcrest.Matchers.sameInstance;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.data.domain.ExampleSpec.NullHandler;
|
||||
import org.springframework.data.domain.ExampleSpec.StringMatcher;
|
||||
|
||||
/**
|
||||
* Unit test for {@link ExampleSpec}.
|
||||
*
|
||||
* @author Mark Paluch
|
||||
* @soundtrack Harmonic Rush - The Dark Side of Persia (ahmed romel remix)
|
||||
*/
|
||||
public class TypedExampleSpecUnitTests {
|
||||
|
||||
TypedExampleSpec<Person> exampleSpec;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
exampleSpec = ExampleSpec.typed(Person.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATACMNS-810
|
||||
*/
|
||||
@Test
|
||||
public void typeShouldReturnConfiguredType() throws Exception {
|
||||
assertThat(exampleSpec.getType(), equalTo(Person.class));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATACMNS-810
|
||||
*/
|
||||
@Test
|
||||
public void defaultStringMatcherShouldReturnDefault() throws Exception {
|
||||
assertThat(exampleSpec.getDefaultStringMatcher(), is(StringMatcher.DEFAULT));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATACMNS-810
|
||||
*/
|
||||
@Test
|
||||
public void defaultStringMatcherShouldReturnContainingWhenConfigured() throws Exception {
|
||||
|
||||
exampleSpec = ExampleSpec.typed(Person.class).withStringMatcherContaining();
|
||||
assertThat(exampleSpec.getDefaultStringMatcher(), is(StringMatcher.CONTAINING));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATACMNS-810
|
||||
*/
|
||||
@Test
|
||||
public void defaultStringMatcherShouldReturnStartingWhenConfigured() throws Exception {
|
||||
|
||||
exampleSpec = ExampleSpec.typed(Person.class).withStringMatcherStarting();
|
||||
assertThat(exampleSpec.getDefaultStringMatcher(), is(StringMatcher.STARTING));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATACMNS-810
|
||||
*/
|
||||
@Test
|
||||
public void defaultStringMatcherShouldReturnEndingWhenConfigured() throws Exception {
|
||||
|
||||
exampleSpec = ExampleSpec.typed(Person.class).withStringMatcherEnding();
|
||||
assertThat(exampleSpec.getDefaultStringMatcher(), is(StringMatcher.ENDING));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATACMNS-810
|
||||
*/
|
||||
@Test
|
||||
public void ignoreCaseShouldReturnFalseByDefault() throws Exception {
|
||||
assertThat(exampleSpec.isIgnoreCaseEnabled(), is(false));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATACMNS-810
|
||||
*/
|
||||
@Test
|
||||
public void ignoredPathsIsEmptyByDefault() throws Exception {
|
||||
assertThat(exampleSpec.getIgnoredPaths(), is(empty()));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATACMNS-810
|
||||
*/
|
||||
@Test
|
||||
public void nullHandlerShouldReturnIgnoreByDefault() throws Exception {
|
||||
assertThat(exampleSpec.getNullHandler(), is(NullHandler.IGNORE));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATACMNS-810
|
||||
*/
|
||||
@Test(expected = UnsupportedOperationException.class)
|
||||
public void ignoredPathsIsNotModifiable() throws Exception {
|
||||
exampleSpec.getIgnoredPaths().add("¯\\_(ツ)_/¯");
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATACMNS-810
|
||||
*/
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void defaultExampleSpecWithoutTypeFails() throws Exception {
|
||||
ExampleSpec.typed(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATACMNS-810
|
||||
*/
|
||||
@Test
|
||||
public void ignoreCaseShouldReturnTrueWhenIgnoreCaseEnabled() throws Exception {
|
||||
|
||||
exampleSpec = ExampleSpec.typed(Person.class).withIgnoreCase();
|
||||
|
||||
assertThat(exampleSpec.isIgnoreCaseEnabled(), is(true));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATACMNS-810
|
||||
*/
|
||||
@Test
|
||||
public void ignoreCaseShouldReturnTrueWhenIgnoreCaseSet() throws Exception {
|
||||
|
||||
exampleSpec = ExampleSpec.typed(Person.class).withIgnoreCase(true);
|
||||
|
||||
assertThat(exampleSpec.isIgnoreCaseEnabled(), is(true));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATACMNS-810
|
||||
*/
|
||||
@Test
|
||||
public void nullHandlerShouldReturnInclude() throws Exception {
|
||||
|
||||
exampleSpec = ExampleSpec.typed(Person.class).withIncludeNullValues();
|
||||
|
||||
assertThat(exampleSpec.getNullHandler(), is(NullHandler.INCLUDE));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATACMNS-810
|
||||
*/
|
||||
@Test
|
||||
public void nullHandlerShouldReturnIgnore() throws Exception {
|
||||
|
||||
exampleSpec = ExampleSpec.typed(Person.class).withIgnoreNullValues();
|
||||
|
||||
assertThat(exampleSpec.getNullHandler(), is(NullHandler.IGNORE));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATACMNS-810
|
||||
*/
|
||||
@Test
|
||||
public void nullHandlerShouldReturnConfiguredValue() throws Exception {
|
||||
|
||||
exampleSpec = ExampleSpec.typed(Person.class).withNullHandler(NullHandler.INCLUDE);
|
||||
|
||||
assertThat(exampleSpec.getNullHandler(), is(NullHandler.INCLUDE));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATACMNS-810
|
||||
*/
|
||||
@Test
|
||||
public void ignoredPathsShouldReturnCorrectProperties() throws Exception {
|
||||
|
||||
exampleSpec = ExampleSpec.typed(Person.class).withIgnorePaths("foo", "bar", "baz");
|
||||
|
||||
assertThat(exampleSpec.getIgnoredPaths(), contains("foo", "bar", "baz"));
|
||||
assertThat(exampleSpec.getIgnoredPaths(), hasSize(3));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATACMNS-810
|
||||
*/
|
||||
@Test
|
||||
public void ignoredPathsShouldReturnUniqueProperties() throws Exception {
|
||||
|
||||
exampleSpec = ExampleSpec.typed(Person.class).withIgnorePaths("foo", "bar", "foo");
|
||||
|
||||
assertThat(exampleSpec.getIgnoredPaths(), contains("foo", "bar"));
|
||||
assertThat(exampleSpec.getIgnoredPaths(), hasSize(2));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATACMNS-810
|
||||
*/
|
||||
@Test
|
||||
public void withCreatesNewInstance() throws Exception {
|
||||
|
||||
exampleSpec = ExampleSpec.typed(Person.class).withIgnorePaths("foo", "bar", "foo");
|
||||
TypedExampleSpec<Person> configuredExampleSpec = exampleSpec.withIgnoreCase();
|
||||
|
||||
assertThat(exampleSpec, is(not(sameInstance(configuredExampleSpec))));
|
||||
assertThat(exampleSpec.getIgnoredPaths(), hasSize(2));
|
||||
assertThat(exampleSpec.isIgnoreCaseEnabled(), is(false));
|
||||
|
||||
assertThat(configuredExampleSpec.getIgnoredPaths(), hasSize(2));
|
||||
assertThat(configuredExampleSpec.isIgnoreCaseEnabled(), is(true));
|
||||
}
|
||||
|
||||
static class Person {
|
||||
|
||||
String firstname;
|
||||
}
|
||||
}
|
||||
@@ -1,315 +0,0 @@
|
||||
/*
|
||||
* Copyright 2016 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.repository.core.support;
|
||||
|
||||
import static org.hamcrest.Matchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.data.domain.ExampleSpec;
|
||||
import org.springframework.data.domain.ExampleSpec.GenericPropertyMatcher;
|
||||
import org.springframework.data.domain.ExampleSpec.GenericPropertyMatchers;
|
||||
import org.springframework.data.domain.ExampleSpec.MatcherConfigurer;
|
||||
import org.springframework.data.domain.ExampleSpec.NoOpPropertyValueTransformer;
|
||||
import org.springframework.data.domain.ExampleSpec.NullHandler;
|
||||
import org.springframework.data.domain.ExampleSpec.PropertyValueTransformer;
|
||||
import org.springframework.data.domain.ExampleSpec.StringMatcher;
|
||||
import org.springframework.data.domain.TypedExampleSpec;
|
||||
|
||||
/**
|
||||
* Test for {@link ExampleSpecAccessor}.
|
||||
*
|
||||
* @author Mark Paluch
|
||||
* @soundtrack Cabballero - Dancing With Tears In My Eyes (Dance Maxi)
|
||||
*/
|
||||
public class ExampleSpecAccessorTypedExampleSpecUnitTests {
|
||||
|
||||
private Person person;
|
||||
private TypedExampleSpec<Person> exampleSpec;
|
||||
private ExampleSpecAccessor exampleSpecAccessor;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
|
||||
person = new Person();
|
||||
person.firstname = "rand";
|
||||
|
||||
exampleSpec = ExampleSpec.typed(Person.class);
|
||||
exampleSpecAccessor = new ExampleSpecAccessor(exampleSpec);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATACMNS-810
|
||||
*/
|
||||
@Test
|
||||
public void isTypedShouldReturnTrue() {
|
||||
assertThat(exampleSpecAccessor.isTyped(), is(true));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATACMNS-810
|
||||
*/
|
||||
@Test
|
||||
public void defaultStringMatcherShouldReturnDefault() {
|
||||
assertThat(exampleSpecAccessor.getDefaultStringMatcher(), equalTo(StringMatcher.DEFAULT));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATACMNS-810
|
||||
*/
|
||||
@Test
|
||||
public void nullHandlerShouldReturnInclude() {
|
||||
|
||||
exampleSpec = ExampleSpec.typed(Person.class).withIncludeNullValues();
|
||||
exampleSpecAccessor = new ExampleSpecAccessor(exampleSpec);
|
||||
|
||||
assertThat(exampleSpecAccessor.getNullHandler(), equalTo(NullHandler.INCLUDE));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATACMNS-810
|
||||
*/
|
||||
@Test
|
||||
public void exampleShouldIgnorePaths() {
|
||||
|
||||
exampleSpec = ExampleSpec.typed(Person.class).withIgnorePaths("firstname");
|
||||
exampleSpecAccessor = new ExampleSpecAccessor(exampleSpec);
|
||||
|
||||
assertThat(exampleSpecAccessor.isIgnoredPath("firstname"), equalTo(true));
|
||||
assertThat(exampleSpecAccessor.isIgnoredPath("lastname"), equalTo(false));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATACMNS-810
|
||||
*/
|
||||
@Test
|
||||
public void exampleShouldUseDefaultStringMatcherForPathThatDoesNotHavePropertySpecifier() {
|
||||
assertThat(exampleSpecAccessor.getStringMatcherForPath("firstname"),
|
||||
equalTo(exampleSpec.getDefaultStringMatcher()));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATACMNS-810
|
||||
*/
|
||||
@Test
|
||||
public void exampleShouldUseConfiguredStringMatcherAsDefaultForPathThatDoesNotHavePropertySpecifier() {
|
||||
|
||||
exampleSpec = ExampleSpec.typed(Person.class).withStringMatcher(StringMatcher.CONTAINING);
|
||||
exampleSpecAccessor = new ExampleSpecAccessor(exampleSpec);
|
||||
|
||||
assertThat(exampleSpecAccessor.getStringMatcherForPath("firstname"), equalTo(StringMatcher.CONTAINING));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATACMNS-810
|
||||
*/
|
||||
@Test
|
||||
public void exampleShouldUseDefaultIgnoreCaseForPathThatDoesHavePropertySpecifierWithMatcher() {
|
||||
|
||||
exampleSpec = ExampleSpec.typed(Person.class).withIgnoreCase().withMatcher("firstname",
|
||||
new GenericPropertyMatcher().contains());
|
||||
exampleSpecAccessor = new ExampleSpecAccessor(exampleSpec);
|
||||
|
||||
assertThat(exampleSpecAccessor.isIgnoreCaseForPath("firstname"), equalTo(true));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATACMNS-810
|
||||
*/
|
||||
@Test
|
||||
public void exampleShouldUseConfiguredIgnoreCaseForPathThatDoesHavePropertySpecifierWithMatcher() {
|
||||
|
||||
exampleSpec = ExampleSpec.typed(Person.class).withIgnoreCase().withMatcher("firstname",
|
||||
new GenericPropertyMatcher().contains().caseSensitive());
|
||||
exampleSpecAccessor = new ExampleSpecAccessor(exampleSpec);
|
||||
|
||||
assertThat(exampleSpecAccessor.isIgnoreCaseForPath("firstname"), equalTo(false));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATACMNS-810
|
||||
*/
|
||||
@Test
|
||||
public void exampleShouldUseDefinedStringMatcherForPathThatDoesHavePropertySpecifierWithStringMatcherStarting() {
|
||||
|
||||
exampleSpec = ExampleSpec.typed(Person.class).withMatcher("firstname", GenericPropertyMatchers.startsWith());
|
||||
exampleSpecAccessor = new ExampleSpecAccessor(exampleSpec);
|
||||
|
||||
assertThat(exampleSpecAccessor.getStringMatcherForPath("firstname"), equalTo(StringMatcher.STARTING));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATACMNS-810
|
||||
*/
|
||||
@Test
|
||||
public void exampleShouldUseDefinedStringMatcherForPathThatDoesHavePropertySpecifierWithStringMatcherContaining() {
|
||||
|
||||
exampleSpec = ExampleSpec.typed(Person.class).withMatcher("firstname", GenericPropertyMatchers.contains());
|
||||
exampleSpecAccessor = new ExampleSpecAccessor(exampleSpec);
|
||||
|
||||
assertThat(exampleSpecAccessor.getStringMatcherForPath("firstname"), equalTo(StringMatcher.CONTAINING));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATACMNS-810
|
||||
*/
|
||||
@Test
|
||||
public void exampleShouldUseDefinedStringMatcherForPathThatDoesHavePropertySpecifierWithStringMatcherRegex() {
|
||||
|
||||
exampleSpec = ExampleSpec.typed(Person.class).withMatcher("firstname", GenericPropertyMatchers.regex());
|
||||
exampleSpecAccessor = new ExampleSpecAccessor(exampleSpec);
|
||||
|
||||
assertThat(exampleSpecAccessor.getStringMatcherForPath("firstname"), equalTo(StringMatcher.REGEX));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATACMNS-810
|
||||
*/
|
||||
@Test
|
||||
public void exampleShouldFavorStringMatcherDefinedForPathOverConfiguredDefaultStringMatcher() {
|
||||
|
||||
exampleSpec = ExampleSpec.typed(Person.class).withStringMatcher(StringMatcher.ENDING)
|
||||
.withMatcher("firstname", new GenericPropertyMatcher().contains())
|
||||
.withMatcher("address.city", new GenericPropertyMatcher().startsWith())
|
||||
.withMatcher("lastname", new MatcherConfigurer<GenericPropertyMatcher>() {
|
||||
@Override
|
||||
public void configureMatcher(GenericPropertyMatcher matcher) {
|
||||
matcher.ignoreCase();
|
||||
}
|
||||
});
|
||||
|
||||
exampleSpecAccessor = new ExampleSpecAccessor(exampleSpec);
|
||||
|
||||
assertThat(exampleSpecAccessor.getPropertySpecifiers(), hasSize(3));
|
||||
assertThat(exampleSpecAccessor.getStringMatcherForPath("firstname"), equalTo(StringMatcher.CONTAINING));
|
||||
assertThat(exampleSpecAccessor.getStringMatcherForPath("lastname"), equalTo(StringMatcher.ENDING));
|
||||
assertThat(exampleSpecAccessor.getStringMatcherForPath("unknownProperty"), equalTo(StringMatcher.ENDING));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATACMNS-810
|
||||
*/
|
||||
@Test
|
||||
public void exampleShouldUseDefaultStringMatcherForPathThatHasPropertySpecifierWithoutStringMatcher() {
|
||||
|
||||
exampleSpec = ExampleSpec.typed(Person.class).withStringMatcher(StringMatcher.STARTING).withMatcher("firstname",
|
||||
new MatcherConfigurer<GenericPropertyMatcher>() {
|
||||
@Override
|
||||
public void configureMatcher(GenericPropertyMatcher matcher) {
|
||||
matcher.ignoreCase();
|
||||
}
|
||||
});
|
||||
|
||||
exampleSpecAccessor = new ExampleSpecAccessor(exampleSpec);
|
||||
|
||||
assertThat(exampleSpecAccessor.getStringMatcherForPath("firstname"), equalTo(StringMatcher.STARTING));
|
||||
assertThat(exampleSpecAccessor.isIgnoreCaseForPath("firstname"), is(true));
|
||||
assertThat(exampleSpecAccessor.isIgnoreCaseForPath("unknownProperty"), is(false));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATACMNS-810
|
||||
*/
|
||||
@Test
|
||||
public void ignoreCaseShouldReturnFalseByDefault() {
|
||||
|
||||
assertThat(exampleSpec.isIgnoreCaseEnabled(), is(false));
|
||||
assertThat(exampleSpecAccessor.isIgnoreCaseForPath("firstname"), is(false));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATACMNS-810
|
||||
*/
|
||||
@Test
|
||||
public void ignoreCaseShouldReturnTrueWhenIgnoreCaseIsEnabled() {
|
||||
|
||||
exampleSpec = ExampleSpec.typed(Person.class).withIgnoreCase();
|
||||
exampleSpecAccessor = new ExampleSpecAccessor(exampleSpec);
|
||||
|
||||
assertThat(exampleSpecAccessor.isIgnoreCaseEnabled(), is(true));
|
||||
assertThat(exampleSpecAccessor.isIgnoreCaseForPath("firstname"), is(true));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATACMNS-810
|
||||
*/
|
||||
@Test
|
||||
public void ignoreCaseShouldFavorPathSpecificSettings() {
|
||||
|
||||
exampleSpec = ExampleSpec.typed(Person.class).withIgnoreCase("firstname");
|
||||
exampleSpecAccessor = new ExampleSpecAccessor(exampleSpec);
|
||||
|
||||
assertThat(exampleSpec.isIgnoreCaseEnabled(), is(false));
|
||||
assertThat(exampleSpecAccessor.isIgnoreCaseForPath("firstname"), is(true));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATACMNS-810
|
||||
*/
|
||||
@Test
|
||||
public void getValueTransformerForPathReturnsNoOpValueTransformerByDefault() {
|
||||
assertThat(exampleSpecAccessor.getValueTransformerForPath("firstname"),
|
||||
instanceOf(NoOpPropertyValueTransformer.class));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATACMNS-810
|
||||
*/
|
||||
@Test
|
||||
public void getValueTransformerForPathReturnsConfigurtedTransformerForPath() {
|
||||
|
||||
PropertyValueTransformer transformer = new PropertyValueTransformer() {
|
||||
|
||||
@Override
|
||||
public Object convert(Object source) {
|
||||
return source.toString();
|
||||
}
|
||||
};
|
||||
|
||||
exampleSpec = ExampleSpec.typed(Person.class).withTransformer("firstname", transformer);
|
||||
exampleSpecAccessor = new ExampleSpecAccessor(exampleSpec);
|
||||
|
||||
assertThat(exampleSpecAccessor.getValueTransformerForPath("firstname"), equalTo(transformer));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATACMNS-810
|
||||
*/
|
||||
@Test
|
||||
public void hasPropertySpecifiersReturnsFalseIfNoneDefined() {
|
||||
assertThat(exampleSpecAccessor.hasPropertySpecifiers(), is(false));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATACMNS-810
|
||||
*/
|
||||
@Test
|
||||
public void hasPropertySpecifiersReturnsTrueWhenAtLeastOneIsSet() {
|
||||
|
||||
exampleSpec = ExampleSpec.typed(Person.class).withStringMatcher(StringMatcher.STARTING).withMatcher("firstname",
|
||||
new GenericPropertyMatcher().contains());
|
||||
exampleSpecAccessor = new ExampleSpecAccessor(exampleSpec);
|
||||
|
||||
assertThat(exampleSpecAccessor.hasPropertySpecifiers(), is(true));
|
||||
}
|
||||
|
||||
static class Person {
|
||||
|
||||
String firstname;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,306 +0,0 @@
|
||||
/*
|
||||
* Copyright 2016 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.repository.core.support;
|
||||
|
||||
import static org.hamcrest.Matchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.data.domain.ExampleSpec;
|
||||
import org.springframework.data.domain.ExampleSpec.GenericPropertyMatcher;
|
||||
import org.springframework.data.domain.ExampleSpec.GenericPropertyMatchers;
|
||||
import org.springframework.data.domain.ExampleSpec.MatcherConfigurer;
|
||||
import org.springframework.data.domain.ExampleSpec.NoOpPropertyValueTransformer;
|
||||
import org.springframework.data.domain.ExampleSpec.NullHandler;
|
||||
import org.springframework.data.domain.ExampleSpec.PropertyValueTransformer;
|
||||
import org.springframework.data.domain.ExampleSpec.StringMatcher;
|
||||
|
||||
/**
|
||||
* Test for {@link ExampleSpecAccessor}.
|
||||
*
|
||||
* @author Mark Paluch
|
||||
* @soundtrack Alex Wackii and Tolga Uzulmez - Diamond Rush (original mix)
|
||||
*/
|
||||
public class ExampleSpecAccessorUntypedExampleSpecUnitTests {
|
||||
|
||||
private Person person;
|
||||
private ExampleSpec exampleSpec;
|
||||
private ExampleSpecAccessor exampleSpecAccessor;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
|
||||
person = new Person();
|
||||
person.firstname = "rand";
|
||||
|
||||
exampleSpec = ExampleSpec.untyped();
|
||||
exampleSpecAccessor = new ExampleSpecAccessor(exampleSpec);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATACMNS-810
|
||||
*/
|
||||
@Test
|
||||
public void defaultStringMatcherShouldReturnDefault() {
|
||||
assertThat(exampleSpecAccessor.getDefaultStringMatcher(), equalTo(StringMatcher.DEFAULT));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATACMNS-810
|
||||
*/
|
||||
@Test
|
||||
public void nullHandlerShouldReturnInclude() {
|
||||
|
||||
exampleSpec = ExampleSpec.untyped().withIncludeNullValues();
|
||||
exampleSpecAccessor = new ExampleSpecAccessor(exampleSpec);
|
||||
|
||||
assertThat(exampleSpecAccessor.getNullHandler(), equalTo(NullHandler.INCLUDE));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATACMNS-810
|
||||
*/
|
||||
@Test
|
||||
public void exampleShouldIgnorePaths() {
|
||||
|
||||
exampleSpec = ExampleSpec.untyped().withIgnorePaths("firstname");
|
||||
exampleSpecAccessor = new ExampleSpecAccessor(exampleSpec);
|
||||
|
||||
assertThat(exampleSpecAccessor.isIgnoredPath("firstname"), equalTo(true));
|
||||
assertThat(exampleSpecAccessor.isIgnoredPath("lastname"), equalTo(false));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATACMNS-810
|
||||
*/
|
||||
@Test
|
||||
public void exampleShouldUseDefaultStringMatcherForPathThatDoesNotHavePropertySpecifier() {
|
||||
assertThat(exampleSpecAccessor.getStringMatcherForPath("firstname"),
|
||||
equalTo(exampleSpec.getDefaultStringMatcher()));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATACMNS-810
|
||||
*/
|
||||
@Test
|
||||
public void exampleShouldUseConfiguredStringMatcherAsDefaultForPathThatDoesNotHavePropertySpecifier() {
|
||||
|
||||
exampleSpec = ExampleSpec.untyped().withStringMatcher(StringMatcher.CONTAINING);
|
||||
exampleSpecAccessor = new ExampleSpecAccessor(exampleSpec);
|
||||
|
||||
assertThat(exampleSpecAccessor.getStringMatcherForPath("firstname"), equalTo(StringMatcher.CONTAINING));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATACMNS-810
|
||||
*/
|
||||
@Test
|
||||
public void exampleShouldUseDefaultIgnoreCaseForPathThatDoesHavePropertySpecifierWithMatcher() {
|
||||
|
||||
exampleSpec = ExampleSpec.untyped().withIgnoreCase().withMatcher("firstname",
|
||||
new GenericPropertyMatcher().contains());
|
||||
exampleSpecAccessor = new ExampleSpecAccessor(exampleSpec);
|
||||
|
||||
assertThat(exampleSpecAccessor.isIgnoreCaseForPath("firstname"), equalTo(true));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATACMNS-810
|
||||
*/
|
||||
@Test
|
||||
public void exampleShouldUseConfiguredIgnoreCaseForPathThatDoesHavePropertySpecifierWithMatcher() {
|
||||
|
||||
exampleSpec = ExampleSpec.untyped().withIgnoreCase().withMatcher("firstname",
|
||||
new GenericPropertyMatcher().contains().caseSensitive());
|
||||
exampleSpecAccessor = new ExampleSpecAccessor(exampleSpec);
|
||||
|
||||
assertThat(exampleSpecAccessor.isIgnoreCaseForPath("firstname"), equalTo(false));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATACMNS-810
|
||||
*/
|
||||
@Test
|
||||
public void exampleShouldUseDefinedStringMatcherForPathThatDoesHavePropertySpecifierWithStringMatcherStarting() {
|
||||
|
||||
exampleSpec = ExampleSpec.untyped().withMatcher("firstname", GenericPropertyMatchers.startsWith());
|
||||
exampleSpecAccessor = new ExampleSpecAccessor(exampleSpec);
|
||||
|
||||
assertThat(exampleSpecAccessor.getStringMatcherForPath("firstname"), equalTo(StringMatcher.STARTING));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATACMNS-810
|
||||
*/
|
||||
@Test
|
||||
public void exampleShouldUseDefinedStringMatcherForPathThatDoesHavePropertySpecifierWithStringMatcherContaining() {
|
||||
|
||||
exampleSpec = ExampleSpec.untyped().withMatcher("firstname", GenericPropertyMatchers.contains());
|
||||
exampleSpecAccessor = new ExampleSpecAccessor(exampleSpec);
|
||||
|
||||
assertThat(exampleSpecAccessor.getStringMatcherForPath("firstname"), equalTo(StringMatcher.CONTAINING));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATACMNS-810
|
||||
*/
|
||||
@Test
|
||||
public void exampleShouldUseDefinedStringMatcherForPathThatDoesHavePropertySpecifierWithStringMatcherRegex() {
|
||||
|
||||
exampleSpec = ExampleSpec.untyped().withMatcher("firstname", GenericPropertyMatchers.regex());
|
||||
exampleSpecAccessor = new ExampleSpecAccessor(exampleSpec);
|
||||
|
||||
assertThat(exampleSpecAccessor.getStringMatcherForPath("firstname"), equalTo(StringMatcher.REGEX));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATACMNS-810
|
||||
*/
|
||||
@Test
|
||||
public void exampleShouldFavorStringMatcherDefinedForPathOverConfiguredDefaultStringMatcher() {
|
||||
|
||||
exampleSpec = ExampleSpec.untyped().withStringMatcher(StringMatcher.ENDING)
|
||||
.withMatcher("firstname", new GenericPropertyMatcher().contains())
|
||||
.withMatcher("address.city", new GenericPropertyMatcher().startsWith())
|
||||
.withMatcher("lastname", new MatcherConfigurer<GenericPropertyMatcher>() {
|
||||
@Override
|
||||
public void configureMatcher(GenericPropertyMatcher matcher) {
|
||||
matcher.ignoreCase();
|
||||
}
|
||||
});
|
||||
|
||||
exampleSpecAccessor = new ExampleSpecAccessor(exampleSpec);
|
||||
|
||||
assertThat(exampleSpecAccessor.getPropertySpecifiers(), hasSize(3));
|
||||
assertThat(exampleSpecAccessor.getStringMatcherForPath("firstname"), equalTo(StringMatcher.CONTAINING));
|
||||
assertThat(exampleSpecAccessor.getStringMatcherForPath("lastname"), equalTo(StringMatcher.ENDING));
|
||||
assertThat(exampleSpecAccessor.getStringMatcherForPath("unknownProperty"), equalTo(StringMatcher.ENDING));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATACMNS-810
|
||||
*/
|
||||
@Test
|
||||
public void exampleShouldUseDefaultStringMatcherForPathThatHasPropertySpecifierWithoutStringMatcher() {
|
||||
|
||||
exampleSpec = ExampleSpec.untyped().withStringMatcher(StringMatcher.STARTING).withMatcher("firstname",
|
||||
new MatcherConfigurer<GenericPropertyMatcher>() {
|
||||
@Override
|
||||
public void configureMatcher(GenericPropertyMatcher matcher) {
|
||||
matcher.ignoreCase();
|
||||
}
|
||||
});
|
||||
|
||||
exampleSpecAccessor = new ExampleSpecAccessor(exampleSpec);
|
||||
|
||||
assertThat(exampleSpecAccessor.getStringMatcherForPath("firstname"), equalTo(StringMatcher.STARTING));
|
||||
assertThat(exampleSpecAccessor.isIgnoreCaseForPath("firstname"), is(true));
|
||||
assertThat(exampleSpecAccessor.isIgnoreCaseForPath("unknownProperty"), is(false));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATACMNS-810
|
||||
*/
|
||||
@Test
|
||||
public void ignoreCaseShouldReturnFalseByDefault() {
|
||||
|
||||
assertThat(exampleSpec.isIgnoreCaseEnabled(), is(false));
|
||||
assertThat(exampleSpecAccessor.isIgnoreCaseForPath("firstname"), is(false));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATACMNS-810
|
||||
*/
|
||||
@Test
|
||||
public void ignoreCaseShouldReturnTrueWhenIgnoreCaseIsEnabled() {
|
||||
|
||||
exampleSpec = ExampleSpec.untyped().withIgnoreCase();
|
||||
exampleSpecAccessor = new ExampleSpecAccessor(exampleSpec);
|
||||
|
||||
assertThat(exampleSpecAccessor.isIgnoreCaseEnabled(), is(true));
|
||||
assertThat(exampleSpecAccessor.isIgnoreCaseForPath("firstname"), is(true));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATACMNS-810
|
||||
*/
|
||||
@Test
|
||||
public void ignoreCaseShouldFavorPathSpecificSettings() {
|
||||
|
||||
exampleSpec = ExampleSpec.untyped().withIgnoreCase("firstname");
|
||||
exampleSpecAccessor = new ExampleSpecAccessor(exampleSpec);
|
||||
|
||||
assertThat(exampleSpec.isIgnoreCaseEnabled(), is(false));
|
||||
assertThat(exampleSpecAccessor.isIgnoreCaseForPath("firstname"), is(true));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATACMNS-810
|
||||
*/
|
||||
@Test
|
||||
public void getValueTransformerForPathReturnsNoOpValueTransformerByDefault() {
|
||||
assertThat(exampleSpecAccessor.getValueTransformerForPath("firstname"),
|
||||
instanceOf(NoOpPropertyValueTransformer.class));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATACMNS-810
|
||||
*/
|
||||
@Test
|
||||
public void getValueTransformerForPathReturnsConfigurtedTransformerForPath() {
|
||||
|
||||
PropertyValueTransformer transformer = new PropertyValueTransformer() {
|
||||
|
||||
@Override
|
||||
public Object convert(Object source) {
|
||||
return source.toString();
|
||||
}
|
||||
};
|
||||
|
||||
exampleSpec = ExampleSpec.untyped().withTransformer("firstname", transformer);
|
||||
exampleSpecAccessor = new ExampleSpecAccessor(exampleSpec);
|
||||
|
||||
assertThat(exampleSpecAccessor.getValueTransformerForPath("firstname"), equalTo(transformer));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATACMNS-810
|
||||
*/
|
||||
@Test
|
||||
public void hasPropertySpecifiersReturnsFalseIfNoneDefined() {
|
||||
assertThat(exampleSpecAccessor.hasPropertySpecifiers(), is(false));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATACMNS-810
|
||||
*/
|
||||
@Test
|
||||
public void hasPropertySpecifiersReturnsTrueWhenAtLeastOneIsSet() {
|
||||
|
||||
exampleSpec = ExampleSpec.untyped().withStringMatcher(StringMatcher.STARTING).withMatcher("firstname",
|
||||
new GenericPropertyMatcher().contains());
|
||||
exampleSpecAccessor = new ExampleSpecAccessor(exampleSpec);
|
||||
|
||||
assertThat(exampleSpecAccessor.hasPropertySpecifiers(), is(true));
|
||||
}
|
||||
|
||||
static class Person {
|
||||
|
||||
String firstname;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,328 @@
|
||||
/*
|
||||
* Copyright 2016 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.repository.core.support;
|
||||
|
||||
import static org.hamcrest.Matchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
import static org.springframework.data.domain.ExampleMatcher.GenericPropertyMatchers.*;
|
||||
import static org.springframework.data.domain.ExampleMatcher.GenericPropertyMatchers.contains;
|
||||
import static org.springframework.data.domain.ExampleMatcher.GenericPropertyMatchers.startsWith;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.data.domain.ExampleMatcher;
|
||||
import org.springframework.data.domain.ExampleMatcher.GenericPropertyMatcher;
|
||||
import org.springframework.data.domain.ExampleMatcher.MatcherConfigurer;
|
||||
import org.springframework.data.domain.ExampleMatcher.NoOpPropertyValueTransformer;
|
||||
import org.springframework.data.domain.ExampleMatcher.NullHandler;
|
||||
import org.springframework.data.domain.ExampleMatcher.PropertyValueTransformer;
|
||||
import org.springframework.data.domain.ExampleMatcher.StringMatcher;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link ExampleMatcherAccessor}.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
* @author Mark Paluch
|
||||
* @soundtrack Ron Spielman Trio - Fretboard Highway (Electric Tales)
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public class ExampleSpecificationAccessorUnitTests {
|
||||
|
||||
Person person;
|
||||
ExampleMatcher specification;
|
||||
ExampleMatcherAccessor exampleSpecificationAccessor;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
|
||||
person = new Person();
|
||||
person.firstname = "rand";
|
||||
|
||||
specification = ExampleMatcher.matching();
|
||||
exampleSpecificationAccessor = new ExampleMatcherAccessor(specification);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATACMNS-810
|
||||
*/
|
||||
@Test
|
||||
public void defaultStringMatcherShouldReturnDefault() {
|
||||
assertThat(exampleSpecificationAccessor.getDefaultStringMatcher(), is(StringMatcher.DEFAULT));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATACMNS-810
|
||||
*/
|
||||
@Test
|
||||
public void nullHandlerShouldReturnInclude() {
|
||||
|
||||
specification = ExampleMatcher.matching().//
|
||||
withIncludeNullValues();
|
||||
exampleSpecificationAccessor = new ExampleMatcherAccessor(specification);
|
||||
|
||||
assertThat(exampleSpecificationAccessor.getNullHandler(), is(NullHandler.INCLUDE));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATACMNS-810
|
||||
*/
|
||||
@Test
|
||||
public void exampleShouldIgnorePaths() {
|
||||
|
||||
specification = ExampleMatcher.matching().withIgnorePaths("firstname");
|
||||
exampleSpecificationAccessor = new ExampleMatcherAccessor(specification);
|
||||
|
||||
assertThat(exampleSpecificationAccessor.isIgnoredPath("firstname"), is(true));
|
||||
assertThat(exampleSpecificationAccessor.isIgnoredPath("lastname"), is(false));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATACMNS-810
|
||||
*/
|
||||
@Test
|
||||
public void exampleShouldUseDefaultStringMatcherForPathThatDoesNotHavePropertySpecifier() {
|
||||
assertThat(exampleSpecificationAccessor.getStringMatcherForPath("firstname"),
|
||||
is(specification.getDefaultStringMatcher()));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATACMNS-810
|
||||
*/
|
||||
@Test
|
||||
public void exampleShouldUseConfiguredStringMatcherAsDefaultForPathThatDoesNotHavePropertySpecifier() {
|
||||
|
||||
specification = ExampleMatcher.matching().//
|
||||
withStringMatcher(StringMatcher.CONTAINING);
|
||||
|
||||
exampleSpecificationAccessor = new ExampleMatcherAccessor(specification);
|
||||
|
||||
assertThat(exampleSpecificationAccessor.getStringMatcherForPath("firstname"), is(StringMatcher.CONTAINING));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATACMNS-810
|
||||
*/
|
||||
@Test
|
||||
public void exampleShouldUseDefaultIgnoreCaseForPathThatDoesHavePropertySpecifierWithMatcher() {
|
||||
|
||||
specification = ExampleMatcher.matching().//
|
||||
withIgnoreCase().//
|
||||
withMatcher("firstname", contains());
|
||||
|
||||
exampleSpecificationAccessor = new ExampleMatcherAccessor(specification);
|
||||
|
||||
assertThat(exampleSpecificationAccessor.isIgnoreCaseForPath("firstname"), is(true));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATACMNS-810
|
||||
*/
|
||||
@Test
|
||||
public void exampleShouldUseConfiguredIgnoreCaseForPathThatDoesHavePropertySpecifierWithMatcher() {
|
||||
|
||||
specification = ExampleMatcher.matching().//
|
||||
withIgnoreCase().//
|
||||
withMatcher("firstname", contains().caseSensitive());
|
||||
|
||||
exampleSpecificationAccessor = new ExampleMatcherAccessor(specification);
|
||||
|
||||
assertThat(exampleSpecificationAccessor.isIgnoreCaseForPath("firstname"), equalTo(false));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATACMNS-810
|
||||
*/
|
||||
@Test
|
||||
public void exampleShouldUseDefinedStringMatcherForPathThatDoesHavePropertySpecifierWithStringMatcherStarting() {
|
||||
|
||||
specification = ExampleMatcher.matching().//
|
||||
withMatcher("firstname", startsWith());
|
||||
|
||||
exampleSpecificationAccessor = new ExampleMatcherAccessor(specification);
|
||||
|
||||
assertThat(exampleSpecificationAccessor.getStringMatcherForPath("firstname"), equalTo(StringMatcher.STARTING));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATACMNS-810
|
||||
*/
|
||||
@Test
|
||||
public void exampleShouldUseDefinedStringMatcherForPathThatDoesHavePropertySpecifierWithStringMatcherContaining() {
|
||||
|
||||
specification = ExampleMatcher.matching().//
|
||||
withMatcher("firstname", contains());
|
||||
|
||||
exampleSpecificationAccessor = new ExampleMatcherAccessor(specification);
|
||||
|
||||
assertThat(exampleSpecificationAccessor.getStringMatcherForPath("firstname"), equalTo(StringMatcher.CONTAINING));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATACMNS-810
|
||||
*/
|
||||
@Test
|
||||
public void exampleShouldUseDefinedStringMatcherForPathThatDoesHavePropertySpecifierWithStringMatcherRegex() {
|
||||
|
||||
specification = ExampleMatcher.matching().//
|
||||
withMatcher("firstname", regex());
|
||||
|
||||
exampleSpecificationAccessor = new ExampleMatcherAccessor(specification);
|
||||
|
||||
assertThat(exampleSpecificationAccessor.getStringMatcherForPath("firstname"), equalTo(StringMatcher.REGEX));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATACMNS-810
|
||||
*/
|
||||
@Test
|
||||
public void exampleShouldFavorStringMatcherDefinedForPathOverConfiguredDefaultStringMatcher() {
|
||||
|
||||
specification = ExampleMatcher.matching().withStringMatcher(StringMatcher.ENDING)
|
||||
.withMatcher("firstname", contains()).withMatcher("address.city", startsWith())
|
||||
.withMatcher("lastname", new MatcherConfigurer<GenericPropertyMatcher>() {
|
||||
@Override
|
||||
public void configureMatcher(GenericPropertyMatcher matcher) {
|
||||
matcher.ignoreCase();
|
||||
}
|
||||
});
|
||||
|
||||
exampleSpecificationAccessor = new ExampleMatcherAccessor(specification);
|
||||
|
||||
assertThat(exampleSpecificationAccessor.getPropertySpecifiers(), hasSize(3));
|
||||
assertThat(exampleSpecificationAccessor.getStringMatcherForPath("firstname"), equalTo(StringMatcher.CONTAINING));
|
||||
assertThat(exampleSpecificationAccessor.getStringMatcherForPath("lastname"), equalTo(StringMatcher.ENDING));
|
||||
assertThat(exampleSpecificationAccessor.getStringMatcherForPath("unknownProperty"), equalTo(StringMatcher.ENDING));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATACMNS-810
|
||||
*/
|
||||
@Test
|
||||
public void exampleShouldUseDefaultStringMatcherForPathThatHasPropertySpecifierWithoutStringMatcher() {
|
||||
|
||||
specification = ExampleMatcher.matching().//
|
||||
withStringMatcher(StringMatcher.STARTING).//
|
||||
withMatcher("firstname", new MatcherConfigurer<GenericPropertyMatcher>() {
|
||||
@Override
|
||||
public void configureMatcher(GenericPropertyMatcher matcher) {
|
||||
matcher.ignoreCase();
|
||||
}
|
||||
});
|
||||
|
||||
exampleSpecificationAccessor = new ExampleMatcherAccessor(specification);
|
||||
|
||||
assertThat(exampleSpecificationAccessor.getStringMatcherForPath("firstname"), equalTo(StringMatcher.STARTING));
|
||||
assertThat(exampleSpecificationAccessor.isIgnoreCaseForPath("firstname"), is(true));
|
||||
assertThat(exampleSpecificationAccessor.isIgnoreCaseForPath("unknownProperty"), is(false));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATACMNS-810
|
||||
*/
|
||||
@Test
|
||||
public void ignoreCaseShouldReturnFalseByDefault() {
|
||||
|
||||
assertThat(specification.isIgnoreCaseEnabled(), is(false));
|
||||
assertThat(exampleSpecificationAccessor.isIgnoreCaseForPath("firstname"), is(false));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATACMNS-810
|
||||
*/
|
||||
@Test
|
||||
public void ignoreCaseShouldReturnTrueWhenIgnoreCaseIsEnabled() {
|
||||
|
||||
specification = ExampleMatcher.matching().//
|
||||
withIgnoreCase();
|
||||
|
||||
exampleSpecificationAccessor = new ExampleMatcherAccessor(specification);
|
||||
|
||||
assertThat(exampleSpecificationAccessor.isIgnoreCaseEnabled(), is(true));
|
||||
assertThat(exampleSpecificationAccessor.isIgnoreCaseForPath("firstname"), is(true));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATACMNS-810
|
||||
*/
|
||||
@Test
|
||||
public void ignoreCaseShouldFavorPathSpecificSettings() {
|
||||
|
||||
specification = ExampleMatcher.matching().//
|
||||
withIgnoreCase("firstname");
|
||||
|
||||
exampleSpecificationAccessor = new ExampleMatcherAccessor(specification);
|
||||
|
||||
assertThat(specification.isIgnoreCaseEnabled(), is(false));
|
||||
assertThat(exampleSpecificationAccessor.isIgnoreCaseForPath("firstname"), is(true));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATACMNS-810
|
||||
*/
|
||||
@Test
|
||||
public void getValueTransformerForPathReturnsNoOpValueTransformerByDefault() {
|
||||
assertThat(exampleSpecificationAccessor.getValueTransformerForPath("firstname"),
|
||||
instanceOf(NoOpPropertyValueTransformer.class));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATACMNS-810
|
||||
*/
|
||||
@Test
|
||||
public void getValueTransformerForPathReturnsConfigurtedTransformerForPath() {
|
||||
|
||||
PropertyValueTransformer transformer = new PropertyValueTransformer() {
|
||||
|
||||
@Override
|
||||
public Object convert(Object source) {
|
||||
return source.toString();
|
||||
}
|
||||
};
|
||||
|
||||
specification = ExampleMatcher.matching().//
|
||||
withTransformer("firstname", transformer);
|
||||
exampleSpecificationAccessor = new ExampleMatcherAccessor(specification);
|
||||
|
||||
assertThat(exampleSpecificationAccessor.getValueTransformerForPath("firstname"), equalTo(transformer));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATACMNS-810
|
||||
*/
|
||||
@Test
|
||||
public void hasPropertySpecifiersReturnsFalseIfNoneDefined() {
|
||||
assertThat(exampleSpecificationAccessor.hasPropertySpecifiers(), is(false));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATACMNS-810
|
||||
*/
|
||||
@Test
|
||||
public void hasPropertySpecifiersReturnsTrueWhenAtLeastOneIsSet() {
|
||||
|
||||
specification = ExampleMatcher.matching().//
|
||||
withStringMatcher(StringMatcher.STARTING).//
|
||||
withMatcher("firstname", contains());
|
||||
|
||||
exampleSpecificationAccessor = new ExampleMatcherAccessor(specification);
|
||||
|
||||
assertThat(exampleSpecificationAccessor.hasPropertySpecifiers(), is(true));
|
||||
}
|
||||
|
||||
static class Person {
|
||||
String firstname;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user