aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrouslan@chromium.org <rouslan@chromium.org@38ededc0-08b8-5190-f2ac-b31f878777ad>2014-05-28 17:07:07 +0000
committerrouslan@chromium.org <rouslan@chromium.org@38ededc0-08b8-5190-f2ac-b31f878777ad>2014-05-28 17:07:07 +0000
commit018e8c28bb50ae78b83921f7211667407512b706 (patch)
tree10757bab69c15562271723dea11af5781ffa8edb
parentea5e77397b59d94af3591644c3dc23dc6f9ba22e (diff)
downloadsrc-018e8c28bb50ae78b83921f7211667407512b706.tar.gz
Separate region data builder from preload supplier.
R=roubert@google.com Review URL: https://codereview.appspot.com/101830044 git-svn-id: http://libaddressinput.googlecode.com/svn/trunk@256 38ededc0-08b8-5190-f2ac-b31f878777ad
-rw-r--r--cpp/include/libaddressinput/preload_supplier.h38
-rw-r--r--cpp/include/libaddressinput/region_data_builder.h80
-rw-r--r--cpp/libaddressinput.gypi2
-rw-r--r--cpp/src/preload_supplier.cc113
-rw-r--r--cpp/src/region_data_builder.cc147
-rw-r--r--cpp/test/preload_supplier_test.cc46
-rw-r--r--cpp/test/region_data_builder_test.cc98
7 files changed, 337 insertions, 187 deletions
diff --git a/cpp/include/libaddressinput/preload_supplier.h b/cpp/include/libaddressinput/preload_supplier.h
index 7226126..447911f 100644
--- a/cpp/include/libaddressinput/preload_supplier.h
+++ b/cpp/include/libaddressinput/preload_supplier.h
@@ -29,7 +29,6 @@ namespace addressinput {
class Downloader;
class LookupKey;
-class RegionData;
class Retriever;
class Rule;
class Storage;
@@ -83,52 +82,15 @@ class PreloadSupplier : public Supplier {
bool IsLoaded(const std::string& region_code) const;
bool IsPending(const std::string& region_code) const;
- // Returns a tree of administrative subdivisions for the |region_code|.
- // Examples:
- // US with en-US UI language.
- // |______________________
- // | | |
- // v v v
- // AL:Alabama AK:Alaska AS:American Samoa ...
- //
- // KR with ko-Latn UI language.
- // |______________________________________
- // | | |
- // v v v
- // 강원도:Gangwon 경기도:Gyeonggi 경상남도:Gyeongnam ...
- //
- // KR with ko-KR UI language.
- // |_______________________________
- // | | |
- // v v v
- // 강원도:강원 경기도:경기 경상남도:경남 ...
- //
- // The BCP 47 |ui_language_tag| is used to choose the best supported language
- // tag for this region (assigned to |best_region_tree_language_tag|). For
- // example, Canada has both English and French names for its administrative
- // subdivisions. If the UI language is French, then the French names are used.
- // The |best_region_tree_language_tag| value may be an empty string.
- //
- // Should be called only if IsLoaded(region_code) returns true. The
- // |best_region_tree_language_tag| parameter should not be NULL.
- const RegionData& BuildRegionTree(const std::string& region_code,
- const std::string& ui_language_tag,
- std::string* best_region_tree_language_tag);
-
private:
- typedef std::map<std::string, const RegionData*> LanguageRegionMap;
- typedef std::map<std::string, LanguageRegionMap*> RegionCodeDataMap;
-
bool GetRuleHierarchy(const LookupKey& lookup_key,
RuleHierarchy* hierarchy) const;
bool IsLoadedKey(const std::string& key) const;
bool IsPendingKey(const std::string& key) const;
- static std::string KeyFromRegionCode(const std::string& region_code);
const scoped_ptr<const Retriever> retriever_;
std::set<std::string> pending_;
std::map<std::string, const Rule*> rule_cache_;
- RegionCodeDataMap region_data_cache_;
DISALLOW_COPY_AND_ASSIGN(PreloadSupplier);
};
diff --git a/cpp/include/libaddressinput/region_data_builder.h b/cpp/include/libaddressinput/region_data_builder.h
new file mode 100644
index 0000000..906ca36
--- /dev/null
+++ b/cpp/include/libaddressinput/region_data_builder.h
@@ -0,0 +1,80 @@
+// 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_REGION_DATA_BUILDER_H_
+#define I18N_ADDRESSINPUT_REGION_DATA_BUILDER_H_
+
+#include <libaddressinput/util/basictypes.h>
+
+#include <map>
+#include <string>
+
+namespace i18n {
+namespace addressinput {
+
+class PreloadSupplier;
+class RegionData;
+
+class RegionDataBuilder {
+ public:
+ // Does not take ownership of |supplier|, which should not be NULL.
+ explicit RegionDataBuilder(PreloadSupplier* supplier);
+ ~RegionDataBuilder();
+
+ // Returns a tree of administrative subdivisions for the |region_code|.
+ // Examples:
+ // US with en-US UI language.
+ // |______________________
+ // | | |
+ // v v v
+ // AL:Alabama AK:Alaska AS:American Samoa ...
+ //
+ // KR with ko-Latn UI language.
+ // |______________________________________
+ // | | |
+ // v v v
+ // 강원도:Gangwon 경기도:Gyeonggi 경상남도:Gyeongnam ...
+ //
+ // KR with ko-KR UI language.
+ // |_______________________________
+ // | | |
+ // v v v
+ // 강원도:강원 경기도:경기 경상남도:경남 ...
+ //
+ // The BCP 47 |ui_language_tag| is used to choose the best supported language
+ // tag for this region (assigned to |best_region_tree_language_tag|). For
+ // example, Canada has both English and French names for its administrative
+ // subdivisions. If the UI language is French, then the French names are used.
+ // The |best_region_tree_language_tag| value may be an empty string.
+ //
+ // Should be called only if supplier->IsLoaded(region_code) returns true. The
+ // |best_region_tree_language_tag| parameter should not be NULL.
+ const RegionData& Build(const std::string& region_code,
+ const std::string& ui_language_tag,
+ std::string* best_region_tree_language_tag);
+
+ private:
+ typedef std::map<std::string, const RegionData*> LanguageRegionMap;
+ typedef std::map<std::string, LanguageRegionMap*> RegionCodeDataMap;
+
+ PreloadSupplier* const supplier_; // Not owned.
+ RegionCodeDataMap cache_;
+
+ DISALLOW_COPY_AND_ASSIGN(RegionDataBuilder);
+};
+
+} // namespace addressinput
+} // namespace i18n
+
+#endif // I18N_ADDRESSINPUT_REGION_DATA_BUILDER_H_
diff --git a/cpp/libaddressinput.gypi b/cpp/libaddressinput.gypi
index 62ebe88..f5e668c 100644
--- a/cpp/libaddressinput.gypi
+++ b/cpp/libaddressinput.gypi
@@ -32,6 +32,7 @@
'src/post_box_matchers.cc',
'src/preload_supplier.cc',
'src/region_data.cc',
+ 'src/region_data_builder.cc',
'src/region_data_constants.cc',
'src/retriever.cc',
'src/rule.cc',
@@ -68,6 +69,7 @@
'test/ondemand_supplier_test.cc',
'test/post_box_matchers_test.cc',
'test/preload_supplier_test.cc',
+ 'test/region_data_builder_test.cc',
'test/region_data_constants_test.cc',
'test/region_data_test.cc',
'test/retriever_test.cc',
diff --git a/cpp/src/preload_supplier.cc b/cpp/src/preload_supplier.cc
index 9504cc6..be438a2 100644
--- a/cpp/src/preload_supplier.cc
+++ b/cpp/src/preload_supplier.cc
@@ -17,7 +17,6 @@
#include <libaddressinput/address_data.h>
#include <libaddressinput/address_field.h>
#include <libaddressinput/callback.h>
-#include <libaddressinput/region_data.h>
#include <libaddressinput/supplier.h>
#include <libaddressinput/util/basictypes.h>
#include <libaddressinput/util/scoped_ptr.h>
@@ -134,58 +133,12 @@ class Helper {
DISALLOW_COPY_AND_ASSIGN(Helper);
};
-// Does not take ownership of |supplier| or |parent_region|, neither of which is
-// allowed to be NULL.
-void BuildRegionTreeRecursively(PreloadSupplier* supplier,
- const LookupKey& parent_key,
- RegionData* parent_region,
- const std::vector<std::string>& keys,
- bool prefer_latin_name) {
- assert(supplier != NULL);
- assert(parent_region != NULL);
-
- LookupKey lookup_key;
- for (std::vector<std::string>::const_iterator key_it = keys.begin();
- key_it != keys.end(); ++key_it) {
- lookup_key.FromLookupKey(parent_key, *key_it);
- const Rule* rule = supplier->GetRule(lookup_key);
- if (rule == NULL) {
- return;
- }
- const std::string& local_name = rule->GetName().empty()
- ? *key_it : rule->GetName();
- const std::string& name =
- prefer_latin_name && !rule->GetLatinName().empty()
- ? rule->GetLatinName() : local_name;
- RegionData* region = parent_region->AddSubRegion(*key_it, name);
- if (!rule->GetSubKeys().empty()) {
- BuildRegionTreeRecursively(supplier, lookup_key, region,
- rule->GetSubKeys(), prefer_latin_name);
- }
- }
-}
-
-// Does not take ownership of |supplier|, which cannot be NULL. The caller owns
-// the result.
-RegionData* BuildRegion(PreloadSupplier* supplier,
- const std::string& region_code,
- const Language& language) {
- assert(supplier != NULL);
-
+std::string KeyFromRegionCode(const std::string& region_code) {
AddressData address;
address.region_code = region_code;
-
LookupKey lookup_key;
lookup_key.FromAddress(address);
-
- const Rule* const rule = supplier->GetRule(lookup_key);
- assert(rule != NULL);
-
- RegionData* region = new RegionData(region_code);
- BuildRegionTreeRecursively(supplier, lookup_key, region,
- rule->GetSubKeys(), language.has_latin_script);
-
- return region;
+ return lookup_key.ToKeyString(0); // Zero depth = COUNTRY level.
}
} // namespace
@@ -195,23 +148,12 @@ PreloadSupplier::PreloadSupplier(const std::string& validation_data_url,
Storage* storage)
: retriever_(new Retriever(validation_data_url, downloader, storage)),
pending_(),
- rule_cache_(),
- region_data_cache_() {}
+ rule_cache_() {}
PreloadSupplier::~PreloadSupplier() {
for (std::map<std::string, const Rule*>::const_iterator
- rule_it = rule_cache_.begin(); rule_it != rule_cache_.end(); ++rule_it) {
- delete rule_it->second;
- }
-
- for (RegionCodeDataMap::const_iterator region_it = region_data_cache_.begin();
- region_it != region_data_cache_.end(); ++region_it) {
- for (LanguageRegionMap::const_iterator
- language_it = region_it->second->begin();
- language_it != region_it->second->end(); ++language_it) {
- delete language_it->second;
- }
- delete region_it->second;
+ it = rule_cache_.begin(); it != rule_cache_.end(); ++it) {
+ delete it->second;
}
}
@@ -261,42 +203,6 @@ bool PreloadSupplier::IsPending(const std::string& region_code) const {
return IsPendingKey(KeyFromRegionCode(region_code));
}
-const RegionData& PreloadSupplier::BuildRegionTree(
- const std::string& region_code,
- const std::string& ui_language_tag,
- std::string* best_region_tree_language_tag) {
- assert(IsLoaded(region_code));
- assert(best_region_tree_language_tag != NULL);
-
- // Look up the region tree in cache first before building it.
- RegionCodeDataMap::const_iterator region_it =
- region_data_cache_.find(region_code);
- if (region_it == region_data_cache_.end()) {
- region_it = region_data_cache_.insert(
- std::make_pair(region_code, new LanguageRegionMap)).first;
- }
-
- // No need to copy from default rule first, because only languages and Latin
- // format are going to be used, which do not exist in the default rule.
- Rule rule;
- rule.ParseSerializedRule(RegionDataConstants::GetRegionData(region_code));
- static const Language kUndefinedLanguage("und");
- const Language& best_language = rule.GetLanguages().empty()
- ? kUndefinedLanguage
- : ChooseBestAddressLanguage(rule, Language(ui_language_tag));
- *best_region_tree_language_tag = best_language.tag;
-
- LanguageRegionMap::const_iterator language_it =
- region_it->second->find(best_language.tag);
- if (language_it == region_it->second->end()) {
- language_it = region_it->second->insert(
- std::make_pair(best_language.tag,
- BuildRegion(this, region_code, best_language))).first;
- }
-
- return *language_it->second;
-}
-
bool PreloadSupplier::GetRuleHierarchy(const LookupKey& lookup_key,
RuleHierarchy* hierarchy) const {
assert(hierarchy != NULL);
@@ -328,14 +234,5 @@ bool PreloadSupplier::IsPendingKey(const std::string& key) const {
return pending_.find(key) != pending_.end();
}
-// static
-std::string PreloadSupplier::KeyFromRegionCode(const std::string& region_code) {
- AddressData address;
- address.region_code = region_code;
- LookupKey lookup_key;
- lookup_key.FromAddress(address);
- return lookup_key.ToKeyString(0); // Zero depth = COUNTRY level.
-}
-
} // namespace addressinput
} // namespace i18n
diff --git a/cpp/src/region_data_builder.cc b/cpp/src/region_data_builder.cc
new file mode 100644
index 0000000..82d223c
--- /dev/null
+++ b/cpp/src/region_data_builder.cc
@@ -0,0 +1,147 @@
+// 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 <libaddressinput/region_data_builder.h>
+
+#include <libaddressinput/address_data.h>
+#include <libaddressinput/preload_supplier.h>
+#include <libaddressinput/region_data.h>
+
+#include <cassert>
+#include <cstddef>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include "language.h"
+#include "lookup_key.h"
+#include "region_data_constants.h"
+#include "rule.h"
+
+namespace i18n {
+namespace addressinput {
+
+namespace {
+
+// Does not take ownership of |supplier| or |parent_region|, neither of which is
+// allowed to be NULL.
+void BuildRegionTreeRecursively(PreloadSupplier* supplier,
+ const LookupKey& parent_key,
+ RegionData* parent_region,
+ const std::vector<std::string>& keys,
+ bool prefer_latin_name) {
+ assert(supplier != NULL);
+ assert(parent_region != NULL);
+
+ LookupKey lookup_key;
+ for (std::vector<std::string>::const_iterator key_it = keys.begin();
+ key_it != keys.end(); ++key_it) {
+ lookup_key.FromLookupKey(parent_key, *key_it);
+ const Rule* rule = supplier->GetRule(lookup_key);
+ if (rule == NULL) {
+ return;
+ }
+ const std::string& local_name = rule->GetName().empty()
+ ? *key_it : rule->GetName();
+ const std::string& name =
+ prefer_latin_name && !rule->GetLatinName().empty()
+ ? rule->GetLatinName() : local_name;
+ RegionData* region = parent_region->AddSubRegion(*key_it, name);
+ if (!rule->GetSubKeys().empty()) {
+ BuildRegionTreeRecursively(supplier, lookup_key, region,
+ rule->GetSubKeys(), prefer_latin_name);
+ }
+ }
+}
+
+// Does not take ownership of |supplier|, which cannot be NULL. The caller owns
+// the result.
+RegionData* BuildRegion(PreloadSupplier* supplier,
+ const std::string& region_code,
+ const Language& language) {
+ assert(supplier != NULL);
+
+ AddressData address;
+ address.region_code = region_code;
+
+ LookupKey lookup_key;
+ lookup_key.FromAddress(address);
+
+ const Rule* const rule = supplier->GetRule(lookup_key);
+ assert(rule != NULL);
+
+ RegionData* region = new RegionData(region_code);
+ BuildRegionTreeRecursively(supplier, lookup_key, region,
+ rule->GetSubKeys(), language.has_latin_script);
+
+ return region;
+}
+
+} // namespace
+
+RegionDataBuilder::RegionDataBuilder(PreloadSupplier* supplier)
+ : supplier_(supplier),
+ cache_() {
+ assert(supplier_ != NULL);
+}
+
+RegionDataBuilder::~RegionDataBuilder() {
+ for (RegionCodeDataMap::const_iterator region_it = cache_.begin();
+ region_it != cache_.end(); ++region_it) {
+ for (LanguageRegionMap::const_iterator
+ language_it = region_it->second->begin();
+ language_it != region_it->second->end(); ++language_it) {
+ delete language_it->second;
+ }
+ delete region_it->second;
+ }
+}
+
+const RegionData& RegionDataBuilder::Build(
+ const std::string& region_code,
+ const std::string& ui_language_tag,
+ std::string* best_region_tree_language_tag) {
+ assert(supplier_->IsLoaded(region_code));
+ assert(best_region_tree_language_tag != NULL);
+
+ // Look up the region tree in cache first before building it.
+ RegionCodeDataMap::const_iterator region_it = cache_.find(region_code);
+ if (region_it == cache_.end()) {
+ region_it =
+ cache_.insert(std::make_pair(region_code, new LanguageRegionMap)).first;
+ }
+
+ // No need to copy from default rule first, because only languages and Latin
+ // format are going to be used, which do not exist in the default rule.
+ Rule rule;
+ rule.ParseSerializedRule(RegionDataConstants::GetRegionData(region_code));
+ static const Language kUndefinedLanguage("und");
+ const Language& best_language = rule.GetLanguages().empty()
+ ? kUndefinedLanguage
+ : ChooseBestAddressLanguage(rule, Language(ui_language_tag));
+ *best_region_tree_language_tag = best_language.tag;
+
+ LanguageRegionMap::const_iterator language_it =
+ region_it->second->find(best_language.tag);
+ if (language_it == region_it->second->end()) {
+ language_it = region_it->second->insert(std::make_pair(
+ best_language.tag,
+ BuildRegion(supplier_, region_code, best_language))).first;
+ }
+
+ return *language_it->second;
+}
+
+} // namespace addressinput
+} // namespace i18n
diff --git a/cpp/test/preload_supplier_test.cc b/cpp/test/preload_supplier_test.cc
index 3ddbc34..b812ef1 100644
--- a/cpp/test/preload_supplier_test.cc
+++ b/cpp/test/preload_supplier_test.cc
@@ -17,7 +17,6 @@
#include <libaddressinput/address_data.h>
#include <libaddressinput/callback.h>
#include <libaddressinput/null_storage.h>
-#include <libaddressinput/region_data.h>
#include <libaddressinput/util/basictypes.h>
#include <libaddressinput/util/scoped_ptr.h>
@@ -38,7 +37,6 @@ using i18n::addressinput::FakeDownloader;
using i18n::addressinput::LookupKey;
using i18n::addressinput::NullStorage;
using i18n::addressinput::PreloadSupplier;
-using i18n::addressinput::RegionData;
using i18n::addressinput::Rule;
using i18n::addressinput::scoped_ptr;
@@ -48,22 +46,20 @@ class PreloadSupplierTest : public testing::Test {
: supplier_(FakeDownloader::kFakeAggregateDataUrl,
new FakeDownloader,
new NullStorage),
- loaded_callback_(BuildCallback(this, &PreloadSupplierTest::OnLoaded)),
- best_language_() {}
+ loaded_callback_(BuildCallback(this, &PreloadSupplierTest::OnLoaded)) {}
- ~PreloadSupplierTest() {}
+ virtual ~PreloadSupplierTest() {}
PreloadSupplier supplier_;
scoped_ptr<PreloadSupplier::Callback> loaded_callback_;
- std::string best_language_;
private:
void OnLoaded(bool success,
const std::string& region_code,
const int& num_rules) {
- EXPECT_TRUE(success);
- EXPECT_FALSE(region_code.empty());
- EXPECT_LT(0, num_rules);
+ ASSERT_TRUE(success);
+ ASSERT_FALSE(region_code.empty());
+ ASSERT_LT(0, num_rules);
ASSERT_TRUE(supplier_.IsLoaded(region_code));
}
@@ -127,36 +123,4 @@ TEST_F(PreloadSupplierTest, GetTooPreciseRule) {
EXPECT_TRUE(rule == NULL);
}
-TEST_F(PreloadSupplierTest, BuildUsRegionTree) {
- supplier_.LoadRules("US", *loaded_callback_);
- const RegionData& tree =
- supplier_.BuildRegionTree("US", "en-US", &best_language_);
- EXPECT_FALSE(tree.sub_regions().empty());
-}
-
-TEST_F(PreloadSupplierTest, BuildCnRegionTree) {
- supplier_.LoadRules("CN", *loaded_callback_);
- const RegionData& tree =
- supplier_.BuildRegionTree("CN", "zh-Hans", &best_language_);
- ASSERT_FALSE(tree.sub_regions().empty());
- EXPECT_FALSE(tree.sub_regions().front()->sub_regions().empty());
-}
-
-TEST_F(PreloadSupplierTest, BuildChRegionTree) {
- supplier_.LoadRules("CH", *loaded_callback_);
- const RegionData& tree =
- supplier_.BuildRegionTree("CH", "de-CH", &best_language_);
- // Although "CH" has information for its administrative divisions, the
- // administrative area field is not used, which results in an empty tree of
- // sub-regions.
- EXPECT_TRUE(tree.sub_regions().empty());
-}
-
-TEST_F(PreloadSupplierTest, BuildZwRegionTree) {
- supplier_.LoadRules("ZW", *loaded_callback_);
- const RegionData& tree =
- supplier_.BuildRegionTree("ZW", "en-ZW", &best_language_);
- EXPECT_TRUE(tree.sub_regions().empty());
-}
-
} // namespace
diff --git a/cpp/test/region_data_builder_test.cc b/cpp/test/region_data_builder_test.cc
new file mode 100644
index 0000000..088a73e
--- /dev/null
+++ b/cpp/test/region_data_builder_test.cc
@@ -0,0 +1,98 @@
+// 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 <libaddressinput/region_data_builder.h>
+
+#include <libaddressinput/callback.h>
+#include <libaddressinput/null_storage.h>
+#include <libaddressinput/preload_supplier.h>
+#include <libaddressinput/region_data.h>
+#include <libaddressinput/util/basictypes.h>
+#include <libaddressinput/util/scoped_ptr.h>
+
+#include "fake_downloader.h"
+
+#include <string>
+
+#include <gtest/gtest.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;
+
+class RegionDataBuilderTest : public testing::Test {
+ protected:
+ RegionDataBuilderTest()
+ : supplier_(FakeDownloader::kFakeAggregateDataUrl,
+ new FakeDownloader,
+ new NullStorage),
+ builder_(&supplier_),
+ loaded_callback_(BuildCallback(this, &RegionDataBuilderTest::OnLoaded)),
+ best_language_() {}
+
+ virtual ~RegionDataBuilderTest() {}
+
+ PreloadSupplier supplier_;
+ RegionDataBuilder builder_;
+ scoped_ptr<PreloadSupplier::Callback> loaded_callback_;
+ std::string best_language_;
+
+ private:
+ void OnLoaded(bool success,
+ const std::string& region_code,
+ const int& num_rules) {
+ ASSERT_TRUE(success);
+ ASSERT_FALSE(region_code.empty());
+ ASSERT_LT(0, num_rules);
+ ASSERT_TRUE(supplier_.IsLoaded(region_code));
+ }
+
+ DISALLOW_COPY_AND_ASSIGN(RegionDataBuilderTest);
+};
+
+TEST_F(RegionDataBuilderTest, BuildUsRegionTree) {
+ supplier_.LoadRules("US", *loaded_callback_);
+ const RegionData& tree = builder_.Build("US", "en-US", &best_language_);
+ EXPECT_FALSE(tree.sub_regions().empty());
+}
+
+TEST_F(RegionDataBuilderTest, BuildCnRegionTree) {
+ supplier_.LoadRules("CN", *loaded_callback_);
+ const RegionData& tree = builder_.Build("CN", "zh-Hans", &best_language_);
+ ASSERT_FALSE(tree.sub_regions().empty());
+ EXPECT_FALSE(tree.sub_regions().front()->sub_regions().empty());
+}
+
+TEST_F(RegionDataBuilderTest, BuildChRegionTree) {
+ supplier_.LoadRules("CH", *loaded_callback_);
+ const RegionData& tree = builder_.Build("CH", "de-CH", &best_language_);
+ // Although "CH" has information for its administrative divisions, the
+ // administrative area field is not used, which results in an empty tree of
+ // sub-regions.
+ EXPECT_TRUE(tree.sub_regions().empty());
+}
+
+TEST_F(RegionDataBuilderTest, BuildZwRegionTree) {
+ supplier_.LoadRules("ZW", *loaded_callback_);
+ const RegionData& tree = builder_.Build("ZW", "en-ZW", &best_language_);
+ EXPECT_TRUE(tree.sub_regions().empty());
+}
+
+} // namespace