Skip to content

Commit dedfd17

Browse files
authored
Add support for PHP 8.4 & 8.5, Remove Prophecy (#337)
* Only call setAccessible() for PHP < 8.1 * Replace Prophecy with native PHPUnit mocks * Add PHP 8.4 and 8.4 to the CI matrix
1 parent b4268d8 commit dedfd17

File tree

6 files changed

+95
-117
lines changed

6 files changed

+95
-117
lines changed

.github/workflows/tests.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,9 @@ jobs:
99
strategy:
1010
fail-fast: false
1111
matrix:
12-
php: [ 7.4, 8.0, 8.1, 8.2, 8.3 ]
12+
php: [ 7.4, 8.0, 8.1, 8.2, 8.3, 8.4, 8.5 ]
1313
include:
14-
- php: 8.2
14+
- php: 8.4
1515
analysis: true
1616

1717
steps:

composer.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@
3131
"twig/twig": "^3.11"
3232
},
3333
"require-dev": {
34-
"phpspec/prophecy-phpunit": "^2.0",
3534
"phpstan/phpstan": "^1.10.59",
3635
"phpunit/phpunit": "^9.6 || ^10",
3736
"psr/http-factory": "^1.0",

tests/TestCase.php

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,20 +10,19 @@
1010

1111
namespace Slim\Tests;
1212

13-
use Prophecy\PhpUnit\ProphecyTrait;
1413
use PHPUnit\Framework\TestCase as PhpUnitTestCase;
1514
use ReflectionProperty;
1615

1716
use function get_class;
1817

1918
abstract class TestCase extends PhpUnitTestCase
2019
{
21-
use ProphecyTrait;
22-
2320
protected function assertInaccessiblePropertySame($expected, $obj, string $name)
2421
{
2522
$prop = new ReflectionProperty(get_class($obj), $name);
26-
$prop->setAccessible(true);
23+
if (PHP_VERSION_ID < 80100) {
24+
$prop->setAccessible(true);
25+
}
2726
$this->assertSame($expected, $prop->getValue($obj));
2827
}
2928
}

tests/TwigMiddlewareTest.php

Lines changed: 55 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,6 @@
1010

1111
namespace Slim\Tests;
1212

13-
use Prophecy\Argument;
14-
use Prophecy\Prophecy\ObjectProphecy;
1513
use Psr\Container\ContainerInterface;
1614
use Psr\Http\Message\ResponseInterface;
1715
use Psr\Http\Message\ServerRequestInterface;
@@ -30,35 +28,34 @@
3028
class TwigMiddlewareTest extends TestCase
3129
{
3230
/**
33-
* Create a twig prophecy given a uri prophecy and a base path.
31+
* Create a twig mock given a uri mock and a base path.
3432
*
35-
* @param ObjectProphecy $uriProphecy
33+
* @param UriInterface $uri
3634
* @param string $basePath
3735
*
38-
* @return ObjectProphecy&Twig
36+
* @return Twig
3937
*/
40-
private function createTwigProphecy(ObjectProphecy $uriProphecy, string $basePath)
38+
private function createTwigMock(UriInterface $uri, string $basePath)
4139
{
4240
$self = $this;
4341

44-
$twigProphecy = $this->prophesize(Twig::class);
42+
$twigMock = $this->createMock(Twig::class);
4543

46-
$twigProphecy
47-
->addRuntimeLoader(Argument::type(RuntimeLoaderInterface::class))
48-
->will(function ($args) use ($self, $uriProphecy, $basePath) {
44+
$twigMock->expects($this->once())
45+
->method('addRuntimeLoader')
46+
->with($this->isInstanceOf(RuntimeLoaderInterface::class))
47+
->willReturnCallback(function ($runtimeLoader) use ($self, $uri, $basePath) {
4948
/** @var TwigRuntimeLoader $runtimeLoader */
50-
$runtimeLoader = $args[0];
5149
$runtimeExtension = $runtimeLoader->load(TwigRuntimeExtension::class);
5250

5351
$self->assertInstanceOf(TwigRuntimeExtension::class, $runtimeExtension);
5452

5553
/** @var TwigRuntimeExtension $runtimeExtension */
56-
$self->assertSame($uriProphecy->reveal(), $runtimeExtension->getUri());
54+
$self->assertSame($uri, $runtimeExtension->getUri());
5755
$self->assertSame($basePath, $runtimeExtension->getBasePath());
58-
})
59-
->shouldBeCalledOnce();
56+
});
6057

61-
return $twigProphecy;
58+
return $twigMock;
6259
}
6360

6461
public function testCreateFromContainer()
@@ -164,79 +161,78 @@ public function testCreate()
164161
public function testProcess()
165162
{
166163
$basePath = '/base-path';
167-
$uriProphecy = $this->prophesize(UriInterface::class);
168-
$twigProphecy = $this->createTwigProphecy($uriProphecy, $basePath);
169-
$routeParserProphecy = $this->prophesize(RouteParserInterface::class);
164+
$uri = $this->createMock(UriInterface::class);
165+
$twig = $this->createTwigMock($uri, $basePath);
166+
$routeParser = $this->createMock(RouteParserInterface::class);
170167

171168
$twigMiddleware = new TwigMiddleware(
172-
$twigProphecy->reveal(),
173-
$routeParserProphecy->reveal(),
169+
$twig,
170+
$routeParser,
174171
$basePath
175172
);
176173

177-
$responseProphecy = $this->prophesize(ResponseInterface::class);
174+
$response = $this->createMock(ResponseInterface::class);
178175

179-
$requestProphecy = $this->prophesize(ServerRequestInterface::class);
180-
$requestProphecy
181-
->getUri()
182-
->willReturn($uriProphecy->reveal())
183-
->shouldBeCalledOnce();
176+
$request = $this->createMock(ServerRequestInterface::class);
177+
$request->expects($this->once())
178+
->method('getUri')
179+
->willReturn($uri);
184180

185-
$requestHandlerProphecy = $this->prophesize(RequestHandlerInterface::class);
186-
$requestHandlerProphecy
187-
->handle($requestProphecy->reveal())
188-
->shouldBeCalledOnce()
189-
->willReturn($responseProphecy->reveal());
181+
$requestHandler = $this->createMock(RequestHandlerInterface::class);
182+
$requestHandler->expects($this->once())
183+
->method('handle')
184+
->with($request)
185+
->willReturn($response);
190186

191-
$twigMiddleware->process($requestProphecy->reveal(), $requestHandlerProphecy->reveal());
187+
$twigMiddleware->process($request, $requestHandler);
192188
}
193189

194190
public function testProcessWithRequestAttribute()
195191
{
196192
$routeParser = $this->createMock(RouteParserInterface::class);
197-
$uriProphecy = $this->prophesize(UriInterface::class);
193+
$uri = $this->createMock(UriInterface::class);
198194

199195
/** @var Twig $twig */
200-
$twig = $this->createTwigProphecy($uriProphecy, '')->reveal();
196+
$twig = $this->createTwigMock($uri, '');
201197

202198
$twigMiddleware = new TwigMiddleware($twig, $routeParser, '', 'view');
203199

204-
$responseProphecy = $this->prophesize(ResponseInterface::class);
200+
$response = $this->createMock(ResponseInterface::class);
205201

206-
// Prophesize the server request that would be returned in the `withAttribute` method.
207-
$requestProphecy2 = $this->prophesize(ServerRequestInterface::class);
202+
// Create the server request that would be returned in the `withAttribute` method.
203+
$request2 = $this->createMock(ServerRequestInterface::class);
208204

209-
// Prophesize the server request.
210-
$requestProphecy = $this->prophesize(ServerRequestInterface::class);
211-
$requestProphecy->withAttribute('view', Argument::type(Twig::class))
212-
->shouldBeCalledOnce()
213-
->will(function ($args) use ($requestProphecy2): ServerRequestInterface {
214-
$requestProphecy2->getAttribute('view')
215-
->shouldBeCalledOnce()
216-
->willReturn($args[1]);
205+
// Create the server request.
206+
$request = $this->createMock(ServerRequestInterface::class);
207+
$request->expects($this->once())
208+
->method('withAttribute')
209+
->with('view', $this->isInstanceOf(Twig::class))
210+
->willReturnCallback(function ($name, $value) use ($request2) {
211+
$request2->expects($this->once())
212+
->method('getAttribute')
213+
->with('view')
214+
->willReturn($value);
217215

218-
return $requestProphecy2->reveal();
216+
return $request2;
219217
});
220218

221-
$requestProphecy
222-
->getUri()
223-
->willReturn($uriProphecy->reveal())
224-
->shouldBeCalledOnce();
219+
$request->expects($this->once())
220+
->method('getUri')
221+
->willReturn($uri);
225222

226-
// Prophesize the request handler.
227-
$requestHandlerProphecy = $this->prophesize(RequestHandlerInterface::class);
223+
// Create the request handler.
224+
$requestHandler = $this->createMock(RequestHandlerInterface::class);
228225
$that = $this;
229-
$requestHandlerProphecy
230-
->handle($requestProphecy2->reveal())
231-
->shouldBeCalledOnce()
232-
->will(function ($args) use ($that, $twig, $responseProphecy): ResponseInterface {
226+
$requestHandler->expects($this->once())
227+
->method('handle')
228+
->with($request2)
229+
->willReturnCallback(function ($serverRequest) use ($that, $twig, $response): ResponseInterface {
233230
/** @var ServerRequestInterface $serverRequest */
234-
$serverRequest = $args[0];
235231
$that->assertSame($twig, $serverRequest->getAttribute('view'));
236232

237-
return $responseProphecy->reveal();
233+
return $response;
238234
});
239235

240-
$twigMiddleware->process($requestProphecy->reveal(), $requestHandlerProphecy->reveal());
236+
$twigMiddleware->process($request, $requestHandler);
241237
}
242238
}

tests/TwigRuntimeExtensionTest.php

Lines changed: 19 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -93,15 +93,10 @@ public function testIsCurrentUrl(string $pattern, array $data, string $path, ?st
9393
$routeName = 'route';
9494
$this->mapRouteCollectorRoute($routeCollector, ['GET'], $pattern, $routeName);
9595

96-
$uriProphecy = $this->prophesize(UriInterface::class);
97-
98-
$uriProphecy
99-
->getPath()
100-
->willReturn($path)
101-
->shouldBeCalledOnce();
102-
103-
/** @var UriInterface $uri */
104-
$uri = $uriProphecy->reveal();
96+
$uri = $this->createMock(UriInterface::class);
97+
$uri->expects($this->once())
98+
->method('getPath')
99+
->willReturn($path);
105100

106101
$extension = new TwigRuntimeExtension($routeParser, $uri, $basePath);
107102
$result = $extension->isCurrentUrl($routeName, $data);
@@ -135,29 +130,24 @@ public function testCurrentUrl(string $pattern, string $url, string $basePath, b
135130
$routeName = 'route';
136131
$this->mapRouteCollectorRoute($routeCollector, ['GET'], $pattern, $routeName);
137132

138-
$uriProphecy = $this->prophesize(UriInterface::class);
133+
$uri = $this->createMock(UriInterface::class);
139134

140135
$path = parse_url($url, PHP_URL_PATH);
141136
$query = parse_url($url, PHP_URL_QUERY) ?? '';
142137

143-
$uriProphecy
144-
->getPath()
145-
->willReturn($path)
146-
->shouldBeCalledOnce();
138+
$uri->expects($this->once())
139+
->method('getPath')
140+
->willReturn($path);
147141

148-
$uriProphecy
149-
->getQuery()
150-
->willReturn($query)
151-
->shouldBeCalledOnce();
142+
$uri->expects($this->once())
143+
->method('getQuery')
144+
->willReturn($query);
152145

153146
$expected = $basePath . $path;
154147
if ($withQueryString) {
155148
$expected .= '?' . $query;
156149
}
157150

158-
/** @var UriInterface $uri */
159-
$uri = $uriProphecy->reveal();
160-
161151
$extension = new TwigRuntimeExtension($routeParser, $uri, $basePath);
162152
$result = $extension->getCurrentUrl($withQueryString);
163153

@@ -195,10 +185,7 @@ public function testUrlFor(
195185
$routeCollector = $this->createRouteCollector($basePath);
196186
$this->mapRouteCollectorRoute($routeCollector, ['GET'], $pattern, $routeName);
197187

198-
$uriProphecy = $this->prophesize(UriInterface::class);
199-
200-
/** @var UriInterface $uri */
201-
$uri = $uriProphecy->reveal();
188+
$uri = $this->createMock(UriInterface::class);
202189

203190
$extension = new TwigRuntimeExtension($routeCollector->getRouteParser(), $uri, $routeCollector->getBasePath());
204191
$this->assertEquals($expectedUrl, $extension->urlFor($routeName, $routeData, $queryParams));
@@ -241,18 +228,15 @@ public function testFullUrlFor(
241228
$routeCollector = $this->createRouteCollector($basePath);
242229
$this->mapRouteCollectorRoute($routeCollector, ['GET'], $pattern, $routeName);
243230

244-
$uriProphecy = $this->prophesize(UriInterface::class);
245-
246-
$uriProphecy->getScheme()
247-
->willReturn('http')
248-
->shouldBeCalledOnce();
231+
$uri = $this->createMock(UriInterface::class);
249232

250-
$uriProphecy->getAuthority()
251-
->willReturn('localhost')
252-
->shouldBeCalledOnce();
233+
$uri->expects($this->once())
234+
->method('getScheme')
235+
->willReturn('http');
253236

254-
/** @var UriInterface $uri */
255-
$uri = $uriProphecy->reveal();
237+
$uri->expects($this->once())
238+
->method('getAuthority')
239+
->willReturn('localhost');
256240

257241
$extension = new TwigRuntimeExtension($routeCollector->getRouteParser(), $uri, $routeCollector->getBasePath());
258242
$this->assertEquals($expectedFullUrl, $extension->fullUrlFor($routeName, $routeData, $queryParams));

tests/TwigTest.php

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -27,25 +27,25 @@ public function testFromRequest()
2727
{
2828
$twig = $this->createMock(Twig::class);
2929

30-
$serverRequestProphecy = $this->prophesize(ServerRequestInterface::class);
31-
$serverRequestProphecy->getAttribute('view')
30+
$serverRequest = $this->createMock(ServerRequestInterface::class);
31+
$serverRequest->expects($this->once())
32+
->method('getAttribute')
33+
->with('view')
3234
->willReturn($twig);
3335

34-
/** @var ServerRequestInterface $serverRequest */
35-
$serverRequest = $serverRequestProphecy->reveal();
3636
$this->assertSame($twig, Twig::fromRequest($serverRequest));
3737
}
3838

3939
public function testFromRequestCustomAttributeName()
4040
{
4141
$twig = $this->createMock(Twig::class);
4242

43-
$serverRequestProphecy = $this->prophesize(ServerRequestInterface::class);
44-
$serverRequestProphecy->getAttribute('foo')
43+
$serverRequest = $this->createMock(ServerRequestInterface::class);
44+
$serverRequest->expects($this->once())
45+
->method('getAttribute')
46+
->with('foo')
4547
->willReturn($twig);
4648

47-
/** @var ServerRequestInterface $serverRequest */
48-
$serverRequest = $serverRequestProphecy->reveal();
4949
$this->assertSame($twig, Twig::fromRequest($serverRequest, 'foo'));
5050
}
5151

@@ -54,12 +54,12 @@ public function testFromRequestTwigNotFound()
5454
$this->expectException(RuntimeException::class);
5555
$this->expectExceptionMessage('Twig could not be found in the server request attributes using the key "view".');
5656

57-
$serverRequestProphecy = $this->prophesize(ServerRequestInterface::class);
58-
$serverRequestProphecy->getAttribute('view')
57+
$serverRequest = $this->createMock(ServerRequestInterface::class);
58+
$serverRequest->expects($this->once())
59+
->method('getAttribute')
60+
->with('view')
5961
->willReturn(null);
6062

61-
/** @var ServerRequestInterface $serverRequest */
62-
$serverRequest = $serverRequestProphecy->reveal();
6363
Twig::fromRequest($serverRequest);
6464
}
6565

@@ -68,12 +68,12 @@ public function testFromRequestNotTwig()
6868
$this->expectException(RuntimeException::class);
6969
$this->expectExceptionMessage('Twig could not be found in the server request attributes using the key "view".');
7070

71-
$serverRequestProphecy = $this->prophesize(ServerRequestInterface::class);
72-
$serverRequestProphecy->getAttribute('view')
71+
$serverRequest = $this->createMock(ServerRequestInterface::class);
72+
$serverRequest->expects($this->once())
73+
->method('getAttribute')
74+
->with('view')
7375
->willReturn('twiggy');
7476

75-
/** @var ServerRequestInterface $serverRequest */
76-
$serverRequest = $serverRequestProphecy->reveal();
7777
Twig::fromRequest($serverRequest);
7878
}
7979

0 commit comments

Comments
 (0)