aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorroubert@google.com <roubert@google.com@38ededc0-08b8-5190-f2ac-b31f878777ad>2014-03-21 12:21:22 +0000
committerroubert@google.com <roubert@google.com@38ededc0-08b8-5190-f2ac-b31f878777ad>2014-03-21 12:21:22 +0000
commit7764218473f33ca749ca4a3cc66d1118793481dd (patch)
treefdaed07e3e171f40dacd91beee286416f6d8e1fb
parente0cd6d6862db732f3fd035cdebd3a5d0ee8701c7 (diff)
downloadsrc-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.gyp2
-rw-r--r--cpp/src/lookup_key.cc101
-rw-r--r--cpp/src/lookup_key.h62
-rw-r--r--cpp/test/lookup_key_test.cc124
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