blob: 70a33f795f8737b5ca1454642bf84d2ddcdf7f52 [file] [log] [blame]
Adam Lesinski59e04c62016-02-04 15:59:23 -08001/*
2 * Copyright (C) 2016 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 "ResourceTable.h"
18#include "proto/ProtoSerialize.h"
19#include "test/Builders.h"
20#include "test/Common.h"
21#include "test/Context.h"
22
23#include <gtest/gtest.h>
24
25namespace aapt {
26
27TEST(TableProtoSerializer, SerializeSinglePackage) {
28 std::unique_ptr<IAaptContext> context = test::ContextBuilder().build();
29 std::unique_ptr<ResourceTable> table = test::ResourceTableBuilder()
30 .setPackageId(u"com.app.a", 0x7f)
31 .addFileReference(u"@com.app.a:layout/main", ResourceId(0x7f020000),
32 u"res/layout/main.xml")
33 .addReference(u"@com.app.a:layout/other", ResourceId(0x7f020001),
34 u"@com.app.a:layout/main")
35 .addString(u"@com.app.a:string/text", {}, u"hi")
36 .addValue(u"@com.app.a:id/foo", {}, util::make_unique<Id>())
37 .build();
38
39 Symbol publicSymbol;
40 publicSymbol.state = SymbolState::kPublic;
41 ASSERT_TRUE(table->setSymbolState(test::parseNameOrDie(u"@com.app.a:layout/main"),
42 ResourceId(0x7f020000),
43 publicSymbol, context->getDiagnostics()));
44
45 Id* id = test::getValue<Id>(table.get(), u"@com.app.a:id/foo");
46 ASSERT_NE(nullptr, id);
47
48 // Make a plural.
49 std::unique_ptr<Plural> plural = util::make_unique<Plural>();
50 plural->values[Plural::One] = util::make_unique<String>(table->stringPool.makeRef(u"one"));
51 ASSERT_TRUE(table->addResource(test::parseNameOrDie(u"@com.app.a:plurals/hey"),
Adam Lesinskie4bb9eb2016-02-12 22:18:51 -080052 ConfigDescription{}, std::string(), std::move(plural),
Adam Lesinski59e04c62016-02-04 15:59:23 -080053 context->getDiagnostics()));
54
Adam Lesinskie4bb9eb2016-02-12 22:18:51 -080055 // Make a resource with different products.
56 ASSERT_TRUE(table->addResource(test::parseNameOrDie(u"@com.app.a:integer/one"),
57 test::parseConfigOrDie("land"), std::string(),
58 test::buildPrimitive(android::Res_value::TYPE_INT_DEC, 123u),
59 context->getDiagnostics()));
60 ASSERT_TRUE(table->addResource(test::parseNameOrDie(u"@com.app.a:integer/one"),
61 test::parseConfigOrDie("land"), std::string("tablet"),
62 test::buildPrimitive(android::Res_value::TYPE_INT_DEC, 321u),
63 context->getDiagnostics()));
64
Adam Lesinski59e04c62016-02-04 15:59:23 -080065 std::unique_ptr<pb::ResourceTable> pbTable = serializeTableToPb(table.get());
66 ASSERT_NE(nullptr, pbTable);
67
68 std::unique_ptr<ResourceTable> newTable = deserializeTableFromPb(*pbTable,
69 Source{ "test" },
70 context->getDiagnostics());
71 ASSERT_NE(nullptr, newTable);
72
73 Id* newId = test::getValue<Id>(newTable.get(), u"@com.app.a:id/foo");
74 ASSERT_NE(nullptr, newId);
75 EXPECT_EQ(id->isWeak(), newId->isWeak());
76
77 Maybe<ResourceTable::SearchResult> result = newTable->findResource(
78 test::parseNameOrDie(u"@com.app.a:layout/main"));
79 AAPT_ASSERT_TRUE(result);
80 EXPECT_EQ(SymbolState::kPublic, result.value().type->symbolStatus.state);
81 EXPECT_EQ(SymbolState::kPublic, result.value().entry->symbolStatus.state);
Adam Lesinskie4bb9eb2016-02-12 22:18:51 -080082
83 // Find the product-dependent values
84 BinaryPrimitive* prim = test::getValueForConfigAndProduct<BinaryPrimitive>(
85 newTable.get(), u"@com.app.a:integer/one", test::parseConfigOrDie("land"), "");
86 ASSERT_NE(nullptr, prim);
87 EXPECT_EQ(123u, prim->value.data);
88
89 prim = test::getValueForConfigAndProduct<BinaryPrimitive>(
90 newTable.get(), u"@com.app.a:integer/one", test::parseConfigOrDie("land"), "tablet");
91 ASSERT_NE(nullptr, prim);
92 EXPECT_EQ(321u, prim->value.data);
Adam Lesinski59e04c62016-02-04 15:59:23 -080093}
94
95TEST(TableProtoSerializer, SerializeFileHeader) {
96 std::unique_ptr<IAaptContext> context = test::ContextBuilder().build();
97
98 ResourceFile f;
99 f.config = test::parseConfigOrDie("hdpi-v9");
100 f.name = test::parseNameOrDie(u"@com.app.a:layout/main");
101 f.source.path = "res/layout-hdpi-v9/main.xml";
102 f.exportedSymbols.push_back(SourcedResourceName{ test::parseNameOrDie(u"@+id/unchecked"), 23u });
103
104 const std::string expectedData = "1234";
105
106 std::unique_ptr<pb::CompiledFile> pbFile = serializeCompiledFileToPb(f);
107
108 std::string outputStr;
109 {
110 google::protobuf::io::StringOutputStream outStream(&outputStr);
111 CompiledFileOutputStream outFileStream(&outStream, pbFile.get());
112
113 ASSERT_TRUE(outFileStream.Write(expectedData.data(), expectedData.size()));
114 ASSERT_TRUE(outFileStream.Finish());
115 }
116
117 CompiledFileInputStream inFileStream(outputStr.data(), outputStr.size());
118 const pb::CompiledFile* newPbFile = inFileStream.CompiledFile();
119 ASSERT_NE(nullptr, newPbFile);
120
121 std::unique_ptr<ResourceFile> file = deserializeCompiledFileFromPb(*newPbFile, Source{ "test" },
122 context->getDiagnostics());
123 ASSERT_NE(nullptr, file);
124
125 std::string actualData((const char*)inFileStream.data(), inFileStream.size());
126 EXPECT_EQ(expectedData, actualData);
127 EXPECT_EQ(0u, reinterpret_cast<uintptr_t>(inFileStream.data()) & 0x03);
128
129 ASSERT_EQ(1u, file->exportedSymbols.size());
130 EXPECT_EQ(test::parseNameOrDie(u"@+id/unchecked"), file->exportedSymbols[0].name);
131}
132
133} // namespace aapt