SerializerTest.php 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383
  1. <?php
  2. /*
  3. * This file is part of the Symfony package.
  4. *
  5. * (c) Fabien Potencier <fabien@symfony.com>
  6. *
  7. * For the full copyright and license information, please view the LICENSE
  8. * file that was distributed with this source code.
  9. */
  10. namespace Symfony\Component\Serializer\Tests;
  11. use Symfony\Component\Serializer\Normalizer\ArrayDenormalizer;
  12. use Symfony\Component\Serializer\Normalizer\DenormalizerAwareInterface;
  13. use Symfony\Component\Serializer\Normalizer\DenormalizerInterface;
  14. use Symfony\Component\Serializer\Normalizer\NormalizerAwareInterface;
  15. use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
  16. use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
  17. use Symfony\Component\Serializer\Normalizer\PropertyNormalizer;
  18. use Symfony\Component\Serializer\Serializer;
  19. use Symfony\Component\Serializer\Encoder\JsonEncoder;
  20. use Symfony\Component\Serializer\Normalizer\GetSetMethodNormalizer;
  21. use Symfony\Component\Serializer\Normalizer\CustomNormalizer;
  22. use Symfony\Component\Serializer\Tests\Fixtures\TraversableDummy;
  23. use Symfony\Component\Serializer\Tests\Fixtures\NormalizableTraversableDummy;
  24. use Symfony\Component\Serializer\Tests\Normalizer\TestNormalizer;
  25. use Symfony\Component\Serializer\Tests\Normalizer\TestDenormalizer;
  26. class SerializerTest extends \PHPUnit_Framework_TestCase
  27. {
  28. public function testInterface()
  29. {
  30. $serializer = new Serializer();
  31. $this->assertInstanceOf('Symfony\Component\Serializer\SerializerInterface', $serializer);
  32. $this->assertInstanceOf('Symfony\Component\Serializer\Normalizer\NormalizerInterface', $serializer);
  33. $this->assertInstanceOf('Symfony\Component\Serializer\Normalizer\DenormalizerInterface', $serializer);
  34. $this->assertInstanceOf('Symfony\Component\Serializer\Encoder\EncoderInterface', $serializer);
  35. $this->assertInstanceOf('Symfony\Component\Serializer\Encoder\DecoderInterface', $serializer);
  36. }
  37. /**
  38. * @expectedException \Symfony\Component\Serializer\Exception\UnexpectedValueException
  39. */
  40. public function testNormalizeNoMatch()
  41. {
  42. $serializer = new Serializer(array($this->getMockBuilder('Symfony\Component\Serializer\Normalizer\CustomNormalizer')->getMock()));
  43. $serializer->normalize(new \stdClass(), 'xml');
  44. }
  45. public function testNormalizeTraversable()
  46. {
  47. $serializer = new Serializer(array(), array('json' => new JsonEncoder()));
  48. $result = $serializer->serialize(new TraversableDummy(), 'json');
  49. $this->assertEquals('{"foo":"foo","bar":"bar"}', $result);
  50. }
  51. public function testNormalizeGivesPriorityToInterfaceOverTraversable()
  52. {
  53. $serializer = new Serializer(array(new CustomNormalizer()), array('json' => new JsonEncoder()));
  54. $result = $serializer->serialize(new NormalizableTraversableDummy(), 'json');
  55. $this->assertEquals('{"foo":"normalizedFoo","bar":"normalizedBar"}', $result);
  56. }
  57. /**
  58. * @expectedException \Symfony\Component\Serializer\Exception\UnexpectedValueException
  59. */
  60. public function testNormalizeOnDenormalizer()
  61. {
  62. $serializer = new Serializer(array(new TestDenormalizer()), array());
  63. $this->assertTrue($serializer->normalize(new \stdClass(), 'json'));
  64. }
  65. /**
  66. * @expectedException \Symfony\Component\Serializer\Exception\UnexpectedValueException
  67. */
  68. public function testDenormalizeNoMatch()
  69. {
  70. $serializer = new Serializer(array($this->getMockBuilder('Symfony\Component\Serializer\Normalizer\CustomNormalizer')->getMock()));
  71. $serializer->denormalize('foo', 'stdClass');
  72. }
  73. /**
  74. * @expectedException \Symfony\Component\Serializer\Exception\UnexpectedValueException
  75. */
  76. public function testDenormalizeOnNormalizer()
  77. {
  78. $serializer = new Serializer(array(new TestNormalizer()), array());
  79. $data = array('title' => 'foo', 'numbers' => array(5, 3));
  80. $this->assertTrue($serializer->denormalize(json_encode($data), 'stdClass', 'json'));
  81. }
  82. public function testCustomNormalizerCanNormalizeCollectionsAndScalar()
  83. {
  84. $serializer = new Serializer(array(new TestNormalizer()), array());
  85. $this->assertNull($serializer->normalize(array('a', 'b')));
  86. $this->assertNull($serializer->normalize(new \ArrayObject(array('c', 'd'))));
  87. $this->assertNull($serializer->normalize(array()));
  88. $this->assertNull($serializer->normalize('test'));
  89. }
  90. public function testNormalizeWithSupportOnData()
  91. {
  92. $normalizer1 = $this->getMockBuilder('Symfony\Component\Serializer\Normalizer\NormalizerInterface')->getMock();
  93. $normalizer1->method('supportsNormalization')
  94. ->willReturnCallback(function ($data, $format) {
  95. return isset($data->test);
  96. });
  97. $normalizer1->method('normalize')->willReturn('test1');
  98. $normalizer2 = $this->getMockBuilder('Symfony\Component\Serializer\Normalizer\NormalizerInterface')->getMock();
  99. $normalizer2->method('supportsNormalization')
  100. ->willReturn(true);
  101. $normalizer2->method('normalize')->willReturn('test2');
  102. $serializer = new Serializer(array($normalizer1, $normalizer2));
  103. $data = new \stdClass();
  104. $data->test = true;
  105. $this->assertEquals('test1', $serializer->normalize($data));
  106. $this->assertEquals('test2', $serializer->normalize(new \stdClass()));
  107. }
  108. public function testDenormalizeWithSupportOnData()
  109. {
  110. $denormalizer1 = $this->getMockBuilder('Symfony\Component\Serializer\Normalizer\DenormalizerInterface')->getMock();
  111. $denormalizer1->method('supportsDenormalization')
  112. ->willReturnCallback(function ($data, $type, $format) {
  113. return isset($data['test1']);
  114. });
  115. $denormalizer1->method('denormalize')->willReturn('test1');
  116. $denormalizer2 = $this->getMockBuilder('Symfony\Component\Serializer\Normalizer\DenormalizerInterface')->getMock();
  117. $denormalizer2->method('supportsDenormalization')
  118. ->willReturn(true);
  119. $denormalizer2->method('denormalize')->willReturn('test2');
  120. $serializer = new Serializer(array($denormalizer1, $denormalizer2));
  121. $this->assertEquals('test1', $serializer->denormalize(array('test1' => true), 'test'));
  122. $this->assertEquals('test2', $serializer->denormalize(array(), 'test'));
  123. }
  124. public function testSerialize()
  125. {
  126. $serializer = new Serializer(array(new GetSetMethodNormalizer()), array('json' => new JsonEncoder()));
  127. $data = array('title' => 'foo', 'numbers' => array(5, 3));
  128. $result = $serializer->serialize(Model::fromArray($data), 'json');
  129. $this->assertEquals(json_encode($data), $result);
  130. }
  131. public function testSerializeScalar()
  132. {
  133. $serializer = new Serializer(array(), array('json' => new JsonEncoder()));
  134. $result = $serializer->serialize('foo', 'json');
  135. $this->assertEquals('"foo"', $result);
  136. }
  137. public function testSerializeArrayOfScalars()
  138. {
  139. $serializer = new Serializer(array(), array('json' => new JsonEncoder()));
  140. $data = array('foo', array(5, 3));
  141. $result = $serializer->serialize($data, 'json');
  142. $this->assertEquals(json_encode($data), $result);
  143. }
  144. /**
  145. * @expectedException \Symfony\Component\Serializer\Exception\UnexpectedValueException
  146. */
  147. public function testSerializeNoEncoder()
  148. {
  149. $serializer = new Serializer(array(), array());
  150. $data = array('title' => 'foo', 'numbers' => array(5, 3));
  151. $serializer->serialize($data, 'json');
  152. }
  153. /**
  154. * @expectedException \Symfony\Component\Serializer\Exception\LogicException
  155. */
  156. public function testSerializeNoNormalizer()
  157. {
  158. $serializer = new Serializer(array(), array('json' => new JsonEncoder()));
  159. $data = array('title' => 'foo', 'numbers' => array(5, 3));
  160. $serializer->serialize(Model::fromArray($data), 'json');
  161. }
  162. public function testDeserialize()
  163. {
  164. $serializer = new Serializer(array(new GetSetMethodNormalizer()), array('json' => new JsonEncoder()));
  165. $data = array('title' => 'foo', 'numbers' => array(5, 3));
  166. $result = $serializer->deserialize(json_encode($data), '\Symfony\Component\Serializer\Tests\Model', 'json');
  167. $this->assertEquals($data, $result->toArray());
  168. }
  169. public function testDeserializeUseCache()
  170. {
  171. $serializer = new Serializer(array(new GetSetMethodNormalizer()), array('json' => new JsonEncoder()));
  172. $data = array('title' => 'foo', 'numbers' => array(5, 3));
  173. $serializer->deserialize(json_encode($data), '\Symfony\Component\Serializer\Tests\Model', 'json');
  174. $data = array('title' => 'bar', 'numbers' => array(2, 8));
  175. $result = $serializer->deserialize(json_encode($data), '\Symfony\Component\Serializer\Tests\Model', 'json');
  176. $this->assertEquals($data, $result->toArray());
  177. }
  178. /**
  179. * @expectedException \Symfony\Component\Serializer\Exception\LogicException
  180. */
  181. public function testDeserializeNoNormalizer()
  182. {
  183. $serializer = new Serializer(array(), array('json' => new JsonEncoder()));
  184. $data = array('title' => 'foo', 'numbers' => array(5, 3));
  185. $serializer->deserialize(json_encode($data), '\Symfony\Component\Serializer\Tests\Model', 'json');
  186. }
  187. /**
  188. * @expectedException \Symfony\Component\Serializer\Exception\UnexpectedValueException
  189. */
  190. public function testDeserializeWrongNormalizer()
  191. {
  192. $serializer = new Serializer(array(new CustomNormalizer()), array('json' => new JsonEncoder()));
  193. $data = array('title' => 'foo', 'numbers' => array(5, 3));
  194. $serializer->deserialize(json_encode($data), '\Symfony\Component\Serializer\Tests\Model', 'json');
  195. }
  196. /**
  197. * @expectedException \Symfony\Component\Serializer\Exception\UnexpectedValueException
  198. */
  199. public function testDeserializeNoEncoder()
  200. {
  201. $serializer = new Serializer(array(), array());
  202. $data = array('title' => 'foo', 'numbers' => array(5, 3));
  203. $serializer->deserialize(json_encode($data), '\Symfony\Component\Serializer\Tests\Model', 'json');
  204. }
  205. public function testDeserializeSupported()
  206. {
  207. $serializer = new Serializer(array(new GetSetMethodNormalizer()), array());
  208. $data = array('title' => 'foo', 'numbers' => array(5, 3));
  209. $this->assertTrue($serializer->supportsDenormalization(json_encode($data), '\Symfony\Component\Serializer\Tests\Model', 'json'));
  210. }
  211. public function testDeserializeNotSupported()
  212. {
  213. $serializer = new Serializer(array(new GetSetMethodNormalizer()), array());
  214. $data = array('title' => 'foo', 'numbers' => array(5, 3));
  215. $this->assertFalse($serializer->supportsDenormalization(json_encode($data), 'stdClass', 'json'));
  216. }
  217. public function testDeserializeNotSupportedMissing()
  218. {
  219. $serializer = new Serializer(array(), array());
  220. $data = array('title' => 'foo', 'numbers' => array(5, 3));
  221. $this->assertFalse($serializer->supportsDenormalization(json_encode($data), '\Symfony\Component\Serializer\Tests\Model', 'json'));
  222. }
  223. public function testEncode()
  224. {
  225. $serializer = new Serializer(array(), array('json' => new JsonEncoder()));
  226. $data = array('foo', array(5, 3));
  227. $result = $serializer->encode($data, 'json');
  228. $this->assertEquals(json_encode($data), $result);
  229. }
  230. public function testDecode()
  231. {
  232. $serializer = new Serializer(array(), array('json' => new JsonEncoder()));
  233. $data = array('foo', array(5, 3));
  234. $result = $serializer->decode(json_encode($data), 'json');
  235. $this->assertEquals($data, $result);
  236. }
  237. public function testSupportsArrayDeserialization()
  238. {
  239. $serializer = new Serializer(
  240. array(
  241. new GetSetMethodNormalizer(),
  242. new PropertyNormalizer(),
  243. new ObjectNormalizer(),
  244. new CustomNormalizer(),
  245. new ArrayDenormalizer(),
  246. ),
  247. array(
  248. 'json' => new JsonEncoder(),
  249. )
  250. );
  251. $this->assertTrue(
  252. $serializer->supportsDenormalization(array(), __NAMESPACE__.'\Model[]', 'json')
  253. );
  254. }
  255. public function testDeserializeArray()
  256. {
  257. $jsonData = '[{"title":"foo","numbers":[5,3]},{"title":"bar","numbers":[2,8]}]';
  258. $expectedData = array(
  259. Model::fromArray(array('title' => 'foo', 'numbers' => array(5, 3))),
  260. Model::fromArray(array('title' => 'bar', 'numbers' => array(2, 8))),
  261. );
  262. $serializer = new Serializer(
  263. array(
  264. new GetSetMethodNormalizer(),
  265. new ArrayDenormalizer(),
  266. ),
  267. array(
  268. 'json' => new JsonEncoder(),
  269. )
  270. );
  271. $this->assertEquals(
  272. $expectedData,
  273. $serializer->deserialize($jsonData, __NAMESPACE__.'\Model[]', 'json')
  274. );
  275. }
  276. public function testNormalizerAware()
  277. {
  278. $normalizerAware = $this->getMockBuilder(NormalizerAwareInterface::class)->getMock();
  279. $normalizerAware->expects($this->once())
  280. ->method('setNormalizer')
  281. ->with($this->isInstanceOf(NormalizerInterface::class));
  282. new Serializer(array($normalizerAware));
  283. }
  284. public function testDenormalizerAware()
  285. {
  286. $denormalizerAware = $this->getMockBuilder(DenormalizerAwareInterface::class)->getMock();
  287. $denormalizerAware->expects($this->once())
  288. ->method('setDenormalizer')
  289. ->with($this->isInstanceOf(DenormalizerInterface::class));
  290. new Serializer(array($denormalizerAware));
  291. }
  292. }
  293. class Model
  294. {
  295. private $title;
  296. private $numbers;
  297. public static function fromArray($array)
  298. {
  299. $model = new self();
  300. if (isset($array['title'])) {
  301. $model->setTitle($array['title']);
  302. }
  303. if (isset($array['numbers'])) {
  304. $model->setNumbers($array['numbers']);
  305. }
  306. return $model;
  307. }
  308. public function getTitle()
  309. {
  310. return $this->title;
  311. }
  312. public function setTitle($title)
  313. {
  314. $this->title = $title;
  315. }
  316. public function getNumbers()
  317. {
  318. return $this->numbers;
  319. }
  320. public function setNumbers($numbers)
  321. {
  322. $this->numbers = $numbers;
  323. }
  324. public function toArray()
  325. {
  326. return array('title' => $this->title, 'numbers' => $this->numbers);
  327. }
  328. }