diff options
Diffstat (limited to 'tools/aapt2/ResourceTable_test.cpp')
-rw-r--r-- | tools/aapt2/ResourceTable_test.cpp | 228 |
1 files changed, 228 insertions, 0 deletions
diff --git a/tools/aapt2/ResourceTable_test.cpp b/tools/aapt2/ResourceTable_test.cpp new file mode 100644 index 0000000..06d8699 --- /dev/null +++ b/tools/aapt2/ResourceTable_test.cpp @@ -0,0 +1,228 @@ +/* + * 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 "ResourceTable.h" +#include "ResourceValues.h" +#include "Util.h" + +#include <algorithm> +#include <gtest/gtest.h> +#include <ostream> +#include <string> + +namespace aapt { + +struct TestValue : public Value { + std::u16string value; + + TestValue(StringPiece16 str) : value(str.toString()) { + } + + TestValue* clone(StringPool* /*newPool*/) const override { + return new TestValue(value); + } + + void print(std::ostream& out) const override { + out << "(test) " << value; + } + + virtual void accept(ValueVisitor&, ValueVisitorArgs&&) override {} + virtual void accept(ConstValueVisitor&, ValueVisitorArgs&&) const override {} +}; + +struct TestWeakValue : public Value { + bool isWeak() const override { + return true; + } + + TestWeakValue* clone(StringPool* /*newPool*/) const override { + return new TestWeakValue(); + } + + void print(std::ostream& out) const override { + out << "(test) [weak]"; + } + + virtual void accept(ValueVisitor&, ValueVisitorArgs&&) override {} + virtual void accept(ConstValueVisitor&, ValueVisitorArgs&&) const override {} +}; + +TEST(ResourceTableTest, FailToAddResourceWithBadName) { + ResourceTable table; + table.setPackage(u"android"); + + EXPECT_FALSE(table.addResource( + ResourceNameRef{ u"android", ResourceType::kId, u"hey,there" }, + {}, SourceLine{ "test.xml", 21 }, + util::make_unique<TestValue>(u"rawValue"))); + + EXPECT_FALSE(table.addResource( + ResourceNameRef{ u"android", ResourceType::kId, u"hey:there" }, + {}, SourceLine{ "test.xml", 21 }, + util::make_unique<TestValue>(u"rawValue"))); +} + +TEST(ResourceTableTest, AddOneResource) { + const std::u16string kAndroidPackage = u"android"; + + ResourceTable table; + table.setPackage(kAndroidPackage); + + const ResourceName name = { kAndroidPackage, ResourceType::kAttr, u"id" }; + + EXPECT_TRUE(table.addResource(name, {}, SourceLine{ "test/path/file.xml", 23 }, + util::make_unique<TestValue>(u"rawValue"))); + + const ResourceTableType* type; + const ResourceEntry* entry; + std::tie(type, entry) = table.findResource(name); + ASSERT_NE(nullptr, type); + ASSERT_NE(nullptr, entry); + EXPECT_EQ(name.entry, entry->name); + + ASSERT_NE(std::end(entry->values), + std::find_if(std::begin(entry->values), std::end(entry->values), + [](const ResourceConfigValue& val) -> bool { + return val.config == ConfigDescription{}; + })); +} + +TEST(ResourceTableTest, AddMultipleResources) { + const std::u16string kAndroidPackage = u"android"; + ResourceTable table; + table.setPackage(kAndroidPackage); + + ConfigDescription config; + ConfigDescription languageConfig; + memcpy(languageConfig.language, "pl", sizeof(languageConfig.language)); + + EXPECT_TRUE(table.addResource( + ResourceName{ kAndroidPackage, ResourceType::kAttr, u"layout_width" }, + config, SourceLine{ "test/path/file.xml", 10 }, + util::make_unique<TestValue>(u"rawValue"))); + + EXPECT_TRUE(table.addResource( + ResourceName{ kAndroidPackage, ResourceType::kAttr, u"id" }, + config, SourceLine{ "test/path/file.xml", 12 }, + util::make_unique<TestValue>(u"rawValue"))); + + EXPECT_TRUE(table.addResource( + ResourceName{ kAndroidPackage, ResourceType::kString, u"ok" }, + config, SourceLine{ "test/path/file.xml", 14 }, + util::make_unique<TestValue>(u"Ok"))); + + EXPECT_TRUE(table.addResource( + ResourceName{ kAndroidPackage, ResourceType::kString, u"ok" }, + languageConfig, SourceLine{ "test/path/file.xml", 20 }, + util::make_unique<TestValue>(u"Tak"))); + + const auto endTypeIter = std::end(table); + auto typeIter = std::begin(table); + + ASSERT_NE(endTypeIter, typeIter); + EXPECT_EQ(ResourceType::kAttr, (*typeIter)->type); + + { + const std::unique_ptr<ResourceTableType>& type = *typeIter; + const auto endEntryIter = std::end(type->entries); + auto entryIter = std::begin(type->entries); + ASSERT_NE(endEntryIter, entryIter); + EXPECT_EQ(std::u16string(u"id"), (*entryIter)->name); + + ++entryIter; + ASSERT_NE(endEntryIter, entryIter); + EXPECT_EQ(std::u16string(u"layout_width"), (*entryIter)->name); + + ++entryIter; + ASSERT_EQ(endEntryIter, entryIter); + } + + ++typeIter; + ASSERT_NE(endTypeIter, typeIter); + EXPECT_EQ(ResourceType::kString, (*typeIter)->type); + + { + const std::unique_ptr<ResourceTableType>& type = *typeIter; + const auto endEntryIter = std::end(type->entries); + auto entryIter = std::begin(type->entries); + ASSERT_NE(endEntryIter, entryIter); + EXPECT_EQ(std::u16string(u"ok"), (*entryIter)->name); + + { + const std::unique_ptr<ResourceEntry>& entry = *entryIter; + const auto endConfigIter = std::end(entry->values); + auto configIter = std::begin(entry->values); + + ASSERT_NE(endConfigIter, configIter); + EXPECT_EQ(config, configIter->config); + const TestValue* value = + dynamic_cast<const TestValue*>(configIter->value.get()); + ASSERT_NE(nullptr, value); + EXPECT_EQ(std::u16string(u"Ok"), value->value); + + ++configIter; + ASSERT_NE(endConfigIter, configIter); + EXPECT_EQ(languageConfig, configIter->config); + EXPECT_NE(nullptr, configIter->value); + + value = dynamic_cast<const TestValue*>(configIter->value.get()); + ASSERT_NE(nullptr, value); + EXPECT_EQ(std::u16string(u"Tak"), value->value); + + ++configIter; + EXPECT_EQ(endConfigIter, configIter); + } + + ++entryIter; + ASSERT_EQ(endEntryIter, entryIter); + } + + ++typeIter; + EXPECT_EQ(endTypeIter, typeIter); +} + +TEST(ResourceTableTest, OverrideWeakResourceValue) { + const std::u16string kAndroid = u"android"; + + ResourceTable table; + table.setPackage(kAndroid); + table.setPackageId(0x01); + + ASSERT_TRUE(table.addResource( + ResourceName{ kAndroid, ResourceType::kAttr, u"foo" }, + {}, {}, util::make_unique<TestWeakValue>())); + + const ResourceTableType* type; + const ResourceEntry* entry; + std::tie(type, entry) = table.findResource( + ResourceNameRef{ kAndroid, ResourceType::kAttr, u"foo" }); + ASSERT_NE(nullptr, type); + ASSERT_NE(nullptr, entry); + ASSERT_EQ(entry->values.size(), 1u); + EXPECT_TRUE(entry->values.front().value->isWeak()); + + ASSERT_TRUE(table.addResource(ResourceName{ kAndroid, ResourceType::kAttr, u"foo" }, {}, {}, + util::make_unique<TestValue>(u"bar"))); + + std::tie(type, entry) = table.findResource( + ResourceNameRef{ kAndroid, ResourceType::kAttr, u"foo" }); + ASSERT_NE(nullptr, type); + ASSERT_NE(nullptr, entry); + ASSERT_EQ(entry->values.size(), 1u); + EXPECT_FALSE(entry->values.front().value->isWeak()); +} + +} // namespace aapt |