1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace AsyncPHP\Icicle\Cache\Test\Driver; |
4
|
|
|
|
5
|
|
|
use AsyncPHP\Icicle\Cache\Driver\MemoryDriver; |
6
|
|
|
use PHPUnit_Framework_TestCase; |
7
|
|
|
use Icicle\Loop; |
8
|
|
|
use Icicle\Coroutine; |
9
|
|
|
|
10
|
|
|
class MemoryDriverTest extends PHPUnit_Framework_TestCase |
11
|
|
|
{ |
12
|
|
View Code Duplication |
public function testValuesNotSet() |
|
|
|
|
13
|
|
|
{ |
14
|
|
|
// create a coroutine to wrap the generator |
15
|
|
|
|
16
|
|
|
Coroutine\create(function() { |
17
|
|
|
$cache = new MemoryDriver(); |
18
|
|
|
$actual = (yield $cache->get("foo")); |
19
|
|
|
|
20
|
|
|
$this->assertEqualsAfterDelay(null, $actual); |
21
|
|
|
})->done(); |
22
|
|
|
|
23
|
|
|
// start the loop, so the coroutine runs |
24
|
|
|
|
25
|
|
|
Loop\run(); |
26
|
|
|
} |
27
|
|
|
|
28
|
|
|
/** |
29
|
|
|
* @param mixed $expected |
30
|
|
|
* @param mixed $actual |
31
|
|
|
*/ |
32
|
|
|
private function assertEqualsAfterDelay($expected, $actual) |
33
|
|
|
{ |
34
|
|
|
// after a small delay, check for a value |
35
|
|
|
|
36
|
|
|
Loop\timer(1, function() use ($expected, $actual) { |
37
|
|
|
$this->assertEquals($expected, $actual); |
38
|
|
|
|
39
|
|
|
// remember to stop the loop when the test if done |
40
|
|
|
|
41
|
|
|
Loop\stop(); |
42
|
|
|
}); |
43
|
|
|
} |
44
|
|
|
|
45
|
|
View Code Duplication |
public function testValueSet() |
|
|
|
|
46
|
|
|
{ |
47
|
|
|
Coroutine\create(function() { |
48
|
|
|
$cache = new MemoryDriver(); |
49
|
|
|
$actual = (yield $cache->set("foo", "bar")); |
50
|
|
|
|
51
|
|
|
$this->assertEqualsAfterDelay("bar", $actual); |
52
|
|
|
})->done(); |
53
|
|
|
|
54
|
|
|
Loop\run(); |
55
|
|
|
} |
56
|
|
|
|
57
|
|
View Code Duplication |
public function testCallbackValuesSet() |
|
|
|
|
58
|
|
|
{ |
59
|
|
|
Coroutine\create(function() { |
60
|
|
|
$cache = new MemoryDriver(); |
61
|
|
|
$actual = (yield $cache->set("foo", function() { |
62
|
|
|
yield "bar"; |
63
|
|
|
})); |
64
|
|
|
|
65
|
|
|
$this->assertEqualsAfterDelay("bar", $actual); |
66
|
|
|
})->done(); |
67
|
|
|
|
68
|
|
|
Loop\run(); |
69
|
|
|
} |
70
|
|
|
|
71
|
|
|
public function testValueForgotten() |
72
|
|
|
{ |
73
|
|
|
Coroutine\create(function() { |
74
|
|
|
$cache = new MemoryDriver(); |
75
|
|
|
yield $cache->set("foo", "bar"); |
76
|
|
|
yield $cache->forget("foo"); |
77
|
|
|
$actual = (yield $cache->get("foo")); |
78
|
|
|
|
79
|
|
|
$this->assertEqualsAfterDelay(null, $actual); |
80
|
|
|
})->done(); |
81
|
|
|
|
82
|
|
|
Loop\run(); |
83
|
|
|
} |
84
|
|
|
|
85
|
|
|
public function testStampedeProtection() |
86
|
|
|
{ |
87
|
|
|
Coroutine\create(function() { |
88
|
|
|
$cache = new MemoryDriver(); |
89
|
|
|
|
90
|
|
|
file_put_contents(__DIR__ . "/stampede", 1); |
91
|
|
|
|
92
|
|
|
$factory = function() use (&$counter) { |
93
|
|
|
$count = (int) file_get_contents(__DIR__ . "/stampede"); |
94
|
|
|
|
95
|
|
|
file_put_contents(__DIR__ . "/stampede", ++$count); |
96
|
|
|
|
97
|
|
|
yield $count; |
98
|
|
|
}; |
99
|
|
|
|
100
|
|
|
$cache->set("counter", $factory); |
101
|
|
|
$cache->set("counter", $factory); |
102
|
|
|
$cache->set("counter", $factory); |
103
|
|
|
|
104
|
|
|
$cache->get("counter"); |
105
|
|
|
$cache->get("counter"); |
106
|
|
|
|
107
|
|
|
// resolve the first "counter" value |
108
|
|
|
|
109
|
|
|
yield $cache->get("counter"); |
110
|
|
|
|
111
|
|
|
// fetch the second "counter" value from the cache memory store |
112
|
|
|
|
113
|
|
|
$actual = (yield $cache->get("counter")); |
114
|
|
|
|
115
|
|
|
// first check to see that the count stored in the filesystem |
116
|
|
|
// is correct... |
117
|
|
|
|
118
|
|
|
Loop\timer(0.5, function() { |
119
|
|
|
$count = (int) file_get_contents(__DIR__ . "/stampede"); |
120
|
|
|
|
121
|
|
|
$this->assertEquals(2, $count); |
122
|
|
|
|
123
|
|
|
unlink(__DIR__ . "/stampede"); |
124
|
|
|
}); |
125
|
|
|
|
126
|
|
|
// then check to see that the count stored in the cache |
127
|
|
|
// is correct... |
128
|
|
|
|
129
|
|
|
$this->assertEqualsAfterDelay(2, $actual); |
130
|
|
|
})->done(); |
131
|
|
|
|
132
|
|
|
Loop\run(); |
133
|
|
|
} |
134
|
|
|
} |
135
|
|
|
|
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.