First basic implementation (#1)

Allows to import a PHP data set within TYPO3 testing framework.
Allows to assert a PHP data set within TYPO3 testing framework.
This commit is contained in:
Daniel Siepmann 2023-04-11 15:12:51 +02:00 committed by GitHub
parent 150e2b6611
commit 5887cb87fe
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
24 changed files with 982 additions and 2 deletions

11
.gitattributes vendored Normal file
View file

@ -0,0 +1,11 @@
Tests export-ignore
.github export-ignore
.gitattributes export-ignore
.gitignore export-ignore
.php-cs-fixer.dist.php export-ignore
phpstan.neon export-ignore
phpunit.xml.dist export-ignore
shell.nix export-ignore

190
.github/workflows/ci.yaml vendored Normal file
View file

@ -0,0 +1,190 @@
name: CI
on:
push:
branches:
- main
pull_request:
jobs:
check-composer:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Install PHP
uses: shivammathur/setup-php@v2
with:
php-version: 8.2
coverage: none
tools: composer:v2
env:
COMPOSER_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Validate composer.json
run: composer validate
php-linting:
runs-on: ubuntu-latest
strategy:
matrix:
php-version:
- 7.3
- 7.4
- 8.0
- 8.1
- 8.2
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Install PHP
uses: shivammathur/setup-php@v2
with:
php-version: "${{ matrix.php-version }}"
coverage: none
- name: PHP lint
run: "find *.php Classes Configuration Tests -name '*.php' -print0 | xargs -0 -n 1 -P 4 php -l"
xml-linting:
runs-on: ubuntu-latest
needs:
- check-composer
steps:
- uses: actions/checkout@v3
- name: Install PHP
uses: shivammathur/setup-php@v2
with:
php-version: "8.2"
coverage: none
tools: composer:v2
env:
COMPOSER_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Install xmllint
run: sudo apt-get install libxml2-utils
- name: Install dependencies
run: composer install --prefer-dist --no-progress
- name: PHPUnit configuration file
run: xmllint --schema vendor/phpunit/phpunit/phpunit.xsd --noout phpunit.xml.dist
coding-guideline:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Install PHP
uses: shivammathur/setup-php@v2
with:
php-version: "8.1"
coverage: none
tools: composer:v2
env:
COMPOSER_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Install dependencies
run: composer install --prefer-dist --no-progress
- name: Coding Guideline
run: ./vendor/bin/php-cs-fixer fix --dry-run --diff
tests-mysql:
runs-on: ubuntu-latest
needs:
- xml-linting
strategy:
matrix:
include:
- db-version: '5.7'
php-version: '7.3'
typo3-version: '^10.4'
- db-version: '8'
php-version: '7.4'
typo3-version: '^10.4'
- db-version: '8'
php-version: '7.4'
typo3-version: '^11.5'
- db-version: '8'
php-version: '8.0'
typo3-version: '^11.5'
- db-version: '8'
php-version: '8.1'
typo3-version: '^11.5'
- db-version: '8'
php-version: '8.2'
typo3-version: '^11.5'
steps:
- uses: actions/checkout@v3
- name: Install PHP
uses: shivammathur/setup-php@v2
with:
php-version: "${{ matrix.php-version }}"
coverage: none
tools: composer:v2
env:
COMPOSER_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Setup MySQL
uses: mirromutth/mysql-action@v1.1
with:
mysql version: '${{ matrix.db-version }}'
mysql database: 'typo3'
mysql root password: 'root'
- name: Wait for MySQL
run: |
while ! mysqladmin ping --host=127.0.0.1 --password=root --silent; do
sleep 1
done
- name: Install dependencies with expected TYPO3 version
run: composer require --prefer-dist --no-progress "typo3/cms-core:${{ matrix.typo3-version }}"
- name: PHPUnit Tests
run: |-
export typo3DatabaseDriver="pdo_mysql"
export typo3DatabaseName="typo3"
export typo3DatabaseHost="127.0.0.1"
export typo3DatabaseUsername="root"
export typo3DatabasePassword="root"
./vendor/bin/phpunit --testdox
code-quality:
runs-on: ubuntu-latest
strategy:
matrix:
include:
- php-version: '7.3'
typo3-version: '^10.4'
- php-version: '7.4'
typo3-version: '^10.4'
- php-version: '7.4'
typo3-version: '^11.5'
- php-version: '8.0'
typo3-version: '^11.5'
- php-version: '8.1'
typo3-version: '^11.5'
- php-version: '8.2'
typo3-version: '^11.5'
steps:
- uses: actions/checkout@v3
- name: Install PHP
uses: shivammathur/setup-php@v2
with:
php-version: "${{ matrix.php-version }}"
coverage: none
tools: composer:v2
env:
COMPOSER_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Install dependencies with expected TYPO3 version
run: composer require --prefer-dist --no-progress "typo3/cms-backend:${{ matrix.typo3-version }}" "typo3/cms-core:${{ matrix.typo3-version }}" "typo3/cms-dashboard:${{ matrix.typo3-version }}"
- name: Code Quality (by PHPStan)
run: ./vendor/bin/phpstan analyse

3
.gitignore vendored Normal file
View file

@ -0,0 +1,3 @@
/.Build/
/composer.lock
/vendor/

62
.php-cs-fixer.dist.php Normal file
View file

@ -0,0 +1,62 @@
<?php
$finder = (new PhpCsFixer\Finder())
->ignoreVCSIgnored(true)
->in(realpath(__DIR__));
return (new \PhpCsFixer\Config())
->setRiskyAllowed(true)
->setRules([
'@DoctrineAnnotation' => true,
'@PSR2' => true,
'array_syntax' => ['syntax' => 'short'],
'blank_line_after_opening_tag' => true,
'braces' => ['allow_single_line_closure' => true],
'cast_spaces' => ['space' => 'none'],
'compact_nullable_typehint' => true,
'concat_space' => ['spacing' => 'one'],
'declare_equal_normalize' => ['space' => 'none'],
'dir_constant' => true,
'function_to_constant' => ['functions' => ['get_called_class', 'get_class', 'get_class_this', 'php_sapi_name', 'phpversion', 'pi']],
'function_typehint_space' => true,
'lowercase_cast' => true,
'method_argument_space' => ['on_multiline' => 'ensure_fully_multiline'],
'modernize_strpos' => true,
'modernize_types_casting' => true,
'native_function_casing' => true,
'new_with_braces' => true,
'no_alias_functions' => true,
'no_blank_lines_after_phpdoc' => true,
'no_empty_phpdoc' => true,
'no_empty_statement' => true,
'no_extra_blank_lines' => true,
'no_leading_import_slash' => true,
'no_leading_namespace_whitespace' => true,
'no_null_property_initialization' => true,
'no_short_bool_cast' => true,
'no_singleline_whitespace_before_semicolons' => true,
'no_superfluous_elseif' => true,
'no_trailing_comma_in_singleline_array' => true,
'no_unneeded_control_parentheses' => true,
'no_unused_imports' => true,
'no_useless_else' => true,
'no_whitespace_in_blank_line' => true,
'ordered_imports' => true,
'php_unit_construct' => ['assertions' => ['assertEquals', 'assertSame', 'assertNotEquals', 'assertNotSame']],
'php_unit_mock_short_will_return' => true,
'php_unit_test_case_static_method_calls' => ['call_type' => 'self'],
'phpdoc_no_access' => true,
'phpdoc_no_empty_return' => true,
'phpdoc_no_package' => true,
'phpdoc_scalar' => true,
'phpdoc_trim' => true,
'phpdoc_types' => true,
'phpdoc_types_order' => ['null_adjustment' => 'always_last', 'sort_algorithm' => 'none'],
'return_type_declaration' => ['space_before' => 'none'],
'single_quote' => true,
'single_line_comment_style' => ['comment_types' => ['hash']],
'single_trait_insert_per_statement' => true,
'trailing_comma_in_multiline' => ['elements' => ['arrays']],
'whitespace_after_comma_in_array' => true,
'yoda_style' => ['equal' => false, 'identical' => false, 'less_and_greater' => false],
])
->setFinder($finder);

52
Classes/PhpDataSet.php Normal file
View file

@ -0,0 +1,52 @@
<?php
declare(strict_types=1);
/*
* Copyright (C) 2023 Daniel Siepmann <coding@daniel-siepmann.de>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*/
namespace Codappix\Typo3PhpDatasets;
use TYPO3\CMS\Core\Database\ConnectionPool;
use TYPO3\CMS\Core\Utility\GeneralUtility;
class PhpDataSet
{
public function import(array $dataSet): void
{
foreach ($dataSet as $tableName => $records) {
$connection = $this->getConnectionPool()->getConnectionForTable($tableName);
$tableDetails = $connection->getSchemaManager()->listTableDetails($tableName);
foreach ($records as $record) {
$types = [];
foreach (array_keys($record) as $columnName) {
$types[] = $tableDetails->getColumn((string)$columnName)->getType()->getBindingType();
}
$connection->insert($tableName, $record, $types);
}
}
}
private function getConnectionPool(): ConnectionPool
{
return GeneralUtility::makeInstance(ConnectionPool::class);
}
}

View file

@ -0,0 +1,104 @@
<?php
declare(strict_types=1);
/*
* Copyright (C) 2023 Daniel Siepmann <coding@daniel-siepmann.de>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*/
namespace Codappix\Typo3PhpDatasets;
use Doctrine\DBAL\DBALException;
use InvalidArgumentException;
/**
* Only use this within an FunctionalTestCase.
*/
trait TestingFramework
{
protected function importPHPDataSet(string $filePath): void
{
$this->ensureFileExists($filePath);
$dataSet = include $filePath;
try {
(new PhpDataSet())->import($dataSet);
} catch (DBALException $e) {
self::fail('SQL Error for PHP data-set "' . $filePath . '":' . PHP_EOL . $e->getMessage());
}
}
/**
* Highly inspired by TYPO3 testing framework.
*/
protected function assertPHPDataSet(string $filePath): void
{
$this->ensureFileExists($filePath);
$dataSet = include $filePath;
$failMessages = [];
foreach ($dataSet as $tableName => $expectedRecords) {
$records = $this->getAllRecords($tableName, true);
foreach ($expectedRecords as $assertion) {
$result = $this->assertInRecords($assertion, $records);
if ($result === false) {
// Handle error
if (isset($assertion['uid']) && empty($records[$assertion['uid']])) {
$failMessages[] = 'Record "' . $tableName . ':' . $assertion['uid'] . '" not found in database';
continue;
}
if (isset($assertion['uid'])) {
$recordIdentifier = $tableName . ':' . $assertion['uid'];
$additionalInformation = $this->renderRecords($assertion, $records[$assertion['uid']]);
} else {
$recordIdentifier = $tableName;
$additionalInformation = $this->arrayToString($assertion);
}
$failMessages[] = 'Assertion in data-set failed for "' . $recordIdentifier . '":' . PHP_EOL . $additionalInformation;
continue;
}
// Unset asserted record
unset($records[$result]);
// Increase assertion counter
self::assertTrue($result !== false);
}
if (!empty($records)) {
foreach ($records as $record) {
$recordIdentifier = $tableName . ':' . $record['uid'];
$failMessages[] = 'Not asserted record found for "' . $recordIdentifier . '".';
}
}
}
if (!empty($failMessages)) {
self::fail(implode(PHP_EOL, $failMessages));
}
}
private function ensureFileExists(string $filePath): void
{
if (file_exists($filePath) === false) {
throw new InvalidArgumentException('The requested PHP data-set file "' . $filePath . '" does not exist.', 1681207108);
}
}
}

View file

@ -1,2 +0,0 @@
# typo3-testing-framework-php-datasets
Enables usage of PHP instead of XML or CSV for datasets

78
README.rst Normal file
View file

@ -0,0 +1,78 @@
PHP DataSets for TYPO3
======================
Provides APIs to use data sets written as PHP arrays with TYPO3.
Why
===
We don't like the approach of TYPO3 Testing Framework regarding DataSets.
We have the following issues:
#. XML is only supported for imports, not for assertions
#. CSV is a bad format that already got hacked, e.g. ``#`` to indicate comments.
We consider it bad as one needs special toolings in order to properly write CSV files, they are not human readable.
That's why we prefer PHP files instead. That way developers are free to use whatever
they want. Either plain PHP or even YAML or other formats. They are not forced to
anything but can stick to their known tooling.
We also have situations where we wanna have static database records on production
that are maintained by PHP data sets and update wizards.
So this package should in general handle PHP data sets for TYPO3.
It should ease the abstract usage by providing convenient integrations for general
use cases, like the testing framework.
Usage
=====
See our own tests for how to use, as they do nothing else.
Within testing framework
------------------------
#. Create data set
A data set is a PHP file that returns an array of tables with their records.
Format is:
.. code-block:: php
return [
'table_name' => [
// Records
[
// column_name => value
'uid' => 1,
],
],
];
#. Add API
.. code-block:: php
use Codappix\Typo3PhpDatasets\TestingFramework;
#. Use API
Import:
.. code-block:: php
$this->importPHPDataSet(__DIR__ . '/Fixtures/SimpleSet.php');
Assert:
.. code-block:: php
$this->assertPHPDataSet(__DIR__ . '/Fixtures/SimpleSet.php');
TODO
====
#. Implement use case to check for necessary updates and allow updates.
Use for static data during deployment within update wizards or other scripts.

View file

@ -0,0 +1,32 @@
<?php
declare(strict_types=1);
/*
* Copyright (C) 2023 Daniel Siepmann <coding@daniel-siepmann.de>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*/
namespace Codappix\Typo3PhpDatasets\Tests\Functional;
use Codappix\Typo3PhpDatasets\TestingFramework;
use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase;
abstract class AbstractFunctionalTestCase extends FunctionalTestCase
{
use TestingFramework;
}

View file

@ -0,0 +1,131 @@
<?php
declare(strict_types=1);
/*
* Copyright (C) 2023 Daniel Siepmann <coding@daniel-siepmann.de>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*/
namespace Codappix\Typo3PhpDatasets\Tests\Functional;
use InvalidArgumentException;
use PHPUnit\Framework\AssertionFailedError;
/**
* @covers \Codappix\Typo3PhpDatasets\PhpDataSet
* @covers \Codappix\Typo3PhpDatasets\TestingFramework
* @testdox The Testing Framework trait
*/
class AssertTest extends AbstractFunctionalTestCase
{
/**
* @test
*/
public function canAssertAgainstSimpleSet(): void
{
$this->importPHPDataSet(__DIR__ . '/Fixtures/SimpleSet.php');
$this->assertPHPDataSet(__DIR__ . '/Fixtures/SimpleSet.php');
}
/**
* @test
*/
public function canAssertAgainstNullValue(): void
{
$this->importPHPDataSet(__DIR__ . '/Fixtures/WithNull.php');
$this->assertPHPDataSet(__DIR__ . '/Fixtures/WithNull.php');
}
/**
* @test
*/
public function canAssertAgainstDifferentSetOfColumns(): void
{
$this->importPHPDataSet(__DIR__ . '/Fixtures/WithDifferentColumns.php');
$this->assertPHPDataSet(__DIR__ . '/Fixtures/WithDifferentColumns.php');
}
/**
* @test
*/
public function failsForMissingAssertionWithUid(): void
{
$this->expectException(AssertionFailedError::class);
$this->expectExceptionMessage('Record "pages:1" not found in database');
$this->assertPHPDataSet(__DIR__ . '/Fixtures/AssertSimpleMissingUidSet.php');
}
/**
* @test
*/
public function failsForDifferingAssertionWithUid(): void
{
$this->importPHPDataSet(__DIR__ . '/Fixtures/SimpleSet.php');
$this->expectException(AssertionFailedError::class);
$this->expectExceptionMessage(
'Assertion in data-set failed for "pages:1":'
. PHP_EOL
. 'Fields|Assertion |Record '
. PHP_EOL
. 'title |Rootpage without match|Rootpage'
. PHP_EOL
);
$this->assertPHPDataSet(__DIR__ . '/Fixtures/AssertDifferingWithUid.php');
}
/**
* @test
*/
public function failsForAssertionWithoutUid(): void
{
$this->importPHPDataSet(__DIR__ . '/Fixtures/SimpleSet.php');
$this->expectException(AssertionFailedError::class);
$this->expectExceptionMessage(implode(PHP_EOL, [
'Assertion in data-set failed for "pages":',
'array(',
' \'pid\' => \'0\', ',
' \'title\' => \'Rootpage without match\'',
')',
]) . PHP_EOL);
$this->assertPHPDataSet(__DIR__ . '/Fixtures/AssertDifferingWithoutUid.php');
}
/**
* @test
*/
public function failsForAdditionalNoneAssertedRecords(): void
{
$this->importPHPDataSet(__DIR__ . '/Fixtures/WithDifferentColumns.php');
$this->expectException(AssertionFailedError::class);
$this->expectExceptionMessage('Not asserted record found for "pages:2".');
$this->assertPHPDataSet(__DIR__ . '/Fixtures/AssertAdditionalRecords.php');
}
/**
* @test
*/
public function throwsExceptionIfFileDoesNotExist(): void
{
$this->expectException(InvalidArgumentException::class);
$this->expectExceptionMessage('The requested PHP data-set file "' . __DIR__ . '/Fixtures/DoesNotExist.php' . '" does not exist.');
$this->assertPHPDataSet(__DIR__ . '/Fixtures/DoesNotExist.php');
}
}

View file

@ -0,0 +1,12 @@
<?php
return [
'pages' => [
[
'uid' => 1,
'pid' => 0,
'is_siteroot' => 1,
'title' => 'Rootpage',
],
],
];

View file

@ -0,0 +1,13 @@
<?php
return [
'pages' => [
[
'uid' => 1,
'pid' => 0,
'is_siteroot' => 1,
'title' => 'Rootpage without match',
'description' => 'Some text',
],
],
];

View file

@ -0,0 +1,10 @@
<?php
return [
'pages' => [
[
'pid' => 0,
'title' => 'Rootpage without match',
],
],
];

View file

@ -0,0 +1,13 @@
<?php
return [
'pages' => [
[
'uid' => 1,
'pid' => 0,
'is_siteroot' => 1,
'title' => 'Rootpage',
'description' => 'Some text',
],
],
];

View file

@ -0,0 +1,13 @@
<?php
return [
'pages' => [
[
'uid' => 1,
'pid' => 0,
'is_siteroot' => 1,
'title' => 'Rootpage',
'description' => 'Some text',
],
],
];

View file

@ -0,0 +1,9 @@
<?php
return [
'pages' => [
[
'none_existing_column' => 1,
],
],
];

View file

@ -0,0 +1,18 @@
<?php
return [
'pages' => [
[
'uid' => 1,
'pid' => 0,
'is_siteroot' => 1,
'title' => 'Rootpage',
],
[
'uid' => 2,
'pid' => 0,
'title' => 'Another Page',
'description' => 'Some other text',
],
],
];

View file

@ -0,0 +1,12 @@
<?php
return [
'pages' => [
[
'uid' => 1,
'pid' => 0,
'is_siteroot' => 1,
'description' => null,
],
],
];

View file

@ -0,0 +1,99 @@
<?php
declare(strict_types=1);
/*
* Copyright (C) 2023 Daniel Siepmann <coding@daniel-siepmann.de>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*/
namespace Codappix\Typo3PhpDatasets\Tests\Functional;
use InvalidArgumentException;
use PHPUnit\Framework\AssertionFailedError;
/**
* @covers \Codappix\Typo3PhpDatasets\PhpDataSet
* @covers \Codappix\Typo3PhpDatasets\TestingFramework
* @testdox The Testing Framework trait
*/
class ImportTest extends AbstractFunctionalTestCase
{
/**
* @test
*/
public function canImportSimpleSet(): void
{
$this->importPHPDataSet(__DIR__ . '/Fixtures/SimpleSet.php');
$records = $this->getAllRecords('pages', true);
self::assertCount(1, $records);
self::assertIsArray($records[1]);
self::assertSame('Rootpage', $records[1]['title']);
self::assertSame('Some text', $records[1]['description']);
}
/**
* @test
*/
public function canImportWithNullValue(): void
{
$this->importPHPDataSet(__DIR__ . '/Fixtures/WithNull.php');
$records = $this->getAllRecords('pages', true);
self::assertNull($records[1]['description']);
}
/**
* @test
*/
public function canImportRecordsWithDifferentSetOfColumns(): void
{
$this->importPHPDataSet(__DIR__ . '/Fixtures/WithDifferentColumns.php');
$records = $this->getAllRecords('pages', true);
self::assertCount(2, $records);
self::assertIsArray($records[1]);
self::assertSame('Rootpage', $records[1]['title']);
self::assertIsArray($records[2]);
self::assertSame('Some other text', $records[2]['description']);
}
/**
* @test
*/
public function failsIfSqlError(): void
{
$this->expectException(AssertionFailedError::class);
$this->expectExceptionMessage(
'SQL Error for PHP data-set "' . __DIR__ . '/Fixtures/WithBrokenSql.php":'
. PHP_EOL
. 'There is no column with name \'none_existing_column\' on table \'pages\'.'
);
$this->importPHPDataSet(__DIR__ . '/Fixtures/WithBrokenSql.php');
}
/**
* @test
*/
public function throwsExceptionIfFileDoesNotExist(): void
{
$this->expectException(InvalidArgumentException::class);
$this->expectExceptionMessage('The requested PHP data-set file "' . __DIR__ . '/Fixtures/DoesNotExist.php' . '" does not exist.');
$this->importPHPDataSet(__DIR__ . '/Fixtures/DoesNotExist.php');
}
}

View file

@ -8,6 +8,11 @@
"Codappix\\Typo3PhpDatasets\\": "Classes/"
}
},
"autoload-dev": {
"psr-4": {
"Codappix\\Typo3PhpDatasets\\Tests\\": "Tests/"
}
},
"authors": [
{
"name": "Daniel Siepmann",
@ -18,5 +23,24 @@
"php": "^7.3 || ^7.4 || ^8.0 || ^8.1 || ^8.2",
"doctrine/dbal": "^2.13",
"typo3/cms-core": "^10.4 || ^11.5"
},
"require-dev": {
"friendsofphp/php-cs-fixer": "^3.4",
"phpstan/phpstan": "^1.10",
"phpstan/phpstan-phpunit": "^1.3",
"phpunit/phpunit": "^9.6",
"typo3/testing-framework": "^6.16"
},
"extra": {
"typo3/cms": {
"app-dir": ".Build",
"web-dir": ".Build/web"
}
},
"config": {
"allow-plugins": {
"typo3/class-alias-loader": true,
"typo3/cms-composer-installers": true
}
}
}

