Passed
Pull Request — master (#6)
by Alexander
01:55
created

ApcuCacheTest::normalizeAPCUoutput()

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 4
c 0
b 0
f 0
dl 0
loc 8
nc 2
nop 1
1
<?php
2
3
namespace Yiisoft\Cache\Apcu\Tests;
4
5
use DateInterval;
6
use Psr\SimpleCache\CacheInterface;
7
use Psr\SimpleCache\InvalidArgumentException;
8
use ReflectionException;
9
use Yiisoft\Cache\Apcu\ApcuCache;
10
11
class ApcuCacheTest extends TestCase
12
{
13
    public static function setUpBeforeClass(): void
14
    {
15
        if (!extension_loaded('apcu')) {
16
            self::markTestSkipped('Required extension "apcu" is not loaded');
17
        }
18
19
        if (!ini_get('apc.enable_cli')) {
20
            self::markTestSkipped('APC is installed but not enabled. Enable with "apc.enable_cli=1" from php.ini. Skipping.');
21
        }
22
    }
23
24
    protected function createCacheInstance(): CacheInterface
25
    {
26
        return new ApcuCache();
27
    }
28
29
    /**
30
     * @dataProvider dataProvider
31
     * @param $key
32
     * @param $value
33
     * @throws InvalidArgumentException
34
     */
35
    public function testSet($key, $value): void
36
    {
37
        $cache = $this->createCacheInstance();
38
        $cache->clear();
39
40
        for ($i = 0; $i < 2; $i++) {
41
            $this->assertTrue($cache->set($key, $value));
42
        }
43
    }
44
45
    /**
46
     * @dataProvider dataProvider
47
     * @param $key
48
     * @param $value
49
     * @throws InvalidArgumentException
50
     */
51
    public function testGet($key, $value): void
52
    {
53
        $cache = $this->createCacheInstance();
54
        $cache->clear();
55
56
        $cache->set($key, $value);
57
        $valueFromCache = $cache->get($key, 'default');
58
59
        $this->assertSameExceptObject($value, $valueFromCache);
60
    }
61
62
    /**
63
     * @dataProvider dataProvider
64
     * @param $key
65
     * @param $value
66
     * @throws InvalidArgumentException
67
     */
68
    public function testValueInCacheCannotBeChanged($key, $value): void
69
    {
70
        $cache = $this->createCacheInstance();
71
        $cache->clear();
72
73
        $cache->set($key, $value);
74
        $valueFromCache = $cache->get($key, 'default');
75
76
        $this->assertSameExceptObject($value, $valueFromCache);
77
78
        if (is_object($value)) {
79
            $originalValue = clone $value;
80
            $valueFromCache->test_field = 'changed';
81
            $value->test_field = 'changed';
82
            $valueFromCacheNew = $cache->get($key, 'default');
83
            $this->assertSameExceptObject($originalValue, $valueFromCacheNew);
84
        }
85
    }
86
87
    /**
88
     * @dataProvider dataProvider
89
     * @param $key
90
     * @param $value
91
     * @throws InvalidArgumentException
92
     */
93
    public function testHas($key, $value): void
94
    {
95
        $cache = $this->createCacheInstance();
96
        $cache->clear();
97
98
        $cache->set($key, $value);
99
100
        $this->assertTrue($cache->has($key));
101
        // check whether exists affects the value
102
        $this->assertSameExceptObject($value, $cache->get($key));
103
104
        $this->assertTrue($cache->has($key));
105
        $this->assertFalse($cache->has('not_exists'));
106
    }
107
108
    public function testGetNonExistent(): void
109
    {
110
        $cache = $this->createCacheInstance();
111
        $cache->clear();
112
113
        $this->assertNull($cache->get('non_existent_key'));
114
    }
115
116
    /**
117
     * @dataProvider dataProvider
118
     * @param $key
119
     * @param $value
120
     * @throws InvalidArgumentException
121
     */
122
    public function testDelete($key, $value): void
123
    {
124
        $cache = $this->createCacheInstance();
125
        $cache->clear();
126
127
        $cache->set($key, $value);
128
129
        $this->assertSameExceptObject($value, $cache->get($key));
130
        $this->assertTrue($cache->delete($key));
131
        $this->assertNull($cache->get($key));
132
    }
133
134
    /**
135
     * @dataProvider dataProvider
136
     * @param $key
137
     * @param $value
138
     * @throws InvalidArgumentException
139
     */
140
    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

140
    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...
141
    {
142
        $cache = $this->createCacheInstance();
143
        $cache = $this->prepare($cache);
144
145
        $this->assertTrue($cache->clear());
146
        $this->assertNull($cache->get($key));
147
    }
148
149
    /**
150
     * @dataProvider dataProviderSetMultiple
151
     * @param int|null $ttl
152
     * @throws InvalidArgumentException
153
     */
154
    public function testSetMultiple(?int $ttl): void
155
    {
156
        $cache = $this->createCacheInstance();
157
        $cache->clear();
158
159
        $data = $this->getDataProviderData();
160
161
        $cache->setMultiple($data, $ttl);
162
163
        foreach ($data as $key => $value) {
164
            $this->assertSameExceptObject($value, $cache->get((string)$key));
165
        }
166
    }
167
168
    /**
169
     * @return array testing multiSet with and without expiry
170
     */
171
    public function dataProviderSetMultiple(): array
172
    {
173
        return [
174
            [null],
175
            [2],
176
        ];
177
    }
178
179
    public function testGetMultiple(): void
180
    {
181
        $cache = $this->createCacheInstance();
182
        $cache->clear();
183
184
        $data = $this->getDataProviderData();
185
        $keys = array_map('strval', array_keys($data));
186
187
        $cache->setMultiple($data);
188
189
        $this->assertSameExceptObject($data, $cache->getMultiple($keys));
190
    }
191
192
    public function testDeleteMultiple(): 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
        $cache->deleteMultiple($keys);
205
206
        $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

206
        $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...
207
            return null;
208
        }, $data);
