Chris@0
|
1 <?php
|
Chris@0
|
2
|
Chris@0
|
3 namespace Drupal\Tests\Component\Utility;
|
Chris@0
|
4
|
Chris@0
|
5 use Drupal\Component\Utility\Unicode;
|
Chris@0
|
6 use PHPUnit\Framework\TestCase;
|
Chris@0
|
7
|
Chris@0
|
8 /**
|
Chris@0
|
9 * Test unicode handling features implemented in Unicode component.
|
Chris@0
|
10 *
|
Chris@0
|
11 * @group Utility
|
Chris@0
|
12 *
|
Chris@0
|
13 * @coversDefaultClass \Drupal\Component\Utility\Unicode
|
Chris@0
|
14 */
|
Chris@0
|
15 class UnicodeTest extends TestCase {
|
Chris@0
|
16
|
Chris@0
|
17 /**
|
Chris@0
|
18 * {@inheritdoc}
|
Chris@0
|
19 *
|
Chris@0
|
20 * @covers ::check
|
Chris@0
|
21 */
|
Chris@0
|
22 protected function setUp() {
|
Chris@0
|
23 // Initialize unicode component.
|
Chris@0
|
24 Unicode::check();
|
Chris@0
|
25 }
|
Chris@0
|
26
|
Chris@0
|
27 /**
|
Chris@0
|
28 * Getting and settings the multibyte environment status.
|
Chris@0
|
29 *
|
Chris@0
|
30 * @dataProvider providerTestStatus
|
Chris@0
|
31 * @covers ::getStatus
|
Chris@0
|
32 * @covers ::setStatus
|
Chris@0
|
33 */
|
Chris@0
|
34 public function testStatus($value, $expected, $invalid = FALSE) {
|
Chris@0
|
35 if ($invalid) {
|
Chris@14
|
36 if (method_exists($this, 'expectException')) {
|
Chris@14
|
37 $this->expectException('InvalidArgumentException');
|
Chris@14
|
38 }
|
Chris@14
|
39 else {
|
Chris@14
|
40 $this->setExpectedException('InvalidArgumentException');
|
Chris@14
|
41 }
|
Chris@0
|
42 }
|
Chris@0
|
43 Unicode::setStatus($value);
|
Chris@0
|
44 $this->assertEquals($expected, Unicode::getStatus());
|
Chris@0
|
45 }
|
Chris@0
|
46
|
Chris@0
|
47 /**
|
Chris@0
|
48 * Data provider for testStatus().
|
Chris@0
|
49 *
|
Chris@0
|
50 * @see testStatus()
|
Chris@0
|
51 *
|
Chris@0
|
52 * @return array
|
Chris@0
|
53 * An array containing:
|
Chris@0
|
54 * - The status value to set.
|
Chris@0
|
55 * - The status value to expect after setting the new value.
|
Chris@0
|
56 * - (optional) Boolean indicating invalid status. Defaults to FALSE.
|
Chris@0
|
57 */
|
Chris@0
|
58 public function providerTestStatus() {
|
Chris@0
|
59 return [
|
Chris@0
|
60 [Unicode::STATUS_SINGLEBYTE, Unicode::STATUS_SINGLEBYTE],
|
Chris@0
|
61 [rand(10, 100), Unicode::STATUS_SINGLEBYTE, TRUE],
|
Chris@0
|
62 [rand(10, 100), Unicode::STATUS_SINGLEBYTE, TRUE],
|
Chris@0
|
63 [Unicode::STATUS_MULTIBYTE, Unicode::STATUS_MULTIBYTE],
|
Chris@0
|
64 [rand(10, 100), Unicode::STATUS_MULTIBYTE, TRUE],
|
Chris@0
|
65 [Unicode::STATUS_ERROR, Unicode::STATUS_ERROR],
|
Chris@0
|
66 [Unicode::STATUS_MULTIBYTE, Unicode::STATUS_MULTIBYTE],
|
Chris@0
|
67 ];
|
Chris@0
|
68 }
|
Chris@0
|
69
|
Chris@0
|
70 /**
|
Chris@0
|
71 * Tests multibyte encoding and decoding.
|
Chris@0
|
72 *
|
Chris@0
|
73 * @dataProvider providerTestMimeHeader
|
Chris@0
|
74 * @covers ::mimeHeaderEncode
|
Chris@0
|
75 * @covers ::mimeHeaderDecode
|
Chris@0
|
76 */
|
Chris@0
|
77 public function testMimeHeader($value, $encoded) {
|
Chris@0
|
78 $this->assertEquals($encoded, Unicode::mimeHeaderEncode($value));
|
Chris@0
|
79 $this->assertEquals($value, Unicode::mimeHeaderDecode($encoded));
|
Chris@0
|
80 }
|
Chris@0
|
81
|
Chris@0
|
82 /**
|
Chris@0
|
83 * Data provider for testMimeHeader().
|
Chris@0
|
84 *
|
Chris@0
|
85 * @see testMimeHeader()
|
Chris@0
|
86 *
|
Chris@0
|
87 * @return array
|
Chris@0
|
88 * An array containing a string and its encoded value.
|
Chris@0
|
89 */
|
Chris@0
|
90 public function providerTestMimeHeader() {
|
Chris@0
|
91 return [
|
Chris@0
|
92 ['tést.txt', '=?UTF-8?B?dMOpc3QudHh0?='],
|
Chris@0
|
93 // Simple ASCII characters.
|
Chris@0
|
94 ['ASCII', 'ASCII'],
|
Chris@0
|
95 ];
|
Chris@0
|
96 }
|
Chris@0
|
97
|
Chris@0
|
98 /**
|
Chris@0
|
99 * Tests multibyte strtolower.
|
Chris@0
|
100 *
|
Chris@0
|
101 * @dataProvider providerStrtolower
|
Chris@0
|
102 * @covers ::strtolower
|
Chris@0
|
103 * @covers ::caseFlip
|
Chris@0
|
104 */
|
Chris@0
|
105 public function testStrtolower($text, $expected, $multibyte = FALSE) {
|
Chris@0
|
106 $status = $multibyte ? Unicode::STATUS_MULTIBYTE : Unicode::STATUS_SINGLEBYTE;
|
Chris@0
|
107 Unicode::setStatus($status);
|
Chris@0
|
108 $this->assertEquals($expected, Unicode::strtolower($text));
|
Chris@0
|
109 }
|
Chris@0
|
110
|
Chris@0
|
111 /**
|
Chris@0
|
112 * Data provider for testStrtolower().
|
Chris@0
|
113 *
|
Chris@0
|
114 * @see testStrtolower()
|
Chris@0
|
115 *
|
Chris@0
|
116 * @return array
|
Chris@0
|
117 * An array containing a string, its lowercase version and whether it should
|
Chris@0
|
118 * be processed as multibyte.
|
Chris@0
|
119 */
|
Chris@0
|
120 public function providerStrtolower() {
|
Chris@0
|
121 $cases = [
|
Chris@0
|
122 ['tHe QUIcK bRoWn', 'the quick brown'],
|
Chris@0
|
123 ['FrançAIS is ÜBER-åwesome', 'français is über-åwesome'],
|
Chris@0
|
124 ];
|
Chris@0
|
125 foreach ($cases as $case) {
|
Chris@0
|
126 // Test the same string both in multibyte and singlebyte conditions.
|
Chris@0
|
127 array_push($case, TRUE);
|
Chris@0
|
128 $cases[] = $case;
|
Chris@0
|
129 }
|
Chris@0
|
130 // Add a multibyte string.
|
Chris@0
|
131 $cases[] = ['ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΣὨ', 'αβγδεζηθικλμνξοσὠ', TRUE];
|
Chris@0
|
132 return $cases;
|
Chris@0
|
133 }
|
Chris@0
|
134
|
Chris@0
|
135 /**
|
Chris@0
|
136 * Tests multibyte strtoupper.
|
Chris@0
|
137 *
|
Chris@0
|
138 * @dataProvider providerStrtoupper
|
Chris@0
|
139 * @covers ::strtoupper
|
Chris@0
|
140 * @covers ::caseFlip
|
Chris@0
|
141 */
|
Chris@0
|
142 public function testStrtoupper($text, $expected, $multibyte = FALSE) {
|
Chris@0
|
143 $status = $multibyte ? Unicode::STATUS_MULTIBYTE : Unicode::STATUS_SINGLEBYTE;
|
Chris@0
|
144 Unicode::setStatus($status);
|
Chris@0
|
145 $this->assertEquals($expected, Unicode::strtoupper($text));
|
Chris@0
|
146 }
|
Chris@0
|
147
|
Chris@0
|
148 /**
|
Chris@0
|
149 * Data provider for testStrtoupper().
|
Chris@0
|
150 *
|
Chris@0
|
151 * @see testStrtoupper()
|
Chris@0
|
152 *
|
Chris@0
|
153 * @return array
|
Chris@0
|
154 * An array containing a string, its uppercase version and whether it should
|
Chris@0
|
155 * be processed as multibyte.
|
Chris@0
|
156 */
|
Chris@0
|
157 public function providerStrtoupper() {
|
Chris@0
|
158 $cases = [
|
Chris@0
|
159 ['tHe QUIcK bRoWn', 'THE QUICK BROWN'],
|
Chris@0
|
160 ['FrançAIS is ÜBER-åwesome', 'FRANÇAIS IS ÜBER-ÅWESOME'],
|
Chris@0
|
161 ];
|
Chris@0
|
162 foreach ($cases as $case) {
|
Chris@0
|
163 // Test the same string both in multibyte and singlebyte conditions.
|
Chris@0
|
164 array_push($case, TRUE);
|
Chris@0
|
165 $cases[] = $case;
|
Chris@0
|
166 }
|
Chris@0
|
167 // Add a multibyte string.
|
Chris@0
|
168 $cases[] = ['αβγδεζηθικλμνξοσὠ', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΣὨ', TRUE];
|
Chris@0
|
169 return $cases;
|
Chris@0
|
170 }
|
Chris@0
|
171
|
Chris@0
|
172 /**
|
Chris@0
|
173 * Tests multibyte ucfirst.
|
Chris@0
|
174 *
|
Chris@0
|
175 * @dataProvider providerUcfirst
|
Chris@0
|
176 * @covers ::ucfirst
|
Chris@0
|
177 */
|
Chris@0
|
178 public function testUcfirst($text, $expected) {
|
Chris@0
|
179 $this->assertEquals($expected, Unicode::ucfirst($text));
|
Chris@0
|
180 }
|
Chris@0
|
181
|
Chris@0
|
182 /**
|
Chris@0
|
183 * Data provider for testUcfirst().
|
Chris@0
|
184 *
|
Chris@0
|
185 * @see testUcfirst()
|
Chris@0
|
186 *
|
Chris@0
|
187 * @return array
|
Chris@0
|
188 * An array containing a string and its uppercase first version.
|
Chris@0
|
189 */
|
Chris@0
|
190 public function providerUcfirst() {
|
Chris@0
|
191 return [
|
Chris@0
|
192 ['tHe QUIcK bRoWn', 'THe QUIcK bRoWn'],
|
Chris@0
|
193 ['françAIS', 'FrançAIS'],
|
Chris@0
|
194 ['über', 'Über'],
|
Chris@0
|
195 ['åwesome', 'Åwesome'],
|
Chris@0
|
196 // A multibyte string.
|
Chris@0
|
197 ['σion', 'Σion'],
|
Chris@0
|
198 ];
|
Chris@0
|
199 }
|
Chris@0
|
200
|
Chris@0
|
201 /**
|
Chris@0
|
202 * Tests multibyte lcfirst.
|
Chris@0
|
203 *
|
Chris@0
|
204 * @dataProvider providerLcfirst
|
Chris@0
|
205 * @covers ::lcfirst
|
Chris@0
|
206 */
|
Chris@0
|
207 public function testLcfirst($text, $expected, $multibyte = FALSE) {
|
Chris@0
|
208 $status = $multibyte ? Unicode::STATUS_MULTIBYTE : Unicode::STATUS_SINGLEBYTE;
|
Chris@0
|
209 Unicode::setStatus($status);
|
Chris@0
|
210 $this->assertEquals($expected, Unicode::lcfirst($text));
|
Chris@0
|
211 }
|
Chris@0
|
212
|
Chris@0
|
213 /**
|
Chris@0
|
214 * Data provider for testLcfirst().
|
Chris@0
|
215 *
|
Chris@0
|
216 * @see testLcfirst()
|
Chris@0
|
217 *
|
Chris@0
|
218 * @return array
|
Chris@0
|
219 * An array containing a string, its lowercase version and whether it should
|
Chris@0
|
220 * be processed as multibyte.
|
Chris@0
|
221 */
|
Chris@0
|
222 public function providerLcfirst() {
|
Chris@0
|
223 return [
|
Chris@0
|
224 ['tHe QUIcK bRoWn', 'tHe QUIcK bRoWn'],
|
Chris@0
|
225 ['FrançAIS is ÜBER-åwesome', 'françAIS is ÜBER-åwesome'],
|
Chris@0
|
226 ['Über', 'über'],
|
Chris@0
|
227 ['Åwesome', 'åwesome'],
|
Chris@0
|
228 // Add a multibyte string.
|
Chris@0
|
229 ['ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΣὨ', 'αΒΓΔΕΖΗΘΙΚΛΜΝΞΟΣὨ', TRUE],
|
Chris@0
|
230 ];
|
Chris@0
|
231 }
|
Chris@0
|
232
|
Chris@0
|
233 /**
|
Chris@0
|
234 * Tests multibyte ucwords.
|
Chris@0
|
235 *
|
Chris@0
|
236 * @dataProvider providerUcwords
|
Chris@0
|
237 * @covers ::ucwords
|
Chris@0
|
238 */
|
Chris@0
|
239 public function testUcwords($text, $expected, $multibyte = FALSE) {
|
Chris@0
|
240 $status = $multibyte ? Unicode::STATUS_MULTIBYTE : Unicode::STATUS_SINGLEBYTE;
|
Chris@0
|
241 Unicode::setStatus($status);
|
Chris@0
|
242 $this->assertEquals($expected, Unicode::ucwords($text));
|
Chris@0
|
243 }
|
Chris@0
|
244
|
Chris@0
|
245 /**
|
Chris@0
|
246 * Data provider for testUcwords().
|
Chris@0
|
247 *
|
Chris@0
|
248 * @see testUcwords()
|
Chris@0
|
249 *
|
Chris@0
|
250 * @return array
|
Chris@0
|
251 * An array containing a string, its capitalized version and whether it should
|
Chris@0
|
252 * be processed as multibyte.
|
Chris@0
|
253 */
|
Chris@0
|
254 public function providerUcwords() {
|
Chris@0
|
255 return [
|
Chris@0
|
256 ['tHe QUIcK bRoWn', 'THe QUIcK BRoWn'],
|
Chris@0
|
257 ['françAIS', 'FrançAIS'],
|
Chris@0
|
258 ['über', 'Über'],
|
Chris@0
|
259 ['åwesome', 'Åwesome'],
|
Chris@0
|
260 // Make sure we don't mangle extra spaces.
|
Chris@0
|
261 ['frànçAIS is über-åwesome', 'FrànçAIS Is Über-Åwesome'],
|
Chris@0
|
262 // Add a multibyte string.
|
Chris@0
|
263 ['σion', 'Σion', TRUE],
|
Chris@0
|
264 ];
|
Chris@0
|
265 }
|
Chris@0
|
266
|
Chris@0
|
267 /**
|
Chris@0
|
268 * Tests multibyte strlen.
|
Chris@0
|
269 *
|
Chris@0
|
270 * @dataProvider providerStrlen
|
Chris@0
|
271 * @covers ::strlen
|
Chris@0
|
272 */
|
Chris@0
|
273 public function testStrlen($text, $expected) {
|
Chris@0
|
274 // Run through multibyte code path.
|
Chris@0
|
275 Unicode::setStatus(Unicode::STATUS_MULTIBYTE);
|
Chris@0
|
276 $this->assertEquals($expected, Unicode::strlen($text));
|
Chris@0
|
277 // Run through singlebyte code path.
|
Chris@0
|
278 Unicode::setStatus(Unicode::STATUS_SINGLEBYTE);
|
Chris@0
|
279 $this->assertEquals($expected, Unicode::strlen($text));
|
Chris@0
|
280 }
|
Chris@0
|
281
|
Chris@0
|
282 /**
|
Chris@0
|
283 * Data provider for testStrlen().
|
Chris@0
|
284 *
|
Chris@0
|
285 * @see testStrlen()
|
Chris@0
|
286 *
|
Chris@0
|
287 * @return array
|
Chris@0
|
288 * An array containing a string and its length.
|
Chris@0
|
289 */
|
Chris@0
|
290 public function providerStrlen() {
|
Chris@0
|
291 return [
|
Chris@0
|
292 ['tHe QUIcK bRoWn', 15],
|
Chris@0
|
293 ['ÜBER-åwesome', 12],
|
Chris@0
|
294 ['以呂波耳・ほへとち。リヌルヲ。', 15],
|
Chris@0
|
295 ];
|
Chris@0
|
296 }
|
Chris@0
|
297
|
Chris@0
|
298 /**
|
Chris@0
|
299 * Tests multibyte substr.
|
Chris@0
|
300 *
|
Chris@0
|
301 * @dataProvider providerSubstr
|
Chris@0
|
302 * @covers ::substr
|
Chris@0
|
303 */
|
Chris@0
|
304 public function testSubstr($text, $start, $length, $expected) {
|
Chris@0
|
305 // Run through multibyte code path.
|
Chris@0
|
306 Unicode::setStatus(Unicode::STATUS_MULTIBYTE);
|
Chris@0
|
307 $this->assertEquals($expected, Unicode::substr($text, $start, $length));
|
Chris@0
|
308 // Run through singlebyte code path.
|
Chris@0
|
309 Unicode::setStatus(Unicode::STATUS_SINGLEBYTE);
|
Chris@0
|
310 $this->assertEquals($expected, Unicode::substr($text, $start, $length));
|
Chris@0
|
311 }
|
Chris@0
|
312
|
Chris@0
|
313 /**
|
Chris@0
|
314 * Data provider for testSubstr().
|
Chris@0
|
315 *
|
Chris@0
|
316 * @see testSubstr()
|
Chris@0
|
317 *
|
Chris@0
|
318 * @return array
|
Chris@0
|
319 * An array containing:
|
Chris@0
|
320 * - The string to test.
|
Chris@0
|
321 * - The start number to be processed by substr.
|
Chris@0
|
322 * - The length number to be processed by substr.
|
Chris@0
|
323 * - The expected string result.
|
Chris@0
|
324 */
|
Chris@0
|
325 public function providerSubstr() {
|
Chris@0
|
326 return [
|
Chris@0
|
327 ['frànçAIS is über-åwesome', 0, NULL, 'frànçAIS is über-åwesome'],
|
Chris@0
|
328 ['frànçAIS is über-åwesome', 0, 0, ''],
|
Chris@0
|
329 ['frànçAIS is über-åwesome', 0, 1, 'f'],
|
Chris@0
|
330 ['frànçAIS is über-åwesome', 0, 8, 'frànçAIS'],
|
Chris@0
|
331 ['frànçAIS is über-åwesome', 0, 23, 'frànçAIS is über-åwesom'],
|
Chris@0
|
332 ['frànçAIS is über-åwesome', 0, 24, 'frànçAIS is über-åwesome'],
|
Chris@0
|
333 ['frànçAIS is über-åwesome', 0, 25, 'frànçAIS is über-åwesome'],
|
Chris@0
|
334 ['frànçAIS is über-åwesome', 0, 100, 'frànçAIS is über-åwesome'],
|
Chris@0
|
335 ['frànçAIS is über-åwesome', 4, 4, 'çAIS'],
|
Chris@0
|
336 ['frànçAIS is über-åwesome', 1, 0, ''],
|
Chris@0
|
337 ['frànçAIS is über-åwesome', 100, 0, ''],
|
Chris@0
|
338 ['frànçAIS is über-åwesome', -4, 2, 'so'],
|
Chris@0
|
339 ['frànçAIS is über-åwesome', -4, 3, 'som'],
|
Chris@0
|
340 ['frànçAIS is über-åwesome', -4, 4, 'some'],
|
Chris@0
|
341 ['frànçAIS is über-åwesome', -4, 5, 'some'],
|
Chris@0
|
342 ['frànçAIS is über-åwesome', -7, 10, 'åwesome'],
|
Chris@0
|
343 ['frànçAIS is über-åwesome', 5, -10, 'AIS is üb'],
|
Chris@0
|
344 ['frànçAIS is über-åwesome', 0, -10, 'frànçAIS is üb'],
|
Chris@0
|
345 ['frànçAIS is über-åwesome', 0, -1, 'frànçAIS is über-åwesom'],
|
Chris@0
|
346 ['frànçAIS is über-åwesome', -7, -2, 'åweso'],
|
Chris@0
|
347 ['frànçAIS is über-åwesome', -7, -6, 'å'],
|
Chris@0
|
348 ['frànçAIS is über-åwesome', -7, -7, ''],
|
Chris@0
|
349 ['frànçAIS is über-åwesome', -7, -8, ''],
|
Chris@0
|
350 ['...', 0, 2, '..'],
|
Chris@0
|
351 ['以呂波耳・ほへとち。リヌルヲ。', 1, 3, '呂波耳'],
|
Chris@0
|
352 ];
|
Chris@0
|
353 }
|
Chris@0
|
354
|
Chris@0
|
355 /**
|
Chris@0
|
356 * Tests multibyte truncate.
|
Chris@0
|
357 *
|
Chris@0
|
358 * @dataProvider providerTruncate
|
Chris@0
|
359 * @covers ::truncate
|
Chris@0
|
360 */
|
Chris@0
|
361 public function testTruncate($text, $max_length, $expected, $wordsafe = FALSE, $add_ellipsis = FALSE) {
|
Chris@0
|
362 $this->assertEquals($expected, Unicode::truncate($text, $max_length, $wordsafe, $add_ellipsis));
|
Chris@0
|
363 }
|
Chris@0
|
364
|
Chris@0
|
365 /**
|
Chris@0
|
366 * Data provider for testTruncate().
|
Chris@0
|
367 *
|
Chris@0
|
368 * @see testTruncate()
|
Chris@0
|
369 *
|
Chris@0
|
370 * @return array
|
Chris@0
|
371 * An array containing:
|
Chris@0
|
372 * - The string to test.
|
Chris@0
|
373 * - The max length to truncate this string to.
|
Chris@0
|
374 * - The expected string result.
|
Chris@0
|
375 * - (optional) Boolean for the $wordsafe flag. Defaults to FALSE.
|
Chris@0
|
376 * - (optional) Boolean for the $add_ellipsis flag. Defaults to FALSE.
|
Chris@0
|
377 */
|
Chris@0
|
378 public function providerTruncate() {
|
Chris@14
|
379 $tests = [
|
Chris@0
|
380 ['frànçAIS is über-åwesome', 24, 'frànçAIS is über-åwesome'],
|
Chris@0
|
381 ['frànçAIS is über-åwesome', 23, 'frànçAIS is über-åwesom'],
|
Chris@0
|
382 ['frànçAIS is über-åwesome', 17, 'frànçAIS is über-'],
|
Chris@0
|
383 ['以呂波耳・ほへとち。リヌルヲ。', 6, '以呂波耳・ほ'],
|
Chris@0
|
384 ['frànçAIS is über-åwesome', 24, 'frànçAIS is über-åwesome', FALSE, TRUE],
|
Chris@0
|
385 ['frànçAIS is über-åwesome', 23, 'frànçAIS is über-åweso…', FALSE, TRUE],
|
Chris@0
|
386 ['frànçAIS is über-åwesome', 17, 'frànçAIS is über…', FALSE, TRUE],
|
Chris@0
|
387 ['123', 1, '…', TRUE, TRUE],
|
Chris@0
|
388 ['123', 2, '1…', TRUE, TRUE],
|
Chris@0
|
389 ['123', 3, '123', TRUE, TRUE],
|
Chris@0
|
390 ['1234', 3, '12…', TRUE, TRUE],
|
Chris@0
|
391 ['1234567890', 10, '1234567890', TRUE, TRUE],
|
Chris@0
|
392 ['12345678901', 10, '123456789…', TRUE, TRUE],
|
Chris@0
|
393 ['12345678901', 11, '12345678901', TRUE, TRUE],
|
Chris@0
|
394 ['123456789012', 11, '1234567890…', TRUE, TRUE],
|
Chris@0
|
395 ['12345 7890', 10, '12345 7890', TRUE, TRUE],
|
Chris@0
|
396 ['12345 7890', 9, '12345…', TRUE, TRUE],
|
Chris@0
|
397 ['123 567 90', 10, '123 567 90', TRUE, TRUE],
|
Chris@0
|
398 ['123 567 901', 10, '123 567…', TRUE, TRUE],
|
Chris@0
|
399 ['Stop. Hammertime.', 17, 'Stop. Hammertime.', TRUE, TRUE],
|
Chris@0
|
400 ['Stop. Hammertime.', 16, 'Stop…', TRUE, TRUE],
|
Chris@0
|
401 ['frànçAIS is über-åwesome', 24, 'frànçAIS is über-åwesome', TRUE, TRUE],
|
Chris@0
|
402 ['frànçAIS is über-åwesome', 23, 'frànçAIS is über…', TRUE, TRUE],
|
Chris@0
|
403 ['frànçAIS is über-åwesome', 17, 'frànçAIS is über…', TRUE, TRUE],
|
Chris@0
|
404 ['¿Dónde está el niño?', 20, '¿Dónde está el niño?', TRUE, TRUE],
|
Chris@0
|
405 ['¿Dónde está el niño?', 19, '¿Dónde está el…', TRUE, TRUE],
|
Chris@0
|
406 ['¿Dónde está el niño?', 13, '¿Dónde está…', TRUE, TRUE],
|
Chris@0
|
407 ['¿Dónde está el niño?', 10, '¿Dónde…', TRUE, TRUE],
|
Chris@0
|
408 ['Help! Help! Help!', 17, 'Help! Help! Help!', TRUE, TRUE],
|
Chris@0
|
409 ['Help! Help! Help!', 16, 'Help! Help!…', TRUE, TRUE],
|
Chris@0
|
410 ['Help! Help! Help!', 15, 'Help! Help!…', TRUE, TRUE],
|
Chris@0
|
411 ['Help! Help! Help!', 14, 'Help! Help!…', TRUE, TRUE],
|
Chris@0
|
412 ['Help! Help! Help!', 13, 'Help! Help!…', TRUE, TRUE],
|
Chris@0
|
413 ['Help! Help! Help!', 12, 'Help! Help!…', TRUE, TRUE],
|
Chris@0
|
414 ['Help! Help! Help!', 11, 'Help! Help…', TRUE, TRUE],
|
Chris@0
|
415 ['Help! Help! Help!', 10, 'Help!…', TRUE, TRUE],
|
Chris@0
|
416 ['Help! Help! Help!', 9, 'Help!…', TRUE, TRUE],
|
Chris@0
|
417 ['Help! Help! Help!', 8, 'Help!…', TRUE, TRUE],
|
Chris@0
|
418 ['Help! Help! Help!', 7, 'Help!…', TRUE, TRUE],
|
Chris@0
|
419 ['Help! Help! Help!', 6, 'Help!…', TRUE, TRUE],
|
Chris@0
|
420 ['Help! Help! Help!', 5, 'Help…', TRUE, TRUE],
|
Chris@0
|
421 ['Help! Help! Help!', 4, 'Hel…', TRUE, TRUE],
|
Chris@0
|
422 ['Help! Help! Help!', 3, 'He…', TRUE, TRUE],
|
Chris@0
|
423 ['Help! Help! Help!', 2, 'H…', TRUE, TRUE],
|
Chris@0
|
424 ];
|
Chris@14
|
425
|
Chris@14
|
426 // Test truncate on text with multiple lines.
|
Chris@14
|
427 $multi_line = <<<EOF
|
Chris@14
|
428 This is a text that spans multiple lines.
|
Chris@14
|
429 Line 2 goes here.
|
Chris@14
|
430 EOF;
|
Chris@14
|
431 $multi_line_wordsafe = <<<EOF
|
Chris@14
|
432 This is a text that spans multiple lines.
|
Chris@14
|
433 Line 2
|
Chris@14
|
434 EOF;
|
Chris@14
|
435 $multi_line_non_wordsafe = <<<EOF
|
Chris@14
|
436 This is a text that spans multiple lines.
|
Chris@14
|
437 Line 2 go
|
Chris@14
|
438 EOF;
|
Chris@14
|
439 $tests[] = [$multi_line, 51, $multi_line_wordsafe, TRUE];
|
Chris@14
|
440 $tests[] = [$multi_line, 51, $multi_line_non_wordsafe, FALSE];
|
Chris@14
|
441
|
Chris@14
|
442 return $tests;
|
Chris@0
|
443 }
|
Chris@0
|
444
|
Chris@0
|
445 /**
|
Chris@0
|
446 * Tests multibyte truncate bytes.
|
Chris@0
|
447 *
|
Chris@0
|
448 * @dataProvider providerTestTruncateBytes
|
Chris@0
|
449 * @covers ::truncateBytes
|
Chris@0
|
450 *
|
Chris@0
|
451 * @param string $text
|
Chris@0
|
452 * The string to truncate.
|
Chris@0
|
453 * @param int $max_length
|
Chris@0
|
454 * The upper limit on the returned string length.
|
Chris@0
|
455 * @param string $expected
|
Chris@0
|
456 * The expected return from Unicode::truncateBytes().
|
Chris@0
|
457 */
|
Chris@0
|
458 public function testTruncateBytes($text, $max_length, $expected) {
|
Chris@0
|
459 $this->assertEquals($expected, Unicode::truncateBytes($text, $max_length), 'The string was not correctly truncated.');
|
Chris@0
|
460 }
|
Chris@0
|
461
|
Chris@0
|
462 /**
|
Chris@0
|
463 * Provides data for self::testTruncateBytes().
|
Chris@0
|
464 *
|
Chris@0
|
465 * @return array
|
Chris@0
|
466 * An array of arrays, each containing the parameters to
|
Chris@0
|
467 * self::testTruncateBytes().
|
Chris@0
|
468 */
|
Chris@0
|
469 public function providerTestTruncateBytes() {
|
Chris@0
|
470 return [
|
Chris@0
|
471 // String shorter than max length.
|
Chris@0
|
472 ['Short string', 42, 'Short string'],
|
Chris@0
|
473 // Simple string longer than max length.
|
Chris@0
|
474 ['Longer string than previous.', 10, 'Longer str'],
|
Chris@0
|
475 // Unicode.
|
Chris@0
|
476 ['以呂波耳・ほへとち。リヌルヲ。', 10, '以呂波'],
|
Chris@0
|
477 ];
|
Chris@0
|
478 }
|
Chris@0
|
479
|
Chris@0
|
480 /**
|
Chris@0
|
481 * Tests UTF-8 validation.
|
Chris@0
|
482 *
|
Chris@0
|
483 * @dataProvider providerTestValidateUtf8
|
Chris@0
|
484 * @covers ::validateUtf8
|
Chris@0
|
485 *
|
Chris@0
|
486 * @param string $text
|
Chris@0
|
487 * The text to validate.
|
Chris@0
|
488 * @param bool $expected
|
Chris@0
|
489 * The expected return value from Unicode::validateUtf8().
|
Chris@0
|
490 * @param string $message
|
Chris@0
|
491 * The message to display on failure.
|
Chris@0
|
492 */
|
Chris@0
|
493 public function testValidateUtf8($text, $expected, $message) {
|
Chris@0
|
494 $this->assertEquals($expected, Unicode::validateUtf8($text), $message);
|
Chris@0
|
495 }
|
Chris@0
|
496
|
Chris@0
|
497 /**
|
Chris@0
|
498 * Provides data for self::testValidateUtf8().
|
Chris@0
|
499 *
|
Chris@0
|
500 * Invalid UTF-8 examples sourced from http://stackoverflow.com/a/11709412/109119.
|
Chris@0
|
501 *
|
Chris@0
|
502 * @return array
|
Chris@0
|
503 * An array of arrays, each containing the parameters for
|
Chris@0
|
504 * self::testValidateUtf8().
|
Chris@0
|
505 */
|
Chris@0
|
506 public function providerTestValidateUtf8() {
|
Chris@0
|
507 return [
|
Chris@0
|
508 // Empty string.
|
Chris@0
|
509 ['', TRUE, 'An empty string did not validate.'],
|
Chris@0
|
510 // Simple text string.
|
Chris@0
|
511 ['Simple text.', TRUE, 'A simple ASCII text string did not validate.'],
|
Chris@0
|
512 // Invalid UTF-8, overlong 5 byte encoding.
|
Chris@0
|
513 [chr(0xF8) . chr(0x80) . chr(0x80) . chr(0x80) . chr(0x80), FALSE, 'Invalid UTF-8 was validated.'],
|
Chris@0
|
514 // High code-point without trailing characters.
|
Chris@0
|
515 [chr(0xD0) . chr(0x01), FALSE, 'Invalid UTF-8 was validated.'],
|
Chris@0
|
516 ];
|
Chris@0
|
517 }
|
Chris@0
|
518
|
Chris@0
|
519 /**
|
Chris@0
|
520 * Tests UTF-8 conversion.
|
Chris@0
|
521 *
|
Chris@0
|
522 * @dataProvider providerTestConvertToUtf8
|
Chris@0
|
523 * @covers ::convertToUtf8
|
Chris@0
|
524 *
|
Chris@0
|
525 * @param string $data
|
Chris@0
|
526 * The data to be converted.
|
Chris@0
|
527 * @param string $encoding
|
Chris@0
|
528 * The encoding the data is in.
|
Chris@0
|
529 * @param string|bool $expected
|
Chris@0
|
530 * The expected result.
|
Chris@0
|
531 */
|
Chris@0
|
532 public function testConvertToUtf8($data, $encoding, $expected) {
|
Chris@0
|
533 $this->assertEquals($expected, Unicode::convertToUtf8($data, $encoding));
|
Chris@0
|
534 }
|
Chris@0
|
535
|
Chris@0
|
536 /**
|
Chris@0
|
537 * Provides data to self::testConvertToUtf8().
|
Chris@0
|
538 *
|
Chris@0
|
539 * @return array
|
Chris@0
|
540 * An array of arrays, each containing the parameters to
|
Chris@0
|
541 * self::testConvertUtf8(). }
|
Chris@0
|
542 */
|
Chris@0
|
543 public function providerTestConvertToUtf8() {
|
Chris@0
|
544 return [
|
Chris@0
|
545 [chr(0x97), 'Windows-1252', '—'],
|
Chris@0
|
546 [chr(0x99), 'Windows-1252', '™'],
|
Chris@0
|
547 [chr(0x80), 'Windows-1252', '€'],
|
Chris@0
|
548 ];
|
Chris@0
|
549 }
|
Chris@0
|
550
|
Chris@0
|
551 /**
|
Chris@0
|
552 * Tests multibyte strpos.
|
Chris@0
|
553 *
|
Chris@0
|
554 * @dataProvider providerStrpos
|
Chris@0
|
555 * @covers ::strpos
|
Chris@0
|
556 */
|
Chris@0
|
557 public function testStrpos($haystack, $needle, $offset, $expected) {
|
Chris@0
|
558 // Run through multibyte code path.
|
Chris@0
|
559 Unicode::setStatus(Unicode::STATUS_MULTIBYTE);
|
Chris@0
|
560 $this->assertEquals($expected, Unicode::strpos($haystack, $needle, $offset));
|
Chris@0
|
561 // Run through singlebyte code path.
|
Chris@0
|
562 Unicode::setStatus(Unicode::STATUS_SINGLEBYTE);
|
Chris@0
|
563 $this->assertEquals($expected, Unicode::strpos($haystack, $needle, $offset));
|
Chris@0
|
564 }
|
Chris@0
|
565
|
Chris@0
|
566 /**
|
Chris@0
|
567 * Data provider for testStrpos().
|
Chris@0
|
568 *
|
Chris@0
|
569 * @see testStrpos()
|
Chris@0
|
570 *
|
Chris@0
|
571 * @return array
|
Chris@0
|
572 * An array containing:
|
Chris@0
|
573 * - The haystack string to be searched in.
|
Chris@0
|
574 * - The needle string to search for.
|
Chris@0
|
575 * - The offset integer to start at.
|
Chris@0
|
576 * - The expected integer/FALSE result.
|
Chris@0
|
577 */
|
Chris@0
|
578 public function providerStrpos() {
|
Chris@0
|
579 return [
|
Chris@0
|
580 ['frànçAIS is über-åwesome', 'frànçAIS is über-åwesome', 0, 0],
|
Chris@0
|
581 ['frànçAIS is über-åwesome', 'rànçAIS is über-åwesome', 0, 1],
|
Chris@0
|
582 ['frànçAIS is über-åwesome', 'not in string', 0, FALSE],
|
Chris@0
|
583 ['frànçAIS is über-åwesome', 'r', 0, 1],
|
Chris@0
|
584 ['frànçAIS is über-åwesome', 'nçAIS', 0, 3],
|
Chris@0
|
585 ['frànçAIS is über-åwesome', 'nçAIS', 2, 3],
|
Chris@0
|
586 ['frànçAIS is über-åwesome', 'nçAIS', 3, 3],
|
Chris@0
|
587 ['以呂波耳・ほへとち。リヌルヲ。', '波耳', 0, 2],
|
Chris@0
|
588 ['以呂波耳・ほへとち。リヌルヲ。', '波耳', 1, 2],
|
Chris@0
|
589 ['以呂波耳・ほへとち。リヌルヲ。', '波耳', 2, 2],
|
Chris@0
|
590 ];
|
Chris@0
|
591 }
|
Chris@0
|
592
|
Chris@0
|
593 }
|