6
phpstan-baseline.neon Normal file
View file

@ -0,0 +1,6 @@
parameters:
ignoreErrors:
-
message: "#^Method Codappix\\\\Typo3PhpDatasets\\\\PhpDataSet\\:\\:getConnectionPool\\(\\) should return TYPO3\\\\CMS\\\\Core\\\\Database\\\\ConnectionPool but returns object\\.$#"
count: 1
path: Classes/PhpDataSet.php

10
phpstan.neon Normal file
View file

@ -0,0 +1,10 @@
includes:
- phpstan-baseline.neon
parameters:
level: max
paths:
- Classes
- Tests
checkMissingIterableValueType: false
reportUnmatchedIgnoredErrors: true
checkGenericClassInNonGenericObjectType: false

35
phpunit.xml.dist Normal file
View file

@ -0,0 +1,35 @@
<?xml version="1.0"?>
<phpunit
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/9.6/phpunit.xsd"
backupGlobals="false"
backupStaticAttributes="false"
bootstrap="vendor/typo3/testing-framework/Resources/Core/Build/FunctionalTestsBootstrap.php"
colors="true"
convertErrorsToExceptions="true"
convertWarningsToExceptions="true"
forceCoversAnnotation="false"
processIsolation="false"
stopOnError="false"
stopOnFailure="false"
stopOnIncomplete="false"
stopOnSkipped="false"
verbose="false"
>
<testsuites>
<testsuite name="functional">
<directory>Tests/Functional/</directory>
</testsuite>
</testsuites>
<coverage>
<include>
<directory suffix=".php">Classes</directory>
</include>
</coverage>
<php>
<env name="typo3DatabaseDriver" value="pdo_sqlite"/>
</php>
</phpunit>

45
shell.nix Normal file
View file

@ -0,0 +1,45 @@
{
pkgs ? import <nixpkgs> { }
,phps ? import <phps>
}:
let
php = phps.packages.x86_64-linux.php81;
inherit(php.packages) composer;
phpWithXdebug = php.buildEnv {
extensions = { enabled, all }: enabled ++ (with all; [
xdebug
]);
extraConfig = ''
xdebug.mode = debug
'';
};
projectInstall = pkgs.writeShellApplication {
name = "project-install";
runtimeInputs = [
php
composer
];
text = ''
composer install --prefer-dist --no-progress --working-dir="$PROJECT_ROOT"
'';
};
in pkgs.mkShell {
name = "TYPO3 PHP Datasets";
buildInputs = [
projectInstall
phpWithXdebug
composer
pkgs.parallel
];
shellHook = ''
export PROJECT_ROOT="$(pwd)"
export typo3DatabaseDriver=pdo_sqlite
'';
}