MediaWiki  REL1_22
FormatJsonTest.php
Go to the documentation of this file.
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 }