• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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