ProguardRules_test.cpp revision a693c4a32ebed4e96dcc1cf6a706e8ebbb004db2
1f762df257574231ffd08679a69e9cf62fe143dcdAdam Lesinski/* 2f762df257574231ffd08679a69e9cf62fe143dcdAdam Lesinski * Copyright (C) 2017 The Android Open Source Project 3f762df257574231ffd08679a69e9cf62fe143dcdAdam Lesinski * 4f762df257574231ffd08679a69e9cf62fe143dcdAdam Lesinski * Licensed under the Apache License, Version 2.0 (the "License"); 5f762df257574231ffd08679a69e9cf62fe143dcdAdam Lesinski * you may not use this file except in compliance with the License. 6f762df257574231ffd08679a69e9cf62fe143dcdAdam Lesinski * You may obtain a copy of the License at 7f762df257574231ffd08679a69e9cf62fe143dcdAdam Lesinski * 8f762df257574231ffd08679a69e9cf62fe143dcdAdam Lesinski * http://www.apache.org/licenses/LICENSE-2.0 9f762df257574231ffd08679a69e9cf62fe143dcdAdam Lesinski * 10f762df257574231ffd08679a69e9cf62fe143dcdAdam Lesinski * Unless required by applicable law or agreed to in writing, software 11f762df257574231ffd08679a69e9cf62fe143dcdAdam Lesinski * distributed under the License is distributed on an "AS IS" BASIS, 12f762df257574231ffd08679a69e9cf62fe143dcdAdam Lesinski * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13f762df257574231ffd08679a69e9cf62fe143dcdAdam Lesinski * See the License for the specific language governing permissions and 14f762df257574231ffd08679a69e9cf62fe143dcdAdam Lesinski * limitations under the License. 15f762df257574231ffd08679a69e9cf62fe143dcdAdam Lesinski */ 16f762df257574231ffd08679a69e9cf62fe143dcdAdam Lesinski 17f762df257574231ffd08679a69e9cf62fe143dcdAdam Lesinski#include "java/ProguardRules.h" 18dc21dea9b8b1157a4a9347b68301da4307c51168Adam Koski#include "link/Linkers.h" 19f762df257574231ffd08679a69e9cf62fe143dcdAdam Lesinski 20a693c4a32ebed4e96dcc1cf6a706e8ebbb004db2Adam Lesinski#include "io/StringStream.h" 21f762df257574231ffd08679a69e9cf62fe143dcdAdam Lesinski#include "test/Test.h" 22f762df257574231ffd08679a69e9cf62fe143dcdAdam Lesinski 23a693c4a32ebed4e96dcc1cf6a706e8ebbb004db2Adam Lesinskiusing ::aapt::io::StringOutputStream; 24f762df257574231ffd08679a69e9cf62fe143dcdAdam Lesinskiusing ::testing::HasSubstr; 25f762df257574231ffd08679a69e9cf62fe143dcdAdam Lesinskiusing ::testing::Not; 26f762df257574231ffd08679a69e9cf62fe143dcdAdam Lesinski 27f762df257574231ffd08679a69e9cf62fe143dcdAdam Lesinskinamespace aapt { 28f762df257574231ffd08679a69e9cf62fe143dcdAdam Lesinski 29a693c4a32ebed4e96dcc1cf6a706e8ebbb004db2Adam Lesinskistd::string GetKeepSetString(const proguard::KeepSet& set) { 30a693c4a32ebed4e96dcc1cf6a706e8ebbb004db2Adam Lesinski std::string out; 31a693c4a32ebed4e96dcc1cf6a706e8ebbb004db2Adam Lesinski StringOutputStream sout(&out); 32a693c4a32ebed4e96dcc1cf6a706e8ebbb004db2Adam Lesinski proguard::WriteKeepSet(set, &sout); 33a693c4a32ebed4e96dcc1cf6a706e8ebbb004db2Adam Lesinski sout.Flush(); 34a693c4a32ebed4e96dcc1cf6a706e8ebbb004db2Adam Lesinski return out; 35a693c4a32ebed4e96dcc1cf6a706e8ebbb004db2Adam Lesinski} 36a693c4a32ebed4e96dcc1cf6a706e8ebbb004db2Adam Lesinski 37f762df257574231ffd08679a69e9cf62fe143dcdAdam LesinskiTEST(ProguardRulesTest, FragmentNameRuleIsEmitted) { 38f762df257574231ffd08679a69e9cf62fe143dcdAdam Lesinski std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build(); 39f762df257574231ffd08679a69e9cf62fe143dcdAdam Lesinski std::unique_ptr<xml::XmlResource> layout = test::BuildXmlDom(R"( 40f762df257574231ffd08679a69e9cf62fe143dcdAdam Lesinski <fragment xmlns:android="http://schemas.android.com/apk/res/android" 41f762df257574231ffd08679a69e9cf62fe143dcdAdam Lesinski android:name="com.foo.Bar"/>)"); 42f762df257574231ffd08679a69e9cf62fe143dcdAdam Lesinski layout->file.name = test::ParseNameOrDie("layout/foo"); 43f762df257574231ffd08679a69e9cf62fe143dcdAdam Lesinski 44f762df257574231ffd08679a69e9cf62fe143dcdAdam Lesinski proguard::KeepSet set; 45dc21dea9b8b1157a4a9347b68301da4307c51168Adam Koski ASSERT_TRUE(proguard::CollectProguardRules(layout.get(), &set)); 46f762df257574231ffd08679a69e9cf62fe143dcdAdam Lesinski 47a693c4a32ebed4e96dcc1cf6a706e8ebbb004db2Adam Lesinski std::string actual = GetKeepSetString(set); 48f762df257574231ffd08679a69e9cf62fe143dcdAdam Lesinski 49f762df257574231ffd08679a69e9cf62fe143dcdAdam Lesinski EXPECT_THAT(actual, HasSubstr("com.foo.Bar")); 50f762df257574231ffd08679a69e9cf62fe143dcdAdam Lesinski} 51f762df257574231ffd08679a69e9cf62fe143dcdAdam Lesinski 52f762df257574231ffd08679a69e9cf62fe143dcdAdam LesinskiTEST(ProguardRulesTest, FragmentClassRuleIsEmitted) { 53f762df257574231ffd08679a69e9cf62fe143dcdAdam Lesinski std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build(); 54f762df257574231ffd08679a69e9cf62fe143dcdAdam Lesinski std::unique_ptr<xml::XmlResource> layout = 55f762df257574231ffd08679a69e9cf62fe143dcdAdam Lesinski test::BuildXmlDom(R"(<fragment class="com.foo.Bar"/>)"); 56f762df257574231ffd08679a69e9cf62fe143dcdAdam Lesinski layout->file.name = test::ParseNameOrDie("layout/foo"); 57f762df257574231ffd08679a69e9cf62fe143dcdAdam Lesinski 58f762df257574231ffd08679a69e9cf62fe143dcdAdam Lesinski proguard::KeepSet set; 59dc21dea9b8b1157a4a9347b68301da4307c51168Adam Koski ASSERT_TRUE(proguard::CollectProguardRules(layout.get(), &set)); 60f762df257574231ffd08679a69e9cf62fe143dcdAdam Lesinski 61a693c4a32ebed4e96dcc1cf6a706e8ebbb004db2Adam Lesinski std::string actual = GetKeepSetString(set); 62f762df257574231ffd08679a69e9cf62fe143dcdAdam Lesinski 63f762df257574231ffd08679a69e9cf62fe143dcdAdam Lesinski EXPECT_THAT(actual, HasSubstr("com.foo.Bar")); 64f762df257574231ffd08679a69e9cf62fe143dcdAdam Lesinski} 65f762df257574231ffd08679a69e9cf62fe143dcdAdam Lesinski 66f762df257574231ffd08679a69e9cf62fe143dcdAdam LesinskiTEST(ProguardRulesTest, FragmentNameAndClassRulesAreEmitted) { 67f762df257574231ffd08679a69e9cf62fe143dcdAdam Lesinski std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build(); 68f762df257574231ffd08679a69e9cf62fe143dcdAdam Lesinski std::unique_ptr<xml::XmlResource> layout = test::BuildXmlDom(R"( 69f762df257574231ffd08679a69e9cf62fe143dcdAdam Lesinski <fragment xmlns:android="http://schemas.android.com/apk/res/android" 70f762df257574231ffd08679a69e9cf62fe143dcdAdam Lesinski android:name="com.foo.Baz" 71f762df257574231ffd08679a69e9cf62fe143dcdAdam Lesinski class="com.foo.Bar"/>)"); 72f762df257574231ffd08679a69e9cf62fe143dcdAdam Lesinski layout->file.name = test::ParseNameOrDie("layout/foo"); 73f762df257574231ffd08679a69e9cf62fe143dcdAdam Lesinski 74f762df257574231ffd08679a69e9cf62fe143dcdAdam Lesinski proguard::KeepSet set; 75dc21dea9b8b1157a4a9347b68301da4307c51168Adam Koski ASSERT_TRUE(proguard::CollectProguardRules(layout.get(), &set)); 76f762df257574231ffd08679a69e9cf62fe143dcdAdam Lesinski 77a693c4a32ebed4e96dcc1cf6a706e8ebbb004db2Adam Lesinski std::string actual = GetKeepSetString(set); 78f762df257574231ffd08679a69e9cf62fe143dcdAdam Lesinski 79f762df257574231ffd08679a69e9cf62fe143dcdAdam Lesinski EXPECT_THAT(actual, HasSubstr("com.foo.Bar")); 80f762df257574231ffd08679a69e9cf62fe143dcdAdam Lesinski EXPECT_THAT(actual, HasSubstr("com.foo.Baz")); 81f762df257574231ffd08679a69e9cf62fe143dcdAdam Lesinski} 82f762df257574231ffd08679a69e9cf62fe143dcdAdam Lesinski 83dc21dea9b8b1157a4a9347b68301da4307c51168Adam KoskiTEST(ProguardRulesTest, CustomViewRulesAreEmitted) { 84dc21dea9b8b1157a4a9347b68301da4307c51168Adam Koski std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build(); 85dc21dea9b8b1157a4a9347b68301da4307c51168Adam Koski std::unique_ptr<xml::XmlResource> layout = test::BuildXmlDom(R"( 86dc21dea9b8b1157a4a9347b68301da4307c51168Adam Koski <View xmlns:android="http://schemas.android.com/apk/res/android"> 87dc21dea9b8b1157a4a9347b68301da4307c51168Adam Koski <com.foo.Bar /> 88dc21dea9b8b1157a4a9347b68301da4307c51168Adam Koski </View>)"); 89dc21dea9b8b1157a4a9347b68301da4307c51168Adam Koski layout->file.name = test::ParseNameOrDie("layout/foo"); 90dc21dea9b8b1157a4a9347b68301da4307c51168Adam Koski 91dc21dea9b8b1157a4a9347b68301da4307c51168Adam Koski proguard::KeepSet set; 92dc21dea9b8b1157a4a9347b68301da4307c51168Adam Koski ASSERT_TRUE(proguard::CollectProguardRules(layout.get(), &set)); 93dc21dea9b8b1157a4a9347b68301da4307c51168Adam Koski 94a693c4a32ebed4e96dcc1cf6a706e8ebbb004db2Adam Lesinski std::string actual = GetKeepSetString(set); 95dc21dea9b8b1157a4a9347b68301da4307c51168Adam Koski 96dc21dea9b8b1157a4a9347b68301da4307c51168Adam Koski EXPECT_THAT(actual, HasSubstr("com.foo.Bar")); 97dc21dea9b8b1157a4a9347b68301da4307c51168Adam Koski} 98dc21dea9b8b1157a4a9347b68301da4307c51168Adam Koski 99dc21dea9b8b1157a4a9347b68301da4307c51168Adam KoskiTEST(ProguardRulesTest, IncludedLayoutRulesAreConditional) { 100dc21dea9b8b1157a4a9347b68301da4307c51168Adam Koski std::unique_ptr<xml::XmlResource> bar_layout = test::BuildXmlDom(R"( 101dc21dea9b8b1157a4a9347b68301da4307c51168Adam Koski <View xmlns:android="http://schemas.android.com/apk/res/android"> 102dc21dea9b8b1157a4a9347b68301da4307c51168Adam Koski <com.foo.Bar /> 103dc21dea9b8b1157a4a9347b68301da4307c51168Adam Koski </View>)"); 104dc21dea9b8b1157a4a9347b68301da4307c51168Adam Koski bar_layout->file.name = test::ParseNameOrDie("com.foo:layout/bar"); 105dc21dea9b8b1157a4a9347b68301da4307c51168Adam Koski 106dc21dea9b8b1157a4a9347b68301da4307c51168Adam Koski ResourceTable table; 107dc21dea9b8b1157a4a9347b68301da4307c51168Adam Koski StdErrDiagnostics errDiagnostics; 108dc21dea9b8b1157a4a9347b68301da4307c51168Adam Koski table.AddResource(bar_layout->file.name, ConfigDescription::DefaultConfig(), "", 109dc21dea9b8b1157a4a9347b68301da4307c51168Adam Koski util::make_unique<FileReference>(), &errDiagnostics); 110dc21dea9b8b1157a4a9347b68301da4307c51168Adam Koski 111dc21dea9b8b1157a4a9347b68301da4307c51168Adam Koski std::unique_ptr<IAaptContext> context = 112dc21dea9b8b1157a4a9347b68301da4307c51168Adam Koski test::ContextBuilder() 113dc21dea9b8b1157a4a9347b68301da4307c51168Adam Koski .SetCompilationPackage("com.foo") 114dc21dea9b8b1157a4a9347b68301da4307c51168Adam Koski .AddSymbolSource(util::make_unique<ResourceTableSymbolSource>(&table)) 115dc21dea9b8b1157a4a9347b68301da4307c51168Adam Koski .Build(); 116dc21dea9b8b1157a4a9347b68301da4307c51168Adam Koski 117dc21dea9b8b1157a4a9347b68301da4307c51168Adam Koski std::unique_ptr<xml::XmlResource> foo_layout = test::BuildXmlDom(R"( 118dc21dea9b8b1157a4a9347b68301da4307c51168Adam Koski <View xmlns:android="http://schemas.android.com/apk/res/android"> 119dc21dea9b8b1157a4a9347b68301da4307c51168Adam Koski <include layout="@layout/bar" /> 120dc21dea9b8b1157a4a9347b68301da4307c51168Adam Koski </View>)"); 121dc21dea9b8b1157a4a9347b68301da4307c51168Adam Koski foo_layout->file.name = test::ParseNameOrDie("com.foo:layout/foo"); 122dc21dea9b8b1157a4a9347b68301da4307c51168Adam Koski 123dc21dea9b8b1157a4a9347b68301da4307c51168Adam Koski XmlReferenceLinker xml_linker; 124dc21dea9b8b1157a4a9347b68301da4307c51168Adam Koski ASSERT_TRUE(xml_linker.Consume(context.get(), bar_layout.get())); 125dc21dea9b8b1157a4a9347b68301da4307c51168Adam Koski ASSERT_TRUE(xml_linker.Consume(context.get(), foo_layout.get())); 126dc21dea9b8b1157a4a9347b68301da4307c51168Adam Koski 127dc21dea9b8b1157a4a9347b68301da4307c51168Adam Koski proguard::KeepSet set = proguard::KeepSet(true); 128dc21dea9b8b1157a4a9347b68301da4307c51168Adam Koski ASSERT_TRUE(proguard::CollectProguardRules(bar_layout.get(), &set)); 129dc21dea9b8b1157a4a9347b68301da4307c51168Adam Koski ASSERT_TRUE(proguard::CollectProguardRules(foo_layout.get(), &set)); 130dc21dea9b8b1157a4a9347b68301da4307c51168Adam Koski 131a693c4a32ebed4e96dcc1cf6a706e8ebbb004db2Adam Lesinski std::string actual = GetKeepSetString(set); 132dc21dea9b8b1157a4a9347b68301da4307c51168Adam Koski 13309ef94e918870a55907b20f35348cc7b77bdc148Adam Koski EXPECT_THAT(actual, HasSubstr("-if class **.R$layout")); 134a693c4a32ebed4e96dcc1cf6a706e8ebbb004db2Adam Lesinski EXPECT_THAT(actual, HasSubstr("-keep class com.foo.Bar { <init>(...); }")); 135dc21dea9b8b1157a4a9347b68301da4307c51168Adam Koski EXPECT_THAT(actual, HasSubstr("int foo")); 136dc21dea9b8b1157a4a9347b68301da4307c51168Adam Koski EXPECT_THAT(actual, HasSubstr("int bar")); 137dc21dea9b8b1157a4a9347b68301da4307c51168Adam Koski EXPECT_THAT(actual, HasSubstr("com.foo.Bar")); 138dc21dea9b8b1157a4a9347b68301da4307c51168Adam Koski} 139dc21dea9b8b1157a4a9347b68301da4307c51168Adam Koski 140dc21dea9b8b1157a4a9347b68301da4307c51168Adam KoskiTEST(ProguardRulesTest, AliasedLayoutRulesAreConditional) { 141dc21dea9b8b1157a4a9347b68301da4307c51168Adam Koski std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build(); 142dc21dea9b8b1157a4a9347b68301da4307c51168Adam Koski std::unique_ptr<xml::XmlResource> layout = test::BuildXmlDom(R"( 143dc21dea9b8b1157a4a9347b68301da4307c51168Adam Koski <View xmlns:android="http://schemas.android.com/apk/res/android"> 144dc21dea9b8b1157a4a9347b68301da4307c51168Adam Koski <com.foo.Bar /> 145dc21dea9b8b1157a4a9347b68301da4307c51168Adam Koski </View>)"); 146dc21dea9b8b1157a4a9347b68301da4307c51168Adam Koski layout->file.name = test::ParseNameOrDie("layout/foo"); 147dc21dea9b8b1157a4a9347b68301da4307c51168Adam Koski 148dc21dea9b8b1157a4a9347b68301da4307c51168Adam Koski proguard::KeepSet set = proguard::KeepSet(true); 149dc21dea9b8b1157a4a9347b68301da4307c51168Adam Koski set.AddReference({test::ParseNameOrDie("layout/bar"), {}}, layout->file.name); 150dc21dea9b8b1157a4a9347b68301da4307c51168Adam Koski ASSERT_TRUE(proguard::CollectProguardRules(layout.get(), &set)); 151dc21dea9b8b1157a4a9347b68301da4307c51168Adam Koski 152a693c4a32ebed4e96dcc1cf6a706e8ebbb004db2Adam Lesinski std::string actual = GetKeepSetString(set); 153dc21dea9b8b1157a4a9347b68301da4307c51168Adam Koski 154a693c4a32ebed4e96dcc1cf6a706e8ebbb004db2Adam Lesinski EXPECT_THAT(actual, HasSubstr("-keep class com.foo.Bar { <init>(...); }")); 15509ef94e918870a55907b20f35348cc7b77bdc148Adam Koski EXPECT_THAT(actual, HasSubstr("-if class **.R$layout")); 156dc21dea9b8b1157a4a9347b68301da4307c51168Adam Koski EXPECT_THAT(actual, HasSubstr("int foo")); 157dc21dea9b8b1157a4a9347b68301da4307c51168Adam Koski EXPECT_THAT(actual, HasSubstr("int bar")); 158dc21dea9b8b1157a4a9347b68301da4307c51168Adam Koski EXPECT_THAT(actual, HasSubstr("com.foo.Bar")); 159dc21dea9b8b1157a4a9347b68301da4307c51168Adam Koski} 160dc21dea9b8b1157a4a9347b68301da4307c51168Adam Koski 161dc21dea9b8b1157a4a9347b68301da4307c51168Adam KoskiTEST(ProguardRulesTest, NonLayoutReferencesAreUnconditional) { 162dc21dea9b8b1157a4a9347b68301da4307c51168Adam Koski std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build(); 163dc21dea9b8b1157a4a9347b68301da4307c51168Adam Koski std::unique_ptr<xml::XmlResource> layout = test::BuildXmlDom(R"( 164dc21dea9b8b1157a4a9347b68301da4307c51168Adam Koski <View xmlns:android="http://schemas.android.com/apk/res/android"> 165dc21dea9b8b1157a4a9347b68301da4307c51168Adam Koski <com.foo.Bar /> 166dc21dea9b8b1157a4a9347b68301da4307c51168Adam Koski </View>)"); 167dc21dea9b8b1157a4a9347b68301da4307c51168Adam Koski layout->file.name = test::ParseNameOrDie("layout/foo"); 168dc21dea9b8b1157a4a9347b68301da4307c51168Adam Koski 169dc21dea9b8b1157a4a9347b68301da4307c51168Adam Koski proguard::KeepSet set = proguard::KeepSet(true); 170dc21dea9b8b1157a4a9347b68301da4307c51168Adam Koski set.AddReference({test::ParseNameOrDie("style/MyStyle"), {}}, layout->file.name); 171dc21dea9b8b1157a4a9347b68301da4307c51168Adam Koski ASSERT_TRUE(proguard::CollectProguardRules(layout.get(), &set)); 172dc21dea9b8b1157a4a9347b68301da4307c51168Adam Koski 173a693c4a32ebed4e96dcc1cf6a706e8ebbb004db2Adam Lesinski std::string actual = GetKeepSetString(set); 174dc21dea9b8b1157a4a9347b68301da4307c51168Adam Koski 17509ef94e918870a55907b20f35348cc7b77bdc148Adam Koski EXPECT_THAT(actual, Not(HasSubstr("-if"))); 176a693c4a32ebed4e96dcc1cf6a706e8ebbb004db2Adam Lesinski EXPECT_THAT(actual, HasSubstr("-keep class com.foo.Bar { <init>(...); }")); 177dc21dea9b8b1157a4a9347b68301da4307c51168Adam Koski} 178dc21dea9b8b1157a4a9347b68301da4307c51168Adam Koski 179f762df257574231ffd08679a69e9cf62fe143dcdAdam LesinskiTEST(ProguardRulesTest, ViewOnClickRuleIsEmitted) { 180f762df257574231ffd08679a69e9cf62fe143dcdAdam Lesinski std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build(); 181f762df257574231ffd08679a69e9cf62fe143dcdAdam Lesinski std::unique_ptr<xml::XmlResource> layout = test::BuildXmlDom(R"( 182f762df257574231ffd08679a69e9cf62fe143dcdAdam Lesinski <View xmlns:android="http://schemas.android.com/apk/res/android" 183f762df257574231ffd08679a69e9cf62fe143dcdAdam Lesinski android:onClick="bar_method" />)"); 184f762df257574231ffd08679a69e9cf62fe143dcdAdam Lesinski layout->file.name = test::ParseNameOrDie("layout/foo"); 185f762df257574231ffd08679a69e9cf62fe143dcdAdam Lesinski 186f762df257574231ffd08679a69e9cf62fe143dcdAdam Lesinski proguard::KeepSet set; 187dc21dea9b8b1157a4a9347b68301da4307c51168Adam Koski ASSERT_TRUE(proguard::CollectProguardRules(layout.get(), &set)); 188f762df257574231ffd08679a69e9cf62fe143dcdAdam Lesinski 189a693c4a32ebed4e96dcc1cf6a706e8ebbb004db2Adam Lesinski std::string actual = GetKeepSetString(set); 190f762df257574231ffd08679a69e9cf62fe143dcdAdam Lesinski 191f762df257574231ffd08679a69e9cf62fe143dcdAdam Lesinski EXPECT_THAT(actual, HasSubstr("bar_method")); 192f762df257574231ffd08679a69e9cf62fe143dcdAdam Lesinski} 193f762df257574231ffd08679a69e9cf62fe143dcdAdam Lesinski 194f762df257574231ffd08679a69e9cf62fe143dcdAdam LesinskiTEST(ProguardRulesTest, MenuRulesAreEmitted) { 195f762df257574231ffd08679a69e9cf62fe143dcdAdam Lesinski std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build(); 196f762df257574231ffd08679a69e9cf62fe143dcdAdam Lesinski std::unique_ptr<xml::XmlResource> menu = test::BuildXmlDom(R"( 197f762df257574231ffd08679a69e9cf62fe143dcdAdam Lesinski <menu xmlns:android="http://schemas.android.com/apk/res/android"> 198f762df257574231ffd08679a69e9cf62fe143dcdAdam Lesinski <item android:onClick="on_click" 199f762df257574231ffd08679a69e9cf62fe143dcdAdam Lesinski android:actionViewClass="com.foo.Bar" 200f762df257574231ffd08679a69e9cf62fe143dcdAdam Lesinski android:actionProviderClass="com.foo.Baz" 201f762df257574231ffd08679a69e9cf62fe143dcdAdam Lesinski android:name="com.foo.Bat" /> 202f762df257574231ffd08679a69e9cf62fe143dcdAdam Lesinski </menu>)"); 203f762df257574231ffd08679a69e9cf62fe143dcdAdam Lesinski menu->file.name = test::ParseNameOrDie("menu/foo"); 204f762df257574231ffd08679a69e9cf62fe143dcdAdam Lesinski 205f762df257574231ffd08679a69e9cf62fe143dcdAdam Lesinski proguard::KeepSet set; 206dc21dea9b8b1157a4a9347b68301da4307c51168Adam Koski ASSERT_TRUE(proguard::CollectProguardRules(menu.get(), &set)); 207f762df257574231ffd08679a69e9cf62fe143dcdAdam Lesinski 208a693c4a32ebed4e96dcc1cf6a706e8ebbb004db2Adam Lesinski std::string actual = GetKeepSetString(set); 209f762df257574231ffd08679a69e9cf62fe143dcdAdam Lesinski 210f762df257574231ffd08679a69e9cf62fe143dcdAdam Lesinski EXPECT_THAT(actual, HasSubstr("on_click")); 211f762df257574231ffd08679a69e9cf62fe143dcdAdam Lesinski EXPECT_THAT(actual, HasSubstr("com.foo.Bar")); 212f762df257574231ffd08679a69e9cf62fe143dcdAdam Lesinski EXPECT_THAT(actual, HasSubstr("com.foo.Baz")); 213f762df257574231ffd08679a69e9cf62fe143dcdAdam Lesinski EXPECT_THAT(actual, Not(HasSubstr("com.foo.Bat"))); 214f762df257574231ffd08679a69e9cf62fe143dcdAdam Lesinski} 215f762df257574231ffd08679a69e9cf62fe143dcdAdam Lesinski 216f762df257574231ffd08679a69e9cf62fe143dcdAdam Lesinski} // namespace aapt 217