More updates to stop using dev or alpha or beta versions.
[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 does not work in PECL.
81    *
82    * @requires extension yaml
83    *
84    * @see \Drupal\Tests\Component\Serialization\YamlTest::testObjectSupportDisabledSymfony()
85    */
86   public function testObjectSupportDisabledPecl() {
87     $object = new \stdClass();
88     $object->foo = 'bar';
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
91     // extension.
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));
95   }
96
97   /**
98    * Ensures that decoding php objects does not work in Symfony.
99    *
100    * @requires extension yaml
101    *
102    * @see \Drupal\Tests\Component\Serialization\YamlTest::testObjectSupportDisabledPecl()
103    */
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/');
107     }
108     else {
109       $this->expectException(InvalidDataTypeException::class);
110       $this->expectExceptionMessageRegExp('/^Object support when parsing a YAML file has been disabled/');
111     }
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
116     // extension.
117     // @see \Drupal\Component\Serialization\Yaml::encode()
118     $yaml = YamlPecl::encode([$object]);
119     YamlSymfony::decode($yaml);
120   }
121
122   /**
123    * Data provider that lists all YAML files in core.
124    */
125   public function providerYamlFilesInCore() {
126     $files = [];
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.
135           continue;
136         }
137         $files[] = [$dir->getRealPath()];
138       }
139     }
140     return $files;
141   }
142
143 }
144
145 class YamlStub extends Yaml {
146
147   public static function getSerializer() {
148     return '\Drupal\Tests\Component\Serialization\YamlParserProxy';
149   }
150
151 }
152
153 class YamlParserProxy implements SerializationInterface {
154
155   /**
156    * @var \Drupal\Component\Serialization\SerializationInterface
157    */
158   protected static $mock;
159
160   public static function setMock($mock) {
161     static::$mock = $mock;
162   }
163
164   public static function encode($data) {
165     return static::$mock->encode($data);
166   }
167
168   public static function decode($raw) {
169     return static::$mock->decode($raw);
170   }
171
172   public static function getFileExtension() {
173     return static::$mock->getFileExtension();
174   }
175
176 }