MediaWiki
REL1_23
|
00001 <?php 00002 00006 class FormatJsonTest extends MediaWikiTestCase { 00007 00008 public static function provideEncoderPrettyPrinting() { 00009 return array( 00010 // Four spaces 00011 array( true, ' ' ), 00012 array( ' ', ' ' ), 00013 // Two spaces 00014 array( ' ', ' ' ), 00015 // One tab 00016 array( "\t", "\t" ), 00017 ); 00018 } 00019 00023 public function testEncoderPrettyPrinting( $pretty, $expectedIndent ) { 00024 $obj = array( 00025 'emptyObject' => new stdClass, 00026 'emptyArray' => array(), 00027 'string' => 'foobar\\', 00028 'filledArray' => array( 00029 array( 00030 123, 00031 456, 00032 ), 00033 // Nested json works without problems 00034 '"7":["8",{"9":"10"}]', 00035 // Whitespace clean up doesn't touch strings that look alike 00036 "{\n\t\"emptyObject\": {\n\t},\n\t\"emptyArray\": [ ]\n}", 00037 ), 00038 ); 00039 00040 // No trailing whitespace, no trailing linefeed 00041 $json = '{ 00042 "emptyObject": {}, 00043 "emptyArray": [], 00044 "string": "foobar\\\\", 00045 "filledArray": [ 00046 [ 00047 123, 00048 456 00049 ], 00050 "\"7\":[\"8\",{\"9\":\"10\"}]", 00051 "{\n\t\"emptyObject\": {\n\t},\n\t\"emptyArray\": [ ]\n}" 00052 ] 00053 }'; 00054 00055 $json = str_replace( "\r", '', $json ); // Windows compat 00056 $json = str_replace( "\t", $expectedIndent, $json ); 00057 $this->assertSame( $json, FormatJson::encode( $obj, $pretty ) ); 00058 } 00059 00060 public static function provideEncodeDefault() { 00061 return self::getEncodeTestCases( array() ); 00062 } 00063 00067 public function testEncodeDefault( $from, $to ) { 00068 $this->assertSame( $to, FormatJson::encode( $from ) ); 00069 } 00070 00071 public static function provideEncodeUtf8() { 00072 return self::getEncodeTestCases( array( 'unicode' ) ); 00073 } 00074 00078 public function testEncodeUtf8( $from, $to ) { 00079 $this->assertSame( $to, FormatJson::encode( $from, false, FormatJson::UTF8_OK ) ); 00080 } 00081 00082 public static function provideEncodeXmlMeta() { 00083 return self::getEncodeTestCases( array( 'xmlmeta' ) ); 00084 } 00085 00089 public function testEncodeXmlMeta( $from, $to ) { 00090 $this->assertSame( $to, FormatJson::encode( $from, false, FormatJson::XMLMETA_OK ) ); 00091 } 00092 00093 public static function provideEncodeAllOk() { 00094 return self::getEncodeTestCases( array( 'unicode', 'xmlmeta' ) ); 00095 } 00096 00100 public function testEncodeAllOk( $from, $to ) { 00101 $this->assertSame( $to, FormatJson::encode( $from, false, FormatJson::ALL_OK ) ); 00102 } 00103 00104 public function testEncodePhpBug46944() { 00105 $this->assertNotEquals( 00106 '\ud840\udc00', 00107 strtolower( FormatJson::encode( "\xf0\xa0\x80\x80" ) ), 00108 'Test encoding an broken json_encode character (U+20000)' 00109 ); 00110 } 00111 00112 public function testDecodeReturnType() { 00113 $this->assertInternalType( 00114 'object', 00115 FormatJson::decode( '{"Name": "Cheeso", "Rank": 7}' ), 00116 'Default to object' 00117 ); 00118 00119 $this->assertInternalType( 00120 'array', 00121 FormatJson::decode( '{"Name": "Cheeso", "Rank": 7}', true ), 00122 'Optional array' 00123 ); 00124 } 00125 00132 private static function getEncodeTestCases( array $unescapedGroups ) { 00133 $groups = array( 00134 'always' => array( 00135 // Forward slash (always unescaped) 00136 '/' => '/', 00137 00138 // Control characters 00139 "\0" => '\u0000', 00140 "\x08" => '\b', 00141 "\t" => '\t', 00142 "\n" => '\n', 00143 "\r" => '\r', 00144 "\f" => '\f', 00145 "\x1f" => '\u001f', // representative example 00146 00147 // Double quotes 00148 '"' => '\"', 00149 00150 // Backslashes 00151 '\\' => '\\\\', 00152 '\\\\' => '\\\\\\\\', 00153 '\\u00e9' => '\\\u00e9', // security check for Unicode unescaping 00154 00155 // Line terminators 00156 "\xe2\x80\xa8" => '\u2028', 00157 "\xe2\x80\xa9" => '\u2029', 00158 ), 00159 'unicode' => array( 00160 "\xc3\xa9" => '\u00e9', 00161 "\xf0\x9d\x92\x9e" => '\ud835\udc9e', // U+1D49E, outside the BMP 00162 ), 00163 'xmlmeta' => array( 00164 '<' => '\u003C', // JSON_HEX_TAG uses uppercase hex digits 00165 '>' => '\u003E', 00166 '&' => '\u0026', 00167 ), 00168 ); 00169 00170 $cases = array(); 00171 foreach ( $groups as $name => $rules ) { 00172 $leaveUnescaped = in_array( $name, $unescapedGroups ); 00173 foreach ( $rules as $from => $to ) { 00174 $cases[] = array( $from, '"' . ( $leaveUnescaped ? $from : $to ) . '"' ); 00175 } 00176 } 00177 00178 return $cases; 00179 } 00180 }