xref: /aosp_15_r20/frameworks/base/tools/aapt2/cmd/Util_test.cpp (revision d57664e9bc4670b3ecf6748a746a57c557b6bc9e)
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