1 /*
2 * Copyright (C) 2015 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 "compile/IdAssigner.h"
18
19 #include "test/Context.h"
20 #include "test/Builders.h"
21
22 #include <gtest/gtest.h>
23
24 namespace aapt {
25
26 ::testing::AssertionResult verifyIds(ResourceTable* table);
27
TEST(IdAssignerTest,AssignIds)28 TEST(IdAssignerTest, AssignIds) {
29 std::unique_ptr<ResourceTable> table = test::ResourceTableBuilder()
30 .addSimple(u"@android:attr/foo")
31 .addSimple(u"@android:attr/bar")
32 .addSimple(u"@android:id/foo")
33 .setPackageId(u"android", 0x01)
34 .build();
35
36 std::unique_ptr<IAaptContext> context = test::ContextBuilder().build();
37 IdAssigner assigner;
38
39 ASSERT_TRUE(assigner.consume(context.get(), table.get()));
40 ASSERT_TRUE(verifyIds(table.get()));
41 }
42
TEST(IdAssignerTest,AssignIdsWithReservedIds)43 TEST(IdAssignerTest, AssignIdsWithReservedIds) {
44 std::unique_ptr<ResourceTable> table = test::ResourceTableBuilder()
45 .addSimple(u"@android:attr/foo", ResourceId(0x01040006))
46 .addSimple(u"@android:attr/bar")
47 .addSimple(u"@android:id/foo")
48 .addSimple(u"@app:id/biz")
49 .setPackageId(u"android", 0x01)
50 .setPackageId(u"app", 0x7f)
51 .build();
52
53 std::unique_ptr<IAaptContext> context = test::ContextBuilder().build();
54 IdAssigner assigner;
55
56 ASSERT_TRUE(assigner.consume(context.get(), table.get()));
57 ASSERT_TRUE(verifyIds(table.get()));
58 }
59
TEST(IdAssignerTest,FailWhenNonUniqueIdsAssigned)60 TEST(IdAssignerTest, FailWhenNonUniqueIdsAssigned) {
61 std::unique_ptr<ResourceTable> table = test::ResourceTableBuilder()
62 .addSimple(u"@android:attr/foo", ResourceId(0x01040006))
63 .addSimple(u"@android:attr/bar", ResourceId(0x01040006))
64 .setPackageId(u"android", 0x01)
65 .setPackageId(u"app", 0x7f)
66 .build();
67
68 std::unique_ptr<IAaptContext> context = test::ContextBuilder().build();
69 IdAssigner assigner;
70
71 ASSERT_FALSE(assigner.consume(context.get(), table.get()));
72 }
73
verifyIds(ResourceTable * table)74 ::testing::AssertionResult verifyIds(ResourceTable* table) {
75 std::set<uint8_t> packageIds;
76 for (auto& package : table->packages) {
77 if (!package->id) {
78 return ::testing::AssertionFailure() << "package " << package->name << " has no ID";
79 }
80
81 if (!packageIds.insert(package->id.value()).second) {
82 return ::testing::AssertionFailure() << "package " << package->name
83 << " has non-unique ID " << std::hex << (int) package->id.value() << std::dec;
84 }
85 }
86
87 for (auto& package : table->packages) {
88 std::set<uint8_t> typeIds;
89 for (auto& type : package->types) {
90 if (!type->id) {
91 return ::testing::AssertionFailure() << "type " << type->type << " of package "
92 << package->name << " has no ID";
93 }
94
95 if (!typeIds.insert(type->id.value()).second) {
96 return ::testing::AssertionFailure() << "type " << type->type
97 << " of package " << package->name << " has non-unique ID "
98 << std::hex << (int) type->id.value() << std::dec;
99 }
100 }
101
102
103 for (auto& type : package->types) {
104 std::set<uint16_t> entryIds;
105 for (auto& entry : type->entries) {
106 if (!entry->id) {
107 return ::testing::AssertionFailure() << "entry " << entry->name << " of type "
108 << type->type << " of package " << package->name << " has no ID";
109 }
110
111 if (!entryIds.insert(entry->id.value()).second) {
112 return ::testing::AssertionFailure() << "entry " << entry->name
113 << " of type " << type->type << " of package " << package->name
114 << " has non-unique ID "
115 << std::hex << (int) entry->id.value() << std::dec;
116 }
117 }
118 }
119 }
120 return ::testing::AssertionSuccess() << "all IDs are unique and assigned";
121 }
122
123 } // namespace aapt
124