Commit 36fcf91c authored by catch's avatar catch
Browse files

Issue #1891516 by sun, Berdir, chx: Remove $install parameter from...

Issue #1891516 by sun, Berdir, chx: Remove $install parameter from DrupalUnitTestBase::enableModules(), encourage to create individual schema tables only.
parent faaddf2f
......@@ -26,7 +26,7 @@ class BlockStorageUnitTest extends DrupalUnitTestBase {
*
* @var array
*/
public static $modules = array('block_test');
public static $modules = array('block', 'block_test');
/**
* The block storage controller.
......@@ -46,7 +46,6 @@ public static function getInfo() {
protected function setUp() {
parent::setUp();
$this->enableModules(array('block'));
$this->controller = $this->container->get('plugin.manager.entity')->getStorageController('block');
}
......@@ -196,7 +195,7 @@ public function testDefaultBlocks() {
$this->assertTrue(empty($entities), 'There are no blocks initially.');
// Install the block_test.module, so that its default config is installed.
$this->enableModules(array('block_test'));
$this->installConfig(array('block_test'));
$entities = $this->controller->load();
$entity = reset($entities);
......
......@@ -163,6 +163,7 @@ function testNameValidation() {
$message = 'Expected ConfigNameException was thrown when attempting to install invalid configuration.';
try {
$this->enableModules(array('config_test_invalid_name'));
$this->installConfig(array('config_test_invalid_name'));
$this->fail($message);
}
catch (ConfigNameException $e) {
......
......@@ -57,6 +57,7 @@ function testModuleInstallation() {
// Install the test module.
$this->enableModules(array('config_test'));
$this->installConfig(array('config_test'));
// Verify that default module config exists.
$config = config($default_config);
......
......@@ -20,7 +20,7 @@ class EditTestBase extends DrupalUnitTestBase {
*
* @var array
*/
public static $modules = array('system', 'entity', 'field_test', 'field', 'number', 'text', 'edit');
public static $modules = array('system', 'entity', 'field', 'field_sql_storage', 'field_test', 'number', 'text', 'edit');
/**
* Sets the default field storage backend for fields created during tests.
......@@ -29,7 +29,8 @@ function setUp() {
parent::setUp();
$this->installSchema('system', 'variable');
$this->enableModules(array('field', 'field_sql_storage', 'field_test'));
$this->installSchema('field', array('field_config', 'field_config_instance'));
$this->installSchema('field_test', 'test_entity');
// Set default storage backend.
variable_set('field_storage_default', $this->default_storage);
......
......@@ -56,6 +56,8 @@ public static function getInfo() {
function setUp() {
parent::setUp();
$this->installSchema('field_test', 'test_entity_revision');
$this->editorManager = new EditorManager();
$this->accessChecker = new MockEditEntityFieldAccessCheck();
$this->editorSelector = new EditorSelector($this->editorManager);
......
......@@ -27,7 +27,7 @@ public static function getInfo() {
protected function setUp() {
parent::setUp();
$this->enableModules(array('field'));
$this->installSchema('field', array('field_config', 'field_config_instance'));
}
/**
......
......@@ -14,7 +14,7 @@
*/
class FilterDefaultConfigTest extends DrupalUnitTestBase {
public static $modules = array('system', 'user', 'filter');
public static $modules = array('system', 'user', 'filter', 'filter_test');
public static function getInfo() {
return array(
......@@ -26,18 +26,20 @@ public static function getInfo() {
function setUp() {
parent::setUp();
$this->enableModules(array('user'));
// filter_permission() calls into url() to output a link in the description.
$this->installSchema('system', 'url_alias');
$this->installSchema('user', array('users_roles', 'role_permission'));
// Install filter_test module, which ships with custom default format.
$this->installConfig(array('user', 'filter_test'));
}
/**
* Tests installation of default formats.
*/
function testInstallation() {
// Install filter_test module, which ships with custom default format.
$this->enableModules(array('filter_test'));
// Verify that the format was installed correctly.
$format = filter_format_load('filter_test');
$this->assertTrue($format);
......@@ -87,9 +89,6 @@ function testInstallation() {
* Tests that changes to FilterFormat::$roles do not have an effect.
*/
function testUpdateRoles() {
// Install filter_test module, which ships with custom default format.
$this->enableModules(array('filter_test'));
// Verify role permissions declared in default config.
$format = filter_format_load('filter_test');
$this->assertEqual(array_keys(filter_get_roles_by_format($format)), array(
......
......@@ -15,12 +15,22 @@
*/
abstract class LanguageTestBase extends ViewUnitTestBase {
/**
* Modules to enable.
*
* @var array
*/
public static $modules = array('system', 'language');
protected function setUp() {
parent::setUp();
$this->installSchema('language', 'language');
$this->installSchema('system', 'variable');
$this->enableModules(array('system', 'language'));
// Create another language beside English.
// Create English and another language beside English.
$language = new Language(array('langcode' => 'en'));
language_save($language);
$language = new Language(array('langcode' => 'xx-lolspeak', 'name' => 'Lolspeak'));
language_save($language);
}
......
......@@ -61,6 +61,14 @@ abstract class DrupalUnitTestBase extends UnitTestBase {
*/
protected $keyValueFactory;
/**
* Overrides \Drupal\simpletest\UnitTestBase::__construct().
*/
function __construct($test_id = NULL) {
parent::__construct($test_id);
$this->skipClasses[__CLASS__] = TRUE;
}
/**
* Sets up Drupal unit test environment.
*
......@@ -89,7 +97,7 @@ protected function setUp() {
// Bootstrap the kernel.
// No need to dump it; this test runs in-memory.
$this->kernel = new DrupalKernel('testing', TRUE, drupal_classloader(), FALSE);
$this->kernel = new DrupalKernel('unit_testing', TRUE, drupal_classloader(), FALSE);
$this->kernel->boot();
// Collect and set a fixed module list.
......@@ -97,22 +105,37 @@ protected function setUp() {
$modules = array();
while ($class) {
if (property_exists($class, 'modules')) {
$modules = array_merge($modules, $class::$modules);
// Only add the modules, if the $modules property was not inherited.
$rp = new \ReflectionProperty($class, 'modules');
if ($rp->class == $class) {
$modules[$class] = $class::$modules;
}
}
$class = get_parent_class($class);
}
$this->enableModules(array_unique($modules), FALSE);
// Modules have been collected in reverse class hierarchy order; modules
// defined by base classes should be sorted first. Then, merge the results
// together.
$modules = array_reverse($modules);
$modules = call_user_func_array('array_merge_recursive', $modules);
$this->enableModules($modules, FALSE);
}
protected function tearDown() {
$this->kernel->shutdown();
parent::tearDown();
}
/**
* Sets up the base service container for this test.
*
* Extend this method in your test to register additional service overrides
* that need to persist a DrupalKernel reboot. This method is only called once
* for each test.
* that need to persist a DrupalKernel reboot. This method is called whenever
* the kernel is rebuilt.
*
* @see DrupalUnitTestBase::setUp()
* @see DrupalUnitTestBase::enableModules()
* @see DrupalUnitTestBase::disableModules()
*/
public function containerBuild($container) {
global $conf;
......@@ -137,7 +160,7 @@ public function containerBuild($container) {
// away with a simple container holding the absolute bare minimum. When
// a kernel is overridden then there's no need to re-register the keyvalue
// service but when a test is happy with the superminimal container put
// together here, it still might a keyvalue storage for anything (for
// together here, it still might a keyvalue storage for anything (for
// eg. module_enable) using state() -- that's why a memory service was
// added in the first place.
$container
......@@ -147,16 +170,34 @@ public function containerBuild($container) {
}
/**
* Installs a specific table from a module schema definition.
* Installs default configuration for a given list of modules.
*
* Use this to install a particular table from System module.
* @param array $modules
* A list of modules for which to install default configuration.
*/
protected function installConfig(array $modules) {
foreach ($modules as $module) {
if (!$this->container->get('module_handler')->moduleExists($module)) {
throw new \RuntimeException(format_string("'@module' module is not enabled.", array(
'@module' => $module,
)));
}
config_install_default_config('module', $module);
}
$this->pass(format_string('Installed default config: %modules.', array(
'%modules' => implode(', ', $modules),
)));
}
/**
* Installs a specific table from a module schema definition.
*
* @param string $module
* The name of the module that defines the table's schema.
* @param string $table
* The name of the table to install.
* @param string|array $tables
* The name or an array of the names of the tables to install.
*/
protected function installSchema($module, $table) {
protected function installSchema($module, $tables) {
// drupal_get_schema_unprocessed() is technically able to install a schema
// of a non-enabled module, but its ability to load the module's .install
// file depends on many other factors. To prevent differences in test
......@@ -167,60 +208,86 @@ protected function installSchema($module, $table) {
'@module' => $module,
)));
}
$schema = drupal_get_schema_unprocessed($module, $table);
if (empty($schema)) {
throw new \RuntimeException(format_string("Unable to retrieve '@module' module schema for '@table' table.", array(
'@module' => $module,
'@table' => $table,
)));
$tables = (array) $tables;
foreach ($tables as $table) {
$schema = drupal_get_schema_unprocessed($module, $table);
if (empty($schema)) {
throw new \RuntimeException(format_string("Unknown '@table' table schema in '@module' module.", array(
'@module' => $module,
'@table' => $table,
)));
}
$this->container->get('database')->schema()->createTable($table, $schema);
}
Database::getConnection()->schema()->createTable($table, $schema);
// We need to refresh the schema cache, as any call to drupal_get_schema()
// would not know of/return the schema otherwise.
// @todo Refactor Schema API to make this obsolete.
drupal_get_schema(NULL, TRUE);
$this->pass(format_string('Installed %module tables: %tables.', array(
'%tables' => '{' . implode('}, {', $tables) . '}',
'%module' => $module,
)));
}
/**
* Enables modules for this test.
*
* Callbacks invoked by module_enable() may need to access information
* provided by info hooks of the new modules already. However, module_enable()
* enables the new modules in the system.module configuration only, but that
* has no effect, since we are operating with a fixed module list.
*
* @param array $modules
* A list of modules to enable. Dependencies are not resolved; i.e.,
* multiple modules have to be specified with dependent modules first.
* @param bool $install
* (optional) Whether to install the list of modules via module_enable().
* Defaults to TRUE. If FALSE, the new modules are only added to the fixed
* module list and loaded.
*
* @todo Remove $install argument and replace all callers that do not pass
* FALSE with module_enable().
* The new modules are only added to the active module list and loaded.
*/
protected function enableModules(array $modules, $install = TRUE) {
if ($install) {
module_enable($modules, FALSE);
protected function enableModules(array $modules) {
// Set the list of modules in the extension handler.
$module_handler = $this->container->get('module_handler');
$module_filenames = $module_handler->getModuleList();
foreach ($modules as $module) {
$module_filenames[$module] = drupal_get_filename('module', $module);
}
// Explicitly set the list of modules in the extension handler.
else {
$module_handler = $this->container->get('module_handler');
$module_filenames = $module_handler->getModuleList();
foreach ($modules as $module) {
$module_filenames[$module] = drupal_get_filename('module', $module);
}
$module_handler->setModuleList($module_filenames);
$module_handler->resetImplementations();
$this->kernel->updateModules($module_filenames, $module_filenames);
$module_handler->setModuleList($module_filenames);
$module_handler->resetImplementations();
// Update the kernel to make their services available.
$this->kernel->updateModules($module_filenames, $module_filenames);
// Ensure isLoaded() is TRUE in order to make theme() work.
// Note that the kernel has rebuilt the container; this $module_handler is
// no longer the $module_handler instance from above.
$module_handler = $this->container->get('module_handler');
$module_handler->reload();
$this->pass(format_string('Enabled modules: %modules.', array(
'%modules' => implode(', ', $modules),
)));
}
/**
* Disables modules for this test.
*
* @param array $modules
* A list of modules to disable. Dependencies are not resolved; i.e.,
* multiple modules have to be specified with dependent modules first.
* Code of previously active modules is still loaded. The modules are only
* removed from the active module list.
*/
protected function disableModules(array $modules) {
// Unset the list of modules in the extension handler.
$module_handler = $this->container->get('module_handler');
$module_filenames = $module_handler->getModuleList();
foreach ($modules as $module) {
unset($module_filenames[$module]);
}
// Regardless of loaded or installed, ensure isLoaded() is TRUE in order to
// make theme() work.
$module_handler->setModuleList($module_filenames);
$module_handler->resetImplementations();
// Update the kernel to remove their services.
$this->kernel->updateModules($module_filenames, $module_filenames);
// Ensure isLoaded() is TRUE in order to make theme() work.
// Note that the kernel has rebuilt the container; this $module_handler is
// no longer the $module_handler instance from above.
$module_handler = $this->container->get('module_handler');
$module_handler->reload();
$this->pass(format_string('Disabled modules: %modules.', array(
'%modules' => implode(', ', $modules),
)));
}
}
......@@ -60,7 +60,7 @@ function testEnableModulesLoad() {
$this->assertFalse(in_array($module, $list), "{$module}_permission() in module_implements() not found.");
// Enable the module.
$this->enableModules(array($module), FALSE);
$this->enableModules(array($module));
// Verify that the module exists.
$this->assertTrue(module_exists($module), "$module module found.");
......@@ -77,10 +77,6 @@ function testEnableModulesInstall() {
$module = 'node';
$table = 'node';
// @todo Remove after configuration system conversion.
$this->enableModules(array('system'), FALSE);
$this->installSchema('system', 'variable');
// Verify that the module does not exist yet.
$this->assertFalse(module_exists($module), "$module module not found.");
$list = array_keys(drupal_container()->get('module_handler')->getModuleList());
......@@ -92,8 +88,8 @@ function testEnableModulesInstall() {
$schema = drupal_get_schema($table);
$this->assertFalse($schema, "'$table' table schema not found.");
// Enable the module.
$this->enableModules(array($module));
// Install the module.
module_enable(array($module));
// Verify that the enabled module exists.
$this->assertTrue(module_exists($module), "$module module found.");
......@@ -107,24 +103,6 @@ function testEnableModulesInstall() {
$this->assertTrue($schema, "'$table' table schema found.");
}
/**
* Tests installing of multiple modules via enableModules().
*
* Regression test: Each passed module has to be enabled and installed on its
* own, in the same way as module_enable() enables only one module after the
* other.
*/
function testEnableModulesInstallMultiple() {
// Field retrieves entity type plugins, and EntityTypeManager calls into
// hook_entity_info_alter(). If both modules would be first enabled together
// instead of each on its own, then Node module's alter implementation
// would be called and this simply blows up. To further complicate matters,
// additionally install Comment module, whose entity bundles depend on node
// types.
$this->enableModules(array('field', 'node', 'comment'));
$this->pass('Comment module was installed.');
}
/**
* Tests installing modules via enableModules() with DepedencyInjection services.
*/
......@@ -133,6 +111,9 @@ function testEnableModulesInstallContainer() {
// @todo field_sql_storage and field should technically not be necessary
// for an entity query.
$this->enableModules(array('field_sql_storage', 'field', 'node'));
$this->installSchema('field', array('field_config', 'field_config_instance'));
$this->installSchema('node', array('node_type', 'node'));
// Perform an entity query against node.
$query = entity_query('node');
// Disable node access checks, since User module is not enabled.
......@@ -158,6 +139,19 @@ function testInstallSchema() {
$schema = drupal_get_schema($table);
$this->assertTrue($schema, "'$table' table schema found.");
// Verify that a unknown table from an enabled module throws an error.
$table = 'unknown_entity_test_table';
try {
$this->installSchema($module, $table);
$this->fail('Exception for non-retrievable schema found.');
}
catch (\Exception $e) {
$this->pass('Exception for non-retrievable schema found.');
}
$this->assertFalse(db_table_exists($table), "'$table' database table not found.");
$schema = drupal_get_schema($table);
$this->assertFalse($schema, "'$table' table schema not found.");
// Verify that a table from a unknown module cannot be installed.
$module = 'database_test';
$table = 'test';
......@@ -173,7 +167,7 @@ function testInstallSchema() {
$this->assertFalse($schema, "'$table' table schema not found.");
// Verify that the same table can be installed after enabling the module.
$this->enableModules(array($module), FALSE);
$this->enableModules(array($module));
$this->installSchema($module, $table);
$this->assertTrue(db_table_exists($table), "'$table' database table found.");
$schema = drupal_get_schema($table);
......@@ -181,7 +175,30 @@ function testInstallSchema() {
}
/**
* Tests that the fixed module list is retained after enabling and installing modules.
* Tests expected behavior of installConfig().
*/
function testInstallConfig() {
$module = 'user';
// Verify that default config can only be installed for enabled modules.
try {
$this->installConfig(array($module));
$this->fail('Exception for non-enabled module found.');
}
catch (\Exception $e) {
$this->pass('Exception for non-enabled module found.');
}
$this->assertFalse($this->container->get('config.storage')->exists('user.settings'));
// Verify that default config can be installed.
$this->enableModules(array('user'));
$this->installConfig(array('user'));
$this->assertTrue($this->container->get('config.storage')->exists('user.settings'));
$this->assertTrue(config('user.settings')->get('register'));
}
/**
* Tests that the module list is retained after enabling/installing/disabling modules.
*/
function testEnableModulesFixedList() {
// entity_test is loaded via $modules; its entity type should exist.
......@@ -189,7 +206,7 @@ function testEnableModulesFixedList() {
$this->assertTrue(TRUE == entity_get_info('entity_test'));
// Load some additional modules; entity_test should still exist.
$this->enableModules(array('entity', 'field', 'field_sql_storage', 'text', 'entity_test'), FALSE);
$this->enableModules(array('entity', 'field', 'field_sql_storage', 'text', 'entity_test'));
$this->assertEqual($this->container->get('module_handler')->moduleExists('entity_test'), TRUE);
$this->assertTrue(TRUE == entity_get_info('entity_test'));
......@@ -209,7 +226,7 @@ function testEnableModulesFixedList() {
$this->assertTrue(TRUE == entity_get_info('entity_test'));
// Reactivate the disabled module without enabling it.
$this->enableModules(array('field_test'), FALSE);
$this->enableModules(array('field_test'));
// Create a field and an instance.
$display = entity_create('entity_display', array(
......@@ -234,14 +251,18 @@ function testEnableModulesFixedList() {
* Tests that theme() works right after loading a module.
*/
function testEnableModulesTheme() {
$element = array(
$original_element = $element = array(
'#type' => 'container',
'#markup' => 'Foo',
'#attributes' => array(),
);
$this->enableModules(array('system'), FALSE);
$this->enableModules(array('system'));
// theme() throws an exception if modules are not loaded yet.
drupal_render($element);
$this->assertTrue(drupal_render($element));
$element = $original_element;
$this->disableModules(array('entity_test'));
$this->assertTrue(drupal_render($element));
}
}
......@@ -17,9 +17,19 @@
*/
abstract class DatabaseTestBase extends DrupalUnitTestBase {
public static $modules = array('database_test');
function setUp() {
parent::setUp();
$this->enableModules(array('database_test'));
$this->installSchema('database_test', array(
'test',
'test_people',
'test_one_blob',
'test_two_blobs',
'test_task',
'test_null',
'test_serialized',
));
self::addSampleData();
}
......
......@@ -17,7 +17,7 @@ class SelectComplexTest extends DatabaseTestBase {
*
* @var array
*/
public static $modules = array('node_access_test');
public static $modules = array('node_access_test', 'field');
public static function getInfo() {