HELLO·Android
系统源代码
IT资讯
技术文章
我的收藏
注册
登录
-
我收藏的文章
创建代码块
我的代码块
我的账号
Nougat 7.0
|
7.0.0_r31
下载
查看原文件
收藏
根目录
frameworks
base
tools
aapt2
ResourceParser_test.cpp
/* * Copyright (C) 2015 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 "ResourceParser.h" #include "ResourceTable.h" #include "ResourceUtils.h" #include "ResourceValues.h" #include "test/Context.h" #include "xml/XmlPullParser.h" #include
#include
#include
namespace aapt { constexpr const char* kXmlPreamble = "\n"; TEST(ResourceParserSingleTest, FailToParseWithNoRootResourcesElement) { std::unique_ptr
context = test::ContextBuilder().build(); std::stringstream input(kXmlPreamble); input << "
" << std::endl; ResourceTable table; ResourceParser parser(context->getDiagnostics(), &table, Source{ "test" }, {}); xml::XmlPullParser xmlParser(input); ASSERT_FALSE(parser.parse(&xmlParser)); } struct ResourceParserTest : public ::testing::Test { ResourceTable mTable; std::unique_ptr
mContext; void SetUp() override { mContext = test::ContextBuilder().build(); } ::testing::AssertionResult testParse(const StringPiece& str) { return testParse(str, ConfigDescription{}); } ::testing::AssertionResult testParse(const StringPiece& str, const ConfigDescription& config) { std::stringstream input(kXmlPreamble); input << "
\n" << str << "\n
" << std::endl; ResourceParserOptions parserOptions; ResourceParser parser(mContext->getDiagnostics(), &mTable, Source{ "test" }, config, parserOptions); xml::XmlPullParser xmlParser(input); if (parser.parse(&xmlParser)) { return ::testing::AssertionSuccess(); } return ::testing::AssertionFailure(); } }; TEST_F(ResourceParserTest, ParseQuotedString) { std::string input = "
\" hey there \"
"; ASSERT_TRUE(testParse(input)); String* str = test::getValue
(&mTable, u"@string/foo"); ASSERT_NE(nullptr, str); EXPECT_EQ(std::u16string(u" hey there "), *str->value); } TEST_F(ResourceParserTest, ParseEscapedString) { std::string input = "
\\?123
"; ASSERT_TRUE(testParse(input)); String* str = test::getValue
(&mTable, u"@string/foo"); ASSERT_NE(nullptr, str); EXPECT_EQ(std::u16string(u"?123"), *str->value); } TEST_F(ResourceParserTest, ParseFormattedString) { std::string input = "
%d %s
"; ASSERT_FALSE(testParse(input)); input = "
%1$d %2$s
"; ASSERT_TRUE(testParse(input)); } TEST_F(ResourceParserTest, IgnoreXliffTags) { std::string input = "
\n" " There are
%1$d
apples
"; ASSERT_TRUE(testParse(input)); String* str = test::getValue
(&mTable, u"@string/foo"); ASSERT_NE(nullptr, str); EXPECT_EQ(StringPiece16(u"There are %1$d apples"), StringPiece16(*str->value)); } TEST_F(ResourceParserTest, ParseNull) { std::string input = "
@null
"; ASSERT_TRUE(testParse(input)); // The Android runtime treats a value of android::Res_value::TYPE_NULL as // a non-existing value, and this causes problems in styles when trying to resolve // an attribute. Null values must be encoded as android::Res_value::TYPE_REFERENCE // with a data value of 0. BinaryPrimitive* integer = test::getValue
(&mTable, u"@integer/foo"); ASSERT_NE(nullptr, integer); EXPECT_EQ(uint16_t(android::Res_value::TYPE_REFERENCE), integer->value.dataType); EXPECT_EQ(0u, integer->value.data); } TEST_F(ResourceParserTest, ParseEmpty) { std::string input = "
@empty
"; ASSERT_TRUE(testParse(input)); BinaryPrimitive* integer = test::getValue
(&mTable, u"@integer/foo"); ASSERT_NE(nullptr, integer); EXPECT_EQ(uint16_t(android::Res_value::TYPE_NULL), integer->value.dataType); EXPECT_EQ(uint32_t(android::Res_value::DATA_NULL_EMPTY), integer->value.data); } TEST_F(ResourceParserTest, ParseAttr) { std::string input = "
\n" "
"; ASSERT_TRUE(testParse(input)); Attribute* attr = test::getValue
(&mTable, u"@attr/foo"); ASSERT_NE(nullptr, attr); EXPECT_EQ(uint32_t(android::ResTable_map::TYPE_STRING), attr->typeMask); attr = test::getValue
(&mTable, u"@attr/bar"); ASSERT_NE(nullptr, attr); EXPECT_EQ(uint32_t(android::ResTable_map::TYPE_ANY), attr->typeMask); } // Old AAPT allowed attributes to be defined under different configurations, but ultimately // stored them with the default configuration. Check that we have the same behavior. TEST_F(ResourceParserTest, ParseAttrAndDeclareStyleableUnderConfigButRecordAsNoConfig) { const ConfigDescription watchConfig = test::parseConfigOrDie("watch"); std::string input = R"EOF(
)EOF"; ASSERT_TRUE(testParse(input, watchConfig)); EXPECT_EQ(nullptr, test::getValueForConfig
(&mTable, u"@attr/foo", watchConfig)); EXPECT_EQ(nullptr, test::getValueForConfig
(&mTable, u"@attr/baz", watchConfig)); EXPECT_EQ(nullptr, test::getValueForConfig
(&mTable, u"@styleable/bar", watchConfig)); EXPECT_NE(nullptr, test::getValue
(&mTable, u"@attr/foo")); EXPECT_NE(nullptr, test::getValue
(&mTable, u"@attr/baz")); EXPECT_NE(nullptr, test::getValue
(&mTable, u"@styleable/bar")); } TEST_F(ResourceParserTest, ParseAttrWithMinMax) { std::string input = "
"; ASSERT_TRUE(testParse(input)); Attribute* attr = test::getValue
(&mTable, u"@attr/foo"); ASSERT_NE(nullptr, attr); EXPECT_EQ(uint32_t(android::ResTable_map::TYPE_INTEGER), attr->typeMask); EXPECT_EQ(10, attr->minInt); EXPECT_EQ(23, attr->maxInt); } TEST_F(ResourceParserTest, FailParseAttrWithMinMaxButNotInteger) { std::string input = "
"; ASSERT_FALSE(testParse(input)); } TEST_F(ResourceParserTest, ParseUseAndDeclOfAttr) { std::string input = "
\n" "
\n" "
\n" "
"; ASSERT_TRUE(testParse(input)); Attribute* attr = test::getValue
(&mTable, u"@attr/foo"); ASSERT_NE(nullptr, attr); EXPECT_EQ(uint32_t(android::ResTable_map::TYPE_STRING), attr->typeMask); } TEST_F(ResourceParserTest, ParseDoubleUseOfAttr) { std::string input = "
" "
\n" "
\n" "
\n" "
\n" "
"; ASSERT_TRUE(testParse(input)); Attribute* attr = test::getValue
(&mTable, u"@attr/foo"); ASSERT_NE(nullptr, attr); EXPECT_EQ(uint32_t(android::ResTable_map::TYPE_BOOLEAN), attr->typeMask); } TEST_F(ResourceParserTest, ParseEnumAttr) { std::string input = "
\n" "
\n" "
\n" "
\n" "
"; ASSERT_TRUE(testParse(input)); Attribute* enumAttr = test::getValue
(&mTable, u"@attr/foo"); ASSERT_NE(enumAttr, nullptr); EXPECT_EQ(enumAttr->typeMask, android::ResTable_map::TYPE_ENUM); ASSERT_EQ(enumAttr->symbols.size(), 3u); AAPT_ASSERT_TRUE(enumAttr->symbols[0].symbol.name); EXPECT_EQ(enumAttr->symbols[0].symbol.name.value().entry, u"bar"); EXPECT_EQ(enumAttr->symbols[0].value, 0u); AAPT_ASSERT_TRUE(enumAttr->symbols[1].symbol.name); EXPECT_EQ(enumAttr->symbols[1].symbol.name.value().entry, u"bat"); EXPECT_EQ(enumAttr->symbols[1].value, 1u); AAPT_ASSERT_TRUE(enumAttr->symbols[2].symbol.name); EXPECT_EQ(enumAttr->symbols[2].symbol.name.value().entry, u"baz"); EXPECT_EQ(enumAttr->symbols[2].value, 2u); } TEST_F(ResourceParserTest, ParseFlagAttr) { std::string input = "
\n" "
\n" "
\n" "
\n" "
"; ASSERT_TRUE(testParse(input)); Attribute* flagAttr = test::getValue
(&mTable, u"@attr/foo"); ASSERT_NE(nullptr, flagAttr); EXPECT_EQ(flagAttr->typeMask, android::ResTable_map::TYPE_FLAGS); ASSERT_EQ(flagAttr->symbols.size(), 3u); AAPT_ASSERT_TRUE(flagAttr->symbols[0].symbol.name); EXPECT_EQ(flagAttr->symbols[0].symbol.name.value().entry, u"bar"); EXPECT_EQ(flagAttr->symbols[0].value, 0u); AAPT_ASSERT_TRUE(flagAttr->symbols[1].symbol.name); EXPECT_EQ(flagAttr->symbols[1].symbol.name.value().entry, u"bat"); EXPECT_EQ(flagAttr->symbols[1].value, 1u); AAPT_ASSERT_TRUE(flagAttr->symbols[2].symbol.name); EXPECT_EQ(flagAttr->symbols[2].symbol.name.value().entry, u"baz"); EXPECT_EQ(flagAttr->symbols[2].value, 2u); std::unique_ptr
flagValue = ResourceUtils::tryParseFlagSymbol(flagAttr, u"baz|bat"); ASSERT_NE(nullptr, flagValue); EXPECT_EQ(flagValue->value.data, 1u | 2u); } TEST_F(ResourceParserTest, FailToParseEnumAttrWithNonUniqueKeys) { std::string input = "
\n" "
\n" "
\n" "
\n" "
"; ASSERT_FALSE(testParse(input)); } TEST_F(ResourceParserTest, ParseStyle) { std::string input = ""; ASSERT_TRUE(testParse(input)); Style* style = test::getValue"; ASSERT_TRUE(testParse(input)); Style* style = test::getValue