DATACMNS-669 - Polishing.

QuerydslBindings now uses a builder style pattern to define custom bindings. This allows to define the same binding for multiple properties of the same type in one configuration call.

Introduced MultiValueBinding to be able to register a binding for multiple source values (i.e. if multiple values are provided for the same parameter). The previously named QuerydslBinding is now a SingleValueBinding which gets adapted to by extracting the first element of the values provided considered as collection.

Slightly refined the generics signature in QuerydslBinding for better type derivation in Lambdas. Removed the need for QuerydslBindingContext by moving a few properties around. The ConversionService instance is now piped into the QuerydslPredicateBuilder directly.

Added a bit of sample data to the Users test domain type to be able to execute the generated Predicates in tests to validate their correctness.

Original pull request: #132.
This commit is contained in:
Oliver Gierke
2015-07-15 09:24:52 +02:00
parent e645501174
commit 5db3def79b
14 changed files with 652 additions and 487 deletions

View File

@@ -22,6 +22,11 @@ import com.mysema.query.annotations.QueryEntity;
*/
@QueryEntity
public class Address {
String street;
String city;
public String street, city;
public Address(String street, String city) {
this.street = street;
this.city = city;
}
}

View File

@@ -28,11 +28,16 @@ import com.mysema.query.annotations.QueryEntity;
@QueryEntity
public class User {
String firstname;
String lastname;
Date dateOfBirth;
public String firstname, lastname;
public Date dateOfBirth;
public Address address;
public List<String> nickNames;
public Long inceptionYear;
Address address;
List<String> nickNames;
Long inceptionYear;
public User(String firstname, String lastname, Address address) {
this.firstname = firstname;
this.lastname = lastname;
this.address = address;
}
}

View File

@@ -0,0 +1,37 @@
/*
* Copyright 2015 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.querydsl;
import java.util.Arrays;
import java.util.List;
/**
* @author Oliver Gierke
*/
public class Users {
public static final User OLIVER, CHRISTOPH;
public static final List<User> USERS;
static {
OLIVER = new User("Oliver", "Gierke", new Address("Somewhere", "Dresden"));
CHRISTOPH = new User("Christoph", "Strobl", new Address("Somewhere", "Linz"));
USERS = Arrays.asList(OLIVER, CHRISTOPH);
}
}

View File

