diff options
author | roubert@google.com <roubert@google.com@38ededc0-08b8-5190-f2ac-b31f878777ad> | 2014-03-21 12:21:22 +0000 |
---|---|---|
committer | roubert@google.com <roubert@google.com@38ededc0-08b8-5190-f2ac-b31f878777ad> | 2014-03-21 12:21:22 +0000 |
commit | 7764218473f33ca749ca4a3cc66d1118793481dd (patch) | |
tree | fdaed07e3e171f40dacd91beee286416f6d8e1fb | |
parent | e0cd6d6862db732f3fd035cdebd3a5d0ee8701c7 (diff) | |
download | src-7764218473f33ca749ca4a3cc66d1118793481dd.tar.gz |
Add the LookupKey helper class.
A LookupKey maps between an AddressData struct and the key string used
to request address data from an address data server.
git-svn-id: http://libaddressinput.googlecode.com/svn/trunk@195 38ededc0-08b8-5190-f2ac-b31f878777ad
-rw-r--r-- | cpp/libaddressinput.gyp | 2 | ||||
-rw-r--r-- | cpp/src/lookup_key.cc | 101 | ||||
-rw-r--r-- | cpp/src/lookup_key.h | 62 | ||||
-rw-r--r-- | cpp/test/lookup_key_test.cc | 124 |
4 files changed, 289 insertions, 0 deletions
diff --git a/cpp/libaddressinput.gyp b/cpp/libaddressinput.gyp index c2b2391..f6ee3b6 100644 --- a/cpp/libaddressinput.gyp +++ b/cpp/libaddressinput.gyp @@ -37,6 +37,7 @@ 'src/address_problem.cc', 'src/address_ui.cc', 'src/localization.cc', + 'src/lookup_key.cc', 'src/lookup_key_util.cc', 'src/null_storage.cc', 'src/region_data_constants.cc', @@ -69,6 +70,7 @@ 'test/fake_storage.cc', 'test/fake_storage_test.cc', 'test/localization_test.cc', + 'test/lookup_key_test.cc', 'test/lookup_key_util_test.cc', 'test/null_storage_test.cc', 'test/region_data_constants_test.cc', diff --git a/cpp/src/lookup_key.cc b/cpp/src/lookup_key.cc new file mode 100644 index 0000000..0b6f7d8 --- /dev/null +++ b/cpp/src/lookup_key.cc @@ -0,0 +1,101 @@ +// 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. + +#include "lookup_key.h" + +#include <cassert> +#include <cstddef> +#include <map> +#include <string> +#include <utility> + +#include <libaddressinput/address_data.h> +#include <libaddressinput/address_field.h> +#include <libaddressinput/util/basictypes.h> + +namespace i18n { +namespace addressinput { + +namespace { + +const char kSlashDelim[] = "/"; +const char kData[] = "data"; +const char kUnknown[] = "ZZ"; + +} // namespace + +const AddressField LookupKey::kHierarchy[] = { + COUNTRY, + ADMIN_AREA, + LOCALITY, + DEPENDENT_LOCALITY +}; + +LookupKey::LookupKey() { +} + +LookupKey::~LookupKey() { +} + +void LookupKey::FromAddress(const AddressData& address) { + nodes_.clear(); + + if (address.region_code.empty()) { + nodes_.insert(std::make_pair(COUNTRY, kUnknown)); + } else { + for (size_t i = 0; i < arraysize(kHierarchy); ++i) { + AddressField field = kHierarchy[i]; + const std::string& value = address.GetFieldValue(field); + if (value.empty()) { + break; + } + nodes_.insert(std::make_pair(field, value)); + } + } +} + +std::string LookupKey::ToKeyString(size_t max_depth) const { + // TODO: For use by the address input widget, this key string would need to + // also include a language tag to request data in the appropriate language. + + assert(max_depth < arraysize(kHierarchy)); + std::string key_string(kData); + + for (size_t i = 0; i <= max_depth; ++i) { + AddressField field = kHierarchy[i]; + std::map<AddressField, std::string>::const_iterator it = nodes_.find(field); + if (it == nodes_.end()) { + break; + } + key_string.append(kSlashDelim); + key_string.append(it->second); + } + + return key_string; +} + +const std::string& LookupKey::GetRegionCode() const { + std::map<AddressField, std::string>::const_iterator it = nodes_.find(COUNTRY); + assert(it != nodes_.end()); + return it->second; +} + +size_t LookupKey::GetDepth() const { + size_t depth = nodes_.size() - 1; + assert(depth < arraysize(kHierarchy)); + return depth; +} + +} // namespace addressinput +} // namespace i18n diff --git a/cpp/src/lookup_key.h b/cpp/src/lookup_key.h new file mode 100644 index 0000000..be76656 --- /dev/null +++ b/cpp/src/lookup_key.h @@ -0,0 +1,62 @@ +// 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. + +#ifndef I18N_ADDRESSINPUT_LOOKUP_KEY_H_ +#define I18N_ADDRESSINPUT_LOOKUP_KEY_H_ + +#include <libaddressinput/address_field.h> +#include <libaddressinput/util/basictypes.h> + +#include <cstddef> +#include <map> +#include <string> + +namespace i18n { +namespace addressinput { + +struct AddressData; + +// A LookupKey maps between an AddressData struct and the key string used to +// request address data from an address data server. +class LookupKey { + public: + // The array length is explicitly specified here, to make it possible to get + // the length through arraysize(LookupKey::kHierarchy). + static const AddressField kHierarchy[4]; + + LookupKey(); + ~LookupKey(); + + // Initializes this object by parsing |address|. + void FromAddress(const AddressData& address); + + // Returns the lookup key string (of |max_depth|). + std::string ToKeyString(size_t max_depth) const; + + // Returns the region code. Must not be called on an empty object. + const std::string& GetRegionCode() const; + + // Returns the depth. Must not be called on an empty object. + size_t GetDepth() const; + + private: + std::map<AddressField, std::string> nodes_; + + DISALLOW_COPY_AND_ASSIGN(LookupKey); +}; + +} // namespace addressinput +} // namespace i18n + +#endif // I18N_ADDRESSINPUT_LOOKUP_KEY_H_ diff --git a/cpp/test/lookup_key_test.cc b/cpp/test/lookup_key_test.cc new file mode 100644 index 0000000..c348fca --- /dev/null +++ b/cpp/test/lookup_key_test.cc @@ -0,0 +1,124 @@ +// 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. + +#include "lookup_key.h" + +#include <libaddressinput/address_data.h> +#include <libaddressinput/util/basictypes.h> + +#include <gtest/gtest.h> + +namespace { + +using i18n::addressinput::AddressData; +using i18n::addressinput::LookupKey; + +const size_t kMaxDepth = arraysize(LookupKey::kHierarchy) - 1; + +TEST(LookupKeyTest, Empty) { + AddressData address; + LookupKey lookup_key; + lookup_key.FromAddress(address); + EXPECT_EQ("data/ZZ", lookup_key.ToKeyString(kMaxDepth)); +} + +TEST(LookupKeyTest, AddressDepth1) { + AddressData address; + address.region_code = "111"; + LookupKey lookup_key; + lookup_key.FromAddress(address); + EXPECT_EQ(0, lookup_key.GetDepth()); + EXPECT_EQ("data/111", lookup_key.ToKeyString(kMaxDepth)); +} + +TEST(LookupKeyTest, AddressDepth2) { + AddressData address; + address.region_code = "111"; + address.administrative_area = "222"; + LookupKey lookup_key; + lookup_key.FromAddress(address); + EXPECT_EQ(1, lookup_key.GetDepth()); + EXPECT_EQ("data/111/222", lookup_key.ToKeyString(kMaxDepth)); +} + +TEST(LookupKeyTest, AddressDepth3) { + AddressData address; + address.region_code = "111"; + address.administrative_area = "222"; + address.locality = "333"; + LookupKey lookup_key; + lookup_key.FromAddress(address); + EXPECT_EQ(2, lookup_key.GetDepth()); + EXPECT_EQ("data/111/222/333", lookup_key.ToKeyString(kMaxDepth)); +} + +TEST(LookupKeyTest, AddressDepth4) { + AddressData address; + address.region_code = "111"; + address.administrative_area = "222"; + address.locality = "333"; + address.dependent_locality = "444"; + LookupKey lookup_key; + lookup_key.FromAddress(address); + EXPECT_EQ(3, lookup_key.GetDepth()); + EXPECT_EQ("data/111/222/333/444", lookup_key.ToKeyString(kMaxDepth)); +} + +TEST(LookupKeyTest, AddressDepthNonContiguous) { + AddressData address; + address.region_code = "111"; + address.administrative_area = "222"; + // No LOCALITY specified. + address.dependent_locality = "444"; + LookupKey lookup_key; + lookup_key.FromAddress(address); + EXPECT_EQ(1, lookup_key.GetDepth()); + EXPECT_EQ("data/111/222", lookup_key.ToKeyString(kMaxDepth)); +} + +TEST(LookupKeyTest, RequestDepth) { + AddressData address; + address.region_code = "111"; + address.administrative_area = "222"; + address.locality = "333"; + address.dependent_locality = "444"; + LookupKey lookup_key; + lookup_key.FromAddress(address); + EXPECT_EQ("data/111", lookup_key.ToKeyString(0)); + EXPECT_EQ("data/111/222", lookup_key.ToKeyString(1)); + EXPECT_EQ("data/111/222/333", lookup_key.ToKeyString(2)); + EXPECT_EQ("data/111/222/333/444", lookup_key.ToKeyString(3)); +} + +TEST(LookupKeyTest, GetRegionCode) { + AddressData address; + address.region_code = "rrr"; + LookupKey lookup_key; + lookup_key.FromAddress(address); + EXPECT_EQ(address.region_code, lookup_key.GetRegionCode()); +} + +TEST(LookupKeyTest, FromAddressClearsExistingNodes) { + AddressData address; + address.region_code = "111"; + address.administrative_area = "222"; + LookupKey lookup_key; + lookup_key.FromAddress(address); + EXPECT_EQ("data/111/222", lookup_key.ToKeyString(kMaxDepth)); + address.administrative_area.clear(); + lookup_key.FromAddress(address); + EXPECT_EQ("data/111", lookup_key.ToKeyString(kMaxDepth)); +} + +} // namespace |