summaryrefslogtreecommitdiffstats
path: root/chrome/browser/autofill
diff options
context:
space:
mode:
authordhollowa@chromium.org <dhollowa@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-03-28 22:54:03 +0000
committerdhollowa@chromium.org <dhollowa@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-03-28 22:54:03 +0000
commit791c8c7d6aa25a182970d4c3a3c50dc88f527171 (patch)
tree31bcfb23927126d630af52f388b8540d8ed5bfc5 /chrome/browser/autofill
parent1561fd6740aedcdb6cf47703fef0de9d292c38b2 (diff)
downloadchromium_src-791c8c7d6aa25a182970d4c3a3c50dc88f527171.zip
chromium_src-791c8c7d6aa25a182970d4c3a3c50dc88f527171.tar.gz
chromium_src-791c8c7d6aa25a182970d4c3a3c50dc88f527171.tar.bz2
Autofill extend profiles to include multi-valued fields, part 3.
Adds new GetMultiInfo/SetMultiInfo methods to the AutofillProfile class and propagates the multi-valued data down through to the WebDatabase layer. Single-valued mechanisms are still in place. Some of these will be removed once Sync is updated. BUG=65625 TEST=WebDatabaseTest.*:AutofillProfileTest.* Review URL: http://codereview.chromium.org/6726042 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@79629 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/autofill')
-rw-r--r--chrome/browser/autofill/address.h2
-rw-r--r--chrome/browser/autofill/autofill_profile.cc226
-rw-r--r--chrome/browser/autofill/autofill_profile.h30
-rw-r--r--chrome/browser/autofill/autofill_profile_unittest.cc176
-rw-r--r--chrome/browser/autofill/contact_info.h6
-rw-r--r--chrome/browser/autofill/fax_number.h2
-rw-r--r--chrome/browser/autofill/home_phone_number.h2
7 files changed, 380 insertions, 64 deletions
diff --git a/chrome/browser/autofill/address.h b/chrome/browser/autofill/address.h
index d030049..de6ac46 100644
--- a/chrome/browser/autofill/address.h
+++ b/chrome/browser/autofill/address.h
@@ -17,7 +17,7 @@
class Address : public FormGroup {
public:
Address();
- explicit Address(const Address& address);
+ Address(const Address& address);
virtual ~Address();
Address& operator=(const Address& address);
diff --git a/chrome/browser/autofill/autofill_profile.cc b/chrome/browser/autofill/autofill_profile.cc
index b8f29a1..cc0ab01 100644
--- a/chrome/browser/autofill/autofill_profile.cc
+++ b/chrome/browser/autofill/autofill_profile.cc
@@ -98,19 +98,58 @@ void GetFieldsForDistinguishingProfiles(
}
}
+// A helper function for string streaming. Concatenates multi-valued entries
+// stored for a given |type| into a single string. This string is returned.
+const string16 MultiString(const AutofillProfile& p, AutofillFieldType type) {
+ std::vector<string16> values;
+ p.GetMultiInfo(type, &values);
+ string16 accumulate;
+ for (size_t i = 0; i < values.size(); ++i) {
+ if (i > 0)
+ accumulate += ASCIIToUTF16(" ");
+ accumulate += values[i];
+ }
+ return accumulate;
+}
+
+template <class T>
+void CopyValuesToItems(AutofillFieldType type,
+ const std::vector<string16>& values,
+ std::vector<T>* form_group_items) {
+ form_group_items->resize(values.size());
+ for (size_t i = 0; i < form_group_items->size(); ++i)
+ (*form_group_items)[i].SetInfo(type, CollapseWhitespace(values[i], false));
+ // Must have at least one (possibly empty) element.
+ if (form_group_items->empty())
+ form_group_items->resize(1);
+}
+
+template <class T>
+void CopyItemsToValues(AutofillFieldType type,
+ const std::vector<T>& form_group_items,
+ std::vector<string16>* values) {
+ values->resize(form_group_items.size());
+ for (size_t i = 0; i < values->size(); ++i)
+ (*values)[i] = form_group_items[i].GetInfo(type);
+}
+
} // namespace
AutofillProfile::AutofillProfile(const std::string& guid)
- : guid_(guid) {
+ : guid_(guid), name_(1), email_(1), home_number_(1), fax_number_(1) {
}
AutofillProfile::AutofillProfile()
- : guid_(guid::GenerateGUID()) {
+ : guid_(guid::GenerateGUID()),
+ name_(1),
+ email_(1),
+ home_number_(1),
+ fax_number_(1) {
}
-AutofillProfile::AutofillProfile(const AutofillProfile& source)
+AutofillProfile::AutofillProfile(const AutofillProfile& profile)
: FormGroup() {
- operator=(source);
+ operator=(profile);
}
AutofillProfile::~AutofillProfile() {
@@ -136,14 +175,14 @@ AutofillProfile& AutofillProfile::operator=(const AutofillProfile& profile) {
void AutofillProfile::GetPossibleFieldTypes(
const string16& text,
FieldTypeSet* possible_types) const {
- FormGroupList info = info_list();
+ FormGroupList info = FormGroups();
for (FormGroupList::const_iterator it = info.begin(); it != info.end(); ++it)
(*it)->GetPossibleFieldTypes(text, possible_types);
}
void AutofillProfile::GetAvailableFieldTypes(
FieldTypeSet* available_types) const {
- FormGroupList info = info_list();
+ FormGroupList info = FormGroups();
for (FormGroupList::const_iterator it = info.begin(); it != info.end(); ++it)
(*it)->GetAvailableFieldTypes(available_types);
}
@@ -161,35 +200,73 @@ void AutofillProfile::FindInfoMatches(
// If the field_type is unknown, then match against all field types.
if (type == UNKNOWN_TYPE) {
- FormGroupList info = info_list();
+ FormGroupList info = FormGroups();
for (FormGroupList::const_iterator it = info.begin();
it != info.end(); ++it)
(*it)->FindInfoMatches(type, clean_info, matched_text);
} else {
- FormGroupMap info = info_map();
- FormGroupMap::const_iterator it = info.find(AutofillType(type).group());
- if (it != info.end())
- it->second->FindInfoMatches(type, clean_info, matched_text);
+ const FormGroup* form_group = FormGroupForType(type);
+ if (form_group)
+ form_group->FindInfoMatches(type, clean_info, matched_text);
}
}
string16 AutofillProfile::GetInfo(AutofillFieldType type) const {
AutofillFieldType return_type = AutofillType::GetEquivalentFieldType(type);
-
- FormGroupMap info = info_map();
- FormGroupMap::const_iterator it =
- info.find(AutofillType(return_type).group());
- if (it == info.end())
+ const FormGroup* form_group = FormGroupForType(return_type);
+ if (!form_group)
return string16();
- return it->second->GetInfo(return_type);
+ return form_group->GetInfo(return_type);
}
void AutofillProfile::SetInfo(AutofillFieldType type, const string16& value) {
- MutableFormGroupMap info = mutable_info_map();
- MutableFormGroupMap::iterator it = info.find(AutofillType(type).group());
- if (it != info.end())
- it->second->SetInfo(type, CollapseWhitespace(value, false));
+ FormGroup* form_group = MutableFormGroupForType(type);
+ if (form_group)
+ form_group->SetInfo(type, CollapseWhitespace(value, false));
+}
+
+void AutofillProfile::SetMultiInfo(AutofillFieldType type,
+ const std::vector<string16>& values) {
+ switch (AutofillType(type).group()) {
+ case AutofillType::NAME:
+ CopyValuesToItems(type, values, &name_);
+ break;
+ case AutofillType::EMAIL:
+ CopyValuesToItems(type, values, &email_);
+ break;
+ case AutofillType::PHONE_HOME:
+ CopyValuesToItems(type, values, &home_number_);
+ break;
+ case AutofillType::PHONE_FAX:
+ CopyValuesToItems(type, values, &fax_number_);
+ break;
+ default:
+ NOTREACHED() << "Attempt to set multiple values on single-valued field.";
+ break;
+ }
+}
+
+void AutofillProfile::GetMultiInfo(AutofillFieldType type,
+ std::vector<string16>* values) const {
+ switch (AutofillType(type).group()) {
+ case AutofillType::NAME:
+ CopyItemsToValues(type, name_, values);
+ break;
+ case AutofillType::EMAIL:
+ CopyItemsToValues(type, email_, values);
+ break;
+ case AutofillType::PHONE_HOME:
+ CopyItemsToValues(type, home_number_, values);
+ break;
+ case AutofillType::PHONE_FAX:
+ CopyItemsToValues(type, fax_number_, values);
+ break;
+ default:
+ NOTREACHED()
+ << "Attempt to get multiple values from a single-valued field.";
+ break;
+ }
}
const string16 AutofillProfile::Label() const {
@@ -300,6 +377,48 @@ int AutofillProfile::Compare(const AutofillProfile& profile) const {
return 0;
}
+int AutofillProfile::CompareMulti(const AutofillProfile& profile) const {
+ const AutofillFieldType single_value_types[] = { COMPANY_NAME,
+ ADDRESS_HOME_LINE1,
+ ADDRESS_HOME_LINE2,
+ ADDRESS_HOME_CITY,
+ ADDRESS_HOME_STATE,
+ ADDRESS_HOME_ZIP,
+ ADDRESS_HOME_COUNTRY };
+
+ for (size_t i = 0; i < arraysize(single_value_types); ++i) {
+ int comparison = GetInfo(single_value_types[i]).compare(
+ profile.GetInfo(single_value_types[i]));
+ if (comparison != 0)
+ return comparison;
+ }
+
+ const AutofillFieldType multi_value_types[] = { NAME_FIRST,
+ NAME_MIDDLE,
+ NAME_LAST,
+ EMAIL_ADDRESS,
+ PHONE_HOME_NUMBER,
+ PHONE_FAX_NUMBER };
+
+ for (size_t i = 0; i < arraysize(multi_value_types); ++i) {
+ std::vector<string16> values_a;
+ std::vector<string16> values_b;
+ GetMultiInfo(multi_value_types[i], &values_a);
+ profile.GetMultiInfo(multi_value_types[i], &values_b);
+ if (values_a.size() < values_b.size())
+ return -1;
+ if (values_a.size() > values_b.size())
+ return 1;
+ for (size_t j = 0; j < values_a.size(); ++j) {
+ int comparison = values_a[j].compare(values_b[j]);
+ if (comparison != 0)
+ return comparison;
+ }
+ }
+
+ return 0;
+}
+
bool AutofillProfile::operator==(const AutofillProfile& profile) const {
return guid_ == profile.guid_ && Compare(profile) == 0;
}
@@ -422,36 +541,47 @@ void AutofillProfile::CreateDifferentiatingLabels(
}
}
-AutofillProfile::FormGroupList AutofillProfile::info_list() const {
+AutofillProfile::FormGroupList AutofillProfile::FormGroups() const {
FormGroupList v(6);
- v[0] = &name_;
- v[1] = &email_;
+ v[0] = &name_[0];
+ v[1] = &email_[0];
v[2] = &company_;
- v[3] = &home_number_;
- v[4] = &fax_number_;
+ v[3] = &home_number_[0];
+ v[4] = &fax_number_[0];
v[5] = &address_;
return v;
}
-AutofillProfile::FormGroupMap AutofillProfile::info_map() const {
- FormGroupMap m;
- m[AutofillType::NAME] = &name_;
- m[AutofillType::EMAIL] = &email_;
- m[AutofillType::COMPANY] = &company_;
- m[AutofillType::PHONE_HOME] = &home_number_;
- m[AutofillType::PHONE_FAX] = &fax_number_;
- m[AutofillType::ADDRESS_HOME] = &address_;
- return m;
+const FormGroup* AutofillProfile::FormGroupForType(
+ AutofillFieldType type) const {
+ return const_cast<AutofillProfile*>(this)->MutableFormGroupForType(type);
}
-AutofillProfile::MutableFormGroupMap AutofillProfile::mutable_info_map() {
- FormGroupMap m_const = info_map();
- MutableFormGroupMap m;
- for (FormGroupMap::const_iterator it = m_const.begin();
- it != m_const.end(); ++it) {
- m[it->first] = const_cast<FormGroup*>(it->second);
+FormGroup* AutofillProfile::MutableFormGroupForType(AutofillFieldType type) {
+ FormGroup* form_group = NULL;
+ switch (AutofillType(type).group()) {
+ case AutofillType::NAME:
+ form_group = &name_[0];
+ break;
+ case AutofillType::EMAIL:
+ form_group = &email_[0];
+ break;
+ case AutofillType::COMPANY:
+ form_group = &company_;
+ break;
+ case AutofillType::PHONE_HOME:
+ form_group = &home_number_[0];
+ break;
+ case AutofillType::PHONE_FAX:
+ form_group = &fax_number_[0];
+ break;
+ case AutofillType::ADDRESS_HOME:
+ form_group = &address_;
+ break;
+ default:
+ break;
}
- return m;
+ return form_group;
}
// So we can compare AutofillProfiles with EXPECT_EQ().
@@ -461,13 +591,13 @@ std::ostream& operator<<(std::ostream& os, const AutofillProfile& profile) {
<< " "
<< profile.guid()
<< " "
- << UTF16ToUTF8(profile.GetInfo(NAME_FIRST))
+ << UTF16ToUTF8(MultiString(profile, NAME_FIRST))
<< " "
- << UTF16ToUTF8(profile.GetInfo(NAME_MIDDLE))
+ << UTF16ToUTF8(MultiString(profile, NAME_MIDDLE))
<< " "
- << UTF16ToUTF8(profile.GetInfo(NAME_LAST))
+ << UTF16ToUTF8(MultiString(profile, NAME_LAST))
<< " "
- << UTF16ToUTF8(profile.GetInfo(EMAIL_ADDRESS))
+ << UTF16ToUTF8(MultiString(profile, EMAIL_ADDRESS))
<< " "
<< UTF16ToUTF8(profile.GetInfo(COMPANY_NAME))
<< " "
@@ -483,7 +613,7 @@ std::ostream& operator<<(std::ostream& os, const AutofillProfile& profile) {
<< " "
<< UTF16ToUTF8(profile.GetInfo(ADDRESS_HOME_COUNTRY))
<< " "
- << UTF16ToUTF8(profile.GetInfo(PHONE_HOME_WHOLE_NUMBER))
+ << UTF16ToUTF8(MultiString(profile, PHONE_HOME_WHOLE_NUMBER))
<< " "
- << UTF16ToUTF8(profile.GetInfo(PHONE_FAX_WHOLE_NUMBER));
+ << UTF16ToUTF8(MultiString(profile, PHONE_FAX_WHOLE_NUMBER));
}
diff --git a/chrome/browser/autofill/autofill_profile.h b/chrome/browser/autofill/autofill_profile.h
index 7b8b50f..11e8bce 100644
--- a/chrome/browser/autofill/autofill_profile.h
+++ b/chrome/browser/autofill/autofill_profile.h
@@ -27,7 +27,7 @@ class AutofillProfile : public FormGroup {
// For use in STL containers.
AutofillProfile();
- AutofillProfile(const AutofillProfile&);
+ AutofillProfile(const AutofillProfile& profile);
virtual ~AutofillProfile();
AutofillProfile& operator=(const AutofillProfile& profile);
@@ -45,6 +45,12 @@ class AutofillProfile : public FormGroup {
virtual string16 GetInfo(AutofillFieldType type) const;
virtual void SetInfo(AutofillFieldType type, const string16& value);
+ // Multi-value equivalents to |GetInfo| and |SetInfo|.
+ void SetMultiInfo(AutofillFieldType type,
+ const std::vector<string16>& values);
+ void GetMultiInfo(AutofillFieldType type,
+ std::vector<string16>* values) const;
+
// The user-visible label of the profile, generated in relation to other
// profiles. Shows at least 2 fields that differentiate profile from other
// profiles. See AdjustInferredLabels() further down for more description.
@@ -95,9 +101,15 @@ class AutofillProfile : public FormGroup {
// culling duplicates. The ordering is based on collation order of the
// textual contents of the fields.
// GUIDs are not compared, only the values of the contents themselves.
+ // DEPRECATED: Use |CompareMulti| instead. |Compare| does not compare
+ // multi-valued items.
int Compare(const AutofillProfile& profile) const;
+ // Comparison for Sync. Same as |Compare| but includes multi-valued fields.
+ int CompareMulti(const AutofillProfile& profile) const;
+
// Equality operators compare GUIDs and the contents in the comparison.
+ // TODO(dhollowa): This needs to be made multi-profile once Sync updates.
bool operator==(const AutofillProfile& profile) const;
virtual bool operator!=(const AutofillProfile& profile) const;
@@ -108,8 +120,6 @@ class AutofillProfile : public FormGroup {
private:
typedef std::vector<const FormGroup*> FormGroupList;
- typedef std::map<FieldTypeGroup, const FormGroup*> FormGroupMap;
- typedef std::map<FieldTypeGroup, FormGroup*> MutableFormGroupMap;
// Builds inferred label from the first |num_fields_to_include| non-empty
// fields in |label_fields|. Uses as many fields as possible if there are not
@@ -132,9 +142,9 @@ class AutofillProfile : public FormGroup {
// Utilities for listing and lookup of the data members that constitute
// user-visible profile information.
- FormGroupList info_list() const;
- FormGroupMap info_map() const;
- MutableFormGroupMap mutable_info_map();
+ FormGroupList FormGroups() const;
+ const FormGroup* FormGroupForType(AutofillFieldType type) const;
+ FormGroup* MutableFormGroupForType(AutofillFieldType type);
// The label presented to the user when selecting a profile.
string16 label_;
@@ -143,11 +153,11 @@ class AutofillProfile : public FormGroup {
std::string guid_;
// Personal information for this profile.
- NameInfo name_;
- EmailInfo email_;
+ std::vector<NameInfo> name_;
+ std::vector<EmailInfo> email_;
CompanyInfo company_;
- HomePhoneNumber home_number_;
- FaxNumber fax_number_;
+ std::vector<HomePhoneNumber> home_number_;
+ std::vector<FaxNumber> fax_number_;
Address address_;
};
diff --git a/chrome/browser/autofill/autofill_profile_unittest.cc b/chrome/browser/autofill/autofill_profile_unittest.cc
index 5f5d214..28b5f84 100644
--- a/chrome/browser/autofill/autofill_profile_unittest.cc
+++ b/chrome/browser/autofill/autofill_profile_unittest.cc
@@ -642,3 +642,179 @@ TEST(AutofillProfileTest, CountryCode) {
profile.SetCountryCode("US");
EXPECT_EQ("US", profile.CountryCode());
}
+
+TEST(AutofillProfileTest, MultiValueNames) {
+ AutofillProfile p;
+ const string16 kJohnDoe(ASCIIToUTF16("John Doe"));
+ const string16 kJohnPDoe(ASCIIToUTF16("John P. Doe"));
+ std::vector<string16> set_values;
+ set_values.push_back(kJohnDoe);
+ set_values.push_back(kJohnPDoe);
+ p.SetMultiInfo(NAME_FULL, set_values);
+
+ // Expect regular |GetInfo| returns the first element.
+ EXPECT_EQ(kJohnDoe, p.GetInfo(NAME_FULL));
+
+ // Ensure that we get out what we put in.
+ std::vector<string16> get_values;
+ p.GetMultiInfo(NAME_FULL, &get_values);
+ ASSERT_EQ(2UL, get_values.size());
+ EXPECT_EQ(kJohnDoe, get_values[0]);
+ EXPECT_EQ(kJohnPDoe, get_values[1]);
+
+ // Update the values.
+ AutofillProfile p2 = p;
+ EXPECT_EQ(0, p.Compare(p2));
+ EXPECT_EQ(0, p.CompareMulti(p2));
+ const string16 kNoOne(ASCIIToUTF16("No One"));
+ set_values[1] = kNoOne;
+ p.SetMultiInfo(NAME_FULL, set_values);
+ p.GetMultiInfo(NAME_FULL, &get_values);
+ ASSERT_EQ(2UL, get_values.size());
+ EXPECT_EQ(kJohnDoe, get_values[0]);
+ EXPECT_EQ(kNoOne, get_values[1]);
+ EXPECT_EQ(0, p.Compare(p2));
+ EXPECT_NE(0, p.CompareMulti(p2));
+
+ // Delete values.
+ set_values.clear();
+ p.SetMultiInfo(NAME_FULL, set_values);
+ p.GetMultiInfo(NAME_FULL, &get_values);
+ ASSERT_EQ(1UL, get_values.size());
+ EXPECT_EQ(string16(), get_values[0]);
+
+ // Expect regular |GetInfo| returns empty value.
+ EXPECT_EQ(string16(), p.GetInfo(NAME_FULL));
+}
+
+TEST(AutofillProfileTest, MultiValueEmails) {
+ AutofillProfile p;
+ const string16 kJohnDoe(ASCIIToUTF16("john@doe.com"));
+ const string16 kJohnPDoe(ASCIIToUTF16("john_p@doe.com"));
+ std::vector<string16> set_values;
+ set_values.push_back(kJohnDoe);
+ set_values.push_back(kJohnPDoe);
+ p.SetMultiInfo(EMAIL_ADDRESS, set_values);
+
+ // Expect regular |GetInfo| returns the first element.
+ EXPECT_EQ(kJohnDoe, p.GetInfo(EMAIL_ADDRESS));
+
+ // Ensure that we get out what we put in.
+ std::vector<string16> get_values;
+ p.GetMultiInfo(EMAIL_ADDRESS, &get_values);
+ ASSERT_EQ(2UL, get_values.size());
+ EXPECT_EQ(kJohnDoe, get_values[0]);
+ EXPECT_EQ(kJohnPDoe, get_values[1]);
+
+ // Update the values.
+ AutofillProfile p2 = p;
+ EXPECT_EQ(0, p.Compare(p2));
+ EXPECT_EQ(0, p.CompareMulti(p2));
+ const string16 kNoOne(ASCIIToUTF16("no@one.com"));
+ set_values[1] = kNoOne;
+ p.SetMultiInfo(EMAIL_ADDRESS, set_values);
+ p.GetMultiInfo(EMAIL_ADDRESS, &get_values);
+ ASSERT_EQ(2UL, get_values.size());
+ EXPECT_EQ(kJohnDoe, get_values[0]);
+ EXPECT_EQ(kNoOne, get_values[1]);
+ EXPECT_EQ(0, p.Compare(p2));
+ EXPECT_NE(0, p.CompareMulti(p2));
+
+ // Delete values.
+ set_values.clear();
+ p.SetMultiInfo(EMAIL_ADDRESS, set_values);
+ p.GetMultiInfo(EMAIL_ADDRESS, &get_values);
+ ASSERT_EQ(1UL, get_values.size());
+ EXPECT_EQ(string16(), get_values[0]);
+
+ // Expect regular |GetInfo| returns empty value.
+ EXPECT_EQ(string16(), p.GetInfo(EMAIL_ADDRESS));
+}
+
+TEST(AutofillProfileTest, MultiValuePhone) {
+ AutofillProfile p;
+ const string16 kJohnDoe(ASCIIToUTF16("4151112222"));
+ const string16 kJohnPDoe(ASCIIToUTF16("4151113333"));
+ std::vector<string16> set_values;
+ set_values.push_back(kJohnDoe);
+ set_values.push_back(kJohnPDoe);
+ p.SetMultiInfo(PHONE_HOME_WHOLE_NUMBER, set_values);
+
+ // Expect regular |GetInfo| returns the first element.
+ EXPECT_EQ(kJohnDoe, p.GetInfo(PHONE_HOME_WHOLE_NUMBER));
+
+ // Ensure that we get out what we put in.
+ std::vector<string16> get_values;
+ p.GetMultiInfo(PHONE_HOME_WHOLE_NUMBER, &get_values);
+ ASSERT_EQ(2UL, get_values.size());
+ EXPECT_EQ(kJohnDoe, get_values[0]);
+ EXPECT_EQ(kJohnPDoe, get_values[1]);
+
+ // Update the values.
+ AutofillProfile p2 = p;
+ EXPECT_EQ(0, p.Compare(p2));
+ EXPECT_EQ(0, p.CompareMulti(p2));
+ const string16 kNoOne(ASCIIToUTF16("4151110000"));
+ set_values[1] = kNoOne;
+ p.SetMultiInfo(PHONE_HOME_WHOLE_NUMBER, set_values);
+ p.GetMultiInfo(PHONE_HOME_WHOLE_NUMBER, &get_values);
+ ASSERT_EQ(2UL, get_values.size());
+ EXPECT_EQ(kJohnDoe, get_values[0]);
+ EXPECT_EQ(kNoOne, get_values[1]);
+ EXPECT_EQ(0, p.Compare(p2));
+ EXPECT_NE(0, p.CompareMulti(p2));
+
+ // Delete values.
+ set_values.clear();
+ p.SetMultiInfo(PHONE_HOME_WHOLE_NUMBER, set_values);
+ p.GetMultiInfo(PHONE_HOME_WHOLE_NUMBER, &get_values);
+ ASSERT_EQ(1UL, get_values.size());
+ EXPECT_EQ(string16(), get_values[0]);
+
+ // Expect regular |GetInfo| returns empty value.
+ EXPECT_EQ(string16(), p.GetInfo(PHONE_HOME_WHOLE_NUMBER));
+}
+
+TEST(AutofillProfileTest, MultiValueFax) {
+ AutofillProfile p;
+ const string16 kJohnDoe(ASCIIToUTF16("4151112222"));
+ const string16 kJohnPDoe(ASCIIToUTF16("4151113333"));
+ std::vector<string16> set_values;
+ set_values.push_back(kJohnDoe);
+ set_values.push_back(kJohnPDoe);
+ p.SetMultiInfo(PHONE_FAX_WHOLE_NUMBER, set_values);
+
+ // Expect regular |GetInfo| returns the first element.
+ EXPECT_EQ(kJohnDoe, p.GetInfo(PHONE_FAX_WHOLE_NUMBER));
+
+ // Ensure that we get out what we put in.
+ std::vector<string16> get_values;
+ p.GetMultiInfo(PHONE_FAX_WHOLE_NUMBER, &get_values);
+ ASSERT_EQ(2UL, get_values.size());
+ EXPECT_EQ(kJohnDoe, get_values[0]);
+ EXPECT_EQ(kJohnPDoe, get_values[1]);
+
+ // Update the values.
+ AutofillProfile p2 = p;
+ EXPECT_EQ(0, p.Compare(p2));
+ EXPECT_EQ(0, p.CompareMulti(p2));
+ const string16 kNoOne(ASCIIToUTF16("4151110000"));
+ set_values[1] = kNoOne;
+ p.SetMultiInfo(PHONE_FAX_WHOLE_NUMBER, set_values);
+ p.GetMultiInfo(PHONE_FAX_WHOLE_NUMBER, &get_values);
+ ASSERT_EQ(2UL, get_values.size());
+ EXPECT_EQ(kJohnDoe, get_values[0]);
+ EXPECT_EQ(kNoOne, get_values[1]);
+ EXPECT_EQ(0, p.Compare(p2));
+ EXPECT_NE(0, p.CompareMulti(p2));
+
+ // Delete values.
+ set_values.clear();
+ p.SetMultiInfo(PHONE_FAX_WHOLE_NUMBER, set_values);
+ p.GetMultiInfo(PHONE_FAX_WHOLE_NUMBER, &get_values);
+ ASSERT_EQ(1UL, get_values.size());
+ EXPECT_EQ(string16(), get_values[0]);
+
+ // Expect regular |GetInfo| returns empty value.
+ EXPECT_EQ(string16(), p.GetInfo(PHONE_FAX_WHOLE_NUMBER));
+}
diff --git a/chrome/browser/autofill/contact_info.h b/chrome/browser/autofill/contact_info.h
index d01e20c..52755aa 100644
--- a/chrome/browser/autofill/contact_info.h
+++ b/chrome/browser/autofill/contact_info.h
@@ -16,7 +16,7 @@
class NameInfo : public FormGroup {
public:
NameInfo();
- explicit NameInfo(const NameInfo& info);
+ NameInfo(const NameInfo& info);
virtual ~NameInfo();
NameInfo& operator=(const NameInfo& info);
@@ -105,7 +105,7 @@ class NameInfo : public FormGroup {
class EmailInfo : public FormGroup {
public:
EmailInfo();
- explicit EmailInfo(const EmailInfo& info);
+ EmailInfo(const EmailInfo& info);
virtual ~EmailInfo();
EmailInfo& operator=(const EmailInfo& info);
@@ -127,7 +127,7 @@ class EmailInfo : public FormGroup {
class CompanyInfo : public FormGroup {
public:
CompanyInfo();
- explicit CompanyInfo(const CompanyInfo& info);
+ CompanyInfo(const CompanyInfo& info);
virtual ~CompanyInfo();
CompanyInfo& operator=(const CompanyInfo& info);
diff --git a/chrome/browser/autofill/fax_number.h b/chrome/browser/autofill/fax_number.h
index 3fdc59e..8c2eda7 100644
--- a/chrome/browser/autofill/fax_number.h
+++ b/chrome/browser/autofill/fax_number.h
@@ -13,7 +13,7 @@ class FormGroup;
class FaxNumber : public PhoneNumber {
public:
FaxNumber();
- explicit FaxNumber(const FaxNumber& fax);
+ FaxNumber(const FaxNumber& fax);
virtual ~FaxNumber();
FaxNumber& operator=(const FaxNumber& fax);
diff --git a/chrome/browser/autofill/home_phone_number.h b/chrome/browser/autofill/home_phone_number.h
index a9e0d145..8c3a10b 100644
--- a/chrome/browser/autofill/home_phone_number.h
+++ b/chrome/browser/autofill/home_phone_number.h
@@ -13,7 +13,7 @@ class FormGroup;
class HomePhoneNumber : public PhoneNumber {
public:
HomePhoneNumber();
- explicit HomePhoneNumber(const HomePhoneNumber& phone);
+ HomePhoneNumber(const HomePhoneNumber& phone);
virtual ~HomePhoneNumber();
HomePhoneNumber& operator=(const HomePhoneNumber& phone);