becd7c0221c4c15fe82c70f1360c0c80256c696d
[yaffs-website] / web / core / tests / Drupal / Tests / Component / Serialization / YamlTest.php
1 <?php
2
3 namespace Drupal\Tests\Component\Serialization;
4
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;
11
12 /**
13  * @coversDefaultClass \Drupal\Component\Serialization\Yaml
14  * @group Serialization
15  */
16 class YamlTest extends TestCase {
17
18   /**
19    * @var \PHPUnit_Framework_MockObject_MockObject
20    */
21   protected $mockParser;
22
23   public function setUp() {
24     parent::setUp();
25     $this->mockParser = $this->getMockBuilder('\stdClass')
26       ->setMethods(['encode', 'decode', 'getFileExtension'])
27       ->getMock();
28     YamlParserProxy::setMock($this->mockParser);
29   }
30
31   public function tearDown() {
32     YamlParserProxy::setMock(NULL);
33     parent::tearDown();
34   }
35
36   /**
37    * @covers ::decode
38    */
39   public function testDecode() {
40     $this->mockParser
41       ->expects($this->once())
42       ->method('decode');
43     YamlStub::decode('test');
44   }
45
46   /**
47    * @covers ::getFileExtension
48    */
49   public function testGetFileExtension() {
50     $this->mockParser
51       ->expects($this->never())
52       ->method('getFileExtension');
53     $this->assertEquals('yml', YamlStub::getFileExtension());
54   }
55
56   /**
57    * Tests all YAML files are decoded in the same way with Symfony and PECL.
58    *
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.
61    *
62    * @todo This should exist as an integration test not part of our unit tests.
63    *   https://www.drupal.org/node/2597730
64    *
65    * @requires extension yaml
66    * @dataProvider providerYamlFilesInCore
67    */
68   public function testYamlFiles($file) {
69     $data = file_get_contents($file);
70     try {
71       $this->assertEquals(YamlSymfony::decode($data), YamlPecl::decode($data), $file);
72     }
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());
76     }
77   }
78
79   /**
80    * Ensures that decoding php objects is similar for PECL and Symfony.
81    *
82    * @requires extension yaml
83    */
84   public function testObjectSupportDisabled() {
85     $object = new \stdClass();
86     $object->foo = 'bar';
87     // In core all Yaml encoding is done via Symfony and it does not support
88     // objects so in order to encode an object we hace to use the PECL
89     // extension.
90     // @see \Drupal\Component\Serialization\Yaml::encode()
91     $yaml = YamlPecl::encode([$object]);
92     $this->assertEquals(['O:8:"stdClass":1:{s:3:"foo";s:3:"bar";}'], YamlPecl::decode($yaml));
93     $this->assertEquals(['!php/object "O:8:\"stdClass\":1:{s:3:\"foo\";s:3:\"bar\";}"'], YamlSymfony::decode($yaml));
94   }
95
96   /**
97    * Data provider that lists all YAML files in core.
98    */
99   public function providerYamlFilesInCore() {
100     $files = [];
101     $dirs = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator(__DIR__ . '/../../../../../', \RecursiveDirectoryIterator::FOLLOW_SYMLINKS));
102     foreach ($dirs as $dir) {
103       $pathname = $dir->getPathname();
104       // Exclude vendor.
105       if ($dir->getExtension() == 'yml' && strpos($pathname, '/../../../../../vendor') === FALSE) {
106         if (strpos($dir->getRealPath(), 'invalid_file') !== FALSE) {
107           // There are some intentionally invalid files provided for testing
108           // library API behaviours, ignore them.
109           continue;
110         }
111         $files[] = [$dir->getRealPath()];
112       }
113     }
114     return $files;
115   }
116
117 }
118
119 class YamlStub extends Yaml {
120
121   public static function getSerializer() {
122     return '\Drupal\Tests\Component\Serialization\YamlParserProxy';
123   }
124
125 }
126
127 class YamlParserProxy implements SerializationInterface {
128
129   /**
130    * @var \Drupal\Component\Serialization\SerializationInterface
131    */
132   protected static $mock;
133
134   public static function setMock($mock) {
135     static::$mock = $mock;
136   }
137
138   public static function encode($data) {
139     return static::$mock->encode($data);
140   }
141
142   public static function decode($raw) {
143     return static::$mock->decode($raw);
144   }
145
146   public static function getFileExtension() {
147     return static::$mock->getFileExtension();
148   }
149
150 }