Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / components / autofill / core / browser / autofill_profile_unittest.cc
index 1da7d58..30e74bc 100644 (file)
@@ -3,20 +3,23 @@
 // found in the LICENSE file.
 
 #include "base/basictypes.h"
+#include "base/format_macros.h"
 #include "base/guid.h"
 #include "base/memory/scoped_ptr.h"
 #include "base/memory/scoped_vector.h"
 #include "base/stl_util.h"
 #include "base/strings/string16.h"
+#include "base/strings/stringprintf.h"
 #include "base/strings/utf_string_conversions.h"
 #include "components/autofill/core/browser/autofill_profile.h"
 #include "components/autofill/core/browser/autofill_test_utils.h"
 #include "components/autofill/core/browser/autofill_type.h"
+#include "components/autofill/core/browser/field_types.h"
 #include "components/autofill/core/common/form_field_data.h"
-#include "grit/component_strings.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 using base::ASCIIToUTF16;
+using base::UTF8ToUTF16;
 
 namespace autofill {
 
@@ -26,10 +29,57 @@ base::string16 GetLabel(AutofillProfile* profile) {
   std::vector<AutofillProfile*> profiles;
   profiles.push_back(profile);
   std::vector<base::string16> labels;
-  AutofillProfile::CreateDifferentiatingLabels(profiles, &labels);
+  AutofillProfile::CreateDifferentiatingLabels(profiles, "en-US", &labels);
   return labels[0];
 }
 
+// Holds the autofill profile |first|, |middle| and |last| names.
+struct NameParts {
+  NameParts(const std::string& first,
+            const std::string& middle,
+            const std::string& last)
+      : first(first), middle(middle), last(last) {}
+
+  std::string first;
+  std::string middle;
+  std::string last;
+};
+
+// Test case to be executed to validate OverwriteOrAppendNames.
+struct TestCase {
+  TestCase(const NameParts& starting_name,
+           const NameParts& additional_name,
+           const NameParts& expected_result)
+      : starting_names(std::vector<NameParts>(1, starting_name)),
+        additional_names(std::vector<NameParts>(1, additional_name)),
+        expected_result(std::vector<NameParts>(1, expected_result)) {}
+
+  TestCase(const std::vector<NameParts>& starting_names,
+           const std::vector<NameParts>& additional_names,
+           const std::vector<NameParts>& expected_result)
+      : starting_names(starting_names),
+        additional_names(additional_names),
+        expected_result(expected_result) {}
+
+  std::vector<NameParts> starting_names;
+  std::vector<NameParts> additional_names;
+  std::vector<NameParts> expected_result;
+};
+
+// Populates |first_names|, |middle_names| and |last_names| from the list of
+// NameParts from |starting_names|, |additional_names| or |expected_result|
+// from the testcase to create and verify the autofill profile.
+void GetNamePartsList(const std::vector<NameParts>& names,
+                      std::vector<base::string16>* first_names,
+                      std::vector<base::string16>* middle_names,
+                      std::vector<base::string16>* last_names) {
+  for (size_t i = 0; i < names.size(); ++i) {
+    first_names->push_back(ASCIIToUTF16(names[i].first));
+    middle_names->push_back(ASCIIToUTF16(names[i].middle));
+    last_names->push_back(ASCIIToUTF16(names[i].last));
+  }
+}
+
 }  // namespace
 
 // Tests different possibilities for summary string generation.
@@ -126,7 +176,7 @@ TEST(AutofillProfileTest, PreviewSummaryString) {
   profiles.push_back(&profile7);
   profiles.push_back(&profile7a);
   std::vector<base::string16> labels;
-  AutofillProfile::CreateDifferentiatingLabels(profiles, &labels);
+  AutofillProfile::CreateDifferentiatingLabels(profiles, "en-US", &labels);
   ASSERT_EQ(profiles.size(), labels.size());
   summary7 = labels[0];
   base::string16 summary7a = labels[1];
@@ -169,7 +219,8 @@ TEST(AutofillProfileTest, AdjustInferredLabels) {
       "US",
       "12345678910");
   std::vector<base::string16> labels;
-  AutofillProfile::CreateDifferentiatingLabels(profiles.get(), &labels);
+  AutofillProfile::CreateDifferentiatingLabels(
+      profiles.get(), "en-US", &labels);
   ASSERT_EQ(2U, labels.size());
   EXPECT_EQ(ASCIIToUTF16("John Doe, 666 Erebus St."), labels[0]);
   EXPECT_EQ(ASCIIToUTF16("Jane Doe, 123 Letha Shore."), labels[1]);
@@ -190,7 +241,8 @@ TEST(AutofillProfileTest, AdjustInferredLabels) {
       "US",
       "16502111111");
   labels.clear();
-  AutofillProfile::CreateDifferentiatingLabels(profiles.get(), &labels);
+  AutofillProfile::CreateDifferentiatingLabels(
+      profiles.get(), "en-US", &labels);
 
   // Profile 0 and 2 inferred label now includes an e-mail.
   ASSERT_EQ(3U, labels.size());
@@ -219,7 +271,8 @@ TEST(AutofillProfileTest, AdjustInferredLabels) {
       "16502111111");
 
   labels.clear();
-  AutofillProfile::CreateDifferentiatingLabels(profiles.get(), &labels);
+  AutofillProfile::CreateDifferentiatingLabels(
+      profiles.get(), "en-US", &labels);
 
   // Profile 0 and 2 inferred label now includes a state.
   ASSERT_EQ(3U, labels.size());
@@ -244,7 +297,8 @@ TEST(AutofillProfileTest, AdjustInferredLabels) {
       "16504444444");  // Phone is different for some.
 
   labels.clear();
-  AutofillProfile::CreateDifferentiatingLabels(profiles.get(), &labels);
+  AutofillProfile::CreateDifferentiatingLabels(
+      profiles.get(), "en-US", &labels);
   ASSERT_EQ(4U, labels.size());
   EXPECT_EQ(ASCIIToUTF16("John Doe, 666 Erebus St., CA"), labels[0]);
   EXPECT_EQ(ASCIIToUTF16("Jane Doe, 123 Letha Shore."), labels[1]);
@@ -272,7 +326,8 @@ TEST(AutofillProfileTest, AdjustInferredLabels) {
       "16504444444");  // Phone is different for some.
 
   labels.clear();
-  AutofillProfile::CreateDifferentiatingLabels(profiles.get(), &labels);
+  AutofillProfile::CreateDifferentiatingLabels(
+      profiles.get(), "en-US", &labels);
   ASSERT_EQ(5U, labels.size());
   EXPECT_EQ(ASCIIToUTF16("John Doe, 666 Erebus St., CA"), labels[0]);
   EXPECT_EQ(ASCIIToUTF16("Jane Doe, 123 Letha Shore."), labels[1]);
@@ -286,6 +341,236 @@ TEST(AutofillProfileTest, AdjustInferredLabels) {
             labels[4]);
 }
 
