blob: e449546f9399b56fd6c77dc11217285b48c68843 [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
Adam Lesinskica5638f2015-10-21 14:42:43 -070017#include "java/JavaClassGenerator.h"
Adam Lesinski1ab598f2015-08-14 14:26:04 -070018
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080019#include <string>
20
Adam Lesinskia693c4a2017-11-09 11:29:39 -080021#include "io/StringStream.h"
Adam Lesinskice5e56e22016-10-21 17:56:45 -070022#include "test/Test.h"
23#include "util/Util.h"
24
Adam Lesinskia693c4a2017-11-09 11:29:39 -080025using ::aapt::io::StringOutputStream;
Adam Lesinski09f4d702017-08-08 10:39:55 -070026using ::android::StringPiece;
27using ::testing::HasSubstr;
Adam Lesinski761d4342017-09-29 11:15:17 -070028using ::testing::Lt;
29using ::testing::Ne;
Adam Lesinski09f4d702017-08-08 10:39:55 -070030using ::testing::Not;
Adam Lesinskid5083f62017-01-16 15:07:21 -080031
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080032namespace aapt {
33
Adam Lesinski1ab598f2015-08-14 14:26:04 -070034TEST(JavaClassGeneratorTest, FailWhenEntryIsJavaKeyword) {
Adam Lesinskice5e56e22016-10-21 17:56:45 -070035 std::unique_ptr<ResourceTable> table =
36 test::ResourceTableBuilder()
37 .SetPackageId("android", 0x01)
38 .AddSimple("android:id/class", ResourceId(0x01020000))
39 .Build();
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080040
Adam Lesinskice5e56e22016-10-21 17:56:45 -070041 std::unique_ptr<IAaptContext> context =
42 test::ContextBuilder()
43 .AddSymbolSource(
44 util::make_unique<ResourceTableSymbolSource>(table.get()))
45 .SetNameManglerPolicy(NameManglerPolicy{"android"})
46 .Build();
47 JavaClassGenerator generator(context.get(), table.get(), {});
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080048
Adam Lesinskia693c4a2017-11-09 11:29:39 -080049 std::string result;
50 StringOutputStream out(&result);
Adam Lesinskice5e56e22016-10-21 17:56:45 -070051 EXPECT_FALSE(generator.Generate("android", &out));
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080052}
53
Adam Lesinski1ab598f2015-08-14 14:26:04 -070054TEST(JavaClassGeneratorTest, TransformInvalidJavaIdentifierCharacter) {
Adam Lesinskice5e56e22016-10-21 17:56:45 -070055 std::unique_ptr<ResourceTable> table =
56 test::ResourceTableBuilder()
57 .SetPackageId("android", 0x01)
58 .AddSimple("android:id/hey-man", ResourceId(0x01020000))
59 .AddValue("android:attr/cool.attr", ResourceId(0x01010000),
Adam Lesinski73bff1e2017-12-08 16:06:10 -080060 test::AttributeBuilder().Build())
Adam Lesinski09f4d702017-08-08 10:39:55 -070061 .AddValue("android:styleable/hey.dude", ResourceId(0x01030000),
62 test::StyleableBuilder()
63 .AddItem("android:attr/cool.attr", ResourceId(0x01010000))
64 .Build())
Adam Lesinskice5e56e22016-10-21 17:56:45 -070065 .Build();
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080066
Adam Lesinskice5e56e22016-10-21 17:56:45 -070067 std::unique_ptr<IAaptContext> context =
68 test::ContextBuilder()
Adam Lesinski09f4d702017-08-08 10:39:55 -070069 .AddSymbolSource(util::make_unique<ResourceTableSymbolSource>(table.get()))
Adam Lesinskice5e56e22016-10-21 17:56:45 -070070 .SetNameManglerPolicy(NameManglerPolicy{"android"})
71 .Build();
72 JavaClassGenerator generator(context.get(), table.get(), {});
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080073
Adam Lesinskia693c4a2017-11-09 11:29:39 -080074 std::string output;
75 StringOutputStream out(&output);
Adam Lesinskice5e56e22016-10-21 17:56:45 -070076 EXPECT_TRUE(generator.Generate("android", &out));
Adam Lesinskia693c4a2017-11-09 11:29:39 -080077 out.Flush();
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080078
Adam Lesinski09f4d702017-08-08 10:39:55 -070079 EXPECT_THAT(output, HasSubstr("public static final int hey_man=0x01020000;"));
80 EXPECT_THAT(output, HasSubstr("public static final int[] hey_dude={"));
81 EXPECT_THAT(output, HasSubstr("public static final int hey_dude_cool_attr=0;"));
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080082}
83
Adam Lesinski9e10ac72015-10-16 14:37:48 -070084TEST(JavaClassGeneratorTest, CorrectPackageNameIsUsed) {
Adam Lesinskice5e56e22016-10-21 17:56:45 -070085 std::unique_ptr<ResourceTable> table =
86 test::ResourceTableBuilder()
87 .SetPackageId("android", 0x01)
88 .AddSimple("android:id/one", ResourceId(0x01020000))
89 .AddSimple("android:id/com.foo$two", ResourceId(0x01020001))
90 .Build();
Adam Lesinski9e10ac72015-10-16 14:37:48 -070091
Adam Lesinskice5e56e22016-10-21 17:56:45 -070092 std::unique_ptr<IAaptContext> context =
93 test::ContextBuilder()
Adam Lesinski09f4d702017-08-08 10:39:55 -070094 .AddSymbolSource(util::make_unique<ResourceTableSymbolSource>(table.get()))
Adam Lesinskice5e56e22016-10-21 17:56:45 -070095 .SetNameManglerPolicy(NameManglerPolicy{"android"})
96 .Build();
97 JavaClassGenerator generator(context.get(), table.get(), {});
Adam Lesinski9e10ac72015-10-16 14:37:48 -070098
Adam Lesinskia693c4a2017-11-09 11:29:39 -080099 std::string output;
100 StringOutputStream out(&output);
101 ASSERT_TRUE(generator.Generate("android", "com.android.internal", &out));
102 out.Flush();
103
Adam Lesinski09f4d702017-08-08 10:39:55 -0700104 EXPECT_THAT(output, HasSubstr("package com.android.internal;"));
105 EXPECT_THAT(output, HasSubstr("public static final int one=0x01020000;"));
106 EXPECT_THAT(output, Not(HasSubstr("two")));
107 EXPECT_THAT(output, Not(HasSubstr("com_foo$two")));
Adam Lesinski9e10ac72015-10-16 14:37:48 -0700108}
109
110TEST(JavaClassGeneratorTest, AttrPrivateIsWrittenAsAttr) {
Adam Lesinskice5e56e22016-10-21 17:56:45 -0700111 std::unique_ptr<ResourceTable> table =
112 test::ResourceTableBuilder()
113 .SetPackageId("android", 0x01)
114 .AddSimple("android:attr/two", ResourceId(0x01010001))
115 .AddSimple("android:^attr-private/one", ResourceId(0x01010000))
116 .Build();
Adam Lesinski9e10ac72015-10-16 14:37:48 -0700117
Adam Lesinskice5e56e22016-10-21 17:56:45 -0700118 std::unique_ptr<IAaptContext> context =
119 test::ContextBuilder()
Adam Lesinski09f4d702017-08-08 10:39:55 -0700120 .AddSymbolSource(util::make_unique<ResourceTableSymbolSource>(table.get()))
Adam Lesinskice5e56e22016-10-21 17:56:45 -0700121 .SetNameManglerPolicy(NameManglerPolicy{"android"})
122 .Build();
123 JavaClassGenerator generator(context.get(), table.get(), {});
Adam Lesinski9e10ac72015-10-16 14:37:48 -0700124
Adam Lesinskia693c4a2017-11-09 11:29:39 -0800125 std::string output;
126 StringOutputStream out(&output);
127 ASSERT_TRUE(generator.Generate("android", &out));
128 out.Flush();
129
Adam Lesinski09f4d702017-08-08 10:39:55 -0700130 EXPECT_THAT(output, HasSubstr("public static final class attr"));
131 EXPECT_THAT(output, Not(HasSubstr("public static final class ^attr-private")));
Adam Lesinski9e10ac72015-10-16 14:37:48 -0700132}
133
134TEST(JavaClassGeneratorTest, OnlyWritePublicResources) {
Adam Lesinskice5e56e22016-10-21 17:56:45 -0700135 StdErrDiagnostics diag;
136 std::unique_ptr<ResourceTable> table =
137 test::ResourceTableBuilder()
138 .SetPackageId("android", 0x01)
139 .AddSimple("android:id/one", ResourceId(0x01020000))
140 .AddSimple("android:id/two", ResourceId(0x01020001))
141 .AddSimple("android:id/three", ResourceId(0x01020002))
Adam Lesinski71be7052017-12-12 16:48:07 -0800142 .SetSymbolState("android:id/one", ResourceId(0x01020000), Visibility::Level::kPublic)
143 .SetSymbolState("android:id/two", ResourceId(0x01020001), Visibility::Level::kPrivate)
Adam Lesinskice5e56e22016-10-21 17:56:45 -0700144 .Build();
Adam Lesinski9e10ac72015-10-16 14:37:48 -0700145
Adam Lesinskice5e56e22016-10-21 17:56:45 -0700146 std::unique_ptr<IAaptContext> context =
147 test::ContextBuilder()
Adam Lesinski09f4d702017-08-08 10:39:55 -0700148 .AddSymbolSource(util::make_unique<ResourceTableSymbolSource>(table.get()))
Adam Lesinskice5e56e22016-10-21 17:56:45 -0700149 .SetNameManglerPolicy(NameManglerPolicy{"android"})
150 .Build();
Adam Lesinski76565542016-03-10 21:55:04 -0800151
Adam Lesinskice5e56e22016-10-21 17:56:45 -0700152 JavaClassGeneratorOptions options;
153 options.types = JavaClassGeneratorOptions::SymbolTypes::kPublic;
154 {
155 JavaClassGenerator generator(context.get(), table.get(), options);
Adam Lesinskia693c4a2017-11-09 11:29:39 -0800156 std::string output;
157 StringOutputStream out(&output);
Adam Lesinskice5e56e22016-10-21 17:56:45 -0700158 ASSERT_TRUE(generator.Generate("android", &out));
Adam Lesinskia693c4a2017-11-09 11:29:39 -0800159 out.Flush();
160
Adam Lesinski09f4d702017-08-08 10:39:55 -0700161 EXPECT_THAT(output, HasSubstr("public static final int one=0x01020000;"));
162 EXPECT_THAT(output, Not(HasSubstr("two")));
163 EXPECT_THAT(output, Not(HasSubstr("three")));
Adam Lesinskice5e56e22016-10-21 17:56:45 -0700164 }
Adam Lesinski9e10ac72015-10-16 14:37:48 -0700165
Adam Lesinskice5e56e22016-10-21 17:56:45 -0700166 options.types = JavaClassGeneratorOptions::SymbolTypes::kPublicPrivate;
167 {
168 JavaClassGenerator generator(context.get(), table.get(), options);
Adam Lesinskia693c4a2017-11-09 11:29:39 -0800169 std::string output;
170 StringOutputStream out(&output);
Adam Lesinskice5e56e22016-10-21 17:56:45 -0700171 ASSERT_TRUE(generator.Generate("android", &out));
Adam Lesinskia693c4a2017-11-09 11:29:39 -0800172 out.Flush();
173
Adam Lesinski09f4d702017-08-08 10:39:55 -0700174 EXPECT_THAT(output, HasSubstr("public static final int one=0x01020000;"));
175 EXPECT_THAT(output, HasSubstr("public static final int two=0x01020001;"));
176 EXPECT_THAT(output, Not(HasSubstr("three")));
Adam Lesinskice5e56e22016-10-21 17:56:45 -0700177 }
Adam Lesinski9e10ac72015-10-16 14:37:48 -0700178
Adam Lesinskice5e56e22016-10-21 17:56:45 -0700179 options.types = JavaClassGeneratorOptions::SymbolTypes::kAll;
180 {
181 JavaClassGenerator generator(context.get(), table.get(), options);
Adam Lesinskia693c4a2017-11-09 11:29:39 -0800182 std::string output;
183 StringOutputStream out(&output);
Adam Lesinskice5e56e22016-10-21 17:56:45 -0700184 ASSERT_TRUE(generator.Generate("android", &out));
Adam Lesinskia693c4a2017-11-09 11:29:39 -0800185 out.Flush();
186
Adam Lesinski09f4d702017-08-08 10:39:55 -0700187 EXPECT_THAT(output, HasSubstr("public static final int one=0x01020000;"));
188 EXPECT_THAT(output, HasSubstr("public static final int two=0x01020001;"));
189 EXPECT_THAT(output, HasSubstr("public static final int three=0x01020002;"));
Adam Lesinskice5e56e22016-10-21 17:56:45 -0700190 }
Adam Lesinski9e10ac72015-10-16 14:37:48 -0700191}
192
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700193/*
194 * TODO(adamlesinski): Re-enable this once we get merging working again.
195 * TEST(JavaClassGeneratorTest, EmitPackageMangledSymbols) {
Adam Lesinski769de982015-04-10 19:43:55 -0700196 ASSERT_TRUE(addResource(ResourceName{ {}, ResourceType::kId, u"foo" },
197 ResourceId{ 0x01, 0x02, 0x0000 }));
198 ResourceTable table;
199 table.setPackage(u"com.lib");
Adam Lesinskice5e56e22016-10-21 17:56:45 -0700200 ASSERT_TRUE(table.addResource(ResourceName{ {}, ResourceType::kId, u"test"
201}, {},
202 Source{ "lib.xml", 33 },
203util::make_unique<Id>()));
Adam Lesinski769de982015-04-10 19:43:55 -0700204 ASSERT_TRUE(mTable->merge(std::move(table)));
205
Adam Lesinski330edcd2015-05-04 17:40:56 -0700206 Linker linker(mTable,
Adam Lesinskice5e56e22016-10-21 17:56:45 -0700207 std::make_shared<MockResolver>(mTable, std::map<ResourceName,
208ResourceId>()),
Adam Lesinski330edcd2015-05-04 17:40:56 -0700209 {});
Adam Lesinski769de982015-04-10 19:43:55 -0700210 ASSERT_TRUE(linker.linkAndValidate());
211
212 JavaClassGenerator generator(mTable, {});
213
214 std::stringstream out;
215 EXPECT_TRUE(generator.generate(mTable->getPackage(), out));
216 std::string output = out.str();
217 EXPECT_NE(std::string::npos, output.find("int foo ="));
218 EXPECT_EQ(std::string::npos, output.find("int test ="));
219
220 out.str("");
221 EXPECT_TRUE(generator.generate(u"com.lib", out));
222 output = out.str();
223 EXPECT_NE(std::string::npos, output.find("int test ="));
224 EXPECT_EQ(std::string::npos, output.find("int foo ="));
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700225}*/
Adam Lesinski838a6872015-05-01 13:14:05 -0700226
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700227TEST(JavaClassGeneratorTest, EmitOtherPackagesAttributesInStyleable) {
Adam Lesinskice5e56e22016-10-21 17:56:45 -0700228 std::unique_ptr<ResourceTable> table =
229 test::ResourceTableBuilder()
230 .SetPackageId("android", 0x01)
231 .SetPackageId("com.lib", 0x02)
Adam Lesinski73bff1e2017-12-08 16:06:10 -0800232 .AddValue("android:attr/bar", ResourceId(0x01010000), test::AttributeBuilder().Build())
233 .AddValue("com.lib:attr/bar", ResourceId(0x02010000), test::AttributeBuilder().Build())
Adam Lesinskice5e56e22016-10-21 17:56:45 -0700234 .AddValue("android:styleable/foo", ResourceId(0x01030000),
235 test::StyleableBuilder()
236 .AddItem("android:attr/bar", ResourceId(0x01010000))
237 .AddItem("com.lib:attr/bar", ResourceId(0x02010000))
238 .Build())
239 .Build();
Adam Lesinski838a6872015-05-01 13:14:05 -0700240
Adam Lesinskice5e56e22016-10-21 17:56:45 -0700241 std::unique_ptr<IAaptContext> context =
242 test::ContextBuilder()
Adam Lesinski09f4d702017-08-08 10:39:55 -0700243 .AddSymbolSource(util::make_unique<ResourceTableSymbolSource>(table.get()))
Adam Lesinskice5e56e22016-10-21 17:56:45 -0700244 .SetNameManglerPolicy(NameManglerPolicy{"android"})
245 .Build();
246 JavaClassGenerator generator(context.get(), table.get(), {});
Adam Lesinski838a6872015-05-01 13:14:05 -0700247
Adam Lesinskia693c4a2017-11-09 11:29:39 -0800248 std::string output;
249 StringOutputStream out(&output);
Adam Lesinskice5e56e22016-10-21 17:56:45 -0700250 EXPECT_TRUE(generator.Generate("android", &out));
Adam Lesinskia693c4a2017-11-09 11:29:39 -0800251 out.Flush();
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700252
Adam Lesinski09f4d702017-08-08 10:39:55 -0700253 EXPECT_THAT(output, HasSubstr("int foo_bar="));
254 EXPECT_THAT(output, HasSubstr("int foo_com_lib_bar="));
Adam Lesinski838a6872015-05-01 13:14:05 -0700255}
Adam Lesinski769de982015-04-10 19:43:55 -0700256
Adam Lesinski3b4cd942015-10-30 16:31:42 -0700257TEST(JavaClassGeneratorTest, CommentsForSimpleResourcesArePresent) {
Adam Lesinskice5e56e22016-10-21 17:56:45 -0700258 std::unique_ptr<ResourceTable> table =
259 test::ResourceTableBuilder()
260 .SetPackageId("android", 0x01)
261 .AddSimple("android:id/foo", ResourceId(0x01010000))
262 .Build();
263 test::GetValue<Id>(table.get(), "android:id/foo")
264 ->SetComment(std::string("This is a comment\n@deprecated"));
Adam Lesinski3b4cd942015-10-30 16:31:42 -0700265
Adam Lesinskice5e56e22016-10-21 17:56:45 -0700266 std::unique_ptr<IAaptContext> context =
267 test::ContextBuilder()
Adam Lesinski09f4d702017-08-08 10:39:55 -0700268 .AddSymbolSource(util::make_unique<ResourceTableSymbolSource>(table.get()))
Adam Lesinskice5e56e22016-10-21 17:56:45 -0700269 .SetNameManglerPolicy(NameManglerPolicy{"android"})
270 .Build();
271 JavaClassGenerator generator(context.get(), table.get(), {});
Adam Lesinskia693c4a2017-11-09 11:29:39 -0800272
273 std::string output;
274 StringOutputStream out(&output);
Adam Lesinskice5e56e22016-10-21 17:56:45 -0700275 ASSERT_TRUE(generator.Generate("android", &out));
Adam Lesinskia693c4a2017-11-09 11:29:39 -0800276 out.Flush();
Adam Lesinski3b4cd942015-10-30 16:31:42 -0700277
Adam Lesinski09f4d702017-08-08 10:39:55 -0700278 const char* expected_text =
Adam Lesinskice5e56e22016-10-21 17:56:45 -0700279 R"EOF(/**
Adam Lesinski3b4cd942015-10-30 16:31:42 -0700280 * This is a comment
281 * @deprecated
282 */
283 @Deprecated
Adam Lesinski803c7c82016-04-06 16:09:43 -0700284 public static final int foo=0x01010000;)EOF";
Adam Lesinski09f4d702017-08-08 10:39:55 -0700285 EXPECT_THAT(output, HasSubstr(expected_text));
Adam Lesinski3b4cd942015-10-30 16:31:42 -0700286}
287
Adam Lesinskice5e56e22016-10-21 17:56:45 -0700288TEST(JavaClassGeneratorTest, CommentsForEnumAndFlagAttributesArePresent) {}
Adam Lesinski3b4cd942015-10-30 16:31:42 -0700289
Adam Lesinskiceb9b2f2017-02-16 12:05:42 -0800290TEST(JavaClassGeneratorTest, CommentsForStyleablesAndNestedAttributesArePresent) {
Adam Lesinski73bff1e2017-12-08 16:06:10 -0800291 Attribute attr;
Adam Lesinskice5e56e22016-10-21 17:56:45 -0700292 attr.SetComment(StringPiece("This is an attribute"));
Adam Lesinski3b4cd942015-10-30 16:31:42 -0700293
Adam Lesinskice5e56e22016-10-21 17:56:45 -0700294 Styleable styleable;
Adam Lesinski09f4d702017-08-08 10:39:55 -0700295 styleable.entries.push_back(Reference(test::ParseNameOrDie("android:attr/one")));
Adam Lesinskice5e56e22016-10-21 17:56:45 -0700296 styleable.SetComment(StringPiece("This is a styleable"));
Adam Lesinski3b4cd942015-10-30 16:31:42 -0700297
Adam Lesinskice5e56e22016-10-21 17:56:45 -0700298 std::unique_ptr<ResourceTable> table =
299 test::ResourceTableBuilder()
300 .SetPackageId("android", 0x01)
301 .AddValue("android:attr/one", util::make_unique<Attribute>(attr))
302 .AddValue("android:styleable/Container",
303 std::unique_ptr<Styleable>(styleable.Clone(nullptr)))
304 .Build();
Adam Lesinski74605cd2016-03-03 15:39:50 -0800305
Adam Lesinskice5e56e22016-10-21 17:56:45 -0700306 std::unique_ptr<IAaptContext> context =
307 test::ContextBuilder()
Adam Lesinski09f4d702017-08-08 10:39:55 -0700308 .AddSymbolSource(util::make_unique<ResourceTableSymbolSource>(table.get()))
Adam Lesinskice5e56e22016-10-21 17:56:45 -0700309 .SetNameManglerPolicy(NameManglerPolicy{"android"})
310 .Build();
311 JavaClassGeneratorOptions options;
312 options.use_final = false;
313 JavaClassGenerator generator(context.get(), table.get(), options);
Adam Lesinskia693c4a2017-11-09 11:29:39 -0800314
315 std::string output;
316 StringOutputStream out(&output);
Adam Lesinskice5e56e22016-10-21 17:56:45 -0700317 ASSERT_TRUE(generator.Generate("android", &out));
Adam Lesinskia693c4a2017-11-09 11:29:39 -0800318 out.Flush();
Adam Lesinski74605cd2016-03-03 15:39:50 -0800319
Adam Lesinski09f4d702017-08-08 10:39:55 -0700320 EXPECT_THAT(output, HasSubstr("attr name android:one"));
321 EXPECT_THAT(output, HasSubstr("attr description"));
322 EXPECT_THAT(output, HasSubstr(attr.GetComment()));
323 EXPECT_THAT(output, HasSubstr(styleable.GetComment()));
Adam Lesinski3b4cd942015-10-30 16:31:42 -0700324}
325
Adam Lesinski761d4342017-09-29 11:15:17 -0700326TEST(JavaClassGeneratorTest, StyleableAndIndicesAreColocated) {
327 std::unique_ptr<ResourceTable> table =
328 test::ResourceTableBuilder()
329 .SetPackageId("android", 0x01)
330 .AddValue("android:attr/layout_gravity", util::make_unique<Attribute>())
331 .AddValue("android:attr/background", util::make_unique<Attribute>())
332 .AddValue("android:styleable/ActionBar",
333 test::StyleableBuilder()
334 .AddItem("android:attr/background", ResourceId(0x01010000))
335 .Build())
336 .AddValue("android:styleable/ActionBar.LayoutParams",
337 test::StyleableBuilder()
338 .AddItem("android:attr/layout_gravity", ResourceId(0x01010001))
339 .Build())
340 .Build();
341
342 std::unique_ptr<IAaptContext> context =
343 test::ContextBuilder()
344 .AddSymbolSource(util::make_unique<ResourceTableSymbolSource>(table.get()))
345 .SetNameManglerPolicy(NameManglerPolicy{"android"})
346 .Build();
347
348 JavaClassGeneratorOptions options;
349 JavaClassGenerator generator(context.get(), table.get(), {});
Adam Lesinskia693c4a2017-11-09 11:29:39 -0800350
351 std::string output;
352 StringOutputStream out(&output);
Adam Lesinski761d4342017-09-29 11:15:17 -0700353 ASSERT_TRUE(generator.Generate("android", &out));
Adam Lesinskia693c4a2017-11-09 11:29:39 -0800354 out.Flush();
Adam Lesinski761d4342017-09-29 11:15:17 -0700355
356 std::string::size_type actionbar_pos = output.find("int[] ActionBar");
357 ASSERT_THAT(actionbar_pos, Ne(std::string::npos));
358
359 std::string::size_type actionbar_background_pos = output.find("int ActionBar_background");
360 ASSERT_THAT(actionbar_background_pos, Ne(std::string::npos));
361
362 std::string::size_type actionbar_layout_params_pos = output.find("int[] ActionBar_LayoutParams");
363 ASSERT_THAT(actionbar_layout_params_pos, Ne(std::string::npos));
364
365 std::string::size_type actionbar_layout_params_layout_gravity_pos =
366 output.find("int ActionBar_LayoutParams_layout_gravity");
367 ASSERT_THAT(actionbar_layout_params_layout_gravity_pos, Ne(std::string::npos));
368
369 EXPECT_THAT(actionbar_pos, Lt(actionbar_background_pos));
370 EXPECT_THAT(actionbar_pos, Lt(actionbar_layout_params_pos));
371 EXPECT_THAT(actionbar_background_pos, Lt(actionbar_layout_params_pos));
372 EXPECT_THAT(actionbar_layout_params_pos, Lt(actionbar_layout_params_layout_gravity_pos));
373}
374
Michael Wrightfeaf99f2016-05-06 17:16:06 +0100375TEST(JavaClassGeneratorTest, CommentsForRemovedAttributesAreNotPresentInClass) {
Adam Lesinski73bff1e2017-12-08 16:06:10 -0800376 Attribute attr;
Adam Lesinskice5e56e22016-10-21 17:56:45 -0700377 attr.SetComment(StringPiece("removed"));
Michael Wrightfeaf99f2016-05-06 17:16:06 +0100378
Adam Lesinskice5e56e22016-10-21 17:56:45 -0700379 std::unique_ptr<ResourceTable> table =
380 test::ResourceTableBuilder()
381 .SetPackageId("android", 0x01)
382 .AddValue("android:attr/one", util::make_unique<Attribute>(attr))
383 .Build();
Michael Wrightfeaf99f2016-05-06 17:16:06 +0100384
Adam Lesinskice5e56e22016-10-21 17:56:45 -0700385 std::unique_ptr<IAaptContext> context =
386 test::ContextBuilder()
Adam Lesinski09f4d702017-08-08 10:39:55 -0700387 .AddSymbolSource(util::make_unique<ResourceTableSymbolSource>(table.get()))
Adam Lesinskice5e56e22016-10-21 17:56:45 -0700388 .SetNameManglerPolicy(NameManglerPolicy{"android"})
389 .Build();
390 JavaClassGeneratorOptions options;
391 options.use_final = false;
392 JavaClassGenerator generator(context.get(), table.get(), options);
Adam Lesinskia693c4a2017-11-09 11:29:39 -0800393
394 std::string output;
395 StringOutputStream out(&output);
Adam Lesinskice5e56e22016-10-21 17:56:45 -0700396 ASSERT_TRUE(generator.Generate("android", &out));
Adam Lesinskia693c4a2017-11-09 11:29:39 -0800397 out.Flush();
Michael Wrightfeaf99f2016-05-06 17:16:06 +0100398
Adam Lesinski09f4d702017-08-08 10:39:55 -0700399 EXPECT_THAT(output, Not(HasSubstr("@attr name android:one")));
400 EXPECT_THAT(output, Not(HasSubstr("@attr description")));
Michael Wrightfeaf99f2016-05-06 17:16:06 +0100401
Adam Lesinskice5e56e22016-10-21 17:56:45 -0700402 // We should find @removed only in the attribute javadoc and not anywhere else
Adam Lesinski09f4d702017-08-08 10:39:55 -0700403 // (i.e. the class javadoc).
404 const std::string kRemoved("removed");
405 ASSERT_THAT(output, HasSubstr(kRemoved));
406 std::string after_first_match = output.substr(output.find(kRemoved) + kRemoved.size());
407 EXPECT_THAT(after_first_match, Not(HasSubstr(kRemoved)));
Michael Wrightfeaf99f2016-05-06 17:16:06 +0100408}
409
Adam Lesinskiceb9b2f2017-02-16 12:05:42 -0800410TEST(JavaClassGeneratorTest, GenerateOnResourcesLoadedCallbackForSharedLibrary) {
411 std::unique_ptr<ResourceTable> table =
412 test::ResourceTableBuilder()
413 .SetPackageId("android", 0x00)
Adam Lesinski73bff1e2017-12-08 16:06:10 -0800414 .AddValue("android:attr/foo", ResourceId(0x00010000), util::make_unique<Attribute>())
Adam Lesinskiceb9b2f2017-02-16 12:05:42 -0800415 .AddValue("android:id/foo", ResourceId(0x00020000), util::make_unique<Id>())
416 .AddValue(
417 "android:style/foo", ResourceId(0x00030000),
418 test::StyleBuilder()
419 .AddItem("android:attr/foo", ResourceId(0x00010000), util::make_unique<Id>())
420 .Build())
421 .Build();
422
423 std::unique_ptr<IAaptContext> context =
424 test::ContextBuilder().SetPackageId(0x00).SetCompilationPackage("android").Build();
425
426 JavaClassGeneratorOptions options;
427 options.use_final = false;
Adam Lesinski09f4d702017-08-08 10:39:55 -0700428 options.rewrite_callback_options = OnResourcesLoadedCallbackOptions{{"com.foo", "com.boo"}};
Adam Lesinskiceb9b2f2017-02-16 12:05:42 -0800429 JavaClassGenerator generator(context.get(), table.get(), options);
430
Adam Lesinskia693c4a2017-11-09 11:29:39 -0800431 std::string output;
432 StringOutputStream out(&output);
Adam Lesinskiceb9b2f2017-02-16 12:05:42 -0800433 ASSERT_TRUE(generator.Generate("android", &out));
Adam Lesinskia693c4a2017-11-09 11:29:39 -0800434 out.Flush();
Adam Lesinskiceb9b2f2017-02-16 12:05:42 -0800435
Adam Lesinski09f4d702017-08-08 10:39:55 -0700436 EXPECT_THAT(output, HasSubstr("void onResourcesLoaded"));
437 EXPECT_THAT(output, HasSubstr("com.foo.R.onResourcesLoaded"));
438 EXPECT_THAT(output, HasSubstr("com.boo.R.onResourcesLoaded"));
Adam Lesinskiceb9b2f2017-02-16 12:05:42 -0800439}
440
Adam Lesinskice5e56e22016-10-21 17:56:45 -0700441} // namespace aapt