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 "DominatorTree.h"
18
19 #include <sstream>
20 #include <string>
21 #include <vector>
22
23 #include "test/Test.h"
24 #include "util/Util.h"
25
26 namespace aapt {
27
28 namespace {
29
30 class PrettyPrinter : public DominatorTree::Visitor {
31 public:
PrettyPrinter(const int indent=2)32 explicit PrettyPrinter(const int indent = 2) : indent_(indent) {}
33
VisitTree(const std::string & product,DominatorTree::Node * root)34 void VisitTree(const std::string& product,
35 DominatorTree::Node* root) override {
36 for (auto& child : root->children()) {
37 VisitNode(child.get(), 0);
38 }
39 }
40
ToString(DominatorTree * tree)41 std::string ToString(DominatorTree* tree) {
42 buffer_.str("");
43 buffer_.clear();
44 tree->Accept(this);
45 return buffer_.str();
46 }
47
48 private:
VisitConfig(const DominatorTree::Node * node,const int indent)49 void VisitConfig(const DominatorTree::Node* node, const int indent) {
50 auto config_string = node->value()->config.toString();
51 buffer_ << std::string(indent, ' ')
52 << (config_string.isEmpty() ? "<default>" : config_string)
53 << std::endl;
54 }
55
VisitNode(const DominatorTree::Node * node,const int indent)56 void VisitNode(const DominatorTree::Node* node, const int indent) {
57 VisitConfig(node, indent);
58 for (const auto& child : node->children()) {
59 VisitNode(child.get(), indent + indent_);
60 }
61 }
62
63 std::stringstream buffer_;
64 const int indent_ = 2;
65 };
66
67 } // namespace
68
TEST(DominatorTreeTest,DefaultDominatesEverything)69 TEST(DominatorTreeTest, DefaultDominatesEverything) {
70 const ConfigDescription default_config = {};
71 const ConfigDescription land_config = test::ParseConfigOrDie("land");
72 const ConfigDescription sw600dp_land_config = test::ParseConfigOrDie("sw600dp-land-v13");
73
74 std::vector<std::unique_ptr<ResourceConfigValue>> configs;
75 configs.push_back(util::make_unique<ResourceConfigValue>(default_config, ""));
76 configs.push_back(util::make_unique<ResourceConfigValue>(land_config, ""));
77 configs.push_back(util::make_unique<ResourceConfigValue>(sw600dp_land_config, ""));
78
79 DominatorTree tree(configs);
80 PrettyPrinter printer;
81
82 std::string expected =
83 "<default>\n"
84 " land\n"
85 " sw600dp-land-v13\n";
86 EXPECT_EQ(expected, printer.ToString(&tree));
87 }
88
TEST(DominatorTreeTest,ProductsAreDominatedSeparately)89 TEST(DominatorTreeTest, ProductsAreDominatedSeparately) {
90 const ConfigDescription default_config = {};
91 const ConfigDescription land_config = test::ParseConfigOrDie("land");
92 const ConfigDescription sw600dp_land_config = test::ParseConfigOrDie("sw600dp-land-v13");
93
94 std::vector<std::unique_ptr<ResourceConfigValue>> configs;
95 configs.push_back(util::make_unique<ResourceConfigValue>(default_config, ""));
96 configs.push_back(util::make_unique<ResourceConfigValue>(land_config, ""));
97 configs.push_back(util::make_unique<ResourceConfigValue>(default_config, "phablet"));
98 configs.push_back(util::make_unique<ResourceConfigValue>(sw600dp_land_config, "phablet"));
99
100 DominatorTree tree(configs);
101 PrettyPrinter printer;
102
103 std::string expected =
104 "<default>\n"
105 " land\n"
106 "<default>\n"
107 " sw600dp-land-v13\n";
108 EXPECT_EQ(expected, printer.ToString(&tree));
109 }
110
TEST(DominatorTreeTest,MoreSpecificConfigurationsAreDominated)111 TEST(DominatorTreeTest, MoreSpecificConfigurationsAreDominated) {
112 const ConfigDescription default_config = {};
113 const ConfigDescription en_config = test::ParseConfigOrDie("en");
114 const ConfigDescription en_v21_config = test::ParseConfigOrDie("en-v21");
115 const ConfigDescription ldrtl_config = test::ParseConfigOrDie("ldrtl-v4");
116 const ConfigDescription ldrtl_xhdpi_config = test::ParseConfigOrDie("ldrtl-xhdpi-v4");
117 const ConfigDescription sw300dp_config = test::ParseConfigOrDie("sw300dp-v13");
118 const ConfigDescription sw540dp_config = test::ParseConfigOrDie("sw540dp-v14");
119 const ConfigDescription sw600dp_config = test::ParseConfigOrDie("sw600dp-v14");
120 const ConfigDescription sw720dp_config = test::ParseConfigOrDie("sw720dp-v13");
121 const ConfigDescription v20_config = test::ParseConfigOrDie("v20");
122
123 std::vector<std::unique_ptr<ResourceConfigValue>> configs;
124 configs.push_back(util::make_unique<ResourceConfigValue>(default_config, ""));
125 configs.push_back(util::make_unique<ResourceConfigValue>(en_config, ""));
126 configs.push_back(util::make_unique<ResourceConfigValue>(en_v21_config, ""));
127 configs.push_back(util::make_unique<ResourceConfigValue>(ldrtl_config, ""));
128 configs.push_back(util::make_unique<ResourceConfigValue>(ldrtl_xhdpi_config, ""));
129 configs.push_back(util::make_unique<ResourceConfigValue>(sw300dp_config, ""));
130 configs.push_back(util::make_unique<ResourceConfigValue>(sw540dp_config, ""));
131 configs.push_back(util::make_unique<ResourceConfigValue>(sw600dp_config, ""));
132 configs.push_back(util::make_unique<ResourceConfigValue>(sw720dp_config, ""));
133 configs.push_back(util::make_unique<ResourceConfigValue>(v20_config, ""));
134
135 DominatorTree tree(configs);
136 PrettyPrinter printer;
137
138 std::string expected =
139 "<default>\n"
140 " ldrtl-v4\n"
141 " ldrtl-xhdpi-v4\n"
142 " sw300dp-v13\n"
143 " sw540dp-v14\n"
144 " sw600dp-v14\n"
145 " sw720dp-v13\n"
146 " v20\n"
147 "en\n"
148 " en-v21\n";
149 EXPECT_EQ(expected, printer.ToString(&tree));
150 }
151
TEST(DominatorTreeTest,LocalesAreNeverDominated)152 TEST(DominatorTreeTest, LocalesAreNeverDominated) {
153 const ConfigDescription fr_config = test::ParseConfigOrDie("fr");
154 const ConfigDescription fr_rCA_config = test::ParseConfigOrDie("fr-rCA");
155 const ConfigDescription fr_rFR_config = test::ParseConfigOrDie("fr-rFR");
156
157 std::vector<std::unique_ptr<ResourceConfigValue>> configs;
158 configs.push_back(util::make_unique<ResourceConfigValue>(ConfigDescription::DefaultConfig(), ""));
159 configs.push_back(util::make_unique<ResourceConfigValue>(fr_config, ""));
160 configs.push_back(util::make_unique<ResourceConfigValue>(fr_rCA_config, ""));
161 configs.push_back(util::make_unique<ResourceConfigValue>(fr_rFR_config, ""));
162
163 DominatorTree tree(configs);
164 PrettyPrinter printer;
165
166 std::string expected =
167 "<default>\n"
168 "fr\n"
169 "fr-rCA\n"
170 "fr-rFR\n";
171 EXPECT_EQ(expected, printer.ToString(&tree));
172 }
173
174 } // namespace aapt
175