Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,11 @@
/.gitignore export-ignore
/CODE_OF_CONDUCT.md export-ignore
/CONTRIBUTING.md export-ignore
/MAINTAINERS.md export-ignore
/README.md export-ignore
/UPGRADING.md export-ignore
/phpcs.xml.dist export-ignore
/phpstan.neon.dist export-ignore
/phpunit.xml.dist export-ignore
/psalm.xml export-ignore
/tests export-ignore
27 changes: 14 additions & 13 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
name: Tests

permissions:
contents: read

on: [push, pull_request]

jobs:
Expand All @@ -12,13 +15,17 @@ jobs:
matrix:
php: [7.4, 8.0, 8.1, 8.2, 8.3, 8.4]
experimental: [false]
composer-options: ['']
include:
- php: 8.2
analysis: true
- php: nightly
experimental: true
composer-options: '--ignore-platform-req=php+'

steps:
- name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v5

- name: Set up PHP ${{ matrix.php }}
uses: shivammathur/setup-php@v2
Expand All @@ -27,12 +34,7 @@ jobs:
coverage: xdebug

- name: Install dependencies with Composer
if: matrix.php < '8.4'
run: composer update --prefer-dist --no-progress --no-interaction --ansi

- name: Install dependencies with Composer
if: matrix.php >= '8.4'
run: composer update --prefer-dist --no-progress --no-interaction --ansi --ignore-platform-reqs
run: composer update --prefer-dist --no-progress --no-interaction --ansi ${{ matrix.composer-options }}

- name: Coding standards
if: matrix.analysis
Expand All @@ -43,12 +45,11 @@ jobs:
run: vendor/bin/phpstan

- name: Tests
run: vendor/bin/phpunit --coverage-clover clover.xml
run: vendor/bin/phpunit ${{ matrix.analysis && '--coverage-clover clover.xml' || '--no-coverage' }}

- name: Upload coverage results to Coveralls
if: matrix.analysis
env:
COVERALLS_REPO_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
composer require php-coveralls/php-coveralls -n -W
vendor/bin/php-coveralls --coverage_clover=clover.xml -v
uses: coverallsapp/github-action@v2
with:
flag-name: php-${{ matrix.php }}
files: clover.xml
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@
"phpspec/prophecy": "^1.19",
"phpspec/prophecy-phpunit": "^2.1",
"phpstan/phpstan": "^1 || ^2",
"phpunit/phpunit": "^9.6",
"phpunit/phpunit": "^9.6 || ^10 || ^11 || ^12",
"slim/http": "^1.3",
"slim/psr7": "^1.6",
"squizlabs/php_codesniffer": "^3.10",
Expand Down
15 changes: 9 additions & 6 deletions phpunit.xml.dist
Original file line number Diff line number Diff line change
@@ -1,24 +1,27 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/9.5/phpunit.xsd"
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/12.3/phpunit.xsd"
beStrictAboutChangesToGlobalState="true"
beStrictAboutOutputDuringTests="true"
colors="true"
bootstrap="tests/bootstrap.php"
executionOrder="random"
cacheDirectory=".phpunit.cache"
>
<testsuites>
<testsuite name="Slim Test Suite">
<directory>tests</directory>
<exclude>tests/Mocks</exclude>
</testsuite>
</testsuites>

<coverage processUncoveredFiles="true">
<include>
<directory>Slim</directory>
</include>
<coverage>
<report>
<html outputDirectory="coverage" lowUpperBound="20" highLowerBound="50"/>
</report>
</coverage>
<source>
<include>
<directory>Slim</directory>
</include>
</source>
</phpunit>
13 changes: 9 additions & 4 deletions tests/AppTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ public function testGetMiddlewareDispatcherGetsSeededAndReturnsInjectedInstance(
$this->assertSame($middlewareDispatcherProphecy->reveal(), $app->getMiddlewareDispatcher());
}