+TEST(AutofillProfileTest, CreateInferredLabelsI18n_CH) {
+  ScopedVector<AutofillProfile> profiles;
+  profiles.push_back(
+      new AutofillProfile(base::GenerateGUID(), "https://www.example.com/"));
+  test::SetProfileInfo(profiles.back(),
+                       "H.",
+                       "R.",
+                       "Giger",
+                       "hrgiger@beispiel.com",
+                       "Beispiel Inc",
+                       "Brandschenkestrasse 110",
+                       "",
+                       "Zurich", "",
+                       "8002",
+                       "CH",
+                       "+41 44-668-1800");
+  profiles.back()->set_language_code("de_CH");
+  static const char* kExpectedLabels[] = {
+    "",
+    "H. R. Giger",
+    "H. R. Giger, Brandschenkestrasse 110",
+    "H. R. Giger, Brandschenkestrasse 110, Zurich",
+    "H. R. Giger, Brandschenkestrasse 110, CH-8002 Zurich",
+    "Beispiel Inc, H. R. Giger, Brandschenkestrasse 110, CH-8002 Zurich",
+    "Beispiel Inc, H. R. Giger, Brandschenkestrasse 110, CH-8002 Zurich, "
+        "Switzerland",
+    "Beispiel Inc, H. R. Giger, Brandschenkestrasse 110, CH-8002 Zurich, "
+        "Switzerland, hrgiger@beispiel.com",
+    "Beispiel Inc, H. R. Giger, Brandschenkestrasse 110, CH-8002 Zurich, "
+        "Switzerland, hrgiger@beispiel.com, +41446681800",
+  };
+
+  std::vector<base::string16> labels;
+  for (size_t i = 0; i < arraysize(kExpectedLabels); ++i) {
+    AutofillProfile::CreateInferredLabels(
+        profiles.get(), NULL, UNKNOWN_TYPE, i, "en-US", &labels);
+    ASSERT_FALSE(labels.empty());
+    EXPECT_EQ(UTF8ToUTF16(kExpectedLabels[i]), labels.back());
+  }
+}
+
+
+TEST(AutofillProfileTest, CreateInferredLabelsI18n_FR) {
+  ScopedVector<AutofillProfile> profiles;
+  profiles.push_back(
+      new AutofillProfile(base::GenerateGUID(), "https://www.example.com/"));
+  test::SetProfileInfo(profiles.back(),
+                       "Antoine",
+                       "",
+                       "de Saint-Exupéry",
+                       "antoine@exemple.com",
+                       "Exemple Inc",
+                       "8 Rue de Londres",
+                       "",
+                       "Paris", "",
+                       "75009",
+                       "FR",
+                       "+33 (0) 1 42 68 53 00");
+  profiles.back()->set_language_code("fr_FR");
+  profiles.back()->SetInfo(
+      AutofillType(ADDRESS_HOME_SORTING_CODE), UTF8ToUTF16("CEDEX"), "en-US");
+  static const char* kExpectedLabels[] = {
+      "",
+      "Antoine de Saint-Exupéry",
+      "Antoine de Saint-Exupéry, 8 Rue de Londres",
+      "Antoine de Saint-Exupéry, 8 Rue de Londres, Paris",
+      "Antoine de Saint-Exupéry, 8 Rue de Londres, 75009 Paris",
+      "Antoine de Saint-Exupéry, 8 Rue de Londres, 75009 Paris CEDEX",
+      "Exemple Inc, Antoine de Saint-Exupéry, 8 Rue de Londres, 75009 Paris "
+          "CEDEX",
+      "Exemple Inc, Antoine de Saint-Exupéry, 8 Rue de Londres, 75009 Paris "
+          "CEDEX, France",
+      "Exemple Inc, Antoine de Saint-Exupéry, 8 Rue de Londres, 75009 Paris "
+          "CEDEX, France, antoine@exemple.com",
+      "Exemple Inc, Antoine de Saint-Exupéry, 8 Rue de Londres, 75009 Paris "
+          "CEDEX, France, antoine@exemple.com, +33142685300",
+      "Exemple Inc, Antoine de Saint-Exupéry, 8 Rue de Londres, 75009 Paris "
+          "CEDEX, France, antoine@exemple.com, +33142685300",
+  };
+
+  std::vector<base::string16> labels;
+  for (size_t i = 0; i < arraysize(kExpectedLabels); ++i) {
+    AutofillProfile::CreateInferredLabels(
+        profiles.get(), NULL, UNKNOWN_TYPE, i, "en-US", &labels);
+    ASSERT_FALSE(labels.empty());
+    EXPECT_EQ(UTF8ToUTF16(kExpectedLabels[i]), labels.back());
+  }
+}
+
+TEST(AutofillProfileTest, CreateInferredLabelsI18n_KR) {
+  ScopedVector<AutofillProfile> profiles;
+  profiles.push_back(
+      new AutofillProfile(base::GenerateGUID(), "https://www.example.com/"));
+  test::SetProfileInfo(profiles.back(),
+                       "Park",
+                       "",
+                       "Jae-sang",
+                       "park@yeleul.com",
+                       "Yeleul Inc",
+                       "Gangnam Finance Center",
+                       "152 Teheran-ro",
+                       "Gangnam-Gu", "Seoul",
+                       "135-984",
+                       "KR",
+                       "+82-2-531-9000");
+  profiles.back()->set_language_code("ko_Latn");
+  profiles.back()->SetInfo(AutofillType(ADDRESS_HOME_DEPENDENT_LOCALITY),
+                           UTF8ToUTF16("Yeoksam-Dong"),
+                           "en-US");
+  static const char* kExpectedLabels[] = {
+      "",
+      "Park Jae-sang",
+      "Park Jae-sang, Gangnam Finance Center",
+      "Park Jae-sang, Gangnam Finance Center, 152 Teheran-ro",
+      "Park Jae-sang, Gangnam Finance Center, 152 Teheran-ro, Yeoksam-Dong",
+      "Park Jae-sang, Gangnam Finance Center, 152 Teheran-ro, Yeoksam-Dong, "
+          "Gangnam-Gu",
+      "Park Jae-sang, Gangnam Finance Center, 152 Teheran-ro, Yeoksam-Dong, "
+          "Gangnam-Gu, Seoul",
+      "Park Jae-sang, Gangnam Finance Center, 152 Teheran-ro, Yeoksam-Dong, "
+          "Gangnam-Gu, Seoul, 135-984",
+      "Park Jae-sang, Yeleul Inc, Gangnam Finance Center, 152 Teheran-ro, "
+          "Yeoksam-Dong, Gangnam-Gu, Seoul, 135-984",
+      "Park Jae-sang, Yeleul Inc, Gangnam Finance Center, 152 Teheran-ro, "
+          "Yeoksam-Dong, Gangnam-Gu, Seoul, 135-984, South Korea",
+      "Park Jae-sang, Yeleul Inc, Gangnam Finance Center, 152 Teheran-ro, "
+          "Yeoksam-Dong, Gangnam-Gu, Seoul, 135-984, South Korea, "
+          "park@yeleul.com",
+      "Park Jae-sang, Yeleul Inc, Gangnam Finance Center, 152 Teheran-ro, "
+          "Yeoksam-Dong, Gangnam-Gu, Seoul, 135-984, South Korea, "
+          "park@yeleul.com, +8225319000",
+  };
+
+  std::vector<base::string16> labels;
+  for (size_t i = 0; i < arraysize(kExpectedLabels); ++i) {
+    AutofillProfile::CreateInferredLabels(
+        profiles.get(), NULL, UNKNOWN_TYPE, i, "en-US", &labels);
+    ASSERT_FALSE(labels.empty());
+    EXPECT_EQ(UTF8ToUTF16(kExpectedLabels[i]), labels.back());
+  }
+}
+
+TEST(AutofillProfileTest, CreateInferredLabelsI18n_JP_Latn) {
+  ScopedVector<AutofillProfile> profiles;
+  profiles.push_back(
+      new AutofillProfile(base::GenerateGUID(), "https://www.example.com/"));
+  test::SetProfileInfo(profiles.back(),
+                       "Miku",
+                       "",
+                       "Hatsune",
+                       "miku@rei.com",
+                       "Rei Inc",
+                       "Roppongi Hills Mori Tower",
+                       "6-10-1 Roppongi",
+                       "Minato-ku", "Tokyo",
+                       "106-6126",
+                       "JP",
+                       "+81-3-6384-9000");
+  profiles.back()->set_language_code("ja_Latn");
+  static const char* kExpectedLabels[] = {
+    "",
+    "Miku Hatsune",
+    "Miku Hatsune, Roppongi Hills Mori Tower",
+    "Miku Hatsune, Roppongi Hills Mori Tower, 6-10-1 Roppongi",
+    "Miku Hatsune, Roppongi Hills Mori Tower, 6-10-1 Roppongi, Minato-ku",
+    "Miku Hatsune, Roppongi Hills Mori Tower, 6-10-1 Roppongi, Minato-ku, "
+        "Tokyo",
+    "Miku Hatsune, Roppongi Hills Mori Tower, 6-10-1 Roppongi, Minato-ku, "
+        "Tokyo, 106-6126",
+    "Miku Hatsune, Rei Inc, Roppongi Hills Mori Tower, 6-10-1 Roppongi, "
+        "Minato-ku, Tokyo, 106-6126",
+    "Miku Hatsune, Rei Inc, Roppongi Hills Mori Tower, 6-10-1 Roppongi, "
+        "Minato-ku, Tokyo, 106-6126, Japan",
+    "Miku Hatsune, Rei Inc, Roppongi Hills Mori Tower, 6-10-1 Roppongi, "
+        "Minato-ku, Tokyo, 106-6126, Japan, miku@rei.com",
+    "Miku Hatsune, Rei Inc, Roppongi Hills Mori Tower, 6-10-1 Roppongi, "
+        "Minato-ku, Tokyo, 106-6126, Japan, miku@rei.com, +81363849000",
+  };
+
+  std::vector<base::string16> labels;
+  for (size_t i = 0; i < arraysize(kExpectedLabels); ++i) {
+    AutofillProfile::CreateInferredLabels(
+        profiles.get(), NULL, UNKNOWN_TYPE, i, "en-US", &labels);
+    ASSERT_FALSE(labels.empty());
+    EXPECT_EQ(UTF8ToUTF16(kExpectedLabels[i]), labels.back());
+  }
+}
+
+TEST(AutofillProfileTest, CreateInferredLabelsI18n_JP_ja) {
+  ScopedVector<AutofillProfile> profiles;
+  profiles.push_back(
+      new AutofillProfile(base::GenerateGUID(), "https://www.example.com/"));
+  test::SetProfileInfo(profiles.back(),
+                       "ミク",
+                       "",
+                       "初音",
+                       "miku@rei.com",
+                       "例",
+                       "六本木ヒルズ森タワー",
+                       "六本木 6-10-1",
+                       "港区", "東京都",
+                       "106-6126",
+                       "JP",
+                       "03-6384-9000");
+  profiles.back()->set_language_code("ja_JP");
+  static const char* kExpectedLabels[] = {
+    "",
+    "ミク 初音",
+    "六本木ヒルズ森タワーミク 初音",
+    "六本木ヒルズ森タワー六本木 6-10-1ミク 初音",
+    "港区六本木ヒルズ森タワー六本木 6-10-1ミク 初音",
+    "東京都港区六本木ヒルズ森タワー六本木 6-10-1ミク 初音",
+    "〒106-6126東京都港区六本木ヒルズ森タワー六本木 6-10-1ミク 初音",
+    "〒106-6126東京都港区六本木ヒルズ森タワー六本木 6-10-1例ミク 初音",
+    "〒106-6126東京都港区六本木ヒルズ森タワー六本木 6-10-1例ミク 初音, Japan",
+    "〒106-6126東京都港区六本木ヒルズ森タワー六本木 6-10-1例ミク 初音, Japan, "
+        "miku@rei.com",
+    "〒106-6126東京都港区六本木ヒルズ森タワー六本木 6-10-1例ミク 初音, Japan, "
+        "miku@rei.com, 0363849000",
+  };
+
+  std::vector<base::string16> labels;
+  for (size_t i = 0; i < arraysize(kExpectedLabels); ++i) {
+    AutofillProfile::CreateInferredLabels(
+        profiles.get(), NULL, UNKNOWN_TYPE, i, "en-US", &labels);
+    ASSERT_FALSE(labels.empty());
+    EXPECT_EQ(UTF8ToUTF16(kExpectedLabels[i]), labels.back());
+  }
+}
+
 TEST(AutofillProfileTest, CreateInferredLabels) {
   ScopedVector<AutofillProfile> profiles;
   profiles.push_back(
@@ -319,13 +604,13 @@ TEST(AutofillProfileTest, CreateInferredLabels) {
   std::vector<base::string16> labels;
   // Two fields at least - no filter.
   AutofillProfile::CreateInferredLabels(profiles.get(), NULL, UNKNOWN_TYPE, 2,
-                                        &labels);
+                                        "en-US", &labels);
   EXPECT_EQ(ASCIIToUTF16("John Doe, 666 Erebus St."), labels[0]);
   EXPECT_EQ(ASCIIToUTF16("Jane Doe, 123 Letha Shore."), labels[1]);
 
   // Three fields at least - no filter.
   AutofillProfile::CreateInferredLabels(profiles.get(), NULL, UNKNOWN_TYPE, 3,
-                                        &labels);
+                                        "en-US", &labels);
   EXPECT_EQ(ASCIIToUTF16("John Doe, 666 Erebus St., Elysium"),
             labels[0]);
   EXPECT_EQ(ASCIIToUTF16("Jane Doe, 123 Letha Shore., Dis"),
@@ -338,36 +623,37 @@ TEST(AutofillProfileTest, CreateInferredLabels) {
 
   // Two fields at least, from suggested fields - no filter.
   AutofillProfile::CreateInferredLabels(profiles.get(), &suggested_fields,
-                                        UNKNOWN_TYPE, 2, &labels);
+                                        UNKNOWN_TYPE, 2, "en-US", &labels);
   EXPECT_EQ(ASCIIToUTF16("Elysium, CA"), labels[0]);
   EXPECT_EQ(ASCIIToUTF16("Dis, CA"), labels[1]);
 
   // Three fields at least, from suggested fields - no filter.
   AutofillProfile::CreateInferredLabels(profiles.get(), &suggested_fields,
-                                        UNKNOWN_TYPE, 3, &labels);
-  EXPECT_EQ(ASCIIToUTF16("Elysium, CA, 91111"), labels[0]);
-  EXPECT_EQ(ASCIIToUTF16("Dis, CA, 91222"), labels[1]);
+                                        UNKNOWN_TYPE, 3, "en-US", &labels);
+  EXPECT_EQ(ASCIIToUTF16("Elysium, CA 91111"), labels[0]);
+  EXPECT_EQ(ASCIIToUTF16("Dis, CA 91222"), labels[1]);
 
   // Three fields at least, from suggested fields - but filter reduces available
   // fields to two.
   AutofillProfile::CreateInferredLabels(profiles.get(), &suggested_fields,
-                                        ADDRESS_HOME_STATE, 3, &labels);
-  EXPECT_EQ(ASCIIToUTF16("Elysium, 91111"), labels[0]);
-  EXPECT_EQ(ASCIIToUTF16("Dis, 91222"), labels[1]);
+                                        ADDRESS_HOME_STATE, 3, "en-US",
+                                        &labels);
+  EXPECT_EQ(ASCIIToUTF16("Elysium 91111"), labels[0]);
+  EXPECT_EQ(ASCIIToUTF16("Dis 91222"), labels[1]);
 
   suggested_fields.clear();
   // In our implementation we always display NAME_FULL for all NAME* fields...
   suggested_fields.push_back(NAME_MIDDLE);
   // One field at least, from suggested fields - no filter.
   AutofillProfile::CreateInferredLabels(profiles.get(), &suggested_fields,
-                                        UNKNOWN_TYPE, 1, &labels);
+                                        UNKNOWN_TYPE, 1, "en-US", &labels);
   EXPECT_EQ(ASCIIToUTF16("John Doe"), labels[0]);
   EXPECT_EQ(ASCIIToUTF16("Jane Doe"), labels[1]);
 
   // One field at least, from suggested fields - filter the same as suggested
   // field.
   AutofillProfile::CreateInferredLabels(profiles.get(), &suggested_fields,
-                                        NAME_MIDDLE, 1, &labels);
+                                        NAME_MIDDLE, 1, "en-US", &labels);
   EXPECT_EQ(base::string16(), labels[0]);
   EXPECT_EQ(base::string16(), labels[1]);
 
