feeds-8.x-3.0-alpha1/tests/src/Unit/Component/CsvParserTest.php
tests/src/Unit/Component/CsvParserTest.php
<?php
namespace Drupal\Tests\feeds\Unit\Component;
use Drupal\feeds\Component\CsvParser;
use Drupal\Tests\feeds\Unit\FeedsUnitTestCase;
/**
* @coversDefaultClass \Drupal\feeds\Component\CsvParser
* @group feeds
*/
class CsvParserTest extends FeedsUnitTestCase {
/**
* Tests parsing a CSV source with several line endings.
*
* @dataProvider provider
*/
public function testAlternateLineEnding(array $expected, $ending) {
$text = file_get_contents(dirname(dirname(dirname(dirname(__DIR__)))) . '/tests/resources/csv/example.csv');
$text = str_replace("\r\n", $ending, $text);
$parser = new \LimitIterator(CsvParser::createFromString($text), 0, 4);
$first = array_slice($expected, 0, 4);
$this->assertSame(count(iterator_to_array($parser)), 4);
$this->assertSame(count(iterator_to_array($parser)), 4);
foreach ($parser as $delta => $row) {
$this->assertSame($first[$delta], $row);
}
// Test second batch.
$last_pos = $parser->lastLinePos();
$parser = (new \LimitIterator(CsvParser::createFromString($text), 0, 4))->setStartByte($last_pos);
$second = array_slice($expected, 4);
// // Test that rewinding works as expected.
$this->assertSame(2, count(iterator_to_array($parser)));
$this->assertSame(2, count(iterator_to_array($parser)));
foreach ($parser as $delta => $row) {
$this->assertSame($second[$delta], $row);
}
}
/**
* Data provider for testAlternateLineEnding().
*/
public function provider() {
$expected = [
['Header A', 'Header B', 'Header C'],
['"1"', '"2"', '"3"'],
['qu"ote', 'qu"ote', 'qu"ote'],
["\r\n\r\nline1", "\r\n\r\nline2", "\r\n\r\nline3"],
["new\r\nline 1", "new\r\nline 2", "new\r\nline 3"],
["\r\n\r\nline1\r\n\r\n", "\r\n\r\nline2\r\n\r\n", "\r\n\r\nline3\r\n\r\n"],
];
$unix = $expected;
array_walk_recursive($unix, function (&$item, $key) {
$item = str_replace("\r\n", "\n", $item);
});
$mac = $expected;
array_walk_recursive($mac, function (&$item, $key) {
$item = str_replace("\r\n", "\r", $item);
});
return [
[$expected, "\r\n"],
[$unix, "\n"],
[$mac, "\r"],
];
}
/**
* @covers ::setHasHeader
* @covers ::getHeader
*/
public function testHasHeader() {
$file = dirname(dirname(dirname(dirname(__DIR__)))) . '/tests/resources/csv/example.csv';
$parser = CsvParser::createFromFilePath($file)->setHasHeader();
$this->assertSame(count(iterator_to_array($parser)), 5);
$this->assertSame(['Header A', 'Header B', 'Header C'], $parser->getHeader());
}
/**
* Tests using an asterisk as delimiter.
*/
public function testAlternateSeparator() {
// This implicitly tests lines without a newline.
$parser = CsvParser::createFromString("a*b*c")
->setDelimiter('*');
$this->assertSame(['a', 'b', 'c'], iterator_to_array($parser)[0]);
}
/**
* Tries to create a CsvParser instance with an invalid file path.
*
* @expectedException \InvalidArgumentException
*/
public function testInvalidFilePath() {
CsvParser::createFromFilePath('beep boop');
}
/**
* Creates a new CsvParser instance with an invalid CSV source.
*
* @expectedException \InvalidArgumentException
*/
public function testInvalidResourcePath() {
new CsvParser('beep boop');
}
/**
* Basic test for parsing CSV.
*
* @dataProvider csvFileProvider
*/
public function testCsvParsing($file, $expected) {
$parser = CsvParser::createFromFilePath($file);
$parser->setHasHeader();
$header = $parser->getHeader();
$output = [];
$test = [];
foreach (iterator_to_array($parser) as $row) {
$new_row = [];
foreach ($row as $key => $value) {
if (isset($header[$key])) {
$new_row[$header[$key]] = $value;
}
}
$output[] = $new_row;
}
$this->assertSame($expected, $output);
}
/**
* Data provider for testCsvParsing().
*/
public function csvFileProvider() {
$path = dirname(dirname(dirname(dirname(__DIR__)))) . '/tests/resources/csv-parser-component-files';
$return = [];
foreach (glob($path . '/csv/*.csv') as $file) {
$json_file = $path . '/json/' . str_replace('.csv', '.json', basename($file));
$return[] = [
$file,
json_decode(file_get_contents($json_file), TRUE),
];
}
return $return;
}
}
