Skip to content

Commit 0e8d758

Browse files
authored
[Tests] Add tests for CompletionSuggestionBuilder#build() (#25575)
This adds a unit test that checks the CompletionSuggestionContext that is the output of CompletionSuggestionBuilder#build.
1 parent 5762bce commit 0e8d758

File tree

5 files changed

+55
-34
lines changed

5 files changed

+55
-34
lines changed

core/src/main/java/org/elasticsearch/search/suggest/completion/CompletionSuggestionBuilder.java

Lines changed: 28 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,12 @@
2424
import org.elasticsearch.common.io.stream.StreamInput;
2525
import org.elasticsearch.common.io.stream.StreamOutput;
2626
import org.elasticsearch.common.unit.Fuzziness;
27+
import org.elasticsearch.common.xcontent.NamedXContentRegistry;
2728
import org.elasticsearch.common.xcontent.ObjectParser;
2829
import org.elasticsearch.common.xcontent.ToXContent;
2930
import org.elasticsearch.common.xcontent.XContentBuilder;
3031
import org.elasticsearch.common.xcontent.XContentFactory;
32+
import org.elasticsearch.common.xcontent.XContentHelper;
3133
import org.elasticsearch.common.xcontent.XContentParser;
3234
import org.elasticsearch.common.xcontent.XContentType;
3335
import org.elasticsearch.index.mapper.CompletionFieldMapper;
@@ -52,6 +54,7 @@
5254
* indexing.
5355
*/
5456
public class CompletionSuggestionBuilder extends SuggestionBuilder<CompletionSuggestionBuilder> {
57+
private static final XContentType CONTEXT_BYTES_XCONTENT_TYPE = XContentType.JSON;
5558
static final String SUGGESTION_NAME = "completion";
5659
static final ParseField CONTEXTS_FIELD = new ParseField("contexts", "context");
5760

@@ -86,7 +89,7 @@ public class CompletionSuggestionBuilder extends SuggestionBuilder<CompletionSug
8689
PARSER.declareInt(CompletionSuggestionBuilder.InnerBuilder::shardSize, SHARDSIZE_FIELD);
8790
PARSER.declareField((p, v, c) -> {
8891
// Copy the current structure. We will parse, once the mapping is provided
89-
XContentBuilder builder = XContentFactory.contentBuilder(XContentType.JSON);
92+
XContentBuilder builder = XContentFactory.contentBuilder(CONTEXT_BYTES_XCONTENT_TYPE);
9093
builder.copyCurrentStructure(p);
9194
v.contextBytes = builder.bytes();
9295
p.skipChildren();
@@ -186,7 +189,7 @@ public CompletionSuggestionBuilder regex(String regex, RegexOptions regexOptions
186189
public CompletionSuggestionBuilder contexts(Map<String, List<? extends ToXContent>> queryContexts) {
187190
Objects.requireNonNull(queryContexts, "contexts must not be null");
188191
try {
189-
XContentBuilder contentBuilder = XContentFactory.jsonBuilder();
192+
XContentBuilder contentBuilder = XContentFactory.contentBuilder(CONTEXT_BYTES_XCONTENT_TYPE);
190193
contentBuilder.startObject();
191194
for (Map.Entry<String, List<? extends ToXContent>> contextEntry : queryContexts.entrySet()) {
192195
contentBuilder.startArray(contextEntry.getKey());
@@ -255,33 +258,16 @@ public SuggestionContext build(QueryShardContext context) throws IOException {
255258
suggestionContext.setFuzzyOptions(fuzzyOptions);
256259
suggestionContext.setRegexOptions(regexOptions);
257260
MappedFieldType mappedFieldType = mapperService.fullName(suggestionContext.getField());
258-
if (mappedFieldType == null ||
259-
mappedFieldType instanceof CompletionFieldMapper.CompletionFieldType == false) {
261+
if (mappedFieldType == null || mappedFieldType instanceof CompletionFieldMapper.CompletionFieldType == false) {
260262
throw new IllegalArgumentException("Field [" + suggestionContext.getField() + "] is not a completion suggest field");
261263
}
262264
if (mappedFieldType instanceof CompletionFieldMapper.CompletionFieldType) {
263265
CompletionFieldMapper.CompletionFieldType type = (CompletionFieldMapper.CompletionFieldType) mappedFieldType;
264266
suggestionContext.setFieldType(type);
265267
if (type.hasContextMappings() && contextBytes != null) {
266-
try (XContentParser contextParser = XContentFactory.xContent(contextBytes).createParser(context.getXContentRegistry(),
267-
contextBytes)) {
268-
if (type.hasContextMappings() && contextParser != null) {
269-
ContextMappings contextMappings = type.getContextMappings();
270-
contextParser.nextToken();
271-
Map<String, List<ContextMapping.InternalQueryContext>> queryContexts = new HashMap<>(contextMappings.size());
272-
assert contextParser.currentToken() == XContentParser.Token.START_OBJECT;
273-
XContentParser.Token currentToken;
274-
String currentFieldName;
275-
while ((currentToken = contextParser.nextToken()) != XContentParser.Token.END_OBJECT) {
276-
if (currentToken == XContentParser.Token.FIELD_NAME) {
277-
currentFieldName = contextParser.currentName();
278-
final ContextMapping mapping = contextMappings.get(currentFieldName);
279-
queryContexts.put(currentFieldName, mapping.parseQueryContext(contextParser));
280-
}
281-
}
282-
suggestionContext.setQueryContexts(queryContexts);
283-
}
284-
}
268+
Map<String, List<ContextMapping.InternalQueryContext>> queryContexts = parseContextBytes(contextBytes,
269+
context.getXContentRegistry(), type.getContextMappings());
270+
suggestionContext.setQueryContexts(queryContexts);
285271
} else if (contextBytes != null) {
286272
throw new IllegalArgumentException("suggester [" + type.name() + "] doesn't expect any context");
287273
}
@@ -290,6 +276,25 @@ public SuggestionContext build(QueryShardContext context) throws IOException {
290276
return suggestionContext;
291277
}
292278

279+
static Map<String, List<ContextMapping.InternalQueryContext>> parseContextBytes(BytesReference contextBytes,
280+
NamedXContentRegistry xContentRegistry, ContextMappings contextMappings) throws IOException {
281+
try (XContentParser contextParser = XContentHelper.createParser(xContentRegistry, contextBytes, CONTEXT_BYTES_XCONTENT_TYPE)) {
282+
contextParser.nextToken();
283+
Map<String, List<ContextMapping.InternalQueryContext>> queryContexts = new HashMap<>(contextMappings.size());
284+
assert contextParser.currentToken() == XContentParser.Token.START_OBJECT;
285+
XContentParser.Token currentToken;
286+
String currentFieldName;
287+
while ((currentToken = contextParser.nextToken()) != XContentParser.Token.END_OBJECT) {
288+
if (currentToken == XContentParser.Token.FIELD_NAME) {
289+
currentFieldName = contextParser.currentName();
290+
final ContextMapping<?> mapping = contextMappings.get(currentFieldName);
291+
queryContexts.put(currentFieldName, mapping.parseQueryContext(contextParser));
292+
}
293+
}
294+
return queryContexts;
295+
}
296+
}
297+
293298
@Override
294299
public String getWriteableName() {
295300
return SUGGESTION_NAME;

core/src/test/java/org/elasticsearch/search/suggest/AbstractSuggestionBuilderTestCase.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -201,14 +201,14 @@ public void testBuild() throws IOException {
201201
} else {
202202
assertEquals("mapperServiceSearchAnalyzer", ((NamedAnalyzer) suggestionContext.getAnalyzer()).name());
203203
}
204-
assertSuggester(suggestionBuilder, suggestionContext);
204+
assertSuggestionContext(suggestionBuilder, suggestionContext);
205205
}
206206
}
207207

208208
/**
209-
* put suggester dependent assertions in the sub type test
209+
* put implementation dependent assertions in the sub-type test
210210
*/
211-
protected abstract void assertSuggester(SB builder, SuggestionContext context);
211+
protected abstract void assertSuggestionContext(SB builder, SuggestionContext context) throws IOException;
212212

213213
protected MappedFieldType mockFieldType() {
214214
return mock(MappedFieldType.class);

core/src/test/java/org/elasticsearch/search/suggest/completion/CompletionSuggesterBuilderTests.java

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -29,17 +29,19 @@
2929
import org.elasticsearch.search.suggest.completion.context.CategoryQueryContext;
3030
import org.elasticsearch.search.suggest.completion.context.ContextBuilder;
3131
import org.elasticsearch.search.suggest.completion.context.ContextMapping;
32+
import org.elasticsearch.search.suggest.completion.context.ContextMapping.InternalQueryContext;
3233
import org.elasticsearch.search.suggest.completion.context.ContextMappings;
3334
import org.elasticsearch.search.suggest.completion.context.GeoQueryContext;
3435

3536
import java.io.IOException;
3637
import java.util.ArrayList;
37-
import java.util.Arrays;
3838
import java.util.Collections;
3939
import java.util.HashMap;
4040
import java.util.List;
4141
import java.util.Map;
4242

43+
import static org.hamcrest.Matchers.instanceOf;
44+
4345
public class CompletionSuggesterBuilderTests extends AbstractSuggestionBuilderTestCase<CompletionSuggestionBuilder> {
4446

4547
private static final String[] SHUFFLE_PROTECTED_FIELDS = new String[] { CompletionSuggestionBuilder.CONTEXTS_FIELD.getPreferredName() };
@@ -54,17 +56,17 @@ protected CompletionSuggestionBuilder randomSuggestionBuilder() {
5456
}
5557

5658
public static CompletionSuggestionBuilder randomCompletionSuggestionBuilder() {
57-
// lazy initialization of context names and mappings, cannot be done in init method because other test
59+
// lazy initialization of context names and mappings, cannot be done in some init method because other test
5860
// also create random CompletionSuggestionBuilder instances
5961
if (categoryContextName == null) {
6062
categoryContextName = randomAlphaOfLength(10);
6163
}
6264
if (geoQueryContextName == null) {
6365
geoQueryContextName = randomAlphaOfLength(10);
6466
}
65-
if (contextMappings == null) {
66-
contextMappings = Arrays.asList(new ContextMapping[] { ContextBuilder.category(categoryContextName).build(),
67-
ContextBuilder.geo(geoQueryContextName).build() });
67+
if (contextMappings.isEmpty()) {
68+
contextMappings.add(ContextBuilder.category(categoryContextName).build());
69+
contextMappings.add(ContextBuilder.geo(geoQueryContextName).build());
6870
}
6971
// lazy initialization of context names and mappings, cannot be done in some init method because other test
7072
// also create random CompletionSuggestionBuilder instances
@@ -165,6 +167,20 @@ protected MappedFieldType mockFieldType() {
165167
}
166168

167169
@Override
168-
protected void assertSuggester(CompletionSuggestionBuilder builder, SuggestionContext context) {
170+
protected void assertSuggestionContext(CompletionSuggestionBuilder builder, SuggestionContext context) throws IOException {
171+
assertThat(context, instanceOf(CompletionSuggestionContext.class));
172+
assertThat(context.getSuggester(), instanceOf(CompletionSuggester.class));
173+
CompletionSuggestionContext completionSuggestionCtx = (CompletionSuggestionContext) context;
174+
assertThat(completionSuggestionCtx.getFieldType(), instanceOf(CompletionFieldType.class) );
175+
assertEquals(builder.fuzzyOptions, completionSuggestionCtx.getFuzzyOptions());
176+
Map<String, List<InternalQueryContext>> parsedContextBytes;
177+
parsedContextBytes = CompletionSuggestionBuilder.parseContextBytes(builder.contextBytes, xContentRegistry(),
178+
new ContextMappings(contextMappings));
179+
Map<String, List<InternalQueryContext>> queryContexts = completionSuggestionCtx.getQueryContexts();
180+
assertEquals(parsedContextBytes.keySet(), queryContexts.keySet());
181+
for (String contextName : queryContexts.keySet()) {
182+
assertEquals(parsedContextBytes.get(contextName), queryContexts.get(contextName));
183+
}
184+
assertEquals(builder.regexOptions, completionSuggestionCtx.getRegexOptions());
169185
}
170186
}

core/src/test/java/org/elasticsearch/search/suggest/phrase/PhraseSuggestionBuilderTests.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,7 @@ public void testInvalidParameters() {
188188
}
189189

190190
@Override
191-
protected void assertSuggester(PhraseSuggestionBuilder builder, SuggestionContext context) {
191+
protected void assertSuggestionContext(PhraseSuggestionBuilder builder, SuggestionContext context) {
192192
assertThat(context, instanceOf(PhraseSuggestionContext.class));
193193
assertThat(context.getSuggester(), instanceOf(PhraseSuggester.class));
194194
PhraseSuggestionContext phraseSuggesterCtx = (PhraseSuggestionContext) context;

core/src/test/java/org/elasticsearch/search/suggest/term/TermSuggestionBuilderTests.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,7 @@ public void testMalformedJson() {
227227
}
228228

229229
@Override
230-
protected void assertSuggester(TermSuggestionBuilder builder, SuggestionContext context) {
230+
protected void assertSuggestionContext(TermSuggestionBuilder builder, SuggestionContext context) {
231231
assertThat(context, instanceOf(TermSuggestionContext.class));
232232
assertThat(context.getSuggester(), instanceOf(TermSuggester.class));
233233
TermSuggestionContext termSuggesterCtx = (TermSuggestionContext) context;

0 commit comments

Comments
 (0)