Merge change I2a52a60a into eclair-mr2
* changes: Implement unit tests for vCard exporter, which depends on the sucess in vCard importer.
This commit is contained in:
@@ -111,6 +111,10 @@ public class VCardComposer {
|
||||
public static final String FAILURE_REASON_NOT_INITIALIZED =
|
||||
"The vCard composer object is not correctly initialized";
|
||||
|
||||
/** Should be visible only from developers... (no need to translate, hopefully) */
|
||||
public static final String FAILURE_REASON_UNSUPPORTED_URI =
|
||||
"The Uri vCard composer received is not supported by the composer.";
|
||||
|
||||
public static final String NO_ERROR = "No error";
|
||||
|
||||
public static final String VCARD_TYPE_STRING_DOCOMO = "docomo";
|
||||
@@ -138,6 +142,15 @@ public class VCardComposer {
|
||||
|
||||
private static final String SHIFT_JIS = "SHIFT_JIS";
|
||||
|
||||
/**
|
||||
* Special URI for testing.
|
||||
*/
|
||||
public static final String VCARD_TEST_AUTHORITY = "com.android.unit_tests.vcard";
|
||||
public static final Uri VCARD_TEST_AUTHORITY_URI =
|
||||
Uri.parse("content://" + VCARD_TEST_AUTHORITY);
|
||||
public static final Uri CONTACTS_TEST_CONTENT_URI =
|
||||
Uri.withAppendedPath(VCARD_TEST_AUTHORITY_URI, "contacts");
|
||||
|
||||
private static final Uri sDataRequestUri;
|
||||
private static final Map<Integer, String> sImMap;
|
||||
|
||||
@@ -286,7 +299,7 @@ public class VCardComposer {
|
||||
|
||||
private String mErrorReason = NO_ERROR;
|
||||
|
||||
private boolean mIsCallLogComposer = false;
|
||||
private boolean mIsCallLogComposer;
|
||||
|
||||
private static final String[] sContactsProjection = new String[] {
|
||||
Contacts._ID,
|
||||
@@ -307,30 +320,24 @@ public class VCardComposer {
|
||||
private static final String FLAG_TIMEZONE_UTC = "Z";
|
||||
|
||||
public VCardComposer(Context context) {
|
||||
this(context, VCardConfig.VCARD_TYPE_DEFAULT, true, false);
|
||||
this(context, VCardConfig.VCARD_TYPE_DEFAULT, true);
|
||||
}
|
||||
|
||||
public VCardComposer(Context context, String vcardTypeStr,
|
||||
boolean careHandlerErrors) {
|
||||
this(context, VCardConfig.getVCardTypeFromString(vcardTypeStr),
|
||||
careHandlerErrors, false);
|
||||
public VCardComposer(Context context, int vcardType) {
|
||||
this(context, vcardType, true);
|
||||
}
|
||||
|
||||
public VCardComposer(Context context, int vcardType, boolean careHandlerErrors) {
|
||||
this(context, vcardType, careHandlerErrors, false);
|
||||
public VCardComposer(Context context, String vcardTypeStr, boolean careHandlerErrors) {
|
||||
this(context, VCardConfig.getVCardTypeFromString(vcardTypeStr), careHandlerErrors);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct for supporting call log entry vCard composing.
|
||||
*
|
||||
* @param isCallLogComposer true if this composer is for creating Call Log vCard.
|
||||
*/
|
||||
public VCardComposer(Context context, int vcardType, boolean careHandlerErrors,
|
||||
boolean isCallLogComposer) {
|
||||
public VCardComposer(Context context, int vcardType, boolean careHandlerErrors) {
|
||||
mContext = context;
|
||||
mVCardType = vcardType;
|
||||
mCareHandlerErrors = careHandlerErrors;
|
||||
mIsCallLogComposer = isCallLogComposer;
|
||||
mContentResolver = context.getContentResolver();
|
||||
|
||||
mIsV30 = VCardConfig.isV30(vcardType);
|
||||
@@ -370,15 +377,26 @@ public class VCardComposer {
|
||||
mHandlerList.add(handler);
|
||||
}
|
||||
|
||||
public boolean init() {
|
||||
return init(null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Returns true when initialization is successful and all the other
|
||||
* methods are available. Returns false otherwise.
|
||||
*/
|
||||
public boolean init() {
|
||||
return init(null, null);
|
||||
}
|
||||
|
||||
public boolean init(final String selection, final String[] selectionArgs) {
|
||||
return init(Contacts.CONTENT_URI, selection, selectionArgs, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Note that this is unstable interface, may be deleted in the future.
|
||||
*/
|
||||
public boolean init(final Uri contentUri, final String selection,
|
||||
final String[] selectionArgs, final String sortOrder) {
|
||||
if (contentUri == null) {
|
||||
return false;
|
||||
}
|
||||
if (mCareHandlerErrors) {
|
||||
List<OneEntryHandler> finishedList = new ArrayList<OneEntryHandler>(
|
||||
mHandlerList.size());
|
||||
@@ -397,13 +415,19 @@ public class VCardComposer {
|
||||
}
|
||||
}
|
||||
|
||||
if (mIsCallLogComposer) {
|
||||
mCursor = mContentResolver.query(CallLog.Calls.CONTENT_URI, sCallLogProjection,
|
||||
selection, selectionArgs, null);
|
||||
final String[] projection;
|
||||
if (CallLog.Calls.CONTENT_URI.equals(contentUri)) {
|
||||
projection = sCallLogProjection;
|
||||
mIsCallLogComposer = true;
|
||||
} else if (Contacts.CONTENT_URI.equals(contentUri) ||
|
||||
CONTACTS_TEST_CONTENT_URI.equals(contentUri)) {
|
||||
projection = sContactsProjection;
|
||||
} else {
|
||||
mCursor = mContentResolver.query(Contacts.CONTENT_URI, sContactsProjection,
|
||||
selection, selectionArgs, null);
|
||||
mErrorReason = FAILURE_REASON_UNSUPPORTED_URI;
|
||||
return false;
|
||||
}
|
||||
mCursor = mContentResolver.query(
|
||||
contentUri, projection, selection, selectionArgs, sortOrder);
|
||||
|
||||
if (mCursor == null) {
|
||||
mErrorReason = FAILURE_REASON_FAILED_TO_GET_DATABASE_INFO;
|
||||
@@ -496,8 +520,7 @@ public class VCardComposer {
|
||||
dataExists = entityIterator.hasNext();
|
||||
while (entityIterator.hasNext()) {
|
||||
Entity entity = entityIterator.next();
|
||||
for (NamedContentValues namedContentValues : entity
|
||||
.getSubValues()) {
|
||||
for (NamedContentValues namedContentValues : entity.getSubValues()) {
|
||||
ContentValues contentValues = namedContentValues.values;
|
||||
String key = contentValues.getAsString(Data.MIMETYPE);
|
||||
if (key != null) {
|
||||
|
||||
@@ -525,10 +525,18 @@ public class VCardParser_V21 extends VCardParser {
|
||||
throw new VCardException("Unknown type \"" + paramName + "\"");
|
||||
}
|
||||
} else {
|
||||
handleType(strArray[0]);
|
||||
handleParamWithoutName(strArray[0]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* vCard 3.0 parser may throw VCardException.
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
protected void handleParamWithoutName(final String paramValue) throws VCardException {
|
||||
handleType(paramValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* ptypeval = knowntype / "X-" word
|
||||
*/
|
||||
@@ -832,6 +840,9 @@ public class VCardParser_V21 extends VCardParser {
|
||||
@Override
|
||||
public boolean parse(InputStream is, String charset, VCardBuilder builder)
|
||||
throws IOException, VCardException {
|
||||
if (charset == null) {
|
||||
charset = VCardConfig.DEFAULT_CHARSET;
|
||||
}
|
||||
final InputStreamReader tmpReader = new InputStreamReader(is, charset);
|
||||
if (VCardConfig.showPerformanceLog()) {
|
||||
mReader = new CustomBufferedReader(tmpReader);
|
||||
|
||||
@@ -46,9 +46,32 @@ public class VCardParser_V30 extends VCardParser_V21 {
|
||||
private static final HashSet<String> acceptablePropsWithoutParam = new HashSet<String>();
|
||||
|
||||
private String mPreviousLine;
|
||||
|
||||
|
||||
private boolean mEmittedAgentWarning = false;
|
||||
|
||||
/**
|
||||
* True when the caller wants the parser to be strict about the input.
|
||||
* Currently this is only for testing.
|
||||
*/
|
||||
private final boolean mStrictParsing;
|
||||
|
||||
public VCardParser_V30() {
|
||||
super();
|
||||
mStrictParsing = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param strictParsing when true, this object throws VCardException when the vcard is not
|
||||
* valid from the view of vCard 3.0 specification (defined in RFC 2426). Note that this class
|
||||
* is not fully yet for being used with this flag and may not notice invalid line(s).
|
||||
*
|
||||
* @hide currently only for testing!
|
||||
*/
|
||||
public VCardParser_V30(boolean strictParsing) {
|
||||
super();
|
||||
mStrictParsing = strictParsing;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getVersion() {
|
||||
return VCardConfig.FLAG_V30;
|
||||
@@ -204,7 +227,16 @@ public class VCardParser_V30 extends VCardParser_V21 {
|
||||
// TODO: fix this.
|
||||
super.handleAnyParam(paramName, paramValue);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void handleParamWithoutName(final String paramValue) throws VCardException {
|
||||
if (mStrictParsing) {
|
||||
throw new VCardException("Parameter without name is not acceptable in vCard 3.0");
|
||||
} else {
|
||||
super.handleParamWithoutName(paramValue);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* vCard 3.0 defines
|
||||
*
|
||||
|
||||
@@ -0,0 +1,254 @@
|
||||
/*
|
||||
* Copyright (C) 2009 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.unit_tests.vcard;
|
||||
|
||||
import android.content.ContentResolver;
|
||||
import android.database.CharArrayBuffer;
|
||||
import android.database.ContentObserver;
|
||||
import android.database.Cursor;
|
||||
import android.database.DataSetObserver;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class MockCursor implements Cursor {
|
||||
public int getColumnCount() {
|
||||
throw new UnsupportedOperationException("unimplemented mock method");
|
||||
}
|
||||
|
||||
public int getColumnIndex(String columnName) {
|
||||
throw new UnsupportedOperationException("unimplemented mock method");
|
||||
}
|
||||
|
||||
public int getColumnIndexOrThrow(String columnName) {
|
||||
throw new UnsupportedOperationException("unimplemented mock method");
|
||||
}
|
||||
|
||||
public String getColumnName(int columnIndex) {
|
||||
throw new UnsupportedOperationException("unimplemented mock method");
|
||||
}
|
||||
|
||||
public String[] getColumnNames() {
|
||||
throw new UnsupportedOperationException("unimplemented mock method");
|
||||
}
|
||||
|
||||
public int getCount() {
|
||||
throw new UnsupportedOperationException("unimplemented mock method");
|
||||
}
|
||||
|
||||
public boolean isNull(int columnIndex) {
|
||||
throw new UnsupportedOperationException("unimplemented mock method");
|
||||
}
|
||||
|
||||
public int getInt(int columnIndex) {
|
||||
throw new UnsupportedOperationException("unimplemented mock method");
|
||||
}
|
||||
|
||||
public long getLong(int columnIndex) {
|
||||
throw new UnsupportedOperationException("unimplemented mock method");
|
||||
}
|
||||
|
||||
public short getShort(int columnIndex) {
|
||||
throw new UnsupportedOperationException("unimplemented mock method");
|
||||
}
|
||||
|
||||
public float getFloat(int columnIndex) {
|
||||
throw new UnsupportedOperationException("unimplemented mock method");
|
||||
}
|
||||
|
||||
public double getDouble(int columnIndex) {
|
||||
throw new UnsupportedOperationException("unimplemented mock method");
|
||||
}
|
||||
|
||||
public byte[] getBlob(int columnIndex) {
|
||||
throw new UnsupportedOperationException("unimplemented mock method");
|
||||
}
|
||||
|
||||
public String getString(int columnIndex) {
|
||||
throw new UnsupportedOperationException("unimplemented mock method");
|
||||
}
|
||||
|
||||
public Bundle getExtras() {
|
||||
throw new UnsupportedOperationException("unimplemented mock method");
|
||||
}
|
||||
|
||||
public int getPosition() {
|
||||
throw new UnsupportedOperationException("unimplemented mock method");
|
||||
}
|
||||
|
||||
public boolean isAfterLast() {
|
||||
throw new UnsupportedOperationException("unimplemented mock method");
|
||||
}
|
||||
|
||||
public boolean isBeforeFirst() {
|
||||
throw new UnsupportedOperationException("unimplemented mock method");
|
||||
}
|
||||
|
||||
public boolean isFirst() {
|
||||
throw new UnsupportedOperationException("unimplemented mock method");
|
||||
}
|
||||
|
||||
public boolean isLast() {
|
||||
throw new UnsupportedOperationException("unimplemented mock method");
|
||||
}
|
||||
|
||||
public boolean move(int offset) {
|
||||
throw new UnsupportedOperationException("unimplemented mock method");
|
||||
}
|
||||
|
||||
public boolean moveToFirst() {
|
||||
throw new UnsupportedOperationException("unimplemented mock method");
|
||||
}
|
||||
|
||||
public boolean moveToLast() {
|
||||
throw new UnsupportedOperationException("unimplemented mock method");
|
||||
}
|
||||
|
||||
public boolean moveToNext() {
|
||||
throw new UnsupportedOperationException("unimplemented mock method");
|
||||
}
|
||||
|
||||
public boolean moveToPrevious() {
|
||||
throw new UnsupportedOperationException("unimplemented mock method");
|
||||
}
|
||||
|
||||
public boolean moveToPosition(int position) {
|
||||
throw new UnsupportedOperationException("unimplemented mock method");
|
||||
}
|
||||
|
||||
public void copyStringToBuffer(int columnIndex, CharArrayBuffer buffer) {
|
||||
throw new UnsupportedOperationException("unimplemented mock method");
|
||||
}
|
||||
|
||||
public void deactivate() {
|
||||
throw new UnsupportedOperationException("unimplemented mock method");
|
||||
}
|
||||
|
||||
public void close() {
|
||||
throw new UnsupportedOperationException("unimplemented mock method");
|
||||
}
|
||||
|
||||
public boolean isClosed() {
|
||||
throw new UnsupportedOperationException("unimplemented mock method");
|
||||
}
|
||||
|
||||
public boolean requery() {
|
||||
throw new UnsupportedOperationException("unimplemented mock method");
|
||||
}
|
||||
|
||||
public void registerContentObserver(ContentObserver observer) {
|
||||
throw new UnsupportedOperationException("unimplemented mock method");
|
||||
}
|
||||
|
||||
public void registerDataSetObserver(DataSetObserver observer) {
|
||||
throw new UnsupportedOperationException("unimplemented mock method");
|
||||
}
|
||||
|
||||
public Bundle respond(Bundle extras) {
|
||||
throw new UnsupportedOperationException("unimplemented mock method");
|
||||
}
|
||||
|
||||
public boolean getWantsAllOnMoveCalls() {
|
||||
throw new UnsupportedOperationException("unimplemented mock method");
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public boolean commitUpdates() {
|
||||
throw new UnsupportedOperationException("unimplemented mock method");
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public boolean commitUpdates(Map<? extends Long, ? extends Map<String, Object>> values) {
|
||||
throw new UnsupportedOperationException("unimplemented mock method");
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public boolean hasUpdates() {
|
||||
throw new UnsupportedOperationException("unimplemented mock method");
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public void setNotificationUri(ContentResolver cr, Uri uri) {
|
||||
throw new UnsupportedOperationException("unimplemented mock method");
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public boolean supportsUpdates() {
|
||||
throw new UnsupportedOperationException("unimplemented mock method");
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public boolean deleteRow() {
|
||||
throw new UnsupportedOperationException("unimplemented mock method");
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public void unregisterContentObserver(ContentObserver observer) {
|
||||
throw new UnsupportedOperationException("unimplemented mock method");
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public void unregisterDataSetObserver(DataSetObserver observer) {
|
||||
throw new UnsupportedOperationException("unimplemented mock method");
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public boolean updateBlob(int columnIndex, byte[] value) {
|
||||
throw new UnsupportedOperationException("unimplemented mock method");
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public boolean updateDouble(int columnIndex, double value) {
|
||||
throw new UnsupportedOperationException("unimplemented mock method");
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public boolean updateFloat(int columnIndex, float value) {
|
||||
throw new UnsupportedOperationException("unimplemented mock method");
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public boolean updateInt(int columnIndex, int value) {
|
||||
throw new UnsupportedOperationException("unimplemented mock method");
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public boolean updateLong(int columnIndex, long value) {
|
||||
throw new UnsupportedOperationException("unimplemented mock method");
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public boolean updateShort(int columnIndex, short value) {
|
||||
throw new UnsupportedOperationException("unimplemented mock method");
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public boolean updateString(int columnIndex, String value) {
|
||||
throw new UnsupportedOperationException("unimplemented mock method");
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public boolean updateToNull(int columnIndex) {
|
||||
throw new UnsupportedOperationException("unimplemented mock method");
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public void abortUpdates() {
|
||||
throw new UnsupportedOperationException("unimplemented mock method");
|
||||
}
|
||||
}
|
||||
@@ -18,15 +18,11 @@ package com.android.unit_tests.vcard;
|
||||
import android.content.ContentValues;
|
||||
import android.pim.vcard.ContactStruct;
|
||||
|
||||
import org.apache.commons.codec.binary.Base64;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* Previously used in main vCard handling code but now exists only for testing.
|
||||
@@ -106,6 +102,15 @@ public class PropertyNode {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
// vCard may contain more than one same line in one entry, while HashSet or any other
|
||||
// library which utilize hashCode() does not honor that, so intentionally throw an
|
||||
// Exception.
|
||||
throw new UnsupportedOperationException(
|
||||
"PropertyNode does not provide hashCode() implementation intentionally.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (!(obj instanceof PropertyNode)) {
|
||||
@@ -165,164 +170,4 @@ public class PropertyNode {
|
||||
builder.append(propValue);
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode this object into a string which can be decoded.
|
||||
*/
|
||||
public String encode() {
|
||||
// PropertyNode#toString() is for reading, not for parsing in the future.
|
||||
// We construct appropriate String here.
|
||||
StringBuilder builder = new StringBuilder();
|
||||
if (propName.length() > 0) {
|
||||
builder.append("propName:[");
|
||||
builder.append(propName);
|
||||
builder.append("],");
|
||||
}
|
||||
int size = propGroupSet.size();
|
||||
if (size > 0) {
|
||||
Set<String> set = propGroupSet;
|
||||
builder.append("propGroup:[");
|
||||
int i = 0;
|
||||
for (String group : set) {
|
||||
// We do not need to double quote groups.
|
||||
// group = 1*(ALPHA / DIGIT / "-")
|
||||
builder.append(group);
|
||||
if (i < size - 1) {
|
||||
builder.append(",");
|
||||
}
|
||||
i++;
|
||||
}
|
||||
builder.append("],");
|
||||
}
|
||||
|
||||
if (paramMap.size() > 0 || paramMap_TYPE.size() > 0) {
|
||||
ContentValues values = paramMap;
|
||||
builder.append("paramMap:[");
|
||||
size = paramMap.size();
|
||||
int i = 0;
|
||||
for (Entry<String, Object> entry : values.valueSet()) {
|
||||
// Assuming param-key does not contain NON-ASCII nor symbols.
|
||||
//
|
||||
// According to vCard 3.0:
|
||||
// param-name = iana-token / x-name
|
||||
builder.append(entry.getKey());
|
||||
|
||||
// param-value may contain any value including NON-ASCIIs.
|
||||
// We use the following replacing rule.
|
||||
// \ -> \\
|
||||
// , -> \,
|
||||
// In String#replaceAll(), "\\\\" means a single backslash.
|
||||
builder.append("=");
|
||||
builder.append(entry.getValue().toString()
|
||||
.replaceAll("\\\\", "\\\\\\\\")
|
||||
.replaceAll(",", "\\\\,"));
|
||||
if (i < size -1) {
|
||||
builder.append(",");
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
Set<String> set = paramMap_TYPE;
|
||||
size = paramMap_TYPE.size();
|
||||
if (i > 0 && size > 0) {
|
||||
builder.append(",");
|
||||
}
|
||||
i = 0;
|
||||
for (String type : set) {
|
||||
builder.append("TYPE=");
|
||||
builder.append(type
|
||||
.replaceAll("\\\\", "\\\\\\\\")
|
||||
.replaceAll(",", "\\\\,"));
|
||||
if (i < size - 1) {
|
||||
builder.append(",");
|
||||
}
|
||||
i++;
|
||||
}
|
||||
builder.append("],");
|
||||
}
|
||||
|
||||
size = propValue_vector.size();
|
||||
if (size > 0) {
|
||||
builder.append("propValue:[");
|
||||
List<String> list = propValue_vector;
|
||||
for (int i = 0; i < size; i++) {
|
||||
builder.append(list.get(i)
|
||||
.replaceAll("\\\\", "\\\\\\\\")
|
||||
.replaceAll(",", "\\\\,"));
|
||||
if (i < size -1) {
|
||||
builder.append(",");
|
||||
}
|
||||
}
|
||||
builder.append("],");
|
||||
}
|
||||
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
public static PropertyNode decode(String encodedString) {
|
||||
PropertyNode propertyNode = new PropertyNode();
|
||||
String trimed = encodedString.trim();
|
||||
if (trimed.length() == 0) {
|
||||
return propertyNode;
|
||||
}
|
||||
String[] elems = trimed.split("],");
|
||||
|
||||
for (String elem : elems) {
|
||||
int index = elem.indexOf('[');
|
||||
String name = elem.substring(0, index - 1);
|
||||
Pattern pattern = Pattern.compile("(?<!\\\\),");
|
||||
String[] values = pattern.split(elem.substring(index + 1), -1);
|
||||
if (name.equals("propName")) {
|
||||
propertyNode.propName = values[0];
|
||||
} else if (name.equals("propGroupSet")) {
|
||||
for (String value : values) {
|
||||
propertyNode.propGroupSet.add(value);
|
||||
}
|
||||
} else if (name.equals("paramMap")) {
|
||||
ContentValues paramMap = propertyNode.paramMap;
|
||||
Set<String> paramMap_TYPE = propertyNode.paramMap_TYPE;
|
||||
for (String value : values) {
|
||||
String[] tmp = value.split("=", 2);
|
||||
String mapKey = tmp[0];
|
||||
// \, -> ,
|
||||
// \\ -> \
|
||||
// In String#replaceAll(), "\\\\" means a single backslash.
|
||||
String mapValue =
|
||||
tmp[1].replaceAll("\\\\,", ",").replaceAll("\\\\\\\\", "\\\\");
|
||||
if (mapKey.equalsIgnoreCase("TYPE")) {
|
||||
paramMap_TYPE.add(mapValue);
|
||||
} else {
|
||||
paramMap.put(mapKey, mapValue);
|
||||
}
|
||||
}
|
||||
} else if (name.equals("propValue")) {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
List<String> list = propertyNode.propValue_vector;
|
||||
int length = values.length;
|
||||
for (int i = 0; i < length; i++) {
|
||||
String normValue = values[i]
|
||||
.replaceAll("\\\\,", ",")
|
||||
.replaceAll("\\\\\\\\", "\\\\");
|
||||
list.add(normValue);
|
||||
builder.append(normValue);
|
||||
if (i < length - 1) {
|
||||
builder.append(";");
|
||||
}
|
||||
}
|
||||
propertyNode.propValue = builder.toString();
|
||||
}
|
||||
}
|
||||
|
||||
// At this time, QUOTED-PRINTABLE is already decoded to Java String.
|
||||
// We just need to decode BASE64 String to binary.
|
||||
String encoding = propertyNode.paramMap.getAsString("ENCODING");
|
||||
if (encoding != null &&
|
||||
(encoding.equalsIgnoreCase("BASE64") ||
|
||||
encoding.equalsIgnoreCase("B"))) {
|
||||
propertyNode.propValue_bytes =
|
||||
Base64.decodeBase64(propertyNode.propValue_vector.get(0).getBytes());
|
||||
}
|
||||
|
||||
return propertyNode;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,235 @@
|
||||
/*
|
||||
* Copyright (C) 2009 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.unit_tests.vcard;
|
||||
|
||||
import android.content.ContentValues;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
/**
|
||||
* Utility class which verifies input VNode.
|
||||
*
|
||||
* This class first checks whether each propertyNode in the VNode is in the
|
||||
* "ordered expected property list".
|
||||
* If the node does not exist in the "ordered list", the class refers to
|
||||
* "unorderd expected property set" and checks the node is expected somewhere.
|
||||
*/
|
||||
public class PropertyNodesVerifier {
|
||||
public static class TypeSet extends HashSet<String> {
|
||||
public TypeSet(String ... array) {
|
||||
super(Arrays.asList(array));
|
||||
}
|
||||
}
|
||||
|
||||
public static class GroupSet extends HashSet<String> {
|
||||
public GroupSet(String ... array) {
|
||||
super(Arrays.asList(array));
|
||||
}
|
||||
}
|
||||
|
||||
private final HashMap<String, List<PropertyNode>> mOrderedNodeMap;
|
||||
// Intentionally use ArrayList instead of Set, assuming there may be more than one
|
||||
// exactly same objects.
|
||||
private final ArrayList<PropertyNode> mUnorderedNodeList;
|
||||
private final TestCase mTestCase;
|
||||
|
||||
public PropertyNodesVerifier(TestCase testCase) {
|
||||
mOrderedNodeMap = new HashMap<String, List<PropertyNode>>();
|
||||
mUnorderedNodeList = new ArrayList<PropertyNode>();
|
||||
mTestCase = testCase;
|
||||
}
|
||||
|
||||
// WithOrder
|
||||
|
||||
public PropertyNodesVerifier addNodeWithOrder(String propName, String propValue) {
|
||||
return addNodeWithOrder(propName, propValue, null, null, null, null, null);
|
||||
}
|
||||
|
||||
public PropertyNodesVerifier addNodeWithOrder(String propName, String propValue,
|
||||
List<String> propValueList) {
|
||||
return addNodeWithOrder(propName, propValue, propValueList, null, null, null, null);
|
||||
}
|
||||
|
||||
public PropertyNodesVerifier addNodeWithOrder(String propName, String propValue,
|
||||
TypeSet paramMap_TYPE) {
|
||||
return addNodeWithOrder(propName, propValue, null, null, null, paramMap_TYPE, null);
|
||||
}
|
||||
|
||||
public PropertyNodesVerifier addNodeWithOrder(String propName, String propValue,
|
||||
List<String> propValueList, TypeSet paramMap_TYPE) {
|
||||
return addNodeWithOrder(propName, propValue, propValueList, null, null,
|
||||
paramMap_TYPE, null);
|
||||
}
|
||||
|
||||
public PropertyNodesVerifier addNodeWithOrder(String propName, String propValue,
|
||||
List<String> propValueList, byte[] propValue_bytes,
|
||||
ContentValues paramMap, TypeSet paramMap_TYPE, GroupSet propGroupSet) {
|
||||
PropertyNode propertyNode = new PropertyNode(propName,
|
||||
propValue, propValueList, propValue_bytes,
|
||||
paramMap, paramMap_TYPE, propGroupSet);
|
||||
List<PropertyNode> expectedNodeList = mOrderedNodeMap.get(propName);
|
||||
if (expectedNodeList == null) {
|
||||
expectedNodeList = new ArrayList<PropertyNode>();
|
||||
mOrderedNodeMap.put(propName, expectedNodeList);
|
||||
}
|
||||
expectedNodeList.add(propertyNode);
|
||||
return this;
|
||||
}
|
||||
|
||||
// WithoutOrder
|
||||
|
||||
public PropertyNodesVerifier addNodeWithoutOrder(String propName, String propValue) {
|
||||
return addNodeWithoutOrder(propName, propValue, null, null, null, null, null);
|
||||
}
|
||||
|
||||
public PropertyNodesVerifier addNodeWithoutOrder(String propName, String propValue,
|
||||
List<String> propValueList) {
|
||||
return addNodeWithoutOrder(propName, propValue, propValueList, null, null, null, null);
|
||||
}
|
||||
|
||||
public PropertyNodesVerifier addNodeWithoutOrder(String propName, String propValue,
|
||||
TypeSet paramMap_TYPE) {
|
||||
return addNodeWithoutOrder(propName, propValue, null, null, null, paramMap_TYPE, null);
|
||||
}
|
||||
|
||||
public PropertyNodesVerifier addNodeWithoutOrder(String propName, String propValue,
|
||||
List<String> propValueList, TypeSet paramMap_TYPE) {
|
||||
return addNodeWithoutOrder(propName, propValue, propValueList, null, null,
|
||||
paramMap_TYPE, null);
|
||||
}
|
||||
|
||||
public PropertyNodesVerifier addNodeWithoutOrder(String propName, String propValue,
|
||||
List<String> propValueList, byte[] propValue_bytes,
|
||||
ContentValues paramMap, TypeSet paramMap_TYPE, GroupSet propGroupSet) {
|
||||
mUnorderedNodeList.add(new PropertyNode(propName, propValue,
|
||||
propValueList, propValue_bytes, paramMap, paramMap_TYPE, propGroupSet));
|
||||
return this;
|
||||
}
|
||||
|
||||
public void verify(VNode vnode) {
|
||||
for (PropertyNode actualNode : vnode.propList) {
|
||||
verifyNode(actualNode.propName, actualNode);
|
||||
}
|
||||
if (!mOrderedNodeMap.isEmpty() || !mUnorderedNodeList.isEmpty()) {
|
||||
List<String> expectedProps = new ArrayList<String>();
|
||||
for (List<PropertyNode> nodes : mOrderedNodeMap.values()) {
|
||||
for (PropertyNode node : nodes) {
|
||||
if (!expectedProps.contains(node.propName)) {
|
||||
expectedProps.add(node.propName);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (PropertyNode node : mUnorderedNodeList) {
|
||||
if (!expectedProps.contains(node.propName)) {
|
||||
expectedProps.add(node.propName);
|
||||
}
|
||||
}
|
||||
mTestCase.fail("Expected property " + Arrays.toString(expectedProps.toArray())
|
||||
+ " was not found.");
|
||||
}
|
||||
}
|
||||
|
||||
private void verifyNode(final String propName, final PropertyNode actualNode) {
|
||||
List<PropertyNode> expectedNodeList = mOrderedNodeMap.get(propName);
|
||||
final int size = (expectedNodeList != null ? expectedNodeList.size() : 0);
|
||||
if (size > 0) {
|
||||
for (int i = 0; i < size; i++) {
|
||||
PropertyNode expectedNode = expectedNodeList.get(i);
|
||||
List<PropertyNode> expectedButDifferentValueList =
|
||||
new ArrayList<PropertyNode>();
|
||||
if (expectedNode.propName.equals(propName)) {
|
||||
if (expectedNode.equals(actualNode)) {
|
||||
expectedNodeList.remove(i);
|
||||
if (expectedNodeList.size() == 0) {
|
||||
mOrderedNodeMap.remove(propName);
|
||||
}
|
||||
return;
|
||||
} else {
|
||||
expectedButDifferentValueList.add(expectedNode);
|
||||
}
|
||||
}
|
||||
|
||||
// "actualNode" is not in ordered expected list.
|
||||
// Try looking over unordered expected list.
|
||||
if (tryFoundExpectedNodeFromUnorderedList(actualNode,
|
||||
expectedButDifferentValueList)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!expectedButDifferentValueList.isEmpty()) {
|
||||
// Same propName exists but with different value(s).
|
||||
failWithExpectedNodeList(propName, actualNode,
|
||||
expectedButDifferentValueList);
|
||||
} else {
|
||||
// There's no expected node with same propName.
|
||||
mTestCase.fail("Unexpected property \"" + propName + "\" exists.");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
List<PropertyNode> expectedButDifferentValueList =
|
||||
new ArrayList<PropertyNode>();
|
||||
if (tryFoundExpectedNodeFromUnorderedList(actualNode, expectedButDifferentValueList)) {
|
||||
return;
|
||||
} else {
|
||||
if (!expectedButDifferentValueList.isEmpty()) {
|
||||
// Same propName exists but with different value(s).
|
||||
failWithExpectedNodeList(propName, actualNode,
|
||||
expectedButDifferentValueList);
|
||||
} else {
|
||||
// There's no expected node with same propName.
|
||||
mTestCase.fail("Unexpected property \"" + propName + "\" exists.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean tryFoundExpectedNodeFromUnorderedList(PropertyNode actualNode,
|
||||
List<PropertyNode> expectedButDifferentValueList) {
|
||||
final String propName = actualNode.propName;
|
||||
int unorderedListSize = mUnorderedNodeList.size();
|
||||
for (int i = 0; i < unorderedListSize; i++) {
|
||||
PropertyNode unorderedExpectedNode = mUnorderedNodeList.get(i);
|
||||
if (unorderedExpectedNode.propName.equals(propName)) {
|
||||
if (unorderedExpectedNode.equals(actualNode)) {
|
||||
mUnorderedNodeList.remove(i);
|
||||
return true;
|
||||
}
|
||||
expectedButDifferentValueList.add(unorderedExpectedNode);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void failWithExpectedNodeList(String propName, PropertyNode actualNode,
|
||||
List<PropertyNode> expectedNodeList) {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
for (PropertyNode expectedNode : expectedNodeList) {
|
||||
builder.append("expected: ");
|
||||
builder.append(expectedNode.toString());
|
||||
builder.append("\n");
|
||||
}
|
||||
mTestCase.fail("Property \"" + propName + "\" has wrong value.\n"
|
||||
+ builder.toString()
|
||||
+ " actual: " + actualNode.toString());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,409 @@
|
||||
/*
|
||||
* Copyright (C) 2009 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.unit_tests.vcard;
|
||||
|
||||
import com.android.unit_tests.vcard.PropertyNodesVerifier.TypeSet;
|
||||
|
||||
import android.content.ContentProvider;
|
||||
import android.content.ContentProviderOperation;
|
||||
import android.content.ContentProviderResult;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.ContentValues;
|
||||
import android.content.Context;
|
||||
import android.content.Entity;
|
||||
import android.content.EntityIterator;
|
||||
import android.content.res.AssetFileDescriptor;
|
||||
import android.database.Cursor;
|
||||
import android.database.CursorWindow;
|
||||
import android.database.IBulkCursor;
|
||||
import android.database.IContentObserver;
|
||||
import android.net.Uri;
|
||||
import android.os.IBinder;
|
||||
import android.os.ParcelFileDescriptor;
|
||||
import android.os.RemoteException;
|
||||
import android.pim.vcard.VCardComposer;
|
||||
import android.pim.vcard.VCardConfig;
|
||||
import android.pim.vcard.VCardParser;
|
||||
import android.pim.vcard.VCardParser_V21;
|
||||
import android.pim.vcard.VCardParser_V30;
|
||||
import android.pim.vcard.exception.VCardException;
|
||||
import android.provider.ContactsContract.Contacts;
|
||||
import android.provider.ContactsContract.Data;
|
||||
import android.provider.ContactsContract.RawContacts;
|
||||
import android.provider.ContactsContract.CommonDataKinds.Photo;
|
||||
import android.provider.ContactsContract.CommonDataKinds.StructuredName;
|
||||
import android.test.AndroidTestCase;
|
||||
import android.test.mock.MockContentResolver;
|
||||
import android.test.mock.MockContext;
|
||||
import android.util.Log;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
/**
|
||||
* Almost a dead copy of android.test.mock.MockContentProvider, but different in that this
|
||||
* class extends ContentProvider, not implementing IContentProvider,
|
||||
* so that MockContentResolver is able to accept this class :(
|
||||
*/
|
||||
class MockContentProvider extends ContentProvider {
|
||||
@Override
|
||||
public boolean onCreate() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int bulkInsert(Uri url, ContentValues[] initialValues) {
|
||||
throw new UnsupportedOperationException("unimplemented mock method");
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public IBulkCursor bulkQuery(Uri url, String[] projection, String selection,
|
||||
String[] selectionArgs, String sortOrder, IContentObserver observer,
|
||||
CursorWindow window) throws RemoteException {
|
||||
throw new UnsupportedOperationException("unimplemented mock method");
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unused")
|
||||
public int delete(Uri url, String selection, String[] selectionArgs) {
|
||||
throw new UnsupportedOperationException("unimplemented mock method");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getType(Uri url) {
|
||||
throw new UnsupportedOperationException("unimplemented mock method");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Uri insert(Uri url, ContentValues initialValues) {
|
||||
throw new UnsupportedOperationException("unimplemented mock method");
|
||||
}
|
||||
|
||||
@Override
|
||||
public ParcelFileDescriptor openFile(Uri url, String mode) {
|
||||
throw new UnsupportedOperationException("unimplemented mock method");
|
||||
}
|
||||
|
||||
@Override
|
||||
public AssetFileDescriptor openAssetFile(Uri uri, String mode) {
|
||||
throw new UnsupportedOperationException("unimplemented mock method");
|
||||
}
|
||||
|
||||
@Override
|
||||
public ContentProviderResult[] applyBatch(ArrayList<ContentProviderOperation> operations) {
|
||||
throw new UnsupportedOperationException("unimplemented mock method");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Cursor query(Uri url, String[] projection, String selection, String[] selectionArgs,
|
||||
String sortOrder) {
|
||||
throw new UnsupportedOperationException("unimplemented mock method");
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
@Override
|
||||
public EntityIterator queryEntities(Uri url, String selection, String[] selectionArgs,
|
||||
String sortOrder) {
|
||||
throw new UnsupportedOperationException("unimplemented mock method");
|
||||
}
|
||||
|
||||
@Override
|
||||
public int update(Uri url, ContentValues values, String selection, String[] selectionArgs) {
|
||||
throw new UnsupportedOperationException("unimplemented mock method");
|
||||
}
|
||||
|
||||
public IBinder asBinder() {
|
||||
throw new UnsupportedOperationException("unimplemented mock method");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests for the code related to vCard exporter, inculding vCard composer.
|
||||
* This test class depends on vCard importer code, so if tests for vCard importer fail,
|
||||
* the result of this class will not be reliable.
|
||||
*/
|
||||
public class VCardExporterTests extends AndroidTestCase {
|
||||
/* package */ static final byte[] sPhotoByteArray =
|
||||
VCardImporterTests.sPhotoByteArrayForComplicatedCase;
|
||||
|
||||
public class ExportTestResolver extends MockContentResolver {
|
||||
ExportTestProvider mProvider = new ExportTestProvider();
|
||||
public ExportTestResolver() {
|
||||
addProvider(VCardComposer.VCARD_TEST_AUTHORITY, mProvider);
|
||||
addProvider(RawContacts.CONTENT_URI.getAuthority(), mProvider);
|
||||
}
|
||||
|
||||
public ContentValues buildData(String mimeType) {
|
||||
return mProvider.buildData(mimeType);
|
||||
}
|
||||
}
|
||||
|
||||
public static class MockEntityIterator implements EntityIterator {
|
||||
Collection<Entity> mEntityCollection;
|
||||
Iterator<Entity> mIterator;
|
||||
|
||||
// TODO: Support multiple vCard entries.
|
||||
public MockEntityIterator(Collection<ContentValues> contentValuesCollection) {
|
||||
mEntityCollection = new ArrayList<Entity>();
|
||||
Entity entity = new Entity(new ContentValues());
|
||||
for (ContentValues contentValues : contentValuesCollection) {
|
||||
entity.addSubValue(Data.CONTENT_URI, contentValues);
|
||||
}
|
||||
mEntityCollection.add(entity);
|
||||
mIterator = mEntityCollection.iterator();
|
||||
}
|
||||
|
||||
public boolean hasNext() {
|
||||
return mIterator.hasNext();
|
||||
}
|
||||
|
||||
public Entity next() {
|
||||
return mIterator.next();
|
||||
}
|
||||
|
||||
public void reset() {
|
||||
mIterator = mEntityCollection.iterator();
|
||||
}
|
||||
|
||||
public void close() {
|
||||
}
|
||||
}
|
||||
|
||||
public class ExportTestProvider extends MockContentProvider {
|
||||
List<ContentValues> mContentValuesList = new ArrayList<ContentValues>();
|
||||
public ContentValues buildData(String mimeType) {
|
||||
ContentValues contentValues = new ContentValues();
|
||||
contentValues.put(Data.MIMETYPE, mimeType);
|
||||
mContentValuesList.add(contentValues);
|
||||
return contentValues;
|
||||
}
|
||||
|
||||
@Override
|
||||
public EntityIterator queryEntities(Uri uri, String selection, String[] selectionArgs,
|
||||
String sortOrder) {
|
||||
assert(uri != null);
|
||||
assert(ContentResolver.SCHEME_CONTENT.equals(uri.getScheme()));
|
||||
final String authority = uri.getAuthority();
|
||||
assert(RawContacts.CONTENT_URI.getAuthority().equals(authority));
|
||||
|
||||
return new MockEntityIterator(mContentValuesList);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
|
||||
String sortOrder) {
|
||||
assert(VCardComposer.CONTACTS_TEST_CONTENT_URI.equals(uri));
|
||||
// Support multiple rows.
|
||||
return new MockCursor() {
|
||||
int mCurrentPosition = -1;
|
||||
|
||||
@Override
|
||||
public int getCount() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean moveToFirst() {
|
||||
mCurrentPosition = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean moveToNext() {
|
||||
if (mCurrentPosition == 0 || mCurrentPosition == -1) {
|
||||
mCurrentPosition++;
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBeforeFirst() {
|
||||
return mCurrentPosition < 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAfterLast() {
|
||||
return mCurrentPosition > 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getColumnIndex(String columnName) {
|
||||
assertEquals(Contacts._ID, columnName);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getInt(int columnIndex) {
|
||||
assertEquals(0, columnIndex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getString(int columnIndex) {
|
||||
return String.valueOf(getInt(columnIndex));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public static class VCardVerificationHandler implements VCardComposer.OneEntryHandler {
|
||||
final private TestCase mTestCase;
|
||||
final private List<PropertyNodesVerifier> mPropertyNodesVerifierList;
|
||||
final private boolean mIsV30;
|
||||
int mCount;
|
||||
|
||||
public VCardVerificationHandler(TestCase testCase, boolean isV30) {
|
||||
mTestCase = testCase;
|
||||
mPropertyNodesVerifierList = new ArrayList<PropertyNodesVerifier>();
|
||||
mIsV30 = isV30;
|
||||
mCount = 1;
|
||||
}
|
||||
|
||||
public PropertyNodesVerifier addNewPropertyNodesVerifier() {
|
||||
PropertyNodesVerifier propertyNodesVerifier = new PropertyNodesVerifier(mTestCase);
|
||||
mPropertyNodesVerifierList.add(propertyNodesVerifier);
|
||||
return propertyNodesVerifier;
|
||||
}
|
||||
|
||||
public boolean onInit(Context context) {
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean onEntryCreated(String vcard) {
|
||||
if (mPropertyNodesVerifierList.size() == 0) {
|
||||
mTestCase.fail("Too many vCard entries seems to be inserted(No."
|
||||
+ mCount + " of the entries (No.1 is the first entry))");
|
||||
}
|
||||
PropertyNodesVerifier propertyNodesVerifier =
|
||||
mPropertyNodesVerifierList.get(0);
|
||||
mPropertyNodesVerifierList.remove(0);
|
||||
VCardParser parser = (mIsV30 ? new VCardParser_V30(true) : new VCardParser_V21());
|
||||
VNodeBuilder builder = new VNodeBuilder();
|
||||
InputStream is;
|
||||
try {
|
||||
is = new ByteArrayInputStream(vcard.getBytes("UTF-8"));
|
||||
mTestCase.assertEquals(true, parser.parse(is, null, builder));
|
||||
is.close();
|
||||
mTestCase.assertEquals(1, builder.vNodeList.size());
|
||||
propertyNodesVerifier.verify(builder.vNodeList.get(0));
|
||||
} catch (IOException e) {
|
||||
mTestCase.fail("Unexpected IOException: " + e.getMessage());
|
||||
} catch (VCardException e) {
|
||||
mTestCase.fail("Unexpected VCardException: " + e.getMessage());
|
||||
} finally {
|
||||
mCount++;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public void onTerminate() {
|
||||
}
|
||||
}
|
||||
|
||||
private class CustomMockContext extends MockContext {
|
||||
final ContentResolver mResolver;
|
||||
public CustomMockContext(ContentResolver resolver) {
|
||||
mResolver = resolver;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ContentResolver getContentResolver() {
|
||||
return mResolver;
|
||||
}
|
||||
}
|
||||
|
||||
//// Followings are actual tests ////
|
||||
|
||||
public void testSimple() {
|
||||
ExportTestResolver resolver = new ExportTestResolver();
|
||||
ContentValues contentValues = resolver.buildData(StructuredName.CONTENT_ITEM_TYPE);
|
||||
contentValues.put(StructuredName.FAMILY_NAME, "Ando");
|
||||
contentValues.put(StructuredName.GIVEN_NAME, "Roid");
|
||||
|
||||
VCardVerificationHandler handler = new VCardVerificationHandler(this, false);
|
||||
handler.addNewPropertyNodesVerifier()
|
||||
.addNodeWithOrder("VERSION", "2.1")
|
||||
.addNodeWithoutOrder("FN", "Roid Ando")
|
||||
.addNodeWithoutOrder("N", "Ando;Roid;;;", Arrays.asList("Ando", "Roid", "", "", ""));
|
||||
|
||||
VCardComposer composer = new VCardComposer(new CustomMockContext(resolver),
|
||||
VCardConfig.VCARD_TYPE_V21_GENERIC);
|
||||
composer.addHandler(handler);
|
||||
if (!composer.init(VCardComposer.CONTACTS_TEST_CONTENT_URI, null, null, null)) {
|
||||
fail("init failed. Reason: " + composer.getErrorReason());
|
||||
}
|
||||
assertFalse(composer.isAfterLast());
|
||||
assertTrue(composer.createOneEntry());
|
||||
assertTrue(composer.isAfterLast());
|
||||
composer.terminate();
|
||||
}
|
||||
|
||||
private void testPhotoCommon(boolean isV30) {
|
||||
ExportTestResolver resolver = new ExportTestResolver();
|
||||
ContentValues contentValues = resolver.buildData(StructuredName.CONTENT_ITEM_TYPE);
|
||||
contentValues.put(StructuredName.FAMILY_NAME, "PhotoTest");
|
||||
|
||||
contentValues = resolver.buildData(Photo.CONTENT_ITEM_TYPE);
|
||||
contentValues.put(Photo.PHOTO, sPhotoByteArray);
|
||||
|
||||
ContentValues contentValuesForPhoto = new ContentValues();
|
||||
contentValuesForPhoto.put("ENCODING", (isV30 ? "b" : "BASE64"));
|
||||
VCardVerificationHandler handler = new VCardVerificationHandler(this, isV30);
|
||||
handler.addNewPropertyNodesVerifier()
|
||||
.addNodeWithOrder("VERSION", (isV30 ? "3.0" : "2.1"))
|
||||
.addNodeWithoutOrder("FN", "PhotoTest")
|
||||
.addNodeWithoutOrder("N", "PhotoTest;;;;", Arrays.asList("PhotoTest", "", "", "", ""))
|
||||
.addNodeWithOrder("PHOTO", null, null, sPhotoByteArray,
|
||||
contentValuesForPhoto, new TypeSet("JPEG"), null);
|
||||
|
||||
int vcardType = (isV30 ? VCardConfig.VCARD_TYPE_V30_GENERIC
|
||||
: VCardConfig.VCARD_TYPE_V21_GENERIC);
|
||||
VCardComposer composer = new VCardComposer(new CustomMockContext(resolver), vcardType);
|
||||
composer.addHandler(handler);
|
||||
if (!composer.init(VCardComposer.CONTACTS_TEST_CONTENT_URI, null, null, null)) {
|
||||
fail("init() failed. Reason: " + composer.getErrorReason());
|
||||
}
|
||||
assertFalse(composer.isAfterLast());
|
||||
assertTrue(composer.createOneEntry());
|
||||
assertTrue(composer.isAfterLast());
|
||||
composer.terminate();
|
||||
}
|
||||
|
||||
public void testPhotoV21() {
|
||||
testPhotoCommon(false);
|
||||
}
|
||||
|
||||
public void testPhotoV30() {
|
||||
testPhotoCommon(true);
|
||||
}
|
||||
}
|
||||
@@ -17,6 +17,7 @@
|
||||
package com.android.unit_tests.vcard;
|
||||
|
||||
import com.android.unit_tests.R;
|
||||
import com.android.unit_tests.vcard.PropertyNodesVerifier.TypeSet;
|
||||
|
||||
import android.content.ContentProviderOperation;
|
||||
import android.content.ContentProviderResult;
|
||||
@@ -56,14 +57,13 @@ import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.SortedMap;
|
||||
import java.util.TreeMap;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
public class VCardImportTests extends AndroidTestCase {
|
||||
public class VCardImporterTests extends AndroidTestCase {
|
||||
// Push data into int array at first since values like 0x80 are
|
||||
// interpreted as int by the compiler and casting all of them is
|
||||
// cumbersome...
|
||||
@@ -423,7 +423,7 @@ public class VCardImportTests extends AndroidTestCase {
|
||||
0x55, 0x25, 0x15, 0x2c, 0x68, 0xa3, 0x30, 0xeb, 0x54, 0xa5, 0x15,
|
||||
0x0c, 0xd1, 0x00, 0xff, 0xd9};
|
||||
|
||||
private static final byte[] sPhotoByteArrayForComplicatedCase;
|
||||
/* package */ static final byte[] sPhotoByteArrayForComplicatedCase;
|
||||
|
||||
static {
|
||||
final int length = sPhotoIntArrayForComplicatedCase.length;
|
||||
@@ -433,69 +433,7 @@ public class VCardImportTests extends AndroidTestCase {
|
||||
}
|
||||
}
|
||||
|
||||
private class PropertyNodesVerifier {
|
||||
private HashMap<String, List<PropertyNode>> mPropertyNodeMap;
|
||||
public PropertyNodesVerifier() {
|
||||
mPropertyNodeMap = new HashMap<String, List<PropertyNode>>();
|
||||
}
|
||||
|
||||
public PropertyNodesVerifier addPropertyNode(String propName, String propValue,
|
||||
List<String> propValue_vector, byte[] propValue_bytes,
|
||||
ContentValues paramMap, Set<String> paramMap_TYPE, Set<String> propGroupSet) {
|
||||
PropertyNode propertyNode = new PropertyNode(propName,
|
||||
propValue, propValue_vector, propValue_bytes,
|
||||
paramMap, paramMap_TYPE, propGroupSet);
|
||||
List<PropertyNode> expectedNodeList = mPropertyNodeMap.get(propName);
|
||||
if (expectedNodeList == null) {
|
||||
expectedNodeList = new ArrayList<PropertyNode>();
|
||||
mPropertyNodeMap.put(propName, expectedNodeList);
|
||||
}
|
||||
expectedNodeList.add(propertyNode);
|
||||
return this;
|
||||
}
|
||||
|
||||
public void verify(VNode vnode) {
|
||||
for (PropertyNode propertyNode : vnode.propList) {
|
||||
String propName = propertyNode.propName;
|
||||
List<PropertyNode> nodes = mPropertyNodeMap.get(propName);
|
||||
if (nodes == null) {
|
||||
fail("Unexpected propName \"" + propName + "\" exists.");
|
||||
}
|
||||
boolean successful = false;
|
||||
int size = nodes.size();
|
||||
for (int i = 0; i < size; i++) {
|
||||
PropertyNode expectedNode = nodes.get(i);
|
||||
if (expectedNode.propName.equals(propName)) {
|
||||
if (expectedNode.equals(propertyNode)) {
|
||||
successful = true;
|
||||
nodes.remove(i);
|
||||
if (nodes.size() == 0) {
|
||||
mPropertyNodeMap.remove(propName);
|
||||
}
|
||||
break;
|
||||
} else {
|
||||
fail("Property \"" + propName + "\" has wrong value.\n"
|
||||
+ "expected: " + expectedNode.toString()
|
||||
+ "\n actual: " + propertyNode.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!successful) {
|
||||
fail("Unexpected property \"" + propName + "\" exists.");
|
||||
}
|
||||
}
|
||||
if (mPropertyNodeMap.size() != 0) {
|
||||
List<String> expectedProps = new ArrayList<String>();
|
||||
for (List<PropertyNode> nodes : mPropertyNodeMap.values()) {
|
||||
for (PropertyNode node : nodes) {
|
||||
expectedProps.add(node.propName);
|
||||
}
|
||||
}
|
||||
fail("expected props " + Arrays.toString(expectedProps.toArray()) +
|
||||
" was not found");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class VerificationResolver extends MockContentResolver {
|
||||
VerificationProvider mVerificationProvider = new VerificationProvider();
|
||||
@@ -749,7 +687,7 @@ public class VCardImportTests extends AndroidTestCase {
|
||||
InputStream is = getContext().getResources().openRawResource(mResourceId);
|
||||
final VCardParser vCardParser;
|
||||
if (VCardConfig.isV30(mVCardType)) {
|
||||
vCardParser = new VCardParser_V30();
|
||||
vCardParser = new VCardParser_V30(true); // use StrictParsing
|
||||
} else {
|
||||
vCardParser = new VCardParser_V21();
|
||||
}
|
||||
@@ -777,9 +715,8 @@ public class VCardImportTests extends AndroidTestCase {
|
||||
assertEquals(true, parser.parse(is,"ISO-8859-1", builder));
|
||||
is.close();
|
||||
assertEquals(1, builder.vNodeList.size());
|
||||
PropertyNodesVerifier verifier = new PropertyNodesVerifier()
|
||||
.addPropertyNode("N", "Ando;Roid;", Arrays.asList("Ando", "Roid", ""),
|
||||
null, null, null, null);
|
||||
PropertyNodesVerifier verifier = new PropertyNodesVerifier(this)
|
||||
.addNodeWithOrder("N", "Ando;Roid;", Arrays.asList("Ando", "Roid", ""));
|
||||
verifier.verify(builder.vNodeList.get(0));
|
||||
}
|
||||
|
||||
@@ -839,12 +776,11 @@ public class VCardImportTests extends AndroidTestCase {
|
||||
assertEquals(true, parser.parse(is,"ISO-8859-1", builder));
|
||||
is.close();
|
||||
assertEquals(1, builder.vNodeList.size());
|
||||
PropertyNodesVerifier verifier = new PropertyNodesVerifier()
|
||||
.addPropertyNode("VERSION", "2.1", null, null, null, null, null)
|
||||
.addPropertyNode("N", ";A;B\\;C\\;;D;:E;\\\\;",
|
||||
Arrays.asList("", "A;B\\", "C\\;", "D", ":E", "\\\\", ""),
|
||||
null, null, null, null)
|
||||
.addPropertyNode("FN", "A;B\\C\\;D:E\\\\", null, null, null, null, null);
|
||||
PropertyNodesVerifier verifier = new PropertyNodesVerifier(this)
|
||||
.addNodeWithOrder("VERSION", "2.1")
|
||||
.addNodeWithOrder("N", ";A;B\\;C\\;;D;:E;\\\\;",
|
||||
Arrays.asList("", "A;B\\", "C\\;", "D", ":E", "\\\\", ""))
|
||||
.addNodeWithOrder("FN", "A;B\\C\\;D:E\\\\");
|
||||
verifier.verify(builder.vNodeList.get(0));
|
||||
}
|
||||
|
||||
@@ -962,63 +898,51 @@ public class VCardImportTests extends AndroidTestCase {
|
||||
contentValuesForQP.put("ENCODING", "QUOTED-PRINTABLE");
|
||||
ContentValues contentValuesForPhoto = new ContentValues();
|
||||
contentValuesForPhoto.put("ENCODING", "BASE64");
|
||||
PropertyNodesVerifier verifier = new PropertyNodesVerifier()
|
||||
.addPropertyNode("VERSION", "2.1", null, null, null, null, null)
|
||||
.addPropertyNode("N", "Gump;Forrest;Hoge;Pos;Tao",
|
||||
Arrays.asList("Gump", "Forrest", "Hoge", "Pos", "Tao"),
|
||||
null, null, null, null)
|
||||
.addPropertyNode("FN", "Joe Due", null, null, null, null, null)
|
||||
.addPropertyNode("ORG", "Gump Shrimp Co.;Sales Dept.;Manager;Fish keeper",
|
||||
Arrays.asList("Gump Shrimp Co.", "Sales Dept.;Manager", "Fish keeper"),
|
||||
null, null, null, null)
|
||||
.addPropertyNode("ROLE", "Fish Cake Keeper!", null, null, null, null, null)
|
||||
.addPropertyNode("TITLE", "Shrimp Man", null, null, null, null, null)
|
||||
.addPropertyNode("X-CLASS", "PUBLIC", null, null, null, null, null)
|
||||
.addPropertyNode("TEL", "(111) 555-1212", null, null, null,
|
||||
new HashSet<String>(Arrays.asList("WORK", "VOICE")), null)
|
||||
.addPropertyNode("TEL", "(404) 555-1212", null, null, null,
|
||||
new HashSet<String>(Arrays.asList("HOME", "VOICE")), null)
|
||||
.addPropertyNode("TEL", "0311111111", null, null, null,
|
||||
new HashSet<String>(Arrays.asList("CELL")), null)
|
||||
.addPropertyNode("TEL", "0322222222", null, null, null,
|
||||
new HashSet<String>(Arrays.asList("VIDEO")), null)
|
||||
.addPropertyNode("TEL", "0333333333", null, null, null,
|
||||
new HashSet<String>(Arrays.asList("VOICE")), null)
|
||||
.addPropertyNode("ADR", ";;100 Waters Edge;Baytown;LA;30314;United States of America",
|
||||
PropertyNodesVerifier verifier = new PropertyNodesVerifier(this)
|
||||
.addNodeWithOrder("VERSION", "2.1")
|
||||
.addNodeWithOrder("N", "Gump;Forrest;Hoge;Pos;Tao",
|
||||
Arrays.asList("Gump", "Forrest", "Hoge", "Pos", "Tao"))
|
||||
.addNodeWithOrder("FN", "Joe Due")
|
||||
.addNodeWithOrder("ORG", "Gump Shrimp Co.;Sales Dept.;Manager;Fish keeper",
|
||||
Arrays.asList("Gump Shrimp Co.", "Sales Dept.;Manager", "Fish keeper"))
|
||||
.addNodeWithOrder("ROLE", "Fish Cake Keeper!")
|
||||
.addNodeWithOrder("TITLE", "Shrimp Man")
|
||||
.addNodeWithOrder("X-CLASS", "PUBLIC")
|
||||
.addNodeWithOrder("TEL", "(111) 555-1212", new TypeSet("WORK", "VOICE"))
|
||||
.addNodeWithOrder("TEL", "(404) 555-1212", new TypeSet("HOME", "VOICE"))
|
||||
.addNodeWithOrder("TEL", "0311111111", new TypeSet("CELL"))
|
||||
.addNodeWithOrder("TEL", "0322222222", new TypeSet("VIDEO"))
|
||||
.addNodeWithOrder("TEL", "0333333333", new TypeSet("VOICE"))
|
||||
.addNodeWithOrder("ADR", ";;100 Waters Edge;Baytown;LA;30314;United States of America",
|
||||
Arrays.asList("", "", "100 Waters Edge", "Baytown",
|
||||
"LA", "30314", "United States of America"),
|
||||
null, null, new HashSet<String>(Arrays.asList("WORK")), null)
|
||||
.addPropertyNode("LABEL",
|
||||
null, null, new TypeSet("WORK"), null)
|
||||
.addNodeWithOrder("LABEL",
|
||||
"100 Waters Edge\r\nBaytown, LA 30314\r\nUnited States of America",
|
||||
null, null, contentValuesForQP,
|
||||
new HashSet<String>(Arrays.asList("WORK")), null)
|
||||
.addPropertyNode("ADR",
|
||||
null, null, contentValuesForQP, new TypeSet("WORK"), null)
|
||||
.addNodeWithOrder("ADR",
|
||||
";;42 Plantation St.;Baytown;LA;30314;United States of America",
|
||||
Arrays.asList("", "", "42 Plantation St.", "Baytown",
|
||||
"LA", "30314", "United States of America"), null, null,
|
||||
new HashSet<String>(Arrays.asList("HOME")), null)
|
||||
.addPropertyNode("LABEL",
|
||||
new TypeSet("HOME"), null)
|
||||
.addNodeWithOrder("LABEL",
|
||||
"42 Plantation St.\r\nBaytown, LA 30314\r\nUnited States of America",
|
||||
null, null, contentValuesForQP,
|
||||
new HashSet<String>(Arrays.asList("HOME")), null)
|
||||
.addPropertyNode("EMAIL", "forrestgump@walladalla.com",
|
||||
null, null, null,
|
||||
new HashSet<String>(Arrays.asList("PREF", "INTERNET")), null)
|
||||
.addPropertyNode("EMAIL", "cell@example.com", null, null, null,
|
||||
new HashSet<String>(Arrays.asList("CELL")), null)
|
||||
.addPropertyNode("NOTE", "The following note is the example from RFC 2045.",
|
||||
null, null, null, null, null)
|
||||
.addPropertyNode("NOTE",
|
||||
new TypeSet("HOME"), null)
|
||||
.addNodeWithOrder("EMAIL", "forrestgump@walladalla.com", new TypeSet("PREF", "INTERNET"))
|
||||
.addNodeWithOrder("EMAIL", "cell@example.com", new TypeSet("CELL"))
|
||||
.addNodeWithOrder("NOTE", "The following note is the example from RFC 2045.")
|
||||
.addNodeWithOrder("NOTE",
|
||||
"Now's the time for all folk to come to the aid of their country.",
|
||||
null, null, contentValuesForQP, null, null)
|
||||
.addPropertyNode("PHOTO", null,
|
||||
.addNodeWithOrder("PHOTO", null,
|
||||
null, sPhotoByteArrayForComplicatedCase, contentValuesForPhoto,
|
||||
new HashSet<String>(Arrays.asList("JPEG")), null)
|
||||
.addPropertyNode("X-ATTRIBUTE", "Some String", null, null, null, null, null)
|
||||
.addPropertyNode("BDAY", "19800101", null, null, null, null, null)
|
||||
.addPropertyNode("GEO", "35.6563854,139.6994233", null, null, null, null, null)
|
||||
.addPropertyNode("URL", "http://www.example.com/", null, null, null, null, null)
|
||||
.addPropertyNode("REV", "20080424T195243Z", null, null, null, null, null);
|
||||
new TypeSet("JPEG"), null)
|
||||
.addNodeWithOrder("X-ATTRIBUTE", "Some String")
|
||||
.addNodeWithOrder("BDAY", "19800101")
|
||||
.addNodeWithOrder("GEO", "35.6563854,139.6994233")
|
||||
.addNodeWithOrder("URL", "http://www.example.com/")
|
||||
.addNodeWithOrder("REV", "20080424T195243Z");
|
||||
verifier.verify(builder.vNodeList.get(0));
|
||||
}
|
||||
|
||||
@@ -1126,22 +1050,19 @@ public class VCardImportTests extends AndroidTestCase {
|
||||
assertEquals(true, parser.parse(is,"ISO-8859-1", builder));
|
||||
is.close();
|
||||
assertEquals(1, builder.vNodeList.size());
|
||||
PropertyNodesVerifier verifier = new PropertyNodesVerifier()
|
||||
.addPropertyNode("VERSION", "3.0", null, null, null, null, null)
|
||||
.addPropertyNode("FN", "And Roid", null, null, null, null, null)
|
||||
.addPropertyNode("N", "And;Roid;;;", Arrays.asList("And", "Roid", "", "", ""),
|
||||
null, null, null, null)
|
||||
.addPropertyNode("ORG", "Open;Handset; Alliance",
|
||||
Arrays.asList("Open", "Handset", " Alliance"),
|
||||
null, null, null, null)
|
||||
.addPropertyNode("SORT-STRING", "android", null, null, null, null, null)
|
||||
.addPropertyNode("TEL", "0300000000", null, null, null,
|
||||
new HashSet<String>(Arrays.asList("PREF", "VOICE")), null)
|
||||
.addPropertyNode("CLASS", "PUBLIC", null, null, null, null, null)
|
||||
.addPropertyNode("X-GNO", "0", null, null, null, null, null)
|
||||
.addPropertyNode("X-GN", "group0", null, null, null, null, null)
|
||||
.addPropertyNode("X-REDUCTION", "0", null, null, null, null, null)
|
||||
.addPropertyNode("REV", "20081031T065854Z", null, null, null, null, null);
|
||||
PropertyNodesVerifier verifier = new PropertyNodesVerifier(this)
|
||||
.addNodeWithOrder("VERSION", "3.0")
|
||||
.addNodeWithOrder("FN", "And Roid")
|
||||
.addNodeWithOrder("N", "And;Roid;;;", Arrays.asList("And", "Roid", "", "", ""))
|
||||
.addNodeWithOrder("ORG", "Open;Handset; Alliance",
|
||||
Arrays.asList("Open", "Handset", " Alliance"))
|
||||
.addNodeWithOrder("SORT-STRING", "android")
|
||||
.addNodeWithOrder("TEL", "0300000000", new TypeSet("PREF", "VOICE"))
|
||||
.addNodeWithOrder("CLASS", "PUBLIC")
|
||||
.addNodeWithOrder("X-GNO", "0")
|
||||
.addNodeWithOrder("X-GN", "group0")
|
||||
.addNodeWithOrder("X-REDUCTION", "0")
|
||||
.addNodeWithOrder("REV", "20081031T065854Z");
|
||||
verifier.verify(builder.vNodeList.get(0));
|
||||
}
|
||||
|
||||
@@ -1182,16 +1103,16 @@ public class VCardImportTests extends AndroidTestCase {
|
||||
// Though Japanese careers append ";;;;" at the end of the value of "SOUND",
|
||||
// vCard 2.1/3.0 specification does not allow multiple values.
|
||||
// Do not need to handle it as multiple values.
|
||||
PropertyNodesVerifier verifier = new PropertyNodesVerifier()
|
||||
.addPropertyNode("VERSION", "2.1", null, null, null, null, null)
|
||||
.addPropertyNode("N", "\u5B89\u85E4\u30ED\u30A4\u30C9;;;;",
|
||||
PropertyNodesVerifier verifier = new PropertyNodesVerifier(this)
|
||||
.addNodeWithOrder("VERSION", "2.1", null, null, null, null, null)
|
||||
.addNodeWithOrder("N", "\u5B89\u85E4\u30ED\u30A4\u30C9;;;;",
|
||||
Arrays.asList("\u5B89\u85E4\u30ED\u30A4\u30C9", "", "", "", ""),
|
||||
null, contentValuesForShiftJis, null, null)
|
||||
.addPropertyNode("SOUND", "\uFF71\uFF9D\uFF84\uFF9E\uFF73\uFF9B\uFF72\uFF84\uFF9E;;;;",
|
||||
.addNodeWithOrder("SOUND", "\uFF71\uFF9D\uFF84\uFF9E\uFF73\uFF9B\uFF72\uFF84\uFF9E;;;;",
|
||||
null, null, contentValuesForShiftJis,
|
||||
new HashSet<String>(Arrays.asList("X-IRMC-N")), null)
|
||||
.addPropertyNode("TEL", "0300000000", null, null, null,
|
||||
new HashSet<String>(Arrays.asList("VOICE", "PREF")), null);
|
||||
new TypeSet("X-IRMC-N"), null)
|
||||
.addNodeWithOrder("TEL", "0300000000", null, null, null,
|
||||
new TypeSet("VOICE", "PREF"), null);
|
||||
verifier.verify(builder.vNodeList.get(0));
|
||||
}
|
||||
|
||||
@@ -1257,19 +1178,19 @@ public class VCardImportTests extends AndroidTestCase {
|
||||
ContentValues contentValuesForQP = new ContentValues();
|
||||
contentValuesForQP.put("ENCODING", "QUOTED-PRINTABLE");
|
||||
contentValuesForQP.put("CHARSET", "SHIFT_JIS");
|
||||
PropertyNodesVerifier verifier = new PropertyNodesVerifier()
|
||||
.addPropertyNode("VERSION", "2.1", null, null, null, null, null)
|
||||
.addPropertyNode("N", "\u5B89\u85E4;\u30ED\u30A4\u30C9\u0031;;;",
|
||||
PropertyNodesVerifier verifier = new PropertyNodesVerifier(this)
|
||||
.addNodeWithOrder("VERSION", "2.1")
|
||||
.addNodeWithOrder("N", "\u5B89\u85E4;\u30ED\u30A4\u30C9\u0031;;;",
|
||||
Arrays.asList("\u5B89\u85E4", "\u30ED\u30A4\u30C9\u0031",
|
||||
"", "", ""),
|
||||
null, contentValuesForShiftJis, null, null)
|
||||
.addPropertyNode("FN", "\u5B89\u85E4\u0020\u30ED\u30A4\u30C9\u0020\u0031",
|
||||
.addNodeWithOrder("FN", "\u5B89\u85E4\u0020\u30ED\u30A4\u30C9\u0020\u0031",
|
||||
null, null, contentValuesForShiftJis, null, null)
|
||||
.addPropertyNode("SOUND",
|
||||
.addNodeWithOrder("SOUND",
|
||||
"\uFF71\uFF9D\uFF84\uFF9E\uFF73;\uFF9B\uFF72\uFF84\uFF9E\u0031;;;",
|
||||
null, null, contentValuesForShiftJis,
|
||||
new HashSet<String>(Arrays.asList("X-IRMC-N")), null)
|
||||
.addPropertyNode("ADR",
|
||||
new TypeSet("X-IRMC-N"), null)
|
||||
.addNodeWithOrder("ADR",
|
||||
";\u6771\u4EAC\u90FD\u6E0B\u8C37\u533A\u685C" +
|
||||
"\u4E18\u753A\u0032\u0036\u002D\u0031\u30BB" +
|
||||
"\u30EB\u30EA\u30A2\u30F3\u30BF\u30EF\u30FC\u0036" +
|
||||
@@ -1279,8 +1200,8 @@ public class VCardImportTests extends AndroidTestCase {
|
||||
"\u4E18\u753A\u0032\u0036\u002D\u0031\u30BB" +
|
||||
"\u30EB\u30EA\u30A2\u30F3\u30BF\u30EF\u30FC" +
|
||||
"\u0036\u968E", "", "", "", "150-8512", ""),
|
||||
null, contentValuesForQP, new HashSet<String>(Arrays.asList("HOME")), null)
|
||||
.addPropertyNode("NOTE", "\u30E1\u30E2", null, null, contentValuesForQP, null, null);
|
||||
null, contentValuesForQP, new TypeSet("HOME"), null)
|
||||
.addNodeWithOrder("NOTE", "\u30E1\u30E2", null, null, contentValuesForQP, null, null);
|
||||
verifier.verify(builder.vNodeList.get(0));
|
||||
}
|
||||
|
||||
@@ -1329,60 +1250,48 @@ public class VCardImportTests extends AndroidTestCase {
|
||||
assertEquals(3, builder.vNodeList.size());
|
||||
ContentValues contentValuesForShiftJis = new ContentValues();
|
||||
contentValuesForShiftJis.put("CHARSET", "SHIFT_JIS");
|
||||
PropertyNodesVerifier verifier = new PropertyNodesVerifier()
|
||||
.addPropertyNode("VERSION", "2.1", null, null, null, null, null)
|
||||
.addPropertyNode("N", "\u5B89\u85E4\u30ED\u30A4\u30C9\u0033;;;;",
|
||||
PropertyNodesVerifier verifier = new PropertyNodesVerifier(this)
|
||||
.addNodeWithOrder("VERSION", "2.1")
|
||||
.addNodeWithOrder("N", "\u5B89\u85E4\u30ED\u30A4\u30C9\u0033;;;;",
|
||||
Arrays.asList("\u5B89\u85E4\u30ED\u30A4\u30C9\u0033", "", "", "", ""),
|
||||
null, contentValuesForShiftJis, null, null)
|
||||
.addPropertyNode("SOUND",
|
||||
.addNodeWithOrder("SOUND",
|
||||
"\uFF71\uFF9D\uFF84\uFF9E\uFF73\uFF9B\uFF72\uFF84\uFF9E\u0033;;;;",
|
||||
null, null, contentValuesForShiftJis,
|
||||
new HashSet<String>(Arrays.asList("X-IRMC-N")), null)
|
||||
.addPropertyNode("TEL", "9", null, null, null,
|
||||
new HashSet<String>(Arrays.asList("X-NEC-SECRET")), null)
|
||||
.addPropertyNode("TEL", "10", null, null, null,
|
||||
new HashSet<String>(Arrays.asList("X-NEC-HOTEL")), null)
|
||||
.addPropertyNode("TEL", "11", null, null, null,
|
||||
new HashSet<String>(Arrays.asList("X-NEC-SCHOOL")), null)
|
||||
.addPropertyNode("TEL", "12", null, null, null,
|
||||
new HashSet<String>(Arrays.asList("FAX", "HOME")), null);
|
||||
new TypeSet("X-IRMC-N"), null)
|
||||
.addNodeWithOrder("TEL", "9", new TypeSet("X-NEC-SECRET"))
|
||||
.addNodeWithOrder("TEL", "10", new TypeSet("X-NEC-HOTEL"))
|
||||
.addNodeWithOrder("TEL", "11", new TypeSet("X-NEC-SCHOOL"))
|
||||
.addNodeWithOrder("TEL", "12", new TypeSet("FAX", "HOME"));
|
||||
verifier.verify(builder.vNodeList.get(0));
|
||||
|
||||
verifier = new PropertyNodesVerifier()
|
||||
.addPropertyNode("VERSION", "2.1", null, null, null, null, null)
|
||||
.addPropertyNode("N", "\u5B89\u85E4\u30ED\u30A4\u30C9\u0034;;;;",
|
||||
verifier = new PropertyNodesVerifier(this)
|
||||
.addNodeWithOrder("VERSION", "2.1")
|
||||
.addNodeWithOrder("N", "\u5B89\u85E4\u30ED\u30A4\u30C9\u0034;;;;",
|
||||
Arrays.asList("\u5B89\u85E4\u30ED\u30A4\u30C9\u0034", "", "", "", ""),
|
||||
null, contentValuesForShiftJis, null, null)
|
||||
.addPropertyNode("SOUND",
|
||||
.addNodeWithOrder("SOUND",
|
||||
"\uFF71\uFF9D\uFF84\uFF9E\uFF73\uFF9B\uFF72\uFF84\uFF9E\u0034;;;;",
|
||||
null, null, contentValuesForShiftJis,
|
||||
new HashSet<String>(Arrays.asList("X-IRMC-N")), null)
|
||||
.addPropertyNode("TEL", "13", null, null, null,
|
||||
new HashSet<String>(Arrays.asList("MODEM")), null)
|
||||
.addPropertyNode("TEL", "14", null, null, null,
|
||||
new HashSet<String>(Arrays.asList("PAGER")), null)
|
||||
.addPropertyNode("TEL", "15", null, null, null,
|
||||
new HashSet<String>(Arrays.asList("X-NEC-FAMILY")), null)
|
||||
.addPropertyNode("TEL", "16", null, null, null,
|
||||
new HashSet<String>(Arrays.asList("X-NEC-GIRL")), null);
|
||||
new TypeSet("X-IRMC-N"), null)
|
||||
.addNodeWithOrder("TEL", "13", new TypeSet("MODEM"))
|
||||
.addNodeWithOrder("TEL", "14", new TypeSet("PAGER"))
|
||||
.addNodeWithOrder("TEL", "15", new TypeSet("X-NEC-FAMILY"))
|
||||
.addNodeWithOrder("TEL", "16", new TypeSet("X-NEC-GIRL"));
|
||||
verifier.verify(builder.vNodeList.get(1));
|
||||
verifier = new PropertyNodesVerifier()
|
||||
.addPropertyNode("VERSION", "2.1", null, null, null, null, null)
|
||||
.addPropertyNode("N", "\u5B89\u85E4\u30ED\u30A4\u30C9\u0035;;;;",
|
||||
verifier = new PropertyNodesVerifier(this)
|
||||
.addNodeWithOrder("VERSION", "2.1")
|
||||
.addNodeWithOrder("N", "\u5B89\u85E4\u30ED\u30A4\u30C9\u0035;;;;",
|
||||
Arrays.asList("\u5B89\u85E4\u30ED\u30A4\u30C9\u0035", "", "", "", ""),
|
||||
null, contentValuesForShiftJis, null, null)
|
||||
.addPropertyNode("SOUND",
|
||||
.addNodeWithOrder("SOUND",
|
||||
"\uFF71\uFF9D\uFF84\uFF9E\uFF73\uFF9B\uFF72\uFF84\uFF9E\u0035;;;;",
|
||||
null, null, contentValuesForShiftJis,
|
||||
new HashSet<String>(Arrays.asList("X-IRMC-N")), null)
|
||||
.addPropertyNode("TEL", "17", null, null, null,
|
||||
new HashSet<String>(Arrays.asList("X-NEC-BOY")), null)
|
||||
.addPropertyNode("TEL", "18", null, null, null,
|
||||
new HashSet<String>(Arrays.asList("X-NEC-FRIEND")), null)
|
||||
.addPropertyNode("TEL", "19", null, null, null,
|
||||
new HashSet<String>(Arrays.asList("X-NEC-PHS")), null)
|
||||
.addPropertyNode("TEL", "20", null, null, null,
|
||||
new HashSet<String>(Arrays.asList("X-NEC-RESTAURANT")), null);
|
||||
new TypeSet("X-IRMC-N"), null)
|
||||
.addNodeWithOrder("TEL", "17", new TypeSet("X-NEC-BOY"))
|
||||
.addNodeWithOrder("TEL", "18", new TypeSet("X-NEC-FRIEND"))
|
||||
.addNodeWithOrder("TEL", "19", new TypeSet("X-NEC-PHS"))
|
||||
.addNodeWithOrder("TEL", "20", new TypeSet("X-NEC-RESTAURANT"));
|
||||
verifier.verify(builder.vNodeList.get(2));
|
||||
}
|
||||
}
|
||||
@@ -190,6 +190,7 @@ public class VNodeBuilder implements VCardBuilder {
|
||||
|
||||
private String handleOneValue(String value, String targetCharset, String encoding) {
|
||||
if (encoding != null) {
|
||||
encoding = encoding.toUpperCase();
|
||||
if (encoding.equals("BASE64") || encoding.equals("B")) {
|
||||
// Assume BASE64 is used only when the number of values is 1.
|
||||
mCurrentPropNode.propValue_bytes =
|
||||
|
||||
Reference in New Issue
Block a user