Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / third_party / libaddressinput / src / cpp / test / address_input_helper_test.cc
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_input_helper.h>
16
17 #include <libaddressinput/address_data.h>
18 #include <libaddressinput/callback.h>
19 #include <libaddressinput/null_storage.h>
20 #include <libaddressinput/preload_supplier.h>
21 #include <libaddressinput/util/basictypes.h>
22 #include <libaddressinput/util/scoped_ptr.h>
23
24 #include <string>
25 #include <utility>
26
27 #include <gtest/gtest.h>
28
29 #include "mock_source.h"
30 #include "testdata_source.h"
31
32 namespace {
33
34 using i18n::addressinput::AddressData;
35 using i18n::addressinput::AddressInputHelper;
36 using i18n::addressinput::BuildCallback;
37 using i18n::addressinput::Callback;
38 using i18n::addressinput::MockSource;
39 using i18n::addressinput::NullStorage;
40 using i18n::addressinput::PreloadSupplier;
41 using i18n::addressinput::scoped_ptr;
42 using i18n::addressinput::TestdataSource;
43
44 class AddressInputHelperTest : public testing::Test {
45  protected:
46   AddressInputHelperTest()
47       // Our PreloadSupplier loads all data for a country at a time.
48       : supplier_(new TestdataSource(true), new NullStorage),
49         address_input_helper_(&supplier_),
50         loaded_(BuildCallback(this, &AddressInputHelperTest::Loaded)) {}
51
52   ~AddressInputHelperTest() {}
53
54   // Helper method to test FillAddress that ensures the PreloadSupplier has the
55   // necessary data preloaded.
56   void FillAddress(AddressData* address) {
57     const std::string& region_code = address->region_code;
58     if (!region_code.empty()) {
59       supplier_.LoadRules(region_code, *loaded_);
60     }
61     address_input_helper_.FillAddress(address);
62   }
63
64  private:
65   // Used to preload data that we need.
66   void Loaded(bool success, const std::string&, int) { ASSERT_TRUE(success); }
67
68   PreloadSupplier supplier_;
69   const AddressInputHelper address_input_helper_;
70   const scoped_ptr<const PreloadSupplier::Callback> loaded_;
71   DISALLOW_COPY_AND_ASSIGN(AddressInputHelperTest);
72 };
73
74 TEST_F(AddressInputHelperTest, AddressWithMissingPostalCode) {
75   AddressData address;
76   address.region_code = "CX";
77   address.administrative_area = "WA";
78
79   // There is only one postal code for Christmas Island
80   AddressData expected = address;
81   expected.postal_code = "6798";
82   FillAddress(&address);
83   EXPECT_EQ(expected, address);
84 }
85
86 TEST_F(AddressInputHelperTest, AddressWithPostalCodeMatchingAdmin) {
87   AddressData address;
88   address.region_code = "US";
89   address.postal_code = "58098";
90   // Other data should be left alone.
91   address.address_line.push_back("10 High St");
92
93   // North Dakota has post codes starting with 58.
94   AddressData expected = address;
95   expected.administrative_area = "ND";
96   FillAddress(&address);
97   EXPECT_EQ(expected, address);
98
99   address.administrative_area = "CA";  // Override the admin area.
100   // Now, since the admin area was already filled in, we don't fix it, even
101   // though it was correct.
102   expected.administrative_area = "CA";
103   FillAddress(&address);
104   EXPECT_EQ(expected, address);
105 }
106
107 TEST_F(AddressInputHelperTest, AddressWithPostalCodeMatchingLowerLevel) {
108   AddressData address;
109   address.region_code = "TW";
110   address.postal_code = "53012";
111
112   /* This matches 二水鄉 - Ershuei Township. */
113   AddressData expected = address;
114   /* This locality is in 彰化縣 - Changhua County. */
115   expected.administrative_area = "\xE5\xBD\xB0\xE5\x8C\x96\xE7\xB8\xA3";
116   expected.locality = "\xE4\xBA\x8C\xE6\xB0\xB4\xE9\x84\x89";
117   FillAddress(&address);
118   EXPECT_EQ(expected, address);
119
120   // Override the admin area.
121   address.administrative_area = "Already filled in";
122   expected.administrative_area = "Already filled in";
123   address.locality = "";
124   // However, the locality will still be filled in.
125   FillAddress(&address);
126   EXPECT_EQ(expected, address);
127 }
128
129 TEST_F(AddressInputHelperTest, AddressWithPostalCodeMatchingLowerLevelLatin) {
130   AddressData address;
131   address.region_code = "TW";
132   address.postal_code = "53012";
133   address.language_code = "zh-Latn";
134
135   /* This matches 二水鄉 - Ershuei Township. */
136   AddressData expected = address;
137   /* This locality is in 彰化縣 - Changhua County. */
138   expected.locality = "Ershuei Township";
139   expected.administrative_area = "Changhua County";
140   FillAddress(&address);
141   EXPECT_EQ(expected, address);
142
143   // Override the admin area.
144   address.administrative_area = "Already filled in";
145   expected.administrative_area = "Already filled in";
146   address.locality = "";
147   // However, the locality will still be filled in.
148   FillAddress(&address);
149   EXPECT_EQ(expected, address);
150 }
151
152 TEST_F(AddressInputHelperTest, AddressWithPostalCodeMatchingDependentLocality) {
153   AddressData address;
154   address.region_code = "KR";
155   // This matches Danwon-gu district.
156   address.postal_code = "425-111";
157
158   AddressData expected = address;
159   /* The province is Gyeonggi - 경기도. */
160   expected.administrative_area = "\xEA\xB2\xBD\xEA\xB8\xB0\xEB\x8F\x84";
161   /* The city is Ansan-si - 안산시. */
162   expected.locality = "\xEC\x95\x88\xEC\x82\xB0\xEC\x8B\x9C";
163   /* The district is Danwon-gu - 단원구 */
164   expected.dependent_locality = "\xEB\x8B\xA8\xEC\x9B\x90\xEA\xB5\xAC";
165
166   FillAddress(&address);
167   EXPECT_EQ(expected, address);
168
169   AddressData address_ko_latn;
170   address_ko_latn.region_code = "KR";
171   address_ko_latn.postal_code = "425-111";
172   address_ko_latn.language_code = "ko-latn";
173
174   expected = address_ko_latn;
175   /* The province is Gyeonggi - 경기도. */
176   expected.administrative_area = "Gyeonggi";
177   /* The city is Ansan-si - 안산시. */
178   expected.locality = "Ansan-si";
179   /* The district is Danwon-gu - 단원구 */
180   expected.dependent_locality = "Danwon-gu";
181
182   FillAddress(&address_ko_latn);
183   EXPECT_EQ(expected, address_ko_latn);
184 }
185
186 TEST_F(AddressInputHelperTest, AddressWithPostalCodeMatchingMultipleValues) {
187   AddressData address;
188   address.region_code = "KR";
189   // This matches Wando-gun and Ganjin-gun, both in Jeonnam province.
190   address.postal_code = "527-111";
191
192   AddressData expected = address;
193   /* The province, Jeonnam - 전라남도 - is known, but we have several locality
194    * matches so none of them are populated. */
195   expected.administrative_area =
196       "\xEC\xA0\x84\xEB\x9D\xBC\xEB\x82\xA8\xEB\x8F\x84";
197   FillAddress(&address);
198   EXPECT_EQ(expected, address);
199 }
200
201 TEST_F(AddressInputHelperTest, AddressWithInvalidPostalCode) {
202   AddressData address;
203   address.postal_code = "970";
204   address.region_code = "US";
205
206   // We don't expect any changes, since the postal code couldn't be determined
207   // as valid.
208   AddressData expected = address;
209   FillAddress(&address);
210   EXPECT_EQ(expected, address);
211 }
212
213 TEST_F(AddressInputHelperTest, AddressWithNoPostalCodeValidation) {
214   AddressData address;
215   address.postal_code = "123";
216   address.region_code = "GA";
217
218   // We don't expect any changes, since the postal code couldn't be determined
219   // as valid - we have no information about postal codes in Gabon (or even that
220   // they are in use).
221   AddressData expected = address;
222   FillAddress(&address);
223   EXPECT_EQ(expected, address);
224 }
225
226 TEST_F(AddressInputHelperTest, AddressWithInvalidOrMissingRegionCode) {
227   AddressData address;
228   address.postal_code = "XXX";
229   address.administrative_area = "YYY";
230
231   // We don't expect any changes, since there was no region code.
232   AddressData expected = address;
233   FillAddress(&address);
234   EXPECT_EQ(expected, address);
235
236   address.region_code = "XXXX";
237   expected.region_code = "XXXX";
238   // Again, nothing should change.
239   FillAddress(&address);
240   EXPECT_EQ(expected, address);
241 }
242
243 class AddressInputHelperMockDataTest : public testing::Test {
244  protected:
245   AddressInputHelperMockDataTest()
246       : source_(new MockSource),
247         // Our PreloadSupplier loads all data for a country at a time.
248         supplier_(source_, new NullStorage),
249         address_input_helper_(&supplier_),
250         loaded_(BuildCallback(this, &AddressInputHelperMockDataTest::Loaded)) {}
251
252   ~AddressInputHelperMockDataTest() {}
253
254   // Helper method to test FillAddress that ensures the PreloadSupplier has the
255   // necessary data preloaded.
256   void FillAddress(AddressData* address) {
257     const std::string& region_code = address->region_code;
258     if (!region_code.empty()) {
259       supplier_.LoadRules(region_code, *loaded_);
260     }
261     address_input_helper_.FillAddress(address);
262   }
263
264   MockSource* const source_;
265
266  private:
267   // Our mock source we assume will always succeed.
268   void Loaded(bool success, const std::string&, int) { ASSERT_TRUE(success); }
269
270   PreloadSupplier supplier_;
271   const AddressInputHelper address_input_helper_;
272   const scoped_ptr<const PreloadSupplier::Callback> loaded_;
273   DISALLOW_COPY_AND_ASSIGN(AddressInputHelperMockDataTest);
274 };
275
276 TEST_F(AddressInputHelperMockDataTest,
277        PostalCodeSharedAcrossDifferentHierarchies) {
278   // Note that this data is in the format of data that would be returned from
279   // the aggregate server.
280   source_->data_.insert(std::make_pair(
281       // We use KR since we need a country where we format all fields down to
282       // dependent locality, or the hierarchy won't be loaded.
283       "data/KR",
284       "{\"data/KR\": "
285       // The top-level ZIP expression must be present for sub-key matches to be
286       // evaluated.
287       "{\"id\":\"data/KR\", \"sub_keys\":\"A~B\", \"zip\":\"\\\\d{5}\"}, "
288       "\"data/KR/A\": "
289       "{\"id\":\"data/KR/A\", \"sub_keys\":\"A1\"}, "
290       "\"data/KR/A/A1\": "
291       "{\"id\":\"data/KR/A/A1\", \"zip\":\"1\"}, "
292       "\"data/KR/B\": "
293       "{\"id\":\"data/KR/B\", \"sub_keys\":\"B1\"}, "
294       "\"data/KR/B/B1\": "
295       "{\"id\":\"data/KR/B/B1\", \"zip\":\"12\"}}"));
296
297   AddressData address;
298   address.region_code = "KR";
299   address.postal_code = "12345";
300   address.administrative_area = "";
301
302   AddressData expected = address;
303   FillAddress(&address);
304   // Nothing should have changed, since the ZIP code matches both of the cities,
305   // and they aren't even in the same state.
306   EXPECT_EQ(expected, address);
307 }
308
309 TEST_F(AddressInputHelperMockDataTest,
310        PostalCodeSharedAcrossDifferentHierarchiesSameState) {
311   // Create data where one state matches the ZIP code, but the other doesn't:
312   // within the state which does, multiple cities and sub-cities match. The only
313   // thing we can be certain of is therefore the state.
314   source_->data_.insert(std::make_pair(
315       // We use KR since we need a country where we format all fields down to
316       // dependent locality, or the hierarchy won't be loaded.
317       "data/KR",
318       "{\"data/KR\": "
319       // The top-level ZIP expression must be present for sub-key matches to be
320       // evaluated.
321       "{\"id\":\"data/KR\", \"sub_keys\":\"A~B\", \"zip\":\"\\\\d{5}\"}, "
322       "\"data/KR/A\": "
323       "{\"id\":\"data/KR/A\", \"sub_keys\":\"A1~A2\"}, "
324       "\"data/KR/A/A1\": "
325       "{\"id\":\"data/KR/A/A1\", \"sub_keys\":\"A1a\", \"zip\":\"1\"}, "
326       // This key matches the ZIP code.
327       "\"data/KR/A/A1/A1a\": "
328       "{\"id\":\"data/KR/A/A1/A1a\", \"zip\":\"12\"}, "
329       "\"data/KR/A/A2\": "
330       "{\"id\":\"data/KR/A/A2\", \"sub_keys\":\"A2a\", \"zip\":\"1\"}, "
331       // This key, also in state A, but in city A2, matches the ZIP code.
332       "\"data/KR/A/A2/A2a\": "
333       "{\"id\":\"data/KR/A/A2/A2a\", \"zip\":\"123\"}, "
334       // This key, in state B, does not match the ZIP code.
335       "\"data/KR/B\": "
336       "{\"id\":\"data/KR/B\", \"zip\":\"2\"}}"));
337
338   AddressData address;
339   address.region_code = "KR";
340   address.postal_code = "12345";
341   address.administrative_area = "";
342
343   AddressData expected = address;
344   expected.administrative_area = "A";
345   FillAddress(&address);
346   // The ZIP code matches multiple city districts and cities; but only one
347   // state, so we fill this in.
348   EXPECT_EQ(expected, address);
349 }
350
351 }  // namespace