Completed
Push — master ( 691f6c...479a44 )
by Divine Niiquaye
03:20 queued 01:32
created

Tests/Psr6CacheTest.php (1 issue)

Labels
Severity
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This file is part of BiuradPHP opensource projects.
7
 *
8
 * PHP version 7.1 and above required
9
 *
10
 * @author    Divine Niiquaye Ibok <[email protected]>
11
 * @copyright 2019 Biurad Group (https://biurad.com/)
12
 * @license   https://opensource.org/licenses/BSD-3-Clause License
13
 *
14
 * For the full copyright and license information, please view the LICENSE
15
 * file that was distributed with this source code.
16
 */
17
18
namespace BiuradPHP\Cache\Tests;
19
20
use __PHP_Incomplete_Class;
21
use BadMethodCallException;
22
use BiuradPHP\Cache\CacheItem;
23
use BiuradPHP\Cache\CacheItemPool;
24
use BiuradPHP\Cache\Exceptions\InvalidArgumentException;
25
use BiuradPHP\Cache\SimpleCache;
26
use DateInterval;
27
use DateTime;
28
use Doctrine\Common\Cache\ArrayCache;
29
use Doctrine\Common\Cache\PhpFileCache;
30
use Generator;
31
use PHPUnit\Framework\TestCase;
32
use Psr\Cache\CacheItemInterface;
33
use Psr\Cache\CacheItemPoolInterface;
34
use ReflectionProperty;
35
36
/**
37
 * @internal
38
 */
39
class Psr6CacheTest extends TestCase
40
{
41
    /** @var CacheItemPool */
42
    private $cache;
43
44
    protected function setUp(): void
45
    {
46
        parent::setUp();
47
48
        $adapter        = new ArrayCache();
49
        $this->cache    = new CacheItemPool(new SimpleCache($adapter));
50
    }
51
52
    /**
53
     * @throws InvalidArgumentException
54
     */
55
    public function testProvider(): void
56
    {
57
        $pool = $this->cache;
58
59
        $this->assertInstanceOf(CacheItemPoolInterface::class, $pool);
60
        $key = 'pool';
61
62
        $this->assertTrue($pool->deleteItem($key));
63
        $this->assertFalse($pool->hasItem($key));
64
65
        $item = $pool->getItem($key);
66
        $item->set('bar');
67
        $this->assertTrue($pool->save($item));
68
        $this->assertTrue($pool->hasItem($key));
69
        $this->assertSame('bar', $pool->getItem($key)->get());
70
71
        $this->assertTrue($pool->deleteItem($key));
72
        $this->assertNull($pool->getItem($key)->get());
73
74
        $item = $pool->getItem($key);
75
        $item->set('bar');
76
        $pool->save($item);
77
        $this->assertTrue($pool->getItem($key)->isHit());
78
79
        $pool->clear();
80
        $this->assertNull($pool->getItem($key)->get());
81
        $this->assertFalse($pool->hasItem($key));
82
    }
83
84
    public function testInvalidKey(): void
85
    {
86
        $pool = $this->cache;
87
88
        $this->expectException(InvalidArgumentException::class);
89
        $this->expectExceptionMessage('Cache key "{}()/\@:" contains reserved characters "{}()/\@:');
90
        $pool->getItem(CacheItem::RESERVED_CHARACTERS);
91
    }
92
93
    public function testCacheItems(): void
94
    {
95
        $pool = $this->cache;
96
97
        $i0  = $pool->getItem('i0');
98
        $i1  = $pool->getItem('i1');
99
        $i2  = $pool->getItem('i2');
100
        $i3  = $pool->getItem('i3');
101
        $foo = $pool->getItem('foo');
102
103
        $pool->save($i0);
104
        $pool->save($i1);
105
        $pool->save($i2);
106
        $pool->save($i3);
107
        $pool->save($foo);
108
109
        $pool->deleteItems(['i0', 'i2']);
110
111
        $this->assertFalse($pool->getItem('i0')->isHit());
112
        $this->assertTrue($pool->getItem('i1')->isHit());
113
        $this->assertFalse($pool->getItem('i2')->isHit());
114
        $this->assertTrue($pool->getItem('i3')->isHit());
115
        $this->assertTrue($pool->getItem('foo')->isHit());
116
117
        $pool->deleteItems(['i1', 'i3']);
118
119
        $this->assertFalse($pool->getItem('i1')->isHit());
120
        $this->assertFalse($pool->getItem('i3')->isHit());
121
        $this->assertTrue($pool->getItem('foo')->isHit());
122
123
        $anotherPoolInstance = $this->cache;
124
125
        $this->assertFalse($anotherPoolInstance->getItem('i1')->isHit());
126
        $this->assertFalse($anotherPoolInstance->getItem('i3')->isHit());
127
        $this->assertTrue($anotherPoolInstance->getItem('foo')->isHit());
128
    }
129
130
    public function testInvalidateCommits(): void
131
    {
132
        $pool = $this->cache;
133
134
        $foo = $pool->getItem('foo');
135
136
        $pool->saveDeferred($foo->set('foo'));
137
138
        // ??: This seems to contradict a bit logic in deleteItems,
139
        // ??: where it does unset($this->deferred[$key]); on key matches
140
141
        $foo = $pool->getItem('foo');
142
143
        $this->assertTrue($foo->isHit());
144
145
        $pool->saveDeferred($foo);
146
        $this->assertTrue($pool->hasItem('foo'));
147
        $pool->clear();
148
149
        $item = $pool->getItem('foo');
150
        $item->set(function () {
151
            return 'value';
152
        });
153
        $pool->saveDeferred($item);
154
155
        $items = $pool->getItems(['foo', 'empty']);
156
        $items = \iterator_to_array($items);
157
158
        $key1 = $items['foo'];
159
        $this->assertIsCallable($key1->get());
160
161
        $key2 = $items['empty'];
162
        $this->assertFalse($key2->isHit());
163
    }
164
165
    /**
166
     * @throws InvalidArgumentException
167
     */
168
    public function testMultiples(): void
169
    {
170
        $data = [
171
            'foo'      => 'baz',
172
            'pool'     => 'bar',
173
        ];
174
        $pool = $this->cache;
175
176
        $this->assertTrue($pool->deleteItems(['foo', 'pool']));
177
        $this->assertFalse($pool->hasItem('foo'));
178
        $this->assertFalse($pool->hasItem('pool'));
179
180
        $item = $pool->getItem('foo');
181
        $item->set($data['foo']);
182
        $pool->save($item);
183
184
        $item = $pool->getItem('pool');
185
        $item->set($data['pool']);
186
        $pool->save($item);
187
188
        $this->assertTrue($pool->hasItem('foo'));
189
        $this->assertTrue($pool->hasItem('pool'));
190
191
        $foundItems = $pool->getItems(\array_keys($data));
192
        $this->assertInstanceOf(Generator::class, $foundItems);
193
194
        $items = [];
195
196
        foreach (\iterator_to_array($foundItems) as $id => $item) {
197
            $this->assertTrue($item->isHit());
198
            $this->assertInstanceOf(CacheItemInterface::class, $item);
199
            $items[$id] = $item->get();
200
        }
201
        $this->assertSame($data, $items);
202
203
        $this->assertTrue($pool->deleteItems(\array_keys($data)));
204
205
        $foundItems = $pool->getItems(\array_keys($data));
206
207
        foreach (\iterator_to_array($foundItems) as $id => $item) {
208
            $this->assertNull($item->get());
209
        }
210
211
        $pool->clear();
212
    }
213
214
    public function testDefaultLifeTime(): void
215
    {
216
        $pool = $this->cache;
217
218
        $item = $pool->getItem('key.dlt');
219
        $r    = new ReflectionProperty($item, 'defaultLifetime');
220
        $r->setAccessible(true);
221
        $r->setValue($item, 2);
222
223
        $item->expiresAfter(null);
224
        $pool->save($item);
225
        $this->assertTrue($pool->getItem('key.dlt')->isHit());
226
227
        \sleep(3);
228
229
        $this->assertFalse($pool->getItem('key.dlt')->isHit());
230
231
        $item = $pool->getItem('foo');
232
        $r    = new ReflectionProperty($item, 'defaultLifetime');
233
        $r->setAccessible(true);
234
        $r->setValue($item, 2);
235
236
        $item->expiresAt(null);
237
        $pool->save($item);
238
239
        \sleep(1);
240
241
        $this->assertTrue($pool->getItem('foo')->isHit());
242
243
        \sleep(3);
244
245
        $this->assertFalse($pool->getItem('foo')->isHit());
246
    }
247
248
    public function testItemExpiry(): void
249
    {
250
        $pool = $this->cache;
251
252
        $item = $pool->getItem('foo');
253
        $item->expiresAfter(2);
254
255
        $pool->save($item);
256
        $this->assertTrue($pool->getItem('foo')->isHit());
257
258
        \sleep(3);
259
260
        $this->assertFalse($pool->getItem('foo')->isHit());
261
262
        $item = $pool->getItem('foo');
263
        $item->expiresAfter(DateInterval::createFromDateString('yesterday'));
264
265
        $pool->save($item);
266
        $this->assertFalse($pool->getItem('foo')->isHit());
267
268
        $item = $pool->getItem('foo');
269
        $item->expiresAt(new DateTime('2 second'));
270
        $pool->save($item);
271
272
        \sleep(1);
273
274
        $this->assertTrue($pool->getItem('foo')->isHit());
275
276
        \sleep(3);
277
278
        $this->assertFalse($pool->getItem('foo')->isHit());
279
280
        $item = $pool->getItem('foo');
281
        $this->expectException(InvalidArgumentException::class);
282
        $this->expectExceptionMessage('Expiration date must be an integer, a DateInterval or null.');
283
        $item->expiresAfter('string');
0 ignored issues
show
'string' of type string is incompatible with the type DateInterval|integer|null expected by parameter $time of Psr\Cache\CacheItemInterface::expiresAfter(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

283
        $item->expiresAfter(/** @scrutinizer ignore-type */ 'string');
Loading history...
284
    }
285
286
    public function testNotUnserializableAndDeferred(): void
287
    {
288
        $pool = new CacheItemPool(new SimpleCache(new PhpFileCache(__DIR__ . '/caches')));
289
        $pool->clear();
290
291
        $item = $pool->getItem('foo');
292
        $item->set(new Fixtures\NotUnserializableTest());
293
        $pool->save($item);
294
        $this->assertNull($pool->getItem('foo')->get());
295
296
        $pool->clear();
297
298
        $this->assertTrue($pool->deleteItems(['foo']));
299
300
        $item = $pool->getItem('foo');
301
        $item->set(new Fixtures\NotUnserializableTest());
302
        $pool->saveDeferred($item);
303
304
        $this->assertTrue($pool->deleteItem('foo'));
305
306
        $pool->clear();
307
    }
308
309
    public function testSerialization(): void
310
    {
311
        $this->expectException(BadMethodCallException::class);
312
        $pool = \serialize($this->cache);
313
        $this->assertInstanceOf(__PHP_Incomplete_Class::class, $pool);
314
        $this->assertInstanceOf(CacheItemPool::class, \unserialize($pool));
315
    }
316
}
317