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