public function lowerCaseRequestMethodsProvider(): array
public static function lowerCaseRequestMethodsProvider(): array
{
return [
['get'],
Expand All @@ -171,6 +171,7 @@ public function lowerCaseRequestMethodsProvider(): array
* @param string $method
* @dataProvider upperCaseRequestMethodsProvider()
*/
#[\PHPUnit\Framework\Attributes\DataProvider('upperCaseRequestMethodsProvider')]
public function testGetPostPutPatchDeleteOptionsMethods(string $method): void
{
$streamProphecy = $this->prophesize(StreamInterface::class);
Expand Down Expand Up @@ -244,7 +245,7 @@ public function testAnyRoute(): void
* Route collector proxy methods
*******************************************************************************/

public function upperCaseRequestMethodsProvider(): array
public static function upperCaseRequestMethodsProvider(): array
{
return [
['GET'],
Expand All @@ -261,6 +262,8 @@ public function upperCaseRequestMethodsProvider(): array
* @dataProvider lowerCaseRequestMethodsProvider
* @dataProvider upperCaseRequestMethodsProvider
*/
#[\PHPUnit\Framework\Attributes\DataProvider('lowerCaseRequestMethodsProvider')]
#[\PHPUnit\Framework\Attributes\DataProvider('upperCaseRequestMethodsProvider')]
public function testMapRoute(string $method): void
{
$streamProphecy = $this->prophesize(StreamInterface::class);
Expand Down Expand Up @@ -376,7 +379,7 @@ public function testRouteWithInternationalCharacters(): void
* Route Patterns
*******************************************************************************/

public function routePatternsProvider(): array
public static function routePatternsProvider(): array
{
return [
[''], // Empty Route
Expand All @@ -391,6 +394,7 @@ public function routePatternsProvider(): array
* @param string $pattern
* @dataProvider routePatternsProvider
*/
#[\PHPUnit\Framework\Attributes\DataProvider('routePatternsProvider')]
public function testRoutePatterns(string $pattern): void
{
$responseFactoryProphecy = $this->prophesize(ResponseFactoryInterface::class);
Expand All @@ -409,7 +413,7 @@ public function testRoutePatterns(string $pattern): void
* Route Groups
*******************************************************************************/

public function routeGroupsDataProvider(): array
public static function routeGroupsDataProvider(): array
{
return [
'empty group with empty route' => [
Expand Down Expand Up @@ -539,6 +543,7 @@ public function testGroupClosureIsBoundToThisClass(): void
* @param array $sequence
* @param string $expectedPath
*/
#[\PHPUnit\Framework\Attributes\DataProvider('routeGroupsDataProvider')]
public function testRouteGroupCombinations(array $sequence, string $expectedPath): void
{
$responseFactoryProphecy = $this->prophesize(ResponseFactoryInterface::class);
Expand Down
7 changes: 6 additions & 1 deletion tests/Factory/AppFactoryTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ protected function tearDown(): void
$reflectionClass->setStaticPropertyValue('responseFactoryClass', DecoratedResponseFactory::class);
}

public function provideImplementations()
public static function provideImplementations()
{
return [
[SlimPsr17Factory::class, SlimResponseFactory::class],
Expand All @@ -66,6 +66,7 @@ public function provideImplementations()
* @param string $psr17factory
* @param string $expectedResponseFactoryClass
*/
#[\PHPUnit\Framework\Attributes\DataProvider('provideImplementations')]
public function testCreateAppWithAllImplementations(string $psr17factory, string $expectedResponseFactoryClass)
{
Psr17FactoryProvider::setFactories([$psr17factory]);
Expand Down Expand Up @@ -134,6 +135,7 @@ public function testSetPsr17FactoryProvider()
/**
* @runInSeparateProcess - Psr17FactoryProvider::setFactories breaks other tests
*/
#[\PHPUnit\Framework\Attributes\RunInSeparateProcess]
public function testResponseFactoryIsStillReturnedIfStreamFactoryIsNotAvailable()
{
Psr17FactoryProvider::setFactories([MockPsr17FactoryWithoutStreamFactory::class]);
Expand All @@ -147,6 +149,7 @@ public function testResponseFactoryIsStillReturnedIfStreamFactoryIsNotAvailable(
/**
* @runInSeparateProcess - AppFactory::setResponseFactory breaks other tests
*/
#[\PHPUnit\Framework\Attributes\RunInSeparateProcess]
public function testAppIsCreatedWithInstancesFromSetters()
{
$responseFactoryProphecy = $this->prophesize(ResponseFactoryInterface::class);
Expand Down Expand Up @@ -204,6 +207,7 @@ public function testAppIsCreatedWithInstancesFromSetters()
* @runInSeparateProcess - AppFactory::create saves $responseFactory into static::$responseFactory,
* this breaks other tests
*/
#[\PHPUnit\Framework\Attributes\RunInSeparateProcess]
public function testAppIsCreatedWithInjectedInstancesFromFunctionArguments()
{
$responseFactoryProphecy = $this->prophesize(ResponseFactoryInterface::class);
Expand Down Expand Up @@ -254,6 +258,7 @@ public function testAppIsCreatedWithInjectedInstancesFromFunctionArguments()
/**
* @runInSeparateProcess - AppFactory::setResponseFactory breaks other tests
*/
#[\PHPUnit\Framework\Attributes\RunInSeparateProcess]
public function testResponseAndStreamFactoryIsBeingInjectedInDecoratedResponseFactory()
{
$responseProphecy = $this->prophesize(ResponseInterface::class);
Expand Down
2 changes: 2 additions & 0 deletions tests/Factory/Psr17/Psr17FactoryProviderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ class Psr17FactoryProviderTest extends TestCase
/**
* @runInSeparateProcess - Psr17FactoryProvider::setFactories breaks other tests
*/
#[\PHPUnit\Framework\Attributes\RunInSeparateProcess]
public function testGetSetFactories()
{
Psr17FactoryProvider::setFactories([]);
Expand All @@ -29,6 +30,7 @@ public function testGetSetFactories()
/**
* @runInSeparateProcess - Psr17FactoryProvider::setFactories breaks other tests
*/
#[\PHPUnit\Framework\Attributes\RunInSeparateProcess]
public function testAddFactory()
{
Psr17FactoryProvider::setFactories(['Factory 1']);
Expand Down
6 changes: 5 additions & 1 deletion tests/Factory/ServerRequestCreatorFactoryTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@

class ServerRequestCreatorFactoryTest extends TestCase
{
public function provideImplementations()
public static function provideImplementations()
{
return [
[SlimPsr17Factory::class, SlimServerRequest::class],
Expand All @@ -47,6 +47,7 @@ public function provideImplementations()
* @param string $psr17factory
* @param string $expectedServerRequestClass
*/
#[\PHPUnit\Framework\Attributes\DataProvider('provideImplementations')]
public function testCreateAppWithAllImplementations(string $psr17factory, string $expectedServerRequestClass)
{
Psr17FactoryProvider::setFactories([$psr17factory]);
Expand All @@ -72,6 +73,7 @@ public function testDetermineServerRequestCreatorReturnsDecoratedServerRequestCr
/**
* @runInSeparateProcess - Psr17FactoryProvider::setFactories breaks other tests
*/
#[\PHPUnit\Framework\Attributes\RunInSeparateProcess]
public function testDetermineServerRequestCreatorThrowsRuntimeException()
{
$this->expectException(RuntimeException::class);
Expand All @@ -96,6 +98,7 @@ public function testSetPsr17FactoryProvider()
/**
* @runInSeparateProcess - ServerRequestCreatorFactory::setServerRequestCreator breaks other tests
*/
#[\PHPUnit\Framework\Attributes\RunInSeparateProcess]
public function testSetServerRequestCreatorWithoutDecorators()
{
ServerRequestCreatorFactory::setSlimHttpDecoratorsAutomaticDetection(false);
Expand All @@ -117,6 +120,7 @@ public function testSetServerRequestCreatorWithoutDecorators()
/**
* @runInSeparateProcess - ServerRequestCreatorFactory::setServerRequestCreator breaks other tests
*/
#[\PHPUnit\Framework\Attributes\RunInSeparateProcess]
public function testSetServerRequestCreatorWithDecorators()
{
ServerRequestCreatorFactory::setSlimHttpDecoratorsAutomaticDetection(true);
Expand Down
30 changes: 6 additions & 24 deletions tests/Handlers/ErrorHandlerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,7 @@ private function getMockLogger(): LoggerInterface

public function testDetermineRenderer()
{
$handler = $this
->getMockBuilder(ErrorHandler::class)
->disableOriginalConstructor()
->getMock();
$handler = $this->createMock(ErrorHandler::class);
$class = new ReflectionClass(ErrorHandler::class);

$callableResolverProperty = $class->getProperty('callableResolver');
Expand Down Expand Up @@ -77,10 +74,7 @@ public function testDetermineRenderer()
public function testDetermineStatusCode()
{
$request = $this->createServerRequest('/');
$handler = $this
->getMockBuilder(ErrorHandler::class)
->disableOriginalConstructor()
->getMock();
$handler = $this->createMock(ErrorHandler::class);
$class = new ReflectionClass(ErrorHandler::class);

$reflectionProperty = $class->getProperty('responseFactory');
Expand Down Expand Up @@ -129,10 +123,7 @@ public function testHalfValidContentType()
->createServerRequest('/', 'GET')
->withHeader('Content-Type', 'unknown/json+');

$handler = $this
->getMockBuilder(ErrorHandler::class)
->disableOriginalConstructor()
->getMock();
$handler = $this->createMock(ErrorHandler::class);
$newErrorRenderers = [
'application/xml' => XmlErrorRenderer::class,
'text/xml' => XmlErrorRenderer::class,
Expand Down Expand Up @@ -164,10 +155,7 @@ public function testDetermineContentTypeTextPlainMultiAcceptHeader()
->withHeader('Content-Type', 'text/plain')
->withHeader('Accept', 'text/plain,text/xml');

$handler = $this
->getMockBuilder(ErrorHandler::class)
->disableOriginalConstructor()
->getMock();
$handler = $this->createMock(ErrorHandler::class);

$errorRenderers = [
'text/plain' => PlainTextErrorRenderer::class,
Expand Down Expand Up @@ -199,10 +187,7 @@ public function testDetermineContentTypeApplicationJsonOrXml()
->withHeader('Content-Type', 'text/json')
->withHeader('Accept', 'application/xhtml+xml');

$handler = $this
->getMockBuilder(ErrorHandler::class)
->disableOriginalConstructor()
->getMock();
$handler = $this->createMock(ErrorHandler::class);

$errorRenderers = [
'application/xml' => XmlErrorRenderer::class
Expand Down Expand Up @@ -242,10 +227,7 @@ public function testAcceptableMediaTypeIsNotFirstInList()
$method->setAccessible(true);

// use a mock object here as ErrorHandler cannot be directly instantiated
$handler = $this
->getMockBuilder(ErrorHandler::class)
->disableOriginalConstructor()
->getMock();
$handler = $this->createMock(ErrorHandler::class);

// call determineContentType()
$return = $method->invoke($handler, $request);
Expand Down
3 changes: 2 additions & 1 deletion tests/Middleware/BodyParsingMiddlewareTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ protected function createRequestWithBody($contentType, $body)
}


public function parsingProvider()
public static function parsingProvider()
{
return [
'form' => [
Expand Down Expand Up @@ -148,6 +148,7 @@ public function parsingProvider()
/**
* @dataProvider parsingProvider
*/
#[\PHPUnit\Framework\Attributes\DataProvider('parsingProvider')]
public function testParsing($contentType, $body, $expected)
{
$request = $this->createRequestWithBody($contentType, $body);
Expand Down
3 changes: 2 additions & 1 deletion tests/MiddlewareDispatcherTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ public function testDeferredResolvedCallableWithDirectConstructorCall(): void
$this->assertSame(1, $handler->getCalledCount());
}

public function deferredCallableProvider(): array
public static function deferredCallableProvider(): array
{
return [
[MockMiddlewareSlimCallable::class . ':custom', new MockMiddlewareSlimCallable()],
Expand All @@ -157,6 +157,7 @@ public function deferredCallableProvider(): array
* @param string $callable
* @param callable|MiddlewareInterface
*/
#[\PHPUnit\Framework\Attributes\DataProvider('deferredCallableProvider')]
public function testDeferredResolvedCallableWithContainerAndNonAdvancedCallableResolverUnableToResolveCallable(
$callable,
$result
Expand Down
Loading