1 /*
2  * Copyright (C) 2013 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.dialer.database;
18 
19 import android.database.MatrixCursor;
20 import android.database.sqlite.SQLiteDatabase;
21 import android.test.suitebuilder.annotation.SmallTest;
22 import android.test.suitebuilder.annotation.Suppress;
23 import android.test.AndroidTestCase;
24 import android.text.TextUtils;
25 import android.util.Log;
26 import android.provider.ContactsContract.CommonDataKinds.Phone;
27 import android.provider.ContactsContract.Contacts;
28 import android.provider.ContactsContract.Data;
29 
30 import com.android.dialer.database.DialerDatabaseHelper;
31 import com.android.dialer.database.DialerDatabaseHelper.ContactNumber;
32 import com.android.dialer.dialpad.SmartDialNameMatcher;
33 import com.android.dialer.dialpad.SmartDialPrefix;
34 
35 import java.lang.Exception;
36 import java.lang.Override;
37 import java.lang.String;
38 import java.util.ArrayList;
39 
40 /**
41  * To run this test, use the command:
42  * adb shell am instrument -w -e class com.android.dialer.database.SmartDialPrefixTest /
43  * com.android.dialer.tests/android.test.InstrumentationTestRunner
44  */
45 @SmallTest
46 public class SmartDialPrefixTest extends AndroidTestCase {
47 
48     private DialerDatabaseHelper mTestHelper;
49 
testIsCountryNanp_CaseInsensitive()50     public void testIsCountryNanp_CaseInsensitive() {
51         assertFalse(SmartDialPrefix.isCountryNanp(null));
52         assertFalse(SmartDialPrefix.isCountryNanp("CN"));
53         assertFalse(SmartDialPrefix.isCountryNanp("HK"));
54         assertFalse(SmartDialPrefix.isCountryNanp("uk"));
55         assertFalse(SmartDialPrefix.isCountryNanp("sg"));
56         assertTrue(SmartDialPrefix.isCountryNanp("US"));
57         assertTrue(SmartDialPrefix.isCountryNanp("CA"));
58         assertTrue(SmartDialPrefix.isCountryNanp("AS"));
59         assertTrue(SmartDialPrefix.isCountryNanp("AI"));
60         assertTrue(SmartDialPrefix.isCountryNanp("AG"));
61         assertTrue(SmartDialPrefix.isCountryNanp("BS"));
62         assertTrue(SmartDialPrefix.isCountryNanp("BB"));
63         assertTrue(SmartDialPrefix.isCountryNanp("bm"));
64         assertTrue(SmartDialPrefix.isCountryNanp("vg"));
65         assertTrue(SmartDialPrefix.isCountryNanp("ky"));
66         assertTrue(SmartDialPrefix.isCountryNanp("dm"));
67         assertTrue(SmartDialPrefix.isCountryNanp("do"));
68         assertTrue(SmartDialPrefix.isCountryNanp("gd"));
69         assertTrue(SmartDialPrefix.isCountryNanp("gu"));
70         assertTrue(SmartDialPrefix.isCountryNanp("jm"));
71         assertTrue(SmartDialPrefix.isCountryNanp("pr"));
72         assertTrue(SmartDialPrefix.isCountryNanp("ms"));
73         assertTrue(SmartDialPrefix.isCountryNanp("mp"));
74         assertTrue(SmartDialPrefix.isCountryNanp("kn"));
75         assertTrue(SmartDialPrefix.isCountryNanp("lc"));
76         assertTrue(SmartDialPrefix.isCountryNanp("vc"));
77         assertTrue(SmartDialPrefix.isCountryNanp("tt"));
78         assertTrue(SmartDialPrefix.isCountryNanp("tc"));
79         assertTrue(SmartDialPrefix.isCountryNanp("vi"));
80     }
81 
82     @Override
setUp()83     protected void setUp() {
84         mTestHelper = DialerDatabaseHelper.getNewInstanceForTest(getContext());
85     }
86 
87     @Override
tearDown()88     protected void tearDown() throws Exception {
89         final SQLiteDatabase db = mTestHelper.getWritableDatabase();
90         mTestHelper.removeAllContacts(db);
91         super.tearDown();
92     }
93 
94     @Suppress
testForNewContacts()95     public void testForNewContacts() {
96     }
97 
98     @Suppress
testForUpdatedContacts()99     public void testForUpdatedContacts() {
100     }
101 
102     @Suppress
testForDeletedContacts()103     public void testForDeletedContacts() {
104     }
105 
106     @Suppress
testSize()107     public void testSize() {
108     }
109 
110 
constructNewNameCursor()111     private MatrixCursor constructNewNameCursor() {
112         final MatrixCursor cursor = new MatrixCursor(new String[]{
113                 DialerDatabaseHelper.SmartDialDbColumns.DISPLAY_NAME_PRIMARY,
114                 DialerDatabaseHelper.SmartDialDbColumns.CONTACT_ID});
115         return cursor;
116     }
117 
constructNewContactCursor()118     private MatrixCursor constructNewContactCursor() {
119         final MatrixCursor cursor = new MatrixCursor(new String[]{
120                     Phone._ID,                          // 0
121                     Phone.TYPE,                         // 1
122                     Phone.LABEL,                        // 2
123                     Phone.NUMBER,                       // 3
124                     Phone.CONTACT_ID,                   // 4
125                     Phone.LOOKUP_KEY,                   // 5
126                     Phone.DISPLAY_NAME_PRIMARY,         // 6
127                     Phone.PHOTO_ID,                     // 7
128                     Data.LAST_TIME_USED,                // 8
129                     Data.TIMES_USED,                    // 9
130                     Contacts.STARRED,                   // 10
131                     Data.IS_SUPER_PRIMARY,              // 11
132                     Contacts.IN_VISIBLE_GROUP,          // 12
133                     Data.IS_PRIMARY});                  // 13
134         return cursor;
135     }
136 
constructNewContactWithDummyIds(MatrixCursor contactCursor, MatrixCursor nameCursor, String number, int id, String displayName)137     private ContactNumber constructNewContactWithDummyIds(MatrixCursor contactCursor,
138             MatrixCursor nameCursor, String number, int id, String displayName) {
139         return constructNewContact(contactCursor, nameCursor, id, number, id, String.valueOf(id),
140                 displayName, 0, 0, 0, 0, 0, 0, 0);
141     }
142 
constructNewContact(MatrixCursor contactCursor, MatrixCursor nameCursor, int id, String number, int contactId, String lookupKey, String displayName, int photoId, int lastTimeUsed, int timesUsed, int starred, int isSuperPrimary, int inVisibleGroup, int isPrimary)143     private ContactNumber constructNewContact(MatrixCursor contactCursor, MatrixCursor nameCursor,
144             int id, String number, int contactId, String lookupKey, String displayName, int photoId,
145             int lastTimeUsed, int timesUsed, int starred, int isSuperPrimary, int inVisibleGroup,
146             int isPrimary) {
147         assertNotNull(contactCursor);
148         assertNotNull(nameCursor);
149 
150         if (TextUtils.isEmpty(number)) {
151             // Add a dummy number, otherwise DialerDatabaseHelper simply ignores the entire
152             // row if the number is empty
153             number = "0";
154         }
155 
156         contactCursor.addRow(new Object[]{id, "", "", number, contactId, lookupKey, displayName,
157                 photoId, lastTimeUsed, timesUsed, starred, isSuperPrimary, inVisibleGroup,
158                 isPrimary});
159         nameCursor.addRow(new Object[]{displayName, contactId});
160 
161         return new ContactNumber(contactId, id, displayName, number, lookupKey, 0);
162     }
163 
getLooseMatchesFromDb(String query)164     private ArrayList<ContactNumber> getLooseMatchesFromDb(String query) {
165         final SmartDialNameMatcher nameMatcher = new SmartDialNameMatcher(query,
166                 SmartDialPrefix.getMap());
167         return mTestHelper.getLooseMatches(query, nameMatcher);
168     }
169 
testPutForFullName()170     public void testPutForFullName() {
171         final SQLiteDatabase db = mTestHelper.getWritableDatabase();
172 
173         final MatrixCursor nameCursor =  constructNewNameCursor();
174         final MatrixCursor contactCursor = constructNewContactCursor();
175         final ContactNumber jasonsmith = constructNewContactWithDummyIds(contactCursor, nameCursor,
176                 "", 0, "Jason Smith");
177         final ContactNumber jasonsmitt = constructNewContactWithDummyIds(contactCursor, nameCursor,
178                 "", 1, "Jason Smitt");
179         final ContactNumber alphabet = constructNewContactWithDummyIds(contactCursor, nameCursor,
180                 "12345678", 2, "abc def ghi jkl mno pqrs tuv wxyz");
181 
182         mTestHelper.insertUpdatedContactsAndNumberPrefix(db, contactCursor, Long.valueOf(0));
183         mTestHelper.insertNamePrefixes(db, nameCursor);
184 
185         nameCursor.close();
186         contactCursor.close();
187 
188         final ArrayList<ContactNumber> result1 = getLooseMatchesFromDb("5276676484");
189         assertFalse(result1.contains(jasonsmitt));
190 
191         final ArrayList<ContactNumber> result2 = getLooseMatchesFromDb("5276676488");
192         assertFalse(result2.contains(jasonsmith));
193         assertTrue(result2.contains(jasonsmitt));
194 
195         assertTrue(getLooseMatchesFromDb("22233344455566677778889999").contains(alphabet));
196         assertTrue(getLooseMatchesFromDb("33344455566677778889999").contains(alphabet));
197         assertTrue(getLooseMatchesFromDb("44455566677778889999").contains(alphabet));
198         assertTrue(getLooseMatchesFromDb("55566677778889999").contains(alphabet));
199         assertTrue(getLooseMatchesFromDb("66677778889999").contains(alphabet));
200         assertTrue(getLooseMatchesFromDb("77778889999").contains(alphabet));
201         assertTrue(getLooseMatchesFromDb("8889999").contains(alphabet));
202         assertTrue(getLooseMatchesFromDb("9999").contains(alphabet));
203 
204         // Makes sure the phone number is correctly added.
205         assertTrue(getLooseMatchesFromDb("12345678").contains(alphabet));
206     }
207 
testPutForPartialName()208     public void testPutForPartialName() {
209         final SQLiteDatabase db = mTestHelper.getWritableDatabase();
210 
211         final MatrixCursor nameCursor =  constructNewNameCursor();
212         final MatrixCursor contactCursor = constructNewContactCursor();
213         final ContactNumber maryjane = constructNewContactWithDummyIds(contactCursor, nameCursor,
214                 "", 0, "Mary Jane");
215         final ContactNumber sarahsmith = constructNewContactWithDummyIds(contactCursor, nameCursor,
216                 "", 1, "Sarah Smith");
217         final ContactNumber jasonsmitt = constructNewContactWithDummyIds(contactCursor, nameCursor,
218                 "", 2, "Jason Smitt");
219 
220         mTestHelper.insertUpdatedContactsAndNumberPrefix(db, contactCursor, Long.valueOf(0));
221         mTestHelper.insertNamePrefixes(db, nameCursor);
222 
223         nameCursor.close();
224         contactCursor.close();
225 
226         final ArrayList<ContactNumber> result1 = getLooseMatchesFromDb("6279");
227         assertTrue(result1.contains(maryjane));
228         assertFalse(result1.contains(jasonsmitt));
229 
230         // 72 corresponds to sa = "Sarah Smith" but not "Jason Smitt" or "Mary Jane"
231         final ArrayList<ContactNumber> result2 = getLooseMatchesFromDb("72");
232         assertFalse(result2.contains(maryjane));
233         assertTrue(result2.contains(sarahsmith));
234         assertFalse(result2.contains(jasonsmitt));
235 
236         // 76 corresponds to sm = "Sarah Smith" and "Jason Smitt" but not "Mary Jane"
237         final ArrayList<ContactNumber> result3 = getLooseMatchesFromDb("76");
238         assertFalse(result3.contains(maryjane));
239         assertTrue(result3.contains(sarahsmith));
240         assertTrue(result3.contains(jasonsmitt));
241     }
242 
testPutForNameTokens()243     public void testPutForNameTokens() {
244         final SQLiteDatabase db = mTestHelper.getWritableDatabase();
245 
246         final MatrixCursor nameCursor =  constructNewNameCursor();
247         final MatrixCursor contactCursor = constructNewContactCursor();
248         final ContactNumber jasonfwilliams = constructNewContactWithDummyIds(contactCursor,
249                 nameCursor, "", 0, "Jason F. Williams");
250 
251         mTestHelper.insertUpdatedContactsAndNumberPrefix(db, contactCursor, Long.valueOf(0));
252         mTestHelper.insertNamePrefixes(db, nameCursor);
253 
254         nameCursor.close();
255         contactCursor.close();
256 
257         assertTrue(getLooseMatchesFromDb("527").contains(jasonfwilliams));
258         // 72 corresponds to sa = "Sarah Smith" but not "Jason Smitt" or "Mary Jane"
259         assertTrue(getLooseMatchesFromDb("945").contains(jasonfwilliams));
260         // 76 corresponds to sm = "Sarah Smith" and "Jason Smitt" but not "Mary Jane"
261         assertFalse(getLooseMatchesFromDb("66").contains(jasonfwilliams));
262     }
263 
testPutForInitialMatches()264     public void testPutForInitialMatches() {
265         final SQLiteDatabase db = mTestHelper.getWritableDatabase();
266 
267         final MatrixCursor nameCursor =  constructNewNameCursor();
268         final MatrixCursor contactCursor = constructNewContactCursor();
269         final ContactNumber martinjuniorharry = constructNewContactWithDummyIds(contactCursor,
270                 nameCursor, "", 0, "Martin Jr Harry");
271 
272         mTestHelper.insertUpdatedContactsAndNumberPrefix(db, contactCursor, Long.valueOf(0));
273         mTestHelper.insertNamePrefixes(db, nameCursor);
274 
275         nameCursor.close();
276         contactCursor.close();
277 
278         // 654 corresponds to mjh = "(M)artin (J)r (H)arry"
279         assertTrue(getLooseMatchesFromDb("654").contains(martinjuniorharry));
280         // The reverse (456) does not match (for now)
281         assertFalse(getLooseMatchesFromDb("456").contains(martinjuniorharry));
282         // 6542 corresponds to mjha = "(M)artin (J)r (Ha)rry"
283         assertTrue(getLooseMatchesFromDb("6542").contains(martinjuniorharry));
284         // 542 corresponds to jha = "Martin (J)r (Ha)rry"
285         assertTrue(getLooseMatchesFromDb("542").contains(martinjuniorharry));
286         // 642 corresponds to mha = "(M)artin Jr (Ha)rry"
287         assertTrue(getLooseMatchesFromDb("642").contains(martinjuniorharry));
288         // 6542779 (M)artin (J)r (Harry)
289         assertTrue(getLooseMatchesFromDb("6542779").contains(martinjuniorharry));
290         // 65742779 (M)artin (Jr) (Harry)
291         assertTrue(getLooseMatchesFromDb("65742779").contains(martinjuniorharry));
292         // 542779 Martin (J)r (Harry)
293         assertTrue(getLooseMatchesFromDb("542779").contains(martinjuniorharry));
294         // 547 doesn't match
295         assertFalse(getLooseMatchesFromDb("547").contains(martinjuniorharry));
296         // 655 doesn't match
297         assertFalse(getLooseMatchesFromDb("655").contains(martinjuniorharry));
298         // 653 doesn't match
299         assertFalse(getLooseMatchesFromDb("653").contains(martinjuniorharry));
300         // 6543 doesn't match
301         assertFalse(getLooseMatchesFromDb("6543").contains(martinjuniorharry));
302 
303         // 7 actual rows, + 1 for the dummy number we added
304         assertEquals(8, mTestHelper.countPrefixTableRows(db));
305     }
306 
testPutForInitialMatchesForLongTokenNames()307     public void testPutForInitialMatchesForLongTokenNames() {
308 
309         final SQLiteDatabase db = mTestHelper.getWritableDatabase();
310 
311         final MatrixCursor nameCursor =  constructNewNameCursor();
312         final MatrixCursor contactCursor = constructNewContactCursor();
313         final ContactNumber alphabet = constructNewContactWithDummyIds(contactCursor, nameCursor,
314                 "12345678", 0, "abc def ghi jkl mno pqrs tuv wxyz");
315 
316         mTestHelper.insertUpdatedContactsAndNumberPrefix(db, contactCursor, Long.valueOf(0));
317         mTestHelper.insertNamePrefixes(db, nameCursor);
318 
319         nameCursor.close();
320         contactCursor.close();
321 
322         // Makes sure only only the first two and last two token are considered for initials.
323         // The cut-off constant can be set in SmartDialPrefix.java
324         assertTrue(getLooseMatchesFromDb("2389999").contains(alphabet));
325         assertTrue(getLooseMatchesFromDb("239999").contains(alphabet));
326         assertTrue(getLooseMatchesFromDb("23888").contains(alphabet));
327         assertTrue(getLooseMatchesFromDb("2333").contains(alphabet));
328         assertTrue(getLooseMatchesFromDb("289999").contains(alphabet));
329         assertTrue(getLooseMatchesFromDb("2888").contains(alphabet));
330         assertTrue(getLooseMatchesFromDb("29999").contains(alphabet));
331         assertTrue(getLooseMatchesFromDb("3888").contains(alphabet));
332         assertTrue(getLooseMatchesFromDb("39999").contains(alphabet));
333         assertTrue(getLooseMatchesFromDb("389999").contains(alphabet));
334         assertTrue(getLooseMatchesFromDb("89999").contains(alphabet));
335     }
336 
testCheckLongToken()337     public void testCheckLongToken() {
338         final SQLiteDatabase db = mTestHelper.getWritableDatabase();
339 
340         final MatrixCursor nameCursor =  constructNewNameCursor();
341         final MatrixCursor contactCursor = constructNewContactCursor();
342         final ContactNumber alphabet = constructNewContactWithDummyIds(contactCursor, nameCursor,
343                 "1", 0,  " aaaa bbbb cccc dddd eeee ffff gggg hhhh iiii jjjj kkkk llll mmmm nnnn" +
344                 " oooo pppp qqqq rrrr ssss tttt uuuu vvvv wwww xxxx yyyy zzzz");
345 
346         final ContactNumber alphabet2 = constructNewContactWithDummyIds(contactCursor, nameCursor,
347                 "1", 1, "aaaabbbbccccddddeeeeffffgggghhhhiiiijjjjkkkkllllmmmmnnnnooooppppqqqqrrrr" +
348                 "ssssttttuuuuvvvvwwwwxxxxyyyyzzzz");
349 
350         mTestHelper.insertUpdatedContactsAndNumberPrefix(db, contactCursor, Long.valueOf(0));
351         mTestHelper.insertNamePrefixes(db, nameCursor);
352 
353         nameCursor.close();
354         contactCursor.close();
355 
356         assertTrue(getLooseMatchesFromDb("2222").contains(alphabet));
357         assertEquals(40, mTestHelper.countPrefixTableRows(db));
358     }
359 
testAccentedCharacters()360     public void testAccentedCharacters() {
361         final SQLiteDatabase db = mTestHelper.getWritableDatabase();
362 
363         final MatrixCursor nameCursor =  constructNewNameCursor();
364         final MatrixCursor contactCursor = constructNewContactCursor();
365         final ContactNumber reene = constructNewContactWithDummyIds(contactCursor, nameCursor,
366                 "0", 0, "Reenée");
367         final ContactNumber bronte = constructNewContactWithDummyIds(contactCursor, nameCursor,
368                 "0", 1, "Brontë");
369 
370         mTestHelper.insertUpdatedContactsAndNumberPrefix(db, contactCursor, Long.valueOf(0));
371         mTestHelper.insertNamePrefixes(db, nameCursor);
372 
373         nameCursor.close();
374         contactCursor.close();
375 
376         assertTrue(getLooseMatchesFromDb("733633").contains(reene));
377         assertTrue(getLooseMatchesFromDb("276683").contains(bronte));
378     }
379 
testNumbersInName()380     public void testNumbersInName() {
381         final SQLiteDatabase db = mTestHelper.getWritableDatabase();
382 
383         final MatrixCursor nameCursor =  constructNewNameCursor();
384         final MatrixCursor contactCursor = constructNewContactCursor();
385         final ContactNumber contact = constructNewContactWithDummyIds(contactCursor, nameCursor,
386                 "0", 0, "12345678");
387         final ContactNumber teacher = constructNewContactWithDummyIds(contactCursor, nameCursor,
388                 "0", 1, "1st Grade Teacher");
389 
390         mTestHelper.insertUpdatedContactsAndNumberPrefix(db, contactCursor, Long.valueOf(0));
391         mTestHelper.insertNamePrefixes(db, nameCursor);
392 
393         nameCursor.close();
394         contactCursor.close();
395 
396         assertTrue(getLooseMatchesFromDb("12345678").contains(contact));
397         assertTrue(getLooseMatchesFromDb("17847233").contains(teacher));
398         assertTrue(getLooseMatchesFromDb("14832").contains(teacher));
399     }
400 
testPutForNumbers()401     public void testPutForNumbers() {
402         final SQLiteDatabase db = mTestHelper.getWritableDatabase();
403 
404         final MatrixCursor nameCursor =  constructNewNameCursor();
405         final MatrixCursor contactCursor = constructNewContactCursor();
406         final ContactNumber contactno1 = constructNewContactWithDummyIds(contactCursor, nameCursor,
407                 "510-527-2357", 0,  "James");
408         final ContactNumber contactno2 = constructNewContactWithDummyIds(contactCursor, nameCursor,
409                 "77212862357", 1, "James");
410         final ContactNumber contactno3 = constructNewContactWithDummyIds(contactCursor, nameCursor,
411                 "+13684976334", 2, "James");
412 
413         mTestHelper.insertUpdatedContactsAndNumberPrefix(db, contactCursor, Long.valueOf(0));
414         mTestHelper.insertNamePrefixes(db, nameCursor);
415 
416         nameCursor.close();
417         contactCursor.close();
418 
419         assertTrue(getLooseMatchesFromDb("510").contains(contactno1));
420         assertFalse(getLooseMatchesFromDb("511").contains(contactno1));
421         assertTrue(getLooseMatchesFromDb("77212862357").contains(contactno2));
422         assertFalse(getLooseMatchesFromDb("77212862356").contains(contactno2));
423         assertTrue(getLooseMatchesFromDb("1368").contains(contactno3));
424         assertFalse(getLooseMatchesFromDb("1367").contains(contactno3));
425     }
426 
testPutNumbersCountryCode()427     public void testPutNumbersCountryCode() {
428         final SQLiteDatabase db = mTestHelper.getWritableDatabase();
429 
430         final MatrixCursor nameCursor =  constructNewNameCursor();
431         final MatrixCursor contactCursor = constructNewContactCursor();
432         final ContactNumber contactno1 = constructNewContactWithDummyIds(contactCursor, nameCursor,
433                 "+13684976334", 0, "James");
434         final ContactNumber contactno2 = constructNewContactWithDummyIds(contactCursor, nameCursor,
435                 "+65 9177-6930", 1, "Jason");
436         final ContactNumber contactno3 = constructNewContactWithDummyIds(contactCursor, nameCursor,
437                 "+85212345678", 2, "Mike");
438         final ContactNumber contactno4 = constructNewContactWithDummyIds(contactCursor, nameCursor,
439                 "+85112345678", 3, "Invalid");
440         final ContactNumber contactno5 = constructNewContactWithDummyIds(contactCursor, nameCursor,
441                 "+852", 4, "Invalid");
442 
443         mTestHelper.insertUpdatedContactsAndNumberPrefix(db, contactCursor, Long.valueOf(0));
444         mTestHelper.insertNamePrefixes(db, nameCursor);
445 
446         nameCursor.close();
447         contactCursor.close();
448 
449         assertTrue(getLooseMatchesFromDb("1368").contains(contactno1));
450         assertTrue(getLooseMatchesFromDb("368497").contains(contactno1));
451         assertFalse(getLooseMatchesFromDb("2368497").contains(contactno1));
452 
453         assertTrue(getLooseMatchesFromDb("6591776930").contains(contactno2));
454         assertTrue(getLooseMatchesFromDb("91776930").contains(contactno2));
455         assertFalse(getLooseMatchesFromDb("591776930").contains(contactno2));
456 
457         assertTrue(getLooseMatchesFromDb("85212345678").contains(contactno3));
458         assertTrue(getLooseMatchesFromDb("12345678").contains(contactno3));
459         assertFalse(getLooseMatchesFromDb("5212345678").contains(contactno3));
460 
461         assertTrue(getLooseMatchesFromDb("85112345678").contains(contactno4));
462         assertFalse(getLooseMatchesFromDb("12345678").contains(contactno4));
463     }
464 
465     // Tests special case handling for NANP numbers
testPutNumbersNANP()466     public void testPutNumbersNANP() {
467         SmartDialPrefix.setUserInNanpRegion(true);
468         final SQLiteDatabase db = mTestHelper.getWritableDatabase();
469 
470         final MatrixCursor nameCursor =  constructNewNameCursor();
471         final MatrixCursor contactCursor = constructNewContactCursor();
472         final ContactNumber contactno1 = constructNewContactWithDummyIds(contactCursor, nameCursor,
473                 "16503337596", 0, "James");
474         final ContactNumber contactno2 = constructNewContactWithDummyIds(contactCursor, nameCursor,
475                 "5109921234", 1, "Michael");
476         final ContactNumber contactno3 = constructNewContactWithDummyIds(contactCursor, nameCursor,
477                 "(415)-123-4567", 2, "Jason");
478         final ContactNumber contactno4 = constructNewContactWithDummyIds(contactCursor, nameCursor,
479                 "1 510-284-9170", 3, "Mike");
480         final ContactNumber contactno5 = constructNewContactWithDummyIds(contactCursor, nameCursor,
481                 "1-415-123-123", 4, "Invalid");
482         final ContactNumber contactno6 = constructNewContactWithDummyIds(contactCursor, nameCursor,
483                 "415-123-123", 5, "Invalid2");
484         final ContactNumber contactno7 = constructNewContactWithDummyIds(contactCursor, nameCursor,
485                 "+1-510-284-9170", 6, "Mike");
486         final ContactNumber contactno8 = constructNewContactWithDummyIds(contactCursor, nameCursor,
487                 "+1-510-284-917", 7, "Invalid");
488         final ContactNumber contactno9 = constructNewContactWithDummyIds(contactCursor, nameCursor,
489                 "+857-510-284-9170", 8, "Inv");
490 
491         mTestHelper.insertUpdatedContactsAndNumberPrefix(db, contactCursor, Long.valueOf(0));
492         mTestHelper.insertNamePrefixes(db, nameCursor);
493 
494         nameCursor.close();
495         contactCursor.close();
496 
497         assertTrue(getLooseMatchesFromDb("16503337596").contains(contactno1));
498         assertTrue(getLooseMatchesFromDb("6503337596").contains(contactno1));
499         assertTrue(getLooseMatchesFromDb("3337596").contains(contactno1));
500 
501         assertTrue(getLooseMatchesFromDb("5109921234").contains(contactno2));
502         assertTrue(getLooseMatchesFromDb("9921234").contains(contactno2));
503 
504         assertTrue(getLooseMatchesFromDb("4151234567").contains(contactno3));
505         assertTrue(getLooseMatchesFromDb("1234567").contains(contactno3));
506 
507         assertTrue(getLooseMatchesFromDb("15102849170").contains(contactno4));
508         assertTrue(getLooseMatchesFromDb("5102849170").contains(contactno4));
509         assertTrue(getLooseMatchesFromDb("2849170").contains(contactno4));
510 
511         assertTrue(getLooseMatchesFromDb("1415123123").contains(contactno5));
512         assertFalse(getLooseMatchesFromDb("415123123").contains(contactno5));
513         assertFalse(getLooseMatchesFromDb("123123").contains(contactno5));
514 
515         assertTrue(getLooseMatchesFromDb("415123123").contains(contactno6));
516         assertFalse(getLooseMatchesFromDb("123123").contains(contactno6));
517 
518         assertTrue(getLooseMatchesFromDb("15102849170").contains(contactno7));
519         assertTrue(getLooseMatchesFromDb("5102849170").contains(contactno7));
520         assertTrue(getLooseMatchesFromDb("2849170").contains(contactno7));
521         assertFalse(getLooseMatchesFromDb("849170").contains(contactno7));
522         assertFalse(getLooseMatchesFromDb("10849170").contains(contactno7));
523 
524         assertTrue(getLooseMatchesFromDb("1510284917").contains(contactno8));
525         assertTrue(getLooseMatchesFromDb("510284917").contains(contactno8));
526         assertFalse(getLooseMatchesFromDb("2849170").contains(contactno8));
527 
528         assertTrue(getLooseMatchesFromDb("8575102849170").contains(contactno9));
529         assertFalse(getLooseMatchesFromDb("5102849170").contains(contactno9));
530         assertFalse(getLooseMatchesFromDb("2849170").contains(contactno9));
531 
532         // TODO(klp) Adds test for non-NANP region number matchings.
533     }
534 
535     // Tests special case handling for non-NANP numbers
testPutNumbersNonNANP()536     public void testPutNumbersNonNANP() {
537         SmartDialPrefix.setUserInNanpRegion(false);
538         final SQLiteDatabase db = mTestHelper.getWritableDatabase();
539 
540         final MatrixCursor nameCursor =  constructNewNameCursor();
541         final MatrixCursor contactCursor = constructNewContactCursor();
542 
543         final ContactNumber contactno0 = constructNewContactWithDummyIds(contactCursor, nameCursor,
544                 "(415)-123-4567", 0, "Jason");
545         final ContactNumber contactno1 = constructNewContactWithDummyIds(contactCursor, nameCursor,
546                 "1 510-284-9170", 1, "Mike");
547 
548 
549         mTestHelper.insertUpdatedContactsAndNumberPrefix(db, contactCursor, Long.valueOf(0));
550         mTestHelper.insertNamePrefixes(db, nameCursor);
551 
552         nameCursor.close();
553         contactCursor.close();
554 
555         assertTrue(getLooseMatchesFromDb("4151234567").contains(contactno0));
556         assertFalse(getLooseMatchesFromDb("1234567").contains(contactno0));
557 
558         assertTrue(getLooseMatchesFromDb("15102849170").contains(contactno1));
559         assertFalse(getLooseMatchesFromDb("5102849170").contains(contactno1));
560         assertFalse(getLooseMatchesFromDb("2849170").contains(contactno1));
561     }
562 
testParseInfo()563     public void testParseInfo() {
564         final String name = "Mcdonald Jamie-Cullum";
565         final ArrayList<String> info = SmartDialPrefix.parseToIndexTokens(name);
566         assertEquals(3, info.size());
567         assertEquals(8, info.get(0).length());
568         assertEquals(5, info.get(1).length());
569         assertEquals(6, info.get(2).length());
570 
571         final String name2 = "aaa bbb ccc ddd eee fff ggg hhh iii jjj kkk";
572         final ArrayList<String> info2 = SmartDialPrefix.parseToIndexTokens(name2);
573         assertEquals(11, info2.size());
574         assertEquals(3, info2.get(0).length());
575         assertEquals(3, info2.get(10).length());
576 
577         final String name3 = "this  is- a,test    name";
578         final ArrayList<String> info3 = SmartDialPrefix.parseToIndexTokens(name3);
579         assertEquals(5, info3.size());
580         assertEquals(2, info3.get(1).length());
581         assertEquals(1, info3.get(2).length());
582         assertEquals(4, info3.get(3).length());
583         assertEquals(4, info3.get(4).length());
584 
585         final String name4 = "M c-Donald James";
586         final ArrayList<String> info4 = SmartDialPrefix.parseToIndexTokens(name4);
587         assertEquals(4, info4.size());
588         assertEquals(1, info4.get(1).length());
589         assertEquals(6, info4.get(2).length());
590 
591         final String name5 = "   Aa'Bb    c    dddd  e'e";
592         final ArrayList<String> info5 = SmartDialPrefix.parseToIndexTokens(name5);
593         assertEquals(6, info5.size());
594         assertEquals(2, info5.get(0).length());
595         assertEquals(1, info5.get(5).length());
596     }
597 }
598