Test Setup Failed
Pull Request — master (#79)
by Marco
31:16
created

LazySessionTest::testIsALazySession()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
eloc 2
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\MockObject\MockObject;
24
use PHPUnit\Framework\TestCase;
25
use PSR7Sessions\Storageless\Session\LazySession;
26
use PSR7Sessions\Storageless\Session\SessionInterface;
27
use function uniqid;
28
29
/**
30
 * @covers \PSR7Sessions\Storageless\Session\LazySession
31
 */
32
final class LazySessionTest extends TestCase
33
{
34
    /** @var SessionInterface|MockObject */
35
    private $wrappedSession;
36
37
    /** @var callable|MockObject */
38
    private $sessionLoader;
39
40
    /** @var LazySession */
41
    private $lazySession;
42
43
    /**
44
     * {@inheritDoc}
45
     */
46
    protected function setUp() : void
47
    {
48
        $this->wrappedSession = $this->createMock(SessionInterface::class);
49
        /** @var callable|MockObject $sessionLoader */
50
        $sessionLoader       = $this->getMockBuilder(\stdClass::class)->setMethods(['__invoke'])->getMock();
51
        $this->sessionLoader = $sessionLoader;
0 ignored issues
show
Documentation Bug introduced by
It seems like $sessionLoader can also be of type object<PHPUnit\Framework\MockObject\MockObject>. However, the property $sessionLoader is declared as type callable. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
52
        $this->lazySession   = LazySession::fromContainerBuildingCallback($this->sessionLoader);
53
    }
54
55
    public function testLazyNonInitializedSessionIsAlwaysNotChanged() : void
56
    {
57
        $this->sessionLoader->expects(self::never())->method('__invoke');
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...
58
59
        self::assertFalse($this->lazySession->hasChanged());
60
    }
61
62
    public function testHasChanged() : void
63
    {
64
        $this->wrappedSessionWillBeLoaded();
65
66
        $this->wrappedSession->expects(self::at(1))->method('hasChanged')->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...
67
        $this->wrappedSession->expects(self::at(2))->method('hasChanged')->willReturn(false);
68
69
        $this->forceWrappedSessionInitialization();
70
71
        self::assertTrue($this->lazySession->hasChanged());
72
        self::assertFalse($this->lazySession->hasChanged());
73
    }
74
75
    public function testHas() : void
76
    {
77
        $this->wrappedSessionWillBeLoaded();
78
79
        $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...
80
            ['foo', false],
81
            ['bar', true],
82
        ]);
83
84
        self::assertFalse($this->lazySession->has('foo'));
85
        self::assertTrue($this->lazySession->has('bar'));
86
    }
87
88
    public function testGet() : void
89
    {
90
        $this->wrappedSessionWillBeLoaded();
91
92
        $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...
93
            ['foo', null, 'bar'],
94
            ['baz', null, 'tab'],
95
            ['baz', 'default', 'taz'],
96
        ]);
97
98
        self::assertSame('bar', $this->lazySession->get('foo'));
99
        self::assertSame('tab', $this->lazySession->get('baz'));
100
        self::assertSame('taz', $this->lazySession->get('baz', 'default'));
101
    }
102
103
    public function testRemove() : void
104
    {
105
        $this->wrappedSessionWillBeLoaded();
106
107
        $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...
108
109
        $this->lazySession->remove('foo');
110
        $this->lazySession->remove('bar');
111
    }
112
113
    public function testClear() : void
114
    {
115
        $this->wrappedSessionWillBeLoaded();
116
117
        $this->wrappedSession->expects(self::exactly(2))->method('clear');
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...
118
119
        $this->lazySession->clear();
120
        $this->lazySession->clear();
121
    }
122
123
    public function testSet() : void
124
    {
125
        $this->wrappedSessionWillBeLoaded();
126
127
        $this
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...
128
            ->wrappedSession
129
            ->expects(self::exactly(2))
130
            ->method('set')
131
            ->with(self::logicalOr('foo', 'baz'), self::logicalOr('bar', 'tab'));
132
133
        $this->lazySession->set('foo', 'bar');
134
        $this->lazySession->set('baz', 'tab');
135
    }
136
137
    public function testIsEmpty() : void
138
    {
139
        $this->wrappedSessionWillBeLoaded();
140
141
        $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...
142
        $this->wrappedSession->expects(self::at(1))->method('isEmpty')->willReturn(false);
143
144
        self::assertTrue($this->lazySession->isEmpty());
145
        self::assertFalse($this->lazySession->isEmpty());
146
    }
147
148
    public function testJsonSerialize() : void
149
    {
150
        $this->wrappedSessionWillBeLoaded();
151
152
        $this->wrappedSession->expects(self::at(0))->method('jsonSerialize')->willReturn((object) ['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...
153
        $this->wrappedSession->expects(self::at(1))->method('jsonSerialize')->willReturn((object) ['baz' => 'tab']);
154
155
        self::assertEquals((object) ['foo' => 'bar'], $this->lazySession->jsonSerialize());
156
        self::assertEquals((object) ['baz' => 'tab'], $this->lazySession->jsonSerialize());
157
    }
158
159
    private function wrappedSessionWillBeLoaded() : void
160
    {
161
        $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...
162
    }
163
164
    private function forceWrappedSessionInitialization() : void
165
    {
166
        // no-op operation that is known to trigger session lazy-loading
167
        $this->lazySession->remove(uniqid('nonExisting', true));
168
    }
169
}
170