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 }
|