@@ -376,7 +662,7 @@ TEST(AutofillProfileTest, CreateInferredLabels) {
   suggested_fields.push_back(NAME_MIDDLE_INITIAL);
   // One field at least, from suggested fields - no filter.
   AutofillProfile::CreateInferredLabels(profiles.get(), &suggested_fields,
-                                        UNKNOWN_TYPE, 1, &labels);
+                                        UNKNOWN_TYPE, 1, "en-US", &labels);
   EXPECT_EQ(ASCIIToUTF16("John Doe"), labels[0]);
   EXPECT_EQ(ASCIIToUTF16("Jane Doe"), labels[1]);
 
@@ -387,7 +673,13 @@ TEST(AutofillProfileTest, CreateInferredLabels) {
   suggested_fields.push_back(NAME_FULL);
   suggested_fields.push_back(ADDRESS_HOME_LINE1);
   AutofillProfile::CreateInferredLabels(profiles.get(), &suggested_fields,
-                                        NAME_FULL, 1, &labels);
+                                        NAME_FULL, 1, "en-US", &labels);
+  EXPECT_EQ(base::string16(ASCIIToUTF16("666 Erebus St.")), labels[0]);
+  EXPECT_EQ(base::string16(ASCIIToUTF16("123 Letha Shore.")), labels[1]);
+
+  // No suggested fields, but non-unknown excluded field.
+  AutofillProfile::CreateInferredLabels(profiles.get(), NULL,
+                                        NAME_FULL, 1, "en-US", &labels);
   EXPECT_EQ(base::string16(ASCIIToUTF16("666 Erebus St.")), labels[0]);
   EXPECT_EQ(base::string16(ASCIIToUTF16("123 Letha Shore.")), labels[1]);
 }
