558cecb94af0bbbed26d3f820cb3677614987e3b
[yaffs-website] / web / core / modules / migrate / tests / src / Unit / MigrateTestCase.php
1 <?php
2
3 namespace Drupal\Tests\migrate\Unit;
4
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;
9
10 /**
11  * Provides setup and helper methods for Migrate module tests.
12  */
13 abstract class MigrateTestCase extends UnitTestCase {
14
15   /**
16    * An array of migration configuration values.
17    *
18    * @var array
19    */
20   protected $migrationConfiguration = [];
21
22   /**
23    * The migration ID map.
24    *
25    * @var \Drupal\migrate\Plugin\MigrateIdMapInterface|\PHPUnit_Framework_MockObject_MockObject
26    */
27   protected $idMap;
28
29   /**
30    * Local store for mocking setStatus()/getStatus().
31    *
32    * @var \Drupal\migrate\Plugin\MigrationInterface::STATUS_*
33    */
34   protected $migrationStatus = MigrationInterface::STATUS_IDLE;
35
36   /**
37    * Retrieves a mocked migration.
38    *
39    * @return \Drupal\migrate\Plugin\MigrationInterface|\PHPUnit_Framework_MockObject_MockObject
40    *   The mocked migration.
41    */
42   protected function getMigration() {
43     $this->migrationConfiguration += ['migrationClass' => 'Drupal\migrate\Plugin\Migration'];
44     $this->idMap = $this->getMock('Drupal\migrate\Plugin\MigrateIdMapInterface');
45
46     $this->idMap
47       ->method('getQualifiedMapTableName')
48       ->willReturn('test_map');
49
50     $migration = $this->getMockBuilder($this->migrationConfiguration['migrationClass'])
51       ->disableOriginalConstructor()
52       ->getMock();
53
54     $migration->method('checkRequirements')
55       ->willReturn(TRUE);
56
57     $migration->method('getIdMap')
58       ->willReturn($this->idMap);
59
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())
63       ->method('getStatus')
64       ->willReturnCallback(function () {
65         return $this->migrationStatus;
66       });
67     $migration->expects($this->any())
68       ->method('setStatus')
69       ->willReturnCallback(function ($status) {
70         $this->migrationStatus = $status;
71       });
72
73     $migration->method('getMigrationDependencies')
74       ->willReturn([
75         'required' => [],
76         'optional' => [],
77       ]);
78
79     $configuration = &$this->migrationConfiguration;
80
81     $migration->method('set')
82       ->willReturnCallback(function ($argument, $value) use (&$configuration) {
83         $configuration[$argument] = $value;
84       });
85
86     $migration->method('id')
87       ->willReturn($configuration['id']);
88
89     return $migration;
90   }
91
92   /**
93    * Gets an SQLite database connection object for use in tests.
94    *
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
100    *   array.
101    *
102    * @return \Drupal\Core\Database\Driver\sqlite\Connection
103    *   The database connection.
104    */
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);
110     }
111     else {
112       $this->markTestSkipped('The pdo_sqlite extension is not available.');
113     }
114
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);
119
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));
124
125       $insert = $connection->insert($table)->fields(array_keys($pilot_row));
126       array_walk($rows, [$insert, 'values']);
127       $insert->execute();
128     }
129
130     return $connection;
131   }
132
133   /**
134    * Generates a table schema from a row.
135    *
136    * @param array $row
137    *   The reference row on which to base the schema.
138    *
139    * @return array
140    *   The Schema API-ready table schema.
141    */
142   protected function createSchemaFromRow(array $row) {
143     // SQLite uses loose ("affinity") typing, so it is OK for every column to be
144     // a text field.
145     $fields = array_map(function () {
146       return ['type' => 'text'];
147     }, $row);
148     return ['fields' => $fields];
149   }
150
151   /**
152    * Tests a query.
153    *
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.
158    */
159   public function queryResultTest($iter, $expected_results) {
160     $this->assertSame(count($expected_results), count($iter), 'Number of results match');
161     $count = 0;
162     foreach ($iter as $data_row) {
163       $expected_row = $expected_results[$count];
164       $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));
167       }
168     }
169     $this->assertSame(count($expected_results), $count);
170   }
171
172   /**
173    * Gets the value on a row for a given key.
174    *
175    * @param array $row
176    *   The row information.
177    * @param string $key
178    *   The key identifier.
179    *
180    * @return mixed
181    *   The value on a row for a given key.
182    */
183   protected function getValue($row, $key) {
184     return $row[$key];
185   }
186
187   /**
188    * Asserts tested values during test retrieval.
189    *
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.
196    */
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)) {
201         return;
202       }
203       $this->assertArrayEquals($expected_value, $actual_value, $message);
204     }
205     else {
206       $this->assertSame((string) $expected_value, (string) $actual_value, $message);
207     }
208   }
209
210 }