1*d57664e9SAndroid Build Coastguard Worker /*
2*d57664e9SAndroid Build Coastguard Worker * Copyright (C) 2017 The Android Open Source Project
3*d57664e9SAndroid Build Coastguard Worker *
4*d57664e9SAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
5*d57664e9SAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
6*d57664e9SAndroid Build Coastguard Worker * You may obtain a copy of the License at
7*d57664e9SAndroid Build Coastguard Worker *
8*d57664e9SAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
9*d57664e9SAndroid Build Coastguard Worker *
10*d57664e9SAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
11*d57664e9SAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
12*d57664e9SAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*d57664e9SAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
14*d57664e9SAndroid Build Coastguard Worker * limitations under the License.
15*d57664e9SAndroid Build Coastguard Worker */
16*d57664e9SAndroid Build Coastguard Worker
17*d57664e9SAndroid Build Coastguard Worker #include "ResourceValues.h"
18*d57664e9SAndroid Build Coastguard Worker
19*d57664e9SAndroid Build Coastguard Worker #include "test/Test.h"
20*d57664e9SAndroid Build Coastguard Worker
21*d57664e9SAndroid Build Coastguard Worker using ::testing::Eq;
22*d57664e9SAndroid Build Coastguard Worker using ::testing::SizeIs;
23*d57664e9SAndroid Build Coastguard Worker using ::testing::StrEq;
24*d57664e9SAndroid Build Coastguard Worker
25*d57664e9SAndroid Build Coastguard Worker namespace aapt {
26*d57664e9SAndroid Build Coastguard Worker
27*d57664e9SAndroid Build Coastguard Worker namespace {
28*d57664e9SAndroid Build Coastguard Worker
29*d57664e9SAndroid Build Coastguard Worker // Attribute types.
30*d57664e9SAndroid Build Coastguard Worker constexpr const uint32_t TYPE_DIMENSION = android::ResTable_map::TYPE_DIMENSION;
31*d57664e9SAndroid Build Coastguard Worker constexpr const uint32_t TYPE_ENUM = android::ResTable_map::TYPE_ENUM;
32*d57664e9SAndroid Build Coastguard Worker constexpr const uint32_t TYPE_FLAGS = android::ResTable_map::TYPE_FLAGS;
33*d57664e9SAndroid Build Coastguard Worker constexpr const uint32_t TYPE_INTEGER = android::ResTable_map::TYPE_INTEGER;
34*d57664e9SAndroid Build Coastguard Worker constexpr const uint32_t TYPE_REFERENCE = android::Res_value::TYPE_REFERENCE;
35*d57664e9SAndroid Build Coastguard Worker constexpr const uint32_t TYPE_STRING = android::ResTable_map::TYPE_STRING;
36*d57664e9SAndroid Build Coastguard Worker
37*d57664e9SAndroid Build Coastguard Worker } // namespace
38*d57664e9SAndroid Build Coastguard Worker
TEST(ResourceValuesTest,PluralEquals)39*d57664e9SAndroid Build Coastguard Worker TEST(ResourceValuesTest, PluralEquals) {
40*d57664e9SAndroid Build Coastguard Worker android::StringPool pool;
41*d57664e9SAndroid Build Coastguard Worker
42*d57664e9SAndroid Build Coastguard Worker Plural a;
43*d57664e9SAndroid Build Coastguard Worker a.values[Plural::One] = util::make_unique<String>(pool.MakeRef("one"));
44*d57664e9SAndroid Build Coastguard Worker a.values[Plural::Other] = util::make_unique<String>(pool.MakeRef("other"));
45*d57664e9SAndroid Build Coastguard Worker
46*d57664e9SAndroid Build Coastguard Worker Plural b;
47*d57664e9SAndroid Build Coastguard Worker b.values[Plural::One] = util::make_unique<String>(pool.MakeRef("une"));
48*d57664e9SAndroid Build Coastguard Worker b.values[Plural::Other] = util::make_unique<String>(pool.MakeRef("autre"));
49*d57664e9SAndroid Build Coastguard Worker
50*d57664e9SAndroid Build Coastguard Worker Plural c;
51*d57664e9SAndroid Build Coastguard Worker c.values[Plural::One] = util::make_unique<String>(pool.MakeRef("one"));
52*d57664e9SAndroid Build Coastguard Worker c.values[Plural::Other] = util::make_unique<String>(pool.MakeRef("other"));
53*d57664e9SAndroid Build Coastguard Worker
54*d57664e9SAndroid Build Coastguard Worker EXPECT_FALSE(a.Equals(&b));
55*d57664e9SAndroid Build Coastguard Worker EXPECT_TRUE(a.Equals(&c));
56*d57664e9SAndroid Build Coastguard Worker }
57*d57664e9SAndroid Build Coastguard Worker
TEST(ResourceValuesTest,PluralClone)58*d57664e9SAndroid Build Coastguard Worker TEST(ResourceValuesTest, PluralClone) {
59*d57664e9SAndroid Build Coastguard Worker android::StringPool pool;
60*d57664e9SAndroid Build Coastguard Worker
61*d57664e9SAndroid Build Coastguard Worker Plural a;
62*d57664e9SAndroid Build Coastguard Worker a.values[Plural::One] = util::make_unique<String>(pool.MakeRef("one"));
63*d57664e9SAndroid Build Coastguard Worker a.values[Plural::Other] = util::make_unique<String>(pool.MakeRef("other"));
64*d57664e9SAndroid Build Coastguard Worker
65*d57664e9SAndroid Build Coastguard Worker CloningValueTransformer cloner(&pool);
66*d57664e9SAndroid Build Coastguard Worker std::unique_ptr<Plural> b(a.Transform(cloner));
67*d57664e9SAndroid Build Coastguard Worker EXPECT_TRUE(a.Equals(b.get()));
68*d57664e9SAndroid Build Coastguard Worker }
69*d57664e9SAndroid Build Coastguard Worker
TEST(ResourceValuesTest,ArrayEquals)70*d57664e9SAndroid Build Coastguard Worker TEST(ResourceValuesTest, ArrayEquals) {
71*d57664e9SAndroid Build Coastguard Worker android::StringPool pool;
72*d57664e9SAndroid Build Coastguard Worker
73*d57664e9SAndroid Build Coastguard Worker Array a;
74*d57664e9SAndroid Build Coastguard Worker a.elements.push_back(util::make_unique<String>(pool.MakeRef("one")));
75*d57664e9SAndroid Build Coastguard Worker a.elements.push_back(util::make_unique<String>(pool.MakeRef("two")));
76*d57664e9SAndroid Build Coastguard Worker
77*d57664e9SAndroid Build Coastguard Worker Array b;
78*d57664e9SAndroid Build Coastguard Worker b.elements.push_back(util::make_unique<String>(pool.MakeRef("une")));
79*d57664e9SAndroid Build Coastguard Worker b.elements.push_back(util::make_unique<String>(pool.MakeRef("deux")));
80*d57664e9SAndroid Build Coastguard Worker
81*d57664e9SAndroid Build Coastguard Worker Array c;
82*d57664e9SAndroid Build Coastguard Worker c.elements.push_back(util::make_unique<String>(pool.MakeRef("uno")));
83*d57664e9SAndroid Build Coastguard Worker
84*d57664e9SAndroid Build Coastguard Worker Array d;
85*d57664e9SAndroid Build Coastguard Worker d.elements.push_back(util::make_unique<String>(pool.MakeRef("one")));
86*d57664e9SAndroid Build Coastguard Worker d.elements.push_back(util::make_unique<String>(pool.MakeRef("two")));
87*d57664e9SAndroid Build Coastguard Worker
88*d57664e9SAndroid Build Coastguard Worker EXPECT_FALSE(a.Equals(&b));
89*d57664e9SAndroid Build Coastguard Worker EXPECT_FALSE(a.Equals(&c));
90*d57664e9SAndroid Build Coastguard Worker EXPECT_FALSE(b.Equals(&c));
91*d57664e9SAndroid Build Coastguard Worker EXPECT_TRUE(a.Equals(&d));
92*d57664e9SAndroid Build Coastguard Worker }
93*d57664e9SAndroid Build Coastguard Worker
TEST(ResourceValuesTest,ArrayClone)94*d57664e9SAndroid Build Coastguard Worker TEST(ResourceValuesTest, ArrayClone) {
95*d57664e9SAndroid Build Coastguard Worker android::StringPool pool;
96*d57664e9SAndroid Build Coastguard Worker
97*d57664e9SAndroid Build Coastguard Worker Array a;
98*d57664e9SAndroid Build Coastguard Worker a.elements.push_back(util::make_unique<String>(pool.MakeRef("one")));
99*d57664e9SAndroid Build Coastguard Worker a.elements.push_back(util::make_unique<String>(pool.MakeRef("two")));
100*d57664e9SAndroid Build Coastguard Worker
101*d57664e9SAndroid Build Coastguard Worker CloningValueTransformer cloner(&pool);
102*d57664e9SAndroid Build Coastguard Worker std::unique_ptr<Array> b(a.Transform(cloner));
103*d57664e9SAndroid Build Coastguard Worker EXPECT_TRUE(a.Equals(b.get()));
104*d57664e9SAndroid Build Coastguard Worker }
105*d57664e9SAndroid Build Coastguard Worker
TEST(ResourceValuesTest,StyleEquals)106*d57664e9SAndroid Build Coastguard Worker TEST(ResourceValuesTest, StyleEquals) {
107*d57664e9SAndroid Build Coastguard Worker android::StringPool pool;
108*d57664e9SAndroid Build Coastguard Worker
109*d57664e9SAndroid Build Coastguard Worker std::unique_ptr<Style> a = test::StyleBuilder()
110*d57664e9SAndroid Build Coastguard Worker .SetParent("android:style/Parent")
111*d57664e9SAndroid Build Coastguard Worker .AddItem("android:attr/foo", ResourceUtils::TryParseInt("1"))
112*d57664e9SAndroid Build Coastguard Worker .AddItem("android:attr/bar", ResourceUtils::TryParseInt("2"))
113*d57664e9SAndroid Build Coastguard Worker .Build();
114*d57664e9SAndroid Build Coastguard Worker
115*d57664e9SAndroid Build Coastguard Worker std::unique_ptr<Style> b = test::StyleBuilder()
116*d57664e9SAndroid Build Coastguard Worker .SetParent("android:style/Parent")
117*d57664e9SAndroid Build Coastguard Worker .AddItem("android:attr/foo", ResourceUtils::TryParseInt("1"))
118*d57664e9SAndroid Build Coastguard Worker .AddItem("android:attr/bar", ResourceUtils::TryParseInt("3"))
119*d57664e9SAndroid Build Coastguard Worker .Build();
120*d57664e9SAndroid Build Coastguard Worker
121*d57664e9SAndroid Build Coastguard Worker std::unique_ptr<Style> c = test::StyleBuilder()
122*d57664e9SAndroid Build Coastguard Worker .SetParent("android:style/NoParent")
123*d57664e9SAndroid Build Coastguard Worker .AddItem("android:attr/foo", ResourceUtils::TryParseInt("1"))
124*d57664e9SAndroid Build Coastguard Worker .AddItem("android:attr/bar", ResourceUtils::TryParseInt("2"))
125*d57664e9SAndroid Build Coastguard Worker .Build();
126*d57664e9SAndroid Build Coastguard Worker
127*d57664e9SAndroid Build Coastguard Worker std::unique_ptr<Style> d = test::StyleBuilder()
128*d57664e9SAndroid Build Coastguard Worker .AddItem("android:attr/foo", ResourceUtils::TryParseInt("1"))
129*d57664e9SAndroid Build Coastguard Worker .AddItem("android:attr/bar", ResourceUtils::TryParseInt("2"))
130*d57664e9SAndroid Build Coastguard Worker .Build();
131*d57664e9SAndroid Build Coastguard Worker
132*d57664e9SAndroid Build Coastguard Worker std::unique_ptr<Style> e = test::StyleBuilder()
133*d57664e9SAndroid Build Coastguard Worker .SetParent("android:style/Parent")
134*d57664e9SAndroid Build Coastguard Worker .AddItem("android:attr/foo", ResourceUtils::TryParseInt("1"))
135*d57664e9SAndroid Build Coastguard Worker .AddItem("android:attr/bat", ResourceUtils::TryParseInt("2"))
136*d57664e9SAndroid Build Coastguard Worker .Build();
137*d57664e9SAndroid Build Coastguard Worker
138*d57664e9SAndroid Build Coastguard Worker std::unique_ptr<Style> f = test::StyleBuilder()
139*d57664e9SAndroid Build Coastguard Worker .SetParent("android:style/Parent")
140*d57664e9SAndroid Build Coastguard Worker .AddItem("android:attr/foo", ResourceUtils::TryParseInt("1"))
141*d57664e9SAndroid Build Coastguard Worker .Build();
142*d57664e9SAndroid Build Coastguard Worker
143*d57664e9SAndroid Build Coastguard Worker std::unique_ptr<Style> g = test::StyleBuilder()
144*d57664e9SAndroid Build Coastguard Worker .SetParent("android:style/Parent")
145*d57664e9SAndroid Build Coastguard Worker .AddItem("android:attr/foo", ResourceUtils::TryParseInt("1"))
146*d57664e9SAndroid Build Coastguard Worker .AddItem("android:attr/bar", ResourceUtils::TryParseInt("2"))
147*d57664e9SAndroid Build Coastguard Worker .Build();
148*d57664e9SAndroid Build Coastguard Worker
149*d57664e9SAndroid Build Coastguard Worker EXPECT_FALSE(a->Equals(b.get()));
150*d57664e9SAndroid Build Coastguard Worker EXPECT_FALSE(a->Equals(c.get()));
151*d57664e9SAndroid Build Coastguard Worker EXPECT_FALSE(a->Equals(d.get()));
152*d57664e9SAndroid Build Coastguard Worker EXPECT_FALSE(a->Equals(e.get()));
153*d57664e9SAndroid Build Coastguard Worker EXPECT_FALSE(a->Equals(f.get()));
154*d57664e9SAndroid Build Coastguard Worker
155*d57664e9SAndroid Build Coastguard Worker EXPECT_TRUE(a->Equals(g.get()));
156*d57664e9SAndroid Build Coastguard Worker }
157*d57664e9SAndroid Build Coastguard Worker
TEST(ResourceValuesTest,StyleClone)158*d57664e9SAndroid Build Coastguard Worker TEST(ResourceValuesTest, StyleClone) {
159*d57664e9SAndroid Build Coastguard Worker std::unique_ptr<Style> a = test::StyleBuilder()
160*d57664e9SAndroid Build Coastguard Worker .SetParent("android:style/Parent")
161*d57664e9SAndroid Build Coastguard Worker .AddItem("android:attr/foo", ResourceUtils::TryParseInt("1"))
162*d57664e9SAndroid Build Coastguard Worker .AddItem("android:attr/bar", ResourceUtils::TryParseInt("2"))
163*d57664e9SAndroid Build Coastguard Worker .Build();
164*d57664e9SAndroid Build Coastguard Worker
165*d57664e9SAndroid Build Coastguard Worker CloningValueTransformer cloner(nullptr);
166*d57664e9SAndroid Build Coastguard Worker std::unique_ptr<Style> b(a->Transform(cloner));
167*d57664e9SAndroid Build Coastguard Worker EXPECT_TRUE(a->Equals(b.get()));
168*d57664e9SAndroid Build Coastguard Worker }
169*d57664e9SAndroid Build Coastguard Worker
TEST(ResourcesValuesTest,StringClones)170*d57664e9SAndroid Build Coastguard Worker TEST(ResourcesValuesTest, StringClones) {
171*d57664e9SAndroid Build Coastguard Worker android::StringPool pool_a;
172*d57664e9SAndroid Build Coastguard Worker android::StringPool pool_b;
173*d57664e9SAndroid Build Coastguard Worker
174*d57664e9SAndroid Build Coastguard Worker String str_a(pool_a.MakeRef("hello", android::StringPool::Context(test::ParseConfigOrDie("en"))));
175*d57664e9SAndroid Build Coastguard Worker
176*d57664e9SAndroid Build Coastguard Worker ASSERT_THAT(pool_a, SizeIs(1u));
177*d57664e9SAndroid Build Coastguard Worker EXPECT_THAT(pool_a.strings()[0]->context.config, Eq(test::ParseConfigOrDie("en")));
178*d57664e9SAndroid Build Coastguard Worker EXPECT_THAT(pool_a.strings()[0]->value, StrEq("hello"));
179*d57664e9SAndroid Build Coastguard Worker
180*d57664e9SAndroid Build Coastguard Worker CloningValueTransformer cloner(&pool_b);
181*d57664e9SAndroid Build Coastguard Worker str_a.Transform(cloner);
182*d57664e9SAndroid Build Coastguard Worker ASSERT_THAT(pool_b, SizeIs(1u));
183*d57664e9SAndroid Build Coastguard Worker EXPECT_THAT(pool_b.strings()[0]->context.config, Eq(test::ParseConfigOrDie("en")));
184*d57664e9SAndroid Build Coastguard Worker EXPECT_THAT(pool_b.strings()[0]->value, StrEq("hello"));
185*d57664e9SAndroid Build Coastguard Worker }
186*d57664e9SAndroid Build Coastguard Worker
TEST(ResourcesValuesTest,StringEquals)187*d57664e9SAndroid Build Coastguard Worker TEST(ResourcesValuesTest, StringEquals) {
188*d57664e9SAndroid Build Coastguard Worker android::StringPool pool;
189*d57664e9SAndroid Build Coastguard Worker
190*d57664e9SAndroid Build Coastguard Worker String str(pool.MakeRef("hello", android::StringPool::Context(test::ParseConfigOrDie("en"))));
191*d57664e9SAndroid Build Coastguard Worker String str2(pool.MakeRef("hello"));
192*d57664e9SAndroid Build Coastguard Worker EXPECT_TRUE(str.Equals(&str2));
193*d57664e9SAndroid Build Coastguard Worker EXPECT_TRUE(str2.Equals(&str));
194*d57664e9SAndroid Build Coastguard Worker
195*d57664e9SAndroid Build Coastguard Worker String str3(pool.MakeRef("how are you"));
196*d57664e9SAndroid Build Coastguard Worker EXPECT_FALSE(str.Equals(&str3));
197*d57664e9SAndroid Build Coastguard Worker }
198*d57664e9SAndroid Build Coastguard Worker
TEST(ResourcesValuesTest,StyledStringEquals)199*d57664e9SAndroid Build Coastguard Worker TEST(ResourcesValuesTest, StyledStringEquals) {
200*d57664e9SAndroid Build Coastguard Worker android::StringPool pool;
201*d57664e9SAndroid Build Coastguard Worker
202*d57664e9SAndroid Build Coastguard Worker StyledString ss(pool.MakeRef(android::StyleString{"hello", {{"b", 0, 1}, {"u", 2, 4}}}));
203*d57664e9SAndroid Build Coastguard Worker StyledString ss2(pool.MakeRef(android::StyleString{"hello", {{"b", 0, 1}, {"u", 2, 4}}}));
204*d57664e9SAndroid Build Coastguard Worker StyledString ss3(pool.MakeRef(android::StyleString{"hi", {{"b", 0, 1}, {"u", 2, 4}}}));
205*d57664e9SAndroid Build Coastguard Worker StyledString ss4(pool.MakeRef(android::StyleString{"hello", {{"b", 0, 1}}}));
206*d57664e9SAndroid Build Coastguard Worker StyledString ss5(pool.MakeRef(android::StyleString{"hello", {{"b", 0, 1}, {"u", 3, 4}}}));
207*d57664e9SAndroid Build Coastguard Worker StyledString ss6(pool.MakeRef(android::StyleString{"hello", {{"b", 0, 1}, {"s", 2, 4}}}));
208*d57664e9SAndroid Build Coastguard Worker EXPECT_TRUE(ss.Equals(&ss2));
209*d57664e9SAndroid Build Coastguard Worker EXPECT_TRUE(ss2.Equals(&ss));
210*d57664e9SAndroid Build Coastguard Worker EXPECT_FALSE(ss.Equals(&ss3));
211*d57664e9SAndroid Build Coastguard Worker EXPECT_FALSE(ss.Equals(&ss4));
212*d57664e9SAndroid Build Coastguard Worker EXPECT_FALSE(ss.Equals(&ss5));
213*d57664e9SAndroid Build Coastguard Worker EXPECT_FALSE(ss.Equals(&ss6));
214*d57664e9SAndroid Build Coastguard Worker }
215*d57664e9SAndroid Build Coastguard Worker
TEST(ResourceValuesTest,StyleMerges)216*d57664e9SAndroid Build Coastguard Worker TEST(ResourceValuesTest, StyleMerges) {
217*d57664e9SAndroid Build Coastguard Worker android::StringPool pool_a;
218*d57664e9SAndroid Build Coastguard Worker android::StringPool pool_b;
219*d57664e9SAndroid Build Coastguard Worker
220*d57664e9SAndroid Build Coastguard Worker std::unique_ptr<Style> a =
221*d57664e9SAndroid Build Coastguard Worker test::StyleBuilder()
222*d57664e9SAndroid Build Coastguard Worker .SetParent("android:style/Parent")
223*d57664e9SAndroid Build Coastguard Worker .AddItem("android:attr/a", util::make_unique<String>(pool_a.MakeRef("FooA")))
224*d57664e9SAndroid Build Coastguard Worker .AddItem("android:attr/b", util::make_unique<String>(pool_a.MakeRef("FooB")))
225*d57664e9SAndroid Build Coastguard Worker .Build();
226*d57664e9SAndroid Build Coastguard Worker
227*d57664e9SAndroid Build Coastguard Worker std::unique_ptr<Style> b =
228*d57664e9SAndroid Build Coastguard Worker test::StyleBuilder()
229*d57664e9SAndroid Build Coastguard Worker .SetParent("android:style/OverlayParent")
230*d57664e9SAndroid Build Coastguard Worker .AddItem("android:attr/c", util::make_unique<String>(pool_b.MakeRef("OverlayFooC")))
231*d57664e9SAndroid Build Coastguard Worker .AddItem("android:attr/a", util::make_unique<String>(pool_b.MakeRef("OverlayFooA")))
232*d57664e9SAndroid Build Coastguard Worker .Build();
233*d57664e9SAndroid Build Coastguard Worker
234*d57664e9SAndroid Build Coastguard Worker a->MergeWith(b.get(), &pool_a);
235*d57664e9SAndroid Build Coastguard Worker
236*d57664e9SAndroid Build Coastguard Worker android::StringPool pool;
237*d57664e9SAndroid Build Coastguard Worker std::unique_ptr<Style> expected =
238*d57664e9SAndroid Build Coastguard Worker test::StyleBuilder()
239*d57664e9SAndroid Build Coastguard Worker .SetParent("android:style/OverlayParent")
240*d57664e9SAndroid Build Coastguard Worker .AddItem("android:attr/a", util::make_unique<String>(pool.MakeRef("OverlayFooA")))
241*d57664e9SAndroid Build Coastguard Worker .AddItem("android:attr/b", util::make_unique<String>(pool.MakeRef("FooB")))
242*d57664e9SAndroid Build Coastguard Worker .AddItem("android:attr/c", util::make_unique<String>(pool.MakeRef("OverlayFooC")))
243*d57664e9SAndroid Build Coastguard Worker .Build();
244*d57664e9SAndroid Build Coastguard Worker
245*d57664e9SAndroid Build Coastguard Worker EXPECT_TRUE(a->Equals(expected.get()));
246*d57664e9SAndroid Build Coastguard Worker }
247*d57664e9SAndroid Build Coastguard Worker
248*d57664e9SAndroid Build Coastguard Worker // TYPE_NULL is encoded as TYPE_REFERENCE with a value of 0. This is represented in AAPT2
249*d57664e9SAndroid Build Coastguard Worker // by a default constructed Reference value.
TEST(ResourcesValuesTest,EmptyReferenceFlattens)250*d57664e9SAndroid Build Coastguard Worker TEST(ResourcesValuesTest, EmptyReferenceFlattens) {
251*d57664e9SAndroid Build Coastguard Worker android::Res_value value = {};
252*d57664e9SAndroid Build Coastguard Worker ASSERT_TRUE(Reference().Flatten(&value));
253*d57664e9SAndroid Build Coastguard Worker
254*d57664e9SAndroid Build Coastguard Worker EXPECT_THAT(value.dataType, Eq(android::Res_value::TYPE_REFERENCE));
255*d57664e9SAndroid Build Coastguard Worker EXPECT_THAT(value.data, Eq(0u));
256*d57664e9SAndroid Build Coastguard Worker }
257*d57664e9SAndroid Build Coastguard Worker
TEST(ResourcesValuesTest,AttributeMatches)258*d57664e9SAndroid Build Coastguard Worker TEST(ResourcesValuesTest, AttributeMatches) {
259*d57664e9SAndroid Build Coastguard Worker constexpr const uint8_t TYPE_INT_DEC = android::Res_value::TYPE_INT_DEC;
260*d57664e9SAndroid Build Coastguard Worker
261*d57664e9SAndroid Build Coastguard Worker Attribute attr1(TYPE_DIMENSION);
262*d57664e9SAndroid Build Coastguard Worker EXPECT_FALSE(attr1.Matches(*ResourceUtils::TryParseColor("#7fff00")));
263*d57664e9SAndroid Build Coastguard Worker EXPECT_TRUE(attr1.Matches(*ResourceUtils::TryParseFloat("23dp")));
264*d57664e9SAndroid Build Coastguard Worker EXPECT_TRUE(attr1.Matches(*ResourceUtils::TryParseReference("@android:string/foo")));
265*d57664e9SAndroid Build Coastguard Worker
266*d57664e9SAndroid Build Coastguard Worker Attribute attr2(TYPE_INTEGER | TYPE_ENUM);
267*d57664e9SAndroid Build Coastguard Worker attr2.min_int = 0;
268*d57664e9SAndroid Build Coastguard Worker attr2.symbols.push_back(Attribute::Symbol{Reference(test::ParseNameOrDie("android:id/foo")),
269*d57664e9SAndroid Build Coastguard Worker static_cast<uint32_t>(-1)});
270*d57664e9SAndroid Build Coastguard Worker EXPECT_FALSE(attr2.Matches(*ResourceUtils::TryParseColor("#7fff00")));
271*d57664e9SAndroid Build Coastguard Worker EXPECT_TRUE(attr2.Matches(BinaryPrimitive(TYPE_INT_DEC, static_cast<uint32_t>(-1))));
272*d57664e9SAndroid Build Coastguard Worker EXPECT_TRUE(attr2.Matches(BinaryPrimitive(TYPE_INT_DEC, 1u)));
273*d57664e9SAndroid Build Coastguard Worker EXPECT_FALSE(attr2.Matches(BinaryPrimitive(TYPE_INT_DEC, static_cast<uint32_t>(-2))));
274*d57664e9SAndroid Build Coastguard Worker
275*d57664e9SAndroid Build Coastguard Worker Attribute attr3(TYPE_INTEGER | TYPE_FLAGS);
276*d57664e9SAndroid Build Coastguard Worker attr3.max_int = 100;
277*d57664e9SAndroid Build Coastguard Worker attr3.symbols.push_back(
278*d57664e9SAndroid Build Coastguard Worker Attribute::Symbol{Reference(test::ParseNameOrDie("android:id/foo")), 0x01u});
279*d57664e9SAndroid Build Coastguard Worker attr3.symbols.push_back(
280*d57664e9SAndroid Build Coastguard Worker Attribute::Symbol{Reference(test::ParseNameOrDie("android:id/bar")), 0x02u});
281*d57664e9SAndroid Build Coastguard Worker attr3.symbols.push_back(
282*d57664e9SAndroid Build Coastguard Worker Attribute::Symbol{Reference(test::ParseNameOrDie("android:id/baz")), 0x04u});
283*d57664e9SAndroid Build Coastguard Worker attr3.symbols.push_back(
284*d57664e9SAndroid Build Coastguard Worker Attribute::Symbol{Reference(test::ParseNameOrDie("android:id/bat")), 0x80u});
285*d57664e9SAndroid Build Coastguard Worker EXPECT_FALSE(attr3.Matches(*ResourceUtils::TryParseColor("#7fff00")));
286*d57664e9SAndroid Build Coastguard Worker EXPECT_TRUE(attr3.Matches(BinaryPrimitive(TYPE_INT_DEC, 0x01u | 0x02u)));
287*d57664e9SAndroid Build Coastguard Worker EXPECT_TRUE(attr3.Matches(BinaryPrimitive(TYPE_INT_DEC, 0x01u | 0x02u | 0x80u)));
288*d57664e9SAndroid Build Coastguard Worker
289*d57664e9SAndroid Build Coastguard Worker // Not a flag, but a value less than max_int.
290*d57664e9SAndroid Build Coastguard Worker EXPECT_TRUE(attr3.Matches(BinaryPrimitive(TYPE_INT_DEC, 0x08u)));
291*d57664e9SAndroid Build Coastguard Worker
292*d57664e9SAndroid Build Coastguard Worker // Not a flag and greater than max_int.
293*d57664e9SAndroid Build Coastguard Worker EXPECT_FALSE(attr3.Matches(BinaryPrimitive(TYPE_INT_DEC, 127u)));
294*d57664e9SAndroid Build Coastguard Worker
295*d57664e9SAndroid Build Coastguard Worker Attribute attr4(TYPE_ENUM);
296*d57664e9SAndroid Build Coastguard Worker attr4.symbols.push_back(
297*d57664e9SAndroid Build Coastguard Worker Attribute::Symbol{Reference(test::ParseNameOrDie("android:id/foo")), 0x01u});
298*d57664e9SAndroid Build Coastguard Worker EXPECT_TRUE(attr4.Matches(BinaryPrimitive(TYPE_INT_DEC, 0x01u)));
299*d57664e9SAndroid Build Coastguard Worker EXPECT_FALSE(attr4.Matches(BinaryPrimitive(TYPE_INT_DEC, 0x02u)));
300*d57664e9SAndroid Build Coastguard Worker }
301*d57664e9SAndroid Build Coastguard Worker
TEST(ResourcesValuesTest,AttributeIsCompatible)302*d57664e9SAndroid Build Coastguard Worker TEST(ResourcesValuesTest, AttributeIsCompatible) {
303*d57664e9SAndroid Build Coastguard Worker Attribute attr_one(TYPE_STRING | TYPE_REFERENCE);
304*d57664e9SAndroid Build Coastguard Worker Attribute attr_two(TYPE_STRING);
305*d57664e9SAndroid Build Coastguard Worker Attribute attr_three(TYPE_ENUM);
306*d57664e9SAndroid Build Coastguard Worker Attribute attr_four(TYPE_REFERENCE);
307*d57664e9SAndroid Build Coastguard Worker
308*d57664e9SAndroid Build Coastguard Worker EXPECT_TRUE(attr_one.IsCompatibleWith(attr_one));
309*d57664e9SAndroid Build Coastguard Worker EXPECT_TRUE(attr_one.IsCompatibleWith(attr_two));
310*d57664e9SAndroid Build Coastguard Worker EXPECT_FALSE(attr_one.IsCompatibleWith(attr_three));
311*d57664e9SAndroid Build Coastguard Worker EXPECT_FALSE(attr_one.IsCompatibleWith(attr_four));
312*d57664e9SAndroid Build Coastguard Worker
313*d57664e9SAndroid Build Coastguard Worker EXPECT_TRUE(attr_two.IsCompatibleWith(attr_one));
314*d57664e9SAndroid Build Coastguard Worker EXPECT_TRUE(attr_two.IsCompatibleWith(attr_two));
315*d57664e9SAndroid Build Coastguard Worker EXPECT_FALSE(attr_two.IsCompatibleWith(attr_three));
316*d57664e9SAndroid Build Coastguard Worker EXPECT_FALSE(attr_two.IsCompatibleWith(attr_four));
317*d57664e9SAndroid Build Coastguard Worker
318*d57664e9SAndroid Build Coastguard Worker EXPECT_FALSE(attr_three.IsCompatibleWith(attr_one));
319*d57664e9SAndroid Build Coastguard Worker EXPECT_FALSE(attr_three.IsCompatibleWith(attr_two));
320*d57664e9SAndroid Build Coastguard Worker EXPECT_FALSE(attr_three.IsCompatibleWith(attr_three));
321*d57664e9SAndroid Build Coastguard Worker EXPECT_FALSE(attr_three.IsCompatibleWith(attr_four));
322*d57664e9SAndroid Build Coastguard Worker }
323*d57664e9SAndroid Build Coastguard Worker
324*d57664e9SAndroid Build Coastguard Worker } // namespace aapt
325