@@ -415,7 +707,7 @@ TEST(AutofillProfileTest, CreateInferredLabelsFallsBackToFullName) {
   suggested_fields.push_back(EMAIL_ADDRESS);
   std::vector<base::string16> labels;
   AutofillProfile::CreateInferredLabels(profiles.get(), &suggested_fields,
-                                        NAME_LAST, 1, &labels);
+                                        NAME_LAST, 1, "en-US", &labels);
   ASSERT_EQ(2U, labels.size());
   EXPECT_EQ(ASCIIToUTF16("88 Nowhere Ave."), labels[0]);
   EXPECT_EQ(ASCIIToUTF16("88 Nowhere Ave."), labels[1]);
@@ -423,7 +715,7 @@ TEST(AutofillProfileTest, CreateInferredLabelsFallsBackToFullName) {
   // Otherwise, we should.
   suggested_fields.push_back(NAME_FIRST);
   AutofillProfile::CreateInferredLabels(profiles.get(),  &suggested_fields,
-                                        NAME_LAST, 1, &labels);
+                                        NAME_LAST, 1, "en-US", &labels);
   ASSERT_EQ(2U, labels.size());
   EXPECT_EQ(ASCIIToUTF16("88 Nowhere Ave., John Doe"), labels[0]);
   EXPECT_EQ(ASCIIToUTF16("88 Nowhere Ave., Johnny K Doe"), labels[1]);
