JavaClassGenerator_test.cpp revision 74605cd40256ca75b44cc3182eeeb886c92d737c
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 "java/JavaClassGenerator.h" 18#include "util/Util.h" 19 20#include "test/Builders.h" 21 22#include <gtest/gtest.h> 23#include <sstream> 24#include <string> 25 26namespace aapt { 27 28TEST(JavaClassGeneratorTest, FailWhenEntryIsJavaKeyword) { 29 std::unique_ptr<ResourceTable> table = test::ResourceTableBuilder() 30 .setPackageId(u"android", 0x01) 31 .addSimple(u"@android:id/class", ResourceId(0x01020000)) 32 .build(); 33 34 JavaClassGenerator generator(table.get(), {}); 35 36 std::stringstream out; 37 EXPECT_FALSE(generator.generate(u"android", &out)); 38} 39 40TEST(JavaClassGeneratorTest, TransformInvalidJavaIdentifierCharacter) { 41 std::unique_ptr<ResourceTable> table = test::ResourceTableBuilder() 42 .setPackageId(u"android", 0x01) 43 .addSimple(u"@android:id/hey-man", ResourceId(0x01020000)) 44 .addSimple(u"@android:attr/cool.attr", ResourceId(0x01010000)) 45 .addValue(u"@android:styleable/hey.dude", ResourceId(0x01030000), 46 test::StyleableBuilder() 47 .addItem(u"@android:attr/cool.attr", ResourceId(0x01010000)) 48 .build()) 49 .build(); 50 51 JavaClassGenerator generator(table.get(), {}); 52 53 std::stringstream out; 54 EXPECT_TRUE(generator.generate(u"android", &out)); 55 56 std::string output = out.str(); 57 58 EXPECT_NE(std::string::npos, 59 output.find("public static final int hey_man=0x01020000;")); 60 61 EXPECT_NE(std::string::npos, 62 output.find("public static final int[] hey_dude={")); 63 64 EXPECT_NE(std::string::npos, 65 output.find("public static final int hey_dude_cool_attr=0;")); 66} 67 68TEST(JavaClassGeneratorTest, CorrectPackageNameIsUsed) { 69 std::unique_ptr<ResourceTable> table = test::ResourceTableBuilder() 70 .setPackageId(u"android", 0x01) 71 .addSimple(u"@android:id/one", ResourceId(0x01020000)) 72 .addSimple(u"@android:id/com.foo$two", ResourceId(0x01020001)) 73 .build(); 74 75 JavaClassGenerator generator(table.get(), {}); 76 std::stringstream out; 77 ASSERT_TRUE(generator.generate(u"android", u"com.android.internal", &out)); 78 79 std::string output = out.str(); 80 EXPECT_NE(std::string::npos, output.find("package com.android.internal;")); 81 EXPECT_NE(std::string::npos, output.find("public static final int one=0x01020000;")); 82 EXPECT_EQ(std::string::npos, output.find("two")); 83 EXPECT_EQ(std::string::npos, output.find("com_foo$two")); 84} 85 86TEST(JavaClassGeneratorTest, AttrPrivateIsWrittenAsAttr) { 87 std::unique_ptr<ResourceTable> table = test::ResourceTableBuilder() 88 .setPackageId(u"android", 0x01) 89 .addSimple(u"@android:attr/two", ResourceId(0x01010001)) 90 .addSimple(u"@android:^attr-private/one", ResourceId(0x01010000)) 91 .build(); 92 93 JavaClassGenerator generator(table.get(), {}); 94 std::stringstream out; 95 ASSERT_TRUE(generator.generate(u"android", &out)); 96 97 std::string output = out.str(); 98 EXPECT_NE(std::string::npos, output.find("public static final class attr")); 99 EXPECT_EQ(std::string::npos, output.find("public static final class ^attr-private")); 100} 101 102TEST(JavaClassGeneratorTest, OnlyWritePublicResources) { 103 StdErrDiagnostics diag; 104 std::unique_ptr<ResourceTable> table = test::ResourceTableBuilder() 105 .setPackageId(u"android", 0x01) 106 .addSimple(u"@android:id/one", ResourceId(0x01020000)) 107 .addSimple(u"@android:id/two", ResourceId(0x01020001)) 108 .addSimple(u"@android:id/three", ResourceId(0x01020002)) 109 .setSymbolState(u"@android:id/one", ResourceId(0x01020000), SymbolState::kPublic) 110 .setSymbolState(u"@android:id/two", ResourceId(0x01020001), SymbolState::kPrivate) 111 .build(); 112 113 JavaClassGeneratorOptions options; 114 options.types = JavaClassGeneratorOptions::SymbolTypes::kPublic; 115 { 116 JavaClassGenerator generator(table.get(), options); 117 std::stringstream out; 118 ASSERT_TRUE(generator.generate(u"android", &out)); 119 std::string output = out.str(); 120 EXPECT_NE(std::string::npos, output.find("public static final int one=0x01020000;")); 121 EXPECT_EQ(std::string::npos, output.find("two")); 122 EXPECT_EQ(std::string::npos, output.find("three")); 123 } 124 125 options.types = JavaClassGeneratorOptions::SymbolTypes::kPublicPrivate; 126 { 127 JavaClassGenerator generator(table.get(), options); 128 std::stringstream out; 129 ASSERT_TRUE(generator.generate(u"android", &out)); 130 std::string output = out.str(); 131 EXPECT_NE(std::string::npos, output.find("public static final int one=0x01020000;")); 132 EXPECT_NE(std::string::npos, output.find("public static final int two=0x01020001;")); 133 EXPECT_EQ(std::string::npos, output.find("three")); 134 } 135 136 options.types = JavaClassGeneratorOptions::SymbolTypes::kAll; 137 { 138 JavaClassGenerator generator(table.get(), options); 139 std::stringstream out; 140 ASSERT_TRUE(generator.generate(u"android", &out)); 141 std::string output = out.str(); 142 EXPECT_NE(std::string::npos, output.find("public static final int one=0x01020000;")); 143 EXPECT_NE(std::string::npos, output.find("public static final int two=0x01020001;")); 144 EXPECT_NE(std::string::npos, output.find("public static final int three=0x01020002;")); 145 } 146} 147 148/* 149 * TODO(adamlesinski): Re-enable this once we get merging working again. 150 * TEST(JavaClassGeneratorTest, EmitPackageMangledSymbols) { 151 ASSERT_TRUE(addResource(ResourceName{ {}, ResourceType::kId, u"foo" }, 152 ResourceId{ 0x01, 0x02, 0x0000 })); 153 ResourceTable table; 154 table.setPackage(u"com.lib"); 155 ASSERT_TRUE(table.addResource(ResourceName{ {}, ResourceType::kId, u"test" }, {}, 156 Source{ "lib.xml", 33 }, util::make_unique<Id>())); 157 ASSERT_TRUE(mTable->merge(std::move(table))); 158 159 Linker linker(mTable, 160 std::make_shared<MockResolver>(mTable, std::map<ResourceName, ResourceId>()), 161 {}); 162 ASSERT_TRUE(linker.linkAndValidate()); 163 164 JavaClassGenerator generator(mTable, {}); 165 166 std::stringstream out; 167 EXPECT_TRUE(generator.generate(mTable->getPackage(), out)); 168 std::string output = out.str(); 169 EXPECT_NE(std::string::npos, output.find("int foo =")); 170 EXPECT_EQ(std::string::npos, output.find("int test =")); 171 172 out.str(""); 173 EXPECT_TRUE(generator.generate(u"com.lib", out)); 174 output = out.str(); 175 EXPECT_NE(std::string::npos, output.find("int test =")); 176 EXPECT_EQ(std::string::npos, output.find("int foo =")); 177}*/ 178 179TEST(JavaClassGeneratorTest, EmitOtherPackagesAttributesInStyleable) { 180 std::unique_ptr<ResourceTable> table = test::ResourceTableBuilder() 181 .setPackageId(u"android", 0x01) 182 .setPackageId(u"com.lib", 0x02) 183 .addSimple(u"@android:attr/bar", ResourceId(0x01010000)) 184 .addSimple(u"@com.lib:attr/bar", ResourceId(0x02010000)) 185 .addValue(u"@android:styleable/foo", ResourceId(0x01030000), 186 test::StyleableBuilder() 187 .addItem(u"@android:attr/bar", ResourceId(0x01010000)) 188 .addItem(u"@com.lib:attr/bar", ResourceId(0x02010000)) 189 .build()) 190 .build(); 191 192 JavaClassGenerator generator(table.get(), {}); 193 194 std::stringstream out; 195 EXPECT_TRUE(generator.generate(u"android", &out)); 196 197 std::string output = out.str(); 198 EXPECT_NE(std::string::npos, output.find("int foo_bar=")); 199 EXPECT_NE(std::string::npos, output.find("int foo_com_lib_bar=")); 200} 201 202TEST(JavaClassGeneratorTest, CommentsForSimpleResourcesArePresent) { 203 std::unique_ptr<ResourceTable> table = test::ResourceTableBuilder() 204 .setPackageId(u"android", 0x01) 205 .addSimple(u"@android:id/foo", ResourceId(0x01010000)) 206 .build(); 207 test::getValue<Id>(table.get(), u"@android:id/foo") 208 ->setComment(std::u16string(u"This is a comment\n@deprecated")); 209 210 JavaClassGenerator generator(table.get(), {}); 211 212 std::stringstream out; 213 ASSERT_TRUE(generator.generate(u"android", &out)); 214 std::string actual = out.str(); 215 216 EXPECT_NE(std::string::npos, actual.find( 217 R"EOF(/** 218 * This is a comment 219 * @deprecated 220 */ 221 @Deprecated 222 public static final int foo=0x01010000;)EOF")); 223} 224 225TEST(JavaClassGeneratorTest, CommentsForEnumAndFlagAttributesArePresent) { 226 227} 228 229TEST(JavaClassGeneratorTest, CommentsForStyleablesAndNestedAttributesArePresent) { 230 Attribute attr(false); 231 attr.setComment(StringPiece16(u"This is an attribute")); 232 233 Styleable styleable; 234 styleable.entries.push_back(Reference(test::parseNameOrDie(u"@android:attr/one"))); 235 styleable.setComment(StringPiece16(u"This is a styleable")); 236 237 std::unique_ptr<ResourceTable> table = test::ResourceTableBuilder() 238 .setPackageId(u"android", 0x01) 239 .addValue(u"@android:attr/one", util::make_unique<Attribute>(attr)) 240 .addValue(u"@android:styleable/Container", 241 std::unique_ptr<Styleable>(styleable.clone(nullptr))) 242 .build(); 243 244 JavaClassGeneratorOptions options; 245 options.useFinal = false; 246 JavaClassGenerator generator(table.get(), options); 247 248 std::stringstream out; 249 ASSERT_TRUE(generator.generate(u"android", &out)); 250 std::string actual = out.str(); 251 252 EXPECT_NE(std::string::npos, actual.find("@attr name android:one")); 253 EXPECT_NE(std::string::npos, actual.find("@attr description")); 254 EXPECT_NE(std::string::npos, actual.find(util::utf16ToUtf8(attr.getComment()))); 255 EXPECT_NE(std::string::npos, actual.find(util::utf16ToUtf8(styleable.getComment()))); 256} 257 258} // namespace aapt 259