Passed
Push — master ( ebb577...c43191 )
by Alexander
03:05
created

ArrayCacheTest::createCacheInstance()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 1
c 1
b 0
f 0
nc 1
nop 0
dl 0
loc 3
rs 10
1
<?php
2
3
namespace Yiisoft\Cache\Tests\ArrayCache;
4
5
require_once __DIR__ . '/../MockHelper.php';
6
7
use DateInterval;
8
use Psr\SimpleCache\CacheInterface;
9
use Psr\SimpleCache\InvalidArgumentException;
10
use ReflectionException;
11
use Yiisoft\Cache\ArrayCache;
12
use Yiisoft\Cache\Cache;
13
use Yiisoft\Cache\MockHelper;
14
use Yiisoft\Cache\Tests\TestCase;
15
16
class ArrayCacheTest extends TestCase
17
{
18
    protected function tearDown(): void
19
    {
20
        MockHelper::$time = null;
21
    }
22
23
    protected function createCacheInstance(): CacheInterface
24
    {
25
        return new ArrayCache();
26
    }
27
28
    public function testExpire(): void
29
    {
30
        $cache = $this->createCacheInstance();
31
        $cache->clear();
32
33
        MockHelper::$time = \time();
34
        $this->assertTrue($cache->set('expire_test', 'expire_test', 2));
35
36
        MockHelper::$time++;
37
        $this->assertTrue($cache->has('expire_test'));
38
        $this->assertSameExceptObject('expire_test', $cache->get('expire_test'));
39
40
        MockHelper::$time++;
41
        $this->assertFalse($cache->has('expire_test'));
42
        $this->assertNull($cache->get('expire_test'));
43
    }
44
45
    /**
46
     * @dataProvider dataProvider
47
     * @param $key
48
     * @param $value
49
     * @throws InvalidArgumentException
50
     */
51
    public function testSet($key, $value): void
52
    {
53
        $cache = $this->createCacheInstance();
54
        $cache->clear();
55
56
        for ($i = 0; $i < 2; $i++) {
57
            $this->assertTrue($cache->set($key, $value));
58
        }
59
    }
60
61
    /**
62
     * @dataProvider dataProvider
63
     * @param $key
64
     * @param $value
65
     * @throws InvalidArgumentException
66
     */
67
    public function testGet($key, $value): void
68
    {
69
        $cache = $this->createCacheInstance();
70
        $cache->clear();
71
72
        $cache->set($key, $value);
73
        $valueFromCache = $cache->get($key, 'default');
74
75
        $this->assertSameExceptObject($value, $valueFromCache);
76
    }
77
78
    /**
79
     * @dataProvider dataProvider
80
     * @param $key
81
     * @param $value
82
     * @throws InvalidArgumentException
83
     */
84
    public function testValueInCacheCannotBeChanged($key, $value): void
85
    {
86
        $cache = $this->createCacheInstance();
87
        $cache->clear();
88
89
        $cache->set($key, $value);
90
        $valueFromCache = $cache->get($key, 'default');
91
92
        $this->assertSameExceptObject($value, $valueFromCache);
93
94
        if (is_object($value)) {
95
            $originalValue = clone $value;
96
            $valueFromCache->test_field = 'changed';
97
            $value->test_field = 'changed';
98
            $valueFromCacheNew = $cache->get($key, 'default');
99
            $this->assertSameExceptObject($originalValue, $valueFromCacheNew);
100
        }
101
    }
102
103
    /**
104
     * @dataProvider dataProvider
105
     * @param $key
106
     * @param $value
107
     * @throws InvalidArgumentException
108
     */
109
    public function testHas($key, $value): void
110
    {
111
        $cache = $this->createCacheInstance();
112
        $cache->clear();
113
114
        $cache->set($key, $value);
115
116
        $this->assertTrue($cache->has($key));
117
        // check whether exists affects the value
118
        $this->assertSameExceptObject($value, $cache->get($key));
119
120
        $this->assertTrue($cache->has($key));
121
        $this->assertFalse($cache->has('not_exists'));
122
    }
123
124
    public function testGetNonExistent(): void
125
    {
126
        $cache = $this->createCacheInstance();
127
        $cache->clear();
128
129
        $this->assertNull($cache->get('non_existent_key'));
130
    }
131
132
    /**
133
     * @dataProvider dataProvider
134
     * @param $key
135
     * @param $value
136
     * @throws InvalidArgumentException
137
     */
138
    public function testDelete($key, $value): void
139
    {
140
        $cache = $this->createCacheInstance();
141
        $cache->clear();
142
143
        $cache->set($key, $value);
144
145
        $this->assertSameExceptObject($value, $cache->get($key));
146
        $this->assertTrue($cache->delete($key));
147
        $this->assertNull($cache->get($key));
148
    }
149
150
    /**
151
     * @dataProvider dataProvider
152
     * @param $key
153
     * @param $value
154
     * @throws InvalidArgumentException
155
     */
156
    public function testClear($key, $value): void
0 ignored issues
show
Unused Code introduced by
The parameter $value is not used and could be removed. ( Ignorable by Annotation )

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

156
    public function testClear($key, /** @scrutinizer ignore-unused */ $value): void

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
157
    {
158
        $cache = $this->createCacheInstance();
159
        $cache = $this->prepare($cache);
160
161
        $this->assertTrue($cache->clear());
162
        $this->assertNull($cache->get($key));
163
    }
164
165
    /**
166
     * @dataProvider dataProviderSetMultiple
167
     * @param int|null $ttl
168
     * @throws InvalidArgumentException
169
     */
170
    public function testSetMultiple(?int $ttl): void
171
    {
172
        $cache = $this->createCacheInstance();
173
        $cache->clear();
174
175
        $data = $this->getDataProviderData();
176
177
        $cache->setMultiple($data, $ttl);
178
179
        foreach ($data as $key => $value) {
180
            $this->assertSameExceptObject($value, $cache->get((string)$key));
181
        }
182
    }
183
184
    /**
185
     * @return array testing multiSet with and without expiry
186
     */
187
    public function dataProviderSetMultiple(): array
188
    {
189
        return [
190
            [null],
191
            [2],
192
        ];
193
    }
194
195
    public function testGetMultiple(): void
196
    {
197
        $cache = $this->createCacheInstance();
198
        $cache->clear();
199
200
        $data = $this->getDataProviderData();
201
        $keys = array_map('strval', array_keys($data));
202
203
        $cache->setMultiple($data);
204
205
        $this->assertSameExceptObject($data, $cache->getMultiple($keys));
206
    }
207
208
    public function testDeleteMultiple(): void
209
    {
210
        $cache = $this->createCacheInstance();
211
        $cache->clear();
212
213
        $data = $this->getDataProviderData();
214
        $keys = array_map('strval', array_keys($data));
215
216
        $cache->setMultiple($data);
217
218
        $this->assertSameExceptObject($data, $cache->getMultiple($keys));
219
220
        $cache->deleteMultiple($keys);
221
222
        $emptyData = array_map(static function ($v) {
0 ignored issues
show
Unused Code introduced by
The parameter $v is not used and could be removed. ( Ignorable by Annotation )

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

222
        $emptyData = array_map(static function (/** @scrutinizer ignore-unused */ $v) {

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
223
            return null;
224
        }, $data);
225
226
        $this->assertSameExceptObject($emptyData, $cache->getMultiple($keys));
227
    }
228
229
    public function testZeroAndNegativeTtl()
230
    {
231
        $cache = $this->createCacheInstance();
232
        $cache->clear();
233
        $cache->setMultiple([
234
            'a' => 1,
235
            'b' => 2,
236
        ]);
237
238
        $this->assertTrue($cache->has('a'));
239
        $this->assertTrue($cache->has('b'));
240
241
        $cache->set('a', 11, -1);
242
243
        $this->assertFalse($cache->has('a'));
244
245
        $cache->set('b', 22, 0);
246
247
        $this->assertFalse($cache->has('b'));
248
    }
249
250
    /**
251
     * @dataProvider dataProviderNormalizeTtl
252
     * @param mixed $ttl
253
     * @param mixed $expectedResult
254
     * @throws ReflectionException
255
     */
256
    public function testNormalizeTtl($ttl, $expectedResult): void
257
    {
258
        $cache = new ArrayCache();
259
        $this->assertSameExceptObject($expectedResult, $this->invokeMethod($cache, 'normalizeTtl', [$ttl]));
260
    }
261
262
    /**
263
     * Data provider for {@see testNormalizeTtl()}
264
     * @return array test data
265
     *
266
     * @throws \Exception
267
     */
268
    public function dataProviderNormalizeTtl(): array
269
    {
270
        return [
271
            [123, 123],
272
            ['123', 123],
273
            [null, null],
274
            [0, 0],
275
            [new DateInterval('PT6H8M'), 6 * 3600 + 8 * 60],
276
            [new DateInterval('P2Y4D'), 2 * 365 * 24 * 3600 + 4 * 24 * 3600],
277
        ];
278
    }
279
280
    /**
281
     * @dataProvider ttlToExpirationProvider
282
     * @param mixed $ttl
283
     * @param mixed $expected
284
     * @throws ReflectionException
285
     */
286
    public function testTtlToExpiration($ttl, $expected): void
287
    {
288
        if ($expected === 'calculate_expiration') {
289
            MockHelper::$time = \time();
290
            $expected = MockHelper::$time + $ttl;
291
        }
292
        $cache = new ArrayCache();
293
        $this->assertSameExceptObject($expected, $this->invokeMethod($cache, 'ttlToExpiration', [$ttl]));
294
    }
295
296
    public function ttlToExpirationProvider(): array
297
    {
298
        return [
299
            [3, 'calculate_expiration'],
300
            [null, 0],
301
            [-5, -1],
302
        ];
303
    }
304
305
    /**
306
     * @dataProvider iterableProvider
307
     * @param array $array
308
     * @param iterable $iterable
309
     * @throws InvalidArgumentException
310
     */
311
    public function testValuesAsIterable(array $array, iterable $iterable): void
312
    {
313
        $cache = $this->createCacheInstance();
314
        $cache->clear();
315
316
        $cache->setMultiple($iterable);
317
318
        $this->assertSameExceptObject($array, $cache->getMultiple(array_keys($array)));
319
    }
320
321
    public function iterableProvider(): array
322
    {
323
        return [
324
            'array' => [
325
                ['a' => 1, 'b' => 2,],
326
                ['a' => 1, 'b' => 2,],
327
            ],
328
            'ArrayIterator' => [
329
                ['a' => 1, 'b' => 2,],
330
                new \ArrayIterator(['a' => 1, 'b' => 2,]),
331
            ],
332
            'IteratorAggregate' => [
333
                ['a' => 1, 'b' => 2,],
334
                new class() implements \IteratorAggregate {
335
                    public function getIterator()
336
                    {
337
                        return new \ArrayIterator(['a' => 1, 'b' => 2,]);
338
                    }
339
                }
340
            ],
341
            'generator' => [
342
                ['a' => 1, 'b' => 2,],
343
                (static function () {
344
                    yield 'a' => 1;
345
                    yield 'b' => 2;
346
                })()
347
            ]
348
        ];
349
    }
350
351
    public function testSetWithDateIntervalTtl()
352
    {
353
        $cache = $this->createCacheInstance();
354
        $cache->clear();
355
356
        $cache->set('a', 1, new DateInterval('PT1H'));
357
        $this->assertSameExceptObject(1, $cache->get('a'));
358
359
        $cache->setMultiple(['b' => 2]);
360
        $this->assertSameExceptObject(['b' => 2], $cache->getMultiple(['b']));
361
    }
362
363
    public function testGetInvalidKey(): void
364
    {
365
        $this->expectException(InvalidArgumentException::class);
366
        $cache = $this->createCacheInstance();
367
        $cache->get(1);
368
    }
369
370
    public function testSetInvalidKey(): void
371
    {
372
        $this->expectException(InvalidArgumentException::class);
373
        $cache = $this->createCacheInstance();
374
        $cache->set(1, 1);
375
    }
376
377
    public function testDeleteInvalidKey(): void
378
    {
379
        $this->expectException(InvalidArgumentException::class);
380
        $cache = $this->createCacheInstance();
381
        $cache->delete(1);
382
    }
383
384
    public function testGetMultipleInvalidKeys(): void
385
    {
386
        $this->expectException(InvalidArgumentException::class);
387
        $cache = $this->createCacheInstance();
388
        $cache->getMultiple([true]);
389
    }
390
391
    public function testGetMultipleInvalidKeysNotIterable(): void
392
    {
393
        $this->expectException(InvalidArgumentException::class);
394
        $cache = $this->createCacheInstance();
395
        $cache->getMultiple(1);
396
    }
397
398
    public function testSetMultipleInvalidKeysNotIterable(): void
399
    {
400
        $this->expectException(InvalidArgumentException::class);
401
        $cache = $this->createCacheInstance();
402
        $cache->setMultiple(1);
403
    }
404
405
    public function testDeleteMultipleInvalidKeys(): void
406
    {
407
        $this->expectException(InvalidArgumentException::class);
408
        $cache = $this->createCacheInstance();
409
        $cache->deleteMultiple([true]);
410
    }
411
412
    public function testDeleteMultipleInvalidKeysNotIterable(): void
413
    {
414
        $this->expectException(InvalidArgumentException::class);
415
        $cache = $this->createCacheInstance();
416
        $cache->deleteMultiple(1);
417
    }
418
419
    public function testHasInvalidKey(): void
420
    {
421
        $this->expectException(InvalidArgumentException::class);
422
        $cache = $this->createCacheInstance();
423
        $cache->has(1);
424
    }
425
}
426