|
1 <?php |
|
2 |
|
3 /** |
|
4 * @file |
|
5 * Various unicode handling tests. |
|
6 */ |
|
7 |
|
8 /** |
|
9 * Test unicode handling features implemented in unicode.inc. |
|
10 */ |
|
11 class UnicodeUnitTest extends DrupalUnitTestCase { |
|
12 |
|
13 /** |
|
14 * Whether to run the extended version of the tests (including non latin1 characters). |
|
15 * |
|
16 * @var boolean |
|
17 */ |
|
18 protected $extendedMode = FALSE; |
|
19 |
|
20 public static function getInfo() { |
|
21 return array( |
|
22 'name' => 'Unicode handling', |
|
23 'description' => 'Tests Drupal Unicode handling.', |
|
24 'group' => 'System', |
|
25 ); |
|
26 } |
|
27 |
|
28 /** |
|
29 * Test full unicode features implemented using the mbstring extension. |
|
30 */ |
|
31 function testMbStringUnicode() { |
|
32 global $multibyte; |
|
33 |
|
34 // mbstring was not detected on this installation, there is no way to test |
|
35 // multibyte features. Treat that as an exception. |
|
36 if ($multibyte == UNICODE_SINGLEBYTE) { |
|
37 $this->error(t('Unable to test Multibyte features: mbstring extension was not detected.')); |
|
38 } |
|
39 |
|
40 $multibyte = UNICODE_MULTIBYTE; |
|
41 |
|
42 $this->extendedMode = TRUE; |
|
43 $this->pass(t('Testing in mbstring mode')); |
|
44 |
|
45 $this->helperTestStrToLower(); |
|
46 $this->helperTestStrToUpper(); |
|
47 $this->helperTestUcFirst(); |
|
48 $this->helperTestStrLen(); |
|
49 $this->helperTestSubStr(); |
|
50 $this->helperTestTruncate(); |
|
51 } |
|
52 |
|
53 /** |
|
54 * Test emulated unicode features. |
|
55 */ |
|
56 function testEmulatedUnicode() { |
|
57 global $multibyte; |
|
58 |
|
59 $multibyte = UNICODE_SINGLEBYTE; |
|
60 |
|
61 $this->extendedMode = FALSE; |
|
62 |
|
63 $this->pass(t('Testing in emulated (best-effort) mode')); |
|
64 |
|
65 $this->helperTestStrToLower(); |
|
66 $this->helperTestStrToUpper(); |
|
67 $this->helperTestUcFirst(); |
|
68 $this->helperTestStrLen(); |
|
69 $this->helperTestSubStr(); |
|
70 $this->helperTestTruncate(); |
|
71 } |
|
72 |
|
73 function helperTestStrToLower() { |
|
74 $testcase = array( |
|
75 'tHe QUIcK bRoWn' => 'the quick brown', |
|
76 'FrançAIS is ÜBER-åwesome' => 'français is über-åwesome', |
|
77 ); |
|
78 if ($this->extendedMode) { |
|
79 $testcase['ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΣὨ'] = 'αβγδεζηθικλμνξοσὠ'; |
|
80 } |
|
81 |
|
82 foreach ($testcase as $input => $output) { |
|
83 $this->assertEqual(drupal_strtolower($input), $output, format_string('%input is lowercased as %output', array('%input' => $input, '%output' => $output))); |
|
84 } |
|
85 } |
|
86 |
|
87 function helperTestStrToUpper() { |
|
88 $testcase = array( |
|
89 'tHe QUIcK bRoWn' => 'THE QUICK BROWN', |
|
90 'FrançAIS is ÜBER-åwesome' => 'FRANÇAIS IS ÜBER-ÅWESOME', |
|
91 ); |
|
92 if ($this->extendedMode) { |
|
93 $testcase['αβγδεζηθικλμνξοσὠ'] = 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΣὨ'; |
|
94 } |
|
95 |
|
96 foreach ($testcase as $input => $output) { |
|
97 $this->assertEqual(drupal_strtoupper($input), $output, format_string('%input is uppercased as %output', array('%input' => $input, '%output' => $output))); |
|
98 } |
|
99 } |
|
100 |
|
101 function helperTestUcFirst() { |
|
102 $testcase = array( |
|
103 'tHe QUIcK bRoWn' => 'THe QUIcK bRoWn', |
|
104 'françAIS' => 'FrançAIS', |
|
105 'über' => 'Über', |
|
106 'åwesome' => 'Åwesome' |
|
107 ); |
|
108 if ($this->extendedMode) { |
|
109 $testcase['σion'] = 'Σion'; |
|
110 } |
|
111 |
|
112 foreach ($testcase as $input => $output) { |
|
113 $this->assertEqual(drupal_ucfirst($input), $output, format_string('%input is ucfirst-ed as %output', array('%input' => $input, '%output' => $output))); |
|
114 } |
|
115 } |
|
116 |
|
117 function helperTestStrLen() { |
|
118 $testcase = array( |
|
119 'tHe QUIcK bRoWn' => 15, |
|
120 'ÜBER-åwesome' => 12, |
|
121 ); |
|
122 |
|
123 foreach ($testcase as $input => $output) { |
|
124 $this->assertEqual(drupal_strlen($input), $output, format_string('%input length is %output', array('%input' => $input, '%output' => $output))); |
|
125 } |
|
126 } |
|
127 |
|
128 function helperTestSubStr() { |
|
129 $testcase = array( |
|
130 // 012345678901234567890123 |
|
131 array('frànçAIS is über-åwesome', 0, 0, |
|
132 ''), |
|
133 array('frànçAIS is über-åwesome', 0, 1, |
|
134 'f'), |
|
135 array('frànçAIS is über-åwesome', 0, 8, |
|
136 'frànçAIS'), |
|
137 array('frànçAIS is über-åwesome', 0, 23, |
|
138 'frànçAIS is über-åwesom'), |
|
139 array('frànçAIS is über-åwesome', 0, 24, |
|
140 'frànçAIS is über-åwesome'), |
|
141 array('frànçAIS is über-åwesome', 0, 25, |
|
142 'frànçAIS is über-åwesome'), |
|
143 array('frànçAIS is über-åwesome', 0, 100, |
|
144 'frànçAIS is über-åwesome'), |
|
145 array('frànçAIS is über-åwesome', 4, 4, |
|
146 'çAIS'), |
|
147 array('frànçAIS is über-åwesome', 1, 0, |
|
148 ''), |
|
149 array('frànçAIS is über-åwesome', 100, 0, |
|
150 ''), |
|
151 array('frànçAIS is über-åwesome', -4, 2, |
|
152 'so'), |
|
153 array('frànçAIS is über-åwesome', -4, 3, |
|
154 'som'), |
|
155 array('frànçAIS is über-åwesome', -4, 4, |
|
156 'some'), |
|
157 array('frànçAIS is über-åwesome', -4, 5, |
|
158 'some'), |
|
159 array('frànçAIS is über-åwesome', -7, 10, |
|
160 'åwesome'), |
|
161 array('frànçAIS is über-åwesome', 5, -10, |
|
162 'AIS is üb'), |
|
163 array('frànçAIS is über-åwesome', 0, -10, |
|
164 'frànçAIS is üb'), |
|
165 array('frànçAIS is über-åwesome', 0, -1, |
|
166 'frànçAIS is über-åwesom'), |
|
167 array('frànçAIS is über-åwesome', -7, -2, |
|
168 'åweso'), |
|
169 array('frànçAIS is über-åwesome', -7, -6, |
|
170 'å'), |
|
171 array('frànçAIS is über-åwesome', -7, -7, |
|
172 ''), |
|
173 array('frànçAIS is über-åwesome', -7, -8, |
|
174 ''), |
|
175 array('...', 0, 2, '..'), |
|
176 array('以呂波耳・ほへとち。リヌルヲ。', 1, 3, |
|
177 '呂波耳'), |
|
178 |
|
179 ); |
|
180 |
|
181 foreach ($testcase as $test) { |
|
182 list($input, $start, $length, $output) = $test; |
|
183 $result = drupal_substr($input, $start, $length); |
|
184 $this->assertEqual($result, $output, format_string('%input substring at offset %offset for %length characters is %output (got %result)', array('%input' => $input, '%offset' => $start, '%length' => $length, '%output' => $output, '%result' => $result))); |
|
185 } |
|
186 } |
|
187 |
|
188 /** |
|
189 * Test decode_entities(). |
|
190 */ |
|
191 function testDecodeEntities() { |
|
192 $testcase = array( |
|
193 'Drupal' => 'Drupal', |
|
194 '<script>' => '<script>', |
|
195 '<script>' => '<script>', |
|
196 '<script>' => '<script>', |
|
197 '&lt;script&gt;' => '<script>', |
|
198 '"' => '"', |
|
199 '"' => '"', |
|
200 '&#34;' => '"', |
|
201 '"' => '"', |
|
202 '&quot;' => '"', |
|
203 "'" => "'", |
|
204 ''' => "'", |
|
205 '&#39;' => ''', |
|
206 '©' => '©', |
|
207 '©' => '©', |
|
208 '©' => '©', |
|
209 '→' => '→', |
|
210 '→' => '→', |
|
211 '➼' => '➼', |
|
212 '➼' => '➼', |
|
213 '€' => '€', |
|
214 ); |
|
215 foreach ($testcase as $input => $output) { |
|
216 $this->assertEqual(decode_entities($input), $output, format_string('Make sure the decoded entity of @input is @output', array('@input' => $input, '@output' => $output))); |
|
217 } |
|
218 } |
|
219 |
|
220 /** |
|
221 * Tests truncate_utf8(). |
|
222 */ |
|
223 function helperTestTruncate() { |
|
224 // Each case is an array with input string, length to truncate to, and |
|
225 // expected return value. |
|
226 |
|
227 // Test non-wordsafe, non-ellipsis cases. |
|
228 $non_wordsafe_non_ellipsis_cases = array( |
|
229 array('frànçAIS is über-åwesome', 24, 'frànçAIS is über-åwesome'), |
|
230 array('frànçAIS is über-åwesome', 23, 'frànçAIS is über-åwesom'), |
|
231 array('frànçAIS is über-åwesome', 17, 'frànçAIS is über-'), |
|
232 array('以呂波耳・ほへとち。リヌルヲ。', 6, '以呂波耳・ほ'), |
|
233 ); |
|
234 $this->runTruncateTests($non_wordsafe_non_ellipsis_cases, FALSE, FALSE); |
|
235 |
|
236 // Test non-wordsafe, ellipsis cases. |
|
237 $non_wordsafe_ellipsis_cases = array( |
|
238 array('frànçAIS is über-åwesome', 24, 'frànçAIS is über-åwesome'), |
|
239 array('frànçAIS is über-åwesome', 23, 'frànçAIS is über-åwe...'), |
|
240 array('frànçAIS is über-åwesome', 17, 'frànçAIS is üb...'), |
|
241 ); |
|
242 $this->runTruncateTests($non_wordsafe_ellipsis_cases, FALSE, TRUE); |
|
243 |
|
244 // Test wordsafe, ellipsis cases. |
|
245 $wordsafe_ellipsis_cases = array( |
|
246 array('123', 1, '.'), |
|
247 array('123', 2, '..'), |
|
248 array('123', 3, '123'), |
|
249 array('1234', 3, '...'), |
|
250 array('1234567890', 10, '1234567890'), |
|
251 array('12345678901', 10, '1234567...'), |
|
252 array('12345678901', 11, '12345678901'), |
|
253 array('123456789012', 11, '12345678...'), |
|
254 array('12345 7890', 10, '12345 7890'), |
|
255 array('12345 7890', 9, '12345...'), |
|
256 array('123 567 90', 10, '123 567 90'), |
|
257 array('123 567 901', 10, '123 567...'), |
|
258 array('Stop. Hammertime.', 17, 'Stop. Hammertime.'), |
|
259 array('Stop. Hammertime.', 16, 'Stop....'), |
|
260 array('frànçAIS is über-åwesome', 24, 'frànçAIS is über-åwesome'), |
|
261 array('frànçAIS is über-åwesome', 23, 'frànçAIS is über...'), |
|
262 array('frànçAIS is über-åwesome', 17, 'frànçAIS is...'), |
|
263 array('¿Dónde está el niño?', 20, '¿Dónde está el niño?'), |
|
264 array('¿Dónde está el niño?', 19, '¿Dónde está el...'), |
|
265 array('¿Dónde está el niño?', 15, '¿Dónde está...'), |
|
266 array('¿Dónde está el niño?', 10, '¿Dónde...'), |
|
267 array('Help! Help! Help!', 17, 'Help! Help! Help!'), |
|
268 array('Help! Help! Help!', 16, 'Help! Help!...'), |
|
269 array('Help! Help! Help!', 15, 'Help! Help!...'), |
|
270 array('Help! Help! Help!', 14, 'Help! Help!...'), |
|
271 array('Help! Help! Help!', 13, 'Help! Help...'), |
|
272 array('Help! Help! Help!', 12, 'Help!...'), |
|
273 array('Help! Help! Help!', 11, 'Help!...'), |
|
274 array('Help! Help! Help!', 10, 'Help!...'), |
|
275 array('Help! Help! Help!', 9, 'Help!...'), |
|
276 array('Help! Help! Help!', 8, 'Help!...'), |
|
277 array('Help! Help! Help!', 7, 'Help...'), |
|
278 array('Help! Help! Help!', 6, 'Hel...'), |
|
279 array('Help! Help! Help!', 5, 'He...'), |
|
280 ); |
|
281 $this->runTruncateTests($wordsafe_ellipsis_cases, TRUE, TRUE); |
|
282 } |
|
283 |
|
284 /** |
|
285 * Runs test cases for helperTestTruncate(). |
|
286 * |
|
287 * Runs each test case through truncate_utf8() and compares the output |
|
288 * to the expected output. |
|
289 * |
|
290 * @param $cases |
|
291 * Cases array. Each case is an array with the input string, length to |
|
292 * truncate to, and expected output. |
|
293 * @param $wordsafe |
|
294 * TRUE to use word-safe truncation, FALSE to not use word-safe truncation. |
|
295 * @param $ellipsis |
|
296 * TRUE to append ... if the input is truncated, FALSE to not append .... |
|
297 */ |
|
298 function runTruncateTests($cases, $wordsafe, $ellipsis) { |
|
299 foreach ($cases as $case) { |
|
300 list($input, $max_length, $expected) = $case; |
|
301 $output = truncate_utf8($input, $max_length, $wordsafe, $ellipsis); |
|
302 $this->assertEqual($output, $expected, format_string('%input truncate to %length characters with %wordsafe, %ellipsis is %expected (got %output)', array('%input' => $input, '%length' => $max_length, '%output' => $output, '%expected' => $expected, '%wordsafe' => ($wordsafe ? 'word-safe' : 'not word-safe'), '%ellipsis' => ($ellipsis ? 'ellipsis' : 'not ellipsis')))); |
|
303 } |
|
304 } |
|
305 } |