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