16f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski/*
26f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * Copyright (C) 2015 The Android Open Source Project
36f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski *
46f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * Licensed under the Apache License, Version 2.0 (the "License");
56f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * you may not use this file except in compliance with the License.
66f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * You may obtain a copy of the License at
76f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski *
86f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski *      http://www.apache.org/licenses/LICENSE-2.0
96f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski *
106f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * Unless required by applicable law or agreed to in writing, software
116f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * distributed under the License is distributed on an "AS IS" BASIS,
126f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
136f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * See the License for the specific language governing permissions and
146f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * limitations under the License.
156f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski */
166f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
176f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski#include "ResourceTable.h"
18cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski#include "Diagnostics.h"
196f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski#include "ResourceValues.h"
20d0f116b619feede0cfdb647157ce5ab4d50a1c46Adam Lesinski#include "test/Test.h"
211ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski#include "util/Util.h"
221ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski
236f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski#include <algorithm>
246f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski#include <ostream>
256f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski#include <string>
266f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
27a45893a5c51cc26f1fd63ec1aa4c39f55911c85bAdam Lesinskiusing ::testing::NotNull;
28a45893a5c51cc26f1fd63ec1aa4c39f55911c85bAdam Lesinski
296f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskinamespace aapt {
306f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
31cc5609d8e484ec82ef1dced793af7f674f059b1cAdam LesinskiTEST(ResourceTableTest, FailToAddResourceWithBadName) {
32cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  ResourceTable table;
33cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski
34ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  EXPECT_FALSE(table.AddResource(
35ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski      test::ParseNameOrDie("android:id/hey,there"), ConfigDescription{}, "",
36ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski      test::ValueBuilder<Id>().SetSource("test.xml", 21u).Build(),
37ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski      test::GetDiagnostics()));
38ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski
39ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  EXPECT_FALSE(table.AddResource(
40ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski      test::ParseNameOrDie("android:id/hey:there"), ConfigDescription{}, "",
41ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski      test::ValueBuilder<Id>().SetSource("test.xml", 21u).Build(),
42ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski      test::GetDiagnostics()));
436f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski}
446f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
45b1afa07745280c7a36077beda6293b69c6ba4ea2Adam LesinskiTEST(ResourceTableTest, AddResourceWithWeirdNameWhenAddingMangledResources) {
46b1afa07745280c7a36077beda6293b69c6ba4ea2Adam Lesinski  ResourceTable table;
47b1afa07745280c7a36077beda6293b69c6ba4ea2Adam Lesinski
48b1afa07745280c7a36077beda6293b69c6ba4ea2Adam Lesinski  EXPECT_TRUE(table.AddResourceAllowMangled(
49b1afa07745280c7a36077beda6293b69c6ba4ea2Adam Lesinski      test::ParseNameOrDie("android:id/heythere       "), ConfigDescription{}, "",
50b1afa07745280c7a36077beda6293b69c6ba4ea2Adam Lesinski      test::ValueBuilder<Id>().SetSource("test.xml", 21u).Build(), test::GetDiagnostics()));
51b1afa07745280c7a36077beda6293b69c6ba4ea2Adam Lesinski}
52b1afa07745280c7a36077beda6293b69c6ba4ea2Adam Lesinski
53cc5609d8e484ec82ef1dced793af7f674f059b1cAdam LesinskiTEST(ResourceTableTest, AddOneResource) {
54cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  ResourceTable table;
556f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
56ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  EXPECT_TRUE(table.AddResource(
57ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski      test::ParseNameOrDie("android:attr/id"), ConfigDescription{}, "",
58ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski      test::ValueBuilder<Id>().SetSource("test/path/file.xml", 23u).Build(),
59ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski      test::GetDiagnostics()));
606f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
61a45893a5c51cc26f1fd63ec1aa4c39f55911c85bAdam Lesinski  EXPECT_THAT(test::GetValue<Id>(&table, "android:attr/id"), NotNull());
626f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski}
636f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
64cc5609d8e484ec82ef1dced793af7f674f059b1cAdam LesinskiTEST(ResourceTableTest, AddMultipleResources) {
65cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  ResourceTable table;
66cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski
67cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  ConfigDescription config;
68ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  ConfigDescription language_config;
69ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  memcpy(language_config.language, "pl", sizeof(language_config.language));
70ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski
71ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  EXPECT_TRUE(table.AddResource(
72ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski      test::ParseNameOrDie("android:attr/layout_width"), config, "",
73ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski      test::ValueBuilder<Id>().SetSource("test/path/file.xml", 10u).Build(),
74ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski      test::GetDiagnostics()));
75ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski
76ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  EXPECT_TRUE(table.AddResource(
77ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski      test::ParseNameOrDie("android:attr/id"), config, "",
78ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski      test::ValueBuilder<Id>().SetSource("test/path/file.xml", 12u).Build(),
79ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski      test::GetDiagnostics()));
80ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski
81ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  EXPECT_TRUE(table.AddResource(
82ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski      test::ParseNameOrDie("android:string/ok"), config, "",
83ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski      test::ValueBuilder<Id>().SetSource("test/path/file.xml", 14u).Build(),
84ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski      test::GetDiagnostics()));
85ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski
86ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  EXPECT_TRUE(table.AddResource(
87ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski      test::ParseNameOrDie("android:string/ok"), language_config, "",
88cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski      test::ValueBuilder<BinaryPrimitive>(android::Res_value{})
89ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski          .SetSource("test/path/file.xml", 20u)
90ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski          .Build(),
91ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski      test::GetDiagnostics()));
92ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski
93a45893a5c51cc26f1fd63ec1aa4c39f55911c85bAdam Lesinski  EXPECT_THAT(test::GetValue<Id>(&table, "android:attr/layout_width"), NotNull());
94a45893a5c51cc26f1fd63ec1aa4c39f55911c85bAdam Lesinski  EXPECT_THAT(test::GetValue<Id>(&table, "android:attr/id"), NotNull());
95a45893a5c51cc26f1fd63ec1aa4c39f55911c85bAdam Lesinski  EXPECT_THAT(test::GetValue<Id>(&table, "android:string/ok"), NotNull());
96a45893a5c51cc26f1fd63ec1aa4c39f55911c85bAdam Lesinski  EXPECT_THAT(test::GetValueForConfig<BinaryPrimitive>(&table, "android:string/ok", language_config), NotNull());
976f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski}
986f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
99cc5609d8e484ec82ef1dced793af7f674f059b1cAdam LesinskiTEST(ResourceTableTest, OverrideWeakResourceValue) {
100cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  ResourceTable table;
101cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski
102ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  ASSERT_TRUE(table.AddResource(
103ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski      test::ParseNameOrDie("android:attr/foo"), ConfigDescription{}, "",
104ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski      util::make_unique<Attribute>(true), test::GetDiagnostics()));
105cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski
106ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  Attribute* attr = test::GetValue<Attribute>(&table, "android:attr/foo");
107a45893a5c51cc26f1fd63ec1aa4c39f55911c85bAdam Lesinski  ASSERT_THAT(attr, NotNull());
108ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  EXPECT_TRUE(attr->IsWeak());
109cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski
110ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  ASSERT_TRUE(table.AddResource(
111ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski      test::ParseNameOrDie("android:attr/foo"), ConfigDescription{}, "",
112ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski      util::make_unique<Attribute>(false), test::GetDiagnostics()));
113cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski
114ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  attr = test::GetValue<Attribute>(&table, "android:attr/foo");
115a45893a5c51cc26f1fd63ec1aa4c39f55911c85bAdam Lesinski  ASSERT_THAT(attr, NotNull());
116ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  EXPECT_FALSE(attr->IsWeak());
1176f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski}
1186f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
119cc5609d8e484ec82ef1dced793af7f674f059b1cAdam LesinskiTEST(ResourceTableTest, ProductVaryingValues) {
120cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  ResourceTable table;
121cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski
122ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  EXPECT_TRUE(table.AddResource(test::ParseNameOrDie("android:string/foo"),
123ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski                                test::ParseConfigOrDie("land"), "tablet",
124cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski                                util::make_unique<Id>(),
125ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski                                test::GetDiagnostics()));
126ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  EXPECT_TRUE(table.AddResource(test::ParseNameOrDie("android:string/foo"),
127ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski                                test::ParseConfigOrDie("land"), "phone",
128cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski                                util::make_unique<Id>(),
129ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski                                test::GetDiagnostics()));
130cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski
131a45893a5c51cc26f1fd63ec1aa4c39f55911c85bAdam Lesinski  EXPECT_THAT(test::GetValueForConfigAndProduct<Id>(&table, "android:string/foo",test::ParseConfigOrDie("land"), "tablet"), NotNull());
132a45893a5c51cc26f1fd63ec1aa4c39f55911c85bAdam Lesinski  EXPECT_THAT(test::GetValueForConfigAndProduct<Id>(&table, "android:string/foo",test::ParseConfigOrDie("land"), "phone"), NotNull());
133cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski
134cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  Maybe<ResourceTable::SearchResult> sr =
135ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski      table.FindResource(test::ParseNameOrDie("android:string/foo"));
136a45893a5c51cc26f1fd63ec1aa4c39f55911c85bAdam Lesinski  ASSERT_TRUE(sr);
137cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  std::vector<ResourceConfigValue*> values =
138b1afa07745280c7a36077beda6293b69c6ba4ea2Adam Lesinski      sr.value().entry->FindAllValues(test::ParseConfigOrDie("land"));
139cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  ASSERT_EQ(2u, values.size());
140cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  EXPECT_EQ(std::string("phone"), values[0]->product);
141cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  EXPECT_EQ(std::string("tablet"), values[1]->product);
142e4bb9eb5af5b0899dc0921d5580220b20e15bd5aAdam Lesinski}
143e4bb9eb5af5b0899dc0921d5580220b20e15bd5aAdam Lesinski
144cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski}  // namespace aapt
145