From 2e22e03fb5dadc84669af8d895f9eb449b2e6d71 Mon Sep 17 00:00:00 2001 From: lucashedding <lucashedding@1463982.no-reply.drupal.org> Date: Fri, 14 Oct 2016 14:11:37 -0600 Subject: [PATCH] Issue #2781573 by sgurlt, heddn: Method for CSV File Object creation --- composer.json | 8 ++ .../migrate_source_csv.source.schema.yml | 3 + phpunit.xml.dist | 21 ----- src/Plugin/migrate/source/CSV.php | 33 +++++--- tests/bootstrap.php | 27 ------- tests/src/Unit/CSVFileObjectTest.php | 20 ++--- tests/src/Unit/CSVUnitTestCase.php | 2 + .../Unit/Plugin/migrate/source/CSVTest.php | 78 +++++++++++-------- 8 files changed, 87 insertions(+), 105 deletions(-) delete mode 100644 phpunit.xml.dist delete mode 100644 tests/bootstrap.php diff --git a/composer.json b/composer.json index 9cc6d6e..e0412a6 100644 --- a/composer.json +++ b/composer.json @@ -17,7 +17,15 @@ "source": "https://cgit.drupalcode.org/migrate_source_csv" }, "minimum-stability": "dev", + "prefer-stable": true, "require": { "drupal/core": "~8.1" + }, + "require-dev": { + "mikey179/vfsStream": "~1", + "phpunit/phpunit": "~4" + }, + "config": { + "preferred-install": "dist" } } diff --git a/config/schema/migrate_source_csv.source.schema.yml b/config/schema/migrate_source_csv.source.schema.yml index 24440a0..1aa2064 100644 --- a/config/schema/migrate_source_csv.source.schema.yml +++ b/config/schema/migrate_source_csv.source.schema.yml @@ -17,3 +17,6 @@ migrate.source.csv: column_names: type: sequence label: 'Numeric key 0-based index of the columns in source CSV file' + file_class: + type: string + label: 'Full class name that includes namespace for an alternative CSV reader' diff --git a/phpunit.xml.dist b/phpunit.xml.dist deleted file mode 100644 index ac02787..0000000 --- a/phpunit.xml.dist +++ /dev/null @@ -1,21 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> - -<phpunit bootstrap="tests/bootstrap.php" colors="true"> - <php> - <!-- Set error reporting to E_ALL. --> - <ini name="error_reporting" value="32767"/> - <!-- Do not limit the amount of memory tests take to run. --> - <ini name="memory_limit" value="-1"/> - </php> - <testsuites> - <testsuite name="Migrate CSV Test Suite"> - <directory>./tests/src/Unit</directory> - </testsuite> - </testsuites> - <!-- Filter for coverage reports. --> - <filter> - <whitelist processUncoveredFilesFromWhitelist="true"> - <directory>./src</directory> - </whitelist> - </filter> -</phpunit> diff --git a/src/Plugin/migrate/source/CSV.php b/src/Plugin/migrate/source/CSV.php index 94f48a0..cdba000 100644 --- a/src/Plugin/migrate/source/CSV.php +++ b/src/Plugin/migrate/source/CSV.php @@ -40,6 +40,20 @@ class CSV extends SourcePluginBase { */ protected $keys = []; + /** + * The file class to read the file. + * + * @var string + */ + protected $fileClass = ''; + + /** + * The file object that reads the CSV file. + * + * @var \SplFileObject + */ + protected $file = NULL; + /** * {@inheritdoc} */ @@ -56,6 +70,7 @@ class CSV extends SourcePluginBase { throw new MigrateException('You must declare "keys" as a unique array of fields in your source settings.'); } + $this->fileClass = empty($configuration['file_class']) ? CSVFileObject::class : $configuration['file_class']; } /** @@ -73,36 +88,36 @@ class CSV extends SourcePluginBase { */ public function initializeIterator() { // File handler using header-rows-respecting extension of SPLFileObject. - $file = new CSVFileObject($this->configuration['path']); + $this->file = new $this->fileClass($this->configuration['path']); // Set basics of CSV behavior based on configuration. $delimiter = !empty($this->configuration['delimiter']) ? $this->configuration['delimiter'] : ','; $enclosure = !empty($this->configuration['enclosure']) ? $this->configuration['enclosure'] : '"'; $escape = !empty($this->configuration['escape']) ? $this->configuration['escape'] : '\\'; - $file->setCsvControl($delimiter, $enclosure, $escape); + $this->file->setCsvControl($delimiter, $enclosure, $escape); // Figure out what CSV column(s) to use. Use either the header row(s) or // explicitly provided column name(s). if (!empty($this->configuration['header_row_count'])) { - $file->setHeaderRowCount($this->configuration['header_row_count']); + $this->file->setHeaderRowCount($this->configuration['header_row_count']); // Find the last header line. - $file->rewind(); - $file->seek($file->getHeaderRowCount() - 1); + $this->file->rewind(); + $this->file->seek($this->file->getHeaderRowCount() - 1); - $row = $file->current(); + $row = $this->file->current(); foreach ($row as $header) { $header = trim($header); $column_names[] = [$header => $header]; } - $file->setColumnNames($column_names); + $this->file->setColumnNames($column_names); } // An explicit list of column name(s) will override any header row(s). if (!empty($this->configuration['column_names'])) { - $file->setColumnNames($this->configuration['column_names']); + $this->file->setColumnNames($this->configuration['column_names']); } - return $file; + return $this->file; } /** diff --git a/tests/bootstrap.php b/tests/bootstrap.php deleted file mode 100644 index 079563d..0000000 --- a/tests/bootstrap.php +++ /dev/null @@ -1,27 +0,0 @@ -<?php - -/** - * @file - * Searches for the core bootstrap file. - */ - -$dir = __DIR__; - -// Match against previous dir for Windows. -$previous_dir = ''; - -while ($dir = dirname($dir)) { - // We've reached the root. - if ($dir === $previous_dir) { - break; - } - - $previous_dir = $dir; - - if (is_file($dir . '/core/tests/bootstrap.php')) { - require_once $dir . '/core/tests/bootstrap.php'; - return; - } -} - -throw new RuntimeException('Unable to load core bootstrap.php.'); diff --git a/tests/src/Unit/CSVFileObjectTest.php b/tests/src/Unit/CSVFileObjectTest.php index 9cc4754..2cf926d 100644 --- a/tests/src/Unit/CSVFileObjectTest.php +++ b/tests/src/Unit/CSVFileObjectTest.php @@ -33,11 +33,9 @@ class CSVFileObjectTest extends CSVUnitTestCase { /** * Tests that the construction appropriately creates a CSVFileObject. * - * @test - * * @covers ::__construct */ - public function create() { + public function testCreate() { $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()); @@ -46,11 +44,9 @@ class CSVFileObjectTest extends CSVUnitTestCase { /** * Tests that the header row count is correctly set. * - * @test - * * @covers ::setHeaderRowCount */ - public function setHeaderRowCount() { + public function testSetHeaderRowCount() { $expected = 2; $this->csvFileObject->setHeaderRowCount($expected); @@ -60,13 +56,11 @@ class CSVFileObjectTest extends CSVUnitTestCase { /** * Tests that the header row count is correctly returned. * - * @test - * * @depends setHeaderRowCount * * @covers ::getHeaderRowCount */ - public function getHeaderRowCount($actual) { + public function testGetHeaderRowCount($actual) { $expected = 2; $this->assertEquals($expected, $actual); } @@ -74,11 +68,9 @@ class CSVFileObjectTest extends CSVUnitTestCase { /** * Tests that line count is correct. * - * @test - * * @covers ::count */ - public function countLines() { + public function testCountLines() { $expected = 15; $this->csvFileObject->setHeaderRowCount(1); $actual = $this->csvFileObject->count(); @@ -89,14 +81,12 @@ class CSVFileObjectTest extends CSVUnitTestCase { /** * Tests that the current row is correctly returned. * - * @test - * * @covers ::current * @covers ::rewind * @covers ::getColumnNames * @covers ::setColumnNames */ - public function current() { + public function testCurrent() { $column_names = [ ['id' => 'Identifier'], ['first_name' => 'First Name'], diff --git a/tests/src/Unit/CSVUnitTestCase.php b/tests/src/Unit/CSVUnitTestCase.php index 69da1d5..270de60 100644 --- a/tests/src/Unit/CSVUnitTestCase.php +++ b/tests/src/Unit/CSVUnitTestCase.php @@ -34,6 +34,8 @@ abstract class CSVUnitTestCase extends UnitTestCase { * {@inheritdoc} */ protected function setUp() { + parent::setUp(); + $root_dir = vfsStream::setup('root'); $happy = <<<'EOD' id,first_name,last_name,email,country,ip_address diff --git a/tests/src/Unit/Plugin/migrate/source/CSVTest.php b/tests/src/Unit/Plugin/migrate/source/CSVTest.php index 0e5e4fc..c9aa05f 100644 --- a/tests/src/Unit/Plugin/migrate/source/CSVTest.php +++ b/tests/src/Unit/Plugin/migrate/source/CSVTest.php @@ -7,9 +7,9 @@ namespace Drupal\Tests\migrate_source_csv\Unit\Plugin\migrate\source; use Drupal\migrate\Plugin\MigrationInterface; +use Drupal\migrate_source_csv\CSVFileObject; use Drupal\migrate_source_csv\Plugin\migrate\source\CSV; use Drupal\Tests\migrate_source_csv\Unit\CSVUnitTestCase; -use Prophecy\Argument; /** * @coversDefaultClass \Drupal\migrate_source_csv\Plugin\migrate\source\CSV @@ -52,9 +52,6 @@ class CSVTest extends CSVUnitTestCase { $plugin = $this->prophesize(MigrationInterface::class); $plugin->getIdMap() ->willReturn(NULL); - // @topo Swap it out for getHighWaterProperty after https://www.drupal.org/node/2694009 - $plugin->getHighWaterProperty() - ->willReturn(NULL); $this->plugin = $plugin->reveal(); } @@ -62,11 +59,9 @@ class CSVTest extends CSVUnitTestCase { /** * Tests the construction of CSV. * - * @test - * * @covers ::__construct */ - public function create() { + public function testCreate() { $configuration = [ 'path' => $this->happyPath, 'keys' => ['id'], @@ -81,26 +76,22 @@ class CSVTest extends CSVUnitTestCase { /** * 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 migrateExceptionPathMissing() { + public function testMigrateExceptionPathMissing() { 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 migrateExceptionKeysMissing() { + public function testMigrateExceptionKeysMissing() { $configuration = [ 'path' => $this->happyPath, ]; @@ -111,11 +102,9 @@ class CSVTest extends CSVUnitTestCase { /** * Tests that toString functions as expected. * - * @test - * * @covers ::__toString */ - public function toString() { + public function testToString() { $configuration = [ 'path' => $this->happyPath, 'keys' => ['id'], @@ -130,11 +119,9 @@ class CSVTest extends CSVUnitTestCase { /** * Tests initialization of the iterator. * - * @test - * * @covers ::initializeIterator */ - public function initializeIterator() { + public function testInitializeIterator() { $configuration = [ 'path' => $this->happyPath, 'keys' => ['id'], @@ -227,11 +214,9 @@ class CSVTest extends CSVUnitTestCase { /** * Tests that the key is properly identified. * - * @test - * * @covers ::getIds */ - public function getIds() { + public function testGetIds() { $configuration = [ 'path' => $this->happyPath, 'keys' => ['id'], @@ -247,11 +232,9 @@ class CSVTest extends CSVUnitTestCase { /** * Tests that fields have a machine name and description. * - * @test - * * @covers ::fields */ - public function fields() { + public function testFields() { $configuration = [ 'path' => $this->happyPath, 'keys' => ['id'], @@ -263,11 +246,11 @@ class CSVTest extends CSVUnitTestCase { ]; $expected = $fields + [ - 'last_name' => 'last_name', - 'email' => 'email', - 'country' => 'country', - 'ip_address' => 'ip_address', - ]; + 'last_name' => 'last_name', + 'email' => 'email', + 'country' => 'country', + 'ip_address' => 'ip_address', + ]; $csv = new CSV($configuration, $this->pluginId, $this->pluginDefinition, $this->plugin); $csv = new CSV($configuration + ['fields' => $fields], $this->pluginId, $this->pluginDefinition, $this->plugin); @@ -278,10 +261,39 @@ class CSVTest extends CSVUnitTestCase { 2 => ['first_name' => 'User first name'], ]; $csv = new CSV($configuration + [ - 'fields' => $fields, - 'column_names' => $column_names, - ], $this->pluginId, $this->pluginDefinition, $this->plugin); + 'fields' => $fields, + 'column_names' => $column_names, + ], $this->pluginId, $this->pluginDefinition, $this->plugin); $this->assertArrayEquals($fields, $csv->fields()); } + /** + * Tests configurable CSV file object. + * + * @covers ::__construct + */ + public function testConfigurableCSVFileObject() { + $configuration = [ + 'path' => $this->happyPath, + 'keys' => ['id'], + 'header_row_count' => 1, + 'file_class' => FooCSVFileObject::class , + ]; + + $csv = new CSV($configuration, $this->pluginId, $this->pluginDefinition, $this->plugin); + $csv->initializeIterator(); + $fileObject = $this->readAttribute($csv, 'file'); + + $this->assertInstanceOf(FooCSVFileObject::class, $fileObject); + } + } + +/** + * Class FooCSVFileObject + * + * Test file object class. + * + * @package Drupal\Tests\migrate_source_csv\Unit\Plugin\migrate\source + */ +class FooCSVFileObject extends CSVFileObject { } -- GitLab