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