Home | History | Annotate | Download | only in test
      1 // Copyright (C) 2013 Google Inc.
      2 //
      3 // Licensed under the Apache License, Version 2.0 (the "License");
      4 // you may not use this file except in compliance with the License.
      5 // You may obtain a copy of the License at
      6 //
      7 // http://www.apache.org/licenses/LICENSE-2.0
      8 //
      9 // Unless required by applicable law or agreed to in writing, software
     10 // distributed under the License is distributed on an "AS IS" BASIS,
     11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     12 // See the License for the specific language governing permissions and
     13 // limitations under the License.
     14 
     15 #include <libaddressinput/address_ui.h>
     16 
     17 #include <libaddressinput/address_field.h>
     18 #include <libaddressinput/address_ui_component.h>
     19 #include <libaddressinput/localization.h>
     20 #include <libaddressinput/util/basictypes.h>
     21 
     22 #include <set>
     23 #include <string>
     24 #include <vector>
     25 
     26 #include <gtest/gtest.h>
     27 
     28 namespace {
     29 
     30 using i18n::addressinput::AddressField;
     31 using i18n::addressinput::AddressUiComponent;
     32 using i18n::addressinput::BuildComponents;
     33 using i18n::addressinput::GetRegionCodes;
     34 using i18n::addressinput::Localization;
     35 
     36 using i18n::addressinput::COUNTRY;
     37 using i18n::addressinput::ADMIN_AREA;
     38 using i18n::addressinput::POSTAL_CODE;
     39 using i18n::addressinput::STREET_ADDRESS;
     40 using i18n::addressinput::ORGANIZATION;
     41 using i18n::addressinput::RECIPIENT;
     42 
     43 static const char kUiLanguageTag[] = "en";
     44 
     45 // Returns testing::AssertionSuccess if the |components| are valid. Uses
     46 // |region_code| in test failure messages.
     47 testing::AssertionResult ComponentsAreValid(
     48     const std::vector<AddressUiComponent>& components) {
     49   if (components.empty()) {
     50     return testing::AssertionFailure() << "no components";
     51   }
     52 
     53   for (std::vector<AddressUiComponent>::const_iterator
     54        component_it = components.begin();
     55        component_it != components.end(); ++component_it) {
     56     static const AddressField kMinAddressField = COUNTRY;
     57     static const AddressField kMaxAddressField = RECIPIENT;
     58     if (component_it->field < kMinAddressField ||
     59         component_it->field > kMaxAddressField) {
     60       return testing::AssertionFailure() << "unexpected field "
     61                                          << component_it->field;
     62     }
     63 
     64     if (component_it->name.empty()) {
     65       return testing::AssertionFailure() << "empty field name for field "
     66                                          << component_it->field;
     67     }
     68   }
     69 
     70   return testing::AssertionSuccess();
     71 }
     72 
     73 // Tests for address UI functions.
     74 class AddressUiTest : public testing::TestWithParam<std::string> {
     75  protected:
     76   AddressUiTest() {}
     77   Localization localization_;
     78   std::string best_address_language_tag_;
     79 
     80  private:
     81   DISALLOW_COPY_AND_ASSIGN(AddressUiTest);
     82 };
     83 
     84 // Verifies that a region code consists of two characters, for example "TW".
     85 TEST_P(AddressUiTest, RegionCodeHasTwoCharacters) {
     86   EXPECT_EQ(2, GetParam().size());
     87 }
     88 
     89 // Verifies that BuildComponents() returns valid UI components for a region
     90 // code.
     91 TEST_P(AddressUiTest, ComponentsAreValid) {
     92   EXPECT_TRUE(ComponentsAreValid(BuildComponents(
     93       GetParam(), localization_, kUiLanguageTag, &best_address_language_tag_)));
     94 }
     95 
     96 // Verifies that BuildComponents() returns at most one input field of each type.
     97 TEST_P(AddressUiTest, UniqueFieldTypes) {
     98   std::set<AddressField> fields;
     99   const std::vector<AddressUiComponent>& components =
    100       BuildComponents(GetParam(), localization_, kUiLanguageTag,
    101                       &best_address_language_tag_);
    102   for (std::vector<AddressUiComponent>::const_iterator it = components.begin();
    103        it != components.end(); ++it) {
    104     EXPECT_TRUE(fields.insert(it->field).second);
    105   }
    106 }
    107 
    108 // Test all regions codes.
    109 INSTANTIATE_TEST_CASE_P(
    110     AllRegions, AddressUiTest,
    111     testing::ValuesIn(GetRegionCodes()));
    112 
    113 // Verifies that BuildComponents() returns an empty vector for an invalid region
    114 // code.
    115 TEST_F(AddressUiTest, InvalidRegionCodeReturnsEmptyVector) {
    116   EXPECT_TRUE(BuildComponents(
    117       "INVALID-REGION-CODE", localization_, kUiLanguageTag,
    118       &best_address_language_tag_).empty());
    119 }
    120 
    121 // Test data for determining the best language tag and whether the right format
    122 // pattern was used (fmt vs lfmt).
    123 struct LanguageTestCase {
    124   LanguageTestCase(const std::string& region_code,
    125                    const std::string& ui_language_tag,
    126                    const std::string& expected_best_address_language_tag,
    127                    AddressField expected_first_field)
    128       : region_code(region_code),
    129         ui_language_tag(ui_language_tag),
    130         expected_best_address_language_tag(expected_best_address_language_tag),
    131         expected_first_field(expected_first_field) {}
    132 
    133   ~LanguageTestCase() {}
    134 
    135   // The CLDR region code to test.
    136   const std::string region_code;
    137 
    138   // The BCP 47 language tag to test.
    139   const std::string ui_language_tag;
    140 
    141   // The expected value for the best language tag returned by BuildComponents().
    142   const std::string expected_best_address_language_tag;
    143 
    144   // The first field expected to be returned from BuildComponents(). Useful for
    145   // determining whether the returned format is in Latin or default order.
    146   const AddressField expected_first_field;
    147 };
    148 
    149 class BestAddressLanguageTagTest
    150     : public testing::TestWithParam<LanguageTestCase> {
    151  protected:
    152   BestAddressLanguageTagTest() {}
    153   Localization localization_;
    154   std::string best_address_language_tag_;
    155 
    156  private:
    157   DISALLOW_COPY_AND_ASSIGN(BestAddressLanguageTagTest);
    158 };
    159 
    160 std::string GetterStub(int) { return std::string(); }
    161 
    162 TEST_P(BestAddressLanguageTagTest, CorrectBestAddressLanguageTag) {
    163   localization_.SetGetter(&GetterStub);
    164   const std::vector<AddressUiComponent>& components = BuildComponents(
    165       GetParam().region_code, localization_, GetParam().ui_language_tag,
    166       &best_address_language_tag_);
    167   EXPECT_EQ(GetParam().expected_best_address_language_tag,
    168             best_address_language_tag_);
    169   ASSERT_FALSE(components.empty());
    170   EXPECT_EQ(GetParam().expected_first_field, components.front().field);
    171 }
    172 
    173 INSTANTIATE_TEST_CASE_P(
    174     LanguageTestCases, BestAddressLanguageTagTest,
    175     testing::Values(
    176         // Armenia supports hy and has a Latin format.
    177         LanguageTestCase("AM", "", "hy", RECIPIENT),
    178         LanguageTestCase("AM", "hy", "hy", RECIPIENT),
    179         LanguageTestCase("AM", "en", "hy-Latn", RECIPIENT),
    180 
    181         // P.R. China supports zh-Hans and has a Latin format.
    182         LanguageTestCase("CN", "zh-hans", "zh-Hans", POSTAL_CODE),
    183         LanguageTestCase("CN", "zh-hant", "zh-Hans", POSTAL_CODE),
    184         LanguageTestCase("CN", "zh-hans-CN", "zh-Hans", POSTAL_CODE),
    185         LanguageTestCase("CN", "zh", "zh-Hans", POSTAL_CODE),
    186         LanguageTestCase("CN", "ZH_HANS", "zh-Hans", POSTAL_CODE),
    187         LanguageTestCase("CN", "zh-cmn-Hans-CN", "zh-Hans", POSTAL_CODE),
    188         LanguageTestCase("CN", "zh-Latn", "zh-Latn", RECIPIENT),
    189         LanguageTestCase("CN", "zh-latn-CN", "zh-Latn", RECIPIENT),
    190         LanguageTestCase("CN", "en", "zh-Latn", RECIPIENT),
    191         LanguageTestCase("CN", "ja", "zh-Latn", RECIPIENT),
    192         LanguageTestCase("CN", "ko", "zh-Latn", RECIPIENT),
    193         LanguageTestCase("CN", "ZH_LATN", "zh-Latn", RECIPIENT),
    194         // Libaddressinput does not have information about extended language
    195         // subtags, so it uses the zh-Latn language tag for all base languages
    196         // that are not zh, even if it's effectively the same language.
    197         // Mandarin Chinese, Simplified script, as used in China:
    198         LanguageTestCase("CN", "cmn-Hans-CN", "zh-Latn", RECIPIENT),
    199 
    200         // Hong Kong supports zh-Hant and en. It has a Latin format.
    201         LanguageTestCase("HK", "zh", "zh-Hant", ADMIN_AREA),
    202         LanguageTestCase("HK", "zh-hans", "zh-Hant", ADMIN_AREA),
    203         LanguageTestCase("HK", "zh-hant", "zh-Hant", ADMIN_AREA),
    204         LanguageTestCase("HK", "zh-yue-HK", "zh-Hant", ADMIN_AREA),
    205         LanguageTestCase("HK", "en", "en", ADMIN_AREA),
    206         LanguageTestCase("HK", "zh-latn", "zh-Latn", RECIPIENT),
    207         LanguageTestCase("HK", "fr", "zh-Latn", RECIPIENT),
    208         LanguageTestCase("HK", "ja", "zh-Latn", RECIPIENT),
    209         LanguageTestCase("HK", "ko", "zh-Latn", RECIPIENT),
    210         // Libaddressinput does not have information about extended language
    211         // subtags, so it uses the zh-Latn language tag for all base languages
    212         // that are not zh or en, even if it's effectively the same language.
    213         // Cantonese Chinese, as used in Hong Kong:
    214         LanguageTestCase("HK", "yue-HK", "zh-Latn", RECIPIENT),
    215 
    216         // Macao supports zh-Hant and pt. It has a Latin format.
    217         LanguageTestCase("MO", "zh", "zh-Hant", STREET_ADDRESS),
    218         LanguageTestCase("MO", "zh-Hant", "zh-Hant", STREET_ADDRESS),
    219         LanguageTestCase("MO", "pt", "pt", STREET_ADDRESS),
    220         LanguageTestCase("MO", "zh-Latn", "zh-Latn", RECIPIENT),
    221         LanguageTestCase("MO", "en", "zh-Latn", RECIPIENT),
    222 
    223         // Switzerland supports de, fr, and it.
    224         LanguageTestCase("CH", "de", "de", ORGANIZATION),
    225         LanguageTestCase("CH", "de-DE", "de", ORGANIZATION),
    226         LanguageTestCase("CH", "de-Latn-DE", "de", ORGANIZATION),
    227         LanguageTestCase("CH", "fr", "fr", ORGANIZATION),
    228         LanguageTestCase("CH", "it", "it", ORGANIZATION),
    229         LanguageTestCase("CH", "en", "de", ORGANIZATION),
    230 
    231         // Antarctica does not have language information.
    232         LanguageTestCase("AQ", "en", "en", RECIPIENT),
    233         LanguageTestCase("AQ", "fr", "fr", RECIPIENT),
    234         LanguageTestCase("AQ", "es", "es", RECIPIENT),
    235         LanguageTestCase("AQ", "zh-Hans", "zh-Hans", RECIPIENT),
    236 
    237         // Egypt supports ar and has a Latin format.
    238         LanguageTestCase("EG", "ar", "ar", RECIPIENT),
    239         LanguageTestCase("EG", "ar-Arab", "ar", RECIPIENT),
    240         LanguageTestCase("EG", "ar-Latn", "ar-Latn", RECIPIENT),
    241         LanguageTestCase("EG", "fr", "ar-Latn", RECIPIENT),
    242         LanguageTestCase("EG", "fa", "ar-Latn", RECIPIENT),
    243         // Libaddressinput does not have language-to-script mapping, so it uses
    244         // the ar-Latn language tag for all base languages that are not ar, even
    245         // if the script is the same.
    246         LanguageTestCase("EG", "fa-Arab", "ar-Latn", RECIPIENT)));
    247 
    248 }  // namespace
    249