1/*
2 * Copyright (C) 2014 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include <androidfw/ResourceTypes.h>
18#include <utils/Log.h>
19#include <utils/String8.h>
20
21#include <gtest/gtest.h>
22namespace android {
23
24TEST(ConfigLocaleTest, packAndUnpack2LetterLanguage) {
25     ResTable_config config;
26     config.packLanguage("en");
27
28     EXPECT_EQ('e', config.language[0]);
29     EXPECT_EQ('n', config.language[1]);
30
31     char out[4] = { 1, 1, 1, 1};
32     config.unpackLanguage(out);
33     EXPECT_EQ('e', out[0]);
34     EXPECT_EQ('n', out[1]);
35     EXPECT_EQ(0, out[2]);
36     EXPECT_EQ(0, out[3]);
37
38     memset(out, 1, sizeof(out));
39     config.locale = 0;
40     config.unpackLanguage(out);
41     EXPECT_EQ(0, out[0]);
42     EXPECT_EQ(0, out[1]);
43     EXPECT_EQ(0, out[2]);
44     EXPECT_EQ(0, out[3]);
45}
46
47TEST(ConfigLocaleTest, packAndUnpack2LetterRegion) {
48     ResTable_config config;
49     config.packRegion("US");
50
51     EXPECT_EQ('U', config.country[0]);
52     EXPECT_EQ('S', config.country[1]);
53
54     char out[4] = { 1, 1, 1, 1};
55     config.unpackRegion(out);
56     EXPECT_EQ('U', out[0]);
57     EXPECT_EQ('S', out[1]);
58     EXPECT_EQ(0, out[2]);
59     EXPECT_EQ(0, out[3]);
60}
61
62TEST(ConfigLocaleTest, packAndUnpack3LetterLanguage) {
63     ResTable_config config;
64     config.packLanguage("eng");
65
66     // 1-00110-01 101-00100
67     EXPECT_EQ('\x99', config.language[0]);
68     EXPECT_EQ('\xA4', config.language[1]);
69
70     char out[4] = { 1, 1, 1, 1};
71     config.unpackLanguage(out);
72     EXPECT_EQ('e', out[0]);
73     EXPECT_EQ('n', out[1]);
74     EXPECT_EQ('g', out[2]);
75     EXPECT_EQ(0, out[3]);
76}
77
78TEST(ConfigLocaleTest, packAndUnpack3LetterLanguageAtOffset16) {
79     ResTable_config config;
80     config.packLanguage("tgp");
81
82     // We had a bug where we would accidentally mask
83     // the 5th bit of both bytes
84     //
85     // packed[0] = 1011 1100
86     // packed[1] = 1101 0011
87     //
88     // which is equivalent to:
89     // 1  [0]   [1]   [2]
90     // 1-01111-00110-10011
91     EXPECT_EQ(char(0xbc), config.language[0]);
92     EXPECT_EQ(char(0xd3), config.language[1]);
93
94     char out[4] = { 1, 1, 1, 1};
95     config.unpackLanguage(out);
96     EXPECT_EQ('t', out[0]);
97     EXPECT_EQ('g', out[1]);
98     EXPECT_EQ('p', out[2]);
99     EXPECT_EQ(0, out[3]);
100}
101
102TEST(ConfigLocaleTest, packAndUnpack3LetterRegion) {
103     ResTable_config config;
104     config.packRegion("419");
105
106     char out[4] = { 1, 1, 1, 1};
107     config.unpackRegion(out);
108
109     EXPECT_EQ('4', out[0]);
110     EXPECT_EQ('1', out[1]);
111     EXPECT_EQ('9', out[2]);
112}
113
114/* static */ void fillIn(const char* lang, const char* country,
115        const char* script, const char* variant, ResTable_config* out) {
116     memset(out, 0, sizeof(ResTable_config));
117     if (lang != NULL) {
118         out->packLanguage(lang);
119     }
120
121     if (country != NULL) {
122         out->packRegion(country);
123     }
124
125     if (script != NULL) {
126         memcpy(out->localeScript, script, 4);
127     }
128
129     if (variant != NULL) {
130         memcpy(out->localeVariant, variant, strlen(variant));
131     }
132}
133
134TEST(ConfigLocaleTest, IsMoreSpecificThan) {
135    ResTable_config l;
136    ResTable_config r;
137
138    fillIn("en", NULL, NULL, NULL, &l);
139    fillIn(NULL, NULL, NULL, NULL, &r);
140
141    EXPECT_TRUE(l.isMoreSpecificThan(r));
142    EXPECT_FALSE(r.isMoreSpecificThan(l));
143
144    fillIn("eng", NULL, NULL, NULL, &l);
145    EXPECT_TRUE(l.isMoreSpecificThan(r));
146    EXPECT_FALSE(r.isMoreSpecificThan(l));
147
148    fillIn("eng", "419", NULL, NULL, &r);
149    EXPECT_FALSE(l.isMoreSpecificThan(r));
150    EXPECT_TRUE(r.isMoreSpecificThan(l));
151
152    fillIn("en", NULL, NULL, NULL, &l);
153    fillIn("en", "US", NULL, NULL, &r);
154    EXPECT_FALSE(l.isMoreSpecificThan(r));
155    EXPECT_TRUE(r.isMoreSpecificThan(l));
156
157    fillIn("en", "US", NULL, NULL, &l);
158    fillIn("en", "US", "Latn", NULL, &r);
159    EXPECT_FALSE(l.isMoreSpecificThan(r));
160    EXPECT_TRUE(r.isMoreSpecificThan(l));
161
162    fillIn("en", "US", NULL, NULL, &l);
163    fillIn("en", "US", NULL, "POSIX", &r);
164    EXPECT_FALSE(l.isMoreSpecificThan(r));
165    EXPECT_TRUE(r.isMoreSpecificThan(l));
166
167    fillIn("en", "US", "Latn", NULL, &l);
168    fillIn("en", "US", NULL, "POSIX", &r);
169    EXPECT_FALSE(l.isMoreSpecificThan(r));
170    EXPECT_TRUE(r.isMoreSpecificThan(l));
171}
172
173TEST(ConfigLocaleTest, setLocale) {
174    ResTable_config test;
175    test.setBcp47Locale("en-US");
176    EXPECT_EQ('e', test.language[0]);
177    EXPECT_EQ('n', test.language[1]);
178    EXPECT_EQ('U', test.country[0]);
179    EXPECT_EQ('S', test.country[1]);
180    EXPECT_EQ(0, test.localeScript[0]);
181    EXPECT_EQ(0, test.localeVariant[0]);
182
183    test.setBcp47Locale("eng-419");
184    char out[4] = { 1, 1, 1, 1};
185    test.unpackLanguage(out);
186    EXPECT_EQ('e', out[0]);
187    EXPECT_EQ('n', out[1]);
188    EXPECT_EQ('g', out[2]);
189    EXPECT_EQ(0, out[3]);
190    memset(out, 1, 4);
191    test.unpackRegion(out);
192    EXPECT_EQ('4', out[0]);
193    EXPECT_EQ('1', out[1]);
194    EXPECT_EQ('9', out[2]);
195
196
197    test.setBcp47Locale("en-Latn-419");
198    memset(out, 1, 4);
199    EXPECT_EQ('e', test.language[0]);
200    EXPECT_EQ('n', test.language[1]);
201
202    EXPECT_EQ(0, memcmp("Latn", test.localeScript, 4));
203    test.unpackRegion(out);
204    EXPECT_EQ('4', out[0]);
205    EXPECT_EQ('1', out[1]);
206    EXPECT_EQ('9', out[2]);
207}
208
209}  // namespace android.
210