|
1
|
|
|
<?php |
|
2
|
|
|
|
|
3
|
|
|
namespace Kodus\Cache\Tests; |
|
4
|
|
|
|
|
5
|
|
|
use function array_merge; |
|
6
|
|
|
use function chr; |
|
7
|
|
|
use function is_array; |
|
8
|
|
|
use function is_bool; |
|
9
|
|
|
use function is_float; |
|
10
|
|
|
use function is_int; |
|
11
|
|
|
use function is_object; |
|
12
|
|
|
use function is_string; |
|
13
|
|
|
use PHPUnit\Framework\TestCase; |
|
14
|
|
|
use Psr\SimpleCache\CacheInterface; |
|
15
|
|
|
use Psr\SimpleCache\InvalidArgumentException; |
|
16
|
|
|
use function sleep; |
|
17
|
|
|
use function sort; |
|
18
|
|
|
use function str_repeat; |
|
19
|
|
|
|
|
20
|
|
|
/** |
|
21
|
|
|
* TODO contribute back to `php-cache/integration-tests` project and depend on that |
|
22
|
|
|
* |
|
23
|
|
|
* @see https://github.com/php-cache/integration-tests/blob/master/src/SimpleCacheTest.php |
|
24
|
|
|
*/ |
|
25
|
|
|
abstract class SimpleCacheTest extends TestCase |
|
26
|
|
|
{ |
|
27
|
|
|
/** |
|
28
|
|
|
* @type array with functionName => reason. |
|
29
|
|
|
*/ |
|
30
|
|
|
protected $skippedTests = []; |
|
31
|
|
|
|
|
32
|
|
|
/** |
|
33
|
|
|
* @type CacheInterface |
|
34
|
|
|
*/ |
|
35
|
|
|
protected $cache; |
|
36
|
|
|
|
|
37
|
|
|
/** |
|
38
|
|
|
* @return CacheInterface that is used in the tests |
|
39
|
|
|
*/ |
|
40
|
|
|
abstract public function createSimpleCache(); |
|
41
|
|
|
|
|
42
|
|
|
protected function setUp(): void |
|
43
|
|
|
{ |
|
44
|
|
|
$this->cache = $this->createSimpleCache(); |
|
45
|
|
|
} |
|
46
|
|
|
|
|
47
|
|
|
protected function tearDown(): void |
|
48
|
|
|
{ |
|
49
|
|
|
if ($this->cache !== null) { |
|
50
|
|
|
$this->cache->clear(); |
|
51
|
|
|
} |
|
52
|
|
|
} |
|
53
|
|
|
|
|
54
|
|
|
/** |
|
55
|
|
|
* Implementations can override this implementation to emulate `sleep()` by |
|
56
|
|
|
* "time traveling" internally in the cache-implementation, for faster testing. |
|
57
|
|
|
* |
|
58
|
|
|
* @param int $time |
|
59
|
|
|
*/ |
|
60
|
|
|
protected function sleep(int $time) |
|
61
|
|
|
{ |
|
62
|
|
|
sleep($time); |
|
63
|
|
|
} |
|
64
|
|
|
|
|
65
|
|
|
/** |
|
66
|
|
|
* Data provider for invalid cache keys. |
|
67
|
|
|
* |
|
68
|
|
|
* @return array |
|
69
|
|
|
*/ |
|
70
|
|
|
public static function invalidKeys() |
|
71
|
|
|
{ |
|
72
|
|
|
return array_merge( |
|
73
|
|
|
self::invalidArrayKeys(), |
|
74
|
|
|
[ |
|
75
|
|
|
[2], |
|
76
|
|
|
] |
|
77
|
|
|
); |
|
78
|
|
|
} |
|
79
|
|
|
|
|
80
|
|
|
/** |
|
81
|
|
|
* Data provider for invalid array keys. |
|
82
|
|
|
* |
|
83
|
|
|
* @return array |
|
84
|
|
|
*/ |
|
85
|
|
|
public static function invalidArrayKeys() |
|
86
|
|
|
{ |
|
87
|
|
|
return [ |
|
88
|
|
|
[''], |
|
89
|
|
|
[true], |
|
90
|
|
|
[false], |
|
91
|
|
|
[null], |
|
92
|
|
|
[2.5], |
|
93
|
|
|
['{str'], |
|
94
|
|
|
['rand{'], |
|
95
|
|
|
['rand{str'], |
|
96
|
|
|
['rand}str'], |
|
97
|
|
|
['rand(str'], |
|
98
|
|
|
['rand)str'], |
|
99
|
|
|
['rand/str'], |
|
100
|
|
|
['rand\\str'], |
|
101
|
|
|
['rand@str'], |
|
102
|
|
|
['rand:str'], |
|
103
|
|
|
[new \stdClass()], |
|
104
|
|
|
[['array']], |
|
105
|
|
|
]; |
|
106
|
|
|
} |
|
107
|
|
|
|
|
108
|
|
|
/** |
|
109
|
|
|
* @return array |
|
110
|
|
|
*/ |
|
111
|
|
|
public static function invalidTtl() |
|
112
|
|
|
{ |
|
113
|
|
|
return [ |
|
114
|
|
|
[''], |
|
115
|
|
|
[true], |
|
116
|
|
|
[false], |
|
117
|
|
|
['abc'], |
|
118
|
|
|
[2.5], |
|
119
|
|
|
[' 1'], // can be casted to a int |
|
120
|
|
|
['12foo'], // can be casted to a int |
|
121
|
|
|
['025'], // can be interpreted as hex |
|
122
|
|
|
[new \stdClass()], |
|
123
|
|
|
[['array']], |
|
124
|
|
|
]; |
|
125
|
|
|
} |
|
126
|
|
|
|
|
127
|
|
|
/** |
|
128
|
|
|
* Data provider for valid keys. |
|
129
|
|
|
* |
|
130
|
|
|
* @return array |
|
131
|
|
|
*/ |
|
132
|
|
|
public static function validKeys() |
|
133
|
|
|
{ |
|
134
|
|
|
return [ |
|
135
|
|
|
['AbC19_.'], |
|
136
|
|
|
['1234567890123456789012345678901234567890123456789012345678901234'], |
|
137
|
|
|
]; |
|
138
|
|
|
} |
|
139
|
|
|
|
|
140
|
|
|
/** |
|
141
|
|
|
* Data provider for valid data to store. |
|
142
|
|
|
* |
|
143
|
|
|
* @return array |
|
144
|
|
|
*/ |
|
145
|
|
|
public static function validData() |
|
146
|
|
|
{ |
|
147
|
|
|
return [ |
|
148
|
|
|
['AbC19_.'], |
|
149
|
|
|
[4711], |
|
150
|
|
|
[47.11], |
|
151
|
|
|
[true], |
|
152
|
|
|
[null], |
|
153
|
|
|
[['key' => 'value']], |
|
154
|
|
|
[new \stdClass()], |
|
155
|
|
|
]; |
|
156
|
|
|
} |
|
157
|
|
|
|
|
158
|
|
|
public function testSet() |
|
159
|
|
|
{ |
|
160
|
|
|
if (isset($this->skippedTests[__FUNCTION__])) { |
|
161
|
|
|
$this->markTestSkipped($this->skippedTests[__FUNCTION__]); |
|
162
|
|
|
} |
|
163
|
|
|
|
|
164
|
|
|
$result = $this->cache->set('key', 'value'); |
|
165
|
|
|
$this->assertTrue($result, 'set() must return true if success'); |
|
166
|
|
|
$this->assertEquals('value', $this->cache->get('key')); |
|
167
|
|
|
} |
|
168
|
|
|
|
|
169
|
|
|
public function testSetTtl() |
|
170
|
|
|
{ |
|
171
|
|
|
if (isset($this->skippedTests[__FUNCTION__])) { |
|
172
|
|
|
$this->markTestSkipped($this->skippedTests[__FUNCTION__]); |
|
173
|
|
|
} |
|
174
|
|
|
|
|
175
|
|
|
$result = $this->cache->set('key1', 'value', 1); |
|
176
|
|
|
$this->assertTrue($result, 'set() must return true if success'); |
|
177
|
|
|
$this->assertEquals('value', $this->cache->get('key1')); |
|
178
|
|
|
$this->sleep(2); |
|
179
|
|
|
$this->assertNull($this->cache->get('key1'), 'Value must expire after ttl.'); |
|
180
|
|
|
|
|
181
|
|
|
$this->cache->set('key2', 'value', new \DateInterval('PT1S')); |
|
182
|
|
|
$this->assertEquals('value', $this->cache->get('key2')); |
|
183
|
|
|
$this->sleep(2); |
|
184
|
|
|
$this->assertNull($this->cache->get('key2'), 'Value must expire after ttl.'); |
|
185
|
|
|
} |
|
186
|
|
|
|
|
187
|
|
|
public function testSetExpiredTtl() |
|
188
|
|
|
{ |
|
189
|
|
|
if (isset($this->skippedTests[__FUNCTION__])) { |
|
190
|
|
|
$this->markTestSkipped($this->skippedTests[__FUNCTION__]); |
|
191
|
|
|
} |
|
192
|
|
|
|
|
193
|
|
|
$this->cache->set('key0', 'value'); |
|
194
|
|
|
$this->cache->set('key0', 'value', 0); |
|
195
|
|
|
$this->assertNull($this->cache->get('key0')); |
|
196
|
|
|
$this->assertFalse($this->cache->has('key0')); |
|
197
|
|
|
|
|
198
|
|
|
$this->cache->set('key1', 'value', -1); |
|
199
|
|
|
$this->assertNull($this->cache->get('key1')); |
|
200
|
|
|
$this->assertFalse($this->cache->has('key1')); |
|
201
|
|
|
} |
|
202
|
|
|
|
|
203
|
|
View Code Duplication |
public function testGet() |
|
|
|
|
|
|
204
|
|
|
{ |
|
205
|
|
|
if (isset($this->skippedTests[__FUNCTION__])) { |
|
206
|
|
|
$this->markTestSkipped($this->skippedTests[__FUNCTION__]); |
|
207
|
|
|
} |
|
208
|
|
|
|
|
209
|
|
|
$this->assertNull($this->cache->get('key')); |
|
210
|
|
|
$this->assertEquals('foo', $this->cache->get('key', 'foo')); |
|
211
|
|
|
|
|
212
|
|
|
$this->cache->set('key', 'value'); |
|
213
|
|
|
$this->assertEquals('value', $this->cache->get('key', 'foo')); |
|
214
|
|
|
} |
|
215
|
|
|
|
|
216
|
|
View Code Duplication |
public function testDelete() |
|
|
|
|
|
|
217
|
|
|
{ |
|
218
|
|
|
if (isset($this->skippedTests[__FUNCTION__])) { |
|
219
|
|
|
$this->markTestSkipped($this->skippedTests[__FUNCTION__]); |
|
220
|
|
|
} |
|
221
|
|
|
|
|
222
|
|
|
$this->assertTrue($this->cache->delete('key'), 'Deleting a value that does not exist should return true'); |
|
223
|
|
|
$this->cache->set('key', 'value'); |
|
224
|
|
|
$this->assertTrue($this->cache->delete('key'), 'Delete must return true on success'); |
|
225
|
|
|
$this->assertNull($this->cache->get('key'), 'Values must be deleted on delete()'); |
|
226
|
|
|
} |
|
227
|
|
|
|
|
228
|
|
View Code Duplication |
public function testClear() |
|
|
|
|
|
|
229
|
|
|
{ |
|
230
|
|
|
if (isset($this->skippedTests[__FUNCTION__])) { |
|
231
|
|
|
$this->markTestSkipped($this->skippedTests[__FUNCTION__]); |
|
232
|
|
|
} |
|
233
|
|
|
|
|
234
|
|
|
$this->assertTrue($this->cache->clear(), 'Clearing an empty cache should return true'); |
|
235
|
|
|
$this->cache->set('key', 'value'); |
|
236
|
|
|
$this->assertTrue($this->cache->clear(), 'Delete must return true on success'); |
|
237
|
|
|
$this->assertNull($this->cache->get('key'), 'Values must be deleted on clear()'); |
|
238
|
|
|
} |
|
239
|
|
|
|
|
240
|
|
|
public function testSetMultiple() |
|
241
|
|
|
{ |
|
242
|
|
|
if (isset($this->skippedTests[__FUNCTION__])) { |
|
243
|
|
|
$this->markTestSkipped($this->skippedTests[__FUNCTION__]); |
|
244
|
|
|
} |
|
245
|
|
|
|
|
246
|
|
|
$result = $this->cache->setMultiple(['key0' => 'value0', 'key1' => 'value1']); |
|
|
|
|
|
|
247
|
|
|
$this->assertTrue($result, 'setMultiple() must return true if success'); |
|
248
|
|
|
$this->assertEquals('value0', $this->cache->get('key0')); |
|
249
|
|
|
$this->assertEquals('value1', $this->cache->get('key1')); |
|
250
|
|
|
} |
|
251
|
|
|
|
|
252
|
|
View Code Duplication |
public function testSetMultipleWithIntegerArrayKey() |
|
|
|
|
|
|
253
|
|
|
{ |
|
254
|
|
|
if (isset($this->skippedTests[__FUNCTION__])) { |
|
255
|
|
|
$this->markTestSkipped($this->skippedTests[__FUNCTION__]); |
|
256
|
|
|
} |
|
257
|
|
|
|
|
258
|
|
|
$result = $this->cache->setMultiple(['0' => 'value0']); |
|
|
|
|
|
|
259
|
|
|
$this->assertTrue($result, 'setMultiple() must return true if success'); |
|
260
|
|
|
$this->assertEquals('value0', $this->cache->get('0')); |
|
261
|
|
|
} |
|
262
|
|
|
|
|
263
|
|
|
public function testSetMultipleTtl() |
|
264
|
|
|
{ |
|
265
|
|
|
if (isset($this->skippedTests[__FUNCTION__])) { |
|
266
|
|
|
$this->markTestSkipped($this->skippedTests[__FUNCTION__]); |
|
267
|
|
|
} |
|
268
|
|
|
|
|
269
|
|
|
$this->cache->setMultiple(['key2' => 'value2', 'key3' => 'value3'], 1); |
|
|
|
|
|
|
270
|
|
|
$this->assertEquals('value2', $this->cache->get('key2')); |
|
271
|
|
|
$this->assertEquals('value3', $this->cache->get('key3')); |
|
272
|
|
|
$this->sleep(2); |
|
273
|
|
|
$this->assertNull($this->cache->get('key2'), 'Value must expire after ttl.'); |
|
274
|
|
|
$this->assertNull($this->cache->get('key3'), 'Value must expire after ttl.'); |
|
275
|
|
|
|
|
276
|
|
|
$this->cache->setMultiple(['key4' => 'value4'], new \DateInterval('PT1S')); |
|
|
|
|
|
|
277
|
|
|
$this->assertEquals('value4', $this->cache->get('key4')); |
|
278
|
|
|
$this->sleep(2); |
|
279
|
|
|
$this->assertNull($this->cache->get('key4'), 'Value must expire after ttl.'); |
|
280
|
|
|
} |
|
281
|
|
|
|
|
282
|
|
|
public function testSetMultipleExpiredTtl() |
|
283
|
|
|
{ |
|
284
|
|
|
if (isset($this->skippedTests[__FUNCTION__])) { |
|
285
|
|
|
$this->markTestSkipped($this->skippedTests[__FUNCTION__]); |
|
286
|
|
|
} |
|
287
|
|
|
|
|
288
|
|
|
$this->cache->setMultiple(['key0' => 'value0', 'key1' => 'value1'], 0); |
|
|
|
|
|
|
289
|
|
|
$this->assertNull($this->cache->get('key0')); |
|
290
|
|
|
$this->assertNull($this->cache->get('key1')); |
|
291
|
|
|
} |
|
292
|
|
|
|
|
293
|
|
|
public function testSetMultipleWithGenerator() |
|
294
|
|
|
{ |
|
295
|
|
|
if (isset($this->skippedTests[__FUNCTION__])) { |
|
296
|
|
|
$this->markTestSkipped($this->skippedTests[__FUNCTION__]); |
|
297
|
|
|
} |
|
298
|
|
|
|
|
299
|
|
|
$gen = function () { |
|
300
|
|
|
yield 'key0' => 'value0'; |
|
301
|
|
|
yield 'key1' => 'value1'; |
|
302
|
|
|
}; |
|
303
|
|
|
|
|
304
|
|
|
$this->cache->setMultiple($gen()); |
|
305
|
|
|
$this->assertEquals('value0', $this->cache->get('key0')); |
|
306
|
|
|
$this->assertEquals('value1', $this->cache->get('key1')); |
|
307
|
|
|
} |
|
308
|
|
|
|
|
309
|
|
|
public function testGetMultiple() |
|
310
|
|
|
{ |
|
311
|
|
|
if (isset($this->skippedTests[__FUNCTION__])) { |
|
312
|
|
|
$this->markTestSkipped($this->skippedTests[__FUNCTION__]); |
|
313
|
|
|
} |
|
314
|
|
|
|
|
315
|
|
|
$result = $this->cache->getMultiple(['key0', 'key1']); |
|
|
|
|
|
|
316
|
|
|
$keys = []; |
|
317
|
|
|
foreach ($result as $i => $r) { |
|
318
|
|
|
$keys[] = $i; |
|
319
|
|
|
$this->assertNull($r); |
|
320
|
|
|
} |
|
321
|
|
|
sort($keys); |
|
322
|
|
|
$this->assertSame(['key0', 'key1'], $keys); |
|
323
|
|
|
|
|
324
|
|
|
$this->cache->set('key3', 'value'); |
|
325
|
|
|
$result = $this->cache->getMultiple(['key2', 'key3', 'key4'], 'foo'); |
|
|
|
|
|
|
326
|
|
|
$keys = []; |
|
327
|
|
View Code Duplication |
foreach ($result as $key => $r) { |
|
|
|
|
|
|
328
|
|
|
$keys[] = $key; |
|
329
|
|
|
if ($key === 'key3') { |
|
330
|
|
|
$this->assertEquals('value', $r); |
|
331
|
|
|
} else { |
|
332
|
|
|
$this->assertEquals('foo', $r); |
|
333
|
|
|
} |
|
334
|
|
|
} |
|
335
|
|
|
sort($keys); |
|
336
|
|
|
$this->assertSame(['key2', 'key3', 'key4'], $keys); |
|
337
|
|
|
} |
|
338
|
|
|
|
|
339
|
|
|
public function testGetMultipleWithGenerator() |
|
340
|
|
|
{ |
|
341
|
|
|
if (isset($this->skippedTests[__FUNCTION__])) { |
|
342
|
|
|
$this->markTestSkipped($this->skippedTests[__FUNCTION__]); |
|
343
|
|
|
} |
|
344
|
|
|
|
|
345
|
|
|
$gen = function () { |
|
346
|
|
|
yield 1 => 'key0'; |
|
347
|
|
|
yield 1 => 'key1'; |
|
348
|
|
|
}; |
|
349
|
|
|
|
|
350
|
|
|
$this->cache->set('key0', 'value0'); |
|
351
|
|
|
$result = $this->cache->getMultiple($gen()); |
|
352
|
|
|
$keys = []; |
|
353
|
|
View Code Duplication |
foreach ($result as $key => $r) { |
|
|
|
|
|
|
354
|
|
|
$keys[] = $key; |
|
355
|
|
|
if ($key === 'key0') { |
|
356
|
|
|
$this->assertEquals('value0', $r); |
|
357
|
|
|
} elseif ($key === 'key1') { |
|
358
|
|
|
$this->assertNull($r); |
|
359
|
|
|
} else { |
|
360
|
|
|
$this->assertFalse(true, 'This should not happend'); |
|
361
|
|
|
} |
|
362
|
|
|
} |
|
363
|
|
|
sort($keys); |
|
364
|
|
|
$this->assertSame(['key0', 'key1'], $keys); |
|
365
|
|
|
$this->assertEquals('value0', $this->cache->get('key0')); |
|
366
|
|
|
$this->assertNull($this->cache->get('key1')); |
|
367
|
|
|
} |
|
368
|
|
|
|
|
369
|
|
|
public function testDeleteMultiple() |
|
370
|
|
|
{ |
|
371
|
|
|
if (isset($this->skippedTests[__FUNCTION__])) { |
|
372
|
|
|
$this->markTestSkipped($this->skippedTests[__FUNCTION__]); |
|
373
|
|
|
} |
|
374
|
|
|
|
|
375
|
|
|
$this->assertTrue($this->cache->deleteMultiple([]), 'Deleting a empty array should return true'); |
|
|
|
|
|
|
376
|
|
|
$this->assertTrue($this->cache->deleteMultiple(['key']), 'Deleting a value that does not exist should return true'); |
|
|
|
|
|
|
377
|
|
|
|
|
378
|
|
|
$this->cache->set('key0', 'value0'); |
|
379
|
|
|
$this->cache->set('key1', 'value1'); |
|
380
|
|
|
$this->assertTrue($this->cache->deleteMultiple(['key0', 'key1']), 'Delete must return true on success'); |
|
|
|
|
|
|
381
|
|
|
$this->assertNull($this->cache->get('key0'), 'Values must be deleted on deleteMultiple()'); |
|
382
|
|
|
$this->assertNull($this->cache->get('key1'), 'Values must be deleted on deleteMultiple()'); |
|
383
|
|
|
} |
|
384
|
|
|
|
|
385
|
|
|
public function testDeleteMultipleGenerator() |
|
386
|
|
|
{ |
|
387
|
|
|
if (isset($this->skippedTests[__FUNCTION__])) { |
|
388
|
|
|
$this->markTestSkipped($this->skippedTests[__FUNCTION__]); |
|
389
|
|
|
} |
|
390
|
|
|
|
|
391
|
|
|
$gen = function () { |
|
392
|
|
|
yield 1 => 'key0'; |
|
393
|
|
|
yield 1 => 'key1'; |
|
394
|
|
|
}; |
|
395
|
|
|
$this->cache->set('key0', 'value0'); |
|
396
|
|
|
$this->assertTrue($this->cache->deleteMultiple($gen()), 'Deleting a generator should return true'); |
|
397
|
|
|
|
|
398
|
|
|
$this->assertNull($this->cache->get('key0'), 'Values must be deleted on deleteMultiple()'); |
|
399
|
|
|
$this->assertNull($this->cache->get('key1'), 'Values must be deleted on deleteMultiple()'); |
|
400
|
|
|
} |
|
401
|
|
|
|
|
402
|
|
|
public function testHas() |
|
403
|
|
|
{ |
|
404
|
|
|
if (isset($this->skippedTests[__FUNCTION__])) { |
|
405
|
|
|
$this->markTestSkipped($this->skippedTests[__FUNCTION__]); |
|
406
|
|
|
} |
|
407
|
|
|
|
|
408
|
|
|
$this->assertFalse($this->cache->has('key0')); |
|
409
|
|
|
$this->cache->set('key0', 'value0'); |
|
410
|
|
|
$this->assertTrue($this->cache->has('key0')); |
|
411
|
|
|
} |
|
412
|
|
|
|
|
413
|
|
|
public function testBasicUsageWithLongKey() |
|
414
|
|
|
{ |
|
415
|
|
|
if (isset($this->skippedTests[__FUNCTION__])) { |
|
416
|
|
|
$this->markTestSkipped($this->skippedTests[__FUNCTION__]); |
|
417
|
|
|
} |
|
418
|
|
|
|
|
419
|
|
|
$key = str_repeat('a', 300); |
|
420
|
|
|
|
|
421
|
|
|
$this->assertFalse($this->cache->has($key)); |
|
422
|
|
|
$this->assertTrue($this->cache->set($key, 'value')); |
|
423
|
|
|
|
|
424
|
|
|
$this->assertTrue($this->cache->has($key)); |
|
425
|
|
|
$this->assertSame('value', $this->cache->get($key)); |
|
426
|
|
|
|
|
427
|
|
|
$this->assertTrue($this->cache->delete($key)); |
|
428
|
|
|
|
|
429
|
|
|
$this->assertFalse($this->cache->has($key)); |
|
430
|
|
|
} |
|
431
|
|
|
|
|
432
|
|
|
/** |
|
433
|
|
|
* @dataProvider invalidKeys |
|
434
|
|
|
*/ |
|
435
|
|
|
public function testGetInvalidKeys($key) |
|
436
|
|
|
{ |
|
437
|
|
|
$this->expectException(InvalidArgumentException::class); |
|
438
|
|
|
|
|
439
|
|
|
if (isset($this->skippedTests[__FUNCTION__])) { |
|
440
|
|
|
$this->markTestSkipped($this->skippedTests[__FUNCTION__]); |
|
441
|
|
|
} |
|
442
|
|
|
|
|
443
|
|
|
$this->cache->get($key); |
|
444
|
|
|
} |
|
445
|
|
|
|
|
446
|
|
|
/** |
|
447
|
|
|
* @dataProvider invalidKeys |
|
448
|
|
|
*/ |
|
449
|
|
|
public function testGetMultipleInvalidKeys($key) |
|
450
|
|
|
{ |
|
451
|
|
|
$this->expectException(InvalidArgumentException::class); |
|
452
|
|
|
|
|
453
|
|
|
if (isset($this->skippedTests[__FUNCTION__])) { |
|
454
|
|
|
$this->markTestSkipped($this->skippedTests[__FUNCTION__]); |
|
455
|
|
|
} |
|
456
|
|
|
|
|
457
|
|
|
$result = $this->cache->getMultiple(['key1', $key, 'key2']); |
|
|
|
|
|
|
458
|
|
|
} |
|
459
|
|
|
|
|
460
|
|
View Code Duplication |
public function testGetMultipleNoIterable() |
|
|
|
|
|
|
461
|
|
|
{ |
|
462
|
|
|
$this->expectException(InvalidArgumentException::class); |
|
463
|
|
|
|
|
464
|
|
|
if (isset($this->skippedTests[__FUNCTION__])) { |
|
465
|
|
|
$this->markTestSkipped($this->skippedTests[__FUNCTION__]); |
|
466
|
|
|
} |
|
467
|
|
|
|
|
468
|
|
|
$result = $this->cache->getMultiple('key'); |
|
|
|
|
|
|
469
|
|
|
} |
|
470
|
|
|
|
|
471
|
|
|
/** |
|
472
|
|
|
* @dataProvider invalidKeys |
|
473
|
|
|
*/ |
|
474
|
|
View Code Duplication |
public function testSetInvalidKeys($key) |
|
|
|
|
|
|
475
|
|
|
{ |
|
476
|
|
|
$this->expectException(InvalidArgumentException::class); |
|
477
|
|
|
|
|
478
|
|
|
if (isset($this->skippedTests[__FUNCTION__])) { |
|
479
|
|
|
$this->markTestSkipped($this->skippedTests[__FUNCTION__]); |
|
480
|
|
|
} |
|
481
|
|
|
|
|
482
|
|
|
$this->cache->set($key, 'foobar'); |
|
483
|
|
|
} |
|
484
|
|
|
|
|
485
|
|
|
/** |
|
486
|
|
|
* @dataProvider invalidArrayKeys |
|
487
|
|
|
*/ |
|
488
|
|
|
public function testSetMultipleInvalidKeys($key) |
|
489
|
|
|
{ |
|
490
|
|
|
$this->expectException(InvalidArgumentException::class); |
|
491
|
|
|
|
|
492
|
|
|
if (isset($this->skippedTests[__FUNCTION__])) { |
|
493
|
|
|
$this->markTestSkipped($this->skippedTests[__FUNCTION__]); |
|
494
|
|
|
} |
|
495
|
|
|
|
|
496
|
|
|
$values = function () use ($key) { |
|
497
|
|
|
yield 'key1' => 'foo'; |
|
498
|
|
|
yield $key => 'bar'; |
|
499
|
|
|
yield 'key2' => 'baz'; |
|
500
|
|
|
}; |
|
501
|
|
|
|
|
502
|
|
|
$this->cache->setMultiple($values()); |
|
503
|
|
|
} |
|
504
|
|
|
|
|
505
|
|
|
public function testSetMultipleNoIterable() |
|
506
|
|
|
{ |
|
507
|
|
|
$this->expectException(InvalidArgumentException::class); |
|
508
|
|
|
|
|
509
|
|
|
if (isset($this->skippedTests[__FUNCTION__])) { |
|
510
|
|
|
$this->markTestSkipped($this->skippedTests[__FUNCTION__]); |
|
511
|
|
|
} |
|
512
|
|
|
|
|
513
|
|
|
$this->cache->setMultiple('key'); |
|
|
|
|
|
|
514
|
|
|
} |
|
515
|
|
|
|
|
516
|
|
|
/** |
|
517
|
|
|
* @dataProvider invalidKeys |
|
518
|
|
|
*/ |
|
519
|
|
|
public function testHasInvalidKeys($key) |
|
520
|
|
|
{ |
|
521
|
|
|
$this->expectException(InvalidArgumentException::class); |
|
522
|
|
|
|
|
523
|
|
|
if (isset($this->skippedTests[__FUNCTION__])) { |
|
524
|
|
|
$this->markTestSkipped($this->skippedTests[__FUNCTION__]); |
|
525
|
|
|
} |
|
526
|
|
|
|
|
527
|
|
|
$this->cache->has($key); |
|
528
|
|
|
} |
|
529
|
|
|
|
|
530
|
|
|
/** |
|
531
|
|
|
* @dataProvider invalidKeys |
|
532
|
|
|
*/ |
|
533
|
|
|
public function testDeleteInvalidKeys($key) |
|
534
|
|
|
{ |
|
535
|
|
|
$this->expectException(InvalidArgumentException::class); |
|
536
|
|
|
|
|
537
|
|
|
if (isset($this->skippedTests[__FUNCTION__])) { |
|
538
|
|
|
$this->markTestSkipped($this->skippedTests[__FUNCTION__]); |
|
539
|
|
|
} |
|
540
|
|
|
|
|
541
|
|
|
$this->cache->delete($key); |
|
542
|
|
|
} |
|
543
|
|
|
|
|
544
|
|
|
/** |
|
545
|
|
|
* @dataProvider invalidKeys |
|
546
|
|
|
*/ |
|
547
|
|
|
public function testDeleteMultipleInvalidKeys($key) |
|
548
|
|
|
{ |
|
549
|
|
|
$this->expectException(InvalidArgumentException::class); |
|
550
|
|
|
|
|
551
|
|
|
if (isset($this->skippedTests[__FUNCTION__])) { |
|
552
|
|
|
$this->markTestSkipped($this->skippedTests[__FUNCTION__]); |
|
553
|
|
|
} |
|
554
|
|
|
|
|
555
|
|
|
$this->cache->deleteMultiple(['key1', $key, 'key2']); |
|
|
|
|
|
|
556
|
|
|
} |
|
557
|
|
|
|
|
558
|
|
|
public function testDeleteMultipleNoIterable() |
|
559
|
|
|
{ |
|
560
|
|
|
$this->expectException(InvalidArgumentException::class); |
|
561
|
|
|
|
|
562
|
|
|
if (isset($this->skippedTests[__FUNCTION__])) { |
|
563
|
|
|
$this->markTestSkipped($this->skippedTests[__FUNCTION__]); |
|
564
|
|
|
} |
|
565
|
|
|
|
|
566
|
|
|
$this->cache->deleteMultiple('key'); |
|
|
|
|
|
|
567
|
|
|
} |
|
568
|
|
|
|
|
569
|
|
|
/** |
|
570
|
|
|
* @dataProvider invalidTtl |
|
571
|
|
|
*/ |
|
572
|
|
View Code Duplication |
public function testSetInvalidTtl($ttl) |
|
|
|
|
|
|
573
|
|
|
{ |
|
574
|
|
|
$this->expectException(InvalidArgumentException::class); |
|
575
|
|
|
|
|
576
|
|
|
if (isset($this->skippedTests[__FUNCTION__])) { |
|
577
|
|
|
$this->markTestSkipped($this->skippedTests[__FUNCTION__]); |
|
578
|
|
|
} |
|
579
|
|
|
|
|
580
|
|
|
$this->cache->set('key', 'value', $ttl); |
|
581
|
|
|
} |
|
582
|
|
|
|
|
583
|
|
|
/** |
|
584
|
|
|
* @dataProvider invalidTtl |
|
585
|
|
|
*/ |
|
586
|
|
View Code Duplication |
public function testSetMultipleInvalidTtl($ttl) |
|
|
|
|
|
|
587
|
|
|
{ |
|
588
|
|
|
$this->expectException(InvalidArgumentException::class); |
|
589
|
|
|
|
|
590
|
|
|
if (isset($this->skippedTests[__FUNCTION__])) { |
|
591
|
|
|
$this->markTestSkipped($this->skippedTests[__FUNCTION__]); |
|
592
|
|
|
} |
|
593
|
|
|
|
|
594
|
|
|
$this->cache->setMultiple(['key' => 'value'], $ttl); |
|
|
|
|
|
|
595
|
|
|
} |
|
596
|
|
|
|
|
597
|
|
|
public function testNullOverwrite() |
|
598
|
|
|
{ |
|
599
|
|
|
if (isset($this->skippedTests[__FUNCTION__])) { |
|
600
|
|
|
$this->markTestSkipped($this->skippedTests[__FUNCTION__]); |
|
601
|
|
|
} |
|
602
|
|
|
|
|
603
|
|
|
$this->cache->set('key', 5); |
|
604
|
|
|
$this->cache->set('key', null); |
|
605
|
|
|
|
|
606
|
|
|
$this->assertNull($this->cache->get('key'), 'Setting null to a key must overwrite previous value'); |
|
607
|
|
|
} |
|
608
|
|
|
|
|
609
|
|
View Code Duplication |
public function testDataTypeString() |
|
|
|
|
|
|
610
|
|
|
{ |
|
611
|
|
|
if (isset($this->skippedTests[__FUNCTION__])) { |
|
612
|
|
|
$this->markTestSkipped($this->skippedTests[__FUNCTION__]); |
|
613
|
|
|
} |
|
614
|
|
|
|
|
615
|
|
|
$this->cache->set('key', '5'); |
|
616
|
|
|
$result = $this->cache->get('key'); |
|
617
|
|
|
$this->assertTrue('5' === $result, 'Wrong data type. If we store a string we must get an string back.'); |
|
618
|
|
|
$this->assertTrue(is_string($result), 'Wrong data type. If we store a string we must get an string back.'); |
|
619
|
|
|
} |
|
620
|
|
|
|
|
621
|
|
View Code Duplication |
public function testDataTypeInteger() |
|
|
|
|
|
|
622
|
|
|
{ |
|
623
|
|
|
if (isset($this->skippedTests[__FUNCTION__])) { |
|
624
|
|
|
$this->markTestSkipped($this->skippedTests[__FUNCTION__]); |
|
625
|
|
|
} |
|
626
|
|
|
|
|
627
|
|
|
$this->cache->set('key', 5); |
|
628
|
|
|
$result = $this->cache->get('key'); |
|
629
|
|
|
$this->assertTrue(5 === $result, 'Wrong data type. If we store an int we must get an int back.'); |
|
630
|
|
|
$this->assertTrue(is_int($result), 'Wrong data type. If we store an int we must get an int back.'); |
|
631
|
|
|
} |
|
632
|
|
|
|
|
633
|
|
View Code Duplication |
public function testDataTypeFloat() |
|
|
|
|
|
|
634
|
|
|
{ |
|
635
|
|
|
if (isset($this->skippedTests[__FUNCTION__])) { |
|
636
|
|
|
$this->markTestSkipped($this->skippedTests[__FUNCTION__]); |
|
637
|
|
|
} |
|
638
|
|
|
|
|
639
|
|
|
$float = 1.23456789; |
|
640
|
|
|
$this->cache->set('key', $float); |
|
641
|
|
|
$result = $this->cache->get('key'); |
|
642
|
|
|
$this->assertTrue(is_float($result), 'Wrong data type. If we store float we must get an float back.'); |
|
643
|
|
|
$this->assertEquals($float, $result); |
|
644
|
|
|
} |
|
645
|
|
|
|
|
646
|
|
|
public function testDataTypeBoolean() |
|
647
|
|
|
{ |
|
648
|
|
|
if (isset($this->skippedTests[__FUNCTION__])) { |
|
649
|
|
|
$this->markTestSkipped($this->skippedTests[__FUNCTION__]); |
|
650
|
|
|
} |
|
651
|
|
|
|
|
652
|
|
|
$this->cache->set('key', false); |
|
653
|
|
|
$result = $this->cache->get('key'); |
|
654
|
|
|
$this->assertTrue(is_bool($result), 'Wrong data type. If we store boolean we must get an boolean back.'); |
|
655
|
|
|
$this->assertFalse($result); |
|
656
|
|
|
$this->assertTrue($this->cache->has('key'), 'has() should return true when true are stored. '); |
|
657
|
|
|
} |
|
658
|
|
|
|
|
659
|
|
|
public function testDataTypeArray() |
|
660
|
|
|
{ |
|
661
|
|
|
if (isset($this->skippedTests[__FUNCTION__])) { |
|
662
|
|
|
$this->markTestSkipped($this->skippedTests[__FUNCTION__]); |
|
663
|
|
|
} |
|
664
|
|
|
|
|
665
|
|
|
$array = ['a' => 'foo', 2 => 'bar']; |
|
666
|
|
|
$this->cache->set('key', $array); |
|
667
|
|
|
$result = $this->cache->get('key'); |
|
668
|
|
|
$this->assertTrue(is_array($result), 'Wrong data type. If we store array we must get an array back.'); |
|
669
|
|
|
$this->assertEquals($array, $result); |
|
670
|
|
|
} |
|
671
|
|
|
|
|
672
|
|
View Code Duplication |
public function testDataTypeObject() |
|
|
|
|
|
|
673
|
|
|
{ |
|
674
|
|
|
if (isset($this->skippedTests[__FUNCTION__])) { |
|
675
|
|
|
$this->markTestSkipped($this->skippedTests[__FUNCTION__]); |
|
676
|
|
|
} |
|
677
|
|
|
|
|
678
|
|
|
$object = new \stdClass(); |
|
679
|
|
|
$object->a = 'foo'; |
|
680
|
|
|
$this->cache->set('key', $object); |
|
681
|
|
|
$result = $this->cache->get('key'); |
|
682
|
|
|
$this->assertTrue(is_object($result), 'Wrong data type. If we store object we must get an object back.'); |
|
683
|
|
|
$this->assertEquals($object, $result); |
|
684
|
|
|
} |
|
685
|
|
|
|
|
686
|
|
|
public function testBinaryData() |
|
687
|
|
|
{ |
|
688
|
|
|
if (isset($this->skippedTests[__FUNCTION__])) { |
|
689
|
|
|
$this->markTestSkipped($this->skippedTests[__FUNCTION__]); |
|
690
|
|
|
} |
|
691
|
|
|
|
|
692
|
|
|
$data = ''; |
|
693
|
|
|
for ($i = 0; $i < 256; $i++) { |
|
694
|
|
|
$data .= chr($i); |
|
695
|
|
|
} |
|
696
|
|
|
|
|
697
|
|
|
$this->cache->set('key', $data); |
|
698
|
|
|
$result = $this->cache->get('key'); |
|
699
|
|
|
$this->assertTrue($data === $result, 'Binary data must survive a round trip.'); |
|
700
|
|
|
} |
|
701
|
|
|
|
|
702
|
|
|
/** |
|
703
|
|
|
* @dataProvider validKeys |
|
704
|
|
|
*/ |
|
705
|
|
View Code Duplication |
public function testSetValidKeys($key) |
|
|
|
|
|
|
706
|
|
|
{ |
|
707
|
|
|
if (isset($this->skippedTests[__FUNCTION__])) { |
|
708
|
|
|
$this->markTestSkipped($this->skippedTests[__FUNCTION__]); |
|
709
|
|
|
} |
|
710
|
|
|
|
|
711
|
|
|
$this->cache->set($key, 'foobar'); |
|
712
|
|
|
$this->assertEquals('foobar', $this->cache->get($key)); |
|
713
|
|
|
} |
|
714
|
|
|
|
|
715
|
|
|
/** |
|
716
|
|
|
* @dataProvider validKeys |
|
717
|
|
|
*/ |
|
718
|
|
|
public function testSetMultipleValidKeys($key) |
|
719
|
|
|
{ |
|
720
|
|
|
if (isset($this->skippedTests[__FUNCTION__])) { |
|
721
|
|
|
$this->markTestSkipped($this->skippedTests[__FUNCTION__]); |
|
722
|
|
|
} |
|
723
|
|
|
|
|
724
|
|
|
$this->cache->setMultiple([$key => 'foobar']); |
|
|
|
|
|
|
725
|
|
|
$result = $this->cache->getMultiple([$key]); |
|
|
|
|
|
|
726
|
|
|
$keys = []; |
|
727
|
|
|
foreach ($result as $i => $r) { |
|
728
|
|
|
$keys[] = $i; |
|
729
|
|
|
$this->assertEquals($key, $i); |
|
730
|
|
|
$this->assertEquals('foobar', $r); |
|
731
|
|
|
} |
|
732
|
|
|
$this->assertSame([$key], $keys); |
|
733
|
|
|
} |
|
734
|
|
|
|
|
735
|
|
|
/** |
|
736
|
|
|
* @dataProvider validData |
|
737
|
|
|
*/ |
|
738
|
|
View Code Duplication |
public function testSetValidData($data) |
|
|
|
|
|
|
739
|
|
|
{ |
|
740
|
|
|
if (isset($this->skippedTests[__FUNCTION__])) { |
|
741
|
|
|
$this->markTestSkipped($this->skippedTests[__FUNCTION__]); |
|
742
|
|
|
} |
|
743
|
|
|
|
|
744
|
|
|
$this->cache->set('key', $data); |
|
745
|
|
|
$this->assertEquals($data, $this->cache->get('key')); |
|
746
|
|
|
} |
|
747
|
|
|
|
|
748
|
|
|
/** |
|
749
|
|
|
* @dataProvider validData |
|
750
|
|
|
*/ |
|
751
|
|
|
public function testSetMultipleValidData($data) |
|
752
|
|
|
{ |
|
753
|
|
|
if (isset($this->skippedTests[__FUNCTION__])) { |
|
754
|
|
|
$this->markTestSkipped($this->skippedTests[__FUNCTION__]); |
|
755
|
|
|
} |
|
756
|
|
|
|
|
757
|
|
|
$this->cache->setMultiple(['key' => $data]); |
|
|
|
|
|
|
758
|
|
|
$result = $this->cache->getMultiple(['key']); |
|
|
|
|
|
|
759
|
|
|
$keys = []; |
|
760
|
|
|
foreach ($result as $i => $r) { |
|
761
|
|
|
$keys[] = $i; |
|
762
|
|
|
$this->assertEquals($data, $r); |
|
763
|
|
|
} |
|
764
|
|
|
$this->assertSame(['key'], $keys); |
|
765
|
|
|
} |
|
766
|
|
|
|
|
767
|
|
|
public function testObjectAsDefaultValue() |
|
768
|
|
|
{ |
|
769
|
|
|
if (isset($this->skippedTests[__FUNCTION__])) { |
|
770
|
|
|
$this->markTestSkipped($this->skippedTests[__FUNCTION__]); |
|
771
|
|
|
} |
|
772
|
|
|
|
|
773
|
|
|
$obj = new \stdClass(); |
|
774
|
|
|
$obj->foo = 'value'; |
|
775
|
|
|
$this->assertEquals($obj, $this->cache->get('key', $obj)); |
|
776
|
|
|
} |
|
777
|
|
|
|
|
778
|
|
|
public function testObjectDoesNotChangeInCache() |
|
779
|
|
|
{ |
|
780
|
|
|
if (isset($this->skippedTests[__FUNCTION__])) { |
|
781
|
|
|
$this->markTestSkipped($this->skippedTests[__FUNCTION__]); |
|
782
|
|
|
} |
|
783
|
|
|
|
|
784
|
|
|
$obj = new \stdClass(); |
|
785
|
|
|
$obj->foo = 'value'; |
|
786
|
|
|
$this->cache->set('key', $obj); |
|
787
|
|
|
$obj->foo = 'changed'; |
|
788
|
|
|
|
|
789
|
|
|
$cacheObject = $this->cache->get('key'); |
|
790
|
|
|
$this->assertEquals('value', $cacheObject->foo, 'Object in cache should not have their values changed.'); |
|
791
|
|
|
} |
|
792
|
|
|
} |
|
793
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.