Skip to content

Commit

Permalink
HSEARCH-3860 Factorize code related to simple field models in backend…
Browse files Browse the repository at this point in the history
… integration tests
  • Loading branch information
yrodiere committed Mar 13, 2020
1 parent 0f16aa7 commit 6a67ca3
Show file tree
Hide file tree
Showing 5 changed files with 155 additions and 184 deletions.
Expand Up @@ -11,16 +11,14 @@

import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.stream.Stream;

import org.hibernate.search.engine.backend.common.DocumentReference;
import org.hibernate.search.engine.backend.document.DocumentElement;
import org.hibernate.search.engine.backend.document.IndexFieldReference;
import org.hibernate.search.engine.backend.document.IndexObjectFieldReference;
import org.hibernate.search.engine.backend.document.model.dsl.IndexSchemaElement;
import org.hibernate.search.engine.backend.document.model.dsl.IndexSchemaObjectField;
Expand All @@ -35,7 +33,8 @@
import org.hibernate.search.integrationtest.backend.tck.testsupport.types.NormalizedStringFieldTypeDescriptor;
import org.hibernate.search.integrationtest.backend.tck.testsupport.util.ExpectationsAlternative;
import org.hibernate.search.integrationtest.backend.tck.testsupport.util.IndexFieldStructure;
import org.hibernate.search.integrationtest.backend.tck.testsupport.util.StandardFieldMapper;
import org.hibernate.search.integrationtest.backend.tck.testsupport.util.SimpleFieldModel;
import org.hibernate.search.integrationtest.backend.tck.testsupport.util.SimpleFieldModelsByType;
import org.hibernate.search.integrationtest.backend.tck.testsupport.util.TckConfiguration;
import org.hibernate.search.integrationtest.backend.tck.testsupport.util.rule.SearchSetupHelper;
import org.hibernate.search.util.impl.integrationtest.mapper.stub.StubMappingIndexManager;
Expand All @@ -54,17 +53,22 @@
@RunWith(Parameterized.class)
public class FieldSearchSortBaseIT<F> {

private static Stream<FieldTypeDescriptor<?>> supportedTypeDescriptors() {
return FieldTypeDescriptor.getAll().stream()
.filter( typeDescriptor -> typeDescriptor.getFieldSortExpectations().isSupported() );
}

@Parameterized.Parameters(name = "{0} - {1}")
public static Object[][] parameters() {
List<Object[]> parameters = new ArrayList<>();
for ( FieldTypeDescriptor<?> fieldTypeDescriptor : FieldTypeDescriptor.getAll() ) {
supportedTypeDescriptors().forEach( fieldTypeDescriptor -> {
ExpectationsAlternative<?, ?> expectations = fieldTypeDescriptor.getFieldSortExpectations();
if ( expectations.isSupported() ) {
for ( IndexFieldStructure indexFieldStructure : IndexFieldStructure.values() ) {
parameters.add( new Object[] { indexFieldStructure, fieldTypeDescriptor } );
}
}
}
} );
return parameters.toArray( new Object[0][] );
}

Expand Down Expand Up @@ -321,20 +325,24 @@ private String getFieldPath() {
}

private static void initDocument(IndexMapping indexMapping, DocumentElement document, Integer ordinal) {
forEachSupportedTypeDescriptor( typeDescriptor -> {
addValue( document, indexMapping.fieldModels, typeDescriptor, ordinal );
} );
indexMapping.fieldModels.forEach(
fieldModel -> addValue( fieldModel, document, ordinal )
);

// Note: these objects must be single-valued for these tests
DocumentElement flattenedObject = document.addObject( indexMapping.flattenedObject.self );
DocumentElement nestedObject = document.addObject( indexMapping.nestedObject.self );
DocumentElement nestedObjectInNestedObject = nestedObject.addObject( indexMapping.nestedObject.nestedObject.self );

forEachSupportedTypeDescriptor( typeDescriptor -> {
addValue( flattenedObject, indexMapping.flattenedObject.fieldModels, typeDescriptor, ordinal );
addValue( nestedObject, indexMapping.nestedObject.fieldModels, typeDescriptor, ordinal );
addValue( nestedObjectInNestedObject, indexMapping.nestedObject.nestedObject.fieldModels, typeDescriptor, ordinal );
} );
indexMapping.flattenedObject.fieldModels.forEach(
fieldModel -> addValue( fieldModel, flattenedObject, ordinal )
);
indexMapping.nestedObject.fieldModels.forEach(
fieldModel -> addValue( fieldModel, nestedObject, ordinal )
);
indexMapping.nestedObject.nestedObject.fieldModels.forEach(
fieldModel -> addValue( fieldModel, nestedObjectInNestedObject, ordinal )
);
}

@SuppressWarnings("unchecked")
Expand All @@ -351,14 +359,13 @@ private F getSingleValueForMissingUse(int ordinal) {
return value;
}

private static <F> void addValue(DocumentElement documentElement,
FieldModelsByType fieldModels, FieldTypeDescriptor<F> typeDescriptor, Integer ordinal) {
private static <F> void addValue(SimpleFieldModel<F> fieldModel, DocumentElement documentElement, Integer ordinal) {
if ( ordinal == null ) {
return;
}
documentElement.addValue(
fieldModels.get( typeDescriptor ).reference,
typeDescriptor.getAscendingUniqueTermValues().get( ordinal )
fieldModel.reference,
fieldModel.typeDescriptor.getAscendingUniqueTermValues().get( ordinal )
);
}

Expand Down Expand Up @@ -389,18 +396,13 @@ private static void initData() {
.hasDocRefHitsAnyOrder( INDEX_NAME, DOCUMENT_1, DOCUMENT_2, DOCUMENT_3, EMPTY_1, EMPTY_2, EMPTY_3, EMPTY_4 );
}

private static void forEachSupportedTypeDescriptor(Consumer<FieldTypeDescriptor<?>> action) {
FieldTypeDescriptor.getAll().stream()
.filter( typeDescriptor -> typeDescriptor.getFieldSortExpectations().isSupported() )
.forEach( action );
}

private static class AbstractObjectMapping {
final FieldModelsByType fieldModels;
final SimpleFieldModelsByType fieldModels;

AbstractObjectMapping(IndexSchemaElement self,
Consumer<StandardIndexFieldTypeOptionsStep<?, ?>> additionalConfiguration) {
fieldModels = FieldModelsByType.mapSupported( self, "", additionalConfiguration );
fieldModels = SimpleFieldModelsByType.mapAll( supportedTypeDescriptors(), self, "",
c -> c.sortable( Sortable.YES ), additionalConfiguration );
}
}

Expand Down Expand Up @@ -466,44 +468,4 @@ private SecondLevelObjectMapping(String relativeFieldName, IndexSchemaObjectFiel
}
}

private static class FieldModelsByType {
public static FieldModelsByType mapSupported(IndexSchemaElement parent, String prefix,
Consumer<StandardIndexFieldTypeOptionsStep<?, ?>> additionalConfiguration) {
FieldModelsByType result = new FieldModelsByType();
forEachSupportedTypeDescriptor( typeDescriptor -> {
result.content.put(
typeDescriptor,
FieldModel.mapper( typeDescriptor )
.map( parent, prefix + typeDescriptor.getUniqueName(), additionalConfiguration )
);
} );
return result;
}

private final Map<FieldTypeDescriptor<?>, FieldModel<?>> content = new LinkedHashMap<>();

@SuppressWarnings("unchecked")
private <F> FieldModel<F> get(FieldTypeDescriptor<F> typeDescriptor) {
return (FieldModel<F>) content.get( typeDescriptor );
}
}

private static class FieldModel<F> {
static <F> StandardFieldMapper<F, FieldModel<F>> mapper(FieldTypeDescriptor<F> typeDescriptor) {
return StandardFieldMapper.of(
typeDescriptor::configure,
c -> c.sortable( Sortable.YES ),
FieldModel::new
);
}

final IndexFieldReference<F> reference;
final String relativeFieldName;

private FieldModel(IndexFieldReference<F> reference, String relativeFieldName) {
this.reference = reference;
this.relativeFieldName = relativeFieldName;
}
}

}
Expand Up @@ -10,16 +10,14 @@
import static org.hibernate.search.util.impl.integrationtest.mapper.stub.StubMapperUtils.referenceProvider;

