diff options
author | rouslan@chromium.org <rouslan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-07-11 23:18:33 +0000 |
---|---|---|
committer | rouslan@chromium.org <rouslan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-07-11 23:18:33 +0000 |
commit | f91a9ccc1b2be06925899d48eb2d144e695a1d56 (patch) | |
tree | 71805fa02add0fca87f4a467b5174c80b8d430e2 /third_party | |
parent | 0a60abb713ad65f4d5cf202b91e2be79b2dce4c9 (diff) | |
download | chromium_src-f91a9ccc1b2be06925899d48eb2d144e695a1d56.zip chromium_src-f91a9ccc1b2be06925899d48eb2d144e695a1d56.tar.gz chromium_src-f91a9ccc1b2be06925899d48eb2d144e695a1d56.tar.bz2 |
Reland "Use upstream libaddressinput in Chrome."
Remove static initializer and reland https://crrev.com/282408 which was
reverted in https://crrev.com/282426.
TBR=estade@chromium.org,thestig@chromium.org
BUG=389918
Review URL: https://codereview.chromium.org/386873002
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@282726 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'third_party')
34 files changed, 2435 insertions, 775 deletions
diff --git a/third_party/libaddressinput/BUILD.gn b/third_party/libaddressinput/BUILD.gn index 291e549..a0e2341 100644 --- a/third_party/libaddressinput/BUILD.gn +++ b/third_party/libaddressinput/BUILD.gn @@ -4,70 +4,69 @@ import("//tools/grit/grit_rule.gni") -# TODO(rouslan): Use the src/ directory. http://crbug.com/327046 -libaddressinput_dir = "chromium" +# The list of files in libaddressinput.gypi. +gypi_values = exec_script( + "//build/gypi_to_gn.py", + [ rebase_path("src/cpp/libaddressinput.gypi") ], + "scope", + [ "src/cpp/libaddressinput.gypi" ]) + +libaddressinput_util_files = [ + "src/cpp/src/address_data.cc", + "src/cpp/src/address_field.cc", + "src/cpp/src/address_field_util.cc", + "src/cpp/src/address_formatter.cc", + "src/cpp/src/address_metadata.cc", + "src/cpp/src/address_ui.cc", + "src/cpp/src/format_element.cc", + "src/cpp/src/language.cc", + "src/cpp/src/localization.cc", + "src/cpp/src/lookup_key.cc", + "src/cpp/src/region_data_constants.cc", + "src/cpp/src/rule.cc", + "src/cpp/src/util/cctype_tolower_equal.cc", + "src/cpp/src/util/json.cc", + "src/cpp/src/util/string_split.cc", + "src/cpp/src/util/string_util.cc", +] # GYP version: third_party/libaddressinput/libaddressinput.gyp:libaddressinput_strings grit("strings") { - source = "$libaddressinput_dir/cpp/res/libaddressinput_strings.grd" -} - -# GYP version: third_party/libaddressinput/libaddressinput.gyp:libaddressinput_updated_strings -grit("updated_strings") { source = "//chrome/app/address_input_strings.grd" } config("libaddressinput_config") { defines = [ - "CUSTOM_BASICTYPES=\"base/basictypes.h\"", - "CUSTOM_SCOPED_PTR=\"base/memory/scoped_ptr.h\"", + "I18N_ADDRESSINPUT_USE_BASICTYPES_OVERRIDE=1", + "VALIDATION_DATA_URL=\"https://i18napis.appspot.com/ssl-aggregate-address/\"", + ] + include_dirs = [ + "src/cpp/include", + "chromium/override", ] - include_dirs = [ "$libaddressinput_dir/cpp/include" ] } # This target provides basic functionality which is cooked into the build. # GYP version: third_party/libaddressinput/libaddressinput.gyp:libaddressinput_util static_library("util") { - sources = [ + sources = libaddressinput_util_files + sources += [ "chromium/addressinput_util.cc", - "chromium/addressinput_util.h", - "chromium/canonicalize_string.cc", "chromium/json.cc", - "$libaddressinput_dir/cpp/include/libaddressinput/address_data.h", - "$libaddressinput_dir/cpp/include/libaddressinput/address_field.h", - "$libaddressinput_dir/cpp/include/libaddressinput/address_formatter.h", - "$libaddressinput_dir/cpp/include/libaddressinput/address_metadata.h", - "$libaddressinput_dir/cpp/include/libaddressinput/address_problem.h", - "$libaddressinput_dir/cpp/include/libaddressinput/util/basictypes.h", - "$libaddressinput_dir/cpp/include/libaddressinput/util/internal/basictypes.h", - "$libaddressinput_dir/cpp/include/libaddressinput/util/internal/move.h", - "$libaddressinput_dir/cpp/include/libaddressinput/util/internal/scoped_ptr.h", - "$libaddressinput_dir/cpp/include/libaddressinput/util/internal/template_util.h", - "$libaddressinput_dir/cpp/include/libaddressinput/util/scoped_ptr.h", - "$libaddressinput_dir/cpp/src/address_data.cc", - "$libaddressinput_dir/cpp/src/address_field.cc", - "$libaddressinput_dir/cpp/src/address_formatter.cc", - "$libaddressinput_dir/cpp/src/address_metadata.cc", - "$libaddressinput_dir/cpp/src/address_problem.cc", - "$libaddressinput_dir/cpp/src/language.cc", - "$libaddressinput_dir/cpp/src/language.h", - "$libaddressinput_dir/cpp/src/region_data_constants.cc", - "$libaddressinput_dir/cpp/src/region_data_constants.h", - "$libaddressinput_dir/cpp/src/rule.cc", - "$libaddressinput_dir/cpp/src/rule.h", - "$libaddressinput_dir/cpp/src/util/canonicalize_string.h", - "$libaddressinput_dir/cpp/src/util/cctype_tolower_equal.cc", - "$libaddressinput_dir/cpp/src/util/cctype_tolower_equal.h", - "$libaddressinput_dir/cpp/src/util/json.h", - "$libaddressinput_dir/cpp/src/util/stl_util.h", - "$libaddressinput_dir/cpp/src/util/string_util.cc", - "$libaddressinput_dir/cpp/src/util/string_util.h", + ] + sources -= [ + "src/cpp/src/util/json.cc", ] + configs -= [ "//build/config/compiler:chromium_code" ] + configs += [ "//build/config/compiler:no_chromium_code" ] + direct_dependent_configs = [ ":libaddressinput_config" ] - include_dirs = [ "$root_gen_dir/libaddressinput" ] + + include_dirs = [ "$root_gen_dir/third_party/libaddressinput" ] deps = [ + ":strings", "//base", "//base:i18n", "//third_party/icu", @@ -79,41 +78,28 @@ static_library("util") { # for validation rules. # GYP version: third_party/libaddressinput/libaddressinput.gyp:libaddressinput static_library("libaddressinput") { - sources = [ + sources = rebase_path(gypi_values.libaddressinput_files, ".", "src/cpp") + sources += [ + "chromium/chrome_address_validator.cc", "chromium/chrome_downloader_impl.cc", - "chromium/chrome_downloader_impl.h", "chromium/chrome_storage_impl.cc", - "chromium/chrome_storage_impl.h", - "$libaddressinput_dir/cpp/include/libaddressinput/address_ui_component.h", - "$libaddressinput_dir/cpp/include/libaddressinput/address_ui.h", - "$libaddressinput_dir/cpp/include/libaddressinput/address_validator.h", - "$libaddressinput_dir/cpp/include/libaddressinput/load_rules_delegate.h", - "$libaddressinput_dir/cpp/src/address_ui.cc", - "$libaddressinput_dir/cpp/src/address_validator.cc", - "$libaddressinput_dir/cpp/src/country_rules_aggregator.cc", - "$libaddressinput_dir/cpp/src/country_rules_aggregator.h", - "$libaddressinput_dir/cpp/src/fallback_data_store.cc", - "$libaddressinput_dir/cpp/src/fallback_data_store.h", - "$libaddressinput_dir/cpp/src/grit.h", - "$libaddressinput_dir/cpp/src/retriever.cc", - "$libaddressinput_dir/cpp/src/retriever.h", - "$libaddressinput_dir/cpp/src/ruleset.cc", - "$libaddressinput_dir/cpp/src/ruleset.h", - "$libaddressinput_dir/cpp/src/util/md5.cc", - "$libaddressinput_dir/cpp/src/util/md5.h", - "$libaddressinput_dir/cpp/src/util/trie.cc", - "$libaddressinput_dir/cpp/src/util/trie.h", + "chromium/fallback_data_store.cc", + "chromium/input_suggester.cc", + "chromium/string_compare.cc", + "chromium/trie.cc", + ] + sources -= libaddressinput_util_files + sources -= [ + "src/cpp/src/util/string_compare.cc", ] - direct_dependent_configs = [ ":libaddressinput_config" ] + configs -= [ "//build/config/compiler:chromium_code" ] + configs += [ "//build/config/compiler:no_chromium_code" ] - defines = [ - "VALIDATION_DATA_URL=\"https://i18napis.appspot.com/ssl-aggregate-address/\"", - ] + direct_dependent_configs = [ ":libaddressinput_config" ] deps = [ ":strings", - ":updated_strings", ":util", "//base", "//base:i18n", @@ -123,42 +109,27 @@ static_library("libaddressinput") { } test("libaddressinput_unittests") { - sources = [ + sources = rebase_path(gypi_values.libaddressinput_test_files, ".", "src/cpp") + sources += [ "chromium/addressinput_util_unittest.cc", + "chromium/chrome_address_validator_unittest.cc", "chromium/chrome_downloader_impl_unittest.cc", - "chromium/chrome_rule_test.cc", "chromium/chrome_storage_impl_unittest.cc", - "$libaddressinput_dir/cpp/test/address_data_test.cc", - "$libaddressinput_dir/cpp/test/address_ui_test.cc", - "$libaddressinput_dir/cpp/test/address_validator_test.cc", - "$libaddressinput_dir/cpp/test/country_rules_aggregator_test.cc", - "$libaddressinput_dir/cpp/test/countryinfo_example_addresses_test.cc", - "$libaddressinput_dir/cpp/test/fake_downloader.cc", - "$libaddressinput_dir/cpp/test/fake_downloader.h", - "$libaddressinput_dir/cpp/test/fake_downloader_test.cc", - "$libaddressinput_dir/cpp/test/fake_storage.cc", - "$libaddressinput_dir/cpp/test/fake_storage.h", - "$libaddressinput_dir/cpp/test/fake_storage_test.cc", - "$libaddressinput_dir/cpp/test/fallback_data_store_test.cc", - "$libaddressinput_dir/cpp/test/region_data_constants_test.cc", - "$libaddressinput_dir/cpp/test/retriever_test.cc", - "$libaddressinput_dir/cpp/test/rule_test.cc", - "$libaddressinput_dir/cpp/test/storage_test_runner.cc", - "$libaddressinput_dir/cpp/test/storage_test_runner.h", - "$libaddressinput_dir/cpp/test/util/json_test.cc", - "$libaddressinput_dir/cpp/test/util/md5_unittest.cc", - "$libaddressinput_dir/cpp/test/util/scoped_ptr_unittest.cc", - "$libaddressinput_dir/cpp/test/util/stl_util_unittest.cc", - "$libaddressinput_dir/cpp/test/util/string_util_test.cc", - "$libaddressinput_dir/cpp/test/util/trie_test.cc", + "chromium/fallback_data_store_unittest.cc", + "chromium/storage_test_runner.cc", + "chromium/string_compare_unittest.cc", + "chromium/trie_unittest.cc", ] + configs -= [ "//build/config/compiler:chromium_code" ] + configs += [ "//build/config/compiler:no_chromium_code" ] + defines = [ "TEST_DATA_DIR=\"third_party/libaddressinput/src/testdata\"", ] include_dirs = [ - "$libaddressinput_dir/cpp/src", + "src/cpp/src", ] deps = [ diff --git a/third_party/libaddressinput/README.chromium b/third_party/libaddressinput/README.chromium index 348c121..aa5496a 100644 --- a/third_party/libaddressinput/README.chromium +++ b/third_party/libaddressinput/README.chromium @@ -2,8 +2,8 @@ Name: The library to input, validate, and display addresses. Short Name: libaddressinput URL: https://code.google.com/p/libaddressinput/ Version: 0 -Date: 7 July 2014 -Revision: 300 +Date: 10 July 2014 +Revision: 304 License: Apache 2.0 License File: LICENSE Security Critical: no @@ -17,9 +17,5 @@ https://i18napis.appspot.com/ssl-aggregate-address. The library is used in requestAutocomplete dialog and autofill. Local Modifications: -- The package is libaddressinput at revision 176 plus the Chrome-specific - validation logic, which will be upstreamed back to libaddressinput - (http://crbug.com/327046). The Chrome-specific version is in chromium/cpp/ - subdirectory. The original source code is in src/cpp/ subdirectory. Both - versions use the original test data file src/testdata/countryinfo.txt. -- Serbia and Montenegro (YU) was removed as a supported region. +- Use Chrome's version of JSON reader in chromium/json.cc. +- Use Chrome's version of loose string comparison in chromium/string_compare.cc. diff --git a/third_party/libaddressinput/chromium/addressinput_util.cc b/third_party/libaddressinput/chromium/addressinput_util.cc index 3af6137..d9e6725 100644 --- a/third_party/libaddressinput/chromium/addressinput_util.cc +++ b/third_party/libaddressinput/chromium/addressinput_util.cc @@ -8,8 +8,8 @@ #include "base/logging.h" #include "base/macros.h" -#include "third_party/libaddressinput/chromium/cpp/include/libaddressinput/address_data.h" -#include "third_party/libaddressinput/chromium/cpp/include/libaddressinput/address_metadata.h" +#include "third_party/libaddressinput/src/cpp/include/libaddressinput/address_data.h" +#include "third_party/libaddressinput/src/cpp/include/libaddressinput/address_metadata.h" namespace autofill { namespace addressinput { @@ -21,32 +21,32 @@ using ::i18n::addressinput::AddressField; using ::i18n::addressinput::AddressProblem; using ::i18n::addressinput::IsFieldRequired; +using ::i18n::addressinput::MISSING_REQUIRED_FIELD; + // Returns true if the |problem| should not be reported for the |field| because // the |filter| excludes it. -bool FilterExcludes( - const std::multimap<AddressField, AddressProblem::Type>* filter, - AddressField field, - AddressProblem::Type problem) { +bool FilterExcludes(const std::multimap<AddressField, AddressProblem>* filter, + AddressField field, + AddressProblem problem) { return filter != NULL && !filter->empty() && - std::find( - filter->begin(), - filter->end(), - std::multimap<AddressField, AddressProblem::Type>::value_type( - field, problem)) == filter->end(); + std::find(filter->begin(), + filter->end(), + std::multimap<AddressField, AddressProblem>::value_type( + field, problem)) == filter->end(); } } // namespace bool HasAllRequiredFields(const AddressData& address_to_check) { - std::multimap<AddressField, AddressProblem::Type> problems; + std::multimap<AddressField, AddressProblem> problems; ValidateRequiredFields(address_to_check, NULL, &problems); return problems.empty(); } void ValidateRequiredFields( const AddressData& address_to_check, - const std::multimap<AddressField, AddressProblem::Type>* filter, - std::multimap<AddressField, AddressProblem::Type>* problems) { + const std::multimap<AddressField, AddressProblem>* filter, + std::multimap<AddressField, AddressProblem>* problems) { DCHECK(problems); static const AddressField kFields[] = { @@ -63,10 +63,8 @@ void ValidateRequiredFields( AddressField field = kFields[i]; if (address_to_check.IsFieldEmpty(field) && IsFieldRequired(field, address_to_check.region_code) && - !FilterExcludes( - filter, field, AddressProblem::MISSING_REQUIRED_FIELD)) { - problems->insert( - std::make_pair(field, AddressProblem::MISSING_REQUIRED_FIELD)); + !FilterExcludes(filter, field, MISSING_REQUIRED_FIELD)) { + problems->insert(std::make_pair(field, MISSING_REQUIRED_FIELD)); } } } diff --git a/third_party/libaddressinput/chromium/addressinput_util.h b/third_party/libaddressinput/chromium/addressinput_util.h index e3bdaa4..7c888a7 100644 --- a/third_party/libaddressinput/chromium/addressinput_util.h +++ b/third_party/libaddressinput/chromium/addressinput_util.h @@ -7,8 +7,8 @@ #include <map> -#include "third_party/libaddressinput/chromium/cpp/include/libaddressinput/address_field.h" -#include "third_party/libaddressinput/chromium/cpp/include/libaddressinput/address_problem.h" +#include "third_party/libaddressinput/src/cpp/include/libaddressinput/address_field.h" +#include "third_party/libaddressinput/src/cpp/include/libaddressinput/address_problem.h" namespace i18n { namespace addressinput { @@ -32,9 +32,9 @@ bool HasAllRequiredFields( void ValidateRequiredFields( const ::i18n::addressinput::AddressData& address_to_check, const std::multimap< ::i18n::addressinput::AddressField, - ::i18n::addressinput::AddressProblem::Type>* filter, + ::i18n::addressinput::AddressProblem>* filter, std::multimap< ::i18n::addressinput::AddressField, - ::i18n::addressinput::AddressProblem::Type>* problems); + ::i18n::addressinput::AddressProblem>* problems); } // namespace addressinput } // namespace autofill diff --git a/third_party/libaddressinput/chromium/addressinput_util_unittest.cc b/third_party/libaddressinput/chromium/addressinput_util_unittest.cc index 846f3d4..b68ea81 100644 --- a/third_party/libaddressinput/chromium/addressinput_util_unittest.cc +++ b/third_party/libaddressinput/chromium/addressinput_util_unittest.cc @@ -5,7 +5,7 @@ #include "third_party/libaddressinput/chromium/addressinput_util.h" #include "testing/gtest/include/gtest/gtest.h" -#include "third_party/libaddressinput/chromium/cpp/include/libaddressinput/address_data.h" +#include "third_party/libaddressinput/src/cpp/include/libaddressinput/address_data.h" namespace autofill { namespace addressinput { diff --git a/third_party/libaddressinput/chromium/chrome_address_validator.cc b/third_party/libaddressinput/chromium/chrome_address_validator.cc new file mode 100644 index 0000000..b54c74d --- /dev/null +++ b/third_party/libaddressinput/chromium/chrome_address_validator.cc @@ -0,0 +1,154 @@ +// 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 "third_party/libaddressinput/chromium/chrome_address_validator.h" + +#include <cstddef> +#include <string> +#include <vector> + +#include "base/basictypes.h" +#include "base/logging.h" +#include "base/macros.h" +#include "base/memory/scoped_ptr.h" +#include "third_party/libaddressinput/chromium/input_suggester.h" +#include "third_party/libaddressinput/chromium/libaddressinput_util.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_normalizer.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" + +namespace autofill { + +using ::i18n::addressinput::AddressData; +using ::i18n::addressinput::AddressField; +using ::i18n::addressinput::AddressNormalizer; +using ::i18n::addressinput::BuildCallback; +using ::i18n::addressinput::Downloader; +using ::i18n::addressinput::FieldProblemMap; +using ::i18n::addressinput::PreloadSupplier; +using ::i18n::addressinput::Storage; + +using ::i18n::addressinput::ADMIN_AREA; +using ::i18n::addressinput::DEPENDENT_LOCALITY; +using ::i18n::addressinput::POSTAL_CODE; + +AddressValidator::AddressValidator(const std::string& validation_data_url, + scoped_ptr<Downloader> downloader, + scoped_ptr<Storage> storage, + LoadRulesListener* load_rules_listener) + : supplier_(new PreloadSupplier(validation_data_url, + downloader.release(), + storage.release())), + input_suggester_(new InputSuggester(supplier_.get())), + normalizer_(new AddressNormalizer(supplier_.get())), + validator_(new ::i18n::addressinput::AddressValidator(supplier_.get())), + validated_(BuildCallback(this, &AddressValidator::Validated)), + rules_loaded_(BuildCallback(this, &AddressValidator::RulesLoaded)), + load_rules_listener_(load_rules_listener) {} + +AddressValidator::~AddressValidator() {} + +void AddressValidator::LoadRules(const std::string& region_code) { + DCHECK(supplier_); + supplier_->LoadRules(region_code, *rules_loaded_); +} + +AddressValidator::Status AddressValidator::ValidateAddress( + const AddressData& address, + const FieldProblemMap* filter, + FieldProblemMap* problems) const { + DCHECK(supplier_); + DCHECK(validator_); + + if (supplier_->IsPending(address.region_code)) { + if (problems) + addressinput::ValidateRequiredFields(address, filter, problems); + return RULES_NOT_READY; + } + + if (!supplier_->IsLoaded(address.region_code)) { + if (problems) + addressinput::ValidateRequiredFields(address, filter, problems); + return RULES_UNAVAILABLE; + } + + if (!problems) + return SUCCESS; + + validator_->Validate(address, + true, // Allow postal office boxes. + true, // Require recipient name. + filter, + problems, + *validated_); + + return SUCCESS; +} + +AddressValidator::Status AddressValidator::GetSuggestions( + const AddressData& user_input, + AddressField focused_field, + size_t suggestion_limit, + std::vector<AddressData>* suggestions) const { + DCHECK(supplier_); + DCHECK(input_suggester_); + + if (supplier_->IsPending(user_input.region_code)) + return RULES_NOT_READY; + + if (!supplier_->IsLoaded(user_input.region_code)) + return RULES_UNAVAILABLE; + + if (!suggestions) + return SUCCESS; + + suggestions->clear(); + + if (focused_field == POSTAL_CODE || + (focused_field >= ADMIN_AREA && focused_field <= DEPENDENT_LOCALITY)) { + input_suggester_->GetSuggestions( + user_input, focused_field, suggestion_limit, suggestions); + } + + return SUCCESS; +} + +bool AddressValidator::CanonicalizeAdministrativeArea( + AddressData* address) const { + DCHECK(address); + DCHECK(supplier_); + DCHECK(normalizer_); + + if (!supplier_->IsLoaded(address->region_code)) + return false; + + // TODO: It would probably be beneficial to use the full canonicalization. + AddressData tmp(*address); + normalizer_->Normalize(&tmp); + address->administrative_area = tmp.administrative_area; + + return true; +} + +AddressValidator::AddressValidator() : load_rules_listener_(NULL) {} + +void AddressValidator::Validated(bool success, + const AddressData&, + const FieldProblemMap&) { + DCHECK(success); +} + +void AddressValidator::RulesLoaded(bool success, + const std::string& country_code, + int) { + if (load_rules_listener_) + load_rules_listener_->OnAddressValidationRulesLoaded(country_code, success); +} + +} // namespace autofill diff --git a/third_party/libaddressinput/chromium/preload_address_validator.h b/third_party/libaddressinput/chromium/chrome_address_validator.h index 8b22040..49875c8 100644 --- a/third_party/libaddressinput/chromium/preload_address_validator.h +++ b/third_party/libaddressinput/chromium/chrome_address_validator.h @@ -2,8 +2,8 @@ // 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_ +#ifndef THIRD_PARTY_LIBADDRESSINPUT_CHROMIUM_CHROME_ADDRESS_VALIDATOR_H_ +#define THIRD_PARTY_LIBADDRESSINPUT_CHROMIUM_CHROME_ADDRESS_VALIDATOR_H_ #include <cstddef> #include <string> @@ -14,28 +14,49 @@ #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" +#include "third_party/libaddressinput/src/cpp/include/libaddressinput/preload_supplier.h" namespace i18n { namespace addressinput { - +class AddressNormalizer; class Downloader; -class PreloadSupplier; class Storage; -class Synonyms; struct AddressData; - -} // namespace addressinput -} // namespace i18n +} +} namespace autofill { -class Suggestions; +class InputSuggester; -// Interface to the libaddressinput AddressValidator for Chromium Autofill. -class PreloadAddressValidator { +// The object to be notified when loading of address validation rules is +// finished. +class LoadRulesListener { public: - typedef ::i18n::addressinput::Callback<std::string, int> Callback; + virtual ~LoadRulesListener() {} + + // Called when the validation rules for the |country_code| have been loaded. + // The validation rules include the generic rules for the |country_code| and + // specific rules for the country's administrative areas, localities, and + // dependent localities. If a country has language-specific validation rules, + // then these are also loaded. + // + // The |success| parameter is true when the rules were loaded successfully. + virtual void OnAddressValidationRulesLoaded(const std::string& country_code, + bool success) = 0; +}; +// Interface to the libaddressinput AddressValidator for Chromium Autofill. The +// class is named AddressValidator to simplify switching between libaddressinput +// and this version. +// +// It's not possible to name this file address_validator.h because some +// compilers do not handle multiple files with the same name (although in +// different directories) gracefully. This class is a shim between upstream +// libaddressinput API and the API that Chrome expects, hence the file name +// chrome_address_validator.h. +class AddressValidator { + public: // The status of address validation. enum Status { // Address validation completed successfully. Check |problems| to see if any @@ -51,15 +72,15 @@ class PreloadAddressValidator { }; // 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); + AddressValidator(const std::string& validation_data_url, + scoped_ptr< ::i18n::addressinput::Downloader> downloader, + scoped_ptr< ::i18n::addressinput::Storage> storage, + LoadRulesListener* load_rules_listener); - virtual ~PreloadAddressValidator(); + virtual ~AddressValidator(); // Loads the generic validation rules for |region_code| and specific rules - // for the regions's administrative areas, localities, and dependent + // for the region'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. // @@ -67,9 +88,8 @@ class PreloadAddressValidator { // 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); + // Invokes |load_rules_listener| when the loading has finished. + virtual void LoadRules(const std::string& region_code); // Validates the |address| and populates |problems| with the validation // problems, filtered according to the |filter| parameter. @@ -77,7 +97,7 @@ class PreloadAddressValidator { // 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( + virtual Status ValidateAddress( const ::i18n::addressinput::AddressData& address, const ::i18n::addressinput::FieldProblemMap* filter, ::i18n::addressinput::FieldProblemMap* problems) const; @@ -119,23 +139,48 @@ class PreloadAddressValidator { ::i18n::addressinput::AddressData* address) const; private: + friend class MockAddressValidator; + + // Constructor used only for MockAddressValidator. + AddressValidator(); + + // Verifies that |validator_| succeeded. Invoked by |validated_| callback. void Validated(bool success, const ::i18n::addressinput::AddressData&, const ::i18n::addressinput::FieldProblemMap&); + // Invokes the |load_rules_listener_|, if it's not NULL. Called by + // |rules_loaded_| callback. + void RulesLoaded(bool success, const std::string& country_code, int); + + // Loads and stores aggregate rules at COUNTRY level. const scoped_ptr< ::i18n::addressinput::PreloadSupplier> supplier_; - const scoped_ptr<Suggestions> suggestions_; - const scoped_ptr< ::i18n::addressinput::Synonyms> synonyms_; + + // Suggests addresses based on user input. + const scoped_ptr<InputSuggester> input_suggester_; + + // Normalizes addresses into a canonical form. + const scoped_ptr< ::i18n::addressinput::AddressNormalizer> normalizer_; + + // Validates addresses. const scoped_ptr<const ::i18n::addressinput::AddressValidator> validator_; + + // The callback that |validator_| invokes when it finished validating an + // address. const scoped_ptr<const ::i18n::addressinput::AddressValidator::Callback> validated_; - friend class MockAddressValidator; - PreloadAddressValidator(); + // The callback that |supplier_| invokes when it finished loading rules. + const scoped_ptr<const ::i18n::addressinput::PreloadSupplier::Callback> + rules_loaded_; + + // Not owned delegate to invoke when |suppler_| finished loading rules. Can be + // NULL. + LoadRulesListener* const load_rules_listener_; - DISALLOW_COPY_AND_ASSIGN(PreloadAddressValidator); + DISALLOW_COPY_AND_ASSIGN(AddressValidator); }; } // namespace autofill -#endif // THIRD_PARTY_LIBADDRESSINPUT_CHROMIUM_PRELOAD_ADDRESS_VALIDATOR_H_ +#endif // THIRD_PARTY_LIBADDRESSINPUT_CHROMIUM_CHROME_ADDRESS_VALIDATOR_H_ diff --git a/third_party/libaddressinput/chromium/preload_address_validator_unittest.cc b/third_party/libaddressinput/chromium/chrome_address_validator_unittest.cc index 1cc7aaf..906d0a6 100644 --- a/third_party/libaddressinput/chromium/preload_address_validator_unittest.cc +++ b/third_party/libaddressinput/chromium/chrome_address_validator_unittest.cc @@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "third_party/libaddressinput/chromium/chrome_address_validator.h" + #include <cstddef> #include <string> #include <vector> @@ -10,31 +12,30 @@ #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_ui.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 ::autofill::AddressValidator; +using ::autofill::LoadRulesListener; using ::i18n::addressinput::AddressData; using ::i18n::addressinput::AddressField; +using ::i18n::addressinput::AddressProblem; using ::i18n::addressinput::BuildCallback; using ::i18n::addressinput::Downloader; using ::i18n::addressinput::FakeDownloader; using ::i18n::addressinput::FieldProblemMap; +using ::i18n::addressinput::GetRegionCodes; using ::i18n::addressinput::NullStorage; -using ::i18n::addressinput::RegionDataConstants; using ::i18n::addressinput::Storage; using ::i18n::addressinput::COUNTRY; @@ -46,69 +47,113 @@ 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; +using ::i18n::addressinput::MISSING_REQUIRED_FIELD; +using ::i18n::addressinput::UNEXPECTED_FIELD; +using ::i18n::addressinput::UNKNOWN_VALUE; +using ::i18n::addressinput::USES_P_O_BOX; -class PreloadAddressValidatorTest : public testing::Test { +class AddressValidatorTest : public testing::Test, LoadRulesListener { protected: - PreloadAddressValidatorTest() + AddressValidatorTest() : validator_( - new PreloadAddressValidator( - FakeDownloader::kFakeAggregateDataUrl, - scoped_ptr<Downloader>(new FakeDownloader), - scoped_ptr<Storage>(new NullStorage))), - loaded_(BuildCallback(this, &PreloadAddressValidatorTest::Loaded)) { - validator_->LoadRules("US", *loaded_); + new AddressValidator(FakeDownloader::kFakeAggregateDataUrl, + scoped_ptr<Downloader>(new FakeDownloader), + scoped_ptr<Storage>(new NullStorage), + this)) { + validator_->LoadRules("US"); } - virtual ~PreloadAddressValidatorTest() {} + virtual ~AddressValidatorTest() {} - const scoped_ptr<PreloadAddressValidator> validator_; - const scoped_ptr<PreloadAddressValidator::Callback> loaded_; + const scoped_ptr<AddressValidator> validator_; private: - void Loaded(bool success, - const std::string& region_code, - const int& rule_count) { + // LoadRulesListener implementation. + virtual void OnAddressValidationRulesLoaded(const std::string& country_code, + bool success) OVERRIDE { AddressData address_data; - address_data.region_code = region_code; + address_data.region_code = country_code; FieldProblemMap dummy; - PreloadAddressValidator::Status status = - validator_->Validate(address_data, NULL, &dummy); - ASSERT_EQ(success, status == PreloadAddressValidator::SUCCESS); + AddressValidator::Status status = + validator_->ValidateAddress(address_data, NULL, &dummy); + ASSERT_EQ(success, status == AddressValidator::SUCCESS); } - DISALLOW_COPY_AND_ASSIGN(PreloadAddressValidatorTest); + DISALLOW_COPY_AND_ASSIGN(AddressValidatorTest); +}; + +// Use this text fixture if you're going to use a region with a large set of +// validation rules. All rules should be loaded in SetUpTestCase(). +class LargeAddressValidatorTest : public testing::Test { + protected: + LargeAddressValidatorTest() {} + virtual ~LargeAddressValidatorTest() {} + + static void SetUpTestCase() { + validator_ = + new AddressValidator(FakeDownloader::kFakeAggregateDataUrl, + scoped_ptr<Downloader>(new FakeDownloader), + scoped_ptr<Storage>(new NullStorage), + NULL); + validator_->LoadRules("CN"); + validator_->LoadRules("KR"); + validator_->LoadRules("TW"); + } + + static void TearDownTestcase() { + delete validator_; + validator_ = NULL; + } + + // Owned shared instance of validator with large sets validation rules. + static AddressValidator* validator_; + + private: + DISALLOW_COPY_AND_ASSIGN(LargeAddressValidatorTest); }; -TEST_F(PreloadAddressValidatorTest, RegionHasRules) { - const std::vector<std::string>& region_codes = - RegionDataConstants::GetRegionCodes(); +AddressValidator* LargeAddressValidatorTest::validator_ = NULL; + +TEST_F(AddressValidatorTest, RegionHasRules) { + const std::vector<std::string>& region_codes = 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_); + validator_->LoadRules(region_codes[i]); address.region_code = region_codes[i]; FieldProblemMap dummy; - EXPECT_EQ( - PreloadAddressValidator::SUCCESS, - validator_->Validate(address, NULL, &dummy)); + EXPECT_EQ(AddressValidator::SUCCESS, + validator_->ValidateAddress(address, NULL, &dummy)); } } -TEST_F(PreloadAddressValidatorTest, EmptyAddressNoFatalFailure) { +TEST_F(AddressValidatorTest, EmptyAddressNoFatalFailure) { AddressData address; address.region_code = "US"; FieldProblemMap dummy; - EXPECT_EQ( - PreloadAddressValidator::SUCCESS, - validator_->Validate(address, NULL, &dummy)); + EXPECT_EQ(AddressValidator::SUCCESS, + validator_->ValidateAddress(address, NULL, &dummy)); } -TEST_F(PreloadAddressValidatorTest, USZipCode) { +TEST_F(AddressValidatorTest, UsStateNamesAreValidEntries) { AddressData address; + address.region_code = "US"; + address.administrative_area = "California"; + + FieldProblemMap filter; + filter.insert(std::make_pair(ADMIN_AREA, UNKNOWN_VALUE)); + FieldProblemMap problems; + EXPECT_EQ(AddressValidator::SUCCESS, + validator_->ValidateAddress(address, &filter, &problems)); + EXPECT_TRUE(problems.empty()); +} + +TEST_F(AddressValidatorTest, USZipCode) { + AddressData address; + address.recipient = "Mr. Smith"; address.address_line.push_back("340 Main St."); address.locality = "Venice"; address.administrative_area = "CA"; @@ -117,27 +162,24 @@ TEST_F(PreloadAddressValidatorTest, USZipCode) { // Valid Californian zip code. address.postal_code = "90291"; FieldProblemMap problems; - EXPECT_EQ( - PreloadAddressValidator::SUCCESS, - validator_->Validate(address, NULL, &problems)); + EXPECT_EQ(AddressValidator::SUCCESS, + validator_->ValidateAddress(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_EQ(AddressValidator::SUCCESS, + validator_->ValidateAddress(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(AddressValidator::SUCCESS, + validator_->ValidateAddress(address, NULL, &problems)); EXPECT_EQ(1U, problems.size()); EXPECT_EQ(problems.begin()->first, POSTAL_CODE); EXPECT_EQ(problems.begin()->second, MISMATCHING_VALUE); @@ -146,9 +188,8 @@ TEST_F(PreloadAddressValidatorTest, USZipCode) { // A zip code with a "90" in the middle. address.postal_code = "12903"; - EXPECT_EQ( - PreloadAddressValidator::SUCCESS, - validator_->Validate(address, NULL, &problems)); + EXPECT_EQ(AddressValidator::SUCCESS, + validator_->ValidateAddress(address, NULL, &problems)); EXPECT_EQ(1U, problems.size()); EXPECT_EQ(problems.begin()->first, POSTAL_CODE); EXPECT_EQ(problems.begin()->second, MISMATCHING_VALUE); @@ -157,9 +198,8 @@ TEST_F(PreloadAddressValidatorTest, USZipCode) { // Invalid zip code (too many digits). address.postal_code = "902911"; - EXPECT_EQ( - PreloadAddressValidator::SUCCESS, - validator_->Validate(address, NULL, &problems)); + EXPECT_EQ(AddressValidator::SUCCESS, + validator_->ValidateAddress(address, NULL, &problems)); EXPECT_EQ(1U, problems.size()); EXPECT_EQ(problems.begin()->first, POSTAL_CODE); EXPECT_EQ(problems.begin()->second, INVALID_FORMAT); @@ -168,19 +208,16 @@ TEST_F(PreloadAddressValidatorTest, USZipCode) { // Invalid zip code (too few digits). address.postal_code = "9029"; - EXPECT_EQ( - PreloadAddressValidator::SUCCESS, - validator_->Validate(address, NULL, &problems)); + EXPECT_EQ(AddressValidator::SUCCESS, + validator_->ValidateAddress(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) { +TEST_F(AddressValidatorTest, BasicValidation) { // US rules should always be available, even though this load call fails. - validator_->LoadRules("US", *loaded_); + validator_->LoadRules("US"); AddressData address; address.region_code = "US"; address.language_code = "en"; @@ -188,48 +225,44 @@ TEST_F(PreloadAddressValidatorTest, DISABLED_BasicValidation) { address.locality = "Paris"; address.postal_code = "75461"; address.address_line.push_back("123 Main St"); + address.recipient = "Mr. Smith"; FieldProblemMap problems; - EXPECT_EQ( - PreloadAddressValidator::SUCCESS, - validator_->Validate(address, NULL, &problems)); + EXPECT_EQ(AddressValidator::SUCCESS, + validator_->ValidateAddress(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_EQ(AddressValidator::SUCCESS, + validator_->ValidateAddress(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_EQ(AddressValidator::SUCCESS, + validator_->ValidateAddress(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_EQ(AddressValidator::SUCCESS, + validator_->ValidateAddress(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_EQ(AddressValidator::SUCCESS, + validator_->ValidateAddress(address, NULL, &problems)); EXPECT_TRUE(problems.empty()); } -TEST_F(PreloadAddressValidatorTest, BasicValidationFailure) { +TEST_F(AddressValidatorTest, BasicValidationFailure) { // US rules should always be available, even though this load call fails. - validator_->LoadRules("US", *loaded_); + validator_->LoadRules("US"); AddressData address; address.region_code = "US"; address.language_code = "en"; @@ -237,45 +270,45 @@ TEST_F(PreloadAddressValidatorTest, BasicValidationFailure) { address.locality = "Paris"; address.postal_code = "75461"; address.address_line.push_back("123 Main St"); + address.recipient = "Mr. Smith"; FieldProblemMap problems; - EXPECT_EQ( - PreloadAddressValidator::SUCCESS, - validator_->Validate(address, NULL, &problems)); + EXPECT_EQ(AddressValidator::SUCCESS, + validator_->ValidateAddress(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) { +TEST_F(AddressValidatorTest, NoNullSuggestionsCrash) { AddressData address; address.region_code = "US"; - EXPECT_EQ(PreloadAddressValidator::SUCCESS, + EXPECT_EQ(AddressValidator::SUCCESS, validator_->GetSuggestions(address, COUNTRY, 1, NULL)); } -TEST_F(PreloadAddressValidatorTest, SuggestAdminAreaForPostalCode) { +TEST_F(AddressValidatorTest, SuggestAdminAreaForPostalCode) { AddressData address; address.region_code = "US"; address.postal_code = "90291"; std::vector<AddressData> suggestions; - EXPECT_EQ(PreloadAddressValidator::SUCCESS, + EXPECT_EQ(AddressValidator::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_); +TEST_F(LargeAddressValidatorTest, SuggestLocalityForPostalCodeWithAdminArea) { AddressData address; address.region_code = "TW"; address.postal_code = "515"; address.administrative_area = "Changhua"; + address.language_code = "zh-Latn"; std::vector<AddressData> suggestions; - EXPECT_EQ(PreloadAddressValidator::SUCCESS, + EXPECT_EQ(AddressValidator::SUCCESS, validator_->GetSuggestions(address, POSTAL_CODE, 1, &suggestions)); ASSERT_EQ(1U, suggestions.size()); EXPECT_EQ("Dacun Township", suggestions[0].locality); @@ -283,15 +316,15 @@ TEST_F(PreloadAddressValidatorTest, SuggestLocalityForPostalCodeWithAdminArea) { EXPECT_EQ("515", suggestions[0].postal_code); } -TEST_F(PreloadAddressValidatorTest, SuggestAdminAreaForPostalCodeWithLocality) { - validator_->LoadRules("TW", *loaded_); +TEST_F(LargeAddressValidatorTest, SuggestAdminAreaForPostalCodeWithLocality) { AddressData address; address.region_code = "TW"; address.postal_code = "515"; address.locality = "Dacun"; + address.language_code = "zh-Latn"; std::vector<AddressData> suggestions; - EXPECT_EQ(PreloadAddressValidator::SUCCESS, + EXPECT_EQ(AddressValidator::SUCCESS, validator_->GetSuggestions(address, POSTAL_CODE, 1, &suggestions)); ASSERT_EQ(1U, suggestions.size()); EXPECT_EQ("Dacun Township", suggestions[0].locality); @@ -299,149 +332,149 @@ TEST_F(PreloadAddressValidatorTest, SuggestAdminAreaForPostalCodeWithLocality) { EXPECT_EQ("515", suggestions[0].postal_code); } -TEST_F(PreloadAddressValidatorTest, NoSuggestForPostalCodeWithWrongAdminArea) { +TEST_F(AddressValidatorTest, NoSuggestForPostalCodeWithWrongAdminArea) { AddressData address; address.region_code = "US"; address.postal_code = "90066"; address.postal_code = "TX"; std::vector<AddressData> suggestions; - EXPECT_EQ(PreloadAddressValidator::SUCCESS, + EXPECT_EQ(AddressValidator::SUCCESS, validator_->GetSuggestions(address, POSTAL_CODE, 1, &suggestions)); EXPECT_TRUE(suggestions.empty()); } -TEST_F(PreloadAddressValidatorTest, SuggestForLocality) { - validator_->LoadRules("CN", *loaded_); +TEST_F(LargeAddressValidatorTest, SuggestForLocality) { AddressData address; address.region_code = "CN"; address.locality = "Anqin"; + address.language_code = "zh-Latn"; std::vector<AddressData> suggestions; - EXPECT_EQ(PreloadAddressValidator::SUCCESS, + EXPECT_EQ(AddressValidator::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); + EXPECT_EQ("Anhui Sheng", suggestions[0].administrative_area); } -TEST_F(PreloadAddressValidatorTest, SuggestForLocalityAndAdminArea) { - validator_->LoadRules("CN", *loaded_); +TEST_F(LargeAddressValidatorTest, SuggestForLocalityAndAdminArea) { AddressData address; address.region_code = "CN"; address.locality = "Anqing"; address.administrative_area = "Anhui"; + address.language_code = "zh-Latn"; std::vector<AddressData> suggestions; - EXPECT_EQ(PreloadAddressValidator::SUCCESS, + EXPECT_EQ(AddressValidator::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); + EXPECT_EQ("Anhui Sheng", suggestions[0].administrative_area); } -TEST_F(PreloadAddressValidatorTest, SuggestForAdminAreaAndLocality) { - validator_->LoadRules("CN", *loaded_); +TEST_F(LargeAddressValidatorTest, SuggestForAdminAreaAndLocality) { AddressData address; address.region_code = "CN"; address.locality = "Anqing"; address.administrative_area = "Anhui"; + address.language_code = "zh-Latn"; std::vector<AddressData> suggestions; - EXPECT_EQ(PreloadAddressValidator::SUCCESS, + EXPECT_EQ(AddressValidator::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); + EXPECT_EQ("Anhui Sheng", suggestions[0].administrative_area); } -TEST_F(PreloadAddressValidatorTest, SuggestForDependentLocality) { - validator_->LoadRules("CN", *loaded_); +TEST_F(LargeAddressValidatorTest, SuggestForDependentLocality) { AddressData address; address.region_code = "CN"; address.dependent_locality = "Zongyang"; + address.language_code = "zh-Latn"; std::vector<AddressData> suggestions; - EXPECT_EQ(PreloadAddressValidator::SUCCESS, + EXPECT_EQ(AddressValidator::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); + EXPECT_EQ("Anhui Sheng", suggestions[0].administrative_area); } -TEST_F(PreloadAddressValidatorTest, +TEST_F(LargeAddressValidatorTest, NoSuggestForDependentLocalityWithWrongAdminArea) { - validator_->LoadRules("CN", *loaded_); AddressData address; address.region_code = "CN"; address.dependent_locality = "Zongyang"; address.administrative_area = "Sichuan Sheng"; + address.language_code = "zh-Latn"; std::vector<AddressData> suggestions; - EXPECT_EQ(PreloadAddressValidator::SUCCESS, + EXPECT_EQ(AddressValidator::SUCCESS, validator_->GetSuggestions( address, DEPENDENT_LOCALITY, 10, &suggestions)); EXPECT_TRUE(suggestions.empty()); } -TEST_F(PreloadAddressValidatorTest, EmptySuggestionsOverLimit) { +TEST_F(AddressValidatorTest, EmptySuggestionsOverLimit) { AddressData address; address.region_code = "US"; address.administrative_area = "A"; std::vector<AddressData> suggestions; - EXPECT_EQ(PreloadAddressValidator::SUCCESS, + EXPECT_EQ(AddressValidator::SUCCESS, validator_->GetSuggestions(address, ADMIN_AREA, 1, &suggestions)); EXPECT_TRUE(suggestions.empty()); } -TEST_F(PreloadAddressValidatorTest, PreferShortSuggestions) { +TEST_F(AddressValidatorTest, PreferShortSuggestions) { AddressData address; address.region_code = "US"; address.administrative_area = "CA"; std::vector<AddressData> suggestions; - EXPECT_EQ(PreloadAddressValidator::SUCCESS, + EXPECT_EQ(AddressValidator::SUCCESS, validator_->GetSuggestions(address, ADMIN_AREA, 10, &suggestions)); ASSERT_EQ(1U, suggestions.size()); EXPECT_EQ("CA", suggestions[0].administrative_area); } -TEST_F(PreloadAddressValidatorTest, SuggestTheSingleMatchForFullMatchName) { +TEST_F(AddressValidatorTest, SuggestTheSingleMatchForFullMatchName) { AddressData address; address.region_code = "US"; address.administrative_area = "Texas"; std::vector<AddressData> suggestions; - EXPECT_EQ(PreloadAddressValidator::SUCCESS, + EXPECT_EQ(AddressValidator::SUCCESS, validator_->GetSuggestions(address, ADMIN_AREA, 10, &suggestions)); ASSERT_EQ(1U, suggestions.size()); EXPECT_EQ("Texas", suggestions[0].administrative_area); } -TEST_F(PreloadAddressValidatorTest, SuggestAdminArea) { +TEST_F(AddressValidatorTest, SuggestAdminArea) { AddressData address; address.region_code = "US"; address.administrative_area = "Cali"; std::vector<AddressData> suggestions; - EXPECT_EQ(PreloadAddressValidator::SUCCESS, + EXPECT_EQ(AddressValidator::SUCCESS, validator_->GetSuggestions(address, ADMIN_AREA, 10, &suggestions)); ASSERT_EQ(1U, suggestions.size()); EXPECT_EQ("California", suggestions[0].administrative_area); } -TEST_F(PreloadAddressValidatorTest, MultipleSuggestions) { +TEST_F(AddressValidatorTest, MultipleSuggestions) { AddressData address; address.region_code = "US"; address.administrative_area = "MA"; std::vector<AddressData> suggestions; - EXPECT_EQ(PreloadAddressValidator::SUCCESS, + EXPECT_EQ(AddressValidator::SUCCESS, validator_->GetSuggestions(address, ADMIN_AREA, 10, &suggestions)); EXPECT_LT(1U, suggestions.size()); @@ -453,96 +486,104 @@ TEST_F(PreloadAddressValidatorTest, MultipleSuggestions) { expected_suggestions.insert("Marshall Islands"); expected_suggestions.insert("Maryland"); for (std::vector<AddressData>::const_iterator it = suggestions.begin(); - it != suggestions.end(); ++it) { + it != suggestions.end(); + ++it) { expected_suggestions.erase(it->administrative_area); } EXPECT_TRUE(expected_suggestions.empty()); } -TEST_F(PreloadAddressValidatorTest, SuggestNonLatinKeyWhenLanguageMatches) { - validator_->LoadRules("KR", *loaded_); +TEST_F(LargeAddressValidatorTest, SuggestNonLatinKeyWhenLanguageMatches) { AddressData address; address.language_code = "ko"; address.region_code = "KR"; address.postal_code = "210-210"; std::vector<AddressData> suggestions; - EXPECT_EQ(PreloadAddressValidator::SUCCESS, + EXPECT_EQ(AddressValidator::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_); +TEST_F(LargeAddressValidatorTest, SuggestNonLatinKeyWhenUserInputIsNotLatin) { AddressData address; address.language_code = "en"; address.region_code = "KR"; address.administrative_area = "강원"; std::vector<AddressData> suggestions; - EXPECT_EQ(PreloadAddressValidator::SUCCESS, + EXPECT_EQ(AddressValidator::SUCCESS, validator_->GetSuggestions(address, ADMIN_AREA, 1, &suggestions)); ASSERT_EQ(1U, suggestions.size()); EXPECT_EQ("강원도", suggestions[0].administrative_area); } -TEST_F(PreloadAddressValidatorTest, +TEST_F(LargeAddressValidatorTest, SuggestLatinNameWhenLanguageDiffersAndLatinNameAvailable) { - validator_->LoadRules("KR", *loaded_); AddressData address; - address.language_code = "en"; + address.language_code = "ko-Latn"; address.region_code = "KR"; address.postal_code = "210-210"; std::vector<AddressData> suggestions; - EXPECT_EQ(PreloadAddressValidator::SUCCESS, + EXPECT_EQ(AddressValidator::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_); +TEST_F(AddressValidatorTest, NoSuggestionsForEmptyAddress) { AddressData address; - address.language_code = "ko"; - address.region_code = "KR"; - address.administrative_area = "Gang"; + address.region_code = "US"; std::vector<AddressData> suggestions; - EXPECT_EQ(PreloadAddressValidator::SUCCESS, - validator_->GetSuggestions(address, ADMIN_AREA, 1, &suggestions)); + EXPECT_EQ( + AddressValidator::SUCCESS, + validator_->GetSuggestions(address, POSTAL_CODE, 999, &suggestions)); + EXPECT_TRUE(suggestions.empty()); +} + +TEST_F(AddressValidatorTest, SuggestionIncludesCountry) { + AddressData address; + address.region_code = "US"; + address.postal_code = "90291"; + + std::vector<AddressData> suggestions; + EXPECT_EQ(AddressValidator::SUCCESS, + validator_->GetSuggestions(address, POSTAL_CODE, 1, &suggestions)); ASSERT_EQ(1U, suggestions.size()); - EXPECT_EQ("Gangwon", suggestions[0].administrative_area); + EXPECT_EQ("US", suggestions[0].region_code); } -TEST_F(PreloadAddressValidatorTest, NoSuggestionsForEmptyAddress) { +TEST_F(AddressValidatorTest, InvalidPostalCodeNoSuggestions) { AddressData address; address.region_code = "US"; + address.postal_code = "0"; std::vector<AddressData> suggestions; EXPECT_EQ( - PreloadAddressValidator::SUCCESS, + AddressValidator::SUCCESS, validator_->GetSuggestions(address, POSTAL_CODE, 999, &suggestions)); EXPECT_TRUE(suggestions.empty()); } -TEST_F(PreloadAddressValidatorTest, SuggestionIncludesCountry) { +TEST_F(AddressValidatorTest, MismatchedPostalCodeNoSuggestions) { AddressData address; address.region_code = "US"; + address.administrative_area = "TX"; 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); + EXPECT_EQ( + AddressValidator::SUCCESS, + validator_->GetSuggestions(address, POSTAL_CODE, 999, &suggestions)); + EXPECT_TRUE(suggestions.empty()); } -TEST_F(PreloadAddressValidatorTest, - SuggestOnlyForAdministrativeAreasAndPostalCode) { +TEST_F(AddressValidatorTest, SuggestOnlyForAdministrativeAreasAndPostalCode) { AddressData address; address.region_code = "US"; address.administrative_area = "CA"; @@ -568,14 +609,24 @@ TEST_F(PreloadAddressValidatorTest, for (size_t i = 0; i < kNumNoSuggestFields; ++i) { std::vector<AddressData> suggestions; - EXPECT_EQ(PreloadAddressValidator::SUCCESS, + EXPECT_EQ(AddressValidator::SUCCESS, validator_->GetSuggestions( address, kNoSugestFields[i], 999, &suggestions)); EXPECT_TRUE(suggestions.empty()); } } -TEST_F(PreloadAddressValidatorTest, CanonicalizeUsAdminAreaName) { +TEST_F(AddressValidatorTest, SuggestionsAreCleared) { + AddressData address; + address.region_code = "US"; + + std::vector<AddressData> suggestions(1, address); + EXPECT_EQ(AddressValidator::SUCCESS, + validator_->GetSuggestions(address, POSTAL_CODE, 1, &suggestions)); + EXPECT_TRUE(suggestions.empty()); +} + +TEST_F(AddressValidatorTest, CanonicalizeUsAdminAreaName) { AddressData address; address.region_code = "US"; address.administrative_area = "cALIFORNIa"; @@ -583,7 +634,7 @@ TEST_F(PreloadAddressValidatorTest, CanonicalizeUsAdminAreaName) { EXPECT_EQ("CA", address.administrative_area); } -TEST_F(PreloadAddressValidatorTest, CanonicalizeUsAdminAreaKey) { +TEST_F(AddressValidatorTest, CanonicalizeUsAdminAreaKey) { AddressData address; address.region_code = "US"; address.administrative_area = "CA"; @@ -591,8 +642,8 @@ TEST_F(PreloadAddressValidatorTest, CanonicalizeUsAdminAreaKey) { EXPECT_EQ("CA", address.administrative_area); } -TEST_F(PreloadAddressValidatorTest, CanonicalizeJpAdminAreaKey) { - validator_->LoadRules("JP", *loaded_); +TEST_F(AddressValidatorTest, CanonicalizeJpAdminAreaKey) { + validator_->LoadRules("JP"); AddressData address; address.region_code = "JP"; address.administrative_area = "東京都"; @@ -600,8 +651,8 @@ TEST_F(PreloadAddressValidatorTest, CanonicalizeJpAdminAreaKey) { EXPECT_EQ("東京都", address.administrative_area); } -TEST_F(PreloadAddressValidatorTest, CanonicalizeJpAdminAreaLatinName) { - validator_->LoadRules("JP", *loaded_); +TEST_F(AddressValidatorTest, CanonicalizeJpAdminAreaLatinName) { + validator_->LoadRules("JP"); AddressData address; address.region_code = "JP"; address.administrative_area = "tOKYo"; @@ -609,4 +660,81 @@ TEST_F(PreloadAddressValidatorTest, CanonicalizeJpAdminAreaLatinName) { EXPECT_EQ("TOKYO", address.administrative_area); } +TEST_F(AddressValidatorTest, TokushimaSuggestionIsValid) { + validator_->LoadRules("JP"); + AddressData address; + address.region_code = "JP"; + address.administrative_area = "Toku"; + address.language_code = "ja-Latn"; + + std::vector<AddressData> suggestions; + EXPECT_EQ(AddressValidator::SUCCESS, + validator_->GetSuggestions(address, ADMIN_AREA, 1, &suggestions)); + ASSERT_EQ(1U, suggestions.size()); + EXPECT_EQ("TOKUSHIMA", suggestions[0].administrative_area); + + FieldProblemMap filter; + for (int i = UNEXPECTED_FIELD; i <= USES_P_O_BOX; ++i) + filter.insert(std::make_pair(ADMIN_AREA, static_cast<AddressProblem>(i))); + + FieldProblemMap problems; + EXPECT_EQ(AddressValidator::SUCCESS, + validator_->ValidateAddress(suggestions[0], &filter, &problems)); + EXPECT_TRUE(problems.empty()); +} + +TEST_F(AddressValidatorTest, ValidPostalCodeInSuggestion) { + validator_->LoadRules("US"); + AddressData address; + address.region_code = "US"; + address.administrative_area = "New"; + address.postal_code = "13699"; + + std::vector<AddressData> suggestions; + EXPECT_EQ(AddressValidator::SUCCESS, + validator_->GetSuggestions(address, ADMIN_AREA, 999, &suggestions)); + ASSERT_EQ(1U, suggestions.size()); + EXPECT_EQ("New York", suggestions[0].administrative_area); + + address.administrative_area = "New"; + address.postal_code = "03755"; + + EXPECT_EQ(AddressValidator::SUCCESS, + validator_->GetSuggestions(address, ADMIN_AREA, 999, &suggestions)); + ASSERT_EQ(1U, suggestions.size()); + EXPECT_EQ("New Hampshire", suggestions[0].administrative_area); +} + +TEST_F(AddressValidatorTest, ValidateRequiredFieldsWithoutRules) { + // Do not load the rules for JP. + AddressData address; + address.region_code = "JP"; + + FieldProblemMap problems; + EXPECT_EQ(AddressValidator::RULES_UNAVAILABLE, + validator_->ValidateAddress(address, NULL, &problems)); + EXPECT_FALSE(problems.empty()); + + for (FieldProblemMap::const_iterator it = problems.begin(); + it != problems.end(); + ++it) { + EXPECT_EQ(MISSING_REQUIRED_FIELD, it->second); + } +} + +TEST_F(AddressValidatorTest, + DoNotValidateRequiredFieldsWithoutRulesWhenErorrIsFiltered) { + // Do not load the rules for JP. + AddressData address; + address.region_code = "JP"; + + FieldProblemMap filter; + filter.insert(std::make_pair(COUNTRY, UNKNOWN_VALUE)); + + FieldProblemMap problems; + EXPECT_EQ(AddressValidator::RULES_UNAVAILABLE, + validator_->ValidateAddress(address, &filter, &problems)); + EXPECT_TRUE(problems.empty()); +} + } // namespace diff --git a/third_party/libaddressinput/chromium/chrome_downloader_impl.cc b/third_party/libaddressinput/chromium/chrome_downloader_impl.cc index 507cc9e..950500e 100644 --- a/third_party/libaddressinput/chromium/chrome_downloader_impl.cc +++ b/third_party/libaddressinput/chromium/chrome_downloader_impl.cc @@ -55,27 +55,9 @@ ChromeDownloaderImpl::~ChromeDownloaderImpl() { STLDeleteValues(&requests_); } -void ChromeDownloaderImpl::Download( - const std::string& url, - scoped_ptr<Callback> downloaded) { - GURL resource(url); - if (!resource.SchemeIsSecure()) { - (*downloaded)(false, url, make_scoped_ptr(new std::string())); - return; - } - - scoped_ptr<net::URLFetcher> fetcher( - net::URLFetcher::Create(resource, net::URLFetcher::GET, this)); - fetcher->SetLoadFlags( - net::LOAD_DO_NOT_SEND_COOKIES | net::LOAD_DO_NOT_SAVE_COOKIES); - fetcher->SetRequestContext(getter_); - - Request* request = new Request(url, fetcher.Pass(), downloaded.Pass()); - request->fetcher->SaveResponseWithWriter( - scoped_ptr<net::URLFetcherResponseWriter>( - new UnownedStringWriter(&request->data))); - requests_[request->fetcher.get()] = request; - request->fetcher->Start(); +void ChromeDownloaderImpl::Download(const std::string& url, + const Callback& downloaded) const { + const_cast<ChromeDownloaderImpl*>(this)->DoDownload(url, downloaded); } void ChromeDownloaderImpl::OnURLFetchComplete(const net::URLFetcher* source) { @@ -87,7 +69,7 @@ void ChromeDownloaderImpl::OnURLFetchComplete(const net::URLFetcher* source) { scoped_ptr<std::string> data(new std::string()); if (ok) data->swap(request->second->data); - (*request->second->callback)(ok, request->second->url, data.Pass()); + request->second->callback(ok, request->second->url, data.release()); delete request->second; requests_.erase(request); @@ -95,9 +77,31 @@ void ChromeDownloaderImpl::OnURLFetchComplete(const net::URLFetcher* source) { ChromeDownloaderImpl::Request::Request(const std::string& url, scoped_ptr<net::URLFetcher> fetcher, - scoped_ptr<Callback> callback) + const Callback& callback) : url(url), fetcher(fetcher.Pass()), - callback(callback.Pass()) {} + callback(callback) {} + +void ChromeDownloaderImpl::DoDownload(const std::string& url, + const Callback& downloaded) { + GURL resource(url); + if (!resource.SchemeIsSecure()) { + downloaded(false, url, NULL); + return; + } + + scoped_ptr<net::URLFetcher> fetcher( + net::URLFetcher::Create(resource, net::URLFetcher::GET, this)); + fetcher->SetLoadFlags( + net::LOAD_DO_NOT_SEND_COOKIES | net::LOAD_DO_NOT_SAVE_COOKIES); + fetcher->SetRequestContext(getter_); + + Request* request = new Request(url, fetcher.Pass(), downloaded); + request->fetcher->SaveResponseWithWriter( + scoped_ptr<net::URLFetcherResponseWriter>( + new UnownedStringWriter(&request->data))); + requests_[request->fetcher.get()] = request; + request->fetcher->Start(); +} } // namespace autofill diff --git a/third_party/libaddressinput/chromium/chrome_downloader_impl.h b/third_party/libaddressinput/chromium/chrome_downloader_impl.h index 2f0bf0d..ff9ff9f 100644 --- a/third_party/libaddressinput/chromium/chrome_downloader_impl.h +++ b/third_party/libaddressinput/chromium/chrome_downloader_impl.h @@ -10,7 +10,7 @@ #include "base/memory/scoped_vector.h" #include "net/url_request/url_fetcher_delegate.h" -#include "third_party/libaddressinput/chromium/cpp/include/libaddressinput/downloader.h" +#include "third_party/libaddressinput/src/cpp/include/libaddressinput/downloader.h" namespace net { class URLFetcher; @@ -29,7 +29,7 @@ class ChromeDownloaderImpl : public ::i18n::addressinput::Downloader, // ::i18n::addressinput::Downloader: virtual void Download(const std::string& url, - scoped_ptr<Callback> downloaded) OVERRIDE; + const Callback& downloaded) const OVERRIDE; // net::URLFetcherDelegate: virtual void OnURLFetchComplete(const net::URLFetcher* source) OVERRIDE; @@ -38,16 +38,19 @@ class ChromeDownloaderImpl : public ::i18n::addressinput::Downloader, struct Request { Request(const std::string& url, scoped_ptr<net::URLFetcher> fetcher, - scoped_ptr<Callback> callback); + const Callback& callback); std::string url; // The data that's received. std::string data; // The object that manages retrieving the data. scoped_ptr<net::URLFetcher> fetcher; - scoped_ptr<Callback> callback; + const Callback& callback; }; + // Non-const version of Download(). + void DoDownload(const std::string& url, const Callback& downloaded); + net::URLRequestContextGetter* const getter_; // weak // Maps from active url fetcher to request metadata. The value is owned. diff --git a/third_party/libaddressinput/chromium/chrome_downloader_impl_unittest.cc b/third_party/libaddressinput/chromium/chrome_downloader_impl_unittest.cc index 2bf1e01..5fee4d6 100644 --- a/third_party/libaddressinput/chromium/chrome_downloader_impl_unittest.cc +++ b/third_party/libaddressinput/chromium/chrome_downloader_impl_unittest.cc @@ -35,27 +35,31 @@ class ChromeDownloaderImplTest : public testing::Test { scoped_refptr<net::TestURLRequestContextGetter> getter( new net::TestURLRequestContextGetter( base::MessageLoopProxy::current())); - ChromeDownloaderImpl impl(getter); - impl.Download(url_.spec(), BuildCallback()); + ChromeDownloaderImpl impl(getter.get()); + scoped_ptr< ::i18n::addressinput::Downloader::Callback> callback( + ::i18n::addressinput::BuildCallback( + this, &ChromeDownloaderImplTest::OnDownloaded)); + impl.Download(url_.spec(), *callback); base::MessageLoop::current()->RunUntilIdle(); } void set_url(const GURL& url) { url_ = url; } - const std::string& data() { return *data_; } - bool success() { return success_; } + bool success() const { return success_; } + bool has_data() const { return !!data_; } - private: - scoped_ptr<ChromeDownloaderImpl::Callback> BuildCallback() { - return ::i18n::addressinput::BuildScopedPtrCallback( - this, &ChromeDownloaderImplTest::OnDownloaded); + const std::string& data() const { + DCHECK(data_); + return *data_; } + private: // Callback for when download is finished. void OnDownloaded(bool success, const std::string& url, - scoped_ptr<std::string> data) { + std::string* data) { + ASSERT_FALSE(success && data == NULL); success_ = success; - data_ = data.Pass(); + data_.reset(data); } base::MessageLoop loop_; @@ -81,7 +85,7 @@ TEST_F(ChromeDownloaderImplTest, Failure) { SetFakeResponse(kFakePayload, net::HTTP_INTERNAL_SERVER_ERROR); Download(); EXPECT_FALSE(success()); - EXPECT_EQ(std::string(), data()); + EXPECT_TRUE(!has_data() || data().empty()); } TEST_F(ChromeDownloaderImplTest, RejectsInsecureScheme) { @@ -90,7 +94,7 @@ TEST_F(ChromeDownloaderImplTest, RejectsInsecureScheme) { SetFakeResponse(kFakePayload, net::HTTP_OK); Download(); EXPECT_FALSE(success()); - EXPECT_EQ(std::string(), data()); + EXPECT_TRUE(!has_data() || data().empty()); } } // namespace autofill diff --git a/third_party/libaddressinput/chromium/chrome_rule_test.cc b/third_party/libaddressinput/chromium/chrome_rule_test.cc index 064e7da..b1b6682 100644 --- a/third_party/libaddressinput/chromium/chrome_rule_test.cc +++ b/third_party/libaddressinput/chromium/chrome_rule_test.cc @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "third_party/libaddressinput/chromium/cpp/src/rule.h" +#include "third_party/libaddressinput/src/cpp/src/rule.h" #include <string> diff --git a/third_party/libaddressinput/chromium/chrome_storage_impl.cc b/third_party/libaddressinput/chromium/chrome_storage_impl.cc index b9d6d8b..6c559bb 100644 --- a/third_party/libaddressinput/chromium/chrome_storage_impl.cc +++ b/third_party/libaddressinput/chromium/chrome_storage_impl.cc @@ -4,8 +4,10 @@ #include "third_party/libaddressinput/chromium/chrome_storage_impl.h" +#include "base/memory/scoped_ptr.h" #include "base/prefs/writeable_pref_store.h" #include "base/values.h" +#include "third_party/libaddressinput/chromium/fallback_data_store.h" namespace autofill { @@ -17,55 +19,53 @@ ChromeStorageImpl::ChromeStorageImpl(WriteablePrefStore* store) ChromeStorageImpl::~ChromeStorageImpl() {} -void ChromeStorageImpl::Put(const std::string& key, - scoped_ptr<std::string> data) { +void ChromeStorageImpl::Put(const std::string& key, std::string* data) { + DCHECK(data); + scoped_ptr<std::string> owned_data(data); scoped_ptr<base::StringValue> string_value( new base::StringValue(std::string())); - string_value->GetString()->swap(*data); + string_value->GetString()->swap(*owned_data); backing_store_->SetValue(key, string_value.release()); } -void ChromeStorageImpl::Get( - const std::string& key, - scoped_ptr<Storage::Callback> data_ready) const { +void ChromeStorageImpl::Get(const std::string& key, + const Storage::Callback& data_ready) const { // |Get()| should not be const, so this is just a thunk that fixes that. - const_cast<ChromeStorageImpl*>(this)->DoGet(key, data_ready.Pass()); + const_cast<ChromeStorageImpl*>(this)->DoGet(key, data_ready); } void ChromeStorageImpl::OnPrefValueChanged(const std::string& key) {} void ChromeStorageImpl::OnInitializationCompleted(bool succeeded) { - for (std::vector<Request*>::iterator iter = - outstanding_requests_.begin(); + for (std::vector<Request*>::iterator iter = outstanding_requests_.begin(); iter != outstanding_requests_.end(); ++iter) { - DoGet((*iter)->key, (*iter)->callback.Pass()); + DoGet((*iter)->key, (*iter)->callback); } outstanding_requests_.clear(); } -void ChromeStorageImpl::DoGet( - const std::string& key, - scoped_ptr<Storage::Callback> data_ready) { +void ChromeStorageImpl::DoGet(const std::string& key, + const Storage::Callback& data_ready) { if (!backing_store_->IsInitializationComplete()) { - outstanding_requests_.push_back( - new Request(key, data_ready.Pass())); + outstanding_requests_.push_back(new Request(key, data_ready)); return; } const base::Value* value = NULL; - const base::StringValue* string_value = NULL; - if (backing_store_->GetValue(key, &value) && - value->GetAsString(&string_value)) { - (*data_ready)(true, key, string_value->GetString()); + scoped_ptr<std::string> data(new std::string); + if (backing_store_->GetValue(key, &value) && value->GetAsString(data.get())) { + data_ready(true, key, data.release()); + } else if (FallbackDataStore::Get(key, data.get())) { + data_ready(true, key, data.release()); } else { - (*data_ready)(false, key, std::string()); + data_ready(false, key, NULL); } } ChromeStorageImpl::Request::Request(const std::string& key, - scoped_ptr<Storage::Callback> callback) + const Callback& callback) : key(key), - callback(callback.Pass()) {} + callback(callback) {} } // namespace autofill diff --git a/third_party/libaddressinput/chromium/chrome_storage_impl.h b/third_party/libaddressinput/chromium/chrome_storage_impl.h index 5ee657b..b68c72b 100644 --- a/third_party/libaddressinput/chromium/chrome_storage_impl.h +++ b/third_party/libaddressinput/chromium/chrome_storage_impl.h @@ -11,8 +11,7 @@ #include "base/memory/scoped_vector.h" #include "base/prefs/pref_store.h" #include "base/scoped_observer.h" -#include "third_party/libaddressinput/chromium/cpp/include/libaddressinput/storage.h" -#include "third_party/libaddressinput/chromium/cpp/include/libaddressinput/util/scoped_ptr.h" +#include "third_party/libaddressinput/src/cpp/include/libaddressinput/storage.h" class WriteablePrefStore; @@ -28,9 +27,8 @@ class ChromeStorageImpl : public ::i18n::addressinput::Storage, virtual ~ChromeStorageImpl(); // ::i18n::addressinput::Storage implementation. - virtual void Put(const std::string& key, scoped_ptr<std::string> data) - OVERRIDE; - virtual void Get(const std::string& key, scoped_ptr<Callback> data_ready) + virtual void Put(const std::string& key, std::string* data) OVERRIDE; + virtual void Get(const std::string& key, const Callback& data_ready) const OVERRIDE; // PrefStore::Observer implementation. @@ -39,14 +37,14 @@ class ChromeStorageImpl : public ::i18n::addressinput::Storage, private: struct Request { - Request(const std::string& key, scoped_ptr<Callback> callback); + Request(const std::string& key, const Callback& callback); std::string key; - scoped_ptr<Callback> callback; + const Callback& callback; }; // Non-const version of Get(). - void DoGet(const std::string& key, scoped_ptr<Callback> data_ready); + void DoGet(const std::string& key, const Callback& data_ready); WriteablePrefStore* backing_store_; // weak diff --git a/third_party/libaddressinput/chromium/chrome_storage_impl_unittest.cc b/third_party/libaddressinput/chromium/chrome_storage_impl_unittest.cc index 4bbdbd0..277bfb9 100644 --- a/third_party/libaddressinput/chromium/chrome_storage_impl_unittest.cc +++ b/third_party/libaddressinput/chromium/chrome_storage_impl_unittest.cc @@ -7,9 +7,9 @@ #include <string> #include "base/prefs/value_map_pref_store.h" -#include "cpp/test/storage_test_runner.h" #include "testing/gtest/include/gtest/gtest.h" -#include "third_party/libaddressinput/chromium/cpp/include/libaddressinput/callback.h" +#include "third_party/libaddressinput/chromium/storage_test_runner.h" +#include "third_party/libaddressinput/src/cpp/include/libaddressinput/callback.h" namespace autofill { @@ -25,7 +25,7 @@ class ChromeStorageImplTest : public testing::Test { scoped_refptr<ValueMapPrefStore> store_; ChromeStorageImpl storage_; - i18n::addressinput::StorageTestRunner runner_; + StorageTestRunner runner_; }; TEST_F(ChromeStorageImplTest, StandardStorageTests) { diff --git a/third_party/libaddressinput/chromium/fallback_data_store.cc b/third_party/libaddressinput/chromium/fallback_data_store.cc new file mode 100644 index 0000000..4c20aa1 --- /dev/null +++ b/third_party/libaddressinput/chromium/fallback_data_store.cc @@ -0,0 +1,203 @@ +// 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 "fallback_data_store.h" + +#include <string> + +namespace autofill { + +bool FallbackDataStore::Get(const std::string& key, std::string* data) { + if (key != "data/US") + return false; + + // Available at https://i18napis.appspot.com/ssl-aggregate-address/data/US. + // The appended checksum is valid, but the timestamp is old. + data->assign( + "timestamp=0\n" + "checksum=38d4bcdadfe494ffe062a7ad668d66d6\n" + "{\"data/US/LA\": {\"lang\": \"en\", \"zipex\": \"70000,71599\", \"nam" + "e\": \"Louisiana\", \"zip\": \"70|71[0-5]\", \"key\": \"LA\", \"id\":" + " \"data/US/LA\"}, \"data/US/VT\": {\"lang\": \"en\", \"zipex\": \"0500" + "0,05999\", \"name\": \"Vermont\", \"zip\": \"05\", \"key\": \"VT\", \"" + "id\": \"data/US/VT\"}, \"data/US/NM\": {\"lang\": \"en\", \"zipex\": \"" + "87000,88499\", \"name\": \"New Mexico\", \"zip\": \"87|88[0-4]\", \"k" + "ey\": \"NM\", \"id\": \"data/US/NM\"}, \"data/US/NJ\": {\"lang\": \"e" + "n\", \"zipex\": \"07000,08999\", \"name\": \"New Jersey\", \"zip\": \"" + "0[78]\", \"key\": \"NJ\", \"id\": \"data/US/NJ\"}, \"data/US/NH\": {\"" + "lang\": \"en\", \"zipex\": \"03000,03899\", \"name\": \"New Hampshire\"" + ", \"zip\": \"03[0-8]\", \"key\": \"NH\", \"id\": \"data/US/NH\"}, \"d" + "ata/US/ND\": {\"lang\": \"en\", \"zipex\": \"58000,58999\", \"name\":" + " \"North Dakota\", \"zip\": \"58\", \"key\": \"ND\", \"id\": \"data/US" + "/ND\"}, \"data/US/NE\": {\"lang\": \"en\", \"zipex\": \"68000,69999\"," + " \"name\": \"Nebraska\", \"zip\": \"6[89]\", \"key\": \"NE\", \"id\":" + " \"data/US/NE\"}, \"data/US/NC\": {\"lang\": \"en\", \"zipex\": \"2700" + "0,28999\", \"name\": \"North Carolina\", \"zip\": \"2[78]\", \"key\":" + " \"NC\", \"id\": \"data/US/NC\"}, \"data/US/PR\": {\"lang\": \"en\", \"" + "zipex\": \"00600,00799:00900,00999\", \"name\": \"Puerto Rico\", \"zi" + "p\": \"00[679]\", \"key\": \"PR\", \"id\": \"data/US/PR\"}, \"data/US/" + "RI\": {\"lang\": \"en\", \"zipex\": \"02800,02999\", \"name\": \"Rhode" + " Island\", \"zip\": \"02[89]\", \"key\": \"RI\", \"id\": \"data/US/RI\"" + "}, \"data/US/NY\": {\"lang\": \"en\", \"zipex\": \"10000,14999:06390:" + "00501:00544\", \"name\": \"New York\", \"zip\": \"1[0-4]|06390|00501|0" + "0544\", \"key\": \"NY\", \"id\": \"data/US/NY\"}, \"data/US/NV\": {\"l" + "ang\": \"en\", \"zipex\": \"88900,89999\", \"name\": \"Nevada\", \"zi" + "p\": \"889|89\", \"key\": \"NV\", \"id\": \"data/US/NV\"}, \"data/US/K" + "Y\": {\"lang\": \"en\", \"zipex\": \"40000,42799\", \"name\": \"Kentuc" + "ky\", \"zip\": \"4[01]|42[0-7]\", \"key\": \"KY\", \"id\": \"data/US/K" + "Y\"}, \"data/US/PA\": {\"lang\": \"en\", \"zipex\": \"15000,19699\", \"" + "name\": \"Pennsylvania\", \"zip\": \"1[5-8]|19[0-6]\", \"key\": \"PA\"" + ", \"id\": \"data/US/PA\"}, \"data/US/OH\": {\"lang\": \"en\", \"zipe" + "x\": \"43000,45999\", \"name\": \"Ohio\", \"zip\": \"4[3-5]\", \"key\"" + ": \"OH\", \"id\": \"data/US/OH\"}, \"data/US/AS\": {\"lang\": \"en\"," + " \"zipex\": \"96799\", \"name\": \"American Samoa\", \"zip\": \"96799\"" + ", \"key\": \"AS\", \"id\": \"data/US/AS\"}, \"data/US/AA\": {\"lang\"" + ": \"en\", \"zipex\": \"34000,34099\", \"name\": \"Armed Forces (AA)\"," + " \"zip\": \"340\", \"key\": \"AA\", \"id\": \"data/US/AA\"}, \"data/US" + "/GA\": {\"lang\": \"en\", \"zipex\": \"30000,31999:39800,39899:39901\"" + ", \"name\": \"Georgia\", \"zip\": \"3[01]|398|39901\", \"key\": \"GA\"" + ", \"id\": \"data/US/GA\"}, \"data/US/OK\": {\"lang\": \"en\", \"zipex\"" + ": \"73000,74999\", \"name\": \"Oklahoma\", \"zip\": \"7[34]\", \"key\"" + ": \"OK\", \"id\": \"data/US/OK\"}, \"data/US/CO\": {\"lang\": \"en\"," + " \"zipex\": \"80000,81999\", \"name\": \"Colorado\", \"zip\": \"8[01]\"" + ", \"key\": \"CO\", \"id\": \"data/US/CO\"}, \"data/US/AK\": {\"lang\"" + ": \"en\", \"zipex\": \"99500,99999\", \"name\": \"Alaska\", \"zip\": \"" + "99[5-9]\", \"key\": \"AK\", \"id\": \"data/US/AK\"}, \"data/US/WV\": " + "{\"lang\": \"en\", \"zipex\": \"24700,26999\", \"name\": \"West Virgin" + "ia\", \"zip\": \"24[7-9]|2[56]\", \"key\": \"WV\", \"id\": \"data/US/W" + "V\"}, \"data/US/AL\": {\"lang\": \"en\", \"zipex\": \"35000,36999\", \"" + "name\": \"Alabama\", \"zip\": \"3[56]\", \"key\": \"AL\", \"id\": \"d" + "ata/US/AL\"}, \"data/US/GU\": {\"lang\": \"en\", \"zipex\": \"96910,96" + "932\", \"name\": \"Guam\", \"zip\": \"969([1-2]\\\\d|3[12])\", \"key\":" + " \"GU\", \"id\": \"data/US/GU\"}, \"data/US/AR\": {\"lang\": \"en\", \"" + "zipex\": \"71600,72999\", \"name\": \"Arkansas\", \"zip\": \"71[6-9]|" + "72\", \"key\": \"AR\", \"id\": \"data/US/AR\"}, \"data/US/AP\": {\"lan" + "g\": \"en\", \"zipex\": \"96200,96699\", \"name\": \"Armed Forces (AP" + ")\", \"zip\": \"96[2-6]\", \"key\": \"AP\", \"id\": \"data/US/AP\"}, \"" + "data/US/AZ\": {\"lang\": \"en\", \"zipex\": \"85000,86999\", \"name\"" + ": \"Arizona\", \"zip\": \"8[56]\", \"key\": \"AZ\", \"id\": \"data/US/" + "AZ\"}, \"data/US/VI\": {\"lang\": \"en\", \"zipex\": \"00800,00899\"," + " \"name\": \"Virgin Islands\", \"zip\": \"008\", \"key\": \"VI\", \"i" + "d\": \"data/US/VI\"}, \"data/US/CT\": {\"lang\": \"en\", \"zipex\": \"" + "06000,06999\", \"name\": \"Connecticut\", \"zip\": \"06\", \"key\": \"" + "CT\", \"id\": \"data/US/CT\"}, \"data/US/ME\": {\"lang\": \"en\", \"zi" + "pex\": \"03900,04999\", \"name\": \"Maine\", \"zip\": \"039|04\", \"ke" + "y\": \"ME\", \"id\": \"data/US/ME\"}, \"data/US/MD\": {\"lang\": \"en\"" + ", \"zipex\": \"20600,21999\", \"name\": \"Maryland\", \"zip\": \"20[6" + "-9]|21\", \"key\": \"MD\", \"id\": \"data/US/MD\"}, \"data/US/IN\": {\"" + "lang\": \"en\", \"zipex\": \"46000,47999\", \"name\": \"Indiana\", \"" + "zip\": \"4[67]\", \"key\": \"IN\", \"id\": \"data/US/IN\"}, \"data/US/" + "MA\": {\"lang\": \"en\", \"zipex\": \"01000,02799:05501:05544\", \"nam" + "e\": \"Massachusetts\", \"zip\": \"01|02[0-7]|05501|05544\", \"key\":" + " \"MA\", \"id\": \"data/US/MA\"}, \"data/US/IL\": {\"lang\": \"en\", \"" + "zipex\": \"60000,62999\", \"name\": \"Illinois\", \"zip\": \"6[0-2]\"" + ", \"key\": \"IL\", \"id\": \"data/US/IL\"}, \"data/US/MO\": {\"lang\":" + " \"en\", \"zipex\": \"63000,65999\", \"name\": \"Missouri\", \"zip\":" + " \"6[3-5]\", \"key\": \"MO\", \"id\": \"data/US/MO\"}, \"data/US/MN\":" + " {\"lang\": \"en\", \"zipex\": \"55000,56799\", \"name\": \"Minnesota\"" + ", \"zip\": \"55|56[0-7]\", \"key\": \"MN\", \"id\": \"data/US/MN\"}," + " \"data/US/IA\": {\"lang\": \"en\", \"zipex\": \"50000,52999\", \"nam" + "e\": \"Iowa\", \"zip\": \"5[0-2]\", \"key\": \"IA\", \"id\": \"data/US" + "/IA\"}, \"data/US/TN\": {\"lang\": \"en\", \"zipex\": \"37000,38599\"," + " \"name\": \"Tennessee\", \"zip\": \"37|38[0-5]\", \"key\": \"TN\", \"" + "id\": \"data/US/TN\"}, \"data/US/WY\": {\"lang\": \"en\", \"zipex\": \"" + "82000,83199:83414\", \"name\": \"Wyoming\", \"zip\": \"82|83[01]|8341" + "4\", \"key\": \"WY\", \"id\": \"data/US/WY\"}, \"data/US/KS\": {\"lan" + "g\": \"en\", \"zipex\": \"66000,67999\", \"name\": \"Kansas\", \"zip\"" + ": \"6[67]\", \"key\": \"KS\", \"id\": \"data/US/KS\"}, \"data/US/MI\":" + " {\"lang\": \"en\", \"zipex\": \"48000,49999\", \"name\": \"Michigan\"" + ", \"zip\": \"4[89]\", \"key\": \"MI\", \"id\": \"data/US/MI\"}, \"data" + "/US/ID\": {\"lang\": \"en\", \"zipex\": \"83200,83999\", \"name\": \"I" + "daho\", \"zip\": \"83[2-9]\", \"key\": \"ID\", \"id\": \"data/US/ID\"}" + ", \"data/US/MT\": {\"lang\": \"en\", \"zipex\": \"59000,59999\", \"nam" + "e\": \"Montana\", \"zip\": \"59\", \"key\": \"MT\", \"id\": \"data/US/" + "MT\"}, \"data/US/MS\": {\"lang\": \"en\", \"zipex\": \"38600,39799\"," + " \"name\": \"Mississippi\", \"zip\": \"38[6-9]|39[0-7]\", \"key\": \"M" + "S\", \"id\": \"data/US/MS\"}, \"data/US/MP\": {\"lang\": \"en\", \"zip" + "ex\": \"96950,96952\", \"name\": \"Northern Mariana Islands\", \"zip\"" + ": \"9695[0-2]\", \"key\": \"MP\", \"id\": \"data/US/MP\"}, \"data/US/P" + "W\": {\"lang\": \"en\", \"zipex\": \"96940\", \"name\": \"Palau\", \"z" + "ip\": \"969(39|40)\", \"key\": \"PW\", \"id\": \"data/US/PW\"}, \"data" + "/US/SC\": {\"lang\": \"en\", \"zipex\": \"29000,29999\", \"name\": \"S" + "outh Carolina\", \"zip\": \"29\", \"key\": \"SC\", \"id\": \"data/US/S" + "C\"}, \"data/US/MH\": {\"lang\": \"en\", \"zipex\": \"96960,96979\", \"" + "name\": \"Marshall Islands\", \"zip\": \"969[67]\", \"key\": \"MH\"," + " \"id\": \"data/US/MH\"}, \"data/US/WI\": {\"lang\": \"en\", \"zipex\"" + ": \"53000,54999\", \"name\": \"Wisconsin\", \"zip\": \"5[34]\", \"key\"" + ": \"WI\", \"id\": \"data/US/WI\"}, \"data/US/SD\": {\"lang\": \"en\"," + " \"zipex\": \"57000,57999\", \"name\": \"South Dakota\", \"zip\": \"5" + "7\", \"key\": \"SD\", \"id\": \"data/US/SD\"}, \"data/US/OR\": {\"lan" + "g\": \"en\", \"zipex\": \"97000,97999\", \"name\": \"Oregon\", \"zip\"" + ": \"97\", \"key\": \"OR\", \"id\": \"data/US/OR\"}, \"data/US/UT\": {\"" + "lang\": \"en\", \"zipex\": \"84000,84999\", \"name\": \"Utah\", \"zi" + "p\": \"84\", \"key\": \"UT\", \"id\": \"data/US/UT\"}, \"data/US/VA\":" + " {\"lang\": \"en\", \"zipex\": \"20100,20199:22000,24699\", \"name\":" + " \"Virginia\", \"zip\": \"201|2[23]|24[0-6]\", \"key\": \"VA\", \"id\"" + ": \"data/US/VA\"}, \"data/US/AE\": {\"lang\": \"en\", \"zipex\": \"090" + "00,09999\", \"name\": \"Armed Forces (AE)\", \"zip\": \"09\", \"key\":" + " \"AE\", \"id\": \"data/US/AE\"}, \"data/US/FL\": {\"lang\": \"en\", \"" + "zipex\": \"32000,33999:34100,34999\", \"name\": \"Florida\", \"zip\":" + " \"3[23]|34[1-9]\", \"key\": \"FL\", \"id\": \"data/US/FL\"}, \"data/U" + "S/FM\": {\"lang\": \"en\", \"zipex\": \"96941,96944\", \"name\": \"Mic" + "ronesia\", \"zip\": \"9694[1-4]\", \"key\": \"FM\", \"id\": \"data/US/" + "FM\"}, \"data/US/DE\": {\"lang\": \"en\", \"zipex\": \"19700,19999\"," + " \"name\": \"Delaware\", \"zip\": \"19[7-9]\", \"key\": \"DE\", \"id\"" + ": \"data/US/DE\"}, \"data/US/CA\": {\"lang\": \"en\", \"zipex\": \"900" + "00,96199\", \"name\": \"California\", \"zip\": \"9[0-5]|96[01]\", \"ke" + "y\": \"CA\", \"id\": \"data/US/CA\"}, \"data/US\": {\"lang\": \"en\"," + " \"upper\": \"CS\", \"sub_zipexs\": \"35000,36999~99500,99999~96799~85" + "000,86999~71600,72999~34000,34099~09000,09999~96200,96699~90000,96199~" + "80000,81999~06000,06999~19700,19999~20000,20099:20200,20599:56900,5699" + "9~32000,33999:34100,34999~30000,31999:39800,39899:39901~96910,96932~96" + "700,96798:96800,96899~83200,83999~60000,62999~46000,47999~50000,52999~" + "66000,67999~40000,42799~70000,71599~03900,04999~96960,96979~20600,2199" + "9~01000,02799:05501:05544~48000,49999~96941,96944~55000,56799~38600,39" + "799~63000,65999~59000,59999~68000,69999~88900,89999~03000,03899~07000," + "08999~87000,88499~10000,14999:06390:00501:00544~27000,28999~58000,5899" + "9~96950,96952~43000,45999~73000,74999~97000,97999~96940~15000,19699~00" + "600,00799:00900,00999~02800,02999~29000,29999~57000,57999~37000,38599~" + "75000,79999:88500,88599:73301:73344~84000,84999~05000,05999~00800,0089" + "9~20100,20199:22000,24699~98000,99499~24700,26999~53000,54999~82000,83" + "199:83414\", \"zipex\": \"95014,22162-1010\", \"name\": \"UNITED STATE" + "S\", \"zip\": \"\\\\d{5}([ \\\\-]\\\\d{4})?\", \"zip_name_type\": \"zi" + "p\", \"fmt\": \"%N%n%O%n%A%n%C %S %Z\", \"state_name_type\": \"state\"" + ", \"languages\": \"en\", \"sub_keys\": \"AL~AK~AS~AZ~AR~AA~AE~AP~CA~CO" + "~CT~DE~DC~FL~GA~GU~HI~ID~IL~IN~IA~KS~KY~LA~ME~MH~MD~MA~MI~FM~MN~MS~MO~" + "MT~NE~NV~NH~NJ~NM~NY~NC~ND~MP~OH~OK~OR~PW~PA~PR~RI~SC~SD~TN~TX~UT~VT~V" + "I~VA~WA~WV~WI~WY\"," + " \"key\": \"US\", \"require\": \"ACSZ\", \"posturl\": \"https://tools." + "usps.com/go/ZipLookupAction!input.action\", \"id\": \"dat" + "a/US\", \"sub_names\": \"Alabama~Alaska~American Samoa~Arizona~Arkansa" + "s~Armed Forces (AA)~Armed Forces (AE)~Armed Forces (AP)~California~Col" + "orado~Connecticut~Delaware~District of Columbia~Florida~Georgia~Guam~H" + "awaii~Idaho~Illinois~Indiana~Iowa~Kansas~Kentucky~Louisiana~Maine~Mars" + "hall Islands~Maryland~Massachusetts~Michigan~Micronesia~Minnesota~Miss" + "issippi~Missouri~Montana~Nebraska~Nevada~New Hampshire~New Jersey~New " + "Mexico~New York~North Carolina~North Dakota~Northern Mariana Islands~O" + "hio~Oklahoma~Oregon~Palau~Pennsylvania~Puerto Rico~Rhode Island~South " + "Carolina~South Dakota~Tennessee~Texas~Utah~Vermont~Virgin Islands~Virg" + "inia~Washington~West Virginia~Wisconsin~Wyoming\", \"sub_zips\": \"3[5" + "6]~99[5-9]~96799~8[56]~71[6-9]|72~340~09~96[2-6]~9[0-5]|96[01]~8[01]~0" + "6~19[7-9]~20[02-5]|569~3[23]|34[1-9]~3[01]|398|39901~969([1-2]\\\\d|3[12" + "])~967[0-8]|9679[0-8]|968~83[2-9]~6[0-2]~4[67]~5[0-2]~6[67]~4[01]|42[0" + "-7]~70|71[0-5]~039|04~969[67]~20[6-9]|21~01|02[0-7]|05501|05544~4[89]~" + "9694[1-4]~55|56[0-7]~38[6-9]|39[0-7]~6[3-5]~59~6[89]~889|89~03[0-8]~0[" + "78]~87|88[0-4]~1[0-4]|06390|00501|00544~2[78]~58~9695[0-2]~4[3-5]~7[34" + "]~97~969(39|40)~1[5-8]|19[0-6]~00[679]~02[89]~29~57~37|38[0-5]~7[5-9]|" + "885|73301|73344~84~05~008~201|2[23]|24[0-6]~98|99[0-4]~24[7-9]|2[56]~5" + "[34]~82|83[01]|83414\"}, \"data/US/TX\": {\"lang\": \"en\", \"zipex\":" + " \"75000,79999:88500,88599:73301:73344\", \"name\": \"Texas\", \"zip\"" + ": \"7[5-9]|885|73301|73344\", \"key\": \"TX\", \"id\": \"data/US/TX\"}" + ", \"data/US/WA\": {\"lang\": \"en\", \"zipex\": \"98000,99499\", \"nam" + "e\": \"Washington\", \"zip\": \"98|99[0-4]\", \"key\": \"WA\", \"id\":" + " \"data/US/WA\"}, \"data/US/DC\": {\"lang\": \"en\", \"zipex\": \"2000" + "0,20099:20200,20599:56900,56999\", \"name\": \"District of Columbia\"," + " \"zip\": \"20[02-5]|569\", \"key\": \"DC\", \"id\": \"data/US/DC\"}," + " \"data/US/HI\": {\"lang\": \"en\", \"zipex\": \"96700,96798:96800,968" + "99\", \"name\": \"Hawaii\", \"zip\": \"967[0-8]|9679[0-8]|968\", \"key" + "\": \"HI\", \"id\": \"data/US/HI\"}}"); + return true; +} + +} // namespace autofill diff --git a/third_party/libaddressinput/chromium/fallback_data_store.h b/third_party/libaddressinput/chromium/fallback_data_store.h new file mode 100644 index 0000000..fd8d680 --- /dev/null +++ b/third_party/libaddressinput/chromium/fallback_data_store.h @@ -0,0 +1,22 @@ +// 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_FALLBACK_DATA_STORE_H_ +#define THIRD_PARTY_LIBADDRESSINPUT_CHROMIUM_FALLBACK_DATA_STORE_H_ + +#include <string> + +namespace autofill { + +class FallbackDataStore { + public: + // Gets stale, but valid static data for |key|. Should only be used as a last + // resort after attempts to check the local cache or the webserver have + // failed. + static bool Get(const std::string& key, std::string* data); +}; + +} // namespace autofill + +#endif // THIRD_PARTY_LIBADDRESSINPUT_CHROMIUM_FALLBACK_DATA_STORE_H_ diff --git a/third_party/libaddressinput/chromium/fallback_data_store_unittest.cc b/third_party/libaddressinput/chromium/fallback_data_store_unittest.cc new file mode 100644 index 0000000..31f32b1 --- /dev/null +++ b/third_party/libaddressinput/chromium/fallback_data_store_unittest.cc @@ -0,0 +1,40 @@ +// 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 "third_party/libaddressinput/chromium/fallback_data_store.h" + +#include <cstddef> +#include <ctime> +#include <string> + +#include "testing/gtest/include/gtest/gtest.h" +#include "third_party/libaddressinput/src/cpp/src/util/json.h" +#include "third_party/libaddressinput/src/cpp/src/validating_util.h" + +namespace autofill { + +using i18n::addressinput::Json; +using i18n::addressinput::ValidatingUtil; + +TEST(FallbackDataStore, Parsability) { + std::string data; + ASSERT_TRUE(FallbackDataStore::Get("data/US", &data)); + + // Should be stale. + EXPECT_FALSE(ValidatingUtil::UnwrapTimestamp(&data, time(NULL))); + + // Should be uncorrupted. + EXPECT_TRUE(ValidatingUtil::UnwrapChecksum(&data)); + + // Should be valid JSON. + Json json; + ASSERT_TRUE(json.ParseObject(data)); + + // Should have a dictionary for "data/US", as this is aggregate data. + std::string not_checked; + EXPECT_FALSE(json.GetStringValueForKey("data/US", ¬_checked)); + EXPECT_TRUE(json.HasDictionaryValueForKey("data/US")); +} + +} // namespace autofill diff --git a/third_party/libaddressinput/chromium/input_suggester.cc b/third_party/libaddressinput/chromium/input_suggester.cc new file mode 100644 index 0000000..5e6c7e7 --- /dev/null +++ b/third_party/libaddressinput/chromium/input_suggester.cc @@ -0,0 +1,521 @@ +// 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 "third_party/libaddressinput/chromium/input_suggester.h" + +#include <cstddef> +#include <set> +#include <utility> + +#include "base/logging.h" +#include "third_party/libaddressinput/chromium/trie.h" +#include "third_party/libaddressinput/src/cpp/include/libaddressinput/address_data.h" +#include "third_party/libaddressinput/src/cpp/include/libaddressinput/callback.h" +#include "third_party/libaddressinput/src/cpp/include/libaddressinput/preload_supplier.h" +#include "third_party/libaddressinput/src/cpp/include/libaddressinput/region_data.h" + +namespace autofill { + +using ::i18n::addressinput::AddressData; +using ::i18n::addressinput::AddressField; +using ::i18n::addressinput::BuildCallback; +using ::i18n::addressinput::FieldProblemMap; +using ::i18n::addressinput::PreloadSupplier; +using ::i18n::addressinput::RegionData; +using ::i18n::addressinput::RegionDataBuilder; + +using ::i18n::addressinput::ADMIN_AREA; +using ::i18n::addressinput::COUNTRY; +using ::i18n::addressinput::DEPENDENT_LOCALITY; +using ::i18n::addressinput::LOCALITY; +using ::i18n::addressinput::POSTAL_CODE; + +using ::i18n::addressinput::INVALID_FORMAT; +using ::i18n::addressinput::MISMATCHING_VALUE; + +namespace { + +// Initial size for the buffer used in the canonicalizer. +static const size_t kInitialBufferSize = 32; + +// A region and its metadata useful for constructing a suggestion. +struct Suggestion { + public: + // Builds a suggestion of |region_to_suggest|. Does not take ownership of + // |region_to_suggest|, which should not be NULL. + Suggestion(const RegionData* region_to_suggest, + AddressField matching_address_field, + bool region_key_matches) + : region_to_suggest(region_to_suggest), + matching_address_field(matching_address_field), + region_key_matches(region_key_matches) { + DCHECK(region_to_suggest); + } + + ~Suggestion() {} + + // The region that should be suggested. For example, if the region is ("CA", + // "California"), then either "CA" or "California" should be suggested. + const RegionData* region_to_suggest; + + // The field in the address for which the suggestion should be made. For + // example, ADMIN_AREA in US means the suggestion should be made for the field + // labeled "State". + AddressField matching_address_field; + + // True if the key of the region matches user input (the name may or may not + // match). "CA" should be suggested for a ("CA", "California") region. + // + // False if only the name of the region matches user input (the key does not + // match). "California" should be suggested for a ("CA", "California") region. + bool region_key_matches; +}; + +// Suggestions for an address. Contains lists of suggestions for administrative +// area, locality, and dependent locality fields of an address. +class AddressSuggestions { + public: + AddressSuggestions() {} + ~AddressSuggestions() {} + + // Marks all regions at |address_field| level as matching user input. + void AllRegionsMatchForField(AddressField address_field) { + all_regions_match_input_.insert(address_field); + } + + // Marks given regions at |address_field| level as matching user input. The + // |regions_match_key| parameter contains the regions that match user input by + // their keys. The |regions_match_name| parameter contains the regions that + // match user input by their names. + // + // The |address_field| parameter should be either ADMIN_AREA, LOCALITY, or + // DEPENDENT_LOCALITY. + bool AddRegions(AddressField address_field, + const std::set<const RegionData*>& regions_match_key, + const std::set<const RegionData*>& regions_match_name) { + DCHECK(address_field >= ADMIN_AREA); + DCHECK(address_field <= DEPENDENT_LOCALITY); + + AddressField parent_address_field = + static_cast<AddressField>(address_field - 1); + + bool all_parents_match = + parent_address_field == COUNTRY || + all_regions_match_input_.find(parent_address_field) != + all_regions_match_input_.end(); + + // Cannot build |address_field| level suggestions if there are no matches in + // |parent_address_field| level regions. + const RegionsMatchInput* parents = NULL; + if (address_field > ADMIN_AREA && !all_parents_match) { + parents = ®ions_match_input_[parent_address_field]; + if (parents->keys.empty() && parents->names.empty()) + return false; + } + + RegionsMatchInput* regions = NULL; + if (address_field < DEPENDENT_LOCALITY) + regions = ®ions_match_input_[address_field]; + + std::vector<Suggestion>* suggestions = &suggestions_[address_field]; + bool added_suggestions = false; + + // Iterate over both |regions_match_key| and |regions_match_name| and build + // Suggestion objects based on the given RegionData objects. Advance either + // one iterator at a time (if they point to different data) or both + // iterators at once (if they point to the same data). + for (std::set<const RegionData*>::const_iterator + key_it = regions_match_key.begin(), + name_it = regions_match_name.begin(); + key_it != regions_match_key.end() || + name_it != regions_match_name.end();) { + const RegionData* key_region = + key_it != regions_match_key.end() ? *key_it : NULL; + const RegionData* name_region = + name_it != regions_match_name.end() ? *name_it : NULL; + + // Regions that do not have a parent that also matches input will not + // become suggestions. + bool key_region_has_parent = + all_parents_match || + (parents && !parents->keys.empty() && key_region && + parents->keys.find(&key_region->parent()) != parents->keys.end()); + bool name_region_has_parent = + all_parents_match || + (parents && !parents->names.empty() && name_region && + parents->names.find(&name_region->parent()) != parents->names.end()); + + if (name_region && (!key_region || name_region < key_region)) { + if (name_region_has_parent) { + suggestions->push_back(Suggestion(name_region, address_field, false)); + added_suggestions = true; + if (regions) + regions->names.insert(name_region); + } + + ++name_it; + } else if (key_region && (!name_region || key_region < name_region)) { + if (key_region_has_parent) { + suggestions->push_back(Suggestion(key_region, address_field, true)); + added_suggestions = true; + if (regions) + regions->keys.insert(key_region); + } + + ++key_it; + } else { + if (key_region_has_parent) { + suggestions->push_back(Suggestion(key_region, address_field, true)); + added_suggestions = true; + if (regions) { + regions->keys.insert(key_region); + regions->names.insert(name_region); + } + } + + ++key_it; + ++name_it; + } + } + + return added_suggestions; + } + + // Swaps the suggestions for the smallest sub-region into |suggestions|. + // |this| is not usable after this call due to using the swap() operation. + // + // The |suggestions| parameter should not be NULL. + void SwapSmallestSubRegionSuggestions(std::vector<Suggestion>* suggestions) { + DCHECK(suggestions); + for (int i = DEPENDENT_LOCALITY; i >= ADMIN_AREA; --i) { + std::vector<Suggestion>* result = + &suggestions_[static_cast<AddressField>(i)]; + if (!result->empty()) { + suggestions->swap(*result); + return; + } + } + } + + private: + // The sets of non-owned regions used for looking up regions that match user + // input by keys and names. + struct RegionsMatchInput { + std::set<const RegionData*> keys; + std::set<const RegionData*> names; + }; + + // The regions that match user input at ADMIN_AREA and LOCALITY levels. + std::map<AddressField, RegionsMatchInput> regions_match_input_; + + // The set of fields for which all regions match user input. Used to avoid + // storing a long list in |regions_match_input_| and later looking it up + // there. + std::set<AddressField> all_regions_match_input_; + + // Suggestions at ADMIN_AREA, LOCALITY, and DEPENDENT_LOCALITY levels. + std::map<AddressField, std::vector<Suggestion> > suggestions_; + + DISALLOW_COPY_AND_ASSIGN(AddressSuggestions); +}; + +} // namespace + +InputSuggester::StringCanonicalizer::StringCanonicalizer() + : buffer_(kInitialBufferSize, 0) { + UErrorCode error_code = U_ZERO_ERROR; + collator_.reset( + icu::Collator::createInstance(icu::Locale::getRoot(), error_code)); + DCHECK(U_SUCCESS(error_code)); + collator_->setStrength(icu::Collator::PRIMARY); +} + +InputSuggester::StringCanonicalizer::~StringCanonicalizer() {} + +const std::vector<uint8_t>& InputSuggester::StringCanonicalizer::Canonicalize( + const std::string& original) const { + DCHECK(!original.empty()); + + icu::UnicodeString icu_str(original.c_str(), + static_cast<int32_t>(original.length())); + int32_t sort_key_size = + collator_->getSortKey(icu_str, &buffer_[0], buffer_size()); + DCHECK_LT(0, sort_key_size); + + if (sort_key_size > buffer_size()) { + buffer_.resize(sort_key_size * 2, 0); + sort_key_size = collator_->getSortKey(icu_str, &buffer_[0], buffer_size()); + DCHECK_LT(0, sort_key_size); + DCHECK_GT(buffer_size(), sort_key_size); + } + + return buffer_; +} + +int32_t InputSuggester::StringCanonicalizer::buffer_size() const { + return static_cast<int32_t>(buffer_.size()); +} + +// All sub-regions of a COUNTRY level region, organized into tries for lookup by +// region name or key. +class InputSuggester::SubRegionData { + public: + SubRegionData() + : initialized_(false), + smallest_region_size_(COUNTRY), + canonicalizer_(NULL) {} + + ~SubRegionData() {} + + bool is_initialized() const { return initialized_; } + + // Adds the sub-regions of |country_region| into tries. Uses + // |shared_canonicalizer| for case and diacritic insensitive lookup of the + // sub-regions. Should be called at most once. + void Initialize(const RegionData& country_region, + const StringCanonicalizer& shared_canonicalizer) { + DCHECK(!initialized_); + DCHECK(!country_region.has_parent()); + + initialized_ = true; + canonicalizer_ = &shared_canonicalizer; + + if (!country_region.sub_regions().empty()) + AddSubRegionsOf(country_region, COUNTRY); + } + + // Adds the suggestions for |user_input| into |suggestions| when user is + // typing in |focused_field|. + void BuildSuggestions(const AddressData& user_input, + AddressField focused_field, + std::vector<Suggestion>* suggestions) { + DCHECK(initialized_); + + // Do not suggest anything if there's no suggestion data for the focused + // field. + if (focused_field != POSTAL_CODE && smallest_region_size_ < focused_field) + return; + + // Non-owned regions that match a field value by region key. + std::set<const RegionData*> regions_match_key; + + // Non-owned regions that match a field value by region name. + std::set<const RegionData*> regions_match_name; + + AddressSuggestions address_suggestions; + for (int i = ADMIN_AREA; i <= focused_field && i <= DEPENDENT_LOCALITY; + ++i) { + AddressField address_field = static_cast<AddressField>(i); + AddressField parent_address_field = static_cast<AddressField>(i - 1); + + const std::string& field_value = user_input.GetFieldValue(address_field); + const std::string& parent_field_value = + user_input.GetFieldValue(parent_address_field); + + if (field_value.empty() && + (address_field == ADMIN_AREA || parent_field_value.empty())) { + address_suggestions.AllRegionsMatchForField(address_field); + continue; + } + + if (field_value.empty()) { + DCHECK_NE(address_field, focused_field); + continue; + } + + regions_match_key.clear(); + regions_match_name.clear(); + + const FieldTries& field_tries = field_tries_[address_field]; + + const std::vector<uint8_t>& canonicalized_value = + canonicalizer_->Canonicalize(field_value); + + field_tries.keys.FindDataForKeyPrefix(canonicalized_value, + ®ions_match_key); + field_tries.names.FindDataForKeyPrefix(canonicalized_value, + ®ions_match_name); + + bool added_suggestions = address_suggestions.AddRegions( + address_field, regions_match_key, regions_match_name); + + // Do not suggest anything if the focused field does not have suggestions. + if (address_field == focused_field && !added_suggestions) + return; + } + + address_suggestions.SwapSmallestSubRegionSuggestions(suggestions); + } + + private: + // The tries to lookup regions for a specific field by keys and names. For + // example, the FieldTries for ADMIN_AREA in US will have keys for "AL", "AK", + // "AS", etc and names for "Alabama", "Alaska", "American Samoa", etc. The + // struct is uncopyable due to Trie objects being uncopyable. + struct FieldTries { + Trie<const RegionData*> keys; + Trie<const RegionData*> names; + }; + + // Adds the sub-regions of |parent_region| into tries. + void AddSubRegionsOf(const RegionData& parent_region, + AddressField parent_field) { + DCHECK(!parent_region.sub_regions().empty()); + + AddressField address_field = static_cast<AddressField>(parent_field + 1); + DCHECK(address_field >= ADMIN_AREA); + DCHECK(address_field <= DEPENDENT_LOCALITY); + + FieldTries* field_tries = &field_tries_[address_field]; + for (std::vector<const RegionData*>::const_iterator it = + parent_region.sub_regions().begin(); + it != parent_region.sub_regions().end(); + ++it) { + const RegionData* region = *it; + DCHECK(region); + DCHECK(!region->key().empty()); + DCHECK(!region->name().empty()); + + field_tries->keys.AddDataForKey( + canonicalizer_->Canonicalize(region->key()), region); + + field_tries->names.AddDataForKey( + canonicalizer_->Canonicalize(region->name()), region); + + if (smallest_region_size_ < address_field) + smallest_region_size_ = address_field; + + if (!region->sub_regions().empty()) + AddSubRegionsOf(*region, address_field); + } + } + + // True after Initialize() has been called. + bool initialized_; + + // The tries to lookup regions for ADMIN_AREA, LOCALITY, and + // DEPENDENT_LOCALITY. + std::map<AddressField, FieldTries> field_tries_; + + // The smallest size of a sub-region that has data. For example, this is + // ADMIN_AREA in US, but DEPENDENT_LOCALITY in CN. + AddressField smallest_region_size_; + + // A shared instance of string canonicalizer for case and diacritic comparison + // of region keys and names. + const StringCanonicalizer* canonicalizer_; +}; + +InputSuggester::InputSuggester(PreloadSupplier* supplier) + : region_data_builder_(supplier), + input_helper_(supplier), + validator_(supplier), + validated_(BuildCallback(this, &InputSuggester::Validated)) {} + +InputSuggester::~InputSuggester() {} + +void InputSuggester::GetSuggestions(const AddressData& user_input, + AddressField focused_field, + size_t suggestions_limit, + std::vector<AddressData>* suggestions) { + DCHECK(suggestions); + DCHECK(focused_field == POSTAL_CODE || + (focused_field >= ADMIN_AREA && focused_field <= DEPENDENT_LOCALITY)); + + AddressData address_copy = user_input; + + // Do not suggest anything if the user input is empty. + if (address_copy.IsFieldEmpty(focused_field)) + return; + + if (focused_field == POSTAL_CODE) { + // Do not suggest anything if the user is typing an invalid postal code. + FieldProblemMap problems; + FieldProblemMap filter; + filter.insert(std::make_pair(POSTAL_CODE, INVALID_FORMAT)); + validator_.Validate(address_copy, + true, // Allow postal office boxes. + false, // Do not require recipient name. + &filter, + &problems, + *validated_); + if (!problems.empty()) + return; + + // Fill in the sub-regions based on the postal code. + input_helper_.FillAddress(&address_copy); + } + + // Lazily initialize the mapping from COUNTRY level regions to all of their + // sub-regions with metadata for generating suggestions. + std::string unused_best_language; + const RegionData& region_data = + region_data_builder_.Build(address_copy.region_code, + address_copy.language_code, + &unused_best_language); + SubRegionData* sub_region_data = &sub_regions_[®ion_data]; + if (!sub_region_data->is_initialized()) + sub_region_data->Initialize(region_data, canonicalizer_); + + // Build the list of regions that match |address_copy| when the user is typing + // in the |focused_field|. + std::vector<Suggestion> suggested_regions; + sub_region_data->BuildSuggestions( + address_copy, focused_field, &suggested_regions); + + FieldProblemMap problems; + FieldProblemMap filter; + filter.insert(std::make_pair(POSTAL_CODE, MISMATCHING_VALUE)); + + // Generate suggestions based on the regions. + for (std::vector<Suggestion>::const_iterator suggested_region_it = + suggested_regions.begin(); + suggested_region_it != suggested_regions.end(); + ++suggested_region_it) { + AddressData address; + address.region_code = address_copy.region_code; + address.postal_code = address_copy.postal_code; + + // Traverse the tree of regions from the smallest |region_to_suggest| to the + // country-wide "root" of the tree. Use the region names or keys found at + // each of the levels of the tree to build the |address| to suggest. + AddressField address_field = suggested_region_it->matching_address_field; + for (const RegionData* region = suggested_region_it->region_to_suggest; + region->has_parent(); + region = ®ion->parent()) { + address.SetFieldValue(address_field, + suggested_region_it->region_key_matches + ? region->key() + : region->name()); + address_field = static_cast<AddressField>(address_field - 1); + } + + // Do not suggest an address with a mismatching postal code. + problems.clear(); + validator_.Validate(address, + true, // Allow postal office boxes. + false, // Do not require recipient name. + &filter, + &problems, + *validated_); + if (!problems.empty()) + continue; + + // Do not add more suggestions than |suggestions_limit|. + if (suggestions->size() >= suggestions_limit) { + suggestions->clear(); + return; + } + + suggestions->push_back(address); + } +} + +void InputSuggester::Validated(bool success, + const AddressData&, + const FieldProblemMap&) { + DCHECK(success); +} + +} // namespace autofill diff --git a/third_party/libaddressinput/chromium/input_suggester.h b/third_party/libaddressinput/chromium/input_suggester.h new file mode 100644 index 0000000..b361057 --- /dev/null +++ b/third_party/libaddressinput/chromium/input_suggester.h @@ -0,0 +1,133 @@ +// 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_INPUT_SUGGESTER_H_ +#define THIRD_PARTY_LIBADDRESSINPUT_CHROMIUM_INPUT_SUGGESTER_H_ + +#include <stdint.h> +#include <map> +#include <vector> + +#include "base/basictypes.h" +#include "base/memory/scoped_ptr.h" +#include "third_party/icu/source/i18n/unicode/coll.h" +#include "third_party/libaddressinput/src/cpp/include/libaddressinput/address_field.h" +#include "third_party/libaddressinput/src/cpp/include/libaddressinput/address_input_helper.h" +#include "third_party/libaddressinput/src/cpp/include/libaddressinput/address_validator.h" +#include "third_party/libaddressinput/src/cpp/include/libaddressinput/region_data_builder.h" + +namespace i18n { +namespace addressinput { +class PreloadSupplier; +class RegionData; +struct AddressData; +} +} + +namespace autofill { + +// Suggests address completions for a partially entered address from the user. +class InputSuggester { + public: + // Does not take ownership of |supplier|, which should not be NULL. + explicit InputSuggester(::i18n::addressinput::PreloadSupplier* supplier); + ~InputSuggester(); + + // 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. + // + // 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"}] + // + // Builds the index for generating suggestions lazily. + // + // The |suggestions| parameter should not be NULL. The |focused_field| + // parameter should be either POSTAL_CODE or between ADMIN_AREA and + // DEPENDENT_LOCALITY inclusively. + void GetSuggestions( + const ::i18n::addressinput::AddressData& user_input, + ::i18n::addressinput::AddressField focused_field, + size_t suggestion_limit, + std::vector< ::i18n::addressinput::AddressData>* suggestions); + + private: + class SubRegionData; + + // Canonicalizes strings for case and diacritic insensitive comparison. + class StringCanonicalizer { + public: + // Initializes the canonicalizer. This is slow, so avoid calling it more + // often than necessary. + StringCanonicalizer(); + ~StringCanonicalizer(); + + // Returns a 0-terminated canonical version of the string that can be used + // for comparing strings regardless of diacritics and capitalization. + // Canonicalize("Texas") == Canonicalize("T\u00E9xas"); + // Canonicalize("Texas") == Canonicalize("teXas"); + // Canonicalize("Texas") != Canonicalize("California"); + // + // The output is not human-readable. + // Canonicalize("Texas") != "Texas"; + // + // The |original| parameter should not be empty. + const std::vector<uint8_t>& Canonicalize(const std::string& original) const; + + private: + int32_t buffer_size() const; + + mutable std::vector<uint8_t> buffer_; + scoped_ptr<icu::Collator> collator_; + + DISALLOW_COPY_AND_ASSIGN(StringCanonicalizer); + }; + + // The method to be invoked by |validated_| callback. + void Validated(bool success, + const ::i18n::addressinput::AddressData&, + const ::i18n::addressinput::FieldProblemMap&); + + // Data source for region data. + ::i18n::addressinput::RegionDataBuilder region_data_builder_; + + // Suggests sub-regions based on postal code. + const ::i18n::addressinput::AddressInputHelper input_helper_; + + // Verifies that suggested sub-regions match the postal code. + ::i18n::addressinput::AddressValidator validator_; + + // The callback for |validator_| to invoke when validation finishes. + const scoped_ptr<const ::i18n::addressinput::AddressValidator::Callback> + validated_; + + // A mapping from a COUNTRY level region to a collection of all of its + // sub-regions along with metadata used to construct suggestions. + std::map<const ::i18n::addressinput::RegionData*, SubRegionData> sub_regions_; + + // Canonicalizes strings for case and diacritic insensitive search of + // sub-region names. + StringCanonicalizer canonicalizer_; + + DISALLOW_COPY_AND_ASSIGN(InputSuggester); +}; + +} // namespace autofill + +#endif // THIRD_PARTY_LIBADDRESSINPUT_CHROMIUM_INPUT_SUGGESTER_H_ diff --git a/third_party/libaddressinput/chromium/json.cc b/third_party/libaddressinput/chromium/json.cc index 5437e1e..7e1a66a 100644 --- a/third_party/libaddressinput/chromium/json.cc +++ b/third_party/libaddressinput/chromium/json.cc @@ -2,12 +2,16 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "cpp/src/util/json.h" +#include "third_party/libaddressinput/src/cpp/src/util/json.h" + +#include <map> +#include <utility> #include "base/basictypes.h" #include "base/json/json_reader.h" #include "base/logging.h" #include "base/memory/scoped_ptr.h" +#include "base/stl_util.h" #include "base/values.h" namespace i18n { @@ -15,108 +19,128 @@ namespace addressinput { namespace { -// A base class for Chrome Json objects. JSON gets parsed into a -// base::DictionaryValue and data is accessed via the Json interface. -class ChromeJson : public Json { - public: - virtual bool GetStringValueForKey(const std::string& key, std::string* value) - const OVERRIDE; - virtual bool GetJsonValueForKey(const std::string& key, - scoped_ptr<Json>* value) const OVERRIDE; - protected: - ChromeJson() {} - virtual ~ChromeJson() {} +// Returns |json| parsed into a JSON dictionary. Sets |parser_error| to true if +// parsing failed. +::scoped_ptr<const base::DictionaryValue> Parse(const std::string& json, + bool* parser_error) { + DCHECK(parser_error); + ::scoped_ptr<const base::DictionaryValue> result; - virtual const base::DictionaryValue* GetDict() const = 0; + // |json| is converted to a |c_str()| here because rapidjson and other parts + // of the standalone library use char* rather than std::string. + ::scoped_ptr<const base::Value> parsed(base::JSONReader::Read(json.c_str())); + *parser_error = !parsed || !parsed->IsType(base::Value::TYPE_DICTIONARY); - DISALLOW_COPY_AND_ASSIGN(ChromeJson); -}; + if (*parser_error) + result.reset(new base::DictionaryValue); + else + result.reset(static_cast<const base::DictionaryValue*>(parsed.release())); -// A Json object that will parse a string and own the parsed data. -class JsonDataOwner : public ChromeJson { - public: - JsonDataOwner() {} - virtual ~JsonDataOwner() {} + return result.Pass(); +} - virtual bool ParseObject(const std::string& json) OVERRIDE { - dict_.reset(); +// Returns the list of keys in |dict|. +std::vector<std::string> GetKeysFromDictionary( + const base::DictionaryValue& dict) { + std::vector<std::string> keys; + for (base::DictionaryValue::Iterator it(dict); !it.IsAtEnd(); it.Advance()) + keys.push_back(it.key()); + return keys; +} - // |json| is converted to a |c_str()| here because rapidjson and other parts - // of the standalone library use char* rather than std::string. - scoped_ptr<base::Value> parsed(base::JSONReader::Read(json.c_str())); - if (parsed && parsed->IsType(base::Value::TYPE_DICTIONARY)) - dict_.reset(static_cast<base::DictionaryValue*>(parsed.release())); +} // namespace - return !!dict_; - } +// Implementation of JSON parser for libaddressinput using JSON parser in +// Chrome. +class Json::JsonImpl { + public: + explicit JsonImpl(const std::string& json) + : owned_(Parse(json, &parser_error_)), + dict_(*owned_), + keys_(GetKeysFromDictionary(dict_)) {} - protected: - virtual const base::DictionaryValue* GetDict() const OVERRIDE { - return dict_.get(); - } + ~JsonImpl() { STLDeleteValues(&sub_dicts_); } - private: - scoped_ptr<base::DictionaryValue> dict_; + bool parser_error() const { return parser_error_; } - DISALLOW_COPY_AND_ASSIGN(JsonDataOwner); -}; + const std::vector<std::string>& keys() const { return keys_; } -// A Json object which will point to data that's been parsed by a different -// ChromeJson. It does not own its data and is only valid as long as its parent -// ChromeJson is valid. -class JsonDataCopy : public ChromeJson { - public: - explicit JsonDataCopy(const base::DictionaryValue* dict) : - dict_(dict) {} - virtual ~JsonDataCopy() {} + bool GetStringValueForKey(const std::string& key, std::string* value) const { + return dict_.GetStringWithoutPathExpansion(key, value); + } - virtual bool ParseObject(const std::string& json) OVERRIDE { - NOTREACHED(); - return false; + bool HasDictionaryValueForKey(const std::string& key) { + return !!FindDictionary(key); } - protected: - virtual const base::DictionaryValue* GetDict() const OVERRIDE { - return dict_; + const Json& GetDictionaryValueForKey(const std::string& key) { + const Json* result = FindDictionary(key); + DCHECK(result); + return *result; } private: - const base::DictionaryValue* dict_; // weak reference. + explicit JsonImpl(const base::DictionaryValue& dict) + : parser_error_(false), dict_(dict), keys_(GetKeysFromDictionary(dict)) {} - DISALLOW_COPY_AND_ASSIGN(JsonDataCopy); -}; + // The caller does not own the returned value, which can be NULL if there's no + // dictionary for |key|. + const Json* FindDictionary(const std::string& key) { + std::map<std::string, Json*>::const_iterator it = sub_dicts_.find(key); + if (it != sub_dicts_.end()) + return it->second; -// ChromeJson ------------------------------------------------------------------ + const base::DictionaryValue* sub_dict = NULL; + if (!dict_.GetDictionaryWithoutPathExpansion(key, &sub_dict) || !sub_dict) + return NULL; -bool ChromeJson::GetStringValueForKey(const std::string& key, - std::string* value) const { - return GetDict()->GetStringWithoutPathExpansion(key, value); -} + std::pair<std::map<std::string, Json*>::iterator, bool> result = + sub_dicts_.insert(std::make_pair(key, new Json)); + DCHECK(result.second); + + Json* sub_json = result.first->second; + sub_json->impl_.reset(new JsonImpl(*sub_dict)); -bool ChromeJson::GetJsonValueForKey(const std::string& key, - scoped_ptr<Json>* value) const { - const base::DictionaryValue* sub_dict = NULL; - if (!GetDict()->GetDictionaryWithoutPathExpansion(key, &sub_dict) || - !sub_dict) { - return false; + return sub_json; } - if (value) - value->reset(new JsonDataCopy(sub_dict)); + const ::scoped_ptr<const base::DictionaryValue> owned_; + bool parser_error_; + const base::DictionaryValue& dict_; + const std::vector<std::string> keys_; + std::map<std::string, Json*> sub_dicts_; - return true; -} + DISALLOW_COPY_AND_ASSIGN(JsonImpl); +}; -} // namespace +Json::Json() {} Json::~Json() {} -// static -scoped_ptr<Json> Json::Build() { - return scoped_ptr<Json>(new JsonDataOwner); +bool Json::ParseObject(const std::string& json) { + DCHECK(!impl_); + impl_.reset(new JsonImpl(json)); + if (impl_->parser_error()) + impl_.reset(); + return !!impl_; } -Json::Json() {} +const std::vector<std::string>& Json::GetKeys() const { + return impl_->keys(); +} + +bool Json::GetStringValueForKey(const std::string& key, + std::string* value) const { + return impl_->GetStringValueForKey(key, value); +} + +bool Json::HasDictionaryValueForKey(const std::string& key) const { + return impl_->HasDictionaryValueForKey(key); +} + +const Json& Json::GetDictionaryValueForKey(const std::string& key) const { + return impl_->GetDictionaryValueForKey(key); +} } // namespace addressinput } // namespace i18n diff --git a/third_party/libaddressinput/chromium/libaddressinput_util.cc b/third_party/libaddressinput/chromium/libaddressinput_util.cc new file mode 100644 index 0000000..11f675f --- /dev/null +++ b/third_party/libaddressinput/chromium/libaddressinput_util.cc @@ -0,0 +1,72 @@ +// 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 "third_party/libaddressinput/chromium/libaddressinput_util.h" + +#include <algorithm> + +#include "base/logging.h" +#include "base/macros.h" +#include "third_party/libaddressinput/src/cpp/include/libaddressinput/address_data.h" +#include "third_party/libaddressinput/src/cpp/include/libaddressinput/address_metadata.h" + +namespace autofill { +namespace addressinput { + +namespace { + +using ::i18n::addressinput::AddressData; +using ::i18n::addressinput::AddressField; +using ::i18n::addressinput::AddressProblem; +using ::i18n::addressinput::IsFieldRequired; + +using ::i18n::addressinput::MISSING_REQUIRED_FIELD; + +// Based on ::i18n::addressinput::ValidationTask::ShouldReport(). +bool ShouldReport(const std::multimap<AddressField, AddressProblem>* filter, + AddressField field, + AddressProblem problem) { + return filter == NULL || filter->empty() || + std::find(filter->begin(), + filter->end(), + std::multimap<AddressField, AddressProblem>::value_type( + field, problem)) != filter->end(); +} + +} // namespace + +bool HasAllRequiredFields(const AddressData& address_to_check) { + std::multimap<AddressField, AddressProblem> problems; + ValidateRequiredFields(address_to_check, NULL, &problems); + return problems.empty(); +} + +void ValidateRequiredFields( + const AddressData& address_to_check, + const std::multimap<AddressField, AddressProblem>* filter, + std::multimap<AddressField, AddressProblem>* problems) { + DCHECK(problems); + + static const AddressField kFields[] = { + ::i18n::addressinput::COUNTRY, + ::i18n::addressinput::ADMIN_AREA, + ::i18n::addressinput::LOCALITY, + ::i18n::addressinput::DEPENDENT_LOCALITY, + ::i18n::addressinput::SORTING_CODE, + ::i18n::addressinput::POSTAL_CODE, + ::i18n::addressinput::STREET_ADDRESS, + ::i18n::addressinput::RECIPIENT}; + + for (size_t i = 0; i < arraysize(kFields); ++i) { + AddressField field = kFields[i]; + if (address_to_check.IsFieldEmpty(field) && + IsFieldRequired(field, address_to_check.region_code) && + ShouldReport(filter, field, MISSING_REQUIRED_FIELD)) { + problems->insert(std::make_pair(field, MISSING_REQUIRED_FIELD)); + } + } +} + +} // namespace addressinput +} // namespace autofill diff --git a/third_party/libaddressinput/chromium/libaddressinput_util.h b/third_party/libaddressinput/chromium/libaddressinput_util.h new file mode 100644 index 0000000..f03528d --- /dev/null +++ b/third_party/libaddressinput/chromium/libaddressinput_util.h @@ -0,0 +1,42 @@ +// 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_LIBADDRESSINPUT_UTIL_H_ +#define THIRD_PARTY_LIBADDRESSINPUT_CHROMIUM_LIBADDRESSINPUT_UTIL_H_ + +#include <map> + +#include "third_party/libaddressinput/src/cpp/include/libaddressinput/address_field.h" +#include "third_party/libaddressinput/src/cpp/include/libaddressinput/address_problem.h" + +namespace i18n { +namespace addressinput { +struct AddressData; +} +} + +namespace autofill { +namespace addressinput { + +// Returns true if |address_to_check| has all of its required fields. +bool HasAllRequiredFields( + const ::i18n::addressinput::AddressData& address_to_check); + +// Validates required fields in |address_to_check| without loading rules from +// the server. The |problems| parameter cannot be NULL. Does not take ownership +// of its parameters. +// +// See documentation of ::i18n::addressinput::AddressValidator::Validate() for +// description of |filter| and |problems|. +void ValidateRequiredFields( + const ::i18n::addressinput::AddressData& address_to_check, + const std::multimap< ::i18n::addressinput::AddressField, + ::i18n::addressinput::AddressProblem>* filter, + std::multimap< ::i18n::addressinput::AddressField, + ::i18n::addressinput::AddressProblem>* problems); + +} // namespace addressinput +} // namespace autofill + +#endif // THIRD_PARTY_LIBADDRESSINPUT_CHROMIUM_LIBADDRESSINPUT_UTIL_H_ diff --git a/third_party/libaddressinput/chromium/libaddressinput_util_unittest.cc b/third_party/libaddressinput/chromium/libaddressinput_util_unittest.cc new file mode 100644 index 0000000..23b0b93 --- /dev/null +++ b/third_party/libaddressinput/chromium/libaddressinput_util_unittest.cc @@ -0,0 +1,41 @@ +// 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 "third_party/libaddressinput/chromium/libaddressinput_util.h" + +#include "testing/gtest/include/gtest/gtest.h" +#include "third_party/libaddressinput/src/cpp/include/libaddressinput/address_data.h" + +namespace autofill { +namespace addressinput { + +using ::i18n::addressinput::AddressData; + +TEST(RequiredFieldsTest, AddressRequiresRegionCode) { + AddressData address; + EXPECT_FALSE(HasAllRequiredFields(address)); +} + +TEST(RequiredFieldsTest, UsRequiresState) { + AddressData address; + address.region_code = "US"; + address.postal_code = "90291"; + // Leave state empty. + address.locality = "Los Angeles"; + address.address_line.push_back("340 Main St."); + EXPECT_FALSE(HasAllRequiredFields(address)); +} + +TEST(RequiredFieldsTest, CompleteAddressReturnsTrue) { + AddressData address; + address.region_code = "US"; + address.postal_code = "90291"; + address.administrative_area = "CA"; + address.locality = "Los Angeles"; + address.address_line.push_back("340 Main St."); + EXPECT_TRUE(HasAllRequiredFields(address)); +} + +} // namespace addressinput +} // namespace autofill diff --git a/third_party/libaddressinput/chromium/override/basictypes_override.h b/third_party/libaddressinput/chromium/override/basictypes_override.h new file mode 100644 index 0000000..699bc0f --- /dev/null +++ b/third_party/libaddressinput/chromium/override/basictypes_override.h @@ -0,0 +1,10 @@ +// 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_BASICTYPES_OVERRIDE_H_ +#define THIRD_PARTY_LIBADDRESSINPUT_CHROMIUM_BASICTYPES_OVERRIDE_H_ + +#include "base/basictypes.h" + +#endif // THIRD_PARTY_LIBADDRESSINPUT_CHROMIUM_BASICTYPES_OVERRIDE_H_ diff --git a/third_party/libaddressinput/chromium/preload_address_validator.cc b/third_party/libaddressinput/chromium/preload_address_validator.cc deleted file mode 100644 index 816e3a5..0000000 --- a/third_party/libaddressinput/chromium/preload_address_validator.cc +++ /dev/null @@ -1,144 +0,0 @@ -// 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/storage_test_runner.cc b/third_party/libaddressinput/chromium/storage_test_runner.cc new file mode 100644 index 0000000..453f0f2 --- /dev/null +++ b/third_party/libaddressinput/chromium/storage_test_runner.cc @@ -0,0 +1,88 @@ +// 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 "third_party/libaddressinput/chromium/storage_test_runner.h" + +#include <cassert> +#include <cstddef> +#include <string> + +#include "testing/gtest/include/gtest/gtest.h" +#include "third_party/libaddressinput/src/cpp/include/libaddressinput/callback.h" + +namespace autofill { + +using ::i18n::addressinput::Storage; + +StorageTestRunner::StorageTestRunner(Storage* storage) + : storage_(storage), + success_(false), + key_(), + data_() {} + +StorageTestRunner::~StorageTestRunner() {} + +void StorageTestRunner::RunAllTests() { + EXPECT_NO_FATAL_FAILURE(GetWithoutPutReturnsEmptyData()); + EXPECT_NO_FATAL_FAILURE(GetReturnsWhatWasPut()); + EXPECT_NO_FATAL_FAILURE(SecondPutOverwritesData()); +} + +void StorageTestRunner::ClearValues() { + success_ = false; + key_.clear(); + data_.clear(); +} + +scoped_ptr<Storage::Callback> StorageTestRunner::BuildCallback() { + return scoped_ptr<Storage::Callback>(::i18n::addressinput::BuildCallback( + this, &StorageTestRunner::OnDataReady)); +} + +void StorageTestRunner::OnDataReady(bool success, + const std::string& key, + std::string* data) { + assert(!success || data != NULL); + success_ = success; + key_ = key; + if (data != NULL) { + data_ = *data; + delete data; + } +} + +void StorageTestRunner::GetWithoutPutReturnsEmptyData() { + ClearValues(); + scoped_ptr<Storage::Callback> callback(BuildCallback()); + storage_->Get("key", *callback); + + EXPECT_FALSE(success_); + EXPECT_EQ("key", key_); + EXPECT_TRUE(data_.empty()); +} + +void StorageTestRunner::GetReturnsWhatWasPut() { + ClearValues(); + storage_->Put("key", new std::string("value")); + scoped_ptr<Storage::Callback> callback(BuildCallback()); + storage_->Get("key", *callback); + + EXPECT_TRUE(success_); + EXPECT_EQ("key", key_); + EXPECT_EQ("value", data_); +} + +void StorageTestRunner::SecondPutOverwritesData() { + ClearValues(); + storage_->Put("key", new std::string("bad-value")); + storage_->Put("key", new std::string("good-value")); + scoped_ptr<Storage::Callback> callback(BuildCallback()); + storage_->Get("key", *callback); + + EXPECT_TRUE(success_); + EXPECT_EQ("key", key_); + EXPECT_EQ("good-value", data_); +} + +} // namespace autofill diff --git a/third_party/libaddressinput/chromium/storage_test_runner.h b/third_party/libaddressinput/chromium/storage_test_runner.h new file mode 100644 index 0000000..113587d --- /dev/null +++ b/third_party/libaddressinput/chromium/storage_test_runner.h @@ -0,0 +1,47 @@ +// 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_STORAGE_TEST_RUNNER_H_ +#define THIRD_PARTY_LIBADDRESSINPUT_CHROMIUM_STORAGE_TEST_RUNNER_H_ + +#include "third_party/libaddressinput/src/cpp/include/libaddressinput/storage.h" + +#include <string> + +#include "base/basictypes.h" +#include "base/memory/scoped_ptr.h" + +namespace autofill { + +// A test sutie for ::i18n::addressinput::Storage. +class StorageTestRunner { + public: + // Does not take ownership of |storage|. + explicit StorageTestRunner(::i18n::addressinput::Storage* storage); + ~StorageTestRunner(); + + // Runs all the tests from the standard test suite. + void RunAllTests(); + + private: + void ClearValues(); + scoped_ptr< ::i18n::addressinput::Storage::Callback> BuildCallback(); + void OnDataReady(bool success, const std::string& key, std::string* data); + + // Test suite. + void GetWithoutPutReturnsEmptyData(); + void GetReturnsWhatWasPut(); + void SecondPutOverwritesData(); + + ::i18n::addressinput::Storage* storage_; // weak + bool success_; + std::string key_; + std::string data_; + + DISALLOW_COPY_AND_ASSIGN(StorageTestRunner); +}; + +} // namespace autofill + +#endif // THIRD_PARTY_LIBADDRESSINPUT_CHROMIUM_STORAGE_TEST_RUNNER_H_ diff --git a/third_party/libaddressinput/chromium/string_compare.cc b/third_party/libaddressinput/chromium/string_compare.cc new file mode 100644 index 0000000..9d247eb --- /dev/null +++ b/third_party/libaddressinput/chromium/string_compare.cc @@ -0,0 +1,69 @@ +// 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 "third_party/libaddressinput/src/cpp/src/util/string_compare.h" + +#include "base/basictypes.h" +#include "base/lazy_instance.h" +#include "base/logging.h" +#include "base/memory/scoped_ptr.h" +#include "third_party/icu/source/i18n/unicode/coll.h" + +namespace i18n { +namespace addressinput { + +namespace { + +class IcuStringComparer { + public: + IcuStringComparer() { + UErrorCode error_code = U_ZERO_ERROR; + collator_.reset( + icu::Collator::createInstance(icu::Locale::getRoot(), error_code)); + DCHECK(U_SUCCESS(error_code)); + collator_->setStrength(icu::Collator::PRIMARY); + } + + ~IcuStringComparer() {} + + int Compare(const std::string& a, const std::string& b) const { + UErrorCode error_code = U_ZERO_ERROR; + int result = collator_->compareUTF8(a, b, error_code); + DCHECK(U_SUCCESS(error_code)); + return result; + } + + private: + // ::scoped_ptr is from "base/memory/scoped_ptr.h", which does not interfere + // with ::i18n::addressinput::scoped_ptr from + // <libaddressinput/util/scoped_ptr.h>. + ::scoped_ptr<icu::Collator> collator_; + + DISALLOW_COPY_AND_ASSIGN(IcuStringComparer); +}; + +static base::LazyInstance<IcuStringComparer> g_comparer = + LAZY_INSTANCE_INITIALIZER; + +} // namespace + +// Dummy required for scoped_ptr<Impl>. +class StringCompare::Impl {}; + +StringCompare::StringCompare() {} + +StringCompare::~StringCompare() {} + +bool StringCompare::NaturalEquals(const std::string& a, + const std::string& b) const { + return g_comparer.Get().Compare(a, b) == 0; +} + +bool StringCompare::NaturalLess(const std::string& a, + const std::string& b) const { + return g_comparer.Get().Compare(a, b) < 0; +} + +} // namespace addressinput +} // namespace i18n diff --git a/third_party/libaddressinput/chromium/string_compare_unittest.cc b/third_party/libaddressinput/chromium/string_compare_unittest.cc new file mode 100644 index 0000000..0f9d9c7 --- /dev/null +++ b/third_party/libaddressinput/chromium/string_compare_unittest.cc @@ -0,0 +1,26 @@ +// 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 "third_party/libaddressinput/src/cpp/src/util/string_compare.h" + +#include "testing/gtest/include/gtest/gtest.h" + +namespace { + +TEST(ChromeStringCompareTest, IgnoreDiacritics) { + i18n::addressinput::StringCompare sc; + EXPECT_TRUE(sc.NaturalEquals("Texas", "T\u00E9xas")); +} + +TEST(ChromeStringCompareTest, IgnoreCapitalization) { + i18n::addressinput::StringCompare sc; + EXPECT_TRUE(sc.NaturalEquals("Texas", "teXas")); +} + +TEST(ChromeStringCompareTest, DifferentStringAreDifferent) { + i18n::addressinput::StringCompare sc; + EXPECT_FALSE(sc.NaturalEquals("Texas", "California")); +} + +} // namespace diff --git a/third_party/libaddressinput/chromium/trie.cc b/third_party/libaddressinput/chromium/trie.cc new file mode 100644 index 0000000..e9289af --- /dev/null +++ b/third_party/libaddressinput/chromium/trie.cc @@ -0,0 +1,81 @@ +// 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 "third_party/libaddressinput/chromium/trie.h" + +#include <queue> +#include <string> + +#include "base/logging.h" + +// Separating template definitions and declarations requires defining all +// possible template parameters to avoid linking errors. +namespace i18n { +namespace addressinput { +class RegionData; +} +} + +namespace autofill { + +template <typename T> +Trie<T>::Trie() {} + +template <typename T> +Trie<T>::~Trie() {} + +template <typename T> +void Trie<T>::AddDataForKey(const std::vector<uint8_t>& key, + const T& data_item) { + Trie<T>* current_node = this; + for (std::vector<uint8_t>::size_type i = 0; i < key.size(); ++i) { + if (!key[i]) + break; + current_node = ¤t_node->sub_nodes_[key[i]]; + } + current_node->data_list_.insert(data_item); +} + +template <typename T> +void Trie<T>::FindDataForKeyPrefix(const std::vector<uint8_t>& key_prefix, + std::set<T>* results) const { + DCHECK(results); + + // Find the sub-trie for the key prefix. + const Trie<T>* current_node = this; + for (std::vector<uint8_t>::size_type i = 0; i < key_prefix.size(); ++i) { + if (!key_prefix[i]) + break; + + typename std::map<uint8_t, Trie<T> >::const_iterator sub_node_it = + current_node->sub_nodes_.find(key_prefix[i]); + if (sub_node_it == current_node->sub_nodes_.end()) + return; + + current_node = &sub_node_it->second; + } + + // Collect data from all sub-tries. + std::queue<const Trie<T>*> node_queue; + node_queue.push(current_node); + while (!node_queue.empty()) { + const Trie<T>* queue_front = node_queue.front(); + node_queue.pop(); + + results->insert(queue_front->data_list_.begin(), + queue_front->data_list_.end()); + + for (typename std::map<uint8_t, Trie<T> >::const_iterator sub_node_it = + queue_front->sub_nodes_.begin(); + sub_node_it != queue_front->sub_nodes_.end(); + ++sub_node_it) { + node_queue.push(&sub_node_it->second); + } + } +} + +template class Trie<const ::i18n::addressinput::RegionData*>; +template class Trie<std::string>; + +} // namespace autofill diff --git a/third_party/libaddressinput/chromium/trie.h b/third_party/libaddressinput/chromium/trie.h new file mode 100644 index 0000000..914897e --- /dev/null +++ b/third_party/libaddressinput/chromium/trie.h @@ -0,0 +1,54 @@ +// 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_TRIE_H_ +#define THIRD_PARTY_LIBADDRESSINPUT_CHROMIUM_TRIE_H_ + +#include <stdint.h> +#include <map> +#include <set> +#include <vector> + +namespace autofill { + +// A prefix search tree. Can return all objects whose keys start with a prefix +// byte sequence. +// +// Maps keys to multiple objects. This property is useful when mapping region +// names to region objects. For example, there's a "St. Petersburg" in Florida, +// and there's a "St. Petersburg" in Russia. A lookup for "St. Petersburg" key +// should return two distinct objects. +template <typename T> +class Trie { + public: + Trie(); + ~Trie(); + + // Returns true if no data was added in AddDataForKey(). + bool empty() const { return data_list_.empty() && sub_nodes_.empty(); } + + // Adds a mapping from the 0 terminated |key| to |data_item|. Can be called + // with the same |key| multiple times. + void AddDataForKey(const std::vector<uint8_t>& key, const T& data_item); + + // Adds all objects whose keys start with the 0 terminated |key_prefix| to the + // |results| parameter. The |results| parameter should not be NULL. + void FindDataForKeyPrefix(const std::vector<uint8_t>& key_prefix, + std::set<T>* results) const; + + private: + // All objects for this node in the Trie. This field is a collection to enable + // mapping the same key to multiple objects. + std::set<T> data_list_; + + // Trie sub nodes. The root Trie stores the objects for the empty key. The + // children of the root Trie store the objects for the one-byte keys. The + // grand-children of the root Trie store the objects for the two-byte keys, + // and so on. + std::map<uint8_t, Trie<T> > sub_nodes_; +}; + +} // namespace autofill + +#endif // THIRD_PARTY_LIBADDRESSINPUT_CHROMIUM_TRIE_H_ diff --git a/third_party/libaddressinput/chromium/trie_unittest.cc b/third_party/libaddressinput/chromium/trie_unittest.cc new file mode 100644 index 0000000..32b0bb1 --- /dev/null +++ b/third_party/libaddressinput/chromium/trie_unittest.cc @@ -0,0 +1,109 @@ +// 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 "third_party/libaddressinput/chromium/trie.h" + +#include <stdint.h> +#include <set> +#include <string> + +#include "testing/gtest/include/gtest/gtest.h" + +namespace autofill { + +namespace { + +std::vector<uint8_t> ToByteArray(const std::string& text) { + std::vector<uint8_t> result(text.length() + 1, 0); + result.assign(text.begin(), text.end()); + return result; +} + +} // namespace + +TEST(TrieTest, EmptyTrieHasNoData) { + Trie<std::string> trie; + std::set<std::string> result; + trie.FindDataForKeyPrefix(ToByteArray("key"), &result); + EXPECT_TRUE(result.empty()); +} + +TEST(TrieTest, CanGetDataByExactKey) { + Trie<std::string> trie; + trie.AddDataForKey(ToByteArray("hello"), "world"); + std::set<std::string> result; + trie.FindDataForKeyPrefix(ToByteArray("hello"), &result); + std::set<std::string> expected; + expected.insert("world"); + EXPECT_EQ(expected, result); +} + +TEST(TrieTest, CanGetDataByPrefix) { + Trie<std::string> trie; + trie.AddDataForKey(ToByteArray("hello"), "world"); + std::set<std::string> result; + trie.FindDataForKeyPrefix(ToByteArray("he"), &result); + std::set<std::string> expected; + expected.insert("world"); + EXPECT_EQ(expected, result); +} + +TEST(TrieTest, KeyTooLongNoData) { + Trie<std::string> trie; + trie.AddDataForKey(ToByteArray("hello"), "world"); + std::set<std::string> result; + trie.FindDataForKeyPrefix(ToByteArray("helloo"), &result); + EXPECT_TRUE(result.empty()); +} + +TEST(TrieTest, CommonPrefixFindsMultipleData) { + Trie<std::string> trie; + trie.AddDataForKey(ToByteArray("hello"), "world"); + trie.AddDataForKey(ToByteArray("howdy"), "buddy"); + trie.AddDataForKey(ToByteArray("foo"), "bar"); + std::set<std::string> results; + trie.FindDataForKeyPrefix(ToByteArray("h"), &results); + std::set<std::string> expected; + expected.insert("world"); + expected.insert("buddy"); + EXPECT_EQ(expected, results); +} + +TEST(TrieTest, KeyCanBePrefixOfOtherKey) { + Trie<std::string> trie; + trie.AddDataForKey(ToByteArray("hello"), "world"); + trie.AddDataForKey(ToByteArray("helloo"), "woorld"); + trie.AddDataForKey(ToByteArray("hella"), "warld"); + std::set<std::string> results; + trie.FindDataForKeyPrefix(ToByteArray("hello"), &results); + std::set<std::string> expected; + expected.insert("world"); + expected.insert("woorld"); + EXPECT_EQ(expected, results); +} + +TEST(TrieTest, AllowMutlipleKeys) { + Trie<std::string> trie; + trie.AddDataForKey(ToByteArray("hello"), "world"); + trie.AddDataForKey(ToByteArray("hello"), "woorld"); + std::set<std::string> results; + trie.FindDataForKeyPrefix(ToByteArray("hello"), &results); + std::set<std::string> expected; + expected.insert("world"); + expected.insert("woorld"); + EXPECT_EQ(expected, results); +} + +TEST(TrieTest, CanFindVeryLongKey) { + Trie<std::string> trie; + static const char kVeryLongKey[] = "1234567890qwertyuioasdfghj"; + trie.AddDataForKey(ToByteArray(kVeryLongKey), "world"); + std::set<std::string> result; + trie.FindDataForKeyPrefix(ToByteArray(kVeryLongKey), &result); + std::set<std::string> expected; + expected.insert("world"); + EXPECT_EQ(expected, result); +} + +} // namespace autofill diff --git a/third_party/libaddressinput/libaddressinput.gyp b/third_party/libaddressinput/libaddressinput.gyp index e9d1852..e0aa83b 100644 --- a/third_party/libaddressinput/libaddressinput.gyp +++ b/third_party/libaddressinput/libaddressinput.gyp @@ -2,239 +2,160 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. { + 'includes': ['src/cpp/libaddressinput.gypi'], 'variables': { - # TODO(rouslan): Use the src/ directory. http://crbug.com/327046 - 'libaddressinput_dir': 'chromium', - }, - 'target_defaults': { - 'conditions': [ - ['OS=="mac" or OS=="ios"', { - 'xcode_settings': { - 'GCC_WARN_ABOUT_MISSING_NEWLINE': 'NO', - }, - }], - ], - 'defines': [ - 'CUSTOM_BASICTYPES="base/basictypes.h"', - 'CUSTOM_SCOPED_PTR="base/memory/scoped_ptr.h"', + 'libaddressinput_util_files': [ + 'src/cpp/src/address_data.cc', + 'src/cpp/src/address_field.cc', + 'src/cpp/src/address_field_util.cc', + 'src/cpp/src/address_formatter.cc', + 'src/cpp/src/address_metadata.cc', + 'src/cpp/src/address_ui.cc', + 'src/cpp/src/format_element.cc', + 'src/cpp/src/language.cc', + 'src/cpp/src/localization.cc', + 'src/cpp/src/lookup_key.cc', + 'src/cpp/src/region_data_constants.cc', + 'src/cpp/src/rule.cc', + 'src/cpp/src/util/cctype_tolower_equal.cc', + 'src/cpp/src/util/json.cc', + 'src/cpp/src/util/string_split.cc', + 'src/cpp/src/util/string_util.cc', ], }, 'targets': [ { - # GN version: //third_party/libaddressinput:strings 'target_name': 'libaddressinput_strings', 'type': 'none', 'variables': { 'grit_out_dir': '<(SHARED_INTERMEDIATE_DIR)/third_party/libaddressinput/', + 'grit_grd_file': '../../chrome/app/address_input_strings.grd', }, 'actions': [ { 'action_name': 'libaddressinput_strings', 'variables': { - 'grit_grd_file': '<(libaddressinput_dir)/cpp/res/libaddressinput_strings.grd', }, 'includes': [ '../../build/grit_action.gypi', ], }, ], - 'includes': [ - '../../build/grit_target.gypi', - ], - }, - { - # GN version: //third_party/libaddressinput:updated_strings - 'target_name': 'libaddressinput_updated_strings', - 'type': 'none', - 'variables': { - 'grit_out_dir': '<(SHARED_INTERMEDIATE_DIR)/grit/libaddressinput/', + 'direct_dependent_settings': { + # Files in libaddressinput include the grit-generated en_messages.cc + # without knowing its path. + 'include_dirs': [ + '<(grit_out_dir)', + ], }, - 'actions': [ - { - 'action_name': 'libaddressinput_updated_strings', - 'variables': { - 'grit_grd_file': '../../chrome/app/address_input_strings.grd', - }, - 'includes': [ - '../../build/grit_action.gypi', - ], - }, - ], - 'includes': [ - '../../build/grit_target.gypi', - ], }, - # This target provides basic functionality which is cooked into the build. { - # GN version: //third_party/libaddressinput:util 'target_name': 'libaddressinput_util', 'type': 'static_library', - 'include_dirs': [ - '<(libaddressinput_dir)/cpp/include/', - '<(SHARED_INTERMEDIATE_DIR)/libaddressinput/', - ], 'sources': [ + '<@(libaddressinput_util_files)', 'chromium/addressinput_util.cc', - 'chromium/addressinput_util.h', - 'chromium/canonicalize_string.cc', 'chromium/json.cc', - '<(libaddressinput_dir)/cpp/include/libaddressinput/address_data.h', - '<(libaddressinput_dir)/cpp/include/libaddressinput/address_field.h', - '<(libaddressinput_dir)/cpp/include/libaddressinput/address_formatter.h', - '<(libaddressinput_dir)/cpp/include/libaddressinput/address_metadata.h', - '<(libaddressinput_dir)/cpp/include/libaddressinput/address_problem.h', - '<(libaddressinput_dir)/cpp/include/libaddressinput/util/basictypes.h', - '<(libaddressinput_dir)/cpp/include/libaddressinput/util/internal/basictypes.h', - '<(libaddressinput_dir)/cpp/include/libaddressinput/util/internal/move.h', - '<(libaddressinput_dir)/cpp/include/libaddressinput/util/internal/scoped_ptr.h', - '<(libaddressinput_dir)/cpp/include/libaddressinput/util/internal/template_util.h', - '<(libaddressinput_dir)/cpp/include/libaddressinput/util/scoped_ptr.h', - '<(libaddressinput_dir)/cpp/src/address_data.cc', - '<(libaddressinput_dir)/cpp/src/address_field.cc', - '<(libaddressinput_dir)/cpp/src/address_formatter.cc', - '<(libaddressinput_dir)/cpp/src/address_metadata.cc', - '<(libaddressinput_dir)/cpp/src/address_problem.cc', - '<(libaddressinput_dir)/cpp/src/language.cc', - '<(libaddressinput_dir)/cpp/src/language.h', - '<(libaddressinput_dir)/cpp/src/region_data_constants.cc', - '<(libaddressinput_dir)/cpp/src/region_data_constants.h', - '<(libaddressinput_dir)/cpp/src/rule.cc', - '<(libaddressinput_dir)/cpp/src/rule.h', - '<(libaddressinput_dir)/cpp/src/util/canonicalize_string.h', - '<(libaddressinput_dir)/cpp/src/util/cctype_tolower_equal.cc', - '<(libaddressinput_dir)/cpp/src/util/cctype_tolower_equal.h', - '<(libaddressinput_dir)/cpp/src/util/json.h', - '<(libaddressinput_dir)/cpp/src/util/stl_util.h', - '<(libaddressinput_dir)/cpp/src/util/string_util.cc', - '<(libaddressinput_dir)/cpp/src/util/string_util.h', ], - 'dependencies': [ - '<(DEPTH)/base/base.gyp:base', - '<(DEPTH)/base/base.gyp:base_i18n', - '<(DEPTH)/third_party/icu/icu.gyp:icui18n', - '<(DEPTH)/third_party/icu/icu.gyp:icuuc', - '<(DEPTH)/third_party/re2/re2.gyp:re2', + 'sources!': [ + 'src/cpp/src/util/json.cc', + ], + 'conditions': [ + ['OS=="mac" or OS=="ios"', { + # localization.cc in libaddressinput_util_files includes + # grit-generated en_messages.cc, which does not have a newline. + 'xcode_settings': { + 'GCC_WARN_ABOUT_MISSING_NEWLINE': 'NO', + }, + }], + ], + 'include_dirs': [ + 'chromium/override/', + 'src/cpp/include/', + ], + 'defines': [ + 'I18N_ADDRESSINPUT_USE_BASICTYPES_OVERRIDE=1', ], 'direct_dependent_settings': { - 'defines': [ - 'CUSTOM_BASICTYPES="base/basictypes.h"', - 'CUSTOM_SCOPED_PTR="base/memory/scoped_ptr.h"', - ], 'include_dirs': [ - '<(libaddressinput_dir)/cpp/include/', + 'chromium/override/', + 'src/cpp/include/', + ], + 'defines': [ + 'I18N_ADDRESSINPUT_USE_BASICTYPES_OVERRIDE=1', ], }, + 'dependencies': [ + '../re2/re2.gyp:re2', + 'libaddressinput_strings', + ], + 'export_dependent_settings': [ + 'libaddressinput_strings', + ], }, - # This target provides more complicated functionality like pinging servers - # for validation rules. { - # GN version: //third_party/libaddressinput 'target_name': 'libaddressinput', 'type': 'static_library', - 'include_dirs': [ - '<(libaddressinput_dir)/cpp/include/', - '<(SHARED_INTERMEDIATE_DIR)/libaddressinput/', - ], 'sources': [ + '<@(libaddressinput_files)', + 'chromium/chrome_address_validator.cc', 'chromium/chrome_downloader_impl.cc', - 'chromium/chrome_downloader_impl.h', 'chromium/chrome_storage_impl.cc', - 'chromium/chrome_storage_impl.h', - '<(libaddressinput_dir)/cpp/include/libaddressinput/address_ui_component.h', - '<(libaddressinput_dir)/cpp/include/libaddressinput/address_ui.h', - '<(libaddressinput_dir)/cpp/include/libaddressinput/address_validator.h', - '<(libaddressinput_dir)/cpp/include/libaddressinput/load_rules_delegate.h', - '<(libaddressinput_dir)/cpp/src/address_ui.cc', - '<(libaddressinput_dir)/cpp/src/address_validator.cc', - '<(libaddressinput_dir)/cpp/src/country_rules_aggregator.cc', - '<(libaddressinput_dir)/cpp/src/country_rules_aggregator.h', - '<(libaddressinput_dir)/cpp/src/fallback_data_store.cc', - '<(libaddressinput_dir)/cpp/src/fallback_data_store.h', - '<(libaddressinput_dir)/cpp/src/grit.h', - '<(libaddressinput_dir)/cpp/src/retriever.cc', - '<(libaddressinput_dir)/cpp/src/retriever.h', - '<(libaddressinput_dir)/cpp/src/ruleset.cc', - '<(libaddressinput_dir)/cpp/src/ruleset.h', - '<(libaddressinput_dir)/cpp/src/util/md5.cc', - '<(libaddressinput_dir)/cpp/src/util/md5.h', - '<(libaddressinput_dir)/cpp/src/util/trie.cc', - '<(libaddressinput_dir)/cpp/src/util/trie.h', + 'chromium/fallback_data_store.cc', + 'chromium/input_suggester.cc', + 'chromium/string_compare.cc', + 'chromium/trie.cc', ], - 'defines': [ - 'VALIDATION_DATA_URL="https://i18napis.appspot.com/ssl-aggregate-address/"', - ], - 'dependencies': [ - 'libaddressinput_strings', - 'libaddressinput_updated_strings', - 'libaddressinput_util', - '<(DEPTH)/base/base.gyp:base', - '<(DEPTH)/base/base.gyp:base_i18n', - '<(DEPTH)/third_party/icu/icu.gyp:icui18n', - '<(DEPTH)/third_party/icu/icu.gyp:icuuc', - '<(DEPTH)/third_party/re2/re2.gyp:re2', + 'sources!': [ + '<@(libaddressinput_util_files)', + 'src/cpp/src/util/string_compare.cc', ], 'direct_dependent_settings': { 'defines': [ - 'CUSTOM_BASICTYPES="base/basictypes.h"', - 'CUSTOM_SCOPED_PTR="base/memory/scoped_ptr.h"', - ], - 'include_dirs': [ - '<(libaddressinput_dir)/cpp/include/', + 'I18N_ADDRESS_VALIDATION_DATA_URL="https://i18napis.appspot.com/ssl-aggregate-address/"', ], }, + 'dependencies': [ + '../../base/base.gyp:base', + '../../base/base.gyp:base_prefs', + '../../net/net.gyp:net', + '../icu/icu.gyp:icui18n', + '../icu/icu.gyp:icuuc', + '../re2/re2.gyp:re2', + 'libaddressinput_util', + ], + 'export_dependent_settings': [ + 'libaddressinput_util', + ], }, { - # GN version: //third_party/libaddressinput:libaddressinput_unittests 'target_name': 'libaddressinput_unittests', 'type': '<(gtest_target_type)', - 'include_dirs': [ - '<(DEPTH)', - '<(libaddressinput_dir)/cpp/src/', - '<(DEPTH)/testing/gtest/include/', - '<(SHARED_INTERMEDIATE_DIR)/libaddressinput/', - ], 'sources': [ + '<@(libaddressinput_test_files)', 'chromium/addressinput_util_unittest.cc', + 'chromium/chrome_address_validator_unittest.cc', 'chromium/chrome_downloader_impl_unittest.cc', - 'chromium/chrome_rule_test.cc', 'chromium/chrome_storage_impl_unittest.cc', - '<(libaddressinput_dir)/cpp/test/address_data_test.cc', - '<(libaddressinput_dir)/cpp/test/address_formatter_test.cc', - '<(libaddressinput_dir)/cpp/test/address_metadata_test.cc', - '<(libaddressinput_dir)/cpp/test/address_ui_test.cc', - '<(libaddressinput_dir)/cpp/test/address_validator_test.cc', - '<(libaddressinput_dir)/cpp/test/country_rules_aggregator_test.cc', - '<(libaddressinput_dir)/cpp/test/countryinfo_example_addresses_test.cc', - '<(libaddressinput_dir)/cpp/test/fake_downloader.cc', - '<(libaddressinput_dir)/cpp/test/fake_downloader.h', - '<(libaddressinput_dir)/cpp/test/fake_downloader_test.cc', - '<(libaddressinput_dir)/cpp/test/fake_storage.cc', - '<(libaddressinput_dir)/cpp/test/fake_storage.h', - '<(libaddressinput_dir)/cpp/test/fake_storage_test.cc', - '<(libaddressinput_dir)/cpp/test/fallback_data_store_test.cc', - '<(libaddressinput_dir)/cpp/test/language_test.cc', - '<(libaddressinput_dir)/cpp/test/region_data_constants_test.cc', - '<(libaddressinput_dir)/cpp/test/retriever_test.cc', - '<(libaddressinput_dir)/cpp/test/rule_test.cc', - '<(libaddressinput_dir)/cpp/test/storage_test_runner.cc', - '<(libaddressinput_dir)/cpp/test/storage_test_runner.h', - '<(libaddressinput_dir)/cpp/test/util/json_test.cc', - '<(libaddressinput_dir)/cpp/test/util/md5_unittest.cc', - '<(libaddressinput_dir)/cpp/test/util/scoped_ptr_unittest.cc', - '<(libaddressinput_dir)/cpp/test/util/stl_util_unittest.cc', - '<(libaddressinput_dir)/cpp/test/util/string_util_test.cc', - '<(libaddressinput_dir)/cpp/test/util/trie_test.cc', + 'chromium/fallback_data_store_unittest.cc', + 'chromium/storage_test_runner.cc', + 'chromium/string_compare_unittest.cc', + 'chromium/trie_unittest.cc', ], 'defines': [ 'TEST_DATA_DIR="third_party/libaddressinput/src/testdata"', ], + 'include_dirs': [ + '../../', + 'src/cpp/src/', + ], 'dependencies': [ + '../../base/base.gyp:base_prefs', + '../../base/base.gyp:run_all_unittests', + '../../net/net.gyp:net_test_support', + '../../testing/gtest.gyp:gtest', 'libaddressinput', - 'libaddressinput_strings', - '<(DEPTH)/base/base.gyp:base_prefs', - '<(DEPTH)/base/base.gyp:run_all_unittests', - '<(DEPTH)/net/net.gyp:net_test_support', - '<(DEPTH)/testing/gtest.gyp:gtest', + 'libaddressinput_util', ], }, ], |