diff --git a/.travis.yml b/.travis.yml index 9ccebcf..ab8f147 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,26 +1,31 @@ language: php + +sudo: false + php: - - '5.4' - - '5.5' - - '5.6' - - '7.0' + - 7.2 + - 7.3 + - 7.4 + +cache: + directories: + - $HOME/.composer/cache + env: - - SYMFONY_VERSION=2.3.* - - SYMFONY_VERSION=2.7.* - - SYMFONY_VERSION=2.8.* - - SYMFONY_VERSION=3.0.* - - SYMFONY_VERSION=3.1.* -# - SYMFONY_VERSION=dev-master -matrix: - exclude: - - php: '5.4' - env: SYMFONY_VERSION=3.0.* - - php: '5.4' - env: SYMFONY_VERSION=3.1.* -# - php: '5.4' -# env: SYMFONY_VERSION=dev-master + matrix: + - SYMFONY_VERSION=3.4.* + - SYMFONY_VERSION=4.4.* + before_install: + - travis_retry composer self-update - composer require "symfony/framework-bundle:${SYMFONY_VERSION}" --no-update - composer require "symfony/property-access:${SYMFONY_VERSION}" --dev --no-update -install: composer install -script: bin/phpunit + +install: + - travis_retry composer require --no-update symfony/framework-bundle:${SYMFONY_VERSION} + - travis_retry composer update ${COMPOSER_FLAGS} --prefer-source --no-interaction + +script: + - "composer test" + - "composer psalm" + - "phpunit --testsuite=unit --coverage-text --coverage-clover build/logs/clover.xml" diff --git a/Configuration/AbstractConfiguration.php b/Configuration/AbstractConfiguration.php index a8e024c..b4478eb 100644 --- a/Configuration/AbstractConfiguration.php +++ b/Configuration/AbstractConfiguration.php @@ -9,9 +9,9 @@ */ abstract class AbstractConfiguration { - const LINE_ENDING_CRLF = "\r\n"; - const LINE_ENDING_LF = "\n"; - const LINE_ENDING_CR = "\r"; + public const LINE_ENDING_CRLF = "\r\n"; + public const LINE_ENDING_LF = "\n"; + public const LINE_ENDING_CR = "\r"; /** * Delimiting character @@ -31,7 +31,7 @@ abstract class AbstractConfiguration * * @return string */ - public function getDelimiter() + public function getDelimiter(): string { return $this->delimiter; } @@ -43,11 +43,12 @@ public function getDelimiter() * * @throws InvalidConfigurationException */ - public function setDelimiter($delimiter) + public function setDelimiter($delimiter): void { - if (strlen($delimiter) != 1) { + if (strlen($delimiter) !== 1) { throw new InvalidConfigurationException('CSV Configuration error: Delimiter must be exactly 1 character'); } + $this->delimiter = $delimiter; } @@ -68,11 +69,12 @@ public function getLineEnding() * * @throws InvalidConfigurationException */ - public function setLineEnding($lineEnding) + public function setLineEnding($lineEnding): void { - if (!in_array($lineEnding, array(self::LINE_ENDING_CR, self::LINE_ENDING_CRLF, self::LINE_ENDING_LF))) { + if (!in_array($lineEnding, array(self::LINE_ENDING_CR, self::LINE_ENDING_CRLF, self::LINE_ENDING_LF), true)) { throw new InvalidConfigurationException('Invalid line ending provided. Only CR,LF and CRLF allowed'); } + $this->lineEnding = $lineEnding; } } diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php index cb05d39..a5af75b 100644 --- a/DependencyInjection/Configuration.php +++ b/DependencyInjection/Configuration.php @@ -19,10 +19,16 @@ class Configuration implements ConfigurationInterface /** * {@inheritDoc} */ - public function getConfigTreeBuilder() + public function getConfigTreeBuilder(): TreeBuilder { - $treeBuilder = new TreeBuilder(); - $rootNode = $treeBuilder->root('kuborgh_csv'); + $treeBuilder = new TreeBuilder('kuborgh_csv'); + if (method_exists($treeBuilder, 'getRootNode')) { + $rootNode = $treeBuilder->getRootNode(); + } else { + /** @psalm-suppress UndefinedMethod */ + /** @psalm-suppress DeprecatedMethod */ + $rootNode = $treeBuilder->root('kuborgh_csv'); + } $rootNode ->children() diff --git a/DependencyInjection/KuborghCsvExtension.php b/DependencyInjection/KuborghCsvExtension.php index b917b3a..9519c65 100644 --- a/DependencyInjection/KuborghCsvExtension.php +++ b/DependencyInjection/KuborghCsvExtension.php @@ -8,6 +8,7 @@ namespace Kuborgh\CsvBundle\DependencyInjection; +use Exception; use Symfony\Component\Config\FileLocator; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Definition; @@ -23,6 +24,8 @@ class KuborghCsvExtension extends Extension { /** * {@inheritDoc} + * + * @throws Exception */ public function load(array $configs, ContainerBuilder $container) { @@ -43,7 +46,7 @@ public function load(array $configs, ContainerBuilder $container) * @param array $config Config * @param ContainerBuilder $container Container */ - protected function loadParserConfig(array $config, ContainerBuilder $container) + protected function loadParserConfig(array $config, ContainerBuilder $container): void { foreach ($config as $parserName => $parserConfig) { $parserConfigClass = $container->getParameter('kuborgh_csv.configuration.parser.class'); @@ -66,7 +69,7 @@ protected function loadParserConfig(array $config, ContainerBuilder $container) * @param array $config Config * @param ContainerBuilder $container Container */ - protected function loadGeneratorConfig(array $config, ContainerBuilder $container) + protected function loadGeneratorConfig(array $config, ContainerBuilder $container): void { foreach ($config as $parserName => $parserConfig) { // Prepare config object with common settings @@ -92,7 +95,7 @@ protected function loadGeneratorConfig(array $config, ContainerBuilder $containe * * @return Definition */ - protected function loadCommonConfig($parserConfig, $parserConfigClass) + protected function loadCommonConfig($parserConfig, $parserConfigClass): Definition { $parserConfigDef = new Definition($parserConfigClass); diff --git a/Generator/GeneratorInterface.php b/Generator/GeneratorInterface.php index 9369a86..e6162b3 100644 --- a/Generator/GeneratorInterface.php +++ b/Generator/GeneratorInterface.php @@ -23,5 +23,5 @@ public function __construct(GeneratorConfiguration $configuration); * * @return string CSV */ - public function generate(array $array); + public function generate(array $array): string; } diff --git a/Generator/PhpGenerator.php b/Generator/PhpGenerator.php index 4d48e72..04cdbb7 100644 --- a/Generator/PhpGenerator.php +++ b/Generator/PhpGenerator.php @@ -2,12 +2,14 @@ namespace Kuborgh\CsvBundle\Generator; +use InvalidArgumentException; + /** * Generates CSV by means of native php function fputcsv() * This may not be conform to rfc4180. * Also the line ending is for example not configurable */ -class PhpGenerator extends AbstractGenerator implements GeneratorInterface +class PhpGenerator extends AbstractGenerator { /** * Generate csv string from array @@ -16,14 +18,14 @@ class PhpGenerator extends AbstractGenerator implements GeneratorInterface * * @return string CSV */ - public function generate(array $array) + public function generate(array $array): string { - $buffer = fopen('php://temp', 'r+'); + $buffer = fopen('php://temp', 'rb+'); $delim = $this->configuration->getDelimiter(); foreach ($array as $row) { if (!is_array($row)) { - throw new \InvalidArgumentException('Expecting a 2-dimensional array as value'); + throw new InvalidArgumentException('Expecting a 2-dimensional array as value'); } fputcsv($buffer, $row, $delim); } diff --git a/Generator/StringGenerator.php b/Generator/StringGenerator.php index 0a9a7d7..05e1fef 100644 --- a/Generator/StringGenerator.php +++ b/Generator/StringGenerator.php @@ -5,7 +5,7 @@ /** * Generates rfc4180 conform csv by concatenating strings */ -class StringGenerator extends AbstractGenerator implements GeneratorInterface +class StringGenerator extends AbstractGenerator { /** * Generate csv string from array @@ -14,7 +14,7 @@ class StringGenerator extends AbstractGenerator implements GeneratorInterface * * @return string CSV */ - public function generate(array $array) + public function generate(array $array): string { $delim = $this->configuration->getDelimiter(); $lineEnd = $this->configuration->getLineEnding(); @@ -52,8 +52,7 @@ public function generate(array $array) } $lines[] = implode($delim, $newRow); } - $string = implode($lineEnd, $lines); - return $string; + return implode($lineEnd, $lines); } } diff --git a/Parser/CharacterParser.php b/Parser/CharacterParser.php index 2982a4c..4e4a4d6 100644 --- a/Parser/CharacterParser.php +++ b/Parser/CharacterParser.php @@ -8,7 +8,7 @@ * Full-featured rfc4180 parser, but may be slow for large files. * The csv is parsed bytewise with lookahead */ -class CharacterParser extends AbstractParser implements ParserInterface +class CharacterParser extends AbstractParser { /** * Pointer to the next character being read @@ -59,7 +59,7 @@ class CharacterParser extends AbstractParser implements ParserInterface * * @return array */ - public function parse($csvString) + public function parse($csvString): array { $this->init($csvString); @@ -88,7 +88,7 @@ public function parse($csvString) case $lineBreak1: // Do we need an extra character? if ($lineBreak2) { - if ($this->preview() == $lineBreak2) { + if ($this->preview() === $lineBreak2) { $this->read(); $this->finishField(); $this->finishRow(); @@ -119,7 +119,7 @@ public function parse($csvString) * * @param string $csvString */ - protected function init($csvString) + protected function init(string $csvString): void { $this->nextChar = 0; $this->csvString = $csvString; @@ -130,9 +130,10 @@ protected function init($csvString) * Read the current character and forward the pointer * * @return string one character + * * @throws EofException */ - protected function read() + protected function read(): string { $char = $this->preview(); $this->nextChar++; @@ -144,16 +145,16 @@ protected function read() * Peak into the next character without forwarding the pointer * * @return string one character + * * @throws EofException */ - protected function preview() + protected function preview(): string { if ($this->nextChar >= $this->csvLength) { throw new EofException('EOF reached'); } - $char = $this->csvString[$this->nextChar]; - return $char; + return $this->csvString[$this->nextChar]; } /** @@ -161,12 +162,13 @@ protected function preview() * NOTE: The pointer is increased more than it is read (to simulate the quote has been read, too) * * @return string + * * @throws EofException */ - protected function leap() + protected function leap(): string { $pos = strpos($this->csvString, '"', $this->nextChar); - if ($pos === false) { + if (false === $pos) { throw new EofException('EOF reached (in quoted string)'); } $chars = substr($this->csvString, $this->nextChar, $pos - $this->nextChar); @@ -178,7 +180,7 @@ protected function leap() /** * Read quoted string until quote end is reached. */ - protected function readQuotedString() + protected function readQuotedString(): void { do { // Leap forward to next quotation mark @@ -186,7 +188,7 @@ protected function readQuotedString() try { // Two quotes are one quote in the string - if ($this->preview() == '"') { + if ('"' === $this->preview()) { $this->field .= $this->read(); } else { // Quote ended @@ -203,7 +205,7 @@ protected function readQuotedString() * * @param bool $force When force is true, even empty fields are added */ - protected function finishField($force = true) + protected function finishField($force = true): void { if ($force || !empty($this->field)) { $this->row[] = $this->field; @@ -214,7 +216,7 @@ protected function finishField($force = true) /** * Row is complete and can be added to result */ - protected function finishRow() + protected function finishRow(): void { $this->rows[] = $this->row; $this->row = array(); diff --git a/Parser/ParserInterface.php b/Parser/ParserInterface.php index c489bb0..bf6dc03 100644 --- a/Parser/ParserInterface.php +++ b/Parser/ParserInterface.php @@ -23,5 +23,5 @@ public function __construct(ParserConfiguration $configuration); * * @return array */ - public function parse($csvString); + public function parse($csvString): array; } diff --git a/Parser/SimpleParser.php b/Parser/SimpleParser.php index f37c53a..dd69f70 100644 --- a/Parser/SimpleParser.php +++ b/Parser/SimpleParser.php @@ -5,7 +5,7 @@ /** * Very very simple CSV Parser without escaping support */ -class SimpleParser extends AbstractParser implements ParserInterface +class SimpleParser extends AbstractParser { /** * Parse the given string into an php array @@ -14,7 +14,7 @@ class SimpleParser extends AbstractParser implements ParserInterface * * @return array */ - public function parse($csvString) + public function parse($csvString): array { $lineEnding = $this->configuration->getLineEnding(); $delimiter = $this->configuration->getDelimiter(); diff --git a/Test/Configuration/AbstractConfigrationTest.php b/Test/Configuration/AbstractConfigrationTest.php deleted file mode 100644 index 7cf3154..0000000 --- a/Test/Configuration/AbstractConfigrationTest.php +++ /dev/null @@ -1,46 +0,0 @@ -assertEquals(',', $this->configration->getDelimiter()); - $this->configration->setDelimiter(';'); - $this->assertEquals(';', $this->configration->getDelimiter()); - } - - /** - * @expectedException \Kuborgh\CsvBundle\Exception\InvalidConfigurationException - */ - public function testInvalidDelimiter() - { - $this->configration->setDelimiter('\/'); - } - - public function testLineEnding() - { - $this->assertEquals("\r\n", $this->configration->getLineEnding()); - $this->configration->setLineEnding("\n"); - $this->assertEquals("\n", $this->configration->getLineEnding()); - $this->configration->setLineEnding("\r"); - $this->assertEquals("\r", $this->configration->getLineEnding()); - } - - /** - * @expectedException \Kuborgh\CsvBundle\Exception\InvalidConfigurationException - */ - public function testInvalidLineEnding() - { - $this->configration->setLineEnding('+'); - } -} diff --git a/Test/Configuration/AbstractConfigurationTest.php b/Test/Configuration/AbstractConfigurationTest.php new file mode 100644 index 0000000..3d0bf18 --- /dev/null +++ b/Test/Configuration/AbstractConfigurationTest.php @@ -0,0 +1,58 @@ +assertEquals(',', $this->configuration->getDelimiter()); + $this->configuration->setDelimiter(';'); + $this->assertEquals(';', $this->configuration->getDelimiter()); + } + + /** + * @throws InvalidConfigurationException + */ + public function testInvalidDelimiter(): void + { + $this->expectException(InvalidConfigurationException::class); + + $this->configuration->setDelimiter('\/'); + } + + /** + * @throws InvalidConfigurationException + */ + public function testLineEnding(): void + { + $this->assertEquals("\r\n", $this->configuration->getLineEnding()); + $this->configuration->setLineEnding("\n"); + $this->assertEquals("\n", $this->configuration->getLineEnding()); + $this->configuration->setLineEnding("\r"); + $this->assertEquals("\r", $this->configuration->getLineEnding()); + } + + /** + * @throws InvalidConfigurationException + */ + public function testInvalidLineEnding(): void + { + $this->expectException(InvalidConfigurationException::class); + + $this->configuration->setLineEnding('+'); + } +} diff --git a/Test/Configuration/ParserConfigrationTest.php b/Test/Configuration/ParserConfigurationTest.php similarity index 66% rename from Test/Configuration/ParserConfigrationTest.php rename to Test/Configuration/ParserConfigurationTest.php index 8fc7690..f57887e 100644 --- a/Test/Configuration/ParserConfigrationTest.php +++ b/Test/Configuration/ParserConfigurationTest.php @@ -7,8 +7,8 @@ */ class ParserConfigurationTest extends AbstractConfigurationTest { - protected function setUp() + public function setUp(): void { - $this->configration = new ParserConfiguration(); + $this->configuration = new ParserConfiguration(); } } diff --git a/Test/DependencyInjectionTest.php b/Test/DependencyInjectionTest.php index bda6d8d..9491cfe 100644 --- a/Test/DependencyInjectionTest.php +++ b/Test/DependencyInjectionTest.php @@ -1,13 +1,17 @@ container = new ContainerBuilder(); + $this->extension = new KuborghCsvExtension(); + } + + /** + * @throws ReflectionException + * @throws Exception + */ + public function testDefaultParserConfiguration(): void { $config = array('kuborgh_csv' => array('parser' => array('test' => array()))); $this->extension->load($config, $this->container); - /** @var \Kuborgh\CsvBundle\Parser\ParserInterface $testParser */ + /** @var ParserInterface $testParser */ $testParser = $this->container->get('kuborgh_csv.parser.test'); $class = new ReflectionClass(get_class($testParser)); $reflCconfig = $class->getProperty('configuration'); $reflCconfig->setAccessible(true); - /** @var \Kuborgh\CsvBundle\Configuration\ParserConfiguration $config */ + /** @var ParserConfiguration $config */ $config = $reflCconfig->getValue($testParser); $this->assertEquals(',', $config->getDelimiter()); $this->assertEquals("\r\n", $config->getLineEnding()); } - public function testParserConfiguration() + /** + * @throws ReflectionException + * @throws Exception + */ + public function testParserConfiguration(): void { $config = array( 'kuborgh_csv' => array( @@ -52,7 +70,7 @@ public function testParserConfiguration() ); $this->extension->load($config, $this->container); - /** @var \Kuborgh\CsvBundle\Parser\ParserInterface $testParser */ + /** @var ParserInterface $testParser */ $testParser = $this->container->get('kuborgh_csv.parser.test'); $class = new ReflectionClass(get_class($testParser)); @@ -64,25 +82,33 @@ public function testParserConfiguration() $this->assertEquals("\n", $config->getLineEnding()); } - public function testDefaultGeneratorConfiguration() + /** + * @throws ReflectionException + * @throws Exception + */ + public function testDefaultGeneratorConfiguration(): void { $config = array('kuborgh_csv' => array('generator' => array('test' => array()))); $this->extension->load($config, $this->container); - /** @var \Kuborgh\CsvBundle\Generator\GeneratorInterface $testGenerator */ + /** @var GeneratorInterface $testGenerator */ $testGenerator = $this->container->get('kuborgh_csv.generator.test'); $class = new ReflectionClass(get_class($testGenerator)); $reflCconfig = $class->getProperty('configuration'); $reflCconfig->setAccessible(true); - /** @var \Kuborgh\CsvBundle\Configuration\ParserConfiguration $config */ + /** @var ParserConfiguration $config */ $config = $reflCconfig->getValue($testGenerator); $this->assertEquals(',', $config->getDelimiter()); $this->assertEquals("\r\n", $config->getLineEnding()); } - public function testGeneratorConfiguration() + /** + * @throws ReflectionException + * @throws Exception + */ + public function testGeneratorConfiguration(): void { $config = array( 'kuborgh_csv' => array( @@ -97,7 +123,7 @@ public function testGeneratorConfiguration() ); $this->extension->load($config, $this->container); - /** @var \Kuborgh\CsvBundle\Generator\PhpGenerator $testGenerator */ + /** @var PhpGenerator $testGenerator */ $testGenerator = $this->container->get('kuborgh_csv.generator.test'); $class = new ReflectionClass(get_class($testGenerator)); @@ -108,10 +134,4 @@ public function testGeneratorConfiguration() $this->assertEquals('7', $config->getDelimiter()); $this->assertEquals("\n", $config->getLineEnding()); } - - protected function setUp() - { - $this->container = new ContainerBuilder(); - $this->extension = new KuborghCsvExtension(); - } } diff --git a/Test/Generator/AbstractGeneratorTest.php b/Test/Generator/AbstractGeneratorTest.php index 8b5b0e3..365505f 100644 --- a/Test/Generator/AbstractGeneratorTest.php +++ b/Test/Generator/AbstractGeneratorTest.php @@ -2,19 +2,20 @@ use Kuborgh\CsvBundle\Configuration\GeneratorConfiguration; use Kuborgh\CsvBundle\Generator\GeneratorInterface; +use PHPUnit\Framework\TestCase; use Symfony\Component\PropertyAccess\PropertyAccess; /** * Test generator */ -abstract class AbstractGeneratorTest extends PHPUnit_Framework_TestCase +abstract class AbstractGeneratorTest extends TestCase { /** * @var GeneratorInterface */ protected $generator; - protected function setUp() + protected function setUp(): void { $this->setConfiguration(); } @@ -24,7 +25,7 @@ protected function setUp() * * @param array $config */ - protected function setConfiguration(array $config = array()) + protected function setConfiguration(array $config = array()): void { // apply attributes $configObj = new GeneratorConfiguration(); @@ -44,5 +45,5 @@ protected function setConfiguration(array $config = array()) * * @return GeneratorInterface */ - abstract protected function newGenerator(GeneratorConfiguration $config); + abstract protected function newGenerator(GeneratorConfiguration $config): GeneratorInterface; } diff --git a/Test/Generator/PhpGeneratorTest.php b/Test/Generator/PhpGeneratorTest.php index d7b915e..15009dc 100644 --- a/Test/Generator/PhpGeneratorTest.php +++ b/Test/Generator/PhpGeneratorTest.php @@ -9,7 +9,7 @@ */ class PhpGeneratorTest extends AbstractGeneratorTest { - public function testSimpleCsv() + public function testSimpleCsv(): void { $array = array( array('a', 'b', 1), @@ -19,7 +19,7 @@ public function testSimpleCsv() $this->assertEquals("a,b,1\nc,hallo,welt\n", $csv); } - public function testOtherDelimiter() + public function testOtherDelimiter(): void { $this->setConfiguration(array('delimiter' => ';')); $array = array( @@ -30,11 +30,10 @@ public function testOtherDelimiter() $this->assertEquals("a;b;1\nc;hallo;welt\n", $csv); } - /** - * @expectedException \InvalidArgumentException - */ - public function testInvalidData() + public function testInvalidData(): array { + $this->expectException(InvalidArgumentException::class); + $array = array(7); $this->generator->generate($array); } @@ -46,7 +45,7 @@ public function testInvalidData() * * @return GeneratorInterface */ - protected function newGenerator(GeneratorConfiguration $config) + protected function newGenerator(GeneratorConfiguration $config): GeneratorInterface { return new PhpGenerator($config); } diff --git a/Test/Generator/StringGeneratorTest.php b/Test/Generator/StringGeneratorTest.php index 4d38e10..2b3f9d1 100644 --- a/Test/Generator/StringGeneratorTest.php +++ b/Test/Generator/StringGeneratorTest.php @@ -9,7 +9,7 @@ */ class StringGeneratorTest extends AbstractGeneratorTest { - public function testQuotingAndTypesEscaping() + public function testQuotingAndTypesEscaping(): void { $array = array( array('Hello', '"World"', 7), @@ -20,18 +20,18 @@ public function testQuotingAndTypesEscaping() $this->assertEquals("\"Hello\",\"\"\"World\"\"\",7\r\n,,0\r\n\"Float\"\"\",,\"\"\"\"", $csv); } - public function testFloatDe() + public function testFloatDe(): void { $array = array( array(1.0, 1.2, 1.23456789012345), - array((float)122.0, 22.22, (float)0.0), + array((float) 122.0, 22.22, (float) 0.0), ); setlocale(LC_NUMERIC, 'de_DE'); $csv = $this->generator->generate($array); $this->assertEquals("1,1.2,1.23456789012345\r\n122,22.219999999999999,0", $csv); } - public function testFloatEn() + public function testFloatEn(): void { $array = array( array(1.0, 1.2, 1.2345678901234), @@ -41,33 +41,31 @@ public function testFloatEn() $this->assertEquals("1,1.2,1.2345678901234", $csv); } - /** - * @expectedException \InvalidArgumentException - */ - public function testInvalidType1() + + public function testInvalidType1(): void { + $this->expectException(InvalidArgumentException::class); + $array = array( array(array(1)), ); $this->generator->generate($array); } - /** - * @expectedException \InvalidArgumentException - */ - public function testInvalidType2() + public function testInvalidType2(): void { + $this->expectException(InvalidArgumentException::class); + $array = array( array(new \stdClass()), ); $this->generator->generate($array); } - /** - * @expectedException \InvalidArgumentException - */ - public function testInvalidStructure() + public function testInvalidStructure(): void { + $this->expectException(InvalidArgumentException::class); + $array = array(1); $this->generator->generate($array); } @@ -79,7 +77,7 @@ public function testInvalidStructure() * * @return GeneratorInterface */ - protected function newGenerator(GeneratorConfiguration $config) + protected function newGenerator(GeneratorConfiguration $config): GeneratorInterface { return new StringGenerator($config); } diff --git a/Test/Parser/AbstractParserTest.php b/Test/Parser/AbstractParserTest.php index 868ab73..87e81f3 100644 --- a/Test/Parser/AbstractParserTest.php +++ b/Test/Parser/AbstractParserTest.php @@ -2,19 +2,20 @@ use Kuborgh\CsvBundle\Configuration\ParserConfiguration; use Kuborgh\CsvBundle\Parser\ParserInterface; +use PHPUnit\Framework\TestCase; use Symfony\Component\PropertyAccess\PropertyAccess; /** * Test parser */ -abstract class AbstractParserTest extends PHPUnit_Framework_TestCase +abstract class AbstractParserTest extends TestCase { /** * @var ParserInterface */ protected $parser; - protected function setUp() + protected function setUp(): void { $this->setConfiguration(); } @@ -23,7 +24,7 @@ protected function setUp() * @param int $num * @param array $array */ - protected function assertNumRows($num, $array) + protected function assertNumRows($num, $array): void { $cnt = count($array); $errMsg = sprintf('Number of rows differs. Found %d but expected %d', $cnt, $num); @@ -50,7 +51,7 @@ protected function assertNumCols($num, $array) * * @param array $config */ - protected function setConfiguration(array $config = array()) + protected function setConfiguration(array $config = array()): void { // apply attributes $configObj = new ParserConfiguration(); @@ -70,5 +71,5 @@ protected function setConfiguration(array $config = array()) * * @return ParserInterface */ - abstract protected function newParser(ParserConfiguration $config); + abstract protected function newParser(ParserConfiguration $config): ParserInterface; } diff --git a/Test/Parser/CharacterParserTest.php b/Test/Parser/CharacterParserTest.php index 90277f4..da4f37a 100644 --- a/Test/Parser/CharacterParserTest.php +++ b/Test/Parser/CharacterParserTest.php @@ -1,20 +1,21 @@ parser->parse($csv); $this->assertNumRows(2, $array); @@ -27,7 +28,7 @@ public function testSimpleParsing() $this->assertEquals('f', $array[1][2]); } - public function testConfiguredParsing() + public function testConfiguredParsing(): void { $config = array( 'delimiter' => ';', @@ -38,6 +39,7 @@ public function testConfiguredParsing() a;b;c d;e;f EOT; + $array = $this->parser->parse($csv); $this->assertNumRows(2, $array); @@ -50,7 +52,7 @@ public function testConfiguredParsing() $this->assertEquals('f', $array[1][2]); } - public function testEscaping() + public function testEscaping(): void { $config = array( 'delimiter' => ';', @@ -77,7 +79,7 @@ public function testEscaping() $this->assertEquals('When not starting with a quote, it may end with one "', $array[1][4]); } - public function testQuotes() + public function testQuotes(): void { $config = array( 'delimiter' => ';', @@ -101,7 +103,7 @@ public function testQuotes() $this->assertEquals('""', $array[1][2]); } - public function testInvalidLineBreak() + public function testInvalidLineBreak(): void { $config = array( 'delimiter' => ';', @@ -119,11 +121,10 @@ public function testInvalidLineBreak() $this->assertEquals("e\n", $array[0][3]); } - /** - * @expectedException \Kuborgh\CsvBundle\Exception\EofException - */ - public function testEofInQuote() + public function testEofInQuote(): void { + $this->expectException(EofException::class); + $csv = '"a","b""'; $this->parser->parse($csv); } @@ -133,9 +134,9 @@ public function testEofInQuote() * * @param ParserConfiguration $config * - * @return \Kuborgh\CsvBundle\Parser\ParserInterface + * @return ParserInterface */ - protected function newParser(ParserConfiguration $config) + protected function newParser(ParserConfiguration $config): ParserInterface { return new CharacterParser($config); } diff --git a/Test/Parser/SimpleParserTest.php b/Test/Parser/SimpleParserTest.php index af4f0dc..34409e8 100644 --- a/Test/Parser/SimpleParserTest.php +++ b/Test/Parser/SimpleParserTest.php @@ -1,6 +1,7 @@ assertEquals('f', $array[1][2]); } - public function testConfiguredParsing() + public function testConfiguredParsing(): void { $config = array( 'delimiter' => ';', @@ -53,9 +54,9 @@ public function testConfiguredParsing() /** * @param ParserConfiguration $config * - * @return SimpleParser + * @return ParserInterface */ - protected function newParser(ParserConfiguration $config) + protected function newParser(ParserConfiguration $config): ParserInterface { return new SimpleParser($config); } diff --git a/Test/TraitsTest.php b/Test/TraitsTest.php index 16a9905..e730f1f 100644 --- a/Test/TraitsTest.php +++ b/Test/TraitsTest.php @@ -1,25 +1,45 @@ container = new ContainerBuilder(); + $this->extension = new KuborghCsvExtension(); + } + /** + * @throws ReflectionException + */ + public function testCsvGeneratorTrait(): void { - $config = new \Kuborgh\CsvBundle\Configuration\GeneratorConfiguration(); - $generator = new \Kuborgh\CsvBundle\Generator\PhpGenerator($config); - /** @var \Kuborgh\CsvBundle\Traits\CsvGeneratorTrait $obj */ - $obj = $this->getObjectForTrait('Kuborgh\CsvBundle\Traits\CsvGeneratorTrait'); + $config = new GeneratorConfiguration(); + $generator = new PhpGenerator($config); + + /** @var CsvGeneratorTrait $obj */ + $obj = $this->getObjectForTrait(CsvGeneratorTrait::class); $obj->setCsvGenerator($generator); $class = new ReflectionClass(get_class($obj)); @@ -31,11 +51,13 @@ public function testCsvGeneratorTrait() } /** - * @expectedException \Exception + * @throws ReflectionException */ - public function testGeneratorNotInjectedException() + public function testGeneratorNotInjectedException(): void { - $obj = $this->getObjectForTrait('Kuborgh\CsvBundle\Traits\CsvGeneratorTrait'); + $this->expectException(RuntimeException::class); + + $obj = $this->getObjectForTrait(CsvGeneratorTrait::class); $class = new ReflectionClass(get_class($obj)); $reflMethod = $class->getMethod('generateCsv'); @@ -43,12 +65,16 @@ public function testGeneratorNotInjectedException() $reflMethod->invoke($obj, array(array('a', 7))); } - public function testCsvParserTrait() + /** + * @throws ReflectionException + */ + public function testCsvParserTrait(): void { - $config = new \Kuborgh\CsvBundle\Configuration\ParserConfiguration(); - $parser = new \Kuborgh\CsvBundle\Parser\SimpleParser($config); - /** @var \Kuborgh\CsvBundle\Traits\CsvParserTrait $obj */ - $obj = $this->getObjectForTrait('Kuborgh\CsvBundle\Traits\CsvParserTrait'); + $config = new ParserConfiguration(); + $parser = new SimpleParser($config); + + /** @var CsvParserTrait $obj */ + $obj = $this->getObjectForTrait(CsvParserTrait::class); $obj->setCsvParser($parser); $class = new ReflectionClass(get_class($obj)); @@ -60,21 +86,17 @@ public function testCsvParserTrait() } /** - * @expectedException \Exception + * @throws ReflectionException */ - public function testParserNotInjectedException() + public function testParserNotInjectedException(): void { - $obj = $this->getObjectForTrait('Kuborgh\CsvBundle\Traits\CsvParserTrait'); + $this->expectException(Exception::class); + + $obj = $this->getObjectForTrait(CsvParserTrait::class); $class = new ReflectionClass(get_class($obj)); $reflMethod = $class->getMethod('parseCsv'); $reflMethod->setAccessible(true); $reflMethod->invoke($obj, 'a,7'); } - - protected function setUp() - { - $this->container = new ContainerBuilder(); - $this->extension = new KuborghCsvExtension(); - } } diff --git a/Traits/CsvGeneratorTrait.php b/Traits/CsvGeneratorTrait.php index 47d8c06..527e592 100644 --- a/Traits/CsvGeneratorTrait.php +++ b/Traits/CsvGeneratorTrait.php @@ -3,6 +3,7 @@ namespace Kuborgh\CsvBundle\Traits; use Kuborgh\CsvBundle\Generator\GeneratorInterface; +use RuntimeException; /** * Helper for setter-injection of a csv generator @@ -19,7 +20,7 @@ trait CsvGeneratorTrait * * @param GeneratorInterface $csvGenerator */ - public function setCsvGenerator($csvGenerator) + public function setCsvGenerator($csvGenerator): void { $this->csvGenerator = $csvGenerator; } @@ -28,12 +29,13 @@ public function setCsvGenerator($csvGenerator) * Get csv generator * * @return GeneratorInterface - * @throws \Exception + * + * @throws RuntimeException */ - protected function getCsvGenerator() + protected function getCsvGenerator(): GeneratorInterface { - if (is_null($this->csvGenerator)) { - throw new \Exception('CSV Generator not injected into '.get_class($this)); + if (null === $this->csvGenerator) { + throw new RuntimeException('CSV Generator not injected into '.get_class($this)); } return $this->csvGenerator; @@ -42,11 +44,13 @@ protected function getCsvGenerator() /** * Convenience wrapper * - * @param array[] $array + * @param array $array * * @return string + * + * @throws RuntimeException */ - protected function generateCsv($array) + protected function generateCsv(array $array): string { return $this->getCsvGenerator()->generate($array); } diff --git a/Traits/CsvParserTrait.php b/Traits/CsvParserTrait.php index 9a7998c..4c61478 100644 --- a/Traits/CsvParserTrait.php +++ b/Traits/CsvParserTrait.php @@ -2,7 +2,9 @@ namespace Kuborgh\CsvBundle\Traits; +use Exception; use Kuborgh\CsvBundle\Parser\ParserInterface; +use RuntimeException; /** * Helper for setter-injection of a csv parser @@ -19,7 +21,7 @@ trait CsvParserTrait * * @param ParserInterface $csvParser */ - public function setCsvParser($csvParser) + public function setCsvParser($csvParser): void { $this->csvParser = $csvParser; } @@ -28,12 +30,13 @@ public function setCsvParser($csvParser) * Get csvParser * * @return ParserInterface - * @throws \Exception + * + * @throws Exception */ - protected function getCsvParser() + protected function getCsvParser(): ParserInterface { - if (is_null($this->csvParser)) { - throw new \Exception('CSV Parser not injected into '.get_class($this)); + if (null === $this->csvParser) { + throw new RuntimeException('CSV Parser not injected into '.get_class($this)); } return $this->csvParser; @@ -42,11 +45,13 @@ protected function getCsvParser() /** * Convenience wrapper * - * @param string $csv + * @param $csv * * @return array + * + * @throws Exception */ - protected function parseCsv($csv) + protected function parseCsv($csv): array { return $this->getCsvParser()->parse($csv); } diff --git a/composer.json b/composer.json index 49a6b6a..e27d44d 100644 --- a/composer.json +++ b/composer.json @@ -18,19 +18,26 @@ } ], "require": { - "symfony/framework-bundle": "~2.3|~3.0" + "php": "^7.2", + "symfony/framework-bundle": "~3.4.31|^4.4", + "symfony/yaml": "^4.4|^5.0" }, "require-dev": { - "phpunit/phpunit": "~4.8", - "symfony/property-access": "~2.3|~3.0" + "phpunit/phpunit": "^7.5|^8.2", + "symfony/property-access": "~2.3|~3.0", + "squizlabs/php_codesniffer": "^3.5", + "escapestudios/symfony2-coding-standard": "^3.10", + "vimeo/psalm": "3.8" }, "autoload": { "psr-0": { "Kuborgh\\CsvBundle": "" } }, - "config": { - "bin-dir": "bin" + "scripts": { + "test": "vendor/bin/phpunit", + "psalm": "vendor/bin/psalm", + "test-ci": "vendor/bin/phpunit --coverage-text --coverage-clover build/coverage.xml" }, "target-dir": "Kuborgh/CsvBundle" } diff --git a/phpcs.xml b/phpcs.xml new file mode 100644 index 0000000..55e5601 --- /dev/null +++ b/phpcs.xml @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/psalm.xml b/psalm.xml new file mode 100644 index 0000000..88f1896 --- /dev/null +++ b/psalm.xml @@ -0,0 +1,62 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +