3 namespace Drupal\Tests\migrate\Unit;
5 use Drupal\Core\Database\Driver\sqlite\Connection;
6 use Drupal\Core\DependencyInjection\ContainerBuilder;
7 use Drupal\migrate\Plugin\MigrationInterface;
8 use Drupal\Tests\UnitTestCase;
11 * Provides setup and helper methods for Migrate module tests.
13 abstract class MigrateTestCase extends UnitTestCase {
16 * An array of migration configuration values.
20 protected $migrationConfiguration = [];
23 * The migration ID map.
25 * @var \Drupal\migrate\Plugin\MigrateIdMapInterface|\PHPUnit_Framework_MockObject_MockObject
30 * Local store for mocking setStatus()/getStatus().
32 * @var \Drupal\migrate\Plugin\MigrationInterface::STATUS_*
34 protected $migrationStatus = MigrationInterface::STATUS_IDLE;
37 * Retrieves a mocked migration.
39 * @return \Drupal\migrate\Plugin\MigrationInterface|\PHPUnit_Framework_MockObject_MockObject
40 * The mocked migration.
42 protected function getMigration() {
43 $this->migrationConfiguration += ['migrationClass' => 'Drupal\migrate\Plugin\Migration'];
44 $this->idMap = $this->getMock('Drupal\migrate\Plugin\MigrateIdMapInterface');
47 ->method('getQualifiedMapTableName')
48 ->willReturn('test_map');
50 $migration = $this->getMockBuilder($this->migrationConfiguration['migrationClass'])
51 ->disableOriginalConstructor()
54 $migration->method('checkRequirements')
57 $migration->method('getIdMap')
58 ->willReturn($this->idMap);
60 // We need the state to be toggled throughout the test so we store the value
61 // on the test class and use a return callback.
62 $migration->expects($this->any())
64 ->willReturnCallback(function () {
65 return $this->migrationStatus;
67 $migration->expects($this->any())
69 ->willReturnCallback(function ($status) {
70 $this->migrationStatus = $status;
73 $migration->method('getMigrationDependencies')
79 $configuration = &$this->migrationConfiguration;
81 $migration->method('set')
82 ->willReturnCallback(function ($argument, $value) use (&$configuration) {
83 $configuration[$argument] = $value;
86 $migration->method('id')
87 ->willReturn($configuration['id']);
93 * Gets an SQLite database connection object for use in tests.
95 * @param array $database_contents
96 * The database contents faked as an array. Each key is a table name, each
97 * value is a list of table rows, an associative array of field => value.
98 * @param array $connection_options
99 * (optional) Options for the database connection. Defaults to an empty
102 * @return \Drupal\Core\Database\Driver\sqlite\Connection
103 * The database connection.
105 protected function getDatabase(array $database_contents, $connection_options = []) {
106 if (extension_loaded('pdo_sqlite')) {
107 $connection_options['database'] = ':memory:';
108 $pdo = Connection::open($connection_options);
109 $connection = new Connection($pdo, $connection_options);
112 $this->markTestSkipped('The pdo_sqlite extension is not available.');
115 // Initialize the DIC with a fake module handler for alterable queries.
116 $container = new ContainerBuilder();
117 $container->set('module_handler', $this->getMock('\Drupal\Core\Extension\ModuleHandlerInterface'));
118 \Drupal::setContainer($container);
120 // Create the tables and load them up with data, skipping empty ones.
121 foreach (array_filter($database_contents) as $table => $rows) {
122 $pilot_row = reset($rows);
123 $connection->schema()->createTable($table, $this->createSchemaFromRow($pilot_row));
125 $insert = $connection->insert($table)->fields(array_keys($pilot_row));
126 array_walk($rows, [$insert, 'values']);
134 * Generates a table schema from a row.
137 * The reference row on which to base the schema.
140 * The Schema API-ready table schema.
142 protected function createSchemaFromRow(array $row) {
143 // SQLite uses loose ("affinity") typing, so it is OK for every column to be
145 $fields = array_map(function () {
146 return ['type' => 'text'];
148 return ['fields' => $fields];
154 * @param array|\Traversable $iter
155 * The countable. foreach-able actual results if a query is being run.
156 * @param array $expected_results
157 * An array of expected results.
159 public function queryResultTest($iter, $expected_results) {
160 $this->assertSame(count($expected_results), count($iter), 'Number of results match');
162 foreach ($iter as $data_row) {
163 $expected_row = $expected_results[$count];
165 foreach ($expected_row as $key => $expected_value) {
166 $this->retrievalAssertHelper($expected_value, $this->getValue($data_row, $key), sprintf('Value matches for key "%s"', $key));
169 $this->assertSame(count($expected_results), $count);
173 * Gets the value on a row for a given key.
176 * The row information.
178 * The key identifier.
181 * The value on a row for a given key.
183 protected function getValue($row, $key) {
188 * Asserts tested values during test retrieval.
190 * @param mixed $expected_value
191 * The incoming expected value to test.
192 * @param mixed $actual_value
193 * The incoming value itself.
194 * @param string $message
195 * The tested result as a formatted string.
197 protected function retrievalAssertHelper($expected_value, $actual_value, $message) {
198 if (is_array($expected_value)) {
199 // If the expected and actual values are empty, no need to array compare.
200 if (empty($expected_value && $actual_value)) {
203 $this->assertArrayEquals($expected_value, $actual_value, $message);
206 $this->assertSame((string) $expected_value, (string) $actual_value, $message);