1 /*
2 * Copyright (C) 2017 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 "Util.h"
18
19 #include "android-base/stringprintf.h"
20
21 #include "AppInfo.h"
22 #include "split/TableSplitter.h"
23 #include "test/Builders.h"
24 #include "test/Test.h"
25 #include "util/Files.h"
26
27 using ::android::ConfigDescription;
28 using testing::Pair;
29 using testing::UnorderedElementsAre;
30
31 namespace aapt {
32
33 #ifdef _WIN32
34 #define CREATE_PATH(path) android::base::StringPrintf(";%s", path)
35 #else
36 #define CREATE_PATH(path) android::base::StringPrintf(":%s", path)
37 #endif
38
39 #define EXPECT_CONFIG_EQ(constraints, config) \
40 EXPECT_EQ(constraints.configs.size(), 1); \
41 EXPECT_EQ(*constraints.configs.begin(), config); \
42 constraints.configs.clear();
43
TEST(UtilTest,SplitNamesAreSanitized)44 TEST(UtilTest, SplitNamesAreSanitized) {
45 AppInfo app_info{"com.pkg"};
46 SplitConstraints split_constraints{
47 {test::ParseConfigOrDie("en-rUS-land"), test::ParseConfigOrDie("b+sr+Latn")}};
48
49 const auto doc = GenerateSplitManifest(app_info, split_constraints);
50 const auto &root = doc->root;
51 EXPECT_EQ(root->name, "manifest");
52 // split names cannot contain hyphens or plus signs.
53 EXPECT_EQ(root->FindAttribute("", "split")->value, "config.b_sr_Latn_en_rUS_land");
54 // but we should use resource qualifiers verbatim in 'targetConfig'.
55 EXPECT_EQ(root->FindAttribute("", "targetConfig")->value, "b+sr+Latn,en-rUS-land");
56 }
57
TEST(UtilTest,LongVersionCodeDefined)58 TEST (UtilTest, LongVersionCodeDefined) {
59 auto doc = test::BuildXmlDom(R"(
60 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
61 package="com.android.aapt.test" android:versionCode="0x1" android:versionCodeMajor="0x1">
62 </manifest>)");
63 SetLongVersionCode(doc->root.get(), 42);
64
65 auto version_code = doc->root->FindAttribute(xml::kSchemaAndroid, "versionCode");
66 ASSERT_NE(version_code, nullptr);
67 EXPECT_EQ(version_code->value, "0x0000002a");
68
69 ASSERT_NE(version_code->compiled_value, nullptr);
70 auto compiled_version_code = ValueCast<BinaryPrimitive>(version_code->compiled_value.get());
71 ASSERT_NE(compiled_version_code, nullptr);
72 EXPECT_EQ(compiled_version_code->value.data, 42U);
73
74 auto version_code_major = doc->root->FindAttribute(xml::kSchemaAndroid, "versionCodeMajor");
75 EXPECT_EQ(version_code_major, nullptr);
76 }
77
78 TEST (UtilTest, LongVersionCodeUndefined) {
79 auto doc = test::BuildXmlDom(R"(
80 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
81 package="com.android.aapt.test">
82 </manifest>)");
83 SetLongVersionCode(doc->root.get(), 420000000000);
84
85 auto version_code = doc->root->FindAttribute(xml::kSchemaAndroid, "versionCode");
86 ASSERT_NE(version_code, nullptr);
87 EXPECT_EQ(version_code->value, "0xc9f36800");
88
89 ASSERT_NE(version_code->compiled_value, nullptr);
90 auto compiled_version_code = ValueCast<BinaryPrimitive>(version_code->compiled_value.get());
91 ASSERT_NE(compiled_version_code, nullptr);
92 EXPECT_EQ(compiled_version_code->value.data, 0xc9f36800);
93
94 auto version_code_major = doc->root->FindAttribute(xml::kSchemaAndroid, "versionCodeMajor");
95 ASSERT_NE(version_code_major, nullptr);
96 EXPECT_EQ(version_code_major->value, "0x00000061");
97
98 ASSERT_NE(version_code_major->compiled_value, nullptr);
99 auto compiled_version_code_major = ValueCast<BinaryPrimitive>(
100 version_code_major->compiled_value.get());
101 ASSERT_NE(compiled_version_code_major, nullptr);
102 EXPECT_EQ(compiled_version_code_major->value.data, 0x61);
103 }
104
105
106 TEST (UtilTest, ParseSplitParameters) {
107 android::IDiagnostics* diagnostics = test::ContextBuilder().Build().get()->GetDiagnostics();
108 std::string path;
109 SplitConstraints constraints;
110 ConfigDescription expected_configuration;
111
112 // ========== Test IMSI ==========
113 // mcc: 'mcc[0-9]{3}'
114 // mnc: 'mnc[0-9]{1,3}'
115 ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("mcc310"),
116 diagnostics, &path, &constraints));
117 expected_configuration = test::ConfigDescriptionBuilder()
118 .setMcc(0x0136)
119 .Build();
120 EXPECT_CONFIG_EQ(constraints, expected_configuration);
121
122 ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("mcc310-mnc004"),
123 diagnostics, &path, &constraints));
124 expected_configuration = test::ConfigDescriptionBuilder()
125 .setMcc(0x0136)
126 .setMnc(0x0004)
127 .Build();
128 EXPECT_CONFIG_EQ(constraints, expected_configuration);
129
130 ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("mcc310-mnc000"),
131 diagnostics, &path, &constraints));
132 expected_configuration = test::ConfigDescriptionBuilder()
133 .setMcc(0x0136)
134 .setMnc(0xFFFF)
135 .Build();
136 EXPECT_CONFIG_EQ(constraints, expected_configuration);
137
138 // ========== Test LOCALE ==========
139 // locale: '[a-z]{2,3}(-r[a-z]{2})?'
140 // locale: 'b+[a-z]{2,3}(+[a-z[0-9]]{2})?'
141 ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("es"),
142 diagnostics, &path, &constraints));
143 expected_configuration = test::ConfigDescriptionBuilder()
144 .setLanguage(0x6573)
145 .Build();
146 EXPECT_CONFIG_EQ(constraints, expected_configuration);
147
148 ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("fr-rCA"),
149 diagnostics, &path, &constraints));
150 expected_configuration = test::ConfigDescriptionBuilder()
151 .setLanguage(0x6672)
152 .setCountry(0x4341)
153 .Build();
154 EXPECT_CONFIG_EQ(constraints, expected_configuration);
155
156 ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("b+es+419"),
157 diagnostics, &path, &constraints));
158 expected_configuration = test::ConfigDescriptionBuilder()
159 .setLanguage(0x6573)
160 .setCountry(0xA424)
161 .Build();
162 EXPECT_CONFIG_EQ(constraints, expected_configuration);
163
164 // ========== Test SCREEN_TYPE ==========
165 // orientation: '(port|land|square)'
166 // touchscreen: '(notouch|stylus|finger)'
167 // density" '(anydpi|nodpi|ldpi|mdpi|tvdpi|hdpi|xhdpi|xxhdpi|xxxhdpi|[0-9]*dpi)'
168 ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("square"),
169 diagnostics, &path, &constraints));
170 expected_configuration = test::ConfigDescriptionBuilder()
171 .setOrientation(0x03)
172 .Build();
173 EXPECT_CONFIG_EQ(constraints, expected_configuration);
174
175 ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("stylus"),
176 diagnostics, &path, &constraints));
177 expected_configuration = test::ConfigDescriptionBuilder()
178 .setTouchscreen(0x02)
179 .Build();
180 EXPECT_CONFIG_EQ(constraints, expected_configuration);
181
182 ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("xxxhdpi"),
183 diagnostics, &path, &constraints));
184 expected_configuration = test::ConfigDescriptionBuilder()
185 .setDensity(0x0280)
186 .setSdkVersion(0x0004) // version [any density requires donut]
187 .Build();
188 EXPECT_CONFIG_EQ(constraints, expected_configuration);
189
190 ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("land-xhdpi-finger"),
191 diagnostics, &path, &constraints));
192 expected_configuration = test::ConfigDescriptionBuilder()
193 .setOrientation(0x02)
194 .setTouchscreen(0x03)
195 .setDensity(0x0140)
196 .setSdkVersion(0x0004) // version [any density requires donut]
197 .Build();
198 EXPECT_CONFIG_EQ(constraints, expected_configuration);
199
200 // ========== Test INPUT ==========
201 // keyboard: '(nokeys|qwerty|12key)'
202 // navigation: '(nonav|dpad|trackball|wheel)'
203 // inputFlags: '(keysexposed|keyshidden|keyssoft)'
204 // inputFlags: '(navexposed|navhidden)'
205 ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("qwerty"),
206 diagnostics, &path, &constraints));
207 expected_configuration = test::ConfigDescriptionBuilder()
208 .setKeyboard(0x02)
209 .Build();
210 EXPECT_CONFIG_EQ(constraints, expected_configuration);
211
212 ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("dpad"),
213 diagnostics, &path, &constraints));
214 expected_configuration = test::ConfigDescriptionBuilder()
215 .setNavigation(0x02)
216 .Build();
217 EXPECT_CONFIG_EQ(constraints, expected_configuration);
218
219 ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("keyssoft-navhidden"),
220 diagnostics, &path, &constraints));
221 expected_configuration = test::ConfigDescriptionBuilder()
222 .setInputFlags(0x0B)
223 .Build();
224 EXPECT_CONFIG_EQ(constraints, expected_configuration);
225
226 ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("keyshidden-nokeys-navexposed-trackball"),
227 diagnostics, &path, &constraints));
228 expected_configuration = test::ConfigDescriptionBuilder()
229 .setKeyboard(0x01)
230 .setNavigation(0x03)
231 .setInputFlags(0x06)
232 .Build();
233 EXPECT_CONFIG_EQ(constraints, expected_configuration);
234
235 // ========== Test SCREEN_SIZE ==========
236 // screenWidth/screenHeight: '[0-9]+x[0-9]+'
237 ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("1920x1080"),
238 diagnostics, &path, &constraints));
239 expected_configuration = test::ConfigDescriptionBuilder()
240 .setScreenWidth(0x0780)
241 .setScreenHeight(0x0438)
242 .Build();
243 EXPECT_CONFIG_EQ(constraints, expected_configuration);
244
245 // ========== Test VERSION ==========
246 // version 'v[0-9]+'
247
248 // ========== Test SCREEN_CONFIG ==========
249 // screenLayout [direction]: '(ldltr|ldrtl)'
250 // screenLayout [size]: '(small|normal|large|xlarge)'
251 // screenLayout [long]: '(long|notlong)'
252 // uiMode [type]: '(desk|car|television|appliance|watch|vrheadset)'
253 // uiMode [night]: '(night|notnight)'
254 // smallestScreenWidthDp: 'sw[0-9]dp'
255 ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("ldrtl"),
256 diagnostics, &path, &constraints));
257 expected_configuration = test::ConfigDescriptionBuilder()
258 .setScreenLayout(0x80)
259 .Build();
260 EXPECT_CONFIG_EQ(constraints, expected_configuration);
261
262 ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("small"),
263 diagnostics, &path, &constraints));
264 expected_configuration = test::ConfigDescriptionBuilder()
265 .setScreenLayout(0x01)
266 .setSdkVersion(0x0004) // screenLayout (size) requires donut
267 .Build();
268 EXPECT_CONFIG_EQ(constraints, expected_configuration);
269
270 ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("notlong"),
271 diagnostics, &path, &constraints));
272 expected_configuration = test::ConfigDescriptionBuilder()
273 .setScreenLayout(0x10)
274 .setSdkVersion(0x0004) // screenLayout (long) requires donut
275 .Build();
276 EXPECT_CONFIG_EQ(constraints, expected_configuration);
277
278 ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("ldltr-normal-long"),
279 diagnostics, &path, &constraints));
280 expected_configuration = test::ConfigDescriptionBuilder()
281 .setScreenLayout(0x62)
282 .setSdkVersion(0x0004) // screenLayout (size|long) requires donut
283 .Build();
284 EXPECT_CONFIG_EQ(constraints, expected_configuration);
285
286 ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("car"),
287 diagnostics, &path, &constraints));
288 expected_configuration = test::ConfigDescriptionBuilder()
289 .setUiMode(0x03)
290 .setSdkVersion(0x0008) // uiMode requires froyo
291 .Build();
292 EXPECT_CONFIG_EQ(constraints, expected_configuration);
293
294 ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("vrheadset"),
295 diagnostics, &path, &constraints));
296 expected_configuration = test::ConfigDescriptionBuilder()
297 .setUiMode(0x07)
298 .setSdkVersion(0x001A) // uiMode 'vrheadset' requires oreo
299 .Build();
300 EXPECT_CONFIG_EQ(constraints, expected_configuration);
301
302 ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("television-night"),
303 diagnostics, &path, &constraints));
304 expected_configuration = test::ConfigDescriptionBuilder()
305 .setUiMode(0x24)
306 .setSdkVersion(0x0008) // uiMode requires froyo
307 .Build();
308 EXPECT_CONFIG_EQ(constraints, expected_configuration);
309
310 ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("sw1920dp"),
311 diagnostics, &path, &constraints));
312 expected_configuration = test::ConfigDescriptionBuilder()
313 .setSmallestScreenWidthDp(0x0780)
314 .setSdkVersion(0x000D) // smallestScreenWidthDp requires honeycomb mr2
315 .Build();
316 EXPECT_CONFIG_EQ(constraints, expected_configuration);
317
318 // ========== Test SCREEN_SIZE_DP ==========
319 // screenWidthDp: 'w[0-9]dp'
320 // screenHeightDp: 'h[0-9]dp'
321 ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("w1920dp"),
322 diagnostics, &path, &constraints));
323 expected_configuration = test::ConfigDescriptionBuilder()
324 .setScreenWidthDp(0x0780)
325 .setSdkVersion(0x000D) // screenWidthDp requires honeycomb mr2
326 .Build();
327 EXPECT_CONFIG_EQ(constraints, expected_configuration);
328
329 ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("h1080dp"),
330 diagnostics, &path, &constraints));
331 expected_configuration = test::ConfigDescriptionBuilder()
332 .setScreenHeightDp(0x0438)
333 .setSdkVersion(0x000D) // screenHeightDp requires honeycomb mr2
334 .Build();
335 EXPECT_CONFIG_EQ(constraints, expected_configuration);
336
337 // ========== Test SCREEN_CONFIG_2 ==========
338 // screenLayout2: '(round|notround)'
339 // colorMode: '(widecg|nowidecg)'
340 // colorMode: '(highhdr|lowdr)'
341 ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("round"),
342 diagnostics, &path, &constraints));
343 expected_configuration = test::ConfigDescriptionBuilder()
344 .setScreenLayout2(0x02)
345 .setSdkVersion(0x0017) // screenLayout2 (round) requires marshmallow
346 .Build();
347 EXPECT_CONFIG_EQ(constraints, expected_configuration);
348
349 ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("widecg-highdr"),
350 diagnostics, &path, &constraints));
351 expected_configuration = test::ConfigDescriptionBuilder()
352 .setColorMode(0x0A)
353 .setSdkVersion(0x001A) // colorMode (hdr|colour gamut) requires oreo
354 .Build();
355 EXPECT_CONFIG_EQ(constraints, expected_configuration);
356 }
357
TEST(UtilTest,ParseFeatureFlagsParameter_Empty)358 TEST(UtilTest, ParseFeatureFlagsParameter_Empty) {
359 auto diagnostics = test::ContextBuilder().Build()->GetDiagnostics();
360 FeatureFlagValues feature_flag_values;
361 ASSERT_TRUE(ParseFeatureFlagsParameter("", diagnostics, &feature_flag_values));
362 EXPECT_TRUE(feature_flag_values.empty());
363 }
364
TEST(UtilTest,ParseFeatureFlagsParameter_TooManyParts)365 TEST(UtilTest, ParseFeatureFlagsParameter_TooManyParts) {
366 auto diagnostics = test::ContextBuilder().Build()->GetDiagnostics();
367 FeatureFlagValues feature_flag_values;
368 ASSERT_FALSE(ParseFeatureFlagsParameter("foo=bar=baz", diagnostics, &feature_flag_values));
369 }
370
TEST(UtilTest,ParseFeatureFlagsParameter_NoNameGiven)371 TEST(UtilTest, ParseFeatureFlagsParameter_NoNameGiven) {
372 auto diagnostics = test::ContextBuilder().Build()->GetDiagnostics();
373 FeatureFlagValues feature_flag_values;
374 ASSERT_FALSE(ParseFeatureFlagsParameter("foo=true,=false", diagnostics, &feature_flag_values));
375 }
376
TEST(UtilTest,ParseFeatureFlagsParameter_InvalidValue)377 TEST(UtilTest, ParseFeatureFlagsParameter_InvalidValue) {
378 auto diagnostics = test::ContextBuilder().Build()->GetDiagnostics();
379 FeatureFlagValues feature_flag_values;
380 ASSERT_FALSE(ParseFeatureFlagsParameter("foo=true,bar=42", diagnostics, &feature_flag_values));
381 }
382
TEST(UtilTest,ParseFeatureFlagsParameter_DuplicateFlag)383 TEST(UtilTest, ParseFeatureFlagsParameter_DuplicateFlag) {
384 auto diagnostics = test::ContextBuilder().Build()->GetDiagnostics();
385 FeatureFlagValues feature_flag_values;
386 ASSERT_TRUE(ParseFeatureFlagsParameter("foo=true,bar:READ_WRITE=true,foo:ro=false", diagnostics,
387 &feature_flag_values));
388 EXPECT_THAT(
389 feature_flag_values,
390 UnorderedElementsAre(Pair("foo", FeatureFlagProperties{true, std::optional<bool>(false)}),
391 Pair("bar", FeatureFlagProperties{false, std::optional<bool>(true)})));
392 }
393
TEST(UtilTest,ParseFeatureFlagsParameter_Valid)394 TEST(UtilTest, ParseFeatureFlagsParameter_Valid) {
395 auto diagnostics = test::ContextBuilder().Build()->GetDiagnostics();
396 FeatureFlagValues feature_flag_values;
397 ASSERT_TRUE(ParseFeatureFlagsParameter("foo:READ_ONLY= true, bar:ro =FALSE,baz:READ_WRITE=, quux",
398 diagnostics, &feature_flag_values));
399 EXPECT_THAT(
400 feature_flag_values,
401 UnorderedElementsAre(Pair("foo", FeatureFlagProperties{true, std::optional<bool>(true)}),
402 Pair("bar", FeatureFlagProperties{true, std::optional<bool>(false)}),
403 Pair("baz", FeatureFlagProperties{false, std::nullopt}),
404 Pair("quux", FeatureFlagProperties{false, std::nullopt})));
405 }
406
TEST(UtilTest,AdjustSplitConstraintsForMinSdk)407 TEST (UtilTest, AdjustSplitConstraintsForMinSdk) {
408 std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build();
409
410 android::IDiagnostics* diagnostics = context.get()->GetDiagnostics();
411 std::vector<SplitConstraints> test_constraints;
412 std::string path;
413
414 test_constraints.push_back({});
415 ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("v7"),
416 diagnostics, &path, &test_constraints.back()));
417 test_constraints.push_back({});
418 ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("xhdpi"),
419 diagnostics, &path, &test_constraints.back()));
420 EXPECT_EQ(test_constraints.size(), 2);
421 EXPECT_EQ(test_constraints[0].name, "v7");
422 EXPECT_EQ(test_constraints[0].configs.size(), 1);
423 EXPECT_NE(*test_constraints[0].configs.begin(), ConfigDescription::DefaultConfig());
424 EXPECT_EQ(test_constraints[1].name, "xhdpi");
425 EXPECT_EQ(test_constraints[1].configs.size(), 1);
426 EXPECT_NE(*test_constraints[0].configs.begin(), ConfigDescription::DefaultConfig());
427
428 auto adjusted_contraints = AdjustSplitConstraintsForMinSdk(26, test_constraints);
429 EXPECT_EQ(adjusted_contraints.size(), 2);
430 EXPECT_EQ(adjusted_contraints[0].name, "v7");
431 EXPECT_EQ(adjusted_contraints[0].configs.size(), 0);
432 EXPECT_EQ(adjusted_contraints[1].name, "xhdpi");
433 EXPECT_EQ(adjusted_contraints[1].configs.size(), 1);
434 EXPECT_NE(*adjusted_contraints[1].configs.begin(), ConfigDescription::DefaultConfig());
435 }
436
TEST(UtilTest,RegularExperssionsSimple)437 TEST (UtilTest, RegularExperssionsSimple) {
438 std::string valid(".bc$");
439 std::regex expression = GetRegularExpression(valid);
440 EXPECT_TRUE(std::regex_search("file.abc", expression));
441 EXPECT_TRUE(std::regex_search("file.123bc", expression));
442 EXPECT_FALSE(std::regex_search("abc.zip", expression));
443 }
444
TEST(UtilTest,RegularExpressionComplex)445 TEST (UtilTest, RegularExpressionComplex) {
446 std::string valid("\\.(d|D)(e|E)(x|X)$");
447 std::regex expression = GetRegularExpression(valid);
448 EXPECT_TRUE(std::regex_search("file.dex", expression));
449 EXPECT_TRUE(std::regex_search("file.DEX", expression));
450 EXPECT_TRUE(std::regex_search("file.dEx", expression));
451 EXPECT_FALSE(std::regex_search("file.dexx", expression));
452 EXPECT_FALSE(std::regex_search("dex.file", expression));
453 EXPECT_FALSE(std::regex_search("file.adex", expression));
454 }
455
TEST(UtilTest,RegularExpressionNonEnglish)456 TEST (UtilTest, RegularExpressionNonEnglish) {
457 std::string valid("\\.(k|K)(o|O)(ń|Ń)(c|C)(ó|Ó)(w|W)(k|K)(a|A)$");
458 std::regex expression = GetRegularExpression(valid);
459 EXPECT_TRUE(std::regex_search("file.końcówka", expression));
460 EXPECT_TRUE(std::regex_search("file.KOŃCÓWKA", expression));
461 EXPECT_TRUE(std::regex_search("file.kOńcÓwkA", expression));
462 EXPECT_FALSE(std::regex_search("file.koncowka", expression));
463 }
464
TEST(UtilTest,ParseConfigWithDirectives)465 TEST(UtilTest, ParseConfigWithDirectives) {
466 const std::string& content = R"(
467 bool/remove_me#remove
468 bool/keep_name#no_collapse
469 layout/keep_path#no_path_shorten
470 string/foo#no_obfuscate
471 dimen/bar#no_obfuscate
472 layout/keep_name_and_path#no_collapse,no_path_shorten
473 )";
474 aapt::test::Context context;
475 std::unordered_set<ResourceName> resource_exclusion;
476 std::set<ResourceName> name_collapse_exemptions;
477 std::set<ResourceName> path_shorten_exemptions;
478
479 EXPECT_TRUE(ParseResourceConfig(content, &context, resource_exclusion, name_collapse_exemptions,
480 path_shorten_exemptions));
481
482 EXPECT_THAT(name_collapse_exemptions,
483 UnorderedElementsAre(ResourceName({}, ResourceType::kString, "foo"),
484 ResourceName({}, ResourceType::kDimen, "bar"),
485 ResourceName({}, ResourceType::kBool, "keep_name"),
486 ResourceName({}, ResourceType::kLayout, "keep_name_and_path")));
487 EXPECT_THAT(path_shorten_exemptions,
488 UnorderedElementsAre(ResourceName({}, ResourceType::kLayout, "keep_path"),
489 ResourceName({}, ResourceType::kLayout, "keep_name_and_path")));
490 EXPECT_THAT(resource_exclusion,
491 UnorderedElementsAre(ResourceName({}, ResourceType::kBool, "remove_me")));
492 }
493
TEST(UtilTest,ParseConfigResourceWithPackage)494 TEST(UtilTest, ParseConfigResourceWithPackage) {
495 const std::string& content = R"(
496 package:bool/remove_me#remove
497 )";
498 aapt::test::Context context;
499 std::unordered_set<ResourceName> resource_exclusion;
500 std::set<ResourceName> name_collapse_exemptions;
501 std::set<ResourceName> path_shorten_exemptions;
502
503 EXPECT_FALSE(ParseResourceConfig(content, &context, resource_exclusion, name_collapse_exemptions,
504 path_shorten_exemptions));
505 }
506
TEST(UtilTest,ParseConfigInvalidName)507 TEST(UtilTest, ParseConfigInvalidName) {
508 const std::string& content = R"(
509 package:bool/1231#remove
510 )";
511 aapt::test::Context context;
512 std::unordered_set<ResourceName> resource_exclusion;
513 std::set<ResourceName> name_collapse_exemptions;
514 std::set<ResourceName> path_shorten_exemptions;
515
516 EXPECT_FALSE(ParseResourceConfig(content, &context, resource_exclusion, name_collapse_exemptions,
517 path_shorten_exemptions));
518 }
519
TEST(UtilTest,ParseConfigNoHash)520 TEST(UtilTest, ParseConfigNoHash) {
521 const std::string& content = R"(
522 package:bool/my_bool
523 )";
524 aapt::test::Context context;
525 std::unordered_set<ResourceName> resource_exclusion;
526 std::set<ResourceName> name_collapse_exemptions;
527 std::set<ResourceName> path_shorten_exemptions;
528
529 EXPECT_FALSE(ParseResourceConfig(content, &context, resource_exclusion, name_collapse_exemptions,
530 path_shorten_exemptions));
531 }
532
533 } // namespace aapt
534