diff --git a/core/lib/Drupal/Component/Discovery/YamlDiscovery.php b/core/lib/Drupal/Component/Discovery/YamlDiscovery.php index 8f8b444..ea5c9c2 100644 --- a/core/lib/Drupal/Component/Discovery/YamlDiscovery.php +++ b/core/lib/Drupal/Component/Discovery/YamlDiscovery.php @@ -61,7 +61,7 @@ public function findAll() { foreach ($provider_by_files as $file => $provider) { // If a file is empty or its contents are commented out, return an empty // array instead of NULL for type consistency. - $all[$provider] = Yaml::decode(file_get_contents($file)) ?: []; + $all[$provider] = $this->decode($file); $file_cache->set($file, $all[$provider]); } } @@ -70,6 +70,17 @@ public function findAll() { } /** + * Decode a YAML file. + * + * @param string $file + * Yaml file path. + * @return array + */ + protected function decode($file) { + return Yaml::decode(file_get_contents($file)) ?: []; + } + + /** * Returns an array of file paths, keyed by provider. * * @return array diff --git a/core/lib/Drupal/Component/Serialization/Yaml.php b/core/lib/Drupal/Component/Serialization/Yaml.php index ca4909c..e65facd 100644 --- a/core/lib/Drupal/Component/Serialization/Yaml.php +++ b/core/lib/Drupal/Component/Serialization/Yaml.php @@ -2,42 +2,37 @@ namespace Drupal\Component\Serialization; -use Drupal\Component\Serialization\Exception\InvalidDataTypeException; -use Symfony\Component\Yaml\Parser; -use Symfony\Component\Yaml\Dumper; - /** - * Default serialization for YAML using the Symfony component. + * Provides a YAML serialization implementation. + * + * Proxy implementation that will choose the best library based on availability. */ class Yaml implements SerializationInterface { /** + * The YAML implementation to use. + * + * @var \Drupal\Component\Serialization\SerializationInterface + */ + protected static $serializer; + + /** * {@inheritdoc} */ public static function encode($data) { - try { - $yaml = new Dumper(); - $yaml->setIndentation(2); - return $yaml->dump($data, PHP_INT_MAX, 0, TRUE, FALSE); - } - catch (\Exception $e) { - throw new InvalidDataTypeException($e->getMessage(), $e->getCode(), $e); - } + // Instead of using \Drupal\Component\Serialization\Yaml::getSerializer(), + // always using Symfony for writing the data, to reduce the risk of having + // differences if different environments (like production and development) + // do not match in terms of what YAML implementation is available. + return YamlSymfony::encode($data); } /** * {@inheritdoc} */ public static function decode($raw) { - try { - $yaml = new Parser(); - // Make sure we have a single trailing newline. A very simple config like - // 'foo: bar' with no newline will fail to parse otherwise. - return $yaml->parse($raw, TRUE, FALSE); - } - catch (\Exception $e) { - throw new InvalidDataTypeException($e->getMessage(), $e->getCode(), $e); - } + $serializer = static::getSerializer(); + return $serializer::decode($raw); } /** @@ -47,4 +42,23 @@ public static function getFileExtension() { return 'yml'; } + /** + * Determines which implementation to use for parsing YAML. + */ + protected static function getSerializer() { + + if (!isset(static::$serializer)) { + // Use the PECL YAML extension if it is available. It has better + // performance for file reads and is YAML compliant. + if (extension_loaded('yaml')) { + static::$serializer = YamlPecl::class; + } + else { + // Otherwise, fallback to the Symfony implementation. + static::$serializer = YamlSymfony::class; + } + } + return static::$serializer; + } + } diff --git a/core/lib/Drupal/Component/Serialization/YamlPecl.php b/core/lib/Drupal/Component/Serialization/YamlPecl.php new file mode 100644 index 0000000..2383bf8 --- /dev/null +++ b/core/lib/Drupal/Component/Serialization/YamlPecl.php @@ -0,0 +1,101 @@ + '\Drupal\Component\Serialization\YamlPecl::applyBooleanCallbacks', + ]); + restore_error_handler(); + return $data; + } + + /** + * Handles errors for \Drupal\Component\Serialization\YamlPecl::decode(). + * + * @param int $severity + * The severity level of the error. + * @param string $message + * The error message to display. + * + * @see \Drupal\Component\Serialization\YamlPecl::decode() + */ + public static function errorHandler($severity, $message) { + restore_error_handler(); + throw new InvalidDataTypeException($message, $severity); + } + + /** + * {@inheritdoc} + */ + public static function getFileExtension() { + return 'yml'; + } + + /** + * Applies callbacks after parsing to ignore 1.1 style booleans. + * + * @param mixed $value + * Value from YAML file. + * @param string $tag + * Tag that triggered the callback. + * @param int $flags + * Scalar entity style flags. + * + * @return string|bool + * FALSE, false, TRUE and true are returned as booleans, everything else is + * returned as a string. + */ + public static function applyBooleanCallbacks($value, $tag, $flags) { + // YAML 1.1 spec dictates that 'Y', 'N', 'y' and 'n' are booleans. But, we + // want the 1.2 behavior, so we only consider 'false', 'FALSE', 'true' and + // 'TRUE' as booleans. + if (!in_array(strtolower($value), ['false', 'true'], TRUE)) { + return $value; + } + $map = [ + 'false' => FALSE, + 'true' => TRUE, + ]; + return $map[strtolower($value)]; + } + +} diff --git a/core/lib/Drupal/Component/Serialization/Yaml.php b/core/lib/Drupal/Component/Serialization/YamlSymfony.php similarity index 95% copy from core/lib/Drupal/Component/Serialization/Yaml.php copy to core/lib/Drupal/Component/Serialization/YamlSymfony.php index ca4909c..8818e52 100644 --- a/core/lib/Drupal/Component/Serialization/Yaml.php +++ b/core/lib/Drupal/Component/Serialization/YamlSymfony.php @@ -9,7 +9,7 @@ /** * Default serialization for YAML using the Symfony component. */ -class Yaml implements SerializationInterface { +class YamlSymfony implements SerializationInterface { /** * {@inheritdoc} diff --git a/core/lib/Drupal/Core/Asset/LibraryDiscoveryParser.php b/core/lib/Drupal/Core/Asset/LibraryDiscoveryParser.php index 9acda6a..799ee07 100644 --- a/core/lib/Drupal/Core/Asset/LibraryDiscoveryParser.php +++ b/core/lib/Drupal/Core/Asset/LibraryDiscoveryParser.php @@ -7,9 +7,9 @@ use Drupal\Core\Asset\Exception\InvalidLibraryFileException; use Drupal\Core\Asset\Exception\LibraryDefinitionMissingLicenseException; use Drupal\Core\Extension\ModuleHandlerInterface; +use Drupal\Core\Serialization\Yaml; use Drupal\Core\Theme\ThemeManagerInterface; use Drupal\Component\Serialization\Exception\InvalidDataTypeException; -use Drupal\Component\Serialization\Yaml; use Drupal\Component\Utility\NestedArray; /** diff --git a/core/lib/Drupal/Core/Config/ConfigManager.php b/core/lib/Drupal/Core/Config/ConfigManager.php index 11d7c84..f00fcd4 100644 --- a/core/lib/Drupal/Core/Config/ConfigManager.php +++ b/core/lib/Drupal/Core/Config/ConfigManager.php @@ -3,12 +3,12 @@ namespace Drupal\Core\Config; use Drupal\Component\Diff\Diff; -use Drupal\Component\Serialization\Yaml; use Drupal\Core\Config\Entity\ConfigDependencyManager; use Drupal\Core\Config\Entity\ConfigEntityInterface; use Drupal\Core\Config\Entity\ConfigEntityTypeInterface; use Drupal\Core\Entity\EntityManagerInterface; use Drupal\Core\Entity\EntityTypeInterface; +use Drupal\Core\Serialization\Yaml; use Drupal\Core\StringTranslation\StringTranslationTrait; use Drupal\Core\StringTranslation\TranslationInterface; use Symfony\Component\EventDispatcher\EventDispatcherInterface; diff --git a/core/lib/Drupal/Core/Config/FileStorage.php b/core/lib/Drupal/Core/Config/FileStorage.php index 2548203..4904576 100644 --- a/core/lib/Drupal/Core/Config/FileStorage.php +++ b/core/lib/Drupal/Core/Config/FileStorage.php @@ -3,8 +3,8 @@ namespace Drupal\Core\Config; use Drupal\Component\FileCache\FileCacheFactory; -use Drupal\Component\Serialization\Yaml; use Drupal\Component\Serialization\Exception\InvalidDataTypeException; +use Drupal\Core\Serialization\Yaml; /** * Defines the file storage. diff --git a/core/lib/Drupal/Core/DependencyInjection/YamlFileLoader.php b/core/lib/Drupal/Core/DependencyInjection/YamlFileLoader.php index 40557d5..da1c08c 100644 --- a/core/lib/Drupal/Core/DependencyInjection/YamlFileLoader.php +++ b/core/lib/Drupal/Core/DependencyInjection/YamlFileLoader.php @@ -4,7 +4,7 @@ namespace Drupal\Core\DependencyInjection; use Drupal\Component\FileCache\FileCacheFactory; -use Drupal\Component\Serialization\Yaml; +use Drupal\Core\Serialization\Yaml; use Symfony\Component\DependencyInjection\Alias; use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\DependencyInjection\Definition; diff --git a/core/lib/Drupal/Core/Discovery/YamlDiscovery.php b/core/lib/Drupal/Core/Discovery/YamlDiscovery.php new file mode 100644 index 0000000..7d85222 --- /dev/null +++ b/core/lib/Drupal/Core/Discovery/YamlDiscovery.php @@ -0,0 +1,22 @@ +discovery = new ComponentYamlDiscovery($name, $directories); + $this->discovery = new CoreYamlDiscovery($name, $directories); } /** diff --git a/core/lib/Drupal/Core/Routing/RouteBuilder.php b/core/lib/Drupal/Core/Routing/RouteBuilder.php index 95057e1..29da760 100644 --- a/core/lib/Drupal/Core/Routing/RouteBuilder.php +++ b/core/lib/Drupal/Core/Routing/RouteBuilder.php @@ -2,9 +2,9 @@ namespace Drupal\Core\Routing; -use Drupal\Component\Discovery\YamlDiscovery; use Drupal\Core\Access\CheckProviderInterface; use Drupal\Core\Controller\ControllerResolverInterface; +use Drupal\Core\Discovery\YamlDiscovery; use Drupal\Core\Extension\ModuleHandlerInterface; use Drupal\Core\Lock\LockBackendInterface; use Drupal\Core\DestructableInterface; diff --git a/core/lib/Drupal/Core/Serialization/Yaml.php b/core/lib/Drupal/Core/Serialization/Yaml.php new file mode 100644 index 0000000..566f8ca --- /dev/null +++ b/core/lib/Drupal/Core/Serialization/Yaml.php @@ -0,0 +1,28 @@ +drupalPostForm('admin/config/development/configuration/single/import', $edit, t('Import')); - $this->assertText('The import failed with the following message: Malformed inline YAML string ({{{) at line 1 (near "{{{")'); + // Assert the static portion of the error since different parsers could give different text in their error. + $this->assertText('The import failed with the following message: '); $import = <<assertFieldByXPath('//select[@name="config_name"]//option[@selected="selected"]', t('Fallback date format (fallback)'), 'The fallback date format config entity is selected when specified in the URL.'); $fallback_date = \Drupal::entityManager()->getStorage('date_format')->load('fallback'); - $data = Yaml::encode($fallback_date->toArray()); - $this->assertFieldByXPath('//textarea[@name="export"]', $data, 'The fallback date format config entity export code is displayed.'); + $yaml_text = (string) $this->xpath('//textarea[@name="export"]')[0]; + $this->assertEqual(Yaml::decode($yaml_text), $fallback_date->toArray(), 'The fallback date format config entity export code is displayed.'); } } diff --git a/core/modules/field/tests/fixtures/update/drupal-8.views_entity_reference_plugins-2429191.php b/core/modules/field/tests/fixtures/update/drupal-8.views_entity_reference_plugins-2429191.php index 4ad0a77..ecedb93 100644 --- a/core/modules/field/tests/fixtures/update/drupal-8.views_entity_reference_plugins-2429191.php +++ b/core/modules/field/tests/fixtures/update/drupal-8.views_entity_reference_plugins-2429191.php @@ -7,7 +7,7 @@ */ use Drupal\Core\Database\Database; -use Drupal\Component\Serialization\Yaml; +use Drupal\Core\Serialization\Yaml; use Drupal\field\Entity\FieldStorageConfig; $connection = Database::getConnection(); diff --git a/core/modules/responsive_image/src/Tests/Update/ResponsiveImageUpdateTest.php b/core/modules/responsive_image/src/Tests/Update/ResponsiveImageUpdateTest.php index 9427d47..1a82bb7b 100644 --- a/core/modules/responsive_image/src/Tests/Update/ResponsiveImageUpdateTest.php +++ b/core/modules/responsive_image/src/Tests/Update/ResponsiveImageUpdateTest.php @@ -2,8 +2,8 @@ namespace Drupal\responsive_image\Tests\Update; -use Drupal\Component\Serialization\Yaml; use Drupal\Core\Entity\Entity\EntityViewDisplay; +use Drupal\Core\Serialization\Yaml; use Drupal\system\Tests\Update\UpdatePathTestBase; /** diff --git a/core/modules/rest/tests/fixtures/update/drupal-8.rest-rest_post_update_resource_granularity.php b/core/modules/rest/tests/fixtures/update/drupal-8.rest-rest_post_update_resource_granularity.php index d657afcf9c13b177c952c1f144825d7b6a007ee3..6ee0d862366415f8479b01ad076588fed8b4cbf2 100644 GIT binary patch delta 48 zcmX@5c~o=4rir)3luCl9=GsqRhmc%&Nqa%>2BV$i&xoNLHomzj3;=YH5(WSO diff --git a/core/modules/rest/tests/fixtures/update/rest-export-with-authentication.php b/core/modules/rest/tests/fixtures/update/rest-export-with-authentication.php index c21e063..46285fc 100644 --- a/core/modules/rest/tests/fixtures/update/rest-export-with-authentication.php +++ b/core/modules/rest/tests/fixtures/update/rest-export-with-authentication.php @@ -5,8 +5,8 @@ * Test fixture for \Drupal\rest\Tests\Update\RestExportAuthUpdateTest. */ -use Drupal\Component\Serialization\Yaml; use Drupal\Core\Database\Database; +use Drupal\Core\Serialization\Yaml; $connection = Database::getConnection(); $config = $connection; diff --git a/core/modules/simpletest/src/WebTestBase.php b/core/modules/simpletest/src/WebTestBase.php index 0593ac1..da77a67 100644 --- a/core/modules/simpletest/src/WebTestBase.php +++ b/core/modules/simpletest/src/WebTestBase.php @@ -5,7 +5,6 @@ use Drupal\block\Entity\Block; use Drupal\Component\FileCache\FileCacheFactory; use Drupal\Component\Serialization\Json; -use Drupal\Component\Serialization\Yaml; use Drupal\Component\Utility\Html; use Drupal\Component\Utility\NestedArray; use Drupal\Component\Utility\UrlHelper; @@ -18,6 +17,7 @@ use Drupal\Core\EventSubscriber\MainContentViewSubscriber; use Drupal\Core\Extension\MissingDependencyException; use Drupal\Core\Render\Element; +use Drupal\Core\Serialization\Yaml; use Drupal\Core\Session\AccountInterface; use Drupal\Core\Session\AnonymousUserSession; use Drupal\Core\Session\UserSession; diff --git a/core/modules/system/src/Tests/Installer/DistributionProfileTest.php b/core/modules/system/src/Tests/Installer/DistributionProfileTest.php index d4d3553..0bb47ac 100644 --- a/core/modules/system/src/Tests/Installer/DistributionProfileTest.php +++ b/core/modules/system/src/Tests/Installer/DistributionProfileTest.php @@ -2,7 +2,7 @@ namespace Drupal\system\Tests\Installer; -use Drupal\Component\Serialization\Yaml; +use Drupal\Core\Serialization\Yaml; use Drupal\simpletest\InstallerTestBase; /** diff --git a/core/modules/system/src/Tests/Installer/DistributionProfileTranslationQueryTest.php b/core/modules/system/src/Tests/Installer/DistributionProfileTranslationQueryTest.php index 83097c4..b8658fb 100644 --- a/core/modules/system/src/Tests/Installer/DistributionProfileTranslationQueryTest.php +++ b/core/modules/system/src/Tests/Installer/DistributionProfileTranslationQueryTest.php @@ -2,7 +2,7 @@ namespace Drupal\system\Tests\Installer; -use Drupal\Component\Serialization\Yaml; +use Drupal\Core\Serialization\Yaml; use Drupal\simpletest\InstallerTestBase; /** diff --git a/core/modules/system/src/Tests/Installer/DistributionProfileTranslationTest.php b/core/modules/system/src/Tests/Installer/DistributionProfileTranslationTest.php index 3c504f7..29b9b3c 100644 --- a/core/modules/system/src/Tests/Installer/DistributionProfileTranslationTest.php +++ b/core/modules/system/src/Tests/Installer/DistributionProfileTranslationTest.php @@ -2,7 +2,7 @@ namespace Drupal\system\Tests\Installer; -use Drupal\Component\Serialization\Yaml; +use Drupal\Core\Serialization\Yaml; use Drupal\simpletest\InstallerTestBase; /** diff --git a/core/modules/system/src/Tests/Installer/SingleVisibleProfileTest.php b/core/modules/system/src/Tests/Installer/SingleVisibleProfileTest.php index 3f74e68..b54c411 100644 --- a/core/modules/system/src/Tests/Installer/SingleVisibleProfileTest.php +++ b/core/modules/system/src/Tests/Installer/SingleVisibleProfileTest.php @@ -2,7 +2,7 @@ namespace Drupal\system\Tests\Installer; -use Drupal\Component\Serialization\Yaml; +use Drupal\Core\Serialization\Yaml; use Drupal\simpletest\InstallerTestBase; /** diff --git a/core/modules/system/src/Tests/Installer/StandardInstallerTest.php b/core/modules/system/src/Tests/Installer/StandardInstallerTest.php index 47842ed..61e7c84 100644 --- a/core/modules/system/src/Tests/Installer/StandardInstallerTest.php +++ b/core/modules/system/src/Tests/Installer/StandardInstallerTest.php @@ -55,15 +55,15 @@ public function testStandardConfig() { $skipped_config = []; // \Drupal\simpletest\WebTestBase::installParameters() uses // simpletest@example.com as mail address. - $skipped_config['contact.form.feedback'][] = ' - simpletest@example.com'; + $skipped_config['contact.form.feedback'][] = '- simpletest@example.com'; // \Drupal\filter\Entity\FilterFormat::toArray() drops the roles of filter // formats. $skipped_config['filter.format.basic_html'][] = 'roles:'; - $skipped_config['filter.format.basic_html'][] = ' - authenticated'; + $skipped_config['filter.format.basic_html'][] = '- authenticated'; $skipped_config['filter.format.full_html'][] = 'roles:'; - $skipped_config['filter.format.full_html'][] = ' - administrator'; + $skipped_config['filter.format.full_html'][] = '- administrator'; $skipped_config['filter.format.restricted_html'][] = 'roles:'; - $skipped_config['filter.format.restricted_html'][] = ' - anonymous'; + $skipped_config['filter.format.restricted_html'][] = '- anonymous'; $this->assertInstalledConfig($skipped_config); } diff --git a/core/modules/system/tests/fixtures/update/drupal-8.block-context-manager-2354889.php b/core/modules/system/tests/fixtures/update/drupal-8.block-context-manager-2354889.php index 34474bf..7f23f90 100644 --- a/core/modules/system/tests/fixtures/update/drupal-8.block-context-manager-2354889.php +++ b/core/modules/system/tests/fixtures/update/drupal-8.block-context-manager-2354889.php @@ -6,8 +6,8 @@ * upgrade path of https://www.drupal.org/node/2354889. */ -use Drupal\Component\Serialization\Yaml; use Drupal\Core\Database\Database; +use Drupal\Core\Serialization\Yaml; $connection = Database::getConnection(); diff --git a/core/modules/system/tests/fixtures/update/drupal-8.local-actions-tasks-into-blocks-507488.php b/core/modules/system/tests/fixtures/update/drupal-8.local-actions-tasks-into-blocks-507488.php index 33861a0..a47f9e0 100644 --- a/core/modules/system/tests/fixtures/update/drupal-8.local-actions-tasks-into-blocks-507488.php +++ b/core/modules/system/tests/fixtures/update/drupal-8.local-actions-tasks-into-blocks-507488.php @@ -6,8 +6,8 @@ * upgrade path of https://www.drupal.org/node/507488. */ -use Drupal\Component\Serialization\Yaml; use Drupal\Core\Database\Database; +use Drupal\Core\Serialization\Yaml; $connection = Database::getConnection(); diff --git a/core/modules/system/tests/fixtures/update/drupal-8.page-title-into-block-2476947.php b/core/modules/system/tests/fixtures/update/drupal-8.page-title-into-block-2476947.php index b259ccc..766e9a6 100644 --- a/core/modules/system/tests/fixtures/update/drupal-8.page-title-into-block-2476947.php +++ b/core/modules/system/tests/fixtures/update/drupal-8.page-title-into-block-2476947.php @@ -6,8 +6,8 @@ * upgrade path of https://www.drupal.org/node/2476947. */ -use Drupal\Component\Serialization\Yaml; use Drupal\Core\Database\Database; +use Drupal\Core\Serialization\Yaml; $connection = Database::getConnection(); diff --git a/core/modules/system/tests/fixtures/update/drupal-8.seven-secondary-local-tasks-block-2569529.php b/core/modules/system/tests/fixtures/update/drupal-8.seven-secondary-local-tasks-block-2569529.php index f19c07c..1ac03ca 100644 --- a/core/modules/system/tests/fixtures/update/drupal-8.seven-secondary-local-tasks-block-2569529.php +++ b/core/modules/system/tests/fixtures/update/drupal-8.seven-secondary-local-tasks-block-2569529.php @@ -6,8 +6,8 @@ * upgrade path of https://www.drupal.org/node/507488. */ -use Drupal\Component\Serialization\Yaml; use Drupal\Core\Database\Database; +use Drupal\Core\Serialization\Yaml; $connection = Database::getConnection(); diff --git a/core/modules/system/tests/fixtures/update/drupal-8.site-branding-into-block-2005546.php b/core/modules/system/tests/fixtures/update/drupal-8.site-branding-into-block-2005546.php index c632060..cd59372 100644 --- a/core/modules/system/tests/fixtures/update/drupal-8.site-branding-into-block-2005546.php +++ b/core/modules/system/tests/fixtures/update/drupal-8.site-branding-into-block-2005546.php @@ -6,8 +6,8 @@ * upgrade path of https://www.drupal.org/node/2005546. */ -use Drupal\Component\Serialization\Yaml; use Drupal\Core\Database\Database; +use Drupal\Core\Serialization\Yaml; $connection = Database::getConnection(); diff --git a/core/modules/system/tests/fixtures/update/drupal-8.views-entity-views-data-2455125.php b/core/modules/system/tests/fixtures/update/drupal-8.views-entity-views-data-2455125.php index fe72370..6ff4d81 100644 --- a/core/modules/system/tests/fixtures/update/drupal-8.views-entity-views-data-2455125.php +++ b/core/modules/system/tests/fixtures/update/drupal-8.views-entity-views-data-2455125.php @@ -6,8 +6,8 @@ * upgrade path of https://www.drupal.org/node/2455125. */ -use Drupal\Component\Serialization\Yaml; use Drupal\Core\Database\Database; +use Drupal\Core\Serialization\Yaml; $connection = Database::getConnection(); diff --git a/core/modules/system/tests/fixtures/update/drupal8.views-image-style-dependency-2649914.php b/core/modules/system/tests/fixtures/update/drupal8.views-image-style-dependency-2649914.php index fcb90ba..1fc1258 100644 --- a/core/modules/system/tests/fixtures/update/drupal8.views-image-style-dependency-2649914.php +++ b/core/modules/system/tests/fixtures/update/drupal8.views-image-style-dependency-2649914.php @@ -6,8 +6,8 @@ * the upgrade path of https://www.drupal.org/node/2649914. */ -use Drupal\Component\Serialization\Yaml; use Drupal\Core\Database\Database; +use Drupal\Core\Serialization\Yaml; $connection = Database::getConnection(); diff --git a/core/modules/user/src/PermissionHandler.php b/core/modules/user/src/PermissionHandler.php index 3a4e6c4..d7179b6 100644 --- a/core/modules/user/src/PermissionHandler.php +++ b/core/modules/user/src/PermissionHandler.php @@ -2,7 +2,7 @@ namespace Drupal\user; -use Drupal\Component\Discovery\YamlDiscovery; +use Drupal\Core\Discovery\YamlDiscovery; use Drupal\Core\Controller\ControllerResolverInterface; use Drupal\Core\Extension\ModuleHandlerInterface; use Drupal\Core\StringTranslation\StringTranslationTrait; @@ -59,7 +59,7 @@ class PermissionHandler implements PermissionHandlerInterface { /** * The YAML discovery class to find all .permissions.yml files. * - * @var \Drupal\Component\Discovery\YamlDiscovery + * @var \Drupal\Core\Discovery\YamlDiscovery */ protected $yamlDiscovery; @@ -91,7 +91,7 @@ public function __construct(ModuleHandlerInterface $module_handler, TranslationI /** * Gets the YAML discovery. * - * @return \Drupal\Component\Discovery\YamlDiscovery + * @return \Drupal\Core\Discovery\YamlDiscovery * The YAML discovery. */ protected function getYamlDiscovery() { diff --git a/core/modules/views/tests/fixtures/update/argument-placeholder.php b/core/modules/views/tests/fixtures/update/argument-placeholder.php index 03181bb..2a7cf4b 100644 --- a/core/modules/views/tests/fixtures/update/argument-placeholder.php +++ b/core/modules/views/tests/fixtures/update/argument-placeholder.php @@ -5,8 +5,8 @@ * Text fixture. */ -use Drupal\Component\Serialization\Yaml; use Drupal\Core\Database\Database; +use Drupal\Core\Serialization\Yaml; $connection = Database::getConnection(); diff --git a/core/modules/views/tests/fixtures/update/duplicate-field-handler.php b/core/modules/views/tests/fixtures/update/duplicate-field-handler.php index 32e74fb..775f75a 100644 --- a/core/modules/views/tests/fixtures/update/duplicate-field-handler.php +++ b/core/modules/views/tests/fixtures/update/duplicate-field-handler.php @@ -5,8 +5,8 @@ * Test fixture. */ -use Drupal\Component\Serialization\Yaml; use Drupal\Core\Database\Database; +use Drupal\Core\Serialization\Yaml; $connection = Database::getConnection(); diff --git a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_summary.yml b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_summary.yml index 3784bd9..468de37 100644 --- a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_summary.yml +++ b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_summary.yml @@ -96,7 +96,6 @@ display: footer: { } empty: { } relationships: { } - fields: { } display_extenders: { } cache_metadata: contexts: diff --git a/core/tests/Drupal/KernelTests/Core/Config/ConfigDiffTest.php b/core/tests/Drupal/KernelTests/Core/Config/ConfigDiffTest.php index 7284802..409b794 100644 --- a/core/tests/Drupal/KernelTests/Core/Config/ConfigDiffTest.php +++ b/core/tests/Drupal/KernelTests/Core/Config/ConfigDiffTest.php @@ -44,9 +44,9 @@ function testDiff() { // Verify that the diff reflects a change. $diff = \Drupal::service('config.manager')->diff($active, $sync, $config_name); $edits = $diff->getEdits(); - $this->assertEqual($edits[0]->type, 'change', 'The first item in the diff is a change.'); - $this->assertEqual($edits[0]->orig[0], $change_key . ': ' . $original_data[$change_key], format_string("The active value for key '%change_key' is '%original_data'.", array('%change_key' => $change_key, '%original_data' => $original_data[$change_key]))); - $this->assertEqual($edits[0]->closing[0], $change_key . ': ' . $change_data, format_string("The sync value for key '%change_key' is '%change_data'.", array('%change_key' => $change_key, '%change_data' => $change_data))); + $this->assertYamlEdit($edits, $change_key, 'change', + [$change_key . ': ' . $original_data[$change_key]], + [$change_key . ': ' . $change_data]); // Reset data back to original, and remove a key $sync_data = $original_data; @@ -56,10 +56,11 @@ function testDiff() { // Verify that the diff reflects a removed key. $diff = \Drupal::service('config.manager')->diff($active, $sync, $config_name); $edits = $diff->getEdits(); - $this->assertEqual($edits[0]->type, 'copy', 'The first item in the diff is a copy.'); - $this->assertEqual($edits[1]->type, 'delete', 'The second item in the diff is a delete.'); - $this->assertEqual($edits[1]->orig[0], $remove_key . ': ' . $original_data[$remove_key], format_string("The active value for key '%remove_key' is '%original_data'.", array('%remove_key' => $remove_key, '%original_data' => $original_data[$remove_key]))); - $this->assertFalse($edits[1]->closing, format_string("The key '%remove_key' does not exist in sync.", array('%remove_key' => $remove_key))); + $this->assertYamlEdit($edits, $change_key, 'copy'); + $this->assertYamlEdit($edits, $remove_key, 'delete', + [$remove_key . ': ' . $original_data[$remove_key]], + FALSE + ); // Reset data back to original and add a key $sync_data = $original_data; @@ -69,10 +70,8 @@ function testDiff() { // Verify that the diff reflects an added key. $diff = \Drupal::service('config.manager')->diff($active, $sync, $config_name); $edits = $diff->getEdits(); - $this->assertEqual($edits[0]->type, 'copy', 'The first item in the diff is a copy.'); - $this->assertEqual($edits[1]->type, 'add', 'The second item in the diff is an add.'); - $this->assertFalse($edits[1]->orig, format_string("The key '%add_key' does not exist in active.", array('%add_key' => $add_key))); - $this->assertEqual($edits[1]->closing[0], $add_key . ': ' . $add_data, format_string("The sync value for key '%add_key' is '%add_data'.", array('%add_key' => $add_key, '%add_data' => $add_data))); + $this->assertYamlEdit($edits, $change_key, 'copy'); + $this->assertYamlEdit($edits, $add_key, 'add', FALSE, [$add_key . ': ' . $add_data]); // Test diffing a renamed config entity. $test_entity_id = $this->randomMachineName(); @@ -97,10 +96,11 @@ function testDiff() { $diff = \Drupal::service('config.manager')->diff($active, $sync, 'config_test.dynamic.' . $new_test_entity_id, $config_name); $edits = $diff->getEdits(); - $this->assertEqual($edits[0]->type, 'copy', 'The first item in the diff is a copy.'); - $this->assertEqual($edits[1]->type, 'change', 'The second item in the diff is a change.'); - $this->assertEqual($edits[1]->orig, array('id: ' . $new_test_entity_id)); - $this->assertEqual($edits[1]->closing, array('id: ' . $test_entity_id)); + $this->assertYamlEdit($edits, 'uuid', 'copy'); + $this->assertYamlEdit($edits, 'id', 'change', + ['id: ' . $new_test_entity_id], + ['id: ' . $test_entity_id]); + $this->assertYamlEdit($edits, 'label', 'copy'); $this->assertEqual($edits[2]->type, 'copy', 'The third item in the diff is a copy.'); $this->assertEqual(count($edits), 3, 'There are three items in the diff.'); } @@ -133,10 +133,56 @@ function testCollectionDiff() { // Test that the differences are detected when diffing the collection. $diff = \Drupal::service('config.manager')->diff($active, $sync, $config_name, NULL, 'test'); $edits = $diff->getEdits(); - $this->assertEqual($edits[0]->type, 'change', 'The second item in the diff is a copy.'); - $this->assertEqual($edits[0]->orig, array('foo: bar')); - $this->assertEqual($edits[0]->closing, array('foo: baz')); - $this->assertEqual($edits[1]->type, 'copy', 'The second item in the diff is a copy.'); + $this->assertYamlEdit($edits, 'foo', 'change', ['foo: bar'], ['foo: baz']); + } + + /** + * Helper method to test that an edit is found in a diff'd YAML file. + * + * @param array $edits + * A list of edits. + * @param string $field + * The field key that is being asserted. + * @param string $type + * The type of edit that is being asserted. + * @param mixed $orig + * (optional) The original value of of the edit. If not supplied, assertion + * is skipped. + * @param mixed $closing + * (optional) The closing value of of the edit. If not supplied, assertion + * is skipped. + */ + protected function assertYamlEdit(array $edits, $field, $type, $orig = NULL, $closing = NULL) { + $match = FALSE; + foreach ($edits as $edit) { + // Choose which section to search for the field. + $haystack = $type == 'add' ? $edit->closing : $edit->orig; + // Look through each line and try and find the key. + if (is_array($haystack)) { + foreach ($haystack as $item) { + if (strpos($item, $field . ':') === 0) { + $match = TRUE; + // Assert that the edit is of the type specified. + $this->assertEqual($edit->type, $type, "The $field item in the diff is a $type"); + // If an original value was given, assert that it matches. + if (isset($orig)) { + $this->assertIdentical($edit->orig, $orig, "The original value for key '$field' is correct."); + } + // If a closing value was given, assert that it matches. + if (isset($closing)) { + $this->assertIdentical($edit->closing, $closing, "The closing value for key '$field' is correct."); + } + // Break out of the search entirely. + break 2; + } + } + } + } + + // If we didn't match anything, fail. + if (!$match) { + $this->fail("$field edit was not matched"); + } } } diff --git a/core/tests/Drupal/KernelTests/Core/Config/Storage/FileStorageTest.php b/core/tests/Drupal/KernelTests/Core/Config/Storage/FileStorageTest.php index c0540dd..fa10a09 100644 --- a/core/tests/Drupal/KernelTests/Core/Config/Storage/FileStorageTest.php +++ b/core/tests/Drupal/KernelTests/Core/Config/Storage/FileStorageTest.php @@ -2,9 +2,9 @@ namespace Drupal\KernelTests\Core\Config\Storage; -use Drupal\Component\Serialization\Yaml; use Drupal\Core\Config\FileStorage; use Drupal\Core\Config\UnsupportedDataTypeConfigException; +use Drupal\Core\Serialization\Yaml; use Drupal\Core\StreamWrapper\PublicStream; /** diff --git a/core/tests/Drupal/Tests/BrowserTestBase.php b/core/tests/Drupal/Tests/BrowserTestBase.php index ce2721b..01e15d0 100644 --- a/core/tests/Drupal/Tests/BrowserTestBase.php +++ b/core/tests/Drupal/Tests/BrowserTestBase.php @@ -8,13 +8,13 @@ use Behat\Mink\Session; use Drupal\Component\FileCache\FileCacheFactory; use Drupal\Component\Serialization\Json; -use Drupal\Component\Serialization\Yaml; use Drupal\Component\Utility\Html; use Drupal\Component\Utility\SafeMarkup; use Drupal\Component\Utility\UrlHelper; use Drupal\Core\Cache\Cache; use Drupal\Core\Database\Database; use Drupal\Core\DrupalKernel; +use Drupal\Core\Serialization\Yaml; use Drupal\Core\Session\AccountInterface; use Drupal\Core\Session\AnonymousUserSession; use Drupal\Core\Session\UserSession; diff --git a/core/tests/Drupal/Tests/Component/Serialization/YamlPeclTest.php b/core/tests/Drupal/Tests/Component/Serialization/YamlPeclTest.php new file mode 100644 index 0000000..ef0d7fb --- /dev/null +++ b/core/tests/Drupal/Tests/Component/Serialization/YamlPeclTest.php @@ -0,0 +1,83 @@ +assertEquals($data, YamlPecl::decode(YamlPecl::encode($data))); + } + + /** + * Tests decoding YAML node anchors. + * + * @covers ::decode + * @dataProvider providerDecodeTests + */ + public function testDecode($string, $data) { + $this->assertEquals($data, YamlPecl::decode($string)); + } + + /** + * Tests our encode settings. + * + * @covers ::encode + */ + public function testEncode() { + $this->assertEquals('--- +foo: + bar: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus sapien ex, venenatis vitae nisi eu, posuere luctus dolor. Nullam convallis +... +', YamlPecl::encode(['foo' => ['bar' => 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus sapien ex, venenatis vitae nisi eu, posuere luctus dolor. Nullam convallis']])); + } + + /** + * Tests YAML boolean callback. + * + * @param string $string + * String value for the YAML boolean. + * @param string|bool $expected + * The expected return value. + * + * @covers ::applyBooleanCallbacks + * @dataProvider providerBoolTest + */ + public function testApplyBooleanCallbacks($string, $expected) { + $this->assertEquals($expected, YamlPecl::applyBooleanCallbacks($string, 'bool', NULL)); + } + + /** + * @covers ::getFileExtension + */ + public function testGetFileExtension() { + $this->assertEquals('yml', YamlPecl::getFileExtension()); + } + + /** + * Tests that invalid YAML throws an exception. + * + * @covers ::errorHandler + * @expectedException \Drupal\Component\Serialization\Exception\InvalidDataTypeException + */ + public function testError() { + YamlPecl::decode('foo: [ads'); + } + +} diff --git a/core/tests/Drupal/Tests/Component/Serialization/YamlSymfonyTest.php b/core/tests/Drupal/Tests/Component/Serialization/YamlSymfonyTest.php new file mode 100644 index 0000000..445150a --- /dev/null +++ b/core/tests/Drupal/Tests/Component/Serialization/YamlSymfonyTest.php @@ -0,0 +1,66 @@ +assertEquals($data, YamlSymfony::decode(YamlSymfony::encode($data))); + } + + /** + * Tests decoding YAML node anchors. + * + * @covers ::decode + * @dataProvider providerDecodeTests + */ + public function testDecode($string, $data) { + $this->assertEquals($data, YamlSymfony::decode($string)); + } + + /** + * Tests our encode settings. + * + * @covers ::encode + */ + public function testEncode() { + $this->assertEquals('foo: + bar: \'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus sapien ex, venenatis vitae nisi eu, posuere luctus dolor. Nullam convallis\' +', YamlSymfony::encode(['foo' => ['bar' => 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus sapien ex, venenatis vitae nisi eu, posuere luctus dolor. Nullam convallis']])); + } + + /** + * @covers ::getFileExtension + */ + public function testGetFileExtension() { + $this->assertEquals('yml', YamlSymfony::getFileExtension()); + } + + /** + * Tests that invalid YAML throws an exception. + * + * @covers ::decode + * @expectedException \Drupal\Component\Serialization\Exception\InvalidDataTypeException + */ + public function testError() { + YamlSymfony::decode('foo: [ads'); + } + +} diff --git a/core/tests/Drupal/Tests/Component/Serialization/YamlTest.php b/core/tests/Drupal/Tests/Component/Serialization/YamlTest.php index bc492e1..04c38d3 100644 --- a/core/tests/Drupal/Tests/Component/Serialization/YamlTest.php +++ b/core/tests/Drupal/Tests/Component/Serialization/YamlTest.php @@ -2,7 +2,11 @@ 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 Drupal\Tests\UnitTestCase; /** @@ -12,47 +16,117 @@ class YamlTest extends UnitTestCase { /** - * @covers ::decode + * @var \PHPUnit_Framework_MockObject_MockObject */ - public function testDecode() { - // Test that files without line break endings are properly interpreted. - $yaml = 'foo: bar'; - $expected = array( - 'foo' => 'bar', - ); - $this->assertSame($expected, Yaml::decode($yaml)); - $yaml .= "\n"; - $this->assertSame($expected, Yaml::decode($yaml)); - $yaml .= "\n"; - $this->assertSame($expected, Yaml::decode($yaml)); - - $yaml = "{}\n"; - $expected = array(); - $this->assertSame($expected, Yaml::decode($yaml)); - - $yaml = ''; - $this->assertNULL(Yaml::decode($yaml)); - $yaml .= "\n"; - $this->assertNULL(Yaml::decode($yaml)); - $yaml .= "\n"; - $this->assertNULL(Yaml::decode($yaml)); + 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(); } /** - * @covers ::encode + * @covers ::decode */ - public function testEncode() { - $decoded = array( - 'foo' => 'bar', - ); - $this->assertSame('foo: bar' . "\n", Yaml::encode($decoded)); + public function testDecode() { + $this->mockParser + ->expects($this->once()) + ->method('decode'); + YamlStub::decode('test'); } /** * @covers ::getFileExtension */ public function testGetFileExtension() { - $this->assertEquals('yml', Yaml::getFileExtension()); + $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()); + } + } + + /** + * 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 + */ + 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(); } } diff --git a/core/tests/Drupal/Tests/Component/Serialization/YamlTestBase.php b/core/tests/Drupal/Tests/Component/Serialization/YamlTestBase.php new file mode 100644 index 0000000..d2b504e --- /dev/null +++ b/core/tests/Drupal/Tests/Component/Serialization/YamlTestBase.php @@ -0,0 +1,99 @@ + 'bar', + 'id' => 'schnitzel', + 'ponies' => ['nope', 'thanks'], + 'how' => [ + 'about' => 'if', + 'i' => 'ask', + 'nicely', + ], + 'the' => [ + 'answer' => [ + 'still' => 'would', + 'be' => 'Y', + ], + ], + 'how_many_times' => 123, + 'should_i_ask' => FALSE, + 1, + FALSE, + [1, FALSE], + [10], + [0 => '123456'], + ], + [NULL] + ]; + } + + /** + * Some data that should be able to be de-serialized. + */ + public function providerDecodeTests() { + $data = [ + // NULL files. + ['', NULL], + ["\n", NULL], + ["---\n...\n", NULL], + + // Node anchors. + [ + " +jquery.ui: + version: &jquery_ui 1.10.2 + +jquery.ui.accordion: + version: *jquery_ui +", + [ + 'jquery.ui' => [ + 'version' => '1.10.2', + ], + 'jquery.ui.accordion' => [ + 'version' => '1.10.2', + ], + ], + ], + ]; + + // 1.2 Bool values. + foreach ($this->providerBoolTest() as $test) { + $data[] = ['bool: ' . $test[0], ['bool' => $test[1]]]; + } + $data = array_merge($data, $this->providerBoolTest()); + + return $data; + } + + /** + * Tests different boolean serialization and de-serialization. + */ + public function providerBoolTest() { + return [ + ['true', TRUE], + ['TRUE', TRUE], + ['True', TRUE], + ['y', 'y'], + ['Y', 'Y'], + ['false', FALSE], + ['FALSE', FALSE], + ['False', FALSE], + ['n', 'n'], + ['N', 'N'], + ]; + } + +} diff --git a/core/tests/Drupal/Tests/Core/Asset/LibraryDiscoveryParserTest.php b/core/tests/Drupal/Tests/Core/Asset/LibraryDiscoveryParserTest.php index ed0c9ce..b79f5b1 100644 --- a/core/tests/Drupal/Tests/Core/Asset/LibraryDiscoveryParserTest.php +++ b/core/tests/Drupal/Tests/Core/Asset/LibraryDiscoveryParserTest.php @@ -211,34 +211,6 @@ public function testVersion() { $this->assertEquals(\Drupal::VERSION, $libraries['core-versioned']['js'][0]['version']); } - /** - * Tests the version property with ISO dates. - * - * We want to make sure that versions defined in the YAML file are the same - * versions that are parsed. - * - * For example, ISO dates are converted into UNIX time by the YAML parser. - * - * @covers ::buildByExtension - */ - public function testNonStringVersion() { - $this->moduleHandler->expects($this->atLeastOnce()) - ->method('moduleExists') - ->with('versions') - ->will($this->returnValue(TRUE)); - - $path = __DIR__ . '/library_test_files'; - $path = substr($path, strlen($this->root) + 1); - $this->libraryDiscoveryParser->setPaths('module', 'versions', $path); - - $libraries = $this->libraryDiscoveryParser->buildByExtension('versions'); - - // As an example, we defined an ISO date in the YAML file and the YAML - // parser converts it into a UNIX timestamp. - $this->assertNotEquals('2014-12-13', $libraries['invalid-version']['version']); - // An example of an ISO date as a string which parses correctly. - $this->assertEquals('2014-12-13', $libraries['valid-version']['version']); - } /** * Tests that the version property of external libraries is handled. diff --git a/core/tests/Drupal/Tests/Core/Asset/library_test_files/versions.libraries.yml b/core/tests/Drupal/Tests/Core/Asset/library_test_files/versions.libraries.yml index bee49f5..7310a09 100644 --- a/core/tests/Drupal/Tests/Core/Asset/library_test_files/versions.libraries.yml +++ b/core/tests/Drupal/Tests/Core/Asset/library_test_files/versions.libraries.yml @@ -20,13 +20,3 @@ core-versioned: core-versioned.css: {} js: core-versioned.js: {} - -invalid-version: - version: 2014-12-13 - js: - versioned.js: {} - -valid-version: - version: "2014-12-13" - js: - versioned.js: {} diff --git a/core/tests/Drupal/Tests/Core/Extension/InfoParserUnitTest.php b/core/tests/Drupal/Tests/Core/Extension/InfoParserUnitTest.php index 454c4a5..74a7649 100644 --- a/core/tests/Drupal/Tests/Core/Extension/InfoParserUnitTest.php +++ b/core/tests/Drupal/Tests/Core/Extension/InfoParserUnitTest.php @@ -147,7 +147,7 @@ public function testInfoParserCommonInfo() { description: 'testing info file parsing' simple_string: 'A simple string' version: "VERSION" -double_colon: dummyClassName:: +double_colon: dummyClassName::method COMMONTEST; vfsStream::setup('modules'); @@ -159,7 +159,7 @@ public function testInfoParserCommonInfo() { $info_values = $this->infoParser->parse(vfsStream::url('modules/fixtures/common_test.info.txt')); $this->assertEquals($info_values['simple_string'], 'A simple string', 'Simple string value was parsed correctly.'); $this->assertEquals($info_values['version'], \Drupal::VERSION, 'Constant value was parsed correctly.'); - $this->assertEquals($info_values['double_colon'], 'dummyClassName::', 'Value containing double-colon was parsed correctly.'); + $this->assertEquals($info_values['double_colon'], 'dummyClassName::method', 'Value containing double-colon was parsed correctly.'); } } diff --git a/core/tests/Drupal/Tests/Core/Routing/RouteBuilderTest.php b/core/tests/Drupal/Tests/Core/Routing/RouteBuilderTest.php index c69c502..a1095cd 100644 --- a/core/tests/Drupal/Tests/Core/Routing/RouteBuilderTest.php +++ b/core/tests/Drupal/Tests/Core/Routing/RouteBuilderTest.php @@ -7,8 +7,8 @@ namespace Drupal\Tests\Core\Routing; -use Drupal\Component\Discovery\YamlDiscovery; use Drupal\Core\DependencyInjection\ContainerBuilder; +use Drupal\Core\Discovery\YamlDiscovery; use Drupal\Core\Routing\RouteBuilder; use Drupal\Core\Routing\RouteBuildEvent; use Drupal\Core\Routing\RoutingEvents; @@ -53,7 +53,7 @@ class RouteBuilderTest extends UnitTestCase { /** * The mocked YAML discovery. * - * @var \Drupal\Component\Discovery\YamlDiscovery|\PHPUnit_Framework_MockObject_MockObject + * @var \Drupal\Core\Discovery\YamlDiscovery|\PHPUnit_Framework_MockObject_MockObject */ protected $yamlDiscovery; @@ -82,7 +82,7 @@ protected function setUp() { $this->dispatcher = $this->getMock('\Symfony\Component\EventDispatcher\EventDispatcherInterface'); $this->moduleHandler = $this->getMock('Drupal\Core\Extension\ModuleHandlerInterface'); $this->controllerResolver = $this->getMock('Drupal\Core\Controller\ControllerResolverInterface'); - $this->yamlDiscovery = $this->getMockBuilder('\Drupal\Component\Discovery\YamlDiscovery') + $this->yamlDiscovery = $this->getMockBuilder('\Drupal\Core\Discovery\YamlDiscovery') ->disableOriginalConstructor() ->getMock(); $this->checkProvider = $this->getMock('\Drupal\Core\Access\CheckProviderInterface'); @@ -284,14 +284,14 @@ class TestRouteBuilder extends RouteBuilder { /** * The mocked YAML discovery. * - * @var \Drupal\Component\Discovery\YamlDiscovery|\PHPUnit_Framework_MockObject_MockObject + * @var \Drupal\Core\Discovery\YamlDiscovery|\PHPUnit_Framework_MockObject_MockObject */ protected $yamlDiscovery; /** * Sets the YAML discovery. * - * @param \Drupal\Component\Discovery\YamlDiscovery $yaml_discovery + * @param \Drupal\Core\Discovery\YamlDiscovery $yaml_discovery * The YAML discovery to set. */ public function setYamlDiscovery(YamlDiscovery $yaml_discovery) { diff --git a/core/tests/Drupal/Tests/Core/Serialization/YamlTest.php b/core/tests/Drupal/Tests/Core/Serialization/YamlTest.php new file mode 100644 index 0000000..ba77d26 --- /dev/null +++ b/core/tests/Drupal/Tests/Core/Serialization/YamlTest.php @@ -0,0 +1,63 @@ + YamlParserProxy::class]); + + $this->assertEquals(YamlParserProxy::class, Settings::get('yaml_parser_class')); + + $mock = $this->getMockBuilder('\stdClass') + ->setMethods(['encode', 'decode', 'getFileExtension']) + ->getMock(); + $mock + ->expects($this->once()) + ->method('decode'); + YamlParserProxy::setMock($mock); + Yaml::decode('---'); + + new Settings([]); + } +} + +class YamlParserProxy implements SerializationInterface { + + /** + * @var \Drupal\Component\Serialization\SerializationInterface + */ + 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(); + } + +} diff --git a/sites/default/default.settings.php b/sites/default/default.settings.php index 67f1104..0da98e8 100644 --- a/sites/default/default.settings.php +++ b/sites/default/default.settings.php @@ -679,6 +679,15 @@ # $settings['container_base_class'] = '\Drupal\Core\DependencyInjection\Container'; /** + * Override the default yaml parser class. + * + * Provide a fully qualified class name here if you would like to provide an + * alternate implementation YAML parser. The class must implement the + * \Drupal\Component\Serialization\SerializationInterface interface. + */ +# $settings['yaml_parser_class'] = NULL; + +/** * Trusted host configuration. * * Drupal core can use the Symfony trusted host mechanism to prevent HTTP Host