| /* | |
| * Copyright (C) 2017 The Android Open Source Project | |
| * | |
| * Licensed under the Apache License, Version 2.0 (the "License"); | |
| * you may not use this file except in compliance with the License. | |
| * You may obtain a copy of the License at | |
| * | |
| * http://www.apache.org/licenses/LICENSE-2.0 | |
| * | |
| * Unless required by applicable law or agreed to in writing, software | |
| * distributed under the License is distributed on an "AS IS" BASIS, | |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| * See the License for the specific language governing permissions and | |
| * limitations under the License. | |
| */ | |
| #include "Util.h" | |
| #include "android-base/stringprintf.h" | |
| #include "AppInfo.h" | |
| #include "split/TableSplitter.h" | |
| #include "test/Builders.h" | |
| #include "test/Test.h" | |
| #include "util/Files.h" | |
| using ::android::ConfigDescription; | |
| using testing::Pair; | |
| using testing::UnorderedElementsAre; | |
| namespace aapt { | |
| #ifdef _WIN32 | |
| #define CREATE_PATH(path) android::base::StringPrintf(";%s", path) | |
| #else | |
| #define CREATE_PATH(path) android::base::StringPrintf(":%s", path) | |
| #endif | |
| #define EXPECT_CONFIG_EQ(constraints, config) \ | |
| EXPECT_EQ(constraints.configs.size(), 1); \ | |
| EXPECT_EQ(*constraints.configs.begin(), config); \ | |
| constraints.configs.clear(); | |
| TEST(UtilTest, SplitNamesAreSanitized) { | |
| AppInfo app_info{"com.pkg"}; | |
| SplitConstraints split_constraints{ | |
| {test::ParseConfigOrDie("en-rUS-land"), test::ParseConfigOrDie("b+sr+Latn")}}; | |
| const auto doc = GenerateSplitManifest(app_info, split_constraints); | |
| const auto &root = doc->root; | |
| EXPECT_EQ(root->name, "manifest"); | |
| // split names cannot contain hyphens or plus signs. | |
| EXPECT_EQ(root->FindAttribute("", "split")->value, "config.b_sr_Latn_en_rUS_land"); | |
| // but we should use resource qualifiers verbatim in 'targetConfig'. | |
| EXPECT_EQ(root->FindAttribute("", "targetConfig")->value, "b+sr+Latn,en-rUS-land"); | |
| } | |
| TEST (UtilTest, LongVersionCodeDefined) { | |
| auto doc = test::BuildXmlDom(R"( | |
| <manifest xmlns:android="http://schemas.android.com/apk/res/android" | |
| package="com.android.aapt.test" android:versionCode="0x1" android:versionCodeMajor="0x1"> | |
| </manifest>)"); | |
| SetLongVersionCode(doc->root.get(), 42); | |
| auto version_code = doc->root->FindAttribute(xml::kSchemaAndroid, "versionCode"); | |
| ASSERT_NE(version_code, nullptr); | |
| EXPECT_EQ(version_code->value, "0x0000002a"); | |
| ASSERT_NE(version_code->compiled_value, nullptr); | |
| auto compiled_version_code = ValueCast<BinaryPrimitive>(version_code->compiled_value.get()); | |
| ASSERT_NE(compiled_version_code, nullptr); | |
| EXPECT_EQ(compiled_version_code->value.data, 42U); | |
| auto version_code_major = doc->root->FindAttribute(xml::kSchemaAndroid, "versionCodeMajor"); | |
| EXPECT_EQ(version_code_major, nullptr); | |
| } | |
| TEST (UtilTest, LongVersionCodeUndefined) { | |
| auto doc = test::BuildXmlDom(R"( | |
| <manifest xmlns:android="http://schemas.android.com/apk/res/android" | |
| package="com.android.aapt.test"> | |
| </manifest>)"); | |
| SetLongVersionCode(doc->root.get(), 420000000000); | |
| auto version_code = doc->root->FindAttribute(xml::kSchemaAndroid, "versionCode"); | |
| ASSERT_NE(version_code, nullptr); | |
| EXPECT_EQ(version_code->value, "0xc9f36800"); | |
| ASSERT_NE(version_code->compiled_value, nullptr); | |
| auto compiled_version_code = ValueCast<BinaryPrimitive>(version_code->compiled_value.get()); | |
| ASSERT_NE(compiled_version_code, nullptr); | |
| EXPECT_EQ(compiled_version_code->value.data, 0xc9f36800); | |
| auto version_code_major = doc->root->FindAttribute(xml::kSchemaAndroid, "versionCodeMajor"); | |
| ASSERT_NE(version_code_major, nullptr); | |
| EXPECT_EQ(version_code_major->value, "0x00000061"); | |
| ASSERT_NE(version_code_major->compiled_value, nullptr); | |
| auto compiled_version_code_major = ValueCast<BinaryPrimitive>( | |
| version_code_major->compiled_value.get()); | |
| ASSERT_NE(compiled_version_code_major, nullptr); | |
| EXPECT_EQ(compiled_version_code_major->value.data, 0x61); | |
| } | |
| TEST (UtilTest, ParseSplitParameters) { | |
| android::IDiagnostics* diagnostics = test::ContextBuilder().Build().get()->GetDiagnostics(); | |
| std::string path; | |
| SplitConstraints constraints; | |
| ConfigDescription expected_configuration; | |
| // ========== Test IMSI ========== | |
| // mcc: 'mcc[0-9]{3}' | |
| // mnc: 'mnc[0-9]{1,3}' | |
| ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("mcc310"), | |
| diagnostics, &path, &constraints)); | |
| expected_configuration = test::ConfigDescriptionBuilder() | |
| .setMcc(0x0136) | |
| .Build(); | |
| EXPECT_CONFIG_EQ(constraints, expected_configuration); | |
| ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("mcc310-mnc004"), | |
| diagnostics, &path, &constraints)); | |
| expected_configuration = test::ConfigDescriptionBuilder() | |
| .setMcc(0x0136) | |
| .setMnc(0x0004) | |
| .Build(); | |
| EXPECT_CONFIG_EQ(constraints, expected_configuration); | |
| ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("mcc310-mnc000"), | |
| diagnostics, &path, &constraints)); | |
| expected_configuration = test::ConfigDescriptionBuilder() | |
| .setMcc(0x0136) | |
| .setMnc(0xFFFF) | |
| .Build(); | |
| EXPECT_CONFIG_EQ(constraints, expected_configuration); | |
| // ========== Test LOCALE ========== | |
| // locale: '[a-z]{2,3}(-r[a-z]{2})?' | |
| // locale: 'b+[a-z]{2,3}(+[a-z[0-9]]{2})?' | |
| ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("es"), | |
| diagnostics, &path, &constraints)); | |
| expected_configuration = test::ConfigDescriptionBuilder() | |
| .setLanguage(0x6573) | |
| .Build(); | |
| EXPECT_CONFIG_EQ(constraints, expected_configuration); | |
| ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("fr-rCA"), | |
| diagnostics, &path, &constraints)); | |
| expected_configuration = test::ConfigDescriptionBuilder() | |
| .setLanguage(0x6672) | |
| .setCountry(0x4341) | |
| .Build(); | |
| EXPECT_CONFIG_EQ(constraints, expected_configuration); | |
| ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("b+es+419"), | |
| diagnostics, &path, &constraints)); | |
| expected_configuration = test::ConfigDescriptionBuilder() | |
| .setLanguage(0x6573) | |
| .setCountry(0xA424) | |
| .Build(); | |
| EXPECT_CONFIG_EQ(constraints, expected_configuration); | |
| // ========== Test SCREEN_TYPE ========== | |
| // orientation: '(port|land|square)' | |
| // touchscreen: '(notouch|stylus|finger)' | |
| // density" '(anydpi|nodpi|ldpi|mdpi|tvdpi|hdpi|xhdpi|xxhdpi|xxxhdpi|[0-9]*dpi)' | |
| ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("square"), | |
| diagnostics, &path, &constraints)); | |
| expected_configuration = test::ConfigDescriptionBuilder() | |
| .setOrientation(0x03) | |
| .Build(); | |
| EXPECT_CONFIG_EQ(constraints, expected_configuration); | |
| ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("stylus"), | |
| diagnostics, &path, &constraints)); | |
| expected_configuration = test::ConfigDescriptionBuilder() | |
| .setTouchscreen(0x02) | |
| .Build(); | |
| EXPECT_CONFIG_EQ(constraints, expected_configuration); | |
| ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("xxxhdpi"), | |
| diagnostics, &path, &constraints)); | |
| expected_configuration = test::ConfigDescriptionBuilder() | |
| .setDensity(0x0280) | |
| .setSdkVersion(0x0004) // version [any density requires donut] | |
| .Build(); | |
| EXPECT_CONFIG_EQ(constraints, expected_configuration); | |
| ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("land-xhdpi-finger"), | |
| diagnostics, &path, &constraints)); | |
| expected_configuration = test::ConfigDescriptionBuilder() | |
| .setOrientation(0x02) | |
| .setTouchscreen(0x03) | |
| .setDensity(0x0140) | |
| .setSdkVersion(0x0004) // version [any density requires donut] | |
| .Build(); | |
| EXPECT_CONFIG_EQ(constraints, expected_configuration); | |
| // ========== Test INPUT ========== | |
| // keyboard: '(nokeys|qwerty|12key)' | |
| // navigation: '(nonav|dpad|trackball|wheel)' | |
| // inputFlags: '(keysexposed|keyshidden|keyssoft)' | |
| // inputFlags: '(navexposed|navhidden)' | |
| ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("qwerty"), | |
| diagnostics, &path, &constraints)); | |
| expected_configuration = test::ConfigDescriptionBuilder() | |
| .setKeyboard(0x02) | |
| .Build(); | |
| EXPECT_CONFIG_EQ(constraints, expected_configuration); | |
| ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("dpad"), | |
| diagnostics, &path, &constraints)); | |
| expected_configuration = test::ConfigDescriptionBuilder() | |
| .setNavigation(0x02) | |
| .Build(); | |
| EXPECT_CONFIG_EQ(constraints, expected_configuration); | |
| ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("keyssoft-navhidden"), | |
| diagnostics, &path, &constraints)); | |
| expected_configuration = test::ConfigDescriptionBuilder() | |
| .setInputFlags(0x0B) | |
| .Build(); | |
| EXPECT_CONFIG_EQ(constraints, expected_configuration); | |
| ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("keyshidden-nokeys-navexposed-trackball"), | |
| diagnostics, &path, &constraints)); | |
| expected_configuration = test::ConfigDescriptionBuilder() | |
| .setKeyboard(0x01) | |
| .setNavigation(0x03) | |
| .setInputFlags(0x06) | |
| .Build(); | |
| EXPECT_CONFIG_EQ(constraints, expected_configuration); | |
| // ========== Test SCREEN_SIZE ========== | |
| // screenWidth/screenHeight: '[0-9]+x[0-9]+' | |
| ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("1920x1080"), | |
| diagnostics, &path, &constraints)); | |
| expected_configuration = test::ConfigDescriptionBuilder() | |
| .setScreenWidth(0x0780) | |
| .setScreenHeight(0x0438) | |
| .Build(); | |
| EXPECT_CONFIG_EQ(constraints, expected_configuration); | |
| // ========== Test VERSION ========== | |
| // version 'v[0-9]+' | |
| // ========== Test SCREEN_CONFIG ========== | |
| // screenLayout [direction]: '(ldltr|ldrtl)' | |
| // screenLayout [size]: '(small|normal|large|xlarge)' | |
| // screenLayout [long]: '(long|notlong)' | |
| // uiMode [type]: '(desk|car|television|appliance|watch|vrheadset)' | |
| // uiMode [night]: '(night|notnight)' | |
| // smallestScreenWidthDp: 'sw[0-9]dp' | |
| ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("ldrtl"), | |
| diagnostics, &path, &constraints)); | |
| expected_configuration = test::ConfigDescriptionBuilder() | |
| .setScreenLayout(0x80) | |
| .Build(); | |
| EXPECT_CONFIG_EQ(constraints, expected_configuration); | |
| ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("small"), | |
| diagnostics, &path, &constraints)); | |
| expected_configuration = test::ConfigDescriptionBuilder() | |
| .setScreenLayout(0x01) | |
| .setSdkVersion(0x0004) // screenLayout (size) requires donut | |
| .Build(); | |
| EXPECT_CONFIG_EQ(constraints, expected_configuration); | |
| ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("notlong"), | |
| diagnostics, &path, &constraints)); | |
| expected_configuration = test::ConfigDescriptionBuilder() | |
| .setScreenLayout(0x10) | |
| .setSdkVersion(0x0004) // screenLayout (long) requires donut | |
| .Build(); | |
| EXPECT_CONFIG_EQ(constraints, expected_configuration); | |
| ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("ldltr-normal-long"), | |
| diagnostics, &path, &constraints)); | |
| expected_configuration = test::ConfigDescriptionBuilder() | |
| .setScreenLayout(0x62) | |
| .setSdkVersion(0x0004) // screenLayout (size|long) requires donut | |
| .Build(); | |
| EXPECT_CONFIG_EQ(constraints, expected_configuration); | |
| ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("car"), | |
| diagnostics, &path, &constraints)); | |
| expected_configuration = test::ConfigDescriptionBuilder() | |
| .setUiMode(0x03) | |
| .setSdkVersion(0x0008) // uiMode requires froyo | |
| .Build(); | |
| EXPECT_CONFIG_EQ(constraints, expected_configuration); | |
| ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("vrheadset"), | |
| diagnostics, &path, &constraints)); | |
| expected_configuration = test::ConfigDescriptionBuilder() | |
| .setUiMode(0x07) | |
| .setSdkVersion(0x001A) // uiMode 'vrheadset' requires oreo | |
| .Build(); | |
| EXPECT_CONFIG_EQ(constraints, expected_configuration); | |
| ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("television-night"), | |
| diagnostics, &path, &constraints)); | |
| expected_configuration = test::ConfigDescriptionBuilder() | |
| .setUiMode(0x24) | |
| .setSdkVersion(0x0008) // uiMode requires froyo | |
| .Build(); | |
| EXPECT_CONFIG_EQ(constraints, expected_configuration); | |
| ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("sw1920dp"), | |
| diagnostics, &path, &constraints)); | |
| expected_configuration = test::ConfigDescriptionBuilder() | |
| .setSmallestScreenWidthDp(0x0780) | |
| .setSdkVersion(0x000D) // smallestScreenWidthDp requires honeycomb mr2 | |
| .Build(); | |
| EXPECT_CONFIG_EQ(constraints, expected_configuration); | |
| // ========== Test SCREEN_SIZE_DP ========== | |
| // screenWidthDp: 'w[0-9]dp' | |
| // screenHeightDp: 'h[0-9]dp' | |
| ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("w1920dp"), | |
| diagnostics, &path, &constraints)); | |
| expected_configuration = test::ConfigDescriptionBuilder() | |
| .setScreenWidthDp(0x0780) | |
| .setSdkVersion(0x000D) // screenWidthDp requires honeycomb mr2 | |
| .Build(); | |
| EXPECT_CONFIG_EQ(constraints, expected_configuration); | |
| ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("h1080dp"), | |
| diagnostics, &path, &constraints)); | |
| expected_configuration = test::ConfigDescriptionBuilder() | |
| .setScreenHeightDp(0x0438) | |
| .setSdkVersion(0x000D) // screenHeightDp requires honeycomb mr2 | |
| .Build(); | |
| EXPECT_CONFIG_EQ(constraints, expected_configuration); | |
| // ========== Test SCREEN_CONFIG_2 ========== | |
| // screenLayout2: '(round|notround)' | |
| // colorMode: '(widecg|nowidecg)' | |
| // colorMode: '(highhdr|lowdr)' | |
| ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("round"), | |
| diagnostics, &path, &constraints)); | |
| expected_configuration = test::ConfigDescriptionBuilder() | |
| .setScreenLayout2(0x02) | |
| .setSdkVersion(0x0017) // screenLayout2 (round) requires marshmallow | |
| .Build(); | |
| EXPECT_CONFIG_EQ(constraints, expected_configuration); | |
| ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("widecg-highdr"), | |
| diagnostics, &path, &constraints)); | |
| expected_configuration = test::ConfigDescriptionBuilder() | |
| .setColorMode(0x0A) | |
| .setSdkVersion(0x001A) // colorMode (hdr|colour gamut) requires oreo | |
| .Build(); | |
| EXPECT_CONFIG_EQ(constraints, expected_configuration); | |
| } | |
| TEST(UtilTest, ParseFeatureFlagsParameter_Empty) { | |
| auto diagnostics = test::ContextBuilder().Build()->GetDiagnostics(); | |
| FeatureFlagValues feature_flag_values; | |
| ASSERT_TRUE(ParseFeatureFlagsParameter("", diagnostics, &feature_flag_values)); | |
| EXPECT_TRUE(feature_flag_values.empty()); | |
| } | |
| TEST(UtilTest, ParseFeatureFlagsParameter_TooManyParts) { | |
| auto diagnostics = test::ContextBuilder().Build()->GetDiagnostics(); | |
| FeatureFlagValues feature_flag_values; | |
| ASSERT_FALSE(ParseFeatureFlagsParameter("foo=bar=baz", diagnostics, &feature_flag_values)); | |
| } | |
| TEST(UtilTest, ParseFeatureFlagsParameter_NoNameGiven) { | |
| auto diagnostics = test::ContextBuilder().Build()->GetDiagnostics(); | |
| FeatureFlagValues feature_flag_values; | |
| ASSERT_FALSE(ParseFeatureFlagsParameter("foo=true,=false", diagnostics, &feature_flag_values)); | |
| } | |
| TEST(UtilTest, ParseFeatureFlagsParameter_InvalidValue) { | |
| auto diagnostics = test::ContextBuilder().Build()->GetDiagnostics(); | |
| FeatureFlagValues feature_flag_values; | |
| ASSERT_FALSE(ParseFeatureFlagsParameter("foo=true,bar=42", diagnostics, &feature_flag_values)); | |
| } | |
| TEST(UtilTest, ParseFeatureFlagsParameter_DuplicateFlag) { | |
| auto diagnostics = test::ContextBuilder().Build()->GetDiagnostics(); | |
| FeatureFlagValues feature_flag_values; | |
| ASSERT_TRUE(ParseFeatureFlagsParameter("foo=true,bar:READ_WRITE=true,foo:ro=false", diagnostics, | |
| &feature_flag_values)); | |
| EXPECT_THAT( | |
| feature_flag_values, | |
| UnorderedElementsAre(Pair("foo", FeatureFlagProperties{true, std::optional<bool>(false)}), | |
| Pair("bar", FeatureFlagProperties{false, std::optional<bool>(true)}))); | |
| } | |
| TEST(UtilTest, ParseFeatureFlagsParameter_Valid) { | |
| auto diagnostics = test::ContextBuilder().Build()->GetDiagnostics(); | |
| FeatureFlagValues feature_flag_values; | |
| ASSERT_TRUE(ParseFeatureFlagsParameter("foo:READ_ONLY= true, bar:ro =FALSE,baz:READ_WRITE=, quux", | |
| diagnostics, &feature_flag_values)); | |
| EXPECT_THAT( | |
| feature_flag_values, | |
| UnorderedElementsAre(Pair("foo", FeatureFlagProperties{true, std::optional<bool>(true)}), | |
| Pair("bar", FeatureFlagProperties{true, std::optional<bool>(false)}), | |
| Pair("baz", FeatureFlagProperties{false, std::nullopt}), | |
| Pair("quux", FeatureFlagProperties{false, std::nullopt}))); | |
| } | |
| TEST (UtilTest, AdjustSplitConstraintsForMinSdk) { | |
| std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build(); | |
| android::IDiagnostics* diagnostics = context.get()->GetDiagnostics(); | |
| std::vector<SplitConstraints> test_constraints; | |
| std::string path; | |
| test_constraints.push_back({}); | |
| ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("v7"), diagnostics, &path, &test_constraints.back())); | |
| test_constraints.push_back({}); | |
| ASSERT_TRUE( | |
| ParseSplitParameter(CREATE_PATH("xhdpi"), diagnostics, &path, &test_constraints.back())); | |
| test_constraints.push_back({}); | |
| ASSERT_TRUE( | |
| ParseSplitParameter(CREATE_PATH("v38.9"), diagnostics, &path, &test_constraints.back())); | |
| EXPECT_EQ(test_constraints.size(), 3); | |
| EXPECT_EQ(test_constraints[0].name, "v7"); | |
| EXPECT_EQ(test_constraints[0].configs.size(), 1); | |
| EXPECT_NE(*test_constraints[0].configs.begin(), ConfigDescription::DefaultConfig()); | |
| EXPECT_EQ(test_constraints[1].name, "xhdpi"); | |
| EXPECT_EQ(test_constraints[1].configs.size(), 1); | |
| EXPECT_NE(*test_constraints[1].configs.begin(), ConfigDescription::DefaultConfig()); | |
| EXPECT_EQ(test_constraints[2].name, "v38.9"); | |
| EXPECT_EQ(test_constraints[2].configs.size(), 1); | |
| EXPECT_NE(*test_constraints[2].configs.begin(), ConfigDescription::DefaultConfig()); | |
| auto adjusted_contraints = AdjustSplitConstraintsForMinSdk(40, test_constraints); | |
| EXPECT_EQ(adjusted_contraints.size(), 3); | |
| EXPECT_EQ(adjusted_contraints[0].name, "v7"); | |
| EXPECT_EQ(adjusted_contraints[0].configs.size(), 0); | |
| EXPECT_EQ(adjusted_contraints[1].name, "xhdpi"); | |
| EXPECT_EQ(adjusted_contraints[1].configs.size(), 1); | |
| EXPECT_NE(*adjusted_contraints[1].configs.begin(), ConfigDescription::DefaultConfig()); | |
| EXPECT_EQ(adjusted_contraints[2].name, "v38.9"); | |
| EXPECT_EQ(adjusted_contraints[2].configs.size(), 0); | |
| } | |
| TEST (UtilTest, RegularExperssionsSimple) { | |
| std::string valid(".bc$"); | |
| std::regex expression = GetRegularExpression(valid); | |
| EXPECT_TRUE(std::regex_search("file.abc", expression)); | |
| EXPECT_TRUE(std::regex_search("file.123bc", expression)); | |
| EXPECT_FALSE(std::regex_search("abc.zip", expression)); | |
| } | |
| TEST (UtilTest, RegularExpressionComplex) { | |
| std::string valid("\\.(d|D)(e|E)(x|X)$"); | |
| std::regex expression = GetRegularExpression(valid); | |
| EXPECT_TRUE(std::regex_search("file.dex", expression)); | |
| EXPECT_TRUE(std::regex_search("file.DEX", expression)); | |
| EXPECT_TRUE(std::regex_search("file.dEx", expression)); | |
| EXPECT_FALSE(std::regex_search("file.dexx", expression)); | |
| EXPECT_FALSE(std::regex_search("dex.file", expression)); | |
| EXPECT_FALSE(std::regex_search("file.adex", expression)); | |
| } | |
| TEST (UtilTest, RegularExpressionNonEnglish) { | |
| std::string valid("\\.(k|K)(o|O)(ń|Ń)(c|C)(ó|Ó)(w|W)(k|K)(a|A)$"); | |
| std::regex expression = GetRegularExpression(valid); | |
| EXPECT_TRUE(std::regex_search("file.końcówka", expression)); | |
| EXPECT_TRUE(std::regex_search("file.KOŃCÓWKA", expression)); | |
| EXPECT_TRUE(std::regex_search("file.kOńcÓwkA", expression)); | |
| EXPECT_FALSE(std::regex_search("file.koncowka", expression)); | |
| } | |
| TEST(UtilTest, ParseConfigWithDirectives) { | |
| const std::string& content = R"( | |
| bool/remove_me#remove | |
| bool/keep_name#no_collapse | |
| layout/keep_path#no_path_shorten | |
| string/foo#no_obfuscate | |
| dimen/bar#no_obfuscate | |
| layout/keep_name_and_path#no_collapse,no_path_shorten | |
| )"; | |
| aapt::test::Context context; | |
| std::unordered_set<ResourceName> resource_exclusion; | |
| std::set<ResourceName> name_collapse_exemptions; | |
| std::set<ResourceName> path_shorten_exemptions; | |
| EXPECT_TRUE(ParseResourceConfig(content, &context, resource_exclusion, name_collapse_exemptions, | |
| path_shorten_exemptions)); | |
| EXPECT_THAT(name_collapse_exemptions, | |
| UnorderedElementsAre(ResourceName({}, ResourceType::kString, "foo"), | |
| ResourceName({}, ResourceType::kDimen, "bar"), | |
| ResourceName({}, ResourceType::kBool, "keep_name"), | |
| ResourceName({}, ResourceType::kLayout, "keep_name_and_path"))); | |
| EXPECT_THAT(path_shorten_exemptions, | |
| UnorderedElementsAre(ResourceName({}, ResourceType::kLayout, "keep_path"), | |
| ResourceName({}, ResourceType::kLayout, "keep_name_and_path"))); | |
| EXPECT_THAT(resource_exclusion, | |
| UnorderedElementsAre(ResourceName({}, ResourceType::kBool, "remove_me"))); | |
| } | |
| TEST(UtilTest, ParseConfigResourceWithPackage) { | |
| const std::string& content = R"( | |
| package:bool/remove_me#remove | |
| )"; | |
| aapt::test::Context context; | |
| std::unordered_set<ResourceName> resource_exclusion; | |
| std::set<ResourceName> name_collapse_exemptions; | |
| std::set<ResourceName> path_shorten_exemptions; | |
| EXPECT_FALSE(ParseResourceConfig(content, &context, resource_exclusion, name_collapse_exemptions, | |
| path_shorten_exemptions)); | |
| } | |
| TEST(UtilTest, ParseConfigInvalidName) { | |
| const std::string& content = R"( | |
| package:bool/1231#remove | |
| )"; | |
| aapt::test::Context context; | |
| std::unordered_set<ResourceName> resource_exclusion; | |
| std::set<ResourceName> name_collapse_exemptions; | |
| std::set<ResourceName> path_shorten_exemptions; | |
| EXPECT_FALSE(ParseResourceConfig(content, &context, resource_exclusion, name_collapse_exemptions, | |
| path_shorten_exemptions)); | |
| } | |
| TEST(UtilTest, ParseConfigNoHash) { | |
| const std::string& content = R"( | |
| package:bool/my_bool | |
| )"; | |
| aapt::test::Context context; | |
| std::unordered_set<ResourceName> resource_exclusion; | |
| std::set<ResourceName> name_collapse_exemptions; | |
| std::set<ResourceName> path_shorten_exemptions; | |
| EXPECT_FALSE(ParseResourceConfig(content, &context, resource_exclusion, name_collapse_exemptions, | |
| path_shorten_exemptions)); | |
| } | |
| } // namespace aapt |