YamlTest.php

Same filename in this branch
  1. 9 core/tests/Drupal/Tests/Core/Serialization/YamlTest.php
Same filename and directory in other branches
  1. 8.9.x core/tests/Drupal/Tests/Core/Serialization/YamlTest.php
  2. 8.9.x core/tests/Drupal/Tests/Component/Serialization/YamlTest.php
  3. 10 core/tests/Drupal/Tests/Component/Serialization/YamlTest.php
  4. 11.x core/tests/Drupal/Tests/Component/Serialization/YamlTest.php

Namespace

Drupal\Tests\Component\Serialization

File

core/tests/Drupal/Tests/Component/Serialization/YamlTest.php

View source
<?php

namespace Drupal\Tests\Component\Serialization;

use Drupal\Component\Serialization\Exception\InvalidDataTypeException;
use Drupal\Component\Serialization\SerializationInterface;
use Drupal\Component\Serialization\Yaml;
use Drupal\Component\Serialization\YamlPecl;
use Drupal\Component\Serialization\YamlSymfony;
use PHPUnit\Framework\TestCase;

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

}
class YamlStub extends Yaml {
  public static function getSerializer() {
    return '\\Drupal\\Tests\\Component\\Serialization\\YamlParserProxy';
  }

}
class YamlParserProxy implements SerializationInterface {
  
  /**
   * @var \Drupal\Component\Serialization\SerializationInterface
   */
  protected static $mock;
  public static function setMock($mock) {
    static::$mock = $mock;
  }
  public static function encode($data) {
    return static::$mock->encode($data);
  }
  public static function decode($raw) {
    return static::$mock->decode($raw);
  }
  public static function getFileExtension() {
    return static::$mock->getFileExtension();
  }

}

Classes

Title Deprecated Summary
YamlParserProxy
YamlStub
YamlTest @coversDefaultClass \Drupal\Component\Serialization\Yaml[[api-linebreak]] @group Serialization

Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.