YamlTest.php 3.61 KB
Newer Older
1 2 3 4
<?php

namespace Drupal\Tests\Component\Serialization;

5 6
use Drupal\Component\Serialization\Exception\InvalidDataTypeException;
use Drupal\Component\Serialization\SerializationInterface;
7
use Drupal\Component\Serialization\Yaml;
8 9
use Drupal\Component\Serialization\YamlPecl;
use Drupal\Component\Serialization\YamlSymfony;
10 11 12 13 14 15 16 17 18
use Drupal\Tests\UnitTestCase;

/**
 * @coversDefaultClass \Drupal\Component\Serialization\Yaml
 * @group Serialization
 */
class YamlTest extends UnitTestCase {

  /**
19
   * @var \PHPUnit_Framework_MockObject_MockObject
20
   */
21 22 23 24 25 26 27 28 29 30 31 32 33
  protected $mockParser;

  public function setUp() {
    parent::setUp();
    $this->mockParser = $this->getMockBuilder('\stdClass')
      ->setMethods(['encode', 'decode', 'getFileExtension'])
      ->getMock();
    YamlParserProxy::setMock($this->mockParser);
  }

  public function tearDown() {
    YamlParserProxy::setMock(NULL);
    parent::tearDown();
34 35 36
  }

  /**
37
   * @covers ::decode
38
   */
39 40 41 42 43
  public function testDecode() {
    $this->mockParser
      ->expects($this->once())
      ->method('decode');
    YamlStub::decode('test');
44 45 46 47 48 49
  }

  /**
   * @covers ::getFileExtension
   */
  public function testGetFileExtension() {
50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68
    $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) {
69
    file_put_contents('/tmp/dup.txt', $file . "\n", FILE_APPEND);
70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131
    $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());
    }
  }

  /**
   * 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 vendor.
      if ($dir->getExtension() == 'yml' && strpos($pathname, '/../../../../../vendor') === FALSE) {
        if (strpos($dir->getRealPath(), 'invalid_file') !== FALSE) {
          // There are some intentionally invalid files provided for testing
          // library API behaviours, 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();
132 133 134
  }

}