summaryrefslogtreecommitdiffstats
path: root/third_party
diff options
context:
space:
mode:
authorroubert@google.com <roubert@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2014-06-03 13:27:40 +0000
committerroubert@google.com <roubert@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2014-06-03 13:27:40 +0000
commit67f87350dba7bf3b11581ee294deea8171246f04 (patch)
treecd2c2e007e1926a87f5586e9317cad557868908b /third_party
parentd6f5dd7dfbcace4dc7fd88d989f0fdfe994c33df (diff)
downloadchromium_src-67f87350dba7bf3b11581ee294deea8171246f04.zip
chromium_src-67f87350dba7bf3b11581ee294deea8171246f04.tar.gz
chromium_src-67f87350dba7bf3b11581ee294deea8171246f04.tar.bz2
Add class PreloadAddressValidator, interface to libaddressinput.
PreloadAddressValidator implements the same interface as Chromium's current AddressValidator but calls libaddressinput AddressValidator to perform the actual work, to simplify switching Chromium Autofill over to using libaddressinput. All existing test cases are ported. The suggestions functionality is currently stubbed out. R=rouslan@chromium.org BUG= Review URL: https://codereview.chromium.org/292313008 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@274507 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'third_party')
-rw-r--r--third_party/libaddressinput/chromium/preload_address_validator.cc144
-rw-r--r--third_party/libaddressinput/chromium/preload_address_validator.h141
-rw-r--r--third_party/libaddressinput/chromium/preload_address_validator_unittest.cc612
3 files changed, 897 insertions, 0 deletions
diff --git a/third_party/libaddressinput/chromium/preload_address_validator.cc b/third_party/libaddressinput/chromium/preload_address_validator.cc
new file mode 100644
index 0000000..816e3a5
--- /dev/null
+++ b/third_party/libaddressinput/chromium/preload_address_validator.cc
@@ -0,0 +1,144 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <cstddef>
+#include <string>
+#include <vector>
+
+#include "base/basictypes.h"
+#include "base/memory/scoped_ptr.h"
+
+#define I18N_ADDRESSINPUT_UTIL_BASICTYPES_H_
+#include "third_party/libaddressinput/chromium/preload_address_validator.h"
+#include "third_party/libaddressinput/chromium/suggestions.h"
+#include "third_party/libaddressinput/src/cpp/include/libaddressinput/address_data.h"
+#include "third_party/libaddressinput/src/cpp/include/libaddressinput/address_validator.h"
+#include "third_party/libaddressinput/src/cpp/include/libaddressinput/callback.h"
+#include "third_party/libaddressinput/src/cpp/include/libaddressinput/downloader.h"
+#include "third_party/libaddressinput/src/cpp/include/libaddressinput/preload_supplier.h"
+#include "third_party/libaddressinput/src/cpp/include/libaddressinput/storage.h"
+#include "third_party/libaddressinput/src/cpp/include/libaddressinput/synonyms.h"
+
+namespace autofill {
+
+using ::i18n::addressinput::AddressData;
+using ::i18n::addressinput::AddressField;
+using ::i18n::addressinput::AddressValidator;
+using ::i18n::addressinput::BuildCallback;
+using ::i18n::addressinput::Downloader;
+using ::i18n::addressinput::FieldProblemMap;
+using ::i18n::addressinput::PreloadSupplier;
+using ::i18n::addressinput::Storage;
+using ::i18n::addressinput::Synonyms;
+
+PreloadAddressValidator::PreloadAddressValidator(
+ const std::string& validation_data_url,
+ scoped_ptr<Downloader> downloader,
+ scoped_ptr<Storage> storage)
+ : supplier_(
+ new PreloadSupplier(
+ validation_data_url,
+ downloader.release(),
+ storage.release())),
+ suggestions_(
+ new Suggestions(
+ supplier_.get())),
+ synonyms_(
+ new Synonyms(
+ supplier_.get())),
+ validator_(
+ new AddressValidator(
+ supplier_.get())),
+ validated_(BuildCallback(this, &PreloadAddressValidator::Validated)) {
+}
+
+PreloadAddressValidator::~PreloadAddressValidator() {
+}
+
+void PreloadAddressValidator::LoadRules(const std::string& region_code,
+ const Callback& loaded) {
+ assert(supplier_ != NULL);
+ supplier_->LoadRules(region_code, loaded);
+}
+
+PreloadAddressValidator::Status PreloadAddressValidator::Validate(
+ const AddressData& address,
+ const FieldProblemMap* filter,
+ FieldProblemMap* problems) const {
+ assert(supplier_ != NULL);
+ assert(validator_ != NULL);
+
+ if (supplier_->IsPending(address.region_code)) {
+ return RULES_NOT_READY;
+ }
+
+ if (!supplier_->IsLoaded(address.region_code)) {
+ return RULES_UNAVAILABLE;
+ }
+
+ validator_->Validate(
+ address,
+ /*allow_postal*/ false,
+ /*require_name*/ false,
+ filter,
+ problems,
+ *validated_);
+
+ return SUCCESS;
+}
+
+PreloadAddressValidator::Status PreloadAddressValidator::GetSuggestions(
+ const AddressData& user_input,
+ AddressField focused_field,
+ size_t suggestion_limit,
+ std::vector<AddressData>* suggestions) const {
+ assert(suggestions_ != NULL);
+ assert(supplier_ != NULL);
+
+ if (supplier_->IsPending(user_input.region_code)) {
+ return RULES_NOT_READY;
+ }
+
+ if (!supplier_->IsLoaded(user_input.region_code)) {
+ return RULES_UNAVAILABLE;
+ }
+
+ suggestions_->GetSuggestions(
+ user_input,
+ focused_field,
+ suggestion_limit,
+ suggestions);
+
+ return SUCCESS;
+}
+
+bool PreloadAddressValidator::CanonicalizeAdministrativeArea(
+ AddressData* address) const {
+ assert(address != NULL);
+ assert(supplier_ != NULL);
+ assert(synonyms_ != NULL);
+
+ if (!supplier_->IsLoaded(address->region_code)) {
+ return false;
+ }
+
+ // TODO: It would probably be beneficial to use the full canonicalization.
+ AddressData tmp(*address);
+ synonyms_->NormalizeForDisplay(&tmp);
+ address->administrative_area = tmp.administrative_area;
+
+ return true;
+}
+
+void PreloadAddressValidator::Validated(bool success,
+ const AddressData&,
+ const FieldProblemMap&) {
+ assert(success);
+}
+
+// Stub constructor for use by MockAddressValidator.
+PreloadAddressValidator::PreloadAddressValidator() {
+}
+
+} // namespace autofill
diff --git a/third_party/libaddressinput/chromium/preload_address_validator.h b/third_party/libaddressinput/chromium/preload_address_validator.h
new file mode 100644
index 0000000..8b22040
--- /dev/null
+++ b/third_party/libaddressinput/chromium/preload_address_validator.h
@@ -0,0 +1,141 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef THIRD_PARTY_LIBADDRESSINPUT_CHROMIUM_PRELOAD_ADDRESS_VALIDATOR_H_
+#define THIRD_PARTY_LIBADDRESSINPUT_CHROMIUM_PRELOAD_ADDRESS_VALIDATOR_H_
+
+#include <cstddef>
+#include <string>
+#include <vector>
+
+#include "base/macros.h"
+#include "base/memory/scoped_ptr.h"
+#include "third_party/libaddressinput/src/cpp/include/libaddressinput/address_field.h"
+#include "third_party/libaddressinput/src/cpp/include/libaddressinput/address_validator.h"
+#include "third_party/libaddressinput/src/cpp/include/libaddressinput/callback.h"
+
+namespace i18n {
+namespace addressinput {
+
+class Downloader;
+class PreloadSupplier;
+class Storage;
+class Synonyms;
+struct AddressData;
+
+} // namespace addressinput
+} // namespace i18n
+
+namespace autofill {
+
+class Suggestions;
+
+// Interface to the libaddressinput AddressValidator for Chromium Autofill.
+class PreloadAddressValidator {
+ public:
+ typedef ::i18n::addressinput::Callback<std::string, int> Callback;
+
+ // The status of address validation.
+ enum Status {
+ // Address validation completed successfully. Check |problems| to see if any
+ // problems were found.
+ SUCCESS,
+
+ // The validation rules are not available, because LoadRules() was not
+ // called or failed. Reload the rules.
+ RULES_UNAVAILABLE,
+
+ // The validation rules are being loaded. Try again later.
+ RULES_NOT_READY
+ };
+
+ // Takes ownership of |downloader| and |storage|.
+ PreloadAddressValidator(
+ const std::string& validation_data_url,
+ scoped_ptr< ::i18n::addressinput::Downloader> downloader,
+ scoped_ptr< ::i18n::addressinput::Storage> storage);
+
+ virtual ~PreloadAddressValidator();
+
+ // Loads the generic validation rules for |region_code| and specific rules
+ // for the regions's administrative areas, localities, and dependent
+ // localities. A typical data size is 10KB. The largest is 250KB. If a region
+ // has language-specific validation rules, then these are also loaded.
+ //
+ // Example rule:
+ // https://i18napis.appspot.com/ssl-aggregate-address/data/US
+ //
+ // If the rules are already in progress of being loaded, it does nothing.
+ // Calls |loaded| when the loading has finished.
+ virtual void LoadRules(const std::string& region_code,
+ const Callback& loaded);
+
+ // Validates the |address| and populates |problems| with the validation
+ // problems, filtered according to the |filter| parameter.
+ //
+ // If the |filter| is empty, then all discovered validation problems are
+ // returned. If the |filter| contains problem elements, then only the problems
+ // in the |filter| may be returned.
+ virtual Status Validate(
+ const ::i18n::addressinput::AddressData& address,
+ const ::i18n::addressinput::FieldProblemMap* filter,
+ ::i18n::addressinput::FieldProblemMap* problems) const;
+
+ // Fills in |suggestions| for the partially typed in |user_input|, assuming
+ // the user is typing in the |focused_field|. If the number of |suggestions|
+ // is over the |suggestion_limit|, then returns no |suggestions| at all.
+ //
+ // If the |solutions| parameter is NULL, the checks whether the validation
+ // rules are available, but does not fill in suggestions.
+ //
+ // Sample user input 1:
+ // country code = "US"
+ // postal code = "90066"
+ // focused field = POSTAL_CODE
+ // suggestions limit = 1
+ // Suggestion:
+ // [{administrative_area: "CA"}]
+ //
+ // Sample user input 2:
+ // country code = "CN"
+ // dependent locality = "Zongyang"
+ // focused field = DEPENDENT_LOCALITY
+ // suggestions limit = 10
+ // Suggestion:
+ // [{dependent_locality: "Zongyang Xian",
+ // locality: "Anqing Shi",
+ // administrative_area: "Anhui Sheng"}]
+ virtual Status GetSuggestions(
+ const ::i18n::addressinput::AddressData& user_input,
+ ::i18n::addressinput::AddressField focused_field,
+ size_t suggestion_limit,
+ std::vector< ::i18n::addressinput::AddressData>* suggestions) const;
+
+ // Canonicalizes the administrative area in |address_data|. For example,
+ // "texas" changes to "TX". Returns true on success, otherwise leaves
+ // |address_data| alone and returns false.
+ virtual bool CanonicalizeAdministrativeArea(
+ ::i18n::addressinput::AddressData* address) const;
+
+ private:
+ void Validated(bool success,
+ const ::i18n::addressinput::AddressData&,
+ const ::i18n::addressinput::FieldProblemMap&);
+
+ const scoped_ptr< ::i18n::addressinput::PreloadSupplier> supplier_;
+ const scoped_ptr<Suggestions> suggestions_;
+ const scoped_ptr< ::i18n::addressinput::Synonyms> synonyms_;
+ const scoped_ptr<const ::i18n::addressinput::AddressValidator> validator_;
+ const scoped_ptr<const ::i18n::addressinput::AddressValidator::Callback>
+ validated_;
+
+ friend class MockAddressValidator;
+ PreloadAddressValidator();
+
+ DISALLOW_COPY_AND_ASSIGN(PreloadAddressValidator);
+};
+
+} // namespace autofill
+
+#endif // THIRD_PARTY_LIBADDRESSINPUT_CHROMIUM_PRELOAD_ADDRESS_VALIDATOR_H_
diff --git a/third_party/libaddressinput/chromium/preload_address_validator_unittest.cc b/third_party/libaddressinput/chromium/preload_address_validator_unittest.cc
new file mode 100644
index 0000000..1cc7aaf
--- /dev/null
+++ b/third_party/libaddressinput/chromium/preload_address_validator_unittest.cc
@@ -0,0 +1,612 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <cstddef>
+#include <string>
+#include <vector>
+
+#include "base/basictypes.h"
+#include "base/macros.h"
+#include "base/memory/scoped_ptr.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+#define I18N_ADDRESSINPUT_UTIL_BASICTYPES_H_
+#include "third_party/libaddressinput/chromium/preload_address_validator.h"
+#include "third_party/libaddressinput/src/cpp/include/libaddressinput/address_data.h"
+#include "third_party/libaddressinput/src/cpp/include/libaddressinput/address_field.h"
+#include "third_party/libaddressinput/src/cpp/include/libaddressinput/address_problem.h"
+#include "third_party/libaddressinput/src/cpp/include/libaddressinput/address_validator.h"
+#include "third_party/libaddressinput/src/cpp/include/libaddressinput/callback.h"
+#include "third_party/libaddressinput/src/cpp/include/libaddressinput/downloader.h"
+#include "third_party/libaddressinput/src/cpp/include/libaddressinput/null_storage.h"
+#include "third_party/libaddressinput/src/cpp/include/libaddressinput/storage.h"
+#include "third_party/libaddressinput/src/cpp/src/region_data_constants.h"
+#include "third_party/libaddressinput/src/cpp/test/fake_downloader.h"
+
+namespace {
+
+using ::autofill::PreloadAddressValidator;
+using ::i18n::addressinput::AddressData;
+using ::i18n::addressinput::AddressField;
+using ::i18n::addressinput::BuildCallback;
+using ::i18n::addressinput::Downloader;
+using ::i18n::addressinput::FakeDownloader;
+using ::i18n::addressinput::FieldProblemMap;
+using ::i18n::addressinput::NullStorage;
+using ::i18n::addressinput::RegionDataConstants;
+using ::i18n::addressinput::Storage;
+
+using ::i18n::addressinput::COUNTRY;
+using ::i18n::addressinput::ADMIN_AREA;
+using ::i18n::addressinput::LOCALITY;
+using ::i18n::addressinput::DEPENDENT_LOCALITY;
+using ::i18n::addressinput::SORTING_CODE;
+using ::i18n::addressinput::POSTAL_CODE;
+using ::i18n::addressinput::STREET_ADDRESS;
+using ::i18n::addressinput::RECIPIENT;
+
+using ::i18n::addressinput::UNKNOWN_VALUE;
+using ::i18n::addressinput::INVALID_FORMAT;
+using ::i18n::addressinput::MISMATCHING_VALUE;
+
+class PreloadAddressValidatorTest : public testing::Test {
+ protected:
+ PreloadAddressValidatorTest()
+ : validator_(
+ new PreloadAddressValidator(
+ FakeDownloader::kFakeAggregateDataUrl,
+ scoped_ptr<Downloader>(new FakeDownloader),
+ scoped_ptr<Storage>(new NullStorage))),
+ loaded_(BuildCallback(this, &PreloadAddressValidatorTest::Loaded)) {
+ validator_->LoadRules("US", *loaded_);
+ }
+
+ virtual ~PreloadAddressValidatorTest() {}
+
+ const scoped_ptr<PreloadAddressValidator> validator_;
+ const scoped_ptr<PreloadAddressValidator::Callback> loaded_;
+
+ private:
+ void Loaded(bool success,
+ const std::string& region_code,
+ const int& rule_count) {
+ AddressData address_data;
+ address_data.region_code = region_code;
+ FieldProblemMap dummy;
+ PreloadAddressValidator::Status status =
+ validator_->Validate(address_data, NULL, &dummy);
+ ASSERT_EQ(success, status == PreloadAddressValidator::SUCCESS);
+ }
+
+ DISALLOW_COPY_AND_ASSIGN(PreloadAddressValidatorTest);
+};
+
+TEST_F(PreloadAddressValidatorTest, RegionHasRules) {
+ const std::vector<std::string>& region_codes =
+ RegionDataConstants::GetRegionCodes();
+ AddressData address;
+ for (size_t i = 0; i < region_codes.size(); ++i) {
+ SCOPED_TRACE("For region: " + region_codes[i]);
+ validator_->LoadRules(region_codes[i], *loaded_);
+ address.region_code = region_codes[i];
+ FieldProblemMap dummy;
+ EXPECT_EQ(
+ PreloadAddressValidator::SUCCESS,
+ validator_->Validate(address, NULL, &dummy));
+ }
+}
+
+TEST_F(PreloadAddressValidatorTest, EmptyAddressNoFatalFailure) {
+ AddressData address;
+ address.region_code = "US";
+
+ FieldProblemMap dummy;
+ EXPECT_EQ(
+ PreloadAddressValidator::SUCCESS,
+ validator_->Validate(address, NULL, &dummy));
+}
+
+TEST_F(PreloadAddressValidatorTest, USZipCode) {
+ AddressData address;
+ address.address_line.push_back("340 Main St.");
+ address.locality = "Venice";
+ address.administrative_area = "CA";
+ address.region_code = "US";
+
+ // Valid Californian zip code.
+ address.postal_code = "90291";
+ FieldProblemMap problems;
+ EXPECT_EQ(
+ PreloadAddressValidator::SUCCESS,
+ validator_->Validate(address, NULL, &problems));
+ EXPECT_TRUE(problems.empty());
+
+ problems.clear();
+
+ // An extended, valid Californian zip code.
+ address.postal_code = "90210-1234";
+ EXPECT_EQ(
+ PreloadAddressValidator::SUCCESS,
+ validator_->Validate(address, NULL, &problems));
+ EXPECT_TRUE(problems.empty());
+
+ problems.clear();
+
+ // New York zip code (which is invalid for California).
+ address.postal_code = "12345";
+ EXPECT_EQ(
+ PreloadAddressValidator::SUCCESS,
+ validator_->Validate(address, NULL, &problems));
+ EXPECT_EQ(1U, problems.size());
+ EXPECT_EQ(problems.begin()->first, POSTAL_CODE);
+ EXPECT_EQ(problems.begin()->second, MISMATCHING_VALUE);
+
+ problems.clear();
+
+ // A zip code with a "90" in the middle.
+ address.postal_code = "12903";
+ EXPECT_EQ(
+ PreloadAddressValidator::SUCCESS,
+ validator_->Validate(address, NULL, &problems));
+ EXPECT_EQ(1U, problems.size());
+ EXPECT_EQ(problems.begin()->first, POSTAL_CODE);
+ EXPECT_EQ(problems.begin()->second, MISMATCHING_VALUE);
+
+ problems.clear();
+
+ // Invalid zip code (too many digits).
+ address.postal_code = "902911";
+ EXPECT_EQ(
+ PreloadAddressValidator::SUCCESS,
+ validator_->Validate(address, NULL, &problems));
+ EXPECT_EQ(1U, problems.size());
+ EXPECT_EQ(problems.begin()->first, POSTAL_CODE);
+ EXPECT_EQ(problems.begin()->second, INVALID_FORMAT);
+
+ problems.clear();
+
+ // Invalid zip code (too few digits).
+ address.postal_code = "9029";
+ EXPECT_EQ(
+ PreloadAddressValidator::SUCCESS,
+ validator_->Validate(address, NULL, &problems));
+ EXPECT_EQ(1U, problems.size());
+ EXPECT_EQ(problems.begin()->first, POSTAL_CODE);
+ EXPECT_EQ(problems.begin()->second, INVALID_FORMAT);
+}
+
+// Test case disabled because libaddressinput address validation doesn't do
+// those kinds of normalizations that this test case expects. TODO: Something.
+TEST_F(PreloadAddressValidatorTest, DISABLED_BasicValidation) {
+ // US rules should always be available, even though this load call fails.
+ validator_->LoadRules("US", *loaded_);
+ AddressData address;
+ address.region_code = "US";
+ address.language_code = "en";
+ address.administrative_area = "TX";
+ address.locality = "Paris";
+ address.postal_code = "75461";
+ address.address_line.push_back("123 Main St");
+ FieldProblemMap problems;
+ EXPECT_EQ(
+ PreloadAddressValidator::SUCCESS,
+ validator_->Validate(address, NULL, &problems));
+ EXPECT_TRUE(problems.empty());
+
+ // The display name works as well as the key.
+ address.administrative_area = "Texas";
+ problems.clear();
+ EXPECT_EQ(
+ PreloadAddressValidator::SUCCESS,
+ validator_->Validate(address, NULL, &problems));
+ EXPECT_TRUE(problems.empty());
+
+ // Ignore capitalization.
+ address.administrative_area = "tx";
+ problems.clear();
+ EXPECT_EQ(
+ PreloadAddressValidator::SUCCESS,
+ validator_->Validate(address, NULL, &problems));
+ EXPECT_TRUE(problems.empty());
+
+ // Ignore capitalization.
+ address.administrative_area = "teXas";
+ problems.clear();
+ EXPECT_EQ(
+ PreloadAddressValidator::SUCCESS,
+ validator_->Validate(address, NULL, &problems));
+ EXPECT_TRUE(problems.empty());
+
+ // Ignore diacriticals.
+ address.administrative_area = "T\u00E9xas";
+ problems.clear();
+ EXPECT_EQ(
+ PreloadAddressValidator::SUCCESS,
+ validator_->Validate(address, NULL, &problems));
+ EXPECT_TRUE(problems.empty());
+}
+
+TEST_F(PreloadAddressValidatorTest, BasicValidationFailure) {
+ // US rules should always be available, even though this load call fails.
+ validator_->LoadRules("US", *loaded_);
+ AddressData address;
+ address.region_code = "US";
+ address.language_code = "en";
+ address.administrative_area = "XT";
+ address.locality = "Paris";
+ address.postal_code = "75461";
+ address.address_line.push_back("123 Main St");
+ FieldProblemMap problems;
+ EXPECT_EQ(
+ PreloadAddressValidator::SUCCESS,
+ validator_->Validate(address, NULL, &problems));
+
+ ASSERT_EQ(1U, problems.size());
+ EXPECT_EQ(UNKNOWN_VALUE, problems.begin()->second);
+ EXPECT_EQ(ADMIN_AREA, problems.begin()->first);
+}
+
+TEST_F(PreloadAddressValidatorTest, NoNullSuggestionsCrash) {
+ AddressData address;
+ address.region_code = "US";
+ EXPECT_EQ(PreloadAddressValidator::SUCCESS,
+ validator_->GetSuggestions(address, COUNTRY, 1, NULL));
+}
+
+TEST_F(PreloadAddressValidatorTest, SuggestAdminAreaForPostalCode) {
+ AddressData address;
+ address.region_code = "US";
+ address.postal_code = "90291";
+
+ std::vector<AddressData> suggestions;
+ EXPECT_EQ(PreloadAddressValidator::SUCCESS,
+ validator_->GetSuggestions(address, POSTAL_CODE, 1, &suggestions));
+ ASSERT_EQ(1U, suggestions.size());
+ EXPECT_EQ("CA", suggestions[0].administrative_area);
+ EXPECT_EQ("90291", suggestions[0].postal_code);
+}
+
+TEST_F(PreloadAddressValidatorTest, SuggestLocalityForPostalCodeWithAdminArea) {
+ validator_->LoadRules("TW", *loaded_);
+ AddressData address;
+ address.region_code = "TW";
+ address.postal_code = "515";
+ address.administrative_area = "Changhua";
+
+ std::vector<AddressData> suggestions;
+ EXPECT_EQ(PreloadAddressValidator::SUCCESS,
+ validator_->GetSuggestions(address, POSTAL_CODE, 1, &suggestions));
+ ASSERT_EQ(1U, suggestions.size());
+ EXPECT_EQ("Dacun Township", suggestions[0].locality);
+ EXPECT_EQ("Changhua County", suggestions[0].administrative_area);
+ EXPECT_EQ("515", suggestions[0].postal_code);
+}
+
+TEST_F(PreloadAddressValidatorTest, SuggestAdminAreaForPostalCodeWithLocality) {
+ validator_->LoadRules("TW", *loaded_);
+ AddressData address;
+ address.region_code = "TW";
+ address.postal_code = "515";
+ address.locality = "Dacun";
+
+ std::vector<AddressData> suggestions;
+ EXPECT_EQ(PreloadAddressValidator::SUCCESS,
+ validator_->GetSuggestions(address, POSTAL_CODE, 1, &suggestions));
+ ASSERT_EQ(1U, suggestions.size());
+ EXPECT_EQ("Dacun Township", suggestions[0].locality);
+ EXPECT_EQ("Changhua County", suggestions[0].administrative_area);
+ EXPECT_EQ("515", suggestions[0].postal_code);
+}
+
+TEST_F(PreloadAddressValidatorTest, NoSuggestForPostalCodeWithWrongAdminArea) {
+ AddressData address;
+ address.region_code = "US";
+ address.postal_code = "90066";
+ address.postal_code = "TX";
+
+ std::vector<AddressData> suggestions;
+ EXPECT_EQ(PreloadAddressValidator::SUCCESS,
+ validator_->GetSuggestions(address, POSTAL_CODE, 1, &suggestions));
+ EXPECT_TRUE(suggestions.empty());
+}
+
+TEST_F(PreloadAddressValidatorTest, SuggestForLocality) {
+ validator_->LoadRules("CN", *loaded_);
+ AddressData address;
+ address.region_code = "CN";
+ address.locality = "Anqin";
+
+ std::vector<AddressData> suggestions;
+ EXPECT_EQ(PreloadAddressValidator::SUCCESS,
+ validator_->GetSuggestions(address, LOCALITY, 10, &suggestions));
+ ASSERT_EQ(1U, suggestions.size());
+ EXPECT_EQ("Anqing Shi", suggestions[0].locality);
+ EXPECT_EQ("ANHUI SHENG", suggestions[0].administrative_area);
+}
+
+TEST_F(PreloadAddressValidatorTest, SuggestForLocalityAndAdminArea) {
+ validator_->LoadRules("CN", *loaded_);
+ AddressData address;
+ address.region_code = "CN";
+ address.locality = "Anqing";
+ address.administrative_area = "Anhui";
+
+ std::vector<AddressData> suggestions;
+ EXPECT_EQ(PreloadAddressValidator::SUCCESS,
+ validator_->GetSuggestions(address, LOCALITY, 10, &suggestions));
+ ASSERT_EQ(1U, suggestions.size());
+ EXPECT_TRUE(suggestions[0].dependent_locality.empty());
+ EXPECT_EQ("Anqing Shi", suggestions[0].locality);
+ EXPECT_EQ("ANHUI SHENG", suggestions[0].administrative_area);
+}
+
+TEST_F(PreloadAddressValidatorTest, SuggestForAdminAreaAndLocality) {
+ validator_->LoadRules("CN", *loaded_);
+ AddressData address;
+ address.region_code = "CN";
+ address.locality = "Anqing";
+ address.administrative_area = "Anhui";
+
+ std::vector<AddressData> suggestions;
+ EXPECT_EQ(PreloadAddressValidator::SUCCESS,
+ validator_->GetSuggestions(address, ADMIN_AREA, 10, &suggestions));
+ ASSERT_EQ(1U, suggestions.size());
+ EXPECT_TRUE(suggestions[0].dependent_locality.empty());
+ EXPECT_TRUE(suggestions[0].locality.empty());
+ EXPECT_EQ("ANHUI SHENG", suggestions[0].administrative_area);
+}
+
+TEST_F(PreloadAddressValidatorTest, SuggestForDependentLocality) {
+ validator_->LoadRules("CN", *loaded_);
+ AddressData address;
+ address.region_code = "CN";
+ address.dependent_locality = "Zongyang";
+
+ std::vector<AddressData> suggestions;
+ EXPECT_EQ(PreloadAddressValidator::SUCCESS,
+ validator_->GetSuggestions(
+ address, DEPENDENT_LOCALITY, 10, &suggestions));
+ ASSERT_EQ(1U, suggestions.size());
+ EXPECT_EQ("Zongyang Xian", suggestions[0].dependent_locality);
+ EXPECT_EQ("Anqing Shi", suggestions[0].locality);
+ EXPECT_EQ("ANHUI SHENG", suggestions[0].administrative_area);
+}
+
+TEST_F(PreloadAddressValidatorTest,
+ NoSuggestForDependentLocalityWithWrongAdminArea) {
+ validator_->LoadRules("CN", *loaded_);
+ AddressData address;
+ address.region_code = "CN";
+ address.dependent_locality = "Zongyang";
+ address.administrative_area = "Sichuan Sheng";
+
+ std::vector<AddressData> suggestions;
+ EXPECT_EQ(PreloadAddressValidator::SUCCESS,
+ validator_->GetSuggestions(
+ address, DEPENDENT_LOCALITY, 10, &suggestions));
+ EXPECT_TRUE(suggestions.empty());
+}
+
+TEST_F(PreloadAddressValidatorTest, EmptySuggestionsOverLimit) {
+ AddressData address;
+ address.region_code = "US";
+ address.administrative_area = "A";
+
+ std::vector<AddressData> suggestions;
+ EXPECT_EQ(PreloadAddressValidator::SUCCESS,
+ validator_->GetSuggestions(address, ADMIN_AREA, 1, &suggestions));
+ EXPECT_TRUE(suggestions.empty());
+}
+
+TEST_F(PreloadAddressValidatorTest, PreferShortSuggestions) {
+ AddressData address;
+ address.region_code = "US";
+ address.administrative_area = "CA";
+
+ std::vector<AddressData> suggestions;
+ EXPECT_EQ(PreloadAddressValidator::SUCCESS,
+ validator_->GetSuggestions(address, ADMIN_AREA, 10, &suggestions));
+ ASSERT_EQ(1U, suggestions.size());
+ EXPECT_EQ("CA", suggestions[0].administrative_area);
+}
+
+TEST_F(PreloadAddressValidatorTest, SuggestTheSingleMatchForFullMatchName) {
+ AddressData address;
+ address.region_code = "US";
+ address.administrative_area = "Texas";
+
+ std::vector<AddressData> suggestions;
+ EXPECT_EQ(PreloadAddressValidator::SUCCESS,
+ validator_->GetSuggestions(address, ADMIN_AREA, 10, &suggestions));
+ ASSERT_EQ(1U, suggestions.size());
+ EXPECT_EQ("Texas", suggestions[0].administrative_area);
+}
+
+TEST_F(PreloadAddressValidatorTest, SuggestAdminArea) {
+ AddressData address;
+ address.region_code = "US";
+ address.administrative_area = "Cali";
+
+ std::vector<AddressData> suggestions;
+ EXPECT_EQ(PreloadAddressValidator::SUCCESS,
+ validator_->GetSuggestions(address, ADMIN_AREA, 10, &suggestions));
+ ASSERT_EQ(1U, suggestions.size());
+ EXPECT_EQ("California", suggestions[0].administrative_area);
+}
+
+TEST_F(PreloadAddressValidatorTest, MultipleSuggestions) {
+ AddressData address;
+ address.region_code = "US";
+ address.administrative_area = "MA";
+
+ std::vector<AddressData> suggestions;
+ EXPECT_EQ(PreloadAddressValidator::SUCCESS,
+ validator_->GetSuggestions(address, ADMIN_AREA, 10, &suggestions));
+ EXPECT_LT(1U, suggestions.size());
+
+ // Massachusetts should not be a suggestion, because it's already covered
+ // under MA.
+ std::set<std::string> expected_suggestions;
+ expected_suggestions.insert("MA");
+ expected_suggestions.insert("Maine");
+ expected_suggestions.insert("Marshall Islands");
+ expected_suggestions.insert("Maryland");
+ for (std::vector<AddressData>::const_iterator it = suggestions.begin();
+ it != suggestions.end(); ++it) {
+ expected_suggestions.erase(it->administrative_area);
+ }
+ EXPECT_TRUE(expected_suggestions.empty());
+}
+
+TEST_F(PreloadAddressValidatorTest, SuggestNonLatinKeyWhenLanguageMatches) {
+ validator_->LoadRules("KR", *loaded_);
+ AddressData address;
+ address.language_code = "ko";
+ address.region_code = "KR";
+ address.postal_code = "210-210";
+
+ std::vector<AddressData> suggestions;
+ EXPECT_EQ(PreloadAddressValidator::SUCCESS,
+ validator_->GetSuggestions(address, POSTAL_CODE, 1, &suggestions));
+ ASSERT_EQ(1U, suggestions.size());
+ EXPECT_EQ("강원도", suggestions[0].administrative_area);
+ EXPECT_EQ("210-210", suggestions[0].postal_code);
+}
+
+TEST_F(PreloadAddressValidatorTest, SuggestNonLatinKeyWhenUserInputIsNotLatin) {
+ validator_->LoadRules("KR", *loaded_);
+ AddressData address;
+ address.language_code = "en";
+ address.region_code = "KR";
+ address.administrative_area = "강원";
+
+ std::vector<AddressData> suggestions;
+ EXPECT_EQ(PreloadAddressValidator::SUCCESS,
+ validator_->GetSuggestions(address, ADMIN_AREA, 1, &suggestions));
+ ASSERT_EQ(1U, suggestions.size());
+ EXPECT_EQ("강원도", suggestions[0].administrative_area);
+}
+
+TEST_F(PreloadAddressValidatorTest,
+ SuggestLatinNameWhenLanguageDiffersAndLatinNameAvailable) {
+ validator_->LoadRules("KR", *loaded_);
+ AddressData address;
+ address.language_code = "en";
+ address.region_code = "KR";
+ address.postal_code = "210-210";
+
+ std::vector<AddressData> suggestions;
+ EXPECT_EQ(PreloadAddressValidator::SUCCESS,
+ validator_->GetSuggestions(address, POSTAL_CODE, 1, &suggestions));
+ ASSERT_EQ(1U, suggestions.size());
+ EXPECT_EQ("Gangwon", suggestions[0].administrative_area);
+ EXPECT_EQ("210-210", suggestions[0].postal_code);
+}
+
+TEST_F(PreloadAddressValidatorTest, SuggestLatinNameWhenUserInputIsLatin) {
+ validator_->LoadRules("KR", *loaded_);
+ AddressData address;
+ address.language_code = "ko";
+ address.region_code = "KR";
+ address.administrative_area = "Gang";
+
+ std::vector<AddressData> suggestions;
+ EXPECT_EQ(PreloadAddressValidator::SUCCESS,
+ validator_->GetSuggestions(address, ADMIN_AREA, 1, &suggestions));
+ ASSERT_EQ(1U, suggestions.size());
+ EXPECT_EQ("Gangwon", suggestions[0].administrative_area);
+}
+
+TEST_F(PreloadAddressValidatorTest, NoSuggestionsForEmptyAddress) {
+ AddressData address;
+ address.region_code = "US";
+
+ std::vector<AddressData> suggestions;
+ EXPECT_EQ(
+ PreloadAddressValidator::SUCCESS,
+ validator_->GetSuggestions(address, POSTAL_CODE, 999, &suggestions));
+ EXPECT_TRUE(suggestions.empty());
+}
+
+TEST_F(PreloadAddressValidatorTest, SuggestionIncludesCountry) {
+ AddressData address;
+ address.region_code = "US";
+ address.postal_code = "90291";
+
+ std::vector<AddressData> suggestions;
+ EXPECT_EQ(PreloadAddressValidator::SUCCESS,
+ validator_->GetSuggestions(address, POSTAL_CODE, 1, &suggestions));
+ ASSERT_EQ(1U, suggestions.size());
+ EXPECT_EQ("US", suggestions[0].region_code);
+}
+
+TEST_F(PreloadAddressValidatorTest,
+ SuggestOnlyForAdministrativeAreasAndPostalCode) {
+ AddressData address;
+ address.region_code = "US";
+ address.administrative_area = "CA";
+ address.locality = "Los Angeles";
+ address.dependent_locality = "Venice";
+ address.postal_code = "90291";
+ address.sorting_code = "123";
+ address.address_line.push_back("123 Main St");
+ address.recipient = "Jon Smith";
+
+ // Fields that should not have suggestions in US.
+ static const AddressField kNoSugestFields[] = {
+ COUNTRY,
+ LOCALITY,
+ DEPENDENT_LOCALITY,
+ SORTING_CODE,
+ STREET_ADDRESS,
+ RECIPIENT
+ };
+
+ static const size_t kNumNoSuggestFields =
+ sizeof kNoSugestFields / sizeof (AddressField);
+
+ for (size_t i = 0; i < kNumNoSuggestFields; ++i) {
+ std::vector<AddressData> suggestions;
+ EXPECT_EQ(PreloadAddressValidator::SUCCESS,
+ validator_->GetSuggestions(
+ address, kNoSugestFields[i], 999, &suggestions));
+ EXPECT_TRUE(suggestions.empty());
+ }
+}
+
+TEST_F(PreloadAddressValidatorTest, CanonicalizeUsAdminAreaName) {
+ AddressData address;
+ address.region_code = "US";
+ address.administrative_area = "cALIFORNIa";
+ EXPECT_TRUE(validator_->CanonicalizeAdministrativeArea(&address));
+ EXPECT_EQ("CA", address.administrative_area);
+}
+
+TEST_F(PreloadAddressValidatorTest, CanonicalizeUsAdminAreaKey) {
+ AddressData address;
+ address.region_code = "US";
+ address.administrative_area = "CA";
+ EXPECT_TRUE(validator_->CanonicalizeAdministrativeArea(&address));
+ EXPECT_EQ("CA", address.administrative_area);
+}
+
+TEST_F(PreloadAddressValidatorTest, CanonicalizeJpAdminAreaKey) {
+ validator_->LoadRules("JP", *loaded_);
+ AddressData address;
+ address.region_code = "JP";
+ address.administrative_area = "東京都";
+ EXPECT_TRUE(validator_->CanonicalizeAdministrativeArea(&address));
+ EXPECT_EQ("東京都", address.administrative_area);
+}
+
+TEST_F(PreloadAddressValidatorTest, CanonicalizeJpAdminAreaLatinName) {
+ validator_->LoadRules("JP", *loaded_);
+ AddressData address;
+ address.region_code = "JP";
+ address.administrative_area = "tOKYo";
+ EXPECT_TRUE(validator_->CanonicalizeAdministrativeArea(&address));
+ EXPECT_EQ("TOKYO", address.administrative_area);
+}
+
+} // namespace