@@ -451,7 +743,7 @@ TEST(AutofillProfileTest, CreateInferredLabelsNoDuplicatedFields) {
   suggested_fields.push_back(EMAIL_ADDRESS);
   std::vector<base::string16> labels;
   AutofillProfile::CreateInferredLabels(profiles.get(), &suggested_fields,
-                                        UNKNOWN_TYPE, 2, &labels);
+                                        UNKNOWN_TYPE, 2, "en-US", &labels);
   ASSERT_EQ(2U, labels.size());
   EXPECT_EQ(ASCIIToUTF16("88 Nowhere Ave., doe@example.com"), labels[0]);
   EXPECT_EQ(ASCIIToUTF16("88 Nowhere Ave., dojo@example.com"), labels[1]);
@@ -478,7 +770,7 @@ TEST(AutofillProfileTest, CreateInferredLabelsSkipsEmptyFields) {
 
   std::vector<base::string16> labels;
   AutofillProfile::CreateInferredLabels(profiles.get(), NULL, UNKNOWN_TYPE, 3,
-                                        &labels);
+                                        "en-US", &labels);
   ASSERT_EQ(3U, labels.size());
   EXPECT_EQ(ASCIIToUTF16("John Doe, doe@example.com, Gogole"), labels[0]);
   EXPECT_EQ(ASCIIToUTF16("John Doe, doe@example.com, Ggoole"), labels[1]);
