annotate core/modules/migrate/tests/src/Unit/MigrateTestCase.php @ 19:fa3358dc1485 tip

Add ndrum files
author Chris Cannam
date Wed, 28 Aug 2019 13:14:47 +0100
parents 129ea1e6d783
children
rev   line source
Chris@0 1 <?php
Chris@0 2
Chris@0 3 namespace Drupal\Tests\migrate\Unit;
Chris@0 4
Chris@0 5 use Drupal\Core\Database\Driver\sqlite\Connection;
Chris@0 6 use Drupal\Core\DependencyInjection\ContainerBuilder;
Chris@0 7 use Drupal\migrate\Plugin\MigrationInterface;
Chris@0 8 use Drupal\Tests\UnitTestCase;
Chris@0 9
Chris@0 10 /**
Chris@0 11 * Provides setup and helper methods for Migrate module tests.
Chris@0 12 */
Chris@0 13 abstract class MigrateTestCase extends UnitTestCase {
Chris@0 14
Chris@0 15 /**
Chris@0 16 * An array of migration configuration values.
Chris@0 17 *
Chris@0 18 * @var array
Chris@0 19 */
Chris@0 20 protected $migrationConfiguration = [];
Chris@0 21
Chris@0 22 /**
Chris@0 23 * The migration ID map.
Chris@0 24 *
Chris@0 25 * @var \Drupal\migrate\Plugin\MigrateIdMapInterface|\PHPUnit_Framework_MockObject_MockObject
Chris@0 26 */
Chris@0 27 protected $idMap;
Chris@0 28
Chris@0 29 /**
Chris@0 30 * Local store for mocking setStatus()/getStatus().
Chris@0 31 *
Chris@17 32 * @var int
Chris@0 33 */
Chris@0 34 protected $migrationStatus = MigrationInterface::STATUS_IDLE;
Chris@0 35
Chris@0 36 /**
Chris@0 37 * Retrieves a mocked migration.
Chris@0 38 *
Chris@0 39 * @return \Drupal\migrate\Plugin\MigrationInterface|\PHPUnit_Framework_MockObject_MockObject
Chris@0 40 * The mocked migration.
Chris@0 41 */
Chris@0 42 protected function getMigration() {
Chris@0 43 $this->migrationConfiguration += ['migrationClass' => 'Drupal\migrate\Plugin\Migration'];
Chris@0 44 $this->idMap = $this->getMock('Drupal\migrate\Plugin\MigrateIdMapInterface');
Chris@0 45
Chris@0 46 $this->idMap
Chris@0 47 ->method('getQualifiedMapTableName')
Chris@0 48 ->willReturn('test_map');
Chris@0 49
Chris@0 50 $migration = $this->getMockBuilder($this->migrationConfiguration['migrationClass'])
Chris@0 51 ->disableOriginalConstructor()
Chris@0 52 ->getMock();
Chris@0 53
Chris@0 54 $migration->method('checkRequirements')
Chris@0 55 ->willReturn(TRUE);
Chris@0 56
Chris@0 57 $migration->method('getIdMap')
Chris@0 58 ->willReturn($this->idMap);
Chris@0 59
Chris@0 60 // We need the state to be toggled throughout the test so we store the value
Chris@0 61 // on the test class and use a return callback.
Chris@0 62 $migration->expects($this->any())
Chris@0 63 ->method('getStatus')
Chris@0 64 ->willReturnCallback(function () {
Chris@0 65 return $this->migrationStatus;
Chris@0 66 });
Chris@0 67 $migration->expects($this->any())
Chris@0 68 ->method('setStatus')
Chris@0 69 ->willReturnCallback(function ($status) {
Chris@0 70 $this->migrationStatus = $status;
Chris@0 71 });
Chris@0 72
Chris@0 73 $migration->method('getMigrationDependencies')
Chris@0 74 ->willReturn([
Chris@0 75 'required' => [],
Chris@0 76 'optional' => [],
Chris@0 77 ]);
Chris@0 78
Chris@0 79 $configuration = &$this->migrationConfiguration;
Chris@0 80
Chris@0 81 $migration->method('set')
Chris@0 82 ->willReturnCallback(function ($argument, $value) use (&$configuration) {
Chris@0 83 $configuration[$argument] = $value;
Chris@0 84 });
Chris@0 85
Chris@0 86 $migration->method('id')
Chris@0 87 ->willReturn($configuration['id']);
Chris@0 88
Chris@0 89 return $migration;
Chris@0 90 }
Chris@0 91
Chris@0 92 /**
Chris@0 93 * Gets an SQLite database connection object for use in tests.
Chris@0 94 *
Chris@0 95 * @param array $database_contents
Chris@0 96 * The database contents faked as an array. Each key is a table name, each
Chris@0 97 * value is a list of table rows, an associative array of field => value.
Chris@0 98 * @param array $connection_options
Chris@0 99 * (optional) Options for the database connection. Defaults to an empty
Chris@0 100 * array.
Chris@0 101 *
Chris@0 102 * @return \Drupal\Core\Database\Driver\sqlite\Connection
Chris@0 103 * The database connection.
Chris@0 104 */
Chris@0 105 protected function getDatabase(array $database_contents, $connection_options = []) {
Chris@0 106 if (extension_loaded('pdo_sqlite')) {
Chris@0 107 $connection_options['database'] = ':memory:';
Chris@0 108 $pdo = Connection::open($connection_options);
Chris@0 109 $connection = new Connection($pdo, $connection_options);
Chris@0 110 }
Chris@0 111 else {
Chris@0 112 $this->markTestSkipped('The pdo_sqlite extension is not available.');
Chris@0 113 }
Chris@0 114
Chris@0 115 // Initialize the DIC with a fake module handler for alterable queries.
Chris@0 116 $container = new ContainerBuilder();
Chris@0 117 $container->set('module_handler', $this->getMock('\Drupal\Core\Extension\ModuleHandlerInterface'));
Chris@0 118 \Drupal::setContainer($container);
Chris@0 119
Chris@0 120 // Create the tables and load them up with data, skipping empty ones.
Chris@0 121 foreach (array_filter($database_contents) as $table => $rows) {
Chris@0 122 $pilot_row = reset($rows);
Chris@0 123 $connection->schema()->createTable($table, $this->createSchemaFromRow($pilot_row));
Chris@0 124
Chris@0 125 $insert = $connection->insert($table)->fields(array_keys($pilot_row));
Chris@0 126 array_walk($rows, [$insert, 'values']);
Chris@0 127 $insert->execute();
Chris@0 128 }
Chris@0 129
Chris@0 130 return $connection;
Chris@0 131 }
Chris@0 132
Chris@0 133 /**
Chris@0 134 * Generates a table schema from a row.
Chris@0 135 *
Chris@0 136 * @param array $row
Chris@0 137 * The reference row on which to base the schema.
Chris@0 138 *
Chris@0 139 * @return array
Chris@0 140 * The Schema API-ready table schema.
Chris@0 141 */
Chris@0 142 protected function createSchemaFromRow(array $row) {
Chris@0 143 // SQLite uses loose ("affinity") typing, so it is OK for every column to be
Chris@0 144 // a text field.
Chris@0 145 $fields = array_map(function () {
Chris@0 146 return ['type' => 'text'];
Chris@0 147 }, $row);
Chris@0 148 return ['fields' => $fields];
Chris@0 149 }
Chris@0 150
Chris@0 151 /**
Chris@0 152 * Tests a query.
Chris@0 153 *
Chris@0 154 * @param array|\Traversable $iter
Chris@0 155 * The countable. foreach-able actual results if a query is being run.
Chris@0 156 * @param array $expected_results
Chris@0 157 * An array of expected results.
Chris@0 158 */
Chris@0 159 public function queryResultTest($iter, $expected_results) {
Chris@0 160 $this->assertSame(count($expected_results), count($iter), 'Number of results match');
Chris@0 161 $count = 0;
Chris@0 162 foreach ($iter as $data_row) {
Chris@0 163 $expected_row = $expected_results[$count];
Chris@0 164 $count++;
Chris@0 165 foreach ($expected_row as $key => $expected_value) {
Chris@0 166 $this->retrievalAssertHelper($expected_value, $this->getValue($data_row, $key), sprintf('Value matches for key "%s"', $key));
Chris@0 167 }
Chris@0 168 }
Chris@0 169 $this->assertSame(count($expected_results), $count);
Chris@0 170 }
Chris@0 171
Chris@0 172 /**
Chris@0 173 * Gets the value on a row for a given key.
Chris@0 174 *
Chris@0 175 * @param array $row
Chris@0 176 * The row information.
Chris@0 177 * @param string $key
Chris@0 178 * The key identifier.
Chris@0 179 *
Chris@0 180 * @return mixed
Chris@0 181 * The value on a row for a given key.
Chris@0 182 */
Chris@0 183 protected function getValue($row, $key) {
Chris@0 184 return $row[$key];
Chris@0 185 }
Chris@0 186
Chris@0 187 /**
Chris@0 188 * Asserts tested values during test retrieval.
Chris@0 189 *
Chris@0 190 * @param mixed $expected_value
Chris@0 191 * The incoming expected value to test.
Chris@0 192 * @param mixed $actual_value
Chris@0 193 * The incoming value itself.
Chris@0 194 * @param string $message
Chris@0 195 * The tested result as a formatted string.
Chris@0 196 */
Chris@0 197 protected function retrievalAssertHelper($expected_value, $actual_value, $message) {
Chris@0 198 if (is_array($expected_value)) {
Chris@0 199 // If the expected and actual values are empty, no need to array compare.
Chris@0 200 if (empty($expected_value && $actual_value)) {
Chris@0 201 return;
Chris@0 202 }
Chris@0 203 $this->assertArrayEquals($expected_value, $actual_value, $message);
Chris@0 204 }
Chris@0 205 else {
Chris@0 206 $this->assertSame((string) $expected_value, (string) $actual_value, $message);
Chris@0 207 }
Chris@0 208 }
Chris@0 209
Chris@0 210 }