OLD | NEW |
---|---|
(Empty) | |
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include "chrome/browser/browser_theme_pack.h" | |
6 | |
7 #include "app/gfx/color_utils.h" | |
8 #include "app/theme_provider.h" | |
9 #include "base/file_util.h" | |
10 #include "base/json/json_reader.h" | |
11 #include "base/path_service.h" | |
12 #include "base/scoped_temp_dir.h" | |
13 #include "base/values.h" | |
14 #include "chrome/browser/theme_resources_util.h" | |
15 #include "chrome/browser/browser_theme_provider.h" | |
16 #include "chrome/common/chrome_paths.h" | |
17 #include "chrome/common/json_value_serializer.h" | |
18 #include "grit/theme_resources.h" | |
19 #include "testing/gtest/include/gtest/gtest.h" | |
20 | |
21 class BrowserThemePackTest : public ::testing::Test { | |
22 public: | |
23 BrowserThemePackTest() : theme_pack_(new BrowserThemePack) { } | |
24 | |
25 // Transformation for link underline colors. | |
26 SkColor BuildThirdOpacity(SkColor color_link) { | |
27 return SkColorSetA(color_link, SkColorGetA(color_link) / 3); | |
28 } | |
29 | |
30 void GenerateDefaultFrameColor(std::map<int, SkColor>* colors, | |
31 int color, int tint) { | |
32 (*colors)[color] = HSLShift( | |
33 BrowserThemeProvider::GetDefaultColor( | |
34 BrowserThemeProvider::COLOR_FRAME), | |
35 BrowserThemeProvider::GetDefaultTint(tint)); | |
36 } | |
37 | |
38 // Returns a mapping from each COLOR_* constant to the default value for this | |
39 // constant. Callers get this map, and then modify expected values and then | |
40 // run the resulting thing through VerifyColorMap(). | |
41 std::map<int, SkColor> GetDefaultColorMap() { | |
42 std::map<int, SkColor> colors; | |
43 for (int i = BrowserThemeProvider::COLOR_FRAME; | |
44 i <= BrowserThemeProvider::COLOR_BUTTON_BACKGROUND; ++i) { | |
45 colors[i] = BrowserThemeProvider::GetDefaultColor(i); | |
46 } | |
47 | |
48 GenerateDefaultFrameColor(&colors, BrowserThemeProvider::COLOR_FRAME, | |
49 BrowserThemeProvider::TINT_FRAME); | |
50 GenerateDefaultFrameColor(&colors, | |
51 BrowserThemeProvider::COLOR_FRAME_INACTIVE, | |
52 BrowserThemeProvider::TINT_FRAME_INACTIVE); | |
53 GenerateDefaultFrameColor(&colors, | |
54 BrowserThemeProvider::COLOR_FRAME_INCOGNITO, | |
55 BrowserThemeProvider::TINT_FRAME_INCOGNITO); | |
56 GenerateDefaultFrameColor( | |
57 &colors, | |
58 BrowserThemeProvider::COLOR_FRAME_INCOGNITO_INACTIVE, | |
59 BrowserThemeProvider::TINT_FRAME_INCOGNITO_INACTIVE); | |
60 | |
61 return colors; | |
62 } | |
63 | |
64 void VerifyColorMap(const std::map<int, SkColor>& color_map) { | |
65 for (std::map<int, SkColor>::const_iterator it = color_map.begin(); | |
66 it != color_map.end(); ++it) { | |
67 SkColor color = BrowserThemeProvider::GetDefaultColor(it->first); | |
68 theme_pack_->GetColor(it->first, &color); | |
69 EXPECT_EQ(it->second, color) << "Color id = " << it->first; | |
70 } | |
71 } | |
72 | |
73 void LoadColorJSON(const std::string& json) { | |
74 scoped_ptr<Value> value(base::JSONReader::Read(json, false)); | |
75 ASSERT_TRUE(value->IsType(Value::TYPE_DICTIONARY)); | |
76 theme_pack_->BuildColorsFromJSON( | |
77 static_cast<DictionaryValue*>(value.get())); | |
78 } | |
79 | |
80 void LoadTintJSON(const std::string& json) { | |
81 scoped_ptr<Value> value(base::JSONReader::Read(json, false)); | |
82 ASSERT_TRUE(value->IsType(Value::TYPE_DICTIONARY)); | |
83 theme_pack_->BuildTintsFromJSON( | |
84 static_cast<DictionaryValue*>(value.get())); | |
85 } | |
86 | |
87 void LoadDisplayPropertiesJSON(const std::string& json) { | |
88 scoped_ptr<Value> value(base::JSONReader::Read(json, false)); | |
89 ASSERT_TRUE(value->IsType(Value::TYPE_DICTIONARY)); | |
90 theme_pack_->BuildDisplayPropertiesFromJSON( | |
91 static_cast<DictionaryValue*>(value.get())); | |
92 } | |
93 | |
94 void ParseImageNames(const std::string& json, | |
95 std::map<int, FilePath>* out_file_paths) { | |
96 scoped_ptr<Value> value(base::JSONReader::Read(json, false)); | |
97 ASSERT_TRUE(value->IsType(Value::TYPE_DICTIONARY)); | |
98 theme_pack_->ParseImageNamesFromJSON( | |
99 static_cast<DictionaryValue*>(value.get()), | |
100 FilePath(), out_file_paths); | |
101 } | |
102 | |
103 FilePath GetStarGazingPath() { | |
104 FilePath test_path; | |
105 if (!PathService::Get(chrome::DIR_TEST_DATA, &test_path)) { | |
106 NOTREACHED(); | |
107 return test_path; | |
108 } | |
109 | |
110 test_path = test_path.AppendASCII("profiles"); | |
111 test_path = test_path.AppendASCII("complex_theme"); | |
112 test_path = test_path.AppendASCII("Default"); | |
113 test_path = test_path.AppendASCII("Extensions"); | |
114 test_path = test_path.AppendASCII("mblmlcbknbnfebdfjnolmcapmdofhmme"); | |
115 test_path = test_path.AppendASCII("1.1"); | |
116 return FilePath(test_path); | |
117 } | |
118 | |
119 // Verifies the data in star gazing. We do this multiple times for different | |
120 // BrowserThemePack objects to make sure it works in generated and mmapped | |
121 // mode correctly. | |
122 void VerifyStarGazing(BrowserThemePack* pack) { | |
123 // First check that values we know exist, exist. | |
124 SkColor color; | |
125 EXPECT_TRUE(pack->GetColor(BrowserThemeProvider::COLOR_BOOKMARK_TEXT, | |
126 &color)); | |
127 EXPECT_EQ(SK_ColorBLACK, color); | |
128 | |
129 EXPECT_TRUE(pack->GetColor(BrowserThemeProvider::COLOR_NTP_BACKGROUND, | |
130 &color)); | |
131 EXPECT_EQ(SkColorSetRGB(57, 137, 194), color); | |
132 | |
133 color_utils::HSL expected = { 0.6, 0.553, 0.5 }; | |
134 color_utils::HSL actual; | |
135 EXPECT_TRUE(pack->GetTint(BrowserThemeProvider::TINT_BUTTONS, &actual)); | |
136 EXPECT_DOUBLE_EQ(expected.h, actual.h); | |
137 EXPECT_DOUBLE_EQ(expected.s, actual.s); | |
138 EXPECT_DOUBLE_EQ(expected.l, actual.l); | |
139 | |
140 int val; | |
141 EXPECT_TRUE(pack->GetDisplayProperty( | |
142 BrowserThemeProvider::NTP_BACKGROUND_ALIGNMENT, &val)); | |
143 EXPECT_EQ(BrowserThemeProvider::ALIGN_TOP, val); | |
144 | |
145 EXPECT_TRUE(pack->HasCustomImage(IDR_THEME_FRAME)); | |
146 | |
147 // Make sure we don't have phantom data. | |
148 EXPECT_FALSE(pack->GetColor(BrowserThemeProvider::COLOR_CONTROL_BACKGROUND, | |
149 &color)); | |
150 EXPECT_FALSE(pack->GetTint(BrowserThemeProvider::TINT_FRAME, &actual)); | |
151 } | |
152 | |
153 scoped_refptr<BrowserThemePack> theme_pack_; | |
154 }; | |
155 | |
156 | |
157 TEST_F(BrowserThemePackTest, DeriveUnderlineLinkColor) { | |
158 // If we specify a link color, but don't specify the underline color, the | |
159 // theme provider should create one. | |
160 std::string color_json = "{ \"ntp_link\": [128, 128, 128]," | |
161 " \"ntp_section_link\": [128, 128, 128] }"; | |
162 LoadColorJSON(color_json); | |
163 | |
164 std::map<int, SkColor> colors = GetDefaultColorMap(); | |
165 SkColor link_color = SkColorSetRGB(128, 128, 128); | |
166 colors[BrowserThemeProvider::COLOR_NTP_LINK] = link_color; | |
167 colors[BrowserThemeProvider::COLOR_NTP_LINK_UNDERLINE] = | |
168 BuildThirdOpacity(link_color); | |
169 colors[BrowserThemeProvider::COLOR_NTP_SECTION_LINK] = link_color; | |
170 colors[BrowserThemeProvider::COLOR_NTP_SECTION_LINK_UNDERLINE] = | |
171 BuildThirdOpacity(link_color); | |
172 | |
173 VerifyColorMap(colors); | |
174 } | |
175 | |
176 TEST_F(BrowserThemePackTest, ProvideUnderlineLinkColor) { | |
177 // If we specify the underline color, it shouldn't try to generate one.x | |
Miranda Callahan
2009/12/14 20:47:51
an x crept in here. terminate its existence!
| |
178 std::string color_json = "{ \"ntp_link\": [128, 128, 128]," | |
179 " \"ntp_link_underline\": [255, 255, 255]," | |
180 " \"ntp_section_link\": [128, 128, 128]," | |
181 " \"ntp_section_link_underline\": [255, 255, 255]" | |
182 "}"; | |
183 LoadColorJSON(color_json); | |
184 | |
185 std::map<int, SkColor> colors = GetDefaultColorMap(); | |
186 SkColor link_color = SkColorSetRGB(128, 128, 128); | |
187 SkColor underline_color = SkColorSetRGB(255, 255, 255); | |
188 colors[BrowserThemeProvider::COLOR_NTP_LINK] = link_color; | |
189 colors[BrowserThemeProvider::COLOR_NTP_LINK_UNDERLINE] = underline_color; | |
190 colors[BrowserThemeProvider::COLOR_NTP_SECTION_LINK] = link_color; | |
191 colors[BrowserThemeProvider::COLOR_NTP_SECTION_LINK_UNDERLINE] = | |
192 underline_color; | |
193 | |
194 VerifyColorMap(colors); | |
195 } | |
196 | |
197 TEST_F(BrowserThemePackTest, UseSectionColorAsNTPHeader) { | |
198 std::string color_json = "{ \"ntp_section\": [190, 190, 190] }"; | |
199 LoadColorJSON(color_json); | |
200 | |
201 std::map<int, SkColor> colors = GetDefaultColorMap(); | |
202 SkColor ntp_color = SkColorSetRGB(190, 190, 190); | |
203 colors[BrowserThemeProvider::COLOR_NTP_HEADER] = ntp_color; | |
204 colors[BrowserThemeProvider::COLOR_NTP_SECTION] = ntp_color; | |
205 VerifyColorMap(colors); | |
206 } | |
207 | |
208 TEST_F(BrowserThemePackTest, ProvideNtpHeaderColor) { | |
209 std::string color_json = "{ \"ntp_header\": [120, 120, 120], " | |
210 " \"ntp_section\": [190, 190, 190] }"; | |
211 LoadColorJSON(color_json); | |
212 | |
213 std::map<int, SkColor> colors = GetDefaultColorMap(); | |
214 SkColor ntp_header = SkColorSetRGB(120, 120, 120); | |
215 SkColor ntp_section = SkColorSetRGB(190, 190, 190); | |
216 colors[BrowserThemeProvider::COLOR_NTP_HEADER] = ntp_header; | |
217 colors[BrowserThemeProvider::COLOR_NTP_SECTION] = ntp_section; | |
218 VerifyColorMap(colors); | |
219 } | |
220 | |
221 TEST_F(BrowserThemePackTest, CanReadTints) { | |
222 std::string tint_json = "{ \"buttons\": [ 0.5, 0.5, 0.5 ] }"; | |
223 LoadTintJSON(tint_json); | |
224 | |
225 color_utils::HSL expected = { 0.5, 0.5, 0.5 }; | |
226 color_utils::HSL actual = { -1, -1, -1 }; | |
227 EXPECT_TRUE(theme_pack_->GetTint( | |
228 BrowserThemeProvider::TINT_BUTTONS, &actual)); | |
229 EXPECT_DOUBLE_EQ(expected.h, actual.h); | |
230 EXPECT_DOUBLE_EQ(expected.s, actual.s); | |
231 EXPECT_DOUBLE_EQ(expected.l, actual.l); | |
232 } | |
233 | |
234 TEST_F(BrowserThemePackTest, CanReadDisplayProperties) { | |
235 std::string json = "{ \"ntp_background_alignment\": \"bottom\", " | |
236 " \"ntp_background_repeat\": \"repeat-x\", " | |
237 " \"ntp_logo_alternate\": 0 }"; | |
238 LoadDisplayPropertiesJSON(json); | |
239 | |
240 int out_val; | |
241 EXPECT_TRUE(theme_pack_->GetDisplayProperty( | |
242 BrowserThemeProvider::NTP_BACKGROUND_ALIGNMENT, &out_val)); | |
243 EXPECT_EQ(BrowserThemeProvider::ALIGN_BOTTOM, out_val); | |
244 | |
245 EXPECT_TRUE(theme_pack_->GetDisplayProperty( | |
246 BrowserThemeProvider::NTP_BACKGROUND_TILING, &out_val)); | |
247 EXPECT_EQ(BrowserThemeProvider::REPEAT_X, out_val); | |
248 | |
249 EXPECT_TRUE(theme_pack_->GetDisplayProperty( | |
250 BrowserThemeProvider::NTP_LOGO_ALTERNATE, &out_val)); | |
251 EXPECT_EQ(0, out_val); | |
252 } | |
253 | |
254 TEST_F(BrowserThemePackTest, CanParsePaths) { | |
255 std::string tint_json = "{ \"theme_button_background\": \"one\", " | |
256 " \"theme_toolbar\": \"two\" }"; | |
257 std::map<int, FilePath> out_file_paths; | |
258 ParseImageNames(tint_json, &out_file_paths); | |
259 | |
260 EXPECT_EQ(2u, out_file_paths.size()); | |
261 EXPECT_TRUE(FilePath(FILE_PATH_LITERAL("one")) == out_file_paths[ | |
262 ThemeResourcesUtil::GetId("theme_button_background")]); | |
263 EXPECT_TRUE(FilePath(FILE_PATH_LITERAL("two")) == | |
264 out_file_paths[ThemeResourcesUtil::GetId("theme_toolbar")]); | |
265 } | |
266 | |
267 TEST_F(BrowserThemePackTest, InvalidColors) { | |
268 std::string invalid_color = "{ \"toolbar\": [\"dog\", \"cat\", [12]], " | |
269 " \"sound\": \"woof\" }"; | |
270 LoadColorJSON(invalid_color); | |
271 std::map<int, SkColor> colors = GetDefaultColorMap(); | |
272 VerifyColorMap(colors); | |
273 } | |
274 | |
275 TEST_F(BrowserThemePackTest, InvalidTints) { | |
276 std::string invalid_tints = "{ \"buttons\": [ \"dog\", \"cat\", [\"x\"]], " | |
277 " \"invalid\": \"entry\" }"; | |
278 LoadTintJSON(invalid_tints); | |
279 | |
280 // We shouldn't have a buttons tint, as it was invalid. | |
281 color_utils::HSL actual = { -1, -1, -1 }; | |
282 EXPECT_FALSE(theme_pack_->GetTint(BrowserThemeProvider::TINT_BUTTONS, | |
283 &actual)); | |
284 } | |
285 | |
286 TEST_F(BrowserThemePackTest, InvalidDisplayProperties) { | |
287 std::string invalid_properties = "{ \"ntp_background_alignment\": [15], " | |
288 " \"junk\": [15.3] }"; | |
289 LoadDisplayPropertiesJSON(invalid_properties); | |
290 | |
291 int out_val; | |
292 EXPECT_FALSE(theme_pack_->GetDisplayProperty( | |
293 BrowserThemeProvider::NTP_BACKGROUND_ALIGNMENT, &out_val)); | |
294 } | |
295 | |
296 // TODO(erg): This test should actually test more of the built resources from | |
297 // the extension data, but for now, exists so valgrind can test some of the | |
298 // tricky memory stuff that BrowserThemePack does. | |
299 TEST_F(BrowserThemePackTest, CanBuildAndReadPack) { | |
300 ScopedTempDir dir; | |
301 ASSERT_TRUE(dir.CreateUniqueTempDir()); | |
302 FilePath file = dir.path().Append(FILE_PATH_LITERAL("data.pak")); | |
303 | |
304 // Part 1: Build the pack from an extension. | |
305 { | |
306 FilePath star_gazing_path = GetStarGazingPath(); | |
307 Extension extension(star_gazing_path); | |
308 | |
309 FilePath manifest_path = | |
310 star_gazing_path.AppendASCII("manifest.json"); | |
311 std::string error; | |
312 JSONFileValueSerializer serializer(manifest_path); | |
313 scoped_ptr<DictionaryValue> valid_value( | |
314 static_cast<DictionaryValue*>(serializer.Deserialize(&error))); | |
315 EXPECT_EQ("", error); | |
316 ASSERT_TRUE(valid_value.get()); | |
317 ASSERT_TRUE(extension.InitFromValue(*valid_value, true, &error)); | |
318 ASSERT_EQ("", error); | |
319 | |
320 scoped_refptr<BrowserThemePack> pack = | |
321 BrowserThemePack::BuildFromExtension(&extension); | |
322 ASSERT_TRUE(pack.get()); | |
323 ASSERT_TRUE(pack->WriteToDisk(file)); | |
324 VerifyStarGazing(pack.get()); | |
325 } | |
326 | |
327 // Part 2: Try to read back the data pack that we just wrote to disk. | |
328 { | |
329 scoped_refptr<BrowserThemePack> pack = | |
330 BrowserThemePack::BuildFromDataPack( | |
331 file, "mblmlcbknbnfebdfjnolmcapmdofhmme"); | |
332 ASSERT_TRUE(pack.get()); | |
333 VerifyStarGazing(pack.get()); | |
334 } | |
335 } | |
OLD | NEW |