diff --git a/core/includes/file.inc b/core/includes/file.inc index 545fca3..c487b81 100644 --- a/core/includes/file.inc +++ b/core/includes/file.inc @@ -191,12 +191,16 @@ function file_get_stream_wrappers($filter = STREAM_WRAPPERS_ALL) { $wrappers_storage = &drupal_static(__FUNCTION__); if (!isset($wrappers_storage)) { - $wrappers = \Drupal::moduleHandler()->invokeAll('stream_wrappers'); - foreach ($wrappers as $scheme => $info) { - // Add defaults. - $wrappers[$scheme] += array('type' => STREAM_WRAPPERS_NORMAL); + $wrappers = array(); + $container = \Drupal::getContainer(); + if (is_object($container) && $container->has('module_handler')) { + $wrappers = \Drupal::moduleHandler()->invokeAll('stream_wrappers'); + foreach ($wrappers as $scheme => $info) { + // Add defaults. + $wrappers[$scheme] += array('type' => STREAM_WRAPPERS_NORMAL); + } + drupal_alter('stream_wrappers', $wrappers); } - drupal_alter('stream_wrappers', $wrappers); $existing = stream_get_wrappers(); foreach ($wrappers as $scheme => $info) { // We only register classes that implement our interface. diff --git a/core/modules/simpletest/lib/Drupal/simpletest/DrupalUnitTestBase.php b/core/modules/simpletest/lib/Drupal/simpletest/DrupalUnitTestBase.php index b7848de..89d69b1 100644 --- a/core/modules/simpletest/lib/Drupal/simpletest/DrupalUnitTestBase.php +++ b/core/modules/simpletest/lib/Drupal/simpletest/DrupalUnitTestBase.php @@ -64,6 +64,13 @@ protected $keyValueFactory; /** + * A list of stream wrappers that have been registered by this test. + * + * @var array + */ + private $stream_wrappers = array(); + + /** * Overrides \Drupal\simpletest\UnitTestBase::__construct(). */ function __construct($test_id = NULL) { @@ -88,6 +95,12 @@ protected function setUp() { $this->keyValueFactory = new KeyValueMemoryFactory(); parent::setUp(); + + // UnitTestBase created a public files directory. Tests based on + // DrupalUnitTestBase are entitled to use Drupal's File API, so inject a + // 'public' stream wrapper. + $this->registerStreamWrapper('public', 'Drupal\Core\StreamWrapper\PublicStream'); + // Build a minimal, partially mocked environment for unit tests. $this->containerBuild(\Drupal::getContainer()); // Make sure it survives kernel rebuilds. @@ -134,6 +147,9 @@ protected function setUp() { protected function tearDown() { $this->kernel->shutdown(); + foreach ($this->stream_wrappers as $scheme) { + $this->unregisterStreamWrapper($scheme); + } parent::tearDown(); } @@ -334,4 +350,45 @@ protected function disableModules(array $modules) { ))); } + /** + * Registers a stream wrapper for this test. + * + * @param string $scheme + * The scheme to register. + * @param string $class + * The fully qualified class name to register. + * @param int $type + * The Drupal Stream Wrapper API type. Defaults to + * STREAM_WRAPPERS_LOCAL_NORMAL. + */ + protected function registerStreamWrapper($scheme, $class, $type = STREAM_WRAPPERS_LOCAL_NORMAL) { + if (isset($this->stream_wrappers[$scheme])) { + $this->unregisterStreamWrapper($scheme); + } + $this->stream_wrappers[$scheme] = $scheme; + stream_wrapper_register($scheme, $class); + // @todo Revamp Drupal's stream wrapper API for D8. + $wrappers = &drupal_static('file_get_stream_wrappers'); + $wrappers[$scheme] = array( + 'type' => $type, + 'class' => $class, + ); + $wrappers[STREAM_WRAPPERS_ALL] = $wrappers; + } + + /** + * Unregisters a stream wrapper previously registered by this test. + * + * @param string $scheme + * The scheme to unregister. + */ + protected function unregisterStreamWrapper($scheme) { + stream_wrapper_unregister($scheme); + unset($this->stream_wrappers[$scheme]); + // @todo Revamp Drupal's stream wrapper API for D8. + $wrappers = &drupal_static('file_get_stream_wrappers'); + unset($wrappers[$scheme]); + unset($wrappers[STREAM_WRAPPERS_ALL][$scheme]); + } + } diff --git a/core/modules/simpletest/lib/Drupal/simpletest/TestBase.php b/core/modules/simpletest/lib/Drupal/simpletest/TestBase.php index 669c615..a859d93 100644 --- a/core/modules/simpletest/lib/Drupal/simpletest/TestBase.php +++ b/core/modules/simpletest/lib/Drupal/simpletest/TestBase.php @@ -963,6 +963,12 @@ protected function prepareEnvironment() { // Create and set new configuration directories. $this->prepareConfigDirectories(); + // Unregister all Drupal stream wrappers. + $wrappers = file_get_stream_wrappers(); + foreach ($wrappers as $scheme => $info) { + stream_wrapper_unregister($scheme); + } + // Reset statics before the old container is replaced so that objects with a // __destruct() method still have access to it. // @todo: Remove once they have been converted to services. @@ -1106,13 +1112,6 @@ protected function tearDown() { } } - // In case a fatal error occurred that was not in the test process read the - // log to pick up any fatal errors. - simpletest_log_read($this->testId, $this->databasePrefix, get_class($this), TRUE); - - // Delete temporary files directory. - file_unmanaged_delete_recursive($this->originalFileDirectory . '/simpletest/' . substr($this->databasePrefix, 10), array($this, 'filePreDeleteCallback')); - // Restore original database connection. Database::removeConnection('default'); Database::renameConnection('simpletest_original_default', 'default'); @@ -1139,6 +1138,17 @@ protected function tearDown() { // Restore original statics and globals. \Drupal::setContainer($this->originalContainer); $GLOBALS['config_directories'] = $this->originalConfigDirectories; + + // Re-initialize original stream wrappers. + file_get_stream_wrappers(); + + // In case a fatal error occurred that was not in the test process read the + // log to pick up any fatal errors. + simpletest_log_read($this->testId, $this->databasePrefix, get_class($this), TRUE); + + // Delete temporary files directory. + file_unmanaged_delete_recursive($this->originalFileDirectory . '/simpletest/' . substr($this->databasePrefix, 10), array($this, 'filePreDeleteCallback')); + if (isset($this->originalPrefix)) { drupal_valid_test_ua($this->originalPrefix); } diff --git a/core/modules/system/lib/Drupal/system/Tests/File/ConfigTest.php b/core/modules/system/lib/Drupal/system/Tests/File/ConfigTest.php index ce48dfd..a38322b 100644 --- a/core/modules/system/lib/Drupal/system/Tests/File/ConfigTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/File/ConfigTest.php @@ -7,10 +7,12 @@ namespace Drupal\system\Tests\File; +use Drupal\simpletest\WebTestBase; + /** * File system configuration related tests. */ -class ConfigTest extends FileTestBase { +class ConfigTest extends WebTestBase { public static function getInfo() { return array( diff --git a/core/modules/system/lib/Drupal/system/Tests/File/FileTestBase.php b/core/modules/system/lib/Drupal/system/Tests/File/FileTestBase.php index 540c19a..cc45e7f 100644 --- a/core/modules/system/lib/Drupal/system/Tests/File/FileTestBase.php +++ b/core/modules/system/lib/Drupal/system/Tests/File/FileTestBase.php @@ -8,22 +8,30 @@ namespace Drupal\system\Tests\File; use Drupal\file\FileInterface; -use Drupal\simpletest\WebTestBase; +use Drupal\simpletest\DrupalUnitTestBase; /** * Base class for file tests that adds some additional file specific * assertions and helper functions. */ -abstract class FileTestBase extends WebTestBase { +abstract class FileTestBase extends DrupalUnitTestBase { + + /** + * Modules to enable. + * + * @var array + */ + public static $modules = array('system'); function setUp() { parent::setUp(); - // Make sure that custom stream wrappers are registered. - // @todo This has the potential to be a major bug deeply buried in File API; - // file_unmanaged_*() API functions and test functions are invoking native - // PHP functions directly, whereas Drupal's custom stream wrappers are not - // registered yet. - file_get_stream_wrappers(); + $this->installConfig(array('system')); + $this->registerStreamWrapper('private', 'Drupal\Core\StreamWrapper\PrivateStream'); + $this->registerStreamWrapper('temporary', 'Drupal\Core\StreamWrapper\TemporaryStream'); + + if (isset($this->scheme)) { + $this->registerStreamWrapper($this->scheme, $this->classname); + } } /** diff --git a/core/modules/system/lib/Drupal/system/Tests/File/MimeTypeTest.php b/core/modules/system/lib/Drupal/system/Tests/File/MimeTypeTest.php index 5ee981d..e9c388d 100644 --- a/core/modules/system/lib/Drupal/system/Tests/File/MimeTypeTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/File/MimeTypeTest.php @@ -7,12 +7,10 @@ namespace Drupal\system\Tests\File; -use Drupal\simpletest\WebTestBase; - /** * Tests for file_get_mimetype(). */ -class MimeTypeTest extends WebTestBase { +class MimeTypeTest extends FileTestBase { /** * Modules to enable. diff --git a/core/modules/system/lib/Drupal/system/Tests/File/ReadOnlyStreamWrapperTest.php b/core/modules/system/lib/Drupal/system/Tests/File/ReadOnlyStreamWrapperTest.php index ef84796..779ba12 100644 --- a/core/modules/system/lib/Drupal/system/Tests/File/ReadOnlyStreamWrapperTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/File/ReadOnlyStreamWrapperTest.php @@ -12,13 +12,6 @@ */ class ReadOnlyStreamWrapperTest extends FileTestBase { - /** - * Modules to enable. - * - * @var array - */ - public static $modules = array('file_test'); - protected $scheme = 'dummy-readonly'; protected $classname = 'Drupal\file_test\DummyReadOnlyStreamWrapper'; @@ -30,16 +23,6 @@ public static function getInfo() { ); } - function setUp() { - parent::setUp(); - drupal_static_reset('file_get_stream_wrappers'); - } - - function tearDown() { - parent::tearDown(); - stream_wrapper_unregister($this->scheme); - } - /** * Test write functionality of the read-only stream wrapper. */ diff --git a/core/modules/system/lib/Drupal/system/Tests/File/StreamWrapperTest.php b/core/modules/system/lib/Drupal/system/Tests/File/StreamWrapperTest.php index 16bc592..e095ed4 100644 --- a/core/modules/system/lib/Drupal/system/Tests/File/StreamWrapperTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/File/StreamWrapperTest.php @@ -8,12 +8,11 @@ namespace Drupal\system\Tests\File; use Drupal\Core\StreamWrapper\PublicStream; -use Drupal\simpletest\WebTestBase; /** * Tests stream wrapper functions. */ -class StreamWrapperTest extends WebTestBase { +class StreamWrapperTest extends FileTestBase { /** * Modules to enable. @@ -33,16 +32,6 @@ public static function getInfo() { ); } - function setUp() { - parent::setUp(); - drupal_static_reset('file_get_stream_wrappers'); - } - - function tearDown() { - parent::tearDown(); - stream_wrapper_unregister($this->scheme); - } - /** * Test the getClassName() function. */