Completed
Pull Request — master (#1)
by David
02:43
created

IsSafeHttpRouteTest::routesProvider()   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 25
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 25
rs 8.8571
c 0
b 0
f 0
cc 1
eloc 17
nc 1
nop 0
1
<?php
2
declare(strict_types=1);
3
4
namespace TheCodingMachine\Middlewares\SafeRequests;
5
6
use PHPUnit\Framework\TestCase;
7
use Psr\Http\Message\RequestInterface;
8
use Psr\Http\Message\ServerRequestInterface;
9
use Psr\Http\Message\UriInterface;
10
11
/**
12
 * @covers \TheCodingMachine\Middlewares\SafeRequests\IsSafeHttpRoute
13
 */
14
final class IsSafeHttpRouteTest extends \PHPUnit_Framework_TestCase
15
{
16
    /**
17
     * @dataProvider routesProvider
18
     *
19
     * @param array  $routes
20
     * @param string $path
21
     * @param bool   $expectedResult
22
     */
23
    public function testSafeRoutes(array $routes, string $path, bool $expectedResult)
24
    {
25
        /* @var $uri UriInterface|\PHPUnit_Framework_MockObject_MockObject */
26
        $uri = $this->getMockBuilder(UriInterface::class)->getMock();
27
28
        $uri->expects(self::any())->method('getPath')->willReturn($path);
0 ignored issues
show
Bug introduced by
The method expects does only exist in PHPUnit_Framework_MockObject_MockObject, but not in Psr\Http\Message\UriInterface.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
29
30
        /* @var $request RequestInterface|\PHPUnit_Framework_MockObject_MockObject */
31
        $request = $this->getMockBuilder(ServerRequestInterface::class)->getMock();
32
33
        $request->expects(self::any())->method('getUri')->willReturn($uri);
0 ignored issues
show
Bug introduced by
The method expects does only exist in PHPUnit_Framework_MockObject_MockObject, but not in Psr\Http\Message\RequestInterface.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
34
35
        self::assertSame($expectedResult, (new IsSafeHttpRoute(...$routes))->__invoke($request));
0 ignored issues
show
Documentation introduced by
$request is of type object<Psr\Http\Message\..._MockObject_MockObject>, but the function expects a object<Psr\Http\Message\ServerRequestInterface>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
36
    }
37
38
    public function routesProvider() : array
39
    {
40
        return [
41
            'empty' => [
42
                [],
43
                '/',
44
                false,
45
            ],
46
            'request one' => [
47
                ['#/#'],
48
                '/',
49
                true,
50
            ],
51
            'many routes' => [
52
                ['#^/foo$#', '#^/bar$#'],
53
                '/bar',
54
                true,
55
            ],
56
            'many routes' => [
57
                ['#^/foo$#', '#^/bar$#'],
58
                '/baz',
59
                false,
60
            ],
61
        ];
62
    }
63
}
64