/* * Licensed to Elasticsearch under one or more contributor * license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright * ownership. Elasticsearch licenses this file to you under * the Apache License, Version 2.0 (the "License"); you may * not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.elasticsearch.search.suggest; import org.elasticsearch.common.io.stream.NamedWriteableRegistry; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.xcontent.NamedXContentRegistry; import org.elasticsearch.common.xcontent.ToXContent; import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.xcontent.XContentFactory; import org.elasticsearch.common.xcontent.XContentParser; import org.elasticsearch.common.xcontent.XContentType; import org.elasticsearch.search.SearchModule; import org.elasticsearch.search.suggest.completion.CompletionSuggesterBuilderTests; import org.elasticsearch.search.suggest.phrase.PhraseSuggestionBuilderTests; import org.elasticsearch.search.suggest.term.TermSuggestionBuilderTests; import org.elasticsearch.test.ESTestCase; import org.junit.AfterClass; import org.junit.BeforeClass; import java.io.IOException; import java.util.Map.Entry; import static java.util.Collections.emptyList; import static org.elasticsearch.test.EqualsHashCodeTestUtils.checkEqualsAndHashCode; public class SuggestBuilderTests extends ESTestCase { private static final int NUMBER_OF_RUNS = 20; private static NamedWriteableRegistry namedWriteableRegistry; private static NamedXContentRegistry xContentRegistry; /** * Setup for the whole base test class. */ @BeforeClass public static void init() { SearchModule searchModule = new SearchModule(Settings.EMPTY, false, emptyList()); namedWriteableRegistry = new NamedWriteableRegistry(searchModule.getNamedWriteables()); xContentRegistry = new NamedXContentRegistry(searchModule.getNamedXContents()); } @AfterClass public static void afterClass() { namedWriteableRegistry = null; xContentRegistry = null; } /** * creates random suggestion builder, renders it to xContent and back to new instance that should be equal to original */ public void testFromXContent() throws IOException { for (int runs = 0; runs < NUMBER_OF_RUNS; runs++) { SuggestBuilder suggestBuilder = randomSuggestBuilder(); XContentBuilder xContentBuilder = XContentFactory.contentBuilder(randomFrom(XContentType.values())); if (randomBoolean()) { xContentBuilder.prettyPrint(); } suggestBuilder.toXContent(xContentBuilder, ToXContent.EMPTY_PARAMS); XContentParser parser = createParser(xContentBuilder); SuggestBuilder secondSuggestBuilder = SuggestBuilder.fromXContent(parser); assertNotSame(suggestBuilder, secondSuggestBuilder); assertEquals(suggestBuilder, secondSuggestBuilder); assertEquals(suggestBuilder.hashCode(), secondSuggestBuilder.hashCode()); } } /** * Test equality and hashCode properties */ public void testEqualsAndHashcode() throws IOException { for (int runs = 0; runs < NUMBER_OF_RUNS; runs++) { checkEqualsAndHashCode(randomSuggestBuilder(), original -> { return copyWriteable(original, namedWriteableRegistry, SuggestBuilder::new); }, this::createMutation); } } /** * Test serialization and deserialization */ public void testSerialization() throws IOException { for (int i = 0; i < NUMBER_OF_RUNS; i++) { SuggestBuilder suggestBuilder = randomSuggestBuilder(); SuggestBuilder deserializedModel = copyWriteable(suggestBuilder, namedWriteableRegistry, SuggestBuilder::new); assertEquals(suggestBuilder, deserializedModel); assertEquals(suggestBuilder.hashCode(), deserializedModel.hashCode()); assertNotSame(suggestBuilder, deserializedModel); } } public void testIllegalSuggestionName() { try { new SuggestBuilder().addSuggestion(null, PhraseSuggestionBuilderTests.randomPhraseSuggestionBuilder()); fail("exception expected"); } catch (NullPointerException e) { assertEquals("every suggestion needs a name", e.getMessage()); } try { new SuggestBuilder().addSuggestion("my-suggest", PhraseSuggestionBuilderTests.randomPhraseSuggestionBuilder()) .addSuggestion("my-suggest", PhraseSuggestionBuilderTests.randomPhraseSuggestionBuilder()); fail("exception expected"); } catch (IllegalArgumentException e) { assertEquals("already added another suggestion with name [my-suggest]", e.getMessage()); } } protected SuggestBuilder createMutation(SuggestBuilder original) throws IOException { SuggestBuilder mutation = new SuggestBuilder().setGlobalText(original.getGlobalText()); for (Entry<String, SuggestionBuilder<?>> suggestionBuilder : original.getSuggestions().entrySet()) { mutation.addSuggestion(suggestionBuilder.getKey(), suggestionBuilder.getValue()); } if (randomBoolean()) { mutation.setGlobalText(randomAlphaOfLengthBetween(5, 60)); } else { mutation.addSuggestion(randomAlphaOfLength(10), PhraseSuggestionBuilderTests.randomPhraseSuggestionBuilder()); } return mutation; } public static SuggestBuilder randomSuggestBuilder() { SuggestBuilder builder = new SuggestBuilder(); if (randomBoolean()) { builder.setGlobalText(randomAlphaOfLengthBetween(1, 20)); } final int numSuggestions = randomIntBetween(1, 5); for (int i = 0; i < numSuggestions; i++) { builder.addSuggestion(randomAlphaOfLengthBetween(5, 10), randomSuggestionBuilder()); } return builder; } private static SuggestionBuilder<?> randomSuggestionBuilder() { switch (randomIntBetween(0, 2)) { case 0: return TermSuggestionBuilderTests.randomTermSuggestionBuilder(); case 1: return PhraseSuggestionBuilderTests.randomPhraseSuggestionBuilder(); case 2: return CompletionSuggesterBuilderTests.randomCompletionSuggestionBuilder(); default: return TermSuggestionBuilderTests.randomTermSuggestionBuilder(); } } @Override protected NamedXContentRegistry xContentRegistry() { return xContentRegistry; } }