Passed
Push — master ( f5d81f...40d5c1 )
by Alexander
01:47
created

anonymous//tests/ArrayCache/ArrayCacheTest.php$0   A

Complexity

Total Complexity 1

Size/Duplication

Total Lines 4
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
wmc 1
1
<?php
2
3
namespace Yiisoft\Cache\Tests\ArrayCache;
4
5
use DateInterval;
6
use Psr\SimpleCache\CacheInterface;
7
use Psr\SimpleCache\InvalidArgumentException;
8
use ReflectionException;
9
use Yiisoft\Cache\ArrayCache;
10
use Yiisoft\Cache\Tests\MockHelper;
11
use Yiisoft\Cache\Tests\TestCase;
12
13
class ArrayCacheTest extends TestCase
14
{
15
    protected function tearDown(): void
16
    {
17
        MockHelper::resetMocks();
18
    }
19
20
    protected function createCacheInstance(): CacheInterface
21
    {
22
        return new ArrayCache();
23
    }
24
25
    public function testExpire(): void
26
    {
27
        $cache = $this->createCacheInstance();
28
        $cache->clear();
29
30
        MockHelper::$mock_time = \time();
31
        $this->assertTrue($cache->set('expire_test', 'expire_test', 2));
32
33
        MockHelper::$mock_time++;
34
        $this->assertTrue($cache->has('expire_test'));
35
        $this->assertSameExceptObject('expire_test', $cache->get('expire_test'));
36
37
        MockHelper::$mock_time++;
38
        $this->assertFalse($cache->has('expire_test'));
39
        $this->assertNull($cache->get('expire_test'));
40
    }
41
42
    /**
43
     * @dataProvider dataProvider
44
     * @param $key
45
     * @param $value
46
     * @throws InvalidArgumentException
47
     */
48
    public function testSet($key, $value): void
49
    {
50
        $cache = $this->createCacheInstance();
51
        $cache->clear();
52
53
        for ($i = 0; $i < 2; $i++) {
54
            $this->assertTrue($cache->set($key, $value));
55
        }
56
    }
57
58
    /**
59
     * @dataProvider dataProvider
60
     * @param $key
61
     * @param $value
62
     * @throws InvalidArgumentException
63
     */
64
    public function testGet($key, $value): void
65
    {
66
        $cache = $this->createCacheInstance();
67
        $cache->clear();
68
69
        $cache->set($key, $value);
70
        $valueFromCache = $cache->get($key, 'default');
71
72
        $this->assertSameExceptObject($value, $valueFromCache);
73
    }
74
75
    /**
76
     * @dataProvider dataProvider
77
     * @param $key
78
     * @param $value
79
     * @throws InvalidArgumentException
80
     */
81
    public function testValueInCacheCannotBeChanged($key, $value): void
82
    {
83
        $cache = $this->createCacheInstance();
84
        $cache->clear();
85
86
        $cache->set($key, $value);
87
        $valueFromCache = $cache->get($key, 'default');
88
89
        $this->assertSameExceptObject($value, $valueFromCache);
90
91
        if (is_object($value)) {
92
            $originalValue = clone $value;
93
            $valueFromCache->test_field = 'changed';
94
            $value->test_field = 'changed';
95
            $valueFromCacheNew = $cache->get($key, 'default');
96
            $this->assertSameExceptObject($originalValue, $valueFromCacheNew);
97
        }
98
    }
99
100
    /**
101
     * @dataProvider dataProvider
102
     * @param $key
103
     * @param $value
104
     * @throws InvalidArgumentException
105
     */
106
    public function testHas($key, $value): void
107
    {
108
        $cache = $this->createCacheInstance();
109
        $cache->clear();
110
111
        $cache->set($key, $value);
112
113
        $this->assertTrue($cache->has($key));
114
        // check whether exists affects the value
115
        $this->assertSameExceptObject($value, $cache->get($key));
116
117
        $this->assertTrue($cache->has($key));
118
        $this->assertFalse($cache->has('not_exists'));
119
    }
120
121
    public function testGetNonExistent(): void
122
    {
123
        $cache = $this->createCacheInstance();
124
        $cache->clear();
125
126
        $this->assertNull($cache->get('non_existent_key'));
127
    }
128
129
    /**
130
     * @dataProvider dataProvider
131
     * @param $key
132
     * @param $value
133
     * @throws InvalidArgumentException
134
     */
135
    public function testDelete($key, $value): void
136
    {
137
        $cache = $this->createCacheInstance();
138
        $cache->clear();
139
140
        $cache->set($key, $value);
141
142
        $this->assertSameExceptObject($value, $cache->get($key));
143
        $this->assertTrue($cache->delete($key));
144
        $this->assertNull($cache->get($key));
145
    }
146
147
    /**
148
     * @dataProvider dataProvider
149
     * @param $key
150
     * @param $value
151
     * @throws InvalidArgumentException
152
     */
153
    public function testClear($key, $value): void
154
    {
155
        $cache = $this->createCacheInstance();
156
        $cache = $this->prepare($cache);
157
158
        $this->assertTrue($cache->clear());
159
        $this->assertNull($cache->get($key));
160
    }
161
162
    /**
163
     * @dataProvider dataProviderSetMultiple
164
     * @param int|null $ttl
165
     * @throws InvalidArgumentException
166
     */
167
    public function testSetMultiple(?int $ttl): void
168
    {
169
        $cache = $this->createCacheInstance();
170
        $cache->clear();
171
172
        $data = $this->getDataProviderData();
173
174
        $cache->setMultiple($data, $ttl);
175
176
        foreach ($data as $key => $value) {
177
            $this->assertSameExceptObject($value, $cache->get((string)$key));
178
        }
179
    }
180
181
    /**
182
     * @return array testing multiSet with and without expiry
183
     */
184
    public function dataProviderSetMultiple(): array
185
    {
186
        return [
187
            [null],
188
            [2],
189
        ];
190
    }
191
192
    public function testGetMultiple(): void
193
    {
194
        $cache = $this->createCacheInstance();
195
        $cache->clear();
196
197
        $data = $this->getDataProviderData();
198
        $keys = array_map('strval', array_keys($data));
199
200
        $cache->setMultiple($data);
201
202
        $this->assertSameExceptObject($data, $cache->getMultiple($keys));
203
    }
204
205
    public function testDeleteMultiple(): void
206
    {
207
        $cache = $this->createCacheInstance();
208
        $cache->clear();
209
210
        $data = $this->getDataProviderData();
211
        $keys = array_map('strval', array_keys($data));
212
213
        $cache->setMultiple($data);
214
215
        $this->assertSameExceptObject($data, $cache->getMultiple($keys));
216
217
        $cache->deleteMultiple($keys);
218
219
        $emptyData = array_map(static function ($v) {
220
            return null;
221
        }, $data);
222
223
        $this->assertSameExceptObject($emptyData, $cache->getMultiple($keys));
224
    }
225
226
    public function testZeroAndNegativeTtl()
227
    {
228
        $cache = $this->createCacheInstance();
229
        $cache->clear();
230
        $cache->setMultiple([
231
            'a' => 1,
232
            'b' => 2,
233
        ]);
234
235
        $this->assertTrue($cache->has('a'));
236
        $this->assertTrue($cache->has('b'));
237
238
        $cache->set('a', 11, -1);
239
240
        $this->assertFalse($cache->has('a'));
241
242
        $cache->set('b', 22, 0);
243
244
        $this->assertFalse($cache->has('b'));
245
    }
246
247
    /**
248
     * @dataProvider dataProviderNormalizeTtl
249
     * @param mixed $ttl
250
     * @param mixed $expectedResult
251
     * @throws ReflectionException
252
     */
253
    public function testNormalizeTtl($ttl, $expectedResult): void
254
    {
255
        $cache = new ArrayCache();
256
        $this->assertSameExceptObject($expectedResult, $this->invokeMethod($cache, 'normalizeTtl', [$ttl]));
257
    }
258
259
    /**
260
     * Data provider for {@see testNormalizeTtl()}
261
     * @return array test data
262
     *
263
     * @throws \Exception
264
     */
265
    public function dataProviderNormalizeTtl(): array
266
    {
267
        return [
268
            [123, 123],
269
            ['123', 123],
270
            [null, null],
271
            [0, 0],
272
            [new DateInterval('PT6H8M'), 6 * 3600 + 8 * 60],
273
            [new DateInterval('P2Y4D'), 2 * 365 * 24 * 3600 + 4 * 24 * 3600],
274
        ];
275
    }
276
277
    /**
278
     * @dataProvider ttlToExpirationProvider
279
     * @param mixed $ttl
280
     * @param mixed $expected
281
     * @throws ReflectionException
282
     */
283
    public function testTtlToExpiration($ttl, $expected): void
284
    {
285
        if ($expected === 'calculate_expiration') {
286
            MockHelper::$mock_time = \time();
287
            $expected = MockHelper::$mock_time + $ttl;
288
        }
289
        $cache = new ArrayCache();
290
        $this->assertSameExceptObject($expected, $this->invokeMethod($cache, 'ttlToExpiration', [$ttl]));
291
    }
292
293
    public function ttlToExpirationProvider(): array
294
    {
295
        return [
296
            [3, 'calculate_expiration'],
297
            [null, 0],
298
            [-5, -1],
299
        ];
300
    }
301
302
    /**
303
     * @dataProvider iterableProvider
304
     * @param array $array
305
     * @param iterable $iterable
306
     * @throws InvalidArgumentException
307
     */
308
    public function testValuesAsIterable(array $array, iterable $iterable): void
309
    {
310
        $cache = $this->createCacheInstance();
311
        $cache->clear();
312
313
        $cache->setMultiple($iterable);
314
315
        $this->assertSameExceptObject($array, $cache->getMultiple(array_keys($array)));
316
    }
317
318
    public function iterableProvider(): array
319
    {
320
        return [
321
            'array' => [
322
                ['a' => 1, 'b' => 2,],
323
                ['a' => 1, 'b' => 2,],
324
            ],
325
            'ArrayIterator' => [
326
                ['a' => 1, 'b' => 2,],
327
                new \ArrayIterator(['a' => 1, 'b' => 2,]),
328
            ],
329
            'IteratorAggregate' => [
330
                ['a' => 1, 'b' => 2,],
331
                new class() implements \IteratorAggregate {
332
                    public function getIterator()
333
                    {
334
                        return new \ArrayIterator(['a' => 1, 'b' => 2,]);
335
                    }
336
                }
337
            ],
338
            'generator' => [
339
                ['a' => 1, 'b' => 2,],
340
                (static function () {
341
                    yield 'a' => 1;
342
                    yield 'b' => 2;
343
                })()
344
            ]
345
        ];
346
    }
347
348
    public function testSetWithDateIntervalTtl()
349
    {
350
        $cache = $this->createCacheInstance();
351
        $cache->clear();
352
353
        $cache->set('a', 1, new DateInterval('PT1H'));
354
        $this->assertSameExceptObject(1, $cache->get('a'));
355
356
        $cache->setMultiple(['b' => 2]);
357
        $this->assertSameExceptObject(['b' => 2], $cache->getMultiple(['b']));
358
    }
359
360
    public function testGetInvalidKey(): void
361
    {
362
        $this->expectException(InvalidArgumentException::class);
363
        $cache = $this->createCacheInstance();
364
        $cache->get(1);
365
    }
366
367
    public function testSetInvalidKey(): void
368
    {
369
        $this->expectException(InvalidArgumentException::class);
370
        $cache = $this->createCacheInstance();
371
        $cache->set(1, 1);
372
    }
373
374
    public function testDeleteInvalidKey(): void
375
    {
376
        $this->expectException(InvalidArgumentException::class);
377
        $cache = $this->createCacheInstance();
378
        $cache->delete(1);
379
    }
380
381
    public function testGetMultipleInvalidKeys(): void
382
    {
383
        $this->expectException(InvalidArgumentException::class);
384
        $cache = $this->createCacheInstance();
385
        $cache->getMultiple([true]);
386
    }
387
388
    public function testGetMultipleInvalidKeysNotIterable(): void
389
    {
390
        $this->expectException(InvalidArgumentException::class);
391
        $cache = $this->createCacheInstance();
392
        $cache->getMultiple(1);
393
    }
394
395
    public function testSetMultipleInvalidKeysNotIterable(): void
396
    {
397
        $this->expectException(InvalidArgumentException::class);
398
        $cache = $this->createCacheInstance();
399
        $cache->setMultiple(1);
400
    }
401
402
    public function testDeleteMultipleInvalidKeys(): void
403
    {
404
        $this->expectException(InvalidArgumentException::class);
405
        $cache = $this->createCacheInstance();
406
        $cache->deleteMultiple([true]);
407
    }
408
409
    public function testDeleteMultipleInvalidKeysNotIterable(): void
410
    {
411
        $this->expectException(InvalidArgumentException::class);
412
        $cache = $this->createCacheInstance();
413
        $cache->deleteMultiple(1);
414
    }
415
416
    public function testHasInvalidKey(): void
417
    {
418
        $this->expectException(InvalidArgumentException::class);
419
        $cache = $this->createCacheInstance();
420
        $cache->has(1);
421
    }
422
}
423