Add unit tests for Japanization and fix several bugs.

Internal issue number: 2195990
This commit is contained in:
Daisuke Miyakawa
2009-11-12 11:19:06 +09:00
parent f18a01c77e
commit 592988d307
10 changed files with 334 additions and 137 deletions

View File

@@ -20,8 +20,10 @@ import android.content.ContentProviderOperation;
import android.content.ContentResolver;
import android.content.OperationApplicationException;
import android.database.Cursor;
import android.net.Uri;
import android.os.RemoteException;
import android.provider.ContactsContract;
import android.provider.ContactsContract.Contacts;
import android.provider.ContactsContract.Data;
import android.provider.ContactsContract.Groups;
import android.provider.ContactsContract.RawContacts;
@@ -675,16 +677,53 @@ public class ContactStruct {
*/
@SuppressWarnings("fallthrough")
private void handlePhoneticNameFromSound(List<String> elems) {
// Family, Given, Middle. (1-3)
// This is not from specification but mere assumption. Some Japanese phones use this order.
if (!(TextUtils.isEmpty(mPhoneticFamilyName) &&
TextUtils.isEmpty(mPhoneticMiddleName) &&
TextUtils.isEmpty(mPhoneticGivenName))) {
// This means the other properties like "X-PHONETIC-FIRST-NAME" was already found.
// Ignore "SOUND;X-IRMC-N".
return;
}
int size;
if (elems == null || (size = elems.size()) < 1) {
return;
}
// Assume that the order is "Family, Given, Middle".
// This is not from specification but mere assumption. Some Japanese phones use this order.
if (size > 3) {
size = 3;
}
if (elems.get(0).length() > 0) {
boolean onlyFirstElemIsNonEmpty = true;
for (int i = 1; i < size; i++) {
if (elems.get(i).length() > 0) {
onlyFirstElemIsNonEmpty = false;
break;
}
}
if (onlyFirstElemIsNonEmpty) {
final String[] namesArray = elems.get(0).split(" ");
final int nameArrayLength = namesArray.length;
if (nameArrayLength == 3) {
// Assume the string is "Family Middle Given".
mPhoneticFamilyName = namesArray[0];
mPhoneticMiddleName = namesArray[1];
mPhoneticGivenName = namesArray[2];
} else if (nameArrayLength == 2) {
// Assume the string is "Family Given" based on the Japanese mobile
// phones' preference.
mPhoneticFamilyName = namesArray[0];
mPhoneticGivenName = namesArray[1];
} else {
mPhoneticFullName = elems.get(0);
}
return;
}
}
switch (size) {
// fallthrough
case 3:
@@ -976,36 +1015,8 @@ public class ContactStruct {
if (!TextUtils.isEmpty(mFullName)) {
mDisplayName = mFullName;
} else if (!(TextUtils.isEmpty(mFamilyName) && TextUtils.isEmpty(mGivenName))) {
StringBuilder builder = new StringBuilder();
List<String> nameList;
switch (VCardConfig.getNameOrderType(mVCardType)) {
case VCardConfig.NAME_ORDER_JAPANESE:
if (VCardUtils.containsOnlyPrintableAscii(mFamilyName) &&
VCardUtils.containsOnlyPrintableAscii(mGivenName)) {
nameList = Arrays.asList(mPrefix, mGivenName, mMiddleName, mFamilyName, mSuffix);
} else {
nameList = Arrays.asList(mPrefix, mFamilyName, mMiddleName, mGivenName, mSuffix);
}
break;
case VCardConfig.NAME_ORDER_EUROPE:
nameList = Arrays.asList(mPrefix, mMiddleName, mGivenName, mFamilyName, mSuffix);
break;
default:
nameList = Arrays.asList(mPrefix, mGivenName, mMiddleName, mFamilyName, mSuffix);
break;
}
boolean first = true;
for (String namePart : nameList) {
if (!TextUtils.isEmpty(namePart)) {
if (first) {
first = false;
} else {
builder.append(' ');
}
builder.append(namePart);
}
}
mDisplayName = builder.toString();
mDisplayName = VCardUtils.constructNameFromElements(mVCardType,
mFamilyName, mMiddleName, mGivenName, mPrefix, mSuffix);
} else if (!(TextUtils.isEmpty(mPhoneticFamilyName) &&
TextUtils.isEmpty(mPhoneticGivenName))) {
mDisplayName = VCardUtils.constructNameFromElements(mVCardType,
@@ -1282,6 +1293,15 @@ public class ContactStruct {
}
}
public static ContactStruct buildFromResolver(ContentResolver resolver) {
return buildFromResolver(resolver, Contacts.CONTENT_URI);
}
public static ContactStruct buildFromResolver(ContentResolver resolver, Uri uri) {
return null;
}
private boolean nameFieldsAreEmpty() {
return (TextUtils.isEmpty(mFamilyName)
&& TextUtils.isEmpty(mMiddleName)

View File

@@ -682,10 +682,18 @@ public class VCardComposer {
final String givenName = contentValues.getAsString(StructuredName.GIVEN_NAME);
final String prefix = contentValues.getAsString(StructuredName.PREFIX);
final String suffix = contentValues.getAsString(StructuredName.SUFFIX);
final String phoneticFamilyName =
contentValues.getAsString(StructuredName.PHONETIC_FAMILY_NAME);
final String phoneticMiddleName =
contentValues.getAsString(StructuredName.PHONETIC_MIDDLE_NAME);
final String phoneticGivenName =
contentValues.getAsString(StructuredName.PHONETIC_GIVEN_NAME);
final String displayName = contentValues.getAsString(StructuredName.DISPLAY_NAME);
return !(TextUtils.isEmpty(familyName) && TextUtils.isEmpty(middleName) &&
TextUtils.isEmpty(givenName) && TextUtils.isEmpty(prefix) &&
TextUtils.isEmpty(suffix) && TextUtils.isEmpty(displayName));
TextUtils.isEmpty(suffix) && TextUtils.isEmpty(phoneticFamilyName) &&
TextUtils.isEmpty(phoneticMiddleName) && TextUtils.isEmpty(phoneticGivenName) &&
TextUtils.isEmpty(displayName));
}
private void appendStructuredNamesInternal(final StringBuilder builder,
@@ -865,17 +873,18 @@ public class VCardComposer {
builder.append(VCARD_ITEM_SEPARATOR);
builder.append(VCARD_ITEM_SEPARATOR);
builder.append(VCARD_END_OF_LINE);
if (mIsV30) {
builder.append(Constants.PROPERTY_FN);
// TODO: Not allowed formally...
if (shouldAppendCharsetParameter(displayName)) {
builder.append(VCARD_PARAM_SEPARATOR);
builder.append(mVCardCharsetParameter);
}
builder.append(VCARD_DATA_SEPARATOR);
builder.append(encodedDisplayName);
builder.append(VCARD_END_OF_LINE);
builder.append(Constants.PROPERTY_FN);
// Note: "CHARSET" param is not allowed in vCard 3.0, but we may add it
// when it would be useful for external importers, assuming no external
// importer allows this vioration.
if (shouldAppendCharsetParameter(displayName)) {
builder.append(VCARD_PARAM_SEPARATOR);
builder.append(mVCardCharsetParameter);
}
builder.append(VCARD_DATA_SEPARATOR);
builder.append(encodedDisplayName);
builder.append(VCARD_END_OF_LINE);
} else if (mIsV30) {
// vCard 3.0 specification requires these fields.
appendVCardLine(builder, Constants.PROPERTY_N, "");
@@ -913,15 +922,12 @@ public class VCardComposer {
.constructNameFromElements(mVCardType,
phoneticFamilyName, phoneticMiddleName, phoneticGivenName);
builder.append(Constants.PROPERTY_SORT_STRING);
// Do not need to care about QP, since vCard 3.0 does not allow it.
final String encodedSortString = escapeCharacters(sortString);
if (shouldAppendCharsetParameter(encodedSortString)) {
if (shouldAppendCharsetParameter(sortString)) {
builder.append(VCARD_PARAM_SEPARATOR);
builder.append(mVCardCharsetParameter);
}
builder.append(VCARD_DATA_SEPARATOR);
builder.append(encodedSortString);
builder.append(escapeCharacters(sortString));
builder.append(VCARD_END_OF_LINE);
} else if (mIsJapaneseMobilePhone) {
// Note: There is no appropriate property for expressing
@@ -964,11 +970,31 @@ public class VCardComposer {
builder.append(mVCardCharsetParameter);
}
builder.append(VCARD_DATA_SEPARATOR);
builder.append(encodedPhoneticFamilyName);
// DoCoMo's specification requires vCard composer to use just the first
// column.
{
boolean first = true;
if (!TextUtils.isEmpty(encodedPhoneticFamilyName)) {
builder.append(encodedPhoneticFamilyName);
first = false;
}
if (!TextUtils.isEmpty(encodedPhoneticMiddleName)) {
if (first) {
first = false;
} else {
builder.append(' ');
}
builder.append(encodedPhoneticMiddleName);
}
if (!TextUtils.isEmpty(encodedPhoneticGivenName)) {
if (!first) {
builder.append(' ');
}
builder.append(encodedPhoneticGivenName);
}
}
builder.append(VCARD_ITEM_SEPARATOR);
builder.append(encodedPhoneticGivenName);
builder.append(VCARD_ITEM_SEPARATOR);
builder.append(encodedPhoneticMiddleName);
builder.append(VCARD_ITEM_SEPARATOR);
builder.append(VCARD_ITEM_SEPARATOR);
builder.append(VCARD_END_OF_LINE);
@@ -988,7 +1014,8 @@ public class VCardComposer {
if (mUsesDefactProperty) {
if (!TextUtils.isEmpty(phoneticGivenName)) {
final boolean reallyUseQuotedPrintable =
!VCardUtils.containsOnlyNonCrLfPrintableAscii(phoneticGivenName);
(mUsesQuotedPrintable &&
!VCardUtils.containsOnlyNonCrLfPrintableAscii(phoneticGivenName));
final String encodedPhoneticGivenName;
if (reallyUseQuotedPrintable) {
encodedPhoneticGivenName = encodeQuotedPrintable(phoneticGivenName);
@@ -996,7 +1023,7 @@ public class VCardComposer {
encodedPhoneticGivenName = escapeCharacters(phoneticGivenName);
}
builder.append(Constants.PROPERTY_X_PHONETIC_FIRST_NAME);
if (shouldAppendCharsetParameter(encodedPhoneticGivenName)) {
if (shouldAppendCharsetParameter(phoneticGivenName)) {
builder.append(VCARD_PARAM_SEPARATOR);
builder.append(mVCardCharsetParameter);
}
@@ -1010,7 +1037,8 @@ public class VCardComposer {
}
if (!TextUtils.isEmpty(phoneticMiddleName)) {
final boolean reallyUseQuotedPrintable =
!VCardUtils.containsOnlyNonCrLfPrintableAscii(phoneticMiddleName);
(mUsesQuotedPrintable &&
!VCardUtils.containsOnlyNonCrLfPrintableAscii(phoneticMiddleName));
final String encodedPhoneticMiddleName;
if (reallyUseQuotedPrintable) {
encodedPhoneticMiddleName = encodeQuotedPrintable(phoneticMiddleName);
@@ -1018,7 +1046,7 @@ public class VCardComposer {
encodedPhoneticMiddleName = escapeCharacters(phoneticMiddleName);
}
builder.append(Constants.PROPERTY_X_PHONETIC_MIDDLE_NAME);
if (shouldAppendCharsetParameter(encodedPhoneticMiddleName)) {
if (shouldAppendCharsetParameter(phoneticMiddleName)) {
builder.append(VCARD_PARAM_SEPARATOR);
builder.append(mVCardCharsetParameter);
}
@@ -1032,7 +1060,8 @@ public class VCardComposer {
}
if (!TextUtils.isEmpty(phoneticFamilyName)) {
final boolean reallyUseQuotedPrintable =
!VCardUtils.containsOnlyNonCrLfPrintableAscii(phoneticFamilyName);
(mUsesQuotedPrintable &&
!VCardUtils.containsOnlyNonCrLfPrintableAscii(phoneticFamilyName));
final String encodedPhoneticFamilyName;
if (reallyUseQuotedPrintable) {
encodedPhoneticFamilyName = encodeQuotedPrintable(phoneticFamilyName);
@@ -1040,7 +1069,7 @@ public class VCardComposer {
encodedPhoneticFamilyName = escapeCharacters(phoneticFamilyName);
}
builder.append(Constants.PROPERTY_X_PHONETIC_LAST_NAME);
if (shouldAppendCharsetParameter(encodedPhoneticFamilyName)) {
if (shouldAppendCharsetParameter(phoneticFamilyName)) {
builder.append(VCARD_PARAM_SEPARATOR);
builder.append(mVCardCharsetParameter);
}
@@ -2255,8 +2284,7 @@ public class VCardComposer {
* to know this text is NOT UTF-8 but Shift_Jis.
*/
private boolean shouldAppendCharsetParameter(final String propertyValue) {
return (!VCardUtils.containsOnlyPrintableAscii(propertyValue) &&
(!mIsV30 || !mUsesUtf8));
return (!(mIsV30 && mUsesUtf8) && !VCardUtils.containsOnlyPrintableAscii(propertyValue));
}
private boolean shouldAppendCharsetParameters(final List<String> propertyValueList) {

View File

@@ -60,7 +60,8 @@ public class VCardConfig {
// 0x10 is reserved for safety
private static final int FLAG_CHARSET_UTF8 = 0;
private static final int FLAG_CHARSET_SHIFT_JIS = 0x20;
private static final int FLAG_CHARSET_SHIFT_JIS = 0x100;
private static final int FLAG_CHARSET_MASK = 0xF00;
/**
* The flag indicating the vCard composer will add some "X-" properties used only in Android
@@ -349,8 +350,8 @@ public class VCardConfig {
sJapaneseMobileTypeSet.add(VCARD_TYPE_DOCOMO);
}
public static int getVCardTypeFromString(String vcardTypeString) {
String loweredKey = vcardTypeString.toLowerCase();
public static int getVCardTypeFromString(final String vcardTypeString) {
final String loweredKey = vcardTypeString.toLowerCase();
if (sVCardTypeMap.containsKey(loweredKey)) {
return sVCardTypeMap.get(loweredKey);
} else {
@@ -360,31 +361,31 @@ public class VCardConfig {
}
}
public static boolean isV30(int vcardType) {
public static boolean isV30(final int vcardType) {
return ((vcardType & FLAG_V30) != 0);
}
public static boolean usesQuotedPrintable(int vcardType) {
public static boolean usesQuotedPrintable(final int vcardType) {
return !isV30(vcardType);
}
public static boolean usesUtf8(int vcardType) {
return ((vcardType & FLAG_CHARSET_UTF8) != 0);
public static boolean usesUtf8(final int vcardType) {
return ((vcardType & FLAG_CHARSET_MASK) == FLAG_CHARSET_UTF8);
}
public static boolean usesShiftJis(int vcardType) {
return ((vcardType & FLAG_CHARSET_SHIFT_JIS) != 0);
public static boolean usesShiftJis(final int vcardType) {
return ((vcardType & FLAG_CHARSET_MASK) == FLAG_CHARSET_SHIFT_JIS);
}
public static int getNameOrderType(int vcardType) {
public static int getNameOrderType(final int vcardType) {
return vcardType & NAME_ORDER_MASK;
}
public static boolean usesAndroidSpecificProperty(int vcardType) {
public static boolean usesAndroidSpecificProperty(final int vcardType) {
return ((vcardType & FLAG_USE_ANDROID_PROPERTY) != 0);
}
public static boolean usesDefactProperty(int vcardType) {
public static boolean usesDefactProperty(final int vcardType) {
return ((vcardType & FLAG_USE_DEFACT_PROPERTY) != 0);
}
@@ -392,12 +393,12 @@ public class VCardConfig {
return (VCardConfig.LOG_LEVEL & VCardConfig.LOG_LEVEL_PERFORMANCE_MEASUREMENT) != 0;
}
public static boolean refrainsQPToPrimaryProperties(int vcardType) {
public static boolean refrainsQPToPrimaryProperties(final int vcardType) {
return (!usesQuotedPrintable(vcardType) ||
((vcardType & FLAG_REFRAIN_QP_TO_PRIMARY_PROPERTIES) != 0));
}
public static boolean appendTypeParamName(int vcardType) {
public static boolean appendTypeParamName(final int vcardType) {
return (isV30(vcardType) || ((vcardType & FLAG_APPEND_TYPE_PARAM) != 0));
}
@@ -405,19 +406,19 @@ public class VCardConfig {
* @return true if the device is Japanese and some Japanese convension is
* applied to creating "formatted" something like FORMATTED_ADDRESS.
*/
public static boolean isJapaneseDevice(int vcardType) {
public static boolean isJapaneseDevice(final int vcardType) {
return sJapaneseMobileTypeSet.contains(vcardType);
}
public static boolean needsToConvertPhoneticString(int vcardType) {
public static boolean needsToConvertPhoneticString(final int vcardType) {
return ((vcardType & FLAG_CONVERT_PHONETIC_NAME_STRINGS) != 0);
}
public static boolean onlyOneNoteFieldIsAvailable(int vcardType) {
public static boolean onlyOneNoteFieldIsAvailable(final int vcardType) {
return vcardType == VCARD_TYPE_DOCOMO;
}
public static boolean isDoCoMo(int vcardType) {
public static boolean isDoCoMo(final int vcardType) {
return ((vcardType & FLAG_DOCOMO) != 0);
}

View File

@@ -23,6 +23,7 @@ import android.provider.ContactsContract.CommonDataKinds.Phone;
import android.provider.ContactsContract.CommonDataKinds.StructuredPostal;
import android.telephony.PhoneNumberUtils;
import android.text.TextUtils;
import android.util.Log;
import java.util.ArrayList;
import java.util.Collection;
@@ -181,26 +182,36 @@ public class VCardUtils {
sPhoneTypesSetUnknownToContacts.contains(phoneType));
}
public static String[] sortNameElements(int vcardType,
String familyName, String middleName, String givenName) {
String[] list = new String[3];
switch (VCardConfig.getNameOrderType(vcardType)) {
case VCardConfig.NAME_ORDER_JAPANESE:
// TODO: Should handle Ascii case?
list[0] = familyName;
list[1] = middleName;
list[2] = givenName;
break;
case VCardConfig.NAME_ORDER_EUROPE:
list[0] = middleName;
list[1] = givenName;
list[2] = familyName;
break;
default:
list[0] = givenName;
list[1] = middleName;
list[2] = familyName;
break;
public static String[] sortNameElements(final int vcardType,
final String familyName, final String middleName, final String givenName) {
final String[] list = new String[3];
final int nameOrderType = VCardConfig.getNameOrderType(vcardType);
switch (nameOrderType) {
case VCardConfig.NAME_ORDER_JAPANESE: {
if (containsOnlyPrintableAscii(familyName) &&
containsOnlyPrintableAscii(givenName)) {
list[0] = givenName;
list[1] = middleName;
list[2] = familyName;
} else {
list[0] = familyName;
list[1] = middleName;
list[2] = givenName;
}
break;
}
case VCardConfig.NAME_ORDER_EUROPE: {
list[0] = middleName;
list[1] = givenName;
list[2] = familyName;
break;
}
default: {
list[0] = givenName;
list[1] = middleName;
list[2] = familyName;
break;
}
}
return list;
}
@@ -302,24 +313,23 @@ public class VCardUtils {
return dataArray;
}
public static String constructNameFromElements(int nameOrderType,
String familyName, String middleName, String givenName) {
return constructNameFromElements(nameOrderType, familyName, middleName, givenName,
public static String constructNameFromElements(final int vcardType,
final String familyName, final String middleName, final String givenName) {
return constructNameFromElements(vcardType, familyName, middleName, givenName,
null, null);
}
public static String constructNameFromElements(int nameOrderType,
String familyName, String middleName, String givenName,
String prefix, String suffix) {
StringBuilder builder = new StringBuilder();
String[] nameList = sortNameElements(nameOrderType,
familyName, middleName, givenName);
public static String constructNameFromElements(final int vcardType,
final String familyName, final String middleName, final String givenName,
final String prefix, final String suffix) {
final StringBuilder builder = new StringBuilder();
final String[] nameList = sortNameElements(vcardType, familyName, middleName, givenName);
boolean first = true;
if (!TextUtils.isEmpty(prefix)) {
first = false;
builder.append(prefix);
}
for (String namePart : nameList) {
for (final String namePart : nameList) {
if (!TextUtils.isEmpty(namePart)) {
if (first) {
first = false;

View File

@@ -0,0 +1,10 @@
BEGIN:vCard
VERSION:2.1
UID:357
N:;Conference Call
FN:Conference Call
# This line must be ignored.
NOTE;ENCODING=QUOTED-PRINTABLE:This is an (sharp ->=
#<- sharp) example. This message must NOT be ignored.
# This line must be ignored too.
END:vCard

View File

@@ -162,6 +162,12 @@ class PropertyNodesVerifierElem {
paramMap_TYPE, null);
}
public PropertyNodesVerifierElem addNodeWithOrder(String propName, String propValue,
ContentValues paramMap, TypeSet paramMap_TYPE) {
return addNodeWithOrder(propName, propValue, null, null,
paramMap, paramMap_TYPE, null);
}
public PropertyNodesVerifierElem addNodeWithOrder(String propName, String propValue,
List<String> propValueList, TypeSet paramMap_TYPE) {
return addNodeWithOrder(propName, propValue, propValueList, null, null,
@@ -223,6 +229,12 @@ class PropertyNodesVerifierElem {
paramMap_TYPE, null);
}
public PropertyNodesVerifierElem addNodeWithoutOrder(String propName, String propValue,
ContentValues paramMap, TypeSet paramMap_TYPE) {
return addNodeWithoutOrder(propName, propValue, null, null,
paramMap, paramMap_TYPE, null);
}
public PropertyNodesVerifierElem addNodeWithoutOrder(String propName, String propValue,
List<String> propValueList, byte[] propValue_bytes,
ContentValues paramMap, TypeSet paramMap_TYPE, GroupSet propGroupSet) {

View File

@@ -268,7 +268,7 @@ public class VCardExporterTests extends VCardTestsBase {
.put(Nickname.NAME, "Nicky");
VCardVerifier verifier = new VCardVerifier(resolver, V30);
verifier.addPropertyNodesVerifierWithEmptyName()
verifier.addPropertyNodesVerifierElemWithEmptyName()
.addNodeWithOrder("NICKNAME", "Nicky");
verifier.verify();
@@ -282,7 +282,7 @@ public class VCardExporterTests extends VCardTestsBase {
.put(Phone.TYPE, Phone.TYPE_HOME);
VCardVerifier verifier = new VCardVerifier(resolver, version);
verifier.addPropertyNodesVerifierWithEmptyName()
verifier.addPropertyNodesVerifierElemWithEmptyName()
.addNodeWithoutOrder("TEL", "1", new TypeSet("HOME"));
verifier.verify();
@@ -353,7 +353,7 @@ public class VCardExporterTests extends VCardTestsBase {
.put(Phone.TYPE, Phone.TYPE_MMS);
VCardVerifier verifier = new VCardVerifier(resolver, version);
verifier.addPropertyNodesVerifierWithEmptyName()
verifier.addPropertyNodesVerifierElemWithEmptyName()
.addNodeWithoutOrder("TEL", "10", new TypeSet("HOME"))
.addNodeWithoutOrder("TEL", "20", new TypeSet("WORK"))
.addNodeWithoutOrder("TEL", "30", new TypeSet("HOME", "FAX"))
@@ -403,7 +403,7 @@ public class VCardExporterTests extends VCardTestsBase {
.put(Phone.TYPE, Phone.TYPE_FAX_WORK);
VCardVerifier verifier = new VCardVerifier(resolver, version);
verifier.addPropertyNodesVerifierWithEmptyName()
verifier.addPropertyNodesVerifierElemWithEmptyName()
.addNodeWithoutOrder("TEL", "4", new TypeSet("WORK", "FAX"))
.addNodeWithoutOrder("TEL", "3", new TypeSet("HOME", "FAX", "PREF"))
.addNodeWithoutOrder("TEL", "2", new TypeSet("WORK", "PREF"))
@@ -426,7 +426,7 @@ public class VCardExporterTests extends VCardTestsBase {
VCardVerifier verifier = new VCardVerifier(resolver, version);
verifier.addPropertyNodesVerifierWithEmptyName()
verifier.addPropertyNodesVerifierElemWithEmptyName()
.addNodeWithoutOrder("EMAIL", "sample@example.com");
verifier.verify();
@@ -459,7 +459,7 @@ public class VCardExporterTests extends VCardTestsBase {
VCardVerifier verifier = new VCardVerifier(resolver, version);
verifier.addPropertyNodesVerifierWithEmptyName()
verifier.addPropertyNodesVerifierElemWithEmptyName()
.addNodeWithoutOrder("EMAIL", "type_home@example.com", new TypeSet("HOME"))
.addNodeWithoutOrder("EMAIL", "type_work@example.com", new TypeSet("WORK"))
.addNodeWithoutOrder("EMAIL", "type_mobile@example.com", new TypeSet("CELL"))
@@ -490,7 +490,7 @@ public class VCardExporterTests extends VCardTestsBase {
VCardVerifier verifier = new VCardVerifier(resolver, version);
verifier.addPropertyNodesVerifierWithEmptyName()
verifier.addPropertyNodesVerifierElemWithEmptyName()
.addNodeWithoutOrder("EMAIL", "type_notype@example.com", new TypeSet("PREF"))
.addNodeWithoutOrder("EMAIL", "type_home@example.com", new TypeSet("HOME", "PREF"));
@@ -520,7 +520,7 @@ public class VCardExporterTests extends VCardTestsBase {
.put(StructuredPostal.POSTCODE, "100")
.put(StructuredPostal.COUNTRY, "Country");
VCardVerifier verifier = new VCardVerifier(resolver, version);
verifier.addPropertyNodesVerifierWithEmptyName()
verifier.addPropertyNodesVerifierElemWithEmptyName()
.addNodeWithoutOrder("ADR", "Pobox;Neighborhood;Street;City;Region;100;Country",
Arrays.asList("Pobox", "Neighborhood", "Street", "City",
"Region", "100", "Country"), new TypeSet("HOME"));
@@ -544,7 +544,7 @@ public class VCardExporterTests extends VCardTestsBase {
"Formatted address CA 123-334 United Statue");
VCardVerifier verifier = new VCardVerifier(resolver, version);
verifier.addPropertyNodesVerifierWithEmptyName()
verifier.addPropertyNodesVerifierElemWithEmptyName()
.addNodeWithOrder("ADR", ";Formatted address CA 123-334 United Statue;;;;;",
Arrays.asList("", "Formatted address CA 123-334 United Statue",
"", "", "", "", ""), new TypeSet("HOME"));
@@ -574,7 +574,7 @@ public class VCardExporterTests extends VCardTestsBase {
"Formatted address CA 123-334 United Statue"); // Should be ignored
VCardVerifier verifier = new VCardVerifier(resolver, version);
verifier.addPropertyNodesVerifierWithEmptyName()
verifier.addPropertyNodesVerifierElemWithEmptyName()
.addNodeWithoutOrder("ADR", "Pobox;;;;;;Country",
Arrays.asList("Pobox", "", "", "", "", "", "Country"),
new TypeSet("HOME"));
@@ -615,7 +615,7 @@ public class VCardExporterTests extends VCardTestsBase {
VCardVerifier verifier = new VCardVerifier(resolver, version);
// Currently we do not use group but depend on the order.
verifier.addPropertyNodesVerifierWithEmptyName()
verifier.addPropertyNodesVerifierElemWithEmptyName()
.addNodeWithOrder("ORG", "CompanyX;DepartmentY",
Arrays.asList("CompanyX", "DepartmentY"))
.addNodeWithOrder("TITLE", "TitleZ")
@@ -677,7 +677,7 @@ public class VCardExporterTests extends VCardTestsBase {
// No determined way to express unknown type...
VCardVerifier verifier = new VCardVerifier(resolver, version);
verifier.addPropertyNodesVerifierWithEmptyName()
verifier.addPropertyNodesVerifierElemWithEmptyName()
.addNodeWithoutOrder("X-JABBER", "jabber")
.addNodeWithoutOrder("X-ICQ", "icq")
.addNodeWithoutOrder("X-GOOGLE-TALK", "google talk")
@@ -714,7 +714,7 @@ public class VCardExporterTests extends VCardTestsBase {
.put(Im.IS_PRIMARY, 1);
VCardVerifier verifier = new VCardVerifier(resolver, version);
verifier.addPropertyNodesVerifierWithEmptyName()
verifier.addPropertyNodesVerifierElemWithEmptyName()
.addNodeWithoutOrder("X-AIM", "aim1")
.addNodeWithoutOrder("X-AIM", "aim2", new TypeSet("HOME", "PREF"));
@@ -743,7 +743,7 @@ public class VCardExporterTests extends VCardTestsBase {
// We drop TYPE information since vCard (especially 3.0) does not allow us to emit it.
VCardVerifier verifier = new VCardVerifier(resolver, version);
verifier.addPropertyNodesVerifierWithEmptyName()
verifier.addPropertyNodesVerifierElemWithEmptyName()
.addNodeWithoutOrder("URL", "ftp://ftp.example.android.com/index.html")
.addNodeWithoutOrder("URL", "http://website.example.android.com/index.html");
verifier.verify();
@@ -779,7 +779,7 @@ public class VCardExporterTests extends VCardTestsBase {
.put(Event.START_DATE, "2009-05-19");
VCardVerifier verifier = new VCardVerifier(resolver, version);
verifier.addPropertyNodesVerifierWithEmptyName()
verifier.addPropertyNodesVerifierElemWithEmptyName()
.addNodeWithoutOrder("BDAY", "2008-10-22");
verifier.verify();
@@ -804,7 +804,7 @@ public class VCardExporterTests extends VCardTestsBase {
.put(Note.IS_PRIMARY, 1); // Just ignored.
VCardVerifier verifier = new VCardVerifier(resolver, version);
verifier.addPropertyNodesVerifierWithEmptyName()
verifier.addPropertyNodesVerifierElemWithEmptyName()
.addNodeWithOrder("NOTE", "note1")
.addNodeWithOrder("NOTE", "note2");
@@ -881,7 +881,7 @@ public class VCardExporterTests extends VCardTestsBase {
.put(Nickname.NAME, "Nicky");
VCardVerifier verifier = new VCardVerifier(resolver, V21);
verifier.addPropertyNodesVerifierWithEmptyName()
verifier.addPropertyNodesVerifierElemWithEmptyName()
.addNodeWithOrder("X-ANDROID-CUSTOM",
Nickname.CONTENT_ITEM_TYPE + ";Nicky;;;;;;;;;;;;;;");
verifier.addImportVerifier()
@@ -897,7 +897,7 @@ public class VCardExporterTests extends VCardTestsBase {
.put(Phone.NUMBER, "111-222-3333 (Miami)\n444-5555-666 (Tokyo);"
+ "777-888-9999 (Chicago);111-222-3333 (Miami)");
VCardVerifier verifier = new VCardVerifier(resolver, V21);
verifier.addPropertyNodesVerifierWithEmptyName()
verifier.addPropertyNodesVerifierElemWithEmptyName()
.addNodeWithoutOrder("TEL", "111-222-3333", new TypeSet("HOME"))
.addNodeWithoutOrder("TEL", "444-555-5666", new TypeSet("HOME"))
.addNodeWithoutOrder("TEL", "777-888-9999", new TypeSet("HOME"));

View File

@@ -784,7 +784,7 @@ public class VCardImporterTests extends VCardTestsBase {
.put(StructuredName.DISPLAY_NAME, "\u5B89\u85E4\u30ED\u30A4\u30C9")
// While vCard parser does not split "SOUND" property values,
// ContactStruct care it.
.put(StructuredName.PHONETIC_FAMILY_NAME,
.put(StructuredName.PHONETIC_GIVEN_NAME,
"\uFF71\uFF9D\uFF84\uFF9E\uFF73\uFF9B\uFF72\uFF84\uFF9E");
elem.addExpected(Phone.CONTENT_ITEM_TYPE)
@@ -937,7 +937,7 @@ public class VCardImporterTests extends VCardTestsBase {
elem.addExpected(StructuredName.CONTENT_ITEM_TYPE)
.put(StructuredName.FAMILY_NAME, "\u5B89\u85E4\u30ED\u30A4\u30C9\u0033")
.put(StructuredName.DISPLAY_NAME, "\u5B89\u85E4\u30ED\u30A4\u30C9\u0033")
.put(StructuredName.PHONETIC_FAMILY_NAME,
.put(StructuredName.PHONETIC_GIVEN_NAME,
"\uFF71\uFF9D\uFF84\uFF9E\uFF73\uFF9B\uFF72\uFF84\uFF9E\u0033");
elem.addExpected(Phone.CONTENT_ITEM_TYPE)
.put(Phone.TYPE, Phone.TYPE_CUSTOM)
@@ -959,7 +959,7 @@ public class VCardImporterTests extends VCardTestsBase {
elem.addExpected(StructuredName.CONTENT_ITEM_TYPE)
.put(StructuredName.FAMILY_NAME, "\u5B89\u85E4\u30ED\u30A4\u30C9\u0034")
.put(StructuredName.DISPLAY_NAME, "\u5B89\u85E4\u30ED\u30A4\u30C9\u0034")
.put(StructuredName.PHONETIC_FAMILY_NAME,
.put(StructuredName.PHONETIC_GIVEN_NAME,
"\uFF71\uFF9D\uFF84\uFF9E\uFF73\uFF9B\uFF72\uFF84\uFF9E\u0034");
elem.addExpected(Phone.CONTENT_ITEM_TYPE)
.put(Phone.TYPE, Phone.TYPE_CUSTOM)
@@ -981,7 +981,7 @@ public class VCardImporterTests extends VCardTestsBase {
elem.addExpected(StructuredName.CONTENT_ITEM_TYPE)
.put(StructuredName.FAMILY_NAME, "\u5B89\u85E4\u30ED\u30A4\u30C9\u0035")
.put(StructuredName.DISPLAY_NAME, "\u5B89\u85E4\u30ED\u30A4\u30C9\u0035")
.put(StructuredName.PHONETIC_FAMILY_NAME,
.put(StructuredName.PHONETIC_GIVEN_NAME,
"\uFF71\uFF9D\uFF84\uFF9E\uFF73\uFF9B\uFF72\uFF84\uFF9E\u0035");
elem.addExpected(Phone.CONTENT_ITEM_TYPE)
.put(Phone.TYPE, Phone.TYPE_CUSTOM)
@@ -1031,6 +1031,18 @@ public class VCardImporterTests extends VCardTestsBase {
new VCardParser_V21(VCardParser.PARSER_MODE_SCAN));
}
public void testTolerateInvalidCommentLikeLineV21() throws IOException, VCardException {
ImportVerifier verifier = new ImportVerifier();
ImportVerifierElem elem = verifier.addImportVerifierElem();
elem.addExpected(StructuredName.CONTENT_ITEM_TYPE)
.put(StructuredName.GIVEN_NAME, "Conference Call")
.put(StructuredName.DISPLAY_NAME, "Conference Call");
elem.addExpected(Note.CONTENT_ITEM_TYPE)
.put(Note.NOTE, "This is an (sharp ->#<- sharp) example. "
+ "This message must NOT be ignored.");
verifier.verify(R.raw.v21_invalid_comment_line, V21);
}
public void testPagerV30_Parse() throws IOException, VCardException {
PropertyNodesVerifier verifier = new PropertyNodesVerifier(this);
verifier.addPropertyNodesVerifierElem()

View File

@@ -106,4 +106,102 @@ public class VCardJapanizationTests extends VCardTestsBase {
.addNodeWithoutOrder("X-DCM-HMN-MODE", "");
verifier.verify();
}
private void testPhoneticNameCommon(int vcardType) {
ExportTestResolver resolver = new ExportTestResolver();
resolver.buildContactEntry().buildData(StructuredName.CONTENT_ITEM_TYPE)
.put(StructuredName.PHONETIC_FAMILY_NAME, "\u3084\u307E\u3060")
.put(StructuredName.PHONETIC_MIDDLE_NAME, "\u30DF\u30C9\u30EB\u30CD\u30FC\u30E0")
.put(StructuredName.PHONETIC_GIVEN_NAME, "\u305F\u308D\u3046");
final ContentValues contentValues =
(VCardConfig.usesShiftJis(vcardType) ?
(VCardConfig.isV30(vcardType) ? mContentValuesForSJis :
mContentValuesForQPAndSJis) :
(VCardConfig.isV30(vcardType) ? null : mContentValuesForQPAndUtf8));
VCardVerifier verifier = new VCardVerifier(resolver, vcardType);
PropertyNodesVerifierElem elem = verifier.addPropertyNodesVerifierElemWithEmptyName();
elem.addNodeWithoutOrder("X-PHONETIC-LAST-NAME", "\u3084\u307E\u3060",
contentValues)
.addNodeWithoutOrder("X-PHONETIC-MIDDLE-NAME",
"\u30DF\u30C9\u30EB\u30CD\u30FC\u30E0",
contentValues)
.addNodeWithoutOrder("X-PHONETIC-FIRST-NAME", "\u305F\u308D\u3046",
contentValues);
if (VCardConfig.isV30(vcardType)) {
elem.addNodeWithoutOrder("SORT-STRING",
"\u3084\u307E\u3060 \u30DF\u30C9\u30EB\u30CD\u30FC\u30E0 \u305F\u308D\u3046",
contentValues);
}
ContentValuesBuilder builder = verifier.addImportVerifier()
.addExpected(StructuredName.CONTENT_ITEM_TYPE);
builder.put(StructuredName.PHONETIC_FAMILY_NAME, "\u3084\u307E\u3060")
.put(StructuredName.PHONETIC_MIDDLE_NAME, "\u30DF\u30C9\u30EB\u30CD\u30FC\u30E0")
.put(StructuredName.PHONETIC_GIVEN_NAME, "\u305F\u308D\u3046")
.put(StructuredName.DISPLAY_NAME,
"\u3084\u307E\u3060 \u30DF\u30C9\u30EB\u30CD\u30FC\u30E0 " +
"\u305F\u308D\u3046");
verifier.verify();
}
public void testPhoneticNameForJapaneseV21Utf8() {
testPhoneticNameCommon(VCardConfig.VCARD_TYPE_V21_JAPANESE_UTF8);
}
public void testPhoneticNameForJapaneseV21Sjis() {
testPhoneticNameCommon(VCardConfig.VCARD_TYPE_V21_JAPANESE_SJIS);
}
public void testPhoneticNameForJapaneseV30Utf8() {
testPhoneticNameCommon(VCardConfig.VCARD_TYPE_V30_JAPANESE_UTF8);
}
public void testPhoneticNameForJapaneseV30SJis() {
testPhoneticNameCommon(VCardConfig.VCARD_TYPE_V30_JAPANESE_SJIS);
}
public void testPhoneticNameForMobileV21_1() {
ExportTestResolver resolver = new ExportTestResolver();
resolver.buildContactEntry().buildData(StructuredName.CONTENT_ITEM_TYPE)
.put(StructuredName.PHONETIC_FAMILY_NAME, "\u3084\u307E\u3060")
.put(StructuredName.PHONETIC_MIDDLE_NAME, "\u30DF\u30C9\u30EB\u30CD\u30FC\u30E0")
.put(StructuredName.PHONETIC_GIVEN_NAME, "\u305F\u308D\u3046");
VCardVerifier verifier = new VCardVerifier(resolver,
VCardConfig.VCARD_TYPE_V21_JAPANESE_MOBILE);
verifier.addPropertyNodesVerifierElem()
.addNodeWithoutOrder("SOUND",
"\uFF94\uFF8F\uFF80\uFF9E \uFF90\uFF84\uFF9E\uFF99\uFF88\uFF70\uFF91 " +
"\uFF80\uFF9B\uFF73;;;;",
mContentValuesForSJis, new TypeSet("X-IRMC-N"));
ContentValuesBuilder builder = verifier.addImportVerifier()
.addExpected(StructuredName.CONTENT_ITEM_TYPE);
builder.put(StructuredName.PHONETIC_FAMILY_NAME, "\uFF94\uFF8F\uFF80\uFF9E")
.put(StructuredName.PHONETIC_MIDDLE_NAME,
"\uFF90\uFF84\uFF9E\uFF99\uFF88\uFF70\uFF91")
.put(StructuredName.PHONETIC_GIVEN_NAME, "\uFF80\uFF9B\uFF73")
.put(StructuredName.DISPLAY_NAME,
"\uFF94\uFF8F\uFF80\uFF9E \uFF90\uFF84\uFF9E\uFF99\uFF88\uFF70\uFF91 " +
"\uFF80\uFF9B\uFF73");
verifier.verify();
}
public void testPhoneticNameForMobileV21_2() {
ExportTestResolver resolver = new ExportTestResolver();
resolver.buildContactEntry().buildData(StructuredName.CONTENT_ITEM_TYPE)
.put(StructuredName.PHONETIC_FAMILY_NAME, "\u3084\u307E\u3060")
.put(StructuredName.PHONETIC_GIVEN_NAME, "\u305F\u308D\u3046");
VCardVerifier verifier = new VCardVerifier(resolver,
VCardConfig.VCARD_TYPE_V21_JAPANESE_MOBILE);
verifier.addPropertyNodesVerifierElem()
.addNodeWithoutOrder("SOUND", "\uFF94\uFF8F\uFF80\uFF9E \uFF80\uFF9B\uFF73;;;;",
mContentValuesForSJis, new TypeSet("X-IRMC-N"));
ContentValuesBuilder builder = verifier.addImportVerifier()
.addExpected(StructuredName.CONTENT_ITEM_TYPE);
builder.put(StructuredName.PHONETIC_FAMILY_NAME, "\uFF94\uFF8F\uFF80\uFF9E")
.put(StructuredName.PHONETIC_GIVEN_NAME, "\uFF80\uFF9B\uFF73")
.put(StructuredName.DISPLAY_NAME, "\uFF94\uFF8F\uFF80\uFF9E \uFF80\uFF9B\uFF73");
verifier.verify();
}
}

View File

@@ -349,10 +349,14 @@ class CustomMockContext extends MockContext {
}
}
if (!checked) {
final String failMsg =
"Unexpected ContentValues for MimeType " + mimeType
+ ": " + actualContentValues;
fail(failMsg);
final StringBuilder builder = new StringBuilder();
builder.append("Unexpected: ");
builder.append(convertToEasilyReadableString(actualContentValues));
builder.append("\nExpected: ");
for (ContentValues expectedContentValues : contentValuesCollection) {
builder.append(convertToEasilyReadableString(expectedContentValues));
}
fail(builder.toString());
}
} else {
fail("Unexpected Uri has come: " + uri);
@@ -823,7 +827,7 @@ class CustomMockContext extends MockContext {
return elem;
}
public PropertyNodesVerifierElem addPropertyNodesVerifierWithEmptyName() {
public PropertyNodesVerifierElem addPropertyNodesVerifierElemWithEmptyName() {
PropertyNodesVerifierElem elem = addPropertyNodesVerifierElem();
if (mIsV30) {
elem.addNodeWithOrder("N", "").addNodeWithOrder("FN", "");
@@ -847,14 +851,16 @@ class CustomMockContext extends MockContext {
}
private void verifyOneVCard(final String vcard) {
// Log.d("@@@", vcard);
final VCardBuilder builder;
if (mImportVerifier != null) {
final VNodeBuilder vnodeBuilder = mPropertyNodesVerifier;
final VCardDataBuilder vcardDataBuilder = new VCardDataBuilder();
final VCardDataBuilder vcardDataBuilder =
new VCardDataBuilder(mVCardType);
vcardDataBuilder.addEntryHandler(mImportVerifier);
if (mPropertyNodesVerifier != null) {
builder = new VCardBuilderCollection(Arrays.asList(
vcardDataBuilder, mPropertyNodesVerifier));
mPropertyNodesVerifier, vcardDataBuilder));
} else {
builder = vnodeBuilder;
}