1/* 2 * Copyright (C) 2016 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 "compile/InlineXmlFormatParser.h" 18 19#include "test/Test.h" 20 21namespace aapt { 22 23TEST(InlineXmlFormatParserTest, PassThrough) { 24 std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build(); 25 std::unique_ptr<xml::XmlResource> doc = test::BuildXmlDom(R"EOF( 26 <View xmlns:android="http://schemas.android.com/apk/res/android"> 27 <View android:text="hey"> 28 <View android:id="hi" /> 29 </View> 30 </View>)EOF"); 31 32 InlineXmlFormatParser parser; 33 ASSERT_TRUE(parser.Consume(context.get(), doc.get())); 34 EXPECT_EQ(0u, parser.GetExtractedInlineXmlDocuments().size()); 35} 36 37TEST(InlineXmlFormatParserTest, ExtractOneXmlResource) { 38 std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build(); 39 std::unique_ptr<xml::XmlResource> doc = test::BuildXmlDom(R"EOF( 40 <View1 xmlns:android="http://schemas.android.com/apk/res/android" 41 xmlns:aapt="http://schemas.android.com/aapt"> 42 <aapt:attr name="android:text"> 43 <View2 android:text="hey"> 44 <View3 android:id="hi" /> 45 </View2> 46 </aapt:attr> 47 </View1>)EOF"); 48 49 doc->file.name = test::ParseNameOrDie("layout/main"); 50 51 InlineXmlFormatParser parser; 52 ASSERT_TRUE(parser.Consume(context.get(), doc.get())); 53 54 // One XML resource should have been extracted. 55 EXPECT_EQ(1u, parser.GetExtractedInlineXmlDocuments().size()); 56 57 xml::Element* el = xml::FindRootElement(doc.get()); 58 ASSERT_NE(nullptr, el); 59 60 EXPECT_EQ("View1", el->name); 61 62 // The <aapt:attr> tag should be extracted. 63 EXPECT_EQ(nullptr, el->FindChild(xml::kSchemaAapt, "attr")); 64 65 // The 'android:text' attribute should be set with a reference. 66 xml::Attribute* attr = el->FindAttribute(xml::kSchemaAndroid, "text"); 67 ASSERT_NE(nullptr, attr); 68 69 ResourceNameRef name_ref; 70 ASSERT_TRUE(ResourceUtils::ParseReference(attr->value, &name_ref)); 71 72 xml::XmlResource* extracted_doc = 73 parser.GetExtractedInlineXmlDocuments()[0].get(); 74 ASSERT_NE(nullptr, extracted_doc); 75 76 // Make sure the generated reference is correct. 77 EXPECT_EQ(name_ref.package, extracted_doc->file.name.package); 78 EXPECT_EQ(name_ref.type, extracted_doc->file.name.type); 79 EXPECT_EQ(name_ref.entry, extracted_doc->file.name.entry); 80 81 // Verify the structure of the extracted XML. 82 el = xml::FindRootElement(extracted_doc); 83 ASSERT_NE(nullptr, el); 84 EXPECT_EQ("View2", el->name); 85 EXPECT_NE(nullptr, el->FindChild({}, "View3")); 86} 87 88TEST(InlineXmlFormatParserTest, ExtractTwoXmlResources) { 89 std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build(); 90 std::unique_ptr<xml::XmlResource> doc = test::BuildXmlDom(R"EOF( 91 <View1 xmlns:android="http://schemas.android.com/apk/res/android" 92 xmlns:aapt="http://schemas.android.com/aapt"> 93 <aapt:attr name="android:text"> 94 <View2 android:text="hey"> 95 <View3 android:id="hi" /> 96 </View2> 97 </aapt:attr> 98 99 <aapt:attr name="android:drawable"> 100 <vector /> 101 </aapt:attr> 102 </View1>)EOF"); 103 104 doc->file.name = test::ParseNameOrDie("layout/main"); 105 106 InlineXmlFormatParser parser; 107 ASSERT_TRUE(parser.Consume(context.get(), doc.get())); 108 ASSERT_EQ(2u, parser.GetExtractedInlineXmlDocuments().size()); 109 110 xml::Element* el = xml::FindRootElement(doc.get()); 111 ASSERT_NE(nullptr, el); 112 113 EXPECT_EQ("View1", el->name); 114 115 xml::Attribute* attr_text = el->FindAttribute(xml::kSchemaAndroid, "text"); 116 ASSERT_NE(nullptr, attr_text); 117 118 xml::Attribute* attr_drawable = 119 el->FindAttribute(xml::kSchemaAndroid, "drawable"); 120 ASSERT_NE(nullptr, attr_drawable); 121 122 // The two extracted resources should have different names. 123 EXPECT_NE(attr_text->value, attr_drawable->value); 124 125 // The child <aapt:attr> elements should be gone. 126 EXPECT_EQ(nullptr, el->FindChild(xml::kSchemaAapt, "attr")); 127 128 xml::XmlResource* extracted_doc_text = 129 parser.GetExtractedInlineXmlDocuments()[0].get(); 130 ASSERT_NE(nullptr, extracted_doc_text); 131 el = xml::FindRootElement(extracted_doc_text); 132 ASSERT_NE(nullptr, el); 133 EXPECT_EQ("View2", el->name); 134 135 xml::XmlResource* extracted_doc_drawable = 136 parser.GetExtractedInlineXmlDocuments()[1].get(); 137 ASSERT_NE(nullptr, extracted_doc_drawable); 138 el = xml::FindRootElement(extracted_doc_drawable); 139 ASSERT_NE(nullptr, el); 140 EXPECT_EQ("vector", el->name); 141} 142 143} // namespace aapt 144