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 "ResourceUtils.h" 18 19#include "Resource.h" 20#include "test/Test.h" 21 22using ::aapt::test::ValueEq; 23using ::testing::Pointee; 24 25namespace aapt { 26 27TEST(ResourceUtilsTest, ParseBool) { 28 EXPECT_EQ(Maybe<bool>(true), ResourceUtils::ParseBool("true")); 29 EXPECT_EQ(Maybe<bool>(true), ResourceUtils::ParseBool("TRUE")); 30 EXPECT_EQ(Maybe<bool>(true), ResourceUtils::ParseBool("True")); 31 EXPECT_EQ(Maybe<bool>(false), ResourceUtils::ParseBool("false")); 32 EXPECT_EQ(Maybe<bool>(false), ResourceUtils::ParseBool("FALSE")); 33 EXPECT_EQ(Maybe<bool>(false), ResourceUtils::ParseBool("False")); 34} 35 36TEST(ResourceUtilsTest, ParseResourceName) { 37 ResourceNameRef actual; 38 bool actual_priv = false; 39 EXPECT_TRUE(ResourceUtils::ParseResourceName("android:color/foo", &actual, 40 &actual_priv)); 41 EXPECT_EQ(ResourceNameRef("android", ResourceType::kColor, "foo"), actual); 42 EXPECT_FALSE(actual_priv); 43 44 EXPECT_TRUE( 45 ResourceUtils::ParseResourceName("color/foo", &actual, &actual_priv)); 46 EXPECT_EQ(ResourceNameRef({}, ResourceType::kColor, "foo"), actual); 47 EXPECT_FALSE(actual_priv); 48 49 EXPECT_TRUE(ResourceUtils::ParseResourceName("*android:color/foo", &actual, 50 &actual_priv)); 51 EXPECT_EQ(ResourceNameRef("android", ResourceType::kColor, "foo"), actual); 52 EXPECT_TRUE(actual_priv); 53 54 EXPECT_FALSE(ResourceUtils::ParseResourceName(android::StringPiece(), &actual, &actual_priv)); 55} 56 57TEST(ResourceUtilsTest, ParseReferenceWithNoPackage) { 58 ResourceNameRef expected({}, ResourceType::kColor, "foo"); 59 ResourceNameRef actual; 60 bool create = false; 61 bool private_ref = false; 62 EXPECT_TRUE(ResourceUtils::ParseReference("@color/foo", &actual, &create, 63 &private_ref)); 64 EXPECT_EQ(expected, actual); 65 EXPECT_FALSE(create); 66 EXPECT_FALSE(private_ref); 67} 68 69TEST(ResourceUtilsTest, ParseReferenceWithPackage) { 70 ResourceNameRef expected("android", ResourceType::kColor, "foo"); 71 ResourceNameRef actual; 72 bool create = false; 73 bool private_ref = false; 74 EXPECT_TRUE(ResourceUtils::ParseReference("@android:color/foo", &actual, 75 &create, &private_ref)); 76 EXPECT_EQ(expected, actual); 77 EXPECT_FALSE(create); 78 EXPECT_FALSE(private_ref); 79} 80 81TEST(ResourceUtilsTest, ParseReferenceWithSurroundingWhitespace) { 82 ResourceNameRef expected("android", ResourceType::kColor, "foo"); 83 ResourceNameRef actual; 84 bool create = false; 85 bool private_ref = false; 86 EXPECT_TRUE(ResourceUtils::ParseReference("\t @android:color/foo\n \n\t", 87 &actual, &create, &private_ref)); 88 EXPECT_EQ(expected, actual); 89 EXPECT_FALSE(create); 90 EXPECT_FALSE(private_ref); 91} 92 93TEST(ResourceUtilsTest, ParseAutoCreateIdReference) { 94 ResourceNameRef expected("android", ResourceType::kId, "foo"); 95 ResourceNameRef actual; 96 bool create = false; 97 bool private_ref = false; 98 EXPECT_TRUE(ResourceUtils::ParseReference("@+android:id/foo", &actual, 99 &create, &private_ref)); 100 EXPECT_EQ(expected, actual); 101 EXPECT_TRUE(create); 102 EXPECT_FALSE(private_ref); 103} 104 105TEST(ResourceUtilsTest, ParsePrivateReference) { 106 ResourceNameRef expected("android", ResourceType::kId, "foo"); 107 ResourceNameRef actual; 108 bool create = false; 109 bool private_ref = false; 110 EXPECT_TRUE(ResourceUtils::ParseReference("@*android:id/foo", &actual, 111 &create, &private_ref)); 112 EXPECT_EQ(expected, actual); 113 EXPECT_FALSE(create); 114 EXPECT_TRUE(private_ref); 115} 116 117TEST(ResourceUtilsTest, FailToParseAutoCreateNonIdReference) { 118 bool create = false; 119 bool private_ref = false; 120 ResourceNameRef actual; 121 EXPECT_FALSE(ResourceUtils::ParseReference("@+android:color/foo", &actual, 122 &create, &private_ref)); 123} 124 125TEST(ResourceUtilsTest, ParseAttributeReferences) { 126 EXPECT_TRUE(ResourceUtils::IsAttributeReference("?android")); 127 EXPECT_TRUE(ResourceUtils::IsAttributeReference("?android:foo")); 128 EXPECT_TRUE(ResourceUtils::IsAttributeReference("?attr/foo")); 129 EXPECT_TRUE(ResourceUtils::IsAttributeReference("?android:attr/foo")); 130} 131 132TEST(ResourceUtilsTest, FailParseIncompleteReference) { 133 EXPECT_FALSE(ResourceUtils::IsAttributeReference("?style/foo")); 134 EXPECT_FALSE(ResourceUtils::IsAttributeReference("?android:style/foo")); 135 EXPECT_FALSE(ResourceUtils::IsAttributeReference("?android:")); 136 EXPECT_FALSE(ResourceUtils::IsAttributeReference("?android:attr/")); 137 EXPECT_FALSE(ResourceUtils::IsAttributeReference("?:attr/")); 138 EXPECT_FALSE(ResourceUtils::IsAttributeReference("?:attr/foo")); 139 EXPECT_FALSE(ResourceUtils::IsAttributeReference("?:/")); 140 EXPECT_FALSE(ResourceUtils::IsAttributeReference("?:/foo")); 141 EXPECT_FALSE(ResourceUtils::IsAttributeReference("?attr/")); 142 EXPECT_FALSE(ResourceUtils::IsAttributeReference("?/foo")); 143} 144 145TEST(ResourceUtilsTest, ParseStyleParentReference) { 146 const ResourceName kAndroidStyleFooName("android", ResourceType::kStyle, 147 "foo"); 148 const ResourceName kStyleFooName({}, ResourceType::kStyle, "foo"); 149 150 std::string err_str; 151 Maybe<Reference> ref = 152 ResourceUtils::ParseStyleParentReference("@android:style/foo", &err_str); 153 AAPT_ASSERT_TRUE(ref); 154 EXPECT_EQ(ref.value().name.value(), kAndroidStyleFooName); 155 156 ref = ResourceUtils::ParseStyleParentReference("@style/foo", &err_str); 157 AAPT_ASSERT_TRUE(ref); 158 EXPECT_EQ(ref.value().name.value(), kStyleFooName); 159 160 ref = 161 ResourceUtils::ParseStyleParentReference("?android:style/foo", &err_str); 162 AAPT_ASSERT_TRUE(ref); 163 EXPECT_EQ(ref.value().name.value(), kAndroidStyleFooName); 164 165 ref = ResourceUtils::ParseStyleParentReference("?style/foo", &err_str); 166 AAPT_ASSERT_TRUE(ref); 167 EXPECT_EQ(ref.value().name.value(), kStyleFooName); 168 169 ref = ResourceUtils::ParseStyleParentReference("android:style/foo", &err_str); 170 AAPT_ASSERT_TRUE(ref); 171 EXPECT_EQ(ref.value().name.value(), kAndroidStyleFooName); 172 173 ref = ResourceUtils::ParseStyleParentReference("android:foo", &err_str); 174 AAPT_ASSERT_TRUE(ref); 175 EXPECT_EQ(ref.value().name.value(), kAndroidStyleFooName); 176 177 ref = ResourceUtils::ParseStyleParentReference("@android:foo", &err_str); 178 AAPT_ASSERT_TRUE(ref); 179 EXPECT_EQ(ref.value().name.value(), kAndroidStyleFooName); 180 181 ref = ResourceUtils::ParseStyleParentReference("foo", &err_str); 182 AAPT_ASSERT_TRUE(ref); 183 EXPECT_EQ(ref.value().name.value(), kStyleFooName); 184 185 ref = 186 ResourceUtils::ParseStyleParentReference("*android:style/foo", &err_str); 187 AAPT_ASSERT_TRUE(ref); 188 EXPECT_EQ(ref.value().name.value(), kAndroidStyleFooName); 189 EXPECT_TRUE(ref.value().private_reference); 190} 191 192TEST(ResourceUtilsTest, ParseEmptyFlag) { 193 std::unique_ptr<Attribute> attr = 194 test::AttributeBuilder(false) 195 .SetTypeMask(android::ResTable_map::TYPE_FLAGS) 196 .AddItem("one", 0x01) 197 .AddItem("two", 0x02) 198 .Build(); 199 200 std::unique_ptr<BinaryPrimitive> result = 201 ResourceUtils::TryParseFlagSymbol(attr.get(), ""); 202 ASSERT_NE(nullptr, result); 203 EXPECT_EQ(0u, result->value.data); 204} 205 206TEST(ResourceUtilsTest, NullIsEmptyReference) { 207 auto null_value = ResourceUtils::MakeNull(); 208 ASSERT_THAT(null_value, Pointee(ValueEq(Reference()))); 209 210 auto value = ResourceUtils::TryParseNullOrEmpty("@null"); 211 ASSERT_THAT(value, Pointee(ValueEq(Reference()))); 212} 213 214TEST(ResourceUtilsTest, EmptyIsBinaryPrimitive) { 215 auto empty_value = ResourceUtils::MakeEmpty(); 216 ASSERT_THAT(empty_value, Pointee(ValueEq(BinaryPrimitive(android::Res_value::TYPE_NULL, 217 android::Res_value::DATA_NULL_EMPTY)))); 218 219 auto value = ResourceUtils::TryParseNullOrEmpty("@empty"); 220 ASSERT_THAT(value, Pointee(ValueEq(BinaryPrimitive(android::Res_value::TYPE_NULL, 221 android::Res_value::DATA_NULL_EMPTY)))); 222} 223 224} // namespace aapt 225