Add a test for vCard composer.
Also modify the behavior of vCard composer so that it honer FN than N toward DISPLAY_NAME. Internal issuen number: 2195990
This commit is contained in:
@ -742,10 +742,9 @@ public class VCardComposer {
|
|||||||
encodedSuffix = escapeCharacters(suffix);
|
encodedSuffix = escapeCharacters(suffix);
|
||||||
}
|
}
|
||||||
|
|
||||||
// N property. This order is specified by vCard spec and does not depend on countries.
|
|
||||||
builder.append(Constants.PROPERTY_N);
|
builder.append(Constants.PROPERTY_N);
|
||||||
if (shouldAppendCharsetAttribute(Arrays.asList(
|
if (shouldAppendCharsetAttribute(Arrays.asList(
|
||||||
familyName, givenName, middleName, prefix, suffix))) {
|
encodedFamily, encodedGiven, encodedMiddle, encodedPrefix, encodedSuffix))) {
|
||||||
builder.append(VCARD_ATTR_SEPARATOR);
|
builder.append(VCARD_ATTR_SEPARATOR);
|
||||||
builder.append(mVCardAttributeCharset);
|
builder.append(mVCardAttributeCharset);
|
||||||
}
|
}
|
||||||
@ -766,9 +765,15 @@ public class VCardComposer {
|
|||||||
builder.append(encodedSuffix);
|
builder.append(encodedSuffix);
|
||||||
builder.append(VCARD_COL_SEPARATOR);
|
builder.append(VCARD_COL_SEPARATOR);
|
||||||
|
|
||||||
final String formattedName = VCardUtils.constructNameFromElements(
|
final String formattedName;
|
||||||
|
if (!TextUtils.isEmpty(displayName)) {
|
||||||
|
formattedName = displayName;
|
||||||
|
} else {
|
||||||
|
formattedName = VCardUtils.constructNameFromElements(
|
||||||
VCardConfig.getNameOrderType(mVCardType),
|
VCardConfig.getNameOrderType(mVCardType),
|
||||||
encodedFamily, encodedMiddle, encodedGiven, encodedPrefix, encodedSuffix);
|
encodedFamily, encodedMiddle, encodedGiven, encodedPrefix, encodedSuffix);
|
||||||
|
}
|
||||||
|
|
||||||
final boolean reallyUseQuotedPrintableToFullname =
|
final boolean reallyUseQuotedPrintableToFullname =
|
||||||
!mRefrainsQPToPrimaryProperties &&
|
!mRefrainsQPToPrimaryProperties &&
|
||||||
!VCardUtils.containsOnlyNonCrLfPrintableAscii(formattedName);
|
!VCardUtils.containsOnlyNonCrLfPrintableAscii(formattedName);
|
||||||
@ -1501,7 +1506,7 @@ public class VCardComposer {
|
|||||||
final StringBuilder tmpBuilder = new StringBuilder();
|
final StringBuilder tmpBuilder = new StringBuilder();
|
||||||
final int length = unescaped.length();
|
final int length = unescaped.length();
|
||||||
for (int i = 0; i < length; i++) {
|
for (int i = 0; i < length; i++) {
|
||||||
char ch = unescaped.charAt(i);
|
final char ch = unescaped.charAt(i);
|
||||||
switch (ch) {
|
switch (ch) {
|
||||||
case ';': {
|
case ';': {
|
||||||
tmpBuilder.append('\\');
|
tmpBuilder.append('\\');
|
||||||
@ -1512,7 +1517,7 @@ public class VCardComposer {
|
|||||||
if (i + 1 < length) {
|
if (i + 1 < length) {
|
||||||
char nextChar = unescaped.charAt(i);
|
char nextChar = unescaped.charAt(i);
|
||||||
if (nextChar == '\n') {
|
if (nextChar == '\n') {
|
||||||
continue;
|
break;
|
||||||
} else {
|
} else {
|
||||||
// fall through
|
// fall through
|
||||||
}
|
}
|
||||||
|
@ -70,6 +70,21 @@ public class PropertyNodesVerifier {
|
|||||||
return addNodeWithOrder(propName, propValue, propValueList, null, null, null, null);
|
return addNodeWithOrder(propName, propValue, propValueList, null, null, null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public PropertyNodesVerifier addNodeWithOrder(String propName, List<String> propValueList) {
|
||||||
|
StringBuffer buffer = new StringBuffer();
|
||||||
|
boolean first = true;
|
||||||
|
for (String propValueElem : propValueList) {
|
||||||
|
if (first) {
|
||||||
|
first = false;
|
||||||
|
} else {
|
||||||
|
buffer.append(';');
|
||||||
|
}
|
||||||
|
buffer.append(propValueElem);
|
||||||
|
}
|
||||||
|
return addNodeWithOrder(propName, buffer.toString(), propValueList,
|
||||||
|
null, null, null, null);
|
||||||
|
}
|
||||||
|
|
||||||
public PropertyNodesVerifier addNodeWithOrder(String propName, String propValue,
|
public PropertyNodesVerifier addNodeWithOrder(String propName, String propValue,
|
||||||
TypeSet paramMap_TYPE) {
|
TypeSet paramMap_TYPE) {
|
||||||
return addNodeWithOrder(propName, propValue, null, null, null, paramMap_TYPE, null);
|
return addNodeWithOrder(propName, propValue, null, null, null, paramMap_TYPE, null);
|
||||||
@ -107,6 +122,21 @@ public class PropertyNodesVerifier {
|
|||||||
return addNodeWithoutOrder(propName, propValue, propValueList, null, null, null, null);
|
return addNodeWithoutOrder(propName, propValue, propValueList, null, null, null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public PropertyNodesVerifier addNodeWithoutOrder(String propName, List<String> propValueList) {
|
||||||
|
StringBuffer buffer = new StringBuffer();
|
||||||
|
boolean first = true;
|
||||||
|
for (String propValueElem : propValueList) {
|
||||||
|
if (first) {
|
||||||
|
first = false;
|
||||||
|
} else {
|
||||||
|
buffer.append(';');
|
||||||
|
}
|
||||||
|
buffer.append(propValueElem);
|
||||||
|
}
|
||||||
|
return addNodeWithoutOrder(propName, buffer.toString(), propValueList,
|
||||||
|
null, null, null, null);
|
||||||
|
}
|
||||||
|
|
||||||
public PropertyNodesVerifier addNodeWithoutOrder(String propName, String propValue,
|
public PropertyNodesVerifier addNodeWithoutOrder(String propName, String propValue,
|
||||||
TypeSet paramMap_TYPE) {
|
TypeSet paramMap_TYPE) {
|
||||||
return addNodeWithoutOrder(propName, propValue, null, null, null, paramMap_TYPE, null);
|
return addNodeWithoutOrder(propName, propValue, null, null, null, paramMap_TYPE, null);
|
||||||
|
@ -16,8 +16,6 @@
|
|||||||
|
|
||||||
package com.android.unit_tests.vcard;
|
package com.android.unit_tests.vcard;
|
||||||
|
|
||||||
import com.android.unit_tests.vcard.PropertyNodesVerifier.TypeSet;
|
|
||||||
|
|
||||||
import android.content.ContentProvider;
|
import android.content.ContentProvider;
|
||||||
import android.content.ContentProviderOperation;
|
import android.content.ContentProviderOperation;
|
||||||
import android.content.ContentProviderResult;
|
import android.content.ContentProviderResult;
|
||||||
@ -60,16 +58,20 @@ import android.test.mock.MockContentResolver;
|
|||||||
import android.test.mock.MockContext;
|
import android.test.mock.MockContext;
|
||||||
import android.test.mock.MockCursor;
|
import android.test.mock.MockCursor;
|
||||||
|
|
||||||
|
import com.android.unit_tests.vcard.PropertyNodesVerifier.TypeSet;
|
||||||
|
|
||||||
|
import junit.framework.TestCase;
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
import junit.framework.TestCase;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Almost a dead copy of android.test.mock.MockContentProvider, but different in that this
|
* Almost a dead copy of android.test.mock.MockContentProvider, but different in that this
|
||||||
@ -292,12 +294,16 @@ public class VCardExporterTests extends AndroidTestCase {
|
|||||||
final private TestCase mTestCase;
|
final private TestCase mTestCase;
|
||||||
final private List<PropertyNodesVerifier> mPropertyNodesVerifierList;
|
final private List<PropertyNodesVerifier> mPropertyNodesVerifierList;
|
||||||
final private boolean mIsV30;
|
final private boolean mIsV30;
|
||||||
|
// To allow duplication, use list instead of set.
|
||||||
|
// TODO: support multiple vCard entries.
|
||||||
|
final private List<String> mExpectedLineList;
|
||||||
int mCount;
|
int mCount;
|
||||||
|
|
||||||
public VCardVerificationHandler(TestCase testCase, int version) {
|
public VCardVerificationHandler(final TestCase testCase, final int version) {
|
||||||
mTestCase = testCase;
|
mTestCase = testCase;
|
||||||
mPropertyNodesVerifierList = new ArrayList<PropertyNodesVerifier>();
|
mPropertyNodesVerifierList = new ArrayList<PropertyNodesVerifier>();
|
||||||
mIsV30 = (version == V30);
|
mIsV30 = (version == V30);
|
||||||
|
mExpectedLineList = new ArrayList<String>();
|
||||||
mCount = 1;
|
mCount = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -316,11 +322,51 @@ public class VCardExporterTests extends AndroidTestCase {
|
|||||||
return verifier;
|
return verifier;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean onInit(Context context) {
|
public VCardVerificationHandler addExpectedLine(String line) {
|
||||||
|
mExpectedLineList.add(line);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean onInit(final Context context) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean onEntryCreated(String vcard) {
|
public boolean onEntryCreated(final String vcard) {
|
||||||
|
if (!mExpectedLineList.isEmpty()) {
|
||||||
|
verifyLines(vcard);
|
||||||
|
}
|
||||||
|
verifyNodes(vcard);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void verifyLines(final String vcard) {
|
||||||
|
final String[] lineArray = vcard.split("\\r?\\n");
|
||||||
|
final int length = lineArray.length;
|
||||||
|
for (int i = 0; i < length; i++) {
|
||||||
|
final String line = lineArray[i];
|
||||||
|
// TODO: support multiple vcard entries.
|
||||||
|
if ("BEGIN:VCARD".equals(line) || "END:VCARD".equals(line) ||
|
||||||
|
(mIsV30 ? "VERSION:3.0" : "VERSION:2.1").equals(line)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
final int index = mExpectedLineList.indexOf(line);
|
||||||
|
if (index >= 0) {
|
||||||
|
mExpectedLineList.remove(index);
|
||||||
|
} else {
|
||||||
|
mTestCase.fail("Unexpected line: " + line);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!mExpectedLineList.isEmpty()) {
|
||||||
|
StringBuffer buffer = new StringBuffer();
|
||||||
|
for (String expectedLine : mExpectedLineList) {
|
||||||
|
buffer.append(expectedLine);
|
||||||
|
buffer.append("\n");
|
||||||
|
}
|
||||||
|
mTestCase.fail("Expected line(s) not found:" + buffer.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void verifyNodes(final String vcard) {
|
||||||
if (mPropertyNodesVerifierList.size() == 0) {
|
if (mPropertyNodesVerifierList.size() == 0) {
|
||||||
mTestCase.fail("Too many vCard entries seems to be inserted(No."
|
mTestCase.fail("Too many vCard entries seems to be inserted(No."
|
||||||
+ mCount + " of the entries (No.1 is the first entry))");
|
+ mCount + " of the entries (No.1 is the first entry))");
|
||||||
@ -344,7 +390,6 @@ public class VCardExporterTests extends AndroidTestCase {
|
|||||||
} finally {
|
} finally {
|
||||||
mCount++;
|
mCount++;
|
||||||
}
|
}
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onTerminate() {
|
public void onTerminate() {
|
||||||
@ -1178,8 +1223,6 @@ public class VCardExporterTests extends AndroidTestCase {
|
|||||||
testNoteCommon(V30);
|
testNoteCommon(V30);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: test for non-ascii...
|
|
||||||
|
|
||||||
private void testPhotoCommon(int version) {
|
private void testPhotoCommon(int version) {
|
||||||
final boolean isV30 = version == V30;
|
final boolean isV30 = version == V30;
|
||||||
ExportTestResolver resolver = new ExportTestResolver();
|
ExportTestResolver resolver = new ExportTestResolver();
|
||||||
@ -1208,4 +1251,24 @@ public class VCardExporterTests extends AndroidTestCase {
|
|||||||
public void testPhotoV30() {
|
public void testPhotoV30() {
|
||||||
testPhotoCommon(V30);
|
testPhotoCommon(V30);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testV30HandleEscape() {
|
||||||
|
final int version = V30;
|
||||||
|
ExportTestResolver resolver = new ExportTestResolver();
|
||||||
|
ContentValues contentValues = resolver.buildData(StructuredName.CONTENT_ITEM_TYPE);
|
||||||
|
contentValues.put(StructuredName.FAMILY_NAME, "\\");
|
||||||
|
contentValues.put(StructuredName.GIVEN_NAME, ";");
|
||||||
|
contentValues.put(StructuredName.MIDDLE_NAME, ",");
|
||||||
|
contentValues.put(StructuredName.PREFIX, "\n");
|
||||||
|
contentValues.put(StructuredName.DISPLAY_NAME, "[<{Unescaped:Asciis}>]");
|
||||||
|
VCardVerificationHandler handler = new VCardVerificationHandler(this, version);
|
||||||
|
// Verifies the vCard String correctly escapes each character which must be escaped.
|
||||||
|
handler.addExpectedLine("N:\\\\;\\;;\\,;\\n;")
|
||||||
|
.addExpectedLine("FN:[<{Unescaped:Asciis}>]");
|
||||||
|
handler.addNewVerifier()
|
||||||
|
.addNodeWithoutOrder("FN", "[<{Unescaped:Asciis}>]")
|
||||||
|
.addNodeWithoutOrder("N", Arrays.asList("\\", ";", ",", "\n", ""));
|
||||||
|
|
||||||
|
verifyOneComposition(resolver, handler, version);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user