Java tutorial
/* * Copyright 2015 Zachar Prychoda * * Licensed 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 com.pryzach.suggestions.service.impl; import com.pryzach.suggestions.SuggestionFactory; import com.pryzach.suggestions.model.Word; import com.pryzach.suggestions.model.WordRTL; import com.pryzach.suggestions.service.SuggestionService; import junit.framework.TestCase; import org.apache.commons.lang3.RandomStringUtils; import org.junit.Assert; import java.math.BigDecimal; import java.util.*; public class SuggestionServiceImplTest extends TestCase { private final Random random = new Random(); public void testAddWords() throws Exception { SuggestionService suggestionService = SuggestionFactory.getSuggestionService(); String[] suggestedWordsArray; String suggestedWordsString; String[] suggestedNextLettersArray; String suggestedNextLettersString; // two success words is deliberate suggestionService.addWords(new HashSet<>(Arrays.asList(new Word("success", 10), new Word("success", 10), new Word("succubus-long_one here", 9), new Word("success-very-unpopular", 1)))); suggestedWordsString = suggestionService.suggest("succ", "|", 2); suggestedNextLettersString = suggestionService.suggestNextLetter("succ", suggestedWordsString, "|"); Assert.assertEquals("success|succubus-long_one here", suggestedWordsString); Assert.assertEquals("e|u", suggestedNextLettersString); suggestedWordsArray = suggestionService.suggest("succ", 2); suggestedNextLettersArray = suggestionService.suggestNextLetter("succ", suggestedWordsArray); Assert.assertArrayEquals(suggestedWordsArray, new String[] { "success", "succubus-long_one here" }); Assert.assertArrayEquals(suggestedNextLettersArray, new String[] { "e", "u" }); } public void testSuggestEngine() throws Exception { SuggestionService suggestionService = SuggestionFactory.getSuggestionService(); String[] suggestedWordsArray; String suggestedWordsString; String[] suggestedNextLettersArray; String suggestedNextLettersString; suggestedWordsString = suggestionService.suggest("succes", "|", 10); suggestedNextLettersString = suggestionService.suggestNextLetter("succes", suggestedWordsString, "|"); Assert.assertEquals("", suggestedWordsString); Assert.assertEquals("", suggestedNextLettersString); suggestedWordsArray = suggestionService.suggest("succes", 10); suggestedNextLettersArray = suggestionService.suggestNextLetter("succes", suggestedWordsArray); Assert.assertEquals(0, suggestedWordsArray.length); Assert.assertEquals(0, suggestedNextLettersArray.length); suggestionService.addWord(new Word("success", 10)); suggestedWordsString = suggestionService.suggest("succes", "|", 10); suggestedNextLettersString = suggestionService.suggestNextLetter("succes", suggestedWordsString, "|"); Assert.assertEquals("success", suggestedWordsString); Assert.assertEquals("s", suggestedNextLettersString); suggestedWordsArray = suggestionService.suggest("succes", 10); suggestedNextLettersArray = suggestionService.suggestNextLetter("succes", suggestedWordsArray); Assert.assertArrayEquals(suggestedWordsArray, new String[] { "success" }); Assert.assertArrayEquals(suggestedNextLettersArray, new String[] { "s" }); suggestionService.addWord(new Word("confusuccess", 10)); suggestedWordsString = suggestionService.suggest("succ", "|", 10); suggestedNextLettersString = suggestionService.suggestNextLetter("succ", suggestedWordsString, "|"); Assert.assertEquals("success", suggestedWordsString); Assert.assertEquals("e", suggestedNextLettersString); suggestedWordsArray = suggestionService.suggest("succ", 10); suggestedNextLettersArray = suggestionService.suggestNextLetter("succ", suggestedWordsArray); Assert.assertArrayEquals(suggestedWordsArray, new String[] { "success" }); Assert.assertArrayEquals(suggestedNextLettersArray, new String[] { "e" }); suggestionService.addWord(new Word("succubus-long_one here", 1)); suggestedWordsString = suggestionService.suggest("succ", "|", 10); suggestedNextLettersString = suggestionService.suggestNextLetter("succ", suggestedWordsString, "|"); Assert.assertEquals("success|succubus-long_one here", suggestedWordsString); Assert.assertEquals("e|u", suggestedNextLettersString); suggestedWordsArray = suggestionService.suggest("succ", 10); suggestedNextLettersArray = suggestionService.suggestNextLetter("succ", suggestedWordsArray); Assert.assertArrayEquals(suggestedWordsArray, new String[] { "success", "succubus-long_one here" }); Assert.assertArrayEquals(suggestedNextLettersArray, new String[] { "e", "u" }); suggestionService.addWord(new Word("sucks-if-this-will-appear-in-results", 10)); suggestedWordsString = suggestionService.suggest("succ", "|", 10); suggestedNextLettersString = suggestionService.suggestNextLetter("succ", suggestedWordsString, "|"); Assert.assertEquals("success|succubus-long_one here", suggestedWordsString); Assert.assertEquals("e|u", suggestedNextLettersString); suggestedWordsArray = suggestionService.suggest("succ", 10); suggestedNextLettersArray = suggestionService.suggestNextLetter("succ", suggestedWordsArray); Assert.assertArrayEquals(suggestedWordsArray, new String[] { "success", "succubus-long_one here" }); Assert.assertArrayEquals(suggestedNextLettersArray, new String[] { "e", "u" }); suggestionService.addWord(new Word("success-very-popular", 100)); suggestedWordsString = suggestionService.suggest("succ", "|", 10); suggestedNextLettersString = suggestionService.suggestNextLetter("succ", suggestedWordsString, "|"); Assert.assertEquals("success-very-popular|success|succubus-long_one here", suggestedWordsString); Assert.assertEquals("e|u", suggestedNextLettersString); suggestedWordsArray = suggestionService.suggest("succ", 10); suggestedNextLettersArray = suggestionService.suggestNextLetter("succ", suggestedWordsArray); Assert.assertArrayEquals(suggestedWordsArray, new String[] { "success-very-popular", "success", "succubus-long_one here" }); Assert.assertArrayEquals(suggestedNextLettersArray, new String[] { "e", "u" }); suggestedWordsString = suggestionService.suggest("succ", "|", 2); suggestedNextLettersString = suggestionService.suggestNextLetter("succ", suggestedWordsString, "|"); Assert.assertEquals("success-very-popular|success", suggestedWordsString); Assert.assertEquals("e", suggestedNextLettersString); suggestedWordsArray = suggestionService.suggest("succ", 2); suggestedNextLettersArray = suggestionService.suggestNextLetter("succ", suggestedWordsArray); Assert.assertArrayEquals(suggestedWordsArray, new String[] { "success-very-popular", "success" }); Assert.assertArrayEquals(suggestedNextLettersArray, new String[] { "e" }); // starting to test selectors which exceed caching max length suggestedWordsString = suggestionService.suggest("success-very-", "|", 2); suggestedNextLettersString = suggestionService.suggestNextLetter("success-very-", suggestedWordsString, "|"); Assert.assertEquals("success-very-popular", suggestedWordsString); Assert.assertEquals("p", suggestedNextLettersString); suggestedWordsArray = suggestionService.suggest("success-very-", 2); suggestedNextLettersArray = suggestionService.suggestNextLetter("success-very-", suggestedWordsArray); Assert.assertArrayEquals(suggestedWordsArray, new String[] { "success-very-popular" }); Assert.assertArrayEquals(suggestedNextLettersArray, new String[] { "p" }); suggestionService.addWord(new Word("success-very-long", 101)); suggestedWordsString = suggestionService.suggest("success-very-", "|", 2); suggestedNextLettersString = suggestionService.suggestNextLetter("success-very-", suggestedWordsString, "|"); Assert.assertEquals("success-very-long|success-very-popular", suggestedWordsString); Assert.assertEquals("l|p", suggestedNextLettersString); suggestedWordsArray = suggestionService.suggest("success-very-", 2); suggestedNextLettersArray = suggestionService.suggestNextLetter("success-very-", suggestedWordsArray); Assert.assertArrayEquals(suggestedWordsArray, new String[] { "success-very-long", "success-very-popular" }); Assert.assertArrayEquals(suggestedNextLettersArray, new String[] { "l", "p" }); suggestionService.addWord(new Word("success-very-boring", 1)); suggestedWordsString = suggestionService.suggest("success-very-", "|", 2); suggestedNextLettersString = suggestionService.suggestNextLetter("success-very-", suggestedWordsString, "|"); Assert.assertEquals("success-very-long|success-very-popular", suggestedWordsString); Assert.assertEquals("l|p", suggestedNextLettersString); suggestedWordsArray = suggestionService.suggest("success-very-", 2); suggestedNextLettersArray = suggestionService.suggestNextLetter("success-very-", suggestedWordsArray); Assert.assertArrayEquals(suggestedWordsArray, new String[] { "success-very-long", "success-very-popular" }); Assert.assertArrayEquals(suggestedNextLettersArray, new String[] { "l", "p" }); // confirmation that white spaces are supported suggestionService.addWord(new Word("success with whitespaces", 1)); suggestedWordsString = suggestionService.suggest("success", "|", 4); suggestedNextLettersString = suggestionService.suggestNextLetter("success", suggestedWordsString, "|"); Assert.assertEquals("success-very-long|success-very-popular|success-very-boring|success with whitespaces", suggestedWordsString); Assert.assertEquals("-| ", suggestedNextLettersString); suggestedWordsArray = suggestionService.suggest("success", 4); suggestedNextLettersArray = suggestionService.suggestNextLetter("success", suggestedWordsArray); Assert.assertArrayEquals(suggestedWordsArray, new String[] { "success-very-long", "success-very-popular", "success-very-boring", "success with whitespaces" }); Assert.assertArrayEquals(suggestedNextLettersArray, new String[] { "-", " " }); // confirmation that implementation is case insensitive suggestionService.addWord(new Word("SucCEss_with-different case", 2)); suggestedWordsString = suggestionService.suggest("success", "|", 5); suggestedNextLettersString = suggestionService.suggestNextLetter("success", suggestedWordsString, "|"); Assert.assertEquals( "success-very-long|success-very-popular|SucCEss_with-different case|success-very-boring|success with whitespaces", suggestedWordsString); Assert.assertEquals("-|_| ", suggestedNextLettersString); suggestedWordsArray = suggestionService.suggest("success", 5); suggestedNextLettersArray = suggestionService.suggestNextLetter("success", suggestedWordsArray); Assert.assertArrayEquals(suggestedWordsArray, new String[] { "success-very-long", "success-very-popular", "SucCEss_with-different case", "success-very-boring", "success with whitespaces" }); Assert.assertArrayEquals(suggestedNextLettersArray, new String[] { "-", "_", " " }); } public void testInternationalSupport() { SuggestionService suggestionService = SuggestionFactory.getSuggestionService(); String[] suggestedWordsArray; String suggestedWordsString; String[] suggestedNextLettersArray; String suggestedNextLettersString; // spanish suggestionService.addWord(new Word("xito", 10)); suggestedWordsString = suggestionService.suggest("xi", "|", 10); suggestedNextLettersString = suggestionService.suggestNextLetter("xi", suggestedWordsString, "|"); Assert.assertEquals("xito", suggestedWordsString); Assert.assertEquals("t", suggestedNextLettersString); suggestedWordsArray = suggestionService.suggest("xi", 10); suggestedNextLettersArray = suggestionService.suggestNextLetter("xi", suggestedWordsArray); Assert.assertArrayEquals(suggestedWordsArray, new String[] { "xito" }); Assert.assertArrayEquals(suggestedNextLettersArray, new String[] { "t" }); // german suggestionService.addWord(new Word("gromutter", 10)); suggestedWordsString = suggestionService.suggest("gro", "|", 10); suggestedNextLettersString = suggestionService.suggestNextLetter("gro", suggestedWordsString, "|"); Assert.assertEquals("gromutter", suggestedWordsString); Assert.assertEquals("", suggestedNextLettersString); suggestedWordsArray = suggestionService.suggest("gro", 10); suggestedNextLettersArray = suggestionService.suggestNextLetter("gro", suggestedWordsArray); Assert.assertArrayEquals(suggestedWordsArray, new String[] { "gromutter" }); Assert.assertArrayEquals(suggestedNextLettersArray, new String[] { "" }); // swedish suggestionService.addWord(new Word("framgng", 10)); suggestedWordsString = suggestionService.suggest("fra", "|", 10); suggestedNextLettersString = suggestionService.suggestNextLetter("fra", suggestedWordsString, "|"); Assert.assertEquals("framgng", suggestedWordsString); Assert.assertEquals("m", suggestedNextLettersString); suggestedWordsArray = suggestionService.suggest("fra", 10); suggestedNextLettersArray = suggestionService.suggestNextLetter("fra", suggestedWordsArray); Assert.assertArrayEquals(suggestedWordsArray, new String[] { "framgng" }); Assert.assertArrayEquals(suggestedNextLettersArray, new String[] { "m" }); // russian (cyrillic) suggestionService.addWord(new Word("?", 10)); suggestedWordsString = suggestionService.suggest("?", "|", 10); suggestedNextLettersString = suggestionService.suggestNextLetter("?", suggestedWordsString, "|"); Assert.assertEquals("?", suggestedWordsString); Assert.assertEquals("", suggestedNextLettersString); suggestedWordsArray = suggestionService.suggest("?", 10); suggestedNextLettersArray = suggestionService.suggestNextLetter("?", suggestedWordsArray); Assert.assertArrayEquals(suggestedWordsArray, new String[] { "?" }); Assert.assertArrayEquals(suggestedNextLettersArray, new String[] { "" }); // turkish suggestionService.addWord(new Word("baar", 10)); suggestedWordsString = suggestionService.suggest("ba", "|", 10); suggestedNextLettersString = suggestionService.suggestNextLetter("ba", suggestedWordsString, "|"); Assert.assertEquals("baar", suggestedWordsString); Assert.assertEquals("", suggestedNextLettersString); suggestedWordsArray = suggestionService.suggest("ba", 10); suggestedNextLettersArray = suggestionService.suggestNextLetter("ba", suggestedWordsArray); Assert.assertArrayEquals(suggestedWordsArray, new String[] { "baar" }); Assert.assertArrayEquals(suggestedNextLettersArray, new String[] { "" }); // experimental support of RTL languages, please contact me if you if you want to improve / extend current implementation // RTL languages implementation doesn't provide "next word" functionality, but if you need it - please let me know and I will add it immediately // arabic 1 suggestionService.addWord(new WordRTL("", 10)); WordRTL[] suggestedWordsRLTArray = suggestionService.suggest(new WordRTL(""), 10); suggestedWordsString = suggestionService.suggest(new WordRTL(""), "|", 10); Assert.assertEquals(1, suggestedWordsRLTArray.length); Assert.assertArrayEquals(new String[] { suggestedWordsRLTArray[0].getName() }, new String[] { "" }); Assert.assertEquals(suggestedWordsString, ""); // arabic 2 suggestionService.addWord(new WordRTL("", 11)); suggestedWordsRLTArray = suggestionService.suggest(new WordRTL(""), 10); suggestedWordsString = suggestionService.suggest(new WordRTL(""), "|", 10); Assert.assertEquals(2, suggestedWordsRLTArray.length); Assert.assertArrayEquals( new String[] { suggestedWordsRLTArray[0].getName(), suggestedWordsRLTArray[1].getName() }, new String[] { "", "" }); Assert.assertEquals(suggestedWordsString, "" + "|" + ""); // jewish suggestionService.addWord(new WordRTL("", 11)); suggestedWordsRLTArray = suggestionService.suggest(new WordRTL(""), 10); suggestedWordsString = suggestionService.suggest(new WordRTL(""), "|", 10); Assert.assertEquals(1, suggestedWordsRLTArray.length); Assert.assertArrayEquals(new String[] { suggestedWordsRLTArray[0].getName() }, new String[] { "" }); Assert.assertEquals(suggestedWordsString, ""); } public void testSuggestEnginePerformanceAndReliabilityFullOxfordTest() { System.out.println( "The Second Edition of the 20-volume Oxford English Dictionary contains full entries for 171,476 words in current use"); System.out.println("Started adding 171k words, please wait..."); performanceTest(171476); } public void testSuggestEnginePerformanceAndReliabilityTest() { System.out.println("Started adding 10k words, please wait..."); performanceTest(10000); } private void performanceTest(long amount) { SuggestionService suggestionService = SuggestionFactory.getSuggestionService(); String[] suggestedWordsArray; String[] suggestedNextLettersArray; List<String> selectors = new ArrayList<>(); String wordString; long startTime = new Date().getTime(); Set<Word> words = new HashSet<>(); for (int i = 0; i < amount; i++) { wordString = RandomStringUtils.randomAlphabetic(randomInt(3, 10)); words.add(new Word(wordString, randomInt(1, 100))); if (randomInt(0, 5) == 2 && wordString.length() > 3) { selectors.add(wordString.substring(0, wordString.length() - 3)); } } suggestionService.addWords(words); words.clear(); System.out.println( "Added to service [" + amount + "] and took [" + (new Date().getTime() - startTime) + " ms]"); int i = 0; startTime = new Date().getTime(); for (String selector : selectors) { suggestedWordsArray = suggestionService.suggest(selector, 10); // uncomment below to visually confirm matches // if (i % 1000 == 0) System.out.println("Matched [" + selector + "] to [" + result.get("suggestions") + "]"); Assert.assertTrue(suggestedWordsArray.length >= 1); i++; } System.out.println( "Matched: [" + selectors.size() + "] and took [" + (new Date().getTime() - startTime) + " ms] [" + new BigDecimal(((double) new Date().getTime() - startTime) / selectors.size()) .setScale(5, BigDecimal.ROUND_HALF_UP).toString() + " ms] per match and [" + Math.round(1000 / (((double) new Date().getTime() - startTime) / selectors.size())) + " words] per second"); } private int randomInt(int start, int end) { return random.nextInt(end - start) + start; } }