1/*
2 * Copyright (C) 2016 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 "split/TableSplitter.h"
18
19#include "test/Test.h"
20
21namespace aapt {
22
23TEST(TableSplitterTest, NoSplitPreferredDensity) {
24  std::unique_ptr<ResourceTable> table =
25      test::ResourceTableBuilder()
26          .AddFileReference("android:drawable/icon",
27                            "res/drawable-mdpi/icon.png",
28                            test::ParseConfigOrDie("mdpi"))
29          .AddFileReference("android:drawable/icon",
30                            "res/drawable-hdpi/icon.png",
31                            test::ParseConfigOrDie("hdpi"))
32          .AddFileReference("android:drawable/icon",
33                            "res/drawable-xhdpi/icon.png",
34                            test::ParseConfigOrDie("xhdpi"))
35          .AddFileReference("android:drawable/icon",
36                            "res/drawable-xxhdpi/icon.png",
37                            test::ParseConfigOrDie("xxhdpi"))
38          .AddSimple("android:string/one")
39          .Build();
40
41  TableSplitterOptions options;
42  options.preferred_densities.push_back(ConfigDescription::DENSITY_XHIGH);
43  TableSplitter splitter({}, options);
44  splitter.SplitTable(table.get());
45
46  EXPECT_EQ(nullptr, test::GetValueForConfig<FileReference>(
47                         table.get(), "android:drawable/icon",
48                         test::ParseConfigOrDie("mdpi")));
49  EXPECT_EQ(nullptr, test::GetValueForConfig<FileReference>(
50                         table.get(), "android:drawable/icon",
51                         test::ParseConfigOrDie("hdpi")));
52  EXPECT_NE(nullptr, test::GetValueForConfig<FileReference>(
53                         table.get(), "android:drawable/icon",
54                         test::ParseConfigOrDie("xhdpi")));
55  EXPECT_EQ(nullptr, test::GetValueForConfig<FileReference>(
56                         table.get(), "android:drawable/icon",
57                         test::ParseConfigOrDie("xxhdpi")));
58  EXPECT_NE(nullptr, test::GetValue<Id>(table.get(), "android:string/one"));
59}
60
61TEST(TableSplitterTest, NoSplitMultiplePreferredDensities) {
62  std::unique_ptr<ResourceTable> table =
63      test::ResourceTableBuilder()
64          .AddFileReference("android:drawable/icon",
65                            "res/drawable-mdpi/icon.png",
66                            test::ParseConfigOrDie("mdpi"))
67          .AddFileReference("android:drawable/icon",
68                            "res/drawable-hdpi/icon.png",
69                            test::ParseConfigOrDie("hdpi"))
70          .AddFileReference("android:drawable/icon",
71                            "res/drawable-xhdpi/icon.png",
72                            test::ParseConfigOrDie("xhdpi"))
73          .AddFileReference("android:drawable/icon",
74                            "res/drawable-xxhdpi/icon.png",
75                            test::ParseConfigOrDie("xxhdpi"))
76          .AddSimple("android:string/one")
77          .Build();
78
79  TableSplitterOptions options;
80  options.preferred_densities.push_back(ConfigDescription::DENSITY_LOW);
81  options.preferred_densities.push_back(ConfigDescription::DENSITY_XXXHIGH);
82  TableSplitter splitter({}, options);
83  splitter.SplitTable(table.get());
84
85  // Densities remaining:
86  // "mdpi" is the closest available density for the requested "ldpi" density.
87  EXPECT_NE(nullptr, test::GetValueForConfig<FileReference>(
88                         table.get(), "android:drawable/icon",
89                         test::ParseConfigOrDie("mdpi")));
90  // "xxhdpi" is the closest available density for the requested "xxxhdpi" density.
91  EXPECT_NE(nullptr, test::GetValueForConfig<FileReference>(
92                         table.get(), "android:drawable/icon",
93                         test::ParseConfigOrDie("xxhdpi")));
94  EXPECT_NE(nullptr, test::GetValue<Id>(table.get(), "android:string/one"));
95
96  // Removed densities:
97  EXPECT_EQ(nullptr, test::GetValueForConfig<FileReference>(
98                         table.get(), "android:drawable/icon",
99                         test::ParseConfigOrDie("hdpi")));
100  EXPECT_EQ(nullptr, test::GetValueForConfig<FileReference>(
101                         table.get(), "android:drawable/icon",
102                         test::ParseConfigOrDie("xhdpi")));
103}
104
105
106TEST(TableSplitterTest, SplitTableByDensity) {
107  std::unique_ptr<ResourceTable> table =
108      test::ResourceTableBuilder()
109          .AddFileReference("android:drawable/foo", "res/drawable-mdpi/foo.png",
110                            test::ParseConfigOrDie("mdpi"))
111          .AddFileReference("android:drawable/foo", "res/drawable-hdpi/foo.png",
112                            test::ParseConfigOrDie("hdpi"))
113          .AddFileReference("android:drawable/foo",
114                            "res/drawable-xhdpi/foo.png",
115                            test::ParseConfigOrDie("xhdpi"))
116          .AddFileReference("android:drawable/foo",
117                            "res/drawable-xxhdpi/foo.png",
118                            test::ParseConfigOrDie("xxhdpi"))
119          .Build();
120
121  std::vector<SplitConstraints> constraints;
122  constraints.push_back(SplitConstraints{{test::ParseConfigOrDie("mdpi")}});
123  constraints.push_back(SplitConstraints{{test::ParseConfigOrDie("hdpi")}});
124  constraints.push_back(SplitConstraints{{test::ParseConfigOrDie("xhdpi")}});
125
126  TableSplitter splitter(constraints, TableSplitterOptions{});
127  splitter.SplitTable(table.get());
128
129  ASSERT_EQ(3u, splitter.splits().size());
130
131  ResourceTable* split_one = splitter.splits()[0].get();
132  ResourceTable* split_two = splitter.splits()[1].get();
133  ResourceTable* split_three = splitter.splits()[2].get();
134
135  // Just xxhdpi should be in the base.
136  EXPECT_EQ(nullptr, test::GetValueForConfig<FileReference>(
137                         table.get(), "android:drawable/foo",
138                         test::ParseConfigOrDie("mdpi")));
139  EXPECT_EQ(nullptr, test::GetValueForConfig<FileReference>(
140                         table.get(), "android:drawable/foo",
141                         test::ParseConfigOrDie("hdpi")));
142  EXPECT_EQ(nullptr, test::GetValueForConfig<FileReference>(
143                         table.get(), "android:drawable/foo",
144                         test::ParseConfigOrDie("xhdpi")));
145  EXPECT_NE(nullptr, test::GetValueForConfig<FileReference>(
146                         table.get(), "android:drawable/foo",
147                         test::ParseConfigOrDie("xxhdpi")));
148
149  // Each split should have one and only one drawable.
150  EXPECT_NE(nullptr, test::GetValueForConfig<FileReference>(
151                         split_one, "android:drawable/foo",
152                         test::ParseConfigOrDie("mdpi")));
153  EXPECT_EQ(nullptr, test::GetValueForConfig<FileReference>(
154                         split_one, "android:drawable/foo",
155                         test::ParseConfigOrDie("hdpi")));
156  EXPECT_EQ(nullptr, test::GetValueForConfig<FileReference>(
157                         split_one, "android:drawable/foo",
158                         test::ParseConfigOrDie("xhdpi")));
159  EXPECT_EQ(nullptr, test::GetValueForConfig<FileReference>(
160                         split_one, "android:drawable/foo",
161                         test::ParseConfigOrDie("xxhdpi")));
162
163  EXPECT_EQ(nullptr, test::GetValueForConfig<FileReference>(
164                         split_two, "android:drawable/foo",
165                         test::ParseConfigOrDie("mdpi")));
166  EXPECT_NE(nullptr, test::GetValueForConfig<FileReference>(
167                         split_two, "android:drawable/foo",
168                         test::ParseConfigOrDie("hdpi")));
169  EXPECT_EQ(nullptr, test::GetValueForConfig<FileReference>(
170                         split_two, "android:drawable/foo",
171                         test::ParseConfigOrDie("xhdpi")));
172  EXPECT_EQ(nullptr, test::GetValueForConfig<FileReference>(
173                         split_two, "android:drawable/foo",
174                         test::ParseConfigOrDie("xxhdpi")));
175
176  EXPECT_EQ(nullptr, test::GetValueForConfig<FileReference>(
177                         split_three, "android:drawable/foo",
178                         test::ParseConfigOrDie("mdpi")));
179  EXPECT_EQ(nullptr, test::GetValueForConfig<FileReference>(
180                         split_three, "android:drawable/foo",
181                         test::ParseConfigOrDie("hdpi")));
182  EXPECT_NE(nullptr, test::GetValueForConfig<FileReference>(
183                         split_three, "android:drawable/foo",
184                         test::ParseConfigOrDie("xhdpi")));
185  EXPECT_EQ(nullptr, test::GetValueForConfig<FileReference>(
186                         split_three, "android:drawable/foo",
187                         test::ParseConfigOrDie("xxhdpi")));
188}
189
190TEST(TableSplitterTest, SplitTableByConfigAndDensity) {
191  ResourceTable table;
192
193  const ResourceName foo = test::ParseNameOrDie("android:string/foo");
194  ASSERT_TRUE(table.AddResource(foo, test::ParseConfigOrDie("land-hdpi"), {},
195                                util::make_unique<Id>(),
196                                test::GetDiagnostics()));
197  ASSERT_TRUE(table.AddResource(foo, test::ParseConfigOrDie("land-xhdpi"), {},
198                                util::make_unique<Id>(),
199                                test::GetDiagnostics()));
200  ASSERT_TRUE(table.AddResource(foo, test::ParseConfigOrDie("land-xxhdpi"), {},
201                                util::make_unique<Id>(),
202                                test::GetDiagnostics()));
203
204  std::vector<SplitConstraints> constraints;
205  constraints.push_back(
206      SplitConstraints{{test::ParseConfigOrDie("land-mdpi")}});
207  constraints.push_back(
208      SplitConstraints{{test::ParseConfigOrDie("land-xhdpi")}});
209
210  TableSplitter splitter(constraints, TableSplitterOptions{});
211  splitter.SplitTable(&table);
212
213  ASSERT_EQ(2u, splitter.splits().size());
214
215  ResourceTable* split_one = splitter.splits()[0].get();
216  ResourceTable* split_two = splitter.splits()[1].get();
217
218  // All but the xxhdpi resource should be gone, since there were closer matches
219  // in land-xhdpi.
220  EXPECT_EQ(nullptr,
221            test::GetValueForConfig<Id>(&table, "android:string/foo",
222                                        test::ParseConfigOrDie("land-hdpi")));
223  EXPECT_EQ(nullptr,
224            test::GetValueForConfig<Id>(&table, "android:string/foo",
225                                        test::ParseConfigOrDie("land-xhdpi")));
226  EXPECT_NE(nullptr,
227            test::GetValueForConfig<Id>(&table, "android:string/foo",
228                                        test::ParseConfigOrDie("land-xxhdpi")));
229
230  EXPECT_NE(nullptr,
231            test::GetValueForConfig<Id>(split_one, "android:string/foo",
232                                        test::ParseConfigOrDie("land-hdpi")));
233  EXPECT_EQ(nullptr,
234            test::GetValueForConfig<Id>(split_one, "android:string/foo",
235                                        test::ParseConfigOrDie("land-xhdpi")));
236  EXPECT_EQ(nullptr,
237            test::GetValueForConfig<Id>(split_one, "android:string/foo",
238                                        test::ParseConfigOrDie("land-xxhdpi")));
239
240  EXPECT_EQ(nullptr,
241            test::GetValueForConfig<Id>(split_two, "android:string/foo",
242                                        test::ParseConfigOrDie("land-hdpi")));
243  EXPECT_NE(nullptr,
244            test::GetValueForConfig<Id>(split_two, "android:string/foo",
245                                        test::ParseConfigOrDie("land-xhdpi")));
246  EXPECT_EQ(nullptr,
247            test::GetValueForConfig<Id>(split_two, "android:string/foo",
248                                        test::ParseConfigOrDie("land-xxhdpi")));
249}
250
251}  // namespace aapt
252