AAPT2: Separate out the various steps
An early refactor. Some ideas became clearer as
development continued. Now the various phases are much
clearer and more easily reusable.
Also added a ton of tests!
Change-Id: Ic8f0a70c8222370352e63533b329c40457c0903e
diff --git a/tools/aapt2/ResourceParser_test.cpp b/tools/aapt2/ResourceParser_test.cpp
index a93d0ff..cb98afd 100644
--- a/tools/aapt2/ResourceParser_test.cpp
+++ b/tools/aapt2/ResourceParser_test.cpp
@@ -16,8 +16,11 @@
#include "ResourceParser.h"
#include "ResourceTable.h"
+#include "ResourceUtils.h"
#include "ResourceValues.h"
-#include "SourceXmlPullParser.h"
+#include "XmlPullParser.h"
+
+#include "test/Context.h"
#include <gtest/gtest.h>
#include <sstream>
@@ -27,156 +30,41 @@
constexpr const char* kXmlPreamble = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n";
-TEST(ResourceParserReferenceTest, ParseReferenceWithNoPackage) {
- ResourceNameRef expected = { {}, ResourceType::kColor, u"foo" };
- ResourceNameRef actual;
- bool create = false;
- bool privateRef = false;
- EXPECT_TRUE(ResourceParser::tryParseReference(u"@color/foo", &actual, &create, &privateRef));
- EXPECT_EQ(expected, actual);
- EXPECT_FALSE(create);
- EXPECT_FALSE(privateRef);
-}
-
-TEST(ResourceParserReferenceTest, ParseReferenceWithPackage) {
- ResourceNameRef expected = { u"android", ResourceType::kColor, u"foo" };
- ResourceNameRef actual;
- bool create = false;
- bool privateRef = false;
- EXPECT_TRUE(ResourceParser::tryParseReference(u"@android:color/foo", &actual, &create,
- &privateRef));
- EXPECT_EQ(expected, actual);
- EXPECT_FALSE(create);
- EXPECT_FALSE(privateRef);
-}
-
-TEST(ResourceParserReferenceTest, ParseReferenceWithSurroundingWhitespace) {
- ResourceNameRef expected = { u"android", ResourceType::kColor, u"foo" };
- ResourceNameRef actual;
- bool create = false;
- bool privateRef = false;
- EXPECT_TRUE(ResourceParser::tryParseReference(u"\t @android:color/foo\n \n\t", &actual,
- &create, &privateRef));
- EXPECT_EQ(expected, actual);
- EXPECT_FALSE(create);
- EXPECT_FALSE(privateRef);
-}
-
-TEST(ResourceParserReferenceTest, ParseAutoCreateIdReference) {
- ResourceNameRef expected = { u"android", ResourceType::kId, u"foo" };
- ResourceNameRef actual;
- bool create = false;
- bool privateRef = false;
- EXPECT_TRUE(ResourceParser::tryParseReference(u"@+android:id/foo", &actual, &create,
- &privateRef));
- EXPECT_EQ(expected, actual);
- EXPECT_TRUE(create);
- EXPECT_FALSE(privateRef);
-}
-
-TEST(ResourceParserReferenceTest, ParsePrivateReference) {
- ResourceNameRef expected = { u"android", ResourceType::kId, u"foo" };
- ResourceNameRef actual;
- bool create = false;
- bool privateRef = false;
- EXPECT_TRUE(ResourceParser::tryParseReference(u"@*android:id/foo", &actual, &create,
- &privateRef));
- EXPECT_EQ(expected, actual);
- EXPECT_FALSE(create);
- EXPECT_TRUE(privateRef);
-}
-
-TEST(ResourceParserReferenceTest, FailToParseAutoCreateNonIdReference) {
- bool create = false;
- bool privateRef = false;
- ResourceNameRef actual;
- EXPECT_FALSE(ResourceParser::tryParseReference(u"@+android:color/foo", &actual, &create,
- &privateRef));
-}
-
-TEST(ResourceParserReferenceTest, ParseStyleParentReference) {
- Reference ref;
- std::string errStr;
- EXPECT_TRUE(ResourceParser::parseStyleParentReference(u"@android:style/foo", &ref, &errStr));
- EXPECT_EQ(ref.name, (ResourceName{ u"android", ResourceType::kStyle, u"foo" }));
-
- EXPECT_TRUE(ResourceParser::parseStyleParentReference(u"@style/foo", &ref, &errStr));
- EXPECT_EQ(ref.name, (ResourceName{ {}, ResourceType::kStyle, u"foo" }));
-
- EXPECT_TRUE(ResourceParser::parseStyleParentReference(u"?android:style/foo", &ref, &errStr));
- EXPECT_EQ(ref.name, (ResourceName{ u"android", ResourceType::kStyle, u"foo" }));
-
- EXPECT_TRUE(ResourceParser::parseStyleParentReference(u"?style/foo", &ref, &errStr));
- EXPECT_EQ(ref.name, (ResourceName{ {}, ResourceType::kStyle, u"foo" }));
-
- EXPECT_TRUE(ResourceParser::parseStyleParentReference(u"android:style/foo", &ref, &errStr));
- EXPECT_EQ(ref.name, (ResourceName{ u"android", ResourceType::kStyle, u"foo" }));
-
- EXPECT_TRUE(ResourceParser::parseStyleParentReference(u"android:foo", &ref, &errStr));
- EXPECT_EQ(ref.name, (ResourceName{ u"android", ResourceType::kStyle, u"foo" }));
-
- EXPECT_TRUE(ResourceParser::parseStyleParentReference(u"foo", &ref, &errStr));
- EXPECT_EQ(ref.name, (ResourceName{ {}, ResourceType::kStyle, u"foo" }));
+TEST(ResourceParserSingleTest, FailToParseWithNoRootResourcesElement) {
+ std::unique_ptr<IAaptContext> context = test::ContextBuilder().build();
+ std::stringstream input(kXmlPreamble);
+ input << "<attr name=\"foo\"/>" << std::endl;
+ ResourceTable table;
+ ResourceParser parser(context->getDiagnostics(), &table, Source{ "test" }, {});
+ XmlPullParser xmlParser(input);
+ ASSERT_FALSE(parser.parse(&xmlParser));
}
struct ResourceParserTest : public ::testing::Test {
- virtual void SetUp() override {
- mTable = std::make_shared<ResourceTable>();
- mTable->setPackage(u"android");
+ ResourceTable mTable;
+ std::unique_ptr<IAaptContext> mContext;
+
+ void SetUp() override {
+ mContext = test::ContextBuilder().build();
}
::testing::AssertionResult testParse(const StringPiece& str) {
std::stringstream input(kXmlPreamble);
input << "<resources>\n" << str << "\n</resources>" << std::endl;
- ResourceParser parser(mTable, Source{ "test" }, {},
- std::make_shared<SourceXmlPullParser>(input));
- if (parser.parse()) {
+ ResourceParser parser(mContext->getDiagnostics(), &mTable, Source{ "test" }, {});
+ XmlPullParser xmlParser(input);
+ if (parser.parse(&xmlParser)) {
return ::testing::AssertionSuccess();
}
return ::testing::AssertionFailure();
}
-
- template <typename T>
- const T* findResource(const ResourceNameRef& name, const ConfigDescription& config) {
- using std::begin;
- using std::end;
-
- const ResourceTableType* type;
- const ResourceEntry* entry;
- std::tie(type, entry) = mTable->findResource(name);
- if (!type || !entry) {
- return nullptr;
- }
-
- for (const auto& configValue : entry->values) {
- if (configValue.config == config) {
- return dynamic_cast<const T*>(configValue.value.get());
- }
- }
- return nullptr;
- }
-
- template <typename T>
- const T* findResource(const ResourceNameRef& name) {
- return findResource<T>(name, {});
- }
-
- std::shared_ptr<ResourceTable> mTable;
};
-TEST_F(ResourceParserTest, FailToParseWithNoRootResourcesElement) {
- std::stringstream input(kXmlPreamble);
- input << "<attr name=\"foo\"/>" << std::endl;
- ResourceParser parser(mTable, {}, {}, std::make_shared<SourceXmlPullParser>(input));
- ASSERT_FALSE(parser.parse());
-}
-
TEST_F(ResourceParserTest, ParseQuotedString) {
std::string input = "<string name=\"foo\"> \" hey there \" </string>";
ASSERT_TRUE(testParse(input));
- const String* str = findResource<String>(ResourceName{
- u"android", ResourceType::kString, u"foo"});
+ String* str = test::getValue<String>(&mTable, u"@string/foo");
ASSERT_NE(nullptr, str);
EXPECT_EQ(std::u16string(u" hey there "), *str->value);
}
@@ -185,12 +73,22 @@
std::string input = "<string name=\"foo\">\\?123</string>";
ASSERT_TRUE(testParse(input));
- const String* str = findResource<String>(ResourceName{
- u"android", ResourceType::kString, u"foo" });
+ String* str = test::getValue<String>(&mTable, u"@string/foo");
ASSERT_NE(nullptr, str);
EXPECT_EQ(std::u16string(u"?123"), *str->value);
}
+TEST_F(ResourceParserTest, IgnoreXliffTags) {
+ std::string input = "<string name=\"foo\" \n"
+ " xmlns:xliff=\"urn:oasis:names:tc:xliff:document:1.2\">\n"
+ " There are <xliff:g id=\"count\">%1$d</xliff:g> apples</string>";
+ ASSERT_TRUE(testParse(input));
+
+ String* str = test::getValue<String>(&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 = "<integer name=\"foo\">@null</integer>";
ASSERT_TRUE(testParse(input));
@@ -199,8 +97,7 @@
// 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.
- const BinaryPrimitive* integer = findResource<BinaryPrimitive>(ResourceName{
- u"android", ResourceType::kInteger, u"foo" });
+ BinaryPrimitive* integer = test::getValue<BinaryPrimitive>(&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);
@@ -210,8 +107,7 @@
std::string input = "<integer name=\"foo\">@empty</integer>";
ASSERT_TRUE(testParse(input));
- const BinaryPrimitive* integer = findResource<BinaryPrimitive>(ResourceName{
- u"android", ResourceType::kInteger, u"foo" });
+ BinaryPrimitive* integer = test::getValue<BinaryPrimitive>(&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);
@@ -222,14 +118,12 @@
"<attr name=\"bar\"/>";
ASSERT_TRUE(testParse(input));
- const Attribute* attr = findResource<Attribute>(ResourceName{
- u"android", ResourceType::kAttr, u"foo"});
- EXPECT_NE(nullptr, attr);
+ Attribute* attr = test::getValue<Attribute>(&mTable, u"@attr/foo");
+ ASSERT_NE(nullptr, attr);
EXPECT_EQ(uint32_t(android::ResTable_map::TYPE_STRING), attr->typeMask);
- attr = findResource<Attribute>(ResourceName{
- u"android", ResourceType::kAttr, u"bar"});
- EXPECT_NE(nullptr, attr);
+ attr = test::getValue<Attribute>(&mTable, u"@attr/bar");
+ ASSERT_NE(nullptr, attr);
EXPECT_EQ(uint32_t(android::ResTable_map::TYPE_ANY), attr->typeMask);
}
@@ -240,8 +134,7 @@
"<attr name=\"foo\" format=\"string\"/>";
ASSERT_TRUE(testParse(input));
- const Attribute* attr = findResource<Attribute>(ResourceName{
- u"android", ResourceType::kAttr, u"foo"});
+ Attribute* attr = test::getValue<Attribute>(&mTable, u"@attr/foo");
ASSERT_NE(nullptr, attr);
EXPECT_EQ(uint32_t(android::ResTable_map::TYPE_STRING), attr->typeMask);
}
@@ -255,8 +148,7 @@
"</declare-styleable>";
ASSERT_TRUE(testParse(input));
- const Attribute* attr = findResource<Attribute>(ResourceName{
- u"android", ResourceType::kAttr, u"foo"});
+ Attribute* attr = test::getValue<Attribute>(&mTable, u"@attr/foo");
ASSERT_NE(nullptr, attr);
EXPECT_EQ(uint32_t(android::ResTable_map::TYPE_BOOLEAN), attr->typeMask);
}
@@ -269,19 +161,21 @@
"</attr>";
ASSERT_TRUE(testParse(input));
- const Attribute* enumAttr = findResource<Attribute>(ResourceName{
- u"android", ResourceType::kAttr, u"foo"});
+ Attribute* enumAttr = test::getValue<Attribute>(&mTable, u"@attr/foo");
ASSERT_NE(enumAttr, nullptr);
EXPECT_EQ(enumAttr->typeMask, android::ResTable_map::TYPE_ENUM);
ASSERT_EQ(enumAttr->symbols.size(), 3u);
- EXPECT_EQ(enumAttr->symbols[0].symbol.name.entry, u"bar");
+ 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);
- EXPECT_EQ(enumAttr->symbols[1].symbol.name.entry, u"bat");
+ 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);
- EXPECT_EQ(enumAttr->symbols[2].symbol.name.entry, u"baz");
+ 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);
}
@@ -293,23 +187,25 @@
"</attr>";
ASSERT_TRUE(testParse(input));
- const Attribute* flagAttr = findResource<Attribute>(ResourceName{
- u"android", ResourceType::kAttr, u"foo"});
+ Attribute* flagAttr = test::getValue<Attribute>(&mTable, u"@attr/foo");
ASSERT_NE(flagAttr, nullptr);
EXPECT_EQ(flagAttr->typeMask, android::ResTable_map::TYPE_FLAGS);
ASSERT_EQ(flagAttr->symbols.size(), 3u);
- EXPECT_EQ(flagAttr->symbols[0].symbol.name.entry, u"bar");
+ 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);
- EXPECT_EQ(flagAttr->symbols[1].symbol.name.entry, u"bat");
+ 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);
- EXPECT_EQ(flagAttr->symbols[2].symbol.name.entry, u"baz");
+ 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<BinaryPrimitive> flagValue =
- ResourceParser::tryParseFlagSymbol(*flagAttr, u"baz|bat");
+ std::unique_ptr<BinaryPrimitive> flagValue = ResourceUtils::tryParseFlagSymbol(flagAttr,
+ u"baz|bat");
ASSERT_NE(flagValue, nullptr);
EXPECT_EQ(flagValue->value.data, 1u | 2u);
}
@@ -331,28 +227,32 @@
"</style>";
ASSERT_TRUE(testParse(input));
- const Style* style = findResource<Style>(ResourceName{
- u"android", ResourceType::kStyle, u"foo"});
+ Style* style = test::getValue<Style>(&mTable, u"@style/foo");
ASSERT_NE(style, nullptr);
- EXPECT_EQ(ResourceNameRef(u"android", ResourceType::kStyle, u"fu"), style->parent.name);
- ASSERT_EQ(style->entries.size(), 3u);
+ AAPT_ASSERT_TRUE(style->parent);
+ AAPT_ASSERT_TRUE(style->parent.value().name);
+ EXPECT_EQ(test::parseNameOrDie(u"@style/fu"), style->parent.value().name.value());
+ ASSERT_EQ(3u, style->entries.size());
- EXPECT_EQ(style->entries[0].key.name,
- (ResourceName{ u"android", ResourceType::kAttr, u"bar" }));
- EXPECT_EQ(style->entries[1].key.name,
- (ResourceName{ u"android", ResourceType::kAttr, u"bat" }));
- EXPECT_EQ(style->entries[2].key.name,
- (ResourceName{ u"android", ResourceType::kAttr, u"baz" }));
+ AAPT_ASSERT_TRUE(style->entries[0].key.name);
+ EXPECT_EQ(test::parseNameOrDie(u"@attr/bar"), style->entries[0].key.name.value());
+
+ AAPT_ASSERT_TRUE(style->entries[1].key.name);
+ EXPECT_EQ(test::parseNameOrDie(u"@attr/bat"), style->entries[1].key.name.value());
+
+ AAPT_ASSERT_TRUE(style->entries[2].key.name);
+ EXPECT_EQ(test::parseNameOrDie(u"@attr/baz"), style->entries[2].key.name.value());
}
TEST_F(ResourceParserTest, ParseStyleWithShorthandParent) {
std::string input = "<style name=\"foo\" parent=\"com.app:Theme\"/>";
ASSERT_TRUE(testParse(input));
- const Style* style = findResource<Style>(
- ResourceName{ u"android", ResourceType::kStyle, u"foo" });
+ Style* style = test::getValue<Style>(&mTable, u"@style/foo");
ASSERT_NE(style, nullptr);
- EXPECT_EQ(ResourceNameRef(u"com.app", ResourceType::kStyle, u"Theme"), style->parent.name);
+ AAPT_ASSERT_TRUE(style->parent);
+ AAPT_ASSERT_TRUE(style->parent.value().name);
+ EXPECT_EQ(test::parseNameOrDie(u"@com.app:style/Theme"), style->parent.value().name.value());
}
TEST_F(ResourceParserTest, ParseStyleWithPackageAliasedParent) {
@@ -360,10 +260,11 @@
" name=\"foo\" parent=\"app:Theme\"/>";
ASSERT_TRUE(testParse(input));
- const Style* style = findResource<Style>(ResourceName{
- u"android", ResourceType::kStyle, u"foo" });
+ Style* style = test::getValue<Style>(&mTable, u"@style/foo");
ASSERT_NE(style, nullptr);
- EXPECT_EQ(ResourceNameRef(u"android", ResourceType::kStyle, u"Theme"), style->parent.name);
+ AAPT_ASSERT_TRUE(style->parent);
+ AAPT_ASSERT_TRUE(style->parent.value().name);
+ EXPECT_EQ(test::parseNameOrDie(u"@android:style/Theme"), style->parent.value().name.value());
}
TEST_F(ResourceParserTest, ParseStyleWithPackageAliasedItems) {
@@ -373,22 +274,21 @@
"</style>";
ASSERT_TRUE(testParse(input));
- const Style* style = findResource<Style>(ResourceName{
- u"android", ResourceType::kStyle, u"foo" });
+ Style* style = test::getValue<Style>(&mTable, u"@style/foo");
ASSERT_NE(style, nullptr);
ASSERT_EQ(1u, style->entries.size());
- EXPECT_EQ(ResourceNameRef(u"android", ResourceType::kAttr, u"bar"),
- style->entries[0].key.name);
+ EXPECT_EQ(test::parseNameOrDie(u"@android:attr/bar"), style->entries[0].key.name.value());
}
TEST_F(ResourceParserTest, ParseStyleWithInferredParent) {
std::string input = "<style name=\"foo.bar\"/>";
ASSERT_TRUE(testParse(input));
- const Style* style = findResource<Style>(ResourceName{
- u"android", ResourceType::kStyle, u"foo.bar" });
+ Style* style = test::getValue<Style>(&mTable, u"@style/foo.bar");
ASSERT_NE(style, nullptr);
- EXPECT_EQ(style->parent.name, (ResourceName{ u"android", ResourceType::kStyle, u"foo" }));
+ AAPT_ASSERT_TRUE(style->parent);
+ AAPT_ASSERT_TRUE(style->parent.value().name);
+ EXPECT_EQ(style->parent.value().name.value(), test::parseNameOrDie(u"@style/foo"));
EXPECT_TRUE(style->parentInferred);
}
@@ -396,10 +296,9 @@
std::string input = "<style name=\"foo.bar\" parent=\"\"/>";
ASSERT_TRUE(testParse(input));
- const Style* style = findResource<Style>(ResourceName{
- u"android", ResourceType::kStyle, u"foo.bar" });
+ Style* style = test::getValue<Style>(&mTable, u"@style/foo.bar");
ASSERT_NE(style, nullptr);
- EXPECT_FALSE(style->parent.name.isValid());
+ AAPT_EXPECT_FALSE(style->parent);
EXPECT_FALSE(style->parentInferred);
}
@@ -407,7 +306,7 @@
std::string input = "<string name=\"foo\">@+id/bar</string>";
ASSERT_TRUE(testParse(input));
- const Id* id = findResource<Id>(ResourceName{ u"android", ResourceType::kId, u"bar"});
+ Id* id = test::getValue<Id>(&mTable, u"@id/bar");
ASSERT_NE(id, nullptr);
}
@@ -418,22 +317,20 @@
"</declare-styleable>";
ASSERT_TRUE(testParse(input));
- const Attribute* attr = findResource<Attribute>(ResourceName{
- u"android", ResourceType::kAttr, u"bar"});
+ Attribute* attr = test::getValue<Attribute>(&mTable, u"@attr/bar");
ASSERT_NE(attr, nullptr);
EXPECT_TRUE(attr->isWeak());
- attr = findResource<Attribute>(ResourceName{ u"android", ResourceType::kAttr, u"bat"});
+ attr = test::getValue<Attribute>(&mTable, u"@attr/bat");
ASSERT_NE(attr, nullptr);
EXPECT_TRUE(attr->isWeak());
- const Styleable* styleable = findResource<Styleable>(ResourceName{
- u"android", ResourceType::kStyleable, u"foo" });
+ Styleable* styleable = test::getValue<Styleable>(&mTable, u"@styleable/foo");
ASSERT_NE(styleable, nullptr);
ASSERT_EQ(2u, styleable->entries.size());
- EXPECT_EQ((ResourceName{u"android", ResourceType::kAttr, u"bar"}), styleable->entries[0].name);
- EXPECT_EQ((ResourceName{u"android", ResourceType::kAttr, u"bat"}), styleable->entries[1].name);
+ EXPECT_EQ(test::parseNameOrDie(u"@attr/bar"), styleable->entries[0].name.value());
+ EXPECT_EQ(test::parseNameOrDie(u"@attr/bat"), styleable->entries[1].name.value());
}
TEST_F(ResourceParserTest, ParseArray) {
@@ -444,14 +341,13 @@
"</array>";
ASSERT_TRUE(testParse(input));
- const Array* array = findResource<Array>(ResourceName{
- u"android", ResourceType::kArray, u"foo" });
+ Array* array = test::getValue<Array>(&mTable, u"@array/foo");
ASSERT_NE(array, nullptr);
ASSERT_EQ(3u, array->items.size());
- EXPECT_NE(nullptr, dynamic_cast<const Reference*>(array->items[0].get()));
- EXPECT_NE(nullptr, dynamic_cast<const String*>(array->items[1].get()));
- EXPECT_NE(nullptr, dynamic_cast<const BinaryPrimitive*>(array->items[2].get()));
+ EXPECT_NE(nullptr, valueCast<Reference>(array->items[0].get()));
+ EXPECT_NE(nullptr, valueCast<String>(array->items[1].get()));
+ EXPECT_NE(nullptr, valueCast<BinaryPrimitive>(array->items[2].get()));
}
TEST_F(ResourceParserTest, ParsePlural) {
@@ -467,11 +363,11 @@
"<string name=\"foo\">Hi</string>";
ASSERT_TRUE(testParse(input));
- const ResourceTableType* type;
- const ResourceEntry* entry;
- std::tie(type, entry) = mTable->findResource(ResourceName{
- u"android", ResourceType::kString, u"foo"});
- ASSERT_NE(type, nullptr);
+ Maybe<ResourceTable::SearchResult> result = mTable.findResource(
+ test::parseNameOrDie(u"@string/foo"));
+ AAPT_ASSERT_TRUE(result);
+
+ ResourceEntry* entry = result.value().entry;
ASSERT_NE(entry, nullptr);
ASSERT_FALSE(entry->values.empty());
EXPECT_EQ(entry->values.front().comment, u"This is a comment");
@@ -485,7 +381,7 @@
std::string input = "<public type=\"id\" name=\"foo\"/>";
ASSERT_TRUE(testParse(input));
- const Id* id = findResource<Id>(ResourceName{ u"android", ResourceType::kId, u"foo" });
+ Id* id = test::getValue<Id>(&mTable, u"@id/foo");
ASSERT_NE(nullptr, id);
}