Commit e91db278 authored by heddn's avatar heddn Committed by heddn

Issue #2524434 by heddn: Port MigrateSourceCSV to Drupal 8 missing tests

parent 4af3fd65
......@@ -30,7 +30,7 @@ class CSVFileObject extends \SplFileObject {
*
* @var array
*/
protected $columnNames = array();
protected $columnNames = [];
/**
* {@inheritdoc}
......@@ -38,7 +38,7 @@ class CSVFileObject extends \SplFileObject {
public function __construct($file_name) {
// Necessary to use this approach because SplFileObject doesn't like NULL
// arguments passed to it.
call_user_func_array(array('parent', '__construct'), func_get_args());
call_user_func_array(['parent', '__construct'], func_get_args());
$this->setFlags(CSVFileObject::READ_CSV | CSVFileObject::READ_AHEAD | CSVFileObject::DROP_NEW_LINE | CSVFileObject::SKIP_EMPTY);
}
......@@ -62,6 +62,7 @@ class CSVFileObject extends \SplFileObject {
// Set meaningful keys for the columns mentioned in $this->csvColumns.
foreach ($this->columnNames as $key => $value) {
// Copy value to more descriptive key and unset original.
$value = key($value);
$row[$value] = isset($row[$key]) ? $row[$key] : NULL;
unset($row[$key]);
}
......
......@@ -31,14 +31,14 @@ class CSV extends SourcePluginBase {
*
* @var array
*/
protected $fields = array();
protected $fields = [];
/**
* List of key fields, as indexes.
*
* @var array
*/
protected $keys = array();
protected $keys = [];
/**
* {@inheritdoc}
......@@ -93,7 +93,7 @@ class CSV extends SourcePluginBase {
$row = $file->current();
foreach ($row as $header) {
$header = trim($header);
$column_names[] = $header;
$column_names[] = [$header => $header];
}
$file->setColumnNames($column_names);
}
......@@ -109,7 +109,7 @@ class CSV extends SourcePluginBase {
* {@inheritdoc}
*/
public function getIDs() {
$ids = array();
$ids = [];
foreach ($this->configuration['keys'] as $key) {
$ids[$key]['type'] = 'string';
}
......@@ -120,9 +120,9 @@ class CSV extends SourcePluginBase {
* {@inheritdoc}
*/
public function fields() {
$fields = array();
$fields = [];
foreach ($this->getIterator()->getColumnNames() as $column) {
$fields[$column] = $column;
$fields[key($column)] = reset($column);
}
// Any caller-specified fields with the same names as extracted fields will
......
......@@ -7,144 +7,133 @@
namespace Drupal\Tests\migrate_source_csv\Unit;
use Drupal\migrate_source_csv\CSVFileObject;
use Drupal\Tests\UnitTestCase;
use org\bovigo\vfs\vfsStream;
/**
* @coversDefaultClass \Drupal\migrate_source_csv\CSVFileObject
*
* @group migrate_source_csv
*/
class CSVFileObjectTest extends UnitTestCase {
class CSVFileObjectTest extends CSVUnitTestCase {
/**
* The class under test.
* The CSV file object.
*
* @var \Drupal\migrate_source_csv\CSVFileObject
*/
protected $csvFileObject;
/**
* {@inheritdoc}
*/
public function setUp() {
$this->csvFileObject = new CSVFileObject(dirname(__FILE__) . '/artifacts/data.csv');
protected function setUp() {
parent::setUp();
$this->csvFileObject = new CSVFileObject($this->happyPath);
}
/**
* Happy path CSV data provider.
* Tests that the construction appropriately creates a CSVFileObject.
*
* @test
*
* @return array
* File path as a string. This will be used as a virtual file.
* @covers ::__construct
*/
public function providerCSVFile() {
$file_data = <<<'EOD'
id,first_name,last_name,email,country,ip_address
1,Justin,Dean,jdean0@example.com,Indonesia,60.242.130.40
2,Joan,Jordan,jjordan1@example.com,Thailand,137.230.209.171
3,William,Ray,wray2@example.com,Germany,4.75.251.71
4,Jack,Collins,jcollins3@example.com,Indonesia,118.241.243.64
5,Jean,Moreno,jmoreno4@example.com,Portugal,12.24.215.20
6,Dennis,Mitchell,dmitchell5@example.com,Mexico,185.24.131.116
7,Harry,West,hwest6@example.com,Uzbekistan,101.74.110.171
8,Rebecca,Hunt,rhunt7@example.com,France,253.107.6.23
9,Rose,Rogers,rrogers8@example.com,China,21.2.126.228
10,Juan,Walker,jwalker9@example.com,Angola,192.118.77.225
11,Lois,Price,lpricea@example.com,Greece,231.185.100.19
12,Patricia,Bell,pbellb@example.com,Sweden,226.2.254.94
13,Gerald,Kelly,gkellyc@example.com,China,31.204.2.163
14,Kimberly,Jackson,kjacksond@example.com,Thailand,19.187.65.116
15,Jason,Mason,jmasone@example.com,Greece,225.129.68.203
EOD;
return array(
array(vfsStream::newFile('data.csv')->at(vfsStream::setup('directory'))->withContent($file_data)->url()),
);
public function create() {
$this->assertInstanceOf(CSVFileObject::class, $this->csvFileObject);
$flags = CSVFileObject::READ_CSV | CSVFileObject::READ_AHEAD | CSVFileObject::DROP_NEW_LINE | CSVFileObject::SKIP_EMPTY;
$this->assertSame($flags, $this->csvFileObject->getFlags());
}
/**
* Tests that the header row count is correctly set.
*
* @test
* @covers ::__construct
* @dataProvider providerCSVFile
*
* @covers ::setHeaderRowCount
*/
public function create($file_path) {
$csvFileObject = new CSVFileObject($file_path);
$this->assertInstanceOf('\Drupal\migrate_source_csv\CSVFileObject', $csvFileObject);
$flags = CSVFileObject::READ_CSV | CSVFileObject::READ_AHEAD | CSVFileObject::DROP_NEW_LINE | CSVFileObject::SKIP_EMPTY;
$this->assertEquals($flags, $csvFileObject->getFlags());
public function setHeaderRowCount() {
$expected = 2;
$this->csvFileObject->setHeaderRowCount($expected);
return $this->csvFileObject->getHeaderRowCount();
}
/**
* Tests that the header row count is correctly returned.
*
* @test
*
* @depends setHeaderRowCount
*
* @covers ::getHeaderRowCount
* @covers ::setHeaderRowCount
* @dataProvider providerCSVFile
*/
public function headerRowCount($file_path) {
$csvFileObject = new CSVFileObject($file_path);
$expected = 1;
$csvFileObject->setHeaderRowCount($expected);
$actual = $csvFileObject->getHeaderRowCount();
public function getHeaderRowCount($actual) {
$expected = 2;
$this->assertEquals($expected, $actual);
}
/**
* Tests that line count is correct.
*
* @test
*
* @covers ::count
* @dataProvider providerCSVFile
*/
public function countLines($file_path) {
$csvFileObject = new CSVFileObject($file_path);
public function countLines() {
$expected = 15;
$csvFileObject->setHeaderRowCount(1);
$actual = $csvFileObject->count();
$this->csvFileObject->setHeaderRowCount(1);
$actual = $this->csvFileObject->count();
$this->assertEquals($expected, $actual);
}
/**
* Tests that the current row is correctly returned.
*
* @test
*
* @covers ::current
* @covers ::rewind
* @covers ::getColumnNames
* @covers ::setColumnNames
* @dataProvider providerCSVFile
*/
public function current($file_path) {
$csvFileObject = new CSVFileObject($file_path);
$columns = array(
'id',
'first_name',
'last_name',
'email',
'country',
'ip_address',
);
$row = array(
public function current() {
$column_names = [
['id' => 'Identifier'],
['first_name' => 'First Name'],
['last_name' => 'Last Name'],
['email' => 'Email'],
['country' => 'Country'],
['ip_address' => 'IP Address'],
];
$columns = [];
foreach ($column_names as $values) {
$columns[] = key($values);
}
$row = [
'1',
'Justin',
'Dean',
'jdean0@example.com',
'Indonesia',
'60.242.130.40',
);
];
$csvFileObject->rewind();
$current = $csvFileObject->current();
$csv_file_object = $this->csvFileObject;
$csv_file_object->rewind();
$current = $csv_file_object->current();
$this->assertArrayEquals($columns, $current);
$csvFileObject->setHeaderRowCount(1);
$csvFileObject->rewind();
$current = $csvFileObject->current();
$csv_file_object->setHeaderRowCount(1);
$csv_file_object->rewind();
$current = $csv_file_object->current();
$this->assertArrayEquals($row, $current);
$csvFileObject->setColumnNames($columns);
$csvFileObject->rewind();
$current = $csvFileObject->current();
$csv_file_object->setColumnNames($column_names);
$csv_file_object->rewind();
$current = $csv_file_object->current();
$this->assertArrayEquals($columns, array_keys($current));
$this->assertArrayEquals($row, array_values($current));
$this->assertArrayEquals($columns, $csvFileObject->getColumnNames());
$this->assertArrayEquals($column_names, $csv_file_object->getColumnNames());
}
}
<?php
/**
* @file
* Code for CSVFileObjectTest.php.
*/
namespace Drupal\Tests\migrate_source_csv\Unit;
use Drupal\Tests\UnitTestCase;
use org\bovigo\vfs\vfsStream;
/**
* Base unit test to build csv file contents.
*
* @group migrate_source_csv
*/
abstract class CSVUnitTestCase extends UnitTestCase {
/**
* The happy path file url.
*
* @var string
*/
protected $happyPath;
/**
* The un-happy path file url.
*
* @var string
*/
protected $sad;
/**
* {@inheritdoc}
*/
protected function setUp() {
$root_dir = vfsStream::setup('root');
$happy = <<<'EOD'
id,first_name,last_name,email,country,ip_address
1,Justin,Dean,jdean0@example.com,Indonesia,60.242.130.40
2,Joan,Jordan,jjordan1@example.com,Thailand,137.230.209.171
3,William,Ray,wray2@example.com,Germany,4.75.251.71
4,Jack,Collins,jcollins3@example.com,Indonesia,118.241.243.64
5,Jean,Moreno,jmoreno4@example.com,Portugal,12.24.215.20
6,Dennis,Mitchell,dmitchell5@example.com,Mexico,185.24.131.116
7,Harry,West,hwest6@example.com,Uzbekistan,101.74.110.171
8,Rebecca,Hunt,rhunt7@example.com,France,253.107.6.23
9,Rose,Rogers,rrogers8@example.com,China,21.2.126.228
10,Juan,Walker,jwalker9@example.com,Angola,192.118.77.225
11,Lois,Price,lpricea@example.com,Greece,231.185.100.19
12,Patricia,Bell,pbellb@example.com,Sweden,226.2.254.94
13,Gerald,Kelly,gkellyc@example.com,China,31.204.2.163
14,Kimberly,Jackson,kjacksond@example.com,Thailand,19.187.65.116
15,Jason,Mason,jmasone@example.com,Greece,225.129.68.203
EOD;
$sad = <<<'EOD'
1|%Justin%|Dean|jdean0@example.com|Indonesia|60.242.130.40
2|Joan|Jordan|jjordan1@example.com|Thailand|137.230.209.171
3|William|Ray|wray2@example.com|Germany|4.75.251.71
4|Jack|Collins|jcollins3@example.com|Indonesia|118.241.243.64
5|Jean|Moreno|jmoreno4@example.com|Portugal|12.24.215.20
6|Dennis|Mitchell|dmitchell5@example.com|Mexico|185.24.131.116
7|Harry|West|hwest6@example.com|Uzbekistan|101.74.110.171
8|Rebecca|Hunt|rhunt7@example.com|France|253.107.6.23
9|Rose|Rogers|rrogers8@example.com|China|21.2.126.228
10|Juan|Walker|jwalker9@example.com|Angola|192.118.77.225
11|Lois|Price|lpricea@example.com|Greece|231.185.100.19
12|Patricia|Bell|pbellb@example.com|Sweden|226.2.254.94
13|Gerald|Kelly|gkellyc@example.com|China|31.204.2.163
14|Kimberly|Jackson|kjacksond@example.com|Thailand|19.187.65.116
15|Jason|Mason|jmasone@example.com|Greece|225.129.68.203
EOD;
$this->happyPath = vfsStream::newFile('data.csv')
->at($root_dir)
->withContent($happy)
->url();
$this->sad = vfsStream::newFile('data_edge_case.csv')
->at($root_dir)
->withContent($sad)
->url();
}
}
......@@ -6,29 +6,15 @@
namespace Drupal\Tests\migrate_source_csv\Unit\Plugin\migrate\source;
use \Drupal\Tests\UnitTestCase;
use \Drupal\migrate_source_csv\Plugin\migrate\source\CSV;
use Drupal\migrate_source_csv\Plugin\migrate\source\CSV;
use Drupal\Tests\migrate_source_csv\Unit\CSVUnitTestCase;
/**
* @coversDefaultClass \Drupal\migrate_source_csv\Plugin\migrate\source\CSV
*
* @group migrate_source_csv
*/
class CSVTest extends UnitTestCase {
/**
* The class under test.
*
* @var \Drupal\migrate_source_csv\Plugin\migrate\source\CSV
*/
protected $csv;
/**
* The configuration.
*
* @var array
*/
protected $configuration;
class CSVTest extends CSVUnitTestCase {
/**
* The plugin id.
......@@ -55,59 +41,102 @@ class CSVTest extends UnitTestCase {
* {@inheritdoc}
*/
public function setUp() {
$this->configuration = array(
'path' => dirname(__FILE__) . '/../../../artifacts/data.csv',
'keys' => array('id'),
'header_row_count' => 1,
);
parent::setUp();
$this->pluginId = 'test csv migration';
$this->pluginDefinition = array();
$this->pluginDefinition = [];
$this->plugin = $this->getMock('\Drupal\migrate\Entity\MigrationInterface');
$this->csv = new CSV($this->configuration, $this->pluginId, $this->pluginDefinition, $this->plugin);
}
/**
* Tests the construction of CSV.
*
* @test
*
* @covers ::__construct
*/
public function testCreate() {
$this->assertInstanceOf('\Drupal\migrate_source_csv\Plugin\migrate\source\CSV', $this->csv);
public function create() {
$configuration = [
'path' => $this->happyPath,
'keys' => ['id'],
'header_row_count' => 1,
];
$csv = new CSV($configuration, $this->pluginId, $this->pluginDefinition, $this->plugin);
$this->assertInstanceOf('\Drupal\migrate_source_csv\Plugin\migrate\source\CSV', $csv);
}
/**
* Tests that a missing path will throw an exception.
*
* @test
*
* @expectedException \Drupal\migrate\MigrateException
*
* @expectedExceptionMessage You must declare the "path" to the source CSV file in your source settings.
*/
public function testMigrateExceptionPathMissing() {
new CSV(array(), $this->pluginId, $this->pluginDefinition, $this->plugin);
public function migrateExceptionPathMissing() {
new CSV([], $this->pluginId, $this->pluginDefinition, $this->plugin);
}
/**
* Tests that missing keys will throw an exception.
*
* @test
*
* @expectedException \Drupal\migrate\MigrateException
*
* @expectedExceptionMessage You must declare "keys" as a unique array of fields in your source settings.
*/
public function testMigrateExceptionKeysMissing() {
new CSV(array('path' => 'foo'), $this->pluginId, $this->pluginDefinition, $this->plugin);
public function migrateExceptionKeysMissing() {
$configuration = [
'path' => $this->happyPath,
];
new CSV($configuration, $this->pluginId, $this->pluginDefinition, $this->plugin);
}
/**
* Tests that toString functions as expected.
*
* @test
*
* @covers ::__toString
*/
public function testToString() {
$this->assertEquals($this->configuration['path'], (string) $this->csv);
public function toString() {
$configuration = [
'path' => $this->happyPath,
'keys' => ['id'],
'header_row_count' => 1,
];
$csv = new CSV($configuration, $this->pluginId, $this->pluginDefinition, $this->plugin);
$this->assertEquals($configuration['path'], (string) $csv);
}
/**
* Tests initialization of the iterator.
*
* @test
*
* @covers ::initializeIterator
*/
public function testInitializeIterator() {
$config_common = array(
'path' => dirname(__FILE__) . '/../../../artifacts/data_edge_cases.csv',
'keys' => array('id'),
);
$config_delimiter = array('delimiter' => '|');
$config_enclosure = array('enclosure' => '%');
$config_escape = array('escape' => '`');
public function initializeIterator() {
$configuration = [
'path' => $this->happyPath,
'keys' => ['id'],
'header_row_count' => 1,
];
$config_common = [
'path' => $this->sad,
'keys' => ['id'],
];
$config_delimiter = ['delimiter' => '|'];
$config_enclosure = ['enclosure' => '%'];
$config_escape = ['escape' => '`'];
$csv = new CSV($config_common + $config_delimiter, $this->pluginId, $this->pluginDefinition, $this->plugin);
$this->assertEquals(current($config_delimiter), $csv->initializeIterator()
......@@ -120,97 +149,127 @@ class CSVTest extends UnitTestCase {
->getCsvControl()[1]);
$csv = new CSV($config_common + $config_delimiter + $config_enclosure + $config_escape, $this->pluginId, $this->pluginDefinition, $this->plugin);
$csvFileObject = $csv->initializeIterator();
$row = array(
$csv_file_object = $csv->initializeIterator();
$row = [
'1',
'Justin',
'Dean',
'jdean0@prlog.org',
'jdean0@example.com',
'Indonesia',
'60.242.130.40',
);
$csvFileObject->rewind();
$current = $csvFileObject->current();
];
$csv_file_object->rewind();
$current = $csv_file_object->current();
$this->assertArrayEquals($row, $current);
$csvFileObject = $this->csv->initializeIterator();
$row = array(
$csv = new CSV($configuration, $this->pluginId, $this->pluginDefinition, $this->plugin);
$csv_file_object = $csv->initializeIterator();
$row = [
'id' => '1',
'first_name' => 'Justin',
'last_name' => 'Dean',
'email' => 'jdean0@prlog.org',
'email' => 'jdean0@example.com',
'country' => 'Indonesia',
'ip_address' => '60.242.130.40',
);
$second_row = array(
];
$second_row = [
'id' => '2',
'first_name' => 'Joan',
'last_name' => 'Jordan',
'email' => 'jjordan1@tamu.edu',
'email' => 'jjordan1@example.com',
'country' => 'Thailand',
'ip_address' => '137.230.209.171',
);
];
$csvFileObject->rewind();
$current = $csvFileObject->current();
$csv_file_object->rewind();
$current = $csv_file_object->current();
$this->assertArrayEquals($row, $current);
$csvFileObject->next();
$next = $csvFileObject->current();
$csv_file_object->next();
$next = $csv_file_object->current();
$this->assertArrayEquals($second_row, $next);
$column_names = array(
'column_names' => array(
'id',
'first_name',
),
);
$csv = new CSV($this->configuration + $column_names, $this->pluginId, $this->pluginDefinition, $this->plugin);
$csvFileObject = $csv->initializeIterator();
$row = array(
$column_names = [
'column_names' => [
0 => ['id' => 'identifier'],
2 => ['last_name' => 'User last name'],
],
];
$csv = new CSV($configuration + $column_names, $this->pluginId, $this->pluginDefinition, $this->plugin);
$csv_file_object = $csv->initializeIterator();
$row = [
'id' => '1',
'first_name' => 'Justin',
);
$second_row = array(
'last_name' => 'Dean',
];
$second_row = [
'id' => '2',
'first_name' => 'Joan',
);
'last_name' => 'Jo