Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
HSEARCH-3958 Use as much shared code as possible to test the spatial-…
…within-circle predicate
- Loading branch information
Showing
8 changed files
with
414 additions
and
447 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
307 changes: 307 additions & 0 deletions
307
...arch/integrationtest/backend/tck/search/predicate/SpatialWithinCirclePredicateBaseIT.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,307 @@ | ||
/* | ||
* Hibernate Search, full-text search for your domain model | ||
* | ||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later | ||
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>. | ||
*/ | ||
package org.hibernate.search.integrationtest.backend.tck.search.predicate; | ||
|
||
import static org.assertj.core.api.Assertions.assertThatThrownBy; | ||
|
||
import java.util.ArrayList; | ||
import java.util.List; | ||
|
||
import org.hibernate.search.engine.search.predicate.dsl.PredicateFinalStep; | ||
import org.hibernate.search.engine.search.predicate.dsl.SearchPredicateFactory; | ||
import org.hibernate.search.engine.spatial.GeoPoint; | ||
import org.hibernate.search.integrationtest.backend.tck.testsupport.types.FieldTypeDescriptor; | ||
import org.hibernate.search.integrationtest.backend.tck.testsupport.types.GeoPointFieldTypeDescriptor; | ||
import org.hibernate.search.integrationtest.backend.tck.testsupport.util.rule.SearchSetupHelper; | ||
import org.hibernate.search.util.impl.integrationtest.mapper.stub.BulkIndexer; | ||
import org.hibernate.search.util.impl.integrationtest.mapper.stub.SimpleMappedIndex; | ||
|
||
import org.junit.AssumptionViolatedException; | ||
import org.junit.BeforeClass; | ||
import org.junit.ClassRule; | ||
import org.junit.Test; | ||
import org.junit.experimental.runners.Enclosed; | ||
import org.junit.runner.RunWith; | ||
import org.junit.runners.Parameterized; | ||
|
||
@RunWith(Enclosed.class) | ||
public class SpatialWithinCirclePredicateBaseIT { | ||
|
||
private static final GeoPointFieldTypeDescriptor supportedFieldType; | ||
private static final List<FieldTypeDescriptor<GeoPoint>> supportedFieldTypes = new ArrayList<>(); | ||
private static final List<FieldTypeDescriptor<?>> unsupportedFieldTypes = new ArrayList<>(); | ||
static { | ||
supportedFieldType = GeoPointFieldTypeDescriptor.INSTANCE; | ||
supportedFieldTypes.add( supportedFieldType ); | ||
for ( FieldTypeDescriptor<?> fieldType : FieldTypeDescriptor.getAll() ) { | ||
if ( !supportedFieldType.equals( fieldType ) ) { | ||
unsupportedFieldTypes.add( fieldType ); | ||
} | ||
} | ||
} | ||
|
||
@ClassRule | ||
public static SearchSetupHelper setupHelper = new SearchSetupHelper(); | ||
|
||
@BeforeClass | ||
public static void setup() { | ||
setupHelper.start() | ||
.withIndexes( | ||
SingleFieldIT.index, MultiFieldIT.index, | ||
ScoreIT.index, | ||
InvalidFieldIT.index, UnsupportedTypeIT.index, | ||
SearchableIT.searchableYesIndex, SearchableIT.searchableNoIndex, | ||
ArgumentCheckingIT.index | ||
) | ||
.setup(); | ||
|
||
final BulkIndexer singleFieldIndexer = SingleFieldIT.index.bulkIndexer(); | ||
SingleFieldIT.dataSet.contribute( SingleFieldIT.index, singleFieldIndexer ); | ||
|
||
final BulkIndexer multiFieldIndexer = MultiFieldIT.index.bulkIndexer(); | ||
MultiFieldIT.dataSet.contribute( MultiFieldIT.index, multiFieldIndexer ); | ||
|
||
final BulkIndexer scoreIndexer = ScoreIT.index.bulkIndexer(); | ||
ScoreIT.dataSet.contribute( ScoreIT.index, scoreIndexer ); | ||
|
||
singleFieldIndexer.join( | ||
multiFieldIndexer, | ||
scoreIndexer | ||
); | ||
} | ||
|
||
private static SpatialWithinCirclePredicateTestValues testValues() { | ||
return new SpatialWithinCirclePredicateTestValues(); | ||
} | ||
|
||
@Test | ||
public void takariCpSuiteWorkaround() { | ||
// Workaround to get Takari-CPSuite to run this test. | ||
} | ||
|
||
public static class SingleFieldIT extends AbstractPredicateSingleFieldIT<SpatialWithinCirclePredicateTestValues> { | ||
private static final DataSet<GeoPoint, SpatialWithinCirclePredicateTestValues> dataSet = new DataSet<>( testValues() ); | ||
|
||
private static final SimpleMappedIndex<IndexBinding> index = | ||
SimpleMappedIndex.of( root -> new IndexBinding( root, supportedFieldTypes ) ) | ||
.name( "singleField" ); | ||
|
||
public SingleFieldIT() { | ||
super( index, dataSet ); | ||
} | ||
|
||
@Override | ||
protected PredicateFinalStep predicate(SearchPredicateFactory f, String fieldPath, int matchingDocOrdinal) { | ||
return f.spatial().within().field( fieldPath ) | ||
.circle( dataSet.values.matchingCenter( matchingDocOrdinal ), | ||
dataSet.values.matchingRadius( matchingDocOrdinal ) ); | ||
} | ||
} | ||
|
||
public static class MultiFieldIT extends AbstractPredicateMultiFieldIT<SpatialWithinCirclePredicateTestValues> { | ||
private static final DataSet<GeoPoint, SpatialWithinCirclePredicateTestValues> dataSet = new DataSet<>( testValues() ); | ||
|
||
private static final SimpleMappedIndex<IndexBinding> index = | ||
SimpleMappedIndex.of( root -> new IndexBinding( root, supportedFieldTypes ) ) | ||
.name( "multiField" ); | ||
|
||
public MultiFieldIT() { | ||
super( index, dataSet ); | ||
} | ||
|
||
@Override | ||
protected PredicateFinalStep predicateOnFieldAndField(SearchPredicateFactory f, String fieldPath, | ||
String otherFieldPath, int matchingDocOrdinal) { | ||
return f.spatial().within().field( fieldPath ).field( otherFieldPath ) | ||
.circle( dataSet.values.matchingCenter( matchingDocOrdinal ), | ||
dataSet.values.matchingRadius( matchingDocOrdinal ) ); | ||
} | ||
|
||
@Override | ||
protected PredicateFinalStep predicateOnFields(SearchPredicateFactory f, String[] fieldPaths, int matchingDocOrdinal) { | ||
return f.spatial().within().fields( fieldPaths ) | ||
.circle( dataSet.values.matchingCenter( matchingDocOrdinal ), | ||
dataSet.values.matchingRadius( matchingDocOrdinal ) ); | ||
} | ||
|
||
@Override | ||
protected PredicateFinalStep predicateOnFieldAndFields(SearchPredicateFactory f, String fieldPath, | ||
String[] fieldPaths, int matchingDocOrdinal) { | ||
return f.spatial().within().field( fieldPath ).fields( fieldPaths ) | ||
.circle( dataSet.values.matchingCenter( matchingDocOrdinal ), | ||
dataSet.values.matchingRadius( matchingDocOrdinal ) ); | ||
} | ||
} | ||
|
||
public static class ScoreIT extends AbstractPredicateFieldScoreIT<SpatialWithinCirclePredicateTestValues> { | ||
private static final DataSet<GeoPoint, SpatialWithinCirclePredicateTestValues> dataSet = new DataSet<>( testValues() ); | ||
|
||
private static final SimpleMappedIndex<IndexBinding> index = | ||
SimpleMappedIndex.of( root -> new IndexBinding( root, supportedFieldTypes ) ) | ||
.name( "score" ); | ||
|
||
public ScoreIT() { | ||
super( index, dataSet ); | ||
} | ||
|
||
@Override | ||
protected PredicateFinalStep predicate(SearchPredicateFactory f, String fieldPath, int matchingDocOrdinal) { | ||
return f.spatial().within().field( fieldPath ) | ||
.circle( dataSet.values.matchingCenter( matchingDocOrdinal ), | ||
dataSet.values.matchingRadius( matchingDocOrdinal ) ); | ||
} | ||
|
||
@Override | ||
protected PredicateFinalStep predicateWithConstantScore(SearchPredicateFactory f, String[] fieldPaths, | ||
int matchingDocOrdinal) { | ||
throw scoreIsAlwaysConstant(); | ||
} | ||
|
||
@Override | ||
protected PredicateFinalStep predicateWithPredicateLevelBoost(SearchPredicateFactory f, String[] fieldPaths, | ||
int matchingDocOrdinal, float predicateBoost) { | ||
return f.spatial().within().fields( fieldPaths ) | ||
.circle( dataSet.values.matchingCenter( matchingDocOrdinal ), | ||
dataSet.values.matchingRadius( matchingDocOrdinal ) ) | ||
.boost( predicateBoost ); | ||
} | ||
|
||
@Override | ||
protected PredicateFinalStep predicateWithConstantScoreAndPredicateLevelBoost(SearchPredicateFactory f, | ||
String[] fieldPaths, int matchingDocOrdinal, float predicateBoost) { | ||
throw scoreIsAlwaysConstant(); | ||
} | ||
|
||
@Override | ||
protected PredicateFinalStep predicateWithFieldLevelBoost(SearchPredicateFactory f, String fieldPath, | ||
float fieldBoost, int matchingDocOrdinal) { | ||
return f.spatial().within().field( fieldPath ).boost( fieldBoost ) | ||
.circle( dataSet.values.matchingCenter( matchingDocOrdinal ), | ||
dataSet.values.matchingRadius( matchingDocOrdinal ) ); | ||
} | ||
|
||
@Override | ||
protected PredicateFinalStep predicateWithFieldLevelBoostAndConstantScore(SearchPredicateFactory f, | ||
String fieldPath, float fieldBoost, int matchingDocOrdinal) { | ||
throw scoreIsAlwaysConstant(); | ||
} | ||
|
||
@Override | ||
protected PredicateFinalStep predicateWithFieldLevelBoostAndPredicateLevelBoost(SearchPredicateFactory f, | ||
String fieldPath, float fieldBoost, int matchingDocOrdinal, float predicateBoost) { | ||
return f.spatial().within().field( fieldPath ).boost( fieldBoost ) | ||
.circle( dataSet.values.matchingCenter( matchingDocOrdinal ), | ||
dataSet.values.matchingRadius( matchingDocOrdinal ) ) | ||
.boost( predicateBoost ); | ||
} | ||
|
||
@Override | ||
protected void assumeConstantScoreSupported() { | ||
throw scoreIsAlwaysConstant(); | ||
} | ||
|
||
private AssumptionViolatedException scoreIsAlwaysConstant() { | ||
throw new AssumptionViolatedException( "Score is always constant for geo-point fields" ); | ||
} | ||
} | ||
|
||
public static class InvalidFieldIT extends AbstractPredicateInvalidFieldIT { | ||
private static final SimpleMappedIndex<IndexBinding> index = SimpleMappedIndex.of( IndexBinding::new ) | ||
.name( "invalidField" ); | ||
|
||
public InvalidFieldIT() { | ||
super( index ); | ||
} | ||
|
||
@Override | ||
protected void tryPredicate(SearchPredicateFactory f, String fieldPath) { | ||
f.spatial().within().field( fieldPath ) | ||
// We need this because the backend is not involved before the call to circle() | ||
.circle( GeoPoint.of( 0, 0 ), 1 ); | ||
} | ||
} | ||
|
||
@RunWith(Parameterized.class) | ||
public static class UnsupportedTypeIT extends AbstractPredicateUnsupportedTypeIT { | ||
private static final List<Object[]> parameters = new ArrayList<>(); | ||
static { | ||
for ( FieldTypeDescriptor<?> fieldType : unsupportedFieldTypes ) { | ||
parameters.add( new Object[] { fieldType } ); | ||
} | ||
} | ||
|
||
private static final SimpleMappedIndex<IndexBinding> index = | ||
SimpleMappedIndex.of( root -> new IndexBinding( root, unsupportedFieldTypes ) ) | ||
.name( "unsupportedType" ); | ||
|
||
@Parameterized.Parameters(name = "{0}") | ||
public static List<Object[]> parameters() { | ||
return parameters; | ||
} | ||
|
||
public UnsupportedTypeIT(FieldTypeDescriptor<?> fieldType) { | ||
super( index, fieldType ); | ||
} | ||
|
||
@Override | ||
protected void tryPredicate(SearchPredicateFactory f, String fieldPath) { | ||
f.spatial().within().field( fieldPath ) | ||
// We need this because the backend is not involved before the call to circle() | ||
.circle( GeoPoint.of( 0, 0 ), 1 ); | ||
} | ||
|
||
@Override | ||
protected String predicateNameInErrorMessage() { | ||
return "Spatial predicates"; | ||
} | ||
} | ||
|
||
public static class SearchableIT extends AbstractPredicateSearchableIT { | ||
private static final SimpleMappedIndex<SearchableYesIndexBinding> searchableYesIndex = | ||
SimpleMappedIndex.of( root -> new SearchableYesIndexBinding( root, supportedFieldTypes ) ) | ||
.name( "searchableYes" ); | ||
|
||
private static final SimpleMappedIndex<SearchableNoIndexBinding> searchableNoIndex = | ||
SimpleMappedIndex.of( root -> new SearchableNoIndexBinding( root, supportedFieldTypes ) ) | ||
.name( "searchableNo" ); | ||
|
||
public SearchableIT() { | ||
super( searchableYesIndex, searchableNoIndex, supportedFieldType ); | ||
} | ||
|
||
@Override | ||
protected void tryPredicate(SearchPredicateFactory f, String fieldPath) { | ||
f.spatial().within().field( fieldPath ) | ||
// We need this because the backend is not involved before the call to circle() | ||
.circle( GeoPoint.of( 0, 0 ), 1 ); | ||
} | ||
} | ||
|
||
public static class ArgumentCheckingIT extends AbstractPredicateArgumentCheckingIT { | ||
private static final SimpleMappedIndex<IndexBinding> index = | ||
SimpleMappedIndex.of( root -> new IndexBinding( root, supportedFieldTypes ) ) | ||
.name( "argumentChecking" ); | ||
|
||
public ArgumentCheckingIT() { | ||
super( index, supportedFieldType ); | ||
} | ||
|
||
@Test | ||
public void nullUnit() { | ||
SearchPredicateFactory f = index.createScope().predicate(); | ||
|
||
assertThatThrownBy( () -> f.spatial().within().field( fieldPath() ).circle( 0.0, 0.0, 10.0, null ) ) | ||
.isInstanceOf( IllegalArgumentException.class ) | ||
.hasMessageContainingAll( "must not be null" ); | ||
} | ||
|
||
@Override | ||
protected void tryPredicateWithNullMatchingParam(SearchPredicateFactory f, String fieldPath) { | ||
f.spatial().within().field( fieldPath ).circle( null, 10.0 ); | ||
} | ||
} | ||
} |
54 changes: 54 additions & 0 deletions
54
...integrationtest/backend/tck/search/predicate/SpatialWithinCirclePredicateSpecificsIT.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
/* | ||
* Hibernate Search, full-text search for your domain model | ||
* | ||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later | ||
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>. | ||
*/ | ||
package org.hibernate.search.integrationtest.backend.tck.search.predicate; | ||
|
||
import static org.hibernate.search.util.impl.integrationtest.common.assertion.SearchResultAssert.assertThatQuery; | ||
|
||
import org.hibernate.search.engine.spatial.DistanceUnit; | ||
import org.hibernate.search.engine.spatial.GeoPoint; | ||
|
||
import org.junit.Test; | ||
|
||
public class SpatialWithinCirclePredicateSpecificsIT extends AbstractSpatialWithinSearchPredicateIT { | ||
|
||
private static final GeoPoint METRO_HOTEL_DE_VILLE = GeoPoint.of( 45.7673396, 4.833743 ); | ||
private static final GeoPoint METRO_GARIBALDI = GeoPoint.of( 45.7515926, 4.8514779 ); | ||
|
||
@Test | ||
public void matchMultipleDocuments() { | ||
assertThatQuery( mainIndex.query() | ||
.where( f -> f.spatial().within() | ||
.field( "geoPoint" ) | ||
.circle( METRO_GARIBALDI, 1_500 ) ) ) | ||
.hasDocRefHitsAnyOrder( mainIndex.typeName(), CHEZ_MARGOTTE_ID, IMOUTO_ID ); | ||
|
||
assertThatQuery( mainIndex.query() | ||
.where( f -> f.spatial().within() | ||
.field( "geoPoint" ) | ||
.circle( METRO_HOTEL_DE_VILLE, 500 ) ) ) | ||
.hasDocRefHitsAnyOrder( mainIndex.typeName(), OURSON_QUI_BOIT_ID ); | ||
|
||
assertThatQuery( mainIndex.query() | ||
.where( f -> f.spatial().within() | ||
.field( "geoPoint" ) | ||
.circle( METRO_GARIBALDI.latitude(), METRO_GARIBALDI.longitude(), 1_500 ) ) ) | ||
.hasDocRefHitsAnyOrder( mainIndex.typeName(), CHEZ_MARGOTTE_ID, IMOUTO_ID ); | ||
|
||
assertThatQuery( mainIndex.query() | ||
.where( f -> f.spatial().within() | ||
.field( "geoPoint" ) | ||
.circle( METRO_GARIBALDI.latitude(), METRO_GARIBALDI.longitude(), 1.5, DistanceUnit.KILOMETERS ) ) ) | ||
.hasDocRefHitsAnyOrder( mainIndex.typeName(), CHEZ_MARGOTTE_ID, IMOUTO_ID ); | ||
|
||
assertThatQuery( mainIndex.query() | ||
.where( f -> f.spatial().within() | ||
.field( "geoPoint" ) | ||
.circle( METRO_GARIBALDI, 1.5, DistanceUnit.KILOMETERS ) ) ) | ||
.hasDocRefHitsAnyOrder( mainIndex.typeName(), CHEZ_MARGOTTE_ID, IMOUTO_ID ); | ||
} | ||
|
||
} |
Oops, something went wrong.