12fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood/*
22fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood * Copyright (C) 2010 The Android Open Source Project
32fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood *
42fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood * Licensed under the Apache License, Version 2.0 (the "License");
52fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood * you may not use this file except in compliance with the License.
62fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood * You may obtain a copy of the License at
72fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood *
82fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood *      http://www.apache.org/licenses/LICENSE-2.0
92fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood *
102fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood * Unless required by applicable law or agreed to in writing, software
112fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood * distributed under the License is distributed on an "AS IS" BASIS,
122fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
132fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood * See the License for the specific language governing permissions and
142fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood * limitations under the License.
152fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood */
162fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood
172fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwoodpackage com.android.quicksearchbox;
182fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood
19132a8afcb4970d1b783a6dba7944dc0dd5063101Mathew Inwoodimport com.android.quicksearchbox.MockTextAppearanceFactory.MockStyleSpan;
20f16bea9765ee9838d316655d38cb51b72a3b4acbBjorn Bringertimport com.android.quicksearchbox.util.LevenshteinDistance.Token;
21132a8afcb4970d1b783a6dba7944dc0dd5063101Mathew Inwood
222fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwoodimport android.test.AndroidTestCase;
23f16bea9765ee9838d316655d38cb51b72a3b4acbBjorn Bringertimport android.test.suitebuilder.annotation.SmallTest;
242fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwoodimport android.text.Spanned;
252fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood
262fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood/**
272fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood * Tests for {@link LevenshteinSuggestionFormatter}.
282fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood */
29f16bea9765ee9838d316655d38cb51b72a3b4acbBjorn Bringert@SmallTest
302fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwoodpublic class LevenshteinFormatterTest extends AndroidTestCase {
312fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood
322fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood    private LevenshteinSuggestionFormatter mFormatter;
332fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood    private int mSuggestedStyle;
342fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood    private int mQueryStyle;
352fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood
362fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood    @Override
372fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood    protected void setUp() throws Exception {
38132a8afcb4970d1b783a6dba7944dc0dd5063101Mathew Inwood        mFormatter = new LevenshteinSuggestionFormatter(new MockTextAppearanceFactory());
39132a8afcb4970d1b783a6dba7944dc0dd5063101Mathew Inwood        mSuggestedStyle = MockTextAppearanceFactory.ID_SUGGESTED_TEXT;
40132a8afcb4970d1b783a6dba7944dc0dd5063101Mathew Inwood        mQueryStyle = MockTextAppearanceFactory.ID_QUERY_TEXT;
412fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood    }
422fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood
432fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood    private void verifyTokenizeResult(String input, String... output) {
44f16bea9765ee9838d316655d38cb51b72a3b4acbBjorn Bringert        Token[] tokens = mFormatter.tokenize(input);
45fbbf9be564b7675b2986dea38babfcbe55e5694bMathew Inwood        assertEquals(output.length, tokens.length);
462fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood        for (int i=0; i<output.length; ++i) {
47fbbf9be564b7675b2986dea38babfcbe55e5694bMathew Inwood            assertEquals(output[i], tokens[i].toString());
482fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood        }
492fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood    }
502fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood
512fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood    public void testTokenizeNoTokens() {
522fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood        verifyTokenizeResult("");
532fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood        verifyTokenizeResult("  ");
542fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood    }
552fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood
562fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood    public void testTokenizeSingleToken() {
572fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood        verifyTokenizeResult("singleToken", "singleToken");
582fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood    }
592fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood
602fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood    public void testTokenizeTwoTokens() {
612fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood        verifyTokenizeResult("two tokens", "two", "tokens");
622fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood    }
632fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood
642fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood    public void testTokenizeLeadingSpaces() {
652fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood        verifyTokenizeResult(" evil kittens", "evil", "kittens");
662fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood        verifyTokenizeResult("        furry lizards", "furry", "lizards");
672fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood    }
682fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood
692fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood    public void testTokenizeTrailingSpaces() {
702fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood        verifyTokenizeResult("mechanical elephant ", "mechanical", "elephant");
712fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood        verifyTokenizeResult("disappointed dog       ", "disappointed", "dog");
722fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood    }
732fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood
742fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood    public void testTokenizeManySpaces() {
752fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood        verifyTokenizeResult("happy     horses", "happy", "horses");
762fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood    }
772fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood
782fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood    public void testTokenizeLongSentence() {
792fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood        verifyTokenizeResult("The fool looks at a finger that points at the sky",
802fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood                "The", "fool", "looks", "at", "a", "finger", "that", "points", "at", "the", "sky");
812fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood    }
822fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood
832fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood    public void testTokenizeWithPunctuation() {
842fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood        verifyTokenizeResult("Hitchhiker's guide", "Hitchhiker's", "guide");
852fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood        verifyTokenizeResult("full. stop. ", "full.", "stop.");
862fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood        verifyTokenizeResult("' . ; . ..", "'", ".", ";", ".", "..");
872fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood    }
882fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood
89f16bea9765ee9838d316655d38cb51b72a3b4acbBjorn Bringert    public void testTokenizeWithTabs() {
90f16bea9765ee9838d316655d38cb51b72a3b4acbBjorn Bringert        verifyTokenizeResult("paranoid\tandroid\t", "paranoid", "android");
912fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood    }
922fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood
932fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood    private void verifyFindMatches(String source, String target, String... newTokensInTarget) {
94f16bea9765ee9838d316655d38cb51b72a3b4acbBjorn Bringert        Token[] sourceTokens = mFormatter.tokenize(source);
95f16bea9765ee9838d316655d38cb51b72a3b4acbBjorn Bringert        Token[] targetTokens = mFormatter.tokenize(target);
962fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood
972fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood        int[] matches = mFormatter.findMatches(sourceTokens, targetTokens);
98fbbf9be564b7675b2986dea38babfcbe55e5694bMathew Inwood        assertEquals(targetTokens.length, matches.length);
992fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood        int newTokenCount = 0;
1002fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood        int lastSourceToken = -1;
101fbbf9be564b7675b2986dea38babfcbe55e5694bMathew Inwood        for (int i=0; i<targetTokens.length; ++i) {
1022fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood
1032fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood            int sourceIdx = matches[i];
1042fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood            if (sourceIdx < 0) {
105fbbf9be564b7675b2986dea38babfcbe55e5694bMathew Inwood                String targetToken = targetTokens[i].toString();
1062fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood                assertTrue("Unexpected new token '" + targetToken + "'",
1072fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood                        newTokenCount < newTokensInTarget.length);
1082fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood
1092fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood                assertEquals(newTokensInTarget[newTokenCount], targetToken);
1102fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood                ++newTokenCount;
1112fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood            } else {
1122fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood                assertTrue("Source token out of order", lastSourceToken < sourceIdx);
113f16bea9765ee9838d316655d38cb51b72a3b4acbBjorn Bringert                Token srcToken = sourceTokens[sourceIdx];
114f16bea9765ee9838d316655d38cb51b72a3b4acbBjorn Bringert                Token trgToken = targetTokens[i];
1152fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood                assertTrue("'" + srcToken + "' is not a prefix of '" + trgToken + "'",
1162fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood                        srcToken.prefixOf(trgToken));
1172fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood                lastSourceToken = sourceIdx;
1182fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood            }
1192fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood        }
1202fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood    }
1212fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood
1222fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood    public void testFindMatchesSameTokens() {
1232fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood        verifyFindMatches("", "");
1242fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood        verifyFindMatches("one", "one");
1252fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood        verifyFindMatches("one two three", "one two three");
1262fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood    }
1272fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood
1282fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood    public void testFindMatchesNewTokens() {
1292fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood        verifyFindMatches("", "one", "one");
1302fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood        verifyFindMatches("one", "one two", "two");
1312fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood        verifyFindMatches("one", "one two three", "two", "three");
1322fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood        verifyFindMatches("two", "one two three", "one", "three");
1332fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood        verifyFindMatches("pictures", "pictures of kittens", "of", "kittens");
1342fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood    }
1352fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood
1362fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood    public void testFindMatchesReplacedTokens() {
1372fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood        verifyFindMatches("one", "two", "two");
1382fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood        verifyFindMatches("one", "two three", "two", "three");
1392fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood        verifyFindMatches("two", "one three", "one", "three");
1402fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood        verifyFindMatches("pictures", "of kittens", "of", "kittens");
1412fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood    }
1422fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood
1432fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood    public void testFindMatchesDuplicateTokens() {
1442fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood        verifyFindMatches("badger", "badger badger", "badger");
1452fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood        verifyFindMatches("badger", "badger badger badger", "badger", "badger");
1462fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood        verifyFindMatches("badger badger", "badger badger badger", "badger");
1472fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood        verifyFindMatches("badger badger badger", "badger badger badger");
1482fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood        // mushroom!
1492fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood    }
1502fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood
1512fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood    private void verifyFormatSuggestion(String query, String suggestion, SpanFormat... spans) {
1522fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood        Spanned s = mFormatter.formatSuggestion(query, suggestion);
1532fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood        for (SpanFormat span : spans) {
1542fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood            span.verify(s);
1552fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood        }
1562fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood    }
1572fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood
1582fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood    public void testFormatSuggestionEmptyStrings() {
1592fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood        verifyFormatSuggestion("", "");
1602fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood    }
1612fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood
1622fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood    public void testFormatSuggestionEmptyQuery() {
1632fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood        verifyFormatSuggestion("", "suggestion",
1642fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood                new SpanFormat(0, "suggestion", mSuggestedStyle));
1652fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood    }
1662fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood
1672fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood    public void testFormatSuggestionQuerySuggested() {
1682fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood        verifyFormatSuggestion("query", "query",
1692fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood                new SpanFormat(0, "query", mQueryStyle));
1702fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood    }
1712fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood
1722fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood    public void testFormatSuggestionExtraWordsSuggested() {
1732fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood        verifyFormatSuggestion("query", "query suggested",
1742fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood                new SpanFormat(0, "query", mQueryStyle),
1752fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood                new SpanFormat(6, "suggested", mSuggestedStyle));
1762fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood
1772fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood        verifyFormatSuggestion("pictures", "pictures of kittens",
1782fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood                new SpanFormat(0,  "pictures", mQueryStyle),
1792fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood                new SpanFormat(9,  "of", mSuggestedStyle),
1802fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood                new SpanFormat(12, "kittens", mSuggestedStyle));
1812fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood
1822fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood        verifyFormatSuggestion("pictures of", "pictures of kittens dying",
1832fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood                new SpanFormat(0,  "pictures", mQueryStyle),
1842fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood                new SpanFormat(9,  "of", mQueryStyle),
1852fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood                new SpanFormat(12, "kittens", mSuggestedStyle),
1862fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood                new SpanFormat(20, "dying", mSuggestedStyle));
1872fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood    }
1882fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood
1892fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood    public void testFormatSuggestionExtraWordSuggestedAtStart() {
1902fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood        verifyFormatSuggestion("query", "suggested query",
1912fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood                new SpanFormat(0, "suggested", mSuggestedStyle),
1922fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood                new SpanFormat(10, "query", mQueryStyle));
1932fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood    }
1942fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood
1952fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood    public void testFormatSuggestionAlternativeWordSuggested() {
1962fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood        verifyFormatSuggestion("query", "suggested",
1972fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood                new SpanFormat(0, "suggested", mSuggestedStyle));
1982fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood    }
1992fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood
2002fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood    public void testFormatSuggestionDuplicateWords() {
2012fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood        verifyFormatSuggestion("", "badger badger",
2022fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood                new SpanFormat(0, "badger", mSuggestedStyle),
2032fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood                new SpanFormat(7, "badger", mSuggestedStyle));
2042fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood
2052fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood        verifyFormatSuggestion("badger", "badger badger",
2062fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood                new SpanFormat(0, "badger", mQueryStyle),
2072fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood                new SpanFormat(7, "badger", mSuggestedStyle));
2082fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood
2092fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood        verifyFormatSuggestion("badger badger", "badger badger",
2102fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood                new SpanFormat(0, "badger", mQueryStyle),
2112fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood                new SpanFormat(7, "badger", mQueryStyle));
2122fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood
2132fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood        verifyFormatSuggestion("badger badger", "badger badger badger",
2142fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood                new SpanFormat(0, "badger", mQueryStyle),
2152fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood                new SpanFormat(7, "badger", mQueryStyle),
2162fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood                new SpanFormat(14, "badger", mSuggestedStyle));
2172fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood    }
2182fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood
2192fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood    public void testFormatSuggestionDuplicateSequences() {
2202fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood        verifyFormatSuggestion("dem bones", "dem bones dem bones",
2212fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood                new SpanFormat(0, "dem", mQueryStyle),
2222fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood                new SpanFormat(4, "bones", mQueryStyle),
2232fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood                new SpanFormat(10, "dem", mSuggestedStyle),
2242fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood                new SpanFormat(14, "bones", mSuggestedStyle)
2252fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood        );
2262fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood
2272fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood        verifyFormatSuggestion("dem bones", "dem dry bones dem bones",
2282fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood                new SpanFormat(0, "dem", mQueryStyle),
2292fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood                new SpanFormat(4, "dry", mSuggestedStyle),
2302fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood                new SpanFormat(8, "bones", mQueryStyle),
2312fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood                new SpanFormat(14, "dem", mSuggestedStyle),
2322fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood                new SpanFormat(18, "bones", mSuggestedStyle)
2332fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood        );
2342fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood
2352fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood        verifyFormatSuggestion("dem dry bones", "dry bones dem dry bones dem dry bones",
2362fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood                new SpanFormat(0, "dry", mSuggestedStyle),
2372fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood                new SpanFormat(4, "bones", mSuggestedStyle),
2382fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood                new SpanFormat(10, "dem", mQueryStyle),
2392fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood                new SpanFormat(14, "dry", mQueryStyle),
2402fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood                new SpanFormat(18, "bones", mQueryStyle),
2412fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood                new SpanFormat(24, "dem", mSuggestedStyle),
2422fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood                new SpanFormat(28, "dry", mSuggestedStyle),
2432fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood                new SpanFormat(32, "bones", mSuggestedStyle)
2442fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood        );
2452fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood    }
2462fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood
2472fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood    public void testFormatSuggestionWordCompletion() {
2482fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood        verifyFormatSuggestion("hitch", "hitchhiker",
2492fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood                new SpanFormat(0, "hitch", mQueryStyle),
2502fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood                new SpanFormat(5, "hiker", mSuggestedStyle)
2512fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood        );
2522fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood
2532fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood        verifyFormatSuggestion("hitch", "hitchhiker's guide",
2542fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood                new SpanFormat(0, "hitch", mQueryStyle),
2552fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood                new SpanFormat(5, "hiker's", mSuggestedStyle),
2562fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood                new SpanFormat(13, "guide", mSuggestedStyle)
2572fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood        );
2582fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood
2592fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood        verifyFormatSuggestion("hitchhiker's g", "hitchhiker's guide",
2602fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood                new SpanFormat(0, "hitchhiker's", mQueryStyle),
2612fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood                new SpanFormat(13, "g", mQueryStyle),
2622fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood                new SpanFormat(14, "uide", mSuggestedStyle)
2632fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood        );
2642fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood
2652fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood        verifyFormatSuggestion("hitchhiker's g", "hitchhiker's guide to the galaxy",
2662fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood                new SpanFormat(0, "hitchhiker's", mQueryStyle),
2672fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood                new SpanFormat(13, "g", mQueryStyle),
2682fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood                new SpanFormat(14, "uide", mSuggestedStyle),
2692fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood                new SpanFormat(19, "to", mSuggestedStyle),
2702fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood                new SpanFormat(22, "the", mSuggestedStyle),
2712fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood                new SpanFormat(26, "galaxy", mSuggestedStyle)
2722fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood        );
2732fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood    }
2742fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood
2752fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood    public void testFormatSuggestionWordSplitting() {
2762fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood        verifyFormatSuggestion("dimsum", "dim sum",
2772fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood                new SpanFormat(0, "dim", mSuggestedStyle),
2782fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood                new SpanFormat(4, "sum", mSuggestedStyle)
2792fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood        );
2802fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood
2812fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood        verifyFormatSuggestion("dimsum london", "dim sum london",
2822fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood                new SpanFormat(0, "dim", mSuggestedStyle),
2832fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood                new SpanFormat(4, "sum", mSuggestedStyle),
2842fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood                new SpanFormat(8, "london", mQueryStyle)
2852fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood        );
2862fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood
2872fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood        verifyFormatSuggestion("dimsum london", "dim sum london yummy",
2882fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood                new SpanFormat(0, "dim", mSuggestedStyle),
2892fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood                new SpanFormat(4, "sum", mSuggestedStyle),
2902fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood                new SpanFormat(8, "london", mQueryStyle),
2912fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood                new SpanFormat(15, "yummy", mSuggestedStyle)
2922fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood        );
2932fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood    }
2942fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood
2952fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood    public void testFormatSuggestionWordCombining() {
2962fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood        verifyFormatSuggestion("hos pital", "hospital",
2972fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood                new SpanFormat(0, "hos", mQueryStyle),
2982fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood                new SpanFormat(3, "pital", mSuggestedStyle)
2992fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood        );
3002fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood
3012fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood        verifyFormatSuggestion("hos pital", "hospital waiting times",
3022fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood                new SpanFormat(0, "hos", mQueryStyle),
3032fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood                new SpanFormat(3, "pital", mSuggestedStyle),
3042fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood                new SpanFormat(9, "waiting", mSuggestedStyle),
3052fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood                new SpanFormat(17, "times", mSuggestedStyle)
3062fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood        );
3072fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood
3082fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood        verifyFormatSuggestion("hos pital waiting", "hospital waiting",
3092fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood                new SpanFormat(0, "hos", mQueryStyle),
3102fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood                new SpanFormat(3, "pital", mSuggestedStyle),
3112fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood                new SpanFormat(9, "waiting", mQueryStyle)
3122fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood        );
3132fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood
3142fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood        verifyFormatSuggestion("hospital wait ing times", "hospital waiting times",
3152fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood                new SpanFormat(0, "hospital", mQueryStyle),
3162fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood                new SpanFormat(9, "wait", mQueryStyle),
3172fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood                new SpanFormat(13, "ing", mSuggestedStyle),
3182fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood                new SpanFormat(17, "times", mQueryStyle)
3192fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood        );
3202fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood    }
3212fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood
3222fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood    public void testFormatSuggestionCapitalization() {
3232fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood        verifyFormatSuggestion("Flay", "flay",
3242fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood                new SpanFormat(0, "flay", mQueryStyle));
3252fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood
3262fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood        verifyFormatSuggestion("STEERPI", "steerpike",
3272fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood                new SpanFormat(0, "steerpi", mQueryStyle),
3282fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood                new SpanFormat(7, "ke", mSuggestedStyle));
3292fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood
3302fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood        verifyFormatSuggestion("STEErpi", "steerpike",
3312fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood                new SpanFormat(0, "steerpi", mQueryStyle),
3322fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood                new SpanFormat(7, "ke", mSuggestedStyle));
3332fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood
3342fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood        verifyFormatSuggestion("TITUS", "titus groan",
3352fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood                new SpanFormat(0, "titus", mQueryStyle),
3362fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood                new SpanFormat(6, "groan", mSuggestedStyle));
3372fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood}
3382fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood
3392fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood    private class SpanFormat {
3402fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood        private final int mStart;
3412fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood        private final int mEnd;
3422fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood        private final String mExpectedText;
3432fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood        private final int mStyle;
3442fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood        public SpanFormat(int start, String expectedText, int style) {
3452fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood            mStart = start;
3462fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood            mEnd = start + expectedText.length();
3472fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood            mExpectedText = expectedText;
3482fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood            mStyle = style;
3492fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood        }
3502fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood        public void verify(Spanned spanned) {
3512fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood            String spannedText = spanned.subSequence(mStart, mEnd).toString();
3522fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood            assertEquals("Test error", mExpectedText, spannedText);
353132a8afcb4970d1b783a6dba7944dc0dd5063101Mathew Inwood            MockStyleSpan[] spans = spanned.getSpans(mStart, mEnd, MockStyleSpan.class);
3542fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood            assertEquals("Wrong number of spans in '" + spannedText + "'", 1, spans.length);
3552fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood            assertEquals("Wrong style for '" + spannedText + "' at position " + mStart,
356132a8afcb4970d1b783a6dba7944dc0dd5063101Mathew Inwood                    mStyle, spans[0].getId());
3572fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood        }
3582fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood    }
3592fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood
3602fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood}
361