OLD | NEW |
| (Empty) |
1 // Copyright (c) 2013 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 "ui/message_center/views/bounded_label.h" | |
6 | |
7 #include <limits> | |
8 | |
9 #include "base/string_util.h" | |
10 #include "base/strings/string_split.h" | |
11 #include "base/utf_string_conversions.h" | |
12 #include "testing/gtest/include/gtest/gtest.h" | |
13 #include "ui/gfx/font.h" | |
14 #include "ui/views/controls/label.h" | |
15 | |
16 namespace message_center { | |
17 | |
18 /* Test fixture declaration ***************************************************/ | |
19 | |
20 class BoundedLabelTest : public testing::Test { | |
21 public: | |
22 BoundedLabelTest(); | |
23 virtual ~BoundedLabelTest(); | |
24 | |
25 // Replaces all occurences of three periods ("...") in the specified string | |
26 // with an ellipses character (UTF8 "\xE2\x80\xA6") and returns a string16 | |
27 // with the results. This allows test strings to be specified as ASCII const | |
28 // char* strings, making tests more readable and easier to write. | |
29 string16 ToString(const char* string); | |
30 | |
31 // Converts the specified elision width to pixels. To make tests somewhat | |
32 // independent of the fonts of the platform on which they're run, the elision | |
33 // widths are specified as XYZ integers, with the corresponding width in | |
34 // pixels being X times the width of digit characters plus Y times the width | |
35 // of spaces plus Z times the width of ellipses in the default font of the | |
36 // test plaform. It is assumed that all digits have the same width in that | |
37 // font, that this width is greater than the width of spaces, and that the | |
38 // width of 3 digits is greater than the width of ellipses. | |
39 int ToPixels(int width); | |
40 | |
41 // Exercise BounderLabel::SplitLines() using the fixture's test label. | |
42 string16 SplitLines(int width); | |
43 | |
44 // Exercise BounderLabel::GetPreferredLines() using the fixture's test label. | |
45 int GetPreferredLines(int width); | |
46 | |
47 protected: | |
48 // Creates a label to test with. Returns this fixture, which can be used to | |
49 // test the newly created label using the exercise methods above. | |
50 BoundedLabelTest& Label(string16 text, size_t lines); | |
51 | |
52 private: | |
53 gfx::Font font_; // The default font, which will be used for tests. | |
54 int digit_pixels_; | |
55 int space_pixels_; | |
56 int ellipsis_pixels_; | |
57 scoped_ptr<BoundedLabel> label_; | |
58 }; | |
59 | |
60 /* Test fixture definition ****************************************************/ | |
61 | |
62 BoundedLabelTest::BoundedLabelTest() { | |
63 digit_pixels_ = font_.GetStringWidth(UTF8ToUTF16("0")); | |
64 space_pixels_ = font_.GetStringWidth(UTF8ToUTF16(" ")); | |
65 ellipsis_pixels_ = font_.GetStringWidth(UTF8ToUTF16("\xE2\x80\xA6")); | |
66 } | |
67 | |
68 BoundedLabelTest::~BoundedLabelTest() { | |
69 } | |
70 | |
71 string16 BoundedLabelTest::ToString(const char* string) { | |
72 const string16 periods = UTF8ToUTF16("..."); | |
73 const string16 ellipses = UTF8ToUTF16("\xE2\x80\xA6"); | |
74 string16 result = UTF8ToUTF16(string); | |
75 ReplaceSubstringsAfterOffset(&result, 0, periods, ellipses); | |
76 return result; | |
77 } | |
78 | |
79 int BoundedLabelTest::ToPixels(int width) { | |
80 return digit_pixels_ * width / 100 + | |
81 space_pixels_ * (width % 100) / 10 + | |
82 ellipsis_pixels_ * (width % 10); | |
83 } | |
84 | |
85 string16 BoundedLabelTest::SplitLines(int width) { | |
86 return JoinString(label_->SplitLines(width, label_->GetMaxLines()), '\n'); | |
87 } | |
88 | |
89 int BoundedLabelTest::GetPreferredLines(int width) { | |
90 label_->SetBounds(0, 0, width, font_.GetHeight() * label_->GetMaxLines()); | |
91 return label_->GetPreferredLines(); | |
92 } | |
93 | |
94 BoundedLabelTest& BoundedLabelTest::Label(string16 text, size_t lines) { | |
95 label_.reset(new BoundedLabel(text, font_, lines)); | |
96 return *this; | |
97 } | |
98 | |
99 /* Test macro definitions *****************************************************/ | |
100 | |
101 #define TEST_SPLIT_LINES(expected, text, width, lines) \ | |
102 EXPECT_EQ(ToString(expected), \ | |
103 Label(ToString(text), lines).SplitLines(ToPixels(width))) | |
104 | |
105 #define TEST_GET_PREFERRED_LINES(expected, text, width, lines) \ | |
106 EXPECT_EQ(expected, \ | |
107 Label(ToString(text), lines).GetPreferredLines(ToPixels(width))) | |
108 | |
109 /* Elision tests **************************************************************/ | |
110 | |
111 TEST_F(BoundedLabelTest, ElisionTest) { | |
112 // One word per line: No ellision should be made when not necessary. | |
113 TEST_SPLIT_LINES("123", "123", 301, 1); | |
114 TEST_SPLIT_LINES("123", "123", 301, 2); | |
115 TEST_SPLIT_LINES("123", "123", 301, 3); | |
116 TEST_SPLIT_LINES("123\n456", "123 456", 0, 2); // 301, 2); | |
117 TEST_SPLIT_LINES("123\n456", "123 456", 301, 3); | |
118 TEST_SPLIT_LINES("123\n456\n789", "123 456 789", 301, 3); | |
119 | |
120 // One word per line: Ellisions should be made when necessary. | |
121 TEST_SPLIT_LINES("123...", "123 456", 301, 1); | |
122 TEST_SPLIT_LINES("123...", "123 456 789", 301, 1); | |
123 TEST_SPLIT_LINES("123\n456...", "123 456 789", 301, 2); | |
124 | |
125 // Two words per line: No ellision should be made when not necessary. | |
126 TEST_SPLIT_LINES("123 456", "123 456", 621, 1); | |
127 TEST_SPLIT_LINES("123 456", "123 456", 621, 2); | |
128 TEST_SPLIT_LINES("123 456", "123 456", 621, 3); | |
129 TEST_SPLIT_LINES("123 456\n789 012", "123 456 789 012", 621, 2); | |
130 TEST_SPLIT_LINES("123 456\n789 012", "123 456 789 012", 621, 3); | |
131 TEST_SPLIT_LINES("123 456\n789 012\n345 678", | |
132 "123 456 789 012 345 678", 621, 3); | |
133 | |
134 // Two words per line: Ellisions should be made when necessary. | |
135 TEST_SPLIT_LINES("123 456...", "123 456 789 012", 621, 1); | |
136 TEST_SPLIT_LINES("123 456...", "123 456 789 012 345 678", 621, 1); | |
137 TEST_SPLIT_LINES("123 456\n789 012...", "123 456 789 012 345 678", 621, 2); | |
138 | |
139 // Single trailing spaces: No ellipses should be added. | |
140 TEST_SPLIT_LINES("123", "123 ", 301, 1); | |
141 TEST_SPLIT_LINES("123\n456", "123 456 ", 301, 2); | |
142 TEST_SPLIT_LINES("123\n456\n789", "123 456 789 ", 301, 3); | |
143 TEST_SPLIT_LINES("123 456", "123 456 ", 611, 1); | |
144 TEST_SPLIT_LINES("123 456\n789 012", "123 456 789 012 ", 611, 2); | |
145 TEST_SPLIT_LINES("123 456\n789 012\n345 678", | |
146 "123 456 789 012 345 678 ", 611, 3); | |
147 | |
148 // Multiple trailing spaces: No ellipses should be added. | |
149 TEST_SPLIT_LINES("123", "123 ", 301, 1); | |
150 TEST_SPLIT_LINES("123\n456", "123 456 ", 301, 2); | |
151 TEST_SPLIT_LINES("123\n456\n789", "123 456 789 ", 301, 3); | |
152 TEST_SPLIT_LINES("123 456", "123 456 ", 611, 1); | |
153 TEST_SPLIT_LINES("123 456\n789 012", "123 456 789 012 ", 611, 2); | |
154 TEST_SPLIT_LINES("123 456\n789 012\n345 678", | |
155 "123 456 789 012 345 678 ", 611, 3); | |
156 | |
157 // Multiple spaces between words on the same line: Spaces should be preserved. | |
158 // Test cases for single spaces between such words are included in the "Two | |
159 // words per line" sections above. | |
160 TEST_SPLIT_LINES("123 456", "123 456", 621, 1); | |
161 TEST_SPLIT_LINES("123 456...", "123 456 789 012", 631, 1); | |
162 TEST_SPLIT_LINES("123 456\n789 012", "123 456 789 012", 631, 2); | |
163 TEST_SPLIT_LINES("123 456...", "123 456 789 012 345 678", 621, 1); | |
164 TEST_SPLIT_LINES("123 456\n789 012...", | |
165 "123 456 789 012 345 678", 631, 2); | |
166 TEST_SPLIT_LINES("123 456\n789 012\n345 678", | |
167 "123 456 789 012 345 678", 641, 3); | |
168 | |
169 // Multiple spaces between words split across lines: Spaces should be removed | |
170 // even if lines are wide enough to include those spaces. Test cases for | |
171 // single spaces between such words are included in the "Two words per line" | |
172 // sections above. | |
173 TEST_SPLIT_LINES("123\n456", "123 456", 321, 2); | |
174 TEST_SPLIT_LINES("123\n456", "123 456", 391, 2); | |
175 TEST_SPLIT_LINES("123\n456...", "123 456 789", 321, 2); | |
176 TEST_SPLIT_LINES("123\n456...", "123 456 789", 391, 2); | |
177 TEST_SPLIT_LINES("123 456\n789 012", "123 456 789 012", 641, 2); | |
178 TEST_SPLIT_LINES("123 456\n789 012...", "123 456 789 012 345 678", | |
179 641, 2); | |
180 | |
181 // TODO(dharcourt): Add test cases to verify that: | |
182 // - Spaces before elisions are removed | |
183 // - Leading spaces are preserved | |
184 // - Words are split when they are longer than lines | |
185 // - Words are clipped when they are longer than the last line | |
186 // - No blank line are created before or after clipped word | |
187 // - Spaces at the end of the text are removed | |
188 | |
189 // TODO(dharcourt): Add test cases for: | |
190 // - Empty and very large strings | |
191 // - Zero and very large max lines values | |
192 // - Other input boundary conditions | |
193 // TODO(dharcourt): Add some randomly generated fuzz test cases. | |
194 | |
195 } | |
196 | |
197 /* GetPreferredLinesTest ******************************************************/ | |
198 | |
199 TEST_F(BoundedLabelTest, GetPreferredLinesTest) { | |
200 // Zero, small, and negative width values should yield one word per line. | |
201 TEST_GET_PREFERRED_LINES(2, "123 456", 0, 1); | |
202 TEST_GET_PREFERRED_LINES(2, "123 456", 1, 1); | |
203 TEST_GET_PREFERRED_LINES(2, "123 456", 2, 1); | |
204 TEST_GET_PREFERRED_LINES(2, "123 456", 3, 1); | |
205 TEST_GET_PREFERRED_LINES(2, "123 456", -1, 1); | |
206 TEST_GET_PREFERRED_LINES(2, "123 456", -2, 1); | |
207 TEST_GET_PREFERRED_LINES(2, "123 456", std::numeric_limits<int>::min(), 1); | |
208 | |
209 // Large width values should yield all words on one line. | |
210 TEST_GET_PREFERRED_LINES(1, "123 456", 610, 1); | |
211 TEST_GET_PREFERRED_LINES(1, "123 456", std::numeric_limits<int>::max(), 1); | |
212 } | |
213 | |
214 /* Other tests ****************************************************************/ | |
215 | |
216 // TODO(dharcourt): Add test cases to verify that: | |
217 // - SetMaxLines() affects GetMaxLines(), GetHeightForWidth(), GetTextSize(), | |
218 // and GetTextLines() return values but not GetPreferredLines() or | |
219 // GetTextSize() ones. | |
220 // - Bound changes affects GetPreferredLines(), GetTextSize(), and | |
221 // GetTextLines() return values. | |
222 // - GetTextFlags are as expected. | |
223 | |
224 } // namespace message_center | |
OLD | NEW |