@@ -15,21 +15,18 @@
*/
package org.springframework.data.web.querydsl;
import static org.hamcrest.core.Is.*;
import static org.hamcrest.core.IsNull.*;
import static org.hamcrest.Matchers.*;
import static org.junit.Assert.*;
import java.util.Collections;
import org.junit.Before;
import org.junit.Test;
import org.springframework.beans.MutablePropertyValues;
import org.springframework.core.convert.support.DefaultConversionService;
import org.springframework.data.mapping.PropertyPath;
import org.springframework.data.querydsl.Address;
import org.springframework.data.querydsl.QAddress;
import org.springframework.data.querydsl.QUser;
import org.springframework.data.querydsl.User;
import org.springframework.data.util.ClassTypeInformation;
import org.springframework.test.util.ReflectionTestUtils;
import com.mysema.query.types.Path;
import com.mysema.query.types.Predicate;
import com.mysema.query.types.path.StringPath;
@@ -41,69 +38,50 @@ import com.mysema.query.types.path.StringPath;
*/
public class QuerydslBindingsUnitTests {
private QuerydslPredicateBuilder builder;
private QuerydslBindings typeBasedBindings;
private QuerydslBindings pathBasedBindings;
QuerydslPredicateBuilder builder;
QuerydslBindings bindings;
static final SingleValueBinding<StringPath, String> CONTAINS_BINDING = new SingleValueBinding<StringPath, String>() {
@Override
public Predicate bind(StringPath path, String value) {
return path.contains(value);
}
};
@Before
public void setUp() {
builder = new QuerydslPredicateBuilder();
typeBasedBindings = new QuerydslBindings() {
{
bind(String.class, new QuerydslBinding<StringPath>() {
@Override
public Predicate bind(StringPath path, Object value) {
return path.contains(value.toString());
}
});
}
};
pathBasedBindings = new QuerydslBindings() {
{
bind("address.street", new QuerydslBinding<StringPath>() {
@Override
public Predicate bind(StringPath path, Object value) {
return path.contains(value.toString());
}
});
bind("firstname", new QuerydslBinding<StringPath>() {
@Override
public Predicate bind(StringPath path, Object value) {
return path.contains(value.toString());
}
});
}
};
this.builder = new QuerydslPredicateBuilder(new DefaultConversionService());
this.bindings = new QuerydslBindings();
}
/**
* @see DATACMNS-669
*/
@Test(expected = IllegalArgumentException.class)
public void getBindingForPathShouldThrowErrorWhenPathIsNull() {
pathBasedBindings.getBindingForPath(null);
public void rejectsNullPath() {
bindings.getBindingForPath(null);
}
/**
* @see DATACMNS-669
*/
@Test
public void getBindingForPathShouldReturnNullWhenNoSpecifcBindingAvailable() {
assertThat(pathBasedBindings.getBindingForPath(PropertyPath.from("lastname", User.class)), nullValue());
public void returnsNullIfNoBindingRegisteredForPath() {
assertThat(bindings.getBindingForPath(PropertyPath.from("lastname", User.class)), nullValue());
}
/**
* @see DATACMNS-669
*/
@Test
public void getBindingForPathShouldReturnSpeficicBindingWhenAvailable() {
assertThat(pathBasedBindings.getBindingForPath(PropertyPath.from("firstname", User.class)), notNullValue());
public void returnsRegisteredBindingForSimplePath() {
bindings.bind("firstname").using(CONTAINS_BINDING);
assertAdapterWithTargetBinding(bindings.getBindingForPath(PropertyPath.from("firstname", User.class)),
CONTAINS_BINDING);
}
/**
@@ -111,7 +89,11 @@ public class QuerydslBindingsUnitTests {
*/
@Test
public void getBindingForPathShouldReturnSpeficicBindingForNestedElementsWhenAvailable() {
assertThat(pathBasedBindings.getBindingForPath(PropertyPath.from("address.street", User.class)), notNullValue());
bindings.bind("address.street").using(CONTAINS_BINDING);
assertAdapterWithTargetBinding(bindings.getBindingForPath(PropertyPath.from("address.street", User.class)),
CONTAINS_BINDING);
}
/**
@@ -119,100 +101,112 @@ public class QuerydslBindingsUnitTests {
*/
@Test
public void getBindingForPathShouldReturnSpeficicBindingForTypes() {
assertThat(typeBasedBindings.getBindingForPath(PropertyPath.from("address.street", User.class)), notNullValue());
bindings.bind(String.class).single(CONTAINS_BINDING);
assertAdapterWithTargetBinding(bindings.getBindingForPath(PropertyPath.from("address.street", User.class)),
CONTAINS_BINDING);
}
/**
* @see DATACMNS-669
*/
@Test
public void getBindingForPathShouldIgnoreSpeficicBindingForTypesWhenTypesDoNotMatch() {
assertThat(typeBasedBindings.getBindingForPath(PropertyPath.from("inceptionYear", User.class)), nullValue());
public void propertyNotExplicitlyIncludedAndWithoutTypeBindingIsInvisible() {
bindings.bind(String.class).single(CONTAINS_BINDING);
assertThat(bindings.getBindingForPath(PropertyPath.from("inceptionYear", User.class)), nullValue());
}
/**
* @see DATACMNS-669
*/
@Test
public void isPathVisibleShouldReturnTrueWhenNoRestrictionDefined() {
assertThat(typeBasedBindings.isPathVisible(PropertyPath.from("inceptionYear", User.class)), is(true));
public void pathIsVisibleIfTypeBasedBindingWasRegistered() {
bindings.bind(String.class).single(CONTAINS_BINDING);
assertThat(bindings.isPathVisible(PropertyPath.from("inceptionYear", User.class)), is(true));
}
/**
* @see DATACMNS-669
*/
@Test
public void isPathVisibleShouldReturnTrueWhenPathContainedInIncluding() {
public void explicitlyIncludedPathIsVisible() {
assertThat(
new QuerydslBindings().including("inceptionYear").isPathVisible(PropertyPath.from("inceptionYear", User.class)),
is(true));
bindings.including("inceptionYear");
assertThat(bindings.isPathVisible(PropertyPath.from("inceptionYear", User.class)), is(true));
}
/**
* @see DATACMNS-669
*/
@Test
public void isPathVisibleShouldReturnFalseWhenPathNotContainedInIncluding() {
public void notExplicitlyIncludedPathIsInvisible() {
assertThat(
new QuerydslBindings().including("inceptionYear").isPathVisible(PropertyPath.from("firstname", User.class)),
is(false));
bindings.including("inceptionYear");
assertThat(bindings.isPathVisible(PropertyPath.from("firstname", User.class)), is(false));
}
/**
* @see DATACMNS-669
*/
@Test
public void isPathVisibleShouldReturnFalseWhenPathContainedInExcluding() {
public void excludedPathIsInvisible() {
assertThat(
new QuerydslBindings().excluding("inceptionYear").isPathVisible(PropertyPath.from("inceptionYear", User.class)),
is(false));
bindings.excluding("inceptionYear");
assertThat(bindings.isPathVisible(PropertyPath.from("inceptionYear", User.class)), is(false));
}
/**
* @see DATACMNS-669
*/
@Test
public void isPathVisibleShouldReturnTrueWhenPathNotContainedInExcluding() {
public void pathIsVisibleIfNotExplicitlyExcluded() {
assertThat(
new QuerydslBindings().excluding("inceptionYear").isPathVisible(PropertyPath.from("firstname", User.class)),
is(true));
bindings.excluding("inceptionYear");
assertThat(bindings.isPathVisible(PropertyPath.from("firstname", User.class)), is(true));
}
/**
* @see DATACMNS-669
*/
@Test
public void isPathVisibleShouldReturnTrueWhenPathContainedInExcludingAndIncluding() {
public void pathIsVisibleIfItsBothBlackAndWhitelisted() {
assertThat(
new QuerydslBindings().excluding("inceptionYear").isPathVisible(PropertyPath.from("firstname", User.class)),
is(true));
bindings.excluding("firstname");
bindings.including("firstname");
assertThat(bindings.isPathVisible(PropertyPath.from("firstname", User.class)), is(true));
}
/**
* @see DATACMNS-669
*/
@Test
public void isPathVisibleShouldReturnFalseWhenPartialPathContainedInExcluding() {
public void nestedPathIsInvisibleIfAParanetPathWasExcluded() {
assertThat(
new QuerydslBindings().excluding("address").isPathVisible(PropertyPath.from("address.city", User.class)),
is(false));
bindings.excluding("address");
assertThat(bindings.isPathVisible(PropertyPath.from("address.city", User.class)), is(false));
}
/**
* @see DATACMNS-669
*/
@Test
public void isPathVisibleShouldReturnTrueWhenPartialPathContainedInExcludingButConcretePathIsIncluded() {
public void pathIsVisibleIfConcretePathIsVisibleButParentExcluded() {
assertThat(
new QuerydslBindings().excluding("address").including("address.city")
.isPathVisible(PropertyPath.from("address.city", User.class)), is(true));
bindings.excluding("address");
bindings.including("address.city");
assertThat(bindings.isPathVisible(PropertyPath.from("address.city", User.class)), is(true));
}
/**
@@ -221,22 +215,32 @@ public class QuerydslBindingsUnitTests {
@Test
public void isPathVisibleShouldReturnFalseWhenPartialPathContainedInExcludingAndConcretePathToDifferentPropertyIsIncluded() {
assertThat(
new QuerydslBindings().excluding("address").including("address.city")
.isPathVisible(PropertyPath.from("address.street", User.class)), is(false));
bindings.excluding("address");
bindings.including("address.city");
assertThat(bindings.isPathVisible(PropertyPath.from("address.street", User.class)), is(false));
}
/**
* @see DATACMNS-669
*/
@Test
public void usesTypeBasedBindingIfConfigured() {
public void testname() {
MutablePropertyValues values = new MutablePropertyValues(Collections.singletonMap("city", "Dresden"));
PropertyPath firstname = PropertyPath.from("firstname", User.class);
PropertyPath lastname = PropertyPath.from("lastname", User.class);
PropertyPath city = PropertyPath.from("address.city", User.class);
PropertyPath street = PropertyPath.from("address.street", User.class);
QuerydslBindingContext context = new QuerydslBindingContext(ClassTypeInformation.from(Address.class),
this.typeBasedBindings, null);
bindings.including(QUser.user.firstname, QUser.user.address.street);
assertThat(builder.getPredicate(values, context), is((Predicate) QAddress.address.city.contains("Dresden")));
assertThat(bindings.isPathVisible(firstname), is(true));
assertThat(bindings.isPathVisible(street), is(true));
assertThat(bindings.isPathVisible(lastname), is(false));
assertThat(bindings.isPathVisible(city), is(false));
}
private static <P extends Path<S>, S> void assertAdapterWithTargetBinding(MultiValueBinding<P, S> binding,
SingleValueBinding<? extends Path<?>, ?> expected) {
assertThat(binding, is(instanceOf(QuerydslBindings.MultiValueBindingAdapter.class)));
assertThat(ReflectionTestUtils.getField(binding, "delegate"), is((Object) expected));
}
}

View File

@@ -18,6 +18,7 @@ package org.springframework.data.web.querydsl;
import static org.hamcrest.core.Is.*;
import java.util.Arrays;
import java.util.Collections;
import org.hamcrest.Matcher;
import org.hamcrest.core.Is;
@@ -47,7 +48,7 @@ public class QuerydslDefaultBindingUnitTests {
@Test
public void shouldCreatePredicateCorrectlyWhenPropertyIsInRoot() {
Predicate predicate = builder.bind(QUser.user.firstname, "tam");
Predicate predicate = builder.bind(QUser.user.firstname, Collections.singleton("tam"));
assertThat(predicate, is(QUser.user.firstname.eq("tam")));
}
@@ -58,7 +59,7 @@ public class QuerydslDefaultBindingUnitTests {
@Test
public void shouldCreatePredicateCorrectlyWhenPropertyIsInNestedElement() {
Predicate predicate = builder.bind(QUser.user.address.city, "two rivers");
Predicate predicate = builder.bind(QUser.user.address.city, Collections.singleton("two rivers"));
Assert.assertThat(predicate.toString(), is(QUser.user.address.city.eq("two rivers").toString()));
}
@@ -69,7 +70,7 @@ public class QuerydslDefaultBindingUnitTests {
@Test
public void shouldCreatePredicateCorrectlyWhenValueIsNull() {
Predicate predicate = builder.bind(QUser.user.firstname, null);
Predicate predicate = builder.bind(QUser.user.firstname, Collections.emptySet());
assertThat(predicate, is(QUser.user.firstname.isNull()));
}
@@ -80,7 +81,7 @@ public class QuerydslDefaultBindingUnitTests {
@Test
public void shouldCreatePredicateWithContainingWhenPropertyIsCollectionLikeAndValueIsObject() {
Predicate predicate = builder.bind(QUser.user.nickNames, "dragon reborn");
Predicate predicate = builder.bind(QUser.user.nickNames, Collections.singleton("dragon reborn"));
assertThat(predicate, is(QUser.user.nickNames.contains("dragon reborn")));
}

View File

@@ -18,7 +18,6 @@ package org.springframework.data.web.querydsl;
import static org.hamcrest.core.Is.*;
import static org.junit.Assert.*;
import org.hamcrest.core.Is;
import org.junit.Before;
import org.junit.Test;
import org.springframework.core.MethodParameter;
@@ -34,7 +33,10 @@ import com.mysema.query.types.expr.BooleanExpression;
import com.mysema.query.types.path.StringPath;
/**
* Unit tests for {@link QuerydslPredicateArgumentResolver}.
*
* @author Christoph Strobl
* @author Oliver Gierke
*/
public class QuerydslPredicateArgumentResolverUnitTests {
@@ -90,10 +92,10 @@ public class QuerydslPredicateArgumentResolverUnitTests {
request.addParameter("firstname", "rand");
Object predicate = (BooleanExpression) resolver.resolveArgument(
Predicate predicate = (BooleanExpression) resolver.resolveArgument(
getMethodParameterFor("simpleFind", Predicate.class), null, new ServletWebRequest(request), null);
assertThat(predicate, Is.<Object> is(QUser.user.firstname.eq("rand")));
assertThat(predicate, is((Predicate) QUser.user.firstname.eq("rand")));
}
/**
@@ -105,10 +107,10 @@ public class QuerydslPredicateArgumentResolverUnitTests {
request.addParameter("firstname", "rand");
request.addParameter("lastname", "al'thor");
Object predicate = resolver.resolveArgument(getMethodParameterFor("simpleFind", Predicate.class), null,
Predicate predicate = resolver.resolveArgument(getMethodParameterFor("simpleFind", Predicate.class), null,
new ServletWebRequest(request), null);
assertThat(predicate, Is.<Object> is(QUser.user.firstname.eq("rand").and(QUser.user.lastname.eq("al'thor"))));
assertThat(predicate, is((Predicate) QUser.user.firstname.eq("rand").and(QUser.user.lastname.eq("al'thor"))));
}
/**
@@ -119,10 +121,12 @@ public class QuerydslPredicateArgumentResolverUnitTests {
request.addParameter("address.city", "two rivers");
Object predicate = resolver.resolveArgument(getMethodParameterFor("simpleFind", Predicate.class), null,
Predicate predicate = resolver.resolveArgument(getMethodParameterFor("simpleFind", Predicate.class), null,
new ServletWebRequest(request), null);
assertThat(predicate.toString(), is(QUser.user.address.city.eq("two rivers").toString()));
BooleanExpression eq = QUser.user.address.city.eq("two rivers");
assertThat(predicate, is((Predicate) eq));
}
/**
@@ -133,10 +137,10 @@ public class QuerydslPredicateArgumentResolverUnitTests {
request.addParameter("address.city", "tar valon");
Object predicate = resolver.resolveArgument(getMethodParameterFor("pagedFind", Predicate.class, Pageable.class),
Predicate predicate = resolver.resolveArgument(getMethodParameterFor("pagedFind", Predicate.class, Pageable.class),
null, new ServletWebRequest(request), null);
assertThat(predicate.toString(), is(QUser.user.address.city.eq("tar valon").toString()));
assertThat(predicate, is((Predicate) QUser.user.address.city.eq("tar valon")));
}
/**
@@ -148,12 +152,11 @@ public class QuerydslPredicateArgumentResolverUnitTests {
request.addParameter("firstname", "egwene");
request.addParameter("lastname", "al'vere");
Object predicate = resolver.resolveArgument(getMethodParameterFor("specificFind", Predicate.class), null,
Predicate predicate = resolver.resolveArgument(getMethodParameterFor("specificFind", Predicate.class), null,
new ServletWebRequest(request), null);
assertThat(predicate.toString(),
is(QUser.user.firstname.eq("egwene".toUpperCase()).and(QUser.user.lastname.toLowerCase().eq("al'vere"))
.toString()));
assertThat(predicate, is((Predicate) QUser.user.firstname.eq("egwene".toUpperCase())
.and(QUser.user.lastname.toLowerCase().eq("al'vere"))));
}
/**
@@ -164,10 +167,10 @@ public class QuerydslPredicateArgumentResolverUnitTests {
request.addParameter("inceptionYear", "978");
Object predicate = (BooleanExpression) resolver.resolveArgument(
Predicate predicate = (BooleanExpression) resolver.resolveArgument(
getMethodParameterFor("specificFind", Predicate.class), null, new ServletWebRequest(request), null);
assertThat(predicate, Is.<Object> is(QUser.user.inceptionYear.eq(978L)));
assertThat(predicate, is((Predicate) QUser.user.inceptionYear.eq(978L)));
}
/**
@@ -178,10 +181,10 @@ public class QuerydslPredicateArgumentResolverUnitTests {
request.addParameter("inceptionYear", new String[] { "978", "998" });
Object predicate = (BooleanExpression) resolver.resolveArgument(
Predicate predicate = (BooleanExpression) resolver.resolveArgument(
getMethodParameterFor("specificFind", Predicate.class), null, new ServletWebRequest(request), null);
assertThat(predicate, Is.<Object> is(QUser.user.inceptionYear.in(978L, 998L)));
assertThat(predicate, is((Predicate) QUser.user.inceptionYear.in(978L, 998L)));
}
/**
@@ -199,7 +202,7 @@ public class QuerydslPredicateArgumentResolverUnitTests {
assertThat(predicate.toString(), is(QUser.user.inceptionYear.eq(973L).toString()));
}
private MethodParameter getMethodParameterFor(String methodName, Class<?>... args) throws RuntimeException {
private static MethodParameter getMethodParameterFor(String methodName, Class<?>... args) throws RuntimeException {
try {
return new MethodParameter(Sample.class.getMethod(methodName, args), 0);
@@ -212,19 +215,19 @@ public class QuerydslPredicateArgumentResolverUnitTests {
public SpecificBinding() {
bind("firstname", new QuerydslBinding<StringPath>() {
bind("firstname").using(new SingleValueBinding<StringPath, String>() {
@Override
public Predicate bind(StringPath path, Object value) {
return path.eq(value.toString().toUpperCase());
public Predicate bind(StringPath path, String value) {
return path.eq(value.toUpperCase());
}
});
bind(QUser.user.lastname, new QuerydslBinding<StringPath>() {
bind(QUser.user.lastname).single(new SingleValueBinding<StringPath, String>() {
@Override
public Predicate bind(StringPath path, Object value) {
return path.toLowerCase().eq(value.toString());
public Predicate bind(StringPath path, String value) {
return path.toLowerCase().eq(value);
}
});

View File

@@ -15,32 +15,49 @@
*/
package org.springframework.data.web.querydsl;
import static org.hamcrest.core.Is.*;
import static java.util.Collections.*;
import static org.hamcrest.Matchers.*;
import static org.hamcrest.core.Is.is;
import static org.junit.Assert.*;
import java.util.Collections;
import java.util.List;
import org.hamcrest.core.Is;
import org.junit.Before;
import org.junit.Test;
import org.springframework.beans.MutablePropertyValues;
import org.springframework.core.convert.support.DefaultConversionService;
import org.springframework.data.querydsl.QUser;
import org.springframework.data.querydsl.User;
import org.springframework.data.querydsl.Users;
import org.springframework.data.util.ClassTypeInformation;
import com.mysema.query.BooleanBuilder;
import com.mysema.query.collections.CollQueryFactory;
import com.mysema.query.types.Predicate;
/**
* Unit tests for {@link QuerydslPredicateBuilder}.
*
* @author Christoph Strobl
* @author Oliver Gierke
*/
public class QuerydslPredicateBuilderUnitTests {
static final QuerydslBindings DEFAULT_BINDINGS = new QuerydslBindings();
QuerydslPredicateBuilder builder;
@Before
public void setUp() {
builder = new QuerydslPredicateBuilder();
builder = new QuerydslPredicateBuilder(new DefaultConversionService());
}
/**
* @see DATACMNS-669
*/
@Test(expected = IllegalArgumentException.class)
public void rejectsNullConversionService() {
new QuerydslPredicateBuilder(null);
}
/**
@@ -48,7 +65,7 @@ public class QuerydslPredicateBuilderUnitTests {
*/
@Test(expected = IllegalArgumentException.class)
public void getPredicateShouldThrowErrorWhenBindingContextIsNull() {
builder.getPredicate(new MutablePropertyValues(), null);
builder.getPredicate(new MutablePropertyValues(), null, null);
}
/**
@@ -57,8 +74,8 @@ public class QuerydslPredicateBuilderUnitTests {
@Test
public void getPredicateShouldReturnEmptyPredicateWhenPropertiesAreEmpty() {
assertThat(builder.getPredicate(new MutablePropertyValues(), new QuerydslBindingContext(
ClassTypeInformation.OBJECT, null, null)), is((Predicate) new BooleanBuilder()));
assertThat(builder.getPredicate(new MutablePropertyValues(), DEFAULT_BINDINGS, ClassTypeInformation.OBJECT),
is((Predicate) new BooleanBuilder()));
}
/**
@@ -67,10 +84,31 @@ public class QuerydslPredicateBuilderUnitTests {
@Test
public void resolveArgumentShouldCreateSingleStringParameterPredicateCorrectly() throws Exception {
Predicate predicate = builder.getPredicate(
new MutablePropertyValues(Collections.singletonMap("firstname", new String[] { "rand" })),
new QuerydslBindingContext(ClassTypeInformation.from(User.class), null, null));
Predicate predicate = builder.getPredicate(new MutablePropertyValues(singletonMap("firstname", "Oliver")),
DEFAULT_BINDINGS, ClassTypeInformation.from(User.class));
assertThat(predicate, Is.<Object> is(QUser.user.firstname.eq("rand")));
assertThat(predicate, is((Predicate) QUser.user.firstname.eq("Oliver")));
List<User> result = CollQueryFactory.from(QUser.user, Users.USERS).where(predicate).list(QUser.user);
assertThat(result, hasSize(1));
assertThat(result, hasItem(Users.OLIVER));
}
/**
* @see DATACMNS-669
*/
@Test
public void resolveArgumentShouldCreateNestedStringParameterPredicateCorrectly() throws Exception {
Predicate predicate = builder.getPredicate(new MutablePropertyValues(singletonMap("address.city", "Linz")),
DEFAULT_BINDINGS, ClassTypeInformation.from(User.class));
assertThat(predicate, is((Predicate) QUser.user.address.city.eq("Linz")));
List<User> result = CollQueryFactory.from(QUser.user, Users.USERS).where(predicate).list(QUser.user);
assertThat(result, hasSize(1));
assertThat(result, hasItem(Users.CHRISTOPH));
}
}