blob: 35bc63714e5885dc8d67f31c974f468871e5866e [file] [log] [blame]
Donald Chaib8f078c2017-10-18 23:51:18 -07001/*
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
Ryan Mitchell0ce89732018-10-03 09:20:57 -070019#include "android-base/stringprintf.h"
20
Donald Chaib8f078c2017-10-18 23:51:18 -070021#include "AppInfo.h"
22#include "split/TableSplitter.h"
Ryan Mitchell5fa2bb12018-07-12 11:24:51 -070023#include "test/Builders.h"
Donald Chaib8f078c2017-10-18 23:51:18 -070024#include "test/Test.h"
Ryan Mitchell0ce89732018-10-03 09:20:57 -070025#include "util/Files.h"
Donald Chaib8f078c2017-10-18 23:51:18 -070026
Mårten Kongstad24c9aa62018-06-20 08:46:41 +020027using ::android::ConfigDescription;
Mark Punzalan5579cad2023-10-30 13:47:51 -070028using testing::Pair;
Iurii Makhno054e4332022-10-12 16:03:03 +000029using testing::UnorderedElementsAre;
Mårten Kongstad24c9aa62018-06-20 08:46:41 +020030
Donald Chaib8f078c2017-10-18 23:51:18 -070031namespace aapt {
Ryan Mitchell0ce89732018-10-03 09:20:57 -070032
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
Todd Kennedy9fbdf892018-08-28 16:31:15 -070039#define EXPECT_CONFIG_EQ(constraints, config) \
40 EXPECT_EQ(constraints.configs.size(), 1); \
41 EXPECT_EQ(*constraints.configs.begin(), config); \
42 constraints.configs.clear();
Donald Chaib8f078c2017-10-18 23:51:18 -070043
44TEST(UtilTest, SplitNamesAreSanitized) {
45 AppInfo app_info{"com.pkg"};
Donald Chai414e48a2017-11-09 21:06:52 -080046 SplitConstraints split_constraints{
47 {test::ParseConfigOrDie("en-rUS-land"), test::ParseConfigOrDie("b+sr+Latn")}};
Donald Chaib8f078c2017-10-18 23:51:18 -070048
49 const auto doc = GenerateSplitManifest(app_info, split_constraints);
50 const auto &root = doc->root;
51 EXPECT_EQ(root->name, "manifest");
Donald Chai414e48a2017-11-09 21:06:52 -080052 // split names cannot contain hyphens or plus signs.
53 EXPECT_EQ(root->FindAttribute("", "split")->value, "config.b_sr_Latn_en_rUS_land");
Donald Chaib8f078c2017-10-18 23:51:18 -070054 // but we should use resource qualifiers verbatim in 'targetConfig'.
Donald Chai414e48a2017-11-09 21:06:52 -080055 EXPECT_EQ(root->FindAttribute("", "targetConfig")->value, "b+sr+Latn,en-rUS-land");
Donald Chaib8f078c2017-10-18 23:51:18 -070056}
57
Ryan Mitchell5fa2bb12018-07-12 11:24:51 -070058TEST (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
78TEST (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
Todd Kennedy9fbdf892018-08-28 16:31:15 -0700105
Ryan Mitchell0ce89732018-10-03 09:20:57 -0700106TEST (UtilTest, ParseSplitParameters) {
Jeremy Meyer56f36e82022-05-20 20:35:42 +0000107 android::IDiagnostics* diagnostics = test::ContextBuilder().Build().get()->GetDiagnostics();
Todd Kennedy9fbdf892018-08-28 16:31:15 -0700108 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}'
Ryan Mitchell0ce89732018-10-03 09:20:57 -0700115 ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("mcc310"),
Todd Kennedy9fbdf892018-08-28 16:31:15 -0700116 diagnostics, &path, &constraints));
117 expected_configuration = test::ConfigDescriptionBuilder()
118 .setMcc(0x0136)
119 .Build();
120 EXPECT_CONFIG_EQ(constraints, expected_configuration);
121
Ryan Mitchell0ce89732018-10-03 09:20:57 -0700122 ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("mcc310-mnc004"),
Todd Kennedy9fbdf892018-08-28 16:31:15 -0700123 diagnostics, &path, &constraints));
124 expected_configuration = test::ConfigDescriptionBuilder()
125 .setMcc(0x0136)
126 .setMnc(0x0004)
127 .Build();
128 EXPECT_CONFIG_EQ(constraints, expected_configuration);
129
Ryan Mitchell0ce89732018-10-03 09:20:57 -0700130 ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("mcc310-mnc000"),
Todd Kennedy9fbdf892018-08-28 16:31:15 -0700131 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})?'
Ryan Mitchell0ce89732018-10-03 09:20:57 -0700141 ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("es"),
Todd Kennedy9fbdf892018-08-28 16:31:15 -0700142 diagnostics, &path, &constraints));
143 expected_configuration = test::ConfigDescriptionBuilder()
144 .setLanguage(0x6573)
145 .Build();
146 EXPECT_CONFIG_EQ(constraints, expected_configuration);
147
Ryan Mitchell0ce89732018-10-03 09:20:57 -0700148 ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("fr-rCA"),
Todd Kennedy9fbdf892018-08-28 16:31:15 -0700149 diagnostics, &path, &constraints));
150 expected_configuration = test::ConfigDescriptionBuilder()
151 .setLanguage(0x6672)
152 .setCountry(0x4341)
153 .Build();
154 EXPECT_CONFIG_EQ(constraints, expected_configuration);
155
Ryan Mitchell0ce89732018-10-03 09:20:57 -0700156 ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("b+es+419"),
Todd Kennedy9fbdf892018-08-28 16:31:15 -0700157 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)'
Ryan Mitchell0ce89732018-10-03 09:20:57 -0700168 ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("square"),
Todd Kennedy9fbdf892018-08-28 16:31:15 -0700169 diagnostics, &path, &constraints));
170 expected_configuration = test::ConfigDescriptionBuilder()
171 .setOrientation(0x03)
172 .Build();
173 EXPECT_CONFIG_EQ(constraints, expected_configuration);
174
Ryan Mitchell0ce89732018-10-03 09:20:57 -0700175 ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("stylus"),
Todd Kennedy9fbdf892018-08-28 16:31:15 -0700176 diagnostics, &path, &constraints));
177 expected_configuration = test::ConfigDescriptionBuilder()
178 .setTouchscreen(0x02)
179 .Build();
180 EXPECT_CONFIG_EQ(constraints, expected_configuration);
181
Ryan Mitchell0ce89732018-10-03 09:20:57 -0700182 ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("xxxhdpi"),
Todd Kennedy9fbdf892018-08-28 16:31:15 -0700183 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
Ryan Mitchell0ce89732018-10-03 09:20:57 -0700190 ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("land-xhdpi-finger"),
Todd Kennedy9fbdf892018-08-28 16:31:15 -0700191 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)'
Ryan Mitchell0ce89732018-10-03 09:20:57 -0700205 ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("qwerty"),
Todd Kennedy9fbdf892018-08-28 16:31:15 -0700206 diagnostics, &path, &constraints));
207 expected_configuration = test::ConfigDescriptionBuilder()
208 .setKeyboard(0x02)
209 .Build();
210 EXPECT_CONFIG_EQ(constraints, expected_configuration);
211
Ryan Mitchell0ce89732018-10-03 09:20:57 -0700212 ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("dpad"),
Todd Kennedy9fbdf892018-08-28 16:31:15 -0700213 diagnostics, &path, &constraints));
214 expected_configuration = test::ConfigDescriptionBuilder()
215 .setNavigation(0x02)
216 .Build();
217 EXPECT_CONFIG_EQ(constraints, expected_configuration);
218
Ryan Mitchell0ce89732018-10-03 09:20:57 -0700219 ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("keyssoft-navhidden"),
Todd Kennedy9fbdf892018-08-28 16:31:15 -0700220 diagnostics, &path, &constraints));
221 expected_configuration = test::ConfigDescriptionBuilder()
222 .setInputFlags(0x0B)
223 .Build();
224 EXPECT_CONFIG_EQ(constraints, expected_configuration);
225
Ryan Mitchell0ce89732018-10-03 09:20:57 -0700226 ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("keyshidden-nokeys-navexposed-trackball"),
Todd Kennedy9fbdf892018-08-28 16:31:15 -0700227 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]+'
Ryan Mitchell0ce89732018-10-03 09:20:57 -0700237 ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("1920x1080"),
Todd Kennedy9fbdf892018-08-28 16:31:15 -0700238 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'
Ryan Mitchell0ce89732018-10-03 09:20:57 -0700255 ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("ldrtl"),
Todd Kennedy9fbdf892018-08-28 16:31:15 -0700256 diagnostics, &path, &constraints));
257 expected_configuration = test::ConfigDescriptionBuilder()
258 .setScreenLayout(0x80)
259 .Build();
260 EXPECT_CONFIG_EQ(constraints, expected_configuration);
261
Ryan Mitchell0ce89732018-10-03 09:20:57 -0700262 ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("small"),
Todd Kennedy9fbdf892018-08-28 16:31:15 -0700263 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
Ryan Mitchell0ce89732018-10-03 09:20:57 -0700270 ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("notlong"),
Todd Kennedy9fbdf892018-08-28 16:31:15 -0700271 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
Ryan Mitchell0ce89732018-10-03 09:20:57 -0700278 ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("ldltr-normal-long"),
279 diagnostics, &path, &constraints));
Todd Kennedy9fbdf892018-08-28 16:31:15 -0700280 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
Ryan Mitchell0ce89732018-10-03 09:20:57 -0700286 ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("car"),
Todd Kennedy9fbdf892018-08-28 16:31:15 -0700287 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
Ryan Mitchell0ce89732018-10-03 09:20:57 -0700294 ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("vrheadset"),
Todd Kennedy9fbdf892018-08-28 16:31:15 -0700295 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
Ryan Mitchell0ce89732018-10-03 09:20:57 -0700302 ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("television-night"),
Todd Kennedy9fbdf892018-08-28 16:31:15 -0700303 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
Ryan Mitchell0ce89732018-10-03 09:20:57 -0700310 ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("sw1920dp"),
Todd Kennedy9fbdf892018-08-28 16:31:15 -0700311 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'
Ryan Mitchell0ce89732018-10-03 09:20:57 -0700321 ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("w1920dp"),
Todd Kennedy9fbdf892018-08-28 16:31:15 -0700322 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
Ryan Mitchell0ce89732018-10-03 09:20:57 -0700329 ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("h1080dp"),
Todd Kennedy9fbdf892018-08-28 16:31:15 -0700330 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)'
Ryan Mitchell0ce89732018-10-03 09:20:57 -0700341 ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("round"),
Todd Kennedy9fbdf892018-08-28 16:31:15 -0700342 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
Ryan Mitchell0ce89732018-10-03 09:20:57 -0700349 ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("widecg-highdr"),
Todd Kennedy9fbdf892018-08-28 16:31:15 -0700350 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
Mark Punzalan5579cad2023-10-30 13:47:51 -0700358TEST(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
365TEST(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
371TEST(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
377TEST(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
383TEST(UtilTest, ParseFeatureFlagsParameter_DuplicateFlag) {
384 auto diagnostics = test::ContextBuilder().Build()->GetDiagnostics();
385 FeatureFlagValues feature_flag_values;
Jeremy Meyerfc7aba62024-07-16 20:25:38 +0000386 ASSERT_TRUE(ParseFeatureFlagsParameter("foo=true,bar=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)})));
Mark Punzalan5579cad2023-10-30 13:47:51 -0700392}
393
394TEST(UtilTest, ParseFeatureFlagsParameter_Valid) {
395 auto diagnostics = test::ContextBuilder().Build()->GetDiagnostics();
396 FeatureFlagValues feature_flag_values;
Jeremy Meyerfc7aba62024-07-16 20:25:38 +0000397 ASSERT_TRUE(ParseFeatureFlagsParameter("foo= true, bar:ro =FALSE,baz=, quux", diagnostics,
Mark Punzalan5579cad2023-10-30 13:47:51 -0700398 &feature_flag_values));
Jeremy Meyerfc7aba62024-07-16 20:25:38 +0000399 EXPECT_THAT(
400 feature_flag_values,
401 UnorderedElementsAre(Pair("foo", FeatureFlagProperties{false, 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})));
Mark Punzalan5579cad2023-10-30 13:47:51 -0700405}
406
Todd Kennedy9fbdf892018-08-28 16:31:15 -0700407TEST (UtilTest, AdjustSplitConstraintsForMinSdk) {
408 std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build();
409
Jeremy Meyer56f36e82022-05-20 20:35:42 +0000410 android::IDiagnostics* diagnostics = context.get()->GetDiagnostics();
Todd Kennedy9fbdf892018-08-28 16:31:15 -0700411 std::vector<SplitConstraints> test_constraints;
412 std::string path;
413
414 test_constraints.push_back({});
Ryan Mitchell0ce89732018-10-03 09:20:57 -0700415 ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("v7"),
Todd Kennedy9fbdf892018-08-28 16:31:15 -0700416 diagnostics, &path, &test_constraints.back()));
417 test_constraints.push_back({});
Ryan Mitchell0ce89732018-10-03 09:20:57 -0700418 ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("xhdpi"),
Todd Kennedy9fbdf892018-08-28 16:31:15 -0700419 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
Izabela Orlowska5b89b2d2019-11-27 18:37:09 +0000437TEST (UtilTest, RegularExperssionsSimple) {
Izabela Orlowska0faba5f2018-06-01 12:06:31 +0100438 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));
Izabela Orlowska5b89b2d2019-11-27 18:37:09 +0000443}
444
445TEST (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
456TEST (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}
Izabela Orlowska0faba5f2018-06-01 12:06:31 +0100464
Iurii Makhno054e4332022-10-12 16:03:03 +0000465TEST(UtilTest, ParseConfigWithDirectives) {
466 const std::string& content = R"(
467bool/remove_me#remove
468bool/keep_name#no_collapse
branliuf1ed5232022-12-16 19:02:29 +0800469layout/keep_path#no_path_shorten
Iurii Makhno054e4332022-10-12 16:03:03 +0000470string/foo#no_obfuscate
471dimen/bar#no_obfuscate
branliuf1ed5232022-12-16 19:02:29 +0800472layout/keep_name_and_path#no_collapse,no_path_shorten
Iurii Makhno054e4332022-10-12 16:03:03 +0000473)";
474 aapt::test::Context context;
475 std::unordered_set<ResourceName> resource_exclusion;
476 std::set<ResourceName> name_collapse_exemptions;
branliuf1ed5232022-12-16 19:02:29 +0800477 std::set<ResourceName> path_shorten_exemptions;
Iurii Makhno054e4332022-10-12 16:03:03 +0000478
branliuf1ed5232022-12-16 19:02:29 +0800479 EXPECT_TRUE(ParseResourceConfig(content, &context, resource_exclusion, name_collapse_exemptions,
480 path_shorten_exemptions));
Iurii Makhno054e4332022-10-12 16:03:03 +0000481
482 EXPECT_THAT(name_collapse_exemptions,
483 UnorderedElementsAre(ResourceName({}, ResourceType::kString, "foo"),
484 ResourceName({}, ResourceType::kDimen, "bar"),
branliuf1ed5232022-12-16 19:02:29 +0800485 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")));
Iurii Makhno054e4332022-10-12 16:03:03 +0000490 EXPECT_THAT(resource_exclusion,
491 UnorderedElementsAre(ResourceName({}, ResourceType::kBool, "remove_me")));
492}
493
494TEST(UtilTest, ParseConfigResourceWithPackage) {
495 const std::string& content = R"(
496package:bool/remove_me#remove
497)";
498 aapt::test::Context context;
499 std::unordered_set<ResourceName> resource_exclusion;
500 std::set<ResourceName> name_collapse_exemptions;
branliuf1ed5232022-12-16 19:02:29 +0800501 std::set<ResourceName> path_shorten_exemptions;
Iurii Makhno054e4332022-10-12 16:03:03 +0000502
branliuf1ed5232022-12-16 19:02:29 +0800503 EXPECT_FALSE(ParseResourceConfig(content, &context, resource_exclusion, name_collapse_exemptions,
504 path_shorten_exemptions));
Iurii Makhno054e4332022-10-12 16:03:03 +0000505}
506
507TEST(UtilTest, ParseConfigInvalidName) {
508 const std::string& content = R"(
509package:bool/1231#remove
510)";
511 aapt::test::Context context;
512 std::unordered_set<ResourceName> resource_exclusion;
513 std::set<ResourceName> name_collapse_exemptions;
branliuf1ed5232022-12-16 19:02:29 +0800514 std::set<ResourceName> path_shorten_exemptions;
Iurii Makhno054e4332022-10-12 16:03:03 +0000515
branliuf1ed5232022-12-16 19:02:29 +0800516 EXPECT_FALSE(ParseResourceConfig(content, &context, resource_exclusion, name_collapse_exemptions,
517 path_shorten_exemptions));
Iurii Makhno054e4332022-10-12 16:03:03 +0000518}
519
520TEST(UtilTest, ParseConfigNoHash) {
521 const std::string& content = R"(
522package:bool/my_bool
523)";
524 aapt::test::Context context;
525 std::unordered_set<ResourceName> resource_exclusion;
526 std::set<ResourceName> name_collapse_exemptions;
branliuf1ed5232022-12-16 19:02:29 +0800527 std::set<ResourceName> path_shorten_exemptions;
Iurii Makhno054e4332022-10-12 16:03:03 +0000528
branliuf1ed5232022-12-16 19:02:29 +0800529 EXPECT_FALSE(ParseResourceConfig(content, &context, resource_exclusion, name_collapse_exemptions,
530 path_shorten_exemptions));
Iurii Makhno054e4332022-10-12 16:03:03 +0000531}
532
Donald Chaib8f078c2017-10-18 23:51:18 -0700533} // namespace aapt