Previously the way to name resources in tests was to use reference notation (@[package:][type/]name). Now we use name notation (no @). Change-Id: I68f0a36562d89cc78c582d128f370d9556c58707
171 lines
7.4 KiB
C++
171 lines
7.4 KiB
C++
/*
|
|
* Copyright (C) 2016 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 "proto/ProtoSerialize.h"
|
|
#include "test/Test.h"
|
|
|
|
namespace aapt {
|
|
|
|
TEST(TableProtoSerializer, SerializeSinglePackage) {
|
|
std::unique_ptr<IAaptContext> context = test::ContextBuilder().build();
|
|
std::unique_ptr<ResourceTable> table = test::ResourceTableBuilder()
|
|
.setPackageId("com.app.a", 0x7f)
|
|
.addFileReference("com.app.a:layout/main", ResourceId(0x7f020000),
|
|
"res/layout/main.xml")
|
|
.addReference("com.app.a:layout/other", ResourceId(0x7f020001),
|
|
"com.app.a:layout/main")
|
|
.addString("com.app.a:string/text", {}, "hi")
|
|
.addValue("com.app.a:id/foo", {}, util::make_unique<Id>())
|
|
.build();
|
|
|
|
Symbol publicSymbol;
|
|
publicSymbol.state = SymbolState::kPublic;
|
|
ASSERT_TRUE(table->setSymbolState(test::parseNameOrDie("com.app.a:layout/main"),
|
|
ResourceId(0x7f020000),
|
|
publicSymbol, context->getDiagnostics()));
|
|
|
|
Id* id = test::getValue<Id>(table.get(), "com.app.a:id/foo");
|
|
ASSERT_NE(nullptr, id);
|
|
|
|
// Make a plural.
|
|
std::unique_ptr<Plural> plural = util::make_unique<Plural>();
|
|
plural->values[Plural::One] = util::make_unique<String>(table->stringPool.makeRef("one"));
|
|
ASSERT_TRUE(table->addResource(test::parseNameOrDie("com.app.a:plurals/hey"),
|
|
ConfigDescription{}, {}, std::move(plural),
|
|
context->getDiagnostics()));
|
|
|
|
// Make a resource with different products.
|
|
ASSERT_TRUE(table->addResource(test::parseNameOrDie("com.app.a:integer/one"),
|
|
test::parseConfigOrDie("land"), {},
|
|
test::buildPrimitive(android::Res_value::TYPE_INT_DEC, 123u),
|
|
context->getDiagnostics()));
|
|
ASSERT_TRUE(table->addResource(test::parseNameOrDie("com.app.a:integer/one"),
|
|
test::parseConfigOrDie("land"), "tablet",
|
|
test::buildPrimitive(android::Res_value::TYPE_INT_DEC, 321u),
|
|
context->getDiagnostics()));
|
|
|
|
// Make a reference with both resource name and resource ID.
|
|
// The reference should point to a resource outside of this table to test that both
|
|
// name and id get serialized.
|
|
Reference expectedRef;
|
|
expectedRef.name = test::parseNameOrDie("android:layout/main");
|
|
expectedRef.id = ResourceId(0x01020000);
|
|
ASSERT_TRUE(table->addResource(test::parseNameOrDie("com.app.a:layout/abc"),
|
|
ConfigDescription::defaultConfig(), {},
|
|
util::make_unique<Reference>(expectedRef),
|
|
context->getDiagnostics()));
|
|
|
|
std::unique_ptr<pb::ResourceTable> pbTable = serializeTableToPb(table.get());
|
|
ASSERT_NE(nullptr, pbTable);
|
|
|
|
std::unique_ptr<ResourceTable> newTable = deserializeTableFromPb(*pbTable,
|
|
Source{ "test" },
|
|
context->getDiagnostics());
|
|
ASSERT_NE(nullptr, newTable);
|
|
|
|
Id* newId = test::getValue<Id>(newTable.get(), "com.app.a:id/foo");
|
|
ASSERT_NE(nullptr, newId);
|
|
EXPECT_EQ(id->isWeak(), newId->isWeak());
|
|
|
|
Maybe<ResourceTable::SearchResult> result = newTable->findResource(
|
|
test::parseNameOrDie("com.app.a:layout/main"));
|
|
AAPT_ASSERT_TRUE(result);
|
|
EXPECT_EQ(SymbolState::kPublic, result.value().type->symbolStatus.state);
|
|
EXPECT_EQ(SymbolState::kPublic, result.value().entry->symbolStatus.state);
|
|
|
|
// Find the product-dependent values
|
|
BinaryPrimitive* prim = test::getValueForConfigAndProduct<BinaryPrimitive>(
|
|
newTable.get(), "com.app.a:integer/one", test::parseConfigOrDie("land"), "");
|
|
ASSERT_NE(nullptr, prim);
|
|
EXPECT_EQ(123u, prim->value.data);
|
|
|
|
prim = test::getValueForConfigAndProduct<BinaryPrimitive>(
|
|
newTable.get(), "com.app.a:integer/one", test::parseConfigOrDie("land"), "tablet");
|
|
ASSERT_NE(nullptr, prim);
|
|
EXPECT_EQ(321u, prim->value.data);
|
|
|
|
Reference* actualRef = test::getValue<Reference>(newTable.get(), "com.app.a:layout/abc");
|
|
ASSERT_NE(nullptr, actualRef);
|
|
AAPT_ASSERT_TRUE(actualRef->name);
|
|
AAPT_ASSERT_TRUE(actualRef->id);
|
|
EXPECT_EQ(expectedRef.name.value(), actualRef->name.value());
|
|
EXPECT_EQ(expectedRef.id.value(), actualRef->id.value());
|
|
}
|
|
|
|
TEST(TableProtoSerializer, SerializeFileHeader) {
|
|
std::unique_ptr<IAaptContext> context = test::ContextBuilder().build();
|
|
|
|
ResourceFile f;
|
|
f.config = test::parseConfigOrDie("hdpi-v9");
|
|
f.name = test::parseNameOrDie("com.app.a:layout/main");
|
|
f.source.path = "res/layout-hdpi-v9/main.xml";
|
|
f.exportedSymbols.push_back(SourcedResourceName{ test::parseNameOrDie("id/unchecked"), 23u });
|
|
|
|
const std::string expectedData = "1234";
|
|
|
|
std::unique_ptr<pb::CompiledFile> pbFile = serializeCompiledFileToPb(f);
|
|
|
|
std::string outputStr;
|
|
{
|
|
google::protobuf::io::StringOutputStream outStream(&outputStr);
|
|
CompiledFileOutputStream outFileStream(&outStream, pbFile.get());
|
|
|
|
ASSERT_TRUE(outFileStream.Write(expectedData.data(), expectedData.size()));
|
|
ASSERT_TRUE(outFileStream.Finish());
|
|
}
|
|
|
|
CompiledFileInputStream inFileStream(outputStr.data(), outputStr.size());
|
|
const pb::CompiledFile* newPbFile = inFileStream.CompiledFile();
|
|
ASSERT_NE(nullptr, newPbFile);
|
|
|
|
std::unique_ptr<ResourceFile> file = deserializeCompiledFileFromPb(*newPbFile, Source("test"),
|
|
context->getDiagnostics());
|
|
ASSERT_NE(nullptr, file);
|
|
|
|
std::string actualData((const char*)inFileStream.data(), inFileStream.size());
|
|
EXPECT_EQ(expectedData, actualData);
|
|
EXPECT_EQ(0u, reinterpret_cast<uintptr_t>(inFileStream.data()) & 0x03);
|
|
|
|
ASSERT_EQ(1u, file->exportedSymbols.size());
|
|
EXPECT_EQ(test::parseNameOrDie("id/unchecked"), file->exportedSymbols[0].name);
|
|
}
|
|
|
|
TEST(TableProtoSerializer, DeserializeCorruptHeaderSafely) {
|
|
ResourceFile f;
|
|
std::unique_ptr<pb::CompiledFile> pbFile = serializeCompiledFileToPb(f);
|
|
|
|
const std::string expectedData = "1234";
|
|
|
|
std::string outputStr;
|
|
{
|
|
google::protobuf::io::StringOutputStream outStream(&outputStr);
|
|
CompiledFileOutputStream outFileStream(&outStream, pbFile.get());
|
|
|
|
ASSERT_TRUE(outFileStream.Write(expectedData.data(), expectedData.size()));
|
|
ASSERT_TRUE(outFileStream.Finish());
|
|
}
|
|
|
|
outputStr[0] = 0xff;
|
|
|
|
CompiledFileInputStream inFileStream(outputStr.data(), outputStr.size());
|
|
EXPECT_EQ(nullptr, inFileStream.CompiledFile());
|
|
EXPECT_EQ(nullptr, inFileStream.data());
|
|
EXPECT_EQ(0u, inFileStream.size());
|
|
}
|
|
|
|
} // namespace aapt
|