mirror of
https://github.com/Codappix/typo3-php-datasets.git
synced 2024-12-04 08:56:10 +01:00
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:
parent
150e2b6611
commit
5887cb87fe
24 changed files with 982 additions and 2 deletions
11
.gitattributes
vendored
Normal file
11
.gitattributes
vendored
Normal 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
190
.github/workflows/ci.yaml
vendored
Normal 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
3
.gitignore
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
/.Build/
|
||||
/composer.lock
|
||||
/vendor/
|
62
.php-cs-fixer.dist.php
Normal file
62
.php-cs-fixer.dist.php
Normal 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
52
Classes/PhpDataSet.php
Normal 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);
|
||||
}
|
||||
}
|
104
Classes/TestingFramework.php
Normal file
104
Classes/TestingFramework.php
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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
78
README.rst
Normal 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.
|
32
Tests/Functional/AbstractFunctionalTestCase.php
Normal file
32
Tests/Functional/AbstractFunctionalTestCase.php
Normal 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;
|
||||
}
|
131
Tests/Functional/AssertTest.php
Normal file
131
Tests/Functional/AssertTest.php
Normal 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');
|
||||
}
|
||||
}
|
12
Tests/Functional/Fixtures/AssertAdditionalRecords.php
Normal file
12
Tests/Functional/Fixtures/AssertAdditionalRecords.php
Normal file
|
@ -0,0 +1,12 @@
|
|||
<?php
|
||||
|
||||
return [
|
||||
'pages' => [
|
||||
[
|
||||
'uid' => 1,
|
||||
'pid' => 0,
|
||||
'is_siteroot' => 1,
|
||||
'title' => 'Rootpage',
|
||||
],
|
||||
],
|
||||
];
|
13
Tests/Functional/Fixtures/AssertDifferingWithUid.php
Normal file
13
Tests/Functional/Fixtures/AssertDifferingWithUid.php
Normal file
|
@ -0,0 +1,13 @@
|
|||
<?php
|
||||
|
||||
return [
|
||||
'pages' => [
|
||||
[
|
||||
'uid' => 1,
|
||||
'pid' => 0,
|
||||
'is_siteroot' => 1,
|
||||
'title' => 'Rootpage without match',
|
||||
'description' => 'Some text',
|
||||
],
|
||||
],
|
||||
];
|
10
Tests/Functional/Fixtures/AssertDifferingWithoutUid.php
Normal file
10
Tests/Functional/Fixtures/AssertDifferingWithoutUid.php
Normal file
|
@ -0,0 +1,10 @@
|
|||
<?php
|
||||
|
||||
return [
|
||||
'pages' => [
|
||||
[
|
||||
'pid' => 0,
|
||||
'title' => 'Rootpage without match',
|
||||
],
|
||||
],
|
||||
];
|
13
Tests/Functional/Fixtures/AssertSimpleMissingUidSet.php
Normal file
13
Tests/Functional/Fixtures/AssertSimpleMissingUidSet.php
Normal file
|
@ -0,0 +1,13 @@
|
|||
<?php
|
||||
|
||||
return [
|
||||
'pages' => [
|
||||
[
|
||||
'uid' => 1,
|
||||
'pid' => 0,
|
||||
'is_siteroot' => 1,
|
||||
'title' => 'Rootpage',
|
||||
'description' => 'Some text',
|
||||
],
|
||||
],
|
||||
];
|
13
Tests/Functional/Fixtures/SimpleSet.php
Normal file
13
Tests/Functional/Fixtures/SimpleSet.php
Normal file
|
@ -0,0 +1,13 @@
|
|||
<?php
|
||||
|
||||
return [
|
||||
'pages' => [
|
||||
[
|
||||
'uid' => 1,
|
||||
'pid' => 0,
|
||||
'is_siteroot' => 1,
|
||||
'title' => 'Rootpage',
|
||||
'description' => 'Some text',
|
||||
],
|
||||
],
|
||||
];
|
9
Tests/Functional/Fixtures/WithBrokenSql.php
Normal file
9
Tests/Functional/Fixtures/WithBrokenSql.php
Normal file
|
@ -0,0 +1,9 @@
|
|||
<?php
|
||||
|
||||
return [
|
||||
'pages' => [
|
||||
[
|
||||
'none_existing_column' => 1,
|
||||
],
|
||||
],
|
||||
];
|
18
Tests/Functional/Fixtures/WithDifferentColumns.php
Normal file
18
Tests/Functional/Fixtures/WithDifferentColumns.php
Normal 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',
|
||||
],
|
||||
],
|
||||
];
|
12
Tests/Functional/Fixtures/WithNull.php
Normal file
12
Tests/Functional/Fixtures/WithNull.php
Normal file
|
@ -0,0 +1,12 @@
|
|||
<?php
|
||||
|
||||
return [
|
||||
'pages' => [
|
||||
[
|
||||
'uid' => 1,
|
||||
'pid' => 0,
|
||||
'is_siteroot' => 1,
|
||||
'description' => null,
|
||||
],
|
||||
],
|
||||
];
|
99
Tests/Functional/ImportTest.php
Normal file
99
Tests/Functional/ImportTest.php
Normal 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');
|
||||
}
|
||||
}
|
|
@ -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
6
phpstan-baseline.neon
Normal 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
10
phpstan.neon
Normal 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
35
phpunit.xml.dist
Normal 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
45
shell.nix
Normal 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
|
||||
'';
|
||||
}
|
Loading…
Reference in a new issue