Home | History | Annotate | Download | only in aapt2
      1 /*
      2  * Copyright (C) 2015 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 "SourceXmlPullParser.h"
     18 #include "BindingXmlPullParser.h"
     19 
     20 #include <gtest/gtest.h>
     21 #include <sstream>
     22 #include <string>
     23 
     24 namespace aapt {
     25 
     26 constexpr const char16_t* kAndroidNamespaceUri = u"http://schemas.android.com/apk/res/android";
     27 
     28 TEST(BindingXmlPullParserTest, SubstituteBindingExpressionsWithTag) {
     29     std::stringstream input;
     30     input << "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
     31           << "<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n"
     32           << "              xmlns:bind=\"http://schemas.android.com/apk/binding\"\n"
     33           << "              android:id=\"@+id/content\">\n"
     34           << "  <variable name=\"user\" type=\"com.android.test.User\"/>\n"
     35           << "  <TextView android:text=\"@{user.name}\" android:layout_width=\"wrap_content\"\n"
     36           << "            android:layout_height=\"wrap_content\"/>\n"
     37           << "</LinearLayout>\n";
     38     std::shared_ptr<XmlPullParser> sourceParser = std::make_shared<SourceXmlPullParser>(input);
     39     BindingXmlPullParser parser(sourceParser);
     40 
     41     ASSERT_EQ(XmlPullParser::Event::kStartNamespace, parser.next());
     42     EXPECT_EQ(std::u16string(u"http://schemas.android.com/apk/res/android"),
     43               parser.getNamespaceUri());
     44 
     45     ASSERT_EQ(XmlPullParser::Event::kStartElement, parser.next());
     46     EXPECT_EQ(std::u16string(u"LinearLayout"), parser.getElementName());
     47 
     48     while (parser.next() == XmlPullParser::Event::kText) {}
     49 
     50     ASSERT_EQ(XmlPullParser::Event::kStartElement, parser.getEvent());
     51     EXPECT_EQ(std::u16string(u"TextView"), parser.getElementName());
     52 
     53     ASSERT_EQ(3u, parser.getAttributeCount());
     54     const auto endAttr = parser.endAttributes();
     55     EXPECT_NE(endAttr, parser.findAttribute(kAndroidNamespaceUri, u"layout_width"));
     56     EXPECT_NE(endAttr, parser.findAttribute(kAndroidNamespaceUri, u"layout_height"));
     57     EXPECT_NE(endAttr, parser.findAttribute(kAndroidNamespaceUri, u"tag"));
     58 
     59     while (parser.next() == XmlPullParser::Event::kText) {}
     60 
     61     ASSERT_EQ(XmlPullParser::Event::kEndElement, parser.getEvent());
     62 
     63     while (parser.next() == XmlPullParser::Event::kText) {}
     64 
     65     ASSERT_EQ(XmlPullParser::Event::kEndElement, parser.getEvent());
     66     ASSERT_EQ(XmlPullParser::Event::kEndNamespace, parser.next());
     67 }
     68 
     69 TEST(BindingXmlPullParserTest, GenerateVariableDeclarations) {
     70     std::stringstream input;
     71     input << "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
     72           << "<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n"
     73           << "              xmlns:bind=\"http://schemas.android.com/apk/binding\"\n"
     74           << "              android:id=\"@+id/content\">\n"
     75           << "  <variable name=\"user\" type=\"com.android.test.User\"/>\n"
     76           << "</LinearLayout>\n";
     77     std::shared_ptr<XmlPullParser> sourceParser = std::make_shared<SourceXmlPullParser>(input);
     78     BindingXmlPullParser parser(sourceParser);
     79 
     80     while (XmlPullParser::isGoodEvent(parser.next())) {
     81         ASSERT_NE(XmlPullParser::Event::kBadDocument, parser.getEvent());
     82     }
     83 
     84     std::stringstream output;
     85     ASSERT_TRUE(parser.writeToFile(output));
     86 
     87     std::string result = output.str();
     88     EXPECT_NE(std::string::npos,
     89               result.find("<entries name=\"user\" type=\"com.android.test.User\"/>"));
     90 }
     91 
     92 TEST(BindingXmlPullParserTest, FailOnMissingNameOrTypeInVariableDeclaration) {
     93     std::stringstream input;
     94     input << "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
     95           << "<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n"
     96           << "              xmlns:bind=\"http://schemas.android.com/apk/binding\"\n"
     97           << "              android:id=\"@+id/content\">\n"
     98           << "  <variable name=\"user\"/>\n"
     99           << "</LinearLayout>\n";
    100     std::shared_ptr<XmlPullParser> sourceParser = std::make_shared<SourceXmlPullParser>(input);
    101     BindingXmlPullParser parser(sourceParser);
    102 
    103     while (XmlPullParser::isGoodEvent(parser.next())) {}
    104 
    105     EXPECT_EQ(XmlPullParser::Event::kBadDocument, parser.getEvent());
    106     EXPECT_FALSE(parser.getLastError().empty());
    107 }
    108 
    109 
    110 } // namespace aapt
    111