| OLD | NEW |
| (Empty) |
| 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 "rule.h" | |
| 16 | |
| 17 #include <libaddressinput/address_field.h> | |
| 18 | |
| 19 #include <string> | |
| 20 #include <utility> | |
| 21 #include <vector> | |
| 22 | |
| 23 #include <gtest/gtest.h> | |
| 24 | |
| 25 #include "region_data_constants.h" | |
| 26 | |
| 27 namespace { | |
| 28 | |
| 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; | |
| 40 | |
| 41 bool IsFormatEmpty(const std::vector<std::vector<FormatElement> >& format) { | |
| 42 for (std::vector<std::vector<FormatElement> >::const_iterator | |
| 43 it = format.begin(); | |
| 44 it != format.end(); | |
| 45 ++it) { | |
| 46 if (!it->empty()) { | |
| 47 return false; | |
| 48 } | |
| 49 } | |
| 50 return true; | |
| 51 } | |
| 52 | |
| 53 TEST(RuleTest, CopyOverwritesRule) { | |
| 54 Rule rule; | |
| 55 ASSERT_TRUE(rule.ParseSerializedRule( | |
| 56 "{" | |
| 57 "\"fmt\":\"%S%Z\"," | |
| 58 "\"require\":\"SZ\"," | |
| 59 "\"state_name_type\":\"area\"," | |
| 60 "\"zip_name_type\":\"postal\"," | |
| 61 "\"sub_keys\":\"CA~NY~TX\"," | |
| 62 "\"lang\":\"en\"," | |
| 63 "\"languages\":\"en~fr\"," | |
| 64 "\"zip\":\"\\\\d{5}([ \\\\-]\\\\d{4})?\"" | |
| 65 "}")); | |
| 66 | |
| 67 Rule copy; | |
| 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()); | |
| 78 | |
| 79 copy.CopyFrom(rule); | |
| 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()); | |
| 90 } | |
| 91 | |
| 92 TEST(RuleTest, ParseOverwritesRule) { | |
| 93 Rule rule; | |
| 94 ASSERT_TRUE(rule.ParseSerializedRule( | |
| 95 "{" | |
| 96 "\"fmt\":\"%S%Z\"," | |
| 97 "\"require\":\"SZ\"," | |
| 98 "\"state_name_type\":\"area\"," | |
| 99 "\"zip_name_type\":\"postal\"," | |
| 100 "\"sub_keys\":\"CA~NY~TX\"," | |
| 101 "\"lang\":\"en\"," | |
| 102 "\"languages\":\"en~fr\"," | |
| 103 "\"zip\":\"\\\\d{5}([ \\\\-]\\\\d{4})?\"" | |
| 104 "}")); | |
| 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()); | |
| 113 | |
| 114 ASSERT_TRUE(rule.ParseSerializedRule( | |
| 115 "{" | |
| 116 "\"fmt\":\"\"," | |
| 117 "\"require\":\"\"," | |
| 118 "\"state_name_type\":\"do_si\"," | |
| 119 "\"zip_name_type\":\"zip\"," | |
| 120 "\"sub_keys\":\"\"," | |
| 121 "\"lang\":\"\"," | |
| 122 "\"languages\":\"\"," | |
| 123 "\"zip\":\"\"" | |
| 124 "}")); | |
| 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()); | |
| 133 } | |
| 134 | |
| 135 TEST(RuleTest, ParseEmptyDataDoesNotOverwriteRule) { | |
| 136 Rule rule; | |
| 137 ASSERT_TRUE(rule.ParseSerializedRule( | |
| 138 "{" | |
| 139 "\"fmt\":\"%S%Z\"," | |
| 140 "\"require\":\"SZ\"," | |
| 141 "\"state_name_type\":\"area\"," | |
| 142 "\"zip_name_type\":\"postal\"," | |
| 143 "\"sub_keys\":\"CA~NY~TX\"," | |
| 144 "\"lang\":\"en\"," | |
| 145 "\"languages\":\"en~fr\"," | |
| 146 "\"zip\":\"\\\\d{5}([ \\\\-]\\\\d{4})?\"" | |
| 147 "}")); | |
| 148 | |
| 149 Rule copy; | |
| 150 copy.CopyFrom(rule); | |
| 151 ASSERT_TRUE(copy.ParseSerializedRule("{}")); | |
| 152 | |
| 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()); | |
| 163 } | |
| 164 | |
| 165 TEST(RuleTest, ParseFormatWithNewLines) { | |
| 166 Rule rule; | |
| 167 ASSERT_TRUE( | |
| 168 rule.ParseSerializedRule("{\"fmt\":\"%O%n%N%n%A%nAX-%Z %C%nÅLAND\"}")); | |
| 169 | |
| 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"))); | |
| 184 | |
| 185 EXPECT_EQ(expected_format, rule.GetFormat()); | |
| 186 } | |
| 187 | |
| 188 TEST(RuleTest, DoubleTokenPrefixDoesNotCrash) { | |
| 189 Rule rule; | |
| 190 EXPECT_TRUE(rule.ParseSerializedRule("{\"fmt\":\"%%R\"}")); | |
| 191 } | |
| 192 | |
| 193 TEST(RuleTest, DoubleNewlineFormatDoesNotCrash) { | |
| 194 Rule rule; | |
| 195 EXPECT_TRUE(rule.ParseSerializedRule("{\"fmt\":\"%n%n\"}")); | |
| 196 } | |
| 197 | |
| 198 TEST(RuleTest, FormatTokenWithoutPrefixDoesNotCrash) { | |
| 199 Rule rule; | |
| 200 ASSERT_TRUE(rule.ParseSerializedRule("{\"fmt\":\"R\"}")); | |
| 201 } | |
| 202 | |
| 203 TEST(RuleTest, ParseDuplicateTokenInFormatDoesNotCrash) { | |
| 204 Rule rule; | |
| 205 EXPECT_TRUE(rule.ParseSerializedRule("{\"fmt\":\"%R%R\"}")); | |
| 206 } | |
| 207 | |
| 208 TEST(RuleTest, ParseInvalidFormatFieldsDoesNotCrash) { | |
| 209 Rule rule; | |
| 210 EXPECT_TRUE(rule.ParseSerializedRule("{\"fmt\":\"%K%L\"}")); | |
| 211 } | |
| 212 | |
| 213 TEST(RuleTest, PrefixWithoutTokenFormatDoesNotCrash) { | |
| 214 Rule rule; | |
| 215 EXPECT_TRUE(rule.ParseSerializedRule("{\"fmt\":\"%\"}")); | |
| 216 } | |
| 217 | |
| 218 TEST(RuleTest, EmptyStringFormatDoesNotCrash) { | |
| 219 Rule rule; | |
| 220 EXPECT_TRUE(rule.ParseSerializedRule("{\"fmt\":\"\"}")); | |
| 221 } | |
| 222 | |
| 223 TEST(RuleTest, ParseRequiredFields) { | |
| 224 Rule rule; | |
| 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()); | |
| 233 } | |
| 234 | |
| 235 TEST(RuleTest, ParseEmptyStringRequiredFields) { | |
| 236 Rule rule; | |
| 237 ASSERT_TRUE(rule.ParseSerializedRule("{\"require\":\"\"}")); | |
| 238 EXPECT_TRUE(rule.GetRequired().empty()); | |
| 239 } | |
| 240 | |
| 241 TEST(RuleTest, ParseInvalidRequiredFields) { | |
| 242 Rule rule; | |
| 243 ASSERT_TRUE(rule.ParseSerializedRule("{\"require\":\"garbage\"}")); | |
| 244 EXPECT_TRUE(rule.GetRequired().empty()); | |
| 245 } | |
| 246 | |
| 247 TEST(RuleTest, ParseDuplicateRequiredFields) { | |
| 248 Rule rule; | |
| 249 ASSERT_TRUE(rule.ParseSerializedRule("{\"require\":\"SSS\"}")); | |
| 250 EXPECT_EQ(std::vector<AddressField>(3, ADMIN_AREA), rule.GetRequired()); | |
| 251 } | |
| 252 | |
| 253 TEST(RuleTest, ParsesSubKeysCorrectly) { | |
| 254 Rule rule; | |
| 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()); | |
| 261 } | |
| 262 | |
| 263 TEST(RuleTest, ParsesLanguageCorrectly) { | |
| 264 Rule rule; | |
| 265 ASSERT_TRUE(rule.ParseSerializedRule("{\"lang\":\"en\"}")); | |
| 266 EXPECT_EQ("en", rule.GetLanguage()); | |
| 267 } | |
| 268 | |
| 269 TEST(RuleTest, ParsesLanguagesCorrectly) { | |
| 270 Rule rule; | |
| 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()); | |
| 277 } | |
| 278 | |
| 279 TEST(RuleTest, ParsesPostalCodeFormatCorrectly) { | |
| 280 Rule rule; | |
| 281 ASSERT_TRUE(rule.ParseSerializedRule( | |
| 282 "{" | |
| 283 "\"zip\":\"\\\\d{5}([ \\\\-]\\\\d{4})?\"" | |
| 284 "}")); | |
| 285 EXPECT_EQ("\\d{5}([ \\-]\\d{4})?", rule.GetPostalCodeFormat()); | |
| 286 } | |
| 287 | |
| 288 TEST(RuleTest, EmptyStringIsNotValid) { | |
| 289 Rule rule; | |
| 290 EXPECT_FALSE(rule.ParseSerializedRule(std::string())); | |
| 291 } | |
| 292 | |
| 293 TEST(RuleTest, EmptyDictionaryIsValid) { | |
| 294 Rule rule; | |
| 295 EXPECT_TRUE(rule.ParseSerializedRule("{}")); | |
| 296 } | |
| 297 | |
| 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()); | |
| 305 | |
| 306 std::string sub_key; | |
| 307 EXPECT_TRUE(rule.CanonicalizeSubKey("BAR", false, &sub_key)); | |
| 308 EXPECT_EQ("BAR", sub_key); | |
| 309 sub_key.clear(); | |
| 310 | |
| 311 EXPECT_TRUE(rule.CanonicalizeSubKey("Bartopolis", false, &sub_key)); | |
| 312 EXPECT_EQ("BAR", sub_key); | |
| 313 sub_key.clear(); | |
| 314 | |
| 315 // Unlatinize. | |
| 316 EXPECT_TRUE(rule.CanonicalizeSubKey("Bartopolis2", false, &sub_key)); | |
| 317 EXPECT_EQ("BAR", sub_key); | |
| 318 sub_key.clear(); | |
| 319 | |
| 320 // Keep input latin. | |
| 321 EXPECT_TRUE(rule.CanonicalizeSubKey("Bartopolis2", true, &sub_key)); | |
| 322 EXPECT_EQ("Bartopolis2", sub_key); | |
| 323 sub_key.clear(); | |
| 324 | |
| 325 EXPECT_FALSE(rule.CanonicalizeSubKey("Beertopia", false, &sub_key)); | |
| 326 EXPECT_EQ("", sub_key); | |
| 327 } | |
| 328 | |
| 329 struct LabelData { | |
| 330 LabelData(const std::string& data, const std::string& name_type) | |
| 331 : data(data), name_type(name_type) {} | |
| 332 | |
| 333 ~LabelData() {} | |
| 334 | |
| 335 std::string data; | |
| 336 std::string name_type; | |
| 337 }; | |
| 338 | |
| 339 // Tests for parsing the postal code name. | |
| 340 class PostalCodeNameParseTest : public testing::TestWithParam<LabelData> { | |
| 341 protected: | |
| 342 Rule rule_; | |
| 343 }; | |
| 344 | |
| 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()); | |
| 349 } | |
| 350 | |
| 351 // Test parsing all postal code names. | |
| 352 INSTANTIATE_TEST_CASE_P( | |
| 353 AllPostalCodeNames, PostalCodeNameParseTest, | |
| 354 testing::Values( | |
| 355 LabelData("{\"zip_name_type\":\"postal\"}", "postal"), | |
| 356 LabelData("{\"zip_name_type\":\"zip\"}", "zip"))); | |
| 357 | |
| 358 // Tests for parsing the administrative area name. | |
| 359 class AdminAreaNameParseTest : public testing::TestWithParam<LabelData> { | |
| 360 protected: | |
| 361 Rule rule_; | |
| 362 }; | |
| 363 | |
| 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()); | |
| 368 } | |
| 369 | |
| 370 // Test parsing all administrative area names. | |
| 371 INSTANTIATE_TEST_CASE_P( | |
| 372 AllAdminAreaNames, AdminAreaNameParseTest, | |
| 373 testing::Values( | |
| 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"))); | |
| 385 | |
| 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() | |
| 389 // public API. | |
| 390 TEST(RuleParseTest, ConsecutiveLinesWithMultipleFields) { | |
| 391 const std::vector<std::string>& region_codes = | |
| 392 RegionDataConstants::GetRegionCodes(); | |
| 393 Rule rule; | |
| 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); | |
| 398 | |
| 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(); | |
| 404 ++line_it) { | |
| 405 int num_fields = 0; | |
| 406 for (std::vector<FormatElement>::const_iterator | |
| 407 element_it = line_it->begin(); | |
| 408 element_it != line_it->end(); | |
| 409 ++element_it) { | |
| 410 if (element_it->IsField()) { | |
| 411 ++num_fields; | |
| 412 } | |
| 413 } | |
| 414 if (num_fields == 0) { | |
| 415 continue; | |
| 416 } | |
| 417 ASSERT_TRUE(num_fields == 1 || previous_line_has_single_field); | |
| 418 previous_line_has_single_field = num_fields == 1; | |
| 419 } | |
| 420 } | |
| 421 } | |
| 422 | |
| 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(); | |
| 429 Rule rule; | |
| 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); | |
| 434 | |
| 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(); | |
| 439 ++line_it) { | |
| 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 = | |
| 445 i > 0 && | |
| 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); | |
| 452 } | |
| 453 } | |
| 454 } | |
| 455 } | |
| 456 } | |
| 457 | |
| 458 } // namespace | |
| OLD | NEW |