Chris@0: mockParser = $this->getMockBuilder('\stdClass') Chris@0: ->setMethods(['encode', 'decode', 'getFileExtension']) Chris@0: ->getMock(); Chris@0: YamlParserProxy::setMock($this->mockParser); Chris@0: } Chris@0: Chris@0: public function tearDown() { Chris@0: YamlParserProxy::setMock(NULL); Chris@0: parent::tearDown(); Chris@0: } Chris@0: Chris@0: /** Chris@0: * @covers ::decode Chris@0: */ Chris@0: public function testDecode() { Chris@0: $this->mockParser Chris@0: ->expects($this->once()) Chris@0: ->method('decode'); Chris@0: YamlStub::decode('test'); Chris@0: } Chris@0: Chris@0: /** Chris@0: * @covers ::getFileExtension Chris@0: */ Chris@0: public function testGetFileExtension() { Chris@0: $this->mockParser Chris@0: ->expects($this->never()) Chris@0: ->method('getFileExtension'); Chris@0: $this->assertEquals('yml', YamlStub::getFileExtension()); Chris@0: } Chris@0: Chris@0: /** Chris@0: * Tests all YAML files are decoded in the same way with Symfony and PECL. Chris@0: * Chris@0: * This test is a little bit slow but it tests that we do not have any bugs in Chris@0: * our YAML that might not be decoded correctly in any of our implementations. Chris@0: * Chris@0: * @todo This should exist as an integration test not part of our unit tests. Chris@0: * https://www.drupal.org/node/2597730 Chris@0: * Chris@0: * @requires extension yaml Chris@0: * @dataProvider providerYamlFilesInCore Chris@0: */ Chris@0: public function testYamlFiles($file) { Chris@0: $data = file_get_contents($file); Chris@0: try { Chris@0: $this->assertEquals(YamlSymfony::decode($data), YamlPecl::decode($data), $file); Chris@0: } Chris@0: catch (InvalidDataTypeException $e) { Chris@0: // Provide file context to the failure so the exception message is useful. Chris@0: $this->fail("Exception thrown parsing $file:\n" . $e->getMessage()); Chris@0: } Chris@0: } Chris@0: Chris@0: /** Chris@14: * Ensures that decoding php objects does not work in PECL. Chris@0: * Chris@0: * @requires extension yaml Chris@14: * Chris@14: * @see \Drupal\Tests\Component\Serialization\YamlTest::testObjectSupportDisabledSymfony() Chris@0: */ Chris@14: public function testObjectSupportDisabledPecl() { Chris@0: $object = new \stdClass(); Chris@0: $object->foo = 'bar'; Chris@0: // In core all Yaml encoding is done via Symfony and it does not support Chris@14: // objects so in order to encode an object we have to use the PECL Chris@0: // extension. Chris@0: // @see \Drupal\Component\Serialization\Yaml::encode() Chris@0: $yaml = YamlPecl::encode([$object]); Chris@0: $this->assertEquals(['O:8:"stdClass":1:{s:3:"foo";s:3:"bar";}'], YamlPecl::decode($yaml)); Chris@14: } Chris@14: Chris@14: /** Chris@14: * Ensures that decoding php objects does not work in Symfony. Chris@14: * Chris@14: * @requires extension yaml Chris@14: * Chris@14: * @see \Drupal\Tests\Component\Serialization\YamlTest::testObjectSupportDisabledPecl() Chris@14: */ Chris@14: public function testObjectSupportDisabledSymfony() { Chris@14: if (method_exists($this, 'setExpectedExceptionRegExp')) { Chris@14: $this->setExpectedExceptionRegExp(InvalidDataTypeException::class, '/^Object support when parsing a YAML file has been disabled/'); Chris@14: } Chris@14: else { Chris@14: $this->expectException(InvalidDataTypeException::class); Chris@14: $this->expectExceptionMessageRegExp('/^Object support when parsing a YAML file has been disabled/'); Chris@14: } Chris@14: $object = new \stdClass(); Chris@14: $object->foo = 'bar'; Chris@14: // In core all Yaml encoding is done via Symfony and it does not support Chris@14: // objects so in order to encode an object we have to use the PECL Chris@14: // extension. Chris@14: // @see \Drupal\Component\Serialization\Yaml::encode() Chris@14: $yaml = YamlPecl::encode([$object]); Chris@14: YamlSymfony::decode($yaml); Chris@0: } Chris@0: Chris@0: /** Chris@0: * Data provider that lists all YAML files in core. Chris@0: */ Chris@0: public function providerYamlFilesInCore() { Chris@0: $files = []; Chris@0: $dirs = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator(__DIR__ . '/../../../../../', \RecursiveDirectoryIterator::FOLLOW_SYMLINKS)); Chris@0: foreach ($dirs as $dir) { Chris@0: $pathname = $dir->getPathname(); Chris@14: // Exclude core/node_modules. Chris@14: if ($dir->getExtension() == 'yml' && strpos($pathname, '/../../../../../node_modules') === FALSE) { Chris@0: if (strpos($dir->getRealPath(), 'invalid_file') !== FALSE) { Chris@0: // There are some intentionally invalid files provided for testing Chris@0: // library API behaviours, ignore them. Chris@0: continue; Chris@0: } Chris@0: $files[] = [$dir->getRealPath()]; Chris@0: } Chris@0: } Chris@0: return $files; Chris@0: } Chris@0: Chris@0: } Chris@0: Chris@0: class YamlStub extends Yaml { Chris@0: Chris@0: public static function getSerializer() { Chris@0: return '\Drupal\Tests\Component\Serialization\YamlParserProxy'; Chris@0: } Chris@0: Chris@0: } Chris@0: Chris@0: class YamlParserProxy implements SerializationInterface { Chris@0: Chris@0: /** Chris@0: * @var \Drupal\Component\Serialization\SerializationInterface Chris@0: */ Chris@0: protected static $mock; Chris@0: Chris@0: public static function setMock($mock) { Chris@0: static::$mock = $mock; Chris@0: } Chris@0: Chris@0: public static function encode($data) { Chris@0: return static::$mock->encode($data); Chris@0: } Chris@0: Chris@0: public static function decode($raw) { Chris@0: return static::$mock->decode($raw); Chris@0: } Chris@0: Chris@0: public static function getFileExtension() { Chris@0: return static::$mock->getFileExtension(); Chris@0: } Chris@0: Chris@0: }