Merge "(bug 46615) updateCollation.php: sanity check the collation before proceeding"
[lhc/web/wiklou.git] / tests / phpunit / includes / json / FormatJsonTest.php
1 <?php
2
3 class FormatJsonTest extends MediaWikiTestCase {
4
5 public function testEncoderPrettyPrinting() {
6 $obj = array(
7 'emptyObject' => new stdClass,
8 'emptyArray' => array(),
9 'string' => 'foobar\\',
10 'filledArray' => array(
11 array(
12 123,
13 456,
14 ),
15 '"7":["8",{"9":"10"}]',
16 ),
17 );
18
19 // 4 space indent, no trailing whitespace, no trailing linefeed
20 $json = '{
21 "emptyObject": {
22
23 },
24 "emptyArray": [
25
26 ],
27 "string": "foobar\\\\",
28 "filledArray": [
29 [
30 123,
31 456
32 ],
33 "\"7\":[\"8\",{\"9\":\"10\"}]"
34 ]
35 }';
36
37 $json = str_replace( "\r", '', $json ); // Windows compat
38 $this->assertSame( $json, FormatJson::encode( $obj, true ) );
39 }
40
41 public static function provideEncodeDefault() {
42 return self::getEncodeTestCases( array() );
43 }
44
45 /**
46 * @dataProvider provideEncodeDefault
47 */
48 public function testEncodeDefault( $from, $to ) {
49 $this->assertSame( $to, FormatJson::encode( $from ) );
50 }
51
52 public static function provideEncodeUtf8() {
53 return self::getEncodeTestCases( array( 'unicode' ) );
54 }
55
56 /**
57 * @dataProvider provideEncodeUtf8
58 */
59 public function testEncodeUtf8( $from, $to ) {
60 $this->assertSame( $to, FormatJson::encode( $from, false, FormatJson::UTF8_OK ) );
61 }
62
63 public static function provideEncodeXmlMeta() {
64 return self::getEncodeTestCases( array( 'xmlmeta' ) );
65 }
66
67 /**
68 * @dataProvider provideEncodeXmlMeta
69 */
70 public function testEncodeXmlMeta( $from, $to ) {
71 $this->assertSame( $to, FormatJson::encode( $from, false, FormatJson::XMLMETA_OK ) );
72 }
73
74 public static function provideEncodeAllOk() {
75 return self::getEncodeTestCases( array( 'unicode', 'xmlmeta' ) );
76 }
77
78 /**
79 * @dataProvider provideEncodeAllOk
80 */
81 public function testEncodeAllOk( $from, $to ) {
82 $this->assertSame( $to, FormatJson::encode( $from, false, FormatJson::ALL_OK ) );
83 }
84
85 public function testEncodePhpBug46944() {
86 $this->assertNotEquals(
87 '\ud840\udc00',
88 strtolower( FormatJson::encode( "\xf0\xa0\x80\x80" ) ),
89 'Test encoding an broken json_encode character (U+20000)'
90 );
91
92 }
93
94 public function testDecodeReturnType() {
95 $this->assertInternalType(
96 'object',
97 FormatJson::decode( '{"Name": "Cheeso", "Rank": 7}' ),
98 'Default to object'
99 );
100
101 $this->assertInternalType(
102 'array',
103 FormatJson::decode( '{"Name": "Cheeso", "Rank": 7}', true ),
104 'Optional array'
105 );
106 }
107
108 /**
109 * Generate a set of test cases for a particular combination of encoder options.
110 *
111 * @param array $unescapedGroups List of character groups to leave unescaped
112 * @return array: Arrays of unencoded strings and corresponding encoded strings
113 */
114 private static function getEncodeTestCases( array $unescapedGroups ) {
115 $groups = array(
116 'always' => array(
117 // Forward slash (always unescaped)
118 '/' => '/',
119
120 // Control characters
121 "\0" => '\u0000',
122 "\x08" => '\b',
123 "\t" => '\t',
124 "\n" => '\n',
125 "\r" => '\r',
126 "\f" => '\f',
127 "\x1f" => '\u001f', // representative example
128
129 // Double quotes
130 '"' => '\"',
131
132 // Backslashes
133 '\\' => '\\\\',
134 '\\\\' => '\\\\\\\\',
135 '\\u00e9' => '\\\u00e9', // security check for Unicode unescaping
136
137 // Line terminators
138 "\xe2\x80\xa8" => '\u2028',
139 "\xe2\x80\xa9" => '\u2029',
140 ),
141 'unicode' => array(
142 "\xc3\xa9" => '\u00e9',
143 "\xf0\x9d\x92\x9e" => '\ud835\udc9e', // U+1D49E, outside the BMP
144 ),
145 'xmlmeta' => array(
146 '<' => '\u003C', // JSON_HEX_TAG uses uppercase hex digits
147 '>' => '\u003E',
148 '&' => '\u0026',
149 ),
150 );
151
152 $cases = array();
153 foreach ( $groups as $name => $rules ) {
154 $leaveUnescaped = in_array( $name, $unescapedGroups );
155 foreach ( $rules as $from => $to ) {
156 $cases[] = array( $from, '"' . ( $leaveUnescaped ? $from : $to ) . '"' );
157 }
158 }
159 return $cases;
160 }
161 }