import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.stream.Stream;

import org.hibernate.search.engine.backend.common.DocumentReference;
import org.hibernate.search.engine.backend.document.DocumentElement;
import org.hibernate.search.engine.backend.document.IndexFieldReference;
import org.hibernate.search.engine.backend.document.model.dsl.IndexSchemaElement;
import org.hibernate.search.engine.backend.types.Sortable;
import org.hibernate.search.engine.backend.types.dsl.IndexFieldTypeFactory;
Expand All @@ -34,6 +32,8 @@
import org.hibernate.search.integrationtest.backend.tck.testsupport.types.NormalizedStringFieldTypeDescriptor;
import org.hibernate.search.integrationtest.backend.tck.testsupport.util.ExpectationsAlternative;
import org.hibernate.search.integrationtest.backend.tck.testsupport.util.InvalidType;
import org.hibernate.search.integrationtest.backend.tck.testsupport.util.SimpleFieldModel;
import org.hibernate.search.integrationtest.backend.tck.testsupport.util.SimpleFieldModelsByType;
import org.hibernate.search.integrationtest.backend.tck.testsupport.util.StandardFieldMapper;
import org.hibernate.search.integrationtest.backend.tck.testsupport.util.TckConfiguration;
import org.hibernate.search.integrationtest.backend.tck.testsupport.util.ValueWrapper;
Expand All @@ -57,15 +57,20 @@
@RunWith(Parameterized.class)
public class FieldSearchSortTypeCheckingAndConversionIT<F> {

private static Stream<FieldTypeDescriptor<?>> supportedTypeDescriptors() {
return FieldTypeDescriptor.getAll().stream()
.filter( typeDescriptor -> typeDescriptor.getFieldSortExpectations().isSupported() );
}

@Parameterized.Parameters(name = "{0} - {1}")
public static Object[][] parameters() {
List<Object[]> parameters = new ArrayList<>();
for ( FieldTypeDescriptor<?> fieldTypeDescriptor : FieldTypeDescriptor.getAll() ) {
supportedTypeDescriptors().forEach( fieldTypeDescriptor -> {
ExpectationsAlternative<?, ?> expectations = fieldTypeDescriptor.getFieldSortExpectations();
if ( expectations.isSupported() ) {
parameters.add( new Object[] { fieldTypeDescriptor } );
}
}
} );
return parameters.toArray( new Object[0][] );
}

Expand Down Expand Up @@ -377,10 +382,8 @@ private String getNonSortableFieldPath() {
}

private static void initDocument(IndexMapping indexMapping, DocumentElement document, Integer ordinal) {
forEachSupportedTypeDescriptor( typeDescriptor -> {
addValue( document, indexMapping.fieldModels, typeDescriptor, ordinal );
addValue( document, indexMapping.fieldWithDslConverterModels, typeDescriptor, ordinal );
} );
indexMapping.fieldModels.forEach( fieldModel -> addValue( fieldModel, document, ordinal ) );
indexMapping.fieldWithDslConverterModels.forEach( fieldModel -> addValue( fieldModel, document, ordinal ) );
}

@SuppressWarnings("unchecked")
Expand All @@ -397,14 +400,13 @@ private F getSingleValueForMissingUse(int ordinal) {
return value;
}

private static <F> void addValue(DocumentElement documentElement,
FieldModelsByType fieldModels, FieldTypeDescriptor<F> typeDescriptor, Integer ordinal) {
private static <F> void addValue(SimpleFieldModel<F> fieldModel, DocumentElement documentElement, Integer ordinal) {
if ( ordinal == null ) {
return;
}
documentElement.addValue(
fieldModels.get( typeDescriptor ).reference,
typeDescriptor.getAscendingUniqueTermValues().get( ordinal )
fieldModel.reference,
fieldModel.typeDescriptor.getAscendingUniqueTermValues().get( ordinal )
);
}

Expand Down Expand Up @@ -447,32 +449,31 @@ private static void initData() {
assertThat( query ).hasDocRefHitsAnyOrder( RAW_FIELD_COMPATIBLE_INDEX_NAME, RAW_FIELD_COMPATIBLE_INDEX_DOCUMENT_1 );
}

private static void forEachSupportedTypeDescriptor(Consumer<FieldTypeDescriptor<?>> action) {
FieldTypeDescriptor.getAll().stream()
.filter( typeDescriptor -> typeDescriptor.getFieldSortExpectations().isSupported() )
.forEach( action );
}

private static class IndexMapping {
final FieldModelsByType fieldModels;
final FieldModelsByType fieldWithDslConverterModels;
final FieldModelsByType nonSortableFieldModels;
final SimpleFieldModelsByType fieldModels;
final SimpleFieldModelsByType fieldWithDslConverterModels;
final SimpleFieldModelsByType nonSortableFieldModels;

IndexMapping(IndexSchemaElement root) {
this( root, ignored -> { } );
}

IndexMapping(IndexSchemaElement root,
Consumer<StandardIndexFieldTypeOptionsStep<?, ?>> additionalConfiguration) {
fieldModels = FieldModelsByType.mapSupported( root, "", additionalConfiguration );
fieldWithDslConverterModels = FieldModelsByType.mapSupported(
root, "converted_",
fieldModels = SimpleFieldModelsByType.mapAll(
supportedTypeDescriptors(),
root, "", c -> c.sortable( Sortable.YES ), additionalConfiguration
);
fieldWithDslConverterModels = SimpleFieldModelsByType.mapAll(
supportedTypeDescriptors(), root, "converted_",
c -> c.sortable( Sortable.YES ),
additionalConfiguration.andThen(
c -> c.dslConverter( ValueWrapper.class, ValueWrapper.toIndexFieldConverter() )
)
);
nonSortableFieldModels = FieldModelsByType.mapSupported(
root, "nonSortable_",
nonSortableFieldModels = SimpleFieldModelsByType.mapAll(
supportedTypeDescriptors(), root, "nonSortable_",
c -> c.sortable( Sortable.YES ),
additionalConfiguration.andThen( c -> c.sortable( Sortable.NO ) )
);
}
Expand All @@ -498,7 +499,7 @@ private static class IncompatibleIndexMapping {
}

private static void mapFieldsWithIncompatibleType(IndexSchemaElement parent) {
forEachSupportedTypeDescriptor( typeDescriptor -> {
supportedTypeDescriptors().forEach( typeDescriptor -> {
StandardFieldMapper<?, IncompatibleFieldModel> mapper;
if ( Integer.class.equals( typeDescriptor.getJavaType() ) ) {
mapper = IncompatibleFieldModel.mapper( context -> context.asLong() );
Expand All @@ -511,46 +512,6 @@ private static void mapFieldsWithIncompatibleType(IndexSchemaElement parent) {
}
}

private static class FieldModelsByType {
public static FieldModelsByType mapSupported(IndexSchemaElement parent, String prefix,
Consumer<StandardIndexFieldTypeOptionsStep<?, ?>> additionalConfiguration) {
FieldModelsByType result = new FieldModelsByType();
forEachSupportedTypeDescriptor( typeDescriptor -> {
result.content.put(
typeDescriptor,
FieldModel.mapper( typeDescriptor )
.map( parent, prefix + typeDescriptor.getUniqueName(), additionalConfiguration )
);
} );
return result;
}

private final Map<FieldTypeDescriptor<?>, FieldModel<?>> content = new LinkedHashMap<>();

@SuppressWarnings("unchecked")
private <F> FieldModel<F> get(FieldTypeDescriptor<F> typeDescriptor) {
return (FieldModel<F>) content.get( typeDescriptor );
}
}

private static class FieldModel<F> {
static <F> StandardFieldMapper<F, FieldModel<F>> mapper(FieldTypeDescriptor<F> typeDescriptor) {
return StandardFieldMapper.of(
typeDescriptor::configure,
c -> c.sortable( Sortable.YES ),
FieldModel::new
);
}

final IndexFieldReference<F> reference;
final String relativeFieldName;

private FieldModel(IndexFieldReference<F> reference, String relativeFieldName) {
this.reference = reference;
this.relativeFieldName = relativeFieldName;
}
}

private static class IncompatibleFieldModel {
static <F> StandardFieldMapper<F, IncompatibleFieldModel> mapper(
Function<IndexFieldTypeFactory, StandardIndexFieldTypeOptionsStep<?, F>> configuration) {
Expand Down

0 comments on commit 6a67ca3

Please sign in to comment.