Skip to content

Commit

Permalink
HSEARCH-4574 Test error messages in implicit projections when compili…
Browse files Browse the repository at this point in the history
…ng without the -parameters flag
  • Loading branch information
yrodiere committed May 31, 2023
1 parent e3524d2 commit 15f3f47
Show file tree
Hide file tree
Showing 5 changed files with 97 additions and 6 deletions.
@@ -0,0 +1,86 @@
/*
* 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.mapper.pojo.mapping.definition.noparameters;

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;

import java.lang.invoke.MethodHandles;
import java.lang.reflect.Parameter;

import org.hibernate.search.integrationtest.mapper.pojo.mapping.definition.AbstractProjectionConstructorIT;
import org.hibernate.search.mapper.pojo.mapping.definition.annotation.DocumentId;
import org.hibernate.search.mapper.pojo.mapping.definition.annotation.FullTextField;
import org.hibernate.search.mapper.pojo.mapping.definition.annotation.GenericField;
import org.hibernate.search.mapper.pojo.mapping.definition.annotation.Indexed;
import org.hibernate.search.mapper.pojo.mapping.definition.annotation.ProjectionConstructor;
import org.hibernate.search.util.common.SearchException;
import org.hibernate.search.util.impl.integrationtest.common.reporting.FailureReportUtils;
import org.hibernate.search.util.impl.integrationtest.mapper.pojo.standalone.StandalonePojoMappingSetupHelper;

import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;

public class ProjectionConstructorClassNoParametersCompilerFlagIT extends AbstractProjectionConstructorIT {

@Rule
public StandalonePojoMappingSetupHelper setupHelper = StandalonePojoMappingSetupHelper.withBackendMock( MethodHandles.lookup(), backendMock );

@Before
public void sourcesCompiledWithoutParametersFlag() {
assertThat( ConstructorWithParameters.class.getDeclaredConstructors()[0].getParameters() )
.withFailMessage( "This test only works if compiled *without* the '-parameters' compiler flag." )
.extracting( Parameter::isNamePresent )
.containsOnly( Boolean.FALSE );
}

@Test
public void implicitInnerMapping() {
@ProjectionConstructor
class MyProjection {
private final String someText;
private final Integer someInteger;
MyProjection(String someText, Integer someInteger) {
this.someText = someText;
this.someInteger = someInteger;
}
}
assertThatThrownBy( () -> setupHelper.start()
.withAnnotatedTypes( MyProjection.class )
.setup( IndexedEntity.class ) )
.isInstanceOf( SearchException.class )
.satisfies( FailureReportUtils.hasFailureReport()
.typeContext( MyProjection.class.getName() )
.constructorContext( ProjectionConstructorClassNoParametersCompilerFlagIT.class, String.class, Integer.class )
.methodParameterContext( 1 )
.failure( "Missing parameter names in Java metadata for projection constructor",
"When inferring inner projections from constructor parameters,"
+ " constructor parameter names must be known",
"Make sure this class was compiled with the '-parameters' compiler flag" )
.methodParameterContext( 2 )
.failure( "Missing parameter names in Java metadata for projection constructor",
"When inferring inner projections from constructor parameters,"
+ " constructor parameter names must be known",
"Make sure this class was compiled with the '-parameters' compiler flag" ) );
}

@Indexed(index = INDEX_NAME)
static class IndexedEntity {
@DocumentId
public Integer id;
@FullTextField
public String text;
@GenericField
public Integer integer;
}

static class ConstructorWithParameters {
ConstructorWithParameters(int paramInt, String paramString) {
}
}
}
Expand Up @@ -21,6 +21,7 @@
import org.hibernate.search.mapper.pojo.standalone.mapping.SearchMapping;
import org.hibernate.search.util.impl.integrationtest.mapper.pojo.standalone.StandalonePojoMappingSetupHelper;

import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;

Expand All @@ -29,11 +30,12 @@ public class ProjectionConstructorRecordNoParametersCompilerFlagIT extends Abstr
@Rule
public StandalonePojoMappingSetupHelper setupHelper = StandalonePojoMappingSetupHelper.withBackendMock( MethodHandles.lookup(), backendMock );

@Test
@Before
public void sourcesCompiledWithoutParametersFlag() {
assertThat( ConstructorWithParameters.class.getDeclaredConstructors()[0].getParameters() )
.withFailMessage( "This test only works if compiled *without* the '-parameters' compiler flag." )
.extracting( Parameter::isNamePresent )
.containsOnly( Boolean.FALSE, Boolean.FALSE );
.containsOnly( Boolean.FALSE );
}

@Test
Expand Down
Expand Up @@ -707,9 +707,8 @@ SearchException errorRetrievingConstructorHandle(Constructor<?> constructor,
@Message(id = ID_OFFSET + 114,
value = "Missing parameter names in Java metadata for projection constructor."
+ " When inferring inner projections from constructor parameters, constructor parameter names must be known."
+ " Make sure that '%1$s' was compiled with the '-parameters' compiler flag.")
SearchException missingParameterNameForProjectionConstructor(
@FormatWith(PojoTypeModelFormatter.class) PojoRawTypeModel<?> parentTypeModel);
+ " Make sure this class was compiled with the '-parameters' compiler flag.")
SearchException missingParameterNameForProjectionConstructor();

@Message(id = ID_OFFSET + 115,
value = "Invalid parameter type for projection constructor: %1$s."
Expand Down
Expand Up @@ -225,7 +225,7 @@ InnerProjectionDefinition inferInnerProjection() {
PojoRawTypeModel<?> boundParameterElementRawType = boundParameterElementPath.getExtractedType().rawType();
Optional<String> paramName = parameter.name();
if ( !paramName.isPresent() ) {
throw log.missingParameterNameForProjectionConstructor( parent.constructor.typeModel() );
throw log.missingParameterNameForProjectionConstructor();
}
String innerRelativeFieldPath = paramName.get();
String innerAbsoluteFieldPath = FieldPaths.compose( parent.absoluteFieldPath, innerRelativeFieldPath );
Expand Down
Expand Up @@ -56,6 +56,10 @@ public FailureReportChecker constructorContext(Class<?> ... parameterTypes) {
return contextLiteral( "constructor with parameter types [" + CommaSeparatedClassesFormatter.format( parameterTypes ) + "]" );
}

public FailureReportChecker methodParameterContext(int index) {
return methodParameterContext( index, "<unknown name>" );
}

public FailureReportChecker methodParameterContext(int index, String name) {
return contextLiteral( "parameter at index " + index + " (" + name + ")" );
}
Expand Down

0 comments on commit 15f3f47

Please sign in to comment.