diff --git a/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/repository/AbstractGraphRepository.java b/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/repository/AbstractGraphRepository.java index 23cdff3ea..13f0735c4 100644 --- a/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/repository/AbstractGraphRepository.java +++ b/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/repository/AbstractGraphRepository.java @@ -33,6 +33,7 @@ import org.springframework.data.domain.Sort; import org.springframework.data.neo4j.annotation.QueryType; import org.springframework.data.neo4j.conversion.EndResult; import org.springframework.data.neo4j.conversion.Result; +import org.springframework.data.neo4j.core.TypeRepresentationStrategy; import org.springframework.data.neo4j.mapping.Neo4jPersistentProperty; import org.springframework.data.neo4j.repository.query.CypherQuery; import org.springframework.data.neo4j.support.Neo4jTemplate; @@ -348,9 +349,8 @@ public abstract class AbstractGraphRepository im @Override public EndResult findAll(Sort sort) { - // TODO : Do nicer mechanism for working out if labels are in play - boolean useLabels = template.getInfrastructure().getNodeTypeRepresentationStrategy() instanceof LabelBasedNodeTypeRepresentationStrategy; - CypherQuery cq = new CypherQuery(template.getEntityType(clazz).getEntity(),template,useLabels); + TypeRepresentationStrategy nodeTypeRepresentationStrategy = template.getInfrastructure().getNodeTypeRepresentationStrategy(); + CypherQuery cq = new CypherQuery(template.getEntityType(clazz).getEntity(),template,nodeTypeRepresentationStrategy); return query(cq.toQueryString(sort), Collections.EMPTY_MAP); } diff --git a/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/repository/query/CypherQuery.java b/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/repository/query/CypherQuery.java index d9cb48e04..835bd5cfd 100644 --- a/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/repository/query/CypherQuery.java +++ b/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/repository/query/CypherQuery.java @@ -18,9 +18,12 @@ package org.springframework.data.neo4j.repository.query; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Sort; import org.springframework.data.mapping.context.PersistentPropertyPath; +import org.springframework.data.neo4j.core.TypeRepresentationStrategy; import org.springframework.data.neo4j.mapping.Neo4jPersistentEntity; import org.springframework.data.neo4j.mapping.Neo4jPersistentProperty; import org.springframework.data.neo4j.support.Neo4jTemplate; +import org.springframework.data.neo4j.support.typerepresentation.LabelBasedNodeTypeRepresentationStrategy; +import org.springframework.data.neo4j.support.typerepresentation.TypeRepresentationStrategyFactory; import org.springframework.data.repository.query.Parameter; import org.springframework.data.repository.query.parser.Part; @@ -42,17 +45,17 @@ public class CypherQuery implements CypherQueryDefinition { private boolean isCountQuery = false; private boolean useLabels = false; - public CypherQuery(final Neo4jPersistentEntity entity, Neo4jTemplate template, boolean useLabels) { + public CypherQuery(final Neo4jPersistentEntity entity, Neo4jTemplate template, TypeRepresentationStrategy nodeTypeRepresentationStrategy) { this.entity = entity; this.template = template; - this.useLabels = useLabels; + this.useLabels = nodeTypeRepresentationStrategy instanceof LabelBasedNodeTypeRepresentationStrategy; } private String getEntityName(Neo4jPersistentEntity entity) { return variableContext.getVariableFor(entity); } - private String defaultLegacyStartClause(Neo4jPersistentEntity entity) { + private String defaultIndexBasedStartClause(Neo4jPersistentEntity entity) { return String.format(QueryTemplates.DEFAULT_INDEXBASED_START_CLAUSE, getEntityName(entity), entity.getEntityType().getAlias()); @@ -171,15 +174,15 @@ public class CypherQuery implements CypherQueryDefinition { } private String render() { - String legacyStartClauses = collectionToDelimitedString(this.startClauses, ", "); + String startClauses = collectionToDelimitedString(this.startClauses, ", "); String matchClauses = toQueryString(this.matchClauses); String whereClauses = collectionToDelimitedString(this.whereClauses, " AND "); StringBuilder builder = new StringBuilder(""); boolean matchKeyWordUsed = false; - boolean legacyStartClauseUsed = buildInLegacyStartClauses(builder,legacyStartClauses); - if (!legacyStartClauseUsed && useLabels) { + boolean startClauseUsed = buildStartClauseIfRequired(builder, startClauses); + if (!startClauseUsed && useLabels) { matchKeyWordUsed = true; builder.append(" MATCH ").append(defaultMatchBasedStartClause(entity)); } @@ -205,13 +208,13 @@ public class CypherQuery implements CypherQueryDefinition { * Note: This will change to get rid of the start clauses completely but * for now we just get it to work! */ - private boolean buildInLegacyStartClauses(StringBuilder builder, String legacyStartClauses) { - if (hasText(legacyStartClauses)) { - builder.append("START ").append(legacyStartClauses); + private boolean buildStartClauseIfRequired(StringBuilder builder, String startClauses) { + if (hasText(startClauses)) { + builder.append("START ").append(startClauses); return true; } else if (!useLabels) { // TODO: Need to change index based stuff to also not use START - builder.append("START ").append(defaultLegacyStartClause(entity)); + builder.append("START ").append(defaultIndexBasedStartClause(entity)); return true; } return false; diff --git a/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/repository/query/CypherQueryBuilder.java b/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/repository/query/CypherQueryBuilder.java index 41cca0bea..833586836 100644 --- a/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/repository/query/CypherQueryBuilder.java +++ b/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/repository/query/CypherQueryBuilder.java @@ -36,9 +36,7 @@ class CypherQueryBuilder { public CypherQueryBuilder(MappingContext, Neo4jPersistentProperty> context, Class type, Neo4jTemplate template) { this.context = context; Neo4jPersistentEntity entity = context.getPersistentEntity(type); - // TODO : Do nicer mechanism for working out if labels are in play - boolean useLabels = template.getInfrastructure().getNodeTypeRepresentationStrategy() instanceof LabelBasedNodeTypeRepresentationStrategy; - this.query = new CypherQuery(entity, template, useLabels); + this.query = new CypherQuery(entity, template, template.getInfrastructure().getNodeTypeRepresentationStrategy()); } public CypherQueryBuilder asCountQuery() { diff --git a/spring-data-neo4j/src/test/java/org/springframework/data/neo4j/repository/query/AbstractCypherQueryBuilderTestBase.java b/spring-data-neo4j/src/test/java/org/springframework/data/neo4j/repository/query/AbstractCypherQueryBuilderTestBase.java index 1ca1212a8..9eb416757 100644 --- a/spring-data-neo4j/src/test/java/org/springframework/data/neo4j/repository/query/AbstractCypherQueryBuilderTestBase.java +++ b/spring-data-neo4j/src/test/java/org/springframework/data/neo4j/repository/query/AbstractCypherQueryBuilderTestBase.java @@ -44,8 +44,10 @@ import static org.mockito.Mockito.when; */ public abstract class AbstractCypherQueryBuilderTestBase { - CypherQueryBuilder query; - String queryString; + // Allow subclasses to provide specific expectations + protected String trsSpecificExpectedQuery; + private CypherQueryBuilder query; + final static String CLASS_NAME = Person.class.getSimpleName(); @Before @@ -55,199 +57,138 @@ public abstract class AbstractCypherQueryBuilderTestBase { Infrastructure inf = Mockito.mock(Infrastructure.class); when (template.getInfrastructure()).thenReturn(inf); when (inf.getNodeTypeRepresentationStrategy()).thenReturn(getNodeTypeRepresentationStrategy()); - query = new CypherQueryBuilder(context, Person.class, template); - queryString = null; + this.query = new CypherQueryBuilder(context, Person.class, template); + this.trsSpecificExpectedQuery = null; } abstract NodeTypeRepresentationStrategy getNodeTypeRepresentationStrategy(); - /** - * To be used in conjunction with - * buildQueryForCreatesQueryForSimplePropertyReference() - */ @Test - public abstract void createsQueryForSimplePropertyReference(); - protected void buildQueryForCreatesQueryForSimplePropertyReference() - { + public void createsQueryForSimplePropertyReference() { Part part = new Part("name", Person.class); query.addRestriction(part); - queryString = query.toString(); + assertThat(query.toString(), + is(getExpectedQuery("START `person`=node:`Person`(`name`={0}) RETURN `person`"))); } - /** - * To be used in conjunction with - * buildQueryForCreatesQueryForLikePropertyIndex() - */ @Test - public abstract void createsQueryForLikePropertyIndex(); - protected void buildQueryForCreatesQueryForLikePropertyIndex() { + public void createsQueryForLikePropertyIndex() { Part part = new Part("titleLike", Person.class); query.addRestriction(part); - queryString = query.toString(); + assertThat(query.toString(), + is(getExpectedQuery("START `person`=node:`title`({0}) RETURN `person`"))); } - /** - * To be used in conjunction with - * buildQueryForCreatesQueryForLikeProperty() - */ @Test - public abstract void createsQueryForLikeProperty(); - public void buildQueryForCreatesQueryForLikeProperty() { + public void createsQueryForLikeProperty() { Part part = new Part("infoLike", Person.class); query.addRestriction(part); - queryString = query.toString(); + assertThat(query.toString(), is( getExpectedQuery("trs-specific-test-subclass-expected-to-set-value"))); } - /** - * To be used in conjunction with - * buildQueryForCreatesQueryForGreaterThanPropertyReference() - */ @Test - public abstract void createsQueryForGreaterThanPropertyReference(); - public void buildQueryForCreatesQueryForGreaterThanPropertyReference() { + public void createsQueryForGreaterThanPropertyReference() { Part part = new Part("ageGreaterThan", Person.class); query.addRestriction(part); - queryString = query.toString(); + assertThat(query.toString(), is( getExpectedQuery("trs-specific-test-subclass-expected-to-set-value"))); } - /** - * To be used in conjunction with - * buildQueryForCreatesQueryForTwoPropertyExpressions() - */ @Test - public abstract void createsQueryForTwoPropertyExpressions(); - public void buildQueryForCreatesQueryForTwoPropertyExpressions() { + public void createsQueryForTwoPropertyExpressions() { query.addRestriction(new Part("ageGreaterThan", Person.class)); query.addRestriction(new Part("info", Person.class)); - queryString = query.toString(); + assertThat(query.toString(), is( getExpectedQuery("trs-specific-test-subclass-expected-to-set-value"))); } - /** - * To be used in conjunction with - * buildQueryForCreatesQueryForIsNullPropertyReference() - */ @Test - public abstract void createsQueryForIsNullPropertyReference(); - public void buildQueryForCreatesQueryForIsNullPropertyReference() { + public void createsQueryForIsNullPropertyReference() { Part part = new Part("ageIsNull", Person.class); query.addRestriction(part); - queryString = query.toString(); + assertThat(query.toString(), is( getExpectedQuery("trs-specific-test-subclass-expected-to-set-value"))); } - /** - * To be used in conjunction with - * buildQueryForCreatesQueryForPropertyOnRelationShipReference() - */ @Test - public abstract void createsQueryForPropertyOnRelationShipReference(); - public void buildQueryForCreatesQueryForPropertyOnRelationShipReference() { + public void createsQueryForPropertyOnRelationShipReference() { Part part = new Part("group.name", Person.class); query.addRestriction(part); - queryString = query.toString(); + assertThat(query.toString(), is( getExpectedQuery("trs-specific-test-subclass-expected-to-set-value"))); } - /** - * To be used in conjunction with - * buildQueryForCreatesQueryForMultipleStartClauses() - */ @Test - public abstract void createsQueryForMultipleStartClauses(); - public void buildQueryForCreatesQueryForMultipleStartClauses() { + public void createsQueryForMultipleStartClauses() { query.addRestriction(new Part("name", Person.class)); query.addRestriction(new Part("group.name", Person.class)); - queryString = query.toString(); + assertThat(query.toString(), is( getExpectedQuery("trs-specific-test-subclass-expected-to-set-value"))); } - /** - * To be used in conjunction with - * buildQueryForCreatesSimpleWhereClauseCorrectly() - */ @Test - public abstract void createsSimpleWhereClauseCorrectly(); - public void buildQueryForCreatesSimpleWhereClauseCorrectly() { + public void createsSimpleWhereClauseCorrectly() { query.addRestriction(new Part("age", Person.class)); - queryString = query.toString(); + assertThat(query.toString(), is( getExpectedQuery("trs-specific-test-subclass-expected-to-set-value"))); } - /** - * To be used in conjunction with - * buildQueryForCreatesSimpleTraversalClauseCorrectly() - */ + @Test - public abstract void createsSimpleTraversalClauseCorrectly(); - public void buildQueryForCreatesSimpleTraversalClauseCorrectly() { + public void createsSimpleTraversalClauseCorrectly() { query.addRestriction(new Part("group", Person.class)); - queryString = query.toString(); + assertThat(query.toString(), is( getExpectedQuery("trs-specific-test-subclass-expected-to-set-value"))); } - /** - * To be used in conjunction with - * buildQueryForBuildsComplexQueryCorrectly() - */ + @Test - public abstract void buildsComplexQueryCorrectly(); - public void buildQueryForBuildsComplexQueryCorrectly() { + public void buildsComplexQueryCorrectly() { query.addRestriction(new Part("name", Person.class)); query.addRestriction(new Part("groupName", Person.class)); query.addRestriction(new Part("ageGreaterThan", Person.class)); query.addRestriction(new Part("groupMembersAge", Person.class)); - queryString = query.toString(); + assertThat(query.toString(), is( getExpectedQuery("trs-specific-test-subclass-expected-to-set-value"))); } - /** - * To be used in conjunction with - * buildQueryForBuildsQueryWithSort() - */ @Test - public abstract void buildsQueryWithSort(); - public void buildQueryForBuildsQueryWithSort() { + public void buildsQueryWithSort() { query.addRestriction(new Part("name",Person.class)); - queryString = query.buildQuery(new Sort("person.name")).toQueryString(); + String queryString = query.buildQuery(new Sort("person.name")).toQueryString(); + assertThat(queryString, is("START `person`=node:`Person`(`name`={0}) RETURN `person` ORDER BY person.name ASC")); } - /** - * To be used in conjunction with - * buildQueryForBuildsQueryWithSort() - */ @Test - public abstract void buildsQueryWithTwoSorts(); - public void buildQueryForBuildsQueryWithTwoSorts() { + public void buildsQueryWithTwoSorts() { query.addRestriction(new Part("name",Person.class)); Sort sort = new Sort(new Sort.Order("person.name"),new Sort.Order(Sort.Direction.DESC, "person.age")); - queryString = query.buildQuery(sort).toQueryString(); + String queryString = query.buildQuery(sort).toQueryString(); + assertThat(queryString, is("START `person`=node:`Person`(`name`={0}) RETURN `person` ORDER BY person.name ASC,person.age DESC")); } - /** - * To be used in conjunction with - * buildQueryForBuildsQueryWithSort() - */ @Test - public abstract void buildsQueryWithPage(); - public void buildQueryForBuildsQueryWithPage() { + public void buildsQueryWithPage() { query.addRestriction(new Part("name",Person.class)); Pageable pageable = new PageRequest(3,10,new Sort("person.name")); - queryString = query.buildQuery().toQueryString(pageable); + String queryString = query.buildQuery().toQueryString(pageable); + assertThat(queryString, is("START `person`=node:`Person`(`name`={0}) RETURN `person` ORDER BY person.name ASC SKIP 30 LIMIT 10")); } - /** - * To be used in conjunction with - * buildQueryForShouldFindByNodeEntityForIncomingRelationship() - */ @Test - public abstract void shouldFindByNodeEntity() throws Exception; - public void buildQueryForShouldFindByNodeEntity() throws Exception { + public void shouldFindByNodeEntity() throws Exception { query.addRestriction(new Part("pet", Person.class)); - queryString = query.toString(); + assertThat(query.toString(), is( getExpectedQuery("trs-specific-test-subclass-expected-to-set-value"))); + } + + @Test + public void shouldFindByNodeEntityForIncomingRelationship() { + query.addRestriction(new Part("group", Person.class)); + assertThat(query.toString(), is( getExpectedQuery("trs-specific-test-subclass-expected-to-set-value"))); } /** - * To be used in conjunction with - * buildQueryForShouldFindByNodeEntityForIncomingRelationship() + * This Abstract class defines the template for how to test, however + * gives subclasses an opportunity to override the expected query + * if it is different / specific for the TRS being used. + * This method will either return the trs specific query string if + * this was set, otherwise the default value passed in. */ - @Test - public abstract void shouldFindByNodeEntityForIncomingRelationship(); - public void buildQueryForShouldFindByNodeEntityForIncomingRelationship() { - query.addRestriction(new Part("group", Person.class)); - queryString = query.toString(); + private String getExpectedQuery(String defaultQueryString) { + return (this.trsSpecificExpectedQuery != null) + ? this.trsSpecificExpectedQuery + : defaultQueryString; } } diff --git a/spring-data-neo4j/src/test/java/org/springframework/data/neo4j/repository/query/AbstractDerivedFinderMethodTestBase.java b/spring-data-neo4j/src/test/java/org/springframework/data/neo4j/repository/query/AbstractDerivedFinderMethodTestBase.java index 8b0ea2fe5..6db8d6983 100644 --- a/spring-data-neo4j/src/test/java/org/springframework/data/neo4j/repository/query/AbstractDerivedFinderMethodTestBase.java +++ b/spring-data-neo4j/src/test/java/org/springframework/data/neo4j/repository/query/AbstractDerivedFinderMethodTestBase.java @@ -15,8 +15,8 @@ */ package org.springframework.data.neo4j.repository.query; +import org.junit.Before; import org.junit.Test; -import org.junit.runner.RunWith; import org.neo4j.index.lucene.ValueContext; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.neo4j.annotation.GraphId; @@ -31,15 +31,10 @@ import org.springframework.data.repository.query.DefaultParameters; import org.springframework.data.repository.query.Parameters; import org.springframework.data.repository.query.ParametersParameterAccessor; import org.springframework.data.repository.query.parser.Part; -import org.springframework.test.context.CleanContextCacheTestExecutionListener; -import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.TestExecutionListeners; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import org.springframework.test.context.support.DependencyInjectionTestExecutionListener; -import org.springframework.test.context.transaction.TransactionalTestExecutionListener; import org.springframework.transaction.annotation.Transactional; import java.lang.reflect.Method; +import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.Map; @@ -48,6 +43,14 @@ import java.util.concurrent.TimeUnit; import static java.util.Arrays.asList; import static org.junit.Assert.assertEquals; +/** + * Defines the tests for the various finder method based scenarios with + * expected results irrespective of which Type Representation Strategy (TRS) + * is being employed. Subclasses testing against specific TRS + * can overwrite expectations where they differ from the common approach. + * + * @author Oliver Gierke & Nicki Watt + */ public abstract class AbstractDerivedFinderMethodTestBase { @NodeEntity @@ -89,218 +92,319 @@ public abstract class AbstractDerivedFinderMethodTestBase { @Autowired Neo4jTemplate template; + @Before + public void setup() { + this.trsSpecificExpectedQuery = null; + this.trsSpecificExpectedParams = null; + } + + // Allow subclasses to provide specific expectations + protected String trsSpecificExpectedQuery; + protected Object[] trsSpecificExpectedParams; + @Test public void testCreateIndexQuery() throws Exception { CypherQueryBuilder builder = new CypherQueryBuilder(ctx, Thing.class, template); builder.addRestriction(new Part("firstName",Thing.class)); builder.addRestriction(new Part("lastName",Thing.class)); CypherQueryDefinition query = builder.buildQuery(); - assertEquals("START `thing`=node:`Thing`({0}) RETURN `thing`", query.toQueryString()); + assertEquals( + getExpectedQuery("START `thing`=node:`Thing`({0}) RETURN `thing`"), + query.toQueryString()); } @Test public void testQueryWithGraphId() throws Exception { - assertRepositoryQueryMethod(ThingRepository.class, "findById",new Object[]{123}, - "START `thing`=node({0})", - 123); + assertRepositoryQueryMethod(ThingRepository.class, + "findById", + new Object[]{123}, + getExpectedQuery("START `thing`=node({0})"), + getExpectedParams(123)); } @Test - public abstract void testQueryWithEntityGraphId() throws Exception; + public void testQueryWithEntityGraphId() throws Exception { + assertRepositoryQueryMethod(ThingRepository.class, + "findByOwnerId", + new Object[]{123}, + getExpectedQuery("this-should-def-be-overwritten-to-supply-trs-specific-query"), + getExpectedParams(123)); + } @Test public void testIndexQueryWithTwoParams() throws Exception { - assertRepositoryQueryMethod(ThingRepository.class, "findByFirstNameAndLastName",new Object[]{"foo", "bar"}, - "START `thing`=node:`Thing`({0})", - "firstName:foo AND lastName:bar"); + assertRepositoryQueryMethod(ThingRepository.class, + "findByFirstNameAndLastName", + new Object[]{"foo", "bar"}, + getExpectedQuery("START `thing`=node:`Thing`({0})"), + getExpectedParams("firstName:foo AND lastName:bar")); } @Test public void testIndexQueryWithOneParam() throws Exception { - assertRepositoryQueryMethod(ThingRepository.class, "findByFirstName",new Object[]{"foo"}, - "START `thing`=node:`Thing`(`firstName`={0})", - "foo"); + assertRepositoryQueryMethod(ThingRepository.class, + "findByFirstName", + new Object[]{"foo"}, + getExpectedQuery("START `thing`=node:`Thing`(`firstName`={0})"), + getExpectedParams("foo")); } @Test public void testIndexQueryWithOneParamFullText() throws Exception { - assertRepositoryQueryMethod(ThingRepository.class, "findByDescription", new Object[]{"foo"}, - "START `thing`=node:`search`({0})", - "description:foo"); + assertRepositoryQueryMethod(ThingRepository.class, + "findByDescription", + new Object[]{"foo"}, + getExpectedQuery("START `thing`=node:`search`({0})"), + getExpectedParams("description:foo")); } @Test public void testIndexQueryWithOneParamFullTextAndOneParam() throws Exception { - assertRepositoryQueryMethod(ThingRepository.class, "findByDescriptionAndFirstName", new Object[]{"foo","bar"}, - "START `thing`=node:`search`({0}) WHERE `thing`.`firstName` = {1}", - "description:foo","bar"); + assertRepositoryQueryMethod(ThingRepository.class, + "findByDescriptionAndFirstName", + new Object[]{"foo","bar"}, + getExpectedQuery("START `thing`=node:`search`({0}) WHERE `thing`.`firstName` = {1}"), + getExpectedParams("description:foo","bar")); } @Test public void testIndexQueryWithOneParamAndOneParamFullText() throws Exception { - assertRepositoryQueryMethod(ThingRepository.class, "findByFirstNameAndDescription", new Object[]{"foo","bar"}, - "START `thing`=node:`Thing`(`firstName`={0}) WHERE `thing`.`description` = {1}", - "foo","bar"); + assertRepositoryQueryMethod(ThingRepository.class, + "findByFirstNameAndDescription", + new Object[]{"foo","bar"}, + getExpectedQuery("START `thing`=node:`Thing`(`firstName`={0}) WHERE `thing`.`description` = {1}"), + getExpectedParams("foo","bar")); } @Test public void testIndexQueryWithOneNonIndexedParam() throws Exception { - assertRepositoryQueryMethod(ThingRepository.class, "findByAge", new Object[]{100}, - "WHERE `thing`.`age` = {0}", - 100); + assertRepositoryQueryMethod(ThingRepository.class, + "findByAge", new Object[]{100}, + getExpectedQuery("WHERE `thing`.`age` = {0}"), + getExpectedParams(100)); } @Test public void testIndexQueryWithOneNonIndexedParamAndOneIndexedParam() throws Exception { - assertRepositoryQueryMethod(ThingRepository.class, "findByAgeAndFirstName", new Object[]{100,"foo"}, - "START `thing`=node:`Thing`(`firstName`={1}) WHERE `thing`.`age` = {0}", - 100,"foo"); + assertRepositoryQueryMethod(ThingRepository.class, + "findByAgeAndFirstName", + new Object[]{100, "foo"}, + getExpectedQuery("START `thing`=node:`Thing`(`firstName`={1}) WHERE `thing`.`age` = {0}"), + getExpectedParams(100, "foo")); } @Test public void testIndexQueryWithLikeIndexedParam() throws Exception { - assertRepositoryQueryMethod(ThingRepository.class, "findByFirstNameLike", new Object[]{"foo"}, - "START `thing`=node:`Thing`({0})", - "firstName:foo"); + assertRepositoryQueryMethod(ThingRepository.class, + "findByFirstNameLike", + new Object[]{"foo"}, + getExpectedQuery("START `thing`=node:`Thing`({0})"), + getExpectedParams("firstName:foo")); } @Test public void testIndexQueryWithLikeIndexedParamWithSpaces() throws Exception { - assertRepositoryQueryMethod(ThingRepository.class, "findByFirstNameLike", new Object[]{"foo bar"}, - "START `thing`=node:`Thing`({0})", - "firstName:\"foo bar\""); + assertRepositoryQueryMethod(ThingRepository.class, + "findByFirstNameLike", + new Object[]{"foo bar"}, + getExpectedQuery("START `thing`=node:`Thing`({0})"), + getExpectedParams("firstName:\"foo bar\"")); } @Test public void testIndexQueryWithContainsIndexedParam() throws Exception { - assertRepositoryQueryMethod(ThingRepository.class, "findByFirstNameContains", new Object[]{"foo"}, - "START `thing`=node:`Thing`({0})", - "firstName:*foo*"); + assertRepositoryQueryMethod(ThingRepository.class, + "findByFirstNameContains", + new Object[]{"foo"}, + getExpectedQuery("START `thing`=node:`Thing`({0})"), + getExpectedParams("firstName:*foo*")); } @Test public void testIndexQueryWithStartsWithIndexedParam() throws Exception { - assertRepositoryQueryMethod(ThingRepository.class, "findByFirstNameStartsWith", new Object[]{"foo"}, - "START `thing`=node:`Thing`({0})", - "firstName:foo*"); + assertRepositoryQueryMethod(ThingRepository.class, + "findByFirstNameStartsWith", + new Object[]{"foo"}, + getExpectedQuery("START `thing`=node:`Thing`({0})"), + getExpectedParams("firstName:foo*")); } @Test public void testIndexQueryWithEndsWithIndexedParam() throws Exception { - assertRepositoryQueryMethod(ThingRepository.class, "findByFirstNameEndsWith", new Object[]{"foo"}, - "START `thing`=node:`Thing`({0})", - "firstName:*foo"); + assertRepositoryQueryMethod(ThingRepository.class, + "findByFirstNameEndsWith", + new Object[]{"foo"}, + getExpectedQuery("START `thing`=node:`Thing`({0})"), + getExpectedParams("firstName:*foo")); } @Test(expected = RepositoryQueryException.class) public void testFailIndexQueryWithStartsWithIndexedParamWithSpaces() throws Exception { - assertRepositoryQueryMethod(ThingRepository.class, "findByFirstNameStartsWith", new Object[]{"foo bar"}, - "START `thing`=node:`Thing`({0})"); + assertRepositoryQueryMethod(ThingRepository.class, + "findByFirstNameStartsWith", + new Object[]{"foo bar"}, + getExpectedQuery("START `thing`=node:`Thing`({0})")); } @Test public void testFindBySimpleStringParam() throws Exception { - assertRepositoryQueryMethod(ThingRepository.class, "findByName", new Object[]{"foo"}, - "WHERE `thing`.`name` = {0}", - "foo"); + assertRepositoryQueryMethod(ThingRepository.class, + "findByName", + new Object[]{"foo"}, + getExpectedQuery("WHERE `thing`.`name` = {0}"), + getExpectedParams("foo")); } @Test public void testFindBySimpleStringParamStartsWith() throws Exception { - assertRepositoryQueryMethod(ThingRepository.class, "findByNameStartsWith", new Object[]{"foo"}, - "WHERE `thing`.`name` =~ {0}", - "^foo.*"); + assertRepositoryQueryMethod(ThingRepository.class, + "findByNameStartsWith", + new Object[]{"foo"}, + getExpectedQuery("WHERE `thing`.`name` =~ {0}"), + getExpectedParams("^foo.*")); } @Test public void testFindBySimpleStringParamEndsWith() throws Exception { - assertRepositoryQueryMethod(ThingRepository.class, "findByNameEndsWith", new Object[]{"foo"}, - "WHERE `thing`.`name` =~ {0}", - ".*foo$"); + assertRepositoryQueryMethod(ThingRepository.class, + "findByNameEndsWith", + new Object[]{"foo"}, + getExpectedQuery("WHERE `thing`.`name` =~ {0}"), + getExpectedParams(".*foo$")); } @Test public void testFindBySimpleStringParamContains() throws Exception { - assertRepositoryQueryMethod(ThingRepository.class, "findByNameContains", new Object[]{"foo"}, - "WHERE `thing`.`name` =~ {0}", - ".*foo.*"); + assertRepositoryQueryMethod(ThingRepository.class, + "findByNameContains", + new Object[]{"foo"}, + getExpectedQuery("WHERE `thing`.`name` =~ {0}"), + getExpectedParams(".*foo.*")); } @Test public void testFindBySimpleStringParamLike() throws Exception { - assertRepositoryQueryMethod(ThingRepository.class, "findByNameLike", new Object[]{"foo"}, - "WHERE `thing`.`name` =~ {0}", - "foo"); + assertRepositoryQueryMethod(ThingRepository.class, + "findByNameLike", + new Object[]{"foo"}, + getExpectedQuery("WHERE `thing`.`name` =~ {0}"), + getExpectedParams("foo")); } @Test public void testFindBySimpleStringParamNotLike() throws Exception { - assertRepositoryQueryMethod(ThingRepository.class, "findByNameNotLike", new Object[]{"foo"}, - "WHERE not( `thing`.`name` =~ {0} )", - "foo"); + assertRepositoryQueryMethod(ThingRepository.class, + "findByNameNotLike", + new Object[]{"foo"}, + getExpectedQuery("WHERE not( `thing`.`name` =~ {0} )"), + getExpectedParams("foo")); } @Test public void testFindBySimpleStringParamRegexp() throws Exception { - assertRepositoryQueryMethod(ThingRepository.class, "findByNameMatches", new Object[]{"foo"}, - "WHERE `thing`.`name` =~ {0}", - "foo"); + assertRepositoryQueryMethod(ThingRepository.class, + "findByNameMatches", + new Object[]{"foo"}, + getExpectedQuery("WHERE `thing`.`name` =~ {0}"), + getExpectedParams("foo")); } @Test public void testFindBySimpleBooleanIsTrue() throws Exception { - assertRepositoryQueryMethod(ThingRepository.class, "findByTaggedIsTrue", new Object[]{}, - "WHERE `thing`.`tagged` = true"); + assertRepositoryQueryMethod(ThingRepository.class, + "findByTaggedIsTrue", new Object[]{}, + getExpectedQuery("WHERE `thing`.`tagged` = true")); } @Test public void testFindBySimpleBooleanIsFalse() throws Exception { - assertRepositoryQueryMethod(ThingRepository.class, "findByTaggedIsFalse", new Object[]{}, - "WHERE `thing`.`tagged` = false"); + assertRepositoryQueryMethod(ThingRepository.class, + "findByTaggedIsFalse", new Object[]{}, + getExpectedQuery("WHERE `thing`.`tagged` = false")); } @Test public void testFindBySimpleStringExists() throws Exception { - assertRepositoryQueryMethod(ThingRepository.class, "findByNameExists", new Object[]{}, - "WHERE has(`thing`.`name` )"); + assertRepositoryQueryMethod(ThingRepository.class, + "findByNameExists", new Object[]{}, + getExpectedQuery("WHERE has(`thing`.`name` )")); } @Test public void testFindBySimpleStringInCollection() throws Exception { List param = asList("foo"); - assertRepositoryQueryMethod(ThingRepository.class, "findByNameIn", new Object[]{param}, - "WHERE `thing`.`name` in {0}", - param); + assertRepositoryQueryMethod(ThingRepository.class, + "findByNameIn", new Object[]{param}, + getExpectedQuery("WHERE `thing`.`name` in {0}"), + getExpectedParams(param)); } @Test public void testFindBySimpleStringInCollectionOfEnums() throws Exception { List param = asList(TimeUnit.MINUTES); - assertRepositoryQueryMethod(ThingRepository.class, "findByNameIn", new Object[]{param}, - "WHERE `thing`.`name` in {0}", - param); + assertRepositoryQueryMethod(ThingRepository.class, + "findByNameIn", new Object[]{param}, + getExpectedQuery("WHERE `thing`.`name` in {0}"), + getExpectedParams(param)); } @Test public void testFindBySimpleStringNotInCollection() throws Exception { List param = asList("foo"); - assertRepositoryQueryMethod(ThingRepository.class, "findByNameNotIn", new Object[]{param}, - "WHERE not( `thing`.`name` in {0} )", - param); + assertRepositoryQueryMethod(ThingRepository.class, + "findByNameNotIn", new Object[]{param}, + getExpectedQuery("WHERE not( `thing`.`name` in {0} )"), + getExpectedParams(param)); } @Test public void testFindBySimpleDateBefore() throws Exception { Date param = new Date(1337); - assertRepositoryQueryMethod(ThingRepository.class, "findByBornBefore", new Object[]{param}, - "WHERE `thing`.`born` < {0}", - param.getTime()); + assertRepositoryQueryMethod(ThingRepository.class, + "findByBornBefore", new Object[]{param}, + getExpectedQuery("WHERE `thing`.`born` < {0}"), + getExpectedParams(param.getTime())); } @Test public void testFindBySimpleDateAfter() throws Exception { Date param = new Date(1337); - assertRepositoryQueryMethod(ThingRepository.class, "findByBornAfter", new Object[]{param}, - "WHERE `thing`.`born` > {0}", - param.getTime()); + assertRepositoryQueryMethod(ThingRepository.class, + "findByBornAfter", new Object[]{param}, + getExpectedQuery("WHERE `thing`.`born` > {0}"), + getExpectedParams(param.getTime())); } @Test public void testFindByNumericIndexedField() throws Exception { - assertRepositoryQueryMethod(ThingRepository.class, "findByNumber", new Object[]{10}, - "START `thing`=node:`Thing`(`number`={0})", - ValueContext.numeric(10)); + assertRepositoryQueryMethod(ThingRepository.class, + "findByNumber", new Object[]{10}, + getExpectedQuery("START `thing`=node:`Thing`(`number`={0})"), + getExpectedParams(ValueContext.numeric(10))); + } + + @Test + @Transactional + public void testMultipleIndexedFields() throws Exception { + Thing thing = repository.save(new Thing("John", "Doe")); + assertEquals(thing.id, repository.findByFirstNameAndLastName("John", "Doe").id); + } + + /** + * This Abstract class defines the template for how to test, however + * gives subclasses an opportunity to override the expected query + * if it is different / specific for the TRS being used. + * This method will either return the trs specific query string if + * this was set, otherwise the default value passed in. + */ + private String getExpectedQuery(String defaultQueryString) { + return (this.trsSpecificExpectedQuery != null) + ? this.trsSpecificExpectedQuery + : defaultQueryString; + } + + /** + * This Abstract class defines the template for how to test, however + * gives subclasses an opportunity to override the expected params + * if it is different / specific for the TRS being used. + * This method will either return the trs specific query params if + * this was set, otherwise the default value passed in. + */ + private Object[] getExpectedParams(Object... defaultVals) { + return (this.trsSpecificExpectedParams != null) + ? this.trsSpecificExpectedParams + : (defaultVals == null) ? new Object[0] : defaultVals; } protected void assertRepositoryQueryMethod(Class repositoryClass, String methodName, Object[] paramValues, String expectedQuery, Object...expectedParam) { @@ -328,11 +432,4 @@ public abstract class AbstractDerivedFinderMethodTestBase { } throw new NoSuchMethodError("Method "+methodName+" not found in "+repositoryClass); } - - @Test - @Transactional - public void testMultipleIndexedFields() throws Exception { - Thing thing = repository.save(new Thing("John", "Doe")); - assertEquals(thing.id, repository.findByFirstNameAndLastName("John", "Doe").id); - } } diff --git a/spring-data-neo4j/src/test/java/org/springframework/data/neo4j/repository/query/CypherQueryBuilderForIndexBasedTRSUnitTests.java b/spring-data-neo4j/src/test/java/org/springframework/data/neo4j/repository/query/CypherQueryBuilderForIndexBasedTRSUnitTests.java index 12bf7a9aa..636199c6b 100644 --- a/spring-data-neo4j/src/test/java/org/springframework/data/neo4j/repository/query/CypherQueryBuilderForIndexBasedTRSUnitTests.java +++ b/spring-data-neo4j/src/test/java/org/springframework/data/neo4j/repository/query/CypherQueryBuilderForIndexBasedTRSUnitTests.java @@ -43,123 +43,86 @@ public class CypherQueryBuilderForIndexBasedTRSUnitTests extends AbstractCypherQ return Mockito.mock(IndexBasedNodeTypeRepresentationStrategy.class); } - @Override - @Test - public void createsQueryForSimplePropertyReference() { - buildQueryForCreatesQueryForSimplePropertyReference(); - assertThat(queryString, - is("START `person`=node:`Person`(`name`={0}) RETURN `person`")); - } - - @Override - @Test - public void createsQueryForLikePropertyIndex() { - buildQueryForCreatesQueryForLikePropertyIndex(); - assertThat(queryString, is("START `person`=node:`title`({0}) RETURN `person`")); - } - @Override @Test public void createsQueryForLikeProperty() { - buildQueryForCreatesQueryForLikeProperty(); - assertThat(queryString, is(DEFAULT_START_CLAUSE+" WHERE `person`.`info` =~ {0} RETURN `person`")); + this.trsSpecificExpectedQuery = DEFAULT_START_CLAUSE+" WHERE `person`.`info` =~ {0} RETURN `person`"; + super.createsQueryForLikeProperty(); } @Override @Test public void createsQueryForGreaterThanPropertyReference() { - buildQueryForCreatesQueryForGreaterThanPropertyReference(); - assertThat(queryString, is(DEFAULT_START_CLAUSE+" WHERE `person`.`age` > {0} RETURN `person`")); + this.trsSpecificExpectedQuery = DEFAULT_START_CLAUSE+" WHERE `person`.`age` > {0} RETURN `person`"; + super.createsQueryForGreaterThanPropertyReference(); } @Override @Test public void createsQueryForTwoPropertyExpressions() { - buildQueryForCreatesQueryForTwoPropertyExpressions(); - assertThat(queryString, is(DEFAULT_START_CLAUSE+" WHERE `person`.`age` > {0} AND `person`.`info` = {1} RETURN `person`")); + this.trsSpecificExpectedQuery = DEFAULT_START_CLAUSE+" WHERE `person`.`age` > {0} AND `person`.`info` = {1} RETURN `person`"; + super.createsQueryForTwoPropertyExpressions(); } @Override @Test public void createsQueryForIsNullPropertyReference() { - buildQueryForCreatesQueryForIsNullPropertyReference(); - assertThat(queryString, is(DEFAULT_START_CLAUSE+" WHERE `person`.`age` is null RETURN `person`")); + this.trsSpecificExpectedQuery = DEFAULT_START_CLAUSE+" WHERE `person`.`age` is null RETURN `person`"; + super.createsQueryForIsNullPropertyReference(); } @Override @Test public void createsQueryForPropertyOnRelationShipReference() { - buildQueryForCreatesQueryForPropertyOnRelationShipReference(); - assertThat(queryString, is("START `person_group`=node:`Group`(`name`={0}) MATCH `person`<-[:`members`]-`person_group` RETURN `person`")); + this.trsSpecificExpectedQuery = "START `person_group`=node:`Group`(`name`={0}) MATCH `person`<-[:`members`]-`person_group` RETURN `person`"; + super.createsQueryForPropertyOnRelationShipReference(); } @Override @Test public void createsQueryForMultipleStartClauses() { - buildQueryForCreatesQueryForMultipleStartClauses(); - assertThat(queryString, - is("START `person`=node:`Person`(`name`={0}), `person_group`=node:`Group`(`name`={1}) MATCH `person`<-[:`members`]-`person_group` RETURN `person`")); + this.trsSpecificExpectedQuery = "START `person`=node:`Person`(`name`={0}), `person_group`=node:`Group`(`name`={1}) MATCH `person`<-[:`members`]-`person_group` RETURN `person`"; + super.createsQueryForMultipleStartClauses(); } @Override @Test public void createsSimpleWhereClauseCorrectly() { - buildQueryForCreatesSimpleWhereClauseCorrectly(); - assertThat(queryString, is(DEFAULT_START_CLAUSE +" WHERE `person`.`age` = {0} RETURN `person`")); + this.trsSpecificExpectedQuery = DEFAULT_START_CLAUSE +" WHERE `person`.`age` = {0} RETURN `person`"; + super.createsSimpleWhereClauseCorrectly(); } @Override @Test public void createsSimpleTraversalClauseCorrectly() { - buildQueryForCreatesSimpleTraversalClauseCorrectly(); - assertThat(queryString, is("START `person_group`=node({0}) MATCH `person`<-[:`members`]-`person_group` WHERE `person`.__type__ IN ['Person'] RETURN `person`")); + this.trsSpecificExpectedQuery = "START `person_group`=node({0}) MATCH `person`<-[:`members`]-`person_group` WHERE `person`.__type__ IN ['Person'] RETURN `person`"; + super.createsSimpleTraversalClauseCorrectly(); } @Override @Test public void buildsComplexQueryCorrectly() { - buildQueryForBuildsComplexQueryCorrectly(); - assertThat(queryString, is( - "START `person`=node:`Person`(`name`={0}), `person_group`=node:`Group`(`name`={1}) " + + this.trsSpecificExpectedQuery = + "START `person`=node:`Person`(`name`={0}), `person_group`=node:`Group`(`name`={1}) " + "MATCH `person`<-[:`members`]-`person_group`, `person`<-[:`members`]-`person_group`-[:`members`]->`person_group_members` " + "WHERE `person`.`age` > {2} AND `person_group_members`.`age` = {3} " + - "RETURN `person`" - )); + "RETURN `person`"; + super.buildsComplexQueryCorrectly(); } - @Override - @Test - public void buildsQueryWithSort() { - buildQueryForBuildsQueryWithSort(); - assertThat(queryString, is("START `person`=node:`Person`(`name`={0}) RETURN `person` ORDER BY person.name ASC")); - } - - @Override - @Test - public void buildsQueryWithTwoSorts() { - buildQueryForBuildsQueryWithTwoSorts(); - assertThat(queryString, is("START `person`=node:`Person`(`name`={0}) RETURN `person` ORDER BY person.name ASC,person.age DESC")); - } - - @Override - @Test - public void buildsQueryWithPage() { - buildQueryForBuildsQueryWithPage(); - assertThat(queryString, is("START `person`=node:`Person`(`name`={0}) RETURN `person` ORDER BY person.name ASC SKIP 30 LIMIT 10")); - } @Override @Test public void shouldFindByNodeEntity() throws Exception { - buildQueryForShouldFindByNodeEntity(); - assertThat(queryString, is("START `person_pet`=node({0}) MATCH `person`-[:`owns`]->`person_pet` WHERE `person`.__type__ IN ['Person'] RETURN `person`")); + this.trsSpecificExpectedQuery = "START `person_pet`=node({0}) MATCH `person`-[:`owns`]->`person_pet` WHERE `person`.__type__ IN ['Person'] RETURN `person`"; + super.shouldFindByNodeEntity(); } @Override @Test public void shouldFindByNodeEntityForIncomingRelationship() { - buildQueryForShouldFindByNodeEntityForIncomingRelationship(); - assertThat(queryString, is("START `person_group`=node({0}) MATCH `person`<-[:`members`]-`person_group` WHERE `person`.__type__ IN ['Person'] RETURN `person`")); + this.trsSpecificExpectedQuery = "START `person_group`=node({0}) MATCH `person`<-[:`members`]-`person_group` WHERE `person`.__type__ IN ['Person'] RETURN `person`"; + super.shouldFindByNodeEntityForIncomingRelationship(); } diff --git a/spring-data-neo4j/src/test/java/org/springframework/data/neo4j/repository/query/CypherQueryBuilderForLabelBasedTRSUnitTests.java b/spring-data-neo4j/src/test/java/org/springframework/data/neo4j/repository/query/CypherQueryBuilderForLabelBasedTRSUnitTests.java index f47a7f4c6..cfbec05c6 100644 --- a/spring-data-neo4j/src/test/java/org/springframework/data/neo4j/repository/query/CypherQueryBuilderForLabelBasedTRSUnitTests.java +++ b/spring-data-neo4j/src/test/java/org/springframework/data/neo4j/repository/query/CypherQueryBuilderForLabelBasedTRSUnitTests.java @@ -32,7 +32,7 @@ import static org.junit.Assert.assertThat; */ public class CypherQueryBuilderForLabelBasedTRSUnitTests extends AbstractCypherQueryBuilderTestBase { - private final static String DEFAULT_START_CLAUSE = " MATCH `person`:`" + CLASS_NAME + "`"; + private final static String DEFAULT_MATCH_STARTING_CLAUSE = " MATCH `person`:`" + CLASS_NAME + "`"; @Before public void setUp() { @@ -43,127 +43,92 @@ public class CypherQueryBuilderForLabelBasedTRSUnitTests extends AbstractCypherQ return Mockito.mock(LabelBasedNodeTypeRepresentationStrategy.class); } - @Override - @Test - public void createsQueryForSimplePropertyReference() { - buildQueryForCreatesQueryForSimplePropertyReference(); - assertThat(queryString, - is("START `person`=node:`Person`(`name`={0}) RETURN `person`")); - } - - @Override - @Test - public void createsQueryForLikePropertyIndex() { - buildQueryForCreatesQueryForLikePropertyIndex(); - assertThat(queryString, is("START `person`=node:`title`({0}) RETURN `person`")); - } - @Override @Test public void createsQueryForLikeProperty() { - buildQueryForCreatesQueryForLikeProperty(); - assertThat(queryString, is(DEFAULT_START_CLAUSE+" WHERE `person`.`info` =~ {0} RETURN `person`")); + this.trsSpecificExpectedQuery = DEFAULT_MATCH_STARTING_CLAUSE +" WHERE `person`.`info` =~ {0} RETURN `person`"; + super.createsQueryForLikeProperty(); } @Override @Test public void createsQueryForGreaterThanPropertyReference() { - buildQueryForCreatesQueryForGreaterThanPropertyReference(); - assertThat(queryString, is(DEFAULT_START_CLAUSE+" WHERE `person`.`age` > {0} RETURN `person`")); + this.trsSpecificExpectedQuery = DEFAULT_MATCH_STARTING_CLAUSE +" WHERE `person`.`age` > {0} RETURN `person`"; + super.createsQueryForGreaterThanPropertyReference(); } @Override @Test public void createsQueryForTwoPropertyExpressions() { - buildQueryForCreatesQueryForTwoPropertyExpressions(); - assertThat(queryString, is(DEFAULT_START_CLAUSE+" WHERE `person`.`age` > {0} AND `person`.`info` = {1} RETURN `person`")); + this.trsSpecificExpectedQuery = DEFAULT_MATCH_STARTING_CLAUSE +" WHERE `person`.`age` > {0} AND `person`.`info` = {1} RETURN `person`"; + super.createsQueryForTwoPropertyExpressions(); } @Override @Test public void createsQueryForIsNullPropertyReference() { - buildQueryForCreatesQueryForIsNullPropertyReference(); - assertThat(queryString, is(DEFAULT_START_CLAUSE+" WHERE `person`.`age` is null RETURN `person`")); + this.trsSpecificExpectedQuery = DEFAULT_MATCH_STARTING_CLAUSE +" WHERE `person`.`age` is null RETURN `person`"; + super.createsQueryForIsNullPropertyReference(); } @Override @Test public void createsQueryForPropertyOnRelationShipReference() { - buildQueryForCreatesQueryForPropertyOnRelationShipReference(); - assertThat(queryString, is("START `person_group`=node:`Group`(`name`={0}) MATCH `person`<-[:`members`]-`person_group` RETURN `person`")); + this.trsSpecificExpectedQuery = "START `person_group`=node:`Group`(`name`={0}) MATCH `person`<-[:`members`]-`person_group` RETURN `person`"; + super.createsQueryForPropertyOnRelationShipReference(); } @Override @Test public void createsQueryForMultipleStartClauses() { - buildQueryForCreatesQueryForMultipleStartClauses(); - assertThat(queryString, - is("START `person`=node:`Person`(" + + this.trsSpecificExpectedQuery = + "START `person`=node:`Person`(" + "`name`={0}), " + "`person_group`=node:" + "`Group`(`name`={1}) " + "MATCH `person`<-[:`members`]-`person_group` " + - "RETURN `person`")); + "RETURN `person`"; + super.createsQueryForMultipleStartClauses(); } @Override @Test public void createsSimpleWhereClauseCorrectly() { - buildQueryForCreatesSimpleWhereClauseCorrectly(); - assertThat(queryString, is(DEFAULT_START_CLAUSE +" WHERE `person`.`age` = {0} RETURN `person`")); + this.trsSpecificExpectedQuery = DEFAULT_MATCH_STARTING_CLAUSE +" WHERE `person`.`age` = {0} RETURN `person`"; + super.createsSimpleWhereClauseCorrectly(); } @Override @Test public void createsSimpleTraversalClauseCorrectly() { - buildQueryForCreatesSimpleTraversalClauseCorrectly(); - assertThat(queryString, is("START `person_group`=node({0}) MATCH `person`<-[:`members`]-`person_group` WHERE `person`:`Person` RETURN `person`")); + this.trsSpecificExpectedQuery = "START `person_group`=node({0}) MATCH `person`<-[:`members`]-`person_group` WHERE `person`:`Person` RETURN `person`"; + super.createsSimpleTraversalClauseCorrectly(); } @Override @Test public void buildsComplexQueryCorrectly() { - buildQueryForBuildsComplexQueryCorrectly(); - assertThat(queryString, is( + this.trsSpecificExpectedQuery = "START `person`=node:`Person`(`name`={0}), `person_group`=node:`Group`(`name`={1}) " + "MATCH `person`<-[:`members`]-`person_group`, `person`<-[:`members`]-`person_group`-[:`members`]->`person_group_members` " + "WHERE `person`.`age` > {2} AND `person_group_members`.`age` = {3} " + - "RETURN `person`" - )); - } + "RETURN `person`"; + super.buildsComplexQueryCorrectly(); - @Override - @Test - public void buildsQueryWithSort() { - buildQueryForBuildsQueryWithSort(); - assertThat(queryString, is("START `person`=node:`Person`(`name`={0}) RETURN `person` ORDER BY person.name ASC")); - } - - @Override - @Test - public void buildsQueryWithTwoSorts() { - buildQueryForBuildsQueryWithTwoSorts(); - assertThat(queryString, is("START `person`=node:`Person`(`name`={0}) RETURN `person` ORDER BY person.name ASC,person.age DESC")); - } - - @Override - @Test - public void buildsQueryWithPage() { - buildQueryForBuildsQueryWithPage(); - assertThat(queryString, is("START `person`=node:`Person`(`name`={0}) RETURN `person` ORDER BY person.name ASC SKIP 30 LIMIT 10")); } @Override @Test public void shouldFindByNodeEntity() throws Exception { - buildQueryForShouldFindByNodeEntity(); - assertThat(queryString, is("START `person_pet`=node({0}) MATCH `person`-[:`owns`]->`person_pet` WHERE `person`:`Person` RETURN `person`")); + this.trsSpecificExpectedQuery = "START `person_pet`=node({0}) MATCH `person`-[:`owns`]->`person_pet` WHERE `person`:`Person` RETURN `person`"; + super.shouldFindByNodeEntity(); } @Override @Test public void shouldFindByNodeEntityForIncomingRelationship() { - buildQueryForShouldFindByNodeEntityForIncomingRelationship(); - assertThat(queryString, is("START `person_group`=node({0}) MATCH `person`<-[:`members`]-`person_group` WHERE `person`:`Person` RETURN `person`")); + this.trsSpecificExpectedQuery = "START `person_group`=node({0}) MATCH `person`<-[:`members`]-`person_group` WHERE `person`:`Person` RETURN `person`"; + super.shouldFindByNodeEntityForIncomingRelationship(); } + } diff --git a/spring-data-neo4j/src/test/java/org/springframework/data/neo4j/repository/query/DerivedFinderMethodForIndexedBasedTRSTests.java b/spring-data-neo4j/src/test/java/org/springframework/data/neo4j/repository/query/DerivedFinderMethodForIndexedBasedTRSTests.java index de8c42b49..15b7c7c26 100644 --- a/spring-data-neo4j/src/test/java/org/springframework/data/neo4j/repository/query/DerivedFinderMethodForIndexedBasedTRSTests.java +++ b/spring-data-neo4j/src/test/java/org/springframework/data/neo4j/repository/query/DerivedFinderMethodForIndexedBasedTRSTests.java @@ -47,6 +47,7 @@ public class DerivedFinderMethodForIndexedBasedTRSTests extends AbstractDerivedF @Before public void setup() { + super.setup(); assertThat("The tests in this class should be configured to use the Label " + "based Type Representation Strategy, however it is not ... ", strategy, instanceOf(IndexBasedNodeTypeRepresentationStrategy.class)); @@ -55,9 +56,9 @@ public class DerivedFinderMethodForIndexedBasedTRSTests extends AbstractDerivedF @Test @Override public void testQueryWithEntityGraphId() throws Exception { - assertRepositoryQueryMethod(ThingRepository.class, "findByOwnerId",new Object[]{123}, - "START `thing_owner`=node({0}) MATCH `thing`-[:`owner`]->`thing_owner` WHERE `thing`.__type__ IN ['org.springframework.data.neo4j.repository.query.AbstractDerivedFinderMethodTestBase$Thing'] ", - 123); + this.trsSpecificExpectedQuery = "START `thing_owner`=node({0}) MATCH `thing`-[:`owner`]->`thing_owner` WHERE `thing`.__type__ IN ['org.springframework.data.neo4j.repository.query.AbstractDerivedFinderMethodTestBase$Thing'] "; + this.trsSpecificExpectedParams = new Object[] { 123 }; + super.testQueryWithEntityGraphId(); } } diff --git a/spring-data-neo4j/src/test/java/org/springframework/data/neo4j/repository/query/DerivedFinderMethodForLabelBasedTRSTests.java b/spring-data-neo4j/src/test/java/org/springframework/data/neo4j/repository/query/DerivedFinderMethodForLabelBasedTRSTests.java index 7e537f7c3..b267446a9 100644 --- a/spring-data-neo4j/src/test/java/org/springframework/data/neo4j/repository/query/DerivedFinderMethodForLabelBasedTRSTests.java +++ b/spring-data-neo4j/src/test/java/org/springframework/data/neo4j/repository/query/DerivedFinderMethodForLabelBasedTRSTests.java @@ -47,6 +47,7 @@ public class DerivedFinderMethodForLabelBasedTRSTests extends AbstractDerivedFin @Before public void setup() { + super.setup(); assertThat("The tests in this class should be configured to use the Label " + "based Type Representation Strategy, however it is not ... ", strategy, instanceOf(LabelBasedNodeTypeRepresentationStrategy.class)); @@ -55,8 +56,8 @@ public class DerivedFinderMethodForLabelBasedTRSTests extends AbstractDerivedFin @Test @Override public void testQueryWithEntityGraphId() throws Exception { - assertRepositoryQueryMethod(ThingRepository.class, "findByOwnerId",new Object[]{123}, - "START `thing_owner`=node({0}) MATCH `thing`-[:`owner`]->`thing_owner` WHERE `thing`:`org.springframework.data.neo4j.repository.query.AbstractDerivedFinderMethodTestBase$Thing` ", - 123); + this.trsSpecificExpectedQuery = "START `thing_owner`=node({0}) MATCH `thing`-[:`owner`]->`thing_owner` WHERE `thing`:`org.springframework.data.neo4j.repository.query.AbstractDerivedFinderMethodTestBase$Thing` "; + this.trsSpecificExpectedParams = new Object[] { 123 }; + super.testQueryWithEntityGraphId(); } }