ldc-arcadia-genesis-php-client/tests/Architecture/ArchTest.php
2026-04-16 09:48:49 +02:00

111 lines
3.5 KiB
PHP

<?php
declare(strict_types=1);
use Uwil\ArcadiaGenesisPhpClient\Exception\ArcadiaGenesisApiException;
use Uwil\ArcadiaGenesisPhpClient\Lib\ApiCaller;
use Uwil\ArcadiaGenesisPhpClient\Lib\ApiDto\Dto;
use Uwil\ArcadiaGenesisPhpClient\Lib\ApiDto\Dto\Inco\PortionType;
use Uwil\ArcadiaGenesisPhpClient\Lib\ApiDto\Dto\IncoCompo\AbstractIncoCompoPartDto;
use Uwil\ArcadiaGenesisPhpClient\Lib\ApiDto\Dto\IncoCompo\IncoCompoPartDto;
use Uwil\ArcadiaGenesisPhpClient\Mapper\Mapper;
use Uwil\ArcadiaGenesisPhpClient\Repository\AbstractGenesisRepository;
use Uwil\ArcadiaGenesisPhpClient\Repository\Repository;
$libraryNamespace = 'Uwil\ArcadiaGenesisPhpClient';
describe('coding standards', function () use ($libraryNamespace): void {
arch()->preset()->php();
arch()->preset()->security();
test('no shell execution functions are used')
->expect(['exec', 'shell_exec', 'system', 'passthru', 'proc_open'])
->not->toBeUsed();
test('no eval usage')
->expect(['eval'])
->not->toBeUsed();
test('no dangerous file functions')
->expect(['file_get_contents', 'file_put_contents', 'fopen'])
->not->toBeUsed();
test('no globals are used')
->expect(['$GLOBALS', 'global'])
->not->toBeUsed();
test('no singletons')
->expect(['getInstance', 'instance'])
->not->toBeUsed();
test('no insecure hashing')
->expect(['md5', 'sha1'])
->not->toBeUsed();
test('no sleep function are used')
->expect(['sleep', 'usleep'])
->not->toBeUsed()
->ignoring(ApiCaller::class);
test('no debug globals are used')
->expect(['var_dump', 'die', 'print_r'])
->not->toBeUsed();
arch('all source files use strict types')
->expect($libraryNamespace)
->toUseStrictTypes();
});
describe('naming conventions', function () use ($libraryNamespace): void {
arch('mappers have Mapper suffix')
->expect("{$libraryNamespace}\Mapper")
->toHaveSuffix('Mapper');
arch('repositories have Repository suffix')
->expect("{$libraryNamespace}\Repository")
->toHaveSuffix('Repository')
->ignoring([AbstractGenesisRepository::class]);
arch('services have Service suffix')
->expect("{$libraryNamespace}\Service")
->toHaveSuffix('Service');
});
describe('inheritance contracts', function () use ($libraryNamespace): void {
arch('ApiDtos implements Dto')
->expect("{$libraryNamespace}\Lib\ApiDto\Dto")
->toImplement(Dto::class);
arch('Exceptions implements ArcadiaGenesisApiException')
->expect("{$libraryNamespace}\Exception")
->toImplement(ArcadiaGenesisApiException::class);
arch('Mappers implements Mapper')
->expect("{$libraryNamespace}\Mapper")
->toImplement(Mapper::class);
arch('Repositories implements Repository')
->expect("{$libraryNamespace}\Repository")
->toImplement(Repository::class)
->ignoring([AbstractGenesisRepository::class]);
});
describe('api lib elements', function () use ($libraryNamespace): void {
arch('Api Dto are immutable')
->expect("{$libraryNamespace}\Lib\ApiDto\Dto")
->classes()
->toBeReadonly()
->toBeFinal()
->ignoring([
AbstractIncoCompoPartDto::class,
IncoCompoPartDto::class,
PortionType::class,
]);
arch('Value objects are immutable')
->expect("{$libraryNamespace}\Lib\ApiValueObject")
->classes()
->toBeReadonly()
->toBeFinal();
});