Issue #3163500 by lauriii, jungle, raman.b, JeroenT, catch, longwave, larowlan: Detect when libraries-override or libraries-extend is used on deprecated library
parent
0774f68936
commit
07daa79e14
|
@ -136,6 +136,11 @@ class LibraryDiscoveryCollector extends CacheCollector {
|
|||
$libraries_extend = $this->themeManager->getActiveTheme()->getLibrariesExtend();
|
||||
if (!empty($libraries_extend["$extension/$library_name"])) {
|
||||
foreach ($libraries_extend["$extension/$library_name"] as $library_extend_name) {
|
||||
if (isset($library_definition['deprecated'])) {
|
||||
$extend_message = sprintf('Theme "%s" is extending a deprecated library.', $extension);
|
||||
$library_deprecation = str_replace('%library_id%', "$extension/$library_name", $library_definition['deprecated']);
|
||||
@trigger_error("$extend_message $library_deprecation", E_USER_DEPRECATED);
|
||||
}
|
||||
if (!is_string($library_extend_name)) {
|
||||
// Only string library names are allowed.
|
||||
throw new InvalidLibrariesExtendSpecificationException('The libraries-extend specification for each library must be a list of strings.');
|
||||
|
|
|
@ -382,6 +382,11 @@ class LibraryDiscoveryParser {
|
|||
foreach ($libraries as $library_name => $library) {
|
||||
// Process libraries overrides.
|
||||
if (isset($libraries_overrides["$extension/$library_name"])) {
|
||||
if (isset($library['deprecated'])) {
|
||||
$override_message = sprintf('Theme "%s" is overriding a deprecated library.', $extension);
|
||||
$library_deprecation = str_replace('%library_id%', "$extension/$library_name", $library['deprecated']);
|
||||
@trigger_error("$override_message $library_deprecation", E_USER_DEPRECATED);
|
||||
}
|
||||
// Active theme defines an override for this library.
|
||||
$override_definition = $libraries_overrides["$extension/$library_name"];
|
||||
if (is_string($override_definition) || $override_definition === FALSE) {
|
||||
|
|
|
@ -5,3 +5,17 @@ theme_stylesheets_override_and_remove_test:
|
|||
css/base-remove.css: {}
|
||||
css/sub-override.css: {}
|
||||
css/sub-remove.css: {}
|
||||
|
||||
deprecated_library:
|
||||
version: VERSION
|
||||
css:
|
||||
base:
|
||||
css/foo.css: {}
|
||||
deprecated: 'The "%library_id%" asset library is deprecated in drupal:X.0.0 and is removed from drupal:Y.0.0. Use another library instead. See https://www.example.com'
|
||||
|
||||
another_deprecated_library:
|
||||
version: VERSION
|
||||
css:
|
||||
base:
|
||||
css/bar.css: {}
|
||||
deprecated: 'The "%library_id%" asset library is deprecated in drupal:X.0.0 and is removed from drupal:Y.0.0. Use another library instead. See https://www.example.com'
|
||||
|
|
|
@ -4,3 +4,13 @@ description: 'Test theme to test deprecated functionality.'
|
|||
version: VERSION
|
||||
package: Testing
|
||||
base theme: test_theme
|
||||
|
||||
libraries-override:
|
||||
theme_test/deprecated_library:
|
||||
css:
|
||||
base:
|
||||
css/foo.css: css/bar.css
|
||||
|
||||
libraries-extend:
|
||||
theme_test/another_deprecated_library:
|
||||
- test_legacy_theme/library
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
library:
|
||||
css:
|
||||
base:
|
||||
css/baz.css: {}
|
|
@ -20,6 +20,11 @@ class LibraryDiscoveryIntegrationTest extends KernelTestBase {
|
|||
*/
|
||||
protected $libraryDiscovery;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $modules = ['theme_test'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
@ -208,6 +213,22 @@ class LibraryDiscoveryIntegrationTest extends KernelTestBase {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test deprecated libraries.
|
||||
*
|
||||
* @group legacy
|
||||
*
|
||||
* @expectedDeprecation Theme "theme_test" is overriding a deprecated library. The "theme_test/deprecated_library" asset library is deprecated in drupal:X.0.0 and is removed from drupal:Y.0.0. Use another library instead. See https://www.example.com
|
||||
* @expectedDeprecation Theme "theme_test" is extending a deprecated library. The "theme_test/another_deprecated_library" asset library is deprecated in drupal:X.0.0 and is removed from drupal:Y.0.0. Use another library instead. See https://www.example.com
|
||||
* @expectedDeprecation The "theme_test/deprecated_library" asset library is deprecated in drupal:X.0.0 and is removed from drupal:Y.0.0. Use another library instead. See https://www.example.com
|
||||
* @expectedDeprecation The "theme_test/another_deprecated_library" asset library is deprecated in drupal:X.0.0 and is removed from drupal:Y.0.0. Use another library instead. See https://www.example.com
|
||||
*/
|
||||
public function testDeprecatedLibrary() {
|
||||
$this->activateTheme('test_legacy_theme');
|
||||
$this->libraryDiscovery->getLibraryByName('theme_test', 'deprecated_library');
|
||||
$this->libraryDiscovery->getLibraryByName('theme_test', 'another_deprecated_library');
|
||||
}
|
||||
|
||||
/**
|
||||
* Activates a specified theme.
|
||||
*
|
||||
|
|
|
@ -4,6 +4,7 @@ namespace Drupal\Tests\Core\Asset;
|
|||
|
||||
use Drupal\Core\Asset\LibraryDiscoveryCollector;
|
||||
use Drupal\Core\Cache\Cache;
|
||||
use Drupal\Core\Theme\ActiveTheme;
|
||||
use Drupal\Tests\UnitTestCase;
|
||||
|
||||
/**
|
||||
|
@ -61,6 +62,23 @@ class LibraryDiscoveryCollectorTest extends UnitTestCase {
|
|||
'js' => [],
|
||||
'css' => [],
|
||||
],
|
||||
'test_3' => [
|
||||
'js' => [],
|
||||
'css' => [
|
||||
'theme' => [
|
||||
'foo.css' => [],
|
||||
],
|
||||
],
|
||||
],
|
||||
'test_4' => [
|
||||
'js' => [],
|
||||
'css' => [
|
||||
'theme' => [
|
||||
'bar.css' => [],
|
||||
],
|
||||
],
|
||||
'deprecated' => 'The "%library_id%" asset library is deprecated in drupal:X.0.0 and is removed from drupal:Y.0.0. Use the test_3 library instead. See https://www.example.com',
|
||||
],
|
||||
];
|
||||
|
||||
protected $activeTheme;
|
||||
|
@ -77,7 +95,6 @@ class LibraryDiscoveryCollectorTest extends UnitTestCase {
|
|||
$this->libraryDiscoveryParser = $this->getMockBuilder('Drupal\Core\Asset\LibraryDiscoveryParser')
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -86,10 +103,10 @@ class LibraryDiscoveryCollectorTest extends UnitTestCase {
|
|||
* @covers ::resolveCacheMiss
|
||||
*/
|
||||
public function testResolveCacheMiss() {
|
||||
$this->activeTheme = $this->getMockBuilder('Drupal\Core\Theme\ActiveTheme')
|
||||
$this->activeTheme = $this->getMockBuilder(ActiveTheme::class)
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
$this->themeManager->expects($this->exactly(3))
|
||||
$this->themeManager->expects($this->exactly(5))
|
||||
->method('getActiveTheme')
|
||||
->willReturn($this->activeTheme);
|
||||
$this->activeTheme->expects($this->once())
|
||||
|
@ -112,10 +129,10 @@ class LibraryDiscoveryCollectorTest extends UnitTestCase {
|
|||
* @covers ::destruct
|
||||
*/
|
||||
public function testDestruct() {
|
||||
$this->activeTheme = $this->getMockBuilder('Drupal\Core\Theme\ActiveTheme')
|
||||
$this->activeTheme = $this->getMockBuilder(ActiveTheme::class)
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
$this->themeManager->expects($this->exactly(3))
|
||||
$this->themeManager->expects($this->exactly(5))
|
||||
->method('getActiveTheme')
|
||||
->willReturn($this->activeTheme);
|
||||
$this->activeTheme->expects($this->once())
|
||||
|
@ -150,4 +167,93 @@ class LibraryDiscoveryCollectorTest extends UnitTestCase {
|
|||
$this->libraryDiscoveryCollector->destruct();
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests library with an extend.
|
||||
*
|
||||
* @covers ::applyLibrariesExtend
|
||||
*/
|
||||
public function testLibrariesExtend() {
|
||||
$this->activeTheme = $this->getMockBuilder(ActiveTheme::class)
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
$this->themeManager->expects($this->any())
|
||||
->method('getActiveTheme')
|
||||
->willReturn($this->activeTheme);
|
||||
$this->activeTheme->expects($this->once())
|
||||
->method('getName')
|
||||
->willReturn('kitten_theme');
|
||||
$this->activeTheme->expects($this->atLeastOnce())
|
||||
->method('getLibrariesExtend')
|
||||
->willReturn([
|
||||
'test/test_3' => [
|
||||
'kitten_theme/extend',
|
||||
],
|
||||
]);
|
||||
$this->libraryDiscoveryParser->expects($this->at(0))
|
||||
->method('buildByExtension')
|
||||
->with('test')
|
||||
->willReturn($this->libraryData);
|
||||
$this->libraryDiscoveryParser->expects($this->at(1))
|
||||
->method('buildByExtension')
|
||||
->with('kitten_theme')
|
||||
->willReturn([
|
||||
'extend' => [
|
||||
'css' => [
|
||||
'theme' => [
|
||||
'baz.css' => [],
|
||||
],
|
||||
],
|
||||
],
|
||||
]);
|
||||
$library_discovery_collector = new LibraryDiscoveryCollector($this->cache, $this->lock, $this->libraryDiscoveryParser, $this->themeManager);
|
||||
$libraries = $library_discovery_collector->get('test');
|
||||
$this->assertSame(['foo.css', 'baz.css'], array_keys($libraries['test_3']['css']['theme']));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests a deprecated library with an extend.
|
||||
*
|
||||
* @covers ::applyLibrariesExtend
|
||||
*
|
||||
* @group legacy
|
||||
*
|
||||
* @expectedDeprecation Theme "test" is extending a deprecated library. The "test/test_4" asset library is deprecated in drupal:X.0.0 and is removed from drupal:Y.0.0. Use the test_3 library instead. See https://www.example.com
|
||||
*/
|
||||
public function testLibrariesExtendDeprecated() {
|
||||
$this->activeTheme = $this->getMockBuilder(ActiveTheme::class)
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
$this->themeManager->expects($this->any())
|
||||
->method('getActiveTheme')
|
||||
->willReturn($this->activeTheme);
|
||||
$this->activeTheme->expects($this->once())
|
||||
->method('getName')
|
||||
->willReturn('kitten_theme');
|
||||
$this->activeTheme->expects($this->atLeastOnce())
|
||||
->method('getLibrariesExtend')
|
||||
->willReturn([
|
||||
'test/test_4' => [
|
||||
'kitten_theme/extend',
|
||||
],
|
||||
]);
|
||||
$this->libraryDiscoveryParser->expects($this->at(0))
|
||||
->method('buildByExtension')
|
||||
->with('test')
|
||||
->willReturn($this->libraryData);
|
||||
$this->libraryDiscoveryParser->expects($this->at(1))
|
||||
->method('buildByExtension')
|
||||
->with('kitten_theme')
|
||||
->willReturn([
|
||||
'extend' => [
|
||||
'css' => [
|
||||
'theme' => [
|
||||
'baz.css' => [],
|
||||
],
|
||||
],
|
||||
],
|
||||
]);
|
||||
$library_discovery_collector = new LibraryDiscoveryCollector($this->cache, $this->lock, $this->libraryDiscoveryParser, $this->themeManager);
|
||||
$library_discovery_collector->get('test');
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -13,6 +13,8 @@ use Drupal\Core\Asset\Exception\LibraryDefinitionMissingLicenseException;
|
|||
use Drupal\Core\Asset\LibrariesDirectoryFileFinder;
|
||||
use Drupal\Core\Asset\LibraryDiscoveryParser;
|
||||
use Drupal\Core\StreamWrapper\StreamWrapperManagerInterface;
|
||||
use Drupal\Core\Theme\ActiveTheme;
|
||||
use Drupal\Core\Theme\ThemeManagerInterface;
|
||||
use Drupal\Tests\UnitTestCase;
|
||||
|
||||
/**
|
||||
|
@ -49,6 +51,13 @@ class LibraryDiscoveryParserTest extends UnitTestCase {
|
|||
*/
|
||||
protected $themeManager;
|
||||
|
||||
/**
|
||||
* The mocked active theme.
|
||||
*
|
||||
* @var \Drupal\Core\Theme\ActiveTheme|\PHPUnit\Framework\MockObject\MockObject
|
||||
*/
|
||||
protected $activeTheme;
|
||||
|
||||
/**
|
||||
* The mocked lock backend.
|
||||
*
|
||||
|
@ -77,16 +86,16 @@ class LibraryDiscoveryParserTest extends UnitTestCase {
|
|||
parent::setUp();
|
||||
|
||||
$this->moduleHandler = $this->createMock('Drupal\Core\Extension\ModuleHandlerInterface');
|
||||
$this->themeManager = $this->createMock('Drupal\Core\Theme\ThemeManagerInterface');
|
||||
$mock_active_theme = $this->getMockBuilder('Drupal\Core\Theme\ActiveTheme')
|
||||
$this->themeManager = $this->createMock(ThemeManagerInterface::class);
|
||||
$this->activeTheme = $this->getMockBuilder(ActiveTheme::class)
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
$mock_active_theme->expects($this->any())
|
||||
$this->activeTheme->expects($this->any())
|
||||
->method('getLibrariesOverride')
|
||||
->willReturn([]);
|
||||
$this->themeManager->expects($this->any())
|
||||
->method('getActiveTheme')
|
||||
->willReturn($mock_active_theme);
|
||||
->willReturn($this->activeTheme);
|
||||
$this->streamWrapperManager = $this->createMock(StreamWrapperManagerInterface::class);
|
||||
$this->librariesDirectoryFileFinder = $this->createMock(LibrariesDirectoryFileFinder::class);
|
||||
$this->libraryDiscoveryParser = new TestLibraryDiscoveryParser($this->root, $this->moduleHandler, $this->themeManager, $this->streamWrapperManager, $this->librariesDirectoryFileFinder);
|
||||
|
@ -111,7 +120,7 @@ class LibraryDiscoveryParserTest extends UnitTestCase {
|
|||
$library = $libraries['example'];
|
||||
|
||||
$this->assertCount(0, $library['js']);
|
||||
$this->assertCount(1, $library['css']);
|
||||
$this->assertCount(2, $library['css']);
|
||||
$this->assertCount(0, $library['dependencies']);
|
||||
$this->assertEquals($path . '/css/example.css', $library['css'][0]['data']);
|
||||
|
||||
|
@ -544,6 +553,98 @@ class LibraryDiscoveryParserTest extends UnitTestCase {
|
|||
$this->assertEquals($library['license'], $expected_license);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests libraries with overrides.
|
||||
*
|
||||
* @covers ::applyLibrariesOverride
|
||||
*/
|
||||
public function testLibraryOverride() {
|
||||
$mock_theme_path = 'mocked_themes/kittens';
|
||||
$this->themeManager = $this->createMock(ThemeManagerInterface::class);
|
||||
$this->activeTheme = $this->getMockBuilder(ActiveTheme::class)
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
$this->activeTheme->expects($this->atLeastOnce())
|
||||
->method('getLibrariesOverride')
|
||||
->willReturn([
|
||||
$mock_theme_path => [
|
||||
'example_module/example' => [
|
||||
'css' => [
|
||||
'theme' => [
|
||||
'css/example.css' => 'css/overridden.css',
|
||||
'css/example2.css' => FALSE,
|
||||
],
|
||||
],
|
||||
],
|
||||
],
|
||||
]);
|
||||
$this->themeManager->expects($this->any())
|
||||
->method('getActiveTheme')
|
||||
->willReturn($this->activeTheme);
|
||||
$this->libraryDiscoveryParser = new TestLibraryDiscoveryParser($this->root, $this->moduleHandler, $this->themeManager, $this->streamWrapperManager, $this->librariesDirectoryFileFinder);
|
||||
|
||||
$this->moduleHandler->expects($this->atLeastOnce())
|
||||
->method('moduleExists')
|
||||
->with('example_module')
|
||||
->will($this->returnValue(TRUE));
|
||||
|
||||
$path = __DIR__ . '/library_test_files';
|
||||
$path = substr($path, strlen($this->root) + 1);
|
||||
$this->libraryDiscoveryParser->setPaths('module', 'example_module', $path);
|
||||
|
||||
$libraries = $this->libraryDiscoveryParser->buildByExtension('example_module');
|
||||
$library = $libraries['example'];
|
||||
|
||||
$this->assertCount(0, $library['js']);
|
||||
$this->assertCount(1, $library['css']);
|
||||
$this->assertCount(0, $library['dependencies']);
|
||||
$this->assertEquals($mock_theme_path . '/css/overridden.css', $library['css'][0]['data']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests deprecated library with an override.
|
||||
*
|
||||
* @covers ::applyLibrariesOverride
|
||||
*
|
||||
* @group legacy
|
||||
*
|
||||
* @expectedDeprecation Theme "deprecated" is overriding a deprecated library. The "deprecated/deprecated" asset library is deprecated in drupal:X.0.0 and is removed from drupal:Y.0.0. Use another library instead. See https://www.example.com
|
||||
*/
|
||||
public function testLibraryOverrideDeprecated() {
|
||||
$mock_theme_path = 'mocked_themes/kittens';
|
||||
$this->themeManager = $this->createMock(ThemeManagerInterface::class);
|
||||
$this->activeTheme = $this->getMockBuilder(ActiveTheme::class)
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
$this->activeTheme->expects($this->atLeastOnce())
|
||||
->method('getLibrariesOverride')
|
||||
->willReturn([
|
||||
$mock_theme_path => [
|
||||
'deprecated/deprecated' => [
|
||||
'css' => [
|
||||
'theme' => [
|
||||
'css/example.css' => 'css/overridden.css',
|
||||
],
|
||||
],
|
||||
],
|
||||
],
|
||||
]);
|
||||
$this->themeManager->expects($this->any())
|
||||
->method('getActiveTheme')
|
||||
->willReturn($this->activeTheme);
|
||||
$this->libraryDiscoveryParser = new TestLibraryDiscoveryParser($this->root, $this->moduleHandler, $this->themeManager, $this->streamWrapperManager, $this->librariesDirectoryFileFinder);
|
||||
|
||||
$this->moduleHandler->expects($this->atLeastOnce())
|
||||
->method('moduleExists')
|
||||
->with('deprecated')
|
||||
->will($this->returnValue(TRUE));
|
||||
|
||||
$path = __DIR__ . '/library_test_files';
|
||||
$path = substr($path, strlen($this->root) + 1);
|
||||
$this->libraryDiscoveryParser->setPaths('module', 'deprecated', $path);
|
||||
$this->libraryDiscoveryParser->buildByExtension('deprecated');
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies assertions catch invalid CSS declarations.
|
||||
*
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
deprecated:
|
||||
version: VERSION
|
||||
css:
|
||||
theme:
|
||||
css/example.css: {}
|
||||
deprecated: 'The "%library_id%" asset library is deprecated in drupal:X.0.0 and is removed from drupal:Y.0.0. Use another library instead. See https://www.example.com'
|
|
@ -3,3 +3,4 @@ example:
|
|||
css:
|
||||
theme:
|
||||
css/example.css: {}
|
||||
css/example2.css: {}
|
||||
|
|
Loading…
Reference in New Issue