blob: eb75f947e0bef6eb5deeb3fe93ed4273baffde9b [file] [log] [blame]
Adam Lesinski6f6ceb72014-11-14 14:48:12 -08001/*
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 "ResourceTable.h"
Adam Lesinskicacb28f2016-10-19 12:18:14 -070018#include "Diagnostics.h"
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080019#include "ResourceValues.h"
Adam Lesinskid0f116b2016-07-08 15:00:32 -070020#include "test/Test.h"
Adam Lesinski1ab598f2015-08-14 14:26:04 -070021#include "util/Util.h"
22
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080023#include <algorithm>
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080024#include <ostream>
25#include <string>
26
Adam Lesinski71be7052017-12-12 16:48:07 -080027using ::android::StringPiece;
28using ::testing::Eq;
Adam Lesinskia45893a2017-05-30 15:19:02 -070029using ::testing::NotNull;
Adam Lesinski71be7052017-12-12 16:48:07 -080030using ::testing::StrEq;
Adam Lesinskia45893a2017-05-30 15:19:02 -070031
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080032namespace aapt {
33
Adam Lesinskicc5609d2016-04-05 12:41:07 -070034TEST(ResourceTableTest, FailToAddResourceWithBadName) {
Adam Lesinskicacb28f2016-10-19 12:18:14 -070035 ResourceTable table;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080036
Adam Lesinskice5e56e2016-10-21 17:56:45 -070037 EXPECT_FALSE(table.AddResource(
38 test::ParseNameOrDie("android:id/hey,there"), ConfigDescription{}, "",
39 test::ValueBuilder<Id>().SetSource("test.xml", 21u).Build(),
40 test::GetDiagnostics()));
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080041
Adam Lesinskice5e56e2016-10-21 17:56:45 -070042 EXPECT_FALSE(table.AddResource(
43 test::ParseNameOrDie("android:id/hey:there"), ConfigDescription{}, "",
44 test::ValueBuilder<Id>().SetSource("test.xml", 21u).Build(),
45 test::GetDiagnostics()));
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080046}
47
Adam Lesinskib1afa072017-03-29 13:52:38 -070048TEST(ResourceTableTest, AddResourceWithWeirdNameWhenAddingMangledResources) {
49 ResourceTable table;
50
Adam Lesinski71be7052017-12-12 16:48:07 -080051 EXPECT_TRUE(table.AddResourceMangled(
Adam Lesinskib1afa072017-03-29 13:52:38 -070052 test::ParseNameOrDie("android:id/heythere "), ConfigDescription{}, "",
53 test::ValueBuilder<Id>().SetSource("test.xml", 21u).Build(), test::GetDiagnostics()));
54}
55
Adam Lesinskicc5609d2016-04-05 12:41:07 -070056TEST(ResourceTableTest, AddOneResource) {
Adam Lesinskicacb28f2016-10-19 12:18:14 -070057 ResourceTable table;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080058
Adam Lesinskice5e56e2016-10-21 17:56:45 -070059 EXPECT_TRUE(table.AddResource(
60 test::ParseNameOrDie("android:attr/id"), ConfigDescription{}, "",
61 test::ValueBuilder<Id>().SetSource("test/path/file.xml", 23u).Build(),
62 test::GetDiagnostics()));
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080063
Adam Lesinskia45893a2017-05-30 15:19:02 -070064 EXPECT_THAT(test::GetValue<Id>(&table, "android:attr/id"), NotNull());
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080065}
66
Adam Lesinskicc5609d2016-04-05 12:41:07 -070067TEST(ResourceTableTest, AddMultipleResources) {
Adam Lesinskicacb28f2016-10-19 12:18:14 -070068 ResourceTable table;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080069
Adam Lesinskicacb28f2016-10-19 12:18:14 -070070 ConfigDescription config;
Adam Lesinskice5e56e2016-10-21 17:56:45 -070071 ConfigDescription language_config;
72 memcpy(language_config.language, "pl", sizeof(language_config.language));
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080073
Adam Lesinskice5e56e2016-10-21 17:56:45 -070074 EXPECT_TRUE(table.AddResource(
75 test::ParseNameOrDie("android:attr/layout_width"), config, "",
76 test::ValueBuilder<Id>().SetSource("test/path/file.xml", 10u).Build(),
77 test::GetDiagnostics()));
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080078
Adam Lesinskice5e56e2016-10-21 17:56:45 -070079 EXPECT_TRUE(table.AddResource(
80 test::ParseNameOrDie("android:attr/id"), config, "",
81 test::ValueBuilder<Id>().SetSource("test/path/file.xml", 12u).Build(),
82 test::GetDiagnostics()));
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080083
Adam Lesinskice5e56e2016-10-21 17:56:45 -070084 EXPECT_TRUE(table.AddResource(
85 test::ParseNameOrDie("android:string/ok"), config, "",
86 test::ValueBuilder<Id>().SetSource("test/path/file.xml", 14u).Build(),
87 test::GetDiagnostics()));
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080088
Adam Lesinskice5e56e2016-10-21 17:56:45 -070089 EXPECT_TRUE(table.AddResource(
90 test::ParseNameOrDie("android:string/ok"), language_config, "",
Adam Lesinskicacb28f2016-10-19 12:18:14 -070091 test::ValueBuilder<BinaryPrimitive>(android::Res_value{})
Adam Lesinskice5e56e2016-10-21 17:56:45 -070092 .SetSource("test/path/file.xml", 20u)
93 .Build(),
94 test::GetDiagnostics()));
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080095
Adam Lesinskia45893a2017-05-30 15:19:02 -070096 EXPECT_THAT(test::GetValue<Id>(&table, "android:attr/layout_width"), NotNull());
97 EXPECT_THAT(test::GetValue<Id>(&table, "android:attr/id"), NotNull());
98 EXPECT_THAT(test::GetValue<Id>(&table, "android:string/ok"), NotNull());
99 EXPECT_THAT(test::GetValueForConfig<BinaryPrimitive>(&table, "android:string/ok", language_config), NotNull());
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800100}
101
Adam Lesinskicc5609d2016-04-05 12:41:07 -0700102TEST(ResourceTableTest, OverrideWeakResourceValue) {
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700103 ResourceTable table;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800104
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700105 ASSERT_TRUE(table.AddResource(
106 test::ParseNameOrDie("android:attr/foo"), ConfigDescription{}, "",
107 util::make_unique<Attribute>(true), test::GetDiagnostics()));
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800108
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700109 Attribute* attr = test::GetValue<Attribute>(&table, "android:attr/foo");
Adam Lesinskia45893a2017-05-30 15:19:02 -0700110 ASSERT_THAT(attr, NotNull());
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700111 EXPECT_TRUE(attr->IsWeak());
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800112
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700113 ASSERT_TRUE(table.AddResource(
114 test::ParseNameOrDie("android:attr/foo"), ConfigDescription{}, "",
115 util::make_unique<Attribute>(false), test::GetDiagnostics()));
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800116
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700117 attr = test::GetValue<Attribute>(&table, "android:attr/foo");
Adam Lesinskia45893a2017-05-30 15:19:02 -0700118 ASSERT_THAT(attr, NotNull());
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700119 EXPECT_FALSE(attr->IsWeak());
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800120}
121
Adam Lesinskicc5609d2016-04-05 12:41:07 -0700122TEST(ResourceTableTest, ProductVaryingValues) {
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700123 ResourceTable table;
Adam Lesinskie4bb9eb2016-02-12 22:18:51 -0800124
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700125 EXPECT_TRUE(table.AddResource(test::ParseNameOrDie("android:string/foo"),
126 test::ParseConfigOrDie("land"), "tablet",
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700127 util::make_unique<Id>(),
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700128 test::GetDiagnostics()));
129 EXPECT_TRUE(table.AddResource(test::ParseNameOrDie("android:string/foo"),
130 test::ParseConfigOrDie("land"), "phone",
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700131 util::make_unique<Id>(),
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700132 test::GetDiagnostics()));
Adam Lesinskie4bb9eb2016-02-12 22:18:51 -0800133
Adam Lesinskia45893a2017-05-30 15:19:02 -0700134 EXPECT_THAT(test::GetValueForConfigAndProduct<Id>(&table, "android:string/foo",test::ParseConfigOrDie("land"), "tablet"), NotNull());
135 EXPECT_THAT(test::GetValueForConfigAndProduct<Id>(&table, "android:string/foo",test::ParseConfigOrDie("land"), "phone"), NotNull());
Adam Lesinskie4bb9eb2016-02-12 22:18:51 -0800136
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700137 Maybe<ResourceTable::SearchResult> sr =
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700138 table.FindResource(test::ParseNameOrDie("android:string/foo"));
Adam Lesinskia45893a2017-05-30 15:19:02 -0700139 ASSERT_TRUE(sr);
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700140 std::vector<ResourceConfigValue*> values =
Adam Lesinskib1afa072017-03-29 13:52:38 -0700141 sr.value().entry->FindAllValues(test::ParseConfigOrDie("land"));
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700142 ASSERT_EQ(2u, values.size());
143 EXPECT_EQ(std::string("phone"), values[0]->product);
144 EXPECT_EQ(std::string("tablet"), values[1]->product);
Adam Lesinskie4bb9eb2016-02-12 22:18:51 -0800145}
146
Adam Lesinski71be7052017-12-12 16:48:07 -0800147static StringPiece LevelToString(Visibility::Level level) {
148 switch (level) {
149 case Visibility::Level::kPrivate:
150 return "private";
151 case Visibility::Level::kPublic:
152 return "private";
153 default:
154 return "undefined";
155 }
156}
157
158static ::testing::AssertionResult VisibilityOfResource(const ResourceTable& table,
159 const ResourceNameRef& name,
160 Visibility::Level level,
161 const StringPiece& comment) {
162 Maybe<ResourceTable::SearchResult> result = table.FindResource(name);
163 if (!result) {
164 return ::testing::AssertionFailure() << "no resource '" << name << "' found in table";
165 }
166
167 const Visibility& visibility = result.value().entry->visibility;
168 if (visibility.level != level) {
169 return ::testing::AssertionFailure() << "expected visibility " << LevelToString(level)
170 << " but got " << LevelToString(visibility.level);
171 }
172
173 if (visibility.comment != comment) {
174 return ::testing::AssertionFailure() << "expected visibility comment '" << comment
175 << "' but got '" << visibility.comment << "'";
176 }
177 return ::testing::AssertionSuccess();
178}
179
180TEST(ResourceTableTest, SetVisibility) {
181 using Level = Visibility::Level;
182
183 ResourceTable table;
184 const ResourceName name = test::ParseNameOrDie("android:string/foo");
185
186 Visibility visibility;
187 visibility.level = Visibility::Level::kPrivate;
188 visibility.comment = "private";
189 ASSERT_TRUE(table.SetVisibility(name, visibility, test::GetDiagnostics()));
190 ASSERT_TRUE(VisibilityOfResource(table, name, Level::kPrivate, "private"));
191
192 visibility.level = Visibility::Level::kUndefined;
193 visibility.comment = "undefined";
194 ASSERT_TRUE(table.SetVisibility(name, visibility, test::GetDiagnostics()));
195 ASSERT_TRUE(VisibilityOfResource(table, name, Level::kPrivate, "private"));
196
197 visibility.level = Visibility::Level::kPublic;
198 visibility.comment = "public";
199 ASSERT_TRUE(table.SetVisibility(name, visibility, test::GetDiagnostics()));
200 ASSERT_TRUE(VisibilityOfResource(table, name, Level::kPublic, "public"));
201
202 visibility.level = Visibility::Level::kPrivate;
203 visibility.comment = "private";
204 ASSERT_TRUE(table.SetVisibility(name, visibility, test::GetDiagnostics()));
205 ASSERT_TRUE(VisibilityOfResource(table, name, Level::kPublic, "public"));
206}
207
208TEST(ResourceTableTest, SetAllowNew) {
209 ResourceTable table;
210 const ResourceName name = test::ParseNameOrDie("android:string/foo");
211
212 AllowNew allow_new;
213 Maybe<ResourceTable::SearchResult> result;
214
215 allow_new.comment = "first";
216 ASSERT_TRUE(table.SetAllowNew(name, allow_new, test::GetDiagnostics()));
217 result = table.FindResource(name);
218 ASSERT_TRUE(result);
219 ASSERT_TRUE(result.value().entry->allow_new);
220 ASSERT_THAT(result.value().entry->allow_new.value().comment, StrEq("first"));
221
222 allow_new.comment = "second";
223 ASSERT_TRUE(table.SetAllowNew(name, allow_new, test::GetDiagnostics()));
224 result = table.FindResource(name);
225 ASSERT_TRUE(result);
226 ASSERT_TRUE(result.value().entry->allow_new);
227 ASSERT_THAT(result.value().entry->allow_new.value().comment, StrEq("second"));
228}
229
230TEST(ResourceTableTest, SetOverlayable) {
231 ResourceTable table;
232 const ResourceName name = test::ParseNameOrDie("android:string/foo");
233
234 Overlayable overlayable;
235
236 overlayable.comment = "first";
237 ASSERT_TRUE(table.SetOverlayable(name, overlayable, test::GetDiagnostics()));
238 Maybe<ResourceTable::SearchResult> result = table.FindResource(name);
239 ASSERT_TRUE(result);
240 ASSERT_TRUE(result.value().entry->overlayable);
241 ASSERT_THAT(result.value().entry->overlayable.value().comment, StrEq("first"));
242
243 overlayable.comment = "second";
244 ASSERT_FALSE(table.SetOverlayable(name, overlayable, test::GetDiagnostics()));
245}
246
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700247} // namespace aapt