blob: b151f3f96496cda21816b33842443d6a9266a908 [file] [log] [blame]
Adam Lesinskif90f2f8d2014-06-06 14:27:00 -07001/*
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
Adam Lesinski4c67a472016-11-10 16:43:59 -080017#include "androidfw/ResourceTypes.h"
Adam Lesinskif90f2f8d2014-06-06 14:27:00 -070018
Dan Albert1b4f3162015-04-07 18:43:15 -070019#include <codecvt>
20#include <locale>
21#include <string>
22
Adam Lesinski4c67a472016-11-10 16:43:59 -080023#include "utils/String16.h"
24#include "utils/String8.h"
25
Adam Lesinskif90f2f8d2014-06-06 14:27:00 -070026#include "TestHelpers.h"
Adam Lesinskiccf25c7b2014-08-08 15:32:40 -070027#include "data/basic/R.h"
28#include "data/lib/R.h"
Adam Lesinskif90f2f8d2014-06-06 14:27:00 -070029
Adam Lesinski4c67a472016-11-10 16:43:59 -080030namespace basic = com::android::basic;
31namespace lib = com::android::lib;
Adam Lesinskif90f2f8d2014-06-06 14:27:00 -070032
Adam Lesinski4c67a472016-11-10 16:43:59 -080033namespace android {
Adam Lesinskif90f2f8d2014-06-06 14:27:00 -070034
Adam Lesinski4c67a472016-11-10 16:43:59 -080035TEST(ResTableTest, ShouldLoadSuccessfully) {
36 std::string contents;
37 ASSERT_TRUE(ReadFileFromZipToString(GetTestDataPath() + "/basic/basic.apk",
38 "resources.arsc", &contents));
Adam Lesinskif90f2f8d2014-06-06 14:27:00 -070039
Adam Lesinski4c67a472016-11-10 16:43:59 -080040 ResTable table;
41 ASSERT_EQ(NO_ERROR, table.add(contents.data(), contents.size()));
Adam Lesinskif90f2f8d2014-06-06 14:27:00 -070042}
43
Adam Lesinski4c67a472016-11-10 16:43:59 -080044TEST(ResTableTest, SimpleTypeIsRetrievedCorrectly) {
45 std::string contents;
46 ASSERT_TRUE(ReadFileFromZipToString(GetTestDataPath() + "/basic/basic.apk",
47 "resources.arsc", &contents));
Adam Lesinskif90f2f8d2014-06-06 14:27:00 -070048
Adam Lesinski4c67a472016-11-10 16:43:59 -080049 ResTable table;
50 ASSERT_EQ(NO_ERROR, table.add(contents.data(), contents.size()));
51
52 EXPECT_TRUE(IsStringEqual(table, basic::R::string::test1, "test1"));
Adam Lesinskif90f2f8d2014-06-06 14:27:00 -070053}
54
Adam Lesinski4c67a472016-11-10 16:43:59 -080055TEST(ResTableTest, ResourceNameIsResolved) {
56 std::string contents;
57 ASSERT_TRUE(ReadFileFromZipToString(GetTestDataPath() + "/basic/basic.apk",
58 "resources.arsc", &contents));
Adam Lesinskif90f2f8d2014-06-06 14:27:00 -070059
Adam Lesinski4c67a472016-11-10 16:43:59 -080060 ResTable table;
61 ASSERT_EQ(NO_ERROR, table.add(contents.data(), contents.size()));
62
63 String16 defPackage("com.android.basic");
64 String16 testName("@string/test1");
65 uint32_t resID =
66 table.identifierForName(testName.string(), testName.size(), 0, 0,
67 defPackage.string(), defPackage.size());
68 ASSERT_NE(uint32_t(0x00000000), resID);
69 ASSERT_EQ(basic::R::string::test1, resID);
Adam Lesinskif90f2f8d2014-06-06 14:27:00 -070070}
71
Adam Lesinski4c67a472016-11-10 16:43:59 -080072TEST(ResTableTest, NoParentThemeIsAppliedCorrectly) {
73 std::string contents;
74 ASSERT_TRUE(ReadFileFromZipToString(GetTestDataPath() + "/basic/basic.apk",
75 "resources.arsc", &contents));
Adam Lesinskif90f2f8d2014-06-06 14:27:00 -070076
Adam Lesinski4c67a472016-11-10 16:43:59 -080077 ResTable table;
78 ASSERT_EQ(NO_ERROR, table.add(contents.data(), contents.size()));
Adam Lesinskif90f2f8d2014-06-06 14:27:00 -070079
Adam Lesinski4c67a472016-11-10 16:43:59 -080080 ResTable::Theme theme(table);
81 ASSERT_EQ(NO_ERROR, theme.applyStyle(basic::R::style::Theme1));
Adam Lesinskif90f2f8d2014-06-06 14:27:00 -070082
Adam Lesinski4c67a472016-11-10 16:43:59 -080083 Res_value val;
84 uint32_t specFlags = 0;
85 ssize_t index = theme.getAttribute(basic::R::attr::attr1, &val, &specFlags);
86 ASSERT_GE(index, 0);
87 ASSERT_EQ(Res_value::TYPE_INT_DEC, val.dataType);
88 ASSERT_EQ(uint32_t(100), val.data);
89
90 index = theme.getAttribute(basic::R::attr::attr2, &val, &specFlags);
91 ASSERT_GE(index, 0);
92 ASSERT_EQ(Res_value::TYPE_REFERENCE, val.dataType);
93 ASSERT_EQ(basic::R::integer::number1, val.data);
Adam Lesinskif90f2f8d2014-06-06 14:27:00 -070094}
95
Adam Lesinski4c67a472016-11-10 16:43:59 -080096TEST(ResTableTest, ParentThemeIsAppliedCorrectly) {
97 std::string contents;
98 ASSERT_TRUE(ReadFileFromZipToString(GetTestDataPath() + "/basic/basic.apk",
99 "resources.arsc", &contents));
Adam Lesinskif90f2f8d2014-06-06 14:27:00 -0700100
Adam Lesinski4c67a472016-11-10 16:43:59 -0800101 ResTable table;
102 ASSERT_EQ(NO_ERROR, table.add(contents.data(), contents.size()));
Adam Lesinskif90f2f8d2014-06-06 14:27:00 -0700103
Adam Lesinski4c67a472016-11-10 16:43:59 -0800104 ResTable::Theme theme(table);
105 ASSERT_EQ(NO_ERROR, theme.applyStyle(basic::R::style::Theme2));
Adam Lesinskif90f2f8d2014-06-06 14:27:00 -0700106
Adam Lesinski4c67a472016-11-10 16:43:59 -0800107 Res_value val;
108 uint32_t specFlags = 0;
109 ssize_t index = theme.getAttribute(basic::R::attr::attr1, &val, &specFlags);
110 ASSERT_GE(index, 0);
111 ASSERT_EQ(Res_value::TYPE_INT_DEC, val.dataType);
112 ASSERT_EQ(uint32_t(300), val.data);
113
114 index = theme.getAttribute(basic::R::attr::attr2, &val, &specFlags);
115 ASSERT_GE(index, 0);
116 ASSERT_EQ(Res_value::TYPE_REFERENCE, val.dataType);
117 ASSERT_EQ(basic::R::integer::number1, val.data);
Adam Lesinskiccf25c7b2014-08-08 15:32:40 -0700118}
119
Adam Lesinski4c67a472016-11-10 16:43:59 -0800120TEST(ResTableTest, LibraryThemeIsAppliedCorrectly) {
121 std::string contents;
122 ASSERT_TRUE(ReadFileFromZipToString(GetTestDataPath() + "/lib/lib.apk",
123 "resources.arsc", &contents));
Adam Lesinskiccf25c7b2014-08-08 15:32:40 -0700124
Adam Lesinski4c67a472016-11-10 16:43:59 -0800125 ResTable table;
126 ASSERT_EQ(NO_ERROR, table.add(contents.data(), contents.size()));
Adam Lesinskiccf25c7b2014-08-08 15:32:40 -0700127
Adam Lesinski4c67a472016-11-10 16:43:59 -0800128 ResTable::Theme theme(table);
129 ASSERT_EQ(NO_ERROR, theme.applyStyle(lib::R::style::Theme));
Adam Lesinski8ac51d12016-05-10 10:01:12 -0700130
Adam Lesinski4c67a472016-11-10 16:43:59 -0800131 Res_value val;
132 uint32_t specFlags = 0;
133 ssize_t index = theme.getAttribute(lib::R::attr::attr1, &val, &specFlags);
134 ASSERT_GE(index, 0);
135 ASSERT_EQ(Res_value::TYPE_INT_DEC, val.dataType);
136 ASSERT_EQ(uint32_t(700), val.data);
137
138 index = theme.getAttribute(lib::R::attr::attr2, &val, &specFlags);
139 ASSERT_GE(index, 0);
140 ASSERT_EQ(Res_value::TYPE_INT_DEC, val.dataType);
141 ASSERT_EQ(uint32_t(700), val.data);
Adam Lesinskif90f2f8d2014-06-06 14:27:00 -0700142}
143
Adam Lesinski4c67a472016-11-10 16:43:59 -0800144TEST(ResTableTest, ReferenceToBagIsNotResolved) {
145 std::string contents;
146 ASSERT_TRUE(ReadFileFromZipToString(GetTestDataPath() + "/basic/basic.apk",
147 "resources.arsc", &contents));
Adam Lesinskif90f2f8d2014-06-06 14:27:00 -0700148
Adam Lesinski4c67a472016-11-10 16:43:59 -0800149 ResTable table;
150 ASSERT_EQ(NO_ERROR, table.add(contents.data(), contents.size()));
Adam Lesinskif90f2f8d2014-06-06 14:27:00 -0700151
Adam Lesinski4c67a472016-11-10 16:43:59 -0800152 Res_value val;
153 ssize_t block =
154 table.getResource(basic::R::integer::number2, &val, MAY_NOT_BE_BAG);
155 ASSERT_GE(block, 0);
156 ASSERT_EQ(Res_value::TYPE_REFERENCE, val.dataType);
157 ASSERT_EQ(basic::R::array::integerArray1, val.data);
158
159 ssize_t newBlock = table.resolveReference(&val, block);
160 EXPECT_EQ(block, newBlock);
161 EXPECT_EQ(Res_value::TYPE_REFERENCE, val.dataType);
162 EXPECT_EQ(basic::R::array::integerArray1, val.data);
Adam Lesinskif90f2f8d2014-06-06 14:27:00 -0700163}
164
Adam Lesinski4c67a472016-11-10 16:43:59 -0800165TEST(ResTableTest, ResourcesStillAccessibleAfterParameterChange) {
166 std::string contents;
167 ASSERT_TRUE(ReadFileFromZipToString(GetTestDataPath() + "/basic/basic.apk",
168 "resources.arsc", &contents));
Adam Lesinskif90f2f8d2014-06-06 14:27:00 -0700169
Adam Lesinski4c67a472016-11-10 16:43:59 -0800170 ResTable table;
171 ASSERT_EQ(NO_ERROR, table.add(contents.data(), contents.size()));
Adam Lesinskif90f2f8d2014-06-06 14:27:00 -0700172
Adam Lesinski4c67a472016-11-10 16:43:59 -0800173 Res_value val;
174 ssize_t block =
175 table.getResource(basic::R::integer::number1, &val, MAY_NOT_BE_BAG);
176 ASSERT_GE(block, 0);
177 ASSERT_EQ(Res_value::TYPE_INT_DEC, val.dataType);
Adam Lesinskif90f2f8d2014-06-06 14:27:00 -0700178
Adam Lesinski4c67a472016-11-10 16:43:59 -0800179 const ResTable::bag_entry* entry;
180 ssize_t count = table.lockBag(basic::R::array::integerArray1, &entry);
181 ASSERT_GE(count, 0);
182 table.unlockBag(entry);
Adam Lesinskif90f2f8d2014-06-06 14:27:00 -0700183
Adam Lesinski4c67a472016-11-10 16:43:59 -0800184 ResTable_config param;
185 memset(&param, 0, sizeof(param));
186 param.density = 320;
187 table.setParameters(&param);
Adam Lesinskif90f2f8d2014-06-06 14:27:00 -0700188
Adam Lesinski4c67a472016-11-10 16:43:59 -0800189 block = table.getResource(basic::R::integer::number1, &val, MAY_NOT_BE_BAG);
190 ASSERT_GE(block, 0);
191 ASSERT_EQ(Res_value::TYPE_INT_DEC, val.dataType);
192
193 count = table.lockBag(basic::R::array::integerArray1, &entry);
194 ASSERT_GE(count, 0);
195 table.unlockBag(entry);
Adam Lesinskif90f2f8d2014-06-06 14:27:00 -0700196}
197
Adam Lesinski4c67a472016-11-10 16:43:59 -0800198TEST(ResTableTest, ResourceIsOverridenWithBetterConfig) {
199 std::string contents;
200 ASSERT_TRUE(ReadFileFromZipToString(GetTestDataPath() + "/basic/basic.apk",
201 "resources.arsc", &contents));
Adam Lesinskif90f2f8d2014-06-06 14:27:00 -0700202
Adam Lesinski4c67a472016-11-10 16:43:59 -0800203 ResTable table;
204 ASSERT_EQ(NO_ERROR, table.add(contents.data(), contents.size()));
Adam Lesinskif90f2f8d2014-06-06 14:27:00 -0700205
Adam Lesinski4c67a472016-11-10 16:43:59 -0800206 Res_value val;
207 ssize_t block =
208 table.getResource(basic::R::integer::number1, &val, MAY_NOT_BE_BAG);
209 ASSERT_GE(block, 0);
210 ASSERT_EQ(Res_value::TYPE_INT_DEC, val.dataType);
211 ASSERT_EQ(uint32_t(200), val.data);
Adam Lesinskif90f2f8d2014-06-06 14:27:00 -0700212
Adam Lesinski4c67a472016-11-10 16:43:59 -0800213 ResTable_config param;
214 memset(&param, 0, sizeof(param));
215 param.language[0] = 's';
216 param.language[1] = 'v';
217 param.country[0] = 'S';
218 param.country[1] = 'E';
219 table.setParameters(&param);
220
221 block = table.getResource(basic::R::integer::number1, &val, MAY_NOT_BE_BAG);
222 ASSERT_GE(block, 0);
223 ASSERT_EQ(Res_value::TYPE_INT_DEC, val.dataType);
224 ASSERT_EQ(uint32_t(400), val.data);
Adam Lesinskif90f2f8d2014-06-06 14:27:00 -0700225}
226
Adam Lesinski2cb761e2014-08-15 13:59:02 -0700227TEST(ResTableTest, emptyTableHasSensibleDefaults) {
Adam Lesinski4c67a472016-11-10 16:43:59 -0800228 const int32_t assetCookie = 1;
Adam Lesinski2cb761e2014-08-15 13:59:02 -0700229
Adam Lesinski4c67a472016-11-10 16:43:59 -0800230 ResTable table;
231 ASSERT_EQ(NO_ERROR, table.addEmpty(assetCookie));
Adam Lesinski2cb761e2014-08-15 13:59:02 -0700232
Adam Lesinski4c67a472016-11-10 16:43:59 -0800233 // Adding an empty table gives us one table!
234 ASSERT_EQ(uint32_t(1), table.getTableCount());
Adam Lesinski2cb761e2014-08-15 13:59:02 -0700235
Adam Lesinski4c67a472016-11-10 16:43:59 -0800236 // Adding an empty table doesn't mean we get packages.
237 ASSERT_EQ(uint32_t(0), table.getBasePackageCount());
Adam Lesinski2cb761e2014-08-15 13:59:02 -0700238
Adam Lesinski4c67a472016-11-10 16:43:59 -0800239 Res_value val;
240 ASSERT_LT(table.getResource(basic::R::integer::number1, &val, MAY_NOT_BE_BAG),
241 0);
Adam Lesinski2cb761e2014-08-15 13:59:02 -0700242}
243
Dan Albert1b4f3162015-04-07 18:43:15 -0700244void testU16StringToInt(const char16_t* str, uint32_t expectedValue,
245 bool expectSuccess, bool expectHex) {
Adam Lesinski4c67a472016-11-10 16:43:59 -0800246 size_t len = std::char_traits<char16_t>::length(str);
Dan Albert1b4f3162015-04-07 18:43:15 -0700247
Adam Lesinski4c67a472016-11-10 16:43:59 -0800248 // Gtest can't print UTF-16 strings, so we have to convert to UTF-8 :(
249 std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> convert;
250 std::string s = convert.to_bytes(std::u16string(str, len));
Dan Albert1b4f3162015-04-07 18:43:15 -0700251
Adam Lesinski4c67a472016-11-10 16:43:59 -0800252 Res_value out = {};
253 ASSERT_EQ(expectSuccess, U16StringToInt(str, len, &out)) << "Failed with "
254 << s;
Dan Albert1b4f3162015-04-07 18:43:15 -0700255
Adam Lesinski4c67a472016-11-10 16:43:59 -0800256 if (!expectSuccess) {
257 ASSERT_EQ(out.TYPE_NULL, out.dataType) << "Failed with " << s;
258 return;
259 }
Dan Albert1b4f3162015-04-07 18:43:15 -0700260
Adam Lesinski4c67a472016-11-10 16:43:59 -0800261 if (expectHex) {
262 ASSERT_EQ(out.TYPE_INT_HEX, out.dataType) << "Failed with " << s;
263 } else {
264 ASSERT_EQ(out.TYPE_INT_DEC, out.dataType) << "Failed with " << s;
265 }
Dan Albert1b4f3162015-04-07 18:43:15 -0700266
Adam Lesinski4c67a472016-11-10 16:43:59 -0800267 ASSERT_EQ(expectedValue, out.data) << "Failed with " << s;
Dan Albert1b4f3162015-04-07 18:43:15 -0700268}
269
270TEST(ResTableTest, U16StringToInt) {
Adam Lesinski4c67a472016-11-10 16:43:59 -0800271 testU16StringToInt(u"", 0U, false, false);
272 testU16StringToInt(u" ", 0U, false, false);
273 testU16StringToInt(u"\t\n", 0U, false, false);
Dan Albert1b4f3162015-04-07 18:43:15 -0700274
Adam Lesinski4c67a472016-11-10 16:43:59 -0800275 testU16StringToInt(u"abcd", 0U, false, false);
276 testU16StringToInt(u"10abcd", 0U, false, false);
277 testU16StringToInt(u"42 42", 0U, false, false);
278 testU16StringToInt(u"- 42", 0U, false, false);
279 testU16StringToInt(u"-", 0U, false, false);
Dan Albert1b4f3162015-04-07 18:43:15 -0700280
Adam Lesinski4c67a472016-11-10 16:43:59 -0800281 testU16StringToInt(u"0x", 0U, false, true);
282 testU16StringToInt(u"0xnope", 0U, false, true);
283 testU16StringToInt(u"0X42", 0U, false, true);
284 testU16StringToInt(u"0x42 0x42", 0U, false, true);
285 testU16StringToInt(u"-0x0", 0U, false, true);
286 testU16StringToInt(u"-0x42", 0U, false, true);
287 testU16StringToInt(u"- 0x42", 0U, false, true);
Dan Albert1b4f3162015-04-07 18:43:15 -0700288
Adam Lesinski4c67a472016-11-10 16:43:59 -0800289 // Note that u" 42" would pass. This preserves the old behavior, but it may
290 // not be desired.
291 testU16StringToInt(u"42 ", 0U, false, false);
292 testU16StringToInt(u"0x42 ", 0U, false, true);
Dan Albert1b4f3162015-04-07 18:43:15 -0700293
Adam Lesinski4c67a472016-11-10 16:43:59 -0800294 // Decimal cases.
295 testU16StringToInt(u"0", 0U, true, false);
296 testU16StringToInt(u"-0", 0U, true, false);
297 testU16StringToInt(u"42", 42U, true, false);
298 testU16StringToInt(u" 42", 42U, true, false);
299 testU16StringToInt(u"-42", static_cast<uint32_t>(-42), true, false);
300 testU16StringToInt(u" -42", static_cast<uint32_t>(-42), true, false);
301 testU16StringToInt(u"042", 42U, true, false);
302 testU16StringToInt(u"-042", static_cast<uint32_t>(-42), true, false);
Dan Albert1b4f3162015-04-07 18:43:15 -0700303
Adam Lesinski4c67a472016-11-10 16:43:59 -0800304 // Hex cases.
305 testU16StringToInt(u"0x0", 0x0, true, true);
306 testU16StringToInt(u"0x42", 0x42, true, true);
307 testU16StringToInt(u" 0x42", 0x42, true, true);
Dan Albert1b4f3162015-04-07 18:43:15 -0700308
Adam Lesinski4c67a472016-11-10 16:43:59 -0800309 // Just before overflow cases:
310 testU16StringToInt(u"2147483647", INT_MAX, true, false);
311 testU16StringToInt(u"-2147483648", static_cast<uint32_t>(INT_MIN), true,
312 false);
313 testU16StringToInt(u"0xffffffff", UINT_MAX, true, true);
Dan Albert1b4f3162015-04-07 18:43:15 -0700314
Adam Lesinski4c67a472016-11-10 16:43:59 -0800315 // Overflow cases:
316 testU16StringToInt(u"2147483648", 0U, false, false);
317 testU16StringToInt(u"-2147483649", 0U, false, false);
318 testU16StringToInt(u"0x1ffffffff", 0U, false, true);
Dan Albert1b4f3162015-04-07 18:43:15 -0700319}
320
Adam Lesinskiff5808d2016-02-23 17:49:53 -0800321TEST(ResTableTest, ShareButDontModifyResTable) {
Adam Lesinski4c67a472016-11-10 16:43:59 -0800322 std::string contents;
323 ASSERT_TRUE(ReadFileFromZipToString(GetTestDataPath() + "/basic/basic.apk",
324 "resources.arsc", &contents));
Adam Lesinskiff5808d2016-02-23 17:49:53 -0800325
Adam Lesinski4c67a472016-11-10 16:43:59 -0800326 ResTable sharedTable;
327 ASSERT_EQ(NO_ERROR, sharedTable.add(contents.data(), contents.size()));
Adam Lesinskiff5808d2016-02-23 17:49:53 -0800328
Adam Lesinski4c67a472016-11-10 16:43:59 -0800329 ResTable_config param;
330 memset(&param, 0, sizeof(param));
331 param.language[0] = 'v';
332 param.language[1] = 's';
333 sharedTable.setParameters(&param);
Adam Lesinskiff5808d2016-02-23 17:49:53 -0800334
Adam Lesinski4c67a472016-11-10 16:43:59 -0800335 // Check that we get the default value for @integer:number1
336 Res_value val;
337 ssize_t block =
338 sharedTable.getResource(basic::R::integer::number1, &val, MAY_NOT_BE_BAG);
339 ASSERT_GE(block, 0);
340 ASSERT_EQ(Res_value::TYPE_INT_DEC, val.dataType);
341 ASSERT_EQ(uint32_t(600), val.data);
Adam Lesinskiff5808d2016-02-23 17:49:53 -0800342
Adam Lesinski4c67a472016-11-10 16:43:59 -0800343 // Create a new table that shares the entries of the shared table.
344 ResTable table;
345 ASSERT_EQ(NO_ERROR, table.add(&sharedTable, false));
Adam Lesinskiff5808d2016-02-23 17:49:53 -0800346
Adam Lesinski4c67a472016-11-10 16:43:59 -0800347 // Set a new configuration on the new table.
348 memset(&param, 0, sizeof(param));
349 param.language[0] = 's';
350 param.language[1] = 'v';
351 param.country[0] = 'S';
352 param.country[1] = 'E';
353 table.setParameters(&param);
Adam Lesinskiff5808d2016-02-23 17:49:53 -0800354
Adam Lesinski4c67a472016-11-10 16:43:59 -0800355 // Check that we get a new value in the new table.
356 block = table.getResource(basic::R::integer::number1, &val, MAY_NOT_BE_BAG);
357 ASSERT_GE(block, 0);
358 ASSERT_EQ(Res_value::TYPE_INT_DEC, val.dataType);
359 ASSERT_EQ(uint32_t(400), val.data);
360
361 // Check that we still get the old value in the shared table.
362 block =
363 sharedTable.getResource(basic::R::integer::number1, &val, MAY_NOT_BE_BAG);
364 ASSERT_GE(block, 0);
365 ASSERT_EQ(Res_value::TYPE_INT_DEC, val.dataType);
366 ASSERT_EQ(uint32_t(600), val.data);
Adam Lesinskif90f2f8d2014-06-06 14:27:00 -0700367}
Adam Lesinskiff5808d2016-02-23 17:49:53 -0800368
Adam Lesinskib7e1ce02016-04-11 20:03:01 -0700369TEST(ResTableTest, GetConfigurationsReturnsUniqueList) {
Adam Lesinski4c67a472016-11-10 16:43:59 -0800370 std::string contents;
371 ASSERT_TRUE(ReadFileFromZipToString(GetTestDataPath() + "/basic/basic.apk",
372 "resources.arsc", &contents));
Adam Lesinskib7e1ce02016-04-11 20:03:01 -0700373
Adam Lesinski4c67a472016-11-10 16:43:59 -0800374 std::string system_contents;
375 ASSERT_TRUE(ReadFileFromZipToString(GetTestDataPath() + "/system/system.apk",
376 "resources.arsc", &system_contents));
Adam Lesinskib7e1ce02016-04-11 20:03:01 -0700377
Adam Lesinski4c67a472016-11-10 16:43:59 -0800378 ResTable table;
379 ASSERT_EQ(NO_ERROR,
380 table.add(system_contents.data(), system_contents.size()));
381 ASSERT_EQ(NO_ERROR, table.add(contents.data(), contents.size()));
Adam Lesinskib7e1ce02016-04-11 20:03:01 -0700382
Adam Lesinski4c67a472016-11-10 16:43:59 -0800383 ResTable_config configSv;
384 memset(&configSv, 0, sizeof(configSv));
385 configSv.language[0] = 's';
386 configSv.language[1] = 'v';
Adam Lesinskib7e1ce02016-04-11 20:03:01 -0700387
Adam Lesinski4c67a472016-11-10 16:43:59 -0800388 Vector<ResTable_config> configs;
389 table.getConfigurations(&configs);
Adam Lesinskib7e1ce02016-04-11 20:03:01 -0700390
Adam Lesinski4c67a472016-11-10 16:43:59 -0800391 EXPECT_EQ(1, std::count(configs.begin(), configs.end(), configSv));
392
393 Vector<String8> locales;
394 table.getLocales(&locales);
395
396 EXPECT_EQ(1, std::count(locales.begin(), locales.end(), String8("sv")));
Adam Lesinskib7e1ce02016-04-11 20:03:01 -0700397}
398
Adam Lesinski4c67a472016-11-10 16:43:59 -0800399} // namespace android