Completed
Pull Request — master (#58)
by Thijs
04:00
created

SessionArrayAccessorTest::testOffsetExists()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 13
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 13
rs 9.4285
cc 1
eloc 7
nc 1
nop 0
1
<?php
2
/*
3
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
4
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
5
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
6
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
7
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
8
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
9
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
10
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
11
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
12
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
13
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
14
 *
15
 * This software consists of voluntary contributions made by many individuals
16
 * and is licensed under the MIT license.
17
 */
18
19
declare(strict_types = 1);
20
21
namespace PSR7SessionsTest\Storageless\Session;
22
23
use PHPUnit_Framework_TestCase;
24
use PSR7Sessions\Storageless\Session\LazySession;
25
use PSR7Sessions\Storageless\Session\ArrayAccessor;
26
use PSR7Sessions\Storageless\Session\SessionInterface;
27
28
/**
29
 * @covers \PSR7Sessions\Storageless\Session\ArrayAccessor
30
 */
31
final class SessionArrayAccessorTest extends PHPUnit_Framework_TestCase
32
{
33
    /**
34
     * @var SessionInterface|\PHPUnit_Framework_MockObject_MockObject
35
     */
36
    private $wrappedSession;
37
38
    /**
39
     * @var callable|\PHPUnit_Framework_MockObject_MockObject
40
     */
41
    private $sessionLoader;
42
43
    /**
44
     * @var ArrayAccessor
45
     */
46
    private $arrayAccess;
47
48
    /**
49
     * {@inheritDoc}
50
     */
51
    protected function setUp()
52
    {
53
        $this->wrappedSession = $this->createMock(SessionInterface::class);
54
        $this->sessionLoader = $this->getMockBuilder(\stdClass::class)->setMethods(['__invoke'])->getMock();
55
        $session = LazySession::fromContainerBuildingCallback($this->sessionLoader);
56
57
        $this->arrayAccess = new ArrayAccessor($session);
58
    }
59
60
    public function testIsAnSessionArrayAccessor()
61
    {
62
        self::assertInstanceOf(ArrayAccessor::class, $this->arrayAccess);
63
    }
64
65
    public function testOffsetExists()
66
    {
67
        $this->wrappedSessionWillBeLoaded();
68
        $this->wrappedSession->expects(self::exactly(2))->method('has')->willReturnMap(
0 ignored issues
show
Bug introduced by
The method expects does only exist in PHPUnit_Framework_MockObject_MockObject, but not in PSR7Sessions\Storageless\Session\SessionInterface.

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...
69
            [
70
                ['foo', false],
71
                ['bar', true],
72
            ]
73
        );
74
75
        self::assertFalse($this->arrayAccess->offsetExists('foo'));
76
        self::assertTrue($this->arrayAccess->offsetExists('bar'));
77
    }
78
79
    /**
80
     *
81
     */
82
    public function testOffsetUnset()
83
    {
84
        $this->wrappedSessionWillBeLoaded();
85
        $this->wrappedSession->expects(self::exactly(2))->method('remove')->with(self::logicalOr('foo', 'bar'));
0 ignored issues
show
Bug introduced by
The method expects does only exist in PHPUnit_Framework_MockObject_MockObject, but not in PSR7Sessions\Storageless\Session\SessionInterface.

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...
86
87
        $this->arrayAccess->offsetUnset('foo');
88
        $this->arrayAccess->offsetUnset('bar');
89
    }
90
91
    public function testOffsetGet()
92
    {
93
        $this->wrappedSessionWillBeLoaded();
94
        $this->wrappedSession->expects(self::exactly(3))->method('get')->willReturnMap(
0 ignored issues
show
Bug introduced by
The method expects does only exist in PHPUnit_Framework_MockObject_MockObject, but not in PSR7Sessions\Storageless\Session\SessionInterface.

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...
95
            [
96
                ['foo', null, 'bar'],
97
                ['baz', null, 'tab'],
98
                ['baz', 'default', 'taz'],
99
            ]
100
        );
101
102
        self::assertSame('bar', $this->arrayAccess->offsetGet('foo'));
103
        self::assertSame('tab', $this->arrayAccess->offsetGet('baz'));
104
        self::assertSame('taz', $this->arrayAccess->offsetGet('baz', 'default'));
105
    }
106
107
    public function testOffsetSet()
108
    {
109
        $this->wrappedSessionWillBeLoaded();
110
        $this->wrappedSession->expects(self::exactly(2))->method('set')->with(
0 ignored issues
show
Bug introduced by
The method expects does only exist in PHPUnit_Framework_MockObject_MockObject, but not in PSR7Sessions\Storageless\Session\SessionInterface.

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...
111
            self::logicalOr('foo', 'baz'),
112
            self::logicalOr('bar', 'tab')
113
        );
114
115
        $this->arrayAccess->offsetSet('foo', 'bar');
116
        $this->arrayAccess->offsetSet('baz', 'tab');
117
    }
118
119
    public function testIsEmpty()
120
    {
121
        $this->wrappedSessionWillBeLoaded();
122
123
        $this->wrappedSession->expects(self::at(0))->method('isEmpty')->willReturn(true);
0 ignored issues
show
Bug introduced by
The method expects does only exist in PHPUnit_Framework_MockObject_MockObject, but not in PSR7Sessions\Storageless\Session\SessionInterface.

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...
124
        $this->wrappedSession->expects(self::at(1))->method('isEmpty')->willReturn(false);
125
126
        self::assertTrue($this->arrayAccess->isEmpty());
0 ignored issues
show
Documentation Bug introduced by
The method isEmpty does not exist on object<PSR7Sessions\Stor...\Session\ArrayAccessor>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
127
        self::assertFalse($this->arrayAccess->isEmpty());
0 ignored issues
show
Documentation Bug introduced by
The method isEmpty does not exist on object<PSR7Sessions\Stor...\Session\ArrayAccessor>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
128
    }
129
130
    private function wrappedSessionWillBeLoaded()
131
    {
132
        $this->sessionLoader->expects(self::once())->method('__invoke')->willReturn($this->wrappedSession);
0 ignored issues
show
Bug introduced by
The method expects cannot be called on $this->sessionLoader (of type callable).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
133
    }
134
}
135