1 // Copyright (C) 2013 Google Inc.
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
7 // http://www.apache.org/licenses/LICENSE-2.0
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.
17 #include <libaddressinput/address_field.h>
23 #include <gtest/gtest.h>
25 #include "region_data_constants.h"
29 using i18n::addressinput::AddressField;
30 using i18n::addressinput::ADMIN_AREA;
31 using i18n::addressinput::COUNTRY;
32 using i18n::addressinput::FormatElement;
33 using i18n::addressinput::LOCALITY;
34 using i18n::addressinput::ORGANIZATION;
35 using i18n::addressinput::POSTAL_CODE;
36 using i18n::addressinput::RECIPIENT;
37 using i18n::addressinput::RegionDataConstants;
38 using i18n::addressinput::Rule;
39 using i18n::addressinput::STREET_ADDRESS;
41 bool IsFormatEmpty(const std::vector<std::vector<FormatElement> >& format) {
42 for (std::vector<std::vector<FormatElement> >::const_iterator
53 TEST(RuleTest, CopyOverwritesRule) {
55 ASSERT_TRUE(rule.ParseSerializedRule(
59 "\"state_name_type\":\"area\","
60 "\"zip_name_type\":\"postal\","
61 "\"sub_keys\":\"CA~NY~TX\","
63 "\"languages\":\"en~fr\","
64 "\"zip\":\"\\\\d{5}([ \\\\-]\\\\d{4})?\""
68 EXPECT_NE(rule.GetFormat(), copy.GetFormat());
69 EXPECT_NE(rule.GetRequired(), copy.GetRequired());
70 EXPECT_NE(rule.GetSubKeys(), copy.GetSubKeys());
71 EXPECT_NE(rule.GetLanguages(), copy.GetLanguages());
72 EXPECT_NE(rule.GetLanguage(), copy.GetLanguage());
73 EXPECT_NE(rule.GetPostalCodeFormat(), copy.GetPostalCodeFormat());
74 EXPECT_NE(rule.GetAdminAreaNameType(),
75 copy.GetAdminAreaNameType());
76 EXPECT_NE(rule.GetPostalCodeNameType(),
77 copy.GetPostalCodeNameType());
80 EXPECT_EQ(rule.GetFormat(), copy.GetFormat());
81 EXPECT_EQ(rule.GetRequired(), copy.GetRequired());
82 EXPECT_EQ(rule.GetSubKeys(), copy.GetSubKeys());
83 EXPECT_EQ(rule.GetLanguages(), copy.GetLanguages());
84 EXPECT_EQ(rule.GetLanguage(), copy.GetLanguage());
85 EXPECT_EQ(rule.GetPostalCodeFormat(), copy.GetPostalCodeFormat());
86 EXPECT_EQ(rule.GetAdminAreaNameType(),
87 copy.GetAdminAreaNameType());
88 EXPECT_EQ(rule.GetPostalCodeNameType(),
89 copy.GetPostalCodeNameType());
92 TEST(RuleTest, ParseOverwritesRule) {
94 ASSERT_TRUE(rule.ParseSerializedRule(
98 "\"state_name_type\":\"area\","
99 "\"zip_name_type\":\"postal\","
100 "\"sub_keys\":\"CA~NY~TX\","
102 "\"languages\":\"en~fr\","
103 "\"zip\":\"\\\\d{5}([ \\\\-]\\\\d{4})?\""
105 EXPECT_FALSE(IsFormatEmpty(rule.GetFormat()));
106 EXPECT_FALSE(rule.GetRequired().empty());
107 EXPECT_FALSE(rule.GetSubKeys().empty());
108 EXPECT_FALSE(rule.GetLanguages().empty());
109 EXPECT_FALSE(rule.GetLanguage().empty());
110 EXPECT_FALSE(rule.GetPostalCodeFormat().empty());
111 EXPECT_EQ("area", rule.GetAdminAreaNameType());
112 EXPECT_EQ("postal", rule.GetPostalCodeNameType());
114 ASSERT_TRUE(rule.ParseSerializedRule(
118 "\"state_name_type\":\"do_si\","
119 "\"zip_name_type\":\"zip\","
122 "\"languages\":\"\","
125 EXPECT_TRUE(IsFormatEmpty(rule.GetFormat()));
126 EXPECT_TRUE(rule.GetRequired().empty());
127 EXPECT_TRUE(rule.GetSubKeys().empty());
128 EXPECT_TRUE(rule.GetLanguages().empty());
129 EXPECT_TRUE(rule.GetLanguage().empty());
130 EXPECT_TRUE(rule.GetPostalCodeFormat().empty());
131 EXPECT_EQ("do_si", rule.GetAdminAreaNameType());
132 EXPECT_EQ("zip", rule.GetPostalCodeNameType());
135 TEST(RuleTest, ParseEmptyDataDoesNotOverwriteRule) {
137 ASSERT_TRUE(rule.ParseSerializedRule(
140 "\"require\":\"SZ\","
141 "\"state_name_type\":\"area\","
142 "\"zip_name_type\":\"postal\","
143 "\"sub_keys\":\"CA~NY~TX\","
145 "\"languages\":\"en~fr\","
146 "\"zip\":\"\\\\d{5}([ \\\\-]\\\\d{4})?\""
151 ASSERT_TRUE(copy.ParseSerializedRule("{}"));
153 EXPECT_EQ(rule.GetFormat(), copy.GetFormat());
154 EXPECT_EQ(rule.GetRequired(), copy.GetRequired());
155 EXPECT_EQ(rule.GetSubKeys(), copy.GetSubKeys());
156 EXPECT_EQ(rule.GetLanguages(), copy.GetLanguages());
157 EXPECT_EQ(rule.GetLanguage(), copy.GetLanguage());
158 EXPECT_EQ(rule.GetPostalCodeFormat(), copy.GetPostalCodeFormat());
159 EXPECT_EQ(rule.GetAdminAreaNameType(),
160 copy.GetAdminAreaNameType());
161 EXPECT_EQ(rule.GetPostalCodeNameType(),
162 copy.GetPostalCodeNameType());
165 TEST(RuleTest, ParseFormatWithNewLines) {
168 rule.ParseSerializedRule("{\"fmt\":\"%O%n%N%n%A%nAX-%Z %C%nÅLAND\"}"));
170 std::vector<std::vector<FormatElement> > expected_format;
171 expected_format.push_back(
172 std::vector<FormatElement>(1, FormatElement(ORGANIZATION)));
173 expected_format.push_back(
174 std::vector<FormatElement>(1, FormatElement(RECIPIENT)));
175 expected_format.push_back(
176 std::vector<FormatElement>(1, FormatElement(STREET_ADDRESS)));
177 expected_format.push_back(
178 std::vector<FormatElement>(1, FormatElement("AX-")));
179 expected_format.back().push_back(FormatElement(POSTAL_CODE));
180 expected_format.back().push_back(FormatElement(" "));
181 expected_format.back().push_back(FormatElement(LOCALITY));
182 expected_format.push_back(
183 std::vector<FormatElement>(1, FormatElement("ÅLAND")));
185 EXPECT_EQ(expected_format, rule.GetFormat());
188 TEST(RuleTest, DoubleTokenPrefixDoesNotCrash) {
190 EXPECT_TRUE(rule.ParseSerializedRule("{\"fmt\":\"%%R\"}"));
193 TEST(RuleTest, DoubleNewlineFormatDoesNotCrash) {
195 EXPECT_TRUE(rule.ParseSerializedRule("{\"fmt\":\"%n%n\"}"));
198 TEST(RuleTest, FormatTokenWithoutPrefixDoesNotCrash) {
200 ASSERT_TRUE(rule.ParseSerializedRule("{\"fmt\":\"R\"}"));
203 TEST(RuleTest, ParseDuplicateTokenInFormatDoesNotCrash) {
205 EXPECT_TRUE(rule.ParseSerializedRule("{\"fmt\":\"%R%R\"}"));
208 TEST(RuleTest, ParseInvalidFormatFieldsDoesNotCrash) {
210 EXPECT_TRUE(rule.ParseSerializedRule("{\"fmt\":\"%K%L\"}"));
213 TEST(RuleTest, PrefixWithoutTokenFormatDoesNotCrash) {
215 EXPECT_TRUE(rule.ParseSerializedRule("{\"fmt\":\"%\"}"));
218 TEST(RuleTest, EmptyStringFormatDoesNotCrash) {
220 EXPECT_TRUE(rule.ParseSerializedRule("{\"fmt\":\"\"}"));
223 TEST(RuleTest, ParseRequiredFields) {
225 ASSERT_TRUE(rule.ParseSerializedRule("{\"require\":\"ONAZC\"}"));
226 std::vector<AddressField> expected;
227 expected.push_back(ORGANIZATION);
228 expected.push_back(RECIPIENT);
229 expected.push_back(STREET_ADDRESS);
230 expected.push_back(POSTAL_CODE);
231 expected.push_back(LOCALITY);
232 EXPECT_EQ(expected, rule.GetRequired());
235 TEST(RuleTest, ParseEmptyStringRequiredFields) {
237 ASSERT_TRUE(rule.ParseSerializedRule("{\"require\":\"\"}"));
238 EXPECT_TRUE(rule.GetRequired().empty());
241 TEST(RuleTest, ParseInvalidRequiredFields) {
243 ASSERT_TRUE(rule.ParseSerializedRule("{\"require\":\"garbage\"}"));
244 EXPECT_TRUE(rule.GetRequired().empty());
247 TEST(RuleTest, ParseDuplicateRequiredFields) {
249 ASSERT_TRUE(rule.ParseSerializedRule("{\"require\":\"SSS\"}"));
250 EXPECT_EQ(std::vector<AddressField>(3, ADMIN_AREA), rule.GetRequired());
253 TEST(RuleTest, ParsesSubKeysCorrectly) {
255 ASSERT_TRUE(rule.ParseSerializedRule("{\"sub_keys\":\"CA~NY~TX\"}"));
256 std::vector<std::string> expected;
257 expected.push_back("CA");
258 expected.push_back("NY");
259 expected.push_back("TX");
260 EXPECT_EQ(expected, rule.GetSubKeys());
263 TEST(RuleTest, ParsesLanguageCorrectly) {
265 ASSERT_TRUE(rule.ParseSerializedRule("{\"lang\":\"en\"}"));
266 EXPECT_EQ("en", rule.GetLanguage());
269 TEST(RuleTest, ParsesLanguagesCorrectly) {
271 ASSERT_TRUE(rule.ParseSerializedRule("{\"languages\":\"de~fr~it\"}"));
272 std::vector<std::string> expected;
273 expected.push_back("de");
274 expected.push_back("fr");
275 expected.push_back("it");
276 EXPECT_EQ(expected, rule.GetLanguages());
279 TEST(RuleTest, ParsesPostalCodeFormatCorrectly) {
281 ASSERT_TRUE(rule.ParseSerializedRule(
283 "\"zip\":\"\\\\d{5}([ \\\\-]\\\\d{4})?\""
285 EXPECT_EQ("\\d{5}([ \\-]\\d{4})?", rule.GetPostalCodeFormat());
288 TEST(RuleTest, EmptyStringIsNotValid) {
290 EXPECT_FALSE(rule.ParseSerializedRule(std::string()));
293 TEST(RuleTest, EmptyDictionaryIsValid) {
295 EXPECT_TRUE(rule.ParseSerializedRule("{}"));
298 TEST(RuleTest, ParseSubKeyTest) {
299 i18n::addressinput::Rule rule;
300 ASSERT_TRUE(rule.ParseSerializedRule(
301 "{ \"sub_keys\": \"FOO~BAR~BAZ\","
302 " \"sub_names\": \"Foolandia~Bartopolis~Bazmonia\","
303 " \"sub_lnames\": \"Foolandia2~Bartopolis2~Bazmonia2\" }"));
304 EXPECT_EQ(3U, rule.GetSubKeys().size());
307 EXPECT_TRUE(rule.CanonicalizeSubKey("BAR", false, &sub_key));
308 EXPECT_EQ("BAR", sub_key);
311 EXPECT_TRUE(rule.CanonicalizeSubKey("Bartopolis", false, &sub_key));
312 EXPECT_EQ("BAR", sub_key);
316 EXPECT_TRUE(rule.CanonicalizeSubKey("Bartopolis2", false, &sub_key));
317 EXPECT_EQ("BAR", sub_key);
321 EXPECT_TRUE(rule.CanonicalizeSubKey("Bartopolis2", true, &sub_key));
322 EXPECT_EQ("Bartopolis2", sub_key);
325 EXPECT_FALSE(rule.CanonicalizeSubKey("Beertopia", false, &sub_key));
326 EXPECT_EQ("", sub_key);
330 LabelData(const std::string& data, const std::string& name_type)
331 : data(data), name_type(name_type) {}
336 std::string name_type;
339 // Tests for parsing the postal code name.
340 class PostalCodeNameParseTest : public testing::TestWithParam<LabelData> {
345 // Verifies that a postal code name is parsed correctly.
346 TEST_P(PostalCodeNameParseTest, ParsedCorrectly) {
347 ASSERT_TRUE(rule_.ParseSerializedRule(GetParam().data));
348 EXPECT_EQ(GetParam().name_type, rule_.GetPostalCodeNameType());
351 // Test parsing all postal code names.
352 INSTANTIATE_TEST_CASE_P(
353 AllPostalCodeNames, PostalCodeNameParseTest,
355 LabelData("{\"zip_name_type\":\"postal\"}", "postal"),
356 LabelData("{\"zip_name_type\":\"zip\"}", "zip")));
358 // Tests for parsing the administrative area name.
359 class AdminAreaNameParseTest : public testing::TestWithParam<LabelData> {
364 // Verifies that an administrative area name is parsed correctly.
365 TEST_P(AdminAreaNameParseTest, ParsedCorrectly) {
366 ASSERT_TRUE(rule_.ParseSerializedRule(GetParam().data));
367 EXPECT_EQ(GetParam().name_type, rule_.GetAdminAreaNameType());
370 // Test parsing all administrative area names.
371 INSTANTIATE_TEST_CASE_P(
372 AllAdminAreaNames, AdminAreaNameParseTest,
374 LabelData("{\"state_name_type\":\"area\"}", "area"),
375 LabelData("{\"state_name_type\":\"county\"}", "county"),
376 LabelData("{\"state_name_type\":\"department\"}", "department"),
377 LabelData("{\"state_name_type\":\"district\"}", "district"),
378 LabelData("{\"state_name_type\":\"do_si\"}", "do_si"),
379 LabelData("{\"state_name_type\":\"emirate\"}", "emirate"),
380 LabelData("{\"state_name_type\":\"island\"}", "island"),
381 LabelData("{\"state_name_type\":\"parish\"}", "parish"),
382 LabelData("{\"state_name_type\":\"prefecture\"}", "prefecture"),
383 LabelData("{\"state_name_type\":\"province\"}", "province"),
384 LabelData("{\"state_name_type\":\"state\"}", "state")));
386 // Verifies that an address format does not contain consecutive lines with
387 // multiple fields each. Such address format (e.g. {{ELEMENT, ELEMENT},
388 // {ELEMENT, ELEMENT}}) will result in incorrect behavior of BuildComponents()
390 TEST(RuleParseTest, ConsecutiveLinesWithMultipleFields) {
391 const std::vector<std::string>& region_codes =
392 RegionDataConstants::GetRegionCodes();
394 for (size_t i = 0; i < region_codes.size(); ++i) {
395 const std::string& region_data =
396 RegionDataConstants::GetRegionData(region_codes[i]);
397 SCOPED_TRACE(region_codes[i] + ": " + region_data);
399 ASSERT_TRUE(rule.ParseSerializedRule(region_data));
400 bool previous_line_has_single_field = true;
401 for (std::vector<std::vector<FormatElement> >::const_iterator
402 line_it = rule.GetFormat().begin();
403 line_it != rule.GetFormat().end();
406 for (std::vector<FormatElement>::const_iterator
407 element_it = line_it->begin();
408 element_it != line_it->end();
410 if (element_it->IsField()) {
414 if (num_fields == 0) {
417 ASSERT_TRUE(num_fields == 1 || previous_line_has_single_field);
418 previous_line_has_single_field = num_fields == 1;
423 // Verifies that a street line is surrounded by either newlines or spaces. A
424 // different format will result in incorrect behavior in
425 // AddressData::BuildDisplayLines().
426 TEST(RuleParseTest, StreetAddressSurroundingElements) {
427 const std::vector<std::string>& region_codes =
428 RegionDataConstants::GetRegionCodes();
430 for (size_t i = 0; i < region_codes.size(); ++i) {
431 const std::string& region_data =
432 RegionDataConstants::GetRegionData(region_codes[i]);
433 SCOPED_TRACE(region_codes[i] + ": " + region_data);
435 ASSERT_TRUE(rule.ParseSerializedRule(region_data));
436 for (std::vector<std::vector<FormatElement> >::const_iterator
437 line_it = rule.GetFormat().begin();
438 line_it != rule.GetFormat().end();
440 for (size_t i = 0; i < line_it->size(); ++i) {
441 const FormatElement& element = line_it->at(i);
442 if (element.IsField() && element.field == STREET_ADDRESS) {
443 bool surrounded_by_newlines = line_it->size() == 1;
444 bool surrounded_by_spaces =
446 i < line_it->size() - 1 &&
447 !line_it->at(i - 1).IsField() &&
448 line_it->at(i - 1).literal == " " &&
449 !line_it->at(i + 1).IsField() &&
450 line_it->at(i + 1).literal == " ";
451 EXPECT_TRUE(surrounded_by_newlines || surrounded_by_spaces);