@@ -488,7 +780,7 @@ TEST(AutofillProfileTest, CreateInferredLabelsSkipsEmptyFields) {
   // distinguishing field.
   profiles[1]->SetRawInfo(ADDRESS_HOME_LINE1, ASCIIToUTF16("88 Nowhere Ave."));
   AutofillProfile::CreateInferredLabels(profiles.get(), NULL, UNKNOWN_TYPE, 1,
-                                        &labels);
+                                        "en-US", &labels);
   ASSERT_EQ(3U, labels.size());
   EXPECT_EQ(ASCIIToUTF16("John Doe, doe@example.com, Gogole"), labels[0]);
   EXPECT_EQ(ASCIIToUTF16("John Doe, 88 Nowhere Ave., doe@example.com, Ggoole"),
@@ -512,7 +804,7 @@ TEST(AutofillProfileTest, CreateInferredLabelsFlattensMultiLineValues) {
   suggested_fields.push_back(ADDRESS_HOME_STREET_ADDRESS);
   std::vector<base::string16> labels;
   AutofillProfile::CreateInferredLabels(profiles.get(), &suggested_fields,
-                                        NAME_FULL, 1, &labels);
+                                        NAME_FULL, 1, "en-US", &labels);
   ASSERT_EQ(1U, labels.size());
   EXPECT_EQ(ASCIIToUTF16("88 Nowhere Ave., Apt. 42"), labels[0]);
 }
@@ -559,34 +851,44 @@ TEST(AutofillProfileTest, OverwriteWithOrAddTo) {
                        "marion@me.xyz", "Fox", "123 Zoo St.", "unit 5",
                        "Hollywood", "CA", "91601", "US",
                        "12345678910");
-  std::vector<base::string16> names;
-  a.GetRawMultiInfo(NAME_FULL, &names);
-  names.push_back(ASCIIToUTF16("Marion Morrison"));
-  a.SetRawMultiInfo(NAME_FULL, names);
+  std::vector<base::string16> first_names;
+  a.GetRawMultiInfo(NAME_FIRST, &first_names);
+  first_names.push_back(ASCIIToUTF16("Marion"));
+  a.SetRawMultiInfo(NAME_FIRST, first_names);
+
+  std::vector<base::string16> last_names;
+  a.GetRawMultiInfo(NAME_LAST, &last_names);
+  last_names[last_names.size() - 1] = ASCIIToUTF16("Morrison");
+  a.SetRawMultiInfo(NAME_LAST, last_names);
 
   // Create an identical profile except that the new profile:
   //   (1) Has a different origin,
   //   (2) Has a different address line 2,
-  //   (3) Lacks a company name, and
-  //   (4) Has a different full name variant.
+  //   (3) Lacks a company name,
+  //   (4) Has a different full name variant, and
+  //   (5) Has a language code.
   AutofillProfile b = a;
   b.set_guid(base::GenerateGUID());
   b.set_origin("Chrome settings");
   b.SetRawInfo(ADDRESS_HOME_LINE2, ASCIIToUTF16("area 51"));
   b.SetRawInfo(COMPANY_NAME, base::string16());
-  b.GetRawMultiInfo(NAME_FULL, &names);
+
+  std::vector<base::string16> names;
+  b.GetMultiInfo(AutofillType(NAME_FULL), "en-US", &names);
   names.push_back(ASCIIToUTF16("Marion M. Morrison"));
   b.SetRawMultiInfo(NAME_FULL, names);
+  b.set_language_code("en");
 
   a.OverwriteWithOrAddTo(b, "en-US");
   EXPECT_EQ("Chrome settings", a.origin());
   EXPECT_EQ(ASCIIToUTF16("area 51"), a.GetRawInfo(ADDRESS_HOME_LINE2));
   EXPECT_EQ(ASCIIToUTF16("Fox"), a.GetRawInfo(COMPANY_NAME));
-  a.GetRawMultiInfo(NAME_FULL, &names);
+  a.GetMultiInfo(AutofillType(NAME_FULL), "en-US", &names);
   ASSERT_EQ(3U, names.size());
   EXPECT_EQ(ASCIIToUTF16("Marion Mitchell Morrison"), names[0]);
   EXPECT_EQ(ASCIIToUTF16("Marion Morrison"), names[1]);
   EXPECT_EQ(ASCIIToUTF16("Marion M. Morrison"), names[2]);
