updated core

This commit is contained in:
Bachir Soussi Chiadmi
2018-01-24 13:36:32 +01:00
parent cd7dea45a9
commit f9374cf96d
1997 changed files with 5175 additions and 127715 deletions
@@ -633,4 +633,10 @@ class BrowserTestBaseTest extends BrowserTestBase {
$this->assertSession()->pageTextContains('Test page text.');
}
public function testGetDefaultDriveInstance() {
putenv('MINK_DRIVER_ARGS=' . json_encode([NULL, ['key1' => ['key2' => ['key3' => 3, 'key3.1' => 3.1]]]]));
$this->getDefaultDriverInstance();
$this->assertEquals([NULL, ['key1' => ['key2' => ['key3' => 3, 'key3.1' => 3.1]]]], $this->minkDefaultDriverArgs);
}
}
@@ -112,7 +112,6 @@ class ContentEntityFormFieldValidationFilteringTest extends BrowserTestBase {
'translatable' => FALSE,
])->save();
entity_get_form_display($this->entityTypeId, $this->entityTypeId, 'default')
->setComponent($this->fieldNameSingle, ['type' => 'test_field_widget'])
->setComponent($this->fieldNameMultiple, ['type' => 'test_field_widget'])
@@ -0,0 +1,33 @@
<?php
namespace Drupal\FunctionalTests\Routing;
use Drupal\Tests\BrowserTestBase;
/**
* @group routing
*/
class LazyRouteProviderInstallTest extends BrowserTestBase {
/**
* {@inheritdoc}
*/
protected static $modules = ['lazy_route_provider_install_test'];
/**
* Tests that the lazy route provider is used during a module install.
*/
public function testInstallation() {
$this->container->get('module_installer')->install(['router_test']);
// Note that on DrupalCI the test site is installed in a sub directory so
// we cannot use ::assertEquals().
$this->assertStringEndsWith('/admin', \Drupal::state()->get('Drupal\lazy_route_provider_install_test\PluginManager'));
$this->assertStringEndsWith('/router_test/test1', \Drupal::state()->get('router_test_install'));
// If there is an exception thrown in rebuilding a route then the state
// 'lazy_route_provider_install_test_menu_links_discovered_alter' will be
// set.
// @see lazy_route_provider_install_test_menu_links_discovered_alter().
$this->assertEquals('success', \Drupal::state()->get('lazy_route_provider_install_test_menu_links_discovered_alter', NULL));
}
}
@@ -49,7 +49,6 @@ class GetFilenameTest extends KernelTestBase {
// a fixed location and naming.
$this->assertIdentical(drupal_get_filename('profile', 'testing'), 'core/profiles/testing/testing.info.yml');
// Generate a non-existing module name.
$non_existing_module = uniqid("", TRUE);
@@ -235,9 +235,9 @@ class ConfigDependencyTest extends EntityKernelTestBase {
// Ensure that alphabetical order has no influence on dependency fixing and
// removal.
return [
[['a', 'b', 'c', 'd']],
[['d', 'c', 'b', 'a']],
[['c', 'd', 'a', 'b']],
[['a', 'b', 'c', 'd', 'e']],
[['e', 'd', 'c', 'b', 'a']],
[['e', 'c', 'd', 'a', 'b']],
];
}
@@ -316,6 +316,25 @@ class ConfigDependencyTest extends EntityKernelTestBase {
);
$entity_4->save();
// Entity 5 will be fixed because it is dependent on entity 3, which is
// unchanged, and entity 1 which will be fixed because
// \Drupal\config_test\Entity::onDependencyRemoval() will remove the
// dependency.
$entity_5 = $storage->create(
[
'id' => 'entity_' . $entity_id_suffixes[4],
'dependencies' => [
'enforced' => [
'config' => [
$entity_1->getConfigDependencyName(),
$entity_3->getConfigDependencyName(),
],
],
],
]
);
$entity_5->save();
// Set a more complicated test where dependencies will be fixed.
\Drupal::state()->set('config_test.fix_dependencies', [$entity_1->getConfigDependencyName()]);
\Drupal::state()->set('config_test.on_dependency_removal_called', []);
@@ -323,14 +342,22 @@ class ConfigDependencyTest extends EntityKernelTestBase {
// Do a dry run using
// \Drupal\Core\Config\ConfigManager::getConfigEntitiesToChangeOnDependencyRemoval().
$config_entities = $config_manager->getConfigEntitiesToChangeOnDependencyRemoval('module', ['node']);
// Assert that \Drupal\config_test\Entity\ConfigTest::onDependencyRemoval()
// is called as expected and with the correct dependencies.
$called = \Drupal::state()->get('config_test.on_dependency_removal_called', []);
$this->assertArrayNotHasKey($entity_3->id(), $called, 'ConfigEntityInterface::onDependencyRemoval() is not called for entity 3.');
$this->assertSame([$entity_1->id(), $entity_4->id(), $entity_2->id(), $entity_5->id()], array_keys($called), 'The most dependent entites have ConfigEntityInterface::onDependencyRemoval() called first.');
$this->assertSame(['config' => [], 'content' => [], 'module' => ['node'], 'theme' => []], $called[$entity_1->id()]);
$this->assertSame(['config' => [$entity_1->getConfigDependencyName()], 'content' => [], 'module' => [], 'theme' => []], $called[$entity_2->id()]);
$this->assertSame(['config' => [$entity_1->getConfigDependencyName()], 'content' => [], 'module' => ['node'], 'theme' => []], $called[$entity_4->id()]);
$this->assertSame(['config' => [$entity_1->getConfigDependencyName()], 'content' => [], 'module' => [], 'theme' => []], $called[$entity_5->id()]);
$this->assertEqual($entity_1->uuid(), $config_entities['delete'][1]->uuid(), 'Entity 1 will be deleted.');
$this->assertEqual($entity_2->uuid(), reset($config_entities['update'])->uuid(), 'Entity 2 will be updated.');
$this->assertEqual($entity_2->uuid(), $config_entities['update'][0]->uuid(), 'Entity 2 will be updated.');
$this->assertEqual($entity_3->uuid(), reset($config_entities['unchanged'])->uuid(), 'Entity 3 is not changed.');
$this->assertEqual($entity_4->uuid(), $config_entities['delete'][0]->uuid(), 'Entity 4 will be deleted.');
$called = \Drupal::state()->get('config_test.on_dependency_removal_called', []);
$this->assertFalse(in_array($entity_3->id(), $called), 'ConfigEntityInterface::onDependencyRemoval() is not called for entity 3.');
$this->assertSame([$entity_1->id(), $entity_4->id(), $entity_2->id()], $called, 'The most dependent entites have ConfigEntityInterface::onDependencyRemoval() called first.');
$this->assertEqual($entity_5->uuid(), $config_entities['update'][1]->uuid(), 'Entity 5 is updated.');
// Perform a module rebuild so we can know where the node module is located
// and uninstall it.
@@ -443,8 +470,11 @@ class ConfigDependencyTest extends EntityKernelTestBase {
$this->assertSame($expected, $config_entity_ids);
$called = \Drupal::state()->get('config_test.on_dependency_removal_called', []);
$this->assertFalse(in_array($entity_3->id(), $called), 'ConfigEntityInterface::onDependencyRemoval() is not called for entity 3.');
$this->assertSame([$entity_1->id(), $entity_4->id(), $entity_2->id()], $called, 'The most dependent entities have ConfigEntityInterface::onDependencyRemoval() called first.');
$this->assertArrayNotHasKey($entity_3->id(), $called, 'ConfigEntityInterface::onDependencyRemoval() is not called for entity 3.');
$this->assertSame([$entity_1->id(), $entity_4->id(), $entity_2->id()], array_keys($called), 'The most dependent entities have ConfigEntityInterface::onDependencyRemoval() called first.');
$this->assertSame(['config' => [], 'content' => [], 'module' => ['node'], 'theme' => []], $called[$entity_1->id()]);
$this->assertSame(['config' => [], 'content' => [], 'module' => ['node'], 'theme' => []], $called[$entity_2->id()]);
$this->assertSame(['config' => [], 'content' => [], 'module' => ['node'], 'theme' => []], $called[$entity_4->id()]);
// Perform a module rebuild so we can know where the node module is located
// and uninstall it.
@@ -75,7 +75,7 @@ class ConfigDiffTest extends KernelTestBase {
// Test diffing a renamed config entity.
$test_entity_id = $this->randomMachineName();
$test_entity = entity_create('config_test', [
$test_entity = \Drupal::entityTypeManager()->getStorage('config_test')->create([
'id' => $test_entity_id,
'label' => $this->randomMachineName(),
]);
@@ -24,7 +24,7 @@ class ConfigEntityNormalizeTest extends KernelTestBase {
}
public function testNormalize() {
$config_entity = entity_create('config_test', ['id' => 'system', 'label' => 'foobar', 'weight' => 1]);
$config_entity = \Drupal::entityTypeManager()->getStorage('config_test')->create(['id' => 'system', 'label' => 'foobar', 'weight' => 1]);
$config_entity->save();
// Modify stored config entity, this is comparable with a schema change.
@@ -22,7 +22,7 @@ class ConfigEntityStatusTest extends KernelTestBase {
* Tests the enabling/disabling of entities.
*/
public function testCRUD() {
$entity = entity_create('config_test', [
$entity = \Drupal::entityTypeManager()->getStorage('config_test')->create([
'id' => strtolower($this->randomMachineName()),
]);
$this->assertTrue($entity->status(), 'Default status is enabled.');
@@ -67,7 +67,7 @@ class ConfigImportRenameValidationTest extends KernelTestBase {
public function testRenameValidation() {
// Create a test entity.
$test_entity_id = $this->randomMachineName();
$test_entity = entity_create('config_test', [
$test_entity = \Drupal::entityTypeManager()->getStorage('config_test')->create([
'id' => $test_entity_id,
'label' => $this->randomMachineName(),
]);
@@ -692,7 +692,7 @@ class ConfigImporterTest extends KernelTestBase {
// does not use an install profile. This situation should be impossible
// to get in but site's can removed the install profile setting from
// settings.php so the test is valid.
$this->assertEqual(['Cannot change the install profile from <em class="placeholder">this_will_not_work</em> to <em class="placeholder"></em> once Drupal is installed.'], $error_log);
$this->assertEqual(['Cannot change the install profile from <em class="placeholder"></em> to <em class="placeholder">this_will_not_work</em> once Drupal is installed.'], $error_log);
}
}
@@ -211,7 +211,6 @@ class ConfigSchemaTest extends KernelTestBase {
$expected['mapping']['upscale']['label'] = 'Upscale';
$expected['type'] = 'image.effect.image_scale';
$this->assertEqual($definition, $expected, 'Retrieved the right metadata for image.effect.image_scale');
// Most complex case, get metadata for actual configuration element.
@@ -467,7 +467,6 @@ class SelectTest extends DatabaseTestBase {
],
];
$database = $this->container->get('database');
foreach ($test_groups as $test_group) {
$query = $database->select('test', 't');
@@ -626,7 +626,8 @@ class ConfigEntityQueryTest extends KernelTestBase {
$key_value = $this->container->get('keyvalue')->get(QueryFactory::CONFIG_LOOKUP_PREFIX . 'config_test');
$test_entities = [];
$entity = entity_create('config_test', [
$storage = \Drupal::entityTypeManager()->getStorage('config_test');
$entity = $storage->create([
'label' => $this->randomMachineName(),
'id' => '1',
'style' => 'test',
@@ -635,11 +636,10 @@ class ConfigEntityQueryTest extends KernelTestBase {
$entity->enforceIsNew();
$entity->save();
$expected[] = $entity->getConfigDependencyName();
$this->assertEqual($expected, $key_value->get('style:test'));
$entity = entity_create('config_test', [
$entity = $storage->create([
'label' => $this->randomMachineName(),
'id' => '2',
'style' => 'test',
@@ -650,7 +650,7 @@ class ConfigEntityQueryTest extends KernelTestBase {
$expected[] = $entity->getConfigDependencyName();
$this->assertEqual($expected, $key_value->get('style:test'));
$entity = entity_create('config_test', [
$entity = $storage->create([
'label' => $this->randomMachineName(),
'id' => '3',
'style' => 'blah',
@@ -131,7 +131,6 @@ class ContentEntityCloneTest extends EntityKernelTestBase {
}
$this->assertTrue($different_references, 'The entity object and the cloned entity object reference different field item list objects.');
// Reload the entity, initialize one translation, clone it and check that
// both entity objects reference different field instances.
$entity = $this->reloadEntity($entity);
@@ -63,7 +63,6 @@ class EntityDisplayFormBaseTest extends KernelTestBase {
])
->shouldBeCalled();
// An initially visible field, with a submitted region change.
$entity->getComponent('field_start_visible_change_region')
->willReturn([
@@ -739,13 +739,135 @@ class EntityFieldTest extends EntityKernelTestBase {
}
/**
* Test computed fields.
* Tests all the interaction points of a computed field.
*/
public function testComputedFields() {
$this->installEntitySchema('entity_test_computed_field');
\Drupal::state()->set('entity_test_computed_field_item_list_value', ['foo computed']);
// Check that the values are not computed unnecessarily during the lifecycle
// of an entity when the field is not interacted with directly.
\Drupal::state()->set('computed_test_field_execution', 0);
$entity = EntityTestComputedField::create([]);
$this->assertEquals($entity->computed_string_field->value, 'foo computed');
$this->assertSame(0, \Drupal::state()->get('computed_test_field_execution', 0));
$entity->name->value = $this->randomString();
$this->assertSame(0, \Drupal::state()->get('computed_test_field_execution', 0));
$entity->save();
$this->assertSame(0, \Drupal::state()->get('computed_test_field_execution', 0));
// Test \Drupal\Core\TypedData\ComputedItemListTrait::getValue().
\Drupal::state()->set('computed_test_field_execution', 0);
$entity = EntityTestComputedField::create([]);
$this->assertSame([['value' => 'foo computed']], $entity->computed_string_field->getValue());
// Check that the values are only computed once.
$this->assertSame(1, \Drupal::state()->get('computed_test_field_execution', 0));
// Test \Drupal\Core\TypedData\ComputedItemListTrait::setValue(). This also
// checks that a subsequent getter does not try to re-compute the value.
\Drupal::state()->set('computed_test_field_execution', 0);
$entity = EntityTestComputedField::create([]);
$entity->computed_string_field->setValue([
['value' => 'foo computed 1'],
['value' => 'foo computed 2'],
]);
$this->assertSame([['value' => 'foo computed 1'], ['value' => 'foo computed 2']], $entity->computed_string_field->getValue());
// Check that the values have not been computed when they were explicitly
// set.
$this->assertSame(0, \Drupal::state()->get('computed_test_field_execution', 0));
// Test \Drupal\Core\TypedData\ComputedItemListTrait::getString().
$entity = EntityTestComputedField::create([]);
$this->assertSame('foo computed', $entity->computed_string_field->getString());
// Test \Drupal\Core\TypedData\ComputedItemListTrait::get().
$entity = EntityTestComputedField::create([]);
$this->assertSame('foo computed', $entity->computed_string_field->get(0)->value);
$this->assertEmpty($entity->computed_string_field->get(1));
// Test \Drupal\Core\TypedData\ComputedItemListTrait::set().
$entity = EntityTestComputedField::create([]);
$entity->computed_string_field->set(1, 'foo computed 1');
$this->assertSame('foo computed', $entity->computed_string_field[0]->value);
$this->assertSame('foo computed 1', $entity->computed_string_field[1]->value);
$entity->computed_string_field->set(0, 'foo computed 0');
$this->assertSame('foo computed 0', $entity->computed_string_field[0]->value);
$this->assertSame('foo computed 1', $entity->computed_string_field[1]->value);
// Test \Drupal\Core\TypedData\ComputedItemListTrait::appendItem().
$entity = EntityTestComputedField::create([]);
$entity->computed_string_field->appendItem('foo computed 1');
$this->assertSame('foo computed', $entity->computed_string_field[0]->value);
$this->assertSame('foo computed 1', $entity->computed_string_field[1]->value);
// Test \Drupal\Core\TypedData\ComputedItemListTrait::removeItem().
$entity = EntityTestComputedField::create([]);
$entity->computed_string_field->removeItem(0);
$this->assertTrue($entity->computed_string_field->isEmpty());
// Test \Drupal\Core\TypedData\ComputedItemListTrait::isEmpty().
\Drupal::state()->set('entity_test_computed_field_item_list_value', []);
$entity = EntityTestComputedField::create([]);
$this->assertTrue($entity->computed_string_field->isEmpty());
\Drupal::state()->set('entity_test_computed_field_item_list_value', ['foo computed']);
$entity = EntityTestComputedField::create([]);
$this->assertFalse($entity->computed_string_field->isEmpty());
// Test \Drupal\Core\TypedData\ComputedItemListTrait::filter().
$filter_callback = function ($item) {
return !$item->isEmpty();
};
$entity = EntityTestComputedField::create([]);
$entity->computed_string_field->filter($filter_callback);
$this->assertCount(1, $entity->computed_string_field);
// Add an empty item to the list and check that it is filtered out.
$entity->computed_string_field->appendItem();
$entity->computed_string_field->filter($filter_callback);
$this->assertCount(1, $entity->computed_string_field);
// Add a non-empty item to the list and check that it is not filtered out.
$entity->computed_string_field->appendItem('foo computed 1');
$entity->computed_string_field->filter($filter_callback);
$this->assertCount(2, $entity->computed_string_field);
// Test \Drupal\Core\TypedData\ComputedItemListTrait::offsetExists().
$entity = EntityTestComputedField::create([]);
$this->assertTrue($entity->computed_string_field->offsetExists(0));
$this->assertFalse($entity->computed_string_field->offsetExists(1));
// Test \Drupal\Core\TypedData\ComputedItemListTrait::getIterator().
$entity = EntityTestComputedField::create([]);
foreach ($entity->computed_string_field as $delta => $item) {
$this->assertSame('foo computed', $item->value);
}
// Test \Drupal\Core\TypedData\ComputedItemListTrait::count().
$entity = EntityTestComputedField::create([]);
$this->assertCount(1, $entity->computed_string_field);
// Check that computed items are not auto-created when they have no values.
\Drupal::state()->set('entity_test_computed_field_item_list_value', []);
$entity = EntityTestComputedField::create([]);
$this->assertCount(0, $entity->computed_string_field);
// Test \Drupal\Core\Field\FieldItemList::equals() for a computed field.
\Drupal::state()->set('entity_test_computed_field_item_list_value', ['foo computed']);
$entity = EntityTestComputedField::create([]);
$computed_item_list1 = $entity->computed_string_field;
$entity = EntityTestComputedField::create([]);
$computed_item_list2 = $entity->computed_string_field;
$this->assertTrue($computed_item_list1->equals($computed_item_list2));
$computed_item_list2->value = 'foo computed 2';
$this->assertFalse($computed_item_list1->equals($computed_item_list2));
}
/**
@@ -819,7 +819,6 @@ class EntityQueryTest extends EntityKernelTestBase {
)->execute();
$this->assertIdentical(count($result), 1, 'Case sensitive, exact match.');
// Check the case insensitive field, ENDS_WITH operator.
$result = \Drupal::entityQuery('entity_test_mulrev')->condition(
'field_ci', $fixtures[1]['lowercase'], 'ENDS_WITH'
@@ -842,7 +841,6 @@ class EntityQueryTest extends EntityKernelTestBase {
)->execute();
$this->assertIdentical(count($result), 0, 'Case sensitive, exact match.');
// Check the case insensitive field, CONTAINS operator, use the inner 8
// characters of the uppercase and lowercase strings.
$result = \Drupal::entityQuery('entity_test_mulrev')->condition(
@@ -3,6 +3,7 @@
namespace Drupal\KernelTests\Core\Entity;
use Drupal\Core\Entity\Plugin\Validation\Constraint\CompositeConstraintBase;
use Drupal\language\Entity\ConfigurableLanguage;
/**
* Tests the Entity Validation API.
@@ -16,7 +17,7 @@ class EntityValidationTest extends EntityKernelTestBase {
*
* @var array
*/
public static $modules = ['filter', 'text'];
public static $modules = ['filter', 'text', 'language'];
/**
* @var string
@@ -39,6 +40,10 @@ class EntityValidationTest extends EntityKernelTestBase {
protected function setUp() {
parent::setUp();
// Enable an additional language.
ConfigurableLanguage::createFromLangcode('de')
->save();
// Create the test field.
module_load_install('entity_test');
entity_test_install();
@@ -196,8 +201,53 @@ class EntityValidationTest extends EntityKernelTestBase {
$this->assertTrue($constraint instanceof CompositeConstraintBase, 'Constraint is composite constraint.');
$this->assertEqual('type', $violations[0]->getPropertyPath());
/** @var CompositeConstraintBase $constraint */
/** @var \Drupal\Core\Entity\Plugin\Validation\Constraint\CompositeConstraintBase $constraint */
$this->assertEqual($constraint->coversFields(), ['name', 'type'], 'Information about covered fields can be retrieved.');
}
/**
* Tests the EntityChangedConstraintValidator with multiple translations.
*/
public function testEntityChangedConstraintOnConcurrentMultilingualEditing() {
$this->installEntitySchema('entity_test_mulrev_changed');
$storage = \Drupal::entityTypeManager()
->getStorage('entity_test_mulrev_changed');
// Create a test entity.
$entity = $this->createTestEntity('entity_test_mulrev_changed');
$entity->save();
$entity->setChangedTime($entity->getChangedTime() - 1);
$violations = $entity->validate();
$this->assertEquals(1, $violations->count());
$this->assertEqual($violations[0]->getMessage(), 'The content has either been modified by another user, or you have already submitted modifications. As a result, your changes cannot be saved.');
$entity = $storage->loadUnchanged($entity->id());
$translation = $entity->addTranslation('de');
$entity->save();
// Ensure that the new translation has a newer changed timestamp than the
// default translation.
$this->assertGreaterThan($entity->getChangedTime(), $translation->getChangedTime());
// Simulate concurrent form editing by saving the entity with an altered
// non-translatable field in order for the changed timestamp to be updated
// across all entity translations.
$original_entity_time = $entity->getChangedTime();
$entity->set('not_translatable', $this->randomString());
$entity->save();
// Simulate form submission of an uncached form by setting the previous
// timestamp of an entity translation on the saved entity object. This
// happens in the entity form API where we put the changed timestamp of
// the entity in a form hidden value and then set it on the entity which on
// form submit is loaded from the storage if the form is not yet cached.
$entity->setChangedTime($original_entity_time);
// Setting the changed timestamp from the user input on the entity loaded
// from the storage is used as a prevention from saving a form built with a
// previous version of the entity and thus reverting changes by other users.
$violations = $entity->validate();
$this->assertEquals(1, $violations->count());
$this->assertEqual($violations[0]->getMessage(), 'The content has either been modified by another user, or you have already submitted modifications. As a result, your changes cannot be saved.');
}
}
@@ -60,4 +60,29 @@ class ModuleInstallerTest extends KernelTestBase {
$this->assertEquals(1, $modules['module_handler_test_multiple_child'], 'Weight of module_handler_test_multiple_child is set.');
}
/**
* Tests cache bins defined by modules are removed when uninstalled.
*
* @covers ::removeCacheBins
*/
public function testCacheBinCleanup() {
$schema = $this->container->get('database')->schema();
$table = 'cache_module_cachebin';
$module_installer = $this->container->get('module_installer');
$module_installer->install(['module_cachebin']);
// Prime the bin.
/** @var \Drupal\Core\Cache\CacheBackendInterface $cache_bin */
$cache_bin = $this->container->get('module_cachebin.cache_bin');
$cache_bin->set('foo', 'bar');
// A database backend is used so there is a convenient way check whether the
// backend is uninstalled.
$this->assertTrue($schema->tableExists($table));
$module_installer->uninstall(['module_cachebin']);
$this->assertFalse($schema->tableExists($table));
}
}
@@ -21,7 +21,7 @@ class UrlRewritingTest extends FileTestBase {
/**
* Tests the rewriting of shipped file URLs by hook_file_url_alter().
*/
public function testShippedFileURL() {
public function testShippedFileURL() {
// Test generating a URL to a shipped file (i.e. a file that is part of
// Drupal core, a module or a theme, for example a JavaScript file).
@@ -214,7 +214,9 @@ class ToolkitGdTest extends KernelTestBase {
];
// Systems using non-bundled GD2 don't have imagerotate. Test if available.
if (function_exists('imagerotate')) {
// @todo Remove the version check once
// https://www.drupal.org/project/drupal/issues/2670966 is resolved.
if (function_exists('imagerotate') && (version_compare(phpversion(), '7.0.26') < 0)) {
$operations += [
'rotate_5' => [
'function' => 'rotate',
@@ -383,7 +385,7 @@ class ToolkitGdTest extends KernelTestBase {
$image = $this->imageFactory->get();
$image->createNew(50, 20, image_type_to_extension($type, FALSE), '#ffff00');
$file = 'from_null' . image_type_to_extension($type);
$file_path = $directory . '/' . $file ;
$file_path = $directory . '/' . $file;
$this->assertEqual(50, $image->getWidth(), SafeMarkup::format('Image file %file has the correct width.', ['%file' => $file]));
$this->assertEqual(20, $image->getHeight(), SafeMarkup::format('Image file %file has the correct height.', ['%file' => $file]));
$this->assertEqual(image_type_to_mime_type($type), $image->getMimeType(), SafeMarkup::format('Image file %file has the correct MIME type.', ['%file' => $file]));
@@ -463,7 +465,7 @@ class ToolkitGdTest extends KernelTestBase {
// Color at top-right pixel should be fully transparent while in memory,
// fully opaque after flushing image to file.
$file = 'image-test-no-transparent-color-set.gif';
$file_path = $directory . '/' . $file ;
$file_path = $directory . '/' . $file;
// Create image.
$image = $this->imageFactory->get();
$image->createNew(50, 20, 'gif', NULL);
@@ -54,7 +54,6 @@ class GarbageCollectionTest extends KernelTestBase {
->execute();
}
// Perform a new set operation and then trigger garbage collection.
$store->setWithExpire('autumn', 'winter', rand(500, 1000000));
system_cron();
@@ -62,9 +62,9 @@ class MenuLinkTreeTest extends KernelTestBase {
\Drupal::entityManager()->getStorage('menu')->create(['id' => 'menu1'])->save();
\Drupal::entityManager()->getStorage('menu')->create(['id' => 'menu2'])->save();
\Drupal::entityManager()->getStorage('menu_link_content')->create(['link' => ['uri' => 'internal:/menu_name_test'], 'menu_name' => 'menu1', 'bundle' => 'menu_link_content'])->save();
\Drupal::entityManager()->getStorage('menu_link_content')->create(['link' => ['uri' => 'internal:/menu_name_test'], 'menu_name' => 'menu1', 'bundle' => 'menu_link_content'])->save();
\Drupal::entityManager()->getStorage('menu_link_content')->create(['link' => ['uri' => 'internal:/menu_name_test'], 'menu_name' => 'menu2', 'bundle' => 'menu_link_content'])->save();
\Drupal::entityManager()->getStorage('menu_link_content')->create(['link' => ['uri' => 'internal:/menu_name_test'], 'menu_name' => 'menu1', 'bundle' => 'menu_link_content', 'title' => 'Link test'])->save();
\Drupal::entityManager()->getStorage('menu_link_content')->create(['link' => ['uri' => 'internal:/menu_name_test'], 'menu_name' => 'menu1', 'bundle' => 'menu_link_content', 'title' => 'Link test'])->save();
\Drupal::entityManager()->getStorage('menu_link_content')->create(['link' => ['uri' => 'internal:/menu_name_test'], 'menu_name' => 'menu2', 'bundle' => 'menu_link_content', 'title' => 'Link test'])->save();
$output = $this->linkTree->load('menu1', new MenuTreeParameters());
$this->assertEqual(count($output), 2);
@@ -16,7 +16,7 @@ class RenderTest extends KernelTestBase {
*
* @var array
*/
public static $modules = ['system', 'common_test'];
public static $modules = ['system', 'common_test', 'theme_test'];
/**
* Tests theme preprocess functions being able to attach assets.
@@ -43,6 +43,23 @@ class RenderTest extends KernelTestBase {
\Drupal::state()->set('theme_preprocess_attached_test', FALSE);
}
/**
* Ensures that render array children are processed correctly.
*/
public function testRenderChildren() {
// Ensure that #prefix and #suffix is only being printed once since that is
// the behaviour the caller code expects.
$build = [
'#type' => 'container',
'#theme' => 'theme_test_render_element_children',
'#prefix' => 'kangaroo',
'#suffix' => 'kitten',
];
$this->render($build);
$this->removeWhiteSpace();
$this->assertNoRaw('<div>kangarookitten</div>');
}
/**
* Tests that we get an exception when we try to attach an illegal type.
*/
@@ -23,7 +23,7 @@ class MatcherDumperTest extends KernelTestBase {
/**
* A collection of shared fixture data for tests.
*
* @var RoutingFixtures
* @var \Drupal\Tests\Core\Routing\RoutingFixtures
*/
protected $fixtures;
@@ -41,7 +41,7 @@ class RouteProviderTest extends KernelTestBase {
/**
* A collection of shared fixture data for tests.
*
* @var RoutingFixtures
* @var \Drupal\Tests\Core\Routing\RoutingFixtures
*/
protected $fixtures;
@@ -532,7 +532,6 @@ class RouteProviderTest extends KernelTestBase {
$request = Request::create($path, 'GET');
$routes = $provider->getRoutesByPattern($path);
$this->assertFalse(count($routes), 'No path found with this pattern.');
@@ -164,11 +164,11 @@ class RegistryTest extends KernelTestBase {
*/
public function testThemeSuggestions() {
// Mock the current page as the front page.
/** @var PathMatcherInterface $path_matcher */
/** @var \Drupal\Core\Path\PathMatcherInterface $path_matcher */
$path_matcher = $this->prophesize(PathMatcherInterface::class);
$path_matcher->isFrontPage()->willReturn(TRUE);
$this->container->set('path.matcher', $path_matcher->reveal());
/** @var CurrentPathStack $path_matcher */
/** @var \Drupal\Core\Path\CurrentPathStack $path_matcher */
$path_current = $this->prophesize(CurrentPathStack::class);
$path_current->getPath()->willReturn('/node/1');
$this->container->set('path.current', $path_current->reveal());
@@ -20,6 +20,7 @@ use Drupal\Core\Test\TestDatabase;
use Drupal\simpletest\AssertContentTrait;
use Drupal\Tests\AssertHelperTrait;
use Drupal\Tests\ConfigTestTrait;
use Drupal\Tests\PhpunitCompatibilityTrait;
use Drupal\Tests\RandomGeneratorTrait;
use Drupal\Tests\TestRequirementsTrait;
use Drupal\simpletest\TestServiceProvider;
@@ -76,6 +77,7 @@ abstract class KernelTestBase extends TestCase implements ServiceProviderInterfa
use RandomGeneratorTrait;
use ConfigTestTrait;
use TestRequirementsTrait;
use PhpunitCompatibilityTrait;
/**
* {@inheritdoc}
@@ -324,10 +326,10 @@ abstract class KernelTestBase extends TestCase implements ServiceProviderInterfa
private function bootKernel() {
$this->setSetting('container_yamls', []);
// Allow for test-specific overrides.
$settings_services_file = $this->root . '/sites/default' . '/testing.services.yml';
$settings_services_file = $this->root . '/sites/default/testing.services.yml';
if (file_exists($settings_services_file)) {
// Copy the testing-specific service overrides in place.
$testing_services_file = $this->root . '/' . $this->siteDirectory . '/services.yml';
$testing_services_file = $this->siteDirectory . '/services.yml';
copy($settings_services_file, $testing_services_file);
$this->setSetting('container_yamls', [$testing_services_file]);
}
@@ -827,7 +829,7 @@ abstract class KernelTestBase extends TestCase implements ServiceProviderInterfa
foreach ($modules as $module) {
if ($module_handler->moduleExists($module)) {
throw new \LogicException("$module module is already enabled.");
continue;
}
$module_handler->addModule($module, $module_list[$module]->getPath());
// Maintain the list of enabled modules in configuration.
+30 -11
View File
@@ -35,6 +35,10 @@ use Symfony\Component\CssSelector\CssSelectorConverter;
* Drupal\Tests\yourmodule\Functional namespace and live in the
* modules/yourmodule/tests/src/Functional directory.
*
* Tests extending this base class should only translate text when testing
* translation functionality. For example, avoid wrapping test text with t()
* or TranslatableMarkup().
*
* @ingroup testing
*/
abstract class BrowserTestBase extends TestCase {
@@ -62,6 +66,7 @@ abstract class BrowserTestBase extends TestCase {
createUser as drupalCreateUser;
}
use XdebugRequestTrait;
use PhpunitCompatibilityTrait;
/**
* The database prefix of this test run.
@@ -342,7 +347,7 @@ abstract class BrowserTestBase extends TestCase {
protected function getDefaultDriverInstance() {
// Get default driver params from environment if availables.
if ($arg_json = getenv('MINK_DRIVER_ARGS')) {
$this->minkDefaultDriverArgs = json_decode($arg_json);
$this->minkDefaultDriverArgs = json_decode($arg_json, TRUE);
}
// Get and check default driver class from environment if availables.
@@ -446,6 +451,15 @@ abstract class BrowserTestBase extends TestCase {
* {@inheritdoc}
*/
protected function setUp() {
// Installing Drupal creates 1000s of objects. Garbage collection of these
// objects is expensive. This appears to be causing random segmentation
// faults in PHP 5.x due to https://bugs.php.net/bug.php?id=72286. Once
// Drupal is installed is rebuilt, garbage collection is re-enabled.
$disable_gc = version_compare(PHP_VERSION, '7', '<') && gc_enabled();
if ($disable_gc) {
gc_collect_cycles();
gc_disable();
}
parent::setUp();
$this->setupBaseUrl();
@@ -466,6 +480,11 @@ abstract class BrowserTestBase extends TestCase {
// Set up the browser test output file.
$this->initBrowserOutputFile();
// If garbage collection was disabled prior to rebuilding container,
// re-enable it.
if ($disable_gc) {
gc_enable();
}
}
/**
@@ -777,10 +796,10 @@ abstract class BrowserTestBase extends TestCase {
* be unchecked.
* @param string $submit
* Value of the submit button whose click is to be emulated. For example,
* t('Save'). The processing of the request depends on this value. For
* example, a form may have one button with the value t('Save') and another
* button with the value t('Delete'), and execute different code depending
* on which one is clicked.
* 'Save'. The processing of the request depends on this value. For example,
* a form may have one button with the value 'Save' and another button with
* the value 'Delete', and execute different code depending on which one is
* clicked.
* @param string $form_html_id
* (optional) HTML ID of the form to be submitted. On some pages
* there are many identical forms, so just using the value of the submit
@@ -859,11 +878,11 @@ abstract class BrowserTestBase extends TestCase {
* @code
* // First step in form.
* $edit = array(...);
* $this->drupalPostForm('some_url', $edit, t('Save'));
* $this->drupalPostForm('some_url', $edit, 'Save');
*
* // Second step in form.
* $edit = array(...);
* $this->drupalPostForm(NULL, $edit, t('Save'));
* $this->drupalPostForm(NULL, $edit, 'Save');
* @endcode
* @param array $edit
* Field data in an associative array. Changes the current input fields
@@ -893,10 +912,10 @@ abstract class BrowserTestBase extends TestCase {
* https://www.drupal.org/node/2802401
* @param string $submit
* Value of the submit button whose click is to be emulated. For example,
* t('Save'). The processing of the request depends on this value. For
* example, a form may have one button with the value t('Save') and another
* button with the value t('Delete'), and execute different code depending
* on which one is clicked.
* 'Save'. The processing of the request depends on this value. For example,
* a form may have one button with the value 'Save' and another button with
* the value 'Delete', and execute different code depending on which one is
* clicked.
*
* This function can also be called to emulate an Ajax submission. In this
* case, this value needs to be an array with the following keys:
@@ -167,7 +167,7 @@ class DateTimePlusTest extends TestCase {
* Assertion helper for testTimestamp and testDateTimestamp since they need
* different dataProviders.
*
* @param DateTimePlus $date
* @param \Drupal\Component\Datetime\DateTimePlus $date
* DateTimePlus to test.
* @input mixed $input
* The original input passed to the test method.
@@ -1043,7 +1043,7 @@ class MockInstantiationService {
class MockService {
/**
* @var ContainerInterface
* @var \Symfony\Component\DependencyInjection\ContainerInterface
*/
protected $container;
@@ -1081,7 +1081,7 @@ class MockService {
/**
* Sets the container object.
*
* @param ContainerInterface $container
* @param \Symfony\Component\DependencyInjection\ContainerInterface $container
* The container to inject via setter injection.
*/
public function setContainer(ContainerInterface $container) {
@@ -1091,7 +1091,7 @@ class MockService {
/**
* Gets the container object.
*
* @return ContainerInterface
* @return \Symfony\Component\DependencyInjection\ContainerInterface
* The internally set container.
*/
public function getContainer() {
@@ -125,7 +125,6 @@ class FileCacheFactoryTest extends TestCase {
$class,
];
// Test default configuration plus specific per collection setting.
$data['default-plus-collection-setting'] = [
[
@@ -4,6 +4,8 @@ namespace Drupal\Tests\Component\PhpStorage;
use Drupal\Component\PhpStorage\FileStorage;
use Drupal\Component\Utility\Random;
use org\bovigo\vfs\vfsStreamDirectory;
use PHPUnit_Framework_Error_Warning;
/**
* @coversDefaultClass \Drupal\Component\PhpStorage\FileStorage
@@ -87,4 +89,18 @@ class FileStorageTest extends PhpStorageTestBase {
unset($GLOBALS[$random]);
}
/**
* @covers ::createDirectory
*/
public function testCreateDirectoryFailWarning() {
$directory = new vfsStreamDirectory('permissionDenied', 0200);
$storage = new FileStorage([
'directory' => $directory->url(),
'bin' => 'test',
]);
$code = "<?php\n echo 'here';";
$this->setExpectedException(PHPUnit_Framework_Error_Warning::class, 'mkdir(): Permission Denied');
$storage->save('subdirectory/foo.php', $code);
}
}
@@ -67,9 +67,10 @@ class HtmlTest extends TestCase {
[$id1, $id1, []],
// Verify that valid UTF-8 characters are not stripped from the identifier.
[$id2, $id2, []],
// Verify that invalid characters (including non-breaking space) are stripped from the identifier.
[$id3, $id3],
// Verify that double underscores are not stripped from the identifier.
[$id3, $id3],
// Verify that invalid characters (including non-breaking space) are
// stripped from the identifier.
['invalididentifier', 'invalid !"#$%&\'()*+,./:;<=>?@[\\]^`{|}~ identifier', []],
// Verify that an identifier starting with a digit is replaced.
['_cssidentifier', '1cssidentifier', []],
@@ -617,7 +617,6 @@ class AccessResultTest extends UnitTestCase {
[$allowed_un, 'OR', $neutral_cf, FALSE, NULL],
[$allowed_un, 'OR', $neutral_un, FALSE, NULL],
// Forbidden (ct) OR allowed (ct,cf,un).
[$forbidden_ct, 'OR', $allowed_ct, TRUE, TRUE],
[$forbidden_ct, 'OR', $allowed_cf, TRUE, TRUE],
@@ -657,7 +656,6 @@ class AccessResultTest extends UnitTestCase {
[$forbidden_un, 'OR', $forbidden_cf, FALSE, NULL],
[$forbidden_un, 'OR', $forbidden_un, FALSE, NULL],
// Neutral (ct) OR allowed (ct,cf,un).
[$neutral_ct, 'OR', $allowed_ct, TRUE, TRUE],
[$neutral_ct, 'OR', $allowed_cf, TRUE, FALSE],
@@ -697,7 +695,6 @@ class AccessResultTest extends UnitTestCase {
[$neutral_un, 'OR', $forbidden_cf, FALSE, NULL],
[$neutral_un, 'OR', $forbidden_un, FALSE, NULL],
// Allowed (ct) AND allowed (ct,cf,un).
[$allowed_ct, 'AND', $allowed_ct, TRUE, TRUE],
[$allowed_ct, 'AND', $allowed_cf, TRUE, FALSE],
@@ -737,7 +734,6 @@ class AccessResultTest extends UnitTestCase {
[$allowed_un, 'AND', $neutral_cf, FALSE, NULL],
[$allowed_un, 'AND', $neutral_un, FALSE, NULL],
// Forbidden (ct) AND allowed (ct,cf,un).
[$forbidden_ct, 'AND', $allowed_ct, TRUE, TRUE],
[$forbidden_ct, 'AND', $allowed_cf, TRUE, TRUE],
@@ -777,7 +773,6 @@ class AccessResultTest extends UnitTestCase {
[$forbidden_un, 'AND', $forbidden_cf, FALSE, NULL],
[$forbidden_un, 'AND', $forbidden_un, FALSE, NULL],
// Neutral (ct) AND allowed (ct,cf,un).
[$neutral_ct, 'AND', $allowed_ct, TRUE, TRUE],
[$neutral_ct, 'AND', $allowed_cf, TRUE, TRUE],
@@ -25,6 +25,7 @@ use Drupal\Core\Ajax\SetDialogOptionCommand;
use Drupal\Core\Ajax\SetDialogTitleCommand;
use Drupal\Core\Ajax\RedirectCommand;
use Drupal\Core\Ajax\UpdateBuildIdCommand;
use Drupal\Core\Ajax\OpenDialogCommand;
/**
* Test coverage for various classes in the \Drupal\Core\Ajax namespace.
@@ -293,27 +294,16 @@ class AjaxCommandsTest extends UnitTestCase {
* @covers \Drupal\Core\Ajax\OpenDialogCommand
*/
public function testOpenDialogCommand() {
$command = $this->getMockBuilder('Drupal\Core\Ajax\OpenDialogCommand')
->setConstructorArgs([
'#some-dialog', 'Title', '<p>Text!</p>', [
'url' => FALSE,
'width' => 500,
],
])
->setMethods(['getRenderedContent'])
->getMock();
// This method calls the render service, which isn't available. We want it
// to do nothing so we mock it to return a known value.
$command->expects($this->once())
->method('getRenderedContent')
->willReturn('rendered content');
$command = new OpenDialogCommand('#some-dialog', 'Title', '<p>Text!</p>', [
'url' => FALSE,
'width' => 500,
]);
$expected = [
'command' => 'openDialog',
'selector' => '#some-dialog',
'settings' => NULL,
'data' => 'rendered content',
'data' => '<p>Text!</p>',
'dialogOptions' => [
'url' => FALSE,
'width' => 500,
@@ -322,6 +312,10 @@ class AjaxCommandsTest extends UnitTestCase {
],
];
$this->assertEquals($expected, $command->render());
$command->setDialogTitle('New title');
$expected['dialogOptions']['title'] = 'New title';
$this->assertEquals($expected, $command->render());
}
/**
@@ -97,7 +97,7 @@ class BackendCompilerPassTest extends UnitTestCase {
* bag so the setParameter() call effects the parent container as well.
*
* @param $service
* @return ContainerBuilder
* @return \Symfony\Component\DependencyInjection\ContainerBuilder
*/
protected function getSqliteContainer($service) {
$container = new ContainerBuilder();
@@ -115,7 +115,7 @@ class BackendCompilerPassTest extends UnitTestCase {
* bag so the setParameter() call effects the parent container as well.
*
* @param $service
* @return ContainerBuilder
* @return \Symfony\Component\DependencyInjection\ContainerBuilder
*/
protected function getMysqlContainer($service) {
$container = new ContainerBuilder();
@@ -112,7 +112,7 @@ class EntityAccessCheckTest extends UnitTestCase {
*
* @param \stdClass $object
* Any object, including prophesized mocks based on interfaces.
* @return RouteMatchInterface
* @return \Drupal\Core\Routing\RouteMatchInterface
* A prophesized RouteMatchInterface.
*/
private function createRouteMatchForObject(\stdClass $object) {
@@ -439,7 +439,6 @@ class EntityFieldManagerTest extends UnitTestCase {
})
->shouldBeCalled();
$this->assertSame($expected, $this->entityFieldManager->getFieldStorageDefinitions('test_entity_type'));
$this->entityFieldManager->testClearEntityFieldInfo();
$this->assertSame($expected, $this->entityFieldManager->getFieldStorageDefinitions('test_entity_type'));
@@ -1,42 +0,0 @@
<?php
namespace Drupal\Tests\Core\EventSubscriber;
use Drupal\Core\EventSubscriber\DefaultExceptionSubscriber;
use Drupal\Tests\UnitTestCase;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent;
use Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException;
use Symfony\Component\HttpKernel\HttpKernelInterface;
/**
* @coversDefaultClass \Drupal\Core\EventSubscriber\DefaultExceptionSubscriber
* @group EventSubscriber
*/
class DefaultExceptionSubscriberTest extends UnitTestCase {
/**
* @covers ::onException
* @covers ::onFormatUnknown
*/
public function testOnExceptionWithUnknownFormat() {
$config_factory = $this->getConfigFactoryStub();
$kernel = $this->prophesize(HttpKernelInterface::class);
$request = Request::create('/test?_format=bananas');
$e = new MethodNotAllowedHttpException(['POST', 'PUT'], 'test message');
$event = new GetResponseForExceptionEvent($kernel->reveal(), $request, 'GET', $e);
$subscriber = new DefaultExceptionSubscriber($config_factory);
$subscriber->onException($event);
$response = $event->getResponse();
$this->assertInstanceOf(Response::class, $response);
$this->assertEquals('test message', $response->getContent());
$this->assertEquals(405, $response->getStatusCode());
$this->assertEquals('POST, PUT', $response->headers->get('Allow'));
// Also check that that text/plain content type was added.
$this->assertEquals('text/plain', $response->headers->get('Content-Type'));
}
}
@@ -67,7 +67,7 @@ class RedirectResponseSubscriberTest extends UnitTestCase {
/**
* Test destination detection and redirection.
*
* @param Request $request
* @param \Symfony\Component\HttpFoundation\Request $request
* The request object with destination query set.
* @param string|bool $expected
* The expected target URL or FALSE.
@@ -100,7 +100,6 @@ D rupal is an open source content management platform powering millions of websi
</rss>
RSS;
$data['invalid-feed'] = [$invalid_feed, $invalid_feed];
return $data;
}
@@ -8,4 +8,5 @@
/**
* Test hook.
*/
function module_handler_test_hook_include() {}
function module_handler_test_hook_include() {
}
@@ -5,8 +5,8 @@ package: Testing
# version: VERSION
# core: 8.x
# Information added by Drupal.org packaging script on 2017-11-03
version: '8.4.2'
# Information added by Drupal.org packaging script on 2018-01-03
version: '8.4.4'
core: '8.x'
project: 'drupal'
datestamp: 1509719929
datestamp: 1515021228
@@ -6,8 +6,8 @@ package: Testing
# core: 8.x
hidden: true
# Information added by Drupal.org packaging script on 2017-11-03
version: '8.4.2'
# Information added by Drupal.org packaging script on 2018-01-03
version: '8.4.4'
core: '8.x'
project: 'drupal'
datestamp: 1509719929
datestamp: 1515021228
@@ -6,8 +6,8 @@ package: Testing
# core: 8.x
hidden: true
# Information added by Drupal.org packaging script on 2017-11-03
version: '8.4.2'
# Information added by Drupal.org packaging script on 2018-01-03
version: '8.4.4'
core: '8.x'
project: 'drupal'
datestamp: 1509719929
datestamp: 1515021228
@@ -6,8 +6,8 @@ package: Testing
# core: 8.x
hidden: true
# Information added by Drupal.org packaging script on 2017-11-03
version: '8.4.2'
# Information added by Drupal.org packaging script on 2018-01-03
version: '8.4.4'
core: '8.x'
project: 'drupal'
datestamp: 1509719929
datestamp: 1515021228
@@ -5,8 +5,8 @@ package: Testing
# version: VERSION
# core: 8.x
# Information added by Drupal.org packaging script on 2017-11-03
version: '8.4.2'
# Information added by Drupal.org packaging script on 2018-01-03
version: '8.4.4'
core: '8.x'
project: 'drupal'
datestamp: 1509719929
datestamp: 1515021228
@@ -28,10 +28,24 @@ class FieldItemListTest extends UnitTestCase {
$container->set('plugin.manager.field.field_type', $field_type_manager);
\Drupal::setContainer($container);
// Set up three properties, one of them being computed.
$property_definitions['0'] = $this->getMock('Drupal\Core\TypedData\DataDefinitionInterface');
$property_definitions['0']->expects($this->any())
->method('isComputed')
->willReturn(FALSE);
$property_definitions['1'] = $this->getMock('Drupal\Core\TypedData\DataDefinitionInterface');
$property_definitions['1']->expects($this->any())
->method('isComputed')
->willReturn(FALSE);
$property_definitions['2'] = $this->getMock('Drupal\Core\TypedData\DataDefinitionInterface');
$property_definitions['2']->expects($this->any())
->method('isComputed')
->willReturn(TRUE);
$field_storage_definition = $this->getMock('Drupal\Core\Field\FieldStorageDefinitionInterface');
$field_storage_definition->expects($this->any())
->method('getColumns')
->willReturn([0 => '0', 1 => '1']);
->method('getPropertyDefinitions')
->will($this->returnValue($property_definitions));
$field_definition = $this->getMock('Drupal\Core\Field\FieldDefinitionInterface');
$field_definition->expects($this->any())
->method('getFieldStorageDefinition')
@@ -95,6 +109,30 @@ class FieldItemListTest extends UnitTestCase {
// types.
$datasets[] = [TRUE, $field_item_b, $field_item_e];
/** @var \Drupal\Core\Field\FieldItemBase $field_item_f */
$field_item_f = $this->getMockForAbstractClass('Drupal\Core\Field\FieldItemBase', [], '', FALSE);
$field_item_f->setValue(['0' => 1, '1' => 2, '2' => 3]);
/** @var \Drupal\Core\Field\FieldItemBase $field_item_g */
$field_item_g = $this->getMockForAbstractClass('Drupal\Core\Field\FieldItemBase', [], '', FALSE);
$field_item_g->setValue(['0' => 1, '1' => 2, '2' => 4]);
// Tests field item lists where both have same values for the non-computed
// properties ('0' and '1') and a different value for the computed one
// ('2').
$datasets[] = [TRUE, $field_item_f, $field_item_g];
/** @var \Drupal\Core\Field\FieldItemBase $field_item_h */
$field_item_h = $this->getMockForAbstractClass('Drupal\Core\Field\FieldItemBase', [], '', FALSE);
$field_item_h->setValue(['0' => 1, '1' => 2, '3' => 3]);
/** @var \Drupal\Core\Field\FieldItemBase $field_item_i */
$field_item_i = $this->getMockForAbstractClass('Drupal\Core\Field\FieldItemBase', [], '', FALSE);
$field_item_i->setValue(['0' => 1, '1' => 2, '3' => 4]);
// Tests field item lists where both have same values for the non-computed
// properties ('0' and '1') and a different value for a property that does
// not exist ('3').
$datasets[] = [TRUE, $field_item_h, $field_item_i];
return $datasets;
}
@@ -114,10 +152,20 @@ class FieldItemListTest extends UnitTestCase {
$container->set('plugin.manager.field.field_type', $field_type_manager);
\Drupal::setContainer($container);
// Set up the properties of the field item.
$property_definitions['0'] = $this->getMock('Drupal\Core\TypedData\DataDefinitionInterface');
$property_definitions['0']->expects($this->any())
->method('isComputed')
->willReturn(FALSE);
$property_definitions['1'] = $this->getMock('Drupal\Core\TypedData\DataDefinitionInterface');
$property_definitions['1']->expects($this->any())
->method('isComputed')
->willReturn(FALSE);
$field_storage_definition = $this->getMock('Drupal\Core\Field\FieldStorageDefinitionInterface');
$field_storage_definition->expects($this->any())
->method('getColumns')
->willReturn([0 => '0', 1 => '1']);
->method('getPropertyDefinitions')
->will($this->returnValue($property_definitions));
$field_definition = $this->getMock('Drupal\Core\Field\FieldDefinitionInterface');
$field_definition->expects($this->any())
->method('getFieldStorageDefinition')
@@ -181,7 +181,7 @@ class FormAjaxSubscriberTest extends UnitTestCase {
$this->assertSame(200, $actual_response->headers->get('X-Status-Code'));
$expected_commands[] = [
'command' => 'insert',
'method' => 'replaceWith',
'method' => 'prepend',
'selector' => NULL,
'data' => $rendered_output,
'settings' => NULL,
@@ -72,7 +72,7 @@ class ImageTest extends UnitTestCase {
*
* @param string $class_name
* The name of the GD toolkit operation class to be mocked.
* @param ImageToolkitInterface $toolkit
* @param \Drupal\Core\Image\ImageToolkitInterface $toolkit
* The image toolkit object.
*
* @return \PHPUnit_Framework_MockObject_MockObject
@@ -462,7 +462,6 @@ class LocalTaskManagerTest extends UnitTestCase {
$mock->getCacheTags()->willReturn(isset($info['cache_tags']) ? $info['cache_tags'] : []);
$mock->getCacheMaxAge()->willReturn(isset($info['cache_max_age']) ? $info['cache_max_age'] : Cache::PERMANENT);
$access_manager_map[] = [$info['route_name'], [], $this->account, TRUE, $info['access']];
$map[] = [$info['id'], [], $mock->reveal()];
@@ -133,7 +133,6 @@ class PathValidatorTest extends UnitTestCase {
->method('processInbound')
->willReturnArgument(0);
$this->assertTrue($this->pathValidator->isValid('test-path'));
}
@@ -163,7 +163,6 @@ class BubbleableMetadataTest extends UnitTestCase {
],
];
$expected_when_empty_metadata = [
'#cache' => [
'contexts' => [],
@@ -228,7 +227,6 @@ class BubbleableMetadataTest extends UnitTestCase {
],
];
$data[] = [$empty_render_array, $empty_metadata];
$data[] = [$nonempty_render_array, $nonempty_metadata];
@@ -202,6 +202,22 @@ class HtmlTagTest extends RendererTestBase {
];
$tags['linearGradient'] = [$element, '<linearGradient><stop offset="5%" stop-color="#F60" />' . "\n" . '<stop offset="95%" stop-color="#FF6" />' . "\n" . '</linearGradient>' . "\n"];
// Simple link.
$element = [
'#tag' => 'link',
];
$tags['link'] = [HtmlTag::preRenderConditionalComments($element), '<link />' . "\n"];
// Conditional link.
$element = [
'#tag' => 'link',
'#browsers' => [
'IE' => TRUE,
'!IE' => FALSE,
],
];
$tags['conditional-link'] = [HtmlTag::preRenderConditionalComments($element), "\n" . '<!--[if IE]>' . "\n" . '<link />' . "\n" . '<![endif]-->' . "\n"];
return $tags;
}
@@ -291,6 +291,42 @@ class RendererBubblingTest extends RendererTestBase {
];
$data[] = [$test_element, ['bar', 'foo'], $expected_cache_items];
// Ensure that bubbleable metadata has been collected from children and set
// correctly to the main level of the render array. That ensures that correct
// bubbleable metadata exists if render array gets rendered multiple times.
$test_element = [
'#cache' => [
'keys' => ['parent'],
'tags' => ['yar', 'har']
],
'#markup' => 'parent',
'child' => [
'#render_children' => TRUE,
'subchild' => [
'#cache' => [
'contexts' => ['foo'],
'tags' => ['fiddle', 'dee'],
],
'#attached' => [
'library' => ['foo/bar']
],
'#markup' => '',
]
],
];
$expected_cache_items = [
'parent:foo' => [
'#attached' => ['library' => ['foo/bar']],
'#cache' => [
'contexts' => ['foo'],
'tags' => ['dee', 'fiddle', 'har', 'yar'],
'max-age' => Cache::PERMANENT,
],
'#markup' => 'parent',
],
];
$data[] = [$test_element, ['foo'], $expected_cache_items];
return $data;
}
@@ -65,10 +65,8 @@ class RendererTest extends RendererTestBase {
public function providerTestRenderBasic() {
$data = [];
// Part 1: the most simplistic render arrays possible, none using #theme.
// Pass a NULL.
$data[] = [NULL, ''];
// Pass an empty string.
@@ -216,7 +214,6 @@ class RendererTest extends RendererTestBase {
// Part 2: render arrays using #theme and #theme_wrappers.
// Tests that #theme and #theme_wrappers can co-exist on an element.
$build = [
'#theme' => 'common_test_foo',
@@ -302,10 +299,8 @@ class RendererTest extends RendererTestBase {
};
$data[] = [$build, '<div class="foo"></div>' . "\n", $setup_code];
// Part 3: render arrays using #markup as a fallback for #theme hooks.
// Theme suggestion is not implemented, #markup should be rendered.
$build = [
'#theme' => ['suggestionnotimplemented'],
@@ -357,10 +352,8 @@ class RendererTest extends RendererTestBase {
];
$data[] = [$build, $theme_function_output, $setup_code];
// Part 4: handling of #children and child renderable elements.
// #theme is implemented so the values of both #children and 'child' will
// be ignored - it is the responsibility of the theme hook to render these
// if appropriate.
@@ -410,6 +403,25 @@ class RendererTest extends RendererTestBase {
};
$data[] = [$build, 'baz', $setup_code];
// #theme is implemented but #render_children is TRUE. In this case the
// calling code is expecting only the children to be rendered. #prefix and
// #suffix should not be inherited for the children.
$build = [
'#theme' => 'common_test_foo',
'#children' => '',
'#prefix' => 'kangaroo',
'#suffix' => 'unicorn',
'#render_children' => TRUE,
'child' => [
'#markup' => 'kitten',
],
];
$setup_code = function () {
$this->themeManager->expects($this->never())
->method('render');
};
$data[] = [$build, 'kitten', $setup_code];
return $data;
}
@@ -569,25 +581,81 @@ class RendererTest extends RendererTestBase {
}
/**
* Tests that a first render returns the rendered output and a second doesn't.
* Tests rendering same render array twice.
*
* (Because of the #printed property.)
* Tests that a first render returns the rendered output and a second doesn't
* because of the #printed property. Also tests that correct metadata has been
* set for re-rendering.
*
* @covers ::render
* @covers ::doRender
*
* @dataProvider providerRenderTwice
*/
public function testRenderTwice() {
$build = [
'#markup' => 'test',
];
$this->assertEquals('test', $this->renderer->renderRoot($build));
public function testRenderTwice($build) {
$this->assertEquals('kittens', $this->renderer->renderRoot($build));
$this->assertEquals('kittens', $build['#markup']);
$this->assertEquals(['kittens-147'], $build['#cache']['tags']);
$this->assertTrue($build['#printed']);
// We don't want to reprint already printed render arrays.
$this->assertEquals('', $this->renderer->renderRoot($build));
}
/**
* Provides a list of render array iterations.
*
* @return array
*/
public function providerRenderTwice() {
return [
[
[
'#markup' => 'kittens',
'#cache' => [
'tags' => ['kittens-147']
],
],
],
[
[
'child' => [
'#markup' => 'kittens',
'#cache' => [
'tags' => ['kittens-147'],
],
],
],
],
[
[
'#render_children' => TRUE,
'child' => [
'#markup' => 'kittens',
'#cache' => [
'tags' => ['kittens-147'],
],
],
],
],
];
}
/**
* Ensures that #access is taken in account when rendering #render_children.
*/
public function testRenderChildrenAccess() {
$build = [
'#access' => FALSE,
'#render_children' => TRUE,
'child' => [
'#markup' => 'kittens',
],
];
$this->assertEquals('', $this->renderer->renderRoot($build));
}
/**
* Provides a list of both booleans.
*
@@ -16,7 +16,7 @@ abstract class RouteMatchTestBase extends UnitTestCase {
*
* @param $name
* Route name.
* @param Route $route
* @param \Symfony\Component\Routing\Route $route
* Request object
* @param array $parameters
* Parameters array
@@ -211,7 +211,6 @@ class UrlGeneratorTest extends UnitTestCase {
->method('processOutbound')
->with($this->anything());
// Check that the two generate methods return the same result.
$this->assertGenerateFromRoute('test_1', [], [], $url, (new BubbleableMetadata())->setCacheMaxAge(Cache::PERMANENT));
@@ -232,7 +231,6 @@ class UrlGeneratorTest extends UnitTestCase {
->method('processOutbound')
->with($this->anything());
// Check that the two generate methods return the same result.
$this->assertGenerateFromRoute('test_1', [], [], $url, (new BubbleableMetadata())->setCacheMaxAge(Cache::PERMANENT));
@@ -28,7 +28,7 @@ class SettingsTest extends UnitTestCase {
/**
* @covers ::__construct
*/
protected function setUp(){
protected function setUp() {
$this->config = [
'one' => '1',
'two' => '2',
@@ -0,0 +1,142 @@
<?php
namespace Drupal\Tests;
/**
* Makes Drupal's test API forward compatible with multiple versions of PHPUnit.
*/
trait PhpunitCompatibilityTrait {
/**
* Returns a mock object for the specified class using the available method.
*
* The getMock method does not exist in PHPUnit 6. To provide backward
* compatibility this trait provides the getMock method and uses createMock if
* this method is available on the parent class.
*
* @param string $originalClassName
* Name of the class to mock.
* @param array|null $methods
* When provided, only methods whose names are in the array are replaced
* with a configurable test double. The behavior of the other methods is not
* changed. Providing null means that no methods will be replaced.
* @param array $arguments
* Parameters to pass to the original class' constructor.
* @param string $mockClassName
* Class name for the generated test double class.
* @param bool $callOriginalConstructor
* Can be used to disable the call to the original class' constructor.
* @param bool $callOriginalClone
* Can be used to disable the call to the original class' clone constructor.
* @param bool $callAutoload
* Can be used to disable __autoload() during the generation of the test
* double class.
* @param bool $cloneArguments
* Enables the cloning of arguments passed to mocked methods.
* @param bool $callOriginalMethods
* Enables the invocation of the original methods.
* @param object $proxyTarget
* Sets the proxy target.
*
* @see \PHPUnit_Framework_TestCase::getMock
* @see https://github.com/sebastianbergmann/phpunit/wiki/Release-Announcement-for-PHPUnit-5.4.0
*
* @return \PHPUnit_Framework_MockObject_MockObject
*
* @deprecated in Drupal 8.5.0 and will be removed before Drupal 9.0.0.
* Use \Drupal\Tests\PhpunitCompatibilityTrait::createMock() instead.
*
* @see https://www.drupal.org/node/2907725
*/
public function getMock($originalClassName, $methods = array(), array $arguments = array(), $mockClassName = '', $callOriginalConstructor = TRUE, $callOriginalClone = TRUE, $callAutoload = TRUE, $cloneArguments = FALSE, $callOriginalMethods = FALSE, $proxyTarget = NULL) {
if (!$this->supports('getMock')) {
$mock = $this->getMockBuilder($originalClassName)
->setMethods($methods)
->setConstructorArgs($arguments)
->setMockClassName($mockClassName)
->setProxyTarget($proxyTarget);
if ($callOriginalConstructor) {
$mock->enableOriginalConstructor();
}
else {
$mock->disableOriginalConstructor();
}
if ($callOriginalClone) {
$mock->enableOriginalClone();
}
else {
$mock->disableOriginalClone();
}
if ($callAutoload) {
$mock->enableAutoload();
}
else {
$mock->disableAutoload();
}
if ($cloneArguments) {
$mock->enableArgumentCloning();
}
else {
$mock->disableArgumentCloning();
}
if ($callOriginalMethods) {
$mock->enableProxyingToOriginalMethods();
}
else {
$mock->disableProxyingToOriginalMethods();
}
return $mock->getMock();
}
else {
return parent::getMock($originalClassName, $methods, $arguments, $mockClassName, $callOriginalConstructor, $callOriginalClone, $callAutoload, $cloneArguments, $callOriginalMethods, $proxyTarget);
}
}
/**
* Returns a mock object for the specified class using the available method.
*
* The createMock method does not exist in PHPUnit 4. To provide forward
* compatibility this trait provides the createMock method and uses createMock
* if this method is available on the parent class or falls back to getMock if
* it isn't.
*
* @param string $originalClassName
* Name of the class to mock.
*
* @see \PHPUnit_Framework_TestCase::getMock
*
* @return \PHPUnit_Framework_MockObject_MockObject
*/
public function createMock($originalClassName) {
if ($this->supports('createMock')) {
return parent::createMock($originalClassName);
}
else {
return $this->getMock($originalClassName, [], [], '', FALSE, FALSE);
}
}
/**
* Checks if the trait is used in a class that has a method.
*
* @param string $method
* Method to check.
*
* @return bool
* TRUE if the method is supported, FALSE if not.
*/
private function supports($method) {
// Get the parent class of the currently running test class.
$parent = get_parent_class($this);
// Ensure that the method_exists() check on the createMock method is carried
// out on the first parent of $this that does not have access to this
// trait's methods. This is because the trait also has a method called
// createMock(). Most often the check will be made on
// \PHPUnit\Framework\TestCase.
while (method_exists($parent, 'supports')) {
$parent = get_parent_class($parent);
}
return method_exists($parent, $method);
}
}
@@ -0,0 +1,115 @@
<?php
namespace Drupal\Tests;
/**
* Tests the PHPUnit forward compatibility trait.
*
* @coversDefaultClass \Drupal\Tests\PhpunitCompatibilityTrait
* @group Tests
*/
class PhpunitCompatibilityTraitTest extends UnitTestCase {
/**
* Tests that getMock is available and calls the correct parent method.
*
* @covers ::getMock
* @dataProvider providerMockVersions
*/
public function testGetMock($className, $expected) {
$class = new $className();
$this->assertSame($expected, $class->getMock($this->randomMachineName()));
}
/**
* Tests that createMock is available and calls the correct parent method.
*
* @covers ::createMock
* @dataProvider providerMockVersions
*/
public function testCreateMock($className, $expected) {
$class = new $className();
$this->assertSame($expected, $class->createMock($this->randomMachineName()));
}
/**
* Returns the class names and the string they return.
*
* @return array
*/
public function providerMockVersions() {
return [
[UnitTestCasePhpunit4TestClass::class, 'PHPUnit 4'],
[UnitTestCasePhpunit4TestClassExtends::class, 'PHPUnit 4'],
[UnitTestCasePhpunit6TestClass::class, 'PHPUnit 6'],
[UnitTestCasePhpunit6TestClassExtends::class, 'PHPUnit 6'],
];
}
}
/**
* Test class for \PHPUnit\Framework\TestCase in PHPUnit 4.
*/
class Phpunit4TestClass {
public function getMock($originalClassName) {
return 'PHPUnit 4';
}
}
/**
* Test class for \PHPUnit\Framework\TestCase in PHPUnit 6.
*/
class Phpunit6TestClass {
public function createMock($originalClassName) {
return 'PHPUnit 6';
}
public function getMockbuilder() {
return new Mockbuilder();
}
}
/**
* Test double for PHPUnit_Framework_MockObject_MockBuilder.
*/
class Mockbuilder {
public function __call($name, $arguments) {
return $this;
}
public function getMock() {
return 'PHPUnit 6';
}
}
/**
* Test class for \Drupal\Tests\UnitTestCase with PHPUnit 4.
*/
class UnitTestCasePhpunit4TestClass extends Phpunit4TestClass {
use PhpunitCompatibilityTrait;
}
/**
* Test class for \Drupal\Tests\UnitTestCase with PHPUnit 4.
*/
class UnitTestCasePhpunit4TestClassExtends extends UnitTestCasePhpunit4TestClass {
}
/**
* Test class for \Drupal\Tests\UnitTestCase with PHPUnit 6.
*/
class UnitTestCasePhpunit6TestClass extends Phpunit6TestClass {
use PhpunitCompatibilityTrait;
}
/**
* Test class for \Drupal\Tests\UnitTestCase with PHPUnit 6.
*/
class UnitTestCasePhpunit6TestClassExtends extends UnitTestCasePhpunit6TestClass {
}
@@ -164,7 +164,8 @@ trait TestFileCreationTrait {
}
// Create filename.
file_put_contents('public://' . $filename . '.txt', $text);
$filename = 'public://' . $filename . '.txt';
file_put_contents($filename, $text);
return $filename;
}
+7 -5
View File
@@ -17,6 +17,8 @@ use PHPUnit\Framework\TestCase;
*/
abstract class UnitTestCase extends TestCase {
use PhpunitCompatibilityTrait;
/**
* The random generator.
*
@@ -135,7 +137,7 @@ abstract class UnitTestCase extends TestCase {
}
// Construct a config factory with the array of configuration object stubs
// as its return map.
$config_factory = $this->getMock('Drupal\Core\Config\ConfigFactoryInterface');
$config_factory = $this->createMock('Drupal\Core\Config\ConfigFactoryInterface');
$config_factory->expects($this->any())
->method('get')
->will($this->returnValueMap($config_get_map));
@@ -157,7 +159,7 @@ abstract class UnitTestCase extends TestCase {
* A mocked config storage.
*/
public function getConfigStorageStub(array $configs) {
$config_storage = $this->getMock('Drupal\Core\Config\NullStorage');
$config_storage = $this->createMock('Drupal\Core\Config\NullStorage');
$config_storage->expects($this->any())
->method('listAll')
->will($this->returnValue(array_keys($configs)));
@@ -204,7 +206,7 @@ abstract class UnitTestCase extends TestCase {
* A mock translation object.
*/
public function getStringTranslationStub() {
$translation = $this->getMock('Drupal\Core\StringTranslation\TranslationInterface');
$translation = $this->createMock('Drupal\Core\StringTranslation\TranslationInterface');
$translation->expects($this->any())
->method('translate')
->willReturnCallback(function ($string, array $args = [], array $options = []) use ($translation) {
@@ -234,7 +236,7 @@ abstract class UnitTestCase extends TestCase {
* The container with the cache tags invalidator service.
*/
protected function getContainerWithCacheTagsInvalidator(CacheTagsInvalidatorInterface $cache_tags_validator) {
$container = $this->getMock('Symfony\Component\DependencyInjection\ContainerInterface');
$container = $this->createMock('Symfony\Component\DependencyInjection\ContainerInterface');
$container->expects($this->any())
->method('get')
->with('cache_tags.invalidator')
@@ -251,7 +253,7 @@ abstract class UnitTestCase extends TestCase {
* The class resolver stub.
*/
protected function getClassResolverStub() {
$class_resolver = $this->getMock('Drupal\Core\DependencyInjection\ClassResolverInterface');
$class_resolver = $this->createMock('Drupal\Core\DependencyInjection\ClassResolverInterface');
$class_resolver->expects($this->any())
->method('getInstanceFromDefinition')
->will($this->returnCallback(function ($class) {
+1 -1
View File
@@ -451,7 +451,7 @@ class WebAssert extends MinkWebAssert {
* @throws \Behat\Mink\Exception\ElementNotFoundException
* @throws \Behat\Mink\Exception\ExpectationException
*/
public function fieldDisabled($field, TraversableElement $container = NULL) {
public function fieldDisabled($field, TraversableElement $container = NULL) {
$container = $container ?: $this->session->getPage();
$node = $container->findField($field);