1 /*
2  * Copyright (C) 2009 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.providers.contacts;
18 
19 import android.provider.ContactsContract.FullNameStyle;
20 import android.test.suitebuilder.annotation.SmallTest;
21 
22 import junit.framework.TestCase;
23 
24 import java.text.Collator;
25 import java.util.Arrays;
26 import java.util.Locale;
27 
28 /**
29  * Unit tests for {@link NameLookupBuilder}.
30  *
31  * Run the test like this:
32  * <code>
33  * adb shell am instrument -e class com.android.providers.contacts.NameLookupBuilderTest -w \
34  *         com.android.providers.contacts.tests/android.test.InstrumentationTestRunner
35  * </code>
36  */
37 @SmallTest
38 public class NameLookupBuilderTest extends TestCase {
39 
40     private static class TestNameLookupBuilder extends NameLookupBuilder {
41 
42         StringBuilder sb = new StringBuilder();
43 
TestNameLookupBuilder(NameSplitter splitter)44         public TestNameLookupBuilder(NameSplitter splitter) {
45             super(splitter);
46         }
47 
48         @Override
normalizeName(String name)49         protected String normalizeName(String name) {
50 
51             // TO make the test more readable, simply return the name unnormalized
52             return name;
53         }
54 
55         @Override
getCommonNicknameClusters(String normalizedName)56         protected String[] getCommonNicknameClusters(String normalizedName) {
57             if (normalizedName.equals("Bill")) {
58                 return new String[] {"*William"};
59             } else if (normalizedName.equals("Al")) {
60                 return new String[] {"*Alex", "*Alice"};
61             }
62             return null;
63         }
64 
inserted()65         public String inserted() {
66             return sb.toString();
67         }
68 
69         @Override
insertNameLookup(long rawContactId, long dataId, int lookupType, String string)70         protected void insertNameLookup(long rawContactId, long dataId, int lookupType,
71                 String string) {
72             sb.append("(").append(lookupType).append(":").append(string).append(")");
73         }
74     }
75 
76     private TestNameLookupBuilder mBuilder;
77 
78     @Override
setUp()79     protected void setUp() throws Exception {
80         super.setUp();
81         mBuilder = new TestNameLookupBuilder(
82                 new NameSplitter("Mr", "", "", "", Locale.getDefault()));
83     }
84 
testEmptyName()85     public void testEmptyName() {
86         mBuilder.insertNameLookup(0, 0, "", FullNameStyle.UNDEFINED);
87         assertEquals("", mBuilder.inserted());
88     }
89 
testSingleUniqueName()90     public void testSingleUniqueName() {
91         mBuilder.insertNameLookup(0, 0, "Foo", FullNameStyle.UNDEFINED);
92         assertEquals("(0:Foo)(2:Foo)", mBuilder.inserted());
93     }
94 
testSingleUniqueNameWithPrefix()95     public void testSingleUniqueNameWithPrefix() {
96         mBuilder.insertNameLookup(0, 0, "Mr. Foo", FullNameStyle.UNDEFINED);
97         assertEquals("(0:Mr.Foo)(2:MrFoo)(1:Foo.Mr)(2:FooMr)", mBuilder.inserted());
98     }
99 
testTwoUniqueNames()100     public void testTwoUniqueNames() {
101         mBuilder.insertNameLookup(0, 0, "Foo Bar", FullNameStyle.UNDEFINED);
102         assertEquals("(0:Foo.Bar)(2:FooBar)(1:Bar.Foo)(2:BarFoo)", mBuilder.inserted());
103     }
104 
testThreeUniqueNames()105     public void testThreeUniqueNames() {
106         mBuilder.insertNameLookup(0, 0, "Foo Bar Baz", FullNameStyle.UNDEFINED);
107 
108         // All permutations
109         assertEquals(
110                 "(0:Foo.Bar.Baz)(2:FooBarBaz)" +
111                 "(1:Foo.Baz.Bar)(2:FooBazBar)" +
112 
113                 "(1:Bar.Foo.Baz)(2:BarFooBaz)" +
114                 "(1:Bar.Baz.Foo)(2:BarBazFoo)" +
115 
116                 "(1:Baz.Bar.Foo)(2:BazBarFoo)" +
117                 "(1:Baz.Foo.Bar)(2:BazFooBar)", mBuilder.inserted());
118     }
119 
testFourUniqueNames()120     public void testFourUniqueNames() {
121         mBuilder.insertNameLookup(0, 0, "Foo Bar Baz Biz", FullNameStyle.UNDEFINED);
122 
123         // All permutations
124         assertEquals(
125                 "(0:Foo.Bar.Baz.Biz)(2:FooBarBazBiz)" +
126                 "(1:Foo.Bar.Biz.Baz)(2:FooBarBizBaz)" +
127                 "(1:Foo.Baz.Bar.Biz)(2:FooBazBarBiz)" +
128                 "(1:Foo.Baz.Biz.Bar)(2:FooBazBizBar)" +
129                 "(1:Foo.Biz.Baz.Bar)(2:FooBizBazBar)" +
130                 "(1:Foo.Biz.Bar.Baz)(2:FooBizBarBaz)" +
131 
132                 "(1:Bar.Foo.Baz.Biz)(2:BarFooBazBiz)" +
133                 "(1:Bar.Foo.Biz.Baz)(2:BarFooBizBaz)" +
134                 "(1:Bar.Baz.Foo.Biz)(2:BarBazFooBiz)" +
135                 "(1:Bar.Baz.Biz.Foo)(2:BarBazBizFoo)" +
136                 "(1:Bar.Biz.Baz.Foo)(2:BarBizBazFoo)" +
137                 "(1:Bar.Biz.Foo.Baz)(2:BarBizFooBaz)" +
138 
139                 "(1:Baz.Bar.Foo.Biz)(2:BazBarFooBiz)" +
140                 "(1:Baz.Bar.Biz.Foo)(2:BazBarBizFoo)" +
141                 "(1:Baz.Foo.Bar.Biz)(2:BazFooBarBiz)" +
142                 "(1:Baz.Foo.Biz.Bar)(2:BazFooBizBar)" +
143                 "(1:Baz.Biz.Foo.Bar)(2:BazBizFooBar)" +
144                 "(1:Baz.Biz.Bar.Foo)(2:BazBizBarFoo)" +
145 
146                 "(1:Biz.Bar.Baz.Foo)(2:BizBarBazFoo)" +
147                 "(1:Biz.Bar.Foo.Baz)(2:BizBarFooBaz)" +
148                 "(1:Biz.Baz.Bar.Foo)(2:BizBazBarFoo)" +
149                 "(1:Biz.Baz.Foo.Bar)(2:BizBazFooBar)" +
150                 "(1:Biz.Foo.Baz.Bar)(2:BizFooBazBar)" +
151                 "(1:Biz.Foo.Bar.Baz)(2:BizFooBarBaz)", mBuilder.inserted());
152     }
153 
testSingleNickname()154     public void testSingleNickname() {
155         mBuilder.insertNameLookup(0, 0, "Bill", FullNameStyle.UNDEFINED);
156         assertEquals("(0:Bill)(2:Bill)(1:*William)", mBuilder.inserted());
157     }
158 
testSingleNameWithTwoNicknames()159     public void testSingleNameWithTwoNicknames() {
160         mBuilder.insertNameLookup(0, 0, "Al", FullNameStyle.UNDEFINED);
161         assertEquals("(0:Al)(2:Al)(1:*Alex)(1:*Alice)", mBuilder.inserted());
162     }
163 
testTwoNamesOneOfWhichIsNickname()164     public void testTwoNamesOneOfWhichIsNickname() {
165         mBuilder.insertNameLookup(0, 0, "Foo Al", FullNameStyle.UNDEFINED);
166         assertEquals(
167                 "(0:Foo.Al)(2:FooAl)" +
168                 "(1:Al.Foo)(2:AlFoo)" +
169                 "(1:Foo.*Alex)(1:*Alex.Foo)" +
170                 "(1:Foo.*Alice)(1:*Alice.Foo)", mBuilder.inserted());
171     }
172 
testTwoNamesBothNickname()173     public void testTwoNamesBothNickname() {
174         mBuilder.insertNameLookup(0, 0, "Bill Al", FullNameStyle.UNDEFINED);
175         assertEquals(
176                 "(0:Bill.Al)(2:BillAl)" +
177                 "(1:Al.Bill)(2:AlBill)" +
178                 "(1:*William.Al)(1:Al.*William)" +
179                 "(1:*William.*Alex)(1:*Alex.*William)" +
180                 "(1:*William.*Alice)(1:*Alice.*William)" +
181                 "(1:Bill.*Alex)(1:*Alex.Bill)" +
182                 "(1:Bill.*Alice)(1:*Alice.Bill)", mBuilder.inserted());
183     }
184 
testChineseName()185     public void testChineseName() {
186         // Only run this test when Chinese collation is supported
187         if (!Arrays.asList(Collator.getAvailableLocales()).contains(Locale.CHINA)) {
188             return;
189         }
190 
191         mBuilder.insertNameLookup(0, 0, "\u695A\u8FAD", FullNameStyle.CHINESE);
192         assertEquals(
193                 "(0:\u695A\u8FAD)" +
194                 "(2:\u695A\u8FAD)",
195                 mBuilder.inserted());
196     }
197 
testKoreanName()198     public void testKoreanName() {
199         // Only run this test when Korean collation is supported.
200         if (!Arrays.asList(Collator.getAvailableLocales()).contains(Locale.KOREA)) {
201             return;
202         }
203 
204         // Lee Sang Il
205         mBuilder.insertNameLookup(0, 0, "\uC774\uC0C1\uC77C", FullNameStyle.KOREAN);
206         assertEquals(
207                 "(0:\uC774\uC0C1\uC77C)" + // Lee Sang Il
208                 "(2:\uC774\uC0C1\uC77C)",
209                 mBuilder.inserted());
210     }
211 
testKoreanNameWithTwoCharactersFamilyName()212     public void testKoreanNameWithTwoCharactersFamilyName() {
213         // Only run this test when Chinese collation is supported.
214         if (!Arrays.asList(Collator.getAvailableLocales()).contains(Locale.KOREA)) {
215             return;
216         }
217 
218         // Sun Woo Young Nyeu
219         mBuilder.insertNameLookup(0, 0, "\uC120\uC6B0\uC6A9\uB140", FullNameStyle.KOREAN);
220         assertEquals(
221                 "(0:\uC120\uC6B0\uC6A9\uB140)" + // Sun Woo Young Nyeu
222                 "(2:\uC120\uC6B0\uC6A9\uB140)",  // Sun Woo Young Nyeu
223                 mBuilder.inserted());
224     }
225 
testMultiwordName()226     public void testMultiwordName() {
227         mBuilder.insertNameLookup(0, 0, "Jo Jeffrey John Jessy Longname", FullNameStyle.UNDEFINED);
228         String actual = mBuilder.inserted();
229 
230         // Exact name
231         assertTrue(actual.contains("(0:Jo.Jeffrey.John.Jessy.Longname)"));
232 
233         // Full collation key
234         assertTrue(actual.contains("(2:JoJeffreyJohnJessyLongname)"));
235 
236         // Variant: four longest parts
237         assertTrue(actual.contains("(1:Longname.Jeffrey.Jessy.John)"));
238 
239         // All individual words
240         assertTrue(actual.contains("(2:Jo"));
241         assertTrue(actual.contains("(2:Jeffrey"));
242         assertTrue(actual.contains("(2:John"));
243         assertTrue(actual.contains("(2:Jessy"));
244         assertTrue(actual.contains("(2:Longname"));
245     }
246 }
247