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