• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
21 namespace aapt {
22 
TEST(InlineXmlFormatParserTest,PassThrough)23 TEST(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 
37 TEST(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 
88 TEST(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