+  EXPECT_EQ("en", a.language_code());
 }
 
 TEST(AutofillProfileTest, AssignmentOperator) {
@@ -606,6 +908,26 @@ TEST(AutofillProfileTest, AssignmentOperator) {
   EXPECT_TRUE(a == b);
 }
 
+TEST(AutofillProfileTest, SetMultiInfo) {
+  std::vector<base::string16> full_names;
+  full_names.push_back(ASCIIToUTF16("John Davis"));
+  full_names.push_back(ASCIIToUTF16("Elouise Davis"));
+  AutofillProfile p;
+  p.SetMultiInfo(AutofillType(NAME_FULL), full_names, "en-US");
+
+  std::vector<base::string16> first_names;
+  p.GetMultiInfo(AutofillType(NAME_FIRST), "en-US", &first_names);
+  ASSERT_EQ(2U, first_names.size());
+  EXPECT_EQ(ASCIIToUTF16("John"), first_names[0]);
+  EXPECT_EQ(ASCIIToUTF16("Elouise"), first_names[1]);
+
+  std::vector<base::string16> last_names;
+  p.GetMultiInfo(AutofillType(NAME_LAST), "en-US", &last_names);
+  ASSERT_EQ(2U, last_names.size());
+  EXPECT_EQ(ASCIIToUTF16("Davis"), last_names[0]);
+  EXPECT_EQ(ASCIIToUTF16("Davis"), last_names[1]);
+}
+
 TEST(AutofillProfileTest, Copy) {
   AutofillProfile a(base::GenerateGUID(), "https://www.example.com/");
   test::SetProfileInfo(&a, "Marion", "Mitchell", "Morrison",
@@ -651,6 +973,18 @@ TEST(AutofillProfileTest, Compare) {
       NULL, NULL, NULL, NULL, NULL, NULL, NULL, "408.555.4321");
   EXPECT_GT(0, a.Compare(b));
   EXPECT_LT(0, b.Compare(a));
+
+  // Addresses are compared in full. Regression test for http://crbug.com/375545
+  test::SetProfileInfo(&a, "John", NULL, NULL, NULL,
+      NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
+  a.SetRawInfo(ADDRESS_HOME_STREET_ADDRESS,
+               ASCIIToUTF16("line one\nline two"));
+  test::SetProfileInfo(&b, "John", NULL, NULL, NULL,
+      NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
+  b.SetRawInfo(ADDRESS_HOME_STREET_ADDRESS,
+               ASCIIToUTF16("line one\nline two\nline three"));
+  EXPECT_GT(0, a.Compare(b));
+  EXPECT_LT(0, b.Compare(a));
 }
 
 TEST(AutofillProfileTest, MultiValueNames) {
@@ -850,4 +1184,200 @@ TEST(AutofillProfileTest, SetInfoTrimsWhitespace) {
             profile.GetRawInfo(EMAIL_ADDRESS));
 }
 
+TEST(AutofillProfileTest, FullAddress) {
+  AutofillProfile profile(base::GenerateGUID(), "https://www.example.com/");
+  test::SetProfileInfo(&profile, "Marion", "Mitchell", "Morrison",
+                       "marion@me.xyz", "Fox", "123 Zoo St.", "unit 5",
+                       "Hollywood", "CA", "91601", "US",
+                       "12345678910");
+
+  AutofillType full_address(HTML_TYPE_FULL_ADDRESS, HTML_MODE_NONE);
+  base::string16 formatted_address(ASCIIToUTF16(
+      "Marion Mitchell Morrison\n"
+      "Fox\n"
+      "123 Zoo St.\n"
+      "unit 5\n"
+      "Hollywood, CA 91601"));
+  EXPECT_EQ(formatted_address, profile.GetInfo(full_address, "en-US"));
+  // This should fail and leave the profile unchanged.
+  EXPECT_FALSE(profile.SetInfo(full_address, ASCIIToUTF16("foobar"), "en-US"));
+  EXPECT_EQ(formatted_address, profile.GetInfo(full_address, "en-US"));
+
+  // Some things can be missing...
+  profile.SetInfo(AutofillType(ADDRESS_HOME_LINE2),
+                  base::string16(),
+                  "en-US");
+  profile.SetInfo(AutofillType(EMAIL_ADDRESS),
+                  base::string16(),
+                  "en-US");
+  EXPECT_EQ(ASCIIToUTF16("Marion Mitchell Morrison\n"
+                         "Fox\n"
+                         "123 Zoo St.\n"
+                         "Hollywood, CA 91601"),
+            profile.GetInfo(full_address, "en-US"));
+
+  // ...but nothing comes out if a required field is missing.
+  profile.SetInfo(AutofillType(ADDRESS_HOME_STATE), base::string16(), "en-US");
+  EXPECT_TRUE(profile.GetInfo(full_address, "en-US").empty());
+
+  // Restore the state but remove country. This should also fail.
+  profile.SetInfo(AutofillType(ADDRESS_HOME_STATE),
+                               ASCIIToUTF16("CA"),
+                               "en-US");
+  EXPECT_FALSE(profile.GetInfo(full_address, "en-US").empty());
+  profile.SetInfo(AutofillType(ADDRESS_HOME_COUNTRY),
+                               base::string16(),
+                               "en-US");
+  EXPECT_TRUE(profile.GetInfo(full_address, "en-US").empty());
+}
+
+TEST(AutofillProfileTest, OverwriteOrAppendNames) {
+  std::vector<TestCase> test_cases;
+
+  // Identical name.
+  test_cases.push_back(TestCase(NameParts("Marion", "Mitchell", "Morrison"),
+                                NameParts("Marion", "Mitchell", "Morrison"),
+                                NameParts("Marion", "Mitchell", "Morrison")));
+  test_cases.push_back(TestCase(NameParts("Marion", "Mitchell", "Morrison"),
+                                NameParts("MARION", "MITCHELL", "MORRISON"),
+                                NameParts("Marion", "Mitchell", "Morrison")));
+
+  // A parse that has a two-word last name should take precedence over a
+  // parse that assumes the two names are a middle and a last name.
+  test_cases.push_back(TestCase(NameParts("Marion", "Mitchell", "Morrison"),
+                                NameParts("Marion", "", "Mitchell Morrison"),
+                                NameParts("Marion", "", "Mitchell Morrison")));
+  test_cases.push_back(TestCase(NameParts("Marion", "", "Mitchell Morrison"),
+                                NameParts("Marion", "Mitchell", "Morrison"),
+                                NameParts("Marion", "", "Mitchell Morrison")));
+
+  // A parse that has a two-word first name should take precedence over a
+  // parse that assumes the two names are a first and a middle name.
+  test_cases.push_back(TestCase(NameParts("Marion", "Mitchell", "Morrison"),
+                                NameParts("Marion Mitchell", "", "Morrison"),
+                                NameParts("Marion Mitchell", "", "Morrison")));
+  test_cases.push_back(TestCase(NameParts("Marion Mitchell", "", "Morrison"),
+                                NameParts("Marion", "Mitchell", "Morrison"),
+                                NameParts("Marion Mitchell", "", "Morrison")));
+
+  // Two names that are identical in full, but not in parts: the parse that
+  // does *not* match the heuristic parse should be preferred.
+  test_cases.push_back(
+      TestCase(NameParts("Arthur", "Ignatius Conan", "Doyle"),
+               // Heurstic parse.
+               NameParts("Arthur Ignatius", "Conan", "Doyle"),
+               NameParts("Arthur", "Ignatius Conan", "Doyle")));
+  test_cases.push_back(
+               // Heuristic parse.
+      TestCase(NameParts("Arthur Ignatius", "Conan", "Doyle"),
+               NameParts("Arthur", "Ignatius Conan", "Doyle"),
+               NameParts("Arthur", "Ignatius Conan", "Doyle")));
+
+  // A parse that has a many-word first name and/or last name should take
+  // precedence over a heuristically parsed name.
+  test_cases.push_back(
+               // Heuristic parse.
+      TestCase(NameParts("Roberto Carlos da", "Silva", "Rocha"),
+               NameParts("Roberto Carlos da Silva", "", "Rocha"),
+               NameParts("Roberto Carlos da Silva", "", "Rocha")));
+
+  // Cases where merging 2 profiles with same full names but
+  // different canonical forms appends instead of overwrites,
+  // provided they dont form heuristically parsed names.
+  {
+    NameParts name1("Marion Mitchell", "", "Morrison");
+    NameParts name2("Marion", "", "Mitchell Morrison");
+    std::vector<NameParts> starting_names(1, name1);
+    std::vector<NameParts> additional_names(1, name2);
+    std::vector<NameParts> expected_result;
+    expected_result.push_back(name1);
+    expected_result.push_back(name2);
+    test_cases.push_back(
+        TestCase(starting_names, additional_names, expected_result));
+  }
+
+  // Cases where the names do not have the same full name strings,
+  // i.e. the list of merged names is longer than either of the incoming
+  // lists.
+  {
+    NameParts name1("Antonio", "Augusto Ribeiro", "Reis Jr.");
+    NameParts name2("Juninho", "", "Pernambucano");
+    NameParts name3("Marion", "Mitchell", "Morrison");
+    NameParts name4("Marion", "M.", "Morrison");
+    std::vector<NameParts> starting_names;
+    std::vector<NameParts> additional_names;
+    std::vector<NameParts> expected_result;
+    starting_names.push_back(name1);
+    starting_names.push_back(name2);
+    additional_names.push_back(name3);
+    additional_names.push_back(name4);
+    expected_result.push_back(name1);
+    expected_result.push_back(name2);
+    expected_result.push_back(name3);
+    expected_result.push_back(name4);
+    test_cases.push_back(
+        TestCase(starting_names, additional_names, expected_result));
+  }
+
+  for (std::vector<TestCase>::iterator it = test_cases.begin();
+       it != test_cases.end();
+       ++it) {
+    TestCase current_case = *it;
+    SCOPED_TRACE(current_case.starting_names[0].first + " + " +
+                 current_case.additional_names[0].first + " = " +
+                 current_case.expected_result[0].first);
+
+    std::vector<base::string16> first_names, middle_names, last_names;
+    GetNamePartsList(
+        current_case.starting_names, &first_names, &middle_names, &last_names);
+
+    // Construct the starting_profile.
+    AutofillProfile starting_profile(base::GenerateGUID(),
+                                     "https://www.example.com/");
+
+    starting_profile.SetRawMultiInfo(NAME_FIRST, first_names);
+    starting_profile.SetRawMultiInfo(NAME_MIDDLE, middle_names);
+    starting_profile.SetRawMultiInfo(NAME_LAST, last_names);
+
+    first_names.clear();
+    middle_names.clear();
+    last_names.clear();
+    GetNamePartsList(
+        current_case.additional_names, &first_names, &middle_names,
+        &last_names);
+
+    // Construct the additional_profile.
+    AutofillProfile additional_profile(base::GenerateGUID(),
+                                       "https://www.example.com/");
+    additional_profile.SetRawMultiInfo(NAME_FIRST, first_names);
+    additional_profile.SetRawMultiInfo(NAME_MIDDLE, middle_names);
+    additional_profile.SetRawMultiInfo(NAME_LAST, last_names);
+
+    // Merge the names from the |additional_profile| into the |starting_profile|
+    starting_profile.OverwriteWithOrAddTo(additional_profile, "en-US");
+
+    // Verify the test expectations.
+    first_names.clear();
+    middle_names.clear();
+    last_names.clear();
+    GetNamePartsList(
+        current_case.expected_result, &first_names, &middle_names, &last_names);
+
+    std::vector<base::string16> merged_first_names, merged_middle_names,
+        merged_last_names;
+    starting_profile.GetRawMultiInfo(NAME_FIRST, &merged_first_names);
+    starting_profile.GetRawMultiInfo(NAME_MIDDLE, &merged_middle_names);
+    starting_profile.GetRawMultiInfo(NAME_LAST, &merged_last_names);
+    ASSERT_EQ(current_case.expected_result.size(), merged_first_names.size());
+    ASSERT_EQ(current_case.expected_result.size(), merged_middle_names.size());
+    ASSERT_EQ(current_case.expected_result.size(), merged_last_names.size());
+
+    for (size_t i = 0; i < current_case.expected_result.size(); ++i) {
+      EXPECT_EQ(first_names[i], merged_first_names[i]);
+      EXPECT_EQ(middle_names[i], merged_middle_names[i]);
+      EXPECT_EQ(last_names[i], merged_last_names[i]);
+    }
+  }
+}
+
 }  // namespace autofill