Merge "Avoid master queries in Title::getLinksFrom()"
[lhc/web/wiklou.git] / tests / phpunit / includes / libs / StringUtilsTest.php
1 <?php
2
3 class StringUtilsTest extends PHPUnit_Framework_TestCase {
4
5 /**
6 * This tests StringUtils::isUtf8 whenever we have the mbstring extension
7 * loaded.
8 *
9 * @covers StringUtils::isUtf8
10 * @dataProvider provideStringsForIsUtf8Check
11 */
12 public function testIsUtf8WithMbstring( $expected, $string ) {
13 if ( !function_exists( 'mb_check_encoding' ) ) {
14 $this->markTestSkipped( 'Test requires the mbstring PHP extension' );
15 }
16 $this->assertEquals( $expected,
17 StringUtils::isUtf8( $string ),
18 'Testing string "' . $this->escaped( $string ) . '" with mb_check_encoding'
19 );
20 }
21
22 /**
23 * This tests StringUtils::isUtf8 making sure we use the pure PHP
24 * implementation used as a fallback when mb_check_encoding() is
25 * not available.
26 *
27 * @covers StringUtils::isUtf8
28 * @dataProvider provideStringsForIsUtf8Check
29 */
30 public function testIsUtf8WithPhpFallbackImplementation( $expected, $string ) {
31 $this->assertEquals( $expected,
32 StringUtils::isUtf8( $string, /** disable mbstring: */true ),
33 'Testing string "' . $this->escaped( $string ) . '" with pure PHP implementation'
34 );
35 }
36
37 /**
38 * Print high range characters as a hexadecimal
39 * @param string $string
40 * @return string
41 */
42 function escaped( $string ) {
43 $escaped = '';
44 $length = strlen( $string );
45 for ( $i = 0; $i < $length; $i++ ) {
46 $char = $string[$i];
47 $val = ord( $char );
48 if ( $val > 127 ) {
49 $escaped .= '\x' . dechex( $val );
50 } else {
51 $escaped .= $char;
52 }
53 }
54
55 return $escaped;
56 }
57
58 /**
59 * See also "UTF-8 decoder capability and stress test" by
60 * Markus Kuhn:
61 * http://www.cl.cam.ac.uk/~mgk25/ucs/examples/UTF-8-test.txt
62 */
63 public static function provideStringsForIsUtf8Check() {
64 // Expected return values for StringUtils::isUtf8()
65 $PASS = true;
66 $FAIL = false;
67
68 return [
69 'some ASCII' => [ $PASS, 'Some ASCII' ],
70 'euro sign' => [ $PASS, "Euro sign €" ],
71
72 'first possible sequence 1 byte' => [ $PASS, "\x00" ],
73 'first possible sequence 2 bytes' => [ $PASS, "\xc2\x80" ],
74 'first possible sequence 3 bytes' => [ $PASS, "\xe0\xa0\x80" ],
75 'first possible sequence 4 bytes' => [ $PASS, "\xf0\x90\x80\x80" ],
76 'first possible sequence 5 bytes' => [ $FAIL, "\xf8\x88\x80\x80\x80" ],
77 'first possible sequence 6 bytes' => [ $FAIL, "\xfc\x84\x80\x80\x80\x80" ],
78
79 'last possible sequence 1 byte' => [ $PASS, "\x7f" ],
80 'last possible sequence 2 bytes' => [ $PASS, "\xdf\xbf" ],
81 'last possible sequence 3 bytes' => [ $PASS, "\xef\xbf\xbf" ],
82 'last possible sequence 4 bytes (U+1FFFFF)' => [ $FAIL, "\xf7\xbf\xbf\xbf" ],
83 'last possible sequence 5 bytes' => [ $FAIL, "\xfb\xbf\xbf\xbf\xbf" ],
84 'last possible sequence 6 bytes' => [ $FAIL, "\xfd\xbf\xbf\xbf\xbf\xbf" ],
85
86 'boundary 1' => [ $PASS, "\xed\x9f\xbf" ],
87 'boundary 2' => [ $PASS, "\xee\x80\x80" ],
88 'boundary 3' => [ $PASS, "\xef\xbf\xbd" ],
89 'boundary 4' => [ $PASS, "\xf2\x80\x80\x80" ],
90 'boundary 5 (U+FFFFF)' => [ $PASS, "\xf3\xbf\xbf\xbf" ],
91 'boundary 6 (U+100000)' => [ $PASS, "\xf4\x80\x80\x80" ],
92 'boundary 7 (U+10FFFF)' => [ $PASS, "\xf4\x8f\xbf\xbf" ],
93 'boundary 8 (U+110000)' => [ $FAIL, "\xf4\x90\x80\x80" ],
94
95 'malformed 1' => [ $FAIL, "\x80" ],
96 'malformed 2' => [ $FAIL, "\xbf" ],
97 'malformed 3' => [ $FAIL, "\x80\xbf" ],
98 'malformed 4' => [ $FAIL, "\x80\xbf\x80" ],
99 'malformed 5' => [ $FAIL, "\x80\xbf\x80\xbf" ],
100 'malformed 6' => [ $FAIL, "\x80\xbf\x80\xbf\x80" ],
101 'malformed 7' => [ $FAIL, "\x80\xbf\x80\xbf\x80\xbf" ],
102 'malformed 8' => [ $FAIL, "\x80\xbf\x80\xbf\x80\xbf\x80" ],
103
104 'last byte missing 1' => [ $FAIL, "\xc0" ],
105 'last byte missing 2' => [ $FAIL, "\xe0\x80" ],
106 'last byte missing 3' => [ $FAIL, "\xf0\x80\x80" ],
107 'last byte missing 4' => [ $FAIL, "\xf8\x80\x80\x80" ],
108 'last byte missing 5' => [ $FAIL, "\xfc\x80\x80\x80\x80" ],
109 'last byte missing 6' => [ $FAIL, "\xdf" ],
110 'last byte missing 7' => [ $FAIL, "\xef\xbf" ],
111 'last byte missing 8' => [ $FAIL, "\xf7\xbf\xbf" ],
112 'last byte missing 9' => [ $FAIL, "\xfb\xbf\xbf\xbf" ],
113 'last byte missing 10' => [ $FAIL, "\xfd\xbf\xbf\xbf\xbf" ],
114
115 'extra continuation byte 1' => [ $FAIL, "e\xaf" ],
116 'extra continuation byte 2' => [ $FAIL, "\xc3\x89\xaf" ],
117 'extra continuation byte 3' => [ $FAIL, "\xef\xbc\xa5\xaf" ],
118 'extra continuation byte 4' => [ $FAIL, "\xf0\x9d\x99\xb4\xaf" ],
119
120 'impossible bytes 1' => [ $FAIL, "\xfe" ],
121 'impossible bytes 2' => [ $FAIL, "\xff" ],
122 'impossible bytes 3' => [ $FAIL, "\xfe\xfe\xff\xff" ],
123
124 'overlong sequences 1' => [ $FAIL, "\xc0\xaf" ],
125 'overlong sequences 2' => [ $FAIL, "\xc1\xaf" ],
126 'overlong sequences 3' => [ $FAIL, "\xe0\x80\xaf" ],
127 'overlong sequences 4' => [ $FAIL, "\xf0\x80\x80\xaf" ],
128 'overlong sequences 5' => [ $FAIL, "\xf8\x80\x80\x80\xaf" ],
129 'overlong sequences 6' => [ $FAIL, "\xfc\x80\x80\x80\x80\xaf" ],
130
131 'maximum overlong sequences 1' => [ $FAIL, "\xc1\xbf" ],
132 'maximum overlong sequences 2' => [ $FAIL, "\xe0\x9f\xbf" ],
133 'maximum overlong sequences 3' => [ $FAIL, "\xf0\x8f\xbf\xbf" ],
134 'maximum overlong sequences 4' => [ $FAIL, "\xf8\x87\xbf\xbf" ],
135 'maximum overlong sequences 5' => [ $FAIL, "\xfc\x83\xbf\xbf\xbf\xbf" ],
136
137 'surrogates 1 (U+D799)' => [ $PASS, "\xed\x9f\xbf" ],
138 'surrogates 2 (U+E000)' => [ $PASS, "\xee\x80\x80" ],
139 'surrogates 3 (U+D800)' => [ $FAIL, "\xed\xa0\x80" ],
140 'surrogates 4 (U+DBFF)' => [ $FAIL, "\xed\xaf\xbf" ],
141 'surrogates 5 (U+DC00)' => [ $FAIL, "\xed\xb0\x80" ],
142 'surrogates 6 (U+DFFF)' => [ $FAIL, "\xed\xbf\xbf" ],
143 'surrogates 7 (U+D800 U+DC00)' => [ $FAIL, "\xed\xa0\x80\xed\xb0\x80" ],
144
145 'noncharacters 1' => [ $PASS, "\xef\xbf\xbe" ],
146 'noncharacters 2' => [ $PASS, "\xef\xbf\xbf" ],
147 ];
148 }
149 }