release 1.0

This commit is contained in:
Reindl David (IT-PTR-CEN2-SL10)
2026-05-02 17:53:19 +02:00
parent b1cad04fdf
commit 170b2d2016
26 changed files with 5748 additions and 0 deletions
+199
View File
@@ -0,0 +1,199 @@
<?php
namespace UbsCsvTransformer\Tests;
use PHPUnit\Framework\TestCase;
use UbsCsvTransformer\CsvReader;
class CsvReaderTest extends TestCase
{
private string $tempFile = '';
protected function setUp(): void
{
$this->tempFile = tempnam(sys_get_temp_dir(), 'csvreader_test_');
}
protected function tearDown(): void
{
if (file_exists($this->tempFile)) {
unlink($this->tempFile);
}
}
private function write(string $content): void
{
file_put_contents($this->tempFile, $content);
}
private function reader(int $headerLine = 1, string $delimiter = ';', bool $hasBom = false): CsvReader
{
return new CsvReader(
$this->tempFile,
['inputDelimiter' => $delimiter, 'headerLine' => $headerLine, 'hasBom' => $hasBom]
);
}
// -------------------------------------------------------------------------
// readCsvData – basic parsing
// -------------------------------------------------------------------------
public function testReadCsvDataSimple(): void
{
$this->write("Name;Age\nAlice;30\nBob;25\n");
$data = $this->reader()->readCsvData();
$this->assertCount(2, $data);
$this->assertSame('Alice', $data[0]['Name']);
$this->assertSame('30', $data[0]['Age']);
$this->assertSame('Bob', $data[1]['Name']);
}
public function testReadCsvDataTrimsWhitespace(): void
{
$this->write("Name ; Age\n Alice ; 30 \n");
$data = $this->reader()->readCsvData();
$this->assertSame('Alice', $data[0]['Name']);
$this->assertSame('30', $data[0]['Age']);
}
// -------------------------------------------------------------------------
// headerLine offset
// -------------------------------------------------------------------------
public function testHeaderLineOffset(): void
{
// Lines 1+2 are metadata, header is line 3
$this->write("Meta1\nMeta2\nColA;ColB\nval1;val2\n");
$data = $this->reader(3)->readCsvData();
$this->assertCount(1, $data);
$this->assertSame('val1', $data[0]['ColA']);
$this->assertSame('val2', $data[0]['ColB']);
}
// -------------------------------------------------------------------------
// readMetadataLines
// -------------------------------------------------------------------------
public function testReadMetadataLines(): void
{
$this->write("Line1\nLine2\nHeader;Col\nData;Row\n");
$meta = $this->reader(3)->readMetadataLines();
$this->assertCount(2, $meta);
$this->assertSame('Line1', $meta[0]);
$this->assertSame('Line2', $meta[1]);
}
public function testReadMetadataLinesHeaderOnLine1IsEmpty(): void
{
$this->write("Name;Age\nAlice;30\n");
$meta = $this->reader(1)->readMetadataLines();
$this->assertSame([], $meta);
}
public function testReadMetadataLinesHeaderOnLine2ReturnsOneLine(): void
{
$this->write("MetaInfo\nName;Age\nAlice;30\n");
$meta = $this->reader(2)->readMetadataLines();
$this->assertCount(1, $meta);
$this->assertSame('MetaInfo', $meta[0]);
}
// -------------------------------------------------------------------------
// maxDataRows limit
// -------------------------------------------------------------------------
public function testMaxDataRowsLimit(): void
{
$this->write("Name;Age\nAlice;30\nBob;25\nCarol;20\n");
$data = $this->reader()->readCsvData(2);
$this->assertCount(2, $data);
$this->assertSame('Alice', $data[0]['Name']);
$this->assertSame('Bob', $data[1]['Name']);
}
public function testMaxDataRowsZeroMeansAll(): void
{
$this->write("Name;Age\nAlice;30\nBob;25\nCarol;20\n");
$data = $this->reader()->readCsvData(0);
$this->assertCount(3, $data);
}
// -------------------------------------------------------------------------
// Empty line skipping
// -------------------------------------------------------------------------
public function testEmptyLinesAreSkipped(): void
{
$this->write("Name;Age\nAlice;30\n\nBob;25\n\n");
$data = $this->reader()->readCsvData();
$this->assertCount(2, $data);
}
// -------------------------------------------------------------------------
// BOM removal
// -------------------------------------------------------------------------
public function testBomIsRemovedFromFirstColumnName(): void
{
// UTF-8 BOM followed immediately by the header
$this->write("\xEF\xBB\xBFName;Age\nAlice;30\n");
$data = $this->reader(1, ';', true)->readCsvData();
$this->assertCount(1, $data);
// The column must be 'Name', not the BOM-prefixed version
$this->assertArrayHasKey('Name', $data[0]);
$this->assertSame('Alice', $data[0]['Name']);
}
public function testNoBomFlagLeavesHeaderIntact(): void
{
// If hasBom is false, BOM bytes stay and the key will be mangled — we only
// assert that the clean path (hasBom=true) works, tested above.
// Here we just verify normal CSV without BOM also works when hasBom=false.
$this->write("Name;Age\nAlice;30\n");
$data = $this->reader(1, ';', false)->readCsvData();
$this->assertArrayHasKey('Name', $data[0]);
}
// -------------------------------------------------------------------------
// getHeaders
// -------------------------------------------------------------------------
public function testGetHeaders(): void
{
$this->write("Col1;Col2;Col3\nA;B;C\n");
$headers = $this->reader()->getHeaders();
$this->assertSame(['Col1', 'Col2', 'Col3'], $headers);
}
// -------------------------------------------------------------------------
// Row with fewer columns than headers
// -------------------------------------------------------------------------
public function testShortRowPaddedWithEmpty(): void
{
$this->write("A;B;C\n1;2\n");
$data = $this->reader()->readCsvData();
$this->assertCount(1, $data);
$this->assertSame('1', $data[0]['A']);
$this->assertSame('2', $data[0]['B']);
$this->assertSame('', $data[0]['C']);
}
// -------------------------------------------------------------------------
// Error cases
// -------------------------------------------------------------------------
public function testFileNotFoundThrowsRuntimeException(): void
{
$this->expectException(\RuntimeException::class);
$reader = new CsvReader('/nonexistent/path/file.csv', ['inputDelimiter' => ';', 'headerLine' => 1]);
$reader->readLines();
}
public function testHeaderLineBeyondFileLengthThrows(): void
{
$this->write("Name;Age\nAlice;30\n");
$this->expectException(\RuntimeException::class);
$this->reader(99)->readCsvData();
}
}