annotate core/tests/Drupal/Tests/Component/Serialization/YamlTest.php @ 19:fa3358dc1485 tip

Add ndrum files
author Chris Cannam
date Wed, 28 Aug 2019 13:14:47 +0100
parents 1fec387a4317
children
rev   line source
Chris@0 1 <?php
Chris@0 2
Chris@0 3 namespace Drupal\Tests\Component\Serialization;
Chris@0 4
Chris@0 5 use Drupal\Component\Serialization\Exception\InvalidDataTypeException;
Chris@0 6 use Drupal\Component\Serialization\SerializationInterface;
Chris@0 7 use Drupal\Component\Serialization\Yaml;
Chris@0 8 use Drupal\Component\Serialization\YamlPecl;
Chris@0 9 use Drupal\Component\Serialization\YamlSymfony;
Chris@0 10 use PHPUnit\Framework\TestCase;
Chris@0 11
Chris@0 12 /**
Chris@0 13 * @coversDefaultClass \Drupal\Component\Serialization\Yaml
Chris@0 14 * @group Serialization
Chris@0 15 */
Chris@0 16 class YamlTest extends TestCase {
Chris@0 17
Chris@0 18 /**
Chris@0 19 * @var \PHPUnit_Framework_MockObject_MockObject
Chris@0 20 */
Chris@0 21 protected $mockParser;
Chris@0 22
Chris@0 23 public function setUp() {
Chris@0 24 parent::setUp();
Chris@0 25 $this->mockParser = $this->getMockBuilder('\stdClass')
Chris@0 26 ->setMethods(['encode', 'decode', 'getFileExtension'])
Chris@0 27 ->getMock();
Chris@0 28 YamlParserProxy::setMock($this->mockParser);
Chris@0 29 }
Chris@0 30
Chris@0 31 public function tearDown() {
Chris@0 32 YamlParserProxy::setMock(NULL);
Chris@0 33 parent::tearDown();
Chris@0 34 }
Chris@0 35
Chris@0 36 /**
Chris@0 37 * @covers ::decode
Chris@0 38 */
Chris@0 39 public function testDecode() {
Chris@0 40 $this->mockParser
Chris@0 41 ->expects($this->once())
Chris@0 42 ->method('decode');
Chris@0 43 YamlStub::decode('test');
Chris@0 44 }
Chris@0 45
Chris@0 46 /**
Chris@0 47 * @covers ::getFileExtension
Chris@0 48 */
Chris@0 49 public function testGetFileExtension() {
Chris@0 50 $this->mockParser
Chris@0 51 ->expects($this->never())
Chris@0 52 ->method('getFileExtension');
Chris@0 53 $this->assertEquals('yml', YamlStub::getFileExtension());
Chris@0 54 }
Chris@0 55
Chris@0 56 /**
Chris@0 57 * Tests all YAML files are decoded in the same way with Symfony and PECL.
Chris@0 58 *
Chris@0 59 * This test is a little bit slow but it tests that we do not have any bugs in
Chris@0 60 * our YAML that might not be decoded correctly in any of our implementations.
Chris@0 61 *
Chris@0 62 * @todo This should exist as an integration test not part of our unit tests.
Chris@0 63 * https://www.drupal.org/node/2597730
Chris@0 64 *
Chris@0 65 * @requires extension yaml
Chris@0 66 * @dataProvider providerYamlFilesInCore
Chris@0 67 */
Chris@0 68 public function testYamlFiles($file) {
Chris@0 69 $data = file_get_contents($file);
Chris@0 70 try {
Chris@0 71 $this->assertEquals(YamlSymfony::decode($data), YamlPecl::decode($data), $file);
Chris@0 72 }
Chris@0 73 catch (InvalidDataTypeException $e) {
Chris@0 74 // Provide file context to the failure so the exception message is useful.
Chris@0 75 $this->fail("Exception thrown parsing $file:\n" . $e->getMessage());
Chris@0 76 }
Chris@0 77 }
Chris@0 78
Chris@0 79 /**
Chris@14 80 * Ensures that decoding php objects does not work in PECL.
Chris@0 81 *
Chris@0 82 * @requires extension yaml
Chris@14 83 *
Chris@14 84 * @see \Drupal\Tests\Component\Serialization\YamlTest::testObjectSupportDisabledSymfony()
Chris@0 85 */
Chris@14 86 public function testObjectSupportDisabledPecl() {
Chris@0 87 $object = new \stdClass();
Chris@0 88 $object->foo = 'bar';
Chris@0 89 // In core all Yaml encoding is done via Symfony and it does not support
Chris@14 90 // objects so in order to encode an object we have to use the PECL
Chris@0 91 // extension.
Chris@0 92 // @see \Drupal\Component\Serialization\Yaml::encode()
Chris@0 93 $yaml = YamlPecl::encode([$object]);
Chris@0 94 $this->assertEquals(['O:8:"stdClass":1:{s:3:"foo";s:3:"bar";}'], YamlPecl::decode($yaml));
Chris@14 95 }
Chris@14 96
Chris@14 97 /**
Chris@14 98 * Ensures that decoding php objects does not work in Symfony.
Chris@14 99 *
Chris@14 100 * @requires extension yaml
Chris@14 101 *
Chris@14 102 * @see \Drupal\Tests\Component\Serialization\YamlTest::testObjectSupportDisabledPecl()
Chris@14 103 */
Chris@14 104 public function testObjectSupportDisabledSymfony() {
Chris@14 105 if (method_exists($this, 'setExpectedExceptionRegExp')) {
Chris@14 106 $this->setExpectedExceptionRegExp(InvalidDataTypeException::class, '/^Object support when parsing a YAML file has been disabled/');
Chris@14 107 }
Chris@14 108 else {
Chris@14 109 $this->expectException(InvalidDataTypeException::class);
Chris@14 110 $this->expectExceptionMessageRegExp('/^Object support when parsing a YAML file has been disabled/');
Chris@14 111 }
Chris@14 112 $object = new \stdClass();
Chris@14 113 $object->foo = 'bar';
Chris@14 114 // In core all Yaml encoding is done via Symfony and it does not support
Chris@14 115 // objects so in order to encode an object we have to use the PECL
Chris@14 116 // extension.
Chris@14 117 // @see \Drupal\Component\Serialization\Yaml::encode()
Chris@14 118 $yaml = YamlPecl::encode([$object]);
Chris@14 119 YamlSymfony::decode($yaml);
Chris@0 120 }
Chris@0 121
Chris@0 122 /**
Chris@0 123 * Data provider that lists all YAML files in core.
Chris@0 124 */
Chris@0 125 public function providerYamlFilesInCore() {
Chris@0 126 $files = [];
Chris@0 127 $dirs = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator(__DIR__ . '/../../../../../', \RecursiveDirectoryIterator::FOLLOW_SYMLINKS));
Chris@0 128 foreach ($dirs as $dir) {
Chris@0 129 $pathname = $dir->getPathname();
Chris@14 130 // Exclude core/node_modules.
Chris@14 131 if ($dir->getExtension() == 'yml' && strpos($pathname, '/../../../../../node_modules') === FALSE) {
Chris@0 132 if (strpos($dir->getRealPath(), 'invalid_file') !== FALSE) {
Chris@0 133 // There are some intentionally invalid files provided for testing
Chris@0 134 // library API behaviours, ignore them.
Chris@0 135 continue;
Chris@0 136 }
Chris@0 137 $files[] = [$dir->getRealPath()];
Chris@0 138 }
Chris@0 139 }
Chris@0 140 return $files;
Chris@0 141 }
Chris@0 142
Chris@0 143 }
Chris@0 144
Chris@0 145 class YamlStub extends Yaml {
Chris@0 146
Chris@0 147 public static function getSerializer() {
Chris@0 148 return '\Drupal\Tests\Component\Serialization\YamlParserProxy';
Chris@0 149 }
Chris@0 150
Chris@0 151 }
Chris@0 152
Chris@0 153 class YamlParserProxy implements SerializationInterface {
Chris@0 154
Chris@0 155 /**
Chris@0 156 * @var \Drupal\Component\Serialization\SerializationInterface
Chris@0 157 */
Chris@0 158 protected static $mock;
Chris@0 159
Chris@0 160 public static function setMock($mock) {
Chris@0 161 static::$mock = $mock;
Chris@0 162 }
Chris@0 163
Chris@0 164 public static function encode($data) {
Chris@0 165 return static::$mock->encode($data);
Chris@0 166 }
Chris@0 167
Chris@0 168 public static function decode($raw) {
Chris@0 169 return static::$mock->decode($raw);
Chris@0 170 }
Chris@0 171
Chris@0 172 public static function getFileExtension() {
Chris@0 173 return static::$mock->getFileExtension();
Chris@0 174 }
Chris@0 175
Chris@0 176 }