2
0

JsonTest.php 30 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000
  1. <?php
  2. /**
  3. * Zend Framework
  4. *
  5. * LICENSE
  6. *
  7. * This source file is subject to the new BSD license that is bundled
  8. * with this package in the file LICENSE.txt.
  9. * It is also available through the world-wide-web at this URL:
  10. * http://framework.zend.com/license/new-bsd
  11. * If you did not receive a copy of the license and are unable to
  12. * obtain it through the world-wide-web, please send an email
  13. * to license@zend.com so we can send you a copy immediately.
  14. *
  15. * @category Zend
  16. * @package Zend_Json
  17. * @subpackage UnitTests
  18. * @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
  19. * @license http://framework.zend.com/license/new-bsd New BSD License
  20. * @version $Id$
  21. */
  22. /**
  23. * @see Zend_Json
  24. */
  25. require_once 'Zend/Json.php';
  26. /**
  27. * @see Zend_Json_Expr
  28. */
  29. require_once 'Zend/Json/Expr.php';
  30. /**
  31. * @see Zend_Json_Encoder
  32. */
  33. require_once 'Zend/Json/Encoder.php';
  34. /**
  35. * @see Zend_Json_Decoder
  36. */
  37. require_once 'Zend/Json/Decoder.php';
  38. /**
  39. * @category Zend
  40. * @package Zend_Json
  41. * @subpackage UnitTests
  42. * @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
  43. * @license http://framework.zend.com/license/new-bsd New BSD License
  44. * @group Zend_Json
  45. */
  46. class Zend_JsonTest extends PHPUnit_Framework_TestCase
  47. {
  48. private $_originalUseBuiltinEncoderDecoderValue;
  49. public function setUp()
  50. {
  51. $this->_originalUseBuiltinEncoderDecoderValue = Zend_Json::$useBuiltinEncoderDecoder;
  52. }
  53. public function tearDown()
  54. {
  55. Zend_Json::$useBuiltinEncoderDecoder = $this->_originalUseBuiltinEncoderDecoderValue;
  56. }
  57. public function testJsonWithPhpJsonExtension()
  58. {
  59. if (!extension_loaded('json')) {
  60. $this->markTestSkipped('JSON extension is not loaded');
  61. }
  62. Zend_Json::$useBuiltinEncoderDecoder = false;
  63. $this->_testJson(array('string', 327, true, null));
  64. }
  65. public function testJsonWithBuiltins()
  66. {
  67. Zend_Json::$useBuiltinEncoderDecoder = true;
  68. $this->_testJson(array('string', 327, true, null));
  69. }
  70. /**
  71. * Test encoding and decoding in a single step
  72. * @param array $values array of values to test against encode/decode
  73. */
  74. protected function _testJson($values)
  75. {
  76. $encoded = Zend_Json::encode($values);
  77. $this->assertEquals($values, Zend_Json::decode($encoded));
  78. }
  79. /**
  80. * test null encoding/decoding
  81. */
  82. public function testNull()
  83. {
  84. $this->_testEncodeDecode(array(null));
  85. }
  86. /**
  87. * test boolean encoding/decoding
  88. */
  89. public function testBoolean()
  90. {
  91. $this->assertTrue(Zend_Json_Decoder::decode(Zend_Json_Encoder::encode(true)));
  92. $this->assertFalse(Zend_Json_Decoder::decode(Zend_Json_Encoder::encode(false)));
  93. }
  94. /**
  95. * test integer encoding/decoding
  96. */
  97. public function testInteger()
  98. {
  99. $this->_testEncodeDecode(array(-2));
  100. $this->_testEncodeDecode(array(-1));
  101. $zero = Zend_Json_Decoder::decode(Zend_Json_Encoder::encode(0));
  102. $this->assertEquals(0, $zero, 'Failed 0 integer test. Encoded: ' . serialize(Zend_Json_Encoder::encode(0)));
  103. }
  104. /**
  105. * @group ZF-10185
  106. */
  107. public function testJsonPrettyPrintWorksWithArrayNotationInStringLiteral()
  108. {
  109. $o = new stdClass();
  110. $o->test = 1;
  111. $o->faz = 'fubar';
  112. // The escaped double-quote in item 'stringwithjsonchars' ensures that
  113. // escaped double-quotes don't throw off prettyPrint's string literal detection
  114. $test = array(
  115. 'simple'=>'simple test string',
  116. 'stringwithjsonchars'=>'\"[1,2]',
  117. 'complex'=>array(
  118. 'foo'=>'bar',
  119. 'far'=>'boo',
  120. 'faz'=>array(
  121. 'obj'=>$o
  122. )
  123. )
  124. );
  125. $pretty = Zend_Json::prettyPrint(Zend_Json::encode($test), array("indent" => " "));
  126. $expected = <<<EOB
  127. {
  128. "simple":"simple test string",
  129. "stringwithjsonchars":"\\\\\\"[1,2]",
  130. "complex":{
  131. "foo":"bar",
  132. "far":"boo",
  133. "faz":{
  134. "obj":{
  135. "test":1,
  136. "faz":"fubar"
  137. }
  138. }
  139. }
  140. }
  141. EOB;
  142. $this->assertSame($expected, $pretty);
  143. }
  144. /**
  145. * test float encoding/decoding
  146. */
  147. public function testFloat()
  148. {
  149. $this->_testEncodeDecode(array(-2.1, 1.2));
  150. }
  151. /**
  152. * test string encoding/decoding
  153. */
  154. public function testString()
  155. {
  156. $this->_testEncodeDecode(array('string'));
  157. $this->assertEquals('', Zend_Json_Decoder::decode(Zend_Json_Encoder::encode('')), 'Empty string encoded: ' . serialize(Zend_Json_Encoder::encode('')));
  158. }
  159. /**
  160. * Test backslash escaping of string
  161. */
  162. public function testString2()
  163. {
  164. $string = 'INFO: Path \\\\test\\123\\abc';
  165. $expected = '"INFO: Path \\\\\\\\test\\\\123\\\\abc"';
  166. $encoded = Zend_Json_Encoder::encode($string);
  167. $this->assertEquals($expected, $encoded, 'Backslash encoding incorrect: expected: ' . serialize($expected) . '; received: ' . serialize($encoded) . "\n");
  168. $this->assertEquals($string, Zend_Json_Decoder::decode($encoded));
  169. }
  170. /**
  171. * Test newline escaping of string
  172. */
  173. public function testString3()
  174. {
  175. $expected = '"INFO: Path\nSome more"';
  176. $string = "INFO: Path\nSome more";
  177. $encoded = Zend_Json_Encoder::encode($string);
  178. $this->assertEquals($expected, $encoded, 'Newline encoding incorrect: expected ' . serialize($expected) . '; received: ' . serialize($encoded) . "\n");
  179. $this->assertEquals($string, Zend_Json_Decoder::decode($encoded));
  180. }
  181. /**
  182. * Test tab/non-tab escaping of string
  183. */
  184. public function testString4()
  185. {
  186. $expected = '"INFO: Path\\t\\\\tSome more"';
  187. $string = "INFO: Path\t\\tSome more";
  188. $encoded = Zend_Json_Encoder::encode($string);
  189. $this->assertEquals($expected, $encoded, 'Tab encoding incorrect: expected ' . serialize($expected) . '; received: ' . serialize($encoded) . "\n");
  190. $this->assertEquals($string, Zend_Json_Decoder::decode($encoded));
  191. }
  192. /**
  193. * Test double-quote escaping of string
  194. */
  195. public function testString5()
  196. {
  197. $expected = '"INFO: Path \"Some more\""';
  198. $string = 'INFO: Path "Some more"';
  199. $encoded = Zend_Json_Encoder::encode($string);
  200. $this->assertEquals($expected, $encoded, 'Quote encoding incorrect: expected ' . serialize($expected) . '; received: ' . serialize($encoded) . "\n");
  201. $this->assertEquals($string, Zend_Json_Decoder::decode($encoded));
  202. }
  203. /**
  204. * test indexed array encoding/decoding
  205. */
  206. public function testArray()
  207. {
  208. $array = array(1, 'one', 2, 'two');
  209. $encoded = Zend_Json_Encoder::encode($array);
  210. $this->assertSame($array, Zend_Json_Decoder::decode($encoded), 'Decoded array does not match: ' . serialize($encoded));
  211. }
  212. /**
  213. * test associative array encoding/decoding
  214. */
  215. public function testAssocArray()
  216. {
  217. $this->_testEncodeDecode(array(array('one' => 1, 'two' => 2)));
  218. }
  219. /**
  220. * test associative array encoding/decoding, with mixed key types
  221. */
  222. public function testAssocArray2()
  223. {
  224. $this->_testEncodeDecode(array(array('one' => 1, 2 => 2)));
  225. }
  226. /**
  227. * test associative array encoding/decoding, with integer keys not starting at 0
  228. */
  229. public function testAssocArray3()
  230. {
  231. $this->_testEncodeDecode(array(array(1 => 'one', 2 => 'two')));
  232. }
  233. /**
  234. * test object encoding/decoding (decoding to array)
  235. */
  236. public function testObject()
  237. {
  238. $value = new stdClass();
  239. $value->one = 1;
  240. $value->two = 2;
  241. $array = array('__className' => 'stdClass', 'one' => 1, 'two' => 2);
  242. $encoded = Zend_Json_Encoder::encode($value);
  243. $this->assertSame($array, Zend_Json_Decoder::decode($encoded));
  244. }
  245. /**
  246. * test object encoding/decoding (decoding to stdClass)
  247. */
  248. public function testObjectAsObject()
  249. {
  250. $value = new stdClass();
  251. $value->one = 1;
  252. $value->two = 2;
  253. $encoded = Zend_Json_Encoder::encode($value);
  254. $decoded = Zend_Json_Decoder::decode($encoded, Zend_Json::TYPE_OBJECT);
  255. $this->assertTrue(is_object($decoded), 'Not decoded as an object');
  256. $this->assertTrue($decoded instanceof StdClass, 'Not a StdClass object');
  257. $this->assertTrue(isset($decoded->one), 'Expected property not set');
  258. $this->assertEquals($value->one, $decoded->one, 'Unexpected value');
  259. }
  260. /**
  261. * Test that arrays of objects decode properly; see issue #144
  262. */
  263. public function testDecodeArrayOfObjects()
  264. {
  265. $value = '[{"id":1},{"foo":2}]';
  266. $expect = array(array('id' => 1), array('foo' => 2));
  267. $this->assertEquals($expect, Zend_Json_Decoder::decode($value));
  268. }
  269. /**
  270. * Test that objects of arrays decode properly; see issue #107
  271. */
  272. public function testDecodeObjectOfArrays()
  273. {
  274. $value = '{"codeDbVar" : {"age" : ["int", 5], "prenom" : ["varchar", 50]}, "234" : [22, "jb"], "346" : [64, "francois"], "21" : [12, "paul"]}';
  275. $expect = array(
  276. 'codeDbVar' => array(
  277. 'age' => array('int', 5),
  278. 'prenom' => array('varchar', 50),
  279. ),
  280. 234 => array(22, 'jb'),
  281. 346 => array(64, 'francois'),
  282. 21 => array(12, 'paul')
  283. );
  284. $this->assertEquals($expect, Zend_Json_Decoder::decode($value));
  285. }
  286. /**
  287. * Test encoding and decoding in a single step
  288. * @param array $values array of values to test against encode/decode
  289. */
  290. protected function _testEncodeDecode($values)
  291. {
  292. foreach ($values as $value) {
  293. $encoded = Zend_Json_Encoder::encode($value);
  294. $this->assertEquals($value, Zend_Json_Decoder::decode($encoded));
  295. }
  296. }
  297. /**
  298. * Test that version numbers such as 4.10 are encoded and decoded properly;
  299. * See ZF-377
  300. */
  301. public function testEncodeReleaseNumber()
  302. {
  303. $value = '4.10';
  304. $this->_testEncodeDecode(array($value));
  305. }
  306. /**
  307. * Tests that spaces/linebreaks prior to a closing right bracket don't throw
  308. * exceptions. See ZF-283.
  309. */
  310. public function testEarlyLineBreak()
  311. {
  312. $expected = array('data' => array(1, 2, 3, 4));
  313. $json = '{"data":[1,2,3,4' . "\n]}";
  314. $this->assertEquals($expected, Zend_Json_Decoder::decode($json));
  315. $json = '{"data":[1,2,3,4 ]}';
  316. $this->assertEquals($expected, Zend_Json_Decoder::decode($json));
  317. }
  318. /**
  319. * Tests for ZF-504
  320. *
  321. * Three confirmed issues reported:
  322. * - encoder improperly encoding empty arrays as structs
  323. * - decoder happily decoding clearly borked JSON
  324. * - decoder decoding octal values improperly (shouldn't decode them at all, as JSON does not support them)
  325. */
  326. public function testZf504()
  327. {
  328. $test = array();
  329. $this->assertSame('[]', Zend_Json_Encoder::encode($test));
  330. try {
  331. $json = '[a"],["a],[][]';
  332. $test = Zend_Json_Decoder::decode($json);
  333. $this->fail("Should not be able to decode '$json'");
  334. $json = '[a"],["a]';
  335. $test = Zend_Json_Decoder::decode($json);
  336. $this->fail("Should not be able to decode '$json'");
  337. } catch (Exception $e) {
  338. // success
  339. }
  340. try {
  341. $expected = 010;
  342. $test = Zend_Json_Decoder::decode('010');
  343. $this->fail('Octal values are not supported in JSON notation');
  344. } catch (Exception $e) {
  345. // sucess
  346. }
  347. }
  348. /**
  349. * Tests for ZF-461
  350. *
  351. * Check to see that cycling detection works properly
  352. */
  353. public function testZf461()
  354. {
  355. $item1 = new Zend_JsonTest_Item() ;
  356. $item2 = new Zend_JsonTest_Item() ;
  357. $everything = array() ;
  358. $everything['allItems'] = array($item1, $item2) ;
  359. $everything['currentItem'] = $item1 ;
  360. try {
  361. $encoded = Zend_Json_Encoder::encode($everything);
  362. } catch (Exception $e) {
  363. $this->fail('Object cycling checks should check for recursion, not duplicate usage of an item');
  364. }
  365. try {
  366. $encoded = Zend_Json_Encoder::encode($everything, true);
  367. $this->fail('Object cycling not allowed when cycleCheck parameter is true');
  368. } catch (Exception $e) {
  369. // success
  370. }
  371. }
  372. /**
  373. * Test for ZF-4053
  374. *
  375. * Check to see that cyclical exceptions are silenced when
  376. * $option['silenceCyclicalExceptions'] = true is used
  377. */
  378. public function testZf4053()
  379. {
  380. $item1 = new Zend_JsonTest_Item() ;
  381. $item2 = new Zend_JsonTest_Item() ;
  382. $everything = array() ;
  383. $everything['allItems'] = array($item1, $item2) ;
  384. $everything['currentItem'] = $item1 ;
  385. $options = array('silenceCyclicalExceptions'=>true);
  386. Zend_Json::$useBuiltinEncoderDecoder = true;
  387. $encoded = Zend_Json::encode($everything, true, $options);
  388. $json = '{"allItems":[{"__className":"Zend_JsonTest_Item"},{"__className":"Zend_JsonTest_Item"}],"currentItem":"* RECURSION (Zend_JsonTest_Item) *"}';
  389. $this->assertEquals($encoded,$json);
  390. }
  391. public function testEncodeObject()
  392. {
  393. $actual = new Zend_JsonTest_Object();
  394. $encoded = Zend_Json_Encoder::encode($actual);
  395. $decoded = Zend_Json_Decoder::decode($encoded, Zend_Json::TYPE_OBJECT);
  396. $this->assertTrue(isset($decoded->__className));
  397. $this->assertEquals('Zend_JsonTest_Object', $decoded->__className);
  398. $this->assertTrue(isset($decoded->foo));
  399. $this->assertEquals('bar', $decoded->foo);
  400. $this->assertTrue(isset($decoded->bar));
  401. $this->assertEquals('baz', $decoded->bar);
  402. $this->assertFalse(isset($decoded->_foo));
  403. }
  404. public function testEncodeClass()
  405. {
  406. $encoded = Zend_Json_Encoder::encodeClass('Zend_JsonTest_Object');
  407. $this->assertContains("Class.create('Zend_JsonTest_Object'", $encoded);
  408. $this->assertContains("ZAjaxEngine.invokeRemoteMethod(this, 'foo'", $encoded);
  409. $this->assertContains("ZAjaxEngine.invokeRemoteMethod(this, 'bar'", $encoded);
  410. $this->assertNotContains("ZAjaxEngine.invokeRemoteMethod(this, 'baz'", $encoded);
  411. $this->assertContains('variables:{foo:"bar",bar:"baz"}', $encoded);
  412. $this->assertContains('constants : {FOO: "bar"}', $encoded);
  413. }
  414. public function testEncodeClasses()
  415. {
  416. $encoded = Zend_Json_Encoder::encodeClasses(array('Zend_JsonTest_Object', 'Zend_JsonTest'));
  417. $this->assertContains("Class.create('Zend_JsonTest_Object'", $encoded);
  418. $this->assertContains("Class.create('Zend_JsonTest'", $encoded);
  419. }
  420. public function testToJsonSerialization()
  421. {
  422. $toJsonObject = new ToJsonClass();
  423. $result = Zend_Json::encode($toJsonObject);
  424. $this->assertEquals('{"firstName":"John","lastName":"Doe","email":"john@doe.com"}', $result);
  425. }
  426. /**
  427. * test encoding array with Zend_Json_Expr
  428. *
  429. * @group ZF-4946
  430. */
  431. public function testEncodingArrayWithExpr()
  432. {
  433. $expr = new Zend_Json_Expr('window.alert("Zend Json Expr")');
  434. $array = array('expr'=>$expr, 'int'=>9, 'string'=>'text');
  435. $result = Zend_Json::encode($array, false, array('enableJsonExprFinder' => true));
  436. $expected = '{"expr":window.alert("Zend Json Expr"),"int":9,"string":"text"}';
  437. $this->assertEquals($expected, $result);
  438. }
  439. /**
  440. * test encoding object with Zend_Json_Expr
  441. *
  442. * @group ZF-4946
  443. */
  444. public function testEncodingObjectWithExprAndInternalEncoder()
  445. {
  446. Zend_Json::$useBuiltinEncoderDecoder = true;
  447. $expr = new Zend_Json_Expr('window.alert("Zend Json Expr")');
  448. $obj = new stdClass();
  449. $obj->expr = $expr;
  450. $obj->int = 9;
  451. $obj->string = 'text';
  452. $result = Zend_Json::encode($obj, false, array('enableJsonExprFinder' => true));
  453. $expected = '{"__className":"stdClass","expr":window.alert("Zend Json Expr"),"int":9,"string":"text"}';
  454. $this->assertEquals($expected, $result);
  455. }
  456. /**
  457. * test encoding object with Zend_Json_Expr
  458. *
  459. * @group ZF-4946
  460. */
  461. public function testEncodingObjectWithExprAndExtJson()
  462. {
  463. if(!function_exists('json_encode')) {
  464. $this->markTestSkipped('Test only works with ext/json enabled!');
  465. }
  466. Zend_Json::$useBuiltinEncoderDecoder = false;
  467. $expr = new Zend_Json_Expr('window.alert("Zend Json Expr")');
  468. $obj = new stdClass();
  469. $obj->expr = $expr;
  470. $obj->int = 9;
  471. $obj->string = 'text';
  472. $result = Zend_Json::encode($obj, false, array('enableJsonExprFinder' => true));
  473. $expected = '{"expr":window.alert("Zend Json Expr"),"int":9,"string":"text"}';
  474. $this->assertEquals($expected, $result);
  475. }
  476. /**
  477. * test encoding object with ToJson and Zend_Json_Expr
  478. *
  479. * @group ZF-4946
  480. */
  481. public function testToJsonWithExpr()
  482. {
  483. Zend_Json::$useBuiltinEncoderDecoder = true;
  484. $obj = new Zend_Json_ToJsonWithExpr();
  485. $result = Zend_Json::encode($obj, false, array('enableJsonExprFinder' => true));
  486. $expected = '{"expr":window.alert("Zend Json Expr"),"int":9,"string":"text"}';
  487. $this->assertEquals($expected, $result);
  488. }
  489. /**
  490. * Regression tests for Zend_Json_Expr and mutliple keys with the same name.
  491. *
  492. * @group ZF-4946
  493. */
  494. public function testEncodingMultipleNestedSwitchingSameNameKeysWithDifferentJsonExprSettings()
  495. {
  496. $data = array(
  497. 0 => array(
  498. "alpha" => new Zend_Json_Expr("function(){}"),
  499. "beta" => "gamma",
  500. ),
  501. 1 => array(
  502. "alpha" => "gamma",
  503. "beta" => new Zend_Json_Expr("function(){}"),
  504. ),
  505. 2 => array(
  506. "alpha" => "gamma",
  507. "beta" => "gamma",
  508. )
  509. );
  510. $result = Zend_Json::encode($data, false, array('enableJsonExprFinder' => true));
  511. $this->assertEquals(
  512. '[{"alpha":function(){},"beta":"gamma"},{"alpha":"gamma","beta":function(){}},{"alpha":"gamma","beta":"gamma"}]',
  513. $result
  514. );
  515. }
  516. /**
  517. * Regression tests for Zend_Json_Expr and mutliple keys with the same name.
  518. *
  519. * @group ZF-4946
  520. */
  521. public function testEncodingMultipleNestedIteratedSameNameKeysWithDifferentJsonExprSettings()
  522. {
  523. $data = array(
  524. 0 => array(
  525. "alpha" => "alpha"
  526. ),
  527. 1 => array(
  528. "alpha" => "beta",
  529. ),
  530. 2 => array(
  531. "alpha" => new Zend_Json_Expr("gamma"),
  532. ),
  533. 3 => array(
  534. "alpha" => "delta",
  535. ),
  536. 4 => array(
  537. "alpha" => new Zend_Json_Expr("epsilon"),
  538. )
  539. );
  540. $result = Zend_Json::encode($data, false, array('enableJsonExprFinder' => true));
  541. $this->assertEquals('[{"alpha":"alpha"},{"alpha":"beta"},{"alpha":gamma},{"alpha":"delta"},{"alpha":epsilon}]', $result);
  542. }
  543. public function testDisabledJsonExprFinder()
  544. {
  545. Zend_Json::$useBuiltinEncoderDecoder = true;
  546. $data = array(
  547. 0 => array(
  548. "alpha" => new Zend_Json_Expr("function(){}"),
  549. "beta" => "gamma",
  550. ),
  551. );
  552. $result = Zend_Json::encode($data);
  553. $this->assertEquals(
  554. '[{"alpha":{"__className":"Zend_Json_Expr"},"beta":"gamma"}]',
  555. $result
  556. );
  557. }
  558. /**
  559. * @group ZF-4054
  560. */
  561. public function testEncodeWithUtf8IsTransformedToPackedSyntax()
  562. {
  563. $data = array("Отмена");
  564. $result = Zend_Json_Encoder::encode($data);
  565. $this->assertEquals('["\u041e\u0442\u043c\u0435\u043d\u0430"]', $result);
  566. }
  567. /**
  568. * @group ZF-4054
  569. *
  570. * This test contains assertions from the Solar Framework by Paul M. Jones
  571. * @link http://solarphp.com
  572. */
  573. public function testEncodeWithUtf8IsTransformedSolarRegression()
  574. {
  575. $expect = '"h\u00c3\u00a9ll\u00c3\u00b6 w\u00c3\u00b8r\u00c5\u201ad"';
  576. $this->assertEquals($expect, Zend_Json_Encoder::encode('héllö wørłd'));
  577. $this->assertEquals('héllö wørłd', Zend_Json_Decoder::decode($expect));
  578. $expect = '"\u0440\u0443\u0441\u0441\u0438\u0448"';
  579. $this->assertEquals($expect, Zend_Json_Encoder::encode("руссиш"));
  580. $this->assertEquals("руссиш", Zend_Json_Decoder::decode($expect));
  581. }
  582. /**
  583. * @group ZF-4054
  584. */
  585. public function testEncodeUnicodeStringSolarRegression()
  586. {
  587. $value = 'héllö wørłd';
  588. $expected = 'h\u00c3\u00a9ll\u00c3\u00b6 w\u00c3\u00b8r\u00c5\u201ad';
  589. $this->assertEquals($expected, Zend_Json_Encoder::encodeUnicodeString($value));
  590. $value = "\xC3\xA4";
  591. $expected = '\u00e4';
  592. $this->assertEquals($expected, Zend_Json_Encoder::encodeUnicodeString($value));
  593. $value = "\xE1\x82\xA0\xE1\x82\xA8";
  594. $expected = '\u10a0\u10a8';
  595. $this->assertEquals($expected, Zend_Json_Encoder::encodeUnicodeString($value));
  596. }
  597. /**
  598. * @group ZF-4054
  599. */
  600. public function testDecodeUnicodeStringSolarRegression()
  601. {
  602. $expected = 'héllö wørłd';
  603. $value = 'h\u00c3\u00a9ll\u00c3\u00b6 w\u00c3\u00b8r\u00c5\u201ad';
  604. $this->assertEquals($expected, Zend_Json_Decoder::decodeUnicodeString($value));
  605. $expected = "\xC3\xA4";
  606. $value = '\u00e4';
  607. $this->assertEquals($expected, Zend_Json_Decoder::decodeUnicodeString($value));
  608. $value = '\u10a0';
  609. $expected = "\xE1\x82\xA0";
  610. $this->assertEquals($expected, Zend_Json_Decoder::decodeUnicodeString($value));
  611. }
  612. /**
  613. * @group ZF-4054
  614. *
  615. * This test contains assertions from the Solar Framework by Paul M. Jones
  616. * @link http://solarphp.com
  617. */
  618. public function testEncodeWithUtf8IsTransformedSolarRegressionEqualsJsonExt()
  619. {
  620. if(function_exists('json_encode') == false) {
  621. $this->markTestSkipped('Test can only be run, when ext/json is installed.');
  622. }
  623. $this->assertEquals(
  624. json_encode('héllö wørłd'),
  625. Zend_Json_Encoder::encode('héllö wørłd')
  626. );
  627. $this->assertEquals(
  628. json_encode("руссиш"),
  629. Zend_Json_Encoder::encode("руссиш")
  630. );
  631. }
  632. /**
  633. * @group ZF-4946
  634. */
  635. public function testUtf8JsonExprFinder()
  636. {
  637. $data = array("Отмена" => new Zend_Json_Expr("foo"));
  638. Zend_Json::$useBuiltinEncoderDecoder = true;
  639. $result = Zend_Json::encode($data, false, array('enableJsonExprFinder' => true));
  640. $this->assertEquals('{"\u041e\u0442\u043c\u0435\u043d\u0430":foo}', $result);
  641. Zend_Json::$useBuiltinEncoderDecoder = false;
  642. $result = Zend_Json::encode($data, false, array('enableJsonExprFinder' => true));
  643. $this->assertEquals('{"\u041e\u0442\u043c\u0435\u043d\u0430":foo}', $result);
  644. }
  645. /**
  646. * @group ZF-4437
  647. */
  648. public function testKommaDecimalIsConvertedToCorrectJsonWithDot()
  649. {
  650. $localeInfo = localeconv();
  651. if($localeInfo['decimal_point'] != ",") {
  652. $this->markTestSkipped("This test only works for platforms where , is the decimal point separator.");
  653. }
  654. Zend_Json::$useBuiltinEncoderDecoder = true;
  655. $this->assertEquals("[1.20, 1.68]", Zend_Json_Encoder::encode(array(
  656. (float)"1,20", (float)"1,68"
  657. )));
  658. }
  659. public function testEncodeObjectImplementingIterator()
  660. {
  661. $this->markTestIncomplete('Test is not yet finished.');
  662. }
  663. /**
  664. * @group ZF-8663
  665. */
  666. public function testNativeJsonEncoderWillProperlyEncodeSolidusInStringValues()
  667. {
  668. $source = "</foo><foo>bar</foo>";
  669. $target = '"<\\/foo><foo>bar<\\/foo>"';
  670. // first test ext/json
  671. Zend_Json::$useBuiltinEncoderDecoder = false;
  672. $this->assertEquals($target, Zend_Json::encode($source));
  673. }
  674. /**
  675. * @group ZF-8663
  676. */
  677. public function testBuiltinJsonEncoderWillProperlyEncodeSolidusInStringValues()
  678. {
  679. $source = "</foo><foo>bar</foo>";
  680. $target = '"<\\/foo><foo>bar<\\/foo>"';
  681. // first test ext/json
  682. Zend_Json::$useBuiltinEncoderDecoder = true;
  683. $this->assertEquals($target, Zend_Json::encode($source));
  684. }
  685. /**
  686. * @group ZF-8918
  687. * @expectedException Zend_Json_Exception
  688. */
  689. public function testDecodingInvalidJsonShouldRaiseAnException()
  690. {
  691. Zend_Json::decode(' some string ');
  692. }
  693. /**
  694. * @group ZF-9416
  695. * Encoding an iterator using the internal encoder should handle undefined keys
  696. */
  697. public function testIteratorWithoutDefinedKey()
  698. {
  699. $inputValue = new ArrayIterator(array('foo'));
  700. $encoded = Zend_Json_Encoder::encode($inputValue);
  701. $expectedDecoding = '{"__className":"ArrayIterator","0":"foo"}';
  702. $this->assertEquals($encoded, $expectedDecoding);
  703. }
  704. /**
  705. * @group ZF-11356
  706. */
  707. public function testEncoderEscapesNamespacedClassNamesProperly()
  708. {
  709. if (version_compare(PHP_VERSION, '5.3.0') === -1) {
  710. $this->markTestSkipped('Namespaces not available in PHP < 5.3.0');
  711. }
  712. require_once dirname(__FILE__ ) . "/Json/_files/ZF11356-NamespacedClass.php";
  713. $inputValue = new \Zend\JsonTest\ZF11356\NamespacedClass(array('foo'));
  714. $encoded = Zend_Json_Encoder::encode($inputValue);
  715. $this->assertEquals(
  716. '{"__className":"Zend\\\\JsonTest\\\\ZF11356\\\\NamespacedClass","0":"foo"}',
  717. $encoded
  718. );
  719. }
  720. /**
  721. * @group ZF-9577
  722. */
  723. public function testJsonPrettyPrintWorksWithTxtOutputFormat()
  724. {
  725. $o = new stdClass;
  726. $o->four = 4;
  727. $o->foo = array(1,2,3);
  728. $jsonstr = Zend_Json::encode($o);
  729. $targetTxtOutput = "{\n\t\"four\":4,\n\t\"foo\":[\n\t\t1,\n\t\t2,\n\t\t3\n\t]\n}";
  730. $this->assertEquals($targetTxtOutput, Zend_Json::prettyPrint($jsonstr));
  731. }
  732. /**
  733. * @group ZF-9577
  734. */
  735. public function testJsonPrettyPrintWorksWithHtmlOutputFormat()
  736. {
  737. $o = new stdClass;
  738. $o->four = 4;
  739. $o->foo = array(1,2,3);
  740. $jsonstr = Zend_Json::encode($o);
  741. $targetHtmlOutput = '{<br />&nbsp;&nbsp;&nbsp;&nbsp;"four":4,<br />&nbsp;&nbsp;&nbsp;&nbsp;"foo":[<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1,<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2,<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;3<br />&nbsp;&nbsp;&nbsp;&nbsp;]<br />}';
  742. $this->assertEquals($targetHtmlOutput, Zend_Json::prettyPrint($jsonstr, array('format' => 'html')));
  743. }
  744. /**
  745. * @group ZF-11167
  746. */
  747. public function testEncodeWillUseToArrayMethodWhenAvailable()
  748. {
  749. $o = new ZF11167_ToArrayClass();
  750. $objJson = Zend_Json::encode($o);
  751. $arrJson = Zend_Json::encode($o->toArray());
  752. $this->assertSame($arrJson, $objJson);
  753. }
  754. /**
  755. * @group ZF-11167
  756. */
  757. public function testEncodeWillUseToJsonWhenBothToJsonAndToArrayMethodsAreAvailable()
  758. {
  759. $o = new ZF11167_ToArrayToJsonClass();
  760. $objJson = Zend_Json::encode($o);
  761. $this->assertEquals('"bogus"', $objJson);
  762. $arrJson = Zend_Json::encode($o->toArray());
  763. $this->assertNotSame($objJson, $arrJson);
  764. }
  765. /**
  766. * @group ZF-9521
  767. */
  768. public function testWillEncodeArrayOfObjectsEachWithToJsonMethod()
  769. {
  770. $array = array('one'=>new ToJsonClass());
  771. $expected = '{"one":{"__className":"ToJsonClass","firstName":"John","lastName":"Doe","email":"john@doe.com"}}';
  772. Zend_Json::$useBuiltinEncoderDecoder = true;
  773. $json = Zend_Json::encode($array);
  774. $this->assertEquals($expected, $json);
  775. }
  776. }
  777. /**
  778. * Zend_JsonTest_Item: test item for use with testZf461()
  779. */
  780. class Zend_JsonTest_Item
  781. {
  782. }
  783. /**
  784. * Zend_JsonTest_Object: test class for encoding classes
  785. */
  786. class Zend_JsonTest_Object
  787. {
  788. const FOO = 'bar';
  789. public $foo = 'bar';
  790. public $bar = 'baz';
  791. protected $_foo = 'fooled you';
  792. public function foo($bar, $baz)
  793. {
  794. }
  795. public function bar($baz)
  796. {
  797. }
  798. protected function baz()
  799. {
  800. }
  801. }
  802. class ToJsonClass
  803. {
  804. private $_firstName = 'John';
  805. private $_lastName = 'Doe';
  806. private $_email = 'john@doe.com';
  807. public function toJson()
  808. {
  809. $data = array(
  810. 'firstName' => $this->_firstName,
  811. 'lastName' => $this->_lastName,
  812. 'email' => $this->_email
  813. );
  814. return Zend_Json::encode($data);
  815. }
  816. }
  817. /**
  818. * Serializable class exposing a toArray() method
  819. * @see ZF-11167
  820. */
  821. class ZF11167_ToArrayClass
  822. {
  823. private $_firstName = 'John';
  824. private $_lastName = 'Doe';
  825. private $_email = 'john@doe.com';
  826. public function toArray()
  827. {
  828. $data = array(
  829. 'firstName' => $this->_firstName,
  830. 'lastName' => $this->_lastName,
  831. 'email' => $this->_email
  832. );
  833. return $data;
  834. }
  835. }
  836. /**
  837. * Serializable class exposing both toArray() and toJson() methods
  838. * @see ZF-11167
  839. */
  840. class ZF11167_ToArrayToJsonClass extends ZF11167_ToArrayClass
  841. {
  842. public function toJson()
  843. {
  844. return Zend_Json::encode('bogus');
  845. }
  846. }
  847. /**
  848. * ISSUE ZF-4946
  849. *
  850. */
  851. class Zend_Json_ToJsonWithExpr
  852. {
  853. private $_string = 'text';
  854. private $_int = 9;
  855. private $_expr = 'window.alert("Zend Json Expr")';
  856. public function toJson()
  857. {
  858. $data = array(
  859. 'expr' => new Zend_Json_Expr($this->_expr),
  860. 'int' => $this->_int,
  861. 'string' => $this->_string
  862. );
  863. return Zend_Json::encode($data, false, array('enableJsonExprFinder' => true));
  864. }
  865. }