diff options
31 files changed, 359 insertions, 630 deletions
diff --git a/cpp/include/libaddressinput/address_validator.h b/cpp/include/libaddressinput/address_validator.h index d3a09f3..cdb1edf 100644 --- a/cpp/include/libaddressinput/address_validator.h +++ b/cpp/include/libaddressinput/address_validator.h @@ -38,7 +38,8 @@ typedef std::multimap<AddressField, AddressProblem> FieldProblemMap; // class MyClass { // public: // MyClass() -// : validator_(kMyServerUrl, new MyDownloader, new MyStorage), +// : supplier_(new MySupplier), +// validator_(new AddressValidator(supplier_.get())), // validated_(BuildCallback(this, &MyClass::Validated)) {} // // virtual ~MyClass() {} @@ -61,7 +62,8 @@ typedef std::multimap<AddressField, AddressProblem> FieldProblemMap; // AddressData address_; // FieldProblemMap filter_; // FieldProblemMap problems_; -// const AddressValidator validator_; +// const scoped_ptr<Supplier> supplier_; +// const scoped_ptr<AddressValidator> validator_; // const scoped_ptr<const AddressValidator::Callback> validated_; // }; class AddressValidator { diff --git a/cpp/include/libaddressinput/ondemand_supplier.h b/cpp/include/libaddressinput/ondemand_supplier.h index 0fe33f8..6212d34 100644 --- a/cpp/include/libaddressinput/ondemand_supplier.h +++ b/cpp/include/libaddressinput/ondemand_supplier.h @@ -26,10 +26,10 @@ namespace i18n { namespace addressinput { -class Downloader; class LookupKey; class Retriever; class Rule; +class Source; class Storage; // An implementation of the Supplier interface that owns a Retriever object, @@ -46,14 +46,8 @@ class Storage; // in total less than 2 MB of JSON data.) class OndemandSupplier : public Supplier { public: - // Takes ownership of |downloader| and |storage|. The |validation_data_url| - // should be a URL to an address data server that |downloader| can access. - // - // (See the documentation for the Downloader implementation used for - // information about what URLs are useable with that Downloader.) - OndemandSupplier(const std::string& validation_data_url, - const Downloader* downloader, - Storage* storage); + // Takes ownership of |source| and |storage|. + OndemandSupplier(const Source* source, Storage* storage); virtual ~OndemandSupplier(); // Loads the metadata needed for |lookup_key|, then calls |supplied|. diff --git a/cpp/include/libaddressinput/preload_supplier.h b/cpp/include/libaddressinput/preload_supplier.h index a4025cb..5987c79 100644 --- a/cpp/include/libaddressinput/preload_supplier.h +++ b/cpp/include/libaddressinput/preload_supplier.h @@ -28,11 +28,11 @@ namespace i18n { namespace addressinput { -class Downloader; class IndexMap; class LookupKey; class Retriever; class Rule; +class Source; class Storage; // An implementation of the Supplier interface that owns a Retriever object, @@ -42,8 +42,8 @@ class Storage; // or in progress of being loaded. // // When using a PreloadSupplier, it becomes possible to do synchronous address -// validation using an asynchronous Downloader, and to have full control over -// when network access is being done. +// validation using an asynchronous Source, and to have full control over when +// network access is being done. // // The maximum size of this cache is naturally limited to the amount of data // available from the data server. (Currently this is less than 12,000 items of @@ -52,15 +52,8 @@ class PreloadSupplier : public Supplier { public: typedef i18n::addressinput::Callback<const std::string&, int> Callback; - // Takes ownership of |downloader| and |storage|. The |validation_data_url| - // should be a URL to a service that returns address metadata aggregated per - // region, and which |downloader| can access. - // - // (See the documentation for the Downloader implementation used for - // information about what URLs are useable with that Downloader.) - PreloadSupplier(const std::string& validation_data_url, - const Downloader* downloader, - Storage* storage); + // Takes ownership of |source| and |storage|. + PreloadSupplier(const Source* source, Storage* storage); virtual ~PreloadSupplier(); // Collects the metadata needed for |lookup_key| from the cache, then calls diff --git a/cpp/include/libaddressinput/downloader.h b/cpp/include/libaddressinput/source.h index 0da4e1f..4d91b68 100644 --- a/cpp/include/libaddressinput/downloader.h +++ b/cpp/include/libaddressinput/source.h @@ -12,11 +12,12 @@ // See the License for the specific language governing permissions and // limitations under the License. // -// The interface to be implemented by the user of the library to enable -// downloading validation rules from a server. +// The interface to be implemented by the user of the library to access address +// metadata, typically by downloading this from the address metadata server or +// by linking the metadata into the binary. -#ifndef I18N_ADDRESSINPUT_DOWNLOADER_H_ -#define I18N_ADDRESSINPUT_DOWNLOADER_H_ +#ifndef I18N_ADDRESSINPUT_SOURCE_H_ +#define I18N_ADDRESSINPUT_SOURCE_H_ #include <libaddressinput/callback.h> @@ -25,31 +26,31 @@ namespace i18n { namespace addressinput { -// Downloads validation rules from the server. The downloaded data must be -// allocated on the heap, passing ownership to the callback. Sample usage: +// Gets address metadata. The callback data must be allocated on the heap, +// passing ownership to the callback. Sample usage: // -// class MyDownloader : public Downloader { +// class MySource : public Source { // public: -// virtual void Download(const std::string& url, -// const Callback& downloaded) const { +// virtual void Get(const std::string& key, +// const Callback& data_ready) const { // bool success = ... // std::string* data = new ... -// downloaded(success, url, data); +// data_ready(success, key, data); // } // }; -class Downloader { +class Source { public: typedef i18n::addressinput::Callback<const std::string&, std::string*> Callback; - virtual ~Downloader() {} + virtual ~Source() {} - // Downloads |url| and invokes the |downloaded| callback. - virtual void Download(const std::string& url, - const Callback& downloaded) const = 0; + // Gets metadata for |key| and invokes the |data_ready| callback. + virtual void Get(const std::string& key, + const Callback& data_ready) const = 0; }; } // namespace addressinput } // namespace i18n -#endif // I18N_ADDRESSINPUT_DOWNLOADER_H_ +#endif // I18N_ADDRESSINPUT_SOURCE_H_ diff --git a/cpp/include/libaddressinput/storage.h b/cpp/include/libaddressinput/storage.h index 38fb887..94ad13b 100644 --- a/cpp/include/libaddressinput/storage.h +++ b/cpp/include/libaddressinput/storage.h @@ -13,7 +13,7 @@ // limitations under the License. // // The interface to be implemented by the user of the library to enable storing -// the downloaded validation rules (e.g. on disk). +// address metadata (e.g. on disk). #ifndef I18N_ADDRESSINPUT_STORAGE_H_ #define I18N_ADDRESSINPUT_STORAGE_H_ @@ -25,8 +25,8 @@ namespace i18n { namespace addressinput { -// Stores downloaded validation rules. The data must be allocated on the heap, -// passing ownership to the called function. Sample usage: +// Stores address metadata. The data must be allocated on the heap, passing +// ownership to the called function. Sample usage: // // class MyStorage : public Storage { // public: diff --git a/cpp/libaddressinput.gypi b/cpp/libaddressinput.gypi index 03ecaf9..e36ee95 100644 --- a/cpp/libaddressinput.gypi +++ b/cpp/libaddressinput.gypi @@ -28,7 +28,6 @@ 'src/language.cc', 'src/localization.cc', 'src/lookup_key.cc', - 'src/lookup_key_util.cc', 'src/null_storage.cc', 'src/ondemand_supplier.cc', 'src/ondemand_supply_task.cc', @@ -61,16 +60,13 @@ 'test/address_problem_test.cc', 'test/address_ui_test.cc', 'test/address_validator_test.cc', - 'test/fake_downloader.cc', - 'test/fake_downloader_test.cc', 'test/fake_storage.cc', 'test/fake_storage_test.cc', 'test/format_element_test.cc', 'test/language_test.cc', 'test/localization_test.cc', 'test/lookup_key_test.cc', - 'test/lookup_key_util_test.cc', - 'test/mock_downloader.cc', + 'test/mock_source.cc', 'test/null_storage_test.cc', 'test/ondemand_supply_task_test.cc', 'test/post_box_matchers_test.cc', @@ -82,6 +78,8 @@ 'test/rule_retriever_test.cc', 'test/rule_test.cc', 'test/supplier_test.cc', + 'test/testdata_source.cc', + 'test/testdata_source_test.cc', 'test/util/json_test.cc', 'test/util/md5_unittest.cc', 'test/util/scoped_ptr_unittest.cc', diff --git a/cpp/src/lookup_key_util.cc b/cpp/src/lookup_key_util.cc deleted file mode 100644 index e63e9a5..0000000 --- a/cpp/src/lookup_key_util.cc +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright (C) 2013 Google Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "lookup_key_util.h" - -#include <cassert> -#include <string> - -namespace i18n { -namespace addressinput { - -LookupKeyUtil::LookupKeyUtil(const std::string& validation_data_url) - : validation_data_url_(validation_data_url) { - assert(validation_data_url_.length() > 0); - assert(validation_data_url_[validation_data_url_.length() - 1] == '/'); -} - -LookupKeyUtil::~LookupKeyUtil() {} - -std::string LookupKeyUtil::GetUrlForKey(const std::string& key) const { - return validation_data_url_ + key; -} - -std::string LookupKeyUtil::GetKeyForUrl(const std::string& url) const { - return IsValidationDataUrl(url) ? url.substr(validation_data_url_.length()) - : std::string(); -} - -bool LookupKeyUtil::IsValidationDataUrl(const std::string& url) const { - return - url.compare(0, validation_data_url_.length(), validation_data_url_) == 0; -} - -} // namespace addressinput -} // namespace i18n diff --git a/cpp/src/lookup_key_util.h b/cpp/src/lookup_key_util.h deleted file mode 100644 index 4996c1c..0000000 --- a/cpp/src/lookup_key_util.h +++ /dev/null @@ -1,59 +0,0 @@ -// Copyright (C) 2013 Google Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// Functions for working with lookup keys. The lookup keys are strings that -// identify serialized validation rules. - -#ifndef I18N_ADDRESSINPUT_LOOKUP_KEY_UTIL_H_ -#define I18N_ADDRESSINPUT_LOOKUP_KEY_UTIL_H_ - -#include <string> - -namespace i18n { -namespace addressinput { - -// Utility functions for lookup keys. Sample usage: -// LookupKeyUtil lookup_keys("https://i18napis.appspot.com/ssl-address/"); -// Download(lookup_keys.GetUrlForKey("data/US")); -class LookupKeyUtil { - public: - // Builds a lookup key utility for the |validation_data_url| parameter. The - // parameter must end with a '/'. - explicit LookupKeyUtil(const std::string& validation_data_url); - ~LookupKeyUtil(); - - // Returns the URL where the |key| can be retrieved. For example, returns - // "https://i18napis.appspot.com/ssl-address/data/US" for input "data/US". - // Assumes that the input string is a valid URL segment. - std::string GetUrlForKey(const std::string& key) const; - - // Returns the key for the |url|. For example, returns "data/US" for - // "https://i18napis.appspot.com/ssl-address/data/US". If the |url| does not - // start with |validation_data_url| that was passed to the constructor, then - // returns an empty string. (This can happen if the user of the library - // returns a bad URL in their Downloader implementation.) - std::string GetKeyForUrl(const std::string& url) const; - - // Returns true if the |url| starts with |validation_data_url| that was passed - // to the constructor. - bool IsValidationDataUrl(const std::string& url) const; - - private: - const std::string validation_data_url_; -}; - -} // namespace addressinput -} // namespace i18n - -#endif // I18N_ADDRESSINPUT_LOOKUP_KEY_UTIL_H_ diff --git a/cpp/src/ondemand_supplier.cc b/cpp/src/ondemand_supplier.cc index dddeae5..fa3f88e 100644 --- a/cpp/src/ondemand_supplier.cc +++ b/cpp/src/ondemand_supplier.cc @@ -28,10 +28,8 @@ namespace i18n { namespace addressinput { -OndemandSupplier::OndemandSupplier(const std::string& validation_data_url, - const Downloader* downloader, - Storage* storage) - : retriever_(new Retriever(validation_data_url, downloader, storage)) { +OndemandSupplier::OndemandSupplier(const Source* source, Storage* storage) + : retriever_(new Retriever(source, storage)) { } OndemandSupplier::~OndemandSupplier() { diff --git a/cpp/src/preload_supplier.cc b/cpp/src/preload_supplier.cc index 2557e33..79119bd 100644 --- a/cpp/src/preload_supplier.cc +++ b/cpp/src/preload_supplier.cc @@ -271,10 +271,8 @@ std::string KeyFromRegionCode(const std::string& region_code) { } // namespace -PreloadSupplier::PreloadSupplier(const std::string& validation_data_url, - const Downloader* downloader, - Storage* storage) - : retriever_(new Retriever(validation_data_url, downloader, storage)), +PreloadSupplier::PreloadSupplier(const Source* source, Storage* storage) + : retriever_(new Retriever(source, storage)), pending_(), rule_index_(new IndexMap), rule_storage_(), diff --git a/cpp/src/retriever.cc b/cpp/src/retriever.cc index bdb8145..151b74d 100644 --- a/cpp/src/retriever.cc +++ b/cpp/src/retriever.cc @@ -15,7 +15,7 @@ #include "retriever.h" #include <libaddressinput/callback.h> -#include <libaddressinput/downloader.h> +#include <libaddressinput/source.h> #include <libaddressinput/storage.h> #include <libaddressinput/util/basictypes.h> #include <libaddressinput/util/scoped_ptr.h> @@ -24,7 +24,6 @@ #include <cstddef> #include <string> -#include "lookup_key_util.h" #include "validating_storage.h" namespace i18n { @@ -37,14 +36,12 @@ class Helper { // Does not take ownership of its parameters. Helper(const std::string& key, const Retriever::Callback& retrieved, - const LookupKeyUtil& lookup_key_util, - const Downloader& downloader, + const Source& source, ValidatingStorage* storage) : retrieved_(retrieved), - lookup_key_util_(lookup_key_util), - downloader_(downloader), + source_(source), storage_(storage), - downloaded_(BuildCallback(this, &Helper::OnDownloaded)), + fresh_data_ready_(BuildCallback(this, &Helper::OnFreshDataReady)), validated_data_ready_( BuildCallback(this, &Helper::OnValidatedDataReady)), stale_data_() { @@ -68,13 +65,14 @@ class Helper { if (data != NULL && !data->empty()) { stale_data_ = *data; } - downloader_.Download(lookup_key_util_.GetUrlForKey(key), *downloaded_); + source_.Get(key, *fresh_data_ready_); } delete data; } - void OnDownloaded(bool success, const std::string& url, std::string* data) { - const std::string& key = lookup_key_util_.GetKeyForUrl(url); + void OnFreshDataReady(bool success, + const std::string& key, + std::string* data) { if (success) { assert(data != NULL); retrieved_(true, key, *data); @@ -92,10 +90,9 @@ class Helper { } const Retriever::Callback& retrieved_; - const LookupKeyUtil& lookup_key_util_; - const Downloader& downloader_; + const Source& source_; ValidatingStorage* storage_; - const scoped_ptr<const Downloader::Callback> downloaded_; + const scoped_ptr<const Source::Callback> fresh_data_ready_; const scoped_ptr<const Storage::Callback> validated_data_ready_; std::string stale_data_; @@ -104,21 +101,17 @@ class Helper { } // namespace -Retriever::Retriever(const std::string& validation_data_url, - const Downloader* downloader, - Storage* storage) - : lookup_key_util_(validation_data_url), - downloader_(downloader), - storage_(new ValidatingStorage(storage)) { +Retriever::Retriever(const Source* source, Storage* storage) + : source_(source), storage_(new ValidatingStorage(storage)) { + assert(source_ != NULL); assert(storage_ != NULL); - assert(downloader_ != NULL); } Retriever::~Retriever() {} void Retriever::Retrieve(const std::string& key, const Callback& retrieved) const { - new Helper(key, retrieved, lookup_key_util_, *downloader_, storage_.get()); + new Helper(key, retrieved, *source_, storage_.get()); } } // namespace addressinput diff --git a/cpp/src/retriever.h b/cpp/src/retriever.h index 9634935..4bf27a5 100644 --- a/cpp/src/retriever.h +++ b/cpp/src/retriever.h @@ -23,20 +23,17 @@ #include <string> -#include "lookup_key_util.h" - namespace i18n { namespace addressinput { -class Downloader; +class Source; class Storage; class ValidatingStorage; // Retrieves data. Sample usage: +// Source* source = ...; // Storage* storage = ...; -// Downloader* downloader = ...; -// Retriever retriever("https://i18napis.appspot.com/ssl-address/", -// downloader, storage); +// Retriever retriever(source, storage); // const scoped_ptr<const Retriever::Callback> retrieved( // BuildCallback(this, &MyClass::OnDataRetrieved)); // retriever.Retrieve("data/CA/AB--fr", *retrieved); @@ -45,24 +42,21 @@ class Retriever { typedef i18n::addressinput::Callback<const std::string&, const std::string&> Callback; - // Takes ownership of |downloader| and |storage|. - Retriever(const std::string& validation_data_url, - const Downloader* downloader, - Storage* storage); + // Takes ownership of |source| and |storage|. + Retriever(const Source* source, Storage* storage); ~Retriever(); // Retrieves the data for |key| and invokes the |retrieved| callback. Checks - // for the data in storage first. If storage does not have the data for |key|, - // then downloads the data and places it in storage. If the data in storage is - // corrupted, then it's discarded and redownloaded. If the data is stale, then - // it's redownloaded. If the download fails, then stale data will be returned - // this one time. The next call to Retrieve() will attempt to download fresh - // data again. + // for the data in |storage_| first. If storage does not have the data for + // |key|, then gets the data from |source_| and places it in storage. If the + // data in storage is corrupted, then it's discarded and requested anew. If + // the data is stale, then it's requested anew. If the request fails, then + // stale data will be returned this one time. Any subsequent call to + // Retrieve() will attempt to get fresh data again. void Retrieve(const std::string& key, const Callback& retrieved) const; private: - const LookupKeyUtil lookup_key_util_; - scoped_ptr<const Downloader> downloader_; + scoped_ptr<const Source> source_; scoped_ptr<ValidatingStorage> storage_; DISALLOW_COPY_AND_ASSIGN(Retriever); diff --git a/cpp/test/address_input_helper_test.cc b/cpp/test/address_input_helper_test.cc index 5580ec7..cfae3f3 100644 --- a/cpp/test/address_input_helper_test.cc +++ b/cpp/test/address_input_helper_test.cc @@ -26,8 +26,8 @@ #include <gtest/gtest.h> -#include "fake_downloader.h" -#include "mock_downloader.h" +#include "mock_source.h" +#include "testdata_source.h" namespace { @@ -35,19 +35,17 @@ using i18n::addressinput::AddressData; using i18n::addressinput::AddressInputHelper; using i18n::addressinput::BuildCallback; using i18n::addressinput::Callback; -using i18n::addressinput::FakeDownloader; -using i18n::addressinput::MockDownloader; +using i18n::addressinput::MockSource; using i18n::addressinput::NullStorage; using i18n::addressinput::PreloadSupplier; using i18n::addressinput::scoped_ptr; +using i18n::addressinput::TestdataSource; class AddressInputHelperTest : public testing::Test { protected: AddressInputHelperTest() // Our PreloadSupplier loads all data for a country at a time. - : supplier_(FakeDownloader::kFakeAggregateDataUrl, - new FakeDownloader, - new NullStorage), + : supplier_(new TestdataSource(true), new NullStorage), address_input_helper_(&supplier_), loaded_(BuildCallback(this, &AddressInputHelperTest::Loaded)) {} @@ -245,11 +243,9 @@ TEST_F(AddressInputHelperTest, AddressWithInvalidOrMissingRegionCode) { class AddressInputHelperMockDataTest : public testing::Test { protected: AddressInputHelperMockDataTest() - : downloader_(new MockDownloader), + : source_(new MockSource), // Our PreloadSupplier loads all data for a country at a time. - supplier_(MockDownloader::kMockDataUrl, - downloader_, - new NullStorage), + supplier_(source_, new NullStorage), address_input_helper_(&supplier_), loaded_(BuildCallback(this, &AddressInputHelperMockDataTest::Loaded)) {} @@ -265,10 +261,10 @@ class AddressInputHelperMockDataTest : public testing::Test { address_input_helper_.FillAddress(address); } - MockDownloader* const downloader_; + MockSource* const source_; private: - // Our mock downloader we assume will always succeed. + // Our mock source we assume will always succeed. void Loaded(bool success, const std::string&, int) { ASSERT_TRUE(success); } PreloadSupplier supplier_; @@ -281,7 +277,7 @@ TEST_F(AddressInputHelperMockDataTest, PostalCodeSharedAcrossDifferentHierarchies) { // Note that this data is in the format of data that would be returned from // the aggregate server. - downloader_->data_.insert(std::make_pair( + source_->data_.insert(std::make_pair( // We use KR since we need a country where we format all fields down to // dependent locality, or the hierarchy won't be loaded. "data/KR", @@ -315,7 +311,7 @@ TEST_F(AddressInputHelperMockDataTest, // Create data where one state matches the ZIP code, but the other doesn't: // within the state which does, multiple cities and sub-cities match. The only // thing we can be certain of is therefore the state. - downloader_->data_.insert(std::make_pair( + source_->data_.insert(std::make_pair( // We use KR since we need a country where we format all fields down to // dependent locality, or the hierarchy won't be loaded. "data/KR", diff --git a/cpp/test/address_normalizer_test.cc b/cpp/test/address_normalizer_test.cc index fc4404b..7a01d38 100644 --- a/cpp/test/address_normalizer_test.cc +++ b/cpp/test/address_normalizer_test.cc @@ -25,24 +25,22 @@ #include <gtest/gtest.h> -#include "fake_downloader.h" +#include "testdata_source.h" namespace { using i18n::addressinput::AddressData; using i18n::addressinput::AddressNormalizer; using i18n::addressinput::BuildCallback; -using i18n::addressinput::FakeDownloader; using i18n::addressinput::NullStorage; using i18n::addressinput::PreloadSupplier; using i18n::addressinput::scoped_ptr; +using i18n::addressinput::TestdataSource; class AddressNormalizerTest : public testing::Test { protected: AddressNormalizerTest() - : supplier_(FakeDownloader::kFakeAggregateDataUrl, - new FakeDownloader, - new NullStorage), + : supplier_(new TestdataSource(true), new NullStorage), loaded_(BuildCallback(this, &AddressNormalizerTest::OnLoaded)), normalizer_(&supplier_) {} diff --git a/cpp/test/address_validator_test.cc b/cpp/test/address_validator_test.cc index b90eef9..0b4b025 100644 --- a/cpp/test/address_validator_test.cc +++ b/cpp/test/address_validator_test.cc @@ -29,19 +29,19 @@ #include <gtest/gtest.h> -#include "fake_downloader.h" +#include "testdata_source.h" namespace { using i18n::addressinput::AddressData; using i18n::addressinput::AddressValidator; using i18n::addressinput::BuildCallback; -using i18n::addressinput::FakeDownloader; using i18n::addressinput::FieldProblemMap; using i18n::addressinput::NullStorage; using i18n::addressinput::OndemandSupplier; using i18n::addressinput::PreloadSupplier; using i18n::addressinput::scoped_ptr; +using i18n::addressinput::TestdataSource; using i18n::addressinput::COUNTRY; using i18n::addressinput::ADMIN_AREA; @@ -89,9 +89,7 @@ class OndemandValidatorWrapper : public ValidatorWrapper { private: OndemandValidatorWrapper() - : supplier_(FakeDownloader::kFakeDataUrl, - new FakeDownloader, - new NullStorage), + : supplier_(new TestdataSource(false), new NullStorage), validator_(&supplier_) {} OndemandSupplier supplier_; @@ -126,9 +124,7 @@ class PreloadValidatorWrapper : public ValidatorWrapper { private: PreloadValidatorWrapper() - : supplier_(FakeDownloader::kFakeAggregateDataUrl, - new FakeDownloader, - new NullStorage), + : supplier_(new TestdataSource(true), new NullStorage), validator_(&supplier_), loaded_(BuildCallback(this, &PreloadValidatorWrapper::Loaded)) {} diff --git a/cpp/test/fake_downloader.h b/cpp/test/fake_downloader.h deleted file mode 100644 index 565263b..0000000 --- a/cpp/test/fake_downloader.h +++ /dev/null @@ -1,75 +0,0 @@ -// Copyright (C) 2013 Google Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// A fake downloader object to use in tests. Reads data from a file instead of -// downloading it from a server. - -#ifndef I18N_ADDRESSINPUT_TEST_FAKE_DOWNLOADER_H_ -#define I18N_ADDRESSINPUT_TEST_FAKE_DOWNLOADER_H_ - -#include <libaddressinput/downloader.h> - -#include <string> - -namespace i18n { -namespace addressinput { - -// "Downloads" serialized validation rules from a test data file. Sample usage: -// class MyClass { -// public: -// MyClass() : downloader_(), -// callback_(BuildCallback(this, &MyClass::OnDownloaded)) {} -// -// ~MyClass() {} -// -// void GetData(const std::string& key) { -// downloader_.Download(std::string(FakeDownloader::kFakeDataUrl) + key, -// *callback_); -// } -// -// private: -// void OnDownloaded(bool success, -// const std::string& url, -// std::string* data) { -// ... -// delete data; -// } -// -// FakeDownloader downloader_; -// const scoped_ptr<const Downloader::Callback> callback_; -// -// DISALLOW_COPY_AND_ASSIGN(MyClass); -// }; -class FakeDownloader : public Downloader { - public: - // The fake data URL to be used in tests for retrieving one key at a time. - static const char kFakeDataUrl[]; - - // The fake data URL to be used in tests for retrieving aggregate data, which - // is a JSON dictionary that maps from keys to dictionaries of what you would - // normally get from kFakeDataUrl. - static const char kFakeAggregateDataUrl[]; - - FakeDownloader(); - virtual ~FakeDownloader(); - - // Downloader implementation. - virtual void Download(const std::string& url, - const Callback& downloaded) const; -}; - -} // namespace addressinput -} // namespace i18n - -#endif // I18N_ADDRESSINPUT_TEST_FAKE_DOWNLOADER_H_ diff --git a/cpp/test/fake_storage.h b/cpp/test/fake_storage.h index 9188b3b..55273c6 100644 --- a/cpp/test/fake_storage.h +++ b/cpp/test/fake_storage.h @@ -30,7 +30,7 @@ namespace addressinput { // class MyClass { // public: // MyClass() : storage_(), -// callback(BuildCallback(this, &MyClass::OnDataReady)) {} +// data_ready_(BuildCallback(this, &MyClass::OnDataReady)) {} // // ~MyClass() {} // @@ -39,7 +39,7 @@ namespace addressinput { // } // // void Read() { -// storage_.Get("key", *callback_); +// storage_.Get("key", *data_ready_); // } // // private: @@ -51,7 +51,7 @@ namespace addressinput { // } // // FakeStorage storage_; -// const scoped_ptr<const Storage::Callback> callback_; +// const scoped_ptr<const Storage::Callback> data_ready_; // // DISALLOW_COPY_AND_ASSIGN(MyClass); // }; diff --git a/cpp/test/fake_storage_test.cc b/cpp/test/fake_storage_test.cc index 94fed9e..275c9fc 100644 --- a/cpp/test/fake_storage_test.cc +++ b/cpp/test/fake_storage_test.cc @@ -50,9 +50,7 @@ class FakeStorageTest : public testing::Test { const scoped_ptr<const Storage::Callback> data_ready_; private: - void OnDataReady(bool success, - const std::string& key, - std::string* data) { + void OnDataReady(bool success, const std::string& key, std::string* data) { ASSERT_FALSE(success && data == NULL); success_ = success; key_ = key; diff --git a/cpp/test/lookup_key_util_test.cc b/cpp/test/lookup_key_util_test.cc deleted file mode 100644 index a210bd5..0000000 --- a/cpp/test/lookup_key_util_test.cc +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright (C) 2013 Google Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "lookup_key_util.h" - -#include <gtest/gtest.h> - -namespace { - -using i18n::addressinput::LookupKeyUtil; - -TEST(LookupKeyUtilTest, GetUrlForKey) { - const LookupKeyUtil util("test:///"); - EXPECT_EQ("test:///", util.GetUrlForKey("")); - EXPECT_EQ("test:///data", util.GetUrlForKey("data")); - EXPECT_EQ("test:///data/US", util.GetUrlForKey("data/US")); - EXPECT_EQ("test:///data/CA--fr", util.GetUrlForKey("data/CA--fr")); -} - -TEST(LookupKeyUtilTest, GetKeyForUrl) { - const LookupKeyUtil util("test:///"); - EXPECT_EQ("", util.GetKeyForUrl("test://")); - EXPECT_EQ("", util.GetKeyForUrl("http://www.google.com/")); - EXPECT_EQ("", util.GetKeyForUrl("")); - EXPECT_EQ("", util.GetKeyForUrl("test:///")); - EXPECT_EQ("data", util.GetKeyForUrl("test:///data")); - EXPECT_EQ("data/US", util.GetKeyForUrl("test:///data/US")); - EXPECT_EQ("data/CA--fr", util.GetKeyForUrl("test:///data/CA--fr")); -} - -TEST(LookupKeyUtilTest, IsValidationDataUrl) { - const LookupKeyUtil util("test:///"); - EXPECT_FALSE(util.IsValidationDataUrl("test://")); - EXPECT_FALSE(util.IsValidationDataUrl("http://www.google.com/")); - EXPECT_FALSE(util.IsValidationDataUrl("")); - EXPECT_TRUE(util.IsValidationDataUrl("test:///")); - EXPECT_TRUE(util.IsValidationDataUrl("test:///data")); - EXPECT_TRUE(util.IsValidationDataUrl("test:///data/US")); - EXPECT_TRUE(util.IsValidationDataUrl("test:///data/CA--fr")); -} - -} // namespace diff --git a/cpp/test/mock_downloader.h b/cpp/test/mock_downloader.h deleted file mode 100644 index d12b38d..0000000 --- a/cpp/test/mock_downloader.h +++ /dev/null @@ -1,79 +0,0 @@ -// Copyright (C) 2014 Google Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// A mock downloader object to use in tests. - -#ifndef I18N_ADDRESSINPUT_TEST_MOCK_DOWNLOADER_H_ -#define I18N_ADDRESSINPUT_TEST_MOCK_DOWNLOADER_H_ - -#include <libaddressinput/downloader.h> -#include <libaddressinput/util/basictypes.h> - -#include <map> -#include <string> - -namespace i18n { -namespace addressinput { - -// "Downloads" serialized validation rules from a key-value map. Sample usage: -// class MyClass { -// public: -// MyClass() : downloader_(), -// callback_(BuildCallback(this, &MyClass::OnDownloaded)) { -// downloader_.data_.insert( -// std::make_pair("data/XA", "{\"id\":\"data/XA\"}")); -// } -// -// ~MyClass() {} -// -// void GetData(const std::string& key) { -// downloader_.Download(std::string(MockDownloader::kMockDataUrl) + key, -// *callback_); -// } -// -// private: -// void OnDownloaded(bool success, -// const std::string& url, -// std::string* data) { -// ... -// delete data; -// } -// -// MockDownloader downloader_; -// const scoped_ptr<const Downloader::Callback> callback_; -// -// DISALLOW_COPY_AND_ASSIGN(MyClass); -// }; -class MockDownloader : public Downloader { - public: - // The mock data URL to be used in tests. - static const char kMockDataUrl[]; - - MockDownloader(); - virtual ~MockDownloader(); - - // Downloader implementation. - virtual void Download(const std::string& url, - const Callback& downloaded) const; - - std::map<std::string, std::string> data_; - - private: - DISALLOW_COPY_AND_ASSIGN(MockDownloader); -}; - -} // namespace addressinput -} // namespace i18n - -#endif // I18N_ADDRESSINPUT_TEST_MOCK_DOWNLOADER_H_ diff --git a/cpp/test/mock_downloader.cc b/cpp/test/mock_source.cc index 71256aa..d04598b 100644 --- a/cpp/test/mock_downloader.cc +++ b/cpp/test/mock_source.cc @@ -12,9 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "mock_downloader.h" +#include "mock_source.h" -#include <cassert> #include <cstddef> #include <map> #include <string> @@ -22,27 +21,14 @@ namespace i18n { namespace addressinput { -// static -const char MockDownloader::kMockDataUrl[] = "mock:///"; +MockSource::MockSource() {} -namespace { +MockSource::~MockSource() {} -// The number of characters in the mock data URL prefix. -const size_t kMockDataUrlLength = sizeof MockDownloader::kMockDataUrl - 1; - -} // namespace - -MockDownloader::MockDownloader() {} - -MockDownloader::~MockDownloader() {} - -void MockDownloader::Download(const std::string& url, - const Callback& downloaded) const { - assert(url.compare(0, kMockDataUrlLength, kMockDataUrl) == 0); - std::string key(url, kMockDataUrlLength); +void MockSource::Get(const std::string& key, const Callback& data_ready) const { std::map<std::string, std::string>::const_iterator it = data_.find(key); bool success = it != data_.end(); - downloaded(success, url, success ? new std::string(it->second) : NULL); + data_ready(success, key, success ? new std::string(it->second) : NULL); } } // namespace addressinput diff --git a/cpp/test/mock_source.h b/cpp/test/mock_source.h new file mode 100644 index 0000000..27f75c4 --- /dev/null +++ b/cpp/test/mock_source.h @@ -0,0 +1,74 @@ +// Copyright (C) 2014 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// A mock implementation of the Source interface to be used in tests. + +#ifndef I18N_ADDRESSINPUT_TEST_MOCK_SOURCE_H_ +#define I18N_ADDRESSINPUT_TEST_MOCK_SOURCE_H_ + +#include <libaddressinput/source.h> +#include <libaddressinput/util/basictypes.h> + +#include <map> +#include <string> + +namespace i18n { +namespace addressinput { + +// Gets address metadata from a key-value map. Sample usage: +// class MyClass { +// public: +// MyClass() : source_(), +// data_ready_(BuildCallback(this, &MyClass::OnDataReady)) { +// source_.data_.insert( +// std::make_pair("data/XA", "{\"id\":\"data/XA\"}")); +// } +// +// ~MyClass() {} +// +// void GetData(const std::string& key) { +// source_.Get(key, *data_ready_); +// } +// +// private: +// void OnDataReady(bool success, +// const std::string& key, +// std::string* data) { +// ... +// delete data; +// } +// +// MockSource source_; +// const scoped_ptr<const Source::Callback> data_ready_; +// +// DISALLOW_COPY_AND_ASSIGN(MyClass); +// }; +class MockSource : public Source { + public: + MockSource(); + virtual ~MockSource(); + + // Source implementation. + virtual void Get(const std::string& key, const Callback& data_ready) const; + + std::map<std::string, std::string> data_; + + private: + DISALLOW_COPY_AND_ASSIGN(MockSource); +}; + +} // namespace addressinput +} // namespace i18n + +#endif // I18N_ADDRESSINPUT_TEST_MOCK_SOURCE_H_ diff --git a/cpp/test/ondemand_supply_task_test.cc b/cpp/test/ondemand_supply_task_test.cc index 64f55d0..e15e997 100644 --- a/cpp/test/ondemand_supply_task_test.cc +++ b/cpp/test/ondemand_supply_task_test.cc @@ -29,7 +29,7 @@ #include <gtest/gtest.h> #include "lookup_key.h" -#include "mock_downloader.h" +#include "mock_source.h" #include "retriever.h" #include "rule.h" @@ -37,7 +37,7 @@ namespace { using i18n::addressinput::BuildCallback; using i18n::addressinput::LookupKey; -using i18n::addressinput::MockDownloader; +using i18n::addressinput::MockSource; using i18n::addressinput::NullStorage; using i18n::addressinput::OndemandSupplyTask; using i18n::addressinput::Retriever; @@ -52,11 +52,9 @@ class OndemandSupplyTaskTest : public testing::Test { lookup_key_(), rule_(), called_(false), - downloader_(new MockDownloader), + source_(new MockSource), rule_cache_(), - retriever_( - new Retriever( - MockDownloader::kMockDataUrl, downloader_, new NullStorage)), + retriever_(new Retriever(source_, new NullStorage)), supplied_(BuildCallback(this, &OndemandSupplyTaskTest::Supplied)), task_(new OndemandSupplyTask(lookup_key_, &rule_cache_, *supplied_)) {} @@ -71,11 +69,11 @@ class OndemandSupplyTaskTest : public testing::Test { void Retrieve() { task_->Retrieve(*retriever_); } - bool success_; // Expected status from MockDownloader. + bool success_; // Expected status from MockSource. LookupKey lookup_key_; // Stub. const Rule* rule_[arraysize(LookupKey::kHierarchy)]; bool called_; - MockDownloader* const downloader_; + MockSource* const source_; private: void Supplied(bool success, @@ -115,7 +113,7 @@ TEST_F(OndemandSupplyTaskTest, Invalid) { } TEST_F(OndemandSupplyTaskTest, Valid) { - downloader_->data_.insert(std::make_pair("data/XA", "{\"id\":\"data/XA\"}")); + source_->data_.insert(std::make_pair("data/XA", "{\"id\":\"data/XA\"}")); Queue("data/XA"); @@ -135,13 +133,13 @@ TEST_F(OndemandSupplyTaskTest, Valid) { } TEST_F(OndemandSupplyTaskTest, ValidHierarchy) { - downloader_->data_.insert( + source_->data_.insert( std::make_pair("data/XA", "{\"id\":\"data/XA\"}")); - downloader_->data_.insert( + source_->data_.insert( std::make_pair("data/XA/aa", "{\"id\":\"data/XA/aa\"}")); - downloader_->data_.insert( + source_->data_.insert( std::make_pair("data/XA/aa/bb", "{\"id\":\"data/XA/aa/bb\"}")); - downloader_->data_.insert( + source_->data_.insert( std::make_pair("data/XA/aa/bb/cc", "{\"id\":\"data/XA/aa/bb/cc\"}")); Queue("data/XA"); @@ -175,7 +173,7 @@ TEST_F(OndemandSupplyTaskTest, ValidHierarchy) { } TEST_F(OndemandSupplyTaskTest, InvalidJson1) { - downloader_->data_.insert(std::make_pair("data/XA", ":")); + source_->data_.insert(std::make_pair("data/XA", ":")); success_ = false; @@ -186,8 +184,8 @@ TEST_F(OndemandSupplyTaskTest, InvalidJson1) { } TEST_F(OndemandSupplyTaskTest, InvalidJson2) { - downloader_->data_.insert(std::make_pair("data/XA", "{\"id\":\"data/XA\"}")); - downloader_->data_.insert(std::make_pair("data/XA/aa", ":")); + source_->data_.insert(std::make_pair("data/XA", "{\"id\":\"data/XA\"}")); + source_->data_.insert(std::make_pair("data/XA/aa", ":")); success_ = false; @@ -199,8 +197,8 @@ TEST_F(OndemandSupplyTaskTest, InvalidJson2) { } TEST_F(OndemandSupplyTaskTest, EmptyJsonJustMeansServerKnowsNothingAboutKey) { - downloader_->data_.insert(std::make_pair("data/XA", "{\"id\":\"data/XA\"}")); - downloader_->data_.insert(std::make_pair("data/XA/aa", "{}")); + source_->data_.insert(std::make_pair("data/XA", "{\"id\":\"data/XA\"}")); + source_->data_.insert(std::make_pair("data/XA/aa", "{}")); Queue("data/XA"); Queue("data/XA/aa"); @@ -216,7 +214,7 @@ TEST_F(OndemandSupplyTaskTest, EmptyJsonJustMeansServerKnowsNothingAboutKey) { } TEST_F(OndemandSupplyTaskTest, IfCountryFailsAllFails) { - downloader_->data_.insert( + source_->data_.insert( std::make_pair("data/XA/aa", "{\"id\":\"data/XA/aa\"}")); success_ = false; diff --git a/cpp/test/preload_supplier_test.cc b/cpp/test/preload_supplier_test.cc index 7181ef2..999ee21 100644 --- a/cpp/test/preload_supplier_test.cc +++ b/cpp/test/preload_supplier_test.cc @@ -25,27 +25,25 @@ #include <gtest/gtest.h> -#include "fake_downloader.h" #include "lookup_key.h" #include "rule.h" +#include "testdata_source.h" namespace { using i18n::addressinput::AddressData; using i18n::addressinput::BuildCallback; -using i18n::addressinput::FakeDownloader; using i18n::addressinput::LookupKey; using i18n::addressinput::NullStorage; using i18n::addressinput::PreloadSupplier; using i18n::addressinput::Rule; using i18n::addressinput::scoped_ptr; +using i18n::addressinput::TestdataSource; class PreloadSupplierTest : public testing::Test { protected: PreloadSupplierTest() - : supplier_(FakeDownloader::kFakeAggregateDataUrl, - new FakeDownloader, - new NullStorage), + : supplier_(new TestdataSource(true), new NullStorage), loaded_callback_(BuildCallback(this, &PreloadSupplierTest::OnLoaded)) {} virtual ~PreloadSupplierTest() {} diff --git a/cpp/test/region_data_builder_test.cc b/cpp/test/region_data_builder_test.cc index b8e0ddd..a60189f 100644 --- a/cpp/test/region_data_builder_test.cc +++ b/cpp/test/region_data_builder_test.cc @@ -25,23 +25,22 @@ #include <gtest/gtest.h> -#include "fake_downloader.h" +#include "testdata_source.h" namespace { using i18n::addressinput::BuildCallback; -using i18n::addressinput::FakeDownloader; using i18n::addressinput::NullStorage; using i18n::addressinput::PreloadSupplier; using i18n::addressinput::RegionData; using i18n::addressinput::RegionDataBuilder; using i18n::addressinput::scoped_ptr; +using i18n::addressinput::TestdataSource; class RegionDataBuilderTest : public testing::Test { protected: RegionDataBuilderTest() - : supplier_(FakeDownloader::kFakeAggregateDataUrl, - new FakeDownloader, + : supplier_(new TestdataSource(true), new NullStorage), builder_(&supplier_), loaded_callback_(BuildCallback(this, &RegionDataBuilderTest::OnLoaded)), diff --git a/cpp/test/retriever_test.cc b/cpp/test/retriever_test.cc index 978e9f0..5b884b0 100644 --- a/cpp/test/retriever_test.cc +++ b/cpp/test/retriever_test.cc @@ -25,8 +25,8 @@ #include <gtest/gtest.h> -#include "fake_downloader.h" -#include "mock_downloader.h" +#include "mock_source.h" +#include "testdata_source.h" #define CHECKSUM "dd63dafcbd4d5b28badfcaf86fb6fcdb" #define DATA "{'foo': 'bar'}" @@ -35,16 +35,16 @@ namespace { using i18n::addressinput::BuildCallback; -using i18n::addressinput::FakeDownloader; -using i18n::addressinput::MockDownloader; +using i18n::addressinput::MockSource; using i18n::addressinput::NullStorage; using i18n::addressinput::Retriever; using i18n::addressinput::scoped_ptr; using i18n::addressinput::Storage; +using i18n::addressinput::TestdataSource; const char kKey[] = "data/CA/AB--fr"; -// Empty data that the downloader can return. +// Empty data that the source can return. const char kEmptyData[] = "{}"; // The value of the data that the stale storage returns. @@ -59,9 +59,7 @@ const char kStaleWrappedData[] = "timestamp=" OLD_TIMESTAMP "\n" class RetrieverTest : public testing::Test { protected: RetrieverTest() - : retriever_(FakeDownloader::kFakeDataUrl, - new FakeDownloader, - new NullStorage), + : retriever_(new TestdataSource(false), new NullStorage), success_(false), key_(), data_(), @@ -116,11 +114,9 @@ TEST_F(RetrieverTest, MissingKeyReturnsEmptyData) { EXPECT_EQ(kEmptyData, data_); } -TEST_F(RetrieverTest, FaultyDownloader) { - // An empty MockDownloader will fail for any request. - Retriever bad_retriever(MockDownloader::kMockDataUrl, - new MockDownloader, - new NullStorage); +TEST_F(RetrieverTest, FaultySource) { + // An empty MockSource will fail for any request. + Retriever bad_retriever(new MockSource, new NullStorage); bad_retriever.Retrieve(kKey, *data_ready_); @@ -152,12 +148,11 @@ class StaleStorage : public Storage { DISALLOW_COPY_AND_ASSIGN(StaleStorage); }; -TEST_F(RetrieverTest, UseStaleDataWhenDownloaderFails) { +TEST_F(RetrieverTest, UseStaleDataWhenSourceFails) { // Owned by |resilient_retriver|. StaleStorage* stale_storage = new StaleStorage; - // An empty MockDownloader will fail for any request. - Retriever resilient_retriever( - MockDownloader::kMockDataUrl, new MockDownloader, stale_storage); + // An empty MockSource will fail for any request. + Retriever resilient_retriever(new MockSource, stale_storage); resilient_retriever.Retrieve(kKey, *data_ready_); @@ -167,11 +162,10 @@ TEST_F(RetrieverTest, UseStaleDataWhenDownloaderFails) { EXPECT_FALSE(stale_storage->data_updated_); } -TEST_F(RetrieverTest, DoNotUseStaleDataWhenDownloaderSucceeds) { +TEST_F(RetrieverTest, DoNotUseStaleDataWhenSourceSucceeds) { // Owned by |resilient_retriver|. StaleStorage* stale_storage = new StaleStorage; - Retriever resilient_retriever( - FakeDownloader::kFakeDataUrl, new FakeDownloader, stale_storage); + Retriever resilient_retriever(new TestdataSource(false), stale_storage); resilient_retriever.Retrieve(kKey, *data_ready_); diff --git a/cpp/test/rule_retriever_test.cc b/cpp/test/rule_retriever_test.cc index 7442bb4..656b23b 100644 --- a/cpp/test/rule_retriever_test.cc +++ b/cpp/test/rule_retriever_test.cc @@ -23,27 +23,26 @@ #include <gtest/gtest.h> -#include "fake_downloader.h" #include "retriever.h" #include "rule.h" +#include "testdata_source.h" namespace { using i18n::addressinput::BuildCallback; -using i18n::addressinput::FakeDownloader; using i18n::addressinput::NullStorage; using i18n::addressinput::Retriever; using i18n::addressinput::Rule; using i18n::addressinput::RuleRetriever; using i18n::addressinput::scoped_ptr; +using i18n::addressinput::TestdataSource; // Tests for RuleRetriever object. class RuleRetrieverTest : public testing::Test { protected: RuleRetrieverTest() - : rule_retriever_(new Retriever(FakeDownloader::kFakeDataUrl, - new FakeDownloader, - new NullStorage)), + : rule_retriever_( + new Retriever(new TestdataSource(false), new NullStorage)), success_(false), key_(), rule_(), diff --git a/cpp/test/supplier_test.cc b/cpp/test/supplier_test.cc index f1e2704..bb783db 100644 --- a/cpp/test/supplier_test.cc +++ b/cpp/test/supplier_test.cc @@ -28,9 +28,9 @@ #include <gtest/gtest.h> -#include "fake_downloader.h" #include "lookup_key.h" #include "rule.h" +#include "testdata_source.h" namespace { @@ -53,7 +53,6 @@ const char kKashiShi[] = "\xE5\x96\x80\xE4\xBB\x80\xE5\xB8\x82"; using i18n::addressinput::AddressData; using i18n::addressinput::BuildCallback; -using i18n::addressinput::FakeDownloader; using i18n::addressinput::LookupKey; using i18n::addressinput::NullStorage; using i18n::addressinput::OndemandSupplier; @@ -61,6 +60,7 @@ using i18n::addressinput::PreloadSupplier; using i18n::addressinput::Rule; using i18n::addressinput::scoped_ptr; using i18n::addressinput::Supplier; +using i18n::addressinput::TestdataSource; class SupplierWrapper { public: @@ -82,9 +82,7 @@ class OndemandSupplierWrapper : public SupplierWrapper { private: OndemandSupplierWrapper() - : ondemand_supplier_(FakeDownloader::kFakeDataUrl, - new FakeDownloader, - new NullStorage) {} + : ondemand_supplier_(new TestdataSource(false), new NullStorage) {} OndemandSupplier ondemand_supplier_; DISALLOW_COPY_AND_ASSIGN(OndemandSupplierWrapper); @@ -107,9 +105,7 @@ class PreloadSupplierWrapper : public SupplierWrapper { private: PreloadSupplierWrapper() - : preload_supplier_(FakeDownloader::kFakeAggregateDataUrl, - new FakeDownloader, - new NullStorage), + : preload_supplier_(new TestdataSource(true), new NullStorage), loaded_(BuildCallback(this, &PreloadSupplierWrapper::Loaded)) {} void Loaded(bool success, const std::string&, int) { ASSERT_TRUE(success); } diff --git a/cpp/test/fake_downloader.cc b/cpp/test/testdata_source.cc index 1795b2b..d333cb0 100644 --- a/cpp/test/fake_downloader.cc +++ b/cpp/test/testdata_source.cc @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "fake_downloader.h" +#include "testdata_source.h" #include <cassert> #include <cstddef> @@ -23,29 +23,20 @@ #include <string> #include <utility> -#include "lookup_key_util.h" - namespace i18n { namespace addressinput { -// static -const char FakeDownloader::kFakeDataUrl[] = "test:///plain/"; - -// static -const char FakeDownloader::kFakeAggregateDataUrl[] = "test:///aggregate/"; - namespace { +// For historical reasons, normal and aggregated data is here stored in the +// same data structure, differentiated by giving each key a prefix. It does +// seem like a good idea to refactor this. +const char kNormalPrefix = '-'; +const char kAggregatePrefix = '+'; + // The name of the test data file. const char kDataFileName[] = TEST_DATA_DIR "/countryinfo.txt"; -// The number of characters in the fake data URL prefix. -const size_t kFakeDataUrlLength = sizeof FakeDownloader::kFakeDataUrl - 1; - -// The number of characters in the fake aggregate data URL prefix. -const size_t kFakeAggregateDataUrlLength = - sizeof FakeDownloader::kFakeAggregateDataUrl - 1; - // Each data key begins with this string. Example of a data key: // data/CH/AG const char kDataKeyPrefix[] = "data/"; @@ -60,17 +51,6 @@ const size_t kCldrRegionCodeLength = 2; const size_t kAggregateDataKeyLength = kDataKeyPrefixLength + kCldrRegionCodeLength; -const LookupKeyUtil& GetLookupKeyUtil() { - static const LookupKeyUtil kLookupKeyUtil(FakeDownloader::kFakeDataUrl); - return kLookupKeyUtil; -} - -const LookupKeyUtil& GetAggregateLookupKeyUtil() { - static const LookupKeyUtil kLookupKeyUtil( - FakeDownloader::kFakeAggregateDataUrl); - return kLookupKeyUtil; -} - std::map<std::string, std::string> InitData() { std::map<std::string, std::string> data; std::ifstream file(kDataFileName); @@ -79,6 +59,9 @@ std::map<std::string, std::string> InitData() { std::exit(EXIT_FAILURE); } + const std::string normal_prefix(1, kNormalPrefix); + const std::string aggregate_prefix(1, kAggregatePrefix); + std::string key; std::string value; @@ -97,10 +80,10 @@ std::map<std::string, std::string> InitData() { // {"name": "Aargau"} std::getline(file, value, '\n'); - // For example, map 'test:///plain/data/CH/AG' to '{"name": "Aargau"}'. + // For example, map '-data/CH/AG' to '{"name": "Aargau"}'. last_data_it = data.insert( last_data_it, - std::make_pair(GetLookupKeyUtil().GetUrlForKey(key), value)); + std::make_pair(normal_prefix + key, value)); // Aggregate keys that begin with 'data/'. We don't aggregate keys that // begin with 'example/' because example data is not used anywhere. @@ -108,18 +91,12 @@ std::map<std::string, std::string> InitData() { kDataKeyPrefixLength, kDataKeyPrefix, kDataKeyPrefixLength) == 0) { - // Example aggregate URL: - // test:///aggregate/data/CH - const std::string& aggregate_url = - GetAggregateLookupKeyUtil().GetUrlForKey( - key.substr(0, kAggregateDataKeyLength)); - // If aggregate_data_it and key have the same prefix, e.g. "data/ZZ". if (aggregate_data_it != data.end() && key.compare(0, kAggregateDataKeyLength, aggregate_data_it->first, - kFakeAggregateDataUrlLength, + sizeof kAggregatePrefix, kAggregateDataKeyLength) == 0) { // Append more data to the aggregate string, for example: // , "data/CH/AG": {"name": "Aargau"} @@ -142,11 +119,16 @@ std::map<std::string, std::string> InitData() { aggregate_data_it->second.push_back('}'); } + // Example aggregate prefixed key: + // +data/CH + const std::string& aggregate_key = + aggregate_prefix + key.substr(0, kAggregateDataKeyLength); + // Begin a new aggregate string, for example: // {"data/CH/AG": {"name": "Aargau"} aggregate_data_it = data.insert( aggregate_data_it, - std::make_pair(aggregate_url, "{\"" + key + "\": " + value)); + std::make_pair(aggregate_key, "{\"" + key + "\": " + value)); } } } @@ -163,29 +145,29 @@ const std::map<std::string, std::string>& GetData() { } // namespace -FakeDownloader::FakeDownloader() {} +TestdataSource::TestdataSource(bool aggregate) : aggregate_(aggregate) {} -FakeDownloader::~FakeDownloader() {} +TestdataSource::~TestdataSource() {} -void FakeDownloader::Download(const std::string& url, - const Callback& downloaded) const { +void TestdataSource::Get(const std::string& key, + const Callback& data_ready) const { + std::string prefixed_key(1, aggregate_ ? kAggregatePrefix : kNormalPrefix); + prefixed_key += key; std::map<std::string, std::string>::const_iterator data_it = - GetData().find(url); + GetData().find(prefixed_key); bool success = data_it != GetData().end(); std::string* data = NULL; if (success) { data = new std::string(data_it->second); - } else if (GetLookupKeyUtil().IsValidationDataUrl(url) || - GetAggregateLookupKeyUtil().IsValidationDataUrl(url)) { + } else { // URLs that start with "https://i18napis.appspot.com/ssl-address/" or // "https://i18napis.appspot.com/ssl-aggregate-address/" prefix, but do not // have associated data will always return "{}" with status code 200. - // FakeDownloader imitates this behavior for URLs that start with - // "test://address/" and "test://aggregate-address/" prefixes. + // TestdataSource imitates this behavior. success = true; data = new std::string("{}"); } - downloaded(success, url, data); + data_ready(success, key, data); } } // namespace addressinput diff --git a/cpp/test/testdata_source.h b/cpp/test/testdata_source.h new file mode 100644 index 0000000..626483e --- /dev/null +++ b/cpp/test/testdata_source.h @@ -0,0 +1,71 @@ +// Copyright (C) 2013 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// An implementation of the Source interface, that reads address metadata from a +// text file, to be used in tests. + +#ifndef I18N_ADDRESSINPUT_TEST_TESTDATA_SOURCE_H_ +#define I18N_ADDRESSINPUT_TEST_TESTDATA_SOURCE_H_ + +#include <libaddressinput/source.h> +#include <libaddressinput/util/basictypes.h> + +#include <string> + +namespace i18n { +namespace addressinput { + +// Gets address metadata from a text file. Sample usage: +// class MyClass { +// public: +// MyClass() : source_(), +// data_ready_(BuildCallback(this, &MyClass::OnDataReady)) {} +// +// ~MyClass() {} +// +// void GetData(const std::string& key) { +// source_.Get(key, *data_ready_); +// } +// +// private: +// void OnDataReady(bool success, +// const std::string& key, +// std::string* data) { +// ... +// delete data; +// } +// +// TestdataSource source_; +// const scoped_ptr<const Source::Callback> data_ready_; +// +// DISALLOW_COPY_AND_ASSIGN(MyClass); +// }; +class TestdataSource : public Source { + public: + // Will return aggregate data if |aggregate| is set to true. + explicit TestdataSource(bool aggregate); + virtual ~TestdataSource(); + + // Source implementation. + virtual void Get(const std::string& key, const Callback& data_ready) const; + + private: + const bool aggregate_; + DISALLOW_COPY_AND_ASSIGN(TestdataSource); +}; + +} // namespace addressinput +} // namespace i18n + +#endif // I18N_ADDRESSINPUT_TEST_TESTDATA_SOURCE_H_ diff --git a/cpp/test/fake_downloader_test.cc b/cpp/test/testdata_source_test.cc index 29a3983..095b503 100644 --- a/cpp/test/fake_downloader_test.cc +++ b/cpp/test/testdata_source_test.cc @@ -12,10 +12,10 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "fake_downloader.h" +#include "testdata_source.h" #include <libaddressinput/callback.h> -#include <libaddressinput/downloader.h> +#include <libaddressinput/source.h> #include <libaddressinput/util/basictypes.h> #include <libaddressinput/util/scoped_ptr.h> @@ -29,44 +29,46 @@ namespace { using i18n::addressinput::BuildCallback; -using i18n::addressinput::Downloader; -using i18n::addressinput::FakeDownloader; using i18n::addressinput::RegionDataConstants; using i18n::addressinput::scoped_ptr; +using i18n::addressinput::Source; +using i18n::addressinput::TestdataSource; -// Tests for FakeDownloader object. -class FakeDownloaderTest : public testing::TestWithParam<std::string> { +// Tests for TestdataSource object. +class TestdataSourceTest : public testing::TestWithParam<std::string> { protected: - FakeDownloaderTest() - : downloader_(), + TestdataSourceTest() + : source_(false), + aggregate_source_(true), success_(false), - url_(), + key_(), data_(), - downloaded_(BuildCallback(this, &FakeDownloaderTest::OnDownloaded)) {} + data_ready_(BuildCallback(this, &TestdataSourceTest::OnDataReady)) {} - virtual ~FakeDownloaderTest() {} + virtual ~TestdataSourceTest() {} - FakeDownloader downloader_; + TestdataSource source_; + TestdataSource aggregate_source_; bool success_; - std::string url_; + std::string key_; std::string data_; - const scoped_ptr<const Downloader::Callback> downloaded_; + const scoped_ptr<const Source::Callback> data_ready_; private: - void OnDownloaded(bool success, const std::string& url, std::string* data) { + void OnDataReady(bool success, const std::string& key, std::string* data) { ASSERT_FALSE(success && data == NULL); success_ = success; - url_ = url; + key_ = key; if (data != NULL) { data_ = *data; delete data; } } - DISALLOW_COPY_AND_ASSIGN(FakeDownloaderTest); + DISALLOW_COPY_AND_ASSIGN(TestdataSourceTest); }; -// Returns testing::AssertionSuccess if |data| is valid downloaded data for +// Returns testing::AssertionSuccess if |data| is valid callback data for // |key|. testing::AssertionResult DataIsValid(const std::string& data, const std::string& key) { @@ -94,18 +96,17 @@ testing::AssertionResult DataIsValid(const std::string& data, return testing::AssertionSuccess(); } -// Verifies that FakeDownloader downloads valid data for a region code. -TEST_P(FakeDownloaderTest, FakeDownloaderHasValidDataForRegion) { +// Verifies that TestdataSource gets valid data for a region code. +TEST_P(TestdataSourceTest, TestdataSourceHasValidDataForRegion) { std::string key = "data/" + GetParam(); - std::string url = std::string(FakeDownloader::kFakeDataUrl) + key; - downloader_.Download(url, *downloaded_); + source_.Get(key, *data_ready_); EXPECT_TRUE(success_); - EXPECT_EQ(url, url_); + EXPECT_EQ(key, key_); EXPECT_TRUE(DataIsValid(data_, key)); }; -// Returns testing::AssertionSuccess if |data| is valid aggregated downloaded +// Returns testing::AssertionSuccess if |data| is valid aggregated callback // data for |key|. testing::AssertionResult AggregateDataIsValid(const std::string& data, const std::string& key) { @@ -133,75 +134,59 @@ testing::AssertionResult AggregateDataIsValid(const std::string& data, return testing::AssertionSuccess(); } -// Verifies that FakeDownloader downloads valid aggregated data for a region -// code. -TEST_P(FakeDownloaderTest, FakeDownloaderHasValidAggregatedDataForRegion) { +// Verifies that TestdataSource gets valid aggregated data for a region code. +TEST_P(TestdataSourceTest, TestdataSourceHasValidAggregatedDataForRegion) { std::string key = "data/" + GetParam(); - std::string url = std::string(FakeDownloader::kFakeAggregateDataUrl) + key; - downloader_.Download(url, *downloaded_); + aggregate_source_.Get(key, *data_ready_); EXPECT_TRUE(success_); - EXPECT_EQ(url, url_); + EXPECT_EQ(key, key_); EXPECT_TRUE(AggregateDataIsValid(data_, key)); }; // Test all region codes. INSTANTIATE_TEST_CASE_P( - AllRegions, FakeDownloaderTest, + AllRegions, TestdataSourceTest, testing::ValuesIn(RegionDataConstants::GetRegionCodes())); // Verifies that the key "data" also contains valid data. -TEST_F(FakeDownloaderTest, DownloadExistingData) { +TEST_F(TestdataSourceTest, GetExistingData) { static const std::string kKey = "data"; - static const std::string kUrl = - std::string(FakeDownloader::kFakeDataUrl) + kKey; - downloader_.Download(kUrl, *downloaded_); + source_.Get(kKey, *data_ready_); EXPECT_TRUE(success_); - EXPECT_EQ(kUrl, url_); + EXPECT_EQ(kKey, key_); EXPECT_TRUE(DataIsValid(data_, kKey)); } -// Verifies that downloading a missing key will return "{}". -TEST_F(FakeDownloaderTest, DownloadMissingKeyReturnsEmptyDictionary) { - static const std::string kJunkUrl = - std::string(FakeDownloader::kFakeDataUrl) + "junk"; - downloader_.Download(kJunkUrl, *downloaded_); +// Verifies that requesting a missing key will return "{}". +TEST_F(TestdataSourceTest, GetMissingKeyReturnsEmptyDictionary) { + static const std::string kJunkKey = "junk"; + source_.Get(kJunkKey, *data_ready_); EXPECT_TRUE(success_); - EXPECT_EQ(kJunkUrl, url_); + EXPECT_EQ(kJunkKey, key_); EXPECT_EQ("{}", data_); } -// Verifies that aggregate downloading of a missing key will also return "{}". -TEST_F(FakeDownloaderTest, AggregateDownloadMissingKeyReturnsEmptyDictionary) { - static const std::string kJunkUrl = - std::string(FakeDownloader::kFakeAggregateDataUrl) + "junk"; - downloader_.Download(kJunkUrl, *downloaded_); +// Verifies that aggregate requesting of a missing key will also return "{}". +TEST_F(TestdataSourceTest, AggregateGetMissingKeyReturnsEmptyDictionary) { + static const std::string kJunkKey = "junk"; + aggregate_source_.Get(kJunkKey, *data_ready_); EXPECT_TRUE(success_); - EXPECT_EQ(kJunkUrl, url_); + EXPECT_EQ(kJunkKey, key_); EXPECT_EQ("{}", data_); } -// Verifies that downloading an empty key will return "{}". -TEST_F(FakeDownloaderTest, DownloadEmptyKeyReturnsEmptyDictionary) { - static const std::string kPrefixOnlyUrl = FakeDownloader::kFakeDataUrl; - downloader_.Download(kPrefixOnlyUrl, *downloaded_); +// Verifies that requesting an empty key will return "{}". +TEST_F(TestdataSourceTest, GetEmptyKeyReturnsEmptyDictionary) { + static const std::string kEmptyKey; + source_.Get(kEmptyKey, *data_ready_); EXPECT_TRUE(success_); - EXPECT_EQ(kPrefixOnlyUrl, url_); + EXPECT_EQ(kEmptyKey, key_); EXPECT_EQ("{}", data_); } -// Verifies that downloading a real URL fails. -TEST_F(FakeDownloaderTest, DownloadRealUrlFals) { - static const std::string kRealUrl = "http://www.google.com/"; - downloader_.Download(kRealUrl, *downloaded_); - - EXPECT_FALSE(success_); - EXPECT_EQ(kRealUrl, url_); - EXPECT_TRUE(data_.empty()); -} - } // namespace |