Mercurial > hg > isophonics-drupal-site
diff core/modules/migrate/tests/src/Unit/MigrateTestCase.php @ 0:4c8ae668cc8c
Initial import (non-working)
author | Chris Cannam |
---|---|
date | Wed, 29 Nov 2017 16:09:58 +0000 |
parents | |
children | 1fec387a4317 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/core/modules/migrate/tests/src/Unit/MigrateTestCase.php Wed Nov 29 16:09:58 2017 +0000 @@ -0,0 +1,215 @@ +<?php + +namespace Drupal\Tests\migrate\Unit; + +use Drupal\Core\Database\Driver\sqlite\Connection; +use Drupal\Core\DependencyInjection\ContainerBuilder; +use Drupal\migrate\Plugin\MigrationInterface; +use Drupal\Tests\UnitTestCase; + +/** + * Provides setup and helper methods for Migrate module tests. + */ +abstract class MigrateTestCase extends UnitTestCase { + + /** + * An array of migration configuration values. + * + * @var array + */ + protected $migrationConfiguration = []; + + /** + * The migration ID map. + * + * @var \Drupal\migrate\Plugin\MigrateIdMapInterface|\PHPUnit_Framework_MockObject_MockObject + */ + protected $idMap; + + /** + * Local store for mocking setStatus()/getStatus(). + * + * @var \Drupal\migrate\Plugin\MigrationInterface::STATUS_* + */ + protected $migrationStatus = MigrationInterface::STATUS_IDLE; + + /** + * Retrieves a mocked migration. + * + * @return \Drupal\migrate\Plugin\MigrationInterface|\PHPUnit_Framework_MockObject_MockObject + * The mocked migration. + */ + protected function getMigration() { + $this->migrationConfiguration += ['migrationClass' => 'Drupal\migrate\Plugin\Migration']; + $this->idMap = $this->getMock('Drupal\migrate\Plugin\MigrateIdMapInterface'); + + $this->idMap + ->method('getQualifiedMapTableName') + ->willReturn('test_map'); + + $migration = $this->getMockBuilder($this->migrationConfiguration['migrationClass']) + ->disableOriginalConstructor() + ->getMock(); + + $migration->method('checkRequirements') + ->willReturn(TRUE); + + $migration->method('getIdMap') + ->willReturn($this->idMap); + + // We need the state to be toggled throughout the test so we store the value + // on the test class and use a return callback. + $migration->expects($this->any()) + ->method('getStatus') + ->willReturnCallback(function () { + return $this->migrationStatus; + }); + $migration->expects($this->any()) + ->method('setStatus') + ->willReturnCallback(function ($status) { + $this->migrationStatus = $status; + }); + + $migration->method('getMigrationDependencies') + ->willReturn([ + 'required' => [], + 'optional' => [], + ]); + + $configuration = &$this->migrationConfiguration; + + $migration->method('getHighWaterProperty') + ->willReturnCallback(function () use ($configuration) { + return isset($configuration['high_water_property']) ? $configuration['high_water_property'] : ''; + }); + + $migration->method('set') + ->willReturnCallback(function ($argument, $value) use (&$configuration) { + $configuration[$argument] = $value; + }); + + $migration->method('id') + ->willReturn($configuration['id']); + + return $migration; + } + + /** + * Gets an SQLite database connection object for use in tests. + * + * @param array $database_contents + * The database contents faked as an array. Each key is a table name, each + * value is a list of table rows, an associative array of field => value. + * @param array $connection_options + * (optional) Options for the database connection. Defaults to an empty + * array. + * + * @return \Drupal\Core\Database\Driver\sqlite\Connection + * The database connection. + */ + protected function getDatabase(array $database_contents, $connection_options = []) { + if (extension_loaded('pdo_sqlite')) { + $connection_options['database'] = ':memory:'; + $pdo = Connection::open($connection_options); + $connection = new Connection($pdo, $connection_options); + } + else { + $this->markTestSkipped('The pdo_sqlite extension is not available.'); + } + + // Initialize the DIC with a fake module handler for alterable queries. + $container = new ContainerBuilder(); + $container->set('module_handler', $this->getMock('\Drupal\Core\Extension\ModuleHandlerInterface')); + \Drupal::setContainer($container); + + // Create the tables and load them up with data, skipping empty ones. + foreach (array_filter($database_contents) as $table => $rows) { + $pilot_row = reset($rows); + $connection->schema()->createTable($table, $this->createSchemaFromRow($pilot_row)); + + $insert = $connection->insert($table)->fields(array_keys($pilot_row)); + array_walk($rows, [$insert, 'values']); + $insert->execute(); + } + + return $connection; + } + + /** + * Generates a table schema from a row. + * + * @param array $row + * The reference row on which to base the schema. + * + * @return array + * The Schema API-ready table schema. + */ + protected function createSchemaFromRow(array $row) { + // SQLite uses loose ("affinity") typing, so it is OK for every column to be + // a text field. + $fields = array_map(function () { + return ['type' => 'text']; + }, $row); + return ['fields' => $fields]; + } + + /** + * Tests a query. + * + * @param array|\Traversable $iter + * The countable. foreach-able actual results if a query is being run. + * @param array $expected_results + * An array of expected results. + */ + public function queryResultTest($iter, $expected_results) { + $this->assertSame(count($expected_results), count($iter), 'Number of results match'); + $count = 0; + foreach ($iter as $data_row) { + $expected_row = $expected_results[$count]; + $count++; + foreach ($expected_row as $key => $expected_value) { + $this->retrievalAssertHelper($expected_value, $this->getValue($data_row, $key), sprintf('Value matches for key "%s"', $key)); + } + } + $this->assertSame(count($expected_results), $count); + } + + /** + * Gets the value on a row for a given key. + * + * @param array $row + * The row information. + * @param string $key + * The key identifier. + * + * @return mixed + * The value on a row for a given key. + */ + protected function getValue($row, $key) { + return $row[$key]; + } + + /** + * Asserts tested values during test retrieval. + * + * @param mixed $expected_value + * The incoming expected value to test. + * @param mixed $actual_value + * The incoming value itself. + * @param string $message + * The tested result as a formatted string. + */ + protected function retrievalAssertHelper($expected_value, $actual_value, $message) { + if (is_array($expected_value)) { + // If the expected and actual values are empty, no need to array compare. + if (empty($expected_value && $actual_value)) { + return; + } + $this->assertArrayEquals($expected_value, $actual_value, $message); + } + else { + $this->assertSame((string) $expected_value, (string) $actual_value, $message); + } + } + +}