1*d57664e9SAndroid Build Coastguard Worker /*
2*d57664e9SAndroid Build Coastguard Worker * Copyright (C) 2015 The Android Open Source Project
3*d57664e9SAndroid Build Coastguard Worker *
4*d57664e9SAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
5*d57664e9SAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
6*d57664e9SAndroid Build Coastguard Worker * You may obtain a copy of the License at
7*d57664e9SAndroid Build Coastguard Worker *
8*d57664e9SAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
9*d57664e9SAndroid Build Coastguard Worker *
10*d57664e9SAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
11*d57664e9SAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
12*d57664e9SAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*d57664e9SAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
14*d57664e9SAndroid Build Coastguard Worker * limitations under the License.
15*d57664e9SAndroid Build Coastguard Worker */
16*d57664e9SAndroid Build Coastguard Worker
17*d57664e9SAndroid Build Coastguard Worker #include "ResourceTable.h"
18*d57664e9SAndroid Build Coastguard Worker
19*d57664e9SAndroid Build Coastguard Worker #include <algorithm>
20*d57664e9SAndroid Build Coastguard Worker #include <ostream>
21*d57664e9SAndroid Build Coastguard Worker #include <string>
22*d57664e9SAndroid Build Coastguard Worker
23*d57664e9SAndroid Build Coastguard Worker #include "ResourceValues.h"
24*d57664e9SAndroid Build Coastguard Worker #include "androidfw/IDiagnostics.h"
25*d57664e9SAndroid Build Coastguard Worker #include "test/Test.h"
26*d57664e9SAndroid Build Coastguard Worker #include "util/Util.h"
27*d57664e9SAndroid Build Coastguard Worker
28*d57664e9SAndroid Build Coastguard Worker using ::android::ConfigDescription;
29*d57664e9SAndroid Build Coastguard Worker using ::android::StringPiece;
30*d57664e9SAndroid Build Coastguard Worker using ::testing::Eq;
31*d57664e9SAndroid Build Coastguard Worker using ::testing::NotNull;
32*d57664e9SAndroid Build Coastguard Worker using ::testing::StrEq;
33*d57664e9SAndroid Build Coastguard Worker
34*d57664e9SAndroid Build Coastguard Worker using PolicyFlags = android::ResTable_overlayable_policy_header::PolicyFlags;
35*d57664e9SAndroid Build Coastguard Worker
36*d57664e9SAndroid Build Coastguard Worker namespace aapt {
37*d57664e9SAndroid Build Coastguard Worker
TEST(ResourceTableTest,FailToAddResourceWithBadName)38*d57664e9SAndroid Build Coastguard Worker TEST(ResourceTableTest, FailToAddResourceWithBadName) {
39*d57664e9SAndroid Build Coastguard Worker ResourceTable table;
40*d57664e9SAndroid Build Coastguard Worker
41*d57664e9SAndroid Build Coastguard Worker EXPECT_FALSE(
42*d57664e9SAndroid Build Coastguard Worker table.AddResource(NewResourceBuilder(test::ParseNameOrDie("android:id/hey,there")).Build(),
43*d57664e9SAndroid Build Coastguard Worker test::GetDiagnostics()));
44*d57664e9SAndroid Build Coastguard Worker
45*d57664e9SAndroid Build Coastguard Worker EXPECT_FALSE(
46*d57664e9SAndroid Build Coastguard Worker table.AddResource(NewResourceBuilder(test::ParseNameOrDie("android:id/hey:there")).Build(),
47*d57664e9SAndroid Build Coastguard Worker test::GetDiagnostics()));
48*d57664e9SAndroid Build Coastguard Worker }
49*d57664e9SAndroid Build Coastguard Worker
TEST(ResourceTableTest,AddResourceWithWeirdNameWhenAddingMangledResources)50*d57664e9SAndroid Build Coastguard Worker TEST(ResourceTableTest, AddResourceWithWeirdNameWhenAddingMangledResources) {
51*d57664e9SAndroid Build Coastguard Worker ResourceTable table;
52*d57664e9SAndroid Build Coastguard Worker
53*d57664e9SAndroid Build Coastguard Worker EXPECT_TRUE(
54*d57664e9SAndroid Build Coastguard Worker table.AddResource(NewResourceBuilder(test::ParseNameOrDie("android:id/heythere "))
55*d57664e9SAndroid Build Coastguard Worker .SetAllowMangled(true)
56*d57664e9SAndroid Build Coastguard Worker .Build(),
57*d57664e9SAndroid Build Coastguard Worker test::GetDiagnostics()));
58*d57664e9SAndroid Build Coastguard Worker }
59*d57664e9SAndroid Build Coastguard Worker
TEST(ResourceTableTest,AddOneResource)60*d57664e9SAndroid Build Coastguard Worker TEST(ResourceTableTest, AddOneResource) {
61*d57664e9SAndroid Build Coastguard Worker ResourceTable table;
62*d57664e9SAndroid Build Coastguard Worker
63*d57664e9SAndroid Build Coastguard Worker EXPECT_TRUE(table.AddResource(
64*d57664e9SAndroid Build Coastguard Worker NewResourceBuilder(test::ParseNameOrDie("android:attr/id"))
65*d57664e9SAndroid Build Coastguard Worker .SetValue(test::ValueBuilder<Id>().SetSource("test/path/file.xml", 23u).Build())
66*d57664e9SAndroid Build Coastguard Worker .Build(),
67*d57664e9SAndroid Build Coastguard Worker test::GetDiagnostics()));
68*d57664e9SAndroid Build Coastguard Worker
69*d57664e9SAndroid Build Coastguard Worker EXPECT_THAT(test::GetValue<Id>(&table, "android:attr/id"), NotNull());
70*d57664e9SAndroid Build Coastguard Worker }
71*d57664e9SAndroid Build Coastguard Worker
TEST(ResourceTableTest,AddMultipleResources)72*d57664e9SAndroid Build Coastguard Worker TEST(ResourceTableTest, AddMultipleResources) {
73*d57664e9SAndroid Build Coastguard Worker ResourceTable table;
74*d57664e9SAndroid Build Coastguard Worker
75*d57664e9SAndroid Build Coastguard Worker ConfigDescription language_config;
76*d57664e9SAndroid Build Coastguard Worker memcpy(language_config.language, "pl", sizeof(language_config.language));
77*d57664e9SAndroid Build Coastguard Worker
78*d57664e9SAndroid Build Coastguard Worker EXPECT_TRUE(table.AddResource(
79*d57664e9SAndroid Build Coastguard Worker NewResourceBuilder(test::ParseNameOrDie("android:attr/layout_width"))
80*d57664e9SAndroid Build Coastguard Worker .SetValue(test::ValueBuilder<Id>().SetSource("test/path/file.xml", 10u).Build())
81*d57664e9SAndroid Build Coastguard Worker .Build(),
82*d57664e9SAndroid Build Coastguard Worker test::GetDiagnostics()));
83*d57664e9SAndroid Build Coastguard Worker
84*d57664e9SAndroid Build Coastguard Worker EXPECT_TRUE(table.AddResource(
85*d57664e9SAndroid Build Coastguard Worker NewResourceBuilder(test::ParseNameOrDie("android:attr/id"))
86*d57664e9SAndroid Build Coastguard Worker .SetValue(test::ValueBuilder<Id>().SetSource("test/path/file.xml", 12u).Build())
87*d57664e9SAndroid Build Coastguard Worker .Build(),
88*d57664e9SAndroid Build Coastguard Worker test::GetDiagnostics()));
89*d57664e9SAndroid Build Coastguard Worker
90*d57664e9SAndroid Build Coastguard Worker EXPECT_TRUE(table.AddResource(
91*d57664e9SAndroid Build Coastguard Worker NewResourceBuilder(test::ParseNameOrDie("android:string/ok"))
92*d57664e9SAndroid Build Coastguard Worker .SetValue(test::ValueBuilder<Id>().SetSource("test/path/file.xml", 14u).Build())
93*d57664e9SAndroid Build Coastguard Worker .Build(),
94*d57664e9SAndroid Build Coastguard Worker test::GetDiagnostics()));
95*d57664e9SAndroid Build Coastguard Worker
96*d57664e9SAndroid Build Coastguard Worker EXPECT_TRUE(
97*d57664e9SAndroid Build Coastguard Worker table.AddResource(NewResourceBuilder(test::ParseNameOrDie("android:string/ok"))
98*d57664e9SAndroid Build Coastguard Worker .SetValue(test::ValueBuilder<BinaryPrimitive>(android::Res_value{})
99*d57664e9SAndroid Build Coastguard Worker .SetSource("test/path/file.xml", 20u)
100*d57664e9SAndroid Build Coastguard Worker .Build(),
101*d57664e9SAndroid Build Coastguard Worker language_config)
102*d57664e9SAndroid Build Coastguard Worker .Build(),
103*d57664e9SAndroid Build Coastguard Worker test::GetDiagnostics()));
104*d57664e9SAndroid Build Coastguard Worker
105*d57664e9SAndroid Build Coastguard Worker EXPECT_THAT(test::GetValue<Id>(&table, "android:attr/layout_width"), NotNull());
106*d57664e9SAndroid Build Coastguard Worker EXPECT_THAT(test::GetValue<Id>(&table, "android:attr/id"), NotNull());
107*d57664e9SAndroid Build Coastguard Worker EXPECT_THAT(test::GetValue<Id>(&table, "android:string/ok"), NotNull());
108*d57664e9SAndroid Build Coastguard Worker EXPECT_THAT(test::GetValueForConfig<BinaryPrimitive>(&table, "android:string/ok", language_config), NotNull());
109*d57664e9SAndroid Build Coastguard Worker }
110*d57664e9SAndroid Build Coastguard Worker
TEST(ResourceTableTest,OverrideWeakResourceValue)111*d57664e9SAndroid Build Coastguard Worker TEST(ResourceTableTest, OverrideWeakResourceValue) {
112*d57664e9SAndroid Build Coastguard Worker ResourceTable table;
113*d57664e9SAndroid Build Coastguard Worker ASSERT_TRUE(table.AddResource(NewResourceBuilder(test::ParseNameOrDie("android:attr/foo"))
114*d57664e9SAndroid Build Coastguard Worker .SetValue(test::AttributeBuilder().SetWeak(true).Build())
115*d57664e9SAndroid Build Coastguard Worker .Build(),
116*d57664e9SAndroid Build Coastguard Worker test::GetDiagnostics()));
117*d57664e9SAndroid Build Coastguard Worker
118*d57664e9SAndroid Build Coastguard Worker Attribute* attr = test::GetValue<Attribute>(&table, "android:attr/foo");
119*d57664e9SAndroid Build Coastguard Worker ASSERT_THAT(attr, NotNull());
120*d57664e9SAndroid Build Coastguard Worker EXPECT_TRUE(attr->IsWeak());
121*d57664e9SAndroid Build Coastguard Worker
122*d57664e9SAndroid Build Coastguard Worker ASSERT_TRUE(table.AddResource(NewResourceBuilder(test::ParseNameOrDie("android:attr/foo"))
123*d57664e9SAndroid Build Coastguard Worker .SetValue(util::make_unique<Attribute>())
124*d57664e9SAndroid Build Coastguard Worker .Build(),
125*d57664e9SAndroid Build Coastguard Worker test::GetDiagnostics()));
126*d57664e9SAndroid Build Coastguard Worker
127*d57664e9SAndroid Build Coastguard Worker attr = test::GetValue<Attribute>(&table, "android:attr/foo");
128*d57664e9SAndroid Build Coastguard Worker ASSERT_THAT(attr, NotNull());
129*d57664e9SAndroid Build Coastguard Worker EXPECT_FALSE(attr->IsWeak());
130*d57664e9SAndroid Build Coastguard Worker }
131*d57664e9SAndroid Build Coastguard Worker
TEST(ResourceTableTest,AllowCompatibleDuplicateAttributes)132*d57664e9SAndroid Build Coastguard Worker TEST(ResourceTableTest, AllowCompatibleDuplicateAttributes) {
133*d57664e9SAndroid Build Coastguard Worker ResourceTable table;
134*d57664e9SAndroid Build Coastguard Worker
135*d57664e9SAndroid Build Coastguard Worker const ResourceName name = test::ParseNameOrDie("android:attr/foo");
136*d57664e9SAndroid Build Coastguard Worker Attribute attr_one(android::ResTable_map::TYPE_STRING);
137*d57664e9SAndroid Build Coastguard Worker attr_one.SetWeak(true);
138*d57664e9SAndroid Build Coastguard Worker Attribute attr_two(android::ResTable_map::TYPE_STRING | android::ResTable_map::TYPE_REFERENCE);
139*d57664e9SAndroid Build Coastguard Worker attr_two.SetWeak(true);
140*d57664e9SAndroid Build Coastguard Worker
141*d57664e9SAndroid Build Coastguard Worker ASSERT_TRUE(table.AddResource(
142*d57664e9SAndroid Build Coastguard Worker NewResourceBuilder(name).SetValue(util::make_unique<Attribute>(attr_one)).Build(),
143*d57664e9SAndroid Build Coastguard Worker test::GetDiagnostics()));
144*d57664e9SAndroid Build Coastguard Worker ASSERT_TRUE(table.AddResource(
145*d57664e9SAndroid Build Coastguard Worker NewResourceBuilder(name).SetValue(util::make_unique<Attribute>(attr_two)).Build(),
146*d57664e9SAndroid Build Coastguard Worker test::GetDiagnostics()));
147*d57664e9SAndroid Build Coastguard Worker }
148*d57664e9SAndroid Build Coastguard Worker
TEST(ResourceTableTest,ProductVaryingValues)149*d57664e9SAndroid Build Coastguard Worker TEST(ResourceTableTest, ProductVaryingValues) {
150*d57664e9SAndroid Build Coastguard Worker ResourceTable table;
151*d57664e9SAndroid Build Coastguard Worker ASSERT_TRUE(table.AddResource(
152*d57664e9SAndroid Build Coastguard Worker NewResourceBuilder(test::ParseNameOrDie("android:string/foo"))
153*d57664e9SAndroid Build Coastguard Worker .SetValue(util::make_unique<Id>(), test::ParseConfigOrDie("land"), "tablet")
154*d57664e9SAndroid Build Coastguard Worker .Build(),
155*d57664e9SAndroid Build Coastguard Worker test::GetDiagnostics()));
156*d57664e9SAndroid Build Coastguard Worker
157*d57664e9SAndroid Build Coastguard Worker ASSERT_TRUE(table.AddResource(
158*d57664e9SAndroid Build Coastguard Worker NewResourceBuilder(test::ParseNameOrDie("android:string/foo"))
159*d57664e9SAndroid Build Coastguard Worker .SetValue(util::make_unique<Id>(), test::ParseConfigOrDie("land"), "phone")
160*d57664e9SAndroid Build Coastguard Worker .Build(),
161*d57664e9SAndroid Build Coastguard Worker test::GetDiagnostics()));
162*d57664e9SAndroid Build Coastguard Worker
163*d57664e9SAndroid Build Coastguard Worker EXPECT_THAT(test::GetValueForConfigAndProduct<Id>(&table, "android:string/foo",test::ParseConfigOrDie("land"), "tablet"), NotNull());
164*d57664e9SAndroid Build Coastguard Worker EXPECT_THAT(test::GetValueForConfigAndProduct<Id>(&table, "android:string/foo",test::ParseConfigOrDie("land"), "phone"), NotNull());
165*d57664e9SAndroid Build Coastguard Worker
166*d57664e9SAndroid Build Coastguard Worker std::optional<ResourceTable::SearchResult> sr =
167*d57664e9SAndroid Build Coastguard Worker table.FindResource(test::ParseNameOrDie("android:string/foo"));
168*d57664e9SAndroid Build Coastguard Worker ASSERT_TRUE(sr);
169*d57664e9SAndroid Build Coastguard Worker std::vector<ResourceConfigValue*> values =
170*d57664e9SAndroid Build Coastguard Worker sr.value().entry->FindAllValues(test::ParseConfigOrDie("land"));
171*d57664e9SAndroid Build Coastguard Worker ASSERT_EQ(2u, values.size());
172*d57664e9SAndroid Build Coastguard Worker EXPECT_EQ(std::string("phone"), values[0]->product);
173*d57664e9SAndroid Build Coastguard Worker EXPECT_EQ(std::string("tablet"), values[1]->product);
174*d57664e9SAndroid Build Coastguard Worker }
175*d57664e9SAndroid Build Coastguard Worker
LevelToString(Visibility::Level level)176*d57664e9SAndroid Build Coastguard Worker static StringPiece LevelToString(Visibility::Level level) {
177*d57664e9SAndroid Build Coastguard Worker switch (level) {
178*d57664e9SAndroid Build Coastguard Worker case Visibility::Level::kPrivate:
179*d57664e9SAndroid Build Coastguard Worker return "private";
180*d57664e9SAndroid Build Coastguard Worker case Visibility::Level::kPublic:
181*d57664e9SAndroid Build Coastguard Worker return "private";
182*d57664e9SAndroid Build Coastguard Worker default:
183*d57664e9SAndroid Build Coastguard Worker return "undefined";
184*d57664e9SAndroid Build Coastguard Worker }
185*d57664e9SAndroid Build Coastguard Worker }
186*d57664e9SAndroid Build Coastguard Worker
VisibilityOfResource(const ResourceTable & table,const ResourceNameRef & name,Visibility::Level level,StringPiece comment)187*d57664e9SAndroid Build Coastguard Worker static ::testing::AssertionResult VisibilityOfResource(const ResourceTable& table,
188*d57664e9SAndroid Build Coastguard Worker const ResourceNameRef& name,
189*d57664e9SAndroid Build Coastguard Worker Visibility::Level level,
190*d57664e9SAndroid Build Coastguard Worker StringPiece comment) {
191*d57664e9SAndroid Build Coastguard Worker std::optional<ResourceTable::SearchResult> result = table.FindResource(name);
192*d57664e9SAndroid Build Coastguard Worker if (!result) {
193*d57664e9SAndroid Build Coastguard Worker return ::testing::AssertionFailure() << "no resource '" << name << "' found in table";
194*d57664e9SAndroid Build Coastguard Worker }
195*d57664e9SAndroid Build Coastguard Worker
196*d57664e9SAndroid Build Coastguard Worker const Visibility& visibility = result.value().entry->visibility;
197*d57664e9SAndroid Build Coastguard Worker if (visibility.level != level) {
198*d57664e9SAndroid Build Coastguard Worker return ::testing::AssertionFailure() << "expected visibility " << LevelToString(level)
199*d57664e9SAndroid Build Coastguard Worker << " but got " << LevelToString(visibility.level);
200*d57664e9SAndroid Build Coastguard Worker }
201*d57664e9SAndroid Build Coastguard Worker
202*d57664e9SAndroid Build Coastguard Worker if (visibility.comment != comment) {
203*d57664e9SAndroid Build Coastguard Worker return ::testing::AssertionFailure() << "expected visibility comment '" << comment
204*d57664e9SAndroid Build Coastguard Worker << "' but got '" << visibility.comment << "'";
205*d57664e9SAndroid Build Coastguard Worker }
206*d57664e9SAndroid Build Coastguard Worker return ::testing::AssertionSuccess();
207*d57664e9SAndroid Build Coastguard Worker }
208*d57664e9SAndroid Build Coastguard Worker
TEST(ResourceTableTest,SetVisibility)209*d57664e9SAndroid Build Coastguard Worker TEST(ResourceTableTest, SetVisibility) {
210*d57664e9SAndroid Build Coastguard Worker using Level = Visibility::Level;
211*d57664e9SAndroid Build Coastguard Worker
212*d57664e9SAndroid Build Coastguard Worker ResourceTable table;
213*d57664e9SAndroid Build Coastguard Worker const ResourceName name = test::ParseNameOrDie("android:string/foo");
214*d57664e9SAndroid Build Coastguard Worker
215*d57664e9SAndroid Build Coastguard Worker Visibility visibility;
216*d57664e9SAndroid Build Coastguard Worker visibility.level = Visibility::Level::kPrivate;
217*d57664e9SAndroid Build Coastguard Worker visibility.comment = "private";
218*d57664e9SAndroid Build Coastguard Worker ASSERT_TRUE(table.AddResource(NewResourceBuilder(name).SetVisibility(visibility).Build(),
219*d57664e9SAndroid Build Coastguard Worker test::GetDiagnostics()));
220*d57664e9SAndroid Build Coastguard Worker ASSERT_TRUE(VisibilityOfResource(table, name, Level::kPrivate, "private"));
221*d57664e9SAndroid Build Coastguard Worker
222*d57664e9SAndroid Build Coastguard Worker visibility.level = Visibility::Level::kUndefined;
223*d57664e9SAndroid Build Coastguard Worker visibility.comment = "undefined";
224*d57664e9SAndroid Build Coastguard Worker ASSERT_TRUE(table.AddResource(NewResourceBuilder(name).SetVisibility(visibility).Build(),
225*d57664e9SAndroid Build Coastguard Worker test::GetDiagnostics()));
226*d57664e9SAndroid Build Coastguard Worker ASSERT_TRUE(VisibilityOfResource(table, name, Level::kPrivate, "private"));
227*d57664e9SAndroid Build Coastguard Worker
228*d57664e9SAndroid Build Coastguard Worker visibility.level = Visibility::Level::kPublic;
229*d57664e9SAndroid Build Coastguard Worker visibility.comment = "public";
230*d57664e9SAndroid Build Coastguard Worker ASSERT_TRUE(table.AddResource(NewResourceBuilder(name).SetVisibility(visibility).Build(),
231*d57664e9SAndroid Build Coastguard Worker test::GetDiagnostics()));
232*d57664e9SAndroid Build Coastguard Worker ASSERT_TRUE(VisibilityOfResource(table, name, Level::kPublic, "public"));
233*d57664e9SAndroid Build Coastguard Worker
234*d57664e9SAndroid Build Coastguard Worker visibility.level = Visibility::Level::kPrivate;
235*d57664e9SAndroid Build Coastguard Worker visibility.comment = "private";
236*d57664e9SAndroid Build Coastguard Worker ASSERT_TRUE(table.AddResource(NewResourceBuilder(name).SetVisibility(visibility).Build(),
237*d57664e9SAndroid Build Coastguard Worker test::GetDiagnostics()));
238*d57664e9SAndroid Build Coastguard Worker ASSERT_TRUE(VisibilityOfResource(table, name, Level::kPublic, "public"));
239*d57664e9SAndroid Build Coastguard Worker }
240*d57664e9SAndroid Build Coastguard Worker
TEST(ResourceTableTest,SetAllowNew)241*d57664e9SAndroid Build Coastguard Worker TEST(ResourceTableTest, SetAllowNew) {
242*d57664e9SAndroid Build Coastguard Worker ResourceTable table;
243*d57664e9SAndroid Build Coastguard Worker const ResourceName name = test::ParseNameOrDie("android:string/foo");
244*d57664e9SAndroid Build Coastguard Worker
245*d57664e9SAndroid Build Coastguard Worker AllowNew allow_new;
246*d57664e9SAndroid Build Coastguard Worker std::optional<ResourceTable::SearchResult> result;
247*d57664e9SAndroid Build Coastguard Worker
248*d57664e9SAndroid Build Coastguard Worker allow_new.comment = "first";
249*d57664e9SAndroid Build Coastguard Worker ASSERT_TRUE(table.AddResource(NewResourceBuilder(name).SetAllowNew(allow_new).Build(),
250*d57664e9SAndroid Build Coastguard Worker test::GetDiagnostics()));
251*d57664e9SAndroid Build Coastguard Worker result = table.FindResource(name);
252*d57664e9SAndroid Build Coastguard Worker ASSERT_TRUE(result);
253*d57664e9SAndroid Build Coastguard Worker ASSERT_TRUE(result.value().entry->allow_new);
254*d57664e9SAndroid Build Coastguard Worker ASSERT_THAT(result.value().entry->allow_new.value().comment, StrEq("first"));
255*d57664e9SAndroid Build Coastguard Worker
256*d57664e9SAndroid Build Coastguard Worker allow_new.comment = "second";
257*d57664e9SAndroid Build Coastguard Worker ASSERT_TRUE(table.AddResource(NewResourceBuilder(name).SetAllowNew(allow_new).Build(),
258*d57664e9SAndroid Build Coastguard Worker test::GetDiagnostics()));
259*d57664e9SAndroid Build Coastguard Worker result = table.FindResource(name);
260*d57664e9SAndroid Build Coastguard Worker ASSERT_TRUE(result);
261*d57664e9SAndroid Build Coastguard Worker ASSERT_TRUE(result.value().entry->allow_new);
262*d57664e9SAndroid Build Coastguard Worker ASSERT_THAT(result.value().entry->allow_new.value().comment, StrEq("second"));
263*d57664e9SAndroid Build Coastguard Worker }
264*d57664e9SAndroid Build Coastguard Worker
TEST(ResourceTableTest,SetOverlayable)265*d57664e9SAndroid Build Coastguard Worker TEST(ResourceTableTest, SetOverlayable) {
266*d57664e9SAndroid Build Coastguard Worker ResourceTable table;
267*d57664e9SAndroid Build Coastguard Worker auto overlayable = std::make_shared<Overlayable>(
268*d57664e9SAndroid Build Coastguard Worker "Name", "overlay://theme", android::Source("res/values/overlayable.xml", 40));
269*d57664e9SAndroid Build Coastguard Worker OverlayableItem overlayable_item(overlayable);
270*d57664e9SAndroid Build Coastguard Worker overlayable_item.policies |= PolicyFlags::PRODUCT_PARTITION;
271*d57664e9SAndroid Build Coastguard Worker overlayable_item.policies |= PolicyFlags::VENDOR_PARTITION;
272*d57664e9SAndroid Build Coastguard Worker overlayable_item.comment = "comment";
273*d57664e9SAndroid Build Coastguard Worker overlayable_item.source = android::Source("res/values/overlayable.xml", 42);
274*d57664e9SAndroid Build Coastguard Worker
275*d57664e9SAndroid Build Coastguard Worker const ResourceName name = test::ParseNameOrDie("android:string/foo");
276*d57664e9SAndroid Build Coastguard Worker ASSERT_TRUE(table.AddResource(NewResourceBuilder(name).SetOverlayable(overlayable_item).Build(),
277*d57664e9SAndroid Build Coastguard Worker test::GetDiagnostics()));
278*d57664e9SAndroid Build Coastguard Worker std::optional<ResourceTable::SearchResult> search_result = table.FindResource(name);
279*d57664e9SAndroid Build Coastguard Worker
280*d57664e9SAndroid Build Coastguard Worker ASSERT_TRUE(search_result);
281*d57664e9SAndroid Build Coastguard Worker ASSERT_TRUE(search_result.value().entry->overlayable_item);
282*d57664e9SAndroid Build Coastguard Worker
283*d57664e9SAndroid Build Coastguard Worker OverlayableItem& result_overlayable_item = search_result.value().entry->overlayable_item.value();
284*d57664e9SAndroid Build Coastguard Worker EXPECT_THAT(result_overlayable_item.overlayable->name, Eq("Name"));
285*d57664e9SAndroid Build Coastguard Worker EXPECT_THAT(result_overlayable_item.overlayable->actor, Eq("overlay://theme"));
286*d57664e9SAndroid Build Coastguard Worker EXPECT_THAT(result_overlayable_item.overlayable->source.path, Eq("res/values/overlayable.xml"));
287*d57664e9SAndroid Build Coastguard Worker EXPECT_THAT(result_overlayable_item.overlayable->source.line, 40);
288*d57664e9SAndroid Build Coastguard Worker EXPECT_THAT(result_overlayable_item.policies, Eq(PolicyFlags::PRODUCT_PARTITION
289*d57664e9SAndroid Build Coastguard Worker | PolicyFlags::VENDOR_PARTITION));
290*d57664e9SAndroid Build Coastguard Worker ASSERT_THAT(result_overlayable_item.comment, StrEq("comment"));
291*d57664e9SAndroid Build Coastguard Worker EXPECT_THAT(result_overlayable_item.source.path, Eq("res/values/overlayable.xml"));
292*d57664e9SAndroid Build Coastguard Worker EXPECT_THAT(result_overlayable_item.source.line, 42);
293*d57664e9SAndroid Build Coastguard Worker }
294*d57664e9SAndroid Build Coastguard Worker
TEST(ResourceTableTest,SetMultipleOverlayableResources)295*d57664e9SAndroid Build Coastguard Worker TEST(ResourceTableTest, SetMultipleOverlayableResources) {
296*d57664e9SAndroid Build Coastguard Worker ResourceTable table;
297*d57664e9SAndroid Build Coastguard Worker
298*d57664e9SAndroid Build Coastguard Worker const ResourceName foo = test::ParseNameOrDie("android:string/foo");
299*d57664e9SAndroid Build Coastguard Worker auto group = std::make_shared<Overlayable>("Name", "overlay://theme");
300*d57664e9SAndroid Build Coastguard Worker OverlayableItem overlayable(group);
301*d57664e9SAndroid Build Coastguard Worker overlayable.policies = PolicyFlags::PRODUCT_PARTITION;
302*d57664e9SAndroid Build Coastguard Worker ASSERT_TRUE(table.AddResource(NewResourceBuilder(foo).SetOverlayable(overlayable).Build(),
303*d57664e9SAndroid Build Coastguard Worker test::GetDiagnostics()));
304*d57664e9SAndroid Build Coastguard Worker
305*d57664e9SAndroid Build Coastguard Worker const ResourceName bar = test::ParseNameOrDie("android:string/bar");
306*d57664e9SAndroid Build Coastguard Worker OverlayableItem overlayable2(group);
307*d57664e9SAndroid Build Coastguard Worker overlayable2.policies = PolicyFlags::PRODUCT_PARTITION;
308*d57664e9SAndroid Build Coastguard Worker ASSERT_TRUE(table.AddResource(NewResourceBuilder(bar).SetOverlayable(overlayable2).Build(),
309*d57664e9SAndroid Build Coastguard Worker test::GetDiagnostics()));
310*d57664e9SAndroid Build Coastguard Worker
311*d57664e9SAndroid Build Coastguard Worker const ResourceName baz = test::ParseNameOrDie("android:string/baz");
312*d57664e9SAndroid Build Coastguard Worker OverlayableItem overlayable3(group);
313*d57664e9SAndroid Build Coastguard Worker overlayable3.policies = PolicyFlags::VENDOR_PARTITION;
314*d57664e9SAndroid Build Coastguard Worker ASSERT_TRUE(table.AddResource(NewResourceBuilder(baz).SetOverlayable(overlayable3).Build(),
315*d57664e9SAndroid Build Coastguard Worker test::GetDiagnostics()));
316*d57664e9SAndroid Build Coastguard Worker }
317*d57664e9SAndroid Build Coastguard Worker
TEST(ResourceTableTest,SetOverlayableDifferentResourcesDifferentName)318*d57664e9SAndroid Build Coastguard Worker TEST(ResourceTableTest, SetOverlayableDifferentResourcesDifferentName) {
319*d57664e9SAndroid Build Coastguard Worker ResourceTable table;
320*d57664e9SAndroid Build Coastguard Worker
321*d57664e9SAndroid Build Coastguard Worker const ResourceName foo = test::ParseNameOrDie("android:string/foo");
322*d57664e9SAndroid Build Coastguard Worker OverlayableItem overlayable_item(std::make_shared<Overlayable>("Name", "overlay://theme"));
323*d57664e9SAndroid Build Coastguard Worker overlayable_item.policies = PolicyFlags::PRODUCT_PARTITION;
324*d57664e9SAndroid Build Coastguard Worker ASSERT_TRUE(table.AddResource(NewResourceBuilder(foo).SetOverlayable(overlayable_item).Build(),
325*d57664e9SAndroid Build Coastguard Worker test::GetDiagnostics()));
326*d57664e9SAndroid Build Coastguard Worker
327*d57664e9SAndroid Build Coastguard Worker const ResourceName bar = test::ParseNameOrDie("android:string/bar");
328*d57664e9SAndroid Build Coastguard Worker OverlayableItem overlayable_item2(std::make_shared<Overlayable>("Name2", "overlay://theme"));
329*d57664e9SAndroid Build Coastguard Worker overlayable_item2.policies = PolicyFlags::PRODUCT_PARTITION;
330*d57664e9SAndroid Build Coastguard Worker ASSERT_TRUE(table.AddResource(NewResourceBuilder(bar).SetOverlayable(overlayable_item2).Build(),
331*d57664e9SAndroid Build Coastguard Worker test::GetDiagnostics()));
332*d57664e9SAndroid Build Coastguard Worker }
333*d57664e9SAndroid Build Coastguard Worker
TEST(ResourceTableTest,SetOverlayableSameResourcesFail)334*d57664e9SAndroid Build Coastguard Worker TEST(ResourceTableTest, SetOverlayableSameResourcesFail) {
335*d57664e9SAndroid Build Coastguard Worker ResourceTable table;
336*d57664e9SAndroid Build Coastguard Worker const ResourceName name = test::ParseNameOrDie("android:string/foo");
337*d57664e9SAndroid Build Coastguard Worker
338*d57664e9SAndroid Build Coastguard Worker auto overlayable = std::make_shared<Overlayable>("Name", "overlay://theme");
339*d57664e9SAndroid Build Coastguard Worker OverlayableItem overlayable_item(overlayable);
340*d57664e9SAndroid Build Coastguard Worker ASSERT_TRUE(table.AddResource(NewResourceBuilder(name).SetOverlayable(overlayable_item).Build(),
341*d57664e9SAndroid Build Coastguard Worker test::GetDiagnostics()));
342*d57664e9SAndroid Build Coastguard Worker
343*d57664e9SAndroid Build Coastguard Worker OverlayableItem overlayable_item2(overlayable);
344*d57664e9SAndroid Build Coastguard Worker ASSERT_FALSE(table.AddResource(NewResourceBuilder(name).SetOverlayable(overlayable_item2).Build(),
345*d57664e9SAndroid Build Coastguard Worker test::GetDiagnostics()));
346*d57664e9SAndroid Build Coastguard Worker }
347*d57664e9SAndroid Build Coastguard Worker
TEST(ResourceTableTest,SetOverlayableSameResourcesDifferentNameFail)348*d57664e9SAndroid Build Coastguard Worker TEST(ResourceTableTest, SetOverlayableSameResourcesDifferentNameFail) {
349*d57664e9SAndroid Build Coastguard Worker ResourceTable table;
350*d57664e9SAndroid Build Coastguard Worker const ResourceName name = test::ParseNameOrDie("android:string/foo");
351*d57664e9SAndroid Build Coastguard Worker
352*d57664e9SAndroid Build Coastguard Worker auto overlayable = std::make_shared<Overlayable>("Name", "overlay://theme");
353*d57664e9SAndroid Build Coastguard Worker OverlayableItem overlayable_item(overlayable);
354*d57664e9SAndroid Build Coastguard Worker ASSERT_TRUE(table.AddResource(NewResourceBuilder(name).SetOverlayable(overlayable_item).Build(),
355*d57664e9SAndroid Build Coastguard Worker test::GetDiagnostics()));
356*d57664e9SAndroid Build Coastguard Worker
357*d57664e9SAndroid Build Coastguard Worker auto overlayable2 = std::make_shared<Overlayable>("Other", "overlay://theme");
358*d57664e9SAndroid Build Coastguard Worker OverlayableItem overlayable_item2(overlayable2);
359*d57664e9SAndroid Build Coastguard Worker ASSERT_FALSE(table.AddResource(NewResourceBuilder(name).SetOverlayable(overlayable_item2).Build(),
360*d57664e9SAndroid Build Coastguard Worker test::GetDiagnostics()));
361*d57664e9SAndroid Build Coastguard Worker }
362*d57664e9SAndroid Build Coastguard Worker
TEST(ResourceTableTest,ConflictingIds)363*d57664e9SAndroid Build Coastguard Worker TEST(ResourceTableTest, ConflictingIds) {
364*d57664e9SAndroid Build Coastguard Worker ResourceTable table;
365*d57664e9SAndroid Build Coastguard Worker const ResourceName name = test::ParseNameOrDie("android:string/foo");
366*d57664e9SAndroid Build Coastguard Worker ASSERT_TRUE(table.AddResource(NewResourceBuilder(name).SetId(0x01010000).Build(),
367*d57664e9SAndroid Build Coastguard Worker test::GetDiagnostics()));
368*d57664e9SAndroid Build Coastguard Worker ASSERT_FALSE(table.AddResource(NewResourceBuilder(name).SetId(0x01010001).Build(),
369*d57664e9SAndroid Build Coastguard Worker test::GetDiagnostics()));
370*d57664e9SAndroid Build Coastguard Worker }
371*d57664e9SAndroid Build Coastguard Worker
TEST(ResourceTableTest,ConflictingIdsCreateEntry)372*d57664e9SAndroid Build Coastguard Worker TEST(ResourceTableTest, ConflictingIdsCreateEntry) {
373*d57664e9SAndroid Build Coastguard Worker ResourceTable table;
374*d57664e9SAndroid Build Coastguard Worker const ResourceName name = test::ParseNameOrDie("android:string/foo");
375*d57664e9SAndroid Build Coastguard Worker ASSERT_TRUE(table.AddResource(
376*d57664e9SAndroid Build Coastguard Worker NewResourceBuilder(name).SetId(0x01010000, OnIdConflict::CREATE_ENTRY).Build(),
377*d57664e9SAndroid Build Coastguard Worker test::GetDiagnostics()));
378*d57664e9SAndroid Build Coastguard Worker ASSERT_TRUE(table.AddResource(
379*d57664e9SAndroid Build Coastguard Worker NewResourceBuilder(name).SetId(0x01010001, OnIdConflict::CREATE_ENTRY).Build(),
380*d57664e9SAndroid Build Coastguard Worker test::GetDiagnostics()));
381*d57664e9SAndroid Build Coastguard Worker
382*d57664e9SAndroid Build Coastguard Worker // Non-ambiguous query
383*d57664e9SAndroid Build Coastguard Worker ASSERT_TRUE(table.AddResource(
384*d57664e9SAndroid Build Coastguard Worker NewResourceBuilder(name).SetId(0x01010001).SetValue(std::make_unique<Id>()).Build(),
385*d57664e9SAndroid Build Coastguard Worker test::GetDiagnostics()));
386*d57664e9SAndroid Build Coastguard Worker }
387*d57664e9SAndroid Build Coastguard Worker
388*d57664e9SAndroid Build Coastguard Worker } // namespace aapt
389