3 namespace Drupal\Tests\Component\Serialization;
5 use Drupal\Component\Serialization\Exception\InvalidDataTypeException;
6 use Drupal\Component\Serialization\SerializationInterface;
7 use Drupal\Component\Serialization\Yaml;
8 use Drupal\Component\Serialization\YamlPecl;
9 use Drupal\Component\Serialization\YamlSymfony;
10 use PHPUnit\Framework\TestCase;
13 * @coversDefaultClass \Drupal\Component\Serialization\Yaml
14 * @group Serialization
16 class YamlTest extends TestCase {
19 * @var \PHPUnit_Framework_MockObject_MockObject
21 protected $mockParser;
23 public function setUp() {
25 $this->mockParser = $this->getMockBuilder('\stdClass')
26 ->setMethods(['encode', 'decode', 'getFileExtension'])
28 YamlParserProxy::setMock($this->mockParser);
31 public function tearDown() {
32 YamlParserProxy::setMock(NULL);
39 public function testDecode() {
41 ->expects($this->once())
43 YamlStub::decode('test');
47 * @covers ::getFileExtension
49 public function testGetFileExtension() {
51 ->expects($this->never())
52 ->method('getFileExtension');
53 $this->assertEquals('yml', YamlStub::getFileExtension());
57 * Tests all YAML files are decoded in the same way with Symfony and PECL.
59 * This test is a little bit slow but it tests that we do not have any bugs in
60 * our YAML that might not be decoded correctly in any of our implementations.
62 * @todo This should exist as an integration test not part of our unit tests.
63 * https://www.drupal.org/node/2597730
65 * @requires extension yaml
66 * @dataProvider providerYamlFilesInCore
68 public function testYamlFiles($file) {
69 $data = file_get_contents($file);
71 $this->assertEquals(YamlSymfony::decode($data), YamlPecl::decode($data), $file);
73 catch (InvalidDataTypeException $e) {
74 // Provide file context to the failure so the exception message is useful.
75 $this->fail("Exception thrown parsing $file:\n" . $e->getMessage());
80 * Ensures that decoding php objects does not work in PECL.
82 * @requires extension yaml
84 * @see \Drupal\Tests\Component\Serialization\YamlTest::testObjectSupportDisabledSymfony()
86 public function testObjectSupportDisabledPecl() {
87 $object = new \stdClass();
89 // In core all Yaml encoding is done via Symfony and it does not support
90 // objects so in order to encode an object we have to use the PECL
92 // @see \Drupal\Component\Serialization\Yaml::encode()
93 $yaml = YamlPecl::encode([$object]);
94 $this->assertEquals(['O:8:"stdClass":1:{s:3:"foo";s:3:"bar";}'], YamlPecl::decode($yaml));
98 * Ensures that decoding php objects does not work in Symfony.
100 * @requires extension yaml
102 * @see \Drupal\Tests\Component\Serialization\YamlTest::testObjectSupportDisabledPecl()
104 public function testObjectSupportDisabledSymfony() {
105 if (method_exists($this, 'setExpectedExceptionRegExp')) {
106 $this->setExpectedExceptionRegExp(InvalidDataTypeException::class, '/^Object support when parsing a YAML file has been disabled/');
109 $this->expectException(InvalidDataTypeException::class);
110 $this->expectExceptionMessageRegExp('/^Object support when parsing a YAML file has been disabled/');
112 $object = new \stdClass();
113 $object->foo = 'bar';
114 // In core all Yaml encoding is done via Symfony and it does not support
115 // objects so in order to encode an object we have to use the PECL
117 // @see \Drupal\Component\Serialization\Yaml::encode()
118 $yaml = YamlPecl::encode([$object]);
119 YamlSymfony::decode($yaml);
123 * Data provider that lists all YAML files in core.
125 public function providerYamlFilesInCore() {
127 $dirs = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator(__DIR__ . '/../../../../../', \RecursiveDirectoryIterator::FOLLOW_SYMLINKS));
128 foreach ($dirs as $dir) {
129 $pathname = $dir->getPathname();
130 // Exclude core/node_modules.
131 if ($dir->getExtension() == 'yml' && strpos($pathname, '/../../../../../node_modules') === FALSE) {
132 if (strpos($dir->getRealPath(), 'invalid_file') !== FALSE) {
133 // There are some intentionally invalid files provided for testing
134 // library API behaviours, ignore them.
137 $files[] = [$dir->getRealPath()];
145 class YamlStub extends Yaml {
147 public static function getSerializer() {
148 return '\Drupal\Tests\Component\Serialization\YamlParserProxy';
153 class YamlParserProxy implements SerializationInterface {
156 * @var \Drupal\Component\Serialization\SerializationInterface
158 protected static $mock;
160 public static function setMock($mock) {
161 static::$mock = $mock;
164 public static function encode($data) {
165 return static::$mock->encode($data);
168 public static function decode($raw) {
169 return static::$mock->decode($raw);
172 public static function getFileExtension() {
173 return static::$mock->getFileExtension();