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 "link/ProductFilter.h"
18#include "test/Builders.h"
19#include "test/Context.h"
20
21#include <gtest/gtest.h>
22
23namespace aapt {
24
25TEST(ProductFilterTest, SelectTwoProducts) {
26    std::unique_ptr<IAaptContext> context = test::ContextBuilder().build();
27
28    const ConfigDescription land = test::parseConfigOrDie("land");
29    const ConfigDescription port = test::parseConfigOrDie("port");
30
31    ResourceTable table;
32    ASSERT_TRUE(table.addResource(test::parseNameOrDie(u"@android:string/one"),
33                                  land, "",
34                                  test::ValueBuilder<Id>()
35                                          .setSource(Source("land/default.xml")).build(),
36                                  context->getDiagnostics()));
37    ASSERT_TRUE(table.addResource(test::parseNameOrDie(u"@android:string/one"),
38                                  land, "tablet",
39                                  test::ValueBuilder<Id>()
40                                          .setSource(Source("land/tablet.xml")).build(),
41                                  context->getDiagnostics()));
42
43    ASSERT_TRUE(table.addResource(test::parseNameOrDie(u"@android:string/one"),
44                                  port, "",
45                                  test::ValueBuilder<Id>()
46                                          .setSource(Source("port/default.xml")).build(),
47                                  context->getDiagnostics()));
48    ASSERT_TRUE(table.addResource(test::parseNameOrDie(u"@android:string/one"),
49                                  port, "tablet",
50                                  test::ValueBuilder<Id>()
51                                          .setSource(Source("port/tablet.xml")).build(),
52                                  context->getDiagnostics()));
53
54    ProductFilter filter({ "tablet" });
55    ASSERT_TRUE(filter.consume(context.get(), &table));
56
57    EXPECT_EQ(nullptr, test::getValueForConfigAndProduct<Id>(&table, u"@android:string/one",
58                                                             land, ""));
59    EXPECT_NE(nullptr, test::getValueForConfigAndProduct<Id>(&table, u"@android:string/one",
60                                                             land, "tablet"));
61    EXPECT_EQ(nullptr, test::getValueForConfigAndProduct<Id>(&table, u"@android:string/one",
62                                                             port, ""));
63    EXPECT_NE(nullptr, test::getValueForConfigAndProduct<Id>(&table, u"@android:string/one",
64                                                             port, "tablet"));
65}
66
67TEST(ProductFilterTest, SelectDefaultProduct) {
68    std::unique_ptr<IAaptContext> context = test::ContextBuilder().build();
69
70    ResourceTable table;
71    ASSERT_TRUE(table.addResource(test::parseNameOrDie(u"@android:string/one"),
72                                  ConfigDescription::defaultConfig(), "",
73                                  test::ValueBuilder<Id>()
74                                          .setSource(Source("default.xml")).build(),
75                                  context->getDiagnostics()));
76    ASSERT_TRUE(table.addResource(test::parseNameOrDie(u"@android:string/one"),
77                                  ConfigDescription::defaultConfig(), "tablet",
78                                  test::ValueBuilder<Id>()
79                                          .setSource(Source("tablet.xml")).build(),
80                                  context->getDiagnostics()));
81
82    ProductFilter filter({});
83    ASSERT_TRUE(filter.consume(context.get(), &table));
84
85    EXPECT_NE(nullptr, test::getValueForConfigAndProduct<Id>(&table, u"@android:string/one",
86                                                             ConfigDescription::defaultConfig(),
87                                                             ""));
88    EXPECT_EQ(nullptr, test::getValueForConfigAndProduct<Id>(&table, u"@android:string/one",
89                                                             ConfigDescription::defaultConfig(),
90                                                             "tablet"));
91}
92
93TEST(ProductFilterTest, FailOnAmbiguousProduct) {
94    std::unique_ptr<IAaptContext> context = test::ContextBuilder().build();
95
96    ResourceTable table;
97    ASSERT_TRUE(table.addResource(test::parseNameOrDie(u"@android:string/one"),
98                                  ConfigDescription::defaultConfig(), "",
99                                  test::ValueBuilder<Id>()
100                                          .setSource(Source("default.xml")).build(),
101                                  context->getDiagnostics()));
102    ASSERT_TRUE(table.addResource(test::parseNameOrDie(u"@android:string/one"),
103                                  ConfigDescription::defaultConfig(), "tablet",
104                                  test::ValueBuilder<Id>()
105                                          .setSource(Source("tablet.xml")).build(),
106                                  context->getDiagnostics()));
107    ASSERT_TRUE(table.addResource(test::parseNameOrDie(u"@android:string/one"),
108                                  ConfigDescription::defaultConfig(), "no-sdcard",
109                                  test::ValueBuilder<Id>()
110                                          .setSource(Source("no-sdcard.xml")).build(),
111                                  context->getDiagnostics()));
112
113    ProductFilter filter({ "tablet", "no-sdcard" });
114    ASSERT_FALSE(filter.consume(context.get(), &table));
115}
116
117TEST(ProductFilterTest, FailOnMultipleDefaults) {
118    std::unique_ptr<IAaptContext> context = test::ContextBuilder().build();
119
120    ResourceTable table;
121    ASSERT_TRUE(table.addResource(test::parseNameOrDie(u"@android:string/one"),
122                                  ConfigDescription::defaultConfig(), "",
123                                  test::ValueBuilder<Id>()
124                                          .setSource(Source(".xml")).build(),
125                                  context->getDiagnostics()));
126    ASSERT_TRUE(table.addResource(test::parseNameOrDie(u"@android:string/one"),
127                                  ConfigDescription::defaultConfig(), "default",
128                                  test::ValueBuilder<Id>()
129                                          .setSource(Source("default.xml")).build(),
130                                  context->getDiagnostics()));
131
132    ProductFilter filter({});
133    ASSERT_FALSE(filter.consume(context.get(), &table));
134}
135
136} // namespace aapt
137