209
210
        $this->assertSameExceptObject($emptyData, $cache->getMultiple($keys));
211
    }
212
213
    public function testNegativeTtl(): void
214
    {
215
        $cache = $this->createCacheInstance();
216
        $cache->clear();
217
        $cache->setMultiple([
218
            'a' => 1,
219
            'b' => 2,
220
        ]);
221
222
        $this->assertTrue($cache->has('a'));
223
        $this->assertTrue($cache->has('b'));
224
225
        $cache->set('a', 11, -1);
226
227
        $this->assertFalse($cache->has('a'));
228
    }
229
230
    /**
231
     * @dataProvider dataProviderNormalizeTtl
232
     * @param mixed $ttl
233
     * @param mixed $expectedResult
234
     * @throws ReflectionException
235
     */
236
    public function testNormalizeTtl($ttl, $expectedResult): void
237
    {
238
        $cache = new ApcuCache();
239
        $this->assertSameExceptObject($expectedResult, $this->invokeMethod($cache, 'normalizeTtl', [$ttl]));
240
    }
241
242
    /**
243
     * Data provider for {@see testNormalizeTtl()}
244
     * @return array test data
245
     *
246
     * @throws \Exception
247
     */
248
    public function dataProviderNormalizeTtl(): array
249
    {
250
        return [
251
            [123, 123],
252
            ['123', 123],
253
            ['', 0],
254
            [null, 0],
255
            [0, 0],
256
            [new DateInterval('PT6H8M'), 6 * 3600 + 8 * 60],
257
            [new DateInterval('P2Y4D'), 2 * 365 * 24 * 3600 + 4 * 24 * 3600],
258
        ];
259
    }
260
261
    /**
262
     * @dataProvider iterableProvider
263
     * @param array $array
264
     * @param iterable $iterable
265
     * @throws InvalidArgumentException
266
     */
267
    public function testValuesAsIterable(array $array, iterable $iterable): void
268
    {
269
        $cache = $this->createCacheInstance();
270
        $cache->clear();
271
272
        $cache->setMultiple($iterable);
273
274
        $this->assertSameExceptObject($array, $cache->getMultiple(array_keys($array)));
275
    }
276
277
    public function iterableProvider(): array
278
    {
279
        return [
280
            'array' => [
281
                ['a' => 1, 'b' => 2,],
282
                ['a' => 1, 'b' => 2,],
283
            ],
284
            'ArrayIterator' => [
285
                ['a' => 1, 'b' => 2,],
286
                new \ArrayIterator(['a' => 1, 'b' => 2,]),
287
            ],
288
            'IteratorAggregate' => [
289
                ['a' => 1, 'b' => 2,],
290
                new class() implements \IteratorAggregate
291
                {
292
                    public function getIterator()
293
                    {
294
                        return new \ArrayIterator(['a' => 1, 'b' => 2,]);
295
                    }
296
                }
297
            ],
298
            'generator' => [
299
                ['a' => 1, 'b' => 2,],
300
                (static function () {
301
                    yield 'a' => 1;
302
                    yield 'b' => 2;
303
                })()
304
            ]
305
        ];
306
    }
307
308
    public function testSetWithDateIntervalTtl(): void
309
    {
310
        $cache = $this->createCacheInstance();
311
        $cache->clear();
312
313
        $cache->set('a', 1, new DateInterval('PT1H'));
314
        $this->assertSameExceptObject(1, $cache->get('a'));
315
316
        $cache->setMultiple(['b' => 2]);
317
        $this->assertSameExceptObject(['b' => 2], $cache->getMultiple(['b']));
318
    }
319
320
    public function testGetInvalidKey(): void
321
    {
322
        $this->expectException(InvalidArgumentException::class);
323
        $cache = $this->createCacheInstance();
324
        $cache->get(1);
325
    }
326
327
    public function testSetInvalidKey(): void
328
    {
329
        $this->expectException(InvalidArgumentException::class);
330
        $cache = $this->createCacheInstance();
331
        $cache->set(1, 1);
332
    }
333
334
    public function testDeleteInvalidKey(): void
335
    {
336
        $this->expectException(InvalidArgumentException::class);
337
        $cache = $this->createCacheInstance();
338
        $cache->delete(1);
339
    }
340
341
    public function testGetMultipleInvalidKeys(): void
342
    {
343
        $this->expectException(InvalidArgumentException::class);
344
        $cache = $this->createCacheInstance();
345
        $cache->getMultiple([true]);
346
    }
347
348
    public function testGetMultipleInvalidKeysNotIterable(): void
349
    {
350
        $this->expectException(InvalidArgumentException::class);
351
        $cache = $this->createCacheInstance();
352
        $cache->getMultiple(1);
353
    }
354
355
    public function testSetMultipleInvalidKeysNotIterable(): void
356
    {
357
        $this->expectException(InvalidArgumentException::class);
358
        $cache = $this->createCacheInstance();
359
        $cache->setMultiple(1);
360
    }
361
362
    public function testDeleteMultipleInvalidKeys(): void
363
    {
364
        $this->expectException(InvalidArgumentException::class);
365
        $cache = $this->createCacheInstance();
366
        $cache->deleteMultiple([true]);
367
    }
368
369
    public function testDeleteMultipleInvalidKeysNotIterable(): void
370
    {
371
        $this->expectException(InvalidArgumentException::class);
372
        $cache = $this->createCacheInstance();
373
        $cache->deleteMultiple(1);
374
    }
375
376
    public function testHasInvalidKey(): void
377
    {
378
        $this->expectException(InvalidArgumentException::class);
379
        $cache = $this->createCacheInstance();
380
        $cache->has(1);
381
    }
382
383
    /*public function testTest()
384
    {
385
        $store = \apcu_store('123', '321');
386
        $fetch = \apcu_fetch('123', $success);
387
        $this->assertSame('321', $fetch);
388
389
        $valuesFromCache = \apcu_fetch(['123'], $successMultiple);
390
        $values = $this->normalizeAPCUoutput($valuesFromCache);
391
        $this->assertSame(['123' => '321'], $values);
392
    }*/
393
394
    /**
395
     * Normalizes keys returned from apcu_fetch in multiple mode. If one of the keys is an integer (123) or a string
396
     * representation of an integer ('123') the returned key from the cache doesn't equal neither to an integer nor a
397
     * string ($key !== 123 and $key !== '123'). Coping element from the returned array one by one to the new array
398
     * fixes this issue.
399
     * @param array $values
400
     * @return array
401
     */
402
    private function normalizeAPCUoutput(array $values): array
0 ignored issues
show
Unused Code introduced by
The method normalizeAPCUoutput() is not used, and could be removed.

This check looks for private methods that have been defined, but are not used inside the class.

Loading history...
403
    {
404
        $normalizedValues = [];
405
        foreach ($values as $key => $value) {
406
            $normalizedValues[$key] = $value;
407
        }
408
409
        return $normalizedValues;
410
    }
411
}
412