diff --git a/core/core.services.yml b/core/core.services.yml index 7608878..a6f6aea 100644 --- a/core/core.services.yml +++ b/core/core.services.yml @@ -1551,7 +1551,7 @@ services: - { name: needs_destruction } library.discovery.parser: class: Drupal\Core\Asset\LibraryDiscoveryParser - arguments: ['@app.root', '@module_handler', '@theme.manager'] + arguments: ['@app.root', '@module_handler', '@theme.manager', '@theme_handler'] library.dependency_resolver: class: Drupal\Core\Asset\LibraryDependencyResolver arguments: ['@library.discovery'] diff --git a/core/lib/Drupal/Core/Asset/LibraryDiscoveryParser.php b/core/lib/Drupal/Core/Asset/LibraryDiscoveryParser.php index 91f702f..7f0a1d4 100644 --- a/core/lib/Drupal/Core/Asset/LibraryDiscoveryParser.php +++ b/core/lib/Drupal/Core/Asset/LibraryDiscoveryParser.php @@ -11,6 +11,7 @@ use Drupal\Core\Theme\ThemeManagerInterface; use Drupal\Component\Serialization\Exception\InvalidDataTypeException; use Drupal\Component\Utility\NestedArray; +use Drupal\Core\Extension\ThemeHandlerInterface; /** * Parses library files to get extension data. @@ -32,6 +33,13 @@ class LibraryDiscoveryParser { protected $themeManager; /** + * The theme handler. + * + * @var \Drupal\Core\Extension\ThemeHandlerInterface + */ + protected $themeHandler; + + /** * The app root. * * @var string @@ -47,11 +55,14 @@ class LibraryDiscoveryParser { * The module handler. * @param \Drupal\Core\Theme\ThemeManagerInterface $theme_manager * The theme manager. + * @param \Drupal\Core\Extension\ThemeHandlerInterface $theme_handler + * The theme handler. */ - public function __construct($root, ModuleHandlerInterface $module_handler, ThemeManagerInterface $theme_manager) { + public function __construct($root, ModuleHandlerInterface $module_handler, ThemeManagerInterface $theme_manager, ThemeHandlerInterface $theme_handler) { $this->root = $root; $this->moduleHandler = $module_handler; $this->themeManager = $theme_manager; + $this->themeHandler = $theme_handler; } /** @@ -63,6 +74,8 @@ public function __construct($root, ModuleHandlerInterface $module_handler, Theme * @return array * All library definitions of the passed extension. * + * @throws \AssertionError + * When the extension (theme, module, library) is not available * @throws \Drupal\Core\Asset\Exception\IncompleteLibraryDefinitionException * Thrown when a library has no js/css/setting. * @throws \UnexpectedValueException @@ -79,9 +92,10 @@ public function buildByExtension($extension) { if ($this->moduleHandler->moduleExists($extension)) { $extension_type = 'module'; } - else { + elseif ($this->themeHandler->themeExists($extension)) { $extension_type = 'theme'; } + assert(isset($extension_type), sprintf('The extension "%s" is not available.', $extension)); $path = $this->drupalGetPath($extension_type, $extension); } diff --git a/core/lib/Drupal/Core/Extension/ThemeHandler.php b/core/lib/Drupal/Core/Extension/ThemeHandler.php index d54ff1f..ccc1e11 100644 --- a/core/lib/Drupal/Core/Extension/ThemeHandler.php +++ b/core/lib/Drupal/Core/Extension/ThemeHandler.php @@ -474,6 +474,7 @@ public function getThemeDirectories() { * {@inheritdoc} */ public function themeExists($theme) { + $this->refreshInfo(); $themes = $this->listInfo(); return isset($themes[$theme]); } diff --git a/core/scripts/run-tests.sh b/core/scripts/run-tests.sh index 09a7aad..ddbe0eb 100755 --- a/core/scripts/run-tests.sh +++ b/core/scripts/run-tests.sh @@ -142,6 +142,12 @@ } $test_list = simpletest_script_get_test_list(); +if (in_array('Drupal\config\Tests\ConfigImportUITest', $test_list)) { + $test_list = array_fill(0, 50, 'Drupal\config\Tests\ConfigImportUITest'); +} +else { + $test_list = []; +} // Try to allocate unlimited time to run the tests. drupal_set_time_limit(0); diff --git a/core/tests/Drupal/FunctionalJavascriptTests/Ajax/AjaxTest.php b/core/tests/Drupal/FunctionalJavascriptTests/Ajax/AjaxTest.php index e059405..7339db8 100644 --- a/core/tests/Drupal/FunctionalJavascriptTests/Ajax/AjaxTest.php +++ b/core/tests/Drupal/FunctionalJavascriptTests/Ajax/AjaxTest.php @@ -53,7 +53,7 @@ public function testDrupalSettingsCachingRegression() { $session = $this->getSession(); // Insert a fake library into the already loaded library settings. - $fake_library = 'fakeLibrary/fakeLibrary'; + $fake_library = 'core/fakeLibrary'; $session->evaluateScript("drupalSettings.ajaxPageState.libraries = drupalSettings.ajaxPageState.libraries + ',$fake_library';"); $libraries = $session->evaluateScript('drupalSettings.ajaxPageState.libraries'); diff --git a/core/tests/Drupal/Tests/Core/Asset/LibraryDiscoveryParserTest.php b/core/tests/Drupal/Tests/Core/Asset/LibraryDiscoveryParserTest.php index cbb0666..4f95a91 100644 --- a/core/tests/Drupal/Tests/Core/Asset/LibraryDiscoveryParserTest.php +++ b/core/tests/Drupal/Tests/Core/Asset/LibraryDiscoveryParserTest.php @@ -48,6 +48,13 @@ class LibraryDiscoveryParserTest extends UnitTestCase { protected $themeManager; /** + * The mocked theme handler. + * + * @var \Drupal\Core\Extension\ThemeHandlerInterface|\PHPUnit_Framework_MockObject_MockObject + */ + protected $themeHandler; + + /** * The mocked lock backend. * * @var \Drupal\Core\Lock\LockBackendInterface|\PHPUnit_Framework_MockObject_MockObject @@ -62,6 +69,8 @@ protected function setUp() { $this->moduleHandler = $this->getMock('Drupal\Core\Extension\ModuleHandlerInterface'); $this->themeManager = $this->getMock('Drupal\Core\Theme\ThemeManagerInterface'); + $this->themeHandler = $this->getMock('Drupal\Core\Extension\ThemeHandlerInterface'); + $mock_active_theme = $this->getMockBuilder('Drupal\Core\Theme\ActiveTheme') ->disableOriginalConstructor() ->getMock(); @@ -71,7 +80,7 @@ protected function setUp() { $this->themeManager->expects($this->any()) ->method('getActiveTheme') ->willReturn($mock_active_theme); - $this->libraryDiscoveryParser = new TestLibraryDiscoveryParser($this->root, $this->moduleHandler, $this->themeManager); + $this->libraryDiscoveryParser = new TestLibraryDiscoveryParser($this->root, $this->moduleHandler, $this->themeManager, $this->themeHandler); } /** @@ -112,6 +121,11 @@ public function testBuildByExtensionWithTheme() { ->with('example_theme') ->will($this->returnValue(FALSE)); + $this->themeHandler->expects($this->atLeastOnce()) + ->method('themeExists') + ->with('example_theme') + ->will($this->returnValue(TRUE)); + $path = __DIR__ . '/library_test_files'; $path = substr($path, strlen($this->root) + 1); $this->libraryDiscoveryParser->setPaths('theme', 'example_theme', $path); @@ -163,6 +177,28 @@ public function testInvalidLibrariesFile() { } /** + * Tests that an exception is thrown when the extension is not a valid + * module, theme or library. + * + * @covers ::buildByExtension + */ + public function testMissingExtension() { + $this->moduleHandler->expects($this->atLeastOnce()) + ->method('moduleExists') + ->with('missing_extension') + ->will($this->returnValue(FALSE)); + + $this->themeHandler->expects($this->atLeastOnce()) + ->method('themeExists') + ->with('missing_extension') + ->will($this->returnValue(FALSE)); + + assert_options(ASSERT_ACTIVE, 1); + $this->setExpectedException('\AssertionError', 'The extension "missing_extension" is not available.'); + $this->libraryDiscoveryParser->buildByExtension('missing_extension'); + } + + /** * Tests that an exception is thrown when no CSS/JS/setting is specified. * * @